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, §ion)); 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