xref: /petsc/src/dm/dt/dualspace/impls/simple/dspacesimple.c (revision 28b400f66ebc7ae0049166a2294dfcd3df27e64b)
120cf1dd8SToby Isaac #include <petsc/private/petscfeimpl.h> /*I "petscfe.h" I*/
220cf1dd8SToby Isaac #include <petscdmplex.h>
320cf1dd8SToby Isaac 
4a4ce7ad1SMatthew G. Knepley static PetscErrorCode PetscDualSpaceSetUp_Simple(PetscDualSpace sp)
520cf1dd8SToby Isaac {
620cf1dd8SToby Isaac   PetscDualSpace_Simple *s  = (PetscDualSpace_Simple *) sp->data;
720cf1dd8SToby Isaac   DM                     dm = sp->dm;
8b4457527SToby Isaac   PetscInt               dim, pStart, pEnd;
9b4457527SToby Isaac   PetscSection           section;
1020cf1dd8SToby Isaac 
1120cf1dd8SToby Isaac   PetscFunctionBegin;
125f80ce2aSJacob Faibussowitsch   CHKERRQ(DMGetDimension(dm, &dim));
135f80ce2aSJacob Faibussowitsch   CHKERRQ(DMPlexGetChart(dm, &pStart, &pEnd));
145f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSectionCreate(PETSC_COMM_SELF, &section));
155f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSectionSetChart(section, pStart, pEnd));
165f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSectionSetDof(section, pStart, s->dim));
175f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSectionSetUp(section));
18b4457527SToby Isaac   sp->pointSection = section;
1920cf1dd8SToby Isaac   PetscFunctionReturn(0);
2020cf1dd8SToby Isaac }
2120cf1dd8SToby Isaac 
22a4ce7ad1SMatthew G. Knepley static PetscErrorCode PetscDualSpaceDestroy_Simple(PetscDualSpace sp)
2320cf1dd8SToby Isaac {
2420cf1dd8SToby Isaac   PetscDualSpace_Simple *s = (PetscDualSpace_Simple *) sp->data;
2520cf1dd8SToby Isaac 
2620cf1dd8SToby Isaac   PetscFunctionBegin;
275f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(s->numDof));
285f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(s));
295f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject) sp, "PetscDualSpaceSimpleSetDimension_C", NULL));
305f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject) sp, "PetscDualSpaceSimpleSetFunctional_C", NULL));
3120cf1dd8SToby Isaac   PetscFunctionReturn(0);
3220cf1dd8SToby Isaac }
3320cf1dd8SToby Isaac 
34b4457527SToby Isaac static PetscErrorCode PetscDualSpaceDuplicate_Simple(PetscDualSpace sp, PetscDualSpace spNew)
3520cf1dd8SToby Isaac {
36b4457527SToby Isaac   PetscInt       dim, d;
3720cf1dd8SToby Isaac 
3820cf1dd8SToby Isaac   PetscFunctionBegin;
395f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscDualSpaceGetDimension(sp, &dim));
405f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscDualSpaceSimpleSetDimension(spNew, dim));
4120cf1dd8SToby Isaac   for (d = 0; d < dim; ++d) {
4220cf1dd8SToby Isaac     PetscQuadrature q;
4320cf1dd8SToby Isaac 
445f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscDualSpaceGetFunctional(sp, d, &q));
455f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscDualSpaceSimpleSetFunctional(spNew, d, q));
4620cf1dd8SToby Isaac   }
4720cf1dd8SToby Isaac   PetscFunctionReturn(0);
4820cf1dd8SToby Isaac }
4920cf1dd8SToby Isaac 
50a4ce7ad1SMatthew G. Knepley static PetscErrorCode PetscDualSpaceSetFromOptions_Simple(PetscOptionItems *PetscOptionsObject,PetscDualSpace sp)
5120cf1dd8SToby Isaac {
5220cf1dd8SToby Isaac   PetscFunctionBegin;
5320cf1dd8SToby Isaac   PetscFunctionReturn(0);
5420cf1dd8SToby Isaac }
5520cf1dd8SToby Isaac 
56a4ce7ad1SMatthew G. Knepley static PetscErrorCode PetscDualSpaceSimpleSetDimension_Simple(PetscDualSpace sp, const PetscInt dim)
5720cf1dd8SToby Isaac {
5820cf1dd8SToby Isaac   PetscDualSpace_Simple *s = (PetscDualSpace_Simple *) sp->data;
5920cf1dd8SToby Isaac   DM                     dm;
6020cf1dd8SToby Isaac   PetscInt               spatialDim, f;
6120cf1dd8SToby Isaac 
6220cf1dd8SToby Isaac   PetscFunctionBegin;
635f80ce2aSJacob Faibussowitsch   for (f = 0; f < s->dim; ++f) CHKERRQ(PetscQuadratureDestroy(&sp->functional[f]));
645f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(sp->functional));
6520cf1dd8SToby Isaac   s->dim = dim;
665f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCalloc1(s->dim, &sp->functional));
675f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(s->numDof));
685f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscDualSpaceGetDM(sp, &dm));
695f80ce2aSJacob Faibussowitsch   CHKERRQ(DMGetCoordinateDim(dm, &spatialDim));
705f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscCalloc1(spatialDim+1, &s->numDof));
7120cf1dd8SToby Isaac   s->numDof[spatialDim] = dim;
7220cf1dd8SToby Isaac   PetscFunctionReturn(0);
7320cf1dd8SToby Isaac }
7420cf1dd8SToby Isaac 
75a4ce7ad1SMatthew G. Knepley static PetscErrorCode PetscDualSpaceSimpleSetFunctional_Simple(PetscDualSpace sp, PetscInt f, PetscQuadrature q)
7620cf1dd8SToby Isaac {
7720cf1dd8SToby Isaac   PetscDualSpace_Simple *s = (PetscDualSpace_Simple *) sp->data;
7820cf1dd8SToby Isaac   PetscReal             *weights;
7920cf1dd8SToby Isaac   PetscInt               Nc, c, Nq, p;
8020cf1dd8SToby Isaac 
8120cf1dd8SToby Isaac   PetscFunctionBegin;
822c71b3e2SJacob Faibussowitsch   PetscCheckFalse((f < 0) || (f >= s->dim),PetscObjectComm((PetscObject) sp), PETSC_ERR_ARG_OUTOFRANGE, "Basis index %d not in [0, %d)", f, s->dim);
835f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscQuadratureDuplicate(q, &sp->functional[f]));
8420cf1dd8SToby Isaac   /* Reweight so that it has unit volume: Do we want to do this for Nc > 1? */
855f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscQuadratureGetData(sp->functional[f], NULL, &Nc, &Nq, NULL, (const PetscReal **) &weights));
8620cf1dd8SToby Isaac   for (c = 0; c < Nc; ++c) {
8720cf1dd8SToby Isaac     PetscReal vol = 0.0;
8820cf1dd8SToby Isaac 
8920cf1dd8SToby Isaac     for (p = 0; p < Nq; ++p) vol += weights[p*Nc+c];
9020cf1dd8SToby Isaac     for (p = 0; p < Nq; ++p) weights[p*Nc+c] /= (vol == 0.0 ? 1.0 : vol);
9120cf1dd8SToby Isaac   }
9220cf1dd8SToby Isaac   PetscFunctionReturn(0);
9320cf1dd8SToby Isaac }
9420cf1dd8SToby Isaac 
9520cf1dd8SToby Isaac /*@
9620cf1dd8SToby Isaac   PetscDualSpaceSimpleSetDimension - Set the number of functionals in the dual space basis
9720cf1dd8SToby Isaac 
98d083f849SBarry Smith   Logically Collective on sp
9920cf1dd8SToby Isaac 
10020cf1dd8SToby Isaac   Input Parameters:
10120cf1dd8SToby Isaac + sp  - the PetscDualSpace
10220cf1dd8SToby Isaac - dim - the basis dimension
10320cf1dd8SToby Isaac 
10420cf1dd8SToby Isaac   Level: intermediate
10520cf1dd8SToby Isaac 
10620cf1dd8SToby Isaac .seealso: PetscDualSpaceSimpleSetFunctional()
10720cf1dd8SToby Isaac @*/
10820cf1dd8SToby Isaac PetscErrorCode PetscDualSpaceSimpleSetDimension(PetscDualSpace sp, PetscInt dim)
10920cf1dd8SToby Isaac {
11020cf1dd8SToby Isaac   PetscFunctionBegin;
11120cf1dd8SToby Isaac   PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 1);
11220cf1dd8SToby Isaac   PetscValidLogicalCollectiveInt(sp, dim, 2);
113*28b400f6SJacob Faibussowitsch   PetscCheck(!sp->setupcalled,PetscObjectComm((PetscObject)sp), PETSC_ERR_ARG_WRONGSTATE, "Cannot change dimension after dual space is set up");
1145f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscTryMethod(sp, "PetscDualSpaceSimpleSetDimension_C", (PetscDualSpace,PetscInt),(sp,dim)));
11520cf1dd8SToby Isaac   PetscFunctionReturn(0);
11620cf1dd8SToby Isaac }
11720cf1dd8SToby Isaac 
11820cf1dd8SToby Isaac /*@
11920cf1dd8SToby Isaac   PetscDualSpaceSimpleSetFunctional - Set the given basis element for this dual space
12020cf1dd8SToby Isaac 
12120cf1dd8SToby Isaac   Not Collective
12220cf1dd8SToby Isaac 
12320cf1dd8SToby Isaac   Input Parameters:
12420cf1dd8SToby Isaac + sp  - the PetscDualSpace
12520cf1dd8SToby Isaac . f - the basis index
12620cf1dd8SToby Isaac - q - the basis functional
12720cf1dd8SToby Isaac 
12820cf1dd8SToby Isaac   Level: intermediate
12920cf1dd8SToby Isaac 
13020cf1dd8SToby Isaac   Note: The quadrature will be reweighted so that it has unit volume.
13120cf1dd8SToby Isaac 
13220cf1dd8SToby Isaac .seealso: PetscDualSpaceSimpleSetDimension()
13320cf1dd8SToby Isaac @*/
13420cf1dd8SToby Isaac PetscErrorCode PetscDualSpaceSimpleSetFunctional(PetscDualSpace sp, PetscInt func, PetscQuadrature q)
13520cf1dd8SToby Isaac {
13620cf1dd8SToby Isaac   PetscFunctionBegin;
13720cf1dd8SToby Isaac   PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 1);
1385f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscTryMethod(sp, "PetscDualSpaceSimpleSetFunctional_C", (PetscDualSpace,PetscInt,PetscQuadrature),(sp,func,q)));
13920cf1dd8SToby Isaac   PetscFunctionReturn(0);
14020cf1dd8SToby Isaac }
14120cf1dd8SToby Isaac 
142a4ce7ad1SMatthew G. Knepley static PetscErrorCode PetscDualSpaceInitialize_Simple(PetscDualSpace sp)
14320cf1dd8SToby Isaac {
14420cf1dd8SToby Isaac   PetscFunctionBegin;
14520cf1dd8SToby Isaac   sp->ops->setfromoptions       = PetscDualSpaceSetFromOptions_Simple;
14620cf1dd8SToby Isaac   sp->ops->setup                = PetscDualSpaceSetUp_Simple;
14720cf1dd8SToby Isaac   sp->ops->view                 = NULL;
14820cf1dd8SToby Isaac   sp->ops->destroy              = PetscDualSpaceDestroy_Simple;
14920cf1dd8SToby Isaac   sp->ops->duplicate            = PetscDualSpaceDuplicate_Simple;
150b4457527SToby Isaac   sp->ops->createheightsubspace = NULL;
151b4457527SToby Isaac   sp->ops->createpointsubspace  = NULL;
15220cf1dd8SToby Isaac   sp->ops->getsymmetries        = NULL;
15320cf1dd8SToby Isaac   sp->ops->apply                = PetscDualSpaceApplyDefault;
15420cf1dd8SToby Isaac   sp->ops->applyall             = PetscDualSpaceApplyAllDefault;
155b4457527SToby Isaac   sp->ops->applyint             = PetscDualSpaceApplyInteriorDefault;
156b4457527SToby Isaac   sp->ops->createalldata        = PetscDualSpaceCreateAllDataDefault;
157b4457527SToby Isaac   sp->ops->createintdata        = PetscDualSpaceCreateInteriorDataDefault;
15820cf1dd8SToby Isaac   PetscFunctionReturn(0);
15920cf1dd8SToby Isaac }
16020cf1dd8SToby Isaac 
16120cf1dd8SToby Isaac /*MC
16220cf1dd8SToby Isaac   PETSCDUALSPACESIMPLE = "simple" - A PetscDualSpace object that encapsulates a dual space of arbitrary functionals
16320cf1dd8SToby Isaac 
16420cf1dd8SToby Isaac   Level: intermediate
16520cf1dd8SToby Isaac 
16620cf1dd8SToby Isaac .seealso: PetscDualSpaceType, PetscDualSpaceCreate(), PetscDualSpaceSetType()
16720cf1dd8SToby Isaac M*/
16820cf1dd8SToby Isaac 
16920cf1dd8SToby Isaac PETSC_EXTERN PetscErrorCode PetscDualSpaceCreate_Simple(PetscDualSpace sp)
17020cf1dd8SToby Isaac {
17120cf1dd8SToby Isaac   PetscDualSpace_Simple *s;
17220cf1dd8SToby Isaac 
17320cf1dd8SToby Isaac   PetscFunctionBegin;
17420cf1dd8SToby Isaac   PetscValidHeaderSpecific(sp, PETSCDUALSPACE_CLASSID, 1);
1755f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscNewLog(sp,&s));
17620cf1dd8SToby Isaac   sp->data = s;
17720cf1dd8SToby Isaac 
17820cf1dd8SToby Isaac   s->dim    = 0;
17920cf1dd8SToby Isaac   s->numDof = NULL;
18020cf1dd8SToby Isaac 
1815f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscDualSpaceInitialize_Simple(sp));
1825f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject) sp, "PetscDualSpaceSimpleSetDimension_C", PetscDualSpaceSimpleSetDimension_Simple));
1835f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectComposeFunction((PetscObject) sp, "PetscDualSpaceSimpleSetFunctional_C", PetscDualSpaceSimpleSetFunctional_Simple));
18420cf1dd8SToby Isaac   PetscFunctionReturn(0);
18520cf1dd8SToby Isaac }
186