1*c4762a1bSJed Brown static const char help[] = "Time-dependent Brusselator reaction-diffusion PDE in 1d. Demonstrates IMEX methods and uses MOAB.\n"; 2*c4762a1bSJed Brown /* 3*c4762a1bSJed Brown u_t - alpha u_xx = A + u^2 v - (B+1) u 4*c4762a1bSJed Brown v_t - alpha v_xx = B u - u^2 v 5*c4762a1bSJed Brown 0 < x < 1; 6*c4762a1bSJed Brown A = 1, B = 3, alpha = 1/50 7*c4762a1bSJed Brown 8*c4762a1bSJed Brown Initial conditions: 9*c4762a1bSJed Brown u(x,0) = 1 + sin(2 pi x) 10*c4762a1bSJed Brown v(x,0) = 3 11*c4762a1bSJed Brown 12*c4762a1bSJed Brown Boundary conditions: 13*c4762a1bSJed Brown u(0,t) = u(1,t) = 1 14*c4762a1bSJed Brown v(0,t) = v(1,t) = 3 15*c4762a1bSJed Brown */ 16*c4762a1bSJed Brown 17*c4762a1bSJed Brown // PETSc includes: 18*c4762a1bSJed Brown #include <petscts.h> 19*c4762a1bSJed Brown #include <petscdmmoab.h> 20*c4762a1bSJed Brown 21*c4762a1bSJed Brown typedef struct { 22*c4762a1bSJed Brown PetscScalar u,v; 23*c4762a1bSJed Brown } Field; 24*c4762a1bSJed Brown 25*c4762a1bSJed Brown struct pUserCtx { 26*c4762a1bSJed Brown PetscReal A,B; /* Reaction coefficients */ 27*c4762a1bSJed Brown PetscReal alpha; /* Diffusion coefficient */ 28*c4762a1bSJed Brown Field leftbc; /* Dirichlet boundary conditions at left boundary */ 29*c4762a1bSJed Brown Field rightbc; /* Dirichlet boundary conditions at right boundary */ 30*c4762a1bSJed Brown PetscInt n,npts; /* Number of mesh points */ 31*c4762a1bSJed Brown PetscInt ntsteps; /* Number of time steps */ 32*c4762a1bSJed Brown PetscInt nvars; /* Number of variables in the equation system */ 33*c4762a1bSJed Brown PetscBool io; 34*c4762a1bSJed Brown }; 35*c4762a1bSJed Brown typedef pUserCtx* UserCtx; 36*c4762a1bSJed Brown 37*c4762a1bSJed Brown PetscErrorCode Initialize_AppContext(UserCtx *puser) 38*c4762a1bSJed Brown { 39*c4762a1bSJed Brown UserCtx user; 40*c4762a1bSJed Brown PetscErrorCode ierr; 41*c4762a1bSJed Brown 42*c4762a1bSJed Brown PetscFunctionBegin; 43*c4762a1bSJed Brown ierr = PetscNew(&user);CHKERRQ(ierr); 44*c4762a1bSJed Brown 45*c4762a1bSJed Brown ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Advection-reaction options","ex35.cxx"); 46*c4762a1bSJed Brown { 47*c4762a1bSJed Brown user->nvars = 2; 48*c4762a1bSJed Brown user->A = 1; 49*c4762a1bSJed Brown user->B = 3; 50*c4762a1bSJed Brown user->alpha = 0.02; 51*c4762a1bSJed Brown user->leftbc.u = 1; 52*c4762a1bSJed Brown user->rightbc.u = 1; 53*c4762a1bSJed Brown user->leftbc.v = 3; 54*c4762a1bSJed Brown user->rightbc.v = 3; 55*c4762a1bSJed Brown user->n = 10; 56*c4762a1bSJed Brown user->ntsteps = 10000; 57*c4762a1bSJed Brown user->io = PETSC_FALSE; 58*c4762a1bSJed Brown ierr = PetscOptionsReal("-A","Reaction rate","ex35.cxx",user->A,&user->A,NULL);CHKERRQ(ierr); 59*c4762a1bSJed Brown ierr = PetscOptionsReal("-B","Reaction rate","ex35.cxx",user->B,&user->B,NULL);CHKERRQ(ierr); 60*c4762a1bSJed Brown ierr = PetscOptionsReal("-alpha","Diffusion coefficient","ex35.cxx",user->alpha,&user->alpha,NULL);CHKERRQ(ierr); 61*c4762a1bSJed Brown ierr = PetscOptionsScalar("-uleft","Dirichlet boundary condition","ex35.cxx",user->leftbc.u,&user->leftbc.u,NULL);CHKERRQ(ierr); 62*c4762a1bSJed Brown ierr = PetscOptionsScalar("-uright","Dirichlet boundary condition","ex35.cxx",user->rightbc.u,&user->rightbc.u,NULL);CHKERRQ(ierr); 63*c4762a1bSJed Brown ierr = PetscOptionsScalar("-vleft","Dirichlet boundary condition","ex35.cxx",user->leftbc.v,&user->leftbc.v,NULL);CHKERRQ(ierr); 64*c4762a1bSJed Brown ierr = PetscOptionsScalar("-vright","Dirichlet boundary condition","ex35.cxx",user->rightbc.v,&user->rightbc.v,NULL);CHKERRQ(ierr); 65*c4762a1bSJed Brown ierr = PetscOptionsInt("-n","Number of 1-D elements","ex35.cxx",user->n,&user->n,NULL);CHKERRQ(ierr); 66*c4762a1bSJed Brown ierr = PetscOptionsInt("-ndt","Number of time steps","ex35.cxx",user->ntsteps,&user->ntsteps,NULL);CHKERRQ(ierr); 67*c4762a1bSJed Brown ierr = PetscOptionsBool("-io","Write the mesh and solution output to a file.","ex35.cxx",user->io,&user->io,NULL);CHKERRQ(ierr); 68*c4762a1bSJed Brown user->npts = user->n+1; 69*c4762a1bSJed Brown } 70*c4762a1bSJed Brown ierr = PetscOptionsEnd();CHKERRQ(ierr); 71*c4762a1bSJed Brown 72*c4762a1bSJed Brown *puser = user; 73*c4762a1bSJed Brown PetscFunctionReturn(0); 74*c4762a1bSJed Brown } 75*c4762a1bSJed Brown 76*c4762a1bSJed Brown PetscErrorCode Destroy_AppContext(UserCtx *user) 77*c4762a1bSJed Brown { 78*c4762a1bSJed Brown PetscErrorCode ierr; 79*c4762a1bSJed Brown 80*c4762a1bSJed Brown PetscFunctionBegin; 81*c4762a1bSJed Brown ierr = PetscFree(*user);CHKERRQ(ierr); 82*c4762a1bSJed Brown PetscFunctionReturn(0); 83*c4762a1bSJed Brown } 84*c4762a1bSJed Brown 85*c4762a1bSJed Brown static PetscErrorCode FormInitialSolution(TS,Vec,void*); 86*c4762a1bSJed Brown static PetscErrorCode FormRHSFunction(TS,PetscReal,Vec,Vec,void*); 87*c4762a1bSJed Brown static PetscErrorCode FormIFunction(TS,PetscReal,Vec,Vec,Vec,void*); 88*c4762a1bSJed Brown static PetscErrorCode FormIJacobian(TS,PetscReal,Vec,Vec,PetscReal,Mat,Mat,void*); 89*c4762a1bSJed Brown 90*c4762a1bSJed Brown /**************** 91*c4762a1bSJed Brown * * 92*c4762a1bSJed Brown * MAIN * 93*c4762a1bSJed Brown * * 94*c4762a1bSJed Brown ****************/ 95*c4762a1bSJed Brown int main(int argc,char **argv) 96*c4762a1bSJed Brown { 97*c4762a1bSJed Brown TS ts; /* nonlinear solver */ 98*c4762a1bSJed Brown Vec X; /* solution, residual vectors */ 99*c4762a1bSJed Brown Mat J; /* Jacobian matrix */ 100*c4762a1bSJed Brown PetscInt steps,mx; 101*c4762a1bSJed Brown PetscErrorCode ierr; 102*c4762a1bSJed Brown PetscReal hx,dt,ftime; 103*c4762a1bSJed Brown UserCtx user; /* user-defined work context */ 104*c4762a1bSJed Brown TSConvergedReason reason; 105*c4762a1bSJed Brown 106*c4762a1bSJed Brown DM dm; 107*c4762a1bSJed Brown const char *fields[2] = {"U","V"}; 108*c4762a1bSJed Brown 109*c4762a1bSJed Brown ierr = PetscInitialize(&argc,&argv,(char *)0,help);if (ierr) return ierr; 110*c4762a1bSJed Brown 111*c4762a1bSJed Brown /* Initialize the user context struct */ 112*c4762a1bSJed Brown ierr = Initialize_AppContext(&user);CHKERRQ(ierr); 113*c4762a1bSJed Brown 114*c4762a1bSJed Brown /* Fill in the user defined work context: */ 115*c4762a1bSJed Brown ierr = DMMoabCreateBoxMesh(PETSC_COMM_WORLD, 1, PETSC_FALSE, NULL, user->n, 1, &dm);CHKERRQ(ierr); 116*c4762a1bSJed Brown ierr = DMMoabSetFieldNames(dm, user->nvars, fields);CHKERRQ(ierr); 117*c4762a1bSJed Brown ierr = DMMoabSetBlockSize(dm, user->nvars);CHKERRQ(ierr); 118*c4762a1bSJed Brown ierr = DMSetFromOptions(dm);CHKERRQ(ierr); 119*c4762a1bSJed Brown 120*c4762a1bSJed Brown /* SetUp the data structures for DMMOAB */ 121*c4762a1bSJed Brown ierr = DMSetUp(dm);CHKERRQ(ierr); 122*c4762a1bSJed Brown 123*c4762a1bSJed Brown /* Create timestepping solver context */ 124*c4762a1bSJed Brown ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); 125*c4762a1bSJed Brown ierr = TSSetDM(ts, dm);CHKERRQ(ierr); 126*c4762a1bSJed Brown ierr = TSSetType(ts,TSARKIMEX);CHKERRQ(ierr); 127*c4762a1bSJed Brown ierr = TSSetEquationType(ts,TS_EQ_DAE_IMPLICIT_INDEX1);CHKERRQ(ierr); 128*c4762a1bSJed Brown ierr = DMSetMatType(dm,MATBAIJ);CHKERRQ(ierr); 129*c4762a1bSJed Brown ierr = DMCreateMatrix(dm,&J);CHKERRQ(ierr); 130*c4762a1bSJed Brown 131*c4762a1bSJed Brown ierr = TSSetRHSFunction(ts,NULL,FormRHSFunction,user);CHKERRQ(ierr); 132*c4762a1bSJed Brown ierr = TSSetIFunction(ts,NULL,FormIFunction,user);CHKERRQ(ierr); 133*c4762a1bSJed Brown ierr = TSSetIJacobian(ts,J,J,FormIJacobian,user);CHKERRQ(ierr); 134*c4762a1bSJed Brown 135*c4762a1bSJed Brown ftime = 10.0; 136*c4762a1bSJed Brown ierr = TSSetMaxSteps(ts,user->ntsteps);CHKERRQ(ierr); 137*c4762a1bSJed Brown ierr = TSSetMaxTime(ts,ftime);CHKERRQ(ierr); 138*c4762a1bSJed Brown ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); 139*c4762a1bSJed Brown 140*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 141*c4762a1bSJed Brown Create the solution vector and set the initial conditions 142*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 143*c4762a1bSJed Brown ierr = DMCreateGlobalVector(dm, &X);CHKERRQ(ierr); 144*c4762a1bSJed Brown 145*c4762a1bSJed Brown ierr = FormInitialSolution(ts,X,user);CHKERRQ(ierr); 146*c4762a1bSJed Brown ierr = TSSetSolution(ts,X);CHKERRQ(ierr); 147*c4762a1bSJed Brown ierr = VecGetSize(X,&mx);CHKERRQ(ierr); 148*c4762a1bSJed Brown hx = 1.0/(PetscReal)(mx/2-1); 149*c4762a1bSJed Brown dt = 0.4 * PetscSqr(hx) / user->alpha; /* Diffusive stability limit */ 150*c4762a1bSJed Brown ierr = TSSetTimeStep(ts,dt);CHKERRQ(ierr); 151*c4762a1bSJed Brown 152*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 153*c4762a1bSJed Brown Set runtime options 154*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 155*c4762a1bSJed Brown ierr = TSSetFromOptions(ts);CHKERRQ(ierr); 156*c4762a1bSJed Brown 157*c4762a1bSJed Brown /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 158*c4762a1bSJed Brown Solve nonlinear system 159*c4762a1bSJed Brown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 160*c4762a1bSJed Brown ierr = TSSolve(ts,X);CHKERRQ(ierr); 161*c4762a1bSJed Brown ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); 162*c4762a1bSJed Brown ierr = TSGetStepNumber(ts,&steps);CHKERRQ(ierr); 163*c4762a1bSJed Brown ierr = TSGetConvergedReason(ts,&reason);CHKERRQ(ierr); 164*c4762a1bSJed Brown ierr = PetscPrintf(PETSC_COMM_WORLD,"%s at time %g after %D steps\n",TSConvergedReasons[reason],ftime,steps);CHKERRQ(ierr); 165*c4762a1bSJed Brown 166*c4762a1bSJed Brown if (user->io) { 167*c4762a1bSJed Brown /* Print the numerical solution to screen and then dump to file */ 168*c4762a1bSJed Brown ierr = VecView(X,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 169*c4762a1bSJed Brown 170*c4762a1bSJed Brown /* Write out the solution along with the mesh */ 171*c4762a1bSJed Brown ierr = DMMoabSetGlobalFieldVector(dm, X);CHKERRQ(ierr); 172*c4762a1bSJed Brown #ifdef MOAB_HAVE_HDF5 173*c4762a1bSJed Brown ierr = DMMoabOutput(dm, "ex35.h5m", "");CHKERRQ(ierr); 174*c4762a1bSJed Brown #else 175*c4762a1bSJed Brown /* MOAB does not support true parallel writers that aren't HDF5 based 176*c4762a1bSJed Brown And so if you are using VTK as the output format in parallel, 177*c4762a1bSJed Brown the data could be jumbled due to the order in which the processors 178*c4762a1bSJed Brown write out their parts of the mesh and solution tags 179*c4762a1bSJed Brown */ 180*c4762a1bSJed Brown ierr = DMMoabOutput(dm, "ex35.vtk", "");CHKERRQ(ierr); 181*c4762a1bSJed Brown #endif 182*c4762a1bSJed Brown } 183*c4762a1bSJed Brown 184*c4762a1bSJed Brown /* Free work space. 185*c4762a1bSJed Brown Free all PETSc related resources: */ 186*c4762a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 187*c4762a1bSJed Brown ierr = VecDestroy(&X);CHKERRQ(ierr); 188*c4762a1bSJed Brown ierr = TSDestroy(&ts);CHKERRQ(ierr); 189*c4762a1bSJed Brown ierr = DMDestroy(&dm);CHKERRQ(ierr); 190*c4762a1bSJed Brown 191*c4762a1bSJed Brown /* Free all MOAB related resources: */ 192*c4762a1bSJed Brown ierr = Destroy_AppContext(&user);CHKERRQ(ierr); 193*c4762a1bSJed Brown ierr = PetscFinalize(); 194*c4762a1bSJed Brown return ierr; 195*c4762a1bSJed Brown } 196*c4762a1bSJed Brown 197*c4762a1bSJed Brown 198*c4762a1bSJed Brown /* 199*c4762a1bSJed Brown IJacobian - Compute IJacobian = dF/dU + a dF/dUdot 200*c4762a1bSJed Brown */ 201*c4762a1bSJed Brown PetscErrorCode FormIJacobian(TS ts,PetscReal t,Vec X,Vec Xdot,PetscReal a,Mat J,Mat Jpre,void *ptr) 202*c4762a1bSJed Brown { 203*c4762a1bSJed Brown UserCtx user = (UserCtx)ptr; 204*c4762a1bSJed Brown PetscErrorCode ierr; 205*c4762a1bSJed Brown PetscInt dof; 206*c4762a1bSJed Brown PetscReal hx; 207*c4762a1bSJed Brown DM dm; 208*c4762a1bSJed Brown const moab::Range *vlocal; 209*c4762a1bSJed Brown PetscBool vonboundary; 210*c4762a1bSJed Brown 211*c4762a1bSJed Brown PetscFunctionBegin; 212*c4762a1bSJed Brown ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 213*c4762a1bSJed Brown 214*c4762a1bSJed Brown /* get the essential MOAB mesh related quantities needed for FEM assembly */ 215*c4762a1bSJed Brown ierr = DMMoabGetLocalVertices(dm, &vlocal, NULL);CHKERRQ(ierr); 216*c4762a1bSJed Brown 217*c4762a1bSJed Brown /* compute local element sizes - structured grid */ 218*c4762a1bSJed Brown hx = 1.0/user->n; 219*c4762a1bSJed Brown 220*c4762a1bSJed Brown /* Compute function over the locally owned part of the grid 221*c4762a1bSJed Brown Assemble the operator by looping over edges and computing 222*c4762a1bSJed Brown contribution for each vertex dof */ 223*c4762a1bSJed Brown for(moab::Range::iterator iter = vlocal->begin(); iter != vlocal->end(); iter++) { 224*c4762a1bSJed Brown const moab::EntityHandle vhandle = *iter; 225*c4762a1bSJed Brown 226*c4762a1bSJed Brown ierr = DMMoabGetDofsBlocked(dm, 1, &vhandle, &dof);CHKERRQ(ierr); 227*c4762a1bSJed Brown 228*c4762a1bSJed Brown /* check if vertex is on the boundary */ 229*c4762a1bSJed Brown ierr = DMMoabIsEntityOnBoundary(dm,vhandle,&vonboundary);CHKERRQ(ierr); 230*c4762a1bSJed Brown 231*c4762a1bSJed Brown if (vonboundary) { 232*c4762a1bSJed Brown const PetscScalar bcvals[2][2] = {{hx,0},{0,hx}}; 233*c4762a1bSJed Brown ierr = MatSetValuesBlocked(Jpre,1,&dof,1,&dof,&bcvals[0][0],INSERT_VALUES);CHKERRQ(ierr); 234*c4762a1bSJed Brown } 235*c4762a1bSJed Brown else { 236*c4762a1bSJed Brown const PetscInt row = dof,col[] = {dof-1,dof,dof+1}; 237*c4762a1bSJed Brown const PetscScalar dxxL = -user->alpha/hx,dxx0 = 2.*user->alpha/hx,dxxR = -user->alpha/hx; 238*c4762a1bSJed Brown const PetscScalar vals[2][3][2] = {{{dxxL,0},{a *hx+dxx0,0},{dxxR,0}}, 239*c4762a1bSJed Brown {{0,dxxL},{0,a*hx+dxx0},{0,dxxR}}}; 240*c4762a1bSJed Brown ierr = MatSetValuesBlocked(Jpre,1,&row,3,col,&vals[0][0][0],INSERT_VALUES);CHKERRQ(ierr); 241*c4762a1bSJed Brown } 242*c4762a1bSJed Brown } 243*c4762a1bSJed Brown 244*c4762a1bSJed Brown ierr = MatAssemblyBegin(Jpre,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 245*c4762a1bSJed Brown ierr = MatAssemblyEnd(Jpre,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 246*c4762a1bSJed Brown if (J != Jpre) { 247*c4762a1bSJed Brown ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 248*c4762a1bSJed Brown ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 249*c4762a1bSJed Brown } 250*c4762a1bSJed Brown PetscFunctionReturn(0); 251*c4762a1bSJed Brown } 252*c4762a1bSJed Brown 253*c4762a1bSJed Brown 254*c4762a1bSJed Brown static PetscErrorCode FormRHSFunction(TS ts,PetscReal t,Vec X,Vec F,void *ptr) 255*c4762a1bSJed Brown { 256*c4762a1bSJed Brown UserCtx user = (UserCtx)ptr; 257*c4762a1bSJed Brown DM dm; 258*c4762a1bSJed Brown PetscReal hx; 259*c4762a1bSJed Brown const Field *x; 260*c4762a1bSJed Brown Field *f; 261*c4762a1bSJed Brown PetscInt dof; 262*c4762a1bSJed Brown const moab::Range *ownedvtx; 263*c4762a1bSJed Brown PetscErrorCode ierr; 264*c4762a1bSJed Brown 265*c4762a1bSJed Brown PetscFunctionBegin; 266*c4762a1bSJed Brown hx = 1.0/user->n; 267*c4762a1bSJed Brown ierr = TSGetDM(ts,&dm);CHKERRQ(ierr); 268*c4762a1bSJed Brown 269*c4762a1bSJed Brown /* Get pointers to vector data */ 270*c4762a1bSJed Brown ierr = VecSet(F,0.0);CHKERRQ(ierr); 271*c4762a1bSJed Brown 272*c4762a1bSJed Brown ierr = DMMoabVecGetArrayRead(dm, X, &x);CHKERRQ(ierr); 273*c4762a1bSJed Brown ierr = DMMoabVecGetArray(dm, F, &f);CHKERRQ(ierr); 274*c4762a1bSJed Brown 275*c4762a1bSJed Brown ierr = DMMoabGetLocalVertices(dm, &ownedvtx, NULL);CHKERRQ(ierr); 276*c4762a1bSJed Brown 277*c4762a1bSJed Brown /* Compute function over the locally owned part of the grid */ 278*c4762a1bSJed Brown for(moab::Range::iterator iter = ownedvtx->begin(); iter != ownedvtx->end(); iter++) { 279*c4762a1bSJed Brown const moab::EntityHandle vhandle = *iter; 280*c4762a1bSJed Brown ierr = DMMoabGetDofsBlockedLocal(dm, 1, &vhandle, &dof);CHKERRQ(ierr); 281*c4762a1bSJed Brown 282*c4762a1bSJed Brown PetscScalar u = x[dof].u,v = x[dof].v; 283*c4762a1bSJed Brown f[dof].u = hx*(user->A + u*u*v - (user->B+1)*u); 284*c4762a1bSJed Brown f[dof].v = hx*(user->B*u - u*u*v); 285*c4762a1bSJed Brown } 286*c4762a1bSJed Brown 287*c4762a1bSJed Brown /* Restore vectors */ 288*c4762a1bSJed Brown ierr = DMMoabVecRestoreArrayRead(dm, X, &x);CHKERRQ(ierr); 289*c4762a1bSJed Brown ierr = DMMoabVecRestoreArray(dm, F, &f);CHKERRQ(ierr); 290*c4762a1bSJed Brown PetscFunctionReturn(0); 291*c4762a1bSJed Brown } 292*c4762a1bSJed Brown 293*c4762a1bSJed Brown 294*c4762a1bSJed Brown static PetscErrorCode FormIFunction(TS ts,PetscReal t,Vec X,Vec Xdot,Vec F,void *ctx) 295*c4762a1bSJed Brown { 296*c4762a1bSJed Brown UserCtx user = (UserCtx)ctx; 297*c4762a1bSJed Brown DM dm; 298*c4762a1bSJed Brown Field *x,*xdot,*f; 299*c4762a1bSJed Brown PetscReal hx; 300*c4762a1bSJed Brown Vec Xloc; 301*c4762a1bSJed Brown PetscErrorCode ierr; 302*c4762a1bSJed Brown PetscInt i,bcindx; 303*c4762a1bSJed Brown PetscBool elem_on_boundary; 304*c4762a1bSJed Brown const moab::Range *vlocal; 305*c4762a1bSJed Brown 306*c4762a1bSJed Brown PetscFunctionBegin; 307*c4762a1bSJed Brown hx = 1.0/user->n; 308*c4762a1bSJed Brown ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 309*c4762a1bSJed Brown 310*c4762a1bSJed Brown /* get the essential MOAB mesh related quantities needed for FEM assembly */ 311*c4762a1bSJed Brown ierr = DMMoabGetLocalVertices(dm, &vlocal, NULL);CHKERRQ(ierr); 312*c4762a1bSJed Brown 313*c4762a1bSJed Brown /* reset the residual vector */ 314*c4762a1bSJed Brown ierr = VecSet(F,0.0);CHKERRQ(ierr); 315*c4762a1bSJed Brown 316*c4762a1bSJed Brown ierr = DMGetLocalVector(dm,&Xloc);CHKERRQ(ierr); 317*c4762a1bSJed Brown ierr = DMGlobalToLocalBegin(dm,X,INSERT_VALUES,Xloc);CHKERRQ(ierr); 318*c4762a1bSJed Brown ierr = DMGlobalToLocalEnd(dm,X,INSERT_VALUES,Xloc);CHKERRQ(ierr); 319*c4762a1bSJed Brown 320*c4762a1bSJed Brown /* get the local representation of the arrays from Vectors */ 321*c4762a1bSJed Brown ierr = DMMoabVecGetArrayRead(dm, Xloc, &x);CHKERRQ(ierr); 322*c4762a1bSJed Brown ierr = DMMoabVecGetArrayRead(dm, Xdot, &xdot);CHKERRQ(ierr); 323*c4762a1bSJed Brown ierr = DMMoabVecGetArray(dm, F, &f);CHKERRQ(ierr); 324*c4762a1bSJed Brown 325*c4762a1bSJed Brown /* loop over local elements */ 326*c4762a1bSJed Brown for(moab::Range::iterator iter = vlocal->begin(); iter != vlocal->end(); iter++) { 327*c4762a1bSJed Brown const moab::EntityHandle vhandle = *iter; 328*c4762a1bSJed Brown 329*c4762a1bSJed Brown ierr = DMMoabGetDofsBlockedLocal(dm,1,&vhandle,&i);CHKERRQ(ierr); 330*c4762a1bSJed Brown 331*c4762a1bSJed Brown /* check if vertex is on the boundary */ 332*c4762a1bSJed Brown ierr = DMMoabIsEntityOnBoundary(dm,vhandle,&elem_on_boundary);CHKERRQ(ierr); 333*c4762a1bSJed Brown 334*c4762a1bSJed Brown if (elem_on_boundary) { 335*c4762a1bSJed Brown ierr = DMMoabGetDofsBlocked(dm, 1, &vhandle, &bcindx);CHKERRQ(ierr); 336*c4762a1bSJed Brown if (bcindx == 0) { /* Apply left BC */ 337*c4762a1bSJed Brown f[i].u = hx * (x[i].u - user->leftbc.u); 338*c4762a1bSJed Brown f[i].v = hx * (x[i].v - user->leftbc.v); 339*c4762a1bSJed Brown } else { /* Apply right BC */ 340*c4762a1bSJed Brown f[i].u = hx * (x[i].u - user->rightbc.u); 341*c4762a1bSJed Brown f[i].v = hx * (x[i].v - user->rightbc.v); 342*c4762a1bSJed Brown } 343*c4762a1bSJed Brown } 344*c4762a1bSJed Brown else { 345*c4762a1bSJed Brown f[i].u = hx * xdot[i].u - user->alpha * (x[i-1].u - 2.*x[i].u + x[i+1].u) / hx; 346*c4762a1bSJed Brown f[i].v = hx * xdot[i].v - user->alpha * (x[i-1].v - 2.*x[i].v + x[i+1].v) / hx; 347*c4762a1bSJed Brown } 348*c4762a1bSJed Brown } 349*c4762a1bSJed Brown 350*c4762a1bSJed Brown /* Restore data */ 351*c4762a1bSJed Brown ierr = DMMoabVecRestoreArrayRead(dm, Xloc, &x);CHKERRQ(ierr); 352*c4762a1bSJed Brown ierr = DMMoabVecRestoreArrayRead(dm, Xdot, &xdot);CHKERRQ(ierr); 353*c4762a1bSJed Brown ierr = DMMoabVecRestoreArray(dm, F, &f);CHKERRQ(ierr); 354*c4762a1bSJed Brown ierr = DMRestoreLocalVector(dm, &Xloc);CHKERRQ(ierr); 355*c4762a1bSJed Brown PetscFunctionReturn(0); 356*c4762a1bSJed Brown } 357*c4762a1bSJed Brown 358*c4762a1bSJed Brown 359*c4762a1bSJed Brown PetscErrorCode FormInitialSolution(TS ts,Vec X,void *ctx) 360*c4762a1bSJed Brown { 361*c4762a1bSJed Brown UserCtx user = (UserCtx)ctx; 362*c4762a1bSJed Brown PetscReal vpos[3]; 363*c4762a1bSJed Brown DM dm; 364*c4762a1bSJed Brown Field *x; 365*c4762a1bSJed Brown PetscErrorCode ierr; 366*c4762a1bSJed Brown const moab::Range *vowned; 367*c4762a1bSJed Brown PetscInt dof; 368*c4762a1bSJed Brown moab::Range::iterator iter; 369*c4762a1bSJed Brown 370*c4762a1bSJed Brown PetscFunctionBegin; 371*c4762a1bSJed Brown ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 372*c4762a1bSJed Brown 373*c4762a1bSJed Brown /* get the essential MOAB mesh related quantities needed for FEM assembly */ 374*c4762a1bSJed Brown ierr = DMMoabGetLocalVertices(dm, &vowned, NULL);CHKERRQ(ierr); 375*c4762a1bSJed Brown 376*c4762a1bSJed Brown ierr = VecSet(X, 0.0);CHKERRQ(ierr); 377*c4762a1bSJed Brown 378*c4762a1bSJed Brown /* Get pointers to vector data */ 379*c4762a1bSJed Brown ierr = DMMoabVecGetArray(dm, X, &x);CHKERRQ(ierr); 380*c4762a1bSJed Brown 381*c4762a1bSJed Brown /* Compute function over the locally owned part of the grid */ 382*c4762a1bSJed Brown for(moab::Range::iterator iter = vowned->begin(); iter != vowned->end(); iter++) { 383*c4762a1bSJed Brown const moab::EntityHandle vhandle = *iter; 384*c4762a1bSJed Brown ierr = DMMoabGetDofsBlockedLocal(dm, 1, &vhandle, &dof);CHKERRQ(ierr); 385*c4762a1bSJed Brown 386*c4762a1bSJed Brown /* compute the mid-point of the element and use a 1-point lumped quadrature */ 387*c4762a1bSJed Brown ierr = DMMoabGetVertexCoordinates(dm,1,&vhandle,vpos);CHKERRQ(ierr); 388*c4762a1bSJed Brown 389*c4762a1bSJed Brown PetscReal xi = vpos[0]; 390*c4762a1bSJed Brown x[dof].u = user->leftbc.u*(1.-xi) + user->rightbc.u*xi + PetscSinReal(2.*PETSC_PI*xi); 391*c4762a1bSJed Brown x[dof].v = user->leftbc.v*(1.-xi) + user->rightbc.v*xi; 392*c4762a1bSJed Brown } 393*c4762a1bSJed Brown 394*c4762a1bSJed Brown /* Restore vectors */ 395*c4762a1bSJed Brown ierr = DMMoabVecRestoreArray(dm, X, &x);CHKERRQ(ierr); 396*c4762a1bSJed Brown PetscFunctionReturn(0); 397*c4762a1bSJed Brown } 398*c4762a1bSJed Brown 399*c4762a1bSJed Brown /*TEST 400*c4762a1bSJed Brown 401*c4762a1bSJed Brown build: 402*c4762a1bSJed Brown requires: moab 403*c4762a1bSJed Brown 404*c4762a1bSJed Brown test: 405*c4762a1bSJed Brown args: -n 20 -ts_type rosw -ts_rosw_type 2p -ts_dt 5e-2 -ts_adapt_type none 406*c4762a1bSJed Brown 407*c4762a1bSJed Brown test: 408*c4762a1bSJed Brown suffix: 2 409*c4762a1bSJed Brown nsize: 2 410*c4762a1bSJed Brown args: -n 50 -ts_type glee -ts_adapt_type none -ts_dt 0.1 -io 411*c4762a1bSJed Brown TODO: 412*c4762a1bSJed Brown 413*c4762a1bSJed Brown TEST*/ 414