static PetscErrorCode DMTSConvertPlex(DM dm, DM *plex, PetscBool copy) { PetscBool isPlex; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscObjectTypeCompare((PetscObject) dm, DMPLEX, &isPlex);CHKERRQ(ierr); if (isPlex) { *plex = dm; ierr = PetscObjectReference((PetscObject) dm);CHKERRQ(ierr); } else { ierr = PetscObjectQuery((PetscObject) dm, "dm_plex", (PetscObject *) plex);CHKERRQ(ierr); if (!*plex) { ierr = DMConvert(dm,DMPLEX,plex);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dm, "dm_plex", (PetscObject) *plex);CHKERRQ(ierr); if (copy) { PetscInt i; PetscObject obj; const char *comps[3] = {"A","dmAux","dmCh"}; ierr = DMCopyDMTS(dm, *plex);CHKERRQ(ierr); ierr = DMCopyDMSNES(dm, *plex);CHKERRQ(ierr); for (i = 0; i < 3; i++) { ierr = PetscObjectQuery((PetscObject) dm, comps[i], &obj);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) *plex, comps[i], obj);CHKERRQ(ierr); } } } else { ierr = PetscObjectReference((PetscObject) *plex);CHKERRQ(ierr); } } PetscFunctionReturn(0); }
PetscErrorCode private_PetscViewerDestroy_XDMF(PetscViewer *v) { PetscViewer viewer; DM dm = NULL; long int *bytes; PetscContainer container = NULL; PetscErrorCode ierr; PetscFunctionBegin; if (!v) PetscFunctionReturn(0); viewer = *v; ierr = PetscObjectQuery((PetscObject)viewer,"DMSwarm",(PetscObject*)&dm);CHKERRQ(ierr); if (dm) { ierr = PetscViewerASCIIPrintf(viewer,"</Grid>\n");CHKERRQ(ierr); ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); } /* close xdmf header */ ierr = PetscViewerASCIIPrintf(viewer,"</Domain>\n");CHKERRQ(ierr); ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"</Xdmf>\n");CHKERRQ(ierr); ierr = PetscObjectQuery((PetscObject)viewer,"XDMFViewerContext",(PetscObject*)&container);CHKERRQ(ierr); if (container) { ierr = PetscContainerGetPointer(container,(void**)&bytes);CHKERRQ(ierr); ierr = PetscFree(bytes);CHKERRQ(ierr); ierr = PetscContainerDestroy(&container);CHKERRQ(ierr); } ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); *v = NULL; PetscFunctionReturn(0); }
/*@C DMPlexTSGetGradientDM - Return gradient data layout Input Parameters: + dm - The DM - fv - The PetscFV Output Parameter: . dmGrad - The layout for gradient values Level: developer .seealso: DMPlexTSGetGeometryFVM(), DMPlexTSSetRHSFunctionLocal() @*/ PetscErrorCode DMPlexTSGetGradientDM(DM dm, PetscFV fv, DM *dmGrad) { DMTS dmts; PetscObject obj; PetscBool computeGradients; PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); PetscValidHeaderSpecific(fv,PETSCFV_CLASSID,2); PetscValidPointer(dmGrad,3); ierr = PetscFVGetComputeGradients(fv, &computeGradients);CHKERRQ(ierr); if (!computeGradients) {*dmGrad = NULL; PetscFunctionReturn(0);} ierr = DMGetDMTS(dm, &dmts);CHKERRQ(ierr); ierr = PetscObjectQuery((PetscObject) dmts, "DMPlexTS_dmgrad_fvm", &obj);CHKERRQ(ierr); if (!obj) { DM dmGrad; Vec faceGeometry, cellGeometry; ierr = DMPlexTSGetGeometryFVM(dm, &faceGeometry, &cellGeometry, NULL);CHKERRQ(ierr); ierr = DMPlexComputeGradientFVM(dm, fv, faceGeometry, cellGeometry, &dmGrad);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dmts, "DMPlexTS_dmgrad_fvm", (PetscObject) dmGrad);CHKERRQ(ierr); ierr = DMDestroy(&dmGrad);CHKERRQ(ierr); } ierr = PetscObjectQuery((PetscObject) dmts, "DMPlexTS_dmgrad_fvm", (PetscObject *) dmGrad);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode PCSetUp_LSC(PC pc) { PC_LSC *lsc = (PC_LSC*)pc->data; Mat L,Lp,B,C; PetscErrorCode ierr; PetscFunctionBegin; ierr = PCLSCAllocate_Private(pc);CHKERRQ(ierr); ierr = PetscObjectQuery((PetscObject)pc->mat,"LSC_L",(PetscObject*)&L);CHKERRQ(ierr); if (!L) {ierr = PetscObjectQuery((PetscObject)pc->pmat,"LSC_L",(PetscObject*)&L);CHKERRQ(ierr);} ierr = PetscObjectQuery((PetscObject)pc->pmat,"LSC_Lp",(PetscObject*)&Lp);CHKERRQ(ierr); if (!Lp) {ierr = PetscObjectQuery((PetscObject)pc->mat,"LSC_Lp",(PetscObject*)&Lp);CHKERRQ(ierr);} if (!L) { ierr = MatSchurComplementGetSubMatrices(pc->mat,NULL,NULL,&B,&C,NULL);CHKERRQ(ierr); if (!lsc->L) { ierr = MatMatMult(C,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&lsc->L);CHKERRQ(ierr); } else { ierr = MatMatMult(C,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&lsc->L);CHKERRQ(ierr); } Lp = L = lsc->L; } if (lsc->scale) { Mat Ap; ierr = MatSchurComplementGetSubMatrices(pc->mat,NULL,&Ap,NULL,NULL,NULL);CHKERRQ(ierr); ierr = MatGetDiagonal(Ap,lsc->scale);CHKERRQ(ierr); /* Should be the mass matrix, but we don't have plumbing for that yet */ ierr = VecReciprocal(lsc->scale);CHKERRQ(ierr); } ierr = KSPSetOperators(lsc->kspL,L,Lp);CHKERRQ(ierr); ierr = KSPSetFromOptions(lsc->kspL);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* DMSetVI - Marks a DM as associated with a VI problem. This causes the interpolation/restriction operators to be restricted to only those variables NOT associated with active constraints. */ PetscErrorCode DMSetVI(DM dm,IS inactive) { PetscErrorCode ierr; PetscContainer isnes; DM_SNESVI *dmsnesvi; PetscFunctionBegin; if (!dm) PetscFunctionReturn(0); ierr = PetscObjectReference((PetscObject)inactive);CHKERRQ(ierr); ierr = PetscObjectQuery((PetscObject)dm,"VI",(PetscObject *)&isnes);CHKERRQ(ierr); if (!isnes) { ierr = PetscContainerCreate(((PetscObject)dm)->comm,&isnes);CHKERRQ(ierr); ierr = PetscContainerSetUserDestroy(isnes,(PetscErrorCode (*)(void*))DMDestroy_SNESVI);CHKERRQ(ierr); ierr = PetscNew(DM_SNESVI,&dmsnesvi);CHKERRQ(ierr); ierr = PetscContainerSetPointer(isnes,(void*)dmsnesvi);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject)dm,"VI",(PetscObject)isnes);CHKERRQ(ierr); ierr = PetscContainerDestroy(&isnes);CHKERRQ(ierr); dmsnesvi->createinterpolation = dm->ops->createinterpolation; dm->ops->createinterpolation = DMCreateInterpolation_SNESVI; dmsnesvi->coarsen = dm->ops->coarsen; dm->ops->coarsen = DMCoarsen_SNESVI; dmsnesvi->createglobalvector = dm->ops->createglobalvector; dm->ops->createglobalvector = DMCreateGlobalVector_SNESVI; } else { ierr = PetscContainerGetPointer(isnes,(void**)&dmsnesvi);CHKERRQ(ierr); ierr = ISDestroy(&dmsnesvi->inactive);CHKERRQ(ierr); } ierr = DMClearGlobalVectors(dm);CHKERRQ(ierr); ierr = ISGetLocalSize(inactive,&dmsnesvi->n);CHKERRQ(ierr); dmsnesvi->inactive = inactive; dmsnesvi->dm = dm; PetscFunctionReturn(0); }
PetscErrorCode MatMatMultNumeric_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C) { PetscErrorCode ierr; Mat *seq; Mat_MatMatMultMPI *mult; PetscContainer container; PetscFunctionBegin; ierr = PetscObjectQuery((PetscObject)C,"Mat_MatMatMultMPI",(PetscObject *)&container);CHKERRQ(ierr); if (container) { ierr = PetscContainerGetPointer(container,(void **)&mult);CHKERRQ(ierr); } else { SETERRQ(PETSC_ERR_PLIB,"Container does not exit"); } seq = &mult->B_seq; ierr = MatGetSubMatrices(B,1,&mult->isrowb,&mult->iscolb,MAT_REUSE_MATRIX,&seq);CHKERRQ(ierr); mult->B_seq = *seq; seq = &mult->A_loc; ierr = MatGetSubMatrices(A,1,&mult->isrowa,&mult->isrowb,MAT_REUSE_MATRIX,&seq);CHKERRQ(ierr); mult->A_loc = *seq; ierr = MatMatMult_SeqAIJ_SeqAIJ(mult->A_loc,mult->B_seq,MAT_REUSE_MATRIX,0.0,&mult->C_seq);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject)mult->C_seq);CHKERRQ(ierr); ierr = MatMerge(((PetscObject)A)->comm,mult->C_seq,B->cmap->n,MAT_REUSE_MATRIX,&C);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode SNESComputeJacobian_DMLocal(SNES snes,Vec X,Mat A,Mat B,void *ctx) { PetscErrorCode ierr; DM dm; DMSNES_Local *dmlocalsnes = (DMSNES_Local*)ctx; Vec Xloc; PetscFunctionBegin; ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); if (dmlocalsnes->jacobianlocal) { ierr = DMGetLocalVector(dm,&Xloc);CHKERRQ(ierr); ierr = VecZeroEntries(Xloc);CHKERRQ(ierr); if (dmlocalsnes->boundarylocal) {ierr = (*dmlocalsnes->boundarylocal)(dm,Xloc,dmlocalsnes->boundarylocalctx);CHKERRQ(ierr);} ierr = DMGlobalToLocalBegin(dm,X,INSERT_VALUES,Xloc);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dm,X,INSERT_VALUES,Xloc);CHKERRQ(ierr); CHKMEMQ; ierr = (*dmlocalsnes->jacobianlocal)(dm,Xloc,A,B,dmlocalsnes->jacobianlocalctx);CHKERRQ(ierr); CHKMEMQ; ierr = DMRestoreLocalVector(dm,&Xloc);CHKERRQ(ierr); } else { MatFDColoring fdcoloring; ierr = PetscObjectQuery((PetscObject)dm,"DMDASNES_FDCOLORING",(PetscObject*)&fdcoloring);CHKERRQ(ierr); if (!fdcoloring) { ISColoring coloring; ierr = DMCreateColoring(dm,dm->coloringtype,&coloring);CHKERRQ(ierr); ierr = MatFDColoringCreate(B,coloring,&fdcoloring);CHKERRQ(ierr); ierr = ISColoringDestroy(&coloring);CHKERRQ(ierr); switch (dm->coloringtype) { case IS_COLORING_GLOBAL: ierr = MatFDColoringSetFunction(fdcoloring,(PetscErrorCode (*)(void))SNESComputeFunction_DMLocal,dmlocalsnes);CHKERRQ(ierr); break; default: SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"No support for coloring type '%s'",ISColoringTypes[dm->coloringtype]); } ierr = PetscObjectSetOptionsPrefix((PetscObject)fdcoloring,((PetscObject)dm)->prefix);CHKERRQ(ierr); ierr = MatFDColoringSetFromOptions(fdcoloring);CHKERRQ(ierr); ierr = MatFDColoringSetUp(B,coloring,fdcoloring);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject)dm,"DMDASNES_FDCOLORING",(PetscObject)fdcoloring);CHKERRQ(ierr); ierr = PetscObjectDereference((PetscObject)fdcoloring);CHKERRQ(ierr); /* The following breaks an ugly reference counting loop that deserves a paragraph. MatFDColoringApply() will call * VecDuplicate() with the state Vec and store inside the MatFDColoring. This Vec will duplicate the Vec, but the * MatFDColoring is composed with the DM. We dereference the DM here so that the reference count will eventually * drop to 0. Note the code in DMDestroy() that exits early for a negative reference count. That code path will be * taken when the PetscObjectList for the Vec inside MatFDColoring is destroyed. */ ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr); } ierr = MatFDColoringApply(B,fdcoloring,X,snes);CHKERRQ(ierr); } /* This will be redundant if the user called both, but it's too common to forget. */ if (A != B) { ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode SNESComputeJacobianDefaultColor(SNES snes,Vec x1,Mat J,Mat B,void *ctx) { MatFDColoring color = (MatFDColoring)ctx; PetscErrorCode ierr; DM dm; MatColoring mc; ISColoring iscoloring; PetscBool hascolor; PetscBool solvec,matcolor = PETSC_FALSE; PetscFunctionBegin; if (color) PetscValidHeaderSpecific(color,MAT_FDCOLORING_CLASSID,6); if (!color) {ierr = PetscObjectQuery((PetscObject)B,"SNESMatFDColoring",(PetscObject*)&color);CHKERRQ(ierr);} if (!color) { ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); ierr = DMHasColoring(dm,&hascolor);CHKERRQ(ierr); matcolor = PETSC_FALSE; ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_fd_color_use_mat",&matcolor,NULL);CHKERRQ(ierr); if (hascolor && !matcolor) { ierr = DMCreateColoring(dm,IS_COLORING_GLOBAL,&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringCreate(B,iscoloring,&color);CHKERRQ(ierr); ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))SNESComputeFunctionCtx,NULL);CHKERRQ(ierr); ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); ierr = MatFDColoringSetUp(B,iscoloring,color);CHKERRQ(ierr); ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); } else { ierr = MatColoringCreate(B,&mc);CHKERRQ(ierr); ierr = MatColoringSetDistance(mc,2);CHKERRQ(ierr); ierr = MatColoringSetType(mc,MATCOLORINGSL);CHKERRQ(ierr); ierr = MatColoringSetFromOptions(mc);CHKERRQ(ierr); ierr = MatColoringApply(mc,&iscoloring);CHKERRQ(ierr); ierr = MatColoringDestroy(&mc);CHKERRQ(ierr); ierr = MatFDColoringCreate(B,iscoloring,&color);CHKERRQ(ierr); ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))SNESComputeFunctionCtx,NULL);CHKERRQ(ierr); ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); ierr = MatFDColoringSetUp(B,iscoloring,color);CHKERRQ(ierr); ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); } ierr = PetscObjectCompose((PetscObject)B,"SNESMatFDColoring",(PetscObject)color);CHKERRQ(ierr); ierr = PetscObjectDereference((PetscObject)color);CHKERRQ(ierr); } /* F is only usable if there is no RHS on the SNES and the full solution corresponds to x1 */ ierr = VecEqual(x1,snes->vec_sol,&solvec);CHKERRQ(ierr); if (!snes->vec_rhs && solvec) { Vec F; ierr = SNESGetFunction(snes,&F,NULL,NULL);CHKERRQ(ierr); ierr = MatFDColoringSetF(color,F);CHKERRQ(ierr); } ierr = MatFDColoringApply(B,color,x1,snes);CHKERRQ(ierr); if (J != B) { ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static PetscErrorCode TSThetaGetX0AndXdot(TS ts,DM dm,Vec *X0,Vec *Xdot) { TS_Theta *th = (TS_Theta*)ts->data; PetscErrorCode ierr; PetscFunctionBegin; if (X0) { if (dm && dm != ts->dm) { ierr = PetscObjectQuery((PetscObject)dm,"TSTheta_X0",(PetscObject*)X0);CHKERRQ(ierr); if (!*X0) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_ARG_INCOMP,"TSTheta_X0 has not been composed with DM from SNES"); } else *X0 = ts->vec_sol; } if (Xdot) { if (dm && dm != ts->dm) { ierr = PetscObjectQuery((PetscObject)dm,"TSTheta_Xdot",(PetscObject*)Xdot);CHKERRQ(ierr); if (!*Xdot) SETERRQ(((PetscObject)ts)->comm,PETSC_ERR_ARG_INCOMP,"TSTheta_Xdot has not been composed with DM from SNES"); } else *Xdot = th->Xdot; } PetscFunctionReturn(0); }
/* DMCreateInterpolation_SNESVI - Modifieds the interpolation obtained from the DM by removing all rows and columns associated with active constraints. */ PetscErrorCode DMCreateInterpolation_SNESVI(DM dm1,DM dm2,Mat *mat,Vec *vec) { PetscErrorCode ierr; PetscContainer isnes; DM_SNESVI *dmsnesvi1,*dmsnesvi2; Mat interp; PetscFunctionBegin; ierr = PetscObjectQuery((PetscObject)dm1,"VI",(PetscObject *)&isnes);CHKERRQ(ierr); if (!isnes) SETERRQ(((PetscObject)dm1)->comm,PETSC_ERR_PLIB,"Composed VI data structure is missing"); ierr = PetscContainerGetPointer(isnes,(void**)&dmsnesvi1);CHKERRQ(ierr); ierr = PetscObjectQuery((PetscObject)dm2,"VI",(PetscObject *)&isnes);CHKERRQ(ierr); if (!isnes) SETERRQ(((PetscObject)dm2)->comm,PETSC_ERR_PLIB,"Composed VI data structure is missing"); ierr = PetscContainerGetPointer(isnes,(void**)&dmsnesvi2);CHKERRQ(ierr); ierr = (*dmsnesvi1->createinterpolation)(dm1,dm2,&interp,PETSC_NULL);CHKERRQ(ierr); ierr = MatGetSubMatrix(interp,dmsnesvi2->inactive,dmsnesvi1->inactive,MAT_INITIAL_MATRIX,mat);CHKERRQ(ierr); ierr = MatDestroy(&interp);CHKERRQ(ierr); *vec = 0; PetscFunctionReturn(0); }
/* DMCreateGlobalVector_SNESVI - Creates global vector of the size of the reduced space */ PetscErrorCode DMCreateGlobalVector_SNESVI(DM dm,Vec *vec) { PetscErrorCode ierr; PetscContainer isnes; DM_SNESVI *dmsnesvi; PetscFunctionBegin; ierr = PetscObjectQuery((PetscObject)dm,"VI",(PetscObject *)&isnes);CHKERRQ(ierr); if (!isnes) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_PLIB,"Composed SNES is missing"); ierr = PetscContainerGetPointer(isnes,(void**)&dmsnesvi);CHKERRQ(ierr); ierr = VecCreateMPI(((PetscObject)dm)->comm,dmsnesvi->n,PETSC_DETERMINE,vec);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode SNESComputeJacobianDefaultColor(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) { MatFDColoring color = (MatFDColoring)ctx; PetscErrorCode ierr; DM dm; PetscErrorCode (*func)(SNES,Vec,Vec,void*); Vec F; void *funcctx; ISColoring iscoloring; PetscBool hascolor; PetscBool solvec; PetscFunctionBegin; if (color) PetscValidHeaderSpecific(color,MAT_FDCOLORING_CLASSID,6); else {ierr = PetscObjectQuery((PetscObject)*B,"SNESMatFDColoring",(PetscObject*)&color);CHKERRQ(ierr);} *flag = SAME_NONZERO_PATTERN; ierr = SNESGetFunction(snes,&F,&func,&funcctx);CHKERRQ(ierr); if (!color) { ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); ierr = DMHasColoring(dm,&hascolor);CHKERRQ(ierr); if (hascolor) { ierr = DMCreateColoring(dm,IS_COLORING_GLOBAL,&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringCreate(*B,iscoloring,&color);CHKERRQ(ierr); ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr); ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); } else { ierr = MatGetColoring(*B,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringCreate(*B,iscoloring,&color);CHKERRQ(ierr); ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFunction(color,(PetscErrorCode (*)(void))func,(void*)funcctx);CHKERRQ(ierr); ierr = MatFDColoringSetFromOptions(color);CHKERRQ(ierr); } ierr = PetscObjectCompose((PetscObject)*B,"SNESMatFDColoring",(PetscObject)color);CHKERRQ(ierr); ierr = PetscObjectDereference((PetscObject)color);CHKERRQ(ierr); } /* F is only usable if there is no RHS on the SNES and the full solution corresponds to x1 */ ierr = VecEqual(x1,snes->vec_sol,&solvec);CHKERRQ(ierr); if (!snes->vec_rhs && solvec) { ierr = MatFDColoringSetF(color,F);CHKERRQ(ierr); } ierr = MatFDColoringApply(*B,color,x1,flag,snes);CHKERRQ(ierr); if (*J != *B) { ierr = MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); } PetscFunctionReturn(0); }
/*@ DMPlexTSGetGeometryFVM - Return precomputed geometric data Input Parameter: . dm - The DM Output Parameters: + facegeom - The values precomputed from face geometry . cellgeom - The values precomputed from cell geometry - minRadius - The minimum radius over the mesh of an inscribed sphere in a cell Level: developer .seealso: DMPlexTSSetRHSFunctionLocal() @*/ PetscErrorCode DMPlexTSGetGeometryFVM(DM dm, Vec *facegeom, Vec *cellgeom, PetscReal *minRadius) { DMTS dmts; PetscObject obj; PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); ierr = DMGetDMTS(dm, &dmts);CHKERRQ(ierr); ierr = PetscObjectQuery((PetscObject) dmts, "DMPlexTS_facegeom_fvm", &obj);CHKERRQ(ierr); if (!obj) { Vec cellgeom, facegeom; ierr = DMPlexComputeGeometryFVM(dm, &cellgeom, &facegeom);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dmts, "DMPlexTS_facegeom_fvm", (PetscObject) facegeom);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dmts, "DMPlexTS_cellgeom_fvm", (PetscObject) cellgeom);CHKERRQ(ierr); ierr = VecDestroy(&facegeom);CHKERRQ(ierr); ierr = VecDestroy(&cellgeom);CHKERRQ(ierr); } if (facegeom) {PetscValidPointer(facegeom, 2); ierr = PetscObjectQuery((PetscObject) dmts, "DMPlexTS_facegeom_fvm", (PetscObject *) facegeom);CHKERRQ(ierr);} if (cellgeom) {PetscValidPointer(cellgeom, 3); ierr = PetscObjectQuery((PetscObject) dmts, "DMPlexTS_cellgeom_fvm", (PetscObject *) cellgeom);CHKERRQ(ierr);} if (minRadius) {ierr = DMPlexGetMinRadius(dm, minRadius);CHKERRQ(ierr);} PetscFunctionReturn(0); }
PetscErrorCode MatDestroy_SeqAIJ_RARt(Mat A) { PetscErrorCode ierr; PetscContainer container; Mat_RARt *rart=PETSC_NULL; PetscFunctionBegin; ierr = PetscObjectQuery((PetscObject)A,"Mat_RARt",(PetscObject *)&container);CHKERRQ(ierr); if (!container) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Container does not exit"); ierr = PetscContainerGetPointer(container,(void **)&rart);CHKERRQ(ierr); A->ops->destroy = rart->destroy; if (A->ops->destroy) { ierr = (*A->ops->destroy)(A);CHKERRQ(ierr); } ierr = PetscObjectCompose((PetscObject)A,"Mat_RARt",0);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode MatDestroy_MPIAIJ_MatMatMult(Mat A) { PetscErrorCode ierr; PetscContainer container; Mat_MatMatMultMPI *mult=PETSC_NULL; PetscFunctionBegin; ierr = PetscObjectQuery((PetscObject)A,"Mat_MatMatMultMPI",(PetscObject *)&container);CHKERRQ(ierr); if (container) { ierr = PetscContainerGetPointer(container,(void **)&mult);CHKERRQ(ierr); } else { SETERRQ(PETSC_ERR_PLIB,"Container does not exit"); } A->ops->destroy = mult->MatDestroy; ierr = PetscObjectCompose((PetscObject)A,"Mat_MatMatMultMPI",0);CHKERRQ(ierr); ierr = (*A->ops->destroy)(A);CHKERRQ(ierr); ierr = PetscContainerDestroy(container);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode MatRARtNumeric_SeqAIJ_SeqAIJ(Mat A,Mat R,Mat C) { PetscErrorCode ierr; Mat_RARt *rart; PetscContainer container; MatTransposeColoring matcoloring; Mat Rt,RARt; PetscLogDouble Mult_sp_den=0.0,app1=0.0,app2=0.0,t0,tf; PetscFunctionBegin; ierr = PetscObjectQuery((PetscObject)C,"Mat_RARt",(PetscObject *)&container);CHKERRQ(ierr); if (!container) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Container does not exit"); ierr = PetscContainerGetPointer(container,(void **)&rart);CHKERRQ(ierr); /* Get dense Rt by Apply MatTransposeColoring to R */ matcoloring = rart->matcoloring; Rt = rart->Rt; ierr = PetscGetTime(&t0);CHKERRQ(ierr); ierr = MatTransColoringApplySpToDen(matcoloring,R,Rt);CHKERRQ(ierr); ierr = PetscGetTime(&tf);CHKERRQ(ierr); app1 += tf - t0; /* Get dense RARt = R*A*Rt */ ierr = PetscGetTime(&t0);CHKERRQ(ierr); RARt = rart->RARt; ierr = MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqDense(R,A,Rt,RARt,rart->work);CHKERRQ(ierr); ierr = PetscGetTime(&tf);CHKERRQ(ierr); Mult_sp_den += tf - t0; /* Recover C from C_dense */ ierr = PetscGetTime(&t0);CHKERRQ(ierr); ierr = MatTransColoringApplyDenToSp(matcoloring,RARt,C);CHKERRQ(ierr); ierr = PetscGetTime(&tf);CHKERRQ(ierr); app2 += tf - t0; #if defined(PETSC_USE_INFO) ierr = PetscInfo4(C,"Num = ColorApp %g + %g + Mult_sp_den %g = %g\n",app1,app2,Mult_sp_den,app1+app2+Mult_sp_den);CHKERRQ(ierr); #endif PetscFunctionReturn(0); }
PetscErrorCode MatDuplicate_MPIAIJ_MatMatMult(Mat A, MatDuplicateOption op, Mat *M) { PetscErrorCode ierr; Mat_MatMatMultMPI *mult; PetscContainer container; PetscFunctionBegin; ierr = PetscObjectQuery((PetscObject)A,"Mat_MatMatMultMPI",(PetscObject *)&container);CHKERRQ(ierr); if (container) { ierr = PetscContainerGetPointer(container,(void **)&mult);CHKERRQ(ierr); } else { SETERRQ(PETSC_ERR_PLIB,"Container does not exit"); } /* Note: the container is not duplicated, because it requires deep copying of several large data sets (see PetscContainerDestroy_Mat_MatMatMultMPI()). These data sets are only used for repeated calling of MatMatMultNumeric(). *M is unlikely being used in this way. Thus we create *M with pure mpiaij format */ ierr = (*mult->MatDuplicate)(A,op,M);CHKERRQ(ierr); (*M)->ops->destroy = mult->MatDestroy; /* = MatDestroy_MPIAIJ, *M doesn't duplicate A's container! */ (*M)->ops->duplicate = mult->MatDuplicate; /* = MatDuplicate_MPIAIJ */ PetscFunctionReturn(0); }
/* obj - the PETSc object where the scalar pointer came from base - the Fortran array address addr - the Fortran offset from base N - the amount of data lx - the array space that is to be passed to XXXXRestoreArray() */ PetscErrorCode PetscScalarAddressFromFortran(PetscObject obj,PetscScalar *base,size_t addr,PetscInt N,PetscScalar **lx) { PetscErrorCode ierr; PetscInt shift; PetscContainer container; PetscScalar *tlx; ierr = PetscObjectQuery(obj,"GetArrayPtr",(PetscObject *)&container);CHKERRQ(ierr); if (container) { ierr = PetscContainerGetPointer(container,(void**)lx);CHKERRQ(ierr); tlx = base + addr; shift = *(PetscInt*)*lx; ierr = PetscMemcpy(*lx,tlx,N*sizeof(PetscScalar));CHKERRQ(ierr); tlx = (PetscScalar*)(((char *)tlx) - shift); ierr = PetscFree(tlx);CHKERRQ(ierr); ierr = PetscContainerDestroy(&container);CHKERRQ(ierr); ierr = PetscObjectCompose(obj,"GetArrayPtr",0);CHKERRQ(ierr); } else { *lx = base + addr; } return 0; }
static PetscErrorCode DMPlexVTKWriteAll_ASCII(DM dm, PetscViewer viewer) { MPI_Comm comm; PetscViewer_VTK *vtk = (PetscViewer_VTK*) viewer->data; FILE *fp; PetscViewerVTKObjectLink link; PetscSection coordSection, globalCoordSection; PetscLayout vLayout; Vec coordinates; PetscReal lengthScale; PetscInt vMax, totVertices, totCells; PetscBool hasPoint = PETSC_FALSE, hasCell = PETSC_FALSE, writePartition = PETSC_FALSE; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscObjectGetComm((PetscObject)dm,&comm);CHKERRQ(ierr); ierr = PetscFOpen(comm, vtk->filename, "wb", &fp);CHKERRQ(ierr); ierr = PetscFPrintf(comm, fp, "# vtk DataFile Version 2.0\n");CHKERRQ(ierr); ierr = PetscFPrintf(comm, fp, "Simplicial Mesh Example\n");CHKERRQ(ierr); ierr = PetscFPrintf(comm, fp, "ASCII\n");CHKERRQ(ierr); ierr = PetscFPrintf(comm, fp, "DATASET UNSTRUCTURED_GRID\n");CHKERRQ(ierr); /* Vertices */ ierr = DMPlexGetScale(dm, PETSC_UNIT_LENGTH, &lengthScale);CHKERRQ(ierr); ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); ierr = PetscSectionCreateGlobalSection(coordSection, dm->sf, PETSC_FALSE, PETSC_FALSE, &globalCoordSection);CHKERRQ(ierr); ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); ierr = DMPlexGetHybridBounds(dm, NULL, NULL, NULL, &vMax);CHKERRQ(ierr); if (vMax >= 0) { PetscInt pStart, pEnd, p, localSize = 0; ierr = PetscSectionGetChart(globalCoordSection, &pStart, &pEnd);CHKERRQ(ierr); pEnd = PetscMin(pEnd, vMax); for (p = pStart; p < pEnd; ++p) { PetscInt dof; ierr = PetscSectionGetDof(globalCoordSection, p, &dof);CHKERRQ(ierr); if (dof > 0) ++localSize; } ierr = PetscLayoutCreate(PetscObjectComm((PetscObject)dm), &vLayout);CHKERRQ(ierr); ierr = PetscLayoutSetLocalSize(vLayout, localSize);CHKERRQ(ierr); ierr = PetscLayoutSetBlockSize(vLayout, 1);CHKERRQ(ierr); ierr = PetscLayoutSetUp(vLayout);CHKERRQ(ierr); } else { ierr = PetscSectionGetPointLayout(PetscObjectComm((PetscObject)dm), globalCoordSection, &vLayout);CHKERRQ(ierr); } ierr = PetscLayoutGetSize(vLayout, &totVertices);CHKERRQ(ierr); ierr = PetscFPrintf(comm, fp, "POINTS %d double\n", totVertices);CHKERRQ(ierr); ierr = DMPlexVTKWriteSection_ASCII(dm, coordSection, globalCoordSection, coordinates, fp, 3, PETSC_DETERMINE, lengthScale);CHKERRQ(ierr); /* Cells */ ierr = DMPlexVTKWriteCells_ASCII(dm, fp, &totCells);CHKERRQ(ierr); /* Vertex fields */ for (link = vtk->link; link; link = link->next) { if ((link->ft == PETSC_VTK_POINT_FIELD) || (link->ft == PETSC_VTK_POINT_VECTOR_FIELD)) hasPoint = PETSC_TRUE; if ((link->ft == PETSC_VTK_CELL_FIELD) || (link->ft == PETSC_VTK_CELL_VECTOR_FIELD)) hasCell = PETSC_TRUE; } if (hasPoint) { ierr = PetscFPrintf(comm, fp, "POINT_DATA %d\n", totVertices);CHKERRQ(ierr); for (link = vtk->link; link; link = link->next) { Vec X = (Vec) link->vec; DM dmX; PetscSection section, globalSection, newSection = NULL; const char *name; PetscInt enforceDof = PETSC_DETERMINE; if ((link->ft != PETSC_VTK_POINT_FIELD) && (link->ft != PETSC_VTK_POINT_VECTOR_FIELD)) continue; if (link->ft == PETSC_VTK_POINT_VECTOR_FIELD) enforceDof = 3; ierr = PetscObjectGetName(link->vec, &name);CHKERRQ(ierr); ierr = VecGetDM(X, &dmX);CHKERRQ(ierr); if (dmX) { DMLabel subpointMap, subpointMapX; PetscInt dim, dimX, pStart, pEnd, qStart, qEnd; ierr = DMGetDefaultSection(dmX, §ion);CHKERRQ(ierr); /* Here is where we check whether dmX is a submesh of dm */ ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); ierr = DMGetDimension(dmX, &dimX);CHKERRQ(ierr); ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); ierr = DMPlexGetChart(dmX, &qStart, &qEnd);CHKERRQ(ierr); ierr = DMPlexGetSubpointMap(dm, &subpointMap);CHKERRQ(ierr); ierr = DMPlexGetSubpointMap(dmX, &subpointMapX);CHKERRQ(ierr); if (((dim != dimX) || ((pEnd-pStart) < (qEnd-qStart))) && subpointMap && !subpointMapX) { const PetscInt *ind = NULL; IS subpointIS; PetscInt n = 0, q; ierr = PetscSectionGetChart(section, &qStart, &qEnd);CHKERRQ(ierr); ierr = DMPlexCreateSubpointIS(dm, &subpointIS);CHKERRQ(ierr); if (subpointIS) { ierr = ISGetLocalSize(subpointIS, &n);CHKERRQ(ierr); ierr = ISGetIndices(subpointIS, &ind);CHKERRQ(ierr); } ierr = PetscSectionCreate(comm, &newSection);CHKERRQ(ierr); ierr = PetscSectionSetChart(newSection, pStart, pEnd);CHKERRQ(ierr); for (q = qStart; q < qEnd; ++q) { PetscInt dof, off, p; ierr = PetscSectionGetDof(section, q, &dof);CHKERRQ(ierr); if (dof) { ierr = PetscFindInt(q, n, ind, &p);CHKERRQ(ierr); if (p >= pStart) { ierr = PetscSectionSetDof(newSection, p, dof);CHKERRQ(ierr); ierr = PetscSectionGetOffset(section, q, &off);CHKERRQ(ierr); ierr = PetscSectionSetOffset(newSection, p, off);CHKERRQ(ierr); } } } if (subpointIS) { ierr = ISRestoreIndices(subpointIS, &ind);CHKERRQ(ierr); ierr = ISDestroy(&subpointIS);CHKERRQ(ierr); } /* No need to setup section */ section = newSection; } } else { ierr = PetscObjectQuery(link->vec, "section", (PetscObject*) §ion);CHKERRQ(ierr); if (!section) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Vector %s had no PetscSection composed with it", name); } if (!section) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Vector %s had no PetscSection composed with it", name); ierr = PetscSectionCreateGlobalSection(section, dm->sf, PETSC_FALSE, PETSC_FALSE, &globalSection);CHKERRQ(ierr); ierr = DMPlexVTKWriteField_ASCII(dm, section, globalSection, X, name, fp, enforceDof, PETSC_DETERMINE, 1.0);CHKERRQ(ierr); ierr = PetscSectionDestroy(&globalSection);CHKERRQ(ierr); if (newSection) {ierr = PetscSectionDestroy(&newSection);CHKERRQ(ierr);} } } /* Cell Fields */ ierr = PetscOptionsGetBool(((PetscObject) dm)->prefix, "-dm_view_partition", &writePartition, NULL);CHKERRQ(ierr); if (hasCell || writePartition) { ierr = PetscFPrintf(comm, fp, "CELL_DATA %d\n", totCells);CHKERRQ(ierr); for (link = vtk->link; link; link = link->next) { Vec X = (Vec) link->vec; DM dmX; PetscSection section, globalSection; const char *name; PetscInt enforceDof = PETSC_DETERMINE; if ((link->ft != PETSC_VTK_CELL_FIELD) && (link->ft != PETSC_VTK_CELL_VECTOR_FIELD)) continue; if (link->ft == PETSC_VTK_CELL_VECTOR_FIELD) enforceDof = 3; ierr = PetscObjectGetName(link->vec, &name);CHKERRQ(ierr); ierr = VecGetDM(X, &dmX);CHKERRQ(ierr); if (dmX) { ierr = DMGetDefaultSection(dmX, §ion);CHKERRQ(ierr); } else { PetscContainer c; ierr = PetscObjectQuery(link->vec, "section", (PetscObject*) &c);CHKERRQ(ierr); if (!c) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Vector %s had no PetscSection composed with it", name); ierr = PetscContainerGetPointer(c, (void**) §ion);CHKERRQ(ierr); } if (!section) SETERRQ1(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Vector %s had no PetscSection composed with it", name); ierr = PetscSectionCreateGlobalSection(section, dm->sf, PETSC_FALSE, PETSC_FALSE, &globalSection);CHKERRQ(ierr); ierr = DMPlexVTKWriteField_ASCII(dm, section, globalSection, X, name, fp, enforceDof, PETSC_DETERMINE, 1.0);CHKERRQ(ierr); ierr = PetscSectionDestroy(&globalSection);CHKERRQ(ierr); } if (writePartition) { ierr = PetscFPrintf(comm, fp, "SCALARS partition int 1\n");CHKERRQ(ierr); ierr = PetscFPrintf(comm, fp, "LOOKUP_TABLE default\n");CHKERRQ(ierr); ierr = DMPlexVTKWritePartition_ASCII(dm, fp);CHKERRQ(ierr); } } /* Cleanup */ ierr = PetscSectionDestroy(&globalCoordSection);CHKERRQ(ierr); ierr = PetscLayoutDestroy(&vLayout);CHKERRQ(ierr); ierr = PetscFClose(comm, fp);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode private_DMSwarmView_XDMF(DM dm,PetscViewer viewer) { PetscBool isswarm = PETSC_FALSE; const char *viewername; char datafile[PETSC_MAX_PATH_LEN]; PetscViewer fviewer; PetscInt k,ng,dim; Vec dvec; long int *bytes = NULL; PetscContainer container = NULL; const char *dmname; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscObjectQuery((PetscObject)viewer,"XDMFViewerContext",(PetscObject*)&container);CHKERRQ(ierr); if (container) { ierr = PetscContainerGetPointer(container,(void**)&bytes);CHKERRQ(ierr); } else SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Valid to find attached data XDMFViewerContext"); ierr = PetscObjectTypeCompare((PetscObject)dm,DMSWARM,&isswarm);CHKERRQ(ierr); if (!isswarm) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only valid for DMSwarm"); ierr = PetscObjectCompose((PetscObject)viewer,"DMSwarm",(PetscObject)dm);CHKERRQ(ierr); ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); ierr = PetscObjectGetName((PetscObject)dm,&dmname);CHKERRQ(ierr); if (!dmname) { ierr = DMGetOptionsPrefix(dm,&dmname);CHKERRQ(ierr); } if (!dmname) { ierr = PetscViewerASCIIPrintf(viewer,"<Grid Name=\"DMSwarm\" GridType=\"Uniform\">\n");CHKERRQ(ierr); } else { ierr = PetscViewerASCIIPrintf(viewer,"<Grid Name=\"DMSwarm[%s]\" GridType=\"Uniform\">\n",dmname);CHKERRQ(ierr); } /* create a sub-viewer for topology, geometry and all data fields */ /* name is viewer.name + "_swarm_fields.pbin" */ ierr = PetscViewerCreate(PetscObjectComm((PetscObject)viewer),&fviewer);CHKERRQ(ierr); ierr = PetscViewerSetType(fviewer,PETSCVIEWERBINARY);CHKERRQ(ierr); ierr = PetscViewerBinarySetSkipHeader(fviewer,PETSC_TRUE);CHKERRQ(ierr); ierr = PetscViewerBinarySetSkipInfo(fviewer,PETSC_TRUE);CHKERRQ(ierr); ierr = PetscViewerFileSetMode(fviewer,FILE_MODE_WRITE);CHKERRQ(ierr); ierr = PetscViewerFileGetName(viewer,&viewername);CHKERRQ(ierr); ierr = private_CreateDataFileNameXDMF(viewername,datafile);CHKERRQ(ierr); ierr = PetscViewerFileSetName(fviewer,datafile);CHKERRQ(ierr); ierr = DMSwarmGetSize(dm,&ng);CHKERRQ(ierr); /* write topology header */ ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"<Topology Dimensions=\"%D\" TopologyType=\"Mixed\">\n",ng);CHKERRQ(ierr); ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Int\" Dimensions=\"%D\" Seek=\"%D\">\n",ng*3,bytes[0]);CHKERRQ(ierr); ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"%s\n",datafile);CHKERRQ(ierr); ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"</DataItem>\n");CHKERRQ(ierr); ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"</Topology>\n");CHKERRQ(ierr); ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); /* write topology data */ for (k=0; k<ng; k++) { PetscInt pvertex[3]; pvertex[0] = 1; pvertex[1] = 1; pvertex[2] = k; ierr = PetscViewerBinaryWrite(fviewer,pvertex,3,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); } bytes[0] += sizeof(PetscInt) * ng * 3; /* write geometry header */ ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); switch (dim) { case 1: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for 1D"); break; case 2: ierr = PetscViewerASCIIPrintf(viewer,"<Geometry Type=\"XY\">\n");CHKERRQ(ierr); break; case 3: ierr = PetscViewerASCIIPrintf(viewer,"<Geometry Type=\"XYZ\">\n");CHKERRQ(ierr); break; } ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Float\" Precision=\"8\" Dimensions=\"%D %D\" Seek=\"%D\">\n",ng,dim,bytes[0]);CHKERRQ(ierr); ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"%s\n",datafile);CHKERRQ(ierr); ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"</DataItem>\n");CHKERRQ(ierr); ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"</Geometry>\n");CHKERRQ(ierr); ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); /* write geometry data */ ierr = DMSwarmCreateGlobalVectorFromField(dm,DMSwarmPICField_coor,&dvec);CHKERRQ(ierr); ierr = VecView(dvec,fviewer);CHKERRQ(ierr); ierr = DMSwarmDestroyGlobalVectorFromField(dm,DMSwarmPICField_coor,&dvec);CHKERRQ(ierr); bytes[0] += sizeof(PetscReal) * ng * dim; ierr = PetscViewerDestroy(&fviewer);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode private_ISView_Swarm_XDMF(IS is,PetscViewer viewer) { long int *bytes = NULL; PetscContainer container = NULL; const char *viewername; char datafile[PETSC_MAX_PATH_LEN]; PetscViewer fviewer; PetscInt N,bs; const char *vecname; char fieldname[PETSC_MAX_PATH_LEN]; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscObjectQuery((PetscObject)viewer,"XDMFViewerContext",(PetscObject*)&container);CHKERRQ(ierr); if (container) { ierr = PetscContainerGetPointer(container,(void**)&bytes);CHKERRQ(ierr); } else SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Valid to find attached data XDMFViewerContext"); ierr = PetscViewerFileGetName(viewer,&viewername);CHKERRQ(ierr); ierr = private_CreateDataFileNameXDMF(viewername,datafile);CHKERRQ(ierr); /* re-open a sub-viewer for all data fields */ /* name is viewer.name + "_swarm_fields.pbin" */ ierr = PetscViewerCreate(PetscObjectComm((PetscObject)viewer),&fviewer);CHKERRQ(ierr); ierr = PetscViewerSetType(fviewer,PETSCVIEWERBINARY);CHKERRQ(ierr); ierr = PetscViewerBinarySetSkipHeader(fviewer,PETSC_TRUE);CHKERRQ(ierr); ierr = PetscViewerBinarySetSkipInfo(fviewer,PETSC_TRUE);CHKERRQ(ierr); ierr = PetscViewerFileSetMode(fviewer,FILE_MODE_APPEND);CHKERRQ(ierr); ierr = PetscViewerFileSetName(fviewer,datafile);CHKERRQ(ierr); ierr = ISGetSize(is,&N);CHKERRQ(ierr); ierr = ISGetBlockSize(is,&bs);CHKERRQ(ierr); N = N/bs; ierr = PetscObjectGetName((PetscObject)is,&vecname);CHKERRQ(ierr); if (!vecname) { ierr = PetscSNPrintf(fieldname,PETSC_MAX_PATH_LEN-1,"swarmfield_%D",((PetscObject)is)->tag);CHKERRQ(ierr); } else { ierr = PetscSNPrintf(fieldname,PETSC_MAX_PATH_LEN-1,"%s",vecname);CHKERRQ(ierr); } /* write data header */ ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"<Attribute Center=\"Node\" Name=\"%s\" Type=\"None\">\n",fieldname);CHKERRQ(ierr); ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); if (bs == 1) { ierr = PetscViewerASCIIPrintf(viewer,"<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Int\" Precision=\"4\" Dimensions=\"%D\" Seek=\"%D\">\n",N,bytes[0]);CHKERRQ(ierr); } else { ierr = PetscViewerASCIIPrintf(viewer,"<DataItem Format=\"Binary\" Endian=\"Big\" DataType=\"Int\" Precision=\"4\" Dimensions=\"%D %D\" Seek=\"%D\">\n",N,bs,bytes[0]);CHKERRQ(ierr); } ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"%s\n",datafile);CHKERRQ(ierr); ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"</DataItem>\n");CHKERRQ(ierr); ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(viewer,"</Attribute>\n");CHKERRQ(ierr); ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); /* write data */ ierr = ISView(is,fviewer);CHKERRQ(ierr); bytes[0] += sizeof(PetscInt) * N * bs; ierr = PetscViewerDestroy(&fviewer);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* Performs an efficient scatter on the rows of B needed by this process; this is a modification of the VecScatterBegin_() routines. */ PetscErrorCode MatMPIDenseScatter(Mat A,Mat B,Mat C,Mat *outworkB) { Mat_MPIAIJ *aij = (Mat_MPIAIJ*)A->data; PetscErrorCode ierr; PetscScalar *b,*w,*svalues,*rvalues; VecScatter ctx = aij->Mvctx; VecScatter_MPI_General *from = (VecScatter_MPI_General*) ctx->fromdata; VecScatter_MPI_General *to = ( VecScatter_MPI_General*) ctx->todata; PetscInt i,j,k; PetscInt *sindices,*sstarts,*rindices,*rstarts; PetscMPIInt *sprocs,*rprocs,nrecvs; MPI_Request *swaits,*rwaits; MPI_Comm comm = ((PetscObject)A)->comm; PetscMPIInt tag = ((PetscObject)ctx)->tag,ncols = B->cmap->N, nrows = aij->B->cmap->n,imdex,nrowsB = B->rmap->n; MPI_Status status; MPIAIJ_MPIDense *contents; PetscContainer cont; Mat workB; PetscFunctionBegin; ierr = PetscObjectQuery((PetscObject)C,"workB",(PetscObject*)&cont);CHKERRQ(ierr); ierr = PetscContainerGetPointer(cont,(void**)&contents);CHKERRQ(ierr); workB = *outworkB = contents->workB; if (nrows != workB->rmap->n) SETERRQ2(PETSC_ERR_PLIB,"Number of rows of workB %D not equal to columns of aij->B %D",nrows,workB->cmap->n); sindices = to->indices; sstarts = to->starts; sprocs = to->procs; swaits = contents->swaits; svalues = contents->svalues; rindices = from->indices; rstarts = from->starts; rprocs = from->procs; rwaits = contents->rwaits; rvalues = contents->rvalues; ierr = MatGetArray(B,&b);CHKERRQ(ierr); ierr = MatGetArray(workB,&w);CHKERRQ(ierr); for (i=0; i<from->n; i++) { ierr = MPI_Irecv(rvalues+ncols*rstarts[i],ncols*(rstarts[i+1]-rstarts[i]),MPIU_SCALAR,rprocs[i],tag,comm,rwaits+i);CHKERRQ(ierr); } for (i=0; i<to->n; i++) { /* pack a message at a time */ CHKMEMQ; for (j=0; j<sstarts[i+1]-sstarts[i]; j++){ for (k=0; k<ncols; k++) { svalues[ncols*(sstarts[i] + j) + k] = b[sindices[sstarts[i]+j] + nrowsB*k]; } } CHKMEMQ; ierr = MPI_Isend(svalues+ncols*sstarts[i],ncols*(sstarts[i+1]-sstarts[i]),MPIU_SCALAR,sprocs[i],tag,comm,swaits+i);CHKERRQ(ierr); } nrecvs = from->n; while (nrecvs) { ierr = MPI_Waitany(from->n,rwaits,&imdex,&status);CHKERRQ(ierr); nrecvs--; /* unpack a message at a time */ CHKMEMQ; for (j=0; j<rstarts[imdex+1]-rstarts[imdex]; j++){ for (k=0; k<ncols; k++) { w[rindices[rstarts[imdex]+j] + nrows*k] = rvalues[ncols*(rstarts[imdex] + j) + k]; } } CHKMEMQ; } if (to->n) {ierr = MPI_Waitall(to->n,swaits,to->sstatus);CHKERRQ(ierr)}
/* DMCoarsen_SNESVI - Computes the regular coarsened DM then computes additional information about its inactive set */ PetscErrorCode DMCoarsen_SNESVI(DM dm1,MPI_Comm comm,DM *dm2) { PetscErrorCode ierr; PetscContainer isnes; DM_SNESVI *dmsnesvi1; Vec finemarked,coarsemarked; IS inactive; VecScatter inject; const PetscInt *index; PetscInt n,k,cnt = 0,rstart,*coarseindex; PetscScalar *marked; PetscFunctionBegin; ierr = PetscObjectQuery((PetscObject)dm1,"VI",(PetscObject *)&isnes);CHKERRQ(ierr); if (!isnes) SETERRQ(((PetscObject)dm1)->comm,PETSC_ERR_PLIB,"Composed VI data structure is missing"); ierr = PetscContainerGetPointer(isnes,(void**)&dmsnesvi1);CHKERRQ(ierr); /* get the original coarsen */ ierr = (*dmsnesvi1->coarsen)(dm1,comm,dm2);CHKERRQ(ierr); /* not sure why this extra reference is needed, but without the dm2 disappears too early */ ierr = PetscObjectReference((PetscObject)*dm2);CHKERRQ(ierr); /* need to set back global vectors in order to use the original injection */ ierr = DMClearGlobalVectors(dm1);CHKERRQ(ierr); dm1->ops->createglobalvector = dmsnesvi1->createglobalvector; ierr = DMCreateGlobalVector(dm1,&finemarked);CHKERRQ(ierr); ierr = DMCreateGlobalVector(*dm2,&coarsemarked);CHKERRQ(ierr); /* fill finemarked with locations of inactive points */ ierr = ISGetIndices(dmsnesvi1->inactive,&index);CHKERRQ(ierr); ierr = ISGetLocalSize(dmsnesvi1->inactive,&n);CHKERRQ(ierr); ierr = VecSet(finemarked,0.0);CHKERRQ(ierr); for (k=0;k<n;k++){ ierr = VecSetValue(finemarked,index[k],1.0,INSERT_VALUES);CHKERRQ(ierr); } ierr = VecAssemblyBegin(finemarked);CHKERRQ(ierr); ierr = VecAssemblyEnd(finemarked);CHKERRQ(ierr); ierr = DMCreateInjection(*dm2,dm1,&inject);CHKERRQ(ierr); ierr = VecScatterBegin(inject,finemarked,coarsemarked,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(inject,finemarked,coarsemarked,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterDestroy(&inject);CHKERRQ(ierr); /* create index set list of coarse inactive points from coarsemarked */ ierr = VecGetLocalSize(coarsemarked,&n);CHKERRQ(ierr); ierr = VecGetOwnershipRange(coarsemarked,&rstart,PETSC_NULL);CHKERRQ(ierr); ierr = VecGetArray(coarsemarked,&marked);CHKERRQ(ierr); for (k=0; k<n; k++) { if (marked[k] != 0.0) cnt++; } ierr = PetscMalloc(cnt*sizeof(PetscInt),&coarseindex);CHKERRQ(ierr); cnt = 0; for (k=0; k<n; k++) { if (marked[k] != 0.0) coarseindex[cnt++] = k + rstart; } ierr = VecRestoreArray(coarsemarked,&marked);CHKERRQ(ierr); ierr = ISCreateGeneral(((PetscObject)coarsemarked)->comm,cnt,coarseindex,PETSC_OWN_POINTER,&inactive);CHKERRQ(ierr); ierr = DMClearGlobalVectors(dm1);CHKERRQ(ierr); dm1->ops->createglobalvector = DMCreateGlobalVector_SNESVI; ierr = DMSetVI(*dm2,inactive);CHKERRQ(ierr); ierr = VecDestroy(&finemarked);CHKERRQ(ierr); ierr = VecDestroy(&coarsemarked);CHKERRQ(ierr); ierr = ISDestroy(&inactive);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode SNESComputeJacobian_DMDA(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *mstr,void *ctx) { PetscErrorCode ierr; DM dm; DMSNES_DA *dmdasnes = (DMSNES_DA*)ctx; DMDALocalInfo info; Vec Xloc; void *x; PetscFunctionBegin; if (!dmdasnes->residuallocal) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_PLIB,"Corrupt context"); ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); if (dmdasnes->jacobianlocal) { ierr = DMGetLocalVector(dm,&Xloc);CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(dm,X,INSERT_VALUES,Xloc);CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(dm,X,INSERT_VALUES,Xloc);CHKERRQ(ierr); ierr = DMDAGetLocalInfo(dm,&info);CHKERRQ(ierr); ierr = DMDAVecGetArray(dm,Xloc,&x);CHKERRQ(ierr); CHKMEMQ; ierr = (*dmdasnes->jacobianlocal)(&info,x,*A,*B,mstr,dmdasnes->jacobianlocalctx);CHKERRQ(ierr); CHKMEMQ; ierr = DMDAVecRestoreArray(dm,Xloc,&x);CHKERRQ(ierr); ierr = DMRestoreLocalVector(dm,&Xloc);CHKERRQ(ierr); } else { MatFDColoring fdcoloring; ierr = PetscObjectQuery((PetscObject)dm,"DMDASNES_FDCOLORING",(PetscObject*)&fdcoloring);CHKERRQ(ierr); if (!fdcoloring) { ISColoring coloring; ierr = DMCreateColoring(dm,dm->coloringtype,&coloring);CHKERRQ(ierr); ierr = MatFDColoringCreate(*B,coloring,&fdcoloring);CHKERRQ(ierr); ierr = ISColoringDestroy(&coloring);CHKERRQ(ierr); switch (dm->coloringtype) { case IS_COLORING_GLOBAL: ierr = MatFDColoringSetFunction(fdcoloring,(PetscErrorCode (*)(void))SNESComputeFunction_DMDA,dmdasnes);CHKERRQ(ierr); break; default: SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"No support for coloring type '%s'",ISColoringTypes[dm->coloringtype]); } ierr = PetscObjectSetOptionsPrefix((PetscObject)fdcoloring,((PetscObject)dm)->prefix);CHKERRQ(ierr); ierr = MatFDColoringSetFromOptions(fdcoloring);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject)dm,"DMDASNES_FDCOLORING",(PetscObject)fdcoloring);CHKERRQ(ierr); ierr = PetscObjectDereference((PetscObject)fdcoloring);CHKERRQ(ierr); /* The following breaks an ugly reference counting loop that deserves a paragraph. MatFDColoringApply() will call * VecDuplicate() with the state Vec and store inside the MatFDColoring. This Vec will duplicate the Vec, but the * MatFDColoring is composed with the DM. We dereference the DM here so that the reference count will eventually * drop to 0. Note the code in DMDestroy() that exits early for a negative reference count. That code path will be * taken when the PetscObjectList for the Vec inside MatFDColoring is destroyed. */ ierr = PetscObjectDereference((PetscObject)dm);CHKERRQ(ierr); } *mstr = SAME_NONZERO_PATTERN; ierr = MatFDColoringApply(*B,fdcoloring,X,mstr,snes);CHKERRQ(ierr); } /* This will be redundant if the user called both, but it's too common to forget. */ if (*A != *B) { ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode VecView_MPI_Draw_DA1d(Vec xin,PetscViewer v) { DM da; PetscErrorCode ierr; PetscMPIInt rank,size,tag1,tag2; PetscInt i,n,N,step,istart,isize,j,nbounds; MPI_Status status; PetscReal coors[4],ymin,ymax,min,max,xmin,xmax,tmp,xgtmp; const PetscScalar *array,*xg; PetscDraw draw; PetscBool isnull,showpoints = PETSC_FALSE; MPI_Comm comm; PetscDrawAxis axis; Vec xcoor; DMDABoundaryType bx; const PetscReal *bounds; PetscInt *displayfields; PetscInt k,ndisplayfields; PetscBool flg,hold; PetscFunctionBegin; ierr = PetscViewerDrawGetDraw(v,0,&draw);CHKERRQ(ierr); ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); if (isnull) PetscFunctionReturn(0); ierr = PetscViewerDrawGetBounds(v,&nbounds,&bounds);CHKERRQ(ierr); ierr = PetscObjectQuery((PetscObject)xin,"DM",(PetscObject*)&da);CHKERRQ(ierr); if (!da) SETERRQ(((PetscObject)xin)->comm,PETSC_ERR_ARG_WRONG,"Vector not generated from a DMDA"); ierr = PetscOptionsGetBool(PETSC_NULL,"-draw_vec_mark_points",&showpoints,PETSC_NULL);CHKERRQ(ierr); ierr = DMDAGetInfo(da,0,&N,0,0,0,0,0,&step,0,&bx,0,0,0);CHKERRQ(ierr); ierr = DMDAGetCorners(da,&istart,0,0,&isize,0,0);CHKERRQ(ierr); ierr = VecGetArrayRead(xin,&array);CHKERRQ(ierr); ierr = VecGetLocalSize(xin,&n);CHKERRQ(ierr); n = n/step; /* get coordinates of nodes */ ierr = DMDAGetCoordinates(da,&xcoor);CHKERRQ(ierr); if (!xcoor) { ierr = DMDASetUniformCoordinates(da,0.0,1.0,0.0,0.0,0.0,0.0);CHKERRQ(ierr); ierr = DMDAGetCoordinates(da,&xcoor);CHKERRQ(ierr); } ierr = VecGetArrayRead(xcoor,&xg);CHKERRQ(ierr); ierr = PetscObjectGetComm((PetscObject)xin,&comm);CHKERRQ(ierr); ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); /* Determine the min and max x coordinate in plot */ if (!rank) { xmin = PetscRealPart(xg[0]); } if (rank == size-1) { xmax = PetscRealPart(xg[n-1]); } ierr = MPI_Bcast(&xmin,1,MPIU_REAL,0,comm);CHKERRQ(ierr); ierr = MPI_Bcast(&xmax,1,MPIU_REAL,size-1,comm);CHKERRQ(ierr); ierr = PetscMalloc(step*sizeof(PetscInt),&displayfields);CHKERRQ(ierr); for (i=0; i<step; i++) displayfields[i] = i; ndisplayfields = step; ierr = PetscOptionsGetIntArray(PETSC_NULL,"-draw_fields",displayfields,&ndisplayfields,&flg);CHKERRQ(ierr); if (!flg) ndisplayfields = step; for (k=0; k<ndisplayfields; k++) { j = displayfields[k]; ierr = PetscViewerDrawGetDraw(v,k,&draw);CHKERRQ(ierr); ierr = PetscDrawCheckResizedWindow(draw);CHKERRQ(ierr); /* Determine the min and max y coordinate in plot */ min = 1.e20; max = -1.e20; for (i=0; i<n; i++) { if (PetscRealPart(array[j+i*step]) < min) min = PetscRealPart(array[j+i*step]); if (PetscRealPart(array[j+i*step]) > max) max = PetscRealPart(array[j+i*step]); } if (min + 1.e-10 > max) { min -= 1.e-5; max += 1.e-5; } if (j < nbounds) { min = PetscMin(min,bounds[2*j]); max = PetscMax(max,bounds[2*j+1]); } ierr = MPI_Reduce(&min,&ymin,1,MPIU_REAL,MPIU_MIN,0,comm);CHKERRQ(ierr); ierr = MPI_Reduce(&max,&ymax,1,MPIU_REAL,MPIU_MAX,0,comm);CHKERRQ(ierr); ierr = PetscViewerDrawGetHold(v,&hold);CHKERRQ(ierr); if (!hold) { ierr = PetscDrawSynchronizedClear(draw);CHKERRQ(ierr); } ierr = PetscViewerDrawGetDrawAxis(v,k,&axis);CHKERRQ(ierr); ierr = PetscLogObjectParent(draw,axis);CHKERRQ(ierr); if (!rank) { const char *title; ierr = PetscDrawAxisSetLimits(axis,xmin,xmax,ymin,ymax);CHKERRQ(ierr); ierr = PetscDrawAxisDraw(axis);CHKERRQ(ierr); ierr = PetscDrawGetCoordinates(draw,coors,coors+1,coors+2,coors+3);CHKERRQ(ierr); ierr = DMDAGetFieldName(da,j,&title);CHKERRQ(ierr); if (title) {ierr = PetscDrawSetTitle(draw,title);CHKERRQ(ierr);} } ierr = MPI_Bcast(coors,4,MPIU_REAL,0,comm);CHKERRQ(ierr); if (rank) { ierr = PetscDrawSetCoordinates(draw,coors[0],coors[1],coors[2],coors[3]);CHKERRQ(ierr); } /* draw local part of vector */ ierr = PetscObjectGetNewTag((PetscObject)xin,&tag1);CHKERRQ(ierr); ierr = PetscObjectGetNewTag((PetscObject)xin,&tag2);CHKERRQ(ierr); if (rank < size-1) { /*send value to right */ ierr = MPI_Send((void*)&array[j+(n-1)*step],1,MPIU_REAL,rank+1,tag1,comm);CHKERRQ(ierr); ierr = MPI_Send((void*)&xg[n-1],1,MPIU_REAL,rank+1,tag1,comm);CHKERRQ(ierr); } if (!rank && bx == DMDA_BOUNDARY_PERIODIC && size > 1) { /* first processor sends first value to last */ ierr = MPI_Send((void*)&array[j],1,MPIU_REAL,size-1,tag2,comm);CHKERRQ(ierr); } for (i=1; i<n; i++) { ierr = PetscDrawLine(draw,PetscRealPart(xg[i-1]),PetscRealPart(array[j+step*(i-1)]),PetscRealPart(xg[i]),PetscRealPart(array[j+step*i]),PETSC_DRAW_RED);CHKERRQ(ierr); if (showpoints) { ierr = PetscDrawPoint(draw,PetscRealPart(xg[i-1]),PetscRealPart(array[j+step*(i-1)]),PETSC_DRAW_BLACK);CHKERRQ(ierr); } } if (rank) { /* receive value from left */ ierr = MPI_Recv(&tmp,1,MPIU_REAL,rank-1,tag1,comm,&status);CHKERRQ(ierr); ierr = MPI_Recv(&xgtmp,1,MPIU_REAL,rank-1,tag1,comm,&status);CHKERRQ(ierr); ierr = PetscDrawLine(draw,xgtmp,tmp,PetscRealPart(xg[0]),PetscRealPart(array[j]),PETSC_DRAW_RED);CHKERRQ(ierr); if (showpoints) { ierr = PetscDrawPoint(draw,xgtmp,tmp,PETSC_DRAW_BLACK);CHKERRQ(ierr); } } if (rank == size-1 && bx == DMDA_BOUNDARY_PERIODIC && size > 1) { ierr = MPI_Recv(&tmp,1,MPIU_REAL,0,tag2,comm,&status);CHKERRQ(ierr); ierr = PetscDrawLine(draw,PetscRealPart(xg[n-2]),PetscRealPart(array[j+step*(n-1)]),PetscRealPart(xg[n-1]),tmp,PETSC_DRAW_RED);CHKERRQ(ierr); if (showpoints) { ierr = PetscDrawPoint(draw,PetscRealPart(xg[n-2]),PetscRealPart(array[j+step*(n-1)]),PETSC_DRAW_BLACK);CHKERRQ(ierr); } } ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr); ierr = PetscDrawPause(draw);CHKERRQ(ierr); } ierr = PetscFree(displayfields);CHKERRQ(ierr); ierr = VecRestoreArrayRead(xcoor,&xg);CHKERRQ(ierr); ierr = VecRestoreArrayRead(xin,&array);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* This assumes that the DM has been cloned prior to the call */ PetscErrorCode DMCreateSubDM_Section_Private(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm) { PetscSection section, sectionGlobal; PetscInt *subIndices; PetscInt subSize = 0, subOff = 0, nF, f, pStart, pEnd, p; PetscErrorCode ierr; PetscFunctionBegin; if (!numFields) PetscFunctionReturn(0); ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); ierr = DMGetDefaultGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); if (!section) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Must set default section for DM before splitting fields"); if (!sectionGlobal) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Must set default global section for DM before splitting fields"); ierr = PetscSectionGetNumFields(section, &nF);CHKERRQ(ierr); if (numFields > nF) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Number of requested fields %d greater than number of DM fields %d", numFields, nF); if (is) { ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr); for (p = pStart; p < pEnd; ++p) { PetscInt gdof; ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); if (gdof > 0) { for (f = 0; f < numFields; ++f) { PetscInt fdof, fcdof; ierr = PetscSectionGetFieldDof(section, p, fields[f], &fdof);CHKERRQ(ierr); ierr = PetscSectionGetFieldConstraintDof(section, p, fields[f], &fcdof);CHKERRQ(ierr); subSize += fdof-fcdof; } } } ierr = PetscMalloc1(subSize, &subIndices);CHKERRQ(ierr); for (p = pStart; p < pEnd; ++p) { PetscInt gdof, goff; ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); if (gdof > 0) { ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr); for (f = 0; f < numFields; ++f) { PetscInt fdof, fcdof, fc, f2, poff = 0; /* Can get rid of this loop by storing field information in the global section */ for (f2 = 0; f2 < fields[f]; ++f2) { ierr = PetscSectionGetFieldDof(section, p, f2, &fdof);CHKERRQ(ierr); ierr = PetscSectionGetFieldConstraintDof(section, p, f2, &fcdof);CHKERRQ(ierr); poff += fdof-fcdof; } ierr = PetscSectionGetFieldDof(section, p, fields[f], &fdof);CHKERRQ(ierr); ierr = PetscSectionGetFieldConstraintDof(section, p, fields[f], &fcdof);CHKERRQ(ierr); for (fc = 0; fc < fdof-fcdof; ++fc, ++subOff) { subIndices[subOff] = goff+poff+fc; } } } } ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), subSize, subIndices, PETSC_OWN_POINTER, is);CHKERRQ(ierr); } if (subdm) { PetscSection subsection; PetscBool haveNull = PETSC_FALSE; PetscInt f, nf = 0; ierr = PetscSectionCreateSubsection(section, numFields, fields, &subsection);CHKERRQ(ierr); ierr = DMSetDefaultSection(*subdm, subsection);CHKERRQ(ierr); ierr = PetscSectionDestroy(&subsection);CHKERRQ(ierr); for (f = 0; f < numFields; ++f) { (*subdm)->nullspaceConstructors[f] = dm->nullspaceConstructors[fields[f]]; if ((*subdm)->nullspaceConstructors[f]) { haveNull = PETSC_TRUE; nf = f; } } if (haveNull && is) { MatNullSpace nullSpace; ierr = (*(*subdm)->nullspaceConstructors[nf])(*subdm, nf, &nullSpace);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) *is, "nullspace", (PetscObject) nullSpace);CHKERRQ(ierr); ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr); } if (dm->prob) { PetscInt Nf; ierr = PetscDSGetNumFields(dm->prob, &Nf);CHKERRQ(ierr); if (nF != Nf) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "The number of DM fields %d does not match the number of Section fields %d", Nf, nF); ierr = DMSetNumFields(*subdm, numFields);CHKERRQ(ierr); for (f = 0; f < numFields; ++f) { PetscObject disc; ierr = DMGetField(dm, fields[f], &disc);CHKERRQ(ierr); ierr = DMSetField(*subdm, f, disc);CHKERRQ(ierr); } if (numFields == 1 && is) { PetscObject disc, space, pmat; ierr = DMGetField(*subdm, 0, &disc);CHKERRQ(ierr); ierr = PetscObjectQuery(disc, "nullspace", &space);CHKERRQ(ierr); if (space) {ierr = PetscObjectCompose((PetscObject) *is, "nullspace", space);CHKERRQ(ierr);} ierr = PetscObjectQuery(disc, "nearnullspace", &space);CHKERRQ(ierr); if (space) {ierr = PetscObjectCompose((PetscObject) *is, "nearnullspace", space);CHKERRQ(ierr);} ierr = PetscObjectQuery(disc, "pmat", &pmat);CHKERRQ(ierr); if (pmat) {ierr = PetscObjectCompose((PetscObject) *is, "pmat", pmat);CHKERRQ(ierr);} } } } #if 0 /* We need a way to filter the original SF for given fields: - Keeping the original section around it too much I think - We could keep the distributed section, and subset it */ if (dm->sfNatural) { PetscSF sfNatural; ierr = PetscSectionCreateSubsection(dm->originalSection, numFields, fields, &(*subdm)->originalSection);CHKERRQ(ierr); ierr = DMPlexCreateGlobalToNaturalPetscSF(*subdm, &sfNatural);CHKERRQ(ierr); ierr = DMPlexSetGlobalToNaturalPetscSF(*subdm, sfNatural);CHKERRQ(ierr); } #endif PetscFunctionReturn(0); }
/* This assumes that the DM has been cloned prior to the call */ PetscErrorCode DMCreateSubDM_Section_Private(DM dm, PetscInt numFields, PetscInt fields[], IS *is, DM *subdm) { PetscSection section, sectionGlobal; PetscInt *subIndices; PetscInt subSize = 0, subOff = 0, nF, f, pStart, pEnd, p; PetscErrorCode ierr; PetscFunctionBegin; if (!numFields) PetscFunctionReturn(0); ierr = DMGetDefaultSection(dm, §ion);CHKERRQ(ierr); ierr = DMGetDefaultGlobalSection(dm, §ionGlobal);CHKERRQ(ierr); if (!section) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Must set default section for DM before splitting fields"); if (!sectionGlobal) SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Must set default global section for DM before splitting fields"); ierr = PetscSectionGetNumFields(section, &nF);CHKERRQ(ierr); if (numFields > nF) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Number of requested fields %d greater than number of DM fields %d", numFields, nF); if (is) { ierr = PetscSectionGetChart(sectionGlobal, &pStart, &pEnd);CHKERRQ(ierr); for (p = pStart; p < pEnd; ++p) { PetscInt gdof; ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); if (gdof > 0) { for (f = 0; f < numFields; ++f) { PetscInt fdof, fcdof; ierr = PetscSectionGetFieldDof(section, p, fields[f], &fdof);CHKERRQ(ierr); ierr = PetscSectionGetFieldConstraintDof(section, p, fields[f], &fcdof);CHKERRQ(ierr); subSize += fdof-fcdof; } } } ierr = PetscMalloc1(subSize, &subIndices);CHKERRQ(ierr); for (p = pStart; p < pEnd; ++p) { PetscInt gdof, goff; ierr = PetscSectionGetDof(sectionGlobal, p, &gdof);CHKERRQ(ierr); if (gdof > 0) { ierr = PetscSectionGetOffset(sectionGlobal, p, &goff);CHKERRQ(ierr); for (f = 0; f < numFields; ++f) { PetscInt fdof, fcdof, fc, f2, poff = 0; /* Can get rid of this loop by storing field information in the global section */ for (f2 = 0; f2 < fields[f]; ++f2) { ierr = PetscSectionGetFieldDof(section, p, f2, &fdof);CHKERRQ(ierr); ierr = PetscSectionGetFieldConstraintDof(section, p, f2, &fcdof);CHKERRQ(ierr); poff += fdof-fcdof; } ierr = PetscSectionGetFieldDof(section, p, fields[f], &fdof);CHKERRQ(ierr); ierr = PetscSectionGetFieldConstraintDof(section, p, fields[f], &fcdof);CHKERRQ(ierr); for (fc = 0; fc < fdof-fcdof; ++fc, ++subOff) { subIndices[subOff] = goff+poff+fc; } } } } ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), subSize, subIndices, PETSC_OWN_POINTER, is);CHKERRQ(ierr); } if (subdm) { PetscSection subsection; PetscBool haveNull = PETSC_FALSE; PetscInt f, nf = 0; ierr = PetscSectionCreateSubsection(section, numFields, fields, &subsection);CHKERRQ(ierr); ierr = DMSetDefaultSection(*subdm, subsection);CHKERRQ(ierr); ierr = PetscSectionDestroy(&subsection);CHKERRQ(ierr); for (f = 0; f < numFields; ++f) { (*subdm)->nullspaceConstructors[f] = dm->nullspaceConstructors[fields[f]]; if ((*subdm)->nullspaceConstructors[f]) { haveNull = PETSC_TRUE; nf = f; } } if (haveNull) { MatNullSpace nullSpace; ierr = (*(*subdm)->nullspaceConstructors[nf])(*subdm, nf, &nullSpace);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) *is, "nullspace", (PetscObject) nullSpace);CHKERRQ(ierr); ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr); } if (dm->fields) { if (nF != dm->numFields) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "The number of DM fields %d does not match the number of Section fields %d", dm->numFields, nF); ierr = DMSetNumFields(*subdm, numFields);CHKERRQ(ierr); for (f = 0; f < numFields; ++f) { ierr = PetscObjectListDuplicate(dm->fields[fields[f]]->olist, &(*subdm)->fields[f]->olist);CHKERRQ(ierr); } if (numFields == 1) { MatNullSpace space; Mat pmat; ierr = PetscObjectQuery((*subdm)->fields[0], "nullspace", (PetscObject*) &space);CHKERRQ(ierr); if (space) {ierr = PetscObjectCompose((PetscObject) *is, "nullspace", (PetscObject) space);CHKERRQ(ierr);} ierr = PetscObjectQuery((*subdm)->fields[0], "nearnullspace", (PetscObject*) &space);CHKERRQ(ierr); if (space) {ierr = PetscObjectCompose((PetscObject) *is, "nearnullspace", (PetscObject) space);CHKERRQ(ierr);} ierr = PetscObjectQuery((*subdm)->fields[0], "pmat", (PetscObject*) &pmat);CHKERRQ(ierr); if (pmat) {ierr = PetscObjectCompose((PetscObject) *is, "pmat", (PetscObject) pmat);CHKERRQ(ierr);} } } } PetscFunctionReturn(0); }