00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 #include <stdio.h>
00136 #include <stdlib.h>
00137 #include <math.h>
00138
00139
00140
00141 #include <string.h>
00142 #include <glib.h>
00143
00144 #include <utils/utils.h>
00145 #include <sed/sed_sedflux.h>
00146 #include "bing.h"
00147
00148 #ifndef DENSITY_OF_SEA_WATER
00149 # define DENSITY_OF_SEA_WATER sed_rho_sea_water()
00150 #endif
00151 #ifndef GRAVITY
00152 # define GRAVITY sed_gravity()
00153 #endif
00154 #ifndef EPS
00155 # define EPS .0001
00156 #endif
00157
00158 double *bing(pos_t *bathy,pos_t *fail,bing_t consts,double *deposit)
00159 {
00160 #ifdef BING_STANDALONE
00161 extern FILE *bing_fpout_;
00162 #endif
00163 int Mcount;
00164 int i, j, nFlowNodes, nNodes;
00165 int Xj;
00166 double yieldStrength, viscosity, numericalViscosity, flowDensity, dt, maxTime;
00167 int MC;
00168 double Sj;
00169 double Xgrav, Xpres, Xresi, Xyield, Xmom, Xp1, Xp2;
00170 double dU, Dp, Ds, art1;
00171 double Ttime, Drho;
00172 double *area, *slope;
00173 double *finalX, *finalH;
00174 double *initX, *initY, *finalY;
00175 node *flow;
00176
00177 yieldStrength = consts.yieldStrength;
00178 viscosity = consts.viscosity;
00179 numericalViscosity = consts.numericalViscosity;
00180 flowDensity = consts.flowDensity;
00181 dt = consts.dt;
00182 maxTime = consts.maxTime;
00183 MC = consts.MC;
00184 nFlowNodes = fail->size;
00185 nNodes = bathy->size;
00186
00187
00188
00189
00190 flow = eh_new( node , nFlowNodes );
00191 area = eh_new( double , nFlowNodes );
00192
00193 finalX = eh_new( double , nFlowNodes );
00194 finalH = eh_new( double , nFlowNodes );
00195 finalY = eh_new( double , nFlowNodes );
00196 initX = eh_new( double , nFlowNodes );
00197 initY = eh_new( double , nFlowNodes );
00198
00199 memcpy(initX,fail->x,nFlowNodes*sizeof(double));
00200 interpolate(bathy->x,bathy->y,bathy->size,fail->x,initY,fail->size);
00201
00202 for (i=0;i<nFlowNodes;i++)
00203 {
00204 flow[i].D = fail->y[i];
00205 flow[i].X = fail->x[i];
00206 }
00207
00208 slope = derivative(*bathy);
00209
00210 for (i=0;i<nFlowNodes-1;i++)
00211 area[i] = flow[i].D*(flow[i+1].X-flow[i].X);
00212 area[nFlowNodes-1] = 0.;
00213
00214 for (i=0;i<nFlowNodes;i++)
00215 {
00216 flow[i].Up = EPS;
00217 flow[i].U = .995*flow[i].Up;
00218 flow[i].Uold = flow[i].U;
00219 flow[i].Upold = flow[i].Up;
00220 }
00221
00222
00223
00224
00225 Ttime = 0.0;
00226 Mcount = 0;
00227 Drho = ( flowDensity - DENSITY_OF_SEA_WATER ) / flowDensity;
00228 while ( Ttime < maxTime && flow[nFlowNodes-1].X < bathy->x[bathy->size-1] )
00229 {
00230
00231 for (i=0;i<nFlowNodes-1;i++)
00232 {
00233 flow[i].Xbar = ( flow[i+1].X + flow[i].X ) / 2.0;
00234 flow[i].Ubar = ( flow[i+1].U + flow[i].U ) / 2.0;
00235 flow[i].Upbar = ( flow[i+1].Up + flow[i].Up ) / 2.0;
00236 }
00237
00238
00239 for (i=1;i<nFlowNodes-1;i++)
00240 flow[i].Dbar = ( flow[i-1].D*(flow[i+1].X-flow[i].X)
00241 + flow[i].D *(flow[i].X-flow[i-1].X) )
00242 / ( flow[i+1].X-flow[i-1].X );
00243 flow[0].Dbar = 0;
00244 flow[nFlowNodes-1].Dbar = 0;
00245
00277 for (j=0;j<nFlowNodes;j++)
00278 {
00279
00280 double Dx = bathy->x[1]-bathy->x[0];
00281
00282
00283
00284
00285
00286 Xj = floor((flow[j].X-bathy->x[0])/Dx);
00287
00288 if ( Xj >= nNodes || Xj < 0)
00289 Sj = 0;
00290 else
00291 Sj = slope[Xj];
00292
00293 if ( Xj >= nNodes )
00294 flow[j].Y = bathy->y[nNodes-1];
00295 else if ( Xj < 0 )
00296 flow[j].Y = bathy->y[0];
00297 else
00298 flow[j].Y = bathy->y[Xj];
00299
00300
00301
00302
00303
00304
00305 Xgrav = Drho*GRAVITY*Sj;
00306 if ( j == 0 )
00307 {
00308 if ( abs(flow[j].Upbar) < EPS )
00309 Dp = flow[j].D*(3.0*.995-2.0);
00310 else
00311 Dp = flow[j].D*(3.*flow[j].Ubar/flow[j].Upbar-2.0);
00312 Ds = flow[j].D - Dp;
00313
00314 Xyield = -yieldStrength/flowDensity/flow[j].D*sign(flow[j].Uold);
00315 Xresi = -2.0*viscosity*flow[j].Upbar/flow[j].D/Ds;
00316 Xp2 = -yieldStrength/flowDensity/Dp*sign(flow[j].Uold);
00317
00318 Xpres = -Drho*GRAVITY*(flow[j+1].Dbar) / (flow[j+1].X-flow[j].X);
00319
00320 Xmom = ( .4*sq(flow[j+1].Upold)*flow[j+1].Dbar
00321 + sq(flow[j+1].Uold)*flow[j+1].Dbar
00322 - 1.4*flow[j+1].Uold*flow[j+1].Upold*flow[j+1].Dbar )
00323 / flow[j].D
00324 / (flow[j+1].X-flow[j].X);
00325 Xp1 = -(flow[j].Upbar - flow[j].Ubar)
00326 * (flow[j+1].Upold-flow[j].Upold)
00327 / (flow[j+1].X-flow[j].X);
00328 }
00329 else if ( j == nFlowNodes-1 )
00330 {
00331 if ( abs(flow[j-1].Upbar) < EPS )
00332 Dp = flow[j-1].D*(3.0*.995-2.0);
00333 else
00334 Dp = flow[j-1].D*(3.*flow[j-1].Ubar/flow[j-1].Upbar-2.0);
00335 Ds = flow[j-1].D - Dp;
00336
00337 Xyield = -yieldStrength
00338 / flowDensity
00339 / flow[j-1].D
00340 * sign(flow[j].Uold);
00341 Xresi = -2.0*viscosity*flow[j-1].Upbar/flow[j-1].D/Ds;
00342 Xp2 = -yieldStrength/flowDensity/Dp*sign(flow[j-1].Uold);
00343 Xpres = -Drho*GRAVITY*(-flow[j-1].Dbar)
00344 / (flow[j].X-flow[j-1].X);
00345 Xmom = - ( .4*sq(flow[j-1].Upold)*flow[j-1].Dbar
00346 + sq(flow[j-1].Uold)*flow[j-1].Dbar
00347 - 1.4*flow[j-1].Uold*flow[j-1].Upold*flow[j-1].Dbar)
00348 / flow[j-1].D
00349 / (flow[j].X-flow[j-1].X);
00350 Xp1 = - (flow[j-1].Upbar - flow[j-1].Ubar)
00351 * (flow[j].Upold-flow[j-1].Upold)
00352 / (flow[j].X-flow[j-1].X);
00353 }
00354 else
00355 {
00356 if ( abs(flow[j].Up) < EPS )
00357 Dp = flow[j].Dbar*(3.0*.995-2.0);
00358 else
00359 Dp = flow[j].Dbar*(3.*flow[j].U/flow[j].Up-2.0);
00360 Ds = flow[j].Dbar - Dp;
00361
00362 Xyield = -yieldStrength
00363 / flowDensity
00364 / flow[j].Dbar
00365 * sign(flow[j].Uold);
00366 Xresi = -2.0*viscosity*flow[j].Upold/flow[j].Dbar/Ds;
00367 Xp2 = -yieldStrength/flowDensity/Dp*sign(flow[j].Uold);
00368 Xpres = -Drho*GRAVITY*(flow[j+1].Dbar-flow[j-1].Dbar)
00369 / (flow[j+1].X-flow[j-1].X);
00370 Xmom = ( .4*sq(flow[j+1].Upold)*flow[j+1].Dbar
00371 + sq(flow[j+1].Uold)*flow[j+1].Dbar
00372 - 1.4*flow[j+1].Uold*flow[j+1].Upold*flow[j+1].Dbar)
00373 / flow[j].Dbar
00374 / (flow[j+1].X-flow[j-1].X)
00375 - ( .4*sq(flow[j-1].Upold)*flow[j-1].Dbar
00376 + sq(flow[j-1].Uold)*flow[j-1].Dbar
00377 - 1.4*flow[j-1].Uold*flow[j-1].Upold*flow[j-1].Dbar)
00378 / flow[j].Dbar
00379 / (flow[j+1].X-flow[j-1].X);
00380 Xp1 = -(flow[j].Upold - flow[j].Uold)
00381 * (flow[j+1].Upold-flow[j-1].Upold)
00382 / (flow[j+1].X-flow[j-1].X);
00383 }
00384
00385
00386 dU = (Xgrav+Xpres+Xresi+Xyield+Xmom)*dt;
00387
00388 flow[j].U = flow[j].Uold + dU;
00389
00390 flow[j].Up = flow[j].Upold + (Xgrav+Xp1+Xp2+Xpres)*dt;
00391
00392 if ( j != 0 && j != nFlowNodes-1 )
00393 {
00394 art1 = numericalViscosity
00395 * abs(flow[j+1].Dbar-2*flow[j].Dbar+flow[j-1].Dbar)
00396 / ( abs(flow[j+1].Dbar)
00397 + 2*abs(flow[j].Dbar)
00398 + abs(flow[j-1].Dbar) );
00399 flow[j].U = flow[j].U
00400 + art1*(flow[j+1].Uold-2*flow[j].Uold+flow[j-1].Uold);
00401 flow[j].Up = flow[j].Up
00402 + art1*(flow[j+1].Upold-2*flow[j].Upold+flow[j-1].Upold);
00403 }
00404
00405 if ( flow[j].U/flow[j].Up <= 2./3 )
00406 flow[j].Up=1.499*flow[j].U;
00407 if ( flow[j].U/flow[j].Up >= 1 )
00408 flow[j].Up = 1.001*flow[j].U;
00409 }
00410
00411 #ifdef BING_STANDALONE
00412 if ( Mcount%updateTime == 0 )
00413 {
00414 fprintf(stderr,"\r\t\t\t\tTime = %.1f minutes",Mcount*dt/60.);
00415 fflush(stderr);
00416 }
00417
00418 if ( Mcount%MC == 0 )
00419 {
00420 for (i=0;i<nFlowNodes;i++)
00421 {
00422 finalX[i] = flow[i].X;
00423 finalH[i] = flow[i].Dbar;
00424 }
00425 interpolate(finalX,finalH,nFlowNodes,bathy->x,deposit,bathy->size);
00426 fwrite(deposit,nNodes,sizeof(double),bing_fpout_);
00427 }
00428 #endif
00429
00430
00431
00432 for (i=0;i<nFlowNodes;i++)
00433 flow[i].X = flow[i].X + dt*flow[i].U;
00434
00435
00436 for (i=0;i<nFlowNodes-1;i++)
00437 {
00438 flow[i].D = area[i]/(flow[i+1].X-flow[i].X);
00439 if ( flow[i].D < 0. )
00440 {
00441 for (i=0;i<nNodes;i++)
00442 deposit[i] = -1.;
00443 g_message( "there was a problem running the debris flow." );
00444
00445 eh_free(flow);
00446 eh_free(area);
00447 eh_free(slope);
00448 eh_free(finalX);
00449 eh_free(finalY);
00450 eh_free(finalH);
00451 eh_free(initX);
00452 eh_free(initY);
00453
00454 return NULL;
00455 }
00456 }
00457 flow[nFlowNodes-1].D = 0.0;
00458
00459
00460 for (i=0;i<nFlowNodes;i++)
00461 {
00462 flow[i].Uold = flow[i].U;
00463 flow[i].Upold = flow[i].Up;
00464 }
00465
00466 Ttime += dt/60.0;
00467 Mcount++;
00468 }
00469
00470 for (i=0;i<nFlowNodes;i++)
00471 {
00472 finalX[i] = flow[i].X;
00473 finalH[i] = flow[i].Dbar;
00474 }
00475
00476 interpolate(bathy->x,bathy->y,bathy->size,finalX,finalY,fail->size);
00477
00478
00479
00480
00481
00482
00483
00484
00485 interpolate_bad_val( finalX , finalH , nFlowNodes ,
00486 bathy->x ,deposit , bathy->size , -99. );
00487
00488 eh_free(flow);
00489 eh_free(area);
00490 eh_free(slope);
00491 eh_free(finalX);
00492 eh_free(finalY);
00493 eh_free(finalH);
00494 eh_free(initX);
00495 eh_free(initY);
00496
00497 return deposit;
00498 }
00499
00500 #ifdef WITH_THREADS
00501
00502 typedef struct
00503 {
00504 node_t *flow;
00505 int n_flow_nodes;
00506 pos_t *bathy;
00507 int n_nodes;
00508 double dt;
00509 }
00510 force_t;
00511
00512 void calculate_forces( gpointer data , gpointer user_data )
00513 {
00514 int j = (int)data;
00515 node_t *flow =
00516 pos_t *bathy =
00517 int n_nodes =
00518 double dt =
00519 double numerical_viscosity =
00520 double Dx, dU;
00521 double Xj, Sj;
00522 double Dp, Ds;
00523 double Xgrav, Xpres, Xresi, Xyield, Xmom, Xp1, Xp2;
00524
00525 Dx = bathy->x[1]-bathy->x[0];
00526
00531 Xj = floor((flow[j].X-bathy->x[0])/Dx);
00532
00533 if ( Xj >= n_nodes || Xj < 0)
00534 Sj = 0;
00535 else
00536 Sj = slope[Xj];
00537
00538 if ( Xj >= n_nodes )
00539 flow[j].Y = bathy->y[n_nodes-1];
00540 else if ( Xj < 0 )
00541 flow[j].Y = bathy->y[0];
00542 else
00543 flow[j].Y = bathy->y[Xj];
00544
00550 Xgrav = Drho*GRAVITY*Sj;
00551 if ( j == 0 )
00552 {
00553 if ( abs(flow[j].Upbar) < EPS )
00554 Dp = flow[j].D*(3.0*.995-2.0);
00555 else
00556 Dp = flow[j].D*(3.*flow[j].Ubar/flow[j].Upbar-2.0);
00557 Ds = flow[j].D - Dp;
00558
00559 Xyield = -yieldStrength/flowDensity/flow[j].D*sign(flow[j].Uold);
00560 Xresi = -2.0*viscosity*flow[j].Upbar/flow[j].D/Ds;
00561 Xp2 = -yieldStrength/flowDensity/Dp*sign(flow[j].Uold);
00562
00563 Xpres = -Drho*GRAVITY*(flow[j+1].Dbar) / (flow[j+1].X-flow[j].X);
00564
00565 Xmom = (.4*sq(flow[j+1].Upold)*flow[j+1].Dbar+sq(flow[j+1].Uold)*flow[j+1].Dbar
00566 -1.4*flow[j+1].Uold*flow[j+1].Upold*flow[j+1].Dbar)/flow[j].D/(flow[j+1].X-flow[j].X);
00567 Xp1 = -(flow[j].Upbar - flow[j].Ubar)*(flow[j+1].Upold-flow[j].Upold) / (flow[j+1].X-flow[j].X);
00568 }
00569 else if ( j == nFlowNodes-1 )
00570 {
00571 if ( abs(flow[j-1].Upbar) < EPS )
00572 Dp = flow[j-1].D*(3.0*.995-2.0);
00573 else
00574 Dp = flow[j-1].D*(3.*flow[j-1].Ubar/flow[j-1].Upbar-2.0);
00575 Ds = flow[j-1].D - Dp;
00576
00577 Xyield = -yieldStrength/flowDensity/flow[j-1].D*sign(flow[j].Uold);
00578 Xresi = -2.0*viscosity*flow[j-1].Upbar/flow[j-1].D/Ds;
00579 Xp2 = -yieldStrength/flowDensity/Dp*sign(flow[j-1].Uold);
00580 Xpres = -Drho*GRAVITY*(-flow[j-1].Dbar) / (flow[j].X-flow[j-1].X);
00581 Xmom = - (.4*sq(flow[j-1].Upold)*flow[j-1].Dbar+sq(flow[j-1].Uold)*flow[j-1].Dbar
00582 -1.4*flow[j-1].Uold*flow[j-1].Upold*flow[j-1].Dbar)/flow[j-1].D/(flow[j].X-flow[j-1].X);
00583 Xp1 = -(flow[j-1].Upbar - flow[j-1].Ubar)*(flow[j].Upold-flow[j-1].Upold) / (flow[j].X-flow[j-1].X);
00584 }
00585 else
00586 {
00587 if ( abs(flow[j].Up) < EPS )
00588 Dp = flow[j].Dbar*(3.0*.995-2.0);
00589 else
00590 Dp = flow[j].Dbar*(3.*flow[j].U/flow[j].Up-2.0);
00591 Ds = flow[j].Dbar - Dp;
00592
00593 Xyield = -yieldStrength/flowDensity/flow[j].Dbar*sign(flow[j].Uold);
00594 Xresi = -2.0*viscosity*flow[j].Upold/flow[j].Dbar/Ds;
00595 Xp2 = -yieldStrength/flowDensity/Dp*sign(flow[j].Uold);
00596 Xpres = -Drho*GRAVITY*(flow[j+1].Dbar-flow[j-1].Dbar) / (flow[j+1].X-flow[j-1].X);
00597 Xmom = (.4*sq(flow[j+1].Upold)*flow[j+1].Dbar+sq(flow[j+1].Uold)*flow[j+1].Dbar
00598 -1.4*flow[j+1].Uold*flow[j+1].Upold*flow[j+1].Dbar)/flow[j].Dbar/(flow[j+1].X-flow[j-1].X)
00599 - (.4*sq(flow[j-1].Upold)*flow[j-1].Dbar+sq(flow[j-1].Uold)*flow[j-1].Dbar
00600 -1.4*flow[j-1].Uold*flow[j-1].Upold*flow[j-1].Dbar)/flow[j].Dbar/(flow[j+1].X-flow[j-1].X);
00601 Xp1 = -(flow[j].Upold - flow[j].Uold)*(flow[j+1].Upold-flow[j-1].Upold) / (flow[j+1].X-flow[j-1].X);
00602 }
00603
00604
00605 dU = (Xgrav+Xpres+Xresi+Xyield+Xmom)*dt;
00606
00607 flow[j].U = flow[j].Uold + dU;
00608
00609 flow[j].Up = flow[j].Upold + (Xgrav+Xp1+Xp2+Xpres)*dt;
00610
00611 if ( j != 0 && j != n_flow_nodes-1 )
00612 {
00613 art1 = numerical_viscosity*abs(flow[j+1].Dbar-2*flow[j].Dbar+flow[j-1].Dbar) /
00614 ( abs(flow[j+1].Dbar)+2*abs(flow[j].Dbar)+abs(flow[j-1].Dbar) );
00615 flow[j].U = flow[j].U + art1*(flow[j+1].Uold-2*flow[j].Uold+flow[j-1].Uold);
00616 flow[j].Up = flow[j].Up + art1*(flow[j+1].Upold-2*flow[j].Upold+flow[j-1].Upold);
00617 }
00618
00619 if ( flow[j].U/flow[j].Up <= 2./3 )
00620 flow[j].Up=1.499*flow[j].U;
00621 if ( flow[j].U/flow[j].Up >= 1 )
00622 flow[j].Up = 1.001*flow[j].U;
00623
00624 return;
00625 }
00626
00627 #endif