xref: /petsc/src/snes/tutorials/ex33.c (revision c4762a1b19cd2af06abeed90e8f9d34fb975dd94)
1*c4762a1bSJed Brown static char help[] = "Multiphase flow in a porous medium in 1d.\n\n";
2*c4762a1bSJed Brown #include <petscdm.h>
3*c4762a1bSJed Brown #include <petscdmda.h>
4*c4762a1bSJed Brown #include <petscsnes.h>
5*c4762a1bSJed Brown 
6*c4762a1bSJed Brown typedef struct {
7*c4762a1bSJed Brown   DM        cda;
8*c4762a1bSJed Brown   Vec       uold;
9*c4762a1bSJed Brown   Vec       Kappa;
10*c4762a1bSJed Brown   PetscReal phi;
11*c4762a1bSJed Brown   PetscReal kappaWet;
12*c4762a1bSJed Brown   PetscReal kappaNoWet;
13*c4762a1bSJed Brown   PetscReal dt;
14*c4762a1bSJed Brown   /* Boundary conditions */
15*c4762a1bSJed Brown   PetscReal sl, vl, pl;
16*c4762a1bSJed Brown } AppCtx;
17*c4762a1bSJed Brown 
18*c4762a1bSJed Brown typedef struct {
19*c4762a1bSJed Brown   PetscScalar s; /* The saturation on each cell */
20*c4762a1bSJed Brown   PetscScalar v; /* The velocity on each face */
21*c4762a1bSJed Brown   PetscScalar p; /* The pressure on each cell */
22*c4762a1bSJed Brown } Field;
23*c4762a1bSJed Brown 
24*c4762a1bSJed Brown /*
25*c4762a1bSJed Brown    FormPermeability - Forms permeability field.
26*c4762a1bSJed Brown 
27*c4762a1bSJed Brown    Input Parameters:
28*c4762a1bSJed Brown    user - user-defined application context
29*c4762a1bSJed Brown 
30*c4762a1bSJed Brown    Output Parameter:
31*c4762a1bSJed Brown    Kappa - vector
32*c4762a1bSJed Brown  */
33*c4762a1bSJed Brown PetscErrorCode FormPermeability(DM da, Vec Kappa, AppCtx *user)
34*c4762a1bSJed Brown {
35*c4762a1bSJed Brown   DM             cda;
36*c4762a1bSJed Brown   Vec            c;
37*c4762a1bSJed Brown   PetscScalar    *K;
38*c4762a1bSJed Brown   PetscScalar    *coords;
39*c4762a1bSJed Brown   PetscInt       xs, xm, i;
40*c4762a1bSJed Brown   PetscErrorCode ierr;
41*c4762a1bSJed Brown 
42*c4762a1bSJed Brown   PetscFunctionBeginUser;
43*c4762a1bSJed Brown   ierr = DMGetCoordinateDM(da, &cda);CHKERRQ(ierr);
44*c4762a1bSJed Brown   ierr = DMGetCoordinates(da, &c);CHKERRQ(ierr);
45*c4762a1bSJed Brown   ierr = DMDAGetCorners(da, &xs,NULL,NULL, &xm,NULL,NULL);CHKERRQ(ierr);
46*c4762a1bSJed Brown   ierr = DMDAVecGetArray(da, Kappa, &K);CHKERRQ(ierr);
47*c4762a1bSJed Brown   ierr = DMDAVecGetArray(cda, c, &coords);CHKERRQ(ierr);
48*c4762a1bSJed Brown   for (i = xs; i < xs+xm; ++i) {
49*c4762a1bSJed Brown #if 1
50*c4762a1bSJed Brown     K[i] = 1.0;
51*c4762a1bSJed Brown #else
52*c4762a1bSJed Brown     /* Notch */
53*c4762a1bSJed Brown     if (i == (xs+xm)/2) K[i] = 0.00000001;
54*c4762a1bSJed Brown     else K[i] = 1.0;
55*c4762a1bSJed Brown #endif
56*c4762a1bSJed Brown   }
57*c4762a1bSJed Brown   ierr = DMDAVecRestoreArray(da, Kappa, &K);CHKERRQ(ierr);
58*c4762a1bSJed Brown   ierr = DMDAVecRestoreArray(cda, c, &coords);CHKERRQ(ierr);
59*c4762a1bSJed Brown   PetscFunctionReturn(0);
60*c4762a1bSJed Brown }
61*c4762a1bSJed Brown 
62*c4762a1bSJed Brown /*
63*c4762a1bSJed Brown    FormFunctionLocal - Evaluates nonlinear residual, F(x) on local process patch
64*c4762a1bSJed Brown */
65*c4762a1bSJed Brown PetscErrorCode FormFunctionLocal(DMDALocalInfo *info, Field *u, Field *f, AppCtx *user)
66*c4762a1bSJed Brown {
67*c4762a1bSJed Brown   Vec            L;
68*c4762a1bSJed Brown   PetscReal      phi        = user->phi;
69*c4762a1bSJed Brown   PetscReal      dt         = user->dt;
70*c4762a1bSJed Brown   PetscReal      dx         = 1.0/(PetscReal)(info->mx-1);
71*c4762a1bSJed Brown   PetscReal      alpha      = 2.0;
72*c4762a1bSJed Brown   PetscReal      beta       = 2.0;
73*c4762a1bSJed Brown   PetscReal      kappaWet   = user->kappaWet;
74*c4762a1bSJed Brown   PetscReal      kappaNoWet = user->kappaNoWet;
75*c4762a1bSJed Brown   Field          *uold;
76*c4762a1bSJed Brown   PetscScalar    *Kappa;
77*c4762a1bSJed Brown   PetscInt       i;
78*c4762a1bSJed Brown   PetscErrorCode ierr;
79*c4762a1bSJed Brown 
80*c4762a1bSJed Brown   PetscFunctionBeginUser;
81*c4762a1bSJed Brown   ierr = DMGetGlobalVector(user->cda, &L);CHKERRQ(ierr);
82*c4762a1bSJed Brown 
83*c4762a1bSJed Brown   ierr = DMDAVecGetArray(info->da, user->uold,  &uold);CHKERRQ(ierr);
84*c4762a1bSJed Brown   ierr = DMDAVecGetArray(user->cda, user->Kappa, &Kappa);CHKERRQ(ierr);
85*c4762a1bSJed Brown   /* Compute residual over the locally owned part of the grid */
86*c4762a1bSJed Brown   for (i = info->xs; i < info->xs+info->xm; ++i) {
87*c4762a1bSJed Brown     if (i == 0) {
88*c4762a1bSJed Brown       f[i].s = u[i].s - user->sl;
89*c4762a1bSJed Brown       f[i].v = u[i].v - user->vl;
90*c4762a1bSJed Brown       f[i].p = u[i].p - user->pl;
91*c4762a1bSJed Brown     } else {
92*c4762a1bSJed Brown       PetscScalar K          = 2*dx/(dx/Kappa[i] + dx/Kappa[i-1]);
93*c4762a1bSJed Brown       PetscReal   lambdaWet  = kappaWet*PetscRealPart(PetscPowScalar(u[i].s, alpha));
94*c4762a1bSJed Brown       PetscReal   lambda     = lambdaWet + kappaNoWet*PetscRealPart(PetscPowScalar(1.-u[i].s, beta));
95*c4762a1bSJed Brown       PetscReal   lambdaWetL = kappaWet*PetscRealPart(PetscPowScalar(u[i-1].s, alpha));
96*c4762a1bSJed Brown       PetscReal   lambdaL    = lambdaWetL + kappaNoWet*PetscRealPart(PetscPowScalar(1.-u[i-1].s, beta));
97*c4762a1bSJed Brown 
98*c4762a1bSJed Brown       f[i].s = phi*(u[i].s - uold[i].s) + (dt/dx)*((lambdaWet/lambda)*u[i].v - (lambdaWetL/lambdaL)*u[i-1].v);
99*c4762a1bSJed Brown 
100*c4762a1bSJed Brown       f[i].v = u[i].v + K*lambda*(u[i].p - u[i-1].p)/dx;
101*c4762a1bSJed Brown 
102*c4762a1bSJed Brown       /*pxx     = (2.0*u[i].p - u[i-1].p - u[i+1].p)/dx;*/
103*c4762a1bSJed Brown       f[i].p = u[i].v - u[i-1].v;
104*c4762a1bSJed Brown     }
105*c4762a1bSJed Brown   }
106*c4762a1bSJed Brown   ierr = DMDAVecRestoreArray(info->da, user->uold, &uold);CHKERRQ(ierr);
107*c4762a1bSJed Brown   ierr = DMDAVecRestoreArray(user->cda, user->Kappa, &Kappa);CHKERRQ(ierr);
108*c4762a1bSJed Brown   /* ierr = PetscLogFlops(11.0*info->ym*info->xm);CHKERRQ(ierr); */
109*c4762a1bSJed Brown 
110*c4762a1bSJed Brown   ierr = DMRestoreGlobalVector(user->cda, &L);CHKERRQ(ierr);
111*c4762a1bSJed Brown   PetscFunctionReturn(0);
112*c4762a1bSJed Brown }
113*c4762a1bSJed Brown 
114*c4762a1bSJed Brown int main(int argc, char **argv)
115*c4762a1bSJed Brown {
116*c4762a1bSJed Brown   SNES           snes;   /* nonlinear solver */
117*c4762a1bSJed Brown   DM             da;     /* grid */
118*c4762a1bSJed Brown   Vec            u;      /* solution vector */
119*c4762a1bSJed Brown   AppCtx         user;   /* user-defined work context */
120*c4762a1bSJed Brown   PetscReal      t = 0.0;/* time */
121*c4762a1bSJed Brown   PetscErrorCode ierr;
122*c4762a1bSJed Brown   PetscInt       n;
123*c4762a1bSJed Brown 
124*c4762a1bSJed Brown   ierr = PetscInitialize(&argc, &argv, NULL,help);if (ierr) return ierr;
125*c4762a1bSJed Brown   /* Create solver */
126*c4762a1bSJed Brown   ierr = SNESCreate(PETSC_COMM_WORLD, &snes);CHKERRQ(ierr);
127*c4762a1bSJed Brown   /* Create mesh */
128*c4762a1bSJed Brown   ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,4,3,1,NULL,&da);CHKERRQ(ierr);
129*c4762a1bSJed Brown   ierr = DMSetFromOptions(da);CHKERRQ(ierr);
130*c4762a1bSJed Brown   ierr = DMSetUp(da);CHKERRQ(ierr);
131*c4762a1bSJed Brown   ierr = DMSetApplicationContext(da, &user);CHKERRQ(ierr);
132*c4762a1bSJed Brown   ierr = SNESSetDM(snes, da);CHKERRQ(ierr);
133*c4762a1bSJed Brown   /* Create coefficient */
134*c4762a1bSJed Brown   ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,4,1,1,NULL,&user.cda);CHKERRQ(ierr);
135*c4762a1bSJed Brown   ierr = DMSetFromOptions(user.cda);CHKERRQ(ierr);
136*c4762a1bSJed Brown   ierr = DMSetUp(user.cda);CHKERRQ(ierr);
137*c4762a1bSJed Brown   ierr = DMDASetUniformCoordinates(user.cda, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0);CHKERRQ(ierr);
138*c4762a1bSJed Brown   ierr = DMGetGlobalVector(user.cda, &user.Kappa);CHKERRQ(ierr);
139*c4762a1bSJed Brown   ierr = FormPermeability(user.cda, user.Kappa, &user);CHKERRQ(ierr);
140*c4762a1bSJed Brown   /* Setup Problem */
141*c4762a1bSJed Brown   ierr = DMDASNESSetFunctionLocal(da,INSERT_VALUES,(PetscErrorCode (*)(DMDALocalInfo*,void*,void*,void*))FormFunctionLocal,&user);CHKERRQ(ierr);
142*c4762a1bSJed Brown   ierr = DMGetGlobalVector(da, &u);CHKERRQ(ierr);
143*c4762a1bSJed Brown   ierr = DMGetGlobalVector(da, &user.uold);CHKERRQ(ierr);
144*c4762a1bSJed Brown 
145*c4762a1bSJed Brown   user.sl  = 1.0;
146*c4762a1bSJed Brown   user.vl  = 0.1;
147*c4762a1bSJed Brown   user.pl  = 1.0;
148*c4762a1bSJed Brown   user.phi = 1.0;
149*c4762a1bSJed Brown 
150*c4762a1bSJed Brown   user.kappaWet   = 1.0;
151*c4762a1bSJed Brown   user.kappaNoWet = 0.3;
152*c4762a1bSJed Brown 
153*c4762a1bSJed Brown   /* Time Loop */
154*c4762a1bSJed Brown   user.dt = 0.1;
155*c4762a1bSJed Brown   for (n = 0; n < 100; ++n, t += user.dt) {
156*c4762a1bSJed Brown     ierr = PetscPrintf(PETSC_COMM_WORLD, "Starting time %g\n", (double)t);CHKERRQ(ierr);
157*c4762a1bSJed Brown     ierr = VecView(u, PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);
158*c4762a1bSJed Brown     /* Solve */
159*c4762a1bSJed Brown     ierr = SNESSetFromOptions(snes);CHKERRQ(ierr);
160*c4762a1bSJed Brown     ierr = SNESSolve(snes, NULL, u);CHKERRQ(ierr);
161*c4762a1bSJed Brown     /* Update */
162*c4762a1bSJed Brown     ierr = VecCopy(u, user.uold);CHKERRQ(ierr);
163*c4762a1bSJed Brown 
164*c4762a1bSJed Brown     ierr = VecView(u, PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);
165*c4762a1bSJed Brown   }
166*c4762a1bSJed Brown   /* Cleanup */
167*c4762a1bSJed Brown   ierr = DMRestoreGlobalVector(da, &u);CHKERRQ(ierr);
168*c4762a1bSJed Brown   ierr = DMRestoreGlobalVector(da, &user.uold);CHKERRQ(ierr);
169*c4762a1bSJed Brown   ierr = DMRestoreGlobalVector(user.cda, &user.Kappa);CHKERRQ(ierr);
170*c4762a1bSJed Brown   ierr = DMDestroy(&user.cda);CHKERRQ(ierr);
171*c4762a1bSJed Brown   ierr = DMDestroy(&da);CHKERRQ(ierr);
172*c4762a1bSJed Brown   ierr = SNESDestroy(&snes);CHKERRQ(ierr);
173*c4762a1bSJed Brown   ierr = PetscFinalize();
174*c4762a1bSJed Brown   return ierr;
175*c4762a1bSJed Brown }
176*c4762a1bSJed Brown 
177*c4762a1bSJed Brown /*TEST
178*c4762a1bSJed Brown 
179*c4762a1bSJed Brown   test:
180*c4762a1bSJed Brown     suffix: 0
181*c4762a1bSJed Brown     requires: !single
182*c4762a1bSJed Brown     args: -snes_converged_reason -snes_monitor_short
183*c4762a1bSJed Brown 
184*c4762a1bSJed Brown TEST*/
185