1c0517cd5SMatthew G. Knepley #include <petsc/private/dmimpl.h> /*I "petscdm.h" I*/ 2c0517cd5SMatthew G. Knepley 3c0517cd5SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMIsForest(DM,PetscBool*); 4c0517cd5SMatthew G. Knepley 5c0517cd5SMatthew G. Knepley DMGeneratorFunctionList DMGenerateList = NULL; 6c0517cd5SMatthew G. Knepley PetscBool DMGenerateRegisterAllCalled = PETSC_FALSE; 7c0517cd5SMatthew G. Knepley 8c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_TRIANGLE) 9c0517cd5SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMPlexGenerate_Triangle(DM, PetscBool, DM*); 10c0517cd5SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMPlexRefine_Triangle(DM, double*, DM*); 11c0517cd5SMatthew G. Knepley #endif 12c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_TETGEN) 13c0517cd5SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMPlexGenerate_Tetgen(DM, PetscBool, DM*); 14c0517cd5SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMPlexRefine_Tetgen(DM, double*, DM*); 15c0517cd5SMatthew G. Knepley #endif 16c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_CTETGEN) 17c0517cd5SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMPlexGenerate_CTetgen(DM, PetscBool, DM*); 18c0517cd5SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMPlexRefine_CTetgen(DM, double*, DM*); 19c0517cd5SMatthew G. Knepley #endif 20c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMATIC) 219fe9e680SJoe Wallwork PETSC_EXTERN PetscErrorCode DMAdaptMetric_Pragmatic_Plex(DM, Vec, DMLabel, DMLabel, DM*); 22c0517cd5SMatthew G. Knepley #endif 23c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_MMG) 249fe9e680SJoe Wallwork PETSC_EXTERN PetscErrorCode DMAdaptMetric_Mmg_Plex(DM, Vec, DMLabel, DMLabel, DM*); 25c0517cd5SMatthew G. Knepley #endif 26c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_PARMMG) 279fe9e680SJoe Wallwork PETSC_EXTERN PetscErrorCode DMAdaptMetric_ParMmg_Plex(DM, Vec, DMLabel, DMLabel, DM*); 28c0517cd5SMatthew G. Knepley #endif 299fe9e680SJoe Wallwork PETSC_EXTERN PetscErrorCode DMPlexTransformAdaptLabel(DM, Vec, DMLabel, DMLabel, DM*); 309fe9e680SJoe Wallwork PETSC_EXTERN PetscErrorCode DMAdaptLabel_Forest(DM, Vec, DMLabel, DMLabel, DM*); 31c0517cd5SMatthew G. Knepley 32c0517cd5SMatthew G. Knepley /*@C 33c0517cd5SMatthew G. Knepley DMGenerateRegisterAll - Registers all of the mesh generation methods in the DM package. 34c0517cd5SMatthew G. Knepley 35c0517cd5SMatthew G. Knepley Not Collective 36c0517cd5SMatthew G. Knepley 37c0517cd5SMatthew G. Knepley Level: advanced 38c0517cd5SMatthew G. Knepley 39c0517cd5SMatthew G. Knepley .seealso: DMGenerateRegisterDestroy() 40c0517cd5SMatthew G. Knepley @*/ 41c0517cd5SMatthew G. Knepley PetscErrorCode DMGenerateRegisterAll(void) 42c0517cd5SMatthew G. Knepley { 43c0517cd5SMatthew G. Knepley PetscErrorCode ierr; 44c0517cd5SMatthew G. Knepley 45c0517cd5SMatthew G. Knepley PetscFunctionBegin; 46c0517cd5SMatthew G. Knepley if (DMGenerateRegisterAllCalled) PetscFunctionReturn(0); 47c0517cd5SMatthew G. Knepley DMGenerateRegisterAllCalled = PETSC_TRUE; 48c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_TRIANGLE) 49c0517cd5SMatthew G. Knepley ierr = DMGenerateRegister("triangle",DMPlexGenerate_Triangle,DMPlexRefine_Triangle,NULL,1);CHKERRQ(ierr); 50c0517cd5SMatthew G. Knepley #endif 51c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_CTETGEN) 52c0517cd5SMatthew G. Knepley ierr = DMGenerateRegister("ctetgen",DMPlexGenerate_CTetgen,DMPlexRefine_CTetgen,NULL,2);CHKERRQ(ierr); 53c0517cd5SMatthew G. Knepley #endif 54c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_TETGEN) 55c0517cd5SMatthew G. Knepley ierr = DMGenerateRegister("tetgen",DMPlexGenerate_Tetgen,DMPlexRefine_Tetgen,NULL,2);CHKERRQ(ierr); 56c0517cd5SMatthew G. Knepley #endif 57c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMATIC) 58c0517cd5SMatthew G. Knepley ierr = DMGenerateRegister("pragmatic",NULL,NULL,DMAdaptMetric_Pragmatic_Plex,-1);CHKERRQ(ierr); 59c0517cd5SMatthew G. Knepley #endif 60c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_MMG) 61c0517cd5SMatthew G. Knepley ierr = DMGenerateRegister("mmg",NULL,NULL,DMAdaptMetric_Mmg_Plex,-1);CHKERRQ(ierr); 62c0517cd5SMatthew G. Knepley #endif 63c0517cd5SMatthew G. Knepley #if defined(PETSC_HAVE_PARMMG) 64c0517cd5SMatthew G. Knepley ierr = DMGenerateRegister("parmmg",NULL,NULL,DMAdaptMetric_ParMmg_Plex,-1);CHKERRQ(ierr); 65c0517cd5SMatthew G. Knepley #endif 66c0517cd5SMatthew G. Knepley ierr = DMGenerateRegister("cellrefiner",NULL,NULL,DMPlexTransformAdaptLabel,-1);CHKERRQ(ierr); 67c0517cd5SMatthew G. Knepley ierr = DMGenerateRegister("forest",NULL,NULL,DMAdaptLabel_Forest,-1);CHKERRQ(ierr); 68c0517cd5SMatthew G. Knepley PetscFunctionReturn(0); 69c0517cd5SMatthew G. Knepley } 70c0517cd5SMatthew G. Knepley 71c0517cd5SMatthew G. Knepley /*@C 72c0517cd5SMatthew G. Knepley DMGenerateRegister - Adds a grid generator to DM 73c0517cd5SMatthew G. Knepley 74c0517cd5SMatthew G. Knepley Not Collective 75c0517cd5SMatthew G. Knepley 76c0517cd5SMatthew G. Knepley Input Parameters: 77c0517cd5SMatthew G. Knepley + name_solver - name of a new user-defined grid generator 78c0517cd5SMatthew G. Knepley . fnc - generator function 79c0517cd5SMatthew G. Knepley . rfnc - refinement function 80c0517cd5SMatthew G. Knepley . alfnc - adapt by label function 81c0517cd5SMatthew G. Knepley - dim - dimension of boundary of domain 82c0517cd5SMatthew G. Knepley 83c0517cd5SMatthew G. Knepley Notes: 84c0517cd5SMatthew G. Knepley DMGenerateRegister() may be called multiple times to add several user-defined solvers. 85c0517cd5SMatthew G. Knepley 86c0517cd5SMatthew G. Knepley Sample usage: 87c0517cd5SMatthew G. Knepley .vb 88c0517cd5SMatthew G. Knepley DMGenerateRegister("my_generator",MyGeneratorCreate,MyGeneratorRefiner,MyGeneratorAdaptor,dim); 89c0517cd5SMatthew G. Knepley .ve 90c0517cd5SMatthew G. Knepley 91c0517cd5SMatthew G. Knepley Then, your generator can be chosen with the procedural interface via 92c0517cd5SMatthew G. Knepley $ DMGenerate(dm,"my_generator",...) 93c0517cd5SMatthew G. Knepley or at runtime via the option 94c0517cd5SMatthew G. Knepley $ -dm_generator my_generator 95c0517cd5SMatthew G. Knepley 96c0517cd5SMatthew G. Knepley Level: advanced 97c0517cd5SMatthew G. Knepley 98c0517cd5SMatthew G. Knepley .seealso: DMGenerateRegisterAll(), DMPlexGenerate(), DMGenerateRegisterDestroy() 99c0517cd5SMatthew G. Knepley 100c0517cd5SMatthew G. Knepley @*/ 1019fe9e680SJoe Wallwork PetscErrorCode DMGenerateRegister(const char sname[], PetscErrorCode (*fnc)(DM, PetscBool, DM*), PetscErrorCode (*rfnc)(DM, PetscReal*, DM*), PetscErrorCode (*alfnc)(DM, Vec, DMLabel, DMLabel, DM*), PetscInt dim) 102c0517cd5SMatthew G. Knepley { 103c0517cd5SMatthew G. Knepley DMGeneratorFunctionList entry; 104c0517cd5SMatthew G. Knepley PetscErrorCode ierr; 105c0517cd5SMatthew G. Knepley 106c0517cd5SMatthew G. Knepley PetscFunctionBegin; 107c0517cd5SMatthew G. Knepley ierr = PetscNew(&entry);CHKERRQ(ierr); 108c0517cd5SMatthew G. Knepley ierr = PetscStrallocpy(sname,&entry->name);CHKERRQ(ierr); 109c0517cd5SMatthew G. Knepley entry->generate = fnc; 110c0517cd5SMatthew G. Knepley entry->refine = rfnc; 111c0517cd5SMatthew G. Knepley entry->adapt = alfnc; 112c0517cd5SMatthew G. Knepley entry->dim = dim; 113c0517cd5SMatthew G. Knepley entry->next = NULL; 114c0517cd5SMatthew G. Knepley if (!DMGenerateList) DMGenerateList = entry; 115c0517cd5SMatthew G. Knepley else { 116c0517cd5SMatthew G. Knepley DMGeneratorFunctionList fl = DMGenerateList; 117c0517cd5SMatthew G. Knepley while (fl->next) fl = fl->next; 118c0517cd5SMatthew G. Knepley fl->next = entry; 119c0517cd5SMatthew G. Knepley } 120c0517cd5SMatthew G. Knepley PetscFunctionReturn(0); 121c0517cd5SMatthew G. Knepley } 122c0517cd5SMatthew G. Knepley 123c0517cd5SMatthew G. Knepley extern PetscBool DMGenerateRegisterAllCalled; 124c0517cd5SMatthew G. Knepley 125c0517cd5SMatthew G. Knepley PetscErrorCode DMGenerateRegisterDestroy(void) 126c0517cd5SMatthew G. Knepley { 127c0517cd5SMatthew G. Knepley DMGeneratorFunctionList next, fl; 128c0517cd5SMatthew G. Knepley PetscErrorCode ierr; 129c0517cd5SMatthew G. Knepley 130c0517cd5SMatthew G. Knepley PetscFunctionBegin; 131c0517cd5SMatthew G. Knepley next = fl = DMGenerateList; 132c0517cd5SMatthew G. Knepley while (next) { 133c0517cd5SMatthew G. Knepley next = fl ? fl->next : NULL; 134c0517cd5SMatthew G. Knepley if (fl) {ierr = PetscFree(fl->name);CHKERRQ(ierr);} 135c0517cd5SMatthew G. Knepley ierr = PetscFree(fl);CHKERRQ(ierr); 136c0517cd5SMatthew G. Knepley fl = next; 137c0517cd5SMatthew G. Knepley } 138c0517cd5SMatthew G. Knepley DMGenerateList = NULL; 139c0517cd5SMatthew G. Knepley DMGenerateRegisterAllCalled = PETSC_FALSE; 140c0517cd5SMatthew G. Knepley PetscFunctionReturn(0); 141c0517cd5SMatthew G. Knepley } 142c0517cd5SMatthew G. Knepley 143c0517cd5SMatthew G. Knepley /*@C 144c0517cd5SMatthew G. Knepley DMAdaptLabel - Adapt a dm based on a label with values interpreted as coarsening and refining flags. Specific implementations of DM maybe have 145c0517cd5SMatthew G. Knepley specialized flags, but all implementations should accept flag values DM_ADAPT_DETERMINE, DM_ADAPT_KEEP, DM_ADAPT_REFINE, and DM_ADAPT_COARSEN. 146c0517cd5SMatthew G. Knepley 147c0517cd5SMatthew G. Knepley Collective on dm 148c0517cd5SMatthew G. Knepley 149c0517cd5SMatthew G. Knepley Input parameters: 150c0517cd5SMatthew G. Knepley + dm - the pre-adaptation DM object 151c0517cd5SMatthew G. Knepley - label - label with the flags 152c0517cd5SMatthew G. Knepley 153c0517cd5SMatthew G. Knepley Output parameters: 154c0517cd5SMatthew G. Knepley . dmAdapt - the adapted DM object: may be NULL if an adapted DM could not be produced. 155c0517cd5SMatthew G. Knepley 156c0517cd5SMatthew G. Knepley Level: intermediate 157c0517cd5SMatthew G. Knepley 158c0517cd5SMatthew G. Knepley .seealso: DMAdaptMetric(), DMCoarsen(), DMRefine() 159c0517cd5SMatthew G. Knepley @*/ 160c0517cd5SMatthew G. Knepley PetscErrorCode DMAdaptLabel(DM dm, DMLabel label, DM *dmAdapt) 161c0517cd5SMatthew G. Knepley { 162c0517cd5SMatthew G. Knepley DMGeneratorFunctionList fl; 163c0517cd5SMatthew G. Knepley char adaptname[PETSC_MAX_PATH_LEN]; 164c0517cd5SMatthew G. Knepley const char *name; 165c0517cd5SMatthew G. Knepley PetscInt dim; 166c0517cd5SMatthew G. Knepley PetscBool flg, isForest, found = PETSC_FALSE; 167c0517cd5SMatthew G. Knepley PetscErrorCode ierr; 168c0517cd5SMatthew G. Knepley 169c0517cd5SMatthew G. Knepley PetscFunctionBegin; 170c0517cd5SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 171c0517cd5SMatthew G. Knepley if (label) PetscValidPointer(label, 2); 172c0517cd5SMatthew G. Knepley PetscValidPointer(dmAdapt, 3); 173c0517cd5SMatthew G. Knepley *dmAdapt = NULL; 174c0517cd5SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 175c0517cd5SMatthew G. Knepley ierr = DMIsForest(dm, &isForest);CHKERRQ(ierr); 176c0517cd5SMatthew G. Knepley name = isForest ? "forest" : "cellrefiner"; 177c0517cd5SMatthew G. Knepley ierr = PetscOptionsGetString(((PetscObject) dm)->options, ((PetscObject) dm)->prefix, "-dm_adaptor", adaptname, sizeof(adaptname), &flg);CHKERRQ(ierr); 178c0517cd5SMatthew G. Knepley if (flg) name = adaptname; 179c0517cd5SMatthew G. Knepley 180c0517cd5SMatthew G. Knepley fl = DMGenerateList; 181c0517cd5SMatthew G. Knepley while (fl) { 182c0517cd5SMatthew G. Knepley ierr = PetscStrcmp(fl->name, name, &flg);CHKERRQ(ierr); 183c0517cd5SMatthew G. Knepley if (flg) { 1849fe9e680SJoe Wallwork ierr = (*fl->adapt)(dm, NULL, label, NULL, dmAdapt);CHKERRQ(ierr); 185c0517cd5SMatthew G. Knepley found = PETSC_TRUE; 186c0517cd5SMatthew G. Knepley } 187c0517cd5SMatthew G. Knepley fl = fl->next; 188c0517cd5SMatthew G. Knepley } 189*7a8be351SBarry Smith PetscCheck(found,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Grid adaptor %s not registered; you may need to add --download-%s to your ./configure options", name, name); 190c0517cd5SMatthew G. Knepley if (*dmAdapt) { 191c0517cd5SMatthew G. Knepley (*dmAdapt)->prealloc_only = dm->prealloc_only; /* maybe this should go .... */ 192c0517cd5SMatthew G. Knepley ierr = PetscFree((*dmAdapt)->vectype);CHKERRQ(ierr); 193c0517cd5SMatthew G. Knepley ierr = PetscStrallocpy(dm->vectype,(char**)&(*dmAdapt)->vectype);CHKERRQ(ierr); 194c0517cd5SMatthew G. Knepley ierr = PetscFree((*dmAdapt)->mattype);CHKERRQ(ierr); 195c0517cd5SMatthew G. Knepley ierr = PetscStrallocpy(dm->mattype,(char**)&(*dmAdapt)->mattype);CHKERRQ(ierr); 196c0517cd5SMatthew G. Knepley } 197c0517cd5SMatthew G. Knepley PetscFunctionReturn(0); 198c0517cd5SMatthew G. Knepley } 199c0517cd5SMatthew G. Knepley 200c0517cd5SMatthew G. Knepley /*@C 201c0517cd5SMatthew G. Knepley DMAdaptMetric - Generates a mesh adapted to the specified metric field. 202c0517cd5SMatthew G. Knepley 203c0517cd5SMatthew G. Knepley Input Parameters: 204c0517cd5SMatthew G. Knepley + dm - The DM object 205c0517cd5SMatthew G. Knepley . metric - The metric to which the mesh is adapted, defined vertex-wise. 2069fe9e680SJoe Wallwork . bdLabel - Label for boundary tags, which will be preserved in the output mesh. bdLabel should be NULL if there is no such label, and should be different from "_boundary_". 2079fe9e680SJoe Wallwork - rgLabel - Label for cell tags, which will be preserved in the output mesh. rgLabel should be NULL if there is no such label, and should be different from "_regions_". 208c0517cd5SMatthew G. Knepley 209c0517cd5SMatthew G. Knepley Output Parameter: 210c0517cd5SMatthew G. Knepley . dmAdapt - Pointer to the DM object containing the adapted mesh 211c0517cd5SMatthew G. Knepley 212c0517cd5SMatthew G. Knepley Note: The label in the adapted mesh will be registered under the name of the input DMLabel object 213c0517cd5SMatthew G. Knepley 214c0517cd5SMatthew G. Knepley Level: advanced 215c0517cd5SMatthew G. Knepley 216c0517cd5SMatthew G. Knepley .seealso: DMAdaptLabel(), DMCoarsen(), DMRefine() 217c0517cd5SMatthew G. Knepley @*/ 2189fe9e680SJoe Wallwork PetscErrorCode DMAdaptMetric(DM dm, Vec metric, DMLabel bdLabel, DMLabel rgLabel, DM *dmAdapt) 219c0517cd5SMatthew G. Knepley { 220c0517cd5SMatthew G. Knepley DMGeneratorFunctionList fl; 221c0517cd5SMatthew G. Knepley char adaptname[PETSC_MAX_PATH_LEN]; 22206716a2aSJoe Wallwork const char *name; 22306716a2aSJoe Wallwork const char * const adaptors[3] = {"pragmatic", "mmg", "parmmg"}; 224c0517cd5SMatthew G. Knepley PetscInt dim; 225c0517cd5SMatthew G. Knepley PetscBool flg, found = PETSC_FALSE; 226c0517cd5SMatthew G. Knepley PetscErrorCode ierr; 227c0517cd5SMatthew G. Knepley 228c0517cd5SMatthew G. Knepley PetscFunctionBegin; 229c0517cd5SMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 230c0517cd5SMatthew G. Knepley PetscValidHeaderSpecific(metric, VEC_CLASSID, 2); 231c0517cd5SMatthew G. Knepley if (bdLabel) PetscValidPointer(bdLabel, 3); 2329fe9e680SJoe Wallwork if (rgLabel) PetscValidPointer(rgLabel, 4); 2339fe9e680SJoe Wallwork PetscValidPointer(dmAdapt, 5); 234c0517cd5SMatthew G. Knepley *dmAdapt = NULL; 235c0517cd5SMatthew G. Knepley ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 236c0517cd5SMatthew G. Knepley ierr = PetscOptionsGetString(((PetscObject) dm)->options, ((PetscObject) dm)->prefix, "-dm_adaptor", adaptname, sizeof(adaptname), &flg);CHKERRQ(ierr); 23706716a2aSJoe Wallwork 23806716a2aSJoe Wallwork /* Default to Mmg in serial and ParMmg in parallel */ 239c0517cd5SMatthew G. Knepley if (flg) name = adaptname; 24006716a2aSJoe Wallwork else { 24106716a2aSJoe Wallwork MPI_Comm comm; 24206716a2aSJoe Wallwork PetscMPIInt size; 24306716a2aSJoe Wallwork 24406716a2aSJoe Wallwork ierr = PetscObjectGetComm((PetscObject)dm, &comm);CHKERRQ(ierr); 24506716a2aSJoe Wallwork ierr = MPI_Comm_size(comm, &size);CHKERRMPI(ierr); 24606716a2aSJoe Wallwork if (size == 1) name = adaptors[1]; 24706716a2aSJoe Wallwork else name = adaptors[2]; 24806716a2aSJoe Wallwork } 249c0517cd5SMatthew G. Knepley 250c0517cd5SMatthew G. Knepley fl = DMGenerateList; 251c0517cd5SMatthew G. Knepley while (fl) { 252c0517cd5SMatthew G. Knepley ierr = PetscStrcmp(fl->name, name, &flg);CHKERRQ(ierr); 253c0517cd5SMatthew G. Knepley if (flg) { 2549fe9e680SJoe Wallwork ierr = (*fl->adapt)(dm, metric, bdLabel, rgLabel, dmAdapt);CHKERRQ(ierr); 255c0517cd5SMatthew G. Knepley found = PETSC_TRUE; 256c0517cd5SMatthew G. Knepley } 257c0517cd5SMatthew G. Knepley fl = fl->next; 258c0517cd5SMatthew G. Knepley } 259*7a8be351SBarry Smith PetscCheck(found,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Grid adaptor %s not registered; you may need to add --download-%s to your ./configure options", name, name); 260c0517cd5SMatthew G. Knepley if (*dmAdapt) { 261c0517cd5SMatthew G. Knepley (*dmAdapt)->prealloc_only = dm->prealloc_only; /* maybe this should go .... */ 262c0517cd5SMatthew G. Knepley ierr = PetscFree((*dmAdapt)->vectype);CHKERRQ(ierr); 263c0517cd5SMatthew G. Knepley ierr = PetscStrallocpy(dm->vectype,(char**)&(*dmAdapt)->vectype);CHKERRQ(ierr); 264c0517cd5SMatthew G. Knepley ierr = PetscFree((*dmAdapt)->mattype);CHKERRQ(ierr); 265c0517cd5SMatthew G. Knepley ierr = PetscStrallocpy(dm->mattype,(char**)&(*dmAdapt)->mattype);CHKERRQ(ierr); 266c0517cd5SMatthew G. Knepley } 267c0517cd5SMatthew G. Knepley PetscFunctionReturn(0); 268c0517cd5SMatthew G. Knepley } 269