1af0996ceSBarry Smith #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2d9deefdfSMatthew G. Knepley 3d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexInvertCell_Internal(PetscInt dim, PetscInt numCorners, PetscInt cone[]) 4d9deefdfSMatthew G. Knepley { 5d9deefdfSMatthew G. Knepley int tmpc; 6d9deefdfSMatthew G. Knepley 7d9deefdfSMatthew G. Knepley PetscFunctionBegin; 8d9deefdfSMatthew G. Knepley if (dim != 3) PetscFunctionReturn(0); 9d9deefdfSMatthew G. Knepley switch (numCorners) { 10d9deefdfSMatthew G. Knepley case 4: 11d9deefdfSMatthew G. Knepley tmpc = cone[0]; 12d9deefdfSMatthew G. Knepley cone[0] = cone[1]; 13d9deefdfSMatthew G. Knepley cone[1] = tmpc; 14d9deefdfSMatthew G. Knepley break; 15d9deefdfSMatthew G. Knepley case 8: 16d9deefdfSMatthew G. Knepley tmpc = cone[1]; 17d9deefdfSMatthew G. Knepley cone[1] = cone[3]; 18d9deefdfSMatthew G. Knepley cone[3] = tmpc; 19d9deefdfSMatthew G. Knepley break; 20d9deefdfSMatthew G. Knepley default: break; 21d9deefdfSMatthew G. Knepley } 22d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 23d9deefdfSMatthew G. Knepley } 24d9deefdfSMatthew G. Knepley 25d9deefdfSMatthew G. Knepley /*@C 26d9deefdfSMatthew G. Knepley DMPlexInvertCell - This flips tetrahedron and hexahedron orientation since Plex stores them internally with outward normals. Other cells are left untouched. 27d9deefdfSMatthew G. Knepley 28d9deefdfSMatthew G. Knepley Input Parameters: 29d9deefdfSMatthew G. Knepley + numCorners - The number of vertices in a cell 30d9deefdfSMatthew G. Knepley - cone - The incoming cone 31d9deefdfSMatthew G. Knepley 32d9deefdfSMatthew G. Knepley Output Parameter: 33d9deefdfSMatthew G. Knepley . cone - The inverted cone (in-place) 34d9deefdfSMatthew G. Knepley 35d9deefdfSMatthew G. Knepley Level: developer 36d9deefdfSMatthew G. Knepley 37d9deefdfSMatthew G. Knepley .seealso: DMPlexGenerate() 38d9deefdfSMatthew G. Knepley @*/ 39d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexInvertCell(PetscInt dim, PetscInt numCorners, int cone[]) 40d9deefdfSMatthew G. Knepley { 41d9deefdfSMatthew G. Knepley int tmpc; 42d9deefdfSMatthew G. Knepley 43d9deefdfSMatthew G. Knepley PetscFunctionBegin; 44d9deefdfSMatthew G. Knepley if (dim != 3) PetscFunctionReturn(0); 45d9deefdfSMatthew G. Knepley switch (numCorners) { 46d9deefdfSMatthew G. Knepley case 4: 47d9deefdfSMatthew G. Knepley tmpc = cone[0]; 48d9deefdfSMatthew G. Knepley cone[0] = cone[1]; 49d9deefdfSMatthew G. Knepley cone[1] = tmpc; 50d9deefdfSMatthew G. Knepley break; 51d9deefdfSMatthew G. Knepley case 8: 52d9deefdfSMatthew G. Knepley tmpc = cone[1]; 53d9deefdfSMatthew G. Knepley cone[1] = cone[3]; 54d9deefdfSMatthew G. Knepley cone[3] = tmpc; 55d9deefdfSMatthew G. Knepley break; 56d9deefdfSMatthew G. Knepley default: break; 57d9deefdfSMatthew G. Knepley } 58d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 59d9deefdfSMatthew G. Knepley } 60d9deefdfSMatthew G. Knepley 61d9deefdfSMatthew G. Knepley 6294ef8ddeSSatish Balay /*@C 63d9deefdfSMatthew G. Knepley DMPlexTriangleSetOptions - Set the options used for the Triangle mesh generator 64d9deefdfSMatthew G. Knepley 65d9deefdfSMatthew G. Knepley Not Collective 66d9deefdfSMatthew G. Knepley 67d9deefdfSMatthew G. Knepley Inputs Parameters: 68d9deefdfSMatthew G. Knepley + dm - The DMPlex object 69d9deefdfSMatthew G. Knepley - opts - The command line options 70d9deefdfSMatthew G. Knepley 71d9deefdfSMatthew G. Knepley Level: developer 72d9deefdfSMatthew G. Knepley 73d9deefdfSMatthew G. Knepley .seealso: DMPlexTetgenSetOptions(), DMPlexGenerate() 74d9deefdfSMatthew G. Knepley @*/ 75d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexTriangleSetOptions(DM dm, const char *opts) 76d9deefdfSMatthew G. Knepley { 77d9deefdfSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 78d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 79d9deefdfSMatthew G. Knepley 80d9deefdfSMatthew G. Knepley PetscFunctionBegin; 81d9deefdfSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 82d9deefdfSMatthew G. Knepley PetscValidPointer(opts, 2); 83606ac3a5SMatthew G. Knepley ierr = PetscFree(mesh->triangleOpts);CHKERRQ(ierr); 84606ac3a5SMatthew G. Knepley ierr = PetscStrallocpy(opts, &mesh->triangleOpts);CHKERRQ(ierr); 85d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 86d9deefdfSMatthew G. Knepley } 87d9deefdfSMatthew G. Knepley 8894ef8ddeSSatish Balay /*@C 89d9deefdfSMatthew G. Knepley DMPlexTetgenSetOptions - Set the options used for the Tetgen mesh generator 90d9deefdfSMatthew G. Knepley 91d9deefdfSMatthew G. Knepley Not Collective 92d9deefdfSMatthew G. Knepley 93d9deefdfSMatthew G. Knepley Inputs Parameters: 94d9deefdfSMatthew G. Knepley + dm - The DMPlex object 95d9deefdfSMatthew G. Knepley - opts - The command line options 96d9deefdfSMatthew G. Knepley 97d9deefdfSMatthew G. Knepley Level: developer 98d9deefdfSMatthew G. Knepley 99d9deefdfSMatthew G. Knepley .seealso: DMPlexTriangleSetOptions(), DMPlexGenerate() 100d9deefdfSMatthew G. Knepley @*/ 101d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexTetgenSetOptions(DM dm, const char *opts) 102d9deefdfSMatthew G. Knepley { 103d9deefdfSMatthew G. Knepley DM_Plex *mesh = (DM_Plex*) dm->data; 104d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 105d9deefdfSMatthew G. Knepley 106d9deefdfSMatthew G. Knepley PetscFunctionBegin; 107d9deefdfSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 108d9deefdfSMatthew G. Knepley PetscValidPointer(opts, 2); 109606ac3a5SMatthew G. Knepley ierr = PetscFree(mesh->tetgenOpts);CHKERRQ(ierr); 110606ac3a5SMatthew G. Knepley ierr = PetscStrallocpy(opts, &mesh->tetgenOpts);CHKERRQ(ierr); 111d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 112d9deefdfSMatthew G. Knepley } 113d9deefdfSMatthew G. Knepley 1143a074057SBarry Smith /* 1153a074057SBarry Smith Contains the list of registered DMPlexGenerators routines 1163a074057SBarry Smith */ 1173a074057SBarry Smith PetscFunctionList DMPlexGenerateList = NULL; 118d9deefdfSMatthew G. Knepley 1193a074057SBarry Smith struct _n_PetscFunctionList { 1203a074057SBarry Smith PetscErrorCode (*generate)(DM, PetscBool, DM*); 1213a074057SBarry Smith PetscErrorCode (*refine)(DM,double*, DM*); 1223a074057SBarry Smith char *name; /* string to identify routine */ 1233a074057SBarry Smith PetscInt dim; 1243a074057SBarry Smith PetscFunctionList next; /* next pointer */ 1253a074057SBarry Smith }; 126d9deefdfSMatthew G. Knepley 127d9deefdfSMatthew G. Knepley /*@C 128d9deefdfSMatthew G. Knepley DMPlexGenerate - Generates a mesh. 129d9deefdfSMatthew G. Knepley 130d9deefdfSMatthew G. Knepley Not Collective 131d9deefdfSMatthew G. Knepley 132d9deefdfSMatthew G. Knepley Input Parameters: 133d9deefdfSMatthew G. Knepley + boundary - The DMPlex boundary object 134d9deefdfSMatthew G. Knepley . name - The mesh generation package name 135d9deefdfSMatthew G. Knepley - interpolate - Flag to create intermediate mesh elements 136d9deefdfSMatthew G. Knepley 137d9deefdfSMatthew G. Knepley Output Parameter: 138d9deefdfSMatthew G. Knepley . mesh - The DMPlex object 139d9deefdfSMatthew G. Knepley 140*2c4dacf2SBarry Smith Options Database: 141*2c4dacf2SBarry Smith + -dm_plex_generate <name> - package to generate mesh, for example, triangle, ctetgen or tetgen 142*2c4dacf2SBarry Smith - -dm_plex_generator <name> - package to generate mesh, for example, triangle, ctetgen or tetgen (deprecated) 143*2c4dacf2SBarry Smith 144d9deefdfSMatthew G. Knepley Level: intermediate 145d9deefdfSMatthew G. Knepley 146d9deefdfSMatthew G. Knepley .seealso: DMPlexCreate(), DMRefine() 147d9deefdfSMatthew G. Knepley @*/ 148d9deefdfSMatthew G. Knepley PetscErrorCode DMPlexGenerate(DM boundary, const char name[], PetscBool interpolate, DM *mesh) 149d9deefdfSMatthew G. Knepley { 150d9deefdfSMatthew G. Knepley PetscInt dim; 151d9deefdfSMatthew G. Knepley char genname[1024]; 1523a074057SBarry Smith PetscBool flg; 153d9deefdfSMatthew G. Knepley PetscErrorCode ierr; 1543a074057SBarry Smith PetscFunctionList fl; 155*2c4dacf2SBarry Smith const char* suggestions; 156d9deefdfSMatthew G. Knepley 157d9deefdfSMatthew G. Knepley PetscFunctionBegin; 158d9deefdfSMatthew G. Knepley PetscValidHeaderSpecific(boundary, DM_CLASSID, 1); 159d9deefdfSMatthew G. Knepley PetscValidLogicalCollectiveBool(boundary, interpolate, 2); 160d9deefdfSMatthew G. Knepley ierr = DMGetDimension(boundary, &dim);CHKERRQ(ierr); 161c5929fdfSBarry Smith ierr = PetscOptionsGetString(((PetscObject) boundary)->options,((PetscObject) boundary)->prefix, "-dm_plex_generator", genname, 1024, &flg);CHKERRQ(ierr); 162d9deefdfSMatthew G. Knepley if (flg) name = genname; 163*2c4dacf2SBarry Smith else { 164*2c4dacf2SBarry Smith ierr = PetscOptionsGetString(((PetscObject) boundary)->options,((PetscObject) boundary)->prefix, "-dm_plex_generate", genname, 1024, &flg);CHKERRQ(ierr); 165*2c4dacf2SBarry Smith if (flg) name = genname; 166*2c4dacf2SBarry Smith } 1673a074057SBarry Smith 1683a074057SBarry Smith fl = DMPlexGenerateList; 169d9deefdfSMatthew G. Knepley if (name) { 1703a074057SBarry Smith while (fl) { 1713a074057SBarry Smith ierr = PetscStrcmp(fl->name,name,&flg);CHKERRQ(ierr); 1723a074057SBarry Smith if (flg) { 173367003a6SStefano Zampini ierr = (*fl->generate)(boundary,interpolate,mesh);CHKERRQ(ierr); 1743a074057SBarry Smith PetscFunctionReturn(0); 175d9deefdfSMatthew G. Knepley } 1763a074057SBarry Smith fl = fl->next; 177d9deefdfSMatthew G. Knepley } 178*2c4dacf2SBarry Smith SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Grid generator %s not registered; you may need to add --download-%s to your ./configure options",name,name); 1793a074057SBarry Smith } else { 1803a074057SBarry Smith while (fl) { 1813a074057SBarry Smith if (boundary->dim == fl->dim) { 182367003a6SStefano Zampini ierr = (*fl->generate)(boundary,interpolate,mesh);CHKERRQ(ierr); 1833a074057SBarry Smith PetscFunctionReturn(0); 1843a074057SBarry Smith } 1853a074057SBarry Smith fl = fl->next; 1863a074057SBarry Smith } 187*2c4dacf2SBarry Smith suggestions = ""; 188*2c4dacf2SBarry Smith if (boundary->dim+1 == 2) suggestions = " You may need to add --download-triangle to your ./configure options"; 189*2c4dacf2SBarry Smith else if (boundary->dim+1 == 3) suggestions = " You may need to add --download-ctetgen or --download-tetgen in your ./configure options"; 190*2c4dacf2SBarry Smith SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"No grid generator of dimension %D registered%s",boundary->dim+1,suggestions); 1913a074057SBarry Smith } 1923a074057SBarry Smith PetscFunctionReturn(0); 1933a074057SBarry Smith } 1943a074057SBarry Smith 1953a074057SBarry Smith /*@C 1963a074057SBarry Smith DMPlexGenerateRegister - Adds a grid generator to DMPlex 1973a074057SBarry Smith 1983a074057SBarry Smith Not Collective 1993a074057SBarry Smith 2003a074057SBarry Smith Input Parameters: 201cd921712SStefano Zampini + name_solver - name of a new user-defined grid generator 2023a074057SBarry Smith . fnc - generator function 2033a074057SBarry Smith . rfnc - refinement function 2043a074057SBarry Smith - dim - dimension of boundary of domain 2053a074057SBarry Smith 2063a074057SBarry Smith Notes: 2073a074057SBarry Smith DMPlexGenerateRegister() may be called multiple times to add several user-defined solvers. 2083a074057SBarry Smith 2093a074057SBarry Smith Sample usage: 2103a074057SBarry Smith .vb 211cd921712SStefano Zampini DMPlexGenerateRegister("my_generator",MyGeneratorCreate,MyGeneratorRefiner,dim); 2123a074057SBarry Smith .ve 2133a074057SBarry Smith 2143a074057SBarry Smith Then, your generator can be chosen with the procedural interface via 215cd921712SStefano Zampini $ DMPlexGenerate(dm,"my_generator",...) 2163a074057SBarry Smith or at runtime via the option 217cd921712SStefano Zampini $ -dm_plex_generator my_generator 2183a074057SBarry Smith 2193a074057SBarry Smith Level: advanced 2203a074057SBarry Smith 221cd921712SStefano Zampini .seealso: DMPlexGenerateRegisterAll(), DMPlexGenerate(), DMPlexGenerateRegisterDestroy() 2223a074057SBarry Smith 2233a074057SBarry Smith @*/ 2243a074057SBarry Smith PetscErrorCode DMPlexGenerateRegister(const char sname[],PetscErrorCode (*fnc)(DM, PetscBool,DM*), PetscErrorCode (*rfnc)(DM, double*,DM*),PetscInt dim) 2253a074057SBarry Smith { 2263a074057SBarry Smith PetscErrorCode ierr; 2273a074057SBarry Smith PetscFunctionList entry; 2283a074057SBarry Smith 2293a074057SBarry Smith PetscFunctionBegin; 2303a074057SBarry Smith ierr = PetscNew(&entry);CHKERRQ(ierr); 2313a074057SBarry Smith ierr = PetscStrallocpy(sname,&entry->name);CHKERRQ(ierr); 2323a074057SBarry Smith entry->generate = fnc; 2333a074057SBarry Smith entry->refine = rfnc; 2343a074057SBarry Smith entry->dim = dim; 2353a074057SBarry Smith entry->next = NULL; 2363a074057SBarry Smith if (!DMPlexGenerateList) DMPlexGenerateList = entry; 2373a074057SBarry Smith else { 2383a074057SBarry Smith PetscFunctionList fl = DMPlexGenerateList; 2393a074057SBarry Smith while (fl->next) fl = fl->next; 2403a074057SBarry Smith fl->next = entry; 2413a074057SBarry Smith } 2423a074057SBarry Smith PetscFunctionReturn(0); 2433a074057SBarry Smith } 2443a074057SBarry Smith 2453a074057SBarry Smith extern PetscBool DMPlexGenerateRegisterAllCalled; 2463a074057SBarry Smith 2473a074057SBarry Smith PetscErrorCode DMPlexGenerateRegisterDestroy(void) 2483a074057SBarry Smith { 2493a074057SBarry Smith PetscFunctionList next,fl; 2503a074057SBarry Smith PetscErrorCode ierr; 2513a074057SBarry Smith 2523a074057SBarry Smith PetscFunctionBegin; 2533a074057SBarry Smith next = fl = DMPlexGenerateList; 2543a074057SBarry Smith while (next) { 2553a074057SBarry Smith next = fl ? fl->next : NULL; 2563a074057SBarry Smith if (fl) {ierr = PetscFree(fl->name);CHKERRQ(ierr);} 2573a074057SBarry Smith ierr = PetscFree(fl);CHKERRQ(ierr); 2583a074057SBarry Smith fl = next; 2593a074057SBarry Smith } 2603a074057SBarry Smith DMPlexGenerateList = NULL; 2613a074057SBarry Smith DMPlexGenerateRegisterAllCalled = PETSC_FALSE; 262d9deefdfSMatthew G. Knepley PetscFunctionReturn(0); 263d9deefdfSMatthew G. Knepley } 264