Actual source code: gridDB.c
1: #ifdef PETSC_RCS_HEADER
2: static char vcid[] = "$Id: gridDB.c,v 1.4 2000/07/16 05:40:27 knepley Exp $";
3: #endif
5: #include src/grid/gridimpl.h
7: /*-------------------------------------------------- Field Functions ------------------------------------------------*/
8: /*@C
9: GridAddField - This function defines a field on the grid.
11: Not collective
13: Input Parameters:
14: + grid - The grid
15: . name - The field name
16: . discType - The DiscretizationType for the field
17: - numComp - The nubmer of components in the field
19: Output Parameter:
20: . field - The canonical field number
22: Level: intermediate
24: .keywords: grid, field,
25: .seealso: GridSetFieldName()
26: @*/
27: int GridAddField(Grid grid, const char name[], DiscretizationType discType, int numComp, int *field)
28: {
29: Field *tempFields;
30: int ierr;
34: if (numComp <= 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Invalid number of field components %d", numComp);
35: while (grid->numFields >= grid->maxFields) {
36: PetscMalloc(grid->maxFields*2 * sizeof(Field), &tempFields);
37: PetscLogObjectMemory(grid, grid->maxFields * sizeof(Field));
38: PetscMemcpy(tempFields, grid->fields, grid->maxFields * sizeof(Field));
39: PetscFree(grid->fields);
40: grid->fields = tempFields;
41: grid->maxFields *= 2;
42: }
43: if (field != PETSC_NULL) {
45: *field = grid->numFields;
46: }
48: PetscStrallocpy(name, &grid->fields[grid->numFields].name);
49: PetscStrallocpy(discType, &grid->fields[grid->numFields].discType);
50: grid->fields[grid->numFields].numComp = numComp;
51: grid->fields[grid->numFields].isConstrained = PETSC_FALSE;
52: grid->fields[grid->numFields].constraintCompDiff = 0;
53: grid->fields[grid->numFields].isActive = PETSC_FALSE;
54: DiscretizationCreate(grid->comm, &grid->fields[grid->numFields].disc);
55: DiscretizationSetNumComponents(grid->fields[grid->numFields].disc, numComp);
56: DiscretizationSetField(grid->fields[grid->numFields].disc, grid->numFields);
57: DiscretizationSetType(grid->fields[grid->numFields].disc, discType);
58: DiscretizationSetFromOptions(grid->fields[grid->numFields].disc);
59: grid->numFields++;
60: return(0);
61: }
63: /*@C
64: GridGetNumFields - This function gets the number of fields in the grid.
66: Not collective
68: Input Parameter:
69: . grid - The grid
71: Output Parameter:
72: . num - The number of fields
74: Level: intermediate
76: .keywords: grid, field,
77: .seealso: GridSetFieldName()
78: @*/
79: int GridGetNumFields(Grid grid, int *num)
80: {
84: *num = grid->numFields;
85: return(0);
86: }
88: /*@C
89: GridGetFieldName - This function gets the name of a particular field.
91: Not collective
93: Input Parameters:
94: + grid - The grid
95: - field - The field to name
97: Output Parameter:
98: . name - The name string
100: Level: intermediate
102: .keywords: grid, field, name
103: .seealso: GridSetFieldName()
104: @*/
105: int GridGetFieldName(Grid grid, int field, char **name)
106: {
112: GridValidField(grid, field);
113: if (grid->fields[field].name == PETSC_NULL) {
114: *name = PETSC_NULL;
115: } else {
116: PetscStrallocpy(grid->fields[field].name, name);
117: }
118: return(0);
119: }
121: /*@C
122: GridSetFieldName - This function sets the name of a particular field.
124: Collective on Grid
126: Input Parameters:
127: + grid - The grid
128: . field - The field to name
129: - name - The name string
131: Level: intermediate
133: .keywords: grid, field, name
134: .seealso: GridGetFieldName()
135: @*/
136: int GridSetFieldName(Grid grid, int field, char *name)
137: {
142: GridValidField(grid, field);
144: PetscStrfree(grid->fields[field].name);
145: PetscStrallocpy(name, &grid->fields[field].name);
146: return(0);
147: }
149: /*@C
150: GridGetFieldComponents - This function gets the number of components in a field.
152: Not collective
154: Input Parameters
155: + grid - The grid
156: - field - The field
158: Output Parameter:
159: . comp - The number of components in the field
161: Level: intermediate
163: .keywords: grid, field, component
164: .seealso: GridGetFieldDiscType()
165: @*/
166: int GridGetFieldComponents(Grid grid, int field, int *comp)
167: {
170: GridValidField(grid, field);
172: *comp = grid->fields[field].numComp;
173: return(0);
174: }
176: /*@C
177: GridGetFieldDisc - This function gets the discretization for a field.
179: Not collective
181: Input Parameters:
182: + grid - The grid
183: - field - The field
185: Output Parameter:
186: . disc - The discretization
188: Level: intermediate
190: .keywords: grid, field, discretization
191: .seealso: GridGetFieldComponents()
192: @*/
193: int GridGetFieldDisc(Grid grid, int field, Discretization *disc)
194: {
198: GridValidField(grid, field);
199: *disc = grid->fields[field].disc;
200: return(0);
201: }
203: /*@C
204: GridGetNumActiveFields - This function gets the number of fields participating in the calculation.
206: Not collective
208: Input Parameter:
209: . grid - The grid
211: Output Parameter:
212: . num - The number of active fields
214: Level: intermediate
216: .keywords: grid, field, active
217: .seealso: GridSetFieldName()
218: @*/
219: int GridGetNumActiveFields(Grid grid, int *num)
220: {
224: *num = grid->numActiveFields;
225: return(0);
226: }
228: /*@C
229: GridGetActiveField - This function gets the canonical field number for a certain active field.
231: Not collective
233: Input Parameters:
234: + grid - The grid
235: - n - The nth active field
237: Output Parameter:
238: . field - The field
240: Level: intermediate
242: .keywords: grid, field, active
243: .seealso: GridSetFieldName()
244: @*/
245: int GridGetActiveField(Grid grid, int n, int *field)
246: {
250: if ((n < 0) || (n >= grid->numActiveFields)) {
251: SETERRQ2(PETSC_ERR_ARG_WRONG, "Invalid active field number %d should be in [0,%d)", n, grid->numActiveFields);
252: }
253: *field = grid->defaultFields[n];
254: return(0);
255: }
257: /*@C
258: GridSetActiveField - This function makes one field active for a particular grid.
260: Collective on Grid
262: Input Parameters:
263: + grid - The grid
264: - field - The field to make active
266: Level: intermediate
268: .keywords: grid, active, field
269: .seealso: GridAddActiveField()
270: @*/
271: int GridSetActiveField(Grid grid, int field)
272: {
273: int fieldIndex;
278: GridValidField(grid, field);
279: grid->numActiveFields = 0;
280: for(fieldIndex = 0; fieldIndex < grid->numFields; fieldIndex++) grid->fields[fieldIndex].isActive = PETSC_FALSE;
281: GridAddActiveField(grid, field);
282: return(0);
283: }
285: /*@C
286: GridAddActiveField - This function makes another field active for a particular grid.
288: Collective on Grid
290: Input Parameters:
291: + grid - The grid
292: - field - The field to make active
294: Level: intermediate
296: .keywords: grid, active, field
297: .seealso: GridSetActiveField()
298: @*/
299: int GridAddActiveField(Grid grid, int field)
300: {
301: int *tempFields;
302: int ierr;
306: GridValidField(grid, field);
307: /* Setup assembly variables */
308: while (grid->numActiveFields >= grid->maxActiveFields) {
309: PetscMalloc(grid->maxActiveFields*2 * sizeof(int), &tempFields);
310: PetscLogObjectMemory(grid, grid->maxActiveFields * sizeof(int));
311: PetscMemcpy(tempFields, grid->defaultFields, grid->maxActiveFields * sizeof(int));
312: PetscFree(grid->defaultFields);
313: grid->defaultFields = tempFields;
314: grid->maxActiveFields *= 2;
315: }
316: if (grid->fields[field].isActive == PETSC_FALSE) grid->defaultFields[grid->numActiveFields++] = field;
317: grid->fields[field].isActive = PETSC_TRUE;
318: grid->setupcalled = PETSC_FALSE;
319: grid->bdSetupCalled = PETSC_FALSE;
320: return(0);
321: }
323: /*------------------------------------------------ Variable Functions -----------------------------------------------*/
324: /*@C GridGetNumVars
325: This function gets the number of variables in the grid.
327: Not collective
329: Input Parameter:
330: . grid - The grid
332: Output Parameters:
333: + locNum - The number of local variables
334: . num - The number of variables
335: . locConstNum - The number of local constrained variables
336: - constNum - The number of constrained variables
338: Level: intermediate
340: .keywords grid, field,
341: .seealso GridSetFieldName
342: @*/
343: int GridGetNumVars(Grid grid, int *locNum, int *num, int *locConstNum, int *constNum)
344: {
349: if (grid->order == PETSC_NULL) {
350: GridSetUp(grid);
351: }
352: if (locNum != PETSC_NULL) {
354: *locNum = grid->order->numLocVars;
355: }
356: if (num != PETSC_NULL) {
358: *num = grid->order->numVars;
359: }
360: if (grid->isConstrained == PETSC_TRUE) {
361: if ((grid->constraintOrder == PETSC_NULL) && ((locConstNum != PETSC_NULL) || (constNum != PETSC_NULL))) {
362: SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Constraints are not yet setup");
363: }
364: if (locConstNum != PETSC_NULL) {
366: *locConstNum = grid->constraintOrder->numLocVars;
367: }
368: if (constNum != PETSC_NULL) {
370: *constNum = grid->constraintOrder->numVars;
371: }
372: }
373: return(0);
374: }
376: /*-------------------------------------------------- Rhs Functions --------------------------------------------------*/
377: /*@
378: GridGetNumNonlinearOperators - Returns the number of nonlinear operators for the problem defined on the grid.
380: Not collective
382: Input Parameter:
383: . grid - The grid
385: Output Parameter:
386: . numOps - The number of operators
388: Level: intermediate
390: .keywords: grid, operator, nonlinear
391: .seealso: GridGetNonlinearOperatorStart()
392: @*/
393: int GridGetNumNonlinearOperators(Grid grid, int *numOps)
394: {
395: int op;
400: *numOps = 0;
401: for(op = 0; op < grid->numRhsOps; op++) {
402: if (grid->rhsOps[op].nonlinearOp != PETSC_NULL) *numOps += 1;
403: }
404: return(0);
405: }
407: /*@
408: GridGetNonlinearOperatorStart - Retrieves information about the first nonlinear
409: operator for the problem defined on the grid.
411: Not collective
413: Input Parameter:
414: . grid - The grid
416: Output Parameters:
417: + op - The operator
418: . field - The shape function field
419: . alpha - The multiplier of this operator
420: - isALE - The flag for ALE operators
422: Level: intermediate
424: .keywords: grid, operator, nonlinear
425: .seealso: GridGetNonlinearOperatorNext(), GridGetNumNonlinearOperators()
426: @*/
427: int GridGetNonlinearOperatorStart(Grid grid, NonlinearOperator *op, int *field, PetscScalar *alpha, PetscTruth *isALE)
428: {
433: grid->activeNonlinearOp = -1;
434: GridGetNonlinearOperatorNext(grid, op, field, alpha, isALE);
435: return(0);
436: }
438: /*@
439: GridGetNonlinearOperatorNext - Retrieves information about the next nonlinear
440: operator for the problem defined on the grid.
442: Not collective
444: Input Parameter:
445: . grid - The grid
447: Output Parameters:
448: + op - The operator
449: . field - The shape function field
450: . alpha - The multiplier of this operator
451: - isALE - The flag for ALE operators
453: Level: intermediate
455: .keywords: grid, operator, nonlinear
456: .seealso: GridNonlinearGetOperatorStart(), GridGetNumNonlinearOperators()
457: @*/
458: int GridGetNonlinearOperatorNext(Grid grid, NonlinearOperator *op, int *field, PetscScalar *alpha, PetscTruth *isALE)
459: {
462: grid->activeNonlinearOp++;
463: while((grid->rhsOps[grid->activeNonlinearOp].nonlinearOp == PETSC_NULL) && (grid->activeNonlinearOp < grid->numRhsOps)) {
464: grid->activeNonlinearOp++;
465: }
466: if (grid->activeNonlinearOp >= grid->numRhsOps) {
467: if (op != PETSC_NULL) *op = PETSC_NULL;
468: if (field != PETSC_NULL) *field = -1;
469: if (alpha != PETSC_NULL) *alpha = 0.0;
470: if (isALE != PETSC_NULL) *isALE = PETSC_FALSE;
471: grid->activeNonlinearOp = -1;
472: return(0);
473: }
474: if (op != PETSC_NULL) {
476: *op = grid->rhsOps[grid->activeNonlinearOp].nonlinearOp;
477: }
478: if (field != PETSC_NULL) {
480: *field = grid->rhsOps[grid->activeNonlinearOp].field;
481: }
482: if (alpha != PETSC_NULL) {
484: *alpha = grid->rhsOps[grid->activeNonlinearOp].alpha;
485: }
486: if (isALE != PETSC_NULL) {
488: *isALE = grid->rhsOps[grid->activeNonlinearOp].isALE;
489: }
490: return(0);
491: }
493: /*@C GridAddRhsFunction
494: This function adds the point function to use on the rhs for the given field.
496: Collective on Grid
498: Input Parameters:
499: + grid - The grid
500: . field - The field
501: . func - The point function
502: - alpha - A scalar multiplier
504: Level: beginner
506: .keywords active field
507: .seealso GridSetMatOperator, GridSetRhsOperator
508: @*/
509: int GridAddRhsFunction(Grid grid, int field, PointFunction f, PetscScalar alpha)
510: {
511: GridFunc *tempFuncs;
512: int ierr;
516: GridValidField(grid, field);
517: while (grid->numRhsFuncs >= grid->maxRhsFuncs) {
518: PetscMalloc(grid->maxRhsFuncs*2 * sizeof(GridOp), &tempFuncs);
519: PetscLogObjectMemory(grid, grid->maxRhsFuncs * sizeof(GridOp));
520: PetscMemcpy(tempFuncs, grid->rhsFuncs, grid->maxRhsFuncs * sizeof(GridOp));
521: PetscFree(grid->rhsFuncs);
522: grid->rhsFuncs = tempFuncs;
523: grid->maxRhsFuncs *= 2;
524: }
525: grid->rhsFuncs[grid->numRhsFuncs].func = f;
526: grid->rhsFuncs[grid->numRhsFuncs].field = field;
527: grid->rhsFuncs[grid->numRhsFuncs].alpha = alpha;
528: grid->numRhsFuncs++;
529: return(0);
530: }
532: /*@C GridAddRhsNonlinearOperator
533: This function add the nonlinear operator to use on the Rhs for the given field.
535: Collective on Grid
537: Input Parameters:
538: + grid - The grid
539: . field - The field
540: . f - The function defining the nonlinear operator
541: . alpha - A scalar multiplier
542: - isALE - A flag for ALE operators
544: Level: beginner
546: .keywords active field
547: .seealso GridSetRhsOperator, GridAddRhsOperator
548: @*/
549: int GridAddRhsNonlinearOperator(Grid grid, int field, NonlinearOperator f, PetscScalar alpha, PetscTruth isALE)
550: {
551: GridOp *tempOps;
552: int ierr;
556: GridValidField(grid, field);
557: while (grid->numRhsOps >= grid->maxRhsOps) {
558: PetscMalloc(grid->maxRhsOps*2 * sizeof(GridOp), &tempOps);
559: PetscLogObjectMemory(grid, grid->maxRhsOps * sizeof(GridOp));
560: PetscMemcpy(tempOps, grid->rhsOps, grid->maxRhsOps * sizeof(GridOp));
561: PetscFree(grid->rhsOps);
562: grid->rhsOps = tempOps;
563: grid->maxRhsOps *= 2;
564: }
565: grid->rhsOps[grid->numRhsOps].nonlinearOp = f;
566: grid->rhsOps[grid->numRhsOps].field = field;
567: grid->rhsOps[grid->numRhsOps].alpha = alpha;
568: grid->rhsOps[grid->numRhsOps].isALE = isALE;
569: grid->rhsOps[grid->numRhsOps].op = -1;
570: grid->numRhsOps++;
571: if (isALE == PETSC_TRUE) grid->ALEActive = PETSC_TRUE;
572: return(0);
573: }
575: /*@C GridSetRhsOperator
576: This function sets the operator to use on the Rhs for the given field.
578: Collective on Grid
580: Input Parameters:
581: + grid - The grid
582: . sfield - The field for shape functions
583: . tfield - The field for test functions
584: . op - The operator
585: . alpha - A scalar multiple for the operator
586: - isALE - A flag for ALE operators
588: Output Parameter:
589: . index - [Optional] A unique indentifier for the operator
591: Level: beginner
593: .keywords active field
594: .seealso GridAddRhsOperator, GridAddMatOperator, GridSetRhsFunction
595: @*/
596: int GridSetRhsOperator(Grid grid, int sField, int tField, int op, PetscScalar alpha, PetscTruth isALE, int *index)
597: {
602: grid->numRhsOps = 0;
603: GridAddRhsOperator(grid, sField, tField, op, alpha, isALE, index);
604: return(0);
605: }
607: /*@C GridAddRhsOperator
608: This function adds the operator to the Rhs for the given field.
610: Collective on Grid
612: Input Parameters:
613: + grid - The grid
614: . sfield - The field for shape functions
615: . tfield - The field for test functions
616: . op - The operator
617: . alpha - A scalar multiple for the operator
618: - isALE - A flag for ALE operators
620: Output Parameter:
621: . index - [Optional] A unique indentifier for the operator
623: Level: beginner
625: .keywords active field
626: .seealso GridSetRhsOperator, GridSetMatOperator, GridSetRhsFunction
627: @*/
628: int GridAddRhsOperator(Grid grid, int sField, int tField, int op, PetscScalar alpha, PetscTruth isALE, int *index)
629: {
630: Discretization sDisc = grid->fields[sField].disc;
631: Discretization tDisc = grid->fields[tField].disc;
632: int dim = grid->dim;
633: GridOp *tempOps;
634: int ierr;
638: GridValidField(grid, sField);
639: GridValidField(grid, tField);
640: if ((op < 0) || (op >= sDisc->numOps) || (!sDisc->operators[op])) {
641: SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid operator %d", op);
642: }
643: if ((sDisc->operators[op]->precompInt == PETSC_NULL) &&
644: (sDisc->operators[op]->opFunc == PETSC_NULL) &&
645: (sDisc->operators[op]->ALEOpFunc == PETSC_NULL)) {
646: SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid operator %d has no associated function", op);
647: }
648: if (sDisc->numQuadPoints != tDisc->numQuadPoints) {
649: SETERRQ(PETSC_ERR_ARG_INCOMP, "Incompatible quadrature sets");
650: }
651: while (grid->numRhsOps >= grid->maxRhsOps) {
652: PetscMalloc(grid->maxRhsOps*2 * sizeof(GridOp), &tempOps);
653: PetscLogObjectMemory(grid, grid->maxRhsOps * sizeof(GridOp));
654: PetscMemcpy(tempOps, grid->rhsOps, grid->maxRhsOps * sizeof(GridOp));
655: PetscFree(grid->rhsOps);
656: grid->rhsOps = tempOps;
657: grid->maxRhsOps *= 2;
658: }
659: if (index != PETSC_NULL) {
661: *index = grid->numRhsOps;
662: }
663: grid->rhsOps[grid->numRhsOps].op = op;
664: grid->rhsOps[grid->numRhsOps].field = sField;
665: grid->rhsOps[grid->numRhsOps].alpha = alpha;
666: grid->rhsOps[grid->numRhsOps].isALE = isALE;
667: grid->rhsOps[grid->numRhsOps].nonlinearOp = PETSC_NULL;
668: grid->numRhsOps++;
669: if (isALE == PETSC_TRUE) grid->ALEActive = PETSC_TRUE;
670: /* Assign test function field to operator -- Need more sophisticated checking */
671: switch (op) {
672: case IDENTITY:
673: case LAPLACIAN:
674: if (sDisc->size != tDisc->size) {
675: SETERRQ(PETSC_ERR_ARG_INCOMP, "Incompatible test function field");
676: }
677: break;
678: case GRADIENT:
679: if (sDisc->comp*dim != tDisc->comp) {
680: SETERRQ(PETSC_ERR_ARG_INCOMP, "Incompatible test function field");
681: }
682: break;
683: case DIVERGENCE:
684: if (tDisc->comp*dim != sDisc->comp) {
685: SETERRQ(PETSC_ERR_ARG_INCOMP, "Incompatible test function field");
686: }
687: break;
688: }
689: sDisc->operators[op]->test = tDisc;
690: return(0);
691: }
693: /*@C GridScaleRhs
694: This function multiplies all the current components of the Rhs by the same scalar.
696: Collective on Grid
698: Input Parameters:
699: + grid - The grid
700: - alpha - The scalar
702: Level: intermediate
704: .keywords grid, rhs, scale
705: .seealso GridScaleSystemMatrix()
706: @*/
707: int GridScaleRhs(Grid grid, PetscScalar alpha)
708: {
709: int func, op;
713: /* Scale functions */
714: for(func = 0; func < grid->numRhsFuncs; func++) grid->rhsFuncs[func].alpha *= alpha;
715: /* Scale linear operators */
716: for(op = 0; op < grid->numRhsOps; op++) grid->rhsOps[op].alpha *= alpha;
717: PetscLogFlops(grid->numRhsFuncs + grid->numRhsOps);
718: return(0);
719: }
721: /*@C GridScaleRhsOperator
722: This function multiplies an operator of the Rhs by the a scalar.
724: Collective on Grid
726: Input Parameters:
727: + grid - The grid
728: . alpha - The scalar
729: - index - The unique operator index returned by GridAddRhsOperator()
731: Level: intermediate
733: .keywords grid, rhs, scale, operator
734: .seealso GridScaleSystemMatrix(), GridAddRhsOperator()
735: @*/
736: int GridScaleRhsOperator(Grid grid, PetscScalar alpha, int index)
737: {
740: grid->rhsOps[index].alpha *= alpha;
741: PetscLogFlops(1);
742: return(0);
743: }
745: /*--------------------------------------------- System Matrix Functions ---------------------------------------------*/
746: /*@
747: GridIsMatrixFree - Signals whether operators are applied matrix-free.
749: Not collective
751: Input Parameter:
752: . grid - The grid
754: Output Parameter:
755: . isMatrixFree - The flag for matrix-free operators
757: Level: intermediate
759: .keywords: grid, operator, matrix-free
760: .seealso: GridSetMatrixFree()
761: @*/
762: int GridIsMatrixFree(Grid grid, PetscTruth *isMatrixFree)
763: {
765: *isMatrixFree = grid->isMatrixFree;
766: return(0);
767: }
769: /*@
770: GridSetMatrixFree - Determines whether operators are applied matrix-free.
772: Not collective
774: Input Parameters:
775: . grid - The grid
776: . isMatrixFree - The flag for matrix-free operators
778: Level: intermediate
780: .keywords: grid, operator, matrix-free
781: .seealso: GridIsMatrixFree()
782: @*/
783: int GridSetMatrixFree(Grid grid, PetscTruth isMatrixFree)
784: {
786: grid->isMatrixFree = isMatrixFree;
787: return(0);
788: }
790: /*@
791: GridGetNumRhsOperators - Returns the number of rhs operators for the problem defined on the grid.
793: Not collective
795: Input Parameter:
796: . grid - The grid
798: Output Parameter:
799: . numOps - The number of operators
801: Level: intermediate
803: .keywords: grid, operator
804: .seealso: GridGetRhsOperatorStart()
805: @*/
806: int GridGetNumRhsOperators(Grid grid, int *numOps)
807: {
811: *numOps = grid->numRhsOps;
812: return(0);
813: }
815: /*@
816: GridGetNumMatOperators - Returns the number of matrix operators for the problem defined on the grid.
818: Not collective
820: Input Parameter:
821: . grid - The grid
823: Output Parameter:
824: . numOps - The number of operators
826: Level: intermediate
828: .keywords: grid, operator
829: .seealso: GridGetMatOperatorStart()
830: @*/
831: int GridGetNumMatOperators(Grid grid, int *numOps)
832: {
836: *numOps = grid->numMatOps;
837: return(0);
838: }
840: /*@
841: GridGetMatOperatorStart - Retrieves information about the first matrix operator
842: for the problem defined on the grid.
844: Not collective
846: Input Parameter:
847: . grid - The grid
849: Output Parameters:
850: + op - The operator
851: . sField - The shape function field
852: . tField - The test function field
853: . alpha - The multiplier of this operator
854: - isALE - The flag for ALE operators
856: Level: intermediate
858: .keywords: grid, operator
859: .seealso: GridGetMatOperatorNext(), GridGetNumMatOperators()
860: @*/
861: int GridGetMatOperatorStart(Grid grid, int *op, int *sField, int *tField, PetscScalar *alpha, PetscTruth *isALE)
862: {
867: grid->activeMatOp = -1;
868: GridGetMatOperatorNext(grid, op, sField, tField, alpha, isALE);
869: return(0);
870: }
872: /*@
873: GridGetMatOperatorNext - Retrieves information about the next matrix operator
874: for the problem defined on the grid.
876: Not collective
878: Input Parameter:
879: . grid - The grid
881: Output Parameters:
882: + op - The operator
883: . sField - The shape function field
884: . tField - The test function field
885: . alpha - The multiplier of this operator
886: - isALE - The flag for ALE operators
888: Level: intermediate
890: .keywords: grid, operator
891: .seealso: GridMatGetOperatorStart(), GridGetNumMatOperators()
892: @*/
893: int GridGetMatOperatorNext(Grid grid, int *op, int *sField, int *tField, PetscScalar *alpha, PetscTruth *isALE)
894: {
897: grid->activeMatOp++;
898: if (grid->activeMatOp >= grid->numMatOps) {
899: if (op != PETSC_NULL) *op = -1;
900: if (sField != PETSC_NULL) *sField = -1;
901: if (tField != PETSC_NULL) *tField = -1;
902: if (alpha != PETSC_NULL) *alpha = 0.0;
903: if (isALE != PETSC_NULL) *isALE = PETSC_FALSE;
904: grid->activeMatOp = -1;
905: return(0);
906: }
907: if (op != PETSC_NULL) {
909: *op = grid->matOps[grid->activeMatOp].op;
910: }
911: if (sField != PETSC_NULL) {
913: *sField = grid->matOps[grid->activeMatOp].field;
914: }
915: if (tField != PETSC_NULL) {
917: *tField = grid->fields[grid->matOps[grid->activeMatOp].field].disc->operators[grid->matOps[grid->activeMatOp].op]->test->field;
918: }
919: if (alpha != PETSC_NULL) {
921: *alpha = grid->matOps[grid->activeMatOp].alpha;
922: }
923: if (isALE != PETSC_NULL) {
925: *isALE = grid->matOps[grid->activeMatOp].isALE;
926: }
927: return(0);
928: }
930: /*@C GridSetMatOperator
931: This function sets the operator to use in the system matrix for the given field.
933: Collective on Grid
935: Input Parameters:
936: + grid - The grid
937: . sField - The field for shape functions
938: . tField - The field for test functions
939: . op - The operator
940: . alpha - A scalar multiple for the operator
941: - isALE - A flag for ALE operators
943: Output Parameter:
944: . index - [Optional] A unique indentifier for the operator
946: Level: beginner
948: .keywords active field
949: .seealso GridAddMatOperator, GridAddRhsOperator, GridSetRhsFunction
950: @*/
951: int GridSetMatOperator(Grid grid, int sField, int tField, int op, PetscScalar alpha, PetscTruth isALE, int *index)
952: {
957: grid->numMatOps = 0;
958: GridAddMatOperator(grid, sField, tField, op, alpha, isALE, index);
959: return(0);
960: }
962: /*@C GridAddMatOperator
963: This function adds the operator to the system matrix for the given field.
965: Collective on Grid
967: Input Parameters:
968: + grid - The grid
969: . sField - The field for shape functions
970: . tField - The field for test functions
971: . op - The operator
972: . alpha - A scalar multiple for the operator
973: - isALE - A flag for ALE operators
975: Output Parameter:
976: . index - [Optional] A unique indentifier for the operator
978: Level: beginner
980: .keywords active field
981: .seealso GridSetMatOperator, GridSetRhsOperator, GridSetRhsFunction
982: @*/
983: int GridAddMatOperator(Grid grid, int sField, int tField, int op, PetscScalar alpha, PetscTruth isALE, int *index)
984: {
985: Discretization sDisc = grid->fields[sField].disc;
986: Discretization tDisc = grid->fields[tField].disc;
987: int dim = grid->dim;
988: GridOp *tempOps;
989: int ierr;
993: GridValidField(grid, sField);
994: GridValidField(grid, tField);
995: if ((op < 0) || (op >= sDisc->numOps) || (!sDisc->operators[op])) {
996: SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid operator %d", op);
997: }
998: if ((sDisc->operators[op]->precompInt == PETSC_NULL) &&
999: (sDisc->operators[op]->opFunc == PETSC_NULL) &&
1000: (sDisc->operators[op]->ALEOpFunc == PETSC_NULL)) {
1001: SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid operator %d has no associated function", op);
1002: }
1003: if (sDisc->numQuadPoints != tDisc->numQuadPoints) {
1004: SETERRQ(PETSC_ERR_ARG_INCOMP, "Incompatible quadrature sets");
1005: }
1006: while (grid->numMatOps >= grid->maxMatOps) {
1007: PetscMalloc(grid->maxMatOps*2 * sizeof(GridOp), &tempOps);
1008: PetscLogObjectMemory(grid, grid->maxMatOps * sizeof(GridOp));
1009: PetscMemcpy(tempOps, grid->matOps, grid->maxMatOps * sizeof(GridOp));
1010: PetscFree(grid->matOps);
1011: grid->matOps = tempOps;
1012: grid->maxMatOps *= 2;
1013: }
1014: if (index != PETSC_NULL) {
1016: *index = grid->numMatOps;
1017: }
1018: grid->matOps[grid->numMatOps].op = op;
1019: grid->matOps[grid->numMatOps].field = sField;
1020: grid->matOps[grid->numMatOps].alpha = alpha;
1021: grid->matOps[grid->numMatOps].isALE = isALE;
1022: grid->matOps[grid->numMatOps].nonlinearOp = PETSC_NULL;
1023: grid->numMatOps++;
1024: if (isALE == PETSC_TRUE) grid->ALEActive = PETSC_TRUE;
1025: /* Assign test function field to operator -- Need more sophisticated checking */
1026: switch (op) {
1027: case IDENTITY:
1028: case LAPLACIAN:
1029: if (sDisc->size != tDisc->size) {
1030: SETERRQ(PETSC_ERR_ARG_INCOMP, "Incompatible test function field");
1031: }
1032: break;
1033: case GRADIENT:
1034: if (sDisc->comp*dim != tDisc->comp) {
1035: SETERRQ(PETSC_ERR_ARG_INCOMP, "Incompatible test function field");
1036: }
1037: break;
1038: case DIVERGENCE:
1039: if (tDisc->comp*dim != sDisc->comp) {
1040: SETERRQ(PETSC_ERR_ARG_INCOMP, "Incompatible test function field");
1041: }
1042: break;
1043: }
1044: sDisc->operators[op]->test = tDisc;
1045: return(0);
1046: }
1048: /*@C GridRegisterOperator
1049: This function defines a new operator for a certain field
1051: Collective on Grid
1053: Input Parameters:
1054: + grid - The grid
1055: . field - The field on which the operator acts
1056: - func - The function deinfing the operator
1058: Output Parameter:
1059: . newOp - The index of the new operator
1061: Level: intermediate
1063: .keywords grid, operator, register
1064: .seealso GridAddMatOperator, GridAddRhsOperator, GridSetRhsFunction
1065: @*/
1066: int GridRegisterOperator(Grid grid, int field, OperatorFunction func, int *newOp)
1067: {
1072: GridValidField(grid, field);
1073: DiscretizationRegisterOperator(grid->fields[field].disc, func, newOp);
1074: return(0);
1075: }
1077: /*@C GridRegisterALEOperator
1078: This function defines a new operator for a certain field
1080: Collective on Grid
1082: Input Parameters:
1083: + grid - The grid
1084: . field - The field on which the operator acts
1085: - func - The function deinfing the operator
1087: Output Parameter:
1088: . newOp - The index of the new operator
1090: Level: intermediate
1092: .keywords grid, oeprator, register
1093: .seealso GridAddMatOperator, GridAddRhsOperator, GridSetRhsFunction
1094: @*/
1095: int GridRegisterALEOperator(Grid grid, int field, ALEOperatorFunction func, int *newOp)
1096: {
1101: GridValidField(grid, field);
1102: DiscretizationRegisterALEOperator(grid->fields[field].disc, func, newOp);
1103: return(0);
1104: }
1106: /*@C GridScaleSystemMatrix
1107: This function multiplies all the current components of the system matrix by the same scalar.
1109: Collective on Grid
1111: Input Parameters:
1112: + grid - The grid
1113: - alpha - The scalar
1115: Level: intermediate
1117: .keywords grid, matrix, scale
1118: .seealso GridScaleRhs()
1119: @*/
1120: int GridScaleSystemMatrix(Grid grid, PetscScalar alpha)
1121: {
1122: int op;
1126: /* Scale linear operators */
1127: for(op = 0; op < grid->numMatOps; op++) grid->matOps[op].alpha *= alpha;
1128: PetscLogFlops(grid->numMatOps);
1129: return(0);
1130: }
1132: /*@C GridScaleMatOperator
1133: This function multiplies all the current components of the system matrix by the same scalar.
1135: Collective on Grid
1137: Input Parameters:
1138: + grid - The grid
1139: . alpha - The scalar
1140: - index - The unique operator index returned by GridAddMatOperator()
1142: Level: intermediate
1144: .keywords grid, matrix, scale
1145: .seealso GridScaleRhs(), GridAddMatOperator()
1146: @*/
1147: int GridScaleMatOperator(Grid grid, PetscScalar alpha, int index)
1148: {
1151: grid->matOps[index].alpha *= alpha;
1152: PetscLogFlops(1);
1153: return(0);
1154: }