120cf1dd8SToby Isaac #include <petsc/private/petscfeimpl.h> /*I "petscfe.h" I*/ 220cf1dd8SToby Isaac #include <petscblaslapack.h> 320cf1dd8SToby Isaac 42b99622eSMatthew G. Knepley static PetscErrorCode PetscFEDestroy_Basic(PetscFE fem) 520cf1dd8SToby Isaac { 620cf1dd8SToby Isaac PetscFE_Basic *b = (PetscFE_Basic *) fem->data; 720cf1dd8SToby Isaac 820cf1dd8SToby Isaac PetscFunctionBegin; 9*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(b)); 1020cf1dd8SToby Isaac PetscFunctionReturn(0); 1120cf1dd8SToby Isaac } 1220cf1dd8SToby Isaac 132b99622eSMatthew G. Knepley static PetscErrorCode PetscFEView_Basic_Ascii(PetscFE fe, PetscViewer v) 1420cf1dd8SToby Isaac { 15d9bac1caSLisandro Dalcin PetscInt dim, Nc; 16d9bac1caSLisandro Dalcin PetscSpace basis = NULL; 17d9bac1caSLisandro Dalcin PetscDualSpace dual = NULL; 18d9bac1caSLisandro Dalcin PetscQuadrature quad = NULL; 1920cf1dd8SToby Isaac 2020cf1dd8SToby Isaac PetscFunctionBegin; 21*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetSpatialDimension(fe, &dim)); 22*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetNumComponents(fe, &Nc)); 23*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetBasisSpace(fe, &basis)); 24*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetDualSpace(fe, &dual)); 25*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetQuadrature(fe, &quad)); 26*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPushTab(v)); 27*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(v, "Basic Finite Element in %D dimensions with %D components\n",dim,Nc)); 28*5f80ce2aSJacob Faibussowitsch if (basis) CHKERRQ(PetscSpaceView(basis, v)); 29*5f80ce2aSJacob Faibussowitsch if (dual) CHKERRQ(PetscDualSpaceView(dual, v)); 30*5f80ce2aSJacob Faibussowitsch if (quad) CHKERRQ(PetscQuadratureView(quad, v)); 31*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPopTab(v)); 3220cf1dd8SToby Isaac PetscFunctionReturn(0); 3320cf1dd8SToby Isaac } 3420cf1dd8SToby Isaac 352b99622eSMatthew G. Knepley static PetscErrorCode PetscFEView_Basic(PetscFE fe, PetscViewer v) 3620cf1dd8SToby Isaac { 3720cf1dd8SToby Isaac PetscBool iascii; 3820cf1dd8SToby Isaac 3920cf1dd8SToby Isaac PetscFunctionBegin; 40*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject) v, PETSCVIEWERASCII, &iascii)); 41*5f80ce2aSJacob Faibussowitsch if (iascii) CHKERRQ(PetscFEView_Basic_Ascii(fe, v)); 4220cf1dd8SToby Isaac PetscFunctionReturn(0); 4320cf1dd8SToby Isaac } 4420cf1dd8SToby Isaac 4520cf1dd8SToby Isaac /* Construct the change of basis from prime basis to nodal basis */ 46526996e7SStefano Zampini PETSC_INTERN PetscErrorCode PetscFESetUp_Basic(PetscFE fem) 4720cf1dd8SToby Isaac { 48b9d4cb8dSJed Brown PetscReal *work; 4920cf1dd8SToby Isaac PetscBLASInt *pivots; 5020cf1dd8SToby Isaac PetscBLASInt n, info; 5120cf1dd8SToby Isaac PetscInt pdim, j; 5220cf1dd8SToby Isaac 5320cf1dd8SToby Isaac PetscFunctionBegin; 54*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDimension(fem->dualSpace, &pdim)); 55*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(pdim*pdim,&fem->invV)); 5620cf1dd8SToby Isaac for (j = 0; j < pdim; ++j) { 5720cf1dd8SToby Isaac PetscReal *Bf; 5820cf1dd8SToby Isaac PetscQuadrature f; 5920cf1dd8SToby Isaac const PetscReal *points, *weights; 6020cf1dd8SToby Isaac PetscInt Nc, Nq, q, k, c; 6120cf1dd8SToby Isaac 62*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetFunctional(fem->dualSpace, j, &f)); 63*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetData(f, NULL, &Nc, &Nq, &points, &weights)); 64*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(Nc*Nq*pdim,&Bf)); 65*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceEvaluate(fem->basisSpace, Nq, points, Bf, NULL, NULL)); 6620cf1dd8SToby Isaac for (k = 0; k < pdim; ++k) { 6720cf1dd8SToby Isaac /* V_{jk} = n_j(\phi_k) = \int \phi_k(x) n_j(x) dx */ 68b9d4cb8dSJed Brown fem->invV[j*pdim+k] = 0.0; 6920cf1dd8SToby Isaac 7020cf1dd8SToby Isaac for (q = 0; q < Nq; ++q) { 71b9d4cb8dSJed Brown for (c = 0; c < Nc; ++c) fem->invV[j*pdim+k] += Bf[(q*pdim + k)*Nc + c]*weights[q*Nc + c]; 7220cf1dd8SToby Isaac } 7320cf1dd8SToby Isaac } 74*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(Bf)); 7520cf1dd8SToby Isaac } 76ea2bdf6dSBarry Smith 77*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc2(pdim,&pivots,pdim,&work)); 7820cf1dd8SToby Isaac n = pdim; 79b9d4cb8dSJed Brown PetscStackCallBLAS("LAPACKgetrf", LAPACKREALgetrf_(&n, &n, fem->invV, &n, pivots, &info)); 802c71b3e2SJacob Faibussowitsch PetscCheckFalse(info,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error returned from LAPACKgetrf %D",(PetscInt)info); 81b9d4cb8dSJed Brown PetscStackCallBLAS("LAPACKgetri", LAPACKREALgetri_(&n, fem->invV, &n, pivots, work, &n, &info)); 822c71b3e2SJacob Faibussowitsch PetscCheckFalse(info,PETSC_COMM_SELF,PETSC_ERR_LIB,"Error returned from LAPACKgetri %D",(PetscInt)info); 83*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree2(pivots,work)); 8420cf1dd8SToby Isaac PetscFunctionReturn(0); 8520cf1dd8SToby Isaac } 8620cf1dd8SToby Isaac 8720cf1dd8SToby Isaac PetscErrorCode PetscFEGetDimension_Basic(PetscFE fem, PetscInt *dim) 8820cf1dd8SToby Isaac { 8920cf1dd8SToby Isaac PetscFunctionBegin; 90*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDimension(fem->dualSpace, dim)); 9120cf1dd8SToby Isaac PetscFunctionReturn(0); 9220cf1dd8SToby Isaac } 9320cf1dd8SToby Isaac 94b9d4cb8dSJed Brown /* Tensor contraction on the middle index, 95b9d4cb8dSJed Brown * C[m,n,p] = A[m,k,p] * B[k,n] 96b9d4cb8dSJed Brown * where all matrices use C-style ordering. 97b9d4cb8dSJed Brown */ 98bdb10af2SPierre Jolivet static PetscErrorCode TensorContract_Private(PetscInt m,PetscInt n,PetscInt p,PetscInt k,const PetscReal *A,const PetscReal *B,PetscReal *C) 99bdb10af2SPierre Jolivet { 100b9d4cb8dSJed Brown PetscInt i; 101b9d4cb8dSJed Brown 102b9d4cb8dSJed Brown PetscFunctionBegin; 103b9d4cb8dSJed Brown for (i=0; i<m; i++) { 104b9d4cb8dSJed Brown PetscBLASInt n_,p_,k_,lda,ldb,ldc; 105b9d4cb8dSJed Brown PetscReal one = 1, zero = 0; 106b9d4cb8dSJed Brown /* Taking contiguous submatrices, we wish to comput c[n,p] = a[k,p] * B[k,n] 107b9d4cb8dSJed Brown * or, in Fortran ordering, c(p,n) = a(p,k) * B(n,k) 108b9d4cb8dSJed Brown */ 109*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscBLASIntCast(n,&n_)); 110*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscBLASIntCast(p,&p_)); 111*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscBLASIntCast(k,&k_)); 112b9d4cb8dSJed Brown lda = p_; 113b9d4cb8dSJed Brown ldb = n_; 114b9d4cb8dSJed Brown ldc = p_; 115b9d4cb8dSJed Brown PetscStackCallBLAS("BLASgemm",BLASREALgemm_("N","T",&p_,&n_,&k_,&one,A+i*k*p,&lda,B,&ldb,&zero,C+i*n*p,&ldc)); 116b9d4cb8dSJed Brown } 117*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(2.*m*n*p*k)); 118b9d4cb8dSJed Brown PetscFunctionReturn(0); 119b9d4cb8dSJed Brown } 120b9d4cb8dSJed Brown 121526996e7SStefano Zampini PETSC_INTERN PetscErrorCode PetscFECreateTabulation_Basic(PetscFE fem, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation T) 12220cf1dd8SToby Isaac { 12320cf1dd8SToby Isaac DM dm; 12420cf1dd8SToby Isaac PetscInt pdim; /* Dimension of FE space P */ 12520cf1dd8SToby Isaac PetscInt dim; /* Spatial dimension */ 12620cf1dd8SToby Isaac PetscInt Nc; /* Field components */ 127ef0bb6c7SMatthew G. Knepley PetscReal *B = K >= 0 ? T->T[0] : NULL; 128ef0bb6c7SMatthew G. Knepley PetscReal *D = K >= 1 ? T->T[1] : NULL; 129ef0bb6c7SMatthew G. Knepley PetscReal *H = K >= 2 ? T->T[2] : NULL; 130ef0bb6c7SMatthew G. Knepley PetscReal *tmpB = NULL, *tmpD = NULL, *tmpH = NULL; 13120cf1dd8SToby Isaac 13220cf1dd8SToby Isaac PetscFunctionBegin; 133*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDM(fem->dualSpace, &dm)); 134*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMGetDimension(dm, &dim)); 135*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDualSpaceGetDimension(fem->dualSpace, &pdim)); 136*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetNumComponents(fem, &Nc)); 13720cf1dd8SToby Isaac /* Evaluate the prime basis functions at all points */ 138*5f80ce2aSJacob Faibussowitsch if (K >= 0) CHKERRQ(DMGetWorkArray(dm, npoints*pdim*Nc, MPIU_REAL, &tmpB)); 139*5f80ce2aSJacob Faibussowitsch if (K >= 1) CHKERRQ(DMGetWorkArray(dm, npoints*pdim*Nc*dim, MPIU_REAL, &tmpD)); 140*5f80ce2aSJacob Faibussowitsch if (K >= 2) CHKERRQ(DMGetWorkArray(dm, npoints*pdim*Nc*dim*dim, MPIU_REAL, &tmpH)); 141*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSpaceEvaluate(fem->basisSpace, npoints, points, tmpB, tmpD, tmpH)); 142b9d4cb8dSJed Brown /* Translate from prime to nodal basis */ 14320cf1dd8SToby Isaac if (B) { 144b9d4cb8dSJed Brown /* B[npoints, nodes, Nc] = tmpB[npoints, prime, Nc] * invV[prime, nodes] */ 145*5f80ce2aSJacob Faibussowitsch CHKERRQ(TensorContract_Private(npoints, pdim, Nc, pdim, tmpB, fem->invV, B)); 14620cf1dd8SToby Isaac } 14720cf1dd8SToby Isaac if (D) { 148b9d4cb8dSJed Brown /* D[npoints, nodes, Nc, dim] = tmpD[npoints, prime, Nc, dim] * invV[prime, nodes] */ 149*5f80ce2aSJacob Faibussowitsch CHKERRQ(TensorContract_Private(npoints, pdim, Nc*dim, pdim, tmpD, fem->invV, D)); 15020cf1dd8SToby Isaac } 15120cf1dd8SToby Isaac if (H) { 152b9d4cb8dSJed Brown /* H[npoints, nodes, Nc, dim, dim] = tmpH[npoints, prime, Nc, dim, dim] * invV[prime, nodes] */ 153*5f80ce2aSJacob Faibussowitsch CHKERRQ(TensorContract_Private(npoints, pdim, Nc*dim*dim, pdim, tmpH, fem->invV, H)); 15420cf1dd8SToby Isaac } 155*5f80ce2aSJacob Faibussowitsch if (K >= 0) CHKERRQ(DMRestoreWorkArray(dm, npoints*pdim*Nc, MPIU_REAL, &tmpB)); 156*5f80ce2aSJacob Faibussowitsch if (K >= 1) CHKERRQ(DMRestoreWorkArray(dm, npoints*pdim*Nc*dim, MPIU_REAL, &tmpD)); 157*5f80ce2aSJacob Faibussowitsch if (K >= 2) CHKERRQ(DMRestoreWorkArray(dm, npoints*pdim*Nc*dim*dim, MPIU_REAL, &tmpH)); 15820cf1dd8SToby Isaac PetscFunctionReturn(0); 15920cf1dd8SToby Isaac } 16020cf1dd8SToby Isaac 1612b99622eSMatthew G. Knepley static PetscErrorCode PetscFEIntegrate_Basic(PetscDS ds, PetscInt field, PetscInt Ne, PetscFEGeom *cgeom, 1624bee2e38SMatthew G. Knepley const PetscScalar coefficients[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscScalar integral[]) 16320cf1dd8SToby Isaac { 16420cf1dd8SToby Isaac const PetscInt debug = 0; 1654bee2e38SMatthew G. Knepley PetscFE fe; 16620cf1dd8SToby Isaac PetscPointFunc obj_func; 16720cf1dd8SToby Isaac PetscQuadrature quad; 168ef0bb6c7SMatthew G. Knepley PetscTabulation *T, *TAux = NULL; 1694bee2e38SMatthew G. Knepley PetscScalar *u, *u_x, *a, *a_x; 17020cf1dd8SToby Isaac const PetscScalar *constants; 17120cf1dd8SToby Isaac PetscReal *x; 172ef0bb6c7SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL; 17320cf1dd8SToby Isaac PetscInt dim, dE, Np, numConstants, Nf, NfAux = 0, totDim, totDimAux = 0, cOffset = 0, cOffsetAux = 0, e; 17420cf1dd8SToby Isaac PetscBool isAffine; 17520cf1dd8SToby Isaac const PetscReal *quadPoints, *quadWeights; 17620cf1dd8SToby Isaac PetscInt qNc, Nq, q; 17720cf1dd8SToby Isaac 17820cf1dd8SToby Isaac PetscFunctionBegin; 179*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetObjective(ds, field, &obj_func)); 18020cf1dd8SToby Isaac if (!obj_func) PetscFunctionReturn(0); 181*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(ds, field, (PetscObject *) &fe)); 182*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetSpatialDimension(fe, &dim)); 183*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetQuadrature(fe, &quad)); 184*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(ds, &Nf)); 185*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTotalDimension(ds, &totDim)); 186*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentOffsets(ds, &uOff)); 187*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentDerivativeOffsets(ds, &uOff_x)); 188*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTabulation(ds, &T)); 189*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetEvaluationArrays(ds, &u, NULL, &u_x)); 190*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetWorkspace(ds, &x, NULL, NULL, NULL, NULL)); 191*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetConstants(ds, &numConstants, &constants)); 1924bee2e38SMatthew G. Knepley if (dsAux) { 193*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(dsAux, &NfAux)); 194*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTotalDimension(dsAux, &totDimAux)); 195*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentOffsets(dsAux, &aOff)); 196*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x)); 197*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTabulation(dsAux, &TAux)); 198*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetEvaluationArrays(dsAux, &a, NULL, &a_x)); 1992c71b3e2SJacob Faibussowitsch PetscCheckFalse(T[0]->Np != TAux[0]->Np,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Number of tabulation points %D != %D number of auxiliary tabulation points", T[0]->Np, TAux[0]->Np); 20020cf1dd8SToby Isaac } 201*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetData(quad, NULL, &qNc, &Nq, &quadPoints, &quadWeights)); 2022c71b3e2SJacob Faibussowitsch PetscCheckFalse(qNc != 1,PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supports scalar quadrature, not %D components", qNc); 20320cf1dd8SToby Isaac Np = cgeom->numPoints; 20420cf1dd8SToby Isaac dE = cgeom->dimEmbed; 20520cf1dd8SToby Isaac isAffine = cgeom->isAffine; 20620cf1dd8SToby Isaac for (e = 0; e < Ne; ++e) { 2074bee2e38SMatthew G. Knepley PetscFEGeom fegeom; 20820cf1dd8SToby Isaac 20927f02ce8SMatthew G. Knepley fegeom.dim = cgeom->dim; 21027f02ce8SMatthew G. Knepley fegeom.dimEmbed = cgeom->dimEmbed; 21120cf1dd8SToby Isaac if (isAffine) { 2124bee2e38SMatthew G. Knepley fegeom.v = x; 2134bee2e38SMatthew G. Knepley fegeom.xi = cgeom->xi; 2147132c3f7SMatthew G. Knepley fegeom.J = &cgeom->J[e*Np*dE*dE]; 2157132c3f7SMatthew G. Knepley fegeom.invJ = &cgeom->invJ[e*Np*dE*dE]; 2167132c3f7SMatthew G. Knepley fegeom.detJ = &cgeom->detJ[e*Np]; 21720cf1dd8SToby Isaac } 2184bee2e38SMatthew G. Knepley for (q = 0; q < Nq; ++q) { 2194bee2e38SMatthew G. Knepley PetscScalar integrand; 2204bee2e38SMatthew G. Knepley PetscReal w; 2214bee2e38SMatthew G. Knepley 2224bee2e38SMatthew G. Knepley if (isAffine) { 2237132c3f7SMatthew G. Knepley CoordinatesRefToReal(dE, dim, fegeom.xi, &cgeom->v[e*Np*dE], fegeom.J, &quadPoints[q*dim], x); 2244bee2e38SMatthew G. Knepley } else { 2254bee2e38SMatthew G. Knepley fegeom.v = &cgeom->v[(e*Np+q)*dE]; 2264bee2e38SMatthew G. Knepley fegeom.J = &cgeom->J[(e*Np+q)*dE*dE]; 2274bee2e38SMatthew G. Knepley fegeom.invJ = &cgeom->invJ[(e*Np+q)*dE*dE]; 2284bee2e38SMatthew G. Knepley fegeom.detJ = &cgeom->detJ[e*Np+q]; 2294bee2e38SMatthew G. Knepley } 2304bee2e38SMatthew G. Knepley w = fegeom.detJ[0]*quadWeights[q]; 23120cf1dd8SToby Isaac if (debug > 1 && q < Np) { 232*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " detJ: %g\n", fegeom.detJ[0])); 2337be5e748SToby Isaac #if !defined(PETSC_USE_COMPLEX) 234*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPrintCellMatrix(e, "invJ", dim, dim, fegeom.invJ)); 23520cf1dd8SToby Isaac #endif 23620cf1dd8SToby Isaac } 237*5f80ce2aSJacob Faibussowitsch if (debug) CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " quad point %d\n", q)); 238*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEEvaluateFieldJets_Internal(ds, Nf, 0, q, T, &fegeom, &coefficients[cOffset], NULL, u, u_x, NULL)); 239*5f80ce2aSJacob Faibussowitsch if (dsAux) CHKERRQ(PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, 0, q, TAux, &fegeom, &coefficientsAux[cOffsetAux], NULL, a, a_x, NULL)); 2404bee2e38SMatthew G. Knepley obj_func(dim, Nf, NfAux, uOff, uOff_x, u, NULL, u_x, aOff, aOff_x, a, NULL, a_x, 0.0, fegeom.v, numConstants, constants, &integrand); 2414bee2e38SMatthew G. Knepley integrand *= w; 24220cf1dd8SToby Isaac integral[e*Nf+field] += integrand; 243*5f80ce2aSJacob Faibussowitsch if (debug > 1) CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " int: %g %g\n", (double) PetscRealPart(integrand), (double) PetscRealPart(integral[field]))); 24420cf1dd8SToby Isaac } 24520cf1dd8SToby Isaac cOffset += totDim; 24620cf1dd8SToby Isaac cOffsetAux += totDimAux; 24720cf1dd8SToby Isaac } 24820cf1dd8SToby Isaac PetscFunctionReturn(0); 24920cf1dd8SToby Isaac } 25020cf1dd8SToby Isaac 2512b99622eSMatthew G. Knepley static PetscErrorCode PetscFEIntegrateBd_Basic(PetscDS ds, PetscInt field, 252afe6d6adSToby Isaac PetscBdPointFunc obj_func, 2534bee2e38SMatthew G. Knepley PetscInt Ne, PetscFEGeom *fgeom, const PetscScalar coefficients[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscScalar integral[]) 254afe6d6adSToby Isaac { 255afe6d6adSToby Isaac const PetscInt debug = 0; 2564bee2e38SMatthew G. Knepley PetscFE fe; 257afe6d6adSToby Isaac PetscQuadrature quad; 258ef0bb6c7SMatthew G. Knepley PetscTabulation *Tf, *TfAux = NULL; 2594bee2e38SMatthew G. Knepley PetscScalar *u, *u_x, *a, *a_x, *basisReal, *basisDerReal; 260afe6d6adSToby Isaac const PetscScalar *constants; 261afe6d6adSToby Isaac PetscReal *x; 262ef0bb6c7SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL; 263afe6d6adSToby Isaac PetscBool isAffine, auxOnBd; 264afe6d6adSToby Isaac const PetscReal *quadPoints, *quadWeights; 265afe6d6adSToby Isaac PetscInt qNc, Nq, q, Np, dE; 266afe6d6adSToby Isaac PetscInt dim, dimAux, numConstants, Nf, NfAux = 0, totDim, totDimAux = 0, cOffset = 0, cOffsetAux = 0, e; 267afe6d6adSToby Isaac 268afe6d6adSToby Isaac PetscFunctionBegin; 269afe6d6adSToby Isaac if (!obj_func) PetscFunctionReturn(0); 270*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(ds, field, (PetscObject *) &fe)); 271*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetSpatialDimension(fe, &dim)); 272*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetFaceQuadrature(fe, &quad)); 273*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(ds, &Nf)); 274*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTotalDimension(ds, &totDim)); 275*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentOffsets(ds, &uOff)); 276*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentDerivativeOffsets(ds, &uOff_x)); 277*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetEvaluationArrays(ds, &u, NULL, &u_x)); 278*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetWorkspace(ds, &x, &basisReal, &basisDerReal, NULL, NULL)); 279*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetFaceTabulation(ds, &Tf)); 280*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetConstants(ds, &numConstants, &constants)); 2814bee2e38SMatthew G. Knepley if (dsAux) { 282*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetSpatialDimension(dsAux, &dimAux)); 283*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(dsAux, &NfAux)); 284*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTotalDimension(dsAux, &totDimAux)); 285*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentOffsets(dsAux, &aOff)); 286*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x)); 287*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetEvaluationArrays(dsAux, &a, NULL, &a_x)); 288afe6d6adSToby Isaac auxOnBd = dimAux < dim ? PETSC_TRUE : PETSC_FALSE; 289*5f80ce2aSJacob Faibussowitsch if (auxOnBd) CHKERRQ(PetscDSGetTabulation(dsAux, &TfAux)); 290*5f80ce2aSJacob Faibussowitsch else CHKERRQ(PetscDSGetFaceTabulation(dsAux, &TfAux)); 2912c71b3e2SJacob Faibussowitsch PetscCheckFalse(Tf[0]->Np != TfAux[0]->Np,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Number of tabulation points %D != %D number of auxiliary tabulation points", Tf[0]->Np, TfAux[0]->Np); 292afe6d6adSToby Isaac } 293*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetData(quad, NULL, &qNc, &Nq, &quadPoints, &quadWeights)); 2942c71b3e2SJacob Faibussowitsch PetscCheckFalse(qNc != 1,PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supports scalar quadrature, not %D components", qNc); 295afe6d6adSToby Isaac Np = fgeom->numPoints; 296afe6d6adSToby Isaac dE = fgeom->dimEmbed; 297afe6d6adSToby Isaac isAffine = fgeom->isAffine; 298afe6d6adSToby Isaac for (e = 0; e < Ne; ++e) { 2999f209ee4SMatthew G. Knepley PetscFEGeom fegeom, cgeom; 300afe6d6adSToby Isaac const PetscInt face = fgeom->face[e][0]; /* Local face number in cell */ 301ea78f98cSLisandro Dalcin fegeom.n = NULL; 302ea78f98cSLisandro Dalcin fegeom.v = NULL; 303ea78f98cSLisandro Dalcin fegeom.J = NULL; 304ea78f98cSLisandro Dalcin fegeom.detJ = NULL; 30527f02ce8SMatthew G. Knepley fegeom.dim = fgeom->dim; 30627f02ce8SMatthew G. Knepley fegeom.dimEmbed = fgeom->dimEmbed; 30727f02ce8SMatthew G. Knepley cgeom.dim = fgeom->dim; 30827f02ce8SMatthew G. Knepley cgeom.dimEmbed = fgeom->dimEmbed; 3094bee2e38SMatthew G. Knepley if (isAffine) { 3104bee2e38SMatthew G. Knepley fegeom.v = x; 3114bee2e38SMatthew G. Knepley fegeom.xi = fgeom->xi; 3127132c3f7SMatthew G. Knepley fegeom.J = &fgeom->J[e*Np*dE*dE]; 3137132c3f7SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[e*Np*dE*dE]; 3147132c3f7SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e*Np]; 3157132c3f7SMatthew G. Knepley fegeom.n = &fgeom->n[e*Np*dE]; 3169f209ee4SMatthew G. Knepley 3177132c3f7SMatthew G. Knepley cgeom.J = &fgeom->suppJ[0][e*Np*dE*dE]; 3187132c3f7SMatthew G. Knepley cgeom.invJ = &fgeom->suppInvJ[0][e*Np*dE*dE]; 3197132c3f7SMatthew G. Knepley cgeom.detJ = &fgeom->suppDetJ[0][e*Np]; 3204bee2e38SMatthew G. Knepley } 321afe6d6adSToby Isaac for (q = 0; q < Nq; ++q) { 322afe6d6adSToby Isaac PetscScalar integrand; 3234bee2e38SMatthew G. Knepley PetscReal w; 324afe6d6adSToby Isaac 325afe6d6adSToby Isaac if (isAffine) { 3267132c3f7SMatthew G. Knepley CoordinatesRefToReal(dE, dim-1, fegeom.xi, &fgeom->v[e*Np*dE], fegeom.J, &quadPoints[q*(dim-1)], x); 327afe6d6adSToby Isaac } else { 3283fe841f2SMatthew G. Knepley fegeom.v = &fgeom->v[(e*Np+q)*dE]; 3299f209ee4SMatthew G. Knepley fegeom.J = &fgeom->J[(e*Np+q)*dE*dE]; 3309f209ee4SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[(e*Np+q)*dE*dE]; 3314bee2e38SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e*Np+q]; 3324bee2e38SMatthew G. Knepley fegeom.n = &fgeom->n[(e*Np+q)*dE]; 3339f209ee4SMatthew G. Knepley 3349f209ee4SMatthew G. Knepley cgeom.J = &fgeom->suppJ[0][(e*Np+q)*dE*dE]; 3359f209ee4SMatthew G. Knepley cgeom.invJ = &fgeom->suppInvJ[0][(e*Np+q)*dE*dE]; 3369f209ee4SMatthew G. Knepley cgeom.detJ = &fgeom->suppDetJ[0][e*Np+q]; 337afe6d6adSToby Isaac } 3384bee2e38SMatthew G. Knepley w = fegeom.detJ[0]*quadWeights[q]; 339afe6d6adSToby Isaac if (debug > 1 && q < Np) { 340*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " detJ: %g\n", fegeom.detJ[0])); 341afe6d6adSToby Isaac #ifndef PETSC_USE_COMPLEX 342*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPrintCellMatrix(e, "invJ", dim, dim, fegeom.invJ)); 343afe6d6adSToby Isaac #endif 344afe6d6adSToby Isaac } 345*5f80ce2aSJacob Faibussowitsch if (debug > 1) CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " quad point %d\n", q)); 346*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEEvaluateFieldJets_Internal(ds, Nf, face, q, Tf, &cgeom, &coefficients[cOffset], NULL, u, u_x, NULL)); 347*5f80ce2aSJacob Faibussowitsch if (dsAux) CHKERRQ(PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, face, q, TfAux, &cgeom, &coefficientsAux[cOffsetAux], NULL, a, a_x, NULL)); 3484bee2e38SMatthew G. Knepley obj_func(dim, Nf, NfAux, uOff, uOff_x, u, NULL, u_x, aOff, aOff_x, a, NULL, a_x, 0.0, fegeom.v, fegeom.n, numConstants, constants, &integrand); 3494bee2e38SMatthew G. Knepley integrand *= w; 350afe6d6adSToby Isaac integral[e*Nf+field] += integrand; 351*5f80ce2aSJacob Faibussowitsch if (debug > 1) CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " int: %g %g\n", (double) PetscRealPart(integrand), (double) PetscRealPart(integral[e*Nf+field]))); 352afe6d6adSToby Isaac } 353afe6d6adSToby Isaac cOffset += totDim; 354afe6d6adSToby Isaac cOffsetAux += totDimAux; 355afe6d6adSToby Isaac } 356afe6d6adSToby Isaac PetscFunctionReturn(0); 357afe6d6adSToby Isaac } 358afe6d6adSToby Isaac 35906ad1575SMatthew G. Knepley PetscErrorCode PetscFEIntegrateResidual_Basic(PetscDS ds, PetscFormKey key, PetscInt Ne, PetscFEGeom *cgeom, 3604bee2e38SMatthew G. Knepley const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscReal t, PetscScalar elemVec[]) 36120cf1dd8SToby Isaac { 36220cf1dd8SToby Isaac const PetscInt debug = 0; 3636528b96dSMatthew G. Knepley const PetscInt field = key.field; 3644bee2e38SMatthew G. Knepley PetscFE fe; 3656528b96dSMatthew G. Knepley PetscWeakForm wf; 3666528b96dSMatthew G. Knepley PetscInt n0, n1, i; 3676528b96dSMatthew G. Knepley PetscPointFunc *f0_func, *f1_func; 36820cf1dd8SToby Isaac PetscQuadrature quad; 369ef0bb6c7SMatthew G. Knepley PetscTabulation *T, *TAux = NULL; 3704bee2e38SMatthew G. Knepley PetscScalar *f0, *f1, *u, *u_t = NULL, *u_x, *a, *a_x, *basisReal, *basisDerReal; 37120cf1dd8SToby Isaac const PetscScalar *constants; 37220cf1dd8SToby Isaac PetscReal *x; 373ef0bb6c7SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL; 374ef0bb6c7SMatthew G. Knepley PetscInt dim, numConstants, Nf, NfAux = 0, totDim, totDimAux = 0, cOffset = 0, cOffsetAux = 0, fOffset, e; 37520cf1dd8SToby Isaac const PetscReal *quadPoints, *quadWeights; 3766587ee25SMatthew G. Knepley PetscInt qdim, qNc, Nq, q, dE; 37720cf1dd8SToby Isaac 37820cf1dd8SToby Isaac PetscFunctionBegin; 379*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(ds, field, (PetscObject *) &fe)); 380*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetSpatialDimension(fe, &dim)); 381*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetQuadrature(fe, &quad)); 382*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(ds, &Nf)); 383*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTotalDimension(ds, &totDim)); 384*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentOffsets(ds, &uOff)); 385*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentDerivativeOffsets(ds, &uOff_x)); 386*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetFieldOffset(ds, field, &fOffset)); 387*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetWeakForm(ds, &wf)); 388*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscWeakFormGetResidual(wf, key.label, key.value, key.field, key.part, &n0, &f0_func, &n1, &f1_func)); 3896528b96dSMatthew G. Knepley if (!n0 && !n1) PetscFunctionReturn(0); 390*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetEvaluationArrays(ds, &u, coefficients_t ? &u_t : NULL, &u_x)); 391*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetWorkspace(ds, &x, &basisReal, &basisDerReal, NULL, NULL)); 392*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetWeakFormArrays(ds, &f0, &f1, NULL, NULL, NULL, NULL)); 393*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTabulation(ds, &T)); 394*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetConstants(ds, &numConstants, &constants)); 3954bee2e38SMatthew G. Knepley if (dsAux) { 396*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(dsAux, &NfAux)); 397*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTotalDimension(dsAux, &totDimAux)); 398*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentOffsets(dsAux, &aOff)); 399*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x)); 400*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetEvaluationArrays(dsAux, &a, NULL, &a_x)); 401*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTabulation(dsAux, &TAux)); 4022c71b3e2SJacob Faibussowitsch PetscCheckFalse(T[0]->Np != TAux[0]->Np,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Number of tabulation points %D != %D number of auxiliary tabulation points", T[0]->Np, TAux[0]->Np); 40320cf1dd8SToby Isaac } 404*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetData(quad, &qdim, &qNc, &Nq, &quadPoints, &quadWeights)); 4052c71b3e2SJacob Faibussowitsch PetscCheckFalse(qNc != 1,PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supports scalar quadrature, not %D components", qNc); 40620cf1dd8SToby Isaac dE = cgeom->dimEmbed; 4072c71b3e2SJacob Faibussowitsch PetscCheckFalse(cgeom->dim != qdim,PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "FEGeom dim %D != %D quadrature dim", cgeom->dim, qdim); 40820cf1dd8SToby Isaac for (e = 0; e < Ne; ++e) { 4094bee2e38SMatthew G. Knepley PetscFEGeom fegeom; 41020cf1dd8SToby Isaac 4116587ee25SMatthew G. Knepley fegeom.v = x; /* workspace */ 412*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(f0, Nq*T[field]->Nc)); 413*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(f1, Nq*T[field]->Nc*dE)); 41420cf1dd8SToby Isaac for (q = 0; q < Nq; ++q) { 4154bee2e38SMatthew G. Knepley PetscReal w; 4164bee2e38SMatthew G. Knepley PetscInt c, d; 41720cf1dd8SToby Isaac 418*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGeomGetPoint(cgeom, e, q, &quadPoints[q*cgeom->dim], &fegeom)); 4194bee2e38SMatthew G. Knepley w = fegeom.detJ[0]*quadWeights[q]; 4206587ee25SMatthew G. Knepley if (debug > 1 && q < cgeom->numPoints) { 421*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " detJ: %g\n", fegeom.detJ[0])); 4227be5e748SToby Isaac #if !defined(PETSC_USE_COMPLEX) 423*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPrintCellMatrix(e, "invJ", dim, dim, fegeom.invJ)); 42420cf1dd8SToby Isaac #endif 42520cf1dd8SToby Isaac } 426*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEEvaluateFieldJets_Internal(ds, Nf, 0, q, T, &fegeom, &coefficients[cOffset], &coefficients_t[cOffset], u, u_x, u_t)); 427*5f80ce2aSJacob Faibussowitsch if (dsAux) CHKERRQ(PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, 0, q, TAux, &fegeom, &coefficientsAux[cOffsetAux], NULL, a, a_x, NULL)); 4286528b96dSMatthew G. Knepley for (i = 0; i < n0; ++i) f0_func[i](dim, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, NULL, a_x, t, fegeom.v, numConstants, constants, &f0[q*T[field]->Nc]); 429ef0bb6c7SMatthew G. Knepley for (c = 0; c < T[field]->Nc; ++c) f0[q*T[field]->Nc+c] *= w; 4306528b96dSMatthew G. Knepley for (i = 0; i < n1; ++i) f1_func[i](dim, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, NULL, a_x, t, fegeom.v, numConstants, constants, &f1[q*T[field]->Nc*dim]); 431ef0bb6c7SMatthew G. Knepley for (c = 0; c < T[field]->Nc; ++c) for (d = 0; d < dim; ++d) f1[(q*T[field]->Nc+c)*dim+d] *= w; 432b8025e53SMatthew G. Knepley if (debug) { 433*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " quad point %d wt %g\n", q, quadWeights[q])); 434b8025e53SMatthew G. Knepley if (debug > 2) { 435*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " field %d:", field)); 436*5f80ce2aSJacob Faibussowitsch for (c = 0; c < T[field]->Nc; ++c) CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " %g", u[uOff[field]+c])); 437*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, "\n")); 438*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " resid %d:", field)); 439*5f80ce2aSJacob Faibussowitsch for (c = 0; c < T[field]->Nc; ++c) CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " %g", f0[q*T[field]->Nc+c])); 440*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, "\n")); 441b8025e53SMatthew G. Knepley } 442b8025e53SMatthew G. Knepley } 44320cf1dd8SToby Isaac } 444*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEUpdateElementVec_Internal(fe, T[field], 0, basisReal, basisDerReal, e, cgeom, f0, f1, &elemVec[cOffset+fOffset])); 44520cf1dd8SToby Isaac cOffset += totDim; 44620cf1dd8SToby Isaac cOffsetAux += totDimAux; 44720cf1dd8SToby Isaac } 44820cf1dd8SToby Isaac PetscFunctionReturn(0); 44920cf1dd8SToby Isaac } 45020cf1dd8SToby Isaac 45106ad1575SMatthew G. Knepley PetscErrorCode PetscFEIntegrateBdResidual_Basic(PetscDS ds, PetscWeakForm wf, PetscFormKey key, PetscInt Ne, PetscFEGeom *fgeom, 4524bee2e38SMatthew G. Knepley const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscReal t, PetscScalar elemVec[]) 45320cf1dd8SToby Isaac { 45420cf1dd8SToby Isaac const PetscInt debug = 0; 45506d8a0d3SMatthew G. Knepley const PetscInt field = key.field; 4564bee2e38SMatthew G. Knepley PetscFE fe; 45706d8a0d3SMatthew G. Knepley PetscInt n0, n1, i; 45806d8a0d3SMatthew G. Knepley PetscBdPointFunc *f0_func, *f1_func; 45920cf1dd8SToby Isaac PetscQuadrature quad; 460ef0bb6c7SMatthew G. Knepley PetscTabulation *Tf, *TfAux = NULL; 4614bee2e38SMatthew G. Knepley PetscScalar *f0, *f1, *u, *u_t = NULL, *u_x, *a, *a_x, *basisReal, *basisDerReal; 46220cf1dd8SToby Isaac const PetscScalar *constants; 46320cf1dd8SToby Isaac PetscReal *x; 464ef0bb6c7SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL; 465ef0bb6c7SMatthew G. Knepley PetscInt dim, dimAux, numConstants, Nf, NfAux = 0, totDim, totDimAux = 0, cOffset = 0, cOffsetAux = 0, fOffset, e, NcI; 4666587ee25SMatthew G. Knepley PetscBool auxOnBd = PETSC_FALSE; 46720cf1dd8SToby Isaac const PetscReal *quadPoints, *quadWeights; 4686587ee25SMatthew G. Knepley PetscInt qdim, qNc, Nq, q, dE; 46920cf1dd8SToby Isaac 47020cf1dd8SToby Isaac PetscFunctionBegin; 471*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(ds, field, (PetscObject *) &fe)); 472*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetSpatialDimension(fe, &dim)); 473*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetFaceQuadrature(fe, &quad)); 474*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(ds, &Nf)); 475*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTotalDimension(ds, &totDim)); 476*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentOffsets(ds, &uOff)); 477*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentDerivativeOffsets(ds, &uOff_x)); 478*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetFieldOffset(ds, field, &fOffset)); 479*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscWeakFormGetBdResidual(wf, key.label, key.value, key.field, key.part, &n0, &f0_func, &n1, &f1_func)); 48006d8a0d3SMatthew G. Knepley if (!n0 && !n1) PetscFunctionReturn(0); 481*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetEvaluationArrays(ds, &u, coefficients_t ? &u_t : NULL, &u_x)); 482*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetWorkspace(ds, &x, &basisReal, &basisDerReal, NULL, NULL)); 483*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetWeakFormArrays(ds, &f0, &f1, NULL, NULL, NULL, NULL)); 484*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetFaceTabulation(ds, &Tf)); 485*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetConstants(ds, &numConstants, &constants)); 4864bee2e38SMatthew G. Knepley if (dsAux) { 487*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetSpatialDimension(dsAux, &dimAux)); 488*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(dsAux, &NfAux)); 489*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTotalDimension(dsAux, &totDimAux)); 490*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentOffsets(dsAux, &aOff)); 491*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x)); 492*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetEvaluationArrays(dsAux, &a, NULL, &a_x)); 4937be5e748SToby Isaac auxOnBd = dimAux < dim ? PETSC_TRUE : PETSC_FALSE; 494*5f80ce2aSJacob Faibussowitsch if (auxOnBd) CHKERRQ(PetscDSGetTabulation(dsAux, &TfAux)); 495*5f80ce2aSJacob Faibussowitsch else CHKERRQ(PetscDSGetFaceTabulation(dsAux, &TfAux)); 4962c71b3e2SJacob Faibussowitsch PetscCheckFalse(Tf[0]->Np != TfAux[0]->Np,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Number of tabulation points %D != %D number of auxiliary tabulation points", Tf[0]->Np, TfAux[0]->Np); 49720cf1dd8SToby Isaac } 498ef0bb6c7SMatthew G. Knepley NcI = Tf[field]->Nc; 499*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetData(quad, &qdim, &qNc, &Nq, &quadPoints, &quadWeights)); 5002c71b3e2SJacob Faibussowitsch PetscCheckFalse(qNc != 1,PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supports scalar quadrature, not %D components", qNc); 50120cf1dd8SToby Isaac dE = fgeom->dimEmbed; 5026587ee25SMatthew G. Knepley /* TODO FIX THIS */ 5036587ee25SMatthew G. Knepley fgeom->dim = dim-1; 5042c71b3e2SJacob Faibussowitsch PetscCheckFalse(fgeom->dim != qdim,PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "FEGeom dim %D != %D quadrature dim", fgeom->dim, qdim); 50520cf1dd8SToby Isaac for (e = 0; e < Ne; ++e) { 5069f209ee4SMatthew G. Knepley PetscFEGeom fegeom, cgeom; 50720cf1dd8SToby Isaac const PetscInt face = fgeom->face[e][0]; 5089f209ee4SMatthew G. Knepley 5096587ee25SMatthew G. Knepley fegeom.v = x; /* Workspace */ 510*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(f0, Nq*NcI)); 511*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(f1, Nq*NcI*dE)); 51220cf1dd8SToby Isaac for (q = 0; q < Nq; ++q) { 5134bee2e38SMatthew G. Knepley PetscReal w; 5144bee2e38SMatthew G. Knepley PetscInt c, d; 5154bee2e38SMatthew G. Knepley 516*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGeomGetPoint(fgeom, e, q, &quadPoints[q*fgeom->dim], &fegeom)); 517*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGeomGetCellPoint(fgeom, e, q, &cgeom)); 5184bee2e38SMatthew G. Knepley w = fegeom.detJ[0]*quadWeights[q]; 51962bd480fSMatthew G. Knepley if (debug > 1) { 5206587ee25SMatthew G. Knepley if ((fgeom->isAffine && q == 0) || (!fgeom->isAffine)) { 521*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " detJ: %g\n", fegeom.detJ[0])); 5227be5e748SToby Isaac #if !defined(PETSC_USE_COMPLEX) 523*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPrintCellMatrix(e, "invJ", dim, dim, fegeom.invJ)); 524*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPrintCellVector(e, "n", dim, fegeom.n)); 52520cf1dd8SToby Isaac #endif 52620cf1dd8SToby Isaac } 52762bd480fSMatthew G. Knepley } 528*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEEvaluateFieldJets_Internal(ds, Nf, face, q, Tf, &cgeom, &coefficients[cOffset], &coefficients_t[cOffset], u, u_x, u_t)); 529*5f80ce2aSJacob Faibussowitsch if (dsAux) CHKERRQ(PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, auxOnBd ? 0 : face, q, TfAux, &cgeom, &coefficientsAux[cOffsetAux], NULL, a, a_x, NULL)); 53006d8a0d3SMatthew G. Knepley for (i = 0; i < n0; ++i) f0_func[i](dim, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, NULL, a_x, t, fegeom.v, fegeom.n, numConstants, constants, &f0[q*NcI]); 5314bee2e38SMatthew G. Knepley for (c = 0; c < NcI; ++c) f0[q*NcI+c] *= w; 53206d8a0d3SMatthew G. Knepley for (i = 0; i < n1; ++i) f1_func[i](dim, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, NULL, a_x, t, fegeom.v, fegeom.n, numConstants, constants, &f1[q*NcI*dim]); 5334bee2e38SMatthew G. Knepley for (c = 0; c < NcI; ++c) for (d = 0; d < dim; ++d) f1[(q*NcI+c)*dim+d] *= w; 53462bd480fSMatthew G. Knepley if (debug) { 535*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " elem %D quad point %d\n", e, q)); 53662bd480fSMatthew G. Knepley for (c = 0; c < NcI; ++c) { 537*5f80ce2aSJacob Faibussowitsch if (n0) CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " f0[%D] %g\n", c, f0[q*NcI+c])); 53862bd480fSMatthew G. Knepley if (n1) { 539*5f80ce2aSJacob Faibussowitsch for (d = 0; d < dim; ++d) CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " f1[%D,%D] %g", c, d, f1[(q*NcI + c)*dim + d])); 540*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, "\n")); 54162bd480fSMatthew G. Knepley } 54262bd480fSMatthew G. Knepley } 54362bd480fSMatthew G. Knepley } 54420cf1dd8SToby Isaac } 545*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEUpdateElementVec_Internal(fe, Tf[field], face, basisReal, basisDerReal, e, fgeom, f0, f1, &elemVec[cOffset+fOffset])); 54620cf1dd8SToby Isaac cOffset += totDim; 54720cf1dd8SToby Isaac cOffsetAux += totDimAux; 54820cf1dd8SToby Isaac } 54920cf1dd8SToby Isaac PetscFunctionReturn(0); 55020cf1dd8SToby Isaac } 55120cf1dd8SToby Isaac 55227f02ce8SMatthew G. Knepley /* 55327f02ce8SMatthew G. Knepley BdIntegral: Operates completely in the embedding dimension. The trick is to have special "face quadrature" so we only integrate over the face, but 55427f02ce8SMatthew G. Knepley all transforms operate in the full space and are square. 55527f02ce8SMatthew G. Knepley 55627f02ce8SMatthew G. Knepley HybridIntegral: The discretization is lower dimensional. That means the transforms are non-square. 55727f02ce8SMatthew G. Knepley 1) DMPlexGetCellFields() retrieves from the hybrid cell, so it gets fields from both faces 55827f02ce8SMatthew G. Knepley 2) We need to assume that the orientation is 0 for both 55927f02ce8SMatthew G. Knepley 3) TODO We need to use a non-square Jacobian for the derivative maps, meaning the embedding dimension has to go to EvaluateFieldJets() and UpdateElementVec() 56027f02ce8SMatthew G. Knepley */ 561c2b7495fSMatthew G. Knepley static PetscErrorCode PetscFEIntegrateHybridResidual_Basic(PetscDS ds, PetscFormKey key, PetscInt s, PetscInt Ne, PetscFEGeom *fgeom, 56227f02ce8SMatthew G. Knepley const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscReal t, PetscScalar elemVec[]) 56327f02ce8SMatthew G. Knepley { 56427f02ce8SMatthew G. Knepley const PetscInt debug = 0; 5656528b96dSMatthew G. Knepley const PetscInt field = key.field; 56627f02ce8SMatthew G. Knepley PetscFE fe; 5676528b96dSMatthew G. Knepley PetscWeakForm wf; 5686528b96dSMatthew G. Knepley PetscInt n0, n1, i; 5696528b96dSMatthew G. Knepley PetscBdPointFunc *f0_func, *f1_func; 57027f02ce8SMatthew G. Knepley PetscQuadrature quad; 571665f567fSMatthew G. Knepley PetscTabulation *Tf, *TfAux = NULL; 57227f02ce8SMatthew G. Knepley PetscScalar *f0, *f1, *u, *u_t = NULL, *u_x, *a, *a_x, *basisReal, *basisDerReal; 57327f02ce8SMatthew G. Knepley const PetscScalar *constants; 57427f02ce8SMatthew G. Knepley PetscReal *x; 575665f567fSMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL; 576665f567fSMatthew G. Knepley PetscInt dim, dimAux, numConstants, Nf, NfAux = 0, totDim, totDimAux = 0, cOffset = 0, cOffsetAux = 0, fOffset, e, NcI, NcS; 5776587ee25SMatthew G. Knepley PetscBool isCohesiveField, auxOnBd = PETSC_FALSE; 57827f02ce8SMatthew G. Knepley const PetscReal *quadPoints, *quadWeights; 5796587ee25SMatthew G. Knepley PetscInt qdim, qNc, Nq, q, dE; 58027f02ce8SMatthew G. Knepley 58127f02ce8SMatthew G. Knepley PetscFunctionBegin; 58227f02ce8SMatthew G. Knepley /* Hybrid discretization is posed directly on faces */ 583*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(ds, field, (PetscObject *) &fe)); 584*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetSpatialDimension(fe, &dim)); 585*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetQuadrature(fe, &quad)); 586*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(ds, &Nf)); 587*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTotalDimension(ds, &totDim)); 588*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentOffsetsCohesive(ds, s, &uOff)); 589*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentDerivativeOffsetsCohesive(ds, s, &uOff_x)); 590*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetFieldOffsetCohesive(ds, field, &fOffset)); 591*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetWeakForm(ds, &wf)); 592*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscWeakFormGetBdResidual(wf, key.label, key.value, key.field, key.part, &n0, &f0_func, &n1, &f1_func)); 5936528b96dSMatthew G. Knepley if (!n0 && !n1) PetscFunctionReturn(0); 594*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetEvaluationArrays(ds, &u, coefficients_t ? &u_t : NULL, &u_x)); 595*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetWorkspace(ds, &x, &basisReal, &basisDerReal, NULL, NULL)); 596*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetWeakFormArrays(ds, &f0, &f1, NULL, NULL, NULL, NULL)); 59727f02ce8SMatthew G. Knepley /* NOTE This is a bulk tabulation because the DS is a face discretization */ 598*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTabulation(ds, &Tf)); 599*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetConstants(ds, &numConstants, &constants)); 60027f02ce8SMatthew G. Knepley if (dsAux) { 601*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetSpatialDimension(dsAux, &dimAux)); 602*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(dsAux, &NfAux)); 603*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTotalDimension(dsAux, &totDimAux)); 604*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentOffsets(dsAux, &aOff)); 605*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x)); 606*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetEvaluationArrays(dsAux, &a, NULL, &a_x)); 60701907d53SMatthew G. Knepley auxOnBd = dimAux == dim ? PETSC_TRUE : PETSC_FALSE; 608*5f80ce2aSJacob Faibussowitsch if (auxOnBd) CHKERRQ(PetscDSGetTabulation(dsAux, &TfAux)); 609*5f80ce2aSJacob Faibussowitsch else CHKERRQ(PetscDSGetFaceTabulation(dsAux, &TfAux)); 6102c71b3e2SJacob Faibussowitsch PetscCheckFalse(Tf[0]->Np != TfAux[0]->Np,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Number of tabulation points %D != %D number of auxiliary tabulation points", Tf[0]->Np, TfAux[0]->Np); 61127f02ce8SMatthew G. Knepley } 612*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetCohesive(ds, field, &isCohesiveField)); 613665f567fSMatthew G. Knepley NcI = Tf[field]->Nc; 614c2b7495fSMatthew G. Knepley NcS = NcI; 615*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetData(quad, &qdim, &qNc, &Nq, &quadPoints, &quadWeights)); 6162c71b3e2SJacob Faibussowitsch PetscCheckFalse(qNc != 1,PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supports scalar quadrature, not %D components", qNc); 61727f02ce8SMatthew G. Knepley dE = fgeom->dimEmbed; 6182c71b3e2SJacob Faibussowitsch PetscCheckFalse(fgeom->dim != qdim,PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "FEGeom dim %D != %D quadrature dim", fgeom->dim, qdim); 61927f02ce8SMatthew G. Knepley for (e = 0; e < Ne; ++e) { 62027f02ce8SMatthew G. Knepley PetscFEGeom fegeom; 62127f02ce8SMatthew G. Knepley const PetscInt face = fgeom->face[e][0]; 62227f02ce8SMatthew G. Knepley 6236587ee25SMatthew G. Knepley fegeom.v = x; /* Workspace */ 624*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(f0, Nq*NcS)); 625*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(f1, Nq*NcS*dE)); 62627f02ce8SMatthew G. Knepley for (q = 0; q < Nq; ++q) { 62727f02ce8SMatthew G. Knepley PetscReal w; 62827f02ce8SMatthew G. Knepley PetscInt c, d; 62927f02ce8SMatthew G. Knepley 630*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGeomGetPoint(fgeom, e, q, &quadPoints[q*fgeom->dim], &fegeom)); 63127f02ce8SMatthew G. Knepley w = fegeom.detJ[0]*quadWeights[q]; 6326587ee25SMatthew G. Knepley if (debug > 1 && q < fgeom->numPoints) { 633*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " detJ: %g\n", fegeom.detJ[0])); 63427f02ce8SMatthew G. Knepley #if !defined(PETSC_USE_COMPLEX) 635*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPrintCellMatrix(e, "invJ", dim, dE, fegeom.invJ)); 63627f02ce8SMatthew G. Knepley #endif 63727f02ce8SMatthew G. Knepley } 638*5f80ce2aSJacob Faibussowitsch if (debug) CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " quad point %d\n", q)); 63927f02ce8SMatthew G. Knepley /* TODO Is this cell or face quadrature, meaning should we use 'q' or 'face*Nq+q' */ 640*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEEvaluateFieldJets_Hybrid_Internal(ds, Nf, 0, q, Tf, &fegeom, &coefficients[cOffset], &coefficients_t[cOffset], u, u_x, u_t)); 641*5f80ce2aSJacob Faibussowitsch if (dsAux) CHKERRQ(PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, 0, auxOnBd ? q : face*Nq+q, TfAux, &fegeom, &coefficientsAux[cOffsetAux], NULL, a, a_x, NULL)); 6426528b96dSMatthew G. Knepley for (i = 0; i < n0; ++i) f0_func[i](dim, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, NULL, a_x, t, fegeom.v, fegeom.n, numConstants, constants, &f0[q*NcS]); 64327f02ce8SMatthew G. Knepley for (c = 0; c < NcS; ++c) f0[q*NcS+c] *= w; 6449ee2af8cSMatthew G. Knepley for (i = 0; i < n1; ++i) f1_func[i](dim, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, NULL, a_x, t, fegeom.v, fegeom.n, numConstants, constants, &f1[q*NcS*dE]); 6459ee2af8cSMatthew G. Knepley for (c = 0; c < NcS; ++c) for (d = 0; d < dE; ++d) f1[(q*NcS+c)*dE+d] *= w; 64627f02ce8SMatthew G. Knepley } 6475fedec97SMatthew G. Knepley if (isCohesiveField) {PetscFEUpdateElementVec_Internal(fe, Tf[field], 0, basisReal, basisDerReal, e, fgeom, f0, f1, &elemVec[cOffset+fOffset]);} 6485fedec97SMatthew G. Knepley else {PetscFEUpdateElementVec_Hybrid_Internal(fe, Tf[field], 0, s, basisReal, basisDerReal, fgeom, f0, f1, &elemVec[cOffset+fOffset]);} 64927f02ce8SMatthew G. Knepley cOffset += totDim; 65027f02ce8SMatthew G. Knepley cOffsetAux += totDimAux; 65127f02ce8SMatthew G. Knepley } 65227f02ce8SMatthew G. Knepley PetscFunctionReturn(0); 65327f02ce8SMatthew G. Knepley } 65427f02ce8SMatthew G. Knepley 65506ad1575SMatthew G. Knepley PetscErrorCode PetscFEIntegrateJacobian_Basic(PetscDS ds, PetscFEJacobianType jtype, PetscFormKey key, PetscInt Ne, PetscFEGeom *cgeom, 6564bee2e38SMatthew G. Knepley const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscReal t, PetscReal u_tshift, PetscScalar elemMat[]) 65720cf1dd8SToby Isaac { 65820cf1dd8SToby Isaac const PetscInt debug = 0; 6594bee2e38SMatthew G. Knepley PetscFE feI, feJ; 6606528b96dSMatthew G. Knepley PetscWeakForm wf; 6616528b96dSMatthew G. Knepley PetscPointJac *g0_func, *g1_func, *g2_func, *g3_func; 6626528b96dSMatthew G. Knepley PetscInt n0, n1, n2, n3, i; 66320cf1dd8SToby Isaac PetscInt cOffset = 0; /* Offset into coefficients[] for element e */ 66420cf1dd8SToby Isaac PetscInt cOffsetAux = 0; /* Offset into coefficientsAux[] for element e */ 66520cf1dd8SToby Isaac PetscInt eOffset = 0; /* Offset into elemMat[] for element e */ 66620cf1dd8SToby Isaac PetscInt offsetI = 0; /* Offset into an element vector for fieldI */ 66720cf1dd8SToby Isaac PetscInt offsetJ = 0; /* Offset into an element vector for fieldJ */ 66820cf1dd8SToby Isaac PetscQuadrature quad; 669ef0bb6c7SMatthew G. Knepley PetscTabulation *T, *TAux = NULL; 6704bee2e38SMatthew G. Knepley PetscScalar *g0, *g1, *g2, *g3, *u, *u_t = NULL, *u_x, *a, *a_x, *basisReal, *basisDerReal, *testReal, *testDerReal; 67120cf1dd8SToby Isaac const PetscScalar *constants; 67220cf1dd8SToby Isaac PetscReal *x; 673ef0bb6c7SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL; 674ef0bb6c7SMatthew G. Knepley PetscInt NcI = 0, NcJ = 0; 6756528b96dSMatthew G. Knepley PetscInt dim, numConstants, Nf, fieldI, fieldJ, NfAux = 0, totDim, totDimAux = 0, e; 67620cf1dd8SToby Isaac PetscInt dE, Np; 67720cf1dd8SToby Isaac PetscBool isAffine; 67820cf1dd8SToby Isaac const PetscReal *quadPoints, *quadWeights; 67920cf1dd8SToby Isaac PetscInt qNc, Nq, q; 68020cf1dd8SToby Isaac 68120cf1dd8SToby Isaac PetscFunctionBegin; 682*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(ds, &Nf)); 6836528b96dSMatthew G. Knepley fieldI = key.field / Nf; 6846528b96dSMatthew G. Knepley fieldJ = key.field % Nf; 685*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(ds, fieldI, (PetscObject *) &feI)); 686*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(ds, fieldJ, (PetscObject *) &feJ)); 687*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetSpatialDimension(feI, &dim)); 688*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetQuadrature(feI, &quad)); 689*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTotalDimension(ds, &totDim)); 690*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentOffsets(ds, &uOff)); 691*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentDerivativeOffsets(ds, &uOff_x)); 692*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetWeakForm(ds, &wf)); 69320cf1dd8SToby Isaac switch(jtype) { 694*5f80ce2aSJacob Faibussowitsch case PETSCFE_JACOBIAN_DYN: CHKERRQ(PetscWeakFormGetDynamicJacobian(wf, key.label, key.value, fieldI, fieldJ, key.part, &n0, &g0_func, &n1, &g1_func, &n2, &g2_func, &n3, &g3_func));break; 695*5f80ce2aSJacob Faibussowitsch case PETSCFE_JACOBIAN_PRE: CHKERRQ(PetscWeakFormGetJacobianPreconditioner(wf, key.label, key.value, fieldI, fieldJ, key.part, &n0, &g0_func, &n1, &g1_func, &n2, &g2_func, &n3, &g3_func));break; 696*5f80ce2aSJacob Faibussowitsch case PETSCFE_JACOBIAN: CHKERRQ(PetscWeakFormGetJacobian(wf, key.label, key.value, fieldI, fieldJ, key.part, &n0, &g0_func, &n1, &g1_func, &n2, &g2_func, &n3, &g3_func));break; 69720cf1dd8SToby Isaac } 6986528b96dSMatthew G. Knepley if (!n0 && !n1 && !n2 && !n3) PetscFunctionReturn(0); 699*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetEvaluationArrays(ds, &u, coefficients_t ? &u_t : NULL, &u_x)); 700*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetWorkspace(ds, &x, &basisReal, &basisDerReal, &testReal, &testDerReal)); 701*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetWeakFormArrays(ds, NULL, NULL, &g0, &g1, &g2, &g3)); 702*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTabulation(ds, &T)); 703*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetFieldOffset(ds, fieldI, &offsetI)); 704*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetFieldOffset(ds, fieldJ, &offsetJ)); 705*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetConstants(ds, &numConstants, &constants)); 7064bee2e38SMatthew G. Knepley if (dsAux) { 707*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(dsAux, &NfAux)); 708*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTotalDimension(dsAux, &totDimAux)); 709*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentOffsets(dsAux, &aOff)); 710*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x)); 711*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetEvaluationArrays(dsAux, &a, NULL, &a_x)); 712*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTabulation(dsAux, &TAux)); 7132c71b3e2SJacob Faibussowitsch PetscCheckFalse(T[0]->Np != TAux[0]->Np,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Number of tabulation points %D != %D number of auxiliary tabulation points", T[0]->Np, TAux[0]->Np); 71420cf1dd8SToby Isaac } 71527f02ce8SMatthew G. Knepley NcI = T[fieldI]->Nc; 71627f02ce8SMatthew G. Knepley NcJ = T[fieldJ]->Nc; 7174bee2e38SMatthew G. Knepley Np = cgeom->numPoints; 7184bee2e38SMatthew G. Knepley dE = cgeom->dimEmbed; 7194bee2e38SMatthew G. Knepley isAffine = cgeom->isAffine; 72027f02ce8SMatthew G. Knepley /* Initialize here in case the function is not defined */ 721*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g0, NcI*NcJ)); 722*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g1, NcI*NcJ*dE)); 723*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g2, NcI*NcJ*dE)); 724*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g3, NcI*NcJ*dE*dE)); 725*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetData(quad, NULL, &qNc, &Nq, &quadPoints, &quadWeights)); 7262c71b3e2SJacob Faibussowitsch PetscCheckFalse(qNc != 1,PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supports scalar quadrature, not %D components", qNc); 7274bee2e38SMatthew G. Knepley for (e = 0; e < Ne; ++e) { 7284bee2e38SMatthew G. Knepley PetscFEGeom fegeom; 7294bee2e38SMatthew G. Knepley 73027f02ce8SMatthew G. Knepley fegeom.dim = cgeom->dim; 73127f02ce8SMatthew G. Knepley fegeom.dimEmbed = cgeom->dimEmbed; 7324bee2e38SMatthew G. Knepley if (isAffine) { 7334bee2e38SMatthew G. Knepley fegeom.v = x; 7344bee2e38SMatthew G. Knepley fegeom.xi = cgeom->xi; 7357132c3f7SMatthew G. Knepley fegeom.J = &cgeom->J[e*Np*dE*dE]; 7367132c3f7SMatthew G. Knepley fegeom.invJ = &cgeom->invJ[e*Np*dE*dE]; 7377132c3f7SMatthew G. Knepley fegeom.detJ = &cgeom->detJ[e*Np]; 7384bee2e38SMatthew G. Knepley } 73920cf1dd8SToby Isaac for (q = 0; q < Nq; ++q) { 74020cf1dd8SToby Isaac PetscReal w; 7414bee2e38SMatthew G. Knepley PetscInt c; 74220cf1dd8SToby Isaac 74320cf1dd8SToby Isaac if (isAffine) { 7447132c3f7SMatthew G. Knepley CoordinatesRefToReal(dE, dim, fegeom.xi, &cgeom->v[e*Np*dE], fegeom.J, &quadPoints[q*dim], x); 74520cf1dd8SToby Isaac } else { 7464bee2e38SMatthew G. Knepley fegeom.v = &cgeom->v[(e*Np+q)*dE]; 7474bee2e38SMatthew G. Knepley fegeom.J = &cgeom->J[(e*Np+q)*dE*dE]; 7484bee2e38SMatthew G. Knepley fegeom.invJ = &cgeom->invJ[(e*Np+q)*dE*dE]; 7494bee2e38SMatthew G. Knepley fegeom.detJ = &cgeom->detJ[e*Np+q]; 75020cf1dd8SToby Isaac } 751*5f80ce2aSJacob Faibussowitsch if (debug) CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " quad point %" PetscInt_FMT " weight %g detJ %g\n", q, (double) quadWeights[q], (double) fegeom.detJ[0])); 7524bee2e38SMatthew G. Knepley w = fegeom.detJ[0]*quadWeights[q]; 753*5f80ce2aSJacob Faibussowitsch if (coefficients) CHKERRQ(PetscFEEvaluateFieldJets_Internal(ds, Nf, 0, q, T, &fegeom, &coefficients[cOffset], &coefficients_t[cOffset], u, u_x, u_t)); 754*5f80ce2aSJacob Faibussowitsch if (dsAux) CHKERRQ(PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, 0, q, TAux, &fegeom, &coefficientsAux[cOffsetAux], NULL, a, a_x, NULL)); 755ea672e62SMatthew G. Knepley if (n0) { 756*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g0, NcI*NcJ)); 7576528b96dSMatthew G. Knepley for (i = 0; i < n0; ++i) g0_func[i](dim, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, NULL, a_x, t, u_tshift, fegeom.v, numConstants, constants, g0); 75820cf1dd8SToby Isaac for (c = 0; c < NcI*NcJ; ++c) g0[c] *= w; 75920cf1dd8SToby Isaac } 760ea672e62SMatthew G. Knepley if (n1) { 761*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g1, NcI*NcJ*dE)); 7626528b96dSMatthew G. Knepley for (i = 0; i < n1; ++i) g1_func[i](dim, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, NULL, a_x, t, u_tshift, fegeom.v, numConstants, constants, g1); 7634bee2e38SMatthew G. Knepley for (c = 0; c < NcI*NcJ*dim; ++c) g1[c] *= w; 76420cf1dd8SToby Isaac } 765ea672e62SMatthew G. Knepley if (n2) { 766*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g2, NcI*NcJ*dE)); 7676528b96dSMatthew G. Knepley for (i = 0; i < n2; ++i) g2_func[i](dim, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, NULL, a_x, t, u_tshift, fegeom.v, numConstants, constants, g2); 7684bee2e38SMatthew G. Knepley for (c = 0; c < NcI*NcJ*dim; ++c) g2[c] *= w; 76920cf1dd8SToby Isaac } 770ea672e62SMatthew G. Knepley if (n3) { 771*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g3, NcI*NcJ*dE*dE)); 7726528b96dSMatthew G. Knepley for (i = 0; i < n3; ++i) g3_func[i](dim, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, NULL, a_x, t, u_tshift, fegeom.v, numConstants, constants, g3); 7734bee2e38SMatthew G. Knepley for (c = 0; c < NcI*NcJ*dim*dim; ++c) g3[c] *= w; 77420cf1dd8SToby Isaac } 77520cf1dd8SToby Isaac 776*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEUpdateElementMat_Internal(feI, feJ, 0, q, T[fieldI], basisReal, basisDerReal, T[fieldJ], testReal, testDerReal, &fegeom, g0, g1, g2, g3, eOffset, totDim, offsetI, offsetJ, elemMat)); 77720cf1dd8SToby Isaac } 77820cf1dd8SToby Isaac if (debug > 1) { 77920cf1dd8SToby Isaac PetscInt fc, f, gc, g; 78020cf1dd8SToby Isaac 781*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, "Element matrix for fields %d and %d\n", fieldI, fieldJ)); 782ef0bb6c7SMatthew G. Knepley for (fc = 0; fc < T[fieldI]->Nc; ++fc) { 783ef0bb6c7SMatthew G. Knepley for (f = 0; f < T[fieldI]->Nb; ++f) { 784ef0bb6c7SMatthew G. Knepley const PetscInt i = offsetI + f*T[fieldI]->Nc+fc; 785ef0bb6c7SMatthew G. Knepley for (gc = 0; gc < T[fieldJ]->Nc; ++gc) { 786ef0bb6c7SMatthew G. Knepley for (g = 0; g < T[fieldJ]->Nb; ++g) { 787ef0bb6c7SMatthew G. Knepley const PetscInt j = offsetJ + g*T[fieldJ]->Nc+gc; 788*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " elemMat[%d,%d,%d,%d]: %g\n", f, fc, g, gc, PetscRealPart(elemMat[eOffset+i*totDim+j]))); 78920cf1dd8SToby Isaac } 79020cf1dd8SToby Isaac } 791*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, "\n")); 79220cf1dd8SToby Isaac } 79320cf1dd8SToby Isaac } 79420cf1dd8SToby Isaac } 79520cf1dd8SToby Isaac cOffset += totDim; 79620cf1dd8SToby Isaac cOffsetAux += totDimAux; 79720cf1dd8SToby Isaac eOffset += PetscSqr(totDim); 79820cf1dd8SToby Isaac } 79920cf1dd8SToby Isaac PetscFunctionReturn(0); 80020cf1dd8SToby Isaac } 80120cf1dd8SToby Isaac 80206ad1575SMatthew G. Knepley static PetscErrorCode PetscFEIntegrateBdJacobian_Basic(PetscDS ds, PetscWeakForm wf, PetscFormKey key, PetscInt Ne, PetscFEGeom *fgeom, 8034bee2e38SMatthew G. Knepley const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscReal t, PetscReal u_tshift, PetscScalar elemMat[]) 80420cf1dd8SToby Isaac { 80520cf1dd8SToby Isaac const PetscInt debug = 0; 8064bee2e38SMatthew G. Knepley PetscFE feI, feJ; 80745480ffeSMatthew G. Knepley PetscBdPointJac *g0_func, *g1_func, *g2_func, *g3_func; 80845480ffeSMatthew G. Knepley PetscInt n0, n1, n2, n3, i; 80920cf1dd8SToby Isaac PetscInt cOffset = 0; /* Offset into coefficients[] for element e */ 81020cf1dd8SToby Isaac PetscInt cOffsetAux = 0; /* Offset into coefficientsAux[] for element e */ 81120cf1dd8SToby Isaac PetscInt eOffset = 0; /* Offset into elemMat[] for element e */ 81220cf1dd8SToby Isaac PetscInt offsetI = 0; /* Offset into an element vector for fieldI */ 81320cf1dd8SToby Isaac PetscInt offsetJ = 0; /* Offset into an element vector for fieldJ */ 81420cf1dd8SToby Isaac PetscQuadrature quad; 815ef0bb6c7SMatthew G. Knepley PetscTabulation *T, *TAux = NULL; 8164bee2e38SMatthew G. Knepley PetscScalar *g0, *g1, *g2, *g3, *u, *u_t = NULL, *u_x, *a, *a_x, *basisReal, *basisDerReal, *testReal, *testDerReal; 81720cf1dd8SToby Isaac const PetscScalar *constants; 81820cf1dd8SToby Isaac PetscReal *x; 819ef0bb6c7SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL; 820ef0bb6c7SMatthew G. Knepley PetscInt NcI = 0, NcJ = 0; 82145480ffeSMatthew G. Knepley PetscInt dim, numConstants, Nf, fieldI, fieldJ, NfAux = 0, totDim, totDimAux = 0, e; 82220cf1dd8SToby Isaac PetscBool isAffine; 82320cf1dd8SToby Isaac const PetscReal *quadPoints, *quadWeights; 82420cf1dd8SToby Isaac PetscInt qNc, Nq, q, Np, dE; 82520cf1dd8SToby Isaac 82620cf1dd8SToby Isaac PetscFunctionBegin; 827*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(ds, &Nf)); 82845480ffeSMatthew G. Knepley fieldI = key.field / Nf; 82945480ffeSMatthew G. Knepley fieldJ = key.field % Nf; 830*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(ds, fieldI, (PetscObject *) &feI)); 831*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(ds, fieldJ, (PetscObject *) &feJ)); 832*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetSpatialDimension(feI, &dim)); 833*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetFaceQuadrature(feI, &quad)); 834*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTotalDimension(ds, &totDim)); 835*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentOffsets(ds, &uOff)); 836*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentDerivativeOffsets(ds, &uOff_x)); 837*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetFieldOffset(ds, fieldI, &offsetI)); 838*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetFieldOffset(ds, fieldJ, &offsetJ)); 839*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscWeakFormGetBdJacobian(wf, key.label, key.value, fieldI, fieldJ, key.part, &n0, &g0_func, &n1, &g1_func, &n2, &g2_func, &n3, &g3_func)); 84045480ffeSMatthew G. Knepley if (!n0 && !n1 && !n2 && !n3) PetscFunctionReturn(0); 841*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetEvaluationArrays(ds, &u, coefficients_t ? &u_t : NULL, &u_x)); 842*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetWorkspace(ds, &x, &basisReal, &basisDerReal, &testReal, &testDerReal)); 843*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetWeakFormArrays(ds, NULL, NULL, &g0, &g1, &g2, &g3)); 844*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetFaceTabulation(ds, &T)); 845*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetConstants(ds, &numConstants, &constants)); 8464bee2e38SMatthew G. Knepley if (dsAux) { 847*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(dsAux, &NfAux)); 848*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTotalDimension(dsAux, &totDimAux)); 849*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentOffsets(dsAux, &aOff)); 850*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x)); 851*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetEvaluationArrays(dsAux, &a, NULL, &a_x)); 852*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetFaceTabulation(dsAux, &TAux)); 85320cf1dd8SToby Isaac } 854ef0bb6c7SMatthew G. Knepley NcI = T[fieldI]->Nc, NcJ = T[fieldJ]->Nc; 85520cf1dd8SToby Isaac Np = fgeom->numPoints; 85620cf1dd8SToby Isaac dE = fgeom->dimEmbed; 85720cf1dd8SToby Isaac isAffine = fgeom->isAffine; 85827f02ce8SMatthew G. Knepley /* Initialize here in case the function is not defined */ 859*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g0, NcI*NcJ)); 860*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g1, NcI*NcJ*dE)); 861*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g2, NcI*NcJ*dE)); 862*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g3, NcI*NcJ*dE*dE)); 863*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetData(quad, NULL, &qNc, &Nq, &quadPoints, &quadWeights)); 8642c71b3e2SJacob Faibussowitsch PetscCheckFalse(qNc != 1,PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supports scalar quadrature, not %D components", qNc); 86520cf1dd8SToby Isaac for (e = 0; e < Ne; ++e) { 8669f209ee4SMatthew G. Knepley PetscFEGeom fegeom, cgeom; 86720cf1dd8SToby Isaac const PetscInt face = fgeom->face[e][0]; 868ea78f98cSLisandro Dalcin fegeom.n = NULL; 869ea78f98cSLisandro Dalcin fegeom.v = NULL; 870ea78f98cSLisandro Dalcin fegeom.J = NULL; 871ea78f98cSLisandro Dalcin fegeom.detJ = NULL; 87227f02ce8SMatthew G. Knepley fegeom.dim = fgeom->dim; 87327f02ce8SMatthew G. Knepley fegeom.dimEmbed = fgeom->dimEmbed; 87427f02ce8SMatthew G. Knepley cgeom.dim = fgeom->dim; 87527f02ce8SMatthew G. Knepley cgeom.dimEmbed = fgeom->dimEmbed; 8764bee2e38SMatthew G. Knepley if (isAffine) { 8774bee2e38SMatthew G. Knepley fegeom.v = x; 8784bee2e38SMatthew G. Knepley fegeom.xi = fgeom->xi; 8797132c3f7SMatthew G. Knepley fegeom.J = &fgeom->J[e*Np*dE*dE]; 8807132c3f7SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[e*Np*dE*dE]; 8817132c3f7SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e*Np]; 8827132c3f7SMatthew G. Knepley fegeom.n = &fgeom->n[e*Np*dE]; 8839f209ee4SMatthew G. Knepley 8847132c3f7SMatthew G. Knepley cgeom.J = &fgeom->suppJ[0][e*Np*dE*dE]; 8857132c3f7SMatthew G. Knepley cgeom.invJ = &fgeom->suppInvJ[0][e*Np*dE*dE]; 8867132c3f7SMatthew G. Knepley cgeom.detJ = &fgeom->suppDetJ[0][e*Np]; 8874bee2e38SMatthew G. Knepley } 88820cf1dd8SToby Isaac for (q = 0; q < Nq; ++q) { 88920cf1dd8SToby Isaac PetscReal w; 8904bee2e38SMatthew G. Knepley PetscInt c; 89120cf1dd8SToby Isaac 892*5f80ce2aSJacob Faibussowitsch if (debug) CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " quad point %d\n", q)); 89320cf1dd8SToby Isaac if (isAffine) { 8947132c3f7SMatthew G. Knepley CoordinatesRefToReal(dE, dim-1, fegeom.xi, &fgeom->v[e*Np*dE], fegeom.J, &quadPoints[q*(dim-1)], x); 89520cf1dd8SToby Isaac } else { 8963fe841f2SMatthew G. Knepley fegeom.v = &fgeom->v[(e*Np+q)*dE]; 8979f209ee4SMatthew G. Knepley fegeom.J = &fgeom->J[(e*Np+q)*dE*dE]; 8989f209ee4SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[(e*Np+q)*dE*dE]; 8994bee2e38SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e*Np+q]; 9004bee2e38SMatthew G. Knepley fegeom.n = &fgeom->n[(e*Np+q)*dE]; 9019f209ee4SMatthew G. Knepley 9029f209ee4SMatthew G. Knepley cgeom.J = &fgeom->suppJ[0][(e*Np+q)*dE*dE]; 9039f209ee4SMatthew G. Knepley cgeom.invJ = &fgeom->suppInvJ[0][(e*Np+q)*dE*dE]; 9049f209ee4SMatthew G. Knepley cgeom.detJ = &fgeom->suppDetJ[0][e*Np+q]; 90520cf1dd8SToby Isaac } 9064bee2e38SMatthew G. Knepley w = fegeom.detJ[0]*quadWeights[q]; 907*5f80ce2aSJacob Faibussowitsch if (coefficients) CHKERRQ(PetscFEEvaluateFieldJets_Internal(ds, Nf, face, q, T, &cgeom, &coefficients[cOffset], &coefficients_t[cOffset], u, u_x, u_t)); 908*5f80ce2aSJacob Faibussowitsch if (dsAux) CHKERRQ(PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, face, q, TAux, &cgeom, &coefficientsAux[cOffsetAux], NULL, a, a_x, NULL)); 909ea672e62SMatthew G. Knepley if (n0) { 910*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g0, NcI*NcJ)); 91145480ffeSMatthew G. Knepley for (i = 0; i < n0; ++i) g0_func[i](dim, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, NULL, a_x, t, u_tshift, fegeom.v, fegeom.n, numConstants, constants, g0); 91220cf1dd8SToby Isaac for (c = 0; c < NcI*NcJ; ++c) g0[c] *= w; 91320cf1dd8SToby Isaac } 914ea672e62SMatthew G. Knepley if (n1) { 915*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g1, NcI*NcJ*dE)); 91645480ffeSMatthew G. Knepley for (i = 0; i < n1; ++i) g1_func[i](dim, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, NULL, a_x, t, u_tshift, fegeom.v, fegeom.n, numConstants, constants, g1); 9174bee2e38SMatthew G. Knepley for (c = 0; c < NcI*NcJ*dim; ++c) g1[c] *= w; 91820cf1dd8SToby Isaac } 919ea672e62SMatthew G. Knepley if (n2) { 920*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g2, NcI*NcJ*dE)); 92145480ffeSMatthew G. Knepley for (i = 0; i < n2; ++i) g2_func[i](dim, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, NULL, a_x, t, u_tshift, fegeom.v, fegeom.n, numConstants, constants, g2); 9224bee2e38SMatthew G. Knepley for (c = 0; c < NcI*NcJ*dim; ++c) g2[c] *= w; 92320cf1dd8SToby Isaac } 924ea672e62SMatthew G. Knepley if (n3) { 925*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g3, NcI*NcJ*dE*dE)); 92645480ffeSMatthew G. Knepley for (i = 0; i < n3; ++i) g3_func[i](dim, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, NULL, a_x, t, u_tshift, fegeom.v, fegeom.n, numConstants, constants, g3); 9274bee2e38SMatthew G. Knepley for (c = 0; c < NcI*NcJ*dim*dim; ++c) g3[c] *= w; 92820cf1dd8SToby Isaac } 92920cf1dd8SToby Isaac 930*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEUpdateElementMat_Internal(feI, feJ, face, q, T[fieldI], basisReal, basisDerReal, T[fieldJ], testReal, testDerReal, &cgeom, g0, g1, g2, g3, eOffset, totDim, offsetI, offsetJ, elemMat)); 93120cf1dd8SToby Isaac } 93220cf1dd8SToby Isaac if (debug > 1) { 93320cf1dd8SToby Isaac PetscInt fc, f, gc, g; 93420cf1dd8SToby Isaac 935*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, "Element matrix for fields %d and %d\n", fieldI, fieldJ)); 936ef0bb6c7SMatthew G. Knepley for (fc = 0; fc < T[fieldI]->Nc; ++fc) { 937ef0bb6c7SMatthew G. Knepley for (f = 0; f < T[fieldI]->Nb; ++f) { 938ef0bb6c7SMatthew G. Knepley const PetscInt i = offsetI + f*T[fieldI]->Nc+fc; 939ef0bb6c7SMatthew G. Knepley for (gc = 0; gc < T[fieldJ]->Nc; ++gc) { 940ef0bb6c7SMatthew G. Knepley for (g = 0; g < T[fieldJ]->Nb; ++g) { 941ef0bb6c7SMatthew G. Knepley const PetscInt j = offsetJ + g*T[fieldJ]->Nc+gc; 942*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " elemMat[%d,%d,%d,%d]: %g\n", f, fc, g, gc, PetscRealPart(elemMat[eOffset+i*totDim+j]))); 94320cf1dd8SToby Isaac } 94420cf1dd8SToby Isaac } 945*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, "\n")); 94620cf1dd8SToby Isaac } 94720cf1dd8SToby Isaac } 94820cf1dd8SToby Isaac } 94920cf1dd8SToby Isaac cOffset += totDim; 95020cf1dd8SToby Isaac cOffsetAux += totDimAux; 95120cf1dd8SToby Isaac eOffset += PetscSqr(totDim); 95220cf1dd8SToby Isaac } 95320cf1dd8SToby Isaac PetscFunctionReturn(0); 95420cf1dd8SToby Isaac } 95520cf1dd8SToby Isaac 9565fedec97SMatthew G. Knepley PetscErrorCode PetscFEIntegrateHybridJacobian_Basic(PetscDS ds, PetscFEJacobianType jtype, PetscFormKey key, PetscInt s, PetscInt Ne, PetscFEGeom *fgeom, 95727f02ce8SMatthew G. Knepley const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscReal t, PetscReal u_tshift, PetscScalar elemMat[]) 95827f02ce8SMatthew G. Knepley { 95927f02ce8SMatthew G. Knepley const PetscInt debug = 0; 96027f02ce8SMatthew G. Knepley PetscFE feI, feJ; 961148442b3SMatthew G. Knepley PetscWeakForm wf; 962148442b3SMatthew G. Knepley PetscBdPointJac *g0_func, *g1_func, *g2_func, *g3_func; 963148442b3SMatthew G. Knepley PetscInt n0, n1, n2, n3, i; 96427f02ce8SMatthew G. Knepley PetscInt cOffset = 0; /* Offset into coefficients[] for element e */ 96527f02ce8SMatthew G. Knepley PetscInt cOffsetAux = 0; /* Offset into coefficientsAux[] for element e */ 96627f02ce8SMatthew G. Knepley PetscInt eOffset = 0; /* Offset into elemMat[] for element e */ 96727f02ce8SMatthew G. Knepley PetscInt offsetI = 0; /* Offset into an element vector for fieldI */ 96827f02ce8SMatthew G. Knepley PetscInt offsetJ = 0; /* Offset into an element vector for fieldJ */ 969665f567fSMatthew G. Knepley PetscQuadrature quad; 970665f567fSMatthew G. Knepley PetscTabulation *T, *TAux = NULL; 97127f02ce8SMatthew G. Knepley PetscScalar *g0, *g1, *g2, *g3, *u, *u_t = NULL, *u_x, *a, *a_x, *basisReal, *basisDerReal, *testReal, *testDerReal; 97227f02ce8SMatthew G. Knepley const PetscScalar *constants; 97327f02ce8SMatthew G. Knepley PetscReal *x; 974665f567fSMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL; 975665f567fSMatthew G. Knepley PetscInt NcI = 0, NcJ = 0, NcS, NcT; 97645480ffeSMatthew G. Knepley PetscInt dim, dimAux, numConstants, Nf, fieldI, fieldJ, NfAux = 0, totDim, totDimAux = 0, e; 977665f567fSMatthew G. Knepley PetscBool isCohesiveFieldI, isCohesiveFieldJ, isAffine, auxOnBd = PETSC_FALSE; 97827f02ce8SMatthew G. Knepley const PetscReal *quadPoints, *quadWeights; 97927f02ce8SMatthew G. Knepley PetscInt qNc, Nq, q, Np, dE; 98027f02ce8SMatthew G. Knepley 98127f02ce8SMatthew G. Knepley PetscFunctionBegin; 982*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(ds, &Nf)); 98345480ffeSMatthew G. Knepley fieldI = key.field / Nf; 98445480ffeSMatthew G. Knepley fieldJ = key.field % Nf; 98527f02ce8SMatthew G. Knepley /* Hybrid discretization is posed directly on faces */ 986*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(ds, fieldI, (PetscObject *) &feI)); 987*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetDiscretization(ds, fieldJ, (PetscObject *) &feJ)); 988*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetSpatialDimension(feI, &dim)); 989*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEGetQuadrature(feI, &quad)); 990*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTotalDimension(ds, &totDim)); 991*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentOffsetsCohesive(ds, s, &uOff)); 992*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentDerivativeOffsetsCohesive(ds, s, &uOff_x)); 993*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetWeakForm(ds, &wf)); 99427f02ce8SMatthew G. Knepley switch(jtype) { 995*5f80ce2aSJacob Faibussowitsch case PETSCFE_JACOBIAN_PRE: CHKERRQ(PetscWeakFormGetBdJacobianPreconditioner(wf, key.label, key.value, fieldI, fieldJ, key.part, &n0, &g0_func, &n1, &g1_func, &n2, &g2_func, &n3, &g3_func));break; 996*5f80ce2aSJacob Faibussowitsch case PETSCFE_JACOBIAN: CHKERRQ(PetscWeakFormGetBdJacobian(wf, key.label, key.value, fieldI, fieldJ, key.part, &n0, &g0_func, &n1, &g1_func, &n2, &g2_func, &n3, &g3_func));break; 997665f567fSMatthew G. Knepley case PETSCFE_JACOBIAN_DYN: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No boundary hybrid Jacobians :)"); 99827f02ce8SMatthew G. Knepley } 999148442b3SMatthew G. Knepley if (!n0 && !n1 && !n2 && !n3) PetscFunctionReturn(0); 1000*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetEvaluationArrays(ds, &u, coefficients_t ? &u_t : NULL, &u_x)); 1001*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetWorkspace(ds, &x, &basisReal, &basisDerReal, &testReal, &testDerReal)); 1002*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetWeakFormArrays(ds, NULL, NULL, &g0, &g1, &g2, &g3)); 1003*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTabulation(ds, &T)); 1004*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetFieldOffsetCohesive(ds, fieldI, &offsetI)); 1005*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetFieldOffsetCohesive(ds, fieldJ, &offsetJ)); 1006*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetConstants(ds, &numConstants, &constants)); 100727f02ce8SMatthew G. Knepley if (dsAux) { 1008*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetSpatialDimension(dsAux, &dimAux)); 1009*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetNumFields(dsAux, &NfAux)); 1010*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetTotalDimension(dsAux, &totDimAux)); 1011*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentOffsets(dsAux, &aOff)); 1012*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x)); 1013*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetEvaluationArrays(dsAux, &a, NULL, &a_x)); 101401907d53SMatthew G. Knepley auxOnBd = dimAux == dim ? PETSC_TRUE : PETSC_FALSE; 1015*5f80ce2aSJacob Faibussowitsch if (auxOnBd) CHKERRQ(PetscDSGetTabulation(dsAux, &TAux)); 1016*5f80ce2aSJacob Faibussowitsch else CHKERRQ(PetscDSGetFaceTabulation(dsAux, &TAux)); 10172c71b3e2SJacob Faibussowitsch PetscCheckFalse(T[0]->Np != TAux[0]->Np,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Number of tabulation points %D != %D number of auxiliary tabulation points", T[0]->Np, TAux[0]->Np); 101827f02ce8SMatthew G. Knepley } 1019*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetCohesive(ds, fieldI, &isCohesiveFieldI)); 1020*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDSGetCohesive(ds, fieldJ, &isCohesiveFieldJ)); 1021665f567fSMatthew G. Knepley NcI = T[fieldI]->Nc; 1022665f567fSMatthew G. Knepley NcJ = T[fieldJ]->Nc; 102327f02ce8SMatthew G. Knepley NcS = isCohesiveFieldI ? NcI : 2*NcI; 102427f02ce8SMatthew G. Knepley NcT = isCohesiveFieldJ ? NcJ : 2*NcJ; 102527f02ce8SMatthew G. Knepley Np = fgeom->numPoints; 102627f02ce8SMatthew G. Knepley dE = fgeom->dimEmbed; 102727f02ce8SMatthew G. Knepley isAffine = fgeom->isAffine; 1028*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g0, NcS*NcT)); 1029*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g1, NcS*NcT*dE)); 1030*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g2, NcS*NcT*dE)); 1031*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g3, NcS*NcT*dE*dE)); 1032*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscQuadratureGetData(quad, NULL, &qNc, &Nq, &quadPoints, &quadWeights)); 10332c71b3e2SJacob Faibussowitsch PetscCheckFalse(qNc != 1,PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supports scalar quadrature, not %D components", qNc); 103427f02ce8SMatthew G. Knepley for (e = 0; e < Ne; ++e) { 103527f02ce8SMatthew G. Knepley PetscFEGeom fegeom; 103627f02ce8SMatthew G. Knepley const PetscInt face = fgeom->face[e][0]; 103727f02ce8SMatthew G. Knepley 103827f02ce8SMatthew G. Knepley fegeom.dim = fgeom->dim; 103927f02ce8SMatthew G. Knepley fegeom.dimEmbed = fgeom->dimEmbed; 104027f02ce8SMatthew G. Knepley if (isAffine) { 104127f02ce8SMatthew G. Knepley fegeom.v = x; 104227f02ce8SMatthew G. Knepley fegeom.xi = fgeom->xi; 104327f02ce8SMatthew G. Knepley fegeom.J = &fgeom->J[e*dE*dE]; 104427f02ce8SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[e*dE*dE]; 104527f02ce8SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e]; 104627f02ce8SMatthew G. Knepley fegeom.n = &fgeom->n[e*dE]; 104727f02ce8SMatthew G. Knepley } 104827f02ce8SMatthew G. Knepley for (q = 0; q < Nq; ++q) { 104927f02ce8SMatthew G. Knepley PetscReal w; 105027f02ce8SMatthew G. Knepley PetscInt c; 105127f02ce8SMatthew G. Knepley 105227f02ce8SMatthew G. Knepley if (isAffine) { 105327f02ce8SMatthew G. Knepley /* TODO Is it correct to have 'dim' here, or should it be 'dim-1'? */ 105427f02ce8SMatthew G. Knepley CoordinatesRefToReal(dE, dim, fegeom.xi, &fgeom->v[e*dE], fegeom.J, &quadPoints[q*dim], x); 105527f02ce8SMatthew G. Knepley } else { 105627f02ce8SMatthew G. Knepley fegeom.v = &fegeom.v[(e*Np+q)*dE]; 105727f02ce8SMatthew G. Knepley fegeom.J = &fgeom->J[(e*Np+q)*dE*dE]; 105827f02ce8SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[(e*Np+q)*dE*dE]; 105927f02ce8SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e*Np+q]; 106027f02ce8SMatthew G. Knepley fegeom.n = &fgeom->n[(e*Np+q)*dE]; 106127f02ce8SMatthew G. Knepley } 106227f02ce8SMatthew G. Knepley w = fegeom.detJ[0]*quadWeights[q]; 106327f02ce8SMatthew G. Knepley if (debug > 1 && q < Np) { 1064*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " detJ: %g\n", fegeom.detJ[0])); 106527f02ce8SMatthew G. Knepley #if !defined(PETSC_USE_COMPLEX) 1066*5f80ce2aSJacob Faibussowitsch CHKERRQ(DMPrintCellMatrix(e, "invJ", dim, dim, fegeom.invJ)); 106727f02ce8SMatthew G. Knepley #endif 106827f02ce8SMatthew G. Knepley } 1069*5f80ce2aSJacob Faibussowitsch if (debug) CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " quad point %d\n", q)); 1070*5f80ce2aSJacob Faibussowitsch if (coefficients) CHKERRQ(PetscFEEvaluateFieldJets_Hybrid_Internal(ds, Nf, 0, q, T, &fegeom, &coefficients[cOffset], &coefficients_t[cOffset], u, u_x, u_t)); 1071*5f80ce2aSJacob Faibussowitsch if (dsAux) CHKERRQ(PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, 0, auxOnBd ? q : face*Nq+q, TAux, &fegeom, &coefficientsAux[cOffsetAux], NULL, a, a_x, NULL)); 1072ea672e62SMatthew G. Knepley if (n0) { 1073*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g0, NcS*NcT)); 1074148442b3SMatthew G. Knepley for (i = 0; i < n0; ++i) g0_func[i](dim, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, NULL, a_x, t, u_tshift, fegeom.v, fegeom.n, numConstants, constants, g0); 107527f02ce8SMatthew G. Knepley for (c = 0; c < NcS*NcT; ++c) g0[c] *= w; 107627f02ce8SMatthew G. Knepley } 1077ea672e62SMatthew G. Knepley if (n1) { 1078*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g1, NcS*NcT*dE)); 1079148442b3SMatthew G. Knepley for (i = 0; i < n1; ++i) g1_func[i](dim, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, NULL, a_x, t, u_tshift, fegeom.v, fegeom.n, numConstants, constants, g1); 108027f02ce8SMatthew G. Knepley for (c = 0; c < NcS*NcT*dE; ++c) g1[c] *= w; 108127f02ce8SMatthew G. Knepley } 1082ea672e62SMatthew G. Knepley if (n2) { 1083*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g2, NcS*NcT*dE)); 1084148442b3SMatthew G. Knepley for (i = 0; i < n2; ++i) g2_func[i](dim, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, NULL, a_x, t, u_tshift, fegeom.v, fegeom.n, numConstants, constants, g2); 108527f02ce8SMatthew G. Knepley for (c = 0; c < NcS*NcT*dE; ++c) g2[c] *= w; 108627f02ce8SMatthew G. Knepley } 1087ea672e62SMatthew G. Knepley if (n3) { 1088*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(g3, NcS*NcT*dE*dE)); 1089148442b3SMatthew G. Knepley for (i = 0; i < n3; ++i) g3_func[i](dim, Nf, NfAux, uOff, uOff_x, u, u_t, u_x, aOff, aOff_x, a, NULL, a_x, t, u_tshift, fegeom.v, fegeom.n, numConstants, constants, g3); 109027f02ce8SMatthew G. Knepley for (c = 0; c < NcS*NcT*dE*dE; ++c) g3[c] *= w; 109127f02ce8SMatthew G. Knepley } 109227f02ce8SMatthew G. Knepley 10935fedec97SMatthew G. Knepley if (isCohesiveFieldI) { 10945fedec97SMatthew G. Knepley if (isCohesiveFieldJ) { 1095*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEUpdateElementMat_Internal(feI, feJ, 0, q, T[fieldI], basisReal, basisDerReal, T[fieldJ], testReal, testDerReal, &fegeom, g0, g1, g2, g3, eOffset, totDim, offsetI, offsetJ, elemMat)); 109627f02ce8SMatthew G. Knepley } else { 1097*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEUpdateElementMat_Hybrid_Internal(feI, isCohesiveFieldI, feJ, isCohesiveFieldJ, 0, 0, q, T[fieldI], basisReal, basisDerReal, T[fieldJ], testReal, testDerReal, &fegeom, g0, g1, g2, g3, eOffset, totDim, offsetI, offsetJ, elemMat)); 1098*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEUpdateElementMat_Hybrid_Internal(feI, isCohesiveFieldI, feJ, isCohesiveFieldJ, 0, 1, q, T[fieldI], basisReal, basisDerReal, T[fieldJ], testReal, testDerReal, &fegeom, &g0[NcI*NcJ], &g1[NcI*NcJ*dim], &g2[NcI*NcJ*dim], &g3[NcI*NcJ*dim*dim], eOffset, totDim, offsetI, offsetJ, elemMat)); 10995fedec97SMatthew G. Knepley } 11005fedec97SMatthew G. Knepley } else { 1101*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEUpdateElementMat_Hybrid_Internal(feI, isCohesiveFieldI, feJ, isCohesiveFieldJ, 0, s, q, T[fieldI], basisReal, basisDerReal, T[fieldJ], testReal, testDerReal, &fegeom, g0, g1, g2, g3, eOffset, totDim, offsetI, offsetJ, elemMat)); 110227f02ce8SMatthew G. Knepley } 110327f02ce8SMatthew G. Knepley } 110427f02ce8SMatthew G. Knepley if (debug > 1) { 110527f02ce8SMatthew G. Knepley PetscInt fc, f, gc, g; 110627f02ce8SMatthew G. Knepley 1107*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, "Element matrix for fields %d and %d\n", fieldI, fieldJ)); 110827f02ce8SMatthew G. Knepley for (fc = 0; fc < NcI; ++fc) { 1109665f567fSMatthew G. Knepley for (f = 0; f < T[fieldI]->Nb; ++f) { 111027f02ce8SMatthew G. Knepley const PetscInt i = offsetI + f*NcI+fc; 111127f02ce8SMatthew G. Knepley for (gc = 0; gc < NcJ; ++gc) { 1112665f567fSMatthew G. Knepley for (g = 0; g < T[fieldJ]->Nb; ++g) { 111327f02ce8SMatthew G. Knepley const PetscInt j = offsetJ + g*NcJ+gc; 1114*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, " elemMat[%d,%d,%d,%d]: %g\n", f, fc, g, gc, PetscRealPart(elemMat[eOffset+i*totDim+j]))); 111527f02ce8SMatthew G. Knepley } 111627f02ce8SMatthew G. Knepley } 1117*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF, "\n")); 111827f02ce8SMatthew G. Knepley } 111927f02ce8SMatthew G. Knepley } 112027f02ce8SMatthew G. Knepley } 112127f02ce8SMatthew G. Knepley cOffset += totDim; 112227f02ce8SMatthew G. Knepley cOffsetAux += totDimAux; 112327f02ce8SMatthew G. Knepley eOffset += PetscSqr(totDim); 112427f02ce8SMatthew G. Knepley } 112527f02ce8SMatthew G. Knepley PetscFunctionReturn(0); 112627f02ce8SMatthew G. Knepley } 112727f02ce8SMatthew G. Knepley 11282b99622eSMatthew G. Knepley static PetscErrorCode PetscFEInitialize_Basic(PetscFE fem) 112920cf1dd8SToby Isaac { 113020cf1dd8SToby Isaac PetscFunctionBegin; 113120cf1dd8SToby Isaac fem->ops->setfromoptions = NULL; 113220cf1dd8SToby Isaac fem->ops->setup = PetscFESetUp_Basic; 113320cf1dd8SToby Isaac fem->ops->view = PetscFEView_Basic; 113420cf1dd8SToby Isaac fem->ops->destroy = PetscFEDestroy_Basic; 113520cf1dd8SToby Isaac fem->ops->getdimension = PetscFEGetDimension_Basic; 1136ef0bb6c7SMatthew G. Knepley fem->ops->createtabulation = PetscFECreateTabulation_Basic; 113720cf1dd8SToby Isaac fem->ops->integrate = PetscFEIntegrate_Basic; 1138afe6d6adSToby Isaac fem->ops->integratebd = PetscFEIntegrateBd_Basic; 113920cf1dd8SToby Isaac fem->ops->integrateresidual = PetscFEIntegrateResidual_Basic; 114020cf1dd8SToby Isaac fem->ops->integratebdresidual = PetscFEIntegrateBdResidual_Basic; 114127f02ce8SMatthew G. Knepley fem->ops->integratehybridresidual = PetscFEIntegrateHybridResidual_Basic; 114220cf1dd8SToby Isaac fem->ops->integratejacobianaction = NULL/* PetscFEIntegrateJacobianAction_Basic */; 114320cf1dd8SToby Isaac fem->ops->integratejacobian = PetscFEIntegrateJacobian_Basic; 114420cf1dd8SToby Isaac fem->ops->integratebdjacobian = PetscFEIntegrateBdJacobian_Basic; 114527f02ce8SMatthew G. Knepley fem->ops->integratehybridjacobian = PetscFEIntegrateHybridJacobian_Basic; 114620cf1dd8SToby Isaac PetscFunctionReturn(0); 114720cf1dd8SToby Isaac } 114820cf1dd8SToby Isaac 114920cf1dd8SToby Isaac /*MC 115020cf1dd8SToby Isaac PETSCFEBASIC = "basic" - A PetscFE object that integrates with basic tiling and no vectorization 115120cf1dd8SToby Isaac 115220cf1dd8SToby Isaac Level: intermediate 115320cf1dd8SToby Isaac 115420cf1dd8SToby Isaac .seealso: PetscFEType, PetscFECreate(), PetscFESetType() 115520cf1dd8SToby Isaac M*/ 115620cf1dd8SToby Isaac 115720cf1dd8SToby Isaac PETSC_EXTERN PetscErrorCode PetscFECreate_Basic(PetscFE fem) 115820cf1dd8SToby Isaac { 115920cf1dd8SToby Isaac PetscFE_Basic *b; 116020cf1dd8SToby Isaac 116120cf1dd8SToby Isaac PetscFunctionBegin; 116220cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 1163*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscNewLog(fem,&b)); 116420cf1dd8SToby Isaac fem->data = b; 116520cf1dd8SToby Isaac 1166*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFEInitialize_Basic(fem)); 116720cf1dd8SToby Isaac PetscFunctionReturn(0); 116820cf1dd8SToby Isaac } 1169