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 #include "plumeinput.h"
00037 #include "plumevars.h"
00038 #include <utils/utils.h>
00039
00040
00041
00042
00043 int plumecent( Plume_enviro *env , Plume_grid *grid , Plume_options *opt )
00044 {
00045 #ifdef DBG
00046 FILE *fid1;
00047 #endif
00048 int ii, jj, cci, ll, lp, ll1, ll2, ll3, ll4, zclind, zmi;
00049 double Li, Licc, ccw, ccw2, dccw, ucc;
00050 double aa, AA, avo, nv, v1, v2, zm;
00051 double dyz[4], sin1, cos1, tst, dcl, pra;
00052 double **pct0, **pct1, **pct2, **pct3;
00053 Plume_river river = *(env->river);
00054 Plume_ocean ocean = *(env->ocean);
00055
00056
00057 if( opt->fjrd || opt->strt )
00058 {
00059 for( ii=0 ; ii<grid->lx ; ii++ )
00060 {
00061 grid->pcent[ii][0] = grid->xval[ii];
00062 grid->pcent[ii][1] = 0;
00063 grid->pcent[ii][2] = grid->xval[ii];
00064 }
00065 grid->lc = grid->lx;
00066
00067
00068 for( ii=0 ; ii<grid->lc ; ii++ )
00069 {
00070 if( grid->pcent[ii][2] < plg*river.b0 )
00071 {
00072 grid->pcent[ii][3] = river.u0;
00073 }
00074 else
00075 {
00076 v1 = river.b0/(sqpi*C1*grid->pcent[ii][2]);
00077 v2 = 0;
00078 grid->pcent[ii][3] = river.u0*sqrt(v1)*exp(sq(-v2));
00079 }
00080 }
00081 }
00082 else
00083 {
00084
00085
00086
00087
00088
00089 avo = fabs(ocean.vo);
00090 aa = river.u0/avo;
00091 nv = 0.37;
00092 AA = 1.53 + 0.90*aa;
00093
00094
00095
00096
00097
00098
00099
00100 dyz[0] = 0.9*mn( river.b0*pow( grid->dx/(river.b0*AA) , 1/nv ) ,
00101 grid->dy );
00102 dyz[1] = 0.9*mn( river.b0*pow( (100.+grid->dx)/(river.b0*AA) , 1/nv )
00103 - river.b0*pow( 100/(river.b0*AA) , 1/nv ) ,
00104 grid->dy );
00105 dyz[2] = 0.9*mn( river.b0*pow( (1000.+grid->dx)/(river.b0*AA) , 1/nv )
00106 - river.b0*pow( 1000/(river.b0*AA) , 1/nv ) ,
00107 grid->dy );
00108 dyz[3] = 0.9*mn( river.b0*pow( (10000.+grid->dx)/(river.b0*AA) , 1/nv )
00109 - river.b0*pow( 10000/(river.b0*AA) , 1/nv ) ,
00110 grid->dy );
00111
00112
00113 ll1 = ((int)(( 100- 0)/dyz[0])) + 1;
00114 ll2 = ((int)(( 1000- 100)/dyz[1])) + 1;
00115 ll3 = ((int)((10000-1000)/dyz[2])) + 1;
00116 ll4 = ((int)((mx(1.3*grid->ymax,-1.3*grid->ymin)-10000)/dyz[3])) + 2;
00117 ll = ll1+ll2+ll3+ll4;
00118
00119 #ifdef DBG
00120 fprintf(stderr," PlumeCent: Allocating pct matrices \n");
00121 #endif
00122 pct0 = new_dmatrix( ll , 2 );
00123 pct1 = new_dmatrix( ll , 2 );
00124 pct2 = new_dmatrix( ll , 2 );
00125 pct3 = new_dmatrix( grid->lpc , 2 );
00126 #ifdef DBG
00127 fprintf(stderr," finished Allocation \n");
00128 #endif
00129
00130 pct0[0][1] = 0;
00131 for( ii=1 ; ii<ll ; ii++ )
00132 {
00133 if( pct0[ii-1][1] < 100 )
00134 pct0[ii][1] = pct0[ii-1][1] + dyz[0];
00135 else if( pct0[ii-1][1] < 1000 )
00136 pct0[ii][1] = pct0[ii-1][1] + dyz[1];
00137 else if( pct0[ii-1][1] < 10000 )
00138 pct0[ii][1] = pct0[ii-1][1] + dyz[2];
00139 else
00140 pct0[ii][1] = pct0[ii-1][1] + dyz[3];
00141 }
00142
00143
00144
00145
00146
00147
00148
00149 for( ii=0 ; ii<ll ; ii++ )
00150 pct0[ii][0] = river.b0*AA*pow( pct0[ii][1]/river.b0 , nv );
00151
00152
00153 sin1=sin(river.rma*degTOr);
00154 cos1=cos(river.rma*degTOr);
00155 for( ii=0 ; ii<ll ; ii++ )
00156 {
00157 pct1[ii][0] = -pct0[ii][1]*sin1 + pct0[ii][0]*cos1;
00158 pct1[ii][1] = pct0[ii][1]*cos1 + pct0[ii][0]*sin1;
00159 }
00160
00161
00162 if( opt->kwf )
00163 {
00164
00165
00166
00167 Li = 0.5*(river.u0+avo)/(2*omega*sin(env->lat*degTOr));
00168
00169
00170
00171 ucc = river.u0*sqrt(river.b0/(sqpi*C1*10*Li));
00172 Licc = ucc/(2*omega*sin(env->lat*degTOr));
00173 ccw = ocean.cc*Licc;
00174
00175
00176
00177 dccw = sqrt( pow(2*Li,2) + pow(ccw,2) );
00178
00179
00180
00181 zclind = 0;
00182 tst = fabs( pow(dccw,2) - pow(pct1[0][0],2) - pow(pct1[0][1],2) );
00183 for ( ii=0 ; ii<ll ; ii++ )
00184 {
00185 if ( fabs( pow(dccw,2) - pow(pct1[ii][0],2) - pow(pct1[ii][1],2) )
00186 < tst )
00187 {
00188 zclind = ii;
00189 tst = fabs( pow(dccw,2)
00190 - pow(pct1[ii][0],2)
00191 - pow(pct1[ii][1],2) );
00192 }
00193 }
00194 dcl = sqrt( pow(pct1[zclind][0],2) + pow(pct1[zclind][1],2) );
00195
00196
00197
00198
00199
00200
00201 pra = rTOdeg*(atan2(pct1[zclind][0],pct1[zclind][1])-atan2(ccw,2*Li));
00202
00203
00204
00205
00206
00207 if ( pra > 0 )
00208 {
00209 sin1 = sin(pra*degTOr);
00210 cos1 = cos(pra*degTOr);
00211 }
00212 else
00213 {
00214 sin1 = 0;
00215 cos1 = 1;
00216 }
00217 for( ii=0 ; ii<ll ; ii++ )
00218 {
00219 pct2[ii][0] = -pct1[ii][1]*sin1 + pct1[ii][0]*cos1;
00220 pct2[ii][1] = pct1[ii][1]*cos1 + pct1[ii][0]*sin1;
00221 }
00222 }
00223 else
00224 {
00225
00226
00227
00228
00229 for( ii=0 ; ii<ll ; ii++ )
00230 {
00231 pct2[ii][0] = pct1[ii][0];
00232 pct2[ii][1] = pct1[ii][1];
00233 }
00234 }
00235
00236
00237
00238
00239
00240 pct3[0][0] = rnd(pct2[0][0]/grid->dx)*grid->dx;
00241 pct3[0][1] = rnd(pct2[0][1]/grid->dy)*grid->dy;
00242 zmi = 0;
00243 zm = pct3[0][0];
00244 lp = 1;
00245 for ( ii=1 ; ii<ll ; ii++ )
00246 {
00247 v1 = rnd(pct2[ii][0]/grid->dx)*grid->dx;
00248 v2 = rnd(pct2[ii][1]/grid->dy)*grid->dy;
00249 if ( v1 != pct3[lp-1][0] || v2 != pct3[lp-1][1] )
00250 {
00251 pct3[lp][0] = v1;
00252 pct3[lp][1] = v2;
00253 if ( v1 > zm )
00254 {
00255 zm = v1;
00256 zmi = lp;
00257 }
00258 lp++;
00259 if ( lp > grid->lpc )
00260 {
00261 fprintf(stderr,"PlumeCENT Error (a): pct array is too small. \n");
00262 fprintf(stderr," lp > lpc \n");
00263 fprintf(stderr," increase lpc in PlumeArray.c\n");
00264 fprintf(stderr," lpc = %d \n", grid->lpc);
00265 fprintf(stderr," lp > %d \n", lp);
00266 fprintf(stderr," ii = %d \n", ii);
00267 fprintf(stderr," ll = %d \n", ll);
00268 return 1;
00269 }
00270 }
00271 }
00272
00273
00274
00275
00276 if ( opt->kwf != 0 )
00277 {
00278
00279 ccw2 = rnd(ccw/grid->dx)*grid->dx;
00280
00281
00282 if( zm > ccw2 && pct3[zmi][1] <= 2*Li )
00283 {
00284 ii = zmi;
00285 while( pct3[ii][0] > ccw2 )
00286 ii++;
00287 cci = ii;
00288 }
00289 else if ( zm>ccw2 )
00290 {
00291 ii = 0;
00292 while( pct3[ii][0] < ccw2 )
00293 ii++;
00294 cci = ii;
00295 }
00296 else
00297 {
00298 fprintf(stderr,"\n\n PlumeCent ERROR: program aborted \n");
00299 fprintf(stderr," Plume was over-rotated and never reached ccw \n");
00300 return 1;
00301 }
00302
00303 ii = cci;
00304 while( ii < lp )
00305 {
00306 pct3[ii][0] = ccw2;
00307 ii++;
00308 }
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 if ( ocean.vo > 0 && opt->kwf == 0 )
00320 {
00321 if ( pct3[lp-1][0] > grid->xmax )
00322 {
00323 ii = lp-1;
00324 while( pct3[ii][0] > grid->xmax )
00325 ii--;
00326 }
00327 else
00328 ii = lp-1;
00329 if ( pct3[lp-1][1] > grid->ymax )
00330 {
00331 jj = lp-1;
00332 while( pct3[jj][1] > grid->ymax )
00333 jj--;
00334 }
00335 else
00336 jj = lp-1;
00337 grid->lc = mn(ii,jj)+1;
00338 for ( ii=0 ; ii<grid->lc ; ii++ )
00339 {
00340 grid->pcent[ii][0] = pct3[ii][0];
00341 grid->pcent[ii][1] = pct3[ii][1];
00342 }
00343 }
00344 else if ( ocean.vo>0 && opt->kwf!=0 )
00345 {
00346 if( pct3[lp-1][1] < grid->ymax )
00347 {
00348 fprintf(stderr,"PlumeCent Error (b): not enough centerline grid points, \n");
00349 fprintf(stderr," the centerline does not exit the array.\n");
00350 fprintf(stderr," pct3[lp-1][1] < ymax \n");
00351 fprintf(stderr," Increase lpc in PlumeArray.c \n");
00352 fprintf(stderr," lpc = %d \n", grid->lpc);
00353 fprintf(stderr," lp = %d \n", lp);
00354 fprintf(stderr," ymax = %f \n", grid->ymax);
00355 fprintf(stderr," pct3[lp-1][1] = %g \n", pct3[lp-1][1]);
00356 return 1;
00357 }
00358 jj = lp-1;
00359 while ( pct3[jj][1] > grid->ymax )
00360 jj--;
00361 grid->lc = jj+1;
00362 for ( ii=0 ; ii<grid->lc ; ii++ )
00363 {
00364 grid->pcent[ii][0] = pct3[ii][0];
00365 grid->pcent[ii][1] = pct3[ii][1];
00366 }
00367 }
00368 else if ( ocean.vo < 0 && opt->kwf == 0 )
00369 {
00370 if( pct3[lp-1][0] > grid->xmax )
00371 {
00372 ii = lp-1;
00373 while ( pct3[ii][0] > grid->xmax )
00374 ii--;
00375 }
00376 else
00377 ii = lp-1;
00378 if ( -pct3[lp-1][1] < grid->ymin )
00379 {
00380 jj = lp-1;
00381 while( -pct3[jj][1] < grid->ymin )
00382 jj--;
00383 }
00384 else
00385 jj = lp-1;
00386 grid->lc = mn(ii,jj)+1;
00387 for ( ii=0 ; ii<grid->lc ; ii++ )
00388 {
00389 grid->pcent[ii][0] = pct3[ii][0];
00390 grid->pcent[ii][1] = -pct3[ii][1];
00391 }
00392 }
00393 else
00394 {
00395 if( -pct3[lp-1][1] > grid->ymin )
00396 {
00397 fprintf(stderr,"PlumeCent Error (c): not enough centerline grid points, \n");
00398 fprintf(stderr," the centerline does not exit the array.\n");
00399 fprintf(stderr," -pct3[lp-1][1] > ymin \n");
00400 fprintf(stderr," Increase lpc in PlumeArray.c \n");
00401 fprintf(stderr," lpc = %d \n", grid->lpc);
00402 fprintf(stderr," lp = %d \n", lp);
00403 fprintf(stderr," ymin = %f \n", grid->ymin);
00404 fprintf(stderr," -pct3[lp-1][1] = %g \n", -pct3[lp-1][1]);
00405 return 1;
00406 }
00407 jj = lp-1;
00408
00409 while ( -pct3[jj][1] < grid->ymin )
00410 jj--;
00411 grid->lc = jj+1;
00412 for ( ii=0 ; ii<grid->lc ; ii++ )
00413 {
00414 grid->pcent[ii][0] = pct3[ii][0];
00415 grid->pcent[ii][1] = -pct3[ii][1];
00416 }
00417 }
00418
00419
00420
00421
00422 grid->pcent[0][2] = grid->xval[0];
00423 grid->pcent[0][3] = river.u0;
00424
00425 for( ii=1 ; ii<grid->lc ; ii++ )
00426 {
00427
00428
00429
00430
00431 grid->pcent[ii][2] = grid->pcent[ii-1][2]
00432 + sqrt( sq(grid->pcent[ii][0]-grid->pcent[ii-1][0])
00433 + sq(grid->pcent[ii][1]-grid->pcent[ii-1][1]) );
00434
00435
00436 if ( grid->pcent[ii][2] < plg*river.b0 )
00437 grid->pcent[ii][3] = river.u0;
00438 else
00439 {
00440 v1 = river.b0/(sqpi*C1*grid->pcent[ii][2]);
00441 v2 = 0;
00442 grid->pcent[ii][3] = river.u0*sqrt(v1)*exp(-sq(v2));
00443 }
00444 }
00445
00446
00447 free_dmatrix( pct0 );
00448 free_dmatrix( pct1 );
00449 free_dmatrix( pct2 );
00450 free_dmatrix( pct3 );
00451
00452 }
00453
00454 #ifdef DBG
00455 fid1 = fopen("pcnt.dat","w");
00456 for( ii=0 ; ii<grid->lc ; ii++ )
00457 {
00458 fprintf(fid1,"%g %g %g %g \n", grid->pcent[ii][0], grid->pcent[ii][1], grid->pcent[ii][2], grid->pcent[ii][3] );
00459 }
00460 fclose(fid1);
00461 #endif
00462
00463 return 0;
00464
00465 }
00466