Actual source code: meshcreate.c

  1: #define PETSCDM_DLL
  2: #include <private/meshimpl.h>    /*I   "petscdmmesh.h"   I*/
  3: #include <petscdmda.h>

  7: PetscErrorCode  DMSetFromOptions_Mesh(DM dm)
  8: {
  9:   //DM_Mesh       *mesh = (DM_Mesh *) dm->data;
 10:   char           typeName[256];
 11:   PetscBool      flg;

 16:   PetscOptionsBegin(((PetscObject) dm)->comm, ((PetscObject) dm)->prefix, "DMMesh Options", "DMMesh");
 17:     /* Handle DMMesh refinement */
 18:     /* Handle associated vectors */
 19:     if (!VecRegisterAllCalled) {VecRegisterAll(PETSC_NULL);}
 20:     PetscOptionsList("-dm_vec_type", "Vector type used for created vectors", "DMSetVecType", VecList, dm->vectype, typeName, 256, &flg);
 21:     if (flg) {
 22:       DMSetVecType(dm, typeName);
 23:     }
 24:     /* Handle viewing */
 25:     PetscOptionsBool("-mesh_view_vtk", "Output mesh in VTK format", "DMView", PETSC_FALSE, &flg, PETSC_NULL);
 26:     if (flg) {
 27:       PetscViewer viewer;

 29:       PetscViewerCreate(((PetscObject) dm)->comm, &viewer);
 30:       PetscViewerSetType(viewer, PETSCVIEWERASCII);
 31:       PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_VTK);
 32:       PetscViewerFileSetName(viewer, "mesh.vtk");
 33:       DMView(dm, viewer);
 34:       PetscViewerDestroy(&viewer);
 35:     }
 36:     PetscOptionsBool("-mesh_view", "Exhaustive mesh description", "DMView", PETSC_FALSE, &flg, PETSC_NULL);
 37:     if (flg) {
 38:       ALE::Obj<PETSC_MESH_TYPE> mesh;

 40:       DMMeshGetMesh(dm, mesh);
 41:       mesh->view("Mesh");
 42:     }
 43:     PetscOptionsBool("-mesh_view_simple", "Simple mesh description", "DMView", PETSC_FALSE, &flg, PETSC_NULL);
 44:     if (flg) {
 45:       DMView(dm, PETSC_VIEWER_STDOUT_WORLD);
 46:     }
 47:     /* process any options handlers added with PetscObjectAddOptionsHandler() */
 48:     PetscObjectProcessOptionsHandlers((PetscObject) dm);
 49:   PetscOptionsEnd();
 50:   return(0);
 51: }

 53: #include <sieve/DMBuilder.hh>

 57: PetscErrorCode DMMeshCreateBoxMesh(MPI_Comm comm, PetscInt dim, PetscBool interpolate, DM *dm) {
 58:   PetscInt       debug = 0;

 62:   ALE::DMBuilder::createBoxMesh(comm, dim, false, interpolate, debug, dm);
 63:   return(0);
 64: }

 66: /* External function declarations here */

 84: PetscErrorCode DMConvert_DA_Mesh(DM dm, const DMType newtype, DM *dmNew)
 85: {
 86:   typedef ALE::Mesh<PetscInt,PetscScalar> FlexMesh;
 87:   DM             cda;
 88:   DMDALocalInfo  info;
 89:   Vec            coordinates;
 90:   PetscScalar   *coords;
 91:   PetscInt       M;

 95:   DMDAGetInfo(dm, 0, &M, 0,0,0,0,0,0,0,0,0,0,0);
 96:   DMDAGetLocalInfo(dm, &info);
 97:   if (info.dim > 1) SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Currently, only 1D DMDAs can be converted to DMMeshes.");
 98:   if (info.sw  > 1) SETERRQ(((PetscObject) dm)->comm, PETSC_ERR_SUP, "Currently, only DMDAs with unti stencil width can be converted to DMMeshes.");
 99:   DMDAGetCoordinateDA(dm, &cda);
100:   DMDAGetGhostedCoordinates(dm, &coordinates);
101:   DMDAVecGetArray(dm, coordinates, &coords);
102:   //VecGetArray(coordinates, &coords);

104:   DMMeshCreate(((PetscObject) dm)->comm, dmNew);
105:   ALE::Obj<PETSC_MESH_TYPE>              mesh  = new PETSC_MESH_TYPE(((PetscObject) dm)->comm, info.dim, 0);
106:   ALE::Obj<PETSC_MESH_TYPE::sieve_type>  sieve = new PETSC_MESH_TYPE::sieve_type(((PetscObject) dm)->comm, 0);
107:   ALE::Obj<FlexMesh>                     m     = new FlexMesh(((PetscObject) dm)->comm, info.dim, 0);
108:   ALE::Obj<FlexMesh::sieve_type>         s     = new FlexMesh::sieve_type(((PetscObject) dm)->comm, 0);
109:   PETSC_MESH_TYPE::renumbering_type      renumbering;

111:   m->setSieve(s);
112:   {
113:     /* WE MUST PUT IN HALO VERTICES, BUT MARK THEM SO WE CAN AVOID THEM WHEN ITERATING */
114:     /* M edges if its periodic */
115:     /* Edges are numbered     0..M-2
116:        Vertices are numbered: M-1..2M-2

118:        For vertex names, we just add M-1
119:        Edge i connects vertex (i+M-1) to vertex (i+M), do we add info.xs
120:     */
121:     const PetscInt        numGlobalEdges = M-1;
122:     const PetscInt        numVertices    = info.gxm;
123:     /* const PetscInt        numEdges       = numVertices-1; Do not include edge attached to ghost vertex */
124:     FlexMesh::point_type *vertices       = new FlexMesh::point_type[numVertices];
125:     const ALE::Obj<FlexMesh::label_type>& markers = m->createLabel("marker");

127:     /* Create vertices */
128:     for(int v = info.gxs; v < info.gxs+info.gxm; ++v) {
129:       vertices[v-info.gxs] = FlexMesh::point_type(v+numGlobalEdges);
130:     }
131:     /* Create edges */
132:     int order = 0;

134:     for(int e = 0; e < numVertices-1; ++e) {
135:       FlexMesh::point_type edge(info.gxs+e);

137:       s->addArrow(vertices[e],                 edge, order++);
138:       s->addArrow(vertices[(e+1)%numVertices], edge, order++); /* This must be corrected for periodicity */
139:     }
140:     for(int e = 0; e < numVertices-1; ++e) {
141:       FlexMesh::point_type edge(info.xs+e);

143:       s->addArrow(vertices[e],                 edge, order++);
144:       s->addArrow(vertices[(e+1)%numVertices], edge, order++);
145:     }
146:     if (info.gxs+info.gxm > info.xs+info.xm) {
147:       FlexMesh::point_type edge(info.xs+info.xm-1);

149:       s->addArrow(vertices[numVertices-1],     edge, order++);
150:     }
151:     m->stratify();
152:     /* Mark domain endpoints -- only do this if its not periodic */
153:     if (vertices[0] == M-1) {
154:       m->setValue(markers, vertices[0], 1);
155:     }
156:     if (vertices[numVertices-1] == 2*M-2) {
157:       m->setValue(markers, vertices[numVertices-1], 2);
158:     }
159:     /* Mark ghost nodes */
160:     for(int v = info.gxs; v < info.xs; ++v) {
161:       m->setValue(markers, vertices[v-info.gxs], 3);
162:     }
163:     for(int v = info.xs+info.xm; v < info.gxs+info.gxm; ++v) {
164:       m->setValue(markers, vertices[v-info.gxs], 4);
165:     }
166:     delete [] vertices;
167:     // vertexNumber - (numGlobalEdges - numVertices)
168:     ALE::SieveBuilder<FlexMesh>::buildCoordinates(m, info.dim, coords, numGlobalEdges);
169:   }
170:   mesh->setSieve(sieve);
171:   m->view("Flexible Mesh");
172:   ALE::ISieveConverter::convertMesh(*m, *mesh, renumbering, true);
173:   {
174:     typedef PETSC_MESH_TYPE::point_type point_type;
175:     PETSc::Log::Event("CreateOverlap").begin();
176:     ALE::Obj<PETSC_MESH_TYPE::send_overlap_type> sendParallelMeshOverlap = mesh->getSendOverlap();
177:     ALE::Obj<PETSC_MESH_TYPE::recv_overlap_type> recvParallelMeshOverlap = mesh->getRecvOverlap();
178:     //   Can I figure this out in a nicer way?
179:     ALE::SetFromMap<std::map<point_type,point_type> > globalPoints(renumbering);

181:     ALE::OverlapBuilder<>::constructOverlap(globalPoints, renumbering, sendParallelMeshOverlap, recvParallelMeshOverlap);
182:     sendParallelMeshOverlap->view("Send Overlap");
183:     recvParallelMeshOverlap->view("Recieve Overlap");
184:     mesh->setCalculatedOverlap(true);
185:     PETSc::Log::Event("CreateOverlap").end();
186:   }
187:   VecRestoreArray(coordinates, &coords);
188:   DMMeshSetMesh(*dmNew, mesh);
189:   return(0);
190: }

194: PetscErrorCode DMCreate_Mesh(DM dm)
195: {
196:   DM_Mesh       *mesh;

201:   PetscNewLog(dm, DM_Mesh, &mesh);
202:   dm->data = mesh;

204:   new(&mesh->m) ALE::Obj<PETSC_MESH_TYPE>(PETSC_NULL);

206:   mesh->globalScatter = PETSC_NULL;
207:   mesh->lf            = PETSC_NULL;
208:   mesh->lj            = PETSC_NULL;

210:   PetscStrallocpy(VECSTANDARD, &dm->vectype);
211:   dm->ops->view               = DMView_Mesh;
212:   dm->ops->setfromoptions     = DMSetFromOptions_Mesh;
213:   dm->ops->setup              = 0;
214:   dm->ops->createglobalvector = DMCreateGlobalVector_Mesh;
215:   dm->ops->createlocalvector  = DMCreateLocalVector_Mesh;
216:   dm->ops->createlocaltoglobalmapping      = DMCreateLocalToGlobalMapping_Mesh;
217:   dm->ops->createlocaltoglobalmappingblock = 0;

219:   dm->ops->getcoloring        = 0;
220:   dm->ops->getmatrix          = DMGetMatrix_Mesh;
221:   dm->ops->getinterpolation   = DMGetInterpolation_Mesh;
222:   dm->ops->getaggregates      = 0;
223:   dm->ops->getinjection       = 0;

225:   dm->ops->refine             = DMRefine_Mesh;
226:   dm->ops->coarsen            = 0;
227:   dm->ops->refinehierarchy    = 0;
228:   dm->ops->coarsenhierarchy   = DMCoarsenHierarchy_Mesh;

230:   dm->ops->forminitialguess   = 0;
231:   dm->ops->formfunction       = 0;

233:   dm->ops->globaltolocalbegin = DMGlobalToLocalBegin_Mesh;
234:   dm->ops->globaltolocalend   = DMGlobalToLocalEnd_Mesh;
235:   dm->ops->localtoglobalbegin = DMLocalToGlobalBegin_Mesh;
236:   dm->ops->localtoglobalend   = DMLocalToGlobalEnd_Mesh;

238:   dm->ops->initialguess       = 0;
239:   dm->ops->function           = 0;
240:   dm->ops->functionj          = 0;
241:   dm->ops->jacobian           = 0;

243:   dm->ops->destroy            = DMDestroy_Mesh;

245:   PetscObjectComposeFunction((PetscObject) dm, "DMConvert_da_mesh_C", "DMConvert_DA_Mesh", (void (*)(void)) DMConvert_DA_Mesh);
246:   return(0);
247: }

252: /*@
253:   DMMeshCreate - Creates a DMMesh object.

255:   Collective on MPI_Comm

257:   Input Parameter:
258: . comm - The communicator for the DMMesh object

260:   Output Parameter:
261: . mesh  - The DMMesh object

263:   Level: beginner

265: .keywords: DMMesh, create
266: @*/
267: PetscErrorCode  DMMeshCreate(MPI_Comm comm, DM *mesh)
268: {

273:   DMCreate(comm, mesh);
274:   DMSetType(*mesh, DMMESH);
275:   return(0);
276: }