PETSC_EXTERN void PETSC_STDCALL petscfvsetnumcomponents_(PetscFV fvm,PetscInt *comp, int *__ierr ){ *__ierr = PetscFVSetNumComponents( (PetscFV)PetscToPointer((fvm) ),*comp); }
int main(int argc, char **argv) { MPI_Comm comm; DM base, preForest, postForest; PetscInt dim = 2; PetscInt preCount, postCount; Vec preVec, postVecTransfer, postVecExact; PetscErrorCode (*funcs[1]) (PetscInt,PetscReal,const PetscReal [],PetscInt,PetscScalar [], void *) = {MultiaffineFunction}; void *ctxs[1] = {NULL}; const PetscInt cells[] = {3, 3, 3}; PetscReal diff, tol = PETSC_SMALL; PetscBool linear = PETSC_FALSE; PetscBool useFV = PETSC_FALSE; PetscDS ds; bc_func_ctx bcCtx; DMLabel adaptLabel; PetscErrorCode ierr; ierr = PetscInitialize(&argc, &argv, NULL,help);if (ierr) return ierr; comm = PETSC_COMM_WORLD; ierr = PetscOptionsBegin(comm, "", "DMForestTransferVec() Test Options", "DMFOREST");CHKERRQ(ierr); ierr = PetscOptionsInt("-dim", "The dimension (2 or 3)", "ex2.c", dim, &dim, NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-linear","Transfer a simple linear function", "ex2.c", linear, &linear, NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-use_fv","Use a finite volume approximation", "ex2.c", useFV, &useFV, NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); if (linear) { funcs[0] = LinearFunction; } bcCtx.func = funcs[0]; bcCtx.dim = dim; bcCtx.Nf = 1; bcCtx.ctx = NULL; /* the base mesh */ ierr = DMPlexCreateHexBoxMesh(comm, dim, cells, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, DM_BOUNDARY_NONE, &base);CHKERRQ(ierr); if (useFV) { PetscFV fv; PetscLimiter limiter; DM baseFV; ierr = DMPlexConstructGhostCells(base,NULL,NULL,&baseFV);CHKERRQ(ierr); ierr = DMDestroy(&base);CHKERRQ(ierr); base = baseFV; ierr = PetscFVCreate(comm, &fv);CHKERRQ(ierr); ierr = PetscFVSetSpatialDimension(fv,dim);CHKERRQ(ierr); ierr = PetscFVSetType(fv,PETSCFVLEASTSQUARES);CHKERRQ(ierr); ierr = PetscFVSetNumComponents(fv,1);CHKERRQ(ierr); ierr = PetscLimiterCreate(comm,&limiter);CHKERRQ(ierr); ierr = PetscLimiterSetType(limiter,PETSCLIMITERNONE);CHKERRQ(ierr); ierr = PetscFVSetLimiter(fv,limiter);CHKERRQ(ierr); ierr = PetscLimiterDestroy(&limiter);CHKERRQ(ierr); ierr = PetscFVSetFromOptions(fv);CHKERRQ(ierr); ierr = DMSetField(base,0,(PetscObject)fv);CHKERRQ(ierr); ierr = PetscFVDestroy(&fv);CHKERRQ(ierr); } else { PetscFE fe; ierr = PetscFECreateDefault(base,dim,1,PETSC_FALSE,NULL,PETSC_DEFAULT,&fe);CHKERRQ(ierr); ierr = DMSetField(base,0,(PetscObject)fe);CHKERRQ(ierr); ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); } { PetscDS prob; PetscInt comps[] = {0}; PetscInt ids[] = {1, 2, 3, 4, 5, 6}; ierr = DMGetDS(base,&prob);CHKERRQ(ierr); ierr = PetscDSAddBoundary(prob,PETSC_TRUE, "bc", "marker", 0, 1, comps, useFV ? (void(*)()) bc_func_fv : (void(*)()) funcs[0], 2 * dim, ids, useFV ? (void *) &bcCtx : NULL);CHKERRQ(ierr); } ierr = AddIdentityLabel(base);CHKERRQ(ierr); ierr = DMViewFromOptions(base,NULL,"-dm_base_view");CHKERRQ(ierr); /* the pre adaptivity forest */ ierr = DMCreate(comm,&preForest);CHKERRQ(ierr); ierr = DMSetType(preForest,(dim == 2) ? DMP4EST : DMP8EST);CHKERRQ(ierr); ierr = DMGetDS(base,&ds);CHKERRQ(ierr); ierr = DMSetDS(preForest,ds);CHKERRQ(ierr); ierr = DMForestSetBaseDM(preForest,base);CHKERRQ(ierr); ierr = DMForestSetMinimumRefinement(preForest,1);CHKERRQ(ierr); ierr = DMForestSetInitialRefinement(preForest,1);CHKERRQ(ierr); ierr = DMSetFromOptions(preForest);CHKERRQ(ierr); ierr = DMSetUp(preForest);CHKERRQ(ierr); ierr = DMViewFromOptions(preForest,NULL,"-dm_pre_view");CHKERRQ(ierr); /* the pre adaptivity field */ ierr = DMCreateGlobalVector(preForest,&preVec);CHKERRQ(ierr); ierr = DMProjectFunction(preForest,0.,funcs,ctxs,INSERT_VALUES,preVec);CHKERRQ(ierr); ierr = VecViewFromOptions(preVec,NULL,"-vec_pre_view");CHKERRQ(ierr); ierr = PetscObjectGetReference((PetscObject)preForest,&preCount);CHKERRQ(ierr); /* adapt */ ierr = CreateAdaptivityLabel(preForest,&adaptLabel);CHKERRQ(ierr); ierr = DMForestTemplate(preForest,comm,&postForest);CHKERRQ(ierr); ierr = DMForestSetMinimumRefinement(postForest,0);CHKERRQ(ierr); ierr = DMForestSetInitialRefinement(postForest,0);CHKERRQ(ierr); ierr = DMForestSetAdaptivityLabel(postForest,adaptLabel);CHKERRQ(ierr); ierr = DMLabelDestroy(&adaptLabel);CHKERRQ(ierr); ierr = DMSetUp(postForest);CHKERRQ(ierr); ierr = DMViewFromOptions(postForest,NULL,"-dm_post_view");CHKERRQ(ierr); /* transfer */ ierr = DMCreateGlobalVector(postForest,&postVecTransfer);CHKERRQ(ierr); ierr = DMForestTransferVec(preForest,preVec,postForest,postVecTransfer,PETSC_TRUE,0.0);CHKERRQ(ierr); ierr = VecViewFromOptions(postVecTransfer,NULL,"-vec_post_transfer_view");CHKERRQ(ierr); /* the exact post adaptivity field */ ierr = DMCreateGlobalVector(postForest,&postVecExact);CHKERRQ(ierr); ierr = DMProjectFunction(postForest,0.,funcs,ctxs,INSERT_VALUES,postVecExact);CHKERRQ(ierr); ierr = VecViewFromOptions(postVecExact,NULL,"-vec_post_exact_view");CHKERRQ(ierr); /* compare */ ierr = VecAXPY(postVecTransfer,-1.,postVecExact);CHKERRQ(ierr); ierr = VecViewFromOptions(postVecTransfer,NULL,"-vec_diff_view");CHKERRQ(ierr); ierr = VecNorm(postVecTransfer,NORM_2,&diff);CHKERRQ(ierr); /* output */ if (diff < tol) { ierr = PetscPrintf(comm,"DMForestTransferVec() passes.\n");CHKERRQ(ierr); } else { ierr = PetscPrintf(comm,"DMForestTransferVec() fails with error %g and tolerance %g\n",diff,tol);CHKERRQ(ierr); } /* disconnect preForest from postForest */ ierr = DMForestSetAdaptivityForest(postForest,NULL);CHKERRQ(ierr); ierr = PetscObjectGetReference((PetscObject)preForest,&postCount);CHKERRQ(ierr); if (postCount != preCount) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Adaptation not memory neutral: reference count increase from %d to %d\n",preCount,postCount); /* cleanup */ ierr = VecDestroy(&postVecExact);CHKERRQ(ierr); ierr = VecDestroy(&postVecTransfer);CHKERRQ(ierr); ierr = DMDestroy(&postForest);CHKERRQ(ierr); ierr = VecDestroy(&preVec);CHKERRQ(ierr); ierr = DMDestroy(&preForest);CHKERRQ(ierr); ierr = DMDestroy(&base);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }