Main Page   Data Structures   File List   Data Fields   Globals  

momentum.denis.c

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*/
00002 /* SCCS Information: %W%    %G% */
00003 /*---------------------------------------------------------------------------*/
00004 /*  
00005                                   
00006                         o..............o
00007                         :              :
00008                     a(i-1,j)           :
00009                     u(i,j)             :
00010                  *------>------*   S11, S22(i,j), pressure, divergence
00011                  |      :      |   u**2, v**2, cc(i,j)
00012                  |      :      |       :
00013                  |   S12       | v(i,j):
00014                  ^      o..... ^.......o 
00015                  |             | c(i,j-1)
00016                  |             |
00017                  |             |
00018                  *------>------*
00019     
00020    
00021        SKETCH OF TOP-BOTTOM BOUNDARY CONDITIONS
00022     
00023         *-----*------*------*------*  j =  ny   p(i,ny)
00024         |     |      |      |      |
00025     ....^.....^......^......^......^....        v(i,ny) = 0
00026         |     |      |      |      |
00027         |---------------------->---
00028         |     |      |      |      |  j = ny-1
00029         |     |      |      |      ^
00030         |--------------------------|
00031         |     |      |      |      |
00032     
00033     
00034         |     |      |      |      |
00035         |--------------------------
00036         |     |      |      |      |
00037         |     |      |      |  u(n-1,2)
00038         |---------------------->-- |  p(n-1,2)            | Boundary conditions
00039         |     |      |      |      |                      |    u(i,1) = - u(i,2)
00040     ....^..........................^...  y = 0 v(i,2)     |    p(i,1) = p(i,2) 
00041         |     |      |      |      |                      |    v(i,2) = 0
00042         *-->--*------*------*-->-- *   j=1                   
00043         |     |      |      |      |   p(n-1,1)          
00044         ^     ^      ^      ^      ^   v(n-1,1)
00045         v(2,1)
00046     
00047     Sites on or outside the dotted lines are used to force boundary conditions
00048     There is also one dummy column on each side (not represented).
00049 
00050 
00051     u,v(i,j)  the physical velocities *tau/h
00052 
00053 */
00054 #include "utilf.h"
00055 #include "markers.h"
00056 #include "extra.h"
00057 #include "momentum.h"
00058 #ifdef MG
00059   #include "mg.h"
00060 #else
00061   #include "vmg.h"
00062 #endif
00063 #include "make_bc.h"
00064 
00065 static void coli(real2D cc,
00066                  real2D nu1, real2D nu2, real2D nu3, real2D nu4, 
00067                  real2D c0, real2D c1, real2D c2, real2D c3, real2D c4,
00068                  int nx, int ny);
00069 
00070 void momentum(real2D u, real2D v,
00071               real2D a, real2D c,
00072               real2D w1,
00073               real2D S11, real2D S22, real2D S12,
00074               real2D w2,
00075               real visliq,
00076               real gx, real gy,
00077               real tau,
00078               int nx, int ny)
00079 {
00080   int i, j;
00081   real h;
00082   real gx2, gy2, tau2h;
00083   
00084   h = 1. / (nx - 2);
00085   tau2h = sq(tau) / h;
00086   gx2 = gx * tau2h;
00087   gy2 = gy * tau2h;
00088   visliq *= tau/(h*h);
00089 
00090   /* -----------------------------------------------------------------
00091      Advection term
00092      ------------------------------------------------------------------ */
00093   for (i = 2; i <= nx - 1; i++)
00094     {
00095       for (j = 2; j <= ny - 1; j++)
00096         if (IN(a[i-1][j]))
00097           w1[i][j] = 0.25*(
00098                       (u[i][j] + u[i][j-1])*(v[i][j] + v[i-1][j])
00099                     - (u[i][j+1] + u[i][j])*(v[i][j+1] + v[i-1][j+1])
00100                     + sq(u[i-1][j] + u[i][j]) - sq(u[i][j] + u[i+1][j])
00101                       /* axisymetric term */
00102                     - (v[i][j] + v[i][j+1] + v[i-1][j+1] + v[i-1][j])
00103                       *u[i][j]/((real)j - 1.5));
00104                      
00105       for (j = 3; j <= ny - 1; j++)
00106         if (IN(c[i][j-1]))
00107           w2[i][j] = 0.25*(
00108                       (u[i][j] + u[i][j-1])*(v[i][j] + v[i-1][j])
00109                     - (u[i+1][j] + u[i+1][j-1])*(v[i+1][j] + v[i][j])
00110                     + sq(v[i][j-1] + v[i][j]) - sq(v[i][j] + v[i][j+1])
00111                       /* axisymetric term */
00112                     - sq(2.0*v[i][j])/((real)j - 2.0));
00113     }
00114 
00115   /* ------------------------------------------------------------------
00116      div(S)
00117      Gravity term               
00118      ------------------------------------------------------------------ */
00119   for (i = 2; i <= nx - 1; i++)
00120     {
00121       for (j = 2; j <= ny - 1; j++)
00122         if (IN(a[i-1][j]))
00123           u[i][j] += w1[i][j]
00124             + S12[i][j+1] - S12[i][j] + S11[i][j] - S11[i-1][j]
00125             /* axisymetric term */
00126             /*
00127               + 0.5*(S12[i][j] + S12[i][j+1])/((real)j - 1.5)
00128             */
00129             + gx2;
00130       for (j = 3; j <= ny - 1; j++)
00131         if (IN(c[i][j-1]))
00132           v[i][j] += w2[i][j]
00133             + S12[i+1][j] - S12[i][j] + S22[i][j] - S22[i][j-1]
00134             /* axisymetric term */
00135             + (0.5*(S22[i][j] + S22[i][j-1]) - 2.*visliq*v[i][j]/
00136                ((real)j - 2.0))
00137             /((real)j - 2.0)
00138             + gy2;
00139     }
00140 }
00141 
00142 
00143 void pressure(real2D u, real2D v, real2D p, 
00144               real2D cc, real2D a, real2D c,
00145               real2D div,
00146               real2D nu1, real2D nu2, real2D nu3, real2D nu4,
00147               real2D c0, real2D c1, real2D c2, real2D c3, real2D c4,
00148 #ifdef MG
00149               int ncycle, int npre, int npost, real pa,
00150 #else
00151               real epsilon,
00152 #endif
00153               int nx, int ny, int ng)
00154 {
00155   int i, j;
00156   real h = 1.0/(nx - 2), hi2;
00157   real p0, p3, p4, n3, n4;
00158   hi2 = 1./(h*h);       
00159 
00160   /* ------------------------------------------------------------------
00161      Resolution of the pressure equation
00162      div=divergence
00163      p=pressure
00164      ------------------------------------------------------------------ */
00165   for (i = 2; i <= nx - 1; i++)
00166     for (j = 2; j <= ny - 1; j++)
00167       if (IN(cc[i][j]))
00168         div[i][j] = (((real)j - 1.)*v[i][j+1] - ((real)j - 2.)*v[i][j] +
00169           ((real)j - 1.5)*(u[i+1][j] - u[i][j]))
00170 #ifndef MG
00171           *hi2
00172 #endif
00173           ;
00174       else
00175         div[i][j] = 0.0;
00176 
00177   datbarray(div, nx, ny, "divbefore");
00178   datbarray(p, nx, ny, "pbefore");
00179   datbarray(cc, nx, ny, "cc");
00180   datbarray(u, nx, ny, "ubefore");
00181   datbarray(v, nx, ny, "vbefore");
00182 
00183   coli(cc,
00184        nu1, nu2, nu3, nu4,
00185        c0, c1, c2, c3, c4,
00186        nx, ny);
00187 #ifdef MG
00188   /*
00189     mginit(div, p, cc, ra, rc, rei, pint, work, in, nx, ny, ng);
00190     for (i = 0; i < ncycle; i++)
00191     mgvcycle(ng, nx, ny, npre, npost);
00192   */
00193   for (i = 0; i < ncycle; i++) {
00194     relax(p, div, cc,
00195           nu1, nu2, nu3, nu4,
00196           c0, c1, c2, c3, c4,
00197           nx, ny, pa);
00198     bc_scalar(p, nx, ny, NULGRAD2);
00199   }    
00200 #else
00201   mglin(div, p, cc, ra, rc, rei, epsilon, nx, ny, ng);
00202 #endif
00203 
00204   datbarray(p, nx, ny, "pafter");
00205 
00206   /* ------------------------------------------------------------------
00207      Pressure correction
00208      ------------------------------------------------------------------ */ 
00209   for (i = 2; i <= nx - 1; i++) {
00210     for (j = 2; j <= ny - 1; j++)
00211       if (IN(a[i-1][j])) {
00212         if (IN(cc[i][j])) {
00213           p0 = p[i][j];
00214           if (IN(cc[i-1][j])) { p3 = p[i-1][j]; n3 = 1.0; }
00215           else { p3 = pa; n3 = -nu3[i][j]; }
00216         }
00217         else if (IN(cc[i-1][j])) {
00218           p3 = p[i-1][j];
00219           p0 = pa; n3 = nu1[i-1][j];
00220         }
00221         else {
00222           fprintf(stderr, "pressure(): error for u(%d,%d)\n", i, j);
00223           exit(1);
00224         }
00225         u[i][j] -= (p0 - p3)/n3;
00226       }
00227     for (j = 3; j <= ny - 1; j++)
00228       if (IN(c[i][j-1])) {
00229         if (IN(cc[i][j])) {
00230           p0 = p[i][j];
00231           if (IN(cc[i][j-1])) { p4 = p[i][j-1]; n4 = 1.0; }
00232           else { p4 = pa; n4 = -nu4[i][j]; }
00233         }
00234         else if (IN(cc[i][j-1])) {
00235           p4 = p[i][j-1];
00236           p0 = pa; n4 = nu2[i][j-1];
00237         }
00238         else {
00239           fprintf(stderr, "pressure(): error for v(%d,%d)\n", i, j);
00240           exit(1);
00241         }
00242         v[i][j] -= (p0 - p4)/n4;
00243       }
00244   }
00245 }
00246 
00247 
00248 void coli(real2D cc,
00249           real2D nu1, real2D nu2, real2D nu3, real2D nu4, 
00250           real2D c0, real2D c1, real2D c2, real2D c3, real2D c4,
00251           int nx, int ny)
00252 {
00253   int i, j;
00254   real n1, n2, n3, n4, rj, rj12, rj_12;
00255 
00256   for (i = 2; i < nx; i++)
00257     for (j = 2; j < ny; j++) 
00258       if (IN(cc[i][j])) {
00259         n1 = IN(cc[i+1][j]) ? 1.0 : nu1[i][j];
00260         n2 = IN(cc[i][j+1]) ? 1.0 : nu2[i][j];
00261         n3 = IN(cc[i-1][j]) ? 1.0 : - nu3[i][j];
00262         n4 = IN(cc[i][j-1]) ? 1.0 : - nu4[i][j];
00263 
00264         if (n1 < 0.0 || n2 < 0.0 || n3 < 0.0 || n4 < 0.0) {
00265           fprintf(stderr, "coli(): error at %d,%d: n1: %g n2: %g n3: %g n4: %g\n", i, j, n1, n2, n3, n4);
00266         }
00267         
00268         rj = (real)j - 1.5;
00269         rj12 = (real)j - 1.0;
00270         rj_12 = (real)j - 2.0;
00271         c0[i][j] = n1*n2*n3*n4*(n2 + n4)/(rj*n2*n4*(n2 + n4) + 
00272                                           n1*n3*(rj12*n4 + rj_12*n2));
00273         c1[i][j] = rj/(n1*(n1 + n3));
00274         c2[i][j] = rj12/(n2*(n2 + n4));
00275         c3[i][j] = rj/(n3*(n1 + n3));
00276         c4[i][j] = rj_12/(n4*(n2 + n4));
00277       }
00278 }
00279 
00280 
00281 void adaptative(real2D u, real2D v, real2D divafter, real2D cc,
00282                 int *npre, int *npost,
00283                 real mineps, real maxeps, int nx, int ny)
00284 {
00285   int i, j;
00286   real epsilon, h = 1.0/(nx - 2), hi2;
00287   hi2 = 1.0/(h*h);
00288 
00289   /* ------------------------------------------------------------------
00290      Adaptation of the multigrid for the given precision
00291      ------------------------------------------------------------------ */
00292   for (i = 2; i <= nx - 1; i++)
00293     for (j = 2; j <= ny - 1; j++)
00294       if (IN(cc[i][j]))
00295         divafter[i][j] = (((real)j - 1.)*v[i][j+1] - ((real)j - 2.)*v[i][j] + 
00296                           ((real)j - 1.5)*(u[i+1][j] - u[i][j]))*hi2;
00297       else
00298         divafter[i][j] = 0.0;
00299   /*
00300     datbarray(divafter, nx, ny, "divafter");
00301     */
00302   epsilon = rdivmax(divafter, nx, ny);
00303   if (epsilon > mineps) {
00304     (*npre)++; (*npost)++;
00305   }
00306   else if (epsilon < maxeps) {
00307     *npre = MAX(*npre - 1, 1);
00308     *npost = MAX(*npost - 1, 1);
00309   }
00310 }
00311 
00312 
00313 void adaptative_tau(real2D u, real2D v, 
00314                     real2D divafter, real2D cc, real2D p,
00315                     real *tau,
00316                     real mineps, real maxeps, int nx, int ny)
00317 {
00318   int i, j;
00319   real epsilon, velmax, h = 1.0/(nx - 2), hi2;
00320   hi2 = 1./(h*h);
00321 
00322   /* ------------------------------------------------------------------
00323      Adaptation of the time step for the given precision
00324      ------------------------------------------------------------------ */
00325   for (i = 2; i <= nx - 1; i++)
00326     for (j = 2; j <= ny - 1; j++)
00327       if (IN(cc[i][j]))
00328         divafter[i][j] = (((real)j - 1.)*v[i][j+1] - ((real)j - 2.)*v[i][j] +
00329                           ((real)j - 1.5)*(u[i+1][j] - u[i][j]))*hi2;
00330       else
00331         divafter[i][j] = 0.0;
00332 
00333     datbarray(divafter, nx, ny, "divafter");
00334 
00335   epsilon = rdivmax(divafter, nx, ny);
00336   velmax = findninf(u, v, nx, ny, &i, &j);
00337   if (epsilon > mineps || velmax > 0.1) {
00338     rescale(u, v, p, 0.5, nx, ny);
00339     *tau *= 0.5;
00340   }
00341   else if (epsilon < maxeps && velmax < 0.05) {
00342     rescale(u, v, p, 2.0, nx, ny);
00343     *tau *= 2.;
00344   }
00345 }
00346 
00347 
00348 void rescale(real2D u, real2D v, real2D p,
00349              real tscale,
00350              int nx, int ny)
00351 {
00352   int i, j;
00353   real tscale2 = sq(tscale);
00354   
00355   for (i = 1; i <= nx; i++)
00356     for (j = 1; j <= ny; j++) {
00357       u[i][j] *= tscale;
00358       v[i][j] *= tscale;
00359       p[i][j] *= tscale2;
00360     }    
00361 }
00362 
00363 
00364 
00365 
00366 
00367 
00368 
00369 
00370 
00371 

Generated on Wed Feb 19 22:26:50 2003 for Markers by doxygen1.2.18