int main(int argc, char **argv) { MPI_Comm comm; DM dm; Vec v, nv, rv, coord; PetscBool test_read = PETSC_FALSE, verbose = PETSC_FALSE, flg; PetscViewer hdf5Viewer; PetscInt dim = 2; PetscInt numFields = 1; PetscInt numBC = 0; PetscInt numComp[1] = {2}; PetscInt numDof[3] = {2, 0, 0}; PetscInt bcFields[1] = {0}; IS bcPoints[1] = {NULL}; PetscSection section; PetscReal norm; PetscErrorCode ierr; ierr = PetscInitialize(&argc, &argv, (char *) 0, help);if (ierr) return ierr; comm = PETSC_COMM_WORLD; ierr = PetscOptionsBegin(PETSC_COMM_WORLD,"","Test Options","none");CHKERRQ(ierr); ierr = PetscOptionsBool("-test_read","Test reading from the HDF5 file","",PETSC_FALSE,&test_read,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-verbose","print the Vecs","",PETSC_FALSE,&verbose,NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-dim","the dimension of the problem","",2,&dim,NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd(); ierr = DMPlexCreateBoxMesh(comm, dim, dim == 2 ? 2 : 1, PETSC_TRUE, &dm);CHKERRQ(ierr); ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); numDof[0] = dim; ierr = DMPlexCreateSection(dm, dim, numFields, numComp, numDof, numBC, bcFields, bcPoints, NULL, NULL, §ion);CHKERRQ(ierr); ierr = DMSetDefaultSection(dm, section);CHKERRQ(ierr); ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); ierr = DMSetUseNatural(dm, PETSC_TRUE);CHKERRQ(ierr); { DM dmDist; ierr = DMPlexDistribute(dm, 0, NULL, &dmDist);CHKERRQ(ierr); if (dmDist) { ierr = DMDestroy(&dm);CHKERRQ(ierr); dm = dmDist; } } ierr = DMCreateGlobalVector(dm, &v);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) v, "V");CHKERRQ(ierr); ierr = DMGetCoordinates(dm, &coord);CHKERRQ(ierr); ierr = VecCopy(coord, v);CHKERRQ(ierr); if (verbose) { PetscInt size, bs; ierr = VecGetSize(v, &size);CHKERRQ(ierr); ierr = VecGetBlockSize(v, &bs);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "==== original V in global ordering. size==%d\tblock size=%d\n", size, bs);CHKERRQ(ierr); ierr = VecView(v, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = DMCreateGlobalVector(dm, &nv);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) nv, "NV");CHKERRQ(ierr); ierr = DMPlexGlobalToNaturalBegin(dm, v, nv);CHKERRQ(ierr); ierr = DMPlexGlobalToNaturalEnd(dm, v, nv);CHKERRQ(ierr); if (verbose) { PetscInt size, bs; ierr = VecGetSize(nv, &size);CHKERRQ(ierr); ierr = VecGetBlockSize(nv, &bs);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "==== V in natural ordering. size==%d\tblock size=%d\n", size, bs);CHKERRQ(ierr); ierr = VecView(nv, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = VecViewFromOptions(v, NULL, "-global_vec_view");CHKERRQ(ierr); if (test_read) { ierr = DMCreateGlobalVector(dm, &rv);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) rv, "V");CHKERRQ(ierr); /* Test native read */ ierr = PetscViewerHDF5Open(comm, "V.h5", FILE_MODE_READ, &hdf5Viewer);CHKERRQ(ierr); ierr = PetscViewerPushFormat(hdf5Viewer, PETSC_VIEWER_NATIVE);CHKERRQ(ierr); ierr = VecLoad(rv, hdf5Viewer);CHKERRQ(ierr); ierr = PetscViewerPopFormat(hdf5Viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&hdf5Viewer);CHKERRQ(ierr); if (verbose) { PetscInt size, bs; ierr = VecGetSize(rv, &size);CHKERRQ(ierr); ierr = VecGetBlockSize(rv, &bs);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "==== Vector from file. size==%d\tblock size=%d\n", size, bs);CHKERRQ(ierr); ierr = VecView(rv, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = VecEqual(rv, v, &flg);CHKERRQ(ierr); if (flg) { ierr = PetscPrintf(PETSC_COMM_WORLD, "V and RV are equal\n");CHKERRQ(ierr); } else { ierr = PetscPrintf(PETSC_COMM_WORLD, "V and RV are not equal\n\n");CHKERRQ(ierr); ierr = VecAXPY(rv, -1.0, v);CHKERRQ(ierr); ierr = VecNorm(rv, NORM_INFINITY, &norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "diff norm is = %g\n", (double) norm);CHKERRQ(ierr); ierr = VecView(rv, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } /* Test raw read */ ierr = PetscViewerHDF5Open(comm, "V.h5", FILE_MODE_READ, &hdf5Viewer);CHKERRQ(ierr); ierr = VecLoad(rv, hdf5Viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&hdf5Viewer);CHKERRQ(ierr); if (verbose) { PetscInt size, bs; ierr = VecGetSize(rv, &size);CHKERRQ(ierr); ierr = VecGetBlockSize(rv, &bs);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "==== Vector from file. size==%d\tblock size=%d\n", size, bs);CHKERRQ(ierr); ierr = VecView(rv, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = VecEqual(rv, nv, &flg);CHKERRQ(ierr); if (flg) { ierr = PetscPrintf(PETSC_COMM_WORLD, "NV and RV are equal\n");CHKERRQ(ierr); } else { ierr = PetscPrintf(PETSC_COMM_WORLD, "NV and RV are not equal\n\n");CHKERRQ(ierr); ierr = VecAXPY(rv, -1.0, v);CHKERRQ(ierr); ierr = VecNorm(rv, NORM_INFINITY, &norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "diff norm is = %g\n", (double) norm);CHKERRQ(ierr); ierr = VecView(rv, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = VecDestroy(&rv);CHKERRQ(ierr); } ierr = VecDestroy(&nv);CHKERRQ(ierr); ierr = VecDestroy(&v);CHKERRQ(ierr); ierr = DMDestroy(&dm);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
PetscErrorCode CreateTensorProductHybrid_3D(MPI_Comm comm, PetscInt testNum, DM *dm) { DM idm = NULL, hdm = NULL; DMLabel faultLabel; PetscInt p; PetscMPIInt rank; PetscErrorCode ierr; PetscFunctionBegin; ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); if (!rank) { switch (testNum) { case 0: { PetscInt numPoints[2] = {12, 2}; PetscInt coneSize[14] = {8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; PetscInt cones[16] = {2, 3, 4, 5, 6, 7, 8, 9, 5, 4, 10, 11, 7, 12, 13, 8}; PetscInt coneOrientations[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; PetscScalar vertexCoords[36] = {-1.0, -0.5, -0.5, -1.0, 0.5, -0.5, 0.0, 0.5, -0.5, 0.0, -0.5, -0.5, -1.0, -0.5, 0.5, 0.0, -0.5, 0.5, 0.0, 0.5, 0.5, -1.0, 0.5, 0.5, 1.0, 0.5, -0.5, 1.0, -0.5, -0.5, 1.0, -0.5, 0.5, 1.0, 0.5, 0.5}; PetscInt faultPoints[4] = {2, 3, 5, 6}; ierr = DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); for(p = 0; p < 4; ++p) {ierr = DMSetLabelValue(*dm, "fault", faultPoints[p], 1);CHKERRQ(ierr);} } break; case 1: { PetscInt numPoints[2] = {30, 7}; PetscInt coneSize[37] = {8,8,8,8,8,8,8, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; PetscInt cones[56] = { 8, 21, 20, 7, 13, 12, 23, 24, 14, 15, 10, 9, 13, 8, 21, 24, 15, 16, 11, 10, 24, 21, 22, 25, 30, 29, 28, 21, 35, 24, 33, 34, 24, 21, 30, 35, 25, 36, 31, 22, 27, 20, 21, 28, 32, 33, 24, 23, 15, 24, 13, 14, 19, 18, 17, 26}; PetscInt coneOrientations[56] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; PetscScalar vertexCoords[90] = {-2.0, -2.0, -2.0, -2.0, -1.0, -2.0, -3.0, 0.0, -2.0, -2.0, 1.0, -2.0, -2.0, 2.0, -2.0, -2.0, -2.0, 0.0, -2.0, -1.0, 0.0, -3.0, 0.0, 0.0, -2.0, 1.0, 0.0, -2.0, 2.0, 0.0, -2.0, -1.0, 2.0, -3.0, 0.0, 2.0, -2.0, 1.0, 2.0, 0.0, -2.0, -2.0, 0.0, 0.0, -2.0, 0.0, 2.0, -2.0, 0.0, -2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 2.0, 2.0, -2.0, -2.0, 2.0, -1.0, -2.0, 3.0, 0.0, -2.0, 2.0, 1.0, -2.0, 2.0, 2.0, -2.0, 2.0, -2.0, 0.0, 2.0, -1.0, 0.0, 3.0, 0.0, 0.0, 2.0, 1.0, 0.0, 2.0, 2.0, 0.0}; PetscInt faultPoints[6] = {20, 21, 22, 23, 24, 25}; ierr = DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); for(p = 0; p < 6; ++p) {ierr = DMSetLabelValue(*dm, "fault", faultPoints[p], 1);CHKERRQ(ierr);} } break; default: SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "No test mesh %d", testNum); } ierr = DMPlexCheckSymmetry(*dm);CHKERRQ(ierr); ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); ierr = DMPlexCopyCoordinates(*dm, idm);CHKERRQ(ierr); ierr = DMViewFromOptions(idm, NULL, "-in_dm_view");CHKERRQ(ierr); ierr = DMPlexCheckSymmetry(idm);CHKERRQ(ierr); ierr = DMGetLabel(*dm, "fault", &faultLabel);CHKERRQ(ierr); ierr = DMPlexCreateHybridMesh(idm, faultLabel, NULL, &hdm);CHKERRQ(ierr); ierr = DMDestroy(&idm);CHKERRQ(ierr); ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = hdm; } else { PetscInt numPoints[4] = {0, 0, 0, 0}; ierr = DMPlexCreateFromDAG(*dm, 1, numPoints, NULL, NULL, NULL, NULL);CHKERRQ(ierr); ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); ierr = DMPlexCopyCoordinates(*dm, idm);CHKERRQ(ierr); ierr = DMViewFromOptions(idm, NULL, "-in_dm_view");CHKERRQ(ierr); ierr = DMPlexCreateHybridMesh(idm, NULL, NULL, &hdm);CHKERRQ(ierr); ierr = DMDestroy(&idm);CHKERRQ(ierr); ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = hdm; } PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscMPIInt rank,size; PetscInt M = 14,time_steps = 20,w=1,s=1,localsize,j,i,mybase,myend; PetscErrorCode ierr; DM da; Vec local,global,copy; PetscScalar *localptr,*copyptr; PetscReal h,k; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-M",&M,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-time",&time_steps,NULL);CHKERRQ(ierr); /* Set up the array */ ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,M,w,s,NULL,&da);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&global);CHKERRQ(ierr); ierr = DMCreateLocalVector(da,&local);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); /* Make copy of local array for doing updates */ ierr = VecDuplicate(local,©);CHKERRQ(ierr); ierr = VecGetArray (copy,©ptr);CHKERRQ(ierr); /* determine starting point of each processor */ ierr = VecGetOwnershipRange(global,&mybase,&myend);CHKERRQ(ierr); /* Initialize the Array */ ierr = VecGetLocalSize (local,&localsize);CHKERRQ(ierr); ierr = VecGetArray (local,&localptr);CHKERRQ(ierr); localptr[0] = copyptr[0] = 0.0; localptr[localsize-1] = copyptr[localsize-1] = 1.0; for (i=1; i<localsize-1; i++) { j = (i-1) + mybase; localptr[i] = PetscSinReal((PETSC_PI*j*6)/((PetscReal)M) + 1.2 * PetscSinReal((PETSC_PI*j*2)/((PetscReal)M))) * 4+4; } ierr = VecRestoreArray (copy,©ptr);CHKERRQ(ierr); ierr = VecRestoreArray(local,&localptr);CHKERRQ(ierr); ierr = DMLocalToGlobalBegin(da,local,INSERT_VALUES,global);CHKERRQ(ierr); ierr = DMLocalToGlobalEnd(da,local,INSERT_VALUES,global);CHKERRQ(ierr); /* Assign Parameters */ h= 1.0/M; k= h*h/2.2; for (j=0; j<time_steps; j++) { /* Global to Local */ ierr = DMGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr); /*Extract local array */ ierr = VecGetArray(local,&localptr);CHKERRQ(ierr); ierr = VecGetArray (copy,©ptr);CHKERRQ(ierr); /* Update Locally - Make array of new values */ /* Note: I don't do anything for the first and last entry */ for (i=1; i< localsize-1; i++) { copyptr[i] = localptr[i] + (k/(h*h)) * (localptr[i+1]-2.0*localptr[i]+localptr[i-1]); } ierr = VecRestoreArray (copy,©ptr);CHKERRQ(ierr); ierr = VecRestoreArray(local,&localptr);CHKERRQ(ierr); /* Local to Global */ ierr = DMLocalToGlobalBegin(da,copy,INSERT_VALUES,global);CHKERRQ(ierr); ierr = DMLocalToGlobalEnd(da,copy,INSERT_VALUES,global);CHKERRQ(ierr); /* View Wave */ /* Set Up Display to Show Heat Graph */ #if defined(PETSC_USE_SOCKET_VIEWER) ierr = VecView(global,PETSC_VIEWER_SOCKET_WORLD);CHKERRQ(ierr); #endif } ierr = VecDestroy(©);CHKERRQ(ierr); ierr = VecDestroy(&local);CHKERRQ(ierr); ierr = VecDestroy(&global);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
PetscErrorCode Brusselator(int argc,char **argv,PetscInt cycle) { TS ts; /* nonlinear solver */ Vec X; /* solution, residual vectors */ Mat J; /* Jacobian matrix */ PetscInt steps,maxsteps,mx; PetscErrorCode ierr; DM da; PetscReal ftime,hx,dt,xmax,xmin; struct _User user; /* user-defined work context */ TSConvergedReason reason; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array (DMDA) to manage parallel grid and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,11,2,2,NULL,&da);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extract global vectors from DMDA; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&X);CHKERRQ(ierr); /* Initialize user application context */ ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Advection-reaction options",""); { user.A = 1; user.B = 3; user.alpha = 0.1; user.uleft = 1; user.uright = 1; user.vleft = 3; user.vright = 3; ierr = PetscOptionsReal("-A","Reaction rate","",user.A,&user.A,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-B","Reaction rate","",user.B,&user.B,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-alpha","Diffusion coefficient","",user.alpha,&user.alpha,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-uleft","Dirichlet boundary condition","",user.uleft,&user.uleft,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-uright","Dirichlet boundary condition","",user.uright,&user.uright,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-vleft","Dirichlet boundary condition","",user.vleft,&user.vleft,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-vright","Dirichlet boundary condition","",user.vright,&user.vright,NULL);CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetDM(ts,da);CHKERRQ(ierr); ierr = TSSetType(ts,TSARKIMEX);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,NULL,FormRHSFunction,&user);CHKERRQ(ierr); ierr = TSSetIFunction(ts,NULL,FormIFunction,&user);CHKERRQ(ierr); ierr = DMSetMatType(da,MATAIJ);CHKERRQ(ierr); ierr = DMCreateMatrix(da,&J);CHKERRQ(ierr); ierr = TSSetIJacobian(ts,J,J,FormIJacobian,&user);CHKERRQ(ierr); ftime = 1.0; maxsteps = 10000; ierr = TSSetDuration(ts,maxsteps,ftime);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = FormInitialSolution(ts,X,&user);CHKERRQ(ierr); ierr = TSSetSolution(ts,X);CHKERRQ(ierr); ierr = VecGetSize(X,&mx);CHKERRQ(ierr); hx = 1.0/(PetscReal)(mx/2-1); dt = 0.4 * PetscSqr(hx) / user.alpha; /* Diffusive stability limit */ dt *= PetscPowRealInt(0.2,cycle); /* Shrink the time step in convergence study. */ ierr = TSSetInitialTimeStep(ts,0.0,dt);CHKERRQ(ierr); ierr = TSSetTolerances(ts,1e-3*PetscPowRealInt(0.5,cycle),NULL,1e-3*PetscPowRealInt(0.5,cycle),NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,X);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); ierr = TSGetConvergedReason(ts,&reason);CHKERRQ(ierr); ierr = VecMin(X,NULL,&xmin);CHKERRQ(ierr); ierr = VecMax(X,NULL,&xmax);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"%s at time %g after % 3D steps. Range [%6.4f,%6.4f]\n",TSConvergedReasons[reason],(double)ftime,steps,(double)xmin,(double)xmax);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
/* Two tetrahedrons cell 5 5______ cell 0 / | \ |\ \ 1 17 | 18 | 18 13 21 /8 19 10\ 19 \ \ 2-14-|----4 | 4--22--6 \ 9 | 7 / |10 / / 16 | 15 | 15 12 20 \ | / |/ / 3 3------ */ PetscErrorCode CreateSimplex_3D(MPI_Comm comm, PetscInt testNum, DM *dm) { DM idm = NULL; PetscInt depth = 3; PetscMPIInt rank; PetscErrorCode ierr; PetscFunctionBegin; ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); if (!rank) { switch (testNum) { case 0: { PetscInt numPoints[4] = {5, 9, 7, 2}; PetscInt coneSize[23] = {4, 4, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2}; PetscInt cones[47] = { 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 14, 16, 19, 17, 15, 18, 19, 20, 21, 19, 15, 22, 20, 18, 21, 22, 2, 4, 4, 3, 3, 2, 2, 5, 5, 4, 3, 5, 3, 6, 6, 5, 4, 6}; PetscInt coneOrientations[47] = { 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, -2, -2, 0, -2, -2, -2, -2, 0, 0, -2, -2, 0, -2, -2, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; PetscScalar vertexCoords[15] = {0.0, 0.0, -0.5, 0.0, -0.5, 0.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5}; ierr = DMPlexCreateFromDAG(*dm, depth, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); } break; case 1: { PetscInt numPoints[2] = {5, 2}; PetscInt coneSize[7] = {4, 4, 0, 0, 0, 0, 0}; PetscInt cones[8] = {4, 3, 5, 2, 5, 3, 4, 6}; PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; PetscScalar vertexCoords[15] = {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}; depth = 1; ierr = DMPlexCreateFromDAG(*dm, depth, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); ierr = DMPlexCopyCoordinates(*dm, idm);CHKERRQ(ierr); ierr = DMViewFromOptions(idm, NULL, "-in_dm_view");CHKERRQ(ierr); ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = idm; } break; case 2: { PetscInt numPoints[2] = {4, 1}; PetscInt coneSize[5] = {4, 0, 0, 0, 0}; PetscInt cones[4] = {2, 3, 4, 1}; PetscInt coneOrientations[4] = {0, 0, 0, 0}; PetscScalar vertexCoords[12] = {0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; depth = 1; ierr = DMPlexCreateFromDAG(*dm, depth, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); ierr = DMPlexCopyCoordinates(*dm, idm);CHKERRQ(ierr); ierr = DMViewFromOptions(idm, NULL, "-in_dm_view");CHKERRQ(ierr); ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = idm; } break; default: SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "No test mesh %d", testNum); } } else { PetscInt numPoints[4] = {0, 0, 0, 0}; ierr = DMPlexCreateFromDAG(*dm, depth, numPoints, NULL, NULL, NULL, NULL);CHKERRQ(ierr); switch (testNum) { case 1: ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); ierr = DMPlexCopyCoordinates(*dm, idm);CHKERRQ(ierr); ierr = DMViewFromOptions(idm, NULL, "-in_dm_view");CHKERRQ(ierr); ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = idm; break; } } PetscFunctionReturn(0); }
int main(int argc,char **argv) { SNES snes; /* nonlinear solver */ SNES psnes; /* nonlinear Gauss-Seidel approximate solver */ Vec x,b; /* solution vector */ PetscInt its; /* iterations for convergence */ PetscErrorCode ierr; DM da; PetscBool use_ngs = PETSC_FALSE; /* use the nonlinear Gauss-Seidel approximate solver */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ PetscInitialize(&argc,&argv,(char*)0,help); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create nonlinear solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-use_ngs",&use_ngs,0);CHKERRQ(ierr); if (use_ngs) { ierr = SNESGetPC(snes,&psnes);CHKERRQ(ierr); ierr = SNESSetType(psnes,SNESSHELL);CHKERRQ(ierr); ierr = SNESShellSetSolve(psnes,NonlinearGS);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array (DMDA) to manage parallel grid and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate2d(PETSC_COMM_WORLD, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE,DMDA_STENCIL_STAR,-4,-4,PETSC_DECIDE,PETSC_DECIDE,1,1,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0);CHKERRQ(ierr); ierr = SNESSetDM(snes,da);CHKERRQ(ierr); if (use_ngs) { ierr = SNESShellSetContext(psnes,da);CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extract global vectors from DMDA; then duplicate for remaining vectors that are the same types - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&x);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&b);CHKERRQ(ierr); ierr = VecSetRandom(b,NULL);CHKERRQ(ierr); ierr = SNESSetFunction(snes,NULL,MyComputeFunction,NULL);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,NULL,NULL,MyComputeJacobian,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Customize nonlinear solver; set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESSolve(snes,b,x);CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }
PetscInt main(PetscInt argc,char **args) { typedef enum {RANDOM, CONSTANT, TANH, NUM_FUNCS} FuncType; const char *funcNames[NUM_FUNCS] = {"random", "constant", "tanh"}; Mat A, AA; PetscMPIInt size; PetscInt N,i, stencil=1,dof=1; PetscInt dim[3] = {10,10,10}, ndim = 3; Vec coords,x,y,z,xx,yy,zz; PetscReal h[3]; PetscScalar s; PetscRandom rdm; PetscReal norm, enorm; PetscInt func; FuncType function = TANH; DM da, coordsda; PetscBool view_x = PETSC_FALSE, view_y = PETSC_FALSE, view_z = PETSC_FALSE; PetscErrorCode ierr; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_size(PETSC_COMM_WORLD, &size);CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP, "This is a uniprocessor example only!"); ierr = PetscOptionsBegin(PETSC_COMM_WORLD, NULL, "USFFT Options", "ex27");CHKERRQ(ierr); ierr = PetscOptionsEList("-function", "Function type", "ex27", funcNames, NUM_FUNCS, funcNames[function], &func, NULL);CHKERRQ(ierr); function = (FuncType) func; ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-view_x",&view_x,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-view_y",&view_y,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-view_z",&view_z,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetIntArray(NULL,NULL,"-dim",dim,&ndim,NULL);CHKERRQ(ierr); ierr = DMDACreate3d(PETSC_COMM_SELF,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,dim[0], dim[1], dim[2], PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE,dof, stencil,NULL, NULL, NULL,&da);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); /* Coordinates */ ierr = DMGetCoordinateDM(da, &coordsda); ierr = DMGetGlobalVector(coordsda, &coords);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) coords, "Grid coordinates");CHKERRQ(ierr); for (i = 0, N = 1; i < 3; i++) { h[i] = 1.0/dim[i]; PetscScalar *a; ierr = VecGetArray(coords, &a);CHKERRQ(ierr); PetscInt j,k,n = 0; for (i = 0; i < 3; ++i) { for (j = 0; j < dim[i]; ++j) { for (k = 0; k < 3; ++k) { a[n] = j*h[i]; /* coordinate along the j-th point in the i-th dimension */ ++n; } } } ierr = VecRestoreArray(coords, &a);CHKERRQ(ierr); } ierr = DMSetCoordinates(da, coords);CHKERRQ(ierr); /* Work vectors */ ierr = DMGetGlobalVector(da, &x);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) x, "Real space vector");CHKERRQ(ierr); ierr = DMGetGlobalVector(da, &xx);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) xx, "Real space vector");CHKERRQ(ierr); ierr = DMGetGlobalVector(da, &y);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) y, "USFFT frequency space vector");CHKERRQ(ierr); ierr = DMGetGlobalVector(da, &yy);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) yy, "FFTW frequency space vector");CHKERRQ(ierr); ierr = DMGetGlobalVector(da, &z);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) z, "USFFT reconstructed vector");CHKERRQ(ierr); ierr = DMGetGlobalVector(da, &zz);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) zz, "FFTW reconstructed vector");CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "%3-D: USFFT on vector of ");CHKERRQ(ierr); for (i = 0, N = 1; i < 3; i++) { ierr = PetscPrintf(PETSC_COMM_SELF, "dim[%d] = %d ",i,dim[i]);CHKERRQ(ierr); N *= dim[i]; } ierr = PetscPrintf(PETSC_COMM_SELF, "; total size %d \n",N);CHKERRQ(ierr); if (function == RANDOM) { ierr = PetscRandomCreate(PETSC_COMM_SELF, &rdm);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr); ierr = VecSetRandom(x, rdm);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rdm);CHKERRQ(ierr); } else if (function == CONSTANT) { ierr = VecSet(x, 1.0);CHKERRQ(ierr); } else if (function == TANH) { PetscScalar *a; ierr = VecGetArray(x, &a);CHKERRQ(ierr); PetscInt j,k = 0; for (i = 0; i < 3; ++i) { for (j = 0; j < dim[i]; ++j) { a[k] = tanh((j - dim[i]/2.0)*(10.0/dim[i])); ++k; } } ierr = VecRestoreArray(x, &a);CHKERRQ(ierr); } if (view_x) { ierr = VecView(x, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = VecCopy(x,xx);CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "|x|_2 = %g\n",norm);CHKERRQ(ierr); /* create USFFT object */ ierr = MatCreateSeqUSFFT(coords,da,&A);CHKERRQ(ierr); /* create FFTW object */ ierr = MatCreateSeqFFTW(PETSC_COMM_SELF,3,dim,&AA);CHKERRQ(ierr); /* apply USFFT and FFTW FORWARD "preemptively", so the fftw_plans can be reused on different vectors */ ierr = MatMult(A,x,z);CHKERRQ(ierr); ierr = MatMult(AA,xx,zz);CHKERRQ(ierr); /* Now apply USFFT and FFTW forward several (3) times */ for (i=0; i<3; ++i) { ierr = MatMult(A,x,y);CHKERRQ(ierr); ierr = MatMult(AA,xx,yy);CHKERRQ(ierr); ierr = MatMultTranspose(A,y,z);CHKERRQ(ierr); ierr = MatMultTranspose(AA,yy,zz);CHKERRQ(ierr); } if (view_y) { ierr = PetscPrintf(PETSC_COMM_WORLD, "y = \n");CHKERRQ(ierr); ierr = VecView(y, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "yy = \n");CHKERRQ(ierr); ierr = VecView(yy, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } if (view_z) { ierr = PetscPrintf(PETSC_COMM_WORLD, "z = \n");CHKERRQ(ierr); ierr = VecView(z, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "zz = \n");CHKERRQ(ierr); ierr = VecView(zz, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } /* compare x and z. USFFT computes an unnormalized DFT, thus z = N*x */ s = 1.0/(PetscReal)N; ierr = VecScale(z,s);CHKERRQ(ierr); ierr = VecAXPY(x,-1.0,z);CHKERRQ(ierr); ierr = VecNorm(x,NORM_1,&enorm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "|x-z| = %g\n",enorm);CHKERRQ(ierr); /* compare xx and zz. FFTW computes an unnormalized DFT, thus zz = N*x */ s = 1.0/(PetscReal)N; ierr = VecScale(zz,s);CHKERRQ(ierr); ierr = VecAXPY(xx,-1.0,zz);CHKERRQ(ierr); ierr = VecNorm(xx,NORM_1,&enorm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "|xx-zz| = %g\n",enorm);CHKERRQ(ierr); /* compare y and yy: USFFT and FFTW results*/ ierr = VecNorm(y,NORM_2,&norm);CHKERRQ(ierr); ierr = VecAXPY(y,-1.0,yy);CHKERRQ(ierr); ierr = VecNorm(y,NORM_1,&enorm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "|y|_2 = %g\n",norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "|y-yy| = %g\n",enorm);CHKERRQ(ierr); /* compare z and zz: USFFT and FFTW results*/ ierr = VecNorm(z,NORM_2,&norm);CHKERRQ(ierr); ierr = VecAXPY(z,-1.0,zz);CHKERRQ(ierr); ierr = VecNorm(z,NORM_1,&enorm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "|z|_2 = %g\n",norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "|z-zz| = %g\n",enorm);CHKERRQ(ierr); /* free spaces */ ierr = DMRestoreGlobalVector(da,&x);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&xx);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&y);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&yy);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&z);CHKERRQ(ierr); ierr = DMRestoreGlobalVector(da,&zz);CHKERRQ(ierr); ierr = VecDestroy(&coords);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) { PetscInt dim = user->dim; const char *filename = user->filename; PetscBool interpolate = user->interpolate; PetscReal refinementLimit = user->refinementLimit; PetscBool refinementUniform = user->refinementUniform; PetscInt refinementRounds = user->refinementRounds; const char *partitioner = user->partitioner; size_t len; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = PetscLogEventBegin(user->createMeshEvent,0,0,0,0);CHKERRQ(ierr); ierr = PetscStrlen(filename, &len);CHKERRQ(ierr); if (!len) { ierr = DMPlexCreateBoxMesh(comm, dim, interpolate, dm);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) *dm, "Mesh");CHKERRQ(ierr); } else if (user->checkpoint) { ierr = DMCreate(comm, dm);CHKERRQ(ierr); ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); ierr = DMLoad(*dm, user->checkpoint);CHKERRQ(ierr); ierr = DMPlexSetRefinementUniform(*dm, PETSC_FALSE);CHKERRQ(ierr); } else { PetscMPIInt rank; ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); ierr = DMPlexCreateExodusFromFile(comm, filename, interpolate, dm);CHKERRQ(ierr); ierr = DMPlexSetRefinementUniform(*dm, PETSC_FALSE);CHKERRQ(ierr); /* Must have boundary marker for Dirichlet conditions */ } { DM refinedMesh = NULL; DM distributedMesh = NULL; /* Refine mesh using a volume constraint */ ierr = DMPlexSetRefinementLimit(*dm, refinementLimit);CHKERRQ(ierr); ierr = DMRefine(*dm, comm, &refinedMesh);CHKERRQ(ierr); if (refinedMesh) { const char *name; ierr = PetscObjectGetName((PetscObject) *dm, &name);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) refinedMesh, name);CHKERRQ(ierr); ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = refinedMesh; } /* Distribute mesh over processes */ ierr = DMPlexDistribute(*dm, partitioner, 0, NULL, &distributedMesh);CHKERRQ(ierr); if (distributedMesh) { ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = distributedMesh; } /* Use regular refinement in parallel */ if (refinementUniform) { PetscInt r; ierr = DMPlexSetRefinementUniform(*dm, refinementUniform);CHKERRQ(ierr); for (r = 0; r < refinementRounds; ++r) { ierr = DMRefine(*dm, comm, &refinedMesh);CHKERRQ(ierr); if (refinedMesh) { ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = refinedMesh; } } } } ierr = DMSetFromOptions(*dm);CHKERRQ(ierr); if (user->bcType == NEUMANN) { DMLabel label; ierr = DMPlexCreateLabel(*dm, "boundary");CHKERRQ(ierr); ierr = DMPlexGetLabel(*dm, "boundary", &label);CHKERRQ(ierr); ierr = DMPlexMarkBoundaryFaces(*dm, label);CHKERRQ(ierr); } ierr = DMViewFromOptions(*dm, NULL, "-dm_view");CHKERRQ(ierr); ierr = PetscLogEventEnd(user->createMeshEvent,0,0,0,0);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode SetupDiscretization(DM dm, AppCtx *user) { DM cdm = dm; const PetscInt dim = user->dim; const PetscInt id = 1; PetscFE feAux = NULL; PetscFE feBd = NULL; PetscFE feCh = NULL; PetscFE fe; PetscDS prob; PetscErrorCode ierr; PetscFunctionBeginUser; /* Create finite element */ ierr = PetscFECreateDefault(dm, dim, 1, PETSC_TRUE, NULL, -1, &fe);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) fe, "potential");CHKERRQ(ierr); if (user->bcType == NEUMANN) { ierr = PetscFECreateDefault(dm, dim-1, 1, PETSC_TRUE, "bd_", -1, &feBd);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) feBd, "potential");CHKERRQ(ierr); } if (user->variableCoefficient == COEFF_FIELD) { PetscQuadrature q; ierr = PetscFECreateDefault(dm, dim, 1, PETSC_TRUE, "mat_", -1, &feAux);CHKERRQ(ierr); ierr = PetscFEGetQuadrature(fe, &q);CHKERRQ(ierr); ierr = PetscFESetQuadrature(feAux, q);CHKERRQ(ierr); } if (user->check) {ierr = PetscFECreateDefault(dm, dim, 1, PETSC_TRUE, "ch_", -1, &feCh);CHKERRQ(ierr);} /* Set discretization and boundary conditions for each mesh */ while (cdm) { ierr = DMGetDS(cdm, &prob);CHKERRQ(ierr); ierr = PetscDSSetDiscretization(prob, 0, (PetscObject) fe);CHKERRQ(ierr); ierr = PetscDSSetBdDiscretization(prob, 0, (PetscObject) feBd);CHKERRQ(ierr); if (feAux) { DM dmAux; PetscDS probAux; ierr = DMClone(cdm, &dmAux);CHKERRQ(ierr); ierr = DMPlexCopyCoordinates(cdm, dmAux);CHKERRQ(ierr); ierr = DMGetDS(dmAux, &probAux);CHKERRQ(ierr); ierr = PetscDSSetDiscretization(probAux, 0, (PetscObject) feAux);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dm, "dmAux", (PetscObject) dmAux);CHKERRQ(ierr); ierr = SetupMaterial(cdm, dmAux, user);CHKERRQ(ierr); ierr = DMDestroy(&dmAux);CHKERRQ(ierr); } if (feCh) { DM dmCh; PetscDS probCh; ierr = DMClone(cdm, &dmCh);CHKERRQ(ierr); ierr = DMPlexCopyCoordinates(cdm, dmCh);CHKERRQ(ierr); ierr = DMGetDS(dmCh, &probCh);CHKERRQ(ierr); ierr = PetscDSSetDiscretization(probCh, 0, (PetscObject) feCh);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dm, "dmCh", (PetscObject) dmCh);CHKERRQ(ierr); ierr = DMDestroy(&dmCh);CHKERRQ(ierr); } ierr = SetupProblem(cdm, user);CHKERRQ(ierr); ierr = DMPlexAddBoundary(cdm, user->bcType == DIRICHLET, "wall", user->bcType == NEUMANN ? "boundary" : "marker", 0, user->exactFuncs[0], 1, &id, user);CHKERRQ(ierr); ierr = DMPlexGetCoarseDM(cdm, &cdm);CHKERRQ(ierr); } ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); ierr = PetscFEDestroy(&feBd);CHKERRQ(ierr); ierr = PetscFEDestroy(&feAux);CHKERRQ(ierr); ierr = PetscFEDestroy(&feCh);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc, char *argv[]) { PetscErrorCode ierr; DM dau,dak,pack; const PetscInt *lxu; PetscInt *lxk,m,sizes; User user; SNES snes; Vec X,F,Xu,Xk,Fu,Fk; Mat B; IS *isg; PetscBool view_draw,pass_dm; PetscInitialize(&argc,&argv,0,help); ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,-10,1,1,NULL,&dau);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(dau,"u_");CHKERRQ(ierr); ierr = DMSetFromOptions(dau);CHKERRQ(ierr); ierr = DMDAGetOwnershipRanges(dau,&lxu,0,0);CHKERRQ(ierr); ierr = DMDAGetInfo(dau,0, &m,0,0, &sizes,0,0, 0,0,0,0,0,0);CHKERRQ(ierr); ierr = PetscMalloc1(sizes,&lxk);CHKERRQ(ierr); ierr = PetscMemcpy(lxk,lxu,sizes*sizeof(*lxk));CHKERRQ(ierr); lxk[0]--; ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,m-1,1,1,lxk,&dak);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(dak,"k_");CHKERRQ(ierr); ierr = DMSetFromOptions(dak);CHKERRQ(ierr); ierr = PetscFree(lxk);CHKERRQ(ierr); ierr = DMCompositeCreate(PETSC_COMM_WORLD,&pack);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(pack,"pack_");CHKERRQ(ierr); ierr = DMCompositeAddDM(pack,dau);CHKERRQ(ierr); ierr = DMCompositeAddDM(pack,dak);CHKERRQ(ierr); ierr = DMDASetFieldName(dau,0,"u");CHKERRQ(ierr); ierr = DMDASetFieldName(dak,0,"k");CHKERRQ(ierr); ierr = DMSetFromOptions(pack);CHKERRQ(ierr); ierr = DMCreateGlobalVector(pack,&X);CHKERRQ(ierr); ierr = VecDuplicate(X,&F);CHKERRQ(ierr); ierr = PetscNew(&user);CHKERRQ(ierr); user->pack = pack; ierr = DMCompositeGetGlobalISs(pack,&isg);CHKERRQ(ierr); ierr = DMCompositeGetLocalVectors(pack,&user->Uloc,&user->Kloc);CHKERRQ(ierr); ierr = DMCompositeScatter(pack,X,user->Uloc,user->Kloc);CHKERRQ(ierr); ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Coupled problem options","SNES");CHKERRQ(ierr); { user->ptype = 0; view_draw = PETSC_FALSE; pass_dm = PETSC_TRUE; ierr = PetscOptionsInt("-problem_type","0: solve for u only, 1: solve for k only, 2: solve for both",0,user->ptype,&user->ptype,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-view_draw","Draw the final coupled solution regardless of whether only one physics was solved",0,view_draw,&view_draw,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-pass_dm","Pass the packed DM to SNES to use when determining splits and forward into splits",0,pass_dm,&pass_dm,NULL);CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = FormInitial_Coupled(user,X);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); switch (user->ptype) { case 0: ierr = DMCompositeGetAccess(pack,X,&Xu,0);CHKERRQ(ierr); ierr = DMCompositeGetAccess(pack,F,&Fu,0);CHKERRQ(ierr); ierr = DMCreateMatrix(dau,&B);CHKERRQ(ierr); ierr = SNESSetFunction(snes,Fu,FormFunction_All,user);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,B,B,FormJacobian_All,user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,dau);CHKERRQ(ierr); ierr = SNESSolve(snes,NULL,Xu);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(pack,X,&Xu,0);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(pack,F,&Fu,0);CHKERRQ(ierr); break; case 1: ierr = DMCompositeGetAccess(pack,X,0,&Xk);CHKERRQ(ierr); ierr = DMCompositeGetAccess(pack,F,0,&Fk);CHKERRQ(ierr); ierr = DMCreateMatrix(dak,&B);CHKERRQ(ierr); ierr = SNESSetFunction(snes,Fk,FormFunction_All,user);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,B,B,FormJacobian_All,user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,dak);CHKERRQ(ierr); ierr = SNESSolve(snes,NULL,Xk);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(pack,X,0,&Xk);CHKERRQ(ierr); ierr = DMCompositeRestoreAccess(pack,F,0,&Fk);CHKERRQ(ierr); break; case 2: ierr = DMCreateMatrix(pack,&B);CHKERRQ(ierr); /* This example does not correctly allocate off-diagonal blocks. These options allows new nonzeros (slow). */ ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = SNESSetFunction(snes,F,FormFunction_All,user);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,B,B,FormJacobian_All,user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); if (!pass_dm) { /* Manually provide index sets and names for the splits */ KSP ksp; PC pc; ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCFieldSplitSetIS(pc,"u",isg[0]);CHKERRQ(ierr); ierr = PCFieldSplitSetIS(pc,"k",isg[1]);CHKERRQ(ierr); } else { /* The same names come from the options prefix for dau and dak. This option can support geometric multigrid inside * of splits, but it requires using a DM (perhaps your own implementation). */ ierr = SNESSetDM(snes,pack);CHKERRQ(ierr); } ierr = SNESSolve(snes,NULL,X);CHKERRQ(ierr); break; } if (view_draw) {ierr = VecView(X,PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);} if (0) { PetscInt col = 0; PetscBool mult_dup = PETSC_FALSE,view_dup = PETSC_FALSE; Mat D; Vec Y; ierr = PetscOptionsGetInt(0,"-col",&col,0);CHKERRQ(ierr); ierr = PetscOptionsGetBool(0,"-mult_dup",&mult_dup,0);CHKERRQ(ierr); ierr = PetscOptionsGetBool(0,"-view_dup",&view_dup,0);CHKERRQ(ierr); ierr = VecDuplicate(X,&Y);CHKERRQ(ierr); /* ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); */ /* ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); */ ierr = MatConvert(B,MATAIJ,MAT_INITIAL_MATRIX,&D);CHKERRQ(ierr); ierr = VecZeroEntries(X);CHKERRQ(ierr); ierr = VecSetValue(X,col,1.0,INSERT_VALUES);CHKERRQ(ierr); ierr = VecAssemblyBegin(X);CHKERRQ(ierr); ierr = VecAssemblyEnd(X);CHKERRQ(ierr); ierr = MatMult(mult_dup ? D : B,X,Y);CHKERRQ(ierr); ierr = MatView(view_dup ? D : B,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* ierr = VecView(X,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); */ ierr = VecView(Y,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatDestroy(&D);CHKERRQ(ierr); ierr = VecDestroy(&Y);CHKERRQ(ierr); } ierr = DMCompositeRestoreLocalVectors(pack,&user->Uloc,&user->Kloc);CHKERRQ(ierr); ierr = PetscFree(user);CHKERRQ(ierr); ierr = ISDestroy(&isg[0]);CHKERRQ(ierr); ierr = ISDestroy(&isg[1]);CHKERRQ(ierr); ierr = PetscFree(isg);CHKERRQ(ierr); ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&F);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = DMDestroy(&dau);CHKERRQ(ierr); ierr = DMDestroy(&dak);CHKERRQ(ierr); ierr = DMDestroy(&pack);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); PetscFinalize(); return 0; }
int main(int argc,char **argv) { PetscErrorCode ierr; DM da; /* Initialize the Petsc context */ ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); /* Build of the DMDA -- 1D -- boundary_none */ ierr = PetscPrintf(PETSC_COMM_WORLD,"1D -- DMDA_BOUNDARY_NONE\n");CHKERRQ(ierr); ierr = DMDACreate(PETSC_COMM_WORLD, &da);CHKERRQ(ierr); ierr = DMDASetDim(da, 1);CHKERRQ(ierr); ierr = DMDASetSizes(da, -8, 1, 1);CHKERRQ(ierr); ierr = DMDASetBoundaryType(da, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE);CHKERRQ(ierr); ierr = DMDASetDof(da, 1);CHKERRQ(ierr); ierr = DMDASetStencilWidth(da, 1);CHKERRQ(ierr); ierr = DMDASetOverlap(da,1,1,1);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(da,"n1d_");CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMView(da,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); /* Build of the DMDA -- 1D -- boundary_ghosted */ ierr = PetscPrintf(PETSC_COMM_WORLD,"1D -- DMDA_BOUNDARY_GHOSTED\n");CHKERRQ(ierr); ierr = DMDACreate(PETSC_COMM_WORLD, &da);CHKERRQ(ierr); ierr = DMDASetDim(da, 1);CHKERRQ(ierr); ierr = DMDASetSizes(da, -8, 1, 1);CHKERRQ(ierr); ierr = DMDASetBoundaryType(da, DMDA_BOUNDARY_GHOSTED, DMDA_BOUNDARY_GHOSTED, DMDA_BOUNDARY_GHOSTED);CHKERRQ(ierr); ierr = DMDASetDof(da, 2);CHKERRQ(ierr); ierr = DMDASetStencilWidth(da, 1);CHKERRQ(ierr); ierr = DMDASetOverlap(da,1,1,1);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(da,"g1d_");CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMView(da,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); /* Build of the DMDA -- 1D -- boundary_periodic */ ierr = PetscPrintf(PETSC_COMM_WORLD,"1D -- DMDA_BOUNDARY_PERIODIC\n");CHKERRQ(ierr); ierr = DMDACreate(PETSC_COMM_WORLD, &da);CHKERRQ(ierr); ierr = DMDASetDim(da, 1);CHKERRQ(ierr); ierr = DMDASetSizes(da, -8, 1, 1);CHKERRQ(ierr); ierr = DMDASetBoundaryType(da, DMDA_BOUNDARY_PERIODIC, DMDA_BOUNDARY_PERIODIC, DMDA_BOUNDARY_PERIODIC);CHKERRQ(ierr); ierr = DMDASetDof(da, 2);CHKERRQ(ierr); ierr = DMDASetStencilWidth(da, 1);CHKERRQ(ierr); ierr = DMDASetOverlap(da,1,1,1);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(da,"p1d_");CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMView(da,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); /* Build of the DMDA -- 2D -- boundary_none */ ierr = PetscPrintf(PETSC_COMM_WORLD,"2D -- DMDA_BOUNDARY_NONE\n");CHKERRQ(ierr); ierr = DMDACreate(PETSC_COMM_WORLD, &da);CHKERRQ(ierr); ierr = DMDASetDim(da, 2);CHKERRQ(ierr); ierr = DMDASetSizes(da, -8, -8, 1);CHKERRQ(ierr); ierr = DMDASetBoundaryType(da, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE);CHKERRQ(ierr); ierr = DMDASetDof(da, 2);CHKERRQ(ierr); ierr = DMDASetStencilWidth(da, 1);CHKERRQ(ierr); ierr = DMDASetOverlap(da,1,1,1);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(da,"n2d_");CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMView(da,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); /* Build of the DMDA -- 2D -- boundary_ghosted */ ierr = PetscPrintf(PETSC_COMM_WORLD,"2D -- DMDA_BOUNDARY_GHOSTED\n");CHKERRQ(ierr); ierr = DMDACreate(PETSC_COMM_WORLD, &da);CHKERRQ(ierr); ierr = DMDASetDim(da, 2);CHKERRQ(ierr); ierr = DMDASetSizes(da, -8, -8, 1);CHKERRQ(ierr); ierr = DMDASetBoundaryType(da, DMDA_BOUNDARY_GHOSTED, DMDA_BOUNDARY_GHOSTED, DMDA_BOUNDARY_GHOSTED);CHKERRQ(ierr); ierr = DMDASetDof(da, 2);CHKERRQ(ierr); ierr = DMDASetStencilWidth(da, 1);CHKERRQ(ierr); ierr = DMDASetOverlap(da,1,1,1);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(da,"g2d_");CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMView(da,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); /* Build of the DMDA -- 2D -- boundary_periodic */ ierr = PetscPrintf(PETSC_COMM_WORLD,"2D -- DMDA_BOUNDARY_PERIODIC\n");CHKERRQ(ierr); ierr = DMDACreate(PETSC_COMM_WORLD, &da);CHKERRQ(ierr); ierr = DMDASetDim(da, 2);CHKERRQ(ierr); ierr = DMDASetSizes(da, -8, -8, 1);CHKERRQ(ierr); ierr = DMDASetBoundaryType(da, DMDA_BOUNDARY_PERIODIC, DMDA_BOUNDARY_PERIODIC, DMDA_BOUNDARY_PERIODIC);CHKERRQ(ierr); ierr = DMDASetDof(da, 2);CHKERRQ(ierr); ierr = DMDASetStencilWidth(da, 1);CHKERRQ(ierr); ierr = DMDASetOverlap(da,1,1,1);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(da,"p2d_");CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMView(da,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); /* Build of the DMDA -- 3D -- boundary_none */ ierr = PetscPrintf(PETSC_COMM_WORLD,"3D -- DMDA_BOUNDARY_NONE\n");CHKERRQ(ierr); ierr = DMDACreate(PETSC_COMM_WORLD, &da);CHKERRQ(ierr); ierr = DMDASetDim(da, 3);CHKERRQ(ierr); ierr = DMDASetSizes(da, -8, -8, -8);CHKERRQ(ierr); ierr = DMDASetBoundaryType(da, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE);CHKERRQ(ierr); ierr = DMDASetDof(da, 2);CHKERRQ(ierr); ierr = DMDASetStencilWidth(da, 1);CHKERRQ(ierr); ierr = DMDASetOverlap(da,1,1,1);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(da,"n3d_");CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMView(da,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); /* Build of the DMDA -- 3D -- boundary_ghosted */ ierr = PetscPrintf(PETSC_COMM_WORLD,"3D -- DMDA_BOUNDARY_GHOSTED\n");CHKERRQ(ierr); ierr = DMDACreate(PETSC_COMM_WORLD, &da);CHKERRQ(ierr); ierr = DMDASetDim(da, 3);CHKERRQ(ierr); ierr = DMDASetSizes(da, -8, -8, -8);CHKERRQ(ierr); ierr = DMDASetBoundaryType(da, DMDA_BOUNDARY_GHOSTED, DMDA_BOUNDARY_GHOSTED, DMDA_BOUNDARY_GHOSTED);CHKERRQ(ierr); ierr = DMDASetDof(da, 2);CHKERRQ(ierr); ierr = DMDASetStencilWidth(da, 1);CHKERRQ(ierr); ierr = DMDASetOverlap(da,1,1,1);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(da,"g3d_");CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMView(da,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); /* Build of the DMDA -- 3D -- boundary_periodic */ ierr = PetscPrintf(PETSC_COMM_WORLD,"3D -- DMDA_BOUNDARY_PERIODIC\n");CHKERRQ(ierr); ierr = DMDACreate(PETSC_COMM_WORLD, &da);CHKERRQ(ierr); ierr = DMDASetDim(da, 3);CHKERRQ(ierr); ierr = DMDASetSizes(da, -8, -8, -8);CHKERRQ(ierr); ierr = DMDASetBoundaryType(da, DMDA_BOUNDARY_PERIODIC, DMDA_BOUNDARY_PERIODIC, DMDA_BOUNDARY_PERIODIC);CHKERRQ(ierr); ierr = DMDASetDof(da, 2);CHKERRQ(ierr); ierr = DMDASetStencilWidth(da, 1);CHKERRQ(ierr); ierr = DMDASetOverlap(da,1,1,1);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(da,"p3d_");CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMView(da,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); /* test moving data in and out */ ierr = PetscFinalize(); return 0; }
/* Mm_ratio - ration of grid lines between fine and coarse grids. */ int main(int argc,char **argv) { PetscErrorCode ierr; AppCtx user; PetscMPIInt size,rank; PetscInt m,n,M,N,i,nrows; PetscScalar one = 1.0; PetscReal fill=2.0; Mat A,P,R,C,PtAP; PetscScalar *array; PetscRandom rdm; PetscBool Test_3D=PETSC_FALSE,flg; const PetscInt *ia,*ja; ierr = PetscInitialize(&argc,&argv,NULL,help);if (ierr) return ierr; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); /* Get size of fine grids and coarse grids */ user.ratio = 2; user.coarse.mx = 4; user.coarse.my = 4; user.coarse.mz = 4; ierr = PetscOptionsGetInt(NULL,NULL,"-Mx",&user.coarse.mx,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-My",&user.coarse.my,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-Mz",&user.coarse.mz,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-ratio",&user.ratio,NULL);CHKERRQ(ierr); if (user.coarse.mz) Test_3D = PETSC_TRUE; user.fine.mx = user.ratio*(user.coarse.mx-1)+1; user.fine.my = user.ratio*(user.coarse.my-1)+1; user.fine.mz = user.ratio*(user.coarse.mz-1)+1; if (!rank) { if (!Test_3D) { ierr = PetscPrintf(PETSC_COMM_SELF,"coarse grids: %D %D; fine grids: %D %D\n",user.coarse.mx,user.coarse.my,user.fine.mx,user.fine.my);CHKERRQ(ierr); } else { ierr = PetscPrintf(PETSC_COMM_SELF,"coarse grids: %D %D %D; fine grids: %D %D %D\n",user.coarse.mx,user.coarse.my,user.coarse.mz,user.fine.mx,user.fine.my,user.fine.mz);CHKERRQ(ierr); } } /* Set up distributed array for fine grid */ if (!Test_3D) { ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,user.fine.mx,user.fine.my,PETSC_DECIDE,PETSC_DECIDE,1,1,NULL,NULL,&user.fine.da);CHKERRQ(ierr); } else { ierr = DMDACreate3d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,user.fine.mx,user.fine.my,user.fine.mz,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE, 1,1,NULL,NULL,NULL,&user.fine.da);CHKERRQ(ierr); } ierr = DMSetFromOptions(user.fine.da);CHKERRQ(ierr); ierr = DMSetUp(user.fine.da);CHKERRQ(ierr); /* Create and set A at fine grids */ ierr = DMSetMatType(user.fine.da,MATAIJ);CHKERRQ(ierr); ierr = DMCreateMatrix(user.fine.da,&A);CHKERRQ(ierr); ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); /* set val=one to A (replace with random values!) */ ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rdm);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr); if (size == 1) { ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&nrows,&ia,&ja,&flg);CHKERRQ(ierr); if (flg) { ierr = MatSeqAIJGetArray(A,&array);CHKERRQ(ierr); for (i=0; i<ia[nrows]; i++) array[i] = one; ierr = MatSeqAIJRestoreArray(A,&array);CHKERRQ(ierr); } ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&nrows,&ia,&ja,&flg);CHKERRQ(ierr); } else { Mat AA,AB; ierr = MatMPIAIJGetSeqAIJ(A,&AA,&AB,NULL);CHKERRQ(ierr); ierr = MatGetRowIJ(AA,0,PETSC_FALSE,PETSC_FALSE,&nrows,&ia,&ja,&flg);CHKERRQ(ierr); if (flg) { ierr = MatSeqAIJGetArray(AA,&array);CHKERRQ(ierr); for (i=0; i<ia[nrows]; i++) array[i] = one; ierr = MatSeqAIJRestoreArray(AA,&array);CHKERRQ(ierr); } ierr = MatRestoreRowIJ(AA,0,PETSC_FALSE,PETSC_FALSE,&nrows,&ia,&ja,&flg);CHKERRQ(ierr); ierr = MatGetRowIJ(AB,0,PETSC_FALSE,PETSC_FALSE,&nrows,&ia,&ja,&flg);CHKERRQ(ierr); if (flg) { ierr = MatSeqAIJGetArray(AB,&array);CHKERRQ(ierr); for (i=0; i<ia[nrows]; i++) array[i] = one; ierr = MatSeqAIJRestoreArray(AB,&array);CHKERRQ(ierr); } ierr = MatRestoreRowIJ(AB,0,PETSC_FALSE,PETSC_FALSE,&nrows,&ia,&ja,&flg);CHKERRQ(ierr); } /* Set up distributed array for coarse grid */ if (!Test_3D) { ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,user.coarse.mx,user.coarse.my,PETSC_DECIDE,PETSC_DECIDE,1,1,NULL,NULL,&user.coarse.da);CHKERRQ(ierr); } else { ierr = DMDACreate3d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,user.coarse.mx,user.coarse.my,user.coarse.mz,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,1,1,NULL,NULL,NULL,&user.coarse.da);CHKERRQ(ierr); } ierr = DMSetFromOptions(user.coarse.da);CHKERRQ(ierr); ierr = DMSetUp(user.coarse.da);CHKERRQ(ierr); /* Create interpolation between the fine and coarse grids */ ierr = DMCreateInterpolation(user.coarse.da,user.fine.da,&P,NULL);CHKERRQ(ierr); /* Get R = P^T */ ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&R);CHKERRQ(ierr); /* C = R*A*P */ ierr = MatMatMatMult(R,A,P,MAT_INITIAL_MATRIX,fill,&C);CHKERRQ(ierr); ierr = MatMatMatMult(R,A,P,MAT_REUSE_MATRIX,fill,&C);CHKERRQ(ierr); /* Test C == PtAP */ ierr = MatPtAP(A,P,MAT_INITIAL_MATRIX,fill,&PtAP);CHKERRQ(ierr); ierr = MatPtAP(A,P,MAT_REUSE_MATRIX,fill,&PtAP);CHKERRQ(ierr); ierr = MatEqual(C,PtAP,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Matrices are not equal"); ierr = MatDestroy(&PtAP);CHKERRQ(ierr); /* Clean up */ ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rdm);CHKERRQ(ierr); ierr = DMDestroy(&user.fine.da);CHKERRQ(ierr); ierr = DMDestroy(&user.coarse.da);CHKERRQ(ierr); ierr = MatDestroy(&P);CHKERRQ(ierr); ierr = MatDestroy(&R);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **argv) { PetscInt M1 = 3,M2,dof = 1,s = 1,ratio = 2,dim = 1; PetscErrorCode ierr; DM da_c,da_f; Vec v_c,v_f; Mat Interp; PetscScalar one = 1.0; PetscBool pt; DMDABoundaryType bx = DMDA_BOUNDARY_NONE,by = DMDA_BOUNDARY_NONE,bz = DMDA_BOUNDARY_NONE; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-dim",&dim,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-M",&M1,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-stencil_width",&s,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-ratio",&ratio,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-dof",&dof,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-periodic",(PetscBool*)&pt,NULL);CHKERRQ(ierr); if (pt) { if (dim > 0) bx = DMDA_BOUNDARY_PERIODIC; if (dim > 1) by = DMDA_BOUNDARY_PERIODIC; if (dim > 2) bz = DMDA_BOUNDARY_PERIODIC; } if (bx == DMDA_BOUNDARY_NONE) { M2 = ratio*(M1-1) + 1; } else { M2 = ratio*M1; } /* Set up the array */ if (dim == 1) { ierr = DMDACreate1d(PETSC_COMM_WORLD,bx,M1,dof,s,NULL,&da_c);CHKERRQ(ierr); ierr = DMDACreate1d(PETSC_COMM_WORLD,bx,M2,dof,s,NULL,&da_f);CHKERRQ(ierr); } else if (dim == 2) { ierr = DMDACreate2d(PETSC_COMM_WORLD,bx,by,DMDA_STENCIL_BOX,M1,M1,PETSC_DECIDE,PETSC_DECIDE,dof,s,NULL,NULL,&da_c);CHKERRQ(ierr); ierr = DMDACreate2d(PETSC_COMM_WORLD,bx,by,DMDA_STENCIL_BOX,M2,M2,PETSC_DECIDE,PETSC_DECIDE,dof,s,NULL,NULL,&da_f);CHKERRQ(ierr); } else if (dim == 3) { ierr = DMDACreate3d(PETSC_COMM_WORLD,bx,by,bz,DMDA_STENCIL_BOX,M1,M1,M1,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,dof,s,NULL,NULL,NULL,&da_c);CHKERRQ(ierr); ierr = DMDACreate3d(PETSC_COMM_WORLD,bx,by,bz,DMDA_STENCIL_BOX,M2,M2,M2,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,dof,s,NULL,NULL,NULL,&da_f);CHKERRQ(ierr); } else SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"dim must be 1,2, or 3"); ierr = DMCreateGlobalVector(da_c,&v_c);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da_f,&v_f);CHKERRQ(ierr); ierr = VecSet(v_c,one);CHKERRQ(ierr); ierr = DMCreateInterpolation(da_c,da_f,&Interp,NULL);CHKERRQ(ierr); ierr = MatMult(Interp,v_c,v_f);CHKERRQ(ierr); ierr = VecView(v_f,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatMultTranspose(Interp,v_f,v_c);CHKERRQ(ierr); ierr = VecView(v_c,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatDestroy(&Interp);CHKERRQ(ierr); ierr = VecDestroy(&v_c);CHKERRQ(ierr); ierr = DMDestroy(&da_c);CHKERRQ(ierr); ierr = VecDestroy(&v_f);CHKERRQ(ierr); ierr = DMDestroy(&da_f);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { SNES snes; /* nonlinear solver */ AppCtx user; /* user-defined work context */ PetscInt its; /* iterations for convergence */ PetscErrorCode ierr; DM da; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize program - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ PetscInitialize(&argc,&argv,(char*)0,help); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Initialize problem parameters - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "", "Surface Process Problem Options", "SNES");CHKERRQ(ierr); user.D = 1.0; ierr = PetscOptionsReal("-D", "The diffusion coefficient D", __FILE__, user.D, &user.D, NULL);CHKERRQ(ierr); user.K = 1.0; ierr = PetscOptionsReal("-K", "The advection coefficient K", __FILE__, user.K, &user.K, NULL);CHKERRQ(ierr); user.m = 1; ierr = PetscOptionsInt("-m", "The exponent for A", __FILE__, user.m, &user.m, NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array (DMDA) to manage parallel grid and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate2d(PETSC_COMM_WORLD, DMDA_BOUNDARY_NONE, DMDA_BOUNDARY_NONE,DMDA_STENCIL_STAR,-4,-4,PETSC_DECIDE,PETSC_DECIDE,1,1,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0);CHKERRQ(ierr); ierr = DMSetApplicationContext(da,&user);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD, &snes);CHKERRQ(ierr); ierr = SNESSetDM(snes, da);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set local function evaluation routine - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDASNESSetFunctionLocal(da,INSERT_VALUES,(PetscErrorCode (*)(DMDALocalInfo*,void*,void*,void*))FormFunctionLocal,&user);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Customize solver; set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESSolve(snes,0,0);CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = PetscPrintf(PETSC_COMM_WORLD,"Number of SNES iterations = %D\n",its);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. All PETSc objects should be destroyed when they are no longer needed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }
int main(int argc,char **argv) { Userctx user; Vec p; PetscScalar *x_ptr; PetscErrorCode ierr; PetscMPIInt size; PetscInt i,numDataBuses; KSP ksp; PC pc; Tao tao; TaoConvergedReason reason; Vec lowerb,upperb; PetscViewer viewer; PetscScalar *proj_vec; //PetscLogDouble t0,t1; /* time the inversion process */ //ierr = PetscGetTime(&t0);CHKERRQ(ierr); ierr = PetscInitialize(&argc,&argv,"petscoptions",help);CHKERRQ(ierr); PetscFunctionBeginUser; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size > 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Only for sequential runs"); ierr = ModelSetup(&user);CHKERRQ(ierr); /* hard code the data projection here - for now assume data at all buses */ ierr = VecCreateSeq(PETSC_COMM_WORLD,nbus,&user.proj);CHKERRQ(ierr); /*ierr = VecCreateSeq(PETSC_COMM_WORLD,4,&user.proj);CHKERRQ(ierr);*/ ierr = VecGetArray(user.proj,&proj_vec);CHKERRQ(ierr); for(i=0; i<nbus; i++) { proj_vec[i]=i; } srand( time(NULL) + rand () ); //VecView(user.proj, PETSC_VIEWER_STDOUT_WORLD); /* -- 2 5 6 8 */ /* -- proj_vec[0]=1; proj_vec[1]=4; proj_vec[2]=5; proj_vec[3]=7; */ ierr = VecRestoreArray(user.proj,&proj_vec);CHKERRQ(ierr); /* allocate/set the prior mean and its standard deviation */ ierr = PetscMalloc(3*sizeof(PetscScalar), &user.prior_mean); ierr = PetscMalloc(3*sizeof(PetscScalar), &user.prior_stddev); /*{23.64,6.4,3.01};*/ user.prior_mean[0] = 24.0; user.prior_mean[1] = 6.0; user.prior_mean[2] = 3.1; for(i=0; i<3; i++) user.prior_stddev[i] = user.prior_mean[i]*user.prior_noise; /* Create matrix to store solution */ if(user.saveSol) { ierr = MatCreateSeqDense(PETSC_COMM_SELF, user.neqs_pgrid+1, (PetscInt) round((user.tfinal-user.t0)/user.dt+1), NULL, &user.Sol); CHKERRQ(ierr); } printf("Num cols=%d\n", (PetscInt) round((user.tfinal-user.t0)/user.dt+1)); /* ********************************* * Generate/load observations **********************************/ ierr = VecGetSize(user.proj, &numDataBuses);CHKERRQ(ierr); /* Create matrix to save solutions at each time step */ ierr = MatCreateSeqDense(PETSC_COMM_SELF, 2*numDataBuses, //(PetscInt) round((user.tfinal-user.tdisturb)/user.data_dt)+1, (PetscInt) round((user.tfinal-user.trestore)/user.data_dt)+1, NULL, &user.obs); CHKERRQ(ierr); ierr = InitializeData(H0, &user, user.data_noise, user.data_dt);CHKERRQ(ierr); if(0==strlen(user.loadObsFile)) { /* save observations */ ierr = PetscViewerBinaryOpen(PETSC_COMM_SELF,"obs-perturbed.bin",FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); ierr = MatView(user.obs,viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); printf("Observations generated.\n"); } if(user.saveSol) { ierr = PetscViewerBinaryOpen(PETSC_COMM_SELF,"out_pert.bin",FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); ierr = MatView(user.Sol,viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = MatDestroy(&user.Sol);CHKERRQ(ierr); CHKERRQ(ierr); } if(user.outputCov) { printf("The diagonal of the data noise covariance matrix (%g absolute noise) is:\n", user.data_noise); for(i=0; i<2*numDataBuses; i++) printf("%18.12f ", user.data_stddev[i]*user.data_stddev[i]); printf("\n"); printf("The prior mean is: "); for(i=0; i<3; i++) printf("%18.12f ", user.prior_mean[i]); printf("\n"); printf("The diagonal of the prior covariance matrix (%g relative noise) is:\n", user.prior_noise); for(i=0; i<3; i++) printf("%18.12f ", user.prior_stddev[i]*user.prior_stddev[i]); printf("\n"); goto finalize; } /* *************************************** * Optimization phase * ***************************************/ /* Create TAO solver and set desired solution method */ ierr = TaoCreate(PETSC_COMM_WORLD,&tao);CHKERRQ(ierr); ierr = TaoSetType(tao,TAOBLMVM);CHKERRQ(ierr); /* Optimization starts */ printf("Starting optimization...\n"); /* PetscScalar H_disturb[3]= {25.,6.4,3.01}; New inertia (after tdisturb) to be estimated */ /* Set initial solution guess */ ierr = VecCreateSeq(PETSC_COMM_WORLD,3,&p);CHKERRQ(ierr); ierr = VecGetArray(p,&x_ptr);CHKERRQ(ierr); //x_ptr[0] = H0[0]; x_ptr[1] = H0[1]; x_ptr[2] = H0[2]; x_ptr[0] = H0[0]*1.1; x_ptr[1] = H0[1]*1.1; x_ptr[2] = H0[2]*1.1; ierr = VecRestoreArray(p,&x_ptr);CHKERRQ(ierr); ierr = TaoSetInitialVector(tao,p);CHKERRQ(ierr); /* Set routine for function and gradient evaluation */ //ierr = TaoSetObjectiveRoutine(tao,FormFunction,(void *)&user);CHKERRQ(ierr); //ierr = TaoSetGradientRoutine(tao,TaoDefaultComputeGradient,(void *)&user);CHKERRQ(ierr); /* Sets the cost and gradient evaluation routine for minimization */ ierr = TaoSetObjectiveAndGradientRoutine(tao,FormFunctionGradient,&user);CHKERRQ(ierr); /* Set bounds for the optimization */ ierr = VecDuplicate(p,&lowerb);CHKERRQ(ierr); ierr = VecDuplicate(p,&upperb);CHKERRQ(ierr); ierr = VecGetArray(lowerb,&x_ptr);CHKERRQ(ierr); x_ptr[0] = 20.64; x_ptr[1] = 5.4; x_ptr[2] = 2.01; ierr = VecRestoreArray(lowerb,&x_ptr);CHKERRQ(ierr); ierr = VecGetArray(upperb,&x_ptr);CHKERRQ(ierr); x_ptr[0] = 25.64; x_ptr[1] = 7.4; x_ptr[2] = 4.01; ierr = VecRestoreArray(upperb,&x_ptr);CHKERRQ(ierr); ierr = TaoSetVariableBounds(tao,lowerb,upperb); /* Check for any TAO command line options */ ierr = TaoSetFromOptions(tao);CHKERRQ(ierr); ierr = TaoGetKSP(tao,&ksp);CHKERRQ(ierr); if (ksp) { ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); } //ierr = TaoSetTolerances(tao,1e-8,1e-6,1e-8,1e-6,1e-4); ierr = TaoSetTolerances(tao,1e-8,1e-8,1e-8,1e-8,1e-6); //ierr = TaoSetGradientTolerances(tao,1e-8, 1e-6, 1e-6); /* SOLVE the estimation problem */ ierr = TaoSolve(tao); CHKERRQ(ierr); /* Get information on termination */ printf("--- optimization done\n"); /* time the inversion process */ //ierr = PetscGetTime(&t1);CHKERRQ(ierr); //printf("elapsed_time %f seconds\n", t1 - t0); ierr = TaoGetConvergedReason(tao,&reason);CHKERRQ(ierr); if (reason <= 0){ ierr=PetscPrintf(MPI_COMM_WORLD, "Try another method! \n");CHKERRQ(ierr); } /*ierr = VecView(p,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);*/ ierr = VecGetArray(p,&x_ptr);CHKERRQ(ierr); printf("inertia-out: %.12f %.12f %.12f\n", x_ptr[0], x_ptr[1], x_ptr[2]); ierr = VecRestoreArray(p,&x_ptr);CHKERRQ(ierr); //ierr = EvaluateHessianFD(tao, p, &user);CHKERRQ(ierr); /* Free TAO data structures */ ierr = TaoDestroy(&tao);CHKERRQ(ierr); ierr = VecDestroy(&lowerb);CHKERRQ(ierr); ierr = VecDestroy(&upperb);CHKERRQ(ierr); finalize: ierr = MatDestroy(&user.obs);CHKERRQ(ierr); ierr = VecDestroy(&user.X0_disturb);CHKERRQ(ierr); ierr = PetscFree(user.data_stddev);CHKERRQ(ierr); PetscFree(user.prior_mean); PetscFree(user.prior_stddev); ierr = DMDestroy(&user.dmgen);CHKERRQ(ierr); ierr = DMDestroy(&user.dmnet);CHKERRQ(ierr); ierr = DMDestroy(&user.dmpgrid);CHKERRQ(ierr); ierr = ISDestroy(&user.is_diff);CHKERRQ(ierr); ierr = ISDestroy(&user.is_alg);CHKERRQ(ierr); ierr = MatDestroy(&user.J);CHKERRQ(ierr); ierr = MatDestroy(&user.Jacp);CHKERRQ(ierr); ierr = MatDestroy(&user.Ybus);CHKERRQ(ierr); ierr = VecDestroy(&user.V0);CHKERRQ(ierr); ierr = VecDestroy(&p);CHKERRQ(ierr); ierr = PetscFinalize(); return(0); }
int main(int argc, char **argv) { DM dm; /* Problem specification */ SNES snes; /* nonlinear solver */ Vec u,r; /* solution, residual vectors */ Mat A,J; /* Jacobian matrix */ MatNullSpace nullSpace; /* May be necessary for Neumann conditions */ AppCtx user; /* user-defined work context */ JacActionCtx userJ; /* context for Jacobian MF action */ PetscInt its; /* iterations for convergence */ PetscReal error = 0.0; /* L_2 error in the solution */ PetscErrorCode ierr; ierr = PetscInitialize(&argc, &argv, NULL, help);CHKERRQ(ierr); ierr = ProcessOptions(PETSC_COMM_WORLD, &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); ierr = PetscMalloc(1 * sizeof(void (*)(const PetscReal[], PetscScalar *, void *)), &user.exactFuncs);CHKERRQ(ierr); ierr = SetupDiscretization(dm, &user);CHKERRQ(ierr); ierr = DMCreateGlobalVector(dm, &u);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) u, "potential");CHKERRQ(ierr); ierr = VecDuplicate(u, &r);CHKERRQ(ierr); ierr = DMSetMatType(dm,MATAIJ);CHKERRQ(ierr); ierr = DMCreateMatrix(dm, &J);CHKERRQ(ierr); if (user.jacobianMF) { PetscInt M, m, N, n; ierr = MatGetSize(J, &M, &N);CHKERRQ(ierr); ierr = MatGetLocalSize(J, &m, &n);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD, &A);CHKERRQ(ierr); ierr = MatSetSizes(A, m, n, M, N);CHKERRQ(ierr); ierr = MatSetType(A, MATSHELL);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); #if 0 ierr = MatShellSetOperation(A, MATOP_MULT, (void (*)(void))FormJacobianAction);CHKERRQ(ierr); #endif userJ.dm = dm; userJ.J = J; userJ.user = &user; ierr = DMCreateLocalVector(dm, &userJ.u);CHKERRQ(ierr); ierr = DMPlexProjectFunctionLocal(dm, user.exactFuncs, NULL, INSERT_BC_VALUES, userJ.u);CHKERRQ(ierr); ierr = MatShellSetContext(A, &userJ);CHKERRQ(ierr); } else { A = J; } if (user.bcType == NEUMANN) { ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject) dm), PETSC_TRUE, 0, NULL, &nullSpace);CHKERRQ(ierr); ierr = MatSetNullSpace(J, nullSpace);CHKERRQ(ierr); if (A != J) { ierr = MatSetNullSpace(A, nullSpace);CHKERRQ(ierr); } } ierr = DMSNESSetFunctionLocal(dm, (PetscErrorCode (*)(DM,Vec,Vec,void*)) DMPlexSNESComputeResidualFEM, &user);CHKERRQ(ierr); ierr = DMSNESSetJacobianLocal(dm, (PetscErrorCode (*)(DM,Vec,Mat,Mat,void*)) DMPlexSNESComputeJacobianFEM, &user);CHKERRQ(ierr); ierr = SNESSetJacobian(snes, A, J, NULL, NULL);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = DMPlexProjectFunction(dm, user.exactFuncs, NULL, INSERT_ALL_VALUES, u);CHKERRQ(ierr); if (user.checkpoint) { #if defined(PETSC_HAVE_HDF5) ierr = PetscViewerHDF5PushGroup(user.checkpoint, "/fields");CHKERRQ(ierr); ierr = VecLoad(u, user.checkpoint);CHKERRQ(ierr); ierr = PetscViewerHDF5PopGroup(user.checkpoint);CHKERRQ(ierr); #endif } ierr = PetscViewerDestroy(&user.checkpoint);CHKERRQ(ierr); if (user.showInitial) { Vec lv; ierr = DMGetLocalVector(dm, &lv);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(dm, u, INSERT_VALUES, lv);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dm, u, INSERT_VALUES, lv);CHKERRQ(ierr); ierr = DMPrintLocalVec(dm, "Local function", 1.0e-10, lv);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dm, &lv);CHKERRQ(ierr); } if (user.runType == RUN_FULL) { void (*initialGuess[1])(const PetscReal x[], PetscScalar *, void *ctx) = {zero}; ierr = DMPlexProjectFunction(dm, initialGuess, NULL, INSERT_VALUES, u);CHKERRQ(ierr); if (user.debug) { ierr = PetscPrintf(PETSC_COMM_WORLD, "Initial guess\n");CHKERRQ(ierr); ierr = VecView(u, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } ierr = SNESSolve(snes, NULL, u);CHKERRQ(ierr); ierr = SNESGetIterationNumber(snes, &its);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "Number of SNES iterations = %D\n", its);CHKERRQ(ierr); ierr = DMPlexComputeL2Diff(dm, user.exactFuncs, NULL, u, &error);CHKERRQ(ierr); if (error < 1.0e-11) {ierr = PetscPrintf(PETSC_COMM_WORLD, "L_2 Error: < 1.0e-11\n");CHKERRQ(ierr);} else {ierr = PetscPrintf(PETSC_COMM_WORLD, "L_2 Error: %g\n", error);CHKERRQ(ierr);} if (user.showSolution) { ierr = PetscPrintf(PETSC_COMM_WORLD, "Solution\n");CHKERRQ(ierr); ierr = VecChop(u, 3.0e-9);CHKERRQ(ierr); ierr = VecView(u, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); } } else if (user.runType == RUN_PERF) { PetscReal res = 0.0; ierr = SNESComputeFunction(snes, u, r);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "Initial Residual\n");CHKERRQ(ierr); ierr = VecChop(r, 1.0e-10);CHKERRQ(ierr); ierr = VecNorm(r, NORM_2, &res);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "L_2 Residual: %g\n", res);CHKERRQ(ierr); } else { PetscReal res = 0.0; /* Check discretization error */ ierr = PetscPrintf(PETSC_COMM_WORLD, "Initial guess\n");CHKERRQ(ierr); ierr = VecView(u, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMPlexComputeL2Diff(dm, user.exactFuncs, NULL, u, &error);CHKERRQ(ierr); if (error < 1.0e-11) {ierr = PetscPrintf(PETSC_COMM_WORLD, "L_2 Error: < 1.0e-11\n");CHKERRQ(ierr);} else {ierr = PetscPrintf(PETSC_COMM_WORLD, "L_2 Error: %g\n", error);CHKERRQ(ierr);} /* Check residual */ ierr = SNESComputeFunction(snes, u, r);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "Initial Residual\n");CHKERRQ(ierr); ierr = VecChop(r, 1.0e-10);CHKERRQ(ierr); ierr = VecView(r, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecNorm(r, NORM_2, &res);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "L_2 Residual: %g\n", res);CHKERRQ(ierr); /* Check Jacobian */ { Vec b; ierr = SNESComputeJacobian(snes, u, A, A);CHKERRQ(ierr); ierr = VecDuplicate(u, &b);CHKERRQ(ierr); ierr = VecSet(r, 0.0);CHKERRQ(ierr); ierr = SNESComputeFunction(snes, r, b);CHKERRQ(ierr); ierr = MatMult(A, u, r);CHKERRQ(ierr); ierr = VecAXPY(r, 1.0, b);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "Au - b = Au + F(0)\n");CHKERRQ(ierr); ierr = VecChop(r, 1.0e-10);CHKERRQ(ierr); ierr = VecView(r, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecNorm(r, NORM_2, &res);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "Linear L_2 Residual: %g\n", res);CHKERRQ(ierr); } } ierr = VecViewFromOptions(u, NULL, "-vec_view");CHKERRQ(ierr); if (user.bcType == NEUMANN) {ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr);} if (user.jacobianMF) {ierr = VecDestroy(&userJ.u);CHKERRQ(ierr);} if (A != J) {ierr = MatDestroy(&A);CHKERRQ(ierr);} ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&dm);CHKERRQ(ierr); ierr = PetscFree(user.exactFuncs);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) { DM dmDist = NULL; PetscInt dim = user->dim; PetscBool cellSimplex = user->cellSimplex; const char *filename = user->filename; const PetscInt cells[3] = {2, 2, 2}; size_t len; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = PetscStrlen(filename, &len); CHKERRQ(ierr); if (len) { ierr = DMPlexCreateFromFile(comm, filename, PETSC_TRUE, dm); CHKERRQ(ierr); } else if (cellSimplex) { ierr = DMPlexCreateBoxMesh(comm, dim, PETSC_TRUE, dm); CHKERRQ(ierr); } else { ierr = DMPlexCreateHexBoxMesh(comm, dim, cells, PETSC_FALSE, PETSC_FALSE, PETSC_FALSE, dm); CHKERRQ(ierr); } if (user->testPartition) { PetscPartitioner part; const PetscInt *sizes = NULL; const PetscInt *points = NULL; PetscMPIInt rank, numProcs; ierr = MPI_Comm_rank(comm, &rank); CHKERRQ(ierr); ierr = MPI_Comm_size(comm, &numProcs); CHKERRQ(ierr); if (!rank) { if (dim == 2 && cellSimplex && numProcs == 2) { switch (user->testNum) { case 0: { PetscInt triSizes_p2[2] = {4, 4}; PetscInt triPoints_p2[8] = {3, 5, 6, 7, 0, 1, 2, 4}; sizes = triSizes_p2; points = triPoints_p2; break; } case 1: { PetscInt triSizes_p2[2] = {6, 2}; PetscInt triPoints_p2[8] = {1, 2, 3, 4, 6, 7, 0, 5}; sizes = triSizes_p2; points = triPoints_p2; break; } default: SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test number %d for triangular mesh on 2 procs", user->testNum); } } else if (dim == 2 && cellSimplex && numProcs == 3) { PetscInt triSizes_p3[3] = {3, 3, 2}; PetscInt triPoints_p3[8] = {1, 2, 4, 3, 6, 7, 0, 5}; sizes = triSizes_p3; points = triPoints_p3; } else if (dim == 2 && !cellSimplex && numProcs == 2) { PetscInt quadSizes_p2[2] = {2, 2}; PetscInt quadPoints_p2[4] = {2, 3, 0, 1}; sizes = quadSizes_p2; points = quadPoints_p2; } else SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Could not find matching test partition"); } ierr = DMPlexGetPartitioner(*dm, &part); CHKERRQ(ierr); ierr = PetscPartitionerSetType(part, PETSCPARTITIONERSHELL); CHKERRQ(ierr); ierr = PetscPartitionerShellSetPartition(part, numProcs, sizes, points); CHKERRQ(ierr); } ierr = DMPlexDistribute(*dm, 0, NULL, &dmDist); CHKERRQ(ierr); if (dmDist) { ierr = DMDestroy(dm); CHKERRQ(ierr); *dm = dmDist; } ierr = PetscObjectSetName((PetscObject) *dm, cellSimplex ? "Simplicial Mesh" : "Tensor Product Mesh"); CHKERRQ(ierr); ierr = DMViewFromOptions(*dm, NULL, "-dm_view"); CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscErrorCode ierr; SNES snes; /* nonlinear solver */ Vec Hu; /* solution vector */ AppCtx user; /* user-defined work context */ ExactCtx exact; PetscInt its; /* snes reports iteration count */ SNESConvergedReason reason; /* snes reports convergence */ PetscReal tmp1, tmp2, tmp3, errnorms[2], scaleNode[2], descaleNode[2]; PetscInt i; char dumpfile[80],dxdocstr[80]; PetscBool eps_set = PETSC_FALSE, dump = PETSC_FALSE, exactinitial = PETSC_FALSE, snes_mf_set, snes_fd_set, dx_set; PetscInitialize(&argc,&argv,(char *)0,help); ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &user.rank); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "MARINE solves for thickness and velocity in 1D, steady marine ice sheet\n" " [run with -help for info and options]\n");CHKERRQ(ierr); user.n = 3.0; /* Glen flow law exponent */ user.secpera = 31556926.0; user.rho = 910.0; /* kg m^-3 */ user.rhow = 1028.0; /* kg m^-3 */ user.omega = 1.0 - user.rho / user.rhow; user.g = 9.81; /* m s^-2 */ /* get parameters of exact solution */ ierr = params_exactBod(&tmp1, &(exact.L0), &(exact.xg), &tmp2, &tmp3, &(user.k)); CHKERRQ(ierr); ierr = exactBod(exact.xg,&(exact.Hg),&tmp2,&(exact.Mg)); CHKERRQ(ierr); ierr = exactBodBueler(exact.xg,&tmp1,&(exact.Bg)); CHKERRQ(ierr); user.zocean = user.rho * exact.Hg / user.rhow; /* see ../marineshoot.py: */ #define xa_default 0.2 #define xc_default 0.98 /* define interval [xa,xc] */ user.xa = xa_default * exact.L0; user.xc = xc_default * exact.L0; /* get Dirichlet boundary conditions, and mass balance on shelf */ ierr = exactBod(user.xa, &(user.Ha), &(user.ua), &tmp1); CHKERRQ(ierr); /* regularize using strain rate of 1/(length) per year */ user.epsilon = (1.0 / user.secpera) / (user.xc - user.xa); /*user.epsilon = 0.0;*/ user.Hscale = 1000.0; user.uscale = 100.0 / user.secpera; user.noscale = PETSC_FALSE; user.dx = 10000.0; /* default to coarse 10 km grid */ ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "","options to marine (steady marine ice sheet solver)","");CHKERRQ(ierr); { ierr = PetscOptionsBool("-snes_mf","","",PETSC_FALSE,&snes_mf_set,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-snes_fd","","",PETSC_FALSE,&snes_fd_set,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-noscale","","",PETSC_FALSE,&user.noscale,NULL);CHKERRQ(ierr); snprintf(dxdocstr,80,"target grid spacing (m) on interval of length %.0f m", user.xc-user.xa); ierr = PetscOptionsReal("-dx",dxdocstr,"",user.dx,&user.dx,&dx_set);CHKERRQ(ierr); ierr = PetscOptionsBool("-exactinit", "initialize using exact solution instead of default linear function","", PETSC_FALSE,&exactinitial,NULL);CHKERRQ(ierr); ierr = PetscOptionsString("-dump", "dump approx and exact solution into given file (as ascii matlab format)","", NULL,dumpfile,80,&dump);CHKERRQ(ierr); ierr = PetscOptionsReal("-epsilon","regularizing strain rate for stress computation (a-1)","", user.epsilon * user.secpera,&user.epsilon,&eps_set);CHKERRQ(ierr); if (eps_set) user.epsilon *= 1.0 / user.secpera; } ierr = PetscOptionsEnd();CHKERRQ(ierr); if (snes_fd_set) { ierr = PetscPrintf(PETSC_COMM_WORLD, " using approximate Jacobian; finite-differencing using coloring\n"); CHKERRQ(ierr); } else if (snes_mf_set) { ierr = PetscPrintf(PETSC_COMM_WORLD, " matrix free; no preconditioner\n"); CHKERRQ(ierr); } else { ierr = PetscPrintf(PETSC_COMM_WORLD, " true Jacobian\n"); CHKERRQ(ierr); } if (dx_set && (user.dx <= 0.0)) { PetscPrintf(PETSC_COMM_WORLD, "\n***ERROR: -dx value must be positive ... USAGE FOLLOWS ...\n\n%s",help); PetscEnd(); } user.N = (int)ceil( ((user.xc - user.xa) / user.dx) - 0.5 ); user.Mx = user.N + 2; user.dx = (user.xc - user.xa) / ((PetscReal)(user.N) + 0.5); /* recompute so dx * (N+1/2) = xc - xa */ if (dx_set && (user.dx < 1.0)) { PetscPrintf(PETSC_COMM_WORLD, "\n***WARNING: '-dx %.3f' meters is below one meter and creates grid of %d points\n" " ... probably uncomputable!\n\n", user.dx,user.Mx); } /* residual scaling coeffs; motivation at right */ user.rscHa = 1.0 / user.Hscale, /* Dirichlet cond for H */ user.rscua = 1.0 / user.uscale, /* Dirichlet cond for u */ user.rscuH = user.dx / (user.Hscale * user.uscale), /* flux derivative d(uH)/dx */ user.rscstress = 1.0 / (user.k * user.rho * user.g * user.Hscale * user.uscale), /* beta term in SSA */ user.rsccalv = 1.0 / (0.025 * user.rho * user.g * user.Hscale); /* 0.5 * omega * overburden */ /* Create machinery for parallel grid management (DMDA), nonlinear solver (SNES), and Vecs for fields (solution, RHS). Degrees of freedom = 2 (thickness and velocity at each point). */ ierr = DMDACreate1d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,user.Mx,2,1,PETSC_NULL,&user.da); CHKERRQ(ierr); ierr = DMSetApplicationContext(user.da,&user);CHKERRQ(ierr); ierr = DMDASetFieldName(user.da,0,"ice thickness [non-dimensional]"); CHKERRQ(ierr); ierr = DMDASetFieldName(user.da,1,"ice velocity [non-dimensional]"); CHKERRQ(ierr); ierr = DMSetFromOptions(user.da); CHKERRQ(ierr); ierr = DMDAGetInfo(user.da,PETSC_IGNORE,&user.Mx,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); ierr = DMDAGetCorners(user.da,&user.xs,PETSC_NULL,PETSC_NULL,&user.xm,PETSC_NULL,PETSC_NULL); CHKERRQ(ierr); /* another DMDA for scalar staggered parameters; one fewer point */ ierr = DMDACreate1d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,user.Mx-1,1,1,PETSC_NULL,&user.stagda); CHKERRQ(ierr); /* establish geometry on grid; note xa = x_0 and xc = x_{N+1/2} */ ierr = DMDASetUniformCoordinates(user.da, user.xa, user.xc+0.5*user.dx, 0.0,1.0,0.0,1.0);CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(user.stagda,user.xa+0.5*user.dx,user.xc, 0.0,1.0,0.0,1.0);CHKERRQ(ierr); /* report on current grid */ ierr = PetscPrintf(PETSC_COMM_WORLD, " grid: Mx = N+2 = %D regular points, dx = %.3f m, xa = %.2f km, xc = %.2f km\n", user.Mx, user.dx, user.xa/1000.0, user.xc/1000.0);CHKERRQ(ierr); /* Extract/allocate global vectors from DMDAs and duplicate for remaining same types */ ierr = DMCreateGlobalVector(user.da,&Hu);CHKERRQ(ierr); ierr = VecSetBlockSize(Hu,2);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)Hu,"Hu");CHKERRQ(ierr); ierr = VecDuplicate(Hu,&exact.Hu);CHKERRQ(ierr); /* inherits block size */ ierr = PetscObjectSetName((PetscObject)exact.Hu,"exactHu");CHKERRQ(ierr); ierr = DMCreateGlobalVector(user.stagda,&user.Mstag);CHKERRQ(ierr); ierr = VecDuplicate(user.Mstag,&user.Bstag);CHKERRQ(ierr); /* set up snes */ ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,user.da);CHKERRQ(ierr); ierr = DMDASNESSetFunctionLocal(user.da,INSERT_VALUES,(DMDASNESFunction)scshell,&user);CHKERRQ(ierr); ierr = DMDASNESSetJacobianLocal(user.da,(DMDASNESJacobian)JacobianMatrixLocal,&user);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); /* the exact thickness and exact ice velocity (user.uHexact) are known */ ierr = FillExactSoln(&exact, &user); CHKERRQ(ierr); /* the exact solution allows setting M(x), B(x) */ ierr = FillDistributedParams(&exact, &user);CHKERRQ(ierr); if (exactinitial) { ierr = PetscPrintf(PETSC_COMM_WORLD," using exact solution as initial guess\n"); CHKERRQ(ierr); /* the initial guess is the exact continuum solution */ ierr = VecCopy(exact.Hu,Hu); CHKERRQ(ierr); } else { /* the initial guess is a linear solution */ ierr = FillInitial(&user, &Hu); CHKERRQ(ierr); } /************ SOLVE NONLINEAR SYSTEM ************/ /* recall that RHS r is used internally by KSP, and is set by the SNES */ if (user.noscale) { user.Hscale = 1.0; user.uscale = 1.0; } scaleNode[0] = user.Hscale; scaleNode[1] = user.uscale; for (i = 0; i < 2; i++) descaleNode[i] = 1.0 / scaleNode[i]; ierr = VecStrideScaleAll(Hu,descaleNode); CHKERRQ(ierr); /* de-dimensionalize initial guess */ ierr = SNESSolve(snes,PETSC_NULL,Hu);CHKERRQ(ierr); ierr = VecStrideScaleAll(Hu,scaleNode); CHKERRQ(ierr); /* put back in "real" scale */ /* minimal report on solve */ ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = SNESGetConvergedReason(snes,&reason);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, " %s Number of Newton iterations = %D\n", SNESConvergedReasons[reason],its);CHKERRQ(ierr); if (dump) { ierr = PetscPrintf(PETSC_COMM_WORLD, "dumping results in ascii matlab format to file '%s' ...\n",dumpfile);CHKERRQ(ierr); PetscViewer viewer; ierr = PetscViewerASCIIOpen(PETSC_COMM_WORLD,dumpfile,&viewer);CHKERRQ(ierr); ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); DM coord_da; Vec coord_x; ierr = DMGetCoordinateDM(user.da, &coord_da); CHKERRQ(ierr); ierr = DMGetCoordinates(user.da, &coord_x); CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"%% START MATLAB\n"); CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)coord_x,"x");CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"%% viewing coordinate vector x \n");CHKERRQ(ierr); ierr = VecView(coord_x,viewer); CHKERRQ(ierr); ierr = VecView(Hu,viewer); CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"%% viewing combined result Hu\n");CHKERRQ(ierr); ierr = VecView(Hu,viewer); CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"%% viewing combined exact result exactHu\n");CHKERRQ(ierr); ierr = VecView(exact.Hu,viewer); CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer, "%% defining plottable variables and plotting in Matlab\n" "Mx = %d; secpera = 31556926.0;\n" "H = Hu(1:2:2*Mx-1);\n" "u = Hu(2:2:2*Mx);\n" "exactH = exactHu(1:2:2*Mx-1);\n" "exactu = exactHu(2:2:2*Mx);\n" "figure, plot(x,H,x,exactH);\n" "legend('numerical','exact'), xlabel x, ylabel('H (m)')\n" "figure, plot(x,u*secpera,x,exactu*secpera);\n" "legend('numerical','exact'), xlabel x, ylabel('u (m/a)')\n" "figure, subplot(2,1,1), semilogy(x,abs(H-exactH));\n" "ylabel('H error (m)'), grid\n" "subplot(2,1,2), semilogy(x,abs(u-exactu)*secpera);\n" "xlabel x, ylabel('u error (m/a)'), grid\n", user.Mx); CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"%% END MATLAB\n"); CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); } /* evaluate error relative to exact solution */ ierr = VecAXPY(Hu,-1.0,exact.Hu); CHKERRQ(ierr); /* Hu = - Huexact + Hu */ ierr = VecStrideNormAll(Hu,NORM_INFINITY,errnorms); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "(dx,errHinf,erruinf) %.3f %.4e %.4e\n", user.dx,errnorms[0],errnorms[1]*user.secpera);CHKERRQ(ierr); ierr = VecDestroy(&Hu);CHKERRQ(ierr); ierr = VecDestroy(&(exact.Hu));CHKERRQ(ierr); ierr = VecDestroy(&(user.Mstag));CHKERRQ(ierr); ierr = VecDestroy(&(user.Bstag));CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&(user.da));CHKERRQ(ierr); ierr = DMDestroy(&(user.stagda));CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
int main(int argc,char *argv[]) { char mat_type[256] = "aij"; /* default matrix type */ PetscErrorCode ierr; MPI_Comm comm; PetscMPIInt rank,size; DM slice; PetscInt i,bs=1,N=5,n,m,rstart,ghosts[2],*d_nnz,*o_nnz,dfill[4]={1,0,0,1},ofill[4]={1,1,1,1}; PetscReal alpha =1,K=1,rho0=1,u0=0,sigma=0.2; PetscBool useblock=PETSC_TRUE; PetscScalar *xx; Mat A; Vec x,b,lf; ierr = PetscInitialize(&argc,&argv,0,help);CHKERRQ(ierr); comm = PETSC_COMM_WORLD; ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); ierr = PetscOptionsBegin(comm,0,"Options for DMSliced test",0);CHKERRQ(ierr); { ierr = PetscOptionsInt("-n","Global number of nodes","",N,&N,NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-bs","Block size (1 or 2)","",bs,&bs,NULL);CHKERRQ(ierr); if (bs != 1) { if (bs != 2) SETERRQ(PETSC_COMM_WORLD,1,"Block size must be 1 or 2"); ierr = PetscOptionsReal("-alpha","Inverse time step for wave operator","",alpha,&alpha,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-K","Bulk modulus of compressibility","",K,&K,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-rho0","Reference density","",rho0,&rho0,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-u0","Reference velocity","",u0,&u0,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-sigma","Width of Gaussian density perturbation","",sigma,&sigma,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-block","Use block matrix assembly","",useblock,&useblock,NULL);CHKERRQ(ierr); } ierr = PetscOptionsString("-sliced_mat_type","Matrix type to use (aij or baij)","",mat_type,mat_type,sizeof(mat_type),NULL);CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); /* Split ownership, set up periodic grid in 1D */ n = PETSC_DECIDE; ierr = PetscSplitOwnership(comm,&n,&N);CHKERRQ(ierr); rstart = 0; ierr = MPI_Scan(&n,&rstart,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr); rstart -= n; ghosts[0] = (N+rstart-1)%N; ghosts[1] = (rstart+n)%N; ierr = PetscMalloc2(n,&d_nnz,n,&o_nnz);CHKERRQ(ierr); for (i=0; i<n; i++) { if (size > 1 && (i==0 || i==n-1)) { d_nnz[i] = 2; o_nnz[i] = 1; } else { d_nnz[i] = 3; o_nnz[i] = 0; } } ierr = DMSlicedCreate(comm,bs,n,2,ghosts,d_nnz,o_nnz,&slice);CHKERRQ(ierr); /* Currently does not copy X_nnz so we can't free them until after DMSlicedGetMatrix */ if (!useblock) {ierr = DMSlicedSetBlockFills(slice,dfill,ofill);CHKERRQ(ierr);} /* Irrelevant for baij formats */ ierr = DMSetMatType(slice,mat_type);CHKERRQ(ierr); ierr = DMCreateMatrix(slice,&A);CHKERRQ(ierr); ierr = PetscFree2(d_nnz,o_nnz);CHKERRQ(ierr); ierr = MatSetOption(A,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); ierr = DMCreateGlobalVector(slice,&x);CHKERRQ(ierr); ierr = VecDuplicate(x,&b);CHKERRQ(ierr); ierr = VecGhostGetLocalForm(x,&lf);CHKERRQ(ierr); ierr = VecGetSize(lf,&m);CHKERRQ(ierr); if (m != (n+2)*bs) SETERRQ2(PETSC_COMM_SELF,1,"size of local form %D, expected %D",m,(n+2)*bs); ierr = VecGetArray(lf,&xx);CHKERRQ(ierr); for (i=0; i<n; i++) { PetscInt row[2],col[9],im,ip; PetscScalar v[12]; const PetscReal xref = 2.0*(rstart+i)/N - 1; /* [-1,1] */ const PetscReal h = 1.0/N; /* grid spacing */ im = (i==0) ? n : i-1; ip = (i==n-1) ? n+1 : i+1; switch (bs) { case 1: /* Laplacian with periodic boundaries */ col[0] = im; col[1] = i; col[2] = ip; v[0] = -h; v[1] = 2*h; v[2] = -h; ierr = MatSetValuesLocal(A,1,&i,3,col,v,INSERT_VALUES);CHKERRQ(ierr); xx[i] = PetscSinReal(xref*PETSC_PI); break; case 2: /* Linear acoustic wave operator in variables [rho, u], central differences, periodic, timestep 1/alpha */ v[0] = -0.5*u0; v[1] = -0.5*K; v[2] = alpha; v[3] = 0; v[4] = 0.5*u0; v[5] = 0.5*K; v[6] = -0.5/rho0; v[7] = -0.5*u0; v[8] = 0; v[9] = alpha; v[10] = 0.5/rho0; v[11] = 0.5*u0; if (useblock) { row[0] = i; col[0] = im; col[1] = i; col[2] = ip; ierr = MatSetValuesBlockedLocal(A,1,row,3,col,v,INSERT_VALUES);CHKERRQ(ierr); } else { row[0] = 2*i; row[1] = 2*i+1; col[0] = 2*im; col[1] = 2*im+1; col[2] = 2*i; col[3] = 2*ip; col[4] = 2*ip+1; v[3] = v[4]; v[4] = v[5]; /* pack values in first row */ ierr = MatSetValuesLocal(A,1,row,5,col,v,INSERT_VALUES);CHKERRQ(ierr); col[2] = 2*i+1; v[8] = v[9]; v[9] = v[10]; v[10] = v[11]; /* pack values in second row */ ierr = MatSetValuesLocal(A,1,row+1,5,col,v+6,INSERT_VALUES);CHKERRQ(ierr); } /* Set current state (gaussian density perturbation) */ xx[2*i] = 0.2*PetscExpReal(-PetscSqr(xref)/(2*PetscSqr(sigma))); xx[2*i+1] = 0; break; default: SETERRQ1(PETSC_COMM_SELF,1,"not implemented for block size %D",bs); } } ierr = VecRestoreArray(lf,&xx);CHKERRQ(ierr); ierr = VecGhostRestoreLocalForm(x,&lf);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatMult(A,x,b);CHKERRQ(ierr); ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecView(b,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* Update the ghosted values, view the result on rank 0. */ ierr = VecGhostUpdateBegin(b,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecGhostUpdateEnd(b,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); if (!rank) { ierr = VecGhostGetLocalForm(b,&lf);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_SELF,"Local form of b on rank 0, last two nodes are ghost nodes\n");CHKERRQ(ierr); ierr = VecView(lf,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = VecGhostRestoreLocalForm(b,&lf);CHKERRQ(ierr); } ierr = DMDestroy(&slice);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { TS ts; SNES snes_alg; PetscErrorCode ierr; PetscMPIInt size; Userctx user; PetscViewer Xview,Ybusview; Vec X; Mat J; PetscInt i; ierr = PetscInitialize(&argc,&argv,"petscoptions",help);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size > 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"Only for sequential runs"); user.neqs_gen = 9*ngen; /* # eqs. for generator subsystem */ user.neqs_net = 2*nbus; /* # eqs. for network subsystem */ user.neqs_pgrid = user.neqs_gen + user.neqs_net; /* Create indices for differential and algebraic equations */ PetscInt *idx2; ierr = PetscMalloc1(7*ngen,&idx2);CHKERRQ(ierr); for (i=0; i<ngen; i++) { idx2[7*i] = 9*i; idx2[7*i+1] = 9*i+1; idx2[7*i+2] = 9*i+2; idx2[7*i+3] = 9*i+3; idx2[7*i+4] = 9*i+6; idx2[7*i+5] = 9*i+7; idx2[7*i+6] = 9*i+8; } ierr = ISCreateGeneral(PETSC_COMM_WORLD,7*ngen,idx2,PETSC_COPY_VALUES,&user.is_diff);CHKERRQ(ierr); ierr = ISComplement(user.is_diff,0,user.neqs_pgrid,&user.is_alg);CHKERRQ(ierr); ierr = PetscFree(idx2);CHKERRQ(ierr); /* Read initial voltage vector and Ybus */ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,"X.bin",FILE_MODE_READ,&Xview);CHKERRQ(ierr); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,"Ybus.bin",FILE_MODE_READ,&Ybusview);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_WORLD,&user.V0);CHKERRQ(ierr); ierr = VecSetSizes(user.V0,PETSC_DECIDE,user.neqs_net);CHKERRQ(ierr); ierr = VecLoad(user.V0,Xview);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&user.Ybus);CHKERRQ(ierr); ierr = MatSetSizes(user.Ybus,PETSC_DECIDE,PETSC_DECIDE,user.neqs_net,user.neqs_net);CHKERRQ(ierr); ierr = MatSetType(user.Ybus,MATBAIJ);CHKERRQ(ierr); /* ierr = MatSetBlockSize(user.Ybus,2);CHKERRQ(ierr); */ ierr = MatLoad(user.Ybus,Ybusview);CHKERRQ(ierr); /* Set run time options */ ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Transient stability fault options","");CHKERRQ(ierr); { user.tfaulton = 1.0; user.tfaultoff = 1.2; user.Rfault = 0.0001; user.faultbus = 8; ierr = PetscOptionsReal("-tfaulton","","",user.tfaulton,&user.tfaulton,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-tfaultoff","","",user.tfaultoff,&user.tfaultoff,NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-faultbus","","",user.faultbus,&user.faultbus,NULL);CHKERRQ(ierr); user.t0 = 0.0; user.tmax = 5.0; ierr = PetscOptionsReal("-t0","","",user.t0,&user.t0,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-tmax","","",user.tmax,&user.tmax,NULL);CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = PetscViewerDestroy(&Xview);CHKERRQ(ierr); ierr = PetscViewerDestroy(&Ybusview);CHKERRQ(ierr); /* Create DMs for generator and network subsystems */ ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,user.neqs_gen,1,1,NULL,&user.dmgen);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(user.dmgen,"dmgen_");CHKERRQ(ierr); ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,user.neqs_net,1,1,NULL,&user.dmnet);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(user.dmnet,"dmnet_");CHKERRQ(ierr); /* Create a composite DM packer and add the two DMs */ ierr = DMCompositeCreate(PETSC_COMM_WORLD,&user.dmpgrid);CHKERRQ(ierr); ierr = DMSetOptionsPrefix(user.dmpgrid,"pgrid_");CHKERRQ(ierr); ierr = DMCompositeAddDM(user.dmpgrid,user.dmgen);CHKERRQ(ierr); ierr = DMCompositeAddDM(user.dmpgrid,user.dmnet);CHKERRQ(ierr); ierr = DMCreateGlobalVector(user.dmpgrid,&X);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&J);CHKERRQ(ierr); ierr = MatSetSizes(J,PETSC_DECIDE,PETSC_DECIDE,user.neqs_pgrid,user.neqs_pgrid);CHKERRQ(ierr); ierr = MatSetFromOptions(J);CHKERRQ(ierr); ierr = PreallocateJacobian(J,&user);CHKERRQ(ierr); /* Create matrix to save solutions at each time step */ user.stepnum = 0; ierr = MatCreateSeqDense(PETSC_COMM_SELF,user.neqs_pgrid+1,1002,NULL,&user.Sol);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetEquationType(ts,TS_EQ_DAE_IMPLICIT_INDEX1);CHKERRQ(ierr); ierr = TSARKIMEXSetFullyImplicit(ts,PETSC_TRUE);CHKERRQ(ierr); ierr = TSSetIFunction(ts,NULL,(TSIFunction) IFunction,&user);CHKERRQ(ierr); ierr = TSSetIJacobian(ts,J,J,(TSIJacobian)IJacobian,&user);CHKERRQ(ierr); ierr = TSSetApplicationContext(ts,&user);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SetInitialGuess(X,&user);CHKERRQ(ierr); /* Just to set up the Jacobian structure */ Vec Xdot; ierr = VecDuplicate(X,&Xdot);CHKERRQ(ierr); ierr = IJacobian(ts,0.0,X,Xdot,0.0,J,J,&user);CHKERRQ(ierr); ierr = VecDestroy(&Xdot);CHKERRQ(ierr); /* Save initial solution */ PetscScalar *x,*mat; PetscInt idx=user.stepnum*(user.neqs_pgrid+1); ierr = MatDenseGetArray(user.Sol,&mat);CHKERRQ(ierr); ierr = VecGetArray(X,&x);CHKERRQ(ierr); mat[idx] = 0.0; ierr = PetscMemcpy(mat+idx+1,x,user.neqs_pgrid*sizeof(PetscScalar));CHKERRQ(ierr); ierr = MatDenseRestoreArray(user.Sol,&mat);CHKERRQ(ierr); ierr = VecRestoreArray(X,&x);CHKERRQ(ierr); user.stepnum++; ierr = TSSetDuration(ts,1000,user.tfaulton);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,0.01);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = TSSetPostStep(ts,SaveSolution);CHKERRQ(ierr); user.alg_flg = PETSC_FALSE; /* Prefault period */ ierr = TSSolve(ts,X);CHKERRQ(ierr); /* Create the nonlinear solver for solving the algebraic system */ /* Note that although the algebraic system needs to be solved only for Idq and V, we reuse the entire system including xgen. The xgen variables are held constant by setting their residuals to 0 and putting a 1 on the Jacobian diagonal for xgen rows */ Vec F_alg; ierr = VecDuplicate(X,&F_alg);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes_alg);CHKERRQ(ierr); ierr = SNESSetFunction(snes_alg,F_alg,AlgFunction,&user);CHKERRQ(ierr); ierr = MatZeroEntries(J);CHKERRQ(ierr); ierr = SNESSetJacobian(snes_alg,J,J,AlgJacobian,&user);CHKERRQ(ierr); ierr = SNESSetOptionsPrefix(snes_alg,"alg_");CHKERRQ(ierr); ierr = SNESSetFromOptions(snes_alg);CHKERRQ(ierr); /* Apply disturbance - resistive fault at user.faultbus */ /* This is done by adding shunt conductance to the diagonal location in the Ybus matrix */ PetscInt row_loc,col_loc; PetscScalar val; row_loc = 2*user.faultbus; col_loc = 2*user.faultbus+1; /* Location for G */ val = 1/user.Rfault; ierr = MatSetValues(user.Ybus,1,&row_loc,1,&col_loc,&val,ADD_VALUES);CHKERRQ(ierr); row_loc = 2*user.faultbus+1; col_loc = 2*user.faultbus; /* Location for G */ val = 1/user.Rfault; ierr = MatSetValues(user.Ybus,1,&row_loc,1,&col_loc,&val,ADD_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(user.Ybus,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(user.Ybus,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); user.alg_flg = PETSC_TRUE; /* Solve the algebraic equations */ ierr = SNESSolve(snes_alg,NULL,X);CHKERRQ(ierr); /* Save fault-on solution */ idx = user.stepnum*(user.neqs_pgrid+1); ierr = MatDenseGetArray(user.Sol,&mat);CHKERRQ(ierr); ierr = VecGetArray(X,&x);CHKERRQ(ierr); mat[idx] = user.tfaulton; ierr = PetscMemcpy(mat+idx+1,x,user.neqs_pgrid*sizeof(PetscScalar));CHKERRQ(ierr); ierr = MatDenseRestoreArray(user.Sol,&mat);CHKERRQ(ierr); ierr = VecRestoreArray(X,&x);CHKERRQ(ierr); user.stepnum++; /* Disturbance period */ ierr = TSSetDuration(ts,1000,user.tfaultoff);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,user.tfaulton,.01);CHKERRQ(ierr); user.alg_flg = PETSC_FALSE; ierr = TSSolve(ts,X);CHKERRQ(ierr); /* Remove the fault */ row_loc = 2*user.faultbus; col_loc = 2*user.faultbus+1; val = -1/user.Rfault; ierr = MatSetValues(user.Ybus,1,&row_loc,1,&col_loc,&val,ADD_VALUES);CHKERRQ(ierr); row_loc = 2*user.faultbus+1; col_loc = 2*user.faultbus; val = -1/user.Rfault; ierr = MatSetValues(user.Ybus,1,&row_loc,1,&col_loc,&val,ADD_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(user.Ybus,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(user.Ybus,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatZeroEntries(J);CHKERRQ(ierr); user.alg_flg = PETSC_TRUE; /* Solve the algebraic equations */ ierr = SNESSolve(snes_alg,NULL,X);CHKERRQ(ierr); /* Save tfault off solution */ idx = user.stepnum*(user.neqs_pgrid+1); ierr = MatDenseGetArray(user.Sol,&mat);CHKERRQ(ierr); ierr = VecGetArray(X,&x);CHKERRQ(ierr); mat[idx] = user.tfaultoff; ierr = PetscMemcpy(mat+idx+1,x,user.neqs_pgrid*sizeof(PetscScalar));CHKERRQ(ierr); ierr = MatDenseRestoreArray(user.Sol,&mat);CHKERRQ(ierr); ierr = VecRestoreArray(X,&x);CHKERRQ(ierr); user.stepnum++; /* Post-disturbance period */ ierr = TSSetDuration(ts,1000,user.tmax);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,user.tfaultoff,.01);CHKERRQ(ierr); user.alg_flg = PETSC_TRUE; ierr = TSSolve(ts,X);CHKERRQ(ierr); ierr = MatAssemblyBegin(user.Sol,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(user.Sol,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); Mat A; PetscScalar *amat; ierr = MatCreateSeqDense(PETSC_COMM_SELF,user.neqs_pgrid+1,user.stepnum,NULL,&A);CHKERRQ(ierr); ierr = MatDenseGetArray(user.Sol,&mat);CHKERRQ(ierr); ierr = MatDenseGetArray(A,&amat);CHKERRQ(ierr); ierr = PetscMemcpy(amat,mat,(user.stepnum*(user.neqs_pgrid+1))*sizeof(PetscScalar));CHKERRQ(ierr); ierr = MatDenseRestoreArray(A,&amat);CHKERRQ(ierr); ierr = MatDenseRestoreArray(user.Sol,&mat);CHKERRQ(ierr); PetscViewer viewer; ierr = PetscViewerBinaryOpen(PETSC_COMM_SELF,"out.bin",FILE_MODE_WRITE,&viewer);CHKERRQ(ierr); ierr = MatView(A,viewer);CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = SNESDestroy(&snes_alg);CHKERRQ(ierr); ierr = VecDestroy(&F_alg);CHKERRQ(ierr); ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = MatDestroy(&user.Ybus);CHKERRQ(ierr); ierr = MatDestroy(&user.Sol);CHKERRQ(ierr); ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&user.V0);CHKERRQ(ierr); ierr = DMDestroy(&user.dmgen);CHKERRQ(ierr); ierr = DMDestroy(&user.dmnet);CHKERRQ(ierr); ierr = DMDestroy(&user.dmpgrid);CHKERRQ(ierr); ierr = ISDestroy(&user.is_diff);CHKERRQ(ierr); ierr = ISDestroy(&user.is_alg);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = PetscFinalize(); return(0); }
int main(int argc, char *argv[]) { PetscErrorCode ierr; PetscMPIInt rank; AppCtx user; PetscInt p=2,N=64,C=1; PetscInt ng = p+2; /* integration in each direction */ PetscInt Nx,Ny; Vec U; /* solution vector */ Mat J; TS ts; PetscInt steps; PetscReal ftime; /* This code solve the dimensionless form of the isothermal Navier-Stokes-Korteweg equations as presented in: Gomez, Hughes, Nogueira, Calo Isogeometric analysis of the isothermal Navier-Stokes-Korteweg equations CMAME, 2010 Equation/section numbers reflect this publication. */ // Petsc Initialization rite of passage ierr = PetscInitialize(&argc,&argv,0,help);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank);CHKERRQ(ierr); // Define simulation specific parameters user.L0 = 1.0; // length scale user.C1x = 0.75; user.C1y = 0.50; // bubble centers user.C2x = 0.25; user.C2y = 0.50; user.C3x = 0.40; user.C3y = 0.75; user.R1 = 0.10; user.R2 = 0.15; user.R3 = 0.08; // bubble radii user.alpha = 2.0; // (Eq. 41) user.theta = 0.85; // temperature parameter (just before section 5.1) // Set discretization options ierr = PetscOptionsBegin(PETSC_COMM_WORLD, "", "NavierStokesKorteweg Options", "IGA");CHKERRQ(ierr); ierr = PetscOptionsInt("-p", "polynomial order", __FILE__, p, &p, PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-C", "global continuity order", __FILE__, C, &C, PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-N", "number of elements (along one dimension)", __FILE__, N, &N, PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); // Compute simulation parameters user.h = user.L0/N; // characteristic length scale of mesh (Eq. 43, simplified for uniform elements) user.Ca = user.h/user.L0; // capillarity number (Eq. 38) user.Re = user.alpha/user.Ca; // Reynolds number (Eq. 39) // Test C < p if(p <= C){ SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Discretization inconsistent: polynomial order must be greater than degree of continuity"); } Nx=Ny=N; // Initialize B-spline space ierr = DMCreate(PETSC_COMM_WORLD,&user.iga);CHKERRQ(ierr); ierr = DMSetType(user.iga, DMIGA);CHKERRQ(ierr); ierr = DMIGAInitializeUniform2d(user.iga,PETSC_FALSE,2,3, p,Nx,C,0.0,1.0,PETSC_TRUE,ng, p,Ny,C,0.0,1.0,PETSC_TRUE,ng);CHKERRQ(ierr); ierr = DMCreateGlobalVector(user.iga,&U);CHKERRQ(ierr); ierr = FormInitialCondition(&user,U);CHKERRQ(ierr); ierr = DMIGASetFieldName(user.iga, 0, "density");CHKERRQ(ierr); ierr = DMIGASetFieldName(user.iga, 1, "velocity-u");CHKERRQ(ierr); ierr = DMIGASetFieldName(user.iga, 2, "velocity-v");CHKERRQ(ierr); ierr = DMCreateMatrix(user.iga, MATAIJ, &J);CHKERRQ(ierr); ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetType(ts,TSALPHA);CHKERRQ(ierr); ierr = TSAlphaSetRadius(ts,0.5);CHKERRQ(ierr); ierr = TSSetDM(ts,user.iga);CHKERRQ(ierr); ierr = TSSetSolution(ts,U);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetIFunction(ts,PETSC_NULL,FormResidual,&user);CHKERRQ(ierr); ierr = TSSetIJacobian(ts,J,J,FormTangent,&user);CHKERRQ(ierr); ierr = TSSetDuration(ts,1000000,1000.0);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,0.001);CHKERRQ(ierr); ierr = TSAlphaSetAdapt(ts,TSAlphaAdaptDefault,PETSC_NULL);CHKERRQ(ierr); ierr = TSMonitorSet(ts,OutputMonitor,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = TSSolve(ts,U,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); // Cleanup ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&user.iga);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { PetscErrorCode ierr; ObsCtx user; SNES snes; DM da; Vec u, /* solution */ Xu; /* upper bound */ DMDALocalInfo info; PetscReal error1,errorinf; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = DMDACreate2d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,11,11,/* default to 10x10 grid */ PETSC_DECIDE,PETSC_DECIDE, /* number of processors in each dimension */1,/* dof = 1 */1,/* s = 1; stencil extends out one cell */ NULL,NULL,/* do not specify processor decomposition */&da);CHKERRQ(ierr); ierr = DMSetFromOptions(da);CHKERRQ(ierr); ierr = DMSetUp(da);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&u);CHKERRQ(ierr); ierr = VecDuplicate(u,&(user.uexact));CHKERRQ(ierr); ierr = VecDuplicate(u,&(user.psi));CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da,-2.0,2.0,-2.0,2.0,0.0,1.0);CHKERRQ(ierr); ierr = DMSetApplicationContext(da,&user);CHKERRQ(ierr); ierr = FormPsiAndExactSoln(da);CHKERRQ(ierr); ierr = VecSet(u,0.0);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,da);CHKERRQ(ierr); ierr = SNESSetApplicationContext(snes,&user);CHKERRQ(ierr); ierr = SNESSetType(snes,SNESVINEWTONRSLS);CHKERRQ(ierr); /* set upper and lower bound constraints for VI */ ierr = VecDuplicate(u,&Xu);CHKERRQ(ierr); ierr = VecSet(Xu,PETSC_INFINITY);CHKERRQ(ierr); ierr = SNESVISetVariableBounds(snes,user.psi,Xu);CHKERRQ(ierr); ierr = VecDestroy(&Xu);CHKERRQ(ierr); 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); /* report on setup */ ierr = DMDAGetLocalInfo(da,&info); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"setup done: grid Mx,My = %D,%D with spacing dx,dy = %.4f,%.4f\n", info.mx,info.my,(double)(4.0/(PetscReal)(info.mx-1)),(double)(4.0/(PetscReal)(info.my-1)));CHKERRQ(ierr); /* solve nonlinear system */ ierr = SNESSolve(snes,NULL,u);CHKERRQ(ierr); /* compare to exact */ ierr = VecAXPY(u,-1.0,user.uexact);CHKERRQ(ierr); /* u <- u - uexact */ ierr = VecNorm(u,NORM_1,&error1);CHKERRQ(ierr); error1 /= (PetscReal)info.mx * (PetscReal)info.my; ierr = VecNorm(u,NORM_INFINITY,&errorinf);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"errors: av |u-uexact| = %.3e |u-uexact|_inf = %.3e\n",(double)error1,(double)errorinf);CHKERRQ(ierr); /* Free work space. */ ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&(user.psi));CHKERRQ(ierr); ierr = VecDestroy(&(user.uexact));CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
int main(int argc, char **argv) { PetscErrorCode ierr; /* used to check for functions returning nonzeros */ Vec x; /* variables vector */ Vec xl,xu; /* lower and upper bound on variables */ PetscBool flg; /* A return variable when checking for user options */ SNESConvergedReason reason; AppCtx user; /* user-defined work context */ SNES snes; Vec r; PetscReal zero=0.0,thnd=1000; /* Initialize PETSC */ PetscInitialize(&argc, &argv,(char*)0,help); #if defined(PETSC_USE_COMPLEX) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"This example does not work for scalar type complex\n"); #endif /* Set the default values for the problem parameters */ user.nx = 50; user.ny = 50; user.ecc = 0.1; user.b = 10.0; /* Check for any command line arguments that override defaults */ ierr = PetscOptionsGetReal(NULL,"-ecc",&user.ecc,&flg);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,"-b",&user.b,&flg);CHKERRQ(ierr); /* A two dimensional distributed array will help define this problem, which derives from an elliptic PDE on two dimensional domain. From the distributed array, Create the vectors. */ ierr = DMDACreate2d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE,DMDA_STENCIL_STAR,-50,-50,PETSC_DECIDE,PETSC_DECIDE,1,1,NULL,NULL,&user.da);CHKERRQ(ierr); ierr = DMDAGetIerr(user.da,PETSC_IGNORE,&user.nx,&user.ny,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD,"\n---- Journal Bearing Problem -----\n"); PetscPrintf(PETSC_COMM_WORLD,"mx: %d, my: %d, ecc: %4.3f, b:%3.1f \n", user.nx,user.ny,user.ecc,user.b); /* Extract global and local vectors from DA; the vector user.B is used solely as work space for the evaluation of the function, gradient, and Hessian. Duplicate for remaining vectors that are the same types. */ ierr = DMCreateGlobalVector(user.da,&x);CHKERRQ(ierr); /* Solution */ ierr = VecDuplicate(x,&user.B);CHKERRQ(ierr); /* Linear objective */ ierr = VecDuplicate(x,&r);CHKERRQ(ierr); /* Create matrix user.A to store quadratic, Create a local ordering scheme. */ ierr = DMSetMatType(user.da,MATAIJ);CHKERRQ(ierr); ierr = DMCreateMatrix(user.da,&user.A);CHKERRQ(ierr); /* User defined function -- compute linear term of quadratic */ ierr = ComputeB(&user);CHKERRQ(ierr); /* Create nonlinear solver context */ ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); /* Set function evaluation and Jacobian evaluation routines */ ierr = SNESSetFunction(snes,r,FormGradient,&user);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,user.A,user.A,FormHessian,&user);CHKERRQ(ierr); /* Set the initial solution guess */ ierr = VecSet(x, zero);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); /* Set variable bounds */ ierr = VecDuplicate(x,&xl);CHKERRQ(ierr); ierr = VecDuplicate(x,&xu);CHKERRQ(ierr); ierr = VecSet(xl,zero);CHKERRQ(ierr); ierr = VecSet(xu,thnd);CHKERRQ(ierr); ierr = SNESVISetVariableBounds(snes,xl,xu);CHKERRQ(ierr); /* Solve the application */ ierr = SNESSolve(snes,NULL,x);CHKERRQ(ierr); ierr = SNESGetConvergedReason(snes,&reason);CHKERRQ(ierr); if (reason <= 0) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"The SNESVI solver did not converge, adjust some parameters, or check the function evaluation routines\n"); /* Free memory */ ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&xl);CHKERRQ(ierr); ierr = VecDestroy(&xu);CHKERRQ(ierr); ierr = VecDestroy(&r);CHKERRQ(ierr); ierr = MatDestroy(&user.A);CHKERRQ(ierr); ierr = VecDestroy(&user.B);CHKERRQ(ierr); ierr = DMDestroy(&user.da);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { PetscErrorCode ierr; int time; /* amount of loops */ struct in put; PetscScalar rh; /* relative humidity */ PetscScalar x; /* memory varialbe for relative humidity calculation */ PetscScalar deep_grnd_temp; /* temperature of ground under top soil surface layer */ PetscScalar emma; /* absorption-emission constant for air */ PetscScalar pressure1 = 101300; /* surface pressure */ PetscScalar mixratio; /* mixing ratio */ PetscScalar airtemp; /* temperature of air near boundary layer inversion */ PetscScalar dewtemp; /* dew point temperature */ PetscScalar sfctemp; /* temperature at surface */ PetscScalar pwat; /* total column precipitable water */ PetscScalar cloudTemp; /* temperature at base of cloud */ AppCtx user; /* user-defined work context */ MonitorCtx usermonitor; /* user-defined monitor context */ PetscMPIInt rank,size; TS ts; SNES snes; DM da; Vec T,rhs; /* solution vector */ Mat J; /* Jacobian matrix */ PetscReal ftime,dt; PetscInt steps,dof = 5; PetscBool use_coloring = PETSC_TRUE; MatFDColoring matfdcoloring = 0; PetscBool monitor_off = PETSC_FALSE; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); /* Inputs */ readinput(&put); sfctemp = put.Ts; dewtemp = put.Td; cloudTemp = put.Tc; airtemp = put.Ta; pwat = put.pwt; if (!rank) PetscPrintf(PETSC_COMM_SELF,"Initial Temperature = %g\n",(double)sfctemp); /* input surface temperature */ deep_grnd_temp = sfctemp - 10; /* set underlying ground layer temperature */ emma = emission(pwat); /* accounts for radiative effects of water vapor */ /* Converts from Fahrenheit to Celsuis */ sfctemp = fahr_to_cel(sfctemp); airtemp = fahr_to_cel(airtemp); dewtemp = fahr_to_cel(dewtemp); cloudTemp = fahr_to_cel(cloudTemp); deep_grnd_temp = fahr_to_cel(deep_grnd_temp); /* Converts from Celsius to Kelvin */ sfctemp += 273; airtemp += 273; dewtemp += 273; cloudTemp += 273; deep_grnd_temp += 273; /* Calculates initial relative humidity */ x = calcmixingr(dewtemp,pressure1); mixratio = calcmixingr(sfctemp,pressure1); rh = (x/mixratio)*100; if (!rank) printf("Initial RH = %.1f percent\n\n",(double)rh); /* prints initial relative humidity */ time = 3600*put.time; /* sets amount of timesteps to run model */ /* Configure PETSc TS solver */ /*------------------------------------------*/ /* Create grid */ ierr = DMDACreate2d(PETSC_COMM_WORLD,DM_BOUNDARY_PERIODIC,DM_BOUNDARY_PERIODIC,DMDA_STENCIL_STAR,-20,-20, PETSC_DECIDE,PETSC_DECIDE,dof,1,NULL,NULL,&da);CHKERRQ(ierr); ierr = DMDASetUniformCoordinates(da, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0);CHKERRQ(ierr); /* Define output window for each variable of interest */ ierr = DMDASetFieldName(da,0,"Ts");CHKERRQ(ierr); ierr = DMDASetFieldName(da,1,"Ta");CHKERRQ(ierr); ierr = DMDASetFieldName(da,2,"u");CHKERRQ(ierr); ierr = DMDASetFieldName(da,3,"v");CHKERRQ(ierr); ierr = DMDASetFieldName(da,4,"p");CHKERRQ(ierr); /* set values for appctx */ user.da = da; user.Ts = sfctemp; user.fract = put.fr; /* fraction of sky covered by clouds */ user.dewtemp = dewtemp; /* dew point temperature (mositure in air) */ user.csoil = 2000000; /* heat constant for layer */ user.dzlay = 0.08; /* thickness of top soil layer */ user.emma = emma; /* emission parameter */ user.wind = put.wnd; /* wind spped */ user.pressure1 = pressure1; /* sea level pressure */ user.airtemp = airtemp; /* temperature of air near boundar layer inversion */ user.Tc = cloudTemp; /* temperature at base of lowest cloud layer */ user.init = put.init; /* user chosen initiation scenario */ user.lat = 70*0.0174532; /* converts latitude degrees to latitude in radians */ user.deep_grnd_temp = deep_grnd_temp; /* temp in lowest ground layer */ /* set values for MonitorCtx */ usermonitor.drawcontours = PETSC_FALSE; ierr = PetscOptionsHasName(NULL,NULL,"-drawcontours",&usermonitor.drawcontours);CHKERRQ(ierr); if (usermonitor.drawcontours) { PetscReal bounds[] = {1000.0,-1000., -1000.,-1000., 1000.,-1000., 1000.,-1000., 1000,-1000, 100700,100800}; ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,0,0,0,300,300,&usermonitor.drawviewer);CHKERRQ(ierr); ierr = PetscViewerDrawSetBounds(usermonitor.drawviewer,dof,bounds);CHKERRQ(ierr); } usermonitor.interval = 1; ierr = PetscOptionsGetInt(NULL,NULL,"-monitor_interval",&usermonitor.interval,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extract global vectors from DA; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&T);CHKERRQ(ierr); ierr = VecDuplicate(T,&rhs);CHKERRQ(ierr); /* r: vector to put the computed right hand side */ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR);CHKERRQ(ierr); ierr = TSSetType(ts,TSBEULER);CHKERRQ(ierr); ierr = TSSetRHSFunction(ts,rhs,RhsFunc,&user);CHKERRQ(ierr); /* Set Jacobian evaluation routine - use coloring to compute finite difference Jacobian efficiently */ ierr = DMSetMatType(da,MATAIJ);CHKERRQ(ierr); ierr = DMCreateMatrix(da,&J);CHKERRQ(ierr); ierr = TSGetSNES(ts,&snes);CHKERRQ(ierr); if (use_coloring) { ISColoring iscoloring; ierr = DMCreateColoring(da,IS_COLORING_GLOBAL,&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringCreate(J,iscoloring,&matfdcoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); ierr = MatFDColoringSetUp(J,iscoloring,matfdcoloring);CHKERRQ(ierr); ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))SNESTSFormFunction,ts);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,J,J,SNESComputeJacobianDefaultColor,matfdcoloring);CHKERRQ(ierr); } else { ierr = SNESSetJacobian(snes,J,J,SNESComputeJacobianDefault,NULL);CHKERRQ(ierr); } /* Define what to print for ts_monitor option */ ierr = PetscOptionsHasName(NULL,NULL,"-monitor_off",&monitor_off);CHKERRQ(ierr); if (!monitor_off) { ierr = TSMonitorSet(ts,Monitor,&usermonitor,NULL);CHKERRQ(ierr); } ierr = FormInitialSolution(da,T,&user);CHKERRQ(ierr); dt = TIMESTEP; /* initial time step */ ftime = TIMESTEP*time; if (!rank) printf("time %d, ftime %g hour, TIMESTEP %g\n",time,(double)(ftime/3600),(double)dt); ierr = TSSetInitialTimeStep(ts,0.0,dt);CHKERRQ(ierr); ierr = TSSetDuration(ts,time,ftime);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); ierr = TSSetSolution(ts,T);CHKERRQ(ierr); ierr = TSSetDM(ts,da);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve nonlinear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,T);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); if (!rank) PetscPrintf(PETSC_COMM_WORLD,"Solution T after %g hours %d steps\n",(double)(ftime/3600),steps); if (matfdcoloring) {ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);} if (usermonitor.drawcontours) { ierr = PetscViewerDestroy(&usermonitor.drawviewer);CHKERRQ(ierr); } ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = VecDestroy(&T);CHKERRQ(ierr); ierr = VecDestroy(&rhs);CHKERRQ(ierr); ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
/* Two tetrahedrons separated by a zero-volume cell with 6 vertices cell 6 ___33___10______ cell 0 / | \ |\ \ 1 21 | 23 | 29 27 /12 24 14\ 30 \ \ 3-20-|----5--32-|---9--26--7 \ 13| 11/ |18 / / 19 | 22 | 28 25 \ | / |/ / 4----31----8------ cell 2 */ PetscErrorCode CreateSimplexHybrid_3D(MPI_Comm comm, PetscInt testNum, DM *dm) { DM idm = NULL, hdm = NULL; DMLabel faultLabel, hybridLabel; PetscInt p; PetscMPIInt rank; PetscErrorCode ierr; PetscFunctionBegin; ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); if (!rank) { switch (testNum) { case 0: { PetscInt numPoints[2] = {5, 2}; PetscInt coneSize[7] = {4, 4, 0, 0, 0, 0, 0}; PetscInt cones[8] = {4, 3, 5, 2, 5, 3, 4, 6}; PetscInt coneOrientations[8] = {0, 0, 0, 0, 0, 0, 0, 0}; PetscScalar vertexCoords[15] = {-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0}; PetscInt faultPoints[3] = {3, 4, 5}; ierr = DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); for(p = 0; p < 3; ++p) {ierr = DMSetLabelValue(*dm, "fault", faultPoints[p], 1);CHKERRQ(ierr);} } break; case 1: { /* Tets 0,3,5 and 1,2,4 */ PetscInt numPoints[2] = {9, 6}; PetscInt coneSize[15] = {4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0}; PetscInt cones[24] = { 7, 9, 8, 6, 11, 9, 13, 14, 10, 13, 11, 9, 10, 9, 11, 7, 9, 13, 14, 12, 7, 11, 8, 9}; PetscInt coneOrientations[24] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; PetscScalar vertexCoords[27] = {-2.0, -1.0, 0.0, -2.0, 0.0, 0.0, -2.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 2.0, -1.0, 0.0, 2.0, 0.0, 0.0, 2.0, 0.0, 1.0}; PetscInt faultPoints[3] = {9, 10, 11}; ierr = DMPlexCreateFromDAG(*dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); for(p = 0; p < 3; ++p) {ierr = DMSetLabelValue(*dm, "fault", faultPoints[p], 1);CHKERRQ(ierr);} } break; default: SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "No test mesh %d", testNum); } ierr = DMPlexCheckSymmetry(*dm);CHKERRQ(ierr); ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); ierr = DMPlexCopyCoordinates(*dm, idm);CHKERRQ(ierr); ierr = DMViewFromOptions(idm, NULL, "-in_dm_view");CHKERRQ(ierr); ierr = DMPlexCheckSymmetry(idm);CHKERRQ(ierr); ierr = DMGetLabel(*dm, "fault", &faultLabel);CHKERRQ(ierr); ierr = DMPlexCreateHybridMesh(idm, faultLabel, &hybridLabel, &hdm);CHKERRQ(ierr); ierr = DMLabelDestroy(&hybridLabel);CHKERRQ(ierr); ierr = DMDestroy(&idm);CHKERRQ(ierr); ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = hdm; } else { PetscInt numPoints[4] = {0, 0, 0, 0}; ierr = DMPlexCreateFromDAG(*dm, 1, numPoints, NULL, NULL, NULL, NULL);CHKERRQ(ierr); ierr = DMPlexInterpolate(*dm, &idm);CHKERRQ(ierr); ierr = DMPlexCopyCoordinates(*dm, idm);CHKERRQ(ierr); ierr = DMViewFromOptions(idm, NULL, "-in_dm_view");CHKERRQ(ierr); ierr = DMPlexCreateHybridMesh(idm, NULL, NULL, &hdm);CHKERRQ(ierr); ierr = DMDestroy(&idm);CHKERRQ(ierr); ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = hdm; } PetscFunctionReturn(0); }
/* ------------------------------------------------------- */ int main(int argc,char ** argv) { PetscErrorCode ierr; Wash wash; Junction junctions,junction; Pipe pipe,pipes; PetscInt numEdges,numVertices,KeyPipe,KeyJunction; int *edgelist = NULL; PetscInt i,e,v,eStart,eEnd,vStart,vEnd,pipeOffset,key,frombType,tobType; PetscInt vfrom,vto,vkey,fromOffset,toOffset,type,varoffset,pipeoffset; PetscInt from_nedge_in,from_nedge_out,to_nedge_in; const PetscInt *cone; DM networkdm; PetscMPIInt size,rank; PetscReal ftime = 2500.0; Vec X; TS ts; PetscInt maxsteps=-1,steps; TSConvergedReason reason; PetscBool viewpipes; PetscInt pipesCase; DMNetworkMonitor monitor; DMNetworkComponentGenericDataType *nwarr; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); /* Create and setup network */ /*--------------------------*/ ierr = DMNetworkCreate(PETSC_COMM_WORLD,&networkdm);CHKERRQ(ierr); if (size == 1) { ierr = DMNetworkMonitorCreate(networkdm,&monitor);CHKERRQ(ierr); } /* Register the components in the network */ ierr = DMNetworkRegisterComponent(networkdm,"junctionstruct",sizeof(struct _p_Junction),&KeyJunction);CHKERRQ(ierr); ierr = DMNetworkRegisterComponent(networkdm,"pipestruct",sizeof(struct _p_Pipe),&KeyPipe);CHKERRQ(ierr); /* Set global number of pipes, edges, and vertices */ pipesCase = 2; ierr = PetscOptionsGetInt(NULL,NULL, "-case", &pipesCase, NULL);CHKERRQ(ierr); ierr = WashNetworkCreate(PETSC_COMM_WORLD,pipesCase,&wash,&edgelist);CHKERRQ(ierr); numEdges = wash->nedge; numVertices = wash->nvertex; junctions = wash->junction; pipes = wash->pipe; /* Set number of vertices and edges */ ierr = DMNetworkSetSizes(networkdm,numVertices,numEdges,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); /* Add edge connectivity */ ierr = DMNetworkSetEdgeList(networkdm,edgelist);CHKERRQ(ierr); /* Set up the network layout */ ierr = DMNetworkLayoutSetUp(networkdm);CHKERRQ(ierr); /* Add EDGEDATA component to all edges -- currently networkdm is a sequential network */ ierr = DMNetworkGetEdgeRange(networkdm,&eStart,&eEnd);CHKERRQ(ierr); ierr = DMNetworkGetVertexRange(networkdm,&vStart,&vEnd);CHKERRQ(ierr); for (e = eStart; e < eEnd; e++) { /* Add Pipe component to all edges -- create pipe here */ ierr = DMNetworkAddComponent(networkdm,e,KeyPipe,&pipes[e-eStart]);CHKERRQ(ierr); /* Add number of variables to each edge */ ierr = DMNetworkAddNumVariables(networkdm,e,2*pipes[e-eStart].nnodes);CHKERRQ(ierr); if (size == 1) { /* Add monitor -- show Q_{pipes[e-eStart].id}? */ ierr = DMNetworkMonitorAdd(monitor, "Pipe Q", e, pipes[e-eStart].nnodes, 0, 2, -0.8, 0.8, PETSC_TRUE);CHKERRQ(ierr); ierr = DMNetworkMonitorAdd(monitor, "Pipe H", e, pipes[e-eStart].nnodes, 1, 2, -400.0, 800.0, PETSC_TRUE);CHKERRQ(ierr); } } /* Add Junction component to all vertices */ for (v = vStart; v < vEnd; v++) { ierr = DMNetworkAddComponent(networkdm,v,KeyJunction,&junctions[v-vStart]);CHKERRQ(ierr); /* Add number of variables to vertex */ ierr = DMNetworkAddNumVariables(networkdm,v,2);CHKERRQ(ierr); } /* Set up DM for use */ ierr = DMSetUp(networkdm);CHKERRQ(ierr); ierr = WashNetworkCleanUp(wash,edgelist);CHKERRQ(ierr); /* Network partitioning and distribution of data */ if (size > 1) { DM distnetworkdm; ierr = DMNetworkDistribute(networkdm,0,&distnetworkdm);CHKERRQ(ierr); ierr = DMDestroy(&networkdm);CHKERRQ(ierr); networkdm = distnetworkdm; } /* PipeSetUp -- each process only sets its own pipes */ /*---------------------------------------------------*/ ierr = DMNetworkGetComponentDataArray(networkdm,&nwarr);CHKERRQ(ierr); ierr = DMNetworkGetEdgeRange(networkdm,&eStart,&eEnd);CHKERRQ(ierr); for (e=eStart; e<eEnd; e++) { /* each edge has only one component, pipe */ ierr = DMNetworkGetComponentTypeOffset(networkdm,e,0,&type,&pipeoffset);CHKERRQ(ierr); ierr = DMNetworkGetVariableOffset(networkdm,e,&varoffset);CHKERRQ(ierr); pipe = (Pipe)(nwarr + pipeoffset); /* Setup conntected vertices */ ierr = DMNetworkGetConnectedNodes(networkdm,e,&cone);CHKERRQ(ierr); vfrom = cone[0]; /* local ordering */ vto = cone[1]; /* vfrom */ ierr = DMNetworkGetComponentTypeOffset(networkdm,vfrom,0,&vkey,&fromOffset);CHKERRQ(ierr); junction = (Junction)(nwarr+fromOffset); from_nedge_in = junction->nedges_in; from_nedge_out = junction->nedges_out; /* vto */ ierr = DMNetworkGetComponentTypeOffset(networkdm,vto,0,&vkey,&toOffset);CHKERRQ(ierr); junction = (Junction)(nwarr+toOffset); to_nedge_in = junction->nedges_in; pipe->comm = PETSC_COMM_SELF; /* must be set here, otherwise crashes in my mac??? */ wash->nnodes_loc += pipe->nnodes; /* local total num of nodes, will be used by PipesView() */ ierr = PipeSetParameters(pipe, 600.0, /* length */ pipe->nnodes, /* nnodes -- rm from PipeSetParameters */ 0.5, /* diameter */ 1200.0, /* a */ 0.018);CHKERRQ(ierr); /* friction */ /* set boundary conditions for this pipe */ if (from_nedge_in <= 1 && from_nedge_out > 0) { frombType = 0; } else { frombType = 1; } if (to_nedge_in == 1) { tobType = 0; } else { tobType = 1; } if (frombType == 0) { pipe->boundary.Q0 = PIPE_CHARACTERISTIC; /* will be obtained from characteristic */ pipe->boundary.H0 = wash->H0; } else { pipe->boundary.Q0 = wash->Q0; pipe->boundary.H0 = PIPE_CHARACTERISTIC; /* will be obtained from characteristic */ } if (tobType == 0) { pipe->boundary.QL = wash->QL; pipe->boundary.HL = PIPE_CHARACTERISTIC; /* will be obtained from characteristic */ } else { pipe->boundary.QL = PIPE_CHARACTERISTIC; /* will be obtained from characteristic */ pipe->boundary.HL = wash->HL; } ierr = PipeSetUp(pipe);CHKERRQ(ierr); } /* create vectors */ ierr = DMCreateGlobalVector(networkdm,&X);CHKERRQ(ierr); ierr = DMCreateLocalVector(networkdm,&wash->localX);CHKERRQ(ierr); ierr = DMCreateLocalVector(networkdm,&wash->localXdot);CHKERRQ(ierr); /* Setup solver */ /*--------------------------------------------------------*/ ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); ierr = TSSetDM(ts,(DM)networkdm);CHKERRQ(ierr); ierr = TSSetIFunction(ts,NULL,WASHIFunction,wash);CHKERRQ(ierr); ierr = TSSetDuration(ts,maxsteps,ftime);CHKERRQ(ierr); ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); ierr = TSSetInitialTimeStep(ts,0.0,0.1);CHKERRQ(ierr); ierr = TSSetType(ts,TSBEULER);CHKERRQ(ierr); if (size == 1) { ierr = TSMonitorSet(ts, TSDMNetworkMonitor, monitor, NULL);CHKERRQ(ierr); } ierr = TSSetFromOptions(ts);CHKERRQ(ierr); ierr = WASHSetInitialSolution(networkdm,X,wash);CHKERRQ(ierr); ierr = TSSolve(ts,X);CHKERRQ(ierr); ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr); ierr = TSGetConvergedReason(ts,&reason);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"%s at time %g after %D steps\n",TSConvergedReasons[reason],(double)ftime,steps);CHKERRQ(ierr); /* ierr = VecView(X,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); */ /* View solution q and h */ /* --------------------- */ viewpipes = PETSC_FALSE; ierr = PetscOptionsGetBool(NULL,NULL, "-pipe_view", &viewpipes,NULL);CHKERRQ(ierr); if (viewpipes) { ierr = PipesView(X,networkdm,wash);CHKERRQ(ierr); } /* Free spaces */ /* ----------- */ ierr = TSDestroy(&ts);CHKERRQ(ierr); ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&wash->localX);CHKERRQ(ierr); ierr = VecDestroy(&wash->localXdot);CHKERRQ(ierr); /* Destroy objects from each pipe that are created in PipeSetUp() */ ierr = DMNetworkGetEdgeRange(networkdm,&eStart, &eEnd);CHKERRQ(ierr); for (i = eStart; i < eEnd; i++) { ierr = DMNetworkGetComponentTypeOffset(networkdm,i,0,&key,&pipeOffset);CHKERRQ(ierr); pipe = (Pipe)(nwarr+pipeOffset); ierr = DMDestroy(&(pipe->da));CHKERRQ(ierr); ierr = VecDestroy(&pipe->x);CHKERRQ(ierr); } if (size == 1) { ierr = DMNetworkMonitorDestroy(&monitor);CHKERRQ(ierr); } ierr = DMDestroy(&networkdm);CHKERRQ(ierr); ierr = PetscFree(wash);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) { PetscInt dim = user->dim; PetscInt numRefinements = user->numRefinements; PetscBool cellHybrid = user->cellHybrid; PetscBool cellSimplex = user->cellSimplex; PetscMPIInt rank; PetscErrorCode ierr; PetscFunctionBegin; ierr = MPI_Comm_rank(comm, &rank);CHKERRQ(ierr); ierr = DMCreate(comm, dm);CHKERRQ(ierr); ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); ierr = DMSetDimension(*dm, dim);CHKERRQ(ierr); switch (dim) { case 1: if (cellHybrid) SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot make hybrid meshes for dimension %d", dim); ierr = CreateSimplex_1D(comm, dm);CHKERRQ(ierr); break; case 2: if (cellSimplex) { if (cellHybrid) { ierr = CreateSimplexHybrid_2D(comm, user->testNum, dm);CHKERRQ(ierr); } else { ierr = CreateSimplex_2D(comm, dm);CHKERRQ(ierr); } } else { if (cellHybrid) { ierr = CreateTensorProductHybrid_2D(comm, user->testNum, dm);CHKERRQ(ierr); } else { ierr = CreateTensorProduct_2D(comm, user->testNum, dm);CHKERRQ(ierr); } } break; case 3: if (cellSimplex) { if (cellHybrid) { ierr = CreateSimplexHybrid_3D(comm, user->testNum, dm);CHKERRQ(ierr); } else { ierr = CreateSimplex_3D(comm, user->testNum, dm);CHKERRQ(ierr); } } else { if (cellHybrid) { ierr = CreateTensorProductHybrid_3D(comm, user->testNum, dm);CHKERRQ(ierr); } else { ierr = CreateTensorProduct_3D(comm, user->testNum, dm);CHKERRQ(ierr); } } break; default: SETERRQ1(comm, PETSC_ERR_ARG_OUTOFRANGE, "Cannot make meshes for dimension %d", dim); } { DM refinedMesh = NULL; DM distributedMesh = NULL; PetscInt r; /* Distribute mesh over processes */ ierr = DMPlexDistribute(*dm, 0, NULL, &distributedMesh);CHKERRQ(ierr); if (distributedMesh) { ierr = DMViewFromOptions(distributedMesh, NULL, "-dm_view");CHKERRQ(ierr); ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = distributedMesh; } for (r = 0; r < numRefinements; ++r) { ierr = DMViewFromOptions(*dm, NULL, "-orig_dm_view");CHKERRQ(ierr); ierr = DMPlexCheckSymmetry(*dm);CHKERRQ(ierr); ierr = DMPlexCheckSkeleton(*dm, user->cellSimplex, 0);CHKERRQ(ierr); ierr = DMPlexCheckFaces(*dm, user->cellSimplex, 0);CHKERRQ(ierr); ierr = DMPlexSetRefinementUniform(*dm, PETSC_TRUE);CHKERRQ(ierr); ierr = DMRefine(*dm, comm, &refinedMesh);CHKERRQ(ierr); if (refinedMesh) { ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = refinedMesh; } } } if (user->uninterpolate) { DM udm = NULL; ierr = DMPlexUninterpolate(*dm, &udm);CHKERRQ(ierr); ierr = DMDestroy(dm);CHKERRQ(ierr); *dm = udm; } ierr = PetscObjectSetName((PetscObject) *dm, "Hybrid Mesh");CHKERRQ(ierr); ierr = DMViewFromOptions(*dm, NULL, "-dm_view");CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscErrorCode ierr; PetscInt nredundant1 = 5,nredundant2 = 2,i; ISLocalToGlobalMapping *ltog; PetscMPIInt rank,size; DM packer; Vec global,local1,local2,redundant1,redundant2; PF pf; DM da1,da2,dmred1,dmred2; PetscScalar *redundant1a,*redundant2a; PetscViewer sviewer; PetscBool gather_add = PETSC_FALSE; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = PetscOptionsGetBool(PETSC_NULL,"-gather_add",&gather_add,PETSC_NULL);CHKERRQ(ierr); ierr = DMCompositeCreate(PETSC_COMM_WORLD,&packer);CHKERRQ(ierr); ierr = DMRedundantCreate(PETSC_COMM_WORLD,0,nredundant1,&dmred1);CHKERRQ(ierr); ierr = DMCreateLocalVector(dmred1,&redundant1);CHKERRQ(ierr); ierr = DMCompositeAddDM(packer,dmred1);CHKERRQ(ierr); ierr = DMDACreate1d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,8,1,1,PETSC_NULL,&da1);CHKERRQ(ierr); ierr = DMCreateLocalVector(da1,&local1);CHKERRQ(ierr); ierr = DMCompositeAddDM(packer,da1);CHKERRQ(ierr); ierr = DMRedundantCreate(PETSC_COMM_WORLD,1%size,nredundant2,&dmred2);CHKERRQ(ierr); ierr = DMCreateLocalVector(dmred2,&redundant2);CHKERRQ(ierr); ierr = DMCompositeAddDM(packer,dmred2);CHKERRQ(ierr); ierr = DMDACreate1d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,6,1,1,PETSC_NULL,&da2);CHKERRQ(ierr); ierr = DMCreateLocalVector(da2,&local2);CHKERRQ(ierr); ierr = DMCompositeAddDM(packer,da2);CHKERRQ(ierr); ierr = DMCreateGlobalVector(packer,&global);CHKERRQ(ierr); ierr = PFCreate(PETSC_COMM_WORLD,1,1,&pf);CHKERRQ(ierr); ierr = PFSetType(pf,PFIDENTITY,PETSC_NULL);CHKERRQ(ierr); ierr = PFApplyVec(pf,PETSC_NULL,global);CHKERRQ(ierr); ierr = PFDestroy(&pf);CHKERRQ(ierr); ierr = VecView(global,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = DMCompositeScatter(packer,global,redundant1,local1,redundant2,local2);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD,PETSC_TRUE);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD,"[%d] My part of redundant1 vector\n",rank);CHKERRQ(ierr); ierr = PetscViewerGetSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); ierr = VecView(redundant1,sviewer);CHKERRQ(ierr); ierr = PetscViewerRestoreSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD,PETSC_TRUE);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD,"[%d] My part of da1 vector\n",rank);CHKERRQ(ierr); ierr = PetscViewerGetSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); ierr = VecView(local1,sviewer);CHKERRQ(ierr); ierr = PetscViewerRestoreSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD,PETSC_TRUE);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD,"[%d] My part of redundant2 vector\n",rank);CHKERRQ(ierr); ierr = PetscViewerGetSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); ierr = VecView(redundant2,sviewer);CHKERRQ(ierr); ierr = PetscViewerRestoreSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD,PETSC_TRUE);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD,"[%d] My part of da2 vector\n",rank);CHKERRQ(ierr); ierr = PetscViewerGetSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); ierr = VecView(local2,sviewer);CHKERRQ(ierr); ierr = PetscViewerRestoreSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); ierr = VecGetArray(redundant1,&redundant1a);CHKERRQ(ierr); ierr = VecGetArray(redundant2,&redundant2a);CHKERRQ(ierr); for (i=0; i<nredundant1; i++) redundant1a[i] = (rank+2)*i; for (i=0; i<nredundant2; i++) redundant2a[i] = (rank+10)*i; ierr = VecRestoreArray(redundant1,&redundant1a);CHKERRQ(ierr); ierr = VecRestoreArray(redundant2,&redundant2a);CHKERRQ(ierr); ierr = DMCompositeGather(packer,global,gather_add?ADD_VALUES:INSERT_VALUES,redundant1,local1,redundant2,local2);CHKERRQ(ierr); ierr = VecView(global,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* get the global numbering for each subvector element */ ierr = DMCompositeGetISLocalToGlobalMappings(packer,<og);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD,"Local to global mapping of redundant1 vector\n");CHKERRQ(ierr); ierr = ISLocalToGlobalMappingView(ltog[0],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD,"Local to global mapping of local1 vector\n");CHKERRQ(ierr); ierr = ISLocalToGlobalMappingView(ltog[1],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD,"Local to global mapping of redundant2 vector\n");CHKERRQ(ierr); ierr = ISLocalToGlobalMappingView(ltog[2],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD,"Local to global mapping of local2 vector\n");CHKERRQ(ierr); ierr = ISLocalToGlobalMappingView(ltog[3],PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); for (i=0; i<4; i++) {ierr = ISLocalToGlobalMappingDestroy(<og[i]);CHKERRQ(ierr);} ierr = PetscFree(ltog);CHKERRQ(ierr); ierr = DMDestroy(&da1);CHKERRQ(ierr); ierr = DMDestroy(&dmred1);CHKERRQ(ierr); ierr = DMDestroy(&dmred2);CHKERRQ(ierr); ierr = DMDestroy(&da2);CHKERRQ(ierr); ierr = VecDestroy(&redundant1);CHKERRQ(ierr); ierr = VecDestroy(&redundant2);CHKERRQ(ierr); ierr = VecDestroy(&local1);CHKERRQ(ierr); ierr = VecDestroy(&local2);CHKERRQ(ierr); ierr = VecDestroy(&global);CHKERRQ(ierr); ierr = DMDestroy(&packer);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { PetscMPIInt rank; PetscErrorCode ierr; PetscInt M = 10,N = 8,m = PETSC_DECIDE; PetscInt s=2,w=2,n = PETSC_DECIDE,nloc,l,i,j,kk; PetscInt Xs,Xm,Ys,Ym,iloc,*iglobal,*ltog; PetscInt *lx = PETSC_NULL,*ly = PETSC_NULL; PetscBool testorder = PETSC_FALSE,flg; DMDABoundaryType bx = DMDA_BOUNDARY_NONE,by= DMDA_BOUNDARY_NONE; DM da; PetscViewer viewer; Vec local,global; PetscScalar value; DMDAStencilType st = DMDA_STENCIL_BOX; AO ao; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,0,"",300,0,400,400,&viewer);CHKERRQ(ierr); /* Readoptions */ ierr = PetscOptionsGetInt(PETSC_NULL,"-NX",&M,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-NY",&N,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-m",&m,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-n",&n,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-s",&s,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-w",&w,PETSC_NULL);CHKERRQ(ierr); flg = PETSC_FALSE; ierr = PetscOptionsGetBool(PETSC_NULL,"-xperiodic",&flg,PETSC_NULL);CHKERRQ(ierr); if (flg) bx = DMDA_BOUNDARY_PERIODIC; flg = PETSC_FALSE; ierr = PetscOptionsGetBool(PETSC_NULL,"-yperiodic",&flg,PETSC_NULL);CHKERRQ(ierr); if (flg) by = DMDA_BOUNDARY_PERIODIC; flg = PETSC_FALSE; ierr = PetscOptionsGetBool(PETSC_NULL,"-xghosted",&flg,PETSC_NULL);CHKERRQ(ierr); if (flg) bx = DMDA_BOUNDARY_GHOSTED; flg = PETSC_FALSE; ierr = PetscOptionsGetBool(PETSC_NULL,"-yghosted",&flg,PETSC_NULL);CHKERRQ(ierr); if (flg) by = DMDA_BOUNDARY_GHOSTED; flg = PETSC_FALSE; ierr = PetscOptionsGetBool(PETSC_NULL,"-star",&flg,PETSC_NULL);CHKERRQ(ierr); if (flg) st = DMDA_STENCIL_STAR; flg = PETSC_FALSE; ierr = PetscOptionsGetBool(PETSC_NULL,"-box",&flg,PETSC_NULL);CHKERRQ(ierr); if (flg) st = DMDA_STENCIL_BOX; flg = PETSC_FALSE; ierr = PetscOptionsGetBool(PETSC_NULL,"-testorder",&testorder,PETSC_NULL);CHKERRQ(ierr); /* Test putting two nodes in x and y on each processor, exact last processor in x and y gets the rest. */ flg = PETSC_FALSE; ierr = PetscOptionsGetBool(PETSC_NULL,"-distribute",&flg,PETSC_NULL);CHKERRQ(ierr); if (flg) { if (m == PETSC_DECIDE) SETERRQ(PETSC_COMM_WORLD,1,"Must set -m option with -distribute option"); ierr = PetscMalloc(m*sizeof(PetscInt),&lx);CHKERRQ(ierr); for (i=0; i<m-1; i++) { lx[i] = 4;} lx[m-1] = M - 4*(m-1); if (n == PETSC_DECIDE) SETERRQ(PETSC_COMM_WORLD,1,"Must set -n option with -distribute option"); ierr = PetscMalloc(n*sizeof(PetscInt),&ly);CHKERRQ(ierr); for (i=0; i<n-1; i++) { ly[i] = 2;} ly[n-1] = N - 2*(n-1); } /* Create distributed array and get vectors */ ierr = DMDACreate2d(PETSC_COMM_WORLD,bx,by,st,M,N,m,n,w,s,lx,ly,&da);CHKERRQ(ierr); ierr = PetscFree(lx);CHKERRQ(ierr); ierr = PetscFree(ly);CHKERRQ(ierr); ierr = DMView(da,viewer);CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&global);CHKERRQ(ierr); ierr = DMCreateLocalVector(da,&local);CHKERRQ(ierr); /* Set global vector; send ghost points to local vectors */ value = 1; ierr = VecSet(global,value);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr); /* Scale local vectors according to processor rank; pass to global vector */ ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); value = rank; ierr = VecScale(local,value);CHKERRQ(ierr); ierr = DMLocalToGlobalBegin(da,local,INSERT_VALUES,global);CHKERRQ(ierr); ierr = DMLocalToGlobalEnd(da,local,INSERT_VALUES,global);CHKERRQ(ierr); if (!testorder) { /* turn off printing when testing ordering mappings */ ierr = PetscPrintf (PETSC_COMM_WORLD,"\nGlobal Vectors:\n");CHKERRQ(ierr); ierr = VecView(global,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscPrintf (PETSC_COMM_WORLD,"\n\n");CHKERRQ(ierr); } /* Send ghost points to local vectors */ ierr = DMGlobalToLocalBegin(da,global,INSERT_VALUES,local);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,global,INSERT_VALUES,local);CHKERRQ(ierr); flg = PETSC_FALSE; ierr = PetscOptionsGetBool(PETSC_NULL,"-local_print",&flg,PETSC_NULL);CHKERRQ(ierr); if (flg) { PetscViewer sviewer; ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,"\nLocal Vector: processor %d\n",rank);CHKERRQ(ierr); ierr = PetscViewerGetSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); ierr = VecView(local,sviewer);CHKERRQ(ierr); ierr = PetscViewerRestoreSingleton(PETSC_VIEWER_STDOUT_WORLD,&sviewer);CHKERRQ(ierr); } /* Tests mappings betweeen application/PETSc orderings */ if (testorder) { ierr = DMDAGetGhostCorners(da,&Xs,&Ys,PETSC_NULL,&Xm,&Ym,PETSC_NULL);CHKERRQ(ierr); ierr = DMDAGetGlobalIndices(da,&nloc,<og);CHKERRQ(ierr); ierr = DMDAGetAO(da,&ao);CHKERRQ(ierr); ierr = PetscMalloc(nloc*sizeof(PetscInt),&iglobal);CHKERRQ(ierr); /* Set iglobal to be global indices for each processor's local and ghost nodes, using the DMDA ordering of grid points */ kk = 0; for (j=Ys; j<Ys+Ym; j++) { for (i=Xs; i<Xs+Xm; i++) { iloc = w*((j-Ys)*Xm + i-Xs); for (l=0; l<w; l++) { iglobal[kk++] = ltog[iloc+l]; } } } /* Map this to the application ordering (which for DMDAs is just the natural ordering that would be used for 1 processor, numbering most rapidly by x, then y) */ ierr = AOPetscToApplication(ao,nloc,iglobal);CHKERRQ(ierr); /* Then map the application ordering back to the PETSc DMDA ordering */ ierr = AOApplicationToPetsc(ao,nloc,iglobal);CHKERRQ(ierr); /* Verify the mappings */ kk=0; for (j=Ys; j<Ys+Ym; j++) { for (i=Xs; i<Xs+Xm; i++) { iloc = w*((j-Ys)*Xm + i-Xs); for (l=0; l<w; l++) { if (iglobal[kk] != ltog[iloc+l]) { ierr = PetscFPrintf(PETSC_COMM_SELF,stdout,"[%d] Problem with mapping: j=%D, i=%D, l=%D, petsc1=%D, petsc2=%D\n", rank,j,i,l,ltog[iloc+l],iglobal[kk]);} kk++; } } } ierr = PetscFree(iglobal);CHKERRQ(ierr); } /* Free memory */ ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = VecDestroy(&local);CHKERRQ(ierr); ierr = VecDestroy(&global);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { TS ts; /* nonlinear solver */ Vec u; /* solution, residual vectors */ Mat J; /* Jacobian matrix */ PetscInt maxsteps = 1000; /* iterations for convergence */ PetscInt nsteps; PetscReal vmin,vmax,norm; PetscErrorCode ierr; DM da; PetscReal ftime,dt; AppCtx user; /* user-defined work context */ JacobianType jacType; PetscInitialize(&argc,&argv,(char*)0,help); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create distributed array (DMDA) to manage parallel grid and vectors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMDACreate1d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,-11,1,1,NULL,&da); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Extract global vectors from DMDA; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = DMCreateGlobalVector(da,&u); CHKERRQ(ierr); /* Initialize user application context */ user.c = -30.0; user.boundary = 0; /* 0: Dirichlet BC; 1: Neumann BC */ user.viewJacobian = PETSC_FALSE; ierr = PetscOptionsGetInt(NULL,"-boundary",&user.boundary,NULL); CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,"-viewJacobian",&user.viewJacobian); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create timestepping solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSCreate(PETSC_COMM_WORLD,&ts); CHKERRQ(ierr); ierr = TSSetProblemType(ts,TS_NONLINEAR); CHKERRQ(ierr); ierr = TSSetType(ts,TSTHETA); CHKERRQ(ierr); ierr = TSThetaSetTheta(ts,1.0); CHKERRQ(ierr); /* Make the Theta method behave like backward Euler */ ierr = TSSetIFunction(ts,NULL,FormIFunction,&user); CHKERRQ(ierr); ierr = DMSetMatType(da,MATAIJ); CHKERRQ(ierr); ierr = DMCreateMatrix(da,&J); CHKERRQ(ierr); jacType = JACOBIAN_ANALYTIC; /* use user-provide Jacobian */ ierr = TSSetDM(ts,da); CHKERRQ(ierr); /* Use TSGetDM() to access. Setting here allows easy use of geometric multigrid. */ ftime = 1.0; ierr = TSSetDuration(ts,maxsteps,ftime); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set initial conditions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = FormInitialSolution(ts,u,&user); CHKERRQ(ierr); ierr = TSSetSolution(ts,u); CHKERRQ(ierr); dt = .01; ierr = TSSetInitialTimeStep(ts,0.0,dt); CHKERRQ(ierr); /* Use slow fd Jacobian or fast fd Jacobian with colorings. Note: this requirs snes which is not created until TSSetUp()/TSSetFromOptions() is called */ ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Options for Jacobian evaluation",NULL); CHKERRQ(ierr); ierr = PetscOptionsEnum("-jac_type","Type of Jacobian","",JacobianTypes,(PetscEnum)jacType,(PetscEnum*)&jacType,0); CHKERRQ(ierr); ierr = PetscOptionsEnd(); CHKERRQ(ierr); if (jacType == JACOBIAN_ANALYTIC) { ierr = TSSetIJacobian(ts,J,J,FormIJacobian,&user); CHKERRQ(ierr); } else if (jacType == JACOBIAN_FD_COLORING) { SNES snes; ierr = TSGetSNES(ts,&snes); CHKERRQ(ierr); ierr = SNESSetJacobian(snes,J,J,SNESComputeJacobianDefaultColor,0); CHKERRQ(ierr); } else if (jacType == JACOBIAN_FD_FULL) { SNES snes; ierr = TSGetSNES(ts,&snes); CHKERRQ(ierr); ierr = SNESSetJacobian(snes,J,J,SNESComputeJacobianDefault,&user); CHKERRQ(ierr); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Set runtime options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSetFromOptions(ts); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Integrate ODE system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = TSSolve(ts,u); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Compute diagnostics of the solution - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = VecNorm(u,NORM_1,&norm); CHKERRQ(ierr); ierr = VecMax(u,NULL,&vmax); CHKERRQ(ierr); ierr = VecMin(u,NULL,&vmin); CHKERRQ(ierr); ierr = TSGetTimeStepNumber(ts,&nsteps); CHKERRQ(ierr); ierr = TSGetTime(ts,&ftime); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"timestep %D: time %G, solution norm %G, max %G, min %G\n",nsteps,ftime,norm,vmax,vmin); CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Free work space. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDestroy(&J); CHKERRQ(ierr); ierr = VecDestroy(&u); CHKERRQ(ierr); ierr = TSDestroy(&ts); CHKERRQ(ierr); ierr = DMDestroy(&da); CHKERRQ(ierr); ierr = PetscFinalize(); PetscFunctionReturn(0); }