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