00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022
00023 #include "flow.h"
00024
00025 double *solve_excess_pore_pressure( double *psi , double *k , double *c , int n , double dz , double dt , double psi_top , double sed_rate )
00026 {
00027 double *l = eh_new( double , n );
00028 double *d = eh_new( double , n );
00029 double *u = eh_new( double , n );
00030 double *b = eh_new( double , n );
00031 int i;
00032
00033
00034
00035
00036 get_matrix_coefficients( psi+1 , k+1 , c+1 , sed_rate , dz ,
00037 dt , psi_top , n-2 , 1. , l ,
00038 d , u , b );
00039
00040
00041 if ( !tridiag( l , d , u , b , psi+1 , n-2 ) )
00042 {
00043 eh_watch_dbl( d[0] );
00044 for ( i=0 ; i<n ; i++ )
00045 {
00046 eh_watch_dbl( psi[i] );
00047 psi[i] = psi_top;
00048 }
00049 perror( "tridiag" );
00050 }
00051
00052 psi[0] = psi[2];
00053 psi[n-1] = psi_top;
00054
00055 eh_free( l );
00056 eh_free( d );
00057 eh_free( u );
00058 eh_free( b );
00059
00060 return psi;
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 void get_matrix_coefficients( double *psi , double *k , double *c , double ds , double dz , double dt , double psi_top , int n , double f , double *l , double *d , double *u , double *b )
00127 {
00128 int i;
00129
00130 d[0] = -f*2*k[0]/(dz*dz) - c[0]/dt;
00131 u[0] = f*2*k[0]/(dz*dz);
00132 for ( i=1 ; i<n-1 ; i++ )
00133 {
00134 l[i] = f/(dz*dz)*(.5*k[i-1]+k[i]-.5*k[i+1]);
00135 d[i] = -f/(dz*dz)*2*k[i] - c[i]/dt;
00136 u[i] = f/(dz*dz)*(-.5*k[i-1]+k[i]+.5*k[i+1]);
00137 }
00138 l[n-1] = f/(dz*dz)*(k[n-1]-.5*k[n]+.5*k[n-2]);
00139 d[n-1] = -f/(dz*dz)*2*k[n-1] - c[n-1]/dt;
00140
00141 b[0] = -(1.-f)/(dz*dz)
00142 * ( psi[1]*(.5*k[-1]+k[0]-.5*k[1])
00143 - psi[0] *(2*k[0])
00144 + psi[1]*(-.5*k[-1]+k[0]+.5*k[1]) )
00145 - psi[0]*c[0]/dt;
00146 for ( i=1 ; i<n-1 ; i++ )
00147 {
00148 b[i] = -(1.-f)/(dz*dz)
00149 * ( psi[i-1]*(.5*k[i-1]+k[i]-.5*k[i+1])
00150 - psi[i] *(2*k[i])
00151 + psi[i+1]*(-.5*k[i-1] + k[i] + .5*k[i+1]) )
00152 - psi[i]*c[i]/dt;
00153 }
00154 b[n-1] = -(1.-f)/(dz*dz)
00155 * ( psi[n-2]*(.5*k[n-2]+k[n-1]-.5*k[n])
00156 - psi[n-1] *(2*k[n-1])
00157 + psi_top*(-.5*k[n-2] + k[n-1] + .5*k[n]) )
00158 - psi[n-1]*c[n-1]/dt
00159 - f*psi_top/(dz*dz)*(k[n-1]+.5*k[n]-.5*k[n-2]);
00160
00161 }
00162
00163
00164 double *solve_excess_pore_pressure_mg( double *psi , double *k , double *c , int n , double dz , double dt , double sed_rate )
00165 {
00166 int i;
00167 double *f = eh_new( double , n );
00168 double depth = dz*(n-1);
00169
00170 for ( i=0 ; i<n ; i++ )
00171 f[i] = (-sed_rate/dt - psi[i]/dt);
00172
00173 for ( i=0 ; i<2 ; i++ )
00174 fmg_1d( psi , k , f , n , depth , dt );
00175
00176 eh_free( f );
00177
00178 return psi;
00179 }
00180
00181 double **solve_excess_pore_pressure_mg_2d( double **psi , double **kx , double **kz , double **c , int n , double dx , double dz , double dt , double *sed_rate )
00182 {
00183 int i, j;
00184 double **f = allocate_2d( n );
00185 double depth = dz*(n-1);
00186 double width = dx*(n-1);
00187
00188 for ( i=0 ; i<n ; i++ )
00189 for ( j=0 ; j<n ; j++ )
00190 f[i][j] = (-sed_rate[i]/dt - psi[i][j]/dt);
00191
00192 for ( i=0 ; i<5 ; i++ )
00193 fmg_2d( psi , kx , kz , f , n , width , depth , dt );
00194
00195 eh_free( f[0] );
00196 eh_free( f );
00197
00198 return psi;
00199 }
00200
00201 double ***solve_excess_pore_pressure_mg_3d( double ***psi , double ***kx , double ***kz , double ***c , int n , double dx , double dz , double dt , double **sed_rate )
00202 {
00203 int i, j, k;
00204 double ***f = allocate_3d( n );
00205 double depth = dz*(n-1);
00206 double width = dx*(n-1);
00207
00208 for ( i=0 ; i<n ; i++ )
00209 for ( j=0 ; j<n ; j++ )
00210 for ( k=0 ; k<n ; k++ )
00211 f[i][j][k] = (-sed_rate[i][j]/dt - psi[i][j][k]/dt);
00212
00213 for ( i=0 ; i<5 ; i++ )
00214 fmg_3d( psi , kx , kz , f , n , width , depth , dt );
00215
00216 free_3d( f );
00217
00218 return psi;
00219 }
00220
00221
00222 double *restrict_1d( double *u_2h , double *u_h , int n_h )
00223 {
00224 int i, i_2h;
00225 int n_2h = (n_h+1)/2.;
00226
00227 for ( i_2h=1,i=2 ; i_2h<n_2h-1 ; i_2h++,i+=2 )
00228 u_2h[i_2h] = .5*u_h[i] + .25*(u_h[i-1] + u_h[i+1]);
00229
00230 u_2h[0] = u_h[0];
00231 u_2h[n_2h-1] = u_h[n_h-1];
00232
00233 return u_2h;
00234 }
00235
00236 double **restrict_2d( double **u_2h , double **u_h , int n_h )
00237 {
00238 int i, i_2h;
00239 int j, j_2h;
00240 int n_2h = (n_h+1)/2.;
00241
00242 for ( i_2h=1,i=2 ; i_2h<n_2h-1 ; i_2h++,i+=2 )
00243 for ( j_2h=1,j=2 ; j_2h<n_2h-1 ; j_2h++,j+=2 )
00244 u_2h[i_2h][j_2h] = .5*u_h[i][j] + .125*(u_h[i-1][j] + u_h[i+1][j] + u_h[i][j-1] + u_h[i][j+1]);
00245
00246 for ( j_2h=0,j=0 ; j_2h<n_2h ; j_2h++,j+=2 )
00247 {
00248 u_2h[0][j_2h] = u_h[0][j];
00249 u_2h[n_2h-1][j_2h] = u_h[n_h-1][j];
00250 }
00251
00252 for ( i_2h=0,i=0 ; i_2h<n_2h ; i_2h++,i+=2 )
00253 {
00254 u_2h[i_2h][0] = u_h[i][0];
00255 u_2h[i_2h][n_2h-1] = u_h[i][n_h-1];
00256 }
00257
00258 return u_2h;
00259 }
00260
00261 double ***restrict_3d( double ***u_2h , double ***u_h , int n_h )
00262 {
00263 int i, i_2h;
00264 int j, j_2h;
00265 int k, k_2h;
00266 int n_2h = (n_h+1)/2.;
00267
00268 for ( i_2h=1,i=2 ; i_2h<n_2h-1 ; i_2h++,i+=2 )
00269 for ( j_2h=1,j=2 ; j_2h<n_2h-1 ; j_2h++,j+=2 )
00270 for ( k_2h=1,k=2 ; k_2h<n_2h-1 ; k_2h++,k+=2 )
00271 u_2h[i_2h][j_2h][k_2h] = u_h[i][j][k]/2
00272 + ( u_h[i-1][j][k] + u_h[i+1][j][k]
00273 + u_h[i][j-1][k] + u_h[i][j+1][k]
00274 + u_h[i][j][k-1] + u_h[i][j][k+1] )/12;
00275
00276 for ( i_2h=0,i=0 ; i_2h<n_2h ; i_2h++,i+=2 )
00277 {
00278 for ( j_2h=0,j=0 ; j_2h<n_2h ; j_2h++,j+=2 )
00279 {
00280 u_2h[i_2h][j_2h][0] = u_h[i][j][0];
00281 u_2h[i_2h][j_2h][n_2h-1] = u_h[i][j][n_h-1];
00282
00283 u_2h[i_2h][n_2h-1][j_2h] = u_h[i][n_h-1][j];
00284 u_2h[i_2h][0][j_2h] = u_h[i][0][j];
00285
00286 u_2h[n_2h-1][i_2h][j_2h] = u_h[n_h-1][i][j];
00287 u_2h[0][i_2h][j_2h] = u_h[0][i][j];
00288 }
00289 }
00290
00291 return u_2h;
00292 }
00293
00294 double *inter_1d( double *u_h , double *u_2h , int n_2h )
00295 {
00296 int i, i_h;
00297 int n_h=n_2h*2-1;
00298
00299 for ( i_h=0,i=0 ; i_h<n_h ; i_h+=2,i++ )
00300 u_h[i_h] = u_2h[i];
00301
00302 for ( i_h=1,i=0 ; i_h<n_h ; i_h+=2,i++ )
00303 u_h[i_h] = .5*(u_2h[i] + u_2h[i+1]);
00304
00305 return u_h;
00306 }
00307
00308 double **inter_2d( double **u_h , double **u_2h , int n_2h )
00309 {
00310 int i, i_h;
00311 int j, j_h;
00312 int n_h=n_2h*2-1;
00313
00314 for ( i_h=0,i=0 ; i_h<n_h ; i_h+=2,i++ )
00315 for ( j_h=0,j=0 ; j_h<n_h ; j_h+=2,j++ )
00316 u_h[i_h][j_h] = u_2h[i][j];
00317
00318 for ( i_h=1,i=0 ; i_h<n_h ; i_h+=2,i++ )
00319 for ( j_h=0,j=0 ; j_h<n_h ; j_h+=2,j++ )
00320 u_h[i_h][j_h] = .5*(u_2h[i][j] + u_2h[i+1][j]);
00321
00322 for ( i=0 ; i<n_h ; i++ )
00323 for ( j=1 ; j<n_h ; j+=2 )
00324 u_h[i][j] = .5*(u_h[i][j-1] + u_h[i][j+1]);
00325
00326 return u_h;
00327 }
00328
00329 void print_matrix( double **a , int n );
00330 void print_matrix_3d( double ***a , int n );
00331
00332 double ***inter_3d( double ***u_h , double ***u_2h , int n_2h )
00333 {
00334 int i, i_h;
00335 int j, j_h;
00336 int k, k_h;
00337 int n_h=n_2h*2-1;
00338
00339 for ( i=0 ; i<n_h ; i++ )
00340 for ( j=0 ; j<n_h ; j++ )
00341 for ( k=0 ; k<n_h ; k++ )
00342 u_h[i][j][k] = -1;
00343
00344 for ( i_h=0,i=0 ; i_h<n_h ; i_h+=2,i++ )
00345 for ( j_h=0,j=0 ; j_h<n_h ; j_h+=2,j++ )
00346 for ( k_h=0,k=0 ; k_h<n_h ; k_h+=2,k++ )
00347 u_h[i_h][j_h][k_h] = u_2h[i][j][k];
00348
00349 for ( k_h=0,k=0 ; k_h<n_h ; k_h+=2,k++ )
00350 {
00351
00352 for ( i_h=1,i=0 ; i_h<n_h ; i_h+=2,i++ )
00353 for ( j_h=0,j=0 ; j_h<n_h ; j_h+=2,j++ )
00354 u_h[i_h][j_h][k_h] = .5*(u_2h[i][j][k] + u_2h[i+1][j][k]);
00355
00356 for ( i=0 ; i<n_h ; i++ )
00357 for ( j=1 ; j<n_h ; j+=2 )
00358 u_h[i][j][k_h] = .5*(u_h[i][j-1][k_h] + u_h[i][j+1][k_h]);
00359
00360 }
00361
00362 for ( i=0 ; i<n_h ; i++ )
00363 for ( j=0 ; j<n_h ; j++ )
00364 for ( k=1 ; k<n_h ; k+=2 )
00365 u_h[i][j][k] = .5*(u_h[i][j][k-1] + u_h[i][j][k+1]);
00366
00367 return u_h;
00368 }
00369
00370 double *relax_1d( double *u , double *k , double *f , int n , double dz , double dt )
00371 {
00372 int i;
00373 double h=1./(n-1)*dz;
00374 double h_2 = h*h;
00375 double u0 = u[n-1];
00376
00377 for ( i=1 ; i<n-1 ; i++ )
00378 u[i] = ( (1/h_2)*( u[i-1]*k[i] + u[i+1]*k[i+1] ) - f[i] )*h_2/( k[i+1] + k[i] + h_2/dt );
00379
00380 u[0] = u[1];
00381 u[n-1] = u0;
00382
00383 return u;
00384 }
00385
00386 double **relax_2d( double **u , double **kx , double **kz , double **f , int n , double dx , double dz , double dt )
00387 {
00388 int i, j;
00389 double hx=1./(n-1)*dx;
00390 double hz=1./(n-1)*dz;
00391 double hx_2 = hx*hx;
00392 double hz_2 = hz*hz;
00393
00394 for ( i=1 ; i<n-1 ; i++ )
00395 for ( j=1 ; j<n-1 ; j++ )
00396 u[i][j] = ( ( u[i-1][j]*kx[i][j] + u[i+1][j]*kx[i+1][j] )/hx_2
00397 + ( u[i][j-1]*kz[i][j] + u[i][j+1]*kz[i][j+1] )/hz_2
00398 - f[i][j] )
00399 /( (kx[i][j]+kx[i+1][j])/hx_2 + (kz[i][j]+kz[i][j+1])/hz_2 + 1/dt);
00400
00401
00402 for ( i=0 ; i<n ; i++ )
00403 {
00404 u[0][i] = u[1][i];
00405 u[n-1][i] = u[n-2][i];
00406 u[i][0] = u[i][1];
00407
00408 }
00409
00410 return u;
00411 }
00412
00413 double ***relax_3d( double ***u , double ***kx , double ***kz , double ***f , int n , double dx , double dz , double dt )
00414 {
00415 int i, j, k;
00416 double hx=1./(n-1)*dx;
00417 double hz=1./(n-1)*dz;
00418 double hx_2 = hx*hx;
00419 double hz_2 = hz*hz;
00420
00421 for ( i=1 ; i<n-1 ; i++ )
00422 for ( j=1 ; j<n-1 ; j++ )
00423 for ( k=1 ; k<n-1 ; k++ )
00424 u[i][j][k] = ( ( u[i-1][j][k]*kx[i][j][k] + u[i+1][j][k]*kx[i+1][j][k] )/hx_2
00425 + ( u[i][j-1][k]*kx[i][j][k] + u[i][j+1][k]*kx[i][j+1][k] )/hx_2
00426 + ( u[i][j][k-1]*kz[i][j][k] + u[i][j][k+1]*kz[i][j][k+1] )/hz_2
00427 - f[i][j][k] )
00428 /( (kx[i][j][k]+kx[i+1][j][k])/hx_2 + (kx[i][j][k]+kx[i][j+1][k])/hx_2 + (kz[i][j][k]+kz[i][j][k+1])/hz_2 + 1/dt);
00429
00430 for ( i=0 ; i<n ; i++ )
00431 for ( j=0 ; j<n ; j++ )
00432 {
00433 u[0][i][j] = u[1][i][j];
00434 u[n-1][i][j] = u[n-2][i][j];
00435
00436 u[i][0][j] = u[i][1][j];
00437 u[i][n-1][j] = u[i][n-2][j];
00438
00439 u[i][j][0] = u[i][j][1];
00440
00441 }
00442
00443 return u;
00444 }
00445
00446 double *residual_1d( double *res , double *u , double *k , double *f , int n , double dz , double dt )
00447 {
00448 int i;
00449 double h=1./(n-1)*dz;
00450 double h_2 = h*h;
00451
00452 for ( i=1 ; i<n-1 ; i++ )
00453 res[i] = -( u[i-1]*k[i] + u[i+1]*k[i+1] - u[i]*(k[i+1] + k[i] + h_2/dt) )/h_2 + f[i];
00454
00455 res[0] = f[0];
00456 res[n-1] = 0;
00457
00458 return res;
00459 }
00460
00461 double **residual_2d( double **res , double **u , double **kx , double **kz , double **f , int n , double dx , double dz , double dt )
00462 {
00463 int i, j;
00464 double hx=1./(n-1)*dx;
00465 double hz=1./(n-1)*dz;
00466 double hx_2 = hx*hx;
00467 double hz_2 = hz*hz;
00468
00469 for ( i=1 ; i<n-1 ; i++ )
00470 for ( j=1 ; j<n-1 ; j++ )
00471 res[i][j] = - ( u[i-1][j]*kx[i][j] + u[i+1][j]*kx[i+1][j] )/hx_2
00472 - ( u[i][j-1]*kz[i][j] + u[i][j+1]*kz[i][j+1] )/hz_2
00473 + u[i][j]*( kx[i][j]+kx[i+1][j] )/hx_2
00474 + u[i][j]*( kz[i][j]+kz[i][j+1] )/hz_2
00475 + u[i][j]/dt
00476 + f[i][j];
00477
00478 for ( i=0 ; i<n ; i++ )
00479 {
00480 res[0][i] = f[0][i];
00481 res[n-1][i] = f[n-1][i];
00482 res[i][0] = f[i][0];
00483 res[i][n-1] = 0;
00484 }
00485
00486 return res;
00487 }
00488
00489 double ***residual_3d( double ***res , double ***u , double ***kx , double ***kz , double ***f , int n , double dx , double dz , double dt )
00490 {
00491 int i, j, k;
00492 double hx=1./(n-1)*dx;
00493 double hz=1./(n-1)*dz;
00494 double hx_2 = hx*hx;
00495 double hz_2 = hz*hz;
00496
00497 for ( i=1 ; i<n-1 ; i++ )
00498 for ( j=1 ; j<n-1 ; j++ )
00499 for ( j=1 ; j<n-1 ; j++ )
00500 res[i][j][k] = - ( u[i-1][j][k]*kx[i][j][k] + u[i+1][j][k]*kx[i+1][j][k] )/hx_2
00501 - ( u[i][j-1][k]*kx[i][j][k] + u[i][j+1][k]*kx[i][j+1][k] )/hx_2
00502 - ( u[i][j][k-1]*kz[i][j][k] + u[i][j][k+1]*kz[i][j][k+1] )/hz_2
00503 + u[i][j][k]*( kx[i][j][k]+kx[i+1][j][k] )/hx_2
00504 + u[i][j][k]*( kx[i][j][k]+kx[i][j+1][k] )/hx_2
00505 + u[i][j][k]*( kz[i][j][k]+kz[i][j][k+1] )/hz_2
00506 + u[i][j][k]/dt
00507 + f[i][j][k];
00508
00509 for ( i=0 ; i<n ; i++ )
00510 for ( j=0 ; j<n ; j++ )
00511 {
00512 res[0][i][j] = f[0][i][j];
00513 res[n-1][i][j] = f[n-1][i][j];
00514
00515 res[i][0][j] = f[i][0][j];
00516 res[i][n-1][j] = f[i][n-1][j];
00517
00518 res[i][j][0] = f[i][j][0];
00519 res[i][j][n-1] = 0;
00520 }
00521
00522 return res;
00523 }
00524
00525 double *solve_1d( double *u , double *k , double *f , double dz , double dt )
00526 {
00527 double h=1./(3-1)*dz;
00528 double h_2 = h*h;
00529
00530 u[1] = ( (1/h_2)*( u[0]*k[0] + u[2]*k[2] ) - f[1] )*h_2/( k[2] + k[1] + h_2/dt );
00531
00532 return u;
00533 }
00534
00535 double **solve_2d( double **u , double **kx , double **kz , double **f , double dx , double dz , double dt )
00536 {
00537 double hx=1./(3-1)*dx;
00538 double hz=1./(3-1)*dz;
00539 double hx_2 = hx*hx;
00540 double hz_2 = hz*hz;
00541 int i, j;
00542
00543 i = 1;
00544 j = 1;
00545 u[i][j] = ( ( u[i-1][j]*kx[i][j] + u[i+1][j]*kx[i+1][j] )/hx_2
00546 + ( u[i][j-1]*kz[i][j] + u[i][j+1]*kz[i][j+1] )/hz_2
00547 - f[i][j] )
00548 /( (kx[i][j]+kx[i+1][j])/hx_2 + (kz[i][j]+kz[i][j+1])/hz_2 + 1/dt);
00549 return u;
00550 }
00551
00552 double ***solve_3d( double ***u , double ***kx , double ***kz , double ***f , double dx , double dz , double dt )
00553 {
00554 double hx=1./(3-1)*dx;
00555 double hz=1./(3-1)*dz;
00556 double hx_2 = hx*hx;
00557 double hz_2 = hz*hz;
00558 int i, j, k;
00559
00560 i = 1;
00561 j = 1;
00562 k = 1;
00563 u[i][j][k] = ( ( u[i-1][j][k]*kx[i][j][k] + u[i+1][j][k]*kx[i+1][j][k] )/hx_2
00564 + ( u[i][j-1][k]*kx[i][j][k] + u[i][j+1][k]*kx[i][j+1][k] )/hx_2
00565 + ( u[i][j][k-1]*kz[i][j][k] + u[i][j][k+1]*kz[i][j][k+1] )/hz_2
00566 - f[i][j][k] )
00567 /( (kx[i][j][k]+kx[i+1][j][k])/hx_2 + (kx[i][j][k]+kx[i][j+1][k])/hx_2 + (kz[i][j][k]+kz[i][j][k+1])/hz_2 + 1/dt);
00568 return u;
00569 }
00570
00571 double *add_inter_1d( double *u_h , double *u_2h , int n_2h )
00572 {
00573 int i, n_h=2*n_2h-1;
00574 double *r_h = eh_new( double , n_h );
00575
00576 inter_1d( r_h , u_2h , n_2h );
00577
00578 for ( i=0 ; i<n_h ; i++ )
00579 u_h[i] = u_h[i] + r_h[i];
00580
00581 eh_free( r_h );
00582
00583 return u_h;
00584 }
00585
00586 double **add_inter_2d( double **u_h , double **u_2h , int n_2h )
00587 {
00588 int i, j, n_h=2*n_2h-1;
00589 double **r_h;
00590
00591 r_h = allocate_2d( n_h );
00592
00593 inter_2d( r_h , u_2h , n_2h );
00594
00595 for ( i=0 ; i<n_h ; i++ )
00596 for ( j=0 ; j<n_h ; j++ )
00597 u_h[i][j] = u_h[i][j] + r_h[i][j];
00598
00599 eh_free( r_h[0] );
00600 eh_free( r_h );
00601
00602 return u_h;
00603 }
00604
00605 double ***add_inter_3d( double ***u_h , double ***u_2h , int n_2h )
00606 {
00607 int i, j, k, n_h=2*n_2h-1;
00608 double ***r_h;
00609
00610 r_h = allocate_3d( n_h );
00611
00612 inter_3d( r_h , u_2h , n_2h );
00613
00614 for ( i=0 ; i<n_h ; i++ )
00615 for ( j=0 ; j<n_h ; j++ )
00616 for ( k=0 ; k<n_h ; k++ )
00617 u_h[i][j][k] = u_h[i][j][k] + r_h[i][j][k];
00618
00619 free_3d( r_h );
00620
00621 return u_h;
00622 }
00623
00624 double *mgm_1d( double *u_h , double *k_h , double *f_h , int n_h , double dz , double dt )
00625 {
00626 int n_2h = (n_h+1)/2.;
00627 double *u_2h, *k_2h, *f_2h, *r_h;
00628
00629 u_2h = eh_new0( double , n_2h );
00630 k_2h = eh_new ( double , n_2h );
00631 f_2h = eh_new ( double , n_2h );
00632 r_h = eh_new ( double , n_h );
00633
00634 relax_1d( u_h , k_h , f_h , n_h , dz , dt );
00635 residual_1d( r_h , u_h , k_h , f_h , n_h , dz , dt );
00636
00637 restrict_1d( f_2h , r_h , n_h );
00638 restrict_1d( k_2h , k_h , n_h );
00639
00640 if ( n_2h > 3 )
00641 mgm_1d( u_2h , k_2h , f_2h , n_2h , dz , dt );
00642 else
00643 solve_1d( u_2h , k_2h , f_2h , dz , dt );
00644
00645 add_inter_1d( u_h , u_2h , n_2h );
00646
00647 relax_1d( u_h , k_h , f_h , n_h , dz , dt );
00648
00649 eh_free( u_2h );
00650 eh_free( k_2h );
00651 eh_free( f_2h );
00652 eh_free( r_h );
00653
00654 return u_h;
00655 }
00656
00657 #include <utils/utils.h>
00658
00659 double **mgm_2d( double **u_h , double **kx_h , double **kz_h , double **f_h , int n_h , double dx , double dz , double dt )
00660 {
00661 int i, j, n_2h = (n_h+1)/2.;
00662 double **u_2h, **kx_2h, **kz_2h , **f_2h, **r_h;
00663
00664 u_2h = allocate_2d( n_2h );
00665 kx_2h = allocate_2d( n_2h );
00666 kz_2h = allocate_2d( n_2h );
00667 f_2h = allocate_2d( n_2h );
00668 r_h = allocate_2d( n_h );
00669
00670 for ( i=0 ; i<n_2h ; i++ )
00671 for ( j=0 ; j<n_2h ; j++ )
00672 u_2h[i][j] = 0;
00673
00674 relax_2d( u_h , kx_h , kz_h , f_h , n_h , dx , dz , dt );
00675 residual_2d( r_h , u_h , kx_h , kz_h , f_h , n_h , dx , dz , dt );
00676
00677 restrict_2d( f_2h , r_h , n_h );
00678 restrict_2d( kx_2h , kx_h , n_h );
00679 restrict_2d( kz_2h , kz_h , n_h );
00680
00681 if ( n_2h > 3 )
00682 mgm_2d( u_2h , kx_2h , kz_2h , f_2h , n_2h , dx , dz , dt );
00683 else
00684 solve_2d( u_2h , kx_2h , kz_2h , f_2h , dx , dz , dt );
00685
00686 add_inter_2d( u_h , u_2h , n_2h );
00687
00688 relax_2d( u_h , kx_h , kz_h , f_h , n_h , dx , dz , dt );
00689
00690 eh_free( u_2h[0] );
00691 eh_free( kx_2h[0] );
00692 eh_free( kz_2h[0] );
00693 eh_free( f_2h[0] );
00694 eh_free( r_h[0] );
00695
00696 eh_free( u_2h );
00697 eh_free( kx_2h );
00698 eh_free( kz_2h );
00699 eh_free( f_2h );
00700 eh_free( r_h );
00701
00702 return u_h;
00703 }
00704
00705 double ***mgm_3d( double ***u_h , double ***kx_h , double ***kz_h , double ***f_h , int n_h , double dx , double dz , double dt )
00706 {
00707 int i, j, k, n_2h = (n_h+1)/2.;
00708 double ***u_2h, ***kx_2h, ***kz_2h , ***f_2h, ***r_h;
00709
00710 u_2h = allocate_3d( n_2h );
00711 kx_2h = allocate_3d( n_2h );
00712 kz_2h = allocate_3d( n_2h );
00713 f_2h = allocate_3d( n_2h );
00714 r_h = allocate_3d( n_h );
00715
00716 for ( i=0 ; i<n_2h ; i++ )
00717 for ( j=0 ; j<n_2h ; j++ )
00718 for ( k=0 ; k<n_2h ; k++ )
00719 u_2h[i][j][k] = 0;
00720
00721 relax_3d( u_h , kx_h , kz_h , f_h , n_h , dx , dz , dt );
00722 residual_3d( r_h , u_h , kx_h , kz_h , f_h , n_h , dx , dz , dt );
00723
00724 restrict_3d( f_2h , r_h , n_h );
00725 restrict_3d( kx_2h , kx_h , n_h );
00726 restrict_3d( kz_2h , kz_h , n_h );
00727
00728 if ( n_2h > 3 )
00729 mgm_3d( u_2h , kx_2h , kz_2h , f_2h , n_2h , dx , dz , dt );
00730 else
00731 solve_3d( u_2h , kx_2h , kz_2h , f_2h , dx , dz , dt );
00732
00733 add_inter_3d( u_h , u_2h , n_2h );
00734
00735 relax_3d( u_h , kx_h , kz_h , f_h , n_h , dx , dz , dt );
00736
00737 free_3d( u_2h );
00738 free_3d( kx_2h );
00739 free_3d( kz_2h );
00740 free_3d( f_2h );
00741 free_3d( r_h );
00742
00743 return u_h;
00744 }
00745
00746 #include <utils/utils.h>
00747
00748 double *fmg_1d( double *u_h , double *k_h , double *f_h , int n_h , double dz , double dt )
00749 {
00750 int i, n, n_grid = log2( n_h-1 );
00751 double **u = eh_new( double* , n_grid );
00752 double **k = eh_new( double* , n_grid );
00753 double **f = eh_new( double* , n_grid );
00754 double *u_2h = eh_new( double , n_h );
00755
00756 u[n_grid-1] = u_h;
00757 k[n_grid-1] = k_h;
00758 f[n_grid-1] = f_h;
00759
00760 n = n_h;
00761
00762 for ( i=n_grid-2 ; i>=0 ; i-- )
00763 {
00764 n = (n+1)/2;
00765
00766 u[i] = eh_new( double , n );
00767 k[i] = eh_new( double , n );
00768 f[i] = eh_new( double , n );
00769
00770 restrict_1d( u[i] , u[i+1] , n*2-1 );
00771 restrict_1d( k[i] , k[i+1] , n*2-1 );
00772 restrict_1d( f[i] , f[i+1] , n*2-1 );
00773 }
00774
00775 memcpy( u_2h , u[0] , sizeof(double)*n );
00776
00777 for ( i=1 ; i<n_grid ; i++ )
00778 {
00779
00780 inter_1d( u_h , u_2h , n );
00781 n = n*2-1;
00782
00783 u_h[0] = u_h[1];
00784 u_h[n-1] = u[i][n-1];
00785
00786 mgm_1d( u_h , k[i] , f[i] , n , dz , dt );
00787
00788 memcpy( u_2h , u_h , sizeof(double)*n );
00789
00790 }
00791
00792 return u_h;
00793 }
00794
00795
00796 double **fmg_2d( double **u_h , double **kx_h , double **kz_h , double **f_h , int n_h , double dx , double dz , double dt )
00797 {
00798 int i, j, l, n, n_grid = log2( n_h-1 );
00799 double ***u = eh_new( double** , n_grid );
00800 double ***kx = eh_new( double** , n_grid );
00801 double ***kz = eh_new( double** , n_grid );
00802 double ***f = eh_new( double** , n_grid );
00803 double **u_2h = allocate_2d( n_h );
00804
00805 u[n_grid-1] = allocate_2d( n_h );
00806 memcpy( u[n_grid-1][0] , u_h[0] , sizeof(double)*n_h*n_h );
00807 kx[n_grid-1] = allocate_2d( n_h );
00808 memcpy( kx[n_grid-1][0] , kx_h[0] , sizeof(double)*n_h*n_h );
00809 kz[n_grid-1] = allocate_2d( n_h );
00810 memcpy( kz[n_grid-1][0] , kz_h[0] , sizeof(double)*n_h*n_h );
00811 f[n_grid-1] = allocate_2d( n_h );
00812 memcpy( f[n_grid-1][0] , f_h[0] , sizeof(double)*n_h*n_h );
00813
00814 n = n_h;
00815
00816 for ( i=n_grid-2 ; i>=0 ; i-- )
00817 {
00818 n = (n+1)/2;
00819
00820 u[i] = allocate_2d( n );
00821 kx[i] = allocate_2d( n );
00822 kz[i] = allocate_2d( n );
00823 f[i] = allocate_2d( n );
00824
00825 restrict_2d( u[i] , u[i+1] , n*2-1 );
00826 restrict_2d( kx[i] , kx[i+1] , n*2-1 );
00827 restrict_2d( kz[i] , kz[i+1] , n*2-1 );
00828 restrict_2d( f[i] , f[i+1] , n*2-1 );
00829 }
00830
00831 for (j=0;j<n;j++)
00832 for (l=0;l<n;l++)
00833 u_2h[j][l] = u[0][j][l];
00834
00835 for ( i=1 ; i<n_grid ; i++ )
00836 {
00837
00838 inter_2d( u_h , u_2h , n );
00839 n = n*2-1;
00840
00841 for (j=0;j<n;j++)
00842 {
00843 u_h[j][n-1] = u[i][j][n-1];
00844
00845 u_h[0][j] = u_h[1][j];
00846 u_h[n-1][j] = u_h[n-2][j];
00847 u_h[j][0] = u_h[j][1];
00848 }
00849
00850 mgm_2d( u_h , kx[i] , kz[i] , f[i] , n , dx , dz , dt );
00851
00852 for (j=0;j<n;j++)
00853 for (l=0;l<n;l++)
00854 u_2h[j][l] = u_h[j][l];
00855
00856 }
00857
00858 for ( i=0 ; i<n_grid ; i++ )
00859 {
00860 free_2d( u[i] );
00861 free_2d( kx[i] );
00862 free_2d( kz[i] );
00863 free_2d( f[i] );
00864 }
00865
00866 return u_h;
00867 }
00868
00869 void print_matrix_3d( double ***a , int n );
00870
00871 double ***fmg_3d( double ***u_h , double ***kx_h , double ***kz_h , double ***f_h , int n_h , double dx , double dz , double dt )
00872 {
00873 int i, j, k, l, m, n, n_grid = log2( n_h-1 );
00874 double ****u = eh_new( double*** , n_grid );
00875 double ****kx = eh_new( double*** , n_grid );
00876 double ****kz = eh_new( double*** , n_grid );
00877 double ****f = eh_new( double*** , n_grid );
00878 double ***u_2h = allocate_3d( n_h );
00879
00880 u [n_grid-1] = allocate_3d( n_h );
00881 kx[n_grid-1] = allocate_3d( n_h );
00882 kz[n_grid-1] = allocate_3d( n_h );
00883 f [n_grid-1] = allocate_3d( n_h );
00884
00885 for ( i=0 ; i<n_h ; i++ )
00886 {
00887 for ( j=0 ; j<n_h ; j++ )
00888 {
00889 for ( k=0 ; k<n_h ; k++ )
00890 {
00891 u [n_grid-1][i][j][k] = u_h [i][j][k];
00892 kx[n_grid-1][i][j][k] = kx_h[i][j][k];
00893 kz[n_grid-1][i][j][k] = kz_h[i][j][k];
00894 f [n_grid-1][i][j][k] = f_h [i][j][k];
00895 }
00896 }
00897 }
00898
00899 n = n_h;
00900
00901 for ( i=n_grid-2 ; i>=0 ; i-- )
00902 {
00903 n = (n+1)/2;
00904
00905 u[i] = allocate_3d( n );
00906 kx[i] = allocate_3d( n );
00907 kz[i] = allocate_3d( n );
00908 f[i] = allocate_3d( n );
00909
00910 restrict_3d( u[i] , u[i+1] , n*2-1 );
00911 restrict_3d( kx[i] , kx[i+1] , n*2-1 );
00912 restrict_3d( kz[i] , kz[i+1] , n*2-1 );
00913 restrict_3d( f[i] , f[i+1] , n*2-1 );
00914
00915
00916 }
00917
00918 for (j=0;j<n;j++)
00919 for (l=0;l<n;l++)
00920 for (m=0;m<n;m++)
00921 u_2h[j][l][m] = u[0][j][l][m];
00922
00923 for ( i=1 ; i<n_grid ; i++ )
00924 {
00925
00926
00927 inter_3d( u_h , u_2h , n );
00928 n = n*2-1;
00929
00930 for ( l=0 ; l<n ; l++ )
00931 for ( m=0 ; m<n ; m++ )
00932 {
00933 u_h[0][l][m] = u_h[1][l][m];
00934 u_h[n-1][l][m] = u_h[n-2][l][m];
00935
00936 u_h[l][0][m] = u_h[l][1][m];
00937 u_h[l][n-1][m] = u_h[l][n-2][m];
00938
00939 u_h[l][m][0] = u_h[l][m][1];
00940 u_h[l][m][n-1] = u[i][l][m][n-1];
00941 }
00942
00943
00944 mgm_3d( u_h , kx[i] , kz[i] , f[i] , n , dx , dz , dt );
00945
00946 for (j=0;j<n;j++)
00947 for (l=0;l<n;l++)
00948 for (m=0;m<n;m++)
00949 u_2h[j][l][m] = u_h[j][l][m];
00950
00951 }
00952
00953 for ( i=0 ; i<n_grid ; i++ )
00954 {
00955 free_3d( u[i] );
00956 free_3d( kx[i] );
00957 free_3d( kz[i] );
00958 free_3d( f[i] );
00959 }
00960 free_3d( u_2h );
00961 eh_free( u );
00962 eh_free( kx );
00963 eh_free( kz );
00964 eh_free( f );
00965
00966 return u_h;
00967 }
00968
00969 double *allocate_1d( int n )
00970 {
00971 return eh_new( double , n );
00972 }
00973
00974 double **allocate_2d( int n )
00975 {
00976 int i;
00977 double **ans;
00978 ans = eh_new( double* , n );
00979 ans[0] = eh_new( double , n*n );
00980 for ( i=1 ; i<n ; i++ )
00981 ans[i] = ans[i-1] + n;
00982 return ans;
00983 }
00984
00985 double ***allocate_3d( int n )
00986 {
00987 int i, j;
00988 double ***ans;
00989
00990 ans = eh_new( double** , n );
00991 ans[0] = eh_new( double* , n*n );
00992 ans[0][0] = eh_new( double , n*n*n );
00993
00994 for ( i=1 ; i<n ; i++ )
00995 {
00996 ans[i] = ans[i-1] + n;
00997 ans[i][0] = ans[i-1][0] + n*n;
00998 }
00999
01000 for ( i=0 ; i<n ; i++ )
01001 for ( j=1 ; j<n ; j++ )
01002 ans[i][j] = ans[i][j-1]+n;
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013 return ans;
01014 }
01015
01016 void free_2d( double **a )
01017 {
01018 eh_free( a[0] );
01019 eh_free( a );
01020 }
01021
01022 void free_3d( double ***a )
01023 {
01024 eh_free( a[0][0] );
01025 eh_free( a[0] );
01026 eh_free( a );
01027 }
01028
01029 void print_matrix( double **a , int n )
01030 {
01031 int i, j;
01032 for ( i=0 ; i<n ; i++ )
01033 {
01034 for ( j=0 ; j<n ; j++ )
01035 fprintf( stderr , "%f " , a[i][j] );
01036 fprintf( stderr , "\n" );
01037 }
01038 }
01039
01040 void print_matrix_3d( double ***a , int n )
01041 {
01042 int i, j, k;
01043 for ( k=0 ; k<n ; k++ )
01044 {
01045 fprintf( stderr , "k=%d\n" , k );
01046 for ( j=0 ; j<n ; j++ )
01047 {
01048 for ( i=0 ; i<n ; i++ )
01049 fprintf( stderr , "%.2f " , a[i][j][k] );
01050 fprintf( stderr , "\n" );
01051 }
01052 fprintf( stderr , "\n\n");
01053 }
01054
01055 fprintf( stderr , "\n\n" );
01056 }
01057
01058
01059