Actual source code: fieldClassMap.c

  1: #ifdef PETSC_RCS_HEADER
  2: static char vcid[] = "$Id: fieldClassMap.c,v 1.6 2000/01/31 17:42:32 knepley Exp $";
  3: #endif

 5:  #include src/grid/gridimpl.h

  7: /* Logging support */
  8: int CLASS_MAP_COOKIE;

 10: /*@
 11:   FieldClassMapDestroy - Destroys a class map object.

 13:   Collective on FieldClassMap

 15:   Input Parameter:
 16: . map - The map

 18:   Level: beginner

 20: .keywords: class, field class, class map, destroy
 21: .seealso FieldClassMapCreate()
 22: @*/
 23: int FieldClassMapDestroy(FieldClassMap map)
 24: {
 25:   int f, bd;

 30:   if (--map->refct > 0)
 31:     return(0);
 32:   PetscFree(map->fields);
 33:   for(f = 0; f < map->numFields; f++) {
 34:     PetscFree(map->fieldClasses[f]);
 35:   }
 36:   PetscFree(map->fieldClasses);
 37:   PetscFree(map->classes);
 38:   PetscFree(map->classSizes);
 39:   if (map->isReduced == PETSC_TRUE) {
 40:     for(f = 0; f < map->numFields; f++) {
 41:       PetscFree(map->reduceFieldClasses[f]);
 42:     }
 43:     PetscFree(map->reduceFieldClasses);
 44:   }
 45:   PetscFree(map->isClassConstrained);
 46:   PetscFree(map->classSizeDiffs);
 47:   if (map->classMap != PETSC_NULL) {
 48:     for(bd = 0; bd < map->mapSize; bd++) {
 49:       PetscFree(map->classMap[bd]);
 50:     }
 51:     PetscFree(map->classMap);
 52:   }
 53:   (*map->ops->destroy)(map);
 54:   PetscLogObjectDestroy(map);
 55:   PetscHeaderDestroy(map);
 56:   return(0);
 57: }

 59: /*@
 60:   FieldClassMapView - Views a class map object.

 62:   Collective on FieldClassMap

 64:   Input Parameters:
 65: + map    - The map
 66: - viewer - The viewer with which to view the map

 68:   Level: beginner

 70: .keywords: class, field class, class map, view
 71: .seealso: FieldClassMapDestroy(), PetscViewerDrawOpen()
 72: @*/
 73: int FieldClassMapView(FieldClassMap map, PetscViewer viewer)
 74: {

 79:   if (viewer == PETSC_NULL)
 80:     viewer = PETSC_VIEWER_STDOUT_SELF;
 81:   else
 83:   (*map->ops->view)(map, viewer);
 84:   return(0);
 85: }

 87: /*MC
 88:   FieldClassMapRegister - Adds a creation method to the class map package.

 90:   Synopsis:

 92:   FieldClassMapRegister(char *name, char *path, char *func_name, int (*create_func)(FieldClassMap))

 94:   Not Collective

 96:   Input Parameters:
 97: + name        - The name of a new user-defined creation routine
 98: . path        - The path (either absolute or relative) of the library containing this routine
 99: . func_name   - The name of routine to create method context
100: - create_func - The creation routine itself

102:   Notes:
103:   FieldClassMapRegister() may be called multiple times to add several user-defined mapes.

105:   If dynamic libraries are used, then the fourth input argument (create_func) is ignored.

107:   Sample usage:
108: .vb
109:   FieldClassMapRegister("my_map", /home/username/my_lib/lib/libO/solaris/mylib.a, "MyFunc", MyFunc);
110: .ve

112:   Then, your map type can be chosen with the procedural interface via
113: $     FieldClassMapSetType(vec, "my_map")
114:   or at runtime via the option
115: $     -class_map_type my_map

117:   Level: advanced

119:   $PETSC_ARCH and $BOPT occuring in pathname will be replaced with appropriate values.

121: .keywords: class, field class, class map, register
122: .seealso: FieldClassMapRegisterAll(), FieldClassMapRegisterDestroy()
123: M*/
124: int FieldClassMapRegister_Private(const char sname[], const char path[], const char name[],
125:                                   int (*function)(FieldClassMap))
126: {
127:   char fullname[256];
128:   int  ierr;

131:   PetscStrcpy(fullname, path);
132:   PetscStrcat(fullname, ":");
133:   PetscStrcat(fullname, name);
134:   PetscFListAdd(&FieldClassMapList, sname, fullname, (void (*)(void)) function);
135:   return(0);
136: }

138: /*MC
139:   FieldClassMapSerializeRegister - Adds a serialization method to the class map package.

141:   Synopsis:

143:   FieldClassMapSerializeRegister(char *serialize_name, char *path, char *serialize_func_name,
144:                                  int (*serialize_func)(MPI_Comm, FieldClassMap *, PetscViewer, PetscTruth))

146:   Not Collective

148:   Input Parameters:
149: + serialize_name      - The name of a new user-defined serialization routine
150: . path                - The path (either absolute or relative) of the library containing this routine
151: . serialize_func_name - The name of routine to create method context
152: - serialize_func      - The serialization routine itself

154:   Notes:
155:   FieldClassMapSerializeRegister() may be called multiple times to add several user-defined solvers.

157:   If dynamic libraries are used, then the fourth input argument (serialize_func) is ignored.

159:   Sample usage:
160: .vb
161:   FieldClassMapSerializeRegister("my_store", /home/username/my_lib/lib/libO/solaris/mylib.a, "MyStoreFunc", MyStoreFunc);
162: .ve

164:   Then, your serialization can be chosen with the procedural interface via
165: $     FieldClassMapSetSerializeType(map, "my_store")
166:   or at runtime via the option
167: $     -class_map_serialize_type my_store

169:   Level: advanced

171:   $PETSC_ARCH and $BOPT occuring in pathname will be replaced with appropriate values.

173: .keywords: class, field class, class map, register
174: .seealso: FieldClassMapSerializeRegisterAll(), FieldClassMapSerializeRegisterDestroy()
175: M*/
176: int FieldClassMapSerializeRegister_Private(const char sname[], const char path[], const char name[],
177:                                            int (*function)(MPI_Comm, FieldClassMap *, PetscViewer, PetscTruth))
178: {
179:   char fullname[256];
180:   int  ierr;

183:   PetscStrcpy(fullname, path);
184:   PetscStrcat(fullname, ":");
185:   PetscStrcat(fullname, name);
186:   PetscFListAdd(&FieldClassMapSerializeList, sname, fullname, (void (*)(void)) function);
187:   return(0);
188: }

190: /*@
191:   FieldClassMapCreateSubset - This function creates a new class map from an existing
192:   one on a subset of the fields.
193:   
194:   Collective on FieldClassMap

196:   Input Parameter:
197: . map    - The map

199:   Output Parameter:
200: . newMap - The new map

202:   Level: beginner

204: .keywords: class, field class, class map, subset
205: .seealso FieldClassMapCreate()
206: @*/
207: int FieldClassMapCreateSubset(FieldClassMap map, int numFields, int *fields, FieldClassMap *newMap)
208: {
209:   FieldClassMap cm;
210:   int           f, g, bd;
211:   int           ierr;

216:   /* Check for consistency */
217:   for(f = 0; f < numFields; f++) {
218:     for(g = 0; g < map->numFields; g++) {
219:       if (map->fields[g] == fields[f])
220:         break;
221:     }
222:     if (g == map->numFields) {
223:       SETERRQ1(PETSC_ERR_ARG_INCOMP, "Fields not a subset: field %d not in the existing order", fields[f]);
224:     }
225:   }
226:   /* Create new map */
227:   FieldClassMapCreate(map->comm, &cm);
228:   PetscMemcpy(cm->ops, map->ops, sizeof(FieldClassMapOps));
229:   PetscStrallocpy(map->type_name, &cm->type_name);
230:   cm->data = PETSC_NULL;

232:   cm->numFields        = numFields;
233:   PetscMalloc(cm->numFields * sizeof(int), &cm->fields);
234:   PetscMemcpy(cm->fields, fields, cm->numFields * sizeof(int));
235:   cm->numNodes         = map->numNodes;
236:   cm->numGhostNodes    = map->numGhostNodes;
237:   cm->numOverlapNodes  = map->numOverlapNodes;
238:   cm->numClasses       = map->numClasses;
239:   PetscMalloc(cm->numFields * sizeof(int *), &cm->fieldClasses);
240:   for(f = 0; f < cm->numFields; f++) {
241:     for(g = 0; g < map->numFields; g++)
242:       if (cm->fields[f] == map->fields[g])
243:         break;
244:     if (g == map->numFields) {
245:       SETERRQ1(PETSC_ERR_PLIB, "Unable to locate field %d in superset", cm->fields[f]);
246:     }
247:     PetscMalloc(cm->numClasses * sizeof(int), &cm->fieldClasses[f]);
248:     PetscMemcpy(cm->fieldClasses[f], map->fieldClasses[g], cm->numClasses * sizeof(int));
249:   }
250:   PetscMalloc(cm->numOverlapNodes  * sizeof(int), &cm->classes);
251:   PetscMemcpy(cm->classes, map->classes, cm->numOverlapNodes * sizeof(int));
252:   PetscMalloc(cm->numClasses       * sizeof(int), &cm->classSizes);
253:   PetscMemcpy(cm->classSizes, map->classSizes, cm->numClasses * sizeof(int));
254: #if 0
255:   for(nclass = 0; nclass < cm->numClasses; nclass++) {
256:     for(g = 0; g < map->numFields; g++) {
257:       for(f = 0; f < cm->numFields; f++)
258:         if (cm->fields[f] == map->fields[g])
259:           break;
260:       if (f < cm->numFields) continue;
261:       /* Subtract size of missing fields */
262:       if (map->fieldClasses[g][nclass]) {
263:         GridGetFieldComponents(grid, map->fields[g], &comp);
264:         cm->classSizes[nclass] -= comp;
265:       }
266:     }
267:   }
268: #endif
269:   cm->isReduced = map->isReduced;
270:   if (map->isReduced == PETSC_TRUE) {
271:     PetscMalloc(cm->numFields * sizeof(int *), &cm->reduceFieldClasses);
272:     for(f = 0; f < cm->numFields; f++) {
273:       for(g = 0; g < map->numFields; g++) {
274:         if (cm->fields[f] == map->fields[g])
275:           break;
276:       }
277:       if (g == map->numFields) SETERRQ1(PETSC_ERR_PLIB, "Unable to locate field %d in superset", cm->fields[f]);
278:       PetscMalloc(cm->numClasses * sizeof(int), &cm->reduceFieldClasses[f]);
279:       PetscMemcpy(cm->reduceFieldClasses[f], map->reduceFieldClasses[g], cm->numClasses * sizeof(int));
280:     }
281:   }
282:   cm->isConstrained = map->isConstrained;
283:   PetscMalloc(cm->numClasses * sizeof(int), &cm->isClassConstrained);
284:   PetscMemcpy(cm->isClassConstrained, map->isClassConstrained, cm->numClasses * sizeof(int));
285:   PetscMalloc(cm->numClasses * sizeof(int), &cm->classSizeDiffs);
286:   PetscMemcpy(cm->classSizeDiffs, map->classSizeDiffs, cm->numClasses * sizeof(int));
287:   cm->mapSize       = map->mapSize;
288:   cm->numOldClasses = map->numOldClasses;
289:   if (map->classMap != PETSC_NULL) {
290:     PetscMalloc(cm->mapSize * sizeof(int *), &cm->classMap);
291:     for(bd = 0; bd < cm->mapSize; bd++) {
292:       PetscMalloc(cm->numOldClasses * sizeof(int), &cm->classMap[bd]);
293:       PetscMemcpy(cm->classMap[bd], map->classMap[bd], cm->numOldClasses * sizeof(int));
294:     }
295:   }

297:   PetscLogObjectMemory(cm, (cm->numFields + cm->mapSize) * sizeof(int *) + (cm->numFields*(cm->numClasses + 1) +
298:                    cm->numOverlapNodes + cm->numClasses*3 + cm->numOldClasses*cm->mapSize) * sizeof(int));
299:   *newMap = cm;
300:   return(0);
301: }

303: /*@
304:   FieldClassMapDuplicate - Duplicates a class map object.
305:   
306:   Collective on FieldClassMap

308:   Input Parameter:
309: . map    - The map

311:   Output Parameter:
312: . newMap - The new map

314:   Level: beginner

316: .keywords: class, field class, class map, duplicate
317: .seealso FieldClassMapCreate()
318: @*/
319: int FieldClassMapDuplicate(FieldClassMap map, FieldClassMap *newMap)
320: {
321:   FieldClassMap cm;
322:   int           f, bd;
323:   int           ierr;

328:   FieldClassMapCreate(map->comm, &cm);
329:   PetscMemcpy(cm->ops, map->ops, sizeof(FieldClassMapOps));
330:   PetscStrallocpy(map->type_name, &cm->type_name);
331:   cm->data = PETSC_NULL;

333:   cm->numFields        = map->numFields;
334:   PetscMalloc(cm->numFields * sizeof(int), &cm->fields);
335:   PetscMemcpy(cm->fields, map->fields, cm->numFields * sizeof(int));
336:   cm->numNodes         = map->numNodes;
337:   cm->numGhostNodes    = map->numGhostNodes;
338:   cm->numOverlapNodes  = map->numOverlapNodes;
339:   cm->numClasses       = map->numClasses;
340:   PetscMalloc(cm->numFields * sizeof(int *), &cm->fieldClasses);
341:   for(f = 0; f < cm->numFields; f++) {
342:     PetscMalloc(cm->numClasses * sizeof(int), &cm->fieldClasses[f]);
343:     PetscMemcpy(cm->fieldClasses[f], map->fieldClasses[f], cm->numClasses * sizeof(int));
344:   }
345:   PetscMalloc(cm->numOverlapNodes * sizeof(int), &cm->classes);
346:   PetscMemcpy(cm->classes, map->classes, cm->numOverlapNodes * sizeof(int));
347:   PetscMalloc(cm->numClasses      * sizeof(int), &cm->classSizes);
348:   PetscMemcpy(cm->classSizes, map->classSizes, cm->numClasses * sizeof(int));
349:   cm->isReduced        = map->isReduced;
350:   if (map->isReduced == PETSC_TRUE) {
351:     PetscMalloc(cm->numFields * sizeof(int *), &cm->reduceFieldClasses);
352:     for(f = 0; f < cm->numFields; f++) {
353:       PetscMalloc(cm->numClasses * sizeof(int), &cm->reduceFieldClasses[f]);
354:       PetscMemcpy(cm->reduceFieldClasses[f], map->reduceFieldClasses[f], cm->numClasses * sizeof(int));
355:     }
356:   }
357:   cm->isConstrained = map->isConstrained;
358:   PetscMalloc(cm->numClasses * sizeof(int), &cm->isClassConstrained);
359:   PetscMemcpy(cm->isClassConstrained, map->isClassConstrained, cm->numClasses * sizeof(int));
360:   PetscMalloc(cm->numClasses * sizeof(int), &cm->classSizeDiffs);
361:   PetscMemcpy(cm->classSizeDiffs, map->classSizeDiffs, cm->numClasses * sizeof(int));
362:   cm->mapSize          = map->mapSize;
363:   cm->numOldClasses    = map->numOldClasses;
364:   if (map->classMap != PETSC_NULL) {
365:     PetscMalloc(cm->mapSize * sizeof(int *), &cm->classMap);
366:     for(bd = 0; bd < cm->mapSize; bd++) {
367:       PetscMalloc(cm->numOldClasses * sizeof(int), &cm->classMap[bd]);
368:       PetscMemcpy(cm->classMap[bd], map->classMap[bd], cm->numOldClasses * sizeof(int));
369:     }
370:   }

372:   PetscLogObjectMemory(cm, (cm->numFields + cm->mapSize) * sizeof(int *) + (cm->numFields*(cm->numClasses + 1) +
373:                        cm->numOverlapNodes + cm->numClasses*3 + cm->numOldClasses*cm->mapSize) * sizeof(int));
374:   *newMap = cm;
375:   return(0);
376: }

378: /*@
379:   FieldClassMapConstrain - This function creates a new class map from an existing one by implementing
380:   constraints and boundary conditions registered with the grid.

382:   Collective on FieldClassMap

384:   Input Parameters:
385: + map      - The map
386: . grid     - The grid
387: . useBC    - The flag for reducing boundary conditions
388: - useConst - The flag for using constraints

390:   Output Parameter:
391: . newMap   - The constrained map

393:   Level: advanced

395: .keywords: class, field class, class map, constraint
396: .seealso FieldClassMapCreate()
397: @*/
398: int FieldClassMapConstrain(FieldClassMap map, Grid grid, PetscTruth useBC, PetscTruth useConst, FieldClassMap *newMap)
399: {

405:   (*map->ops->constrain)(map, grid, useBC, useConst, newMap);
406:   return(0);
407: }

409: /*@
410:   FieldClassMapReduce - This function creates a new class map from an existing one which
411:   lies in the space of variables reduced by boundary conditions.

413:   Collective on FieldClassMap

415:   Input Parameters:
416: + map    - The map
417: - grid   - The grid

419:   Output Parameter:
420: . newMap - The reduction map

422:   Note:
423:   This function is normally used to create operators which map elements from the space of
424:   boundary values to the calculation space. Thus you can construct a matrix to add boundary
425:   conditions to the rhs.

427:   Level: advanced

429: .keywords: class, field class, class map, reduction
430: .seealso: FieldClassMapCreate(), FieldClassMapConstrain()
431: @*/
432: int FieldClassMapReduce(FieldClassMap map, Grid grid, FieldClassMap *newMap)
433: {

439:   (*map->ops->reduce)(map, grid, newMap);
440:   return(0);
441: }

443: /*@
444:   FieldClassMapIsConstrained - This function determines whether or not the map is constrained.

446:   Not collective

448:   Input Parameter:
449: . cm            - The class map

451:   Output Parameter:
452: . isConstrained - The constraint flag

454:   Level: intermediate

456: .keywords: class, field class, class map
457: .seealso: FieldClassMapCreate(), FieldClassMapConstrain()
458: @*/
459: int FieldClassMapIsConstrained(FieldClassMap cm, PetscTruth *isConstrained) {
463:   *isConstrained = cm->isConstrained;
464:   return(0);
465: }

467: /*@
468:   FieldClassMapIsDefined - This function determines whether a field is defined on
469:   nodes of a given class, or equivalently whether the field is a member of the class.

471:   Not collective

473:   Input Parameters:
474: + map     - The map
475: . field   - The field
476: - nclass  - The node class

478:   Output Parameter:
479: . defined - The flag for class membership

481:   Level: intermediate

483: .keywords: class, field class, class map
484: .seealso: FieldClassMapCreate(), FieldClassMapConstrain()
485: @*/
486: int FieldClassMapIsDefined(FieldClassMap map, int field, int nclass, PetscTruth *defined)
487: {
488:   int   numFields    = map->numFields;
489:   int   numClasses   = map->numClasses;
490:   int  *fields       = map->fields;
491:   int **fieldClasses = map->fieldClasses;
492:   int   f;

497:   for(f = 0; f < numFields; f++) {
498:     if (field == fields[f]) break;
499:   }
500:   if (f == numFields) SETERRQ1(PETSC_ERR_ARG_WRONG, "Field %d not present in grid", field);
501:   if ((nclass < 0) || (nclass >= numClasses)) {
502:     SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE, "Invalid class %d should be in [0,%d)", nclass, numClasses);
503:   }
504:   if (fieldClasses[f][nclass]) {
505:     *defined = PETSC_TRUE;
506:   } else {
507:     *defined = PETSC_FALSE;
508:   }
509:   return(0);
510: }

512: /*@
513:   FieldClassMapGetNumFields - This function returns the number of fields in the map.

515:   Not collective

517:   Input Parameter:
518: . cm        - The class map

520:   Output Parameter:
521: . numFields - The number of fields in the map

523:   Level: intermediate

525: .keywords: class, class map, field
526: .seealso: FieldClassMapGetField(), FieldClassMapCreate()
527: @*/
528: int FieldClassMapGetNumFields(FieldClassMap cm, int *numFields) {
532:   *numFields = cm->numFields;
533:   return(0);
534: }

536: /*@
537:   FieldClassMapGetField - This function returns the canonical field number of a field index in the map.

539:   Not collective

541:   Input Parameters:
542: + cm    - The class map
543: - f     - The field index in the map

545:   Output Parameter:
546: . field - The canonical field number

548:   Level: intermediate

550: .keywords: class, class map, field
551: .seealso: FieldClassMapGetNumFields(), FieldClassMapCreate()
552: @*/
553: int FieldClassMapGetField(FieldClassMap cm, int f, int *field) {
557:   if ((f < 0) || (f >= cm->numFields)) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE, "Field index %d must be in [0,%d)", f, cm->numFields);
558:   *field = cm->fields[f];
559:   return(0);
560: }

562: /*@
563:   FieldClassMapGetNodeClass - This function returns the class for the given node.

565:   Not collective

567:   Input Parameters:
568: + map    - The map
569: - node   - The node

571:   Output Parameter:
572: . nclass - The node class

574:   Level: intermediate

576: .keywords: class, class map
577: .seealso: FieldClassMapCreate(), FieldClassMapConstrain()
578: @*/
579: int FieldClassMapGetNodeClass(FieldClassMap map, int node, int *nclass)
580: {
581:   int  numOverlapNodes = map->numOverlapNodes;
582:   int *classes         = map->classes;

587:   if ((node < 0) || (node >= numOverlapNodes)) {
588:     SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE, "Invalid node %d should be in [0,%d)", node, numOverlapNodes);
589:   }
590:   *nclass = classes[node];
591:   return(0);
592: }