PetscErrorCode SetupDiscretization(DM dm, AppCtx *user) { DM cdm = dm; const PetscInt dim = user->dim; PetscFE fe[2]; PetscQuadrature q; Parameter *param; MPI_Comm comm; PetscErrorCode ierr; PetscFunctionBeginUser; /* Create finite element */ ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); ierr = PetscFECreateDefault(comm, dim, dim, user->simplex, "vel_", PETSC_DEFAULT, &fe[0]);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) fe[0], "velocity");CHKERRQ(ierr); ierr = PetscFEGetQuadrature(fe[0], &q);CHKERRQ(ierr); ierr = PetscFECreateDefault(comm, dim, 1, user->simplex, "pres_", PETSC_DEFAULT, &fe[1]);CHKERRQ(ierr); ierr = PetscFESetQuadrature(fe[1], q);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) fe[1], "pressure");CHKERRQ(ierr); /* Set discretization and boundary conditions for each mesh */ ierr = DMSetField(dm, 0, NULL, (PetscObject) fe[0]);CHKERRQ(ierr); ierr = DMSetField(dm, 1, NULL, (PetscObject) fe[1]);CHKERRQ(ierr); ierr = DMCreateDS(dm);CHKERRQ(ierr); ierr = SetupProblem(dm, user);CHKERRQ(ierr); ierr = PetscBagGetData(user->bag, (void **) ¶m);CHKERRQ(ierr); while (cdm) { ierr = DMCopyDisc(dm, cdm);CHKERRQ(ierr); ierr = DMPlexCreateBasisRotation(cdm, param->alpha, 0.0, 0.0);CHKERRQ(ierr); ierr = DMGetCoarseDM(cdm, &cdm);CHKERRQ(ierr); } ierr = PetscFEDestroy(&fe[0]);CHKERRQ(ierr); ierr = PetscFEDestroy(&fe[1]);CHKERRQ(ierr); PetscFunctionReturn(0); }
int DoOutput(DMMG *dmmg, int n_plot) /*---------------------------------------------------------------------*/ { AppCtx *user = (AppCtx*)dmmg[0]->user; Parameter *param; int ierr; char filename[FNAME_LENGTH]; PetscViewer viewer; DA da; ierr = PetscBagGetData(user->bag,(void**)¶m); CHKERRQ(ierr); da = DMMGGetDA(dmmg); if (param->output_to_file) { /* send output to binary file */ /* generate filename for time t */ sprintf(filename,"%s_%3.3d",param->output_filename,n_plot); ierr = PetscPrintf(PETSC_COMM_WORLD,"Generating output: time t = %g, ",param->t); ierr = PetscPrintf(PETSC_COMM_WORLD,"file = \"%s\"\n",filename); /* make output files */ ierr = PetscViewerBinaryMatlabOpen(PETSC_COMM_WORLD,filename,&viewer); CHKERRQ(ierr); ierr = PetscViewerBinaryMatlabOutputBag(viewer,"par",user->bag); CHKERRQ(ierr); ierr = DASetFieldNames("u","v","phi",da); CHKERRQ(ierr); ierr = PetscViewerBinaryMatlabOutputVecDA(viewer,"field",DMMGGetx(dmmg),da); CHKERRQ(ierr); ierr = PetscViewerBinaryMatlabDestroy(viewer); CHKERRQ(ierr); } return 0; }
PetscErrorCode SetupProblem(DM dm, AppCtx *user) { PetscDS prob; Parameter *ctx; PetscInt id; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = DMGetDS(dm, &prob);CHKERRQ(ierr); ierr = PetscDSSetResidual(prob, 0, NULL, f1_u);CHKERRQ(ierr); ierr = PetscDSSetResidual(prob, 1, f0_p, NULL);CHKERRQ(ierr); ierr = PetscDSSetBdResidual(prob, 0, f0_bd_u, NULL);CHKERRQ(ierr); ierr = PetscDSSetJacobian(prob, 0, 0, NULL, NULL, NULL, g3_uu);CHKERRQ(ierr); ierr = PetscDSSetJacobian(prob, 0, 1, NULL, NULL, g2_up, NULL);CHKERRQ(ierr); ierr = PetscDSSetJacobian(prob, 1, 0, NULL, g1_pu, NULL, NULL);CHKERRQ(ierr); /* Setup constants */ { Parameter *param; PetscScalar constants[4]; ierr = PetscBagGetData(user->bag, (void **) ¶m);CHKERRQ(ierr); constants[0] = param->Delta; constants[1] = param->nu; constants[2] = param->u_0; constants[3] = param->alpha; ierr = PetscDSSetConstants(prob, 4, constants);CHKERRQ(ierr); } /* Setup Boundary Conditions */ ierr = PetscBagGetData(user->bag, (void **) &ctx);CHKERRQ(ierr); id = 3; ierr = PetscDSAddBoundary(prob, DM_BC_ESSENTIAL, "top wall", "marker", 0, 0, NULL, (void (*)(void)) wall_velocity, 1, &id, ctx);CHKERRQ(ierr); id = 1; ierr = PetscDSAddBoundary(prob, DM_BC_ESSENTIAL, "bottom wall", "marker", 0, 0, NULL, (void (*)(void)) wall_velocity, 1, &id, ctx);CHKERRQ(ierr); id = 2; ierr = PetscDSAddBoundary(prob, DM_BC_NATURAL, "right wall", "marker", 0, 0, NULL, (void (*)(void)) NULL, 1, &id, ctx);CHKERRQ(ierr); /* Setup exact solution */ user->exactFuncs[0] = quadratic_u; user->exactFuncs[1] = linear_p; ierr = PetscDSSetExactSolution(prob, 0, user->exactFuncs[0], ctx);CHKERRQ(ierr); ierr = PetscDSSetExactSolution(prob, 1, user->exactFuncs[1], ctx);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc, char **argv) { SNES snes; /* nonlinear solver */ DM dm; /* problem definition */ Vec u, r; /* solution and residual */ AppCtx user; /* user-defined work context */ PetscErrorCode ierr; ierr = PetscInitialize(&argc, &argv, NULL,help);if (ierr) return ierr; ierr = ProcessOptions(PETSC_COMM_WORLD, &user);CHKERRQ(ierr); ierr = PetscBagCreate(PETSC_COMM_WORLD, sizeof(Parameter), &user.bag);CHKERRQ(ierr); ierr = SetupParameters(&user);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD, &snes);CHKERRQ(ierr); ierr = CreateMesh(PETSC_COMM_WORLD, &user, &dm);CHKERRQ(ierr); ierr = SNESSetDM(snes, dm);CHKERRQ(ierr); ierr = DMSetApplicationContext(dm, &user);CHKERRQ(ierr); /* Setup problem */ ierr = PetscMalloc(2 * sizeof(void (*)(const PetscReal[], PetscScalar *, void *)), &user.exactFuncs);CHKERRQ(ierr); ierr = SetupDiscretization(dm, &user);CHKERRQ(ierr); ierr = DMPlexCreateClosureIndex(dm, NULL);CHKERRQ(ierr); ierr = DMCreateGlobalVector(dm, &u);CHKERRQ(ierr); ierr = VecDuplicate(u, &r);CHKERRQ(ierr); ierr = DMPlexSetSNESLocalFEM(dm,&user,&user,&user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); { Parameter *param; void *ctxs[2]; ierr = PetscBagGetData(user.bag, (void **) ¶m);CHKERRQ(ierr); ctxs[0] = ctxs[1] = param; ierr = DMProjectFunction(dm, 0.0, user.exactFuncs, ctxs, INSERT_ALL_VALUES, u);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) u, "Exact Solution");CHKERRQ(ierr); ierr = VecViewFromOptions(u, NULL, "-exact_vec_view");CHKERRQ(ierr); } ierr = DMSNESCheckFromOptions(snes, u, NULL, NULL);CHKERRQ(ierr); ierr = VecSet(u, 0.0);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) u, "Solution");CHKERRQ(ierr); ierr = SNESSolve(snes, NULL, u);CHKERRQ(ierr); ierr = VecViewFromOptions(u, NULL, "-sol_vec_view");CHKERRQ(ierr); ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = PetscFree(user.exactFuncs);CHKERRQ(ierr); ierr = DMDestroy(&dm);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = PetscBagDestroy(&user.bag);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) { PetscInt dim = user->dim; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = DMPlexCreateBoxMesh(comm, dim, user->simplex, user->cells, NULL, NULL, NULL, PETSC_TRUE, dm);CHKERRQ(ierr); { Parameter *param; Vec coordinates; PetscScalar *coords; PetscReal alpha; PetscInt cdim, N, bs, i; ierr = DMGetCoordinateDim(*dm, &cdim);CHKERRQ(ierr); ierr = DMGetCoordinates(*dm, &coordinates);CHKERRQ(ierr); ierr = VecGetLocalSize(coordinates, &N);CHKERRQ(ierr); ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); if (bs != cdim) SETERRQ2(comm, PETSC_ERR_ARG_WRONG, "Invalid coordinate blocksize %D != embedding dimension %D", bs, cdim); ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); ierr = PetscBagGetData(user->bag, (void **) ¶m);CHKERRQ(ierr); alpha = param->alpha; for (i = 0; i < N; i += cdim) { PetscScalar x = coords[i+0]; PetscScalar y = coords[i+1]; coords[i+0] = PetscCosReal(alpha)*x - PetscSinReal(alpha)*y; coords[i+1] = PetscSinReal(alpha)*x + PetscCosReal(alpha)*y; } ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); ierr = DMSetCoordinates(*dm, coordinates);CHKERRQ(ierr); } { DM pdm = NULL; PetscPartitioner part; ierr = DMPlexGetPartitioner(*dm, &part);CHKERRQ(ierr); ierr = PetscPartitionerSetFromOptions(part);CHKERRQ(ierr); ierr = DMPlexDistribute(*dm, 0, NULL, &pdm);CHKERRQ(ierr); if (pdm) { ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = pdm; } } ierr = DMSetFromOptions(*dm);CHKERRQ(ierr); ierr = DMViewFromOptions(*dm, NULL, "-dm_view");CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode SetupParameters(AppCtx *user) { PetscBag bag; Parameter *p; PetscErrorCode ierr; PetscFunctionBeginUser; /* setup PETSc parameter bag */ ierr = PetscBagGetData(user->bag, (void **) &p);CHKERRQ(ierr); ierr = PetscBagSetName(user->bag, "par", "Poiseuille flow parameters");CHKERRQ(ierr); bag = user->bag; ierr = PetscBagRegisterReal(bag, &p->Delta, 1.0, "Delta", "Pressure drop per unit length");CHKERRQ(ierr); ierr = PetscBagRegisterReal(bag, &p->nu, 1.0, "nu", "Kinematic viscosity");CHKERRQ(ierr); ierr = PetscBagRegisterReal(bag, &p->u_0, 0.0, "u_0", "Tangential velocity at the wall");CHKERRQ(ierr); ierr = PetscBagRegisterReal(bag, &p->alpha, 0.0, "alpha", "Angle of pipe wall to x-axis");CHKERRQ(ierr); PetscFunctionReturn(0); }
int Initialize(DMMG *dmmg) /* ------------------------------------------------------------------- */ { AppCtx *user = (AppCtx*)dmmg[0]->user; Parameter *param; DA da; PetscReal PI = 3.14159265358979323846; PetscReal sigma,xc,zc; PetscReal dx=user->grid->dx,dz=user->grid->dz; int i,j,ierr,is,js,im,jm; Field **x; ierr = PetscBagGetData(user->bag,(void**)¶m); CHKERRQ(ierr); sigma=param->sigma; xc=param->xctr; zc=param->zctr; /* Get the DA and grid */ da = (DA)(dmmg[0]->dm); ierr = DAGetCorners(da,&is,&js,PETSC_NULL,&im,&jm,PETSC_NULL); CHKERRQ(ierr); ierr = DAVecGetArray(da,user->Xold,(void**)&x); CHKERRQ(ierr); for (j=js; j<js+jm; j++) { for (i=is; i<is+im; i++) { if (param->flow_type == SHEAR_CELL) { x[j][i].u = -sin(PI*i*dx)*cos(PI*j*dz)/dx; x[j][i].w = sin(PI*j*dz)*cos(PI*i*dx)/dz; } else { x[j][i].u = 0.0; x[j][i].w = -1.0/dz; } x[j][i].phi = 100*exp(-0.5*((i*dx-xc)*(i*dx-xc)+(j*dz-zc)*(j*dz-zc))/sigma/sigma); } } /* restore the grid to it's vector */ ierr = DAVecRestoreArray(da,user->Xold,(void**)&x); CHKERRQ(ierr); ierr = VecCopy(user->Xold, DMMGGetx(dmmg)); CHKERRQ(ierr); return 0; }
int DoVerification(DMMG *dmmg, AppCtx *user) /*---------------------------------------------------------------------*/ { Parameter *param; PetscReal t1,t2,t3,norms[3]; int ierr; ierr = PetscBagGetData(user->bag,(void**)¶m); CHKERRQ(ierr); ierr = CalcSolnNorms(dmmg, norms); CHKERRQ(ierr); t1 = (norms[0]-param->L1)/param->L1*100.0; t2 = (norms[1]-param->L2)/param->L2*100.0; t3 = (norms[2]-param->LINF)/param->LINF*100.0; if ((fabs(t1)>1.0) || (fabs(t2)>1.0) || (fabs(t3)>5.0)) { param->verify_result = 1; } PetscPrintf(PETSC_COMM_WORLD," Step: %d, Soln norms: %g (L1) %g (L2) %g (LINF)\n",param->n,norms[0],norms[1],norms[2]); PetscPrintf(PETSC_COMM_WORLD," Step: %d, Soln norms %%err: %5.2g (L1) %5.2g (L2) %5.2g (LINF)\n",param->n,t1,t2,t3); return 0; }
/* uses analytic velocity fields */ PetscErrorCode InterpVelocity2D(void *f, PetscReal ij_real[], PetscInt numComp, PetscInt components[], PetscReal velocity[], void *ctx) /*---------------------------------------------------------------------*/ { AppCtx *user = (AppCtx *) ctx; Parameter *param; PetscReal dx=user->grid->dx, dz=user->grid->dz; PetscReal PI = 3.14159265358979323846; int ierr; ierr = PetscBagGetData(user->bag,(void**)¶m); CHKERRQ(ierr); if (param->flow_type == SHEAR_CELL) { velocity[0] = -sin(PI*ij_real[0]*dx)*cos(PI*ij_real[1]*dz)/dx; velocity[1] = sin(PI*ij_real[1]*dz)*cos(PI*ij_real[0]*dx)/dz; } else { velocity[0] = 0.; velocity[1] = -1./dz; } return 0; }
int ReportParams(AppCtx *user) /*---------------------------------------------------------------------*/ { Parameter *param; GridInfo *grid = user->grid; int ierr, ierr_out=0; ierr = PetscBagGetData(user->bag,(void**)¶m); CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD,"---------------MOC test 1----------------\n"); PetscPrintf(PETSC_COMM_WORLD,"Prescribed wind, method of\n"); PetscPrintf(PETSC_COMM_WORLD,"characteristics advection, explicit time-\n"); PetscPrintf(PETSC_COMM_WORLD,"stepping.\n\n"); if (param->flow_type == 0) { PetscPrintf(PETSC_COMM_WORLD,"Flow_type: %d (shear cell).\n\n",param->flow_type); } if (param->flow_type == 1) { PetscPrintf(PETSC_COMM_WORLD,"Flow_type: %d (rigid body rotation).\n\n",param->flow_type); } if (param->verify) { PetscPrintf(PETSC_COMM_WORLD," ** VERIFICATION RUN ** \n\n"); } ierr = PetscPrintf(PETSC_COMM_WORLD," [ni,nj] = %d, %d [dx,dz] = %5.4g, %5.4g\n",grid->ni,grid->nj,grid->dx,grid->dz); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," t_max = %g, cfl = %g, dt = %5.4g,",param->t_max,param->cfl,param->dt); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," t_output = %g\n",param->t_output_interval); CHKERRQ(ierr); if (param->output_to_file) { PetscPrintf(PETSC_COMM_WORLD,"Output File: Binary file \"%s\"\n",param->output_filename); } if (!param->output_to_file) PetscPrintf(PETSC_COMM_WORLD,"Output File: NO OUTPUT!\n"); ierr = PetscPrintf(PETSC_COMM_WORLD,"----------------------------------------\n"); CHKERRQ(ierr); if (param->param_test) PetscEnd(); return ierr_out; }
int main(int argc,char **argv) { PetscErrorCode ierr; PetscBag bag; Parameter *params; PetscViewer viewer; PetscBool flg; char filename[PETSC_MAX_PATH_LEN] = "binaryoutput"; /* Every PETSc routine should begin with the PetscInitialize() routine. argc, argv - These command line arguments are taken to extract the options supplied to PETSc and options supplied to MPI. help - When PETSc executable is invoked with the option -help, it prints the various options that can be applied at runtime. The user can use the "help" variable place additional help messages in this printout. */ ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; /* Create an empty bag */ ierr = PetscBagCreate(PETSC_COMM_WORLD,sizeof(Parameter),&bag);CHKERRQ(ierr); ierr = PetscBagGetData(bag,(void**)¶ms);CHKERRQ(ierr); /* register variables, defaults, names, help strings */ ierr = PetscBagSetName(bag,"ParameterBag","contains parameters for simulations of top-secret, dangerous physics");CHKERRQ(ierr); ierr = PetscBagSetOptionsPrefix(bag, "pbag_");CHKERRQ(ierr); ierr = PetscBagRegisterString(bag,¶ms->filename,PETSC_MAX_PATH_LEN,"myfile","filename","Name of secret file");CHKERRQ(ierr); ierr = PetscBagRegisterReal (bag,¶ms->rho,3.0,"rho","Density, kg/m^3");CHKERRQ(ierr); ierr = PetscBagRegisterScalar(bag,¶ms->W, 5.0,"W","Vertical velocity, m/sec");CHKERRQ(ierr); ierr = PetscBagRegisterInt (bag,¶ms->Ii, 2,"modes_x","Number of modes in x-direction");CHKERRQ(ierr); params->iarray[0] = 1; params->iarray[1] = 2; params->iarray[2] = 3; ierr = PetscBagRegisterIntArray(bag,¶ms->iarray, 3,"int_array","Int array with 3 locations");CHKERRQ(ierr); params->rarray[0] = -1.0; params->rarray[1] = -2.0; ierr = PetscBagRegisterRealArray(bag,¶ms->rarray, 2,"real_array","Real array with 2 locations");CHKERRQ(ierr); ierr = PetscBagRegisterBool (bag,¶ms->T, PETSC_FALSE,"do_output","Write output file (yes/no)");CHKERRQ(ierr); ierr = PetscBagRegisterBoolArray(bag,¶ms->Tarray, 3,"bool_array","Bool array with 3 locations");CHKERRQ(ierr); ierr = PetscBagRegisterEnum (bag,¶ms->dt, PetscDataTypes,(PetscEnum)PETSC_INT,"dt","meaningless datatype");CHKERRQ(ierr); ierr = PetscBagRegisterReal (bag,¶ms->pos.x1,1.0,"x1","x position");CHKERRQ(ierr); ierr = PetscBagRegisterReal (bag,¶ms->pos.x2,1.9,"x2","y position");CHKERRQ(ierr); ierr = PetscBagRegisterEnum (bag,¶ms->which, EnumeratedChoices, (PetscEnum)THAT, "choose","Express yourself by choosing among enumerated things");CHKERRQ(ierr); /* This option allows loading user-provided PetscBag */ ierr = PetscOptionsGetString(NULL,NULL,"-f",filename,sizeof(filename),&flg);CHKERRQ(ierr); if (!flg) { /* write bag to stdio & binary file */ ierr = PetscBagView(bag,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); ierr = PetscBagView(bag,viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } ierr = PetscMemzero(params,sizeof(Parameter));CHKERRQ(ierr); /* load bag from file & write to stdio */ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,filename,FILE_MODE_READ,&viewer);CHKERRQ(ierr); ierr = PetscBagLoad(viewer,bag);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = PetscBagSetFromOptions(bag);CHKERRQ(ierr); ierr = PetscBagView(bag,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* reuse the parameter struct */ ierr = PetscBagGetData(bag,(void**)¶ms);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"The value of rho after loading is: %f\n",(double)params->rho);CHKERRQ(ierr); /* clean up and exit */ ierr = PetscBagDestroy(&bag);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **argv) { PetscErrorCode ierr; PetscBag bag; Parameter *params; PetscViewer viewer; DM da; Vec global,local; PetscMPIInt rank; /* Every PETSc routine should begin with the PetscInitialize() routine. argc, argv - These command line arguments are taken to extract the options supplied to PETSc and options supplied to MPI. help - When PETSc executable is invoked with the option -help, it prints the various options that can be applied at runtime. The user can use the "help" variable place additional help messages in this printout. */ ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; /* Create a DMDA and an associated vector */ ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_BOX,10,10,PETSC_DECIDE,PETSC_DECIDE,2,1,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&global);CHKERRQ(ierr); ierr = DMCreateLocalVector(da,&local);CHKERRQ(ierr); ierr = VecSet(global,-1.0);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = VecScale(local,rank+1);CHKERRQ(ierr); ierr = DMLocalToGlobalBegin(da,local,ADD_VALUES,global);CHKERRQ(ierr); ierr = DMLocalToGlobalEnd(da,local,ADD_VALUES,global);CHKERRQ(ierr); /* Create an empty bag */ ierr = PetscBagCreate(PETSC_COMM_WORLD,sizeof(Parameter),&bag);CHKERRQ(ierr); ierr = PetscBagGetData(bag,(void**)¶ms);CHKERRQ(ierr); /* fill bag: register variables, defaults, names, help strings */ ierr = PetscBagSetName(bag,"ParameterBag","contains problem parameters");CHKERRQ(ierr); ierr = PetscBagRegisterString(bag,¶ms->filename,PETSC_MAX_PATH_LEN,"output_file","filename","Name of secret file");CHKERRQ(ierr); ierr = PetscBagRegisterReal (bag,¶ms->ra,1.0,"param_1","The first parameter");CHKERRQ(ierr); ierr = PetscBagRegisterInt (bag,¶ms->ia,5,"param_2","The second parameter");CHKERRQ(ierr); ierr = PetscBagRegisterBool (bag,¶ms->ta,PETSC_TRUE,"do_output","Write output file (true/false)");CHKERRQ(ierr); /* Write output file with PETSC_VIEWER_BINARY_MATLAB format NOTE: the output generated with this viewer can be loaded into MATLAB using $PETSC_DIR/share/petsc/matlab/PetscReadBinaryMatlab.m */ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,params->filename,FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_BINARY_MATLAB);CHKERRQ(ierr); ierr = PetscBagView(bag,viewer);CHKERRQ(ierr); ierr = DMDASetFieldName(da,0,"field1");CHKERRQ(ierr); ierr = DMDASetFieldName(da,1,"field2");CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)global,"da1");CHKERRQ(ierr); ierr = VecView(global,viewer);CHKERRQ(ierr); ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); /* clean up and exit */ ierr = PetscBagDestroy(&bag);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = VecDestroy(&local);CHKERRQ(ierr); ierr = VecDestroy(&global);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **argv) /*-----------------------------------------------------------------------*/ { DMMG *dmmg; /* multilevel grid structure */ AppCtx *user; /* user-defined work context */ Parameter *param; GridInfo grid; int ierr,result; MPI_Comm comm; DA da; PetscInitialize(&argc,&argv,(char *)0,help); comm = PETSC_COMM_WORLD; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set up the problem parameters. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscMalloc(sizeof(AppCtx),&user); CHKERRQ(ierr); ierr = PetscBagCreate(comm,sizeof(Parameter),&(user->bag)); CHKERRQ(ierr); user->grid = &grid; ierr = SetParams(user); CHKERRQ(ierr); ierr = ReportParams(user); CHKERRQ(ierr); ierr = PetscBagGetData(user->bag,(void**)¶m); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array multigrid object (DMMG) to manage parallel grid and vectors for principal unknowns (x) and governing residuals (f) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMMGCreate(comm,grid.mglevels,user,&dmmg); CHKERRQ(ierr); ierr = DACreate2d(comm,grid.periodic,grid.stencil,grid.ni,grid.nj,PETSC_DECIDE,PETSC_DECIDE,grid.dof,grid.stencil_width,0,0,&da); CHKERRQ(ierr); ierr = DMMGSetDM(dmmg,(DM)da); CHKERRQ(ierr); ierr = DADestroy(da); CHKERRQ(ierr); ierr = DAGetInfo(da,PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL,&(param->pi),&(param->pj),PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL); CHKERRQ(ierr); REG_INTG(user->bag,¶m->pi,param->pi ,"procs_x","<DO NOT SET> Processors in the x-direction"); REG_INTG(user->bag,¶m->pj,param->pj ,"procs_y","<DO NOT SET> Processors in the y-direction"); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create user context, set problem data, create vector data structures. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DAGetGlobalVector(da, &(user->Xold)); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize and solve the nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = Initialize(dmmg); CHKERRQ(ierr); ierr = DoSolve(dmmg); CHKERRQ(ierr); if (param->verify) result = param->verify_result; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DARestoreGlobalVector(da, &(user->Xold)); CHKERRQ(ierr); ierr = PetscBagDestroy(user->bag); CHKERRQ(ierr); ierr = PetscFree(user); CHKERRQ(ierr); ierr = DMMGDestroy(dmmg); CHKERRQ(ierr); ierr = PetscFinalize(); CHKERRQ(ierr); return result; }
int DoSolve(DMMG *dmmg) /* ------------------------------------------------------------------- */ { AppCtx *user = (AppCtx*)dmmg[0]->user; Parameter *param; PetscReal t_output = 0.0; int ierr, n_plot = 0, Ncomponents, components[3]; DA da = DMMGGetDA(dmmg); Vec Xstar; Characteristic c; ierr = PetscBagGetData(user->bag,(void**)¶m); CHKERRQ(ierr); ierr = DAGetGlobalVector(da, &Xstar); CHKERRQ(ierr); /*------------ BEGIN CHARACTERISTIC SETUP ---------------*/ ierr = CharacteristicCreate(PETSC_COMM_WORLD, &c); CHKERRQ(ierr); /* set up the velocity interpolation system */ Ncomponents = 2; components[0] = 0; components[1] = 1; ierr = CharacteristicSetVelocityInterpolationLocal(c, da, DMMGGetx(dmmg), user->Xold, Ncomponents, components, InterpVelocity2D, user); CHKERRQ(ierr); /* set up the fields interpolation system */ Ncomponents = 1; components[0] = 2; ierr = CharacteristicSetFieldInterpolationLocal(c, da, user->Xold, Ncomponents, components, InterpFields2D, user); CHKERRQ(ierr); /*------------ END CHARACTERISTIC SETUP ----------------*/ /* output initial data */ PetscPrintf(PETSC_COMM_WORLD," Initialization, Time: %5.4g\n", param->t); if (param->verify) { ierr = DoVerification(dmmg,user); CHKERRQ(ierr); } ierr = DoOutput(dmmg,n_plot); CHKERRQ(ierr); t_output += param->t_output_interval; n_plot++; /* timestep loop */ for (param->t=param->dt; param->t<=param->t_max; param->t+=param->dt) { if (param->n > param->N_steps) { PetscPrintf(PETSC_COMM_WORLD,"EXCEEDED MAX NUMBER OF TIMESTEPS! EXITING SOLVE!\n"); return 0; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve at time t & copy solution into solution vector. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Copy in the velocities to Xstar */ ierr = VecCopy(DMMGGetx(dmmg), Xstar); CHKERRQ(ierr); /* Put \phi_* into Xstar */ ierr = CharacteristicSolve(c, param->dt, Xstar); CHKERRQ(ierr); /* Copy the advected field into the solution \phi_t = \phi_* */ ierr = VecCopy(Xstar, DMMGGetx(dmmg)); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Copy new solution to old solution in prep for the next timestep. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecCopy(DMMGGetx(dmmg), user->Xold); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Timestep complete, report and update counter. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ PetscPrintf(PETSC_COMM_WORLD," Step: %d, Time: %5.4g\n", param->n, param->t); param->n++; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Verify and make output. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ if (param->verify) { ierr = DoVerification(dmmg,user); CHKERRQ(ierr); } if (param->t >= t_output) { ierr = DoOutput(dmmg,n_plot); CHKERRQ(ierr); t_output += param->t_output_interval; n_plot++; } } ierr = DARestoreGlobalVector(da, &Xstar); CHKERRQ(ierr); ierr = CharacteristicDestroy(c); CHKERRQ(ierr); return 0; }
int SetParams(AppCtx *user) /*---------------------------------------------------------------------*/ { PetscBag bag = user->bag; Parameter *p; GridInfo *grid = user->grid; int ierr, ierr_out=0; ierr = PetscBagGetData(bag,(void**)&p); CHKERRQ(ierr); /* give the bag a name */ ierr = PetscBagSetName(bag,"ex1_params","Parameter bag for ex1.c"); CHKERRQ(ierr); /* verification */ REG_TRUE(bag,&p->verify,PETSC_FALSE ,"verify","Do verification run (T/F)"); /* domain geometry & grid size */ REG_INTG(bag,&p->ni,40 ,"ni","Grid points in x-dir"); REG_INTG(bag,&p->nj,40 ,"nj","Grid points in y-dir"); grid->dx = 1.0/((double)(p->ni - 1)); grid->dz = 1.0/((double)(p->nj - 1)); /* initial conditions */ REG_INTG(bag,&p->flow_type,SHEAR_CELL ,"flow_type","Flow field mode: 0=shear cell, 1=translation"); REG_REAL(bag,&p->sigma,0.07 ,"sigma","Standard deviation of the gaussian IC"); REG_REAL(bag,&p->xctr,0.5 ,"xctr","x-position of the center of the gaussian IC"); REG_REAL(bag,&p->zctr,0.75 ,"zctr","z-position of the center of the gaussian IC"); /* time stepping */ REG_REAL(bag,&p->t_max,1 ,"t_max","Maximum dimensionless time"); REG_REAL(bag,&p->cfl,5 ,"cfl","Courant number"); REG_REAL(bag,&p->t_output_interval,0.1 ,"t_output","Dimensionless time interval for output"); REG_INTG(bag,&p->N_steps,1000 ,"nsteps","Maximum time-steps"); REG_INTG(bag,&p->n,1 ,"nsteps","<DO NOT SET> current time-step"); REG_REAL(bag,&p->t,0.0 ,"time","<DO NOT SET> initial time"); REG_REAL(bag,&p->dt,p->cfl*PetscMin(grid->dx,grid->dz),"dt","<DO NOT SET> time-step size"); /* output options */ REG_TRUE(bag,&p->param_test ,PETSC_FALSE ,"test","Run parameter test only (T/F)"); REG_STRG(bag,&p->output_filename,FNAME_LENGTH ,"null","output_file","Name base for output files, set with: -output_file <filename>"); REG_TRUE(bag,&p->output_to_file,PETSC_FALSE ,"do_output","<DO NOT SET> flag will be true if you specify an output file name"); p->output_to_file = OptionsHasName("-output_file"); if (p->verify) { REG_INTG(bag,&p->verify_result,0 ,"ver_result","<DO NOT SET> Result of verification test"); REG_REAL(bag,&p->L1 ,4924.42 ,"L1","<DO NOT SET> L1"); REG_REAL(bag,&p->L2 ,496.287 ,"L2","<DO NOT SET> L2"); REG_REAL(bag,&p->LINF,100 ,"L3","<DO NOT SET> L3"); p->verify_result = 0; p->L1 = 4924.42; p->L2 = 496.287; p->LINF = 100; grid->ni = grid->nj = 40; grid->dx = 1.0/((double)(grid->ni)); grid->dz = 1.0/((double)(grid->nj)); p->flow_type = SHEAR_CELL; p->sigma = 0.07; p->xctr = 0.5; p->zctr = 0.75; p->t_max = 0.5; p->cfl = 5; p->t_output_interval = 0.1; p->dt = p->cfl*PetscMin(grid->dx,grid->dz); } grid->ni = p->ni; grid->nj = p->nj; grid->periodic = DA_XYPERIODIC; grid->stencil = DA_STENCIL_BOX; grid->dof = 3; grid->stencil_width = 2; grid->mglevels = 1; return ierr_out; }
int main(int argc,char **argv) { DM da; SNES snes; /* nonlinear solver */ AppCtx *user; /* user-defined work context */ PetscBag bag; PetscInt its; /* iterations for convergence */ PetscMPIInt size; SNESConvergedReason reason; PetscErrorCode ierr; PetscReal lambda_max = 6.81, lambda_min = 0.0, error; Vec x; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ PetscInitialize(&argc,&argv,(char*)0,help); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Example only works for one process."); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize problem parameters - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscBagCreate(PETSC_COMM_WORLD, sizeof(AppCtx), &bag);CHKERRQ(ierr); ierr = PetscBagGetData(bag, (void**) &user);CHKERRQ(ierr); ierr = PetscBagSetName(bag, "params", "Parameters for SNES example 4");CHKERRQ(ierr); ierr = PetscBagRegisterReal(bag, &user->alpha, 1.0, "alpha", "Linear coefficient");CHKERRQ(ierr); ierr = PetscBagRegisterReal(bag, &user->lambda, 6.0, "lambda", "Nonlinear coefficient");CHKERRQ(ierr); ierr = PetscBagSetFromOptions(bag);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,"-alpha",&user->alpha,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,"-lambda",&user->lambda,NULL);CHKERRQ(ierr); if (user->lambda > lambda_max || user->lambda < lambda_min) SETERRQ3(PETSC_COMM_SELF,1,"Lambda %g is out of range [%g, %g]", (double)user->lambda, (double)lambda_min, (double)lambda_max); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create multilevel DM data structure (SNES) to manage hierarchical solvers - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array (DMDA) to manage parallel grid and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_BOX,-3,-3,PETSC_DECIDE,PETSC_DECIDE,3,1,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMDASetFieldName(da, 0, "ooblek");CHKERRQ(ierr); ierr = DMSetApplicationContext(da,user);CHKERRQ(ierr); ierr = SNESSetDM(snes, (DM) da);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set the discretization functions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDASNESSetFunctionLocal(da,INSERT_VALUES,(PetscErrorCode (*)(DMDALocalInfo*,void*,void*,void*))FormFunctionLocal,user);CHKERRQ(ierr); ierr = DMDASNESSetJacobianLocal(da,(PetscErrorCode (*)(DMDALocalInfo*,void*,Mat,Mat,void*))FormJacobianLocal,user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSetComputeInitialGuess(snes, FormInitialGuess,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESSolve(snes,NULL,NULL);CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = SNESGetConvergedReason(snes, &reason);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscPrintf(PETSC_COMM_WORLD,"Number of SNES iterations = %D, %s\n",its,SNESConvergedReasons[reason]);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = SNESGetDM(snes,&da);CHKERRQ(ierr); ierr = SNESGetSolution(snes,&x);CHKERRQ(ierr); ierr = L_2Error(da, x, &error, user);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"L_2 error in the solution: %g\n", (double)error);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = PetscBagDestroy(&bag);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }