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: }