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 PetscErrorCode ierr; 820cf1dd8SToby Isaac 920cf1dd8SToby Isaac PetscFunctionBegin; 1020cf1dd8SToby Isaac ierr = PetscFree(b);CHKERRQ(ierr); 1120cf1dd8SToby Isaac PetscFunctionReturn(0); 1220cf1dd8SToby Isaac } 1320cf1dd8SToby Isaac 142b99622eSMatthew G. Knepley static PetscErrorCode PetscFEView_Basic_Ascii(PetscFE fe, PetscViewer v) 1520cf1dd8SToby Isaac { 16d9bac1caSLisandro Dalcin PetscInt dim, Nc; 17d9bac1caSLisandro Dalcin PetscSpace basis = NULL; 18d9bac1caSLisandro Dalcin PetscDualSpace dual = NULL; 19d9bac1caSLisandro Dalcin PetscQuadrature quad = NULL; 2020cf1dd8SToby Isaac PetscErrorCode ierr; 2120cf1dd8SToby Isaac 2220cf1dd8SToby Isaac PetscFunctionBegin; 23d9bac1caSLisandro Dalcin ierr = PetscFEGetSpatialDimension(fe, &dim);CHKERRQ(ierr); 24d9bac1caSLisandro Dalcin ierr = PetscFEGetNumComponents(fe, &Nc);CHKERRQ(ierr); 2520cf1dd8SToby Isaac ierr = PetscFEGetBasisSpace(fe, &basis);CHKERRQ(ierr); 2620cf1dd8SToby Isaac ierr = PetscFEGetDualSpace(fe, &dual);CHKERRQ(ierr); 27d9bac1caSLisandro Dalcin ierr = PetscFEGetQuadrature(fe, &quad);CHKERRQ(ierr); 28d9bac1caSLisandro Dalcin ierr = PetscViewerASCIIPushTab(v);CHKERRQ(ierr); 29d9bac1caSLisandro Dalcin ierr = PetscViewerASCIIPrintf(v, "Basic Finite Element in %D dimensions with %D components\n",dim,Nc);CHKERRQ(ierr); 30d9bac1caSLisandro Dalcin if (basis) {ierr = PetscSpaceView(basis, v);CHKERRQ(ierr);} 31d9bac1caSLisandro Dalcin if (dual) {ierr = PetscDualSpaceView(dual, v);CHKERRQ(ierr);} 32d9bac1caSLisandro Dalcin if (quad) {ierr = PetscQuadratureView(quad, v);CHKERRQ(ierr);} 33d9bac1caSLisandro Dalcin ierr = PetscViewerASCIIPopTab(v);CHKERRQ(ierr); 3420cf1dd8SToby Isaac PetscFunctionReturn(0); 3520cf1dd8SToby Isaac } 3620cf1dd8SToby Isaac 372b99622eSMatthew G. Knepley static PetscErrorCode PetscFEView_Basic(PetscFE fe, PetscViewer v) 3820cf1dd8SToby Isaac { 3920cf1dd8SToby Isaac PetscBool iascii; 4020cf1dd8SToby Isaac PetscErrorCode ierr; 4120cf1dd8SToby Isaac 4220cf1dd8SToby Isaac PetscFunctionBegin; 43d9bac1caSLisandro Dalcin ierr = PetscObjectTypeCompare((PetscObject) v, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 44d9bac1caSLisandro Dalcin if (iascii) {ierr = PetscFEView_Basic_Ascii(fe, v);CHKERRQ(ierr);} 4520cf1dd8SToby Isaac PetscFunctionReturn(0); 4620cf1dd8SToby Isaac } 4720cf1dd8SToby Isaac 4820cf1dd8SToby Isaac /* Construct the change of basis from prime basis to nodal basis */ 4915310ec5SMatthew G. Knepley PetscErrorCode PetscFESetUp_Basic(PetscFE fem) 5020cf1dd8SToby Isaac { 51b9d4cb8dSJed Brown PetscReal *work; 5220cf1dd8SToby Isaac PetscBLASInt *pivots; 5320cf1dd8SToby Isaac PetscBLASInt n, info; 5420cf1dd8SToby Isaac PetscInt pdim, j; 5520cf1dd8SToby Isaac PetscErrorCode ierr; 5620cf1dd8SToby Isaac 5720cf1dd8SToby Isaac PetscFunctionBegin; 5820cf1dd8SToby Isaac ierr = PetscDualSpaceGetDimension(fem->dualSpace, &pdim);CHKERRQ(ierr); 5920cf1dd8SToby Isaac ierr = PetscMalloc1(pdim*pdim,&fem->invV);CHKERRQ(ierr); 6020cf1dd8SToby Isaac for (j = 0; j < pdim; ++j) { 6120cf1dd8SToby Isaac PetscReal *Bf; 6220cf1dd8SToby Isaac PetscQuadrature f; 6320cf1dd8SToby Isaac const PetscReal *points, *weights; 6420cf1dd8SToby Isaac PetscInt Nc, Nq, q, k, c; 6520cf1dd8SToby Isaac 6620cf1dd8SToby Isaac ierr = PetscDualSpaceGetFunctional(fem->dualSpace, j, &f);CHKERRQ(ierr); 6720cf1dd8SToby Isaac ierr = PetscQuadratureGetData(f, NULL, &Nc, &Nq, &points, &weights);CHKERRQ(ierr); 6820cf1dd8SToby Isaac ierr = PetscMalloc1(Nc*Nq*pdim,&Bf);CHKERRQ(ierr); 6920cf1dd8SToby Isaac ierr = PetscSpaceEvaluate(fem->basisSpace, Nq, points, Bf, NULL, NULL);CHKERRQ(ierr); 7020cf1dd8SToby Isaac for (k = 0; k < pdim; ++k) { 7120cf1dd8SToby Isaac /* V_{jk} = n_j(\phi_k) = \int \phi_k(x) n_j(x) dx */ 72b9d4cb8dSJed Brown fem->invV[j*pdim+k] = 0.0; 7320cf1dd8SToby Isaac 7420cf1dd8SToby Isaac for (q = 0; q < Nq; ++q) { 75b9d4cb8dSJed Brown for (c = 0; c < Nc; ++c) fem->invV[j*pdim+k] += Bf[(q*pdim + k)*Nc + c]*weights[q*Nc + c]; 7620cf1dd8SToby Isaac } 7720cf1dd8SToby Isaac } 7820cf1dd8SToby Isaac ierr = PetscFree(Bf);CHKERRQ(ierr); 7920cf1dd8SToby Isaac } 80ea2bdf6dSBarry Smith 8120cf1dd8SToby Isaac ierr = PetscMalloc2(pdim,&pivots,pdim,&work);CHKERRQ(ierr); 8220cf1dd8SToby Isaac n = pdim; 83b9d4cb8dSJed Brown PetscStackCallBLAS("LAPACKgetrf", LAPACKREALgetrf_(&n, &n, fem->invV, &n, pivots, &info)); 84ea2bdf6dSBarry Smith if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error returned from LAPACKgetrf %D",(PetscInt)info); 85b9d4cb8dSJed Brown PetscStackCallBLAS("LAPACKgetri", LAPACKREALgetri_(&n, fem->invV, &n, pivots, work, &n, &info)); 86ea2bdf6dSBarry Smith if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error returned from LAPACKgetri %D",(PetscInt)info); 8720cf1dd8SToby Isaac ierr = PetscFree2(pivots,work);CHKERRQ(ierr); 8820cf1dd8SToby Isaac PetscFunctionReturn(0); 8920cf1dd8SToby Isaac } 9020cf1dd8SToby Isaac 9120cf1dd8SToby Isaac PetscErrorCode PetscFEGetDimension_Basic(PetscFE fem, PetscInt *dim) 9220cf1dd8SToby Isaac { 9320cf1dd8SToby Isaac PetscErrorCode ierr; 9420cf1dd8SToby Isaac 9520cf1dd8SToby Isaac PetscFunctionBegin; 9620cf1dd8SToby Isaac ierr = PetscDualSpaceGetDimension(fem->dualSpace, dim);CHKERRQ(ierr); 9720cf1dd8SToby Isaac PetscFunctionReturn(0); 9820cf1dd8SToby Isaac } 9920cf1dd8SToby Isaac 100b9d4cb8dSJed Brown /* Tensor contraction on the middle index, 101b9d4cb8dSJed Brown * C[m,n,p] = A[m,k,p] * B[k,n] 102b9d4cb8dSJed Brown * where all matrices use C-style ordering. 103b9d4cb8dSJed Brown */ 104b9d4cb8dSJed Brown static PetscErrorCode TensorContract_Private(PetscInt m,PetscInt n,PetscInt p,PetscInt k,const PetscReal *A,const PetscReal *B,PetscReal *C) { 105b9d4cb8dSJed Brown PetscErrorCode ierr; 106b9d4cb8dSJed Brown PetscInt i; 107b9d4cb8dSJed Brown 108b9d4cb8dSJed Brown PetscFunctionBegin; 109b9d4cb8dSJed Brown for (i=0; i<m; i++) { 110b9d4cb8dSJed Brown PetscBLASInt n_,p_,k_,lda,ldb,ldc; 111b9d4cb8dSJed Brown PetscReal one = 1, zero = 0; 112b9d4cb8dSJed Brown /* Taking contiguous submatrices, we wish to comput c[n,p] = a[k,p] * B[k,n] 113b9d4cb8dSJed Brown * or, in Fortran ordering, c(p,n) = a(p,k) * B(n,k) 114b9d4cb8dSJed Brown */ 115b9d4cb8dSJed Brown ierr = PetscBLASIntCast(n,&n_);CHKERRQ(ierr); 116b9d4cb8dSJed Brown ierr = PetscBLASIntCast(p,&p_);CHKERRQ(ierr); 117b9d4cb8dSJed Brown ierr = PetscBLASIntCast(k,&k_);CHKERRQ(ierr); 118b9d4cb8dSJed Brown lda = p_; 119b9d4cb8dSJed Brown ldb = n_; 120b9d4cb8dSJed Brown ldc = p_; 121b9d4cb8dSJed Brown PetscStackCallBLAS("BLASgemm",BLASREALgemm_("N","T",&p_,&n_,&k_,&one,A+i*k*p,&lda,B,&ldb,&zero,C+i*n*p,&ldc)); 122b9d4cb8dSJed Brown } 1236485a3bbSJed Brown ierr = PetscLogFlops(2.*m*n*p*k);CHKERRQ(ierr); 124b9d4cb8dSJed Brown PetscFunctionReturn(0); 125b9d4cb8dSJed Brown } 126b9d4cb8dSJed Brown 127ef0bb6c7SMatthew G. Knepley PetscErrorCode PetscFECreateTabulation_Basic(PetscFE fem, PetscInt npoints, const PetscReal points[], PetscInt K, PetscTabulation T) 12820cf1dd8SToby Isaac { 12920cf1dd8SToby Isaac DM dm; 13020cf1dd8SToby Isaac PetscInt pdim; /* Dimension of FE space P */ 13120cf1dd8SToby Isaac PetscInt dim; /* Spatial dimension */ 13220cf1dd8SToby Isaac PetscInt Nc; /* Field components */ 133ef0bb6c7SMatthew G. Knepley PetscReal *B = K >= 0 ? T->T[0] : NULL; 134ef0bb6c7SMatthew G. Knepley PetscReal *D = K >= 1 ? T->T[1] : NULL; 135ef0bb6c7SMatthew G. Knepley PetscReal *H = K >= 2 ? T->T[2] : NULL; 136ef0bb6c7SMatthew G. Knepley PetscReal *tmpB = NULL, *tmpD = NULL, *tmpH = NULL; 13720cf1dd8SToby Isaac PetscErrorCode ierr; 13820cf1dd8SToby Isaac 13920cf1dd8SToby Isaac PetscFunctionBegin; 14020cf1dd8SToby Isaac ierr = PetscDualSpaceGetDM(fem->dualSpace, &dm);CHKERRQ(ierr); 14120cf1dd8SToby Isaac ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 14220cf1dd8SToby Isaac ierr = PetscDualSpaceGetDimension(fem->dualSpace, &pdim);CHKERRQ(ierr); 14320cf1dd8SToby Isaac ierr = PetscFEGetNumComponents(fem, &Nc);CHKERRQ(ierr); 14420cf1dd8SToby Isaac /* Evaluate the prime basis functions at all points */ 145ef0bb6c7SMatthew G. Knepley if (K >= 0) {ierr = DMGetWorkArray(dm, npoints*pdim*Nc, MPIU_REAL, &tmpB);CHKERRQ(ierr);} 146ef0bb6c7SMatthew G. Knepley if (K >= 1) {ierr = DMGetWorkArray(dm, npoints*pdim*Nc*dim, MPIU_REAL, &tmpD);CHKERRQ(ierr);} 147ef0bb6c7SMatthew G. Knepley if (K >= 2) {ierr = DMGetWorkArray(dm, npoints*pdim*Nc*dim*dim, MPIU_REAL, &tmpH);CHKERRQ(ierr);} 148ef0bb6c7SMatthew G. Knepley ierr = PetscSpaceEvaluate(fem->basisSpace, npoints, points, tmpB, tmpD, tmpH);CHKERRQ(ierr); 149b9d4cb8dSJed Brown /* Translate from prime to nodal basis */ 15020cf1dd8SToby Isaac if (B) { 151b9d4cb8dSJed Brown /* B[npoints, nodes, Nc] = tmpB[npoints, prime, Nc] * invV[prime, nodes] */ 152b9d4cb8dSJed Brown ierr = TensorContract_Private(npoints, pdim, Nc, pdim, tmpB, fem->invV, B);CHKERRQ(ierr); 15320cf1dd8SToby Isaac } 15420cf1dd8SToby Isaac if (D) { 155b9d4cb8dSJed Brown /* D[npoints, nodes, Nc, dim] = tmpD[npoints, prime, Nc, dim] * invV[prime, nodes] */ 156b9d4cb8dSJed Brown ierr = TensorContract_Private(npoints, pdim, Nc*dim, pdim, tmpD, fem->invV, D);CHKERRQ(ierr); 15720cf1dd8SToby Isaac } 15820cf1dd8SToby Isaac if (H) { 159b9d4cb8dSJed Brown /* H[npoints, nodes, Nc, dim, dim] = tmpH[npoints, prime, Nc, dim, dim] * invV[prime, nodes] */ 160b9d4cb8dSJed Brown ierr = TensorContract_Private(npoints, pdim, Nc*dim*dim, pdim, tmpH, fem->invV, H);CHKERRQ(ierr); 16120cf1dd8SToby Isaac } 162ef0bb6c7SMatthew G. Knepley if (K >= 0) {ierr = DMRestoreWorkArray(dm, npoints*pdim*Nc, MPIU_REAL, &tmpB);CHKERRQ(ierr);} 163ef0bb6c7SMatthew G. Knepley if (K >= 1) {ierr = DMRestoreWorkArray(dm, npoints*pdim*Nc*dim, MPIU_REAL, &tmpD);CHKERRQ(ierr);} 164ef0bb6c7SMatthew G. Knepley if (K >= 2) {ierr = DMRestoreWorkArray(dm, npoints*pdim*Nc*dim*dim, MPIU_REAL, &tmpH);CHKERRQ(ierr);} 16520cf1dd8SToby Isaac PetscFunctionReturn(0); 16620cf1dd8SToby Isaac } 16720cf1dd8SToby Isaac 1682b99622eSMatthew G. Knepley static PetscErrorCode PetscFEIntegrate_Basic(PetscDS ds, PetscInt field, PetscInt Ne, PetscFEGeom *cgeom, 1694bee2e38SMatthew G. Knepley const PetscScalar coefficients[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscScalar integral[]) 17020cf1dd8SToby Isaac { 17120cf1dd8SToby Isaac const PetscInt debug = 0; 1724bee2e38SMatthew G. Knepley PetscFE fe; 17320cf1dd8SToby Isaac PetscPointFunc obj_func; 17420cf1dd8SToby Isaac PetscQuadrature quad; 175ef0bb6c7SMatthew G. Knepley PetscTabulation *T, *TAux = NULL; 1764bee2e38SMatthew G. Knepley PetscScalar *u, *u_x, *a, *a_x; 17720cf1dd8SToby Isaac const PetscScalar *constants; 17820cf1dd8SToby Isaac PetscReal *x; 179ef0bb6c7SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL; 18020cf1dd8SToby Isaac PetscInt dim, dE, Np, numConstants, Nf, NfAux = 0, totDim, totDimAux = 0, cOffset = 0, cOffsetAux = 0, e; 18120cf1dd8SToby Isaac PetscBool isAffine; 18220cf1dd8SToby Isaac const PetscReal *quadPoints, *quadWeights; 18320cf1dd8SToby Isaac PetscInt qNc, Nq, q; 18420cf1dd8SToby Isaac PetscErrorCode ierr; 18520cf1dd8SToby Isaac 18620cf1dd8SToby Isaac PetscFunctionBegin; 1874bee2e38SMatthew G. Knepley ierr = PetscDSGetObjective(ds, field, &obj_func);CHKERRQ(ierr); 18820cf1dd8SToby Isaac if (!obj_func) PetscFunctionReturn(0); 1894bee2e38SMatthew G. Knepley ierr = PetscDSGetDiscretization(ds, field, (PetscObject *) &fe);CHKERRQ(ierr); 1904bee2e38SMatthew G. Knepley ierr = PetscFEGetSpatialDimension(fe, &dim);CHKERRQ(ierr); 1914bee2e38SMatthew G. Knepley ierr = PetscFEGetQuadrature(fe, &quad);CHKERRQ(ierr); 1924bee2e38SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 1934bee2e38SMatthew G. Knepley ierr = PetscDSGetTotalDimension(ds, &totDim);CHKERRQ(ierr); 1944bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(ds, &uOff);CHKERRQ(ierr); 1954bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(ds, &uOff_x);CHKERRQ(ierr); 196ef0bb6c7SMatthew G. Knepley ierr = PetscDSGetTabulation(ds, &T);CHKERRQ(ierr); 1974bee2e38SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(ds, &u, NULL, &u_x);CHKERRQ(ierr); 1984bee2e38SMatthew G. Knepley ierr = PetscDSGetWorkspace(ds, &x, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 1994bee2e38SMatthew G. Knepley ierr = PetscDSGetConstants(ds, &numConstants, &constants);CHKERRQ(ierr); 2004bee2e38SMatthew G. Knepley if (dsAux) { 2014bee2e38SMatthew G. Knepley ierr = PetscDSGetNumFields(dsAux, &NfAux);CHKERRQ(ierr); 2024bee2e38SMatthew G. Knepley ierr = PetscDSGetTotalDimension(dsAux, &totDimAux);CHKERRQ(ierr); 2034bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(dsAux, &aOff);CHKERRQ(ierr); 2044bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x);CHKERRQ(ierr); 205ef0bb6c7SMatthew G. Knepley ierr = PetscDSGetTabulation(dsAux, &TAux);CHKERRQ(ierr); 2064bee2e38SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(dsAux, &a, NULL, &a_x);CHKERRQ(ierr); 20720cf1dd8SToby Isaac } 20820cf1dd8SToby Isaac ierr = PetscQuadratureGetData(quad, NULL, &qNc, &Nq, &quadPoints, &quadWeights);CHKERRQ(ierr); 2094bee2e38SMatthew G. Knepley if (qNc != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supports scalar quadrature, not %D components\n", qNc); 21020cf1dd8SToby Isaac Np = cgeom->numPoints; 21120cf1dd8SToby Isaac dE = cgeom->dimEmbed; 21220cf1dd8SToby Isaac isAffine = cgeom->isAffine; 21320cf1dd8SToby Isaac for (e = 0; e < Ne; ++e) { 2144bee2e38SMatthew G. Knepley PetscFEGeom fegeom; 21520cf1dd8SToby Isaac 21627f02ce8SMatthew G. Knepley fegeom.dim = cgeom->dim; 21727f02ce8SMatthew G. Knepley fegeom.dimEmbed = cgeom->dimEmbed; 21820cf1dd8SToby Isaac if (isAffine) { 2194bee2e38SMatthew G. Knepley fegeom.v = x; 2204bee2e38SMatthew G. Knepley fegeom.xi = cgeom->xi; 2217132c3f7SMatthew G. Knepley fegeom.J = &cgeom->J[e*Np*dE*dE]; 2227132c3f7SMatthew G. Knepley fegeom.invJ = &cgeom->invJ[e*Np*dE*dE]; 2237132c3f7SMatthew G. Knepley fegeom.detJ = &cgeom->detJ[e*Np]; 22420cf1dd8SToby Isaac } 2254bee2e38SMatthew G. Knepley for (q = 0; q < Nq; ++q) { 2264bee2e38SMatthew G. Knepley PetscScalar integrand; 2274bee2e38SMatthew G. Knepley PetscReal w; 2284bee2e38SMatthew G. Knepley 2294bee2e38SMatthew G. Knepley if (isAffine) { 2307132c3f7SMatthew G. Knepley CoordinatesRefToReal(dE, dim, fegeom.xi, &cgeom->v[e*Np*dE], fegeom.J, &quadPoints[q*dim], x); 2314bee2e38SMatthew G. Knepley } else { 2324bee2e38SMatthew G. Knepley fegeom.v = &cgeom->v[(e*Np+q)*dE]; 2334bee2e38SMatthew G. Knepley fegeom.J = &cgeom->J[(e*Np+q)*dE*dE]; 2344bee2e38SMatthew G. Knepley fegeom.invJ = &cgeom->invJ[(e*Np+q)*dE*dE]; 2354bee2e38SMatthew G. Knepley fegeom.detJ = &cgeom->detJ[e*Np+q]; 2364bee2e38SMatthew G. Knepley } 2374bee2e38SMatthew G. Knepley w = fegeom.detJ[0]*quadWeights[q]; 23820cf1dd8SToby Isaac if (debug > 1 && q < Np) { 2394bee2e38SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " detJ: %g\n", fegeom.detJ[0]);CHKERRQ(ierr); 2407be5e748SToby Isaac #if !defined(PETSC_USE_COMPLEX) 2414bee2e38SMatthew G. Knepley ierr = DMPrintCellMatrix(e, "invJ", dim, dim, fegeom.invJ);CHKERRQ(ierr); 24220cf1dd8SToby Isaac #endif 24320cf1dd8SToby Isaac } 24420cf1dd8SToby Isaac if (debug) {ierr = PetscPrintf(PETSC_COMM_SELF, " quad point %d\n", q);CHKERRQ(ierr);} 245ef0bb6c7SMatthew G. Knepley ierr = PetscFEEvaluateFieldJets_Internal(ds, Nf, 0, q, T, &fegeom, &coefficients[cOffset], NULL, u, u_x, NULL);CHKERRQ(ierr); 246ef0bb6c7SMatthew G. Knepley if (dsAux) {ierr = PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, 0, q, TAux, &fegeom, &coefficientsAux[cOffsetAux], NULL, a, a_x, NULL);CHKERRQ(ierr);} 2474bee2e38SMatthew 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); 2484bee2e38SMatthew G. Knepley integrand *= w; 24920cf1dd8SToby Isaac integral[e*Nf+field] += integrand; 25020cf1dd8SToby Isaac if (debug > 1) {ierr = PetscPrintf(PETSC_COMM_SELF, " int: %g %g\n", (double) PetscRealPart(integrand), (double) PetscRealPart(integral[field]));CHKERRQ(ierr);} 25120cf1dd8SToby Isaac } 25220cf1dd8SToby Isaac cOffset += totDim; 25320cf1dd8SToby Isaac cOffsetAux += totDimAux; 25420cf1dd8SToby Isaac } 25520cf1dd8SToby Isaac PetscFunctionReturn(0); 25620cf1dd8SToby Isaac } 25720cf1dd8SToby Isaac 2582b99622eSMatthew G. Knepley static PetscErrorCode PetscFEIntegrateBd_Basic(PetscDS ds, PetscInt field, 259afe6d6adSToby Isaac PetscBdPointFunc obj_func, 2604bee2e38SMatthew G. Knepley PetscInt Ne, PetscFEGeom *fgeom, const PetscScalar coefficients[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscScalar integral[]) 261afe6d6adSToby Isaac { 262afe6d6adSToby Isaac const PetscInt debug = 0; 2634bee2e38SMatthew G. Knepley PetscFE fe; 264afe6d6adSToby Isaac PetscQuadrature quad; 265ef0bb6c7SMatthew G. Knepley PetscTabulation *Tf, *TfAux = NULL; 2664bee2e38SMatthew G. Knepley PetscScalar *u, *u_x, *a, *a_x, *basisReal, *basisDerReal; 267afe6d6adSToby Isaac const PetscScalar *constants; 268afe6d6adSToby Isaac PetscReal *x; 269ef0bb6c7SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL; 270afe6d6adSToby Isaac PetscBool isAffine, auxOnBd; 271afe6d6adSToby Isaac const PetscReal *quadPoints, *quadWeights; 272afe6d6adSToby Isaac PetscInt qNc, Nq, q, Np, dE; 273afe6d6adSToby Isaac PetscInt dim, dimAux, numConstants, Nf, NfAux = 0, totDim, totDimAux = 0, cOffset = 0, cOffsetAux = 0, e; 274afe6d6adSToby Isaac PetscErrorCode ierr; 275afe6d6adSToby Isaac 276afe6d6adSToby Isaac PetscFunctionBegin; 277afe6d6adSToby Isaac if (!obj_func) PetscFunctionReturn(0); 2784bee2e38SMatthew G. Knepley ierr = PetscDSGetDiscretization(ds, field, (PetscObject *) &fe);CHKERRQ(ierr); 2794bee2e38SMatthew G. Knepley ierr = PetscFEGetSpatialDimension(fe, &dim);CHKERRQ(ierr); 2804bee2e38SMatthew G. Knepley ierr = PetscFEGetFaceQuadrature(fe, &quad);CHKERRQ(ierr); 2814bee2e38SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 2824bee2e38SMatthew G. Knepley ierr = PetscDSGetTotalDimension(ds, &totDim);CHKERRQ(ierr); 2834bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(ds, &uOff);CHKERRQ(ierr); 2844bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(ds, &uOff_x);CHKERRQ(ierr); 2854bee2e38SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(ds, &u, NULL, &u_x);CHKERRQ(ierr); 2864bee2e38SMatthew G. Knepley ierr = PetscDSGetWorkspace(ds, &x, &basisReal, &basisDerReal, NULL, NULL);CHKERRQ(ierr); 287ef0bb6c7SMatthew G. Knepley ierr = PetscDSGetFaceTabulation(ds, &Tf);CHKERRQ(ierr); 2884bee2e38SMatthew G. Knepley ierr = PetscDSGetConstants(ds, &numConstants, &constants);CHKERRQ(ierr); 2894bee2e38SMatthew G. Knepley if (dsAux) { 2904bee2e38SMatthew G. Knepley ierr = PetscDSGetSpatialDimension(dsAux, &dimAux);CHKERRQ(ierr); 2914bee2e38SMatthew G. Knepley ierr = PetscDSGetNumFields(dsAux, &NfAux);CHKERRQ(ierr); 2924bee2e38SMatthew G. Knepley ierr = PetscDSGetTotalDimension(dsAux, &totDimAux);CHKERRQ(ierr); 2934bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(dsAux, &aOff);CHKERRQ(ierr); 2944bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x);CHKERRQ(ierr); 2954bee2e38SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(dsAux, &a, NULL, &a_x);CHKERRQ(ierr); 296afe6d6adSToby Isaac auxOnBd = dimAux < dim ? PETSC_TRUE : PETSC_FALSE; 297ef0bb6c7SMatthew G. Knepley if (auxOnBd) {ierr = PetscDSGetTabulation(dsAux, &TfAux);CHKERRQ(ierr);} 298ef0bb6c7SMatthew G. Knepley else {ierr = PetscDSGetFaceTabulation(dsAux, &TfAux);CHKERRQ(ierr);} 299afe6d6adSToby Isaac } 300afe6d6adSToby Isaac ierr = PetscQuadratureGetData(quad, NULL, &qNc, &Nq, &quadPoints, &quadWeights);CHKERRQ(ierr); 301afe6d6adSToby Isaac if (qNc != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supports scalar quadrature, not %D components\n", qNc); 302afe6d6adSToby Isaac Np = fgeom->numPoints; 303afe6d6adSToby Isaac dE = fgeom->dimEmbed; 304afe6d6adSToby Isaac isAffine = fgeom->isAffine; 305afe6d6adSToby Isaac for (e = 0; e < Ne; ++e) { 3069f209ee4SMatthew G. Knepley PetscFEGeom fegeom, cgeom; 307afe6d6adSToby Isaac const PetscInt face = fgeom->face[e][0]; /* Local face number in cell */ 3084dcf62a8SSatish Balay fegeom.n = 0; 3094dcf62a8SSatish Balay fegeom.v = 0; 3104dcf62a8SSatish Balay fegeom.J = 0; 3114dcf62a8SSatish Balay fegeom.detJ = 0; 31227f02ce8SMatthew G. Knepley fegeom.dim = fgeom->dim; 31327f02ce8SMatthew G. Knepley fegeom.dimEmbed = fgeom->dimEmbed; 31427f02ce8SMatthew G. Knepley cgeom.dim = fgeom->dim; 31527f02ce8SMatthew G. Knepley cgeom.dimEmbed = fgeom->dimEmbed; 3164bee2e38SMatthew G. Knepley if (isAffine) { 3174bee2e38SMatthew G. Knepley fegeom.v = x; 3184bee2e38SMatthew G. Knepley fegeom.xi = fgeom->xi; 3197132c3f7SMatthew G. Knepley fegeom.J = &fgeom->J[e*Np*dE*dE]; 3207132c3f7SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[e*Np*dE*dE]; 3217132c3f7SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e*Np]; 3227132c3f7SMatthew G. Knepley fegeom.n = &fgeom->n[e*Np*dE]; 3239f209ee4SMatthew G. Knepley 3247132c3f7SMatthew G. Knepley cgeom.J = &fgeom->suppJ[0][e*Np*dE*dE]; 3257132c3f7SMatthew G. Knepley cgeom.invJ = &fgeom->suppInvJ[0][e*Np*dE*dE]; 3267132c3f7SMatthew G. Knepley cgeom.detJ = &fgeom->suppDetJ[0][e*Np]; 3274bee2e38SMatthew G. Knepley } 328afe6d6adSToby Isaac for (q = 0; q < Nq; ++q) { 329afe6d6adSToby Isaac PetscScalar integrand; 3304bee2e38SMatthew G. Knepley PetscReal w; 331afe6d6adSToby Isaac 332afe6d6adSToby Isaac if (isAffine) { 3337132c3f7SMatthew G. Knepley CoordinatesRefToReal(dE, dim-1, fegeom.xi, &fgeom->v[e*Np*dE], fegeom.J, &quadPoints[q*(dim-1)], x); 334afe6d6adSToby Isaac } else { 3353fe841f2SMatthew G. Knepley fegeom.v = &fgeom->v[(e*Np+q)*dE]; 3369f209ee4SMatthew G. Knepley fegeom.J = &fgeom->J[(e*Np+q)*dE*dE]; 3379f209ee4SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[(e*Np+q)*dE*dE]; 3384bee2e38SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e*Np+q]; 3394bee2e38SMatthew G. Knepley fegeom.n = &fgeom->n[(e*Np+q)*dE]; 3409f209ee4SMatthew G. Knepley 3419f209ee4SMatthew G. Knepley cgeom.J = &fgeom->suppJ[0][(e*Np+q)*dE*dE]; 3429f209ee4SMatthew G. Knepley cgeom.invJ = &fgeom->suppInvJ[0][(e*Np+q)*dE*dE]; 3439f209ee4SMatthew G. Knepley cgeom.detJ = &fgeom->suppDetJ[0][e*Np+q]; 344afe6d6adSToby Isaac } 3454bee2e38SMatthew G. Knepley w = fegeom.detJ[0]*quadWeights[q]; 346afe6d6adSToby Isaac if (debug > 1 && q < Np) { 3474bee2e38SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " detJ: %g\n", fegeom.detJ[0]);CHKERRQ(ierr); 348afe6d6adSToby Isaac #ifndef PETSC_USE_COMPLEX 3494bee2e38SMatthew G. Knepley ierr = DMPrintCellMatrix(e, "invJ", dim, dim, fegeom.invJ);CHKERRQ(ierr); 350afe6d6adSToby Isaac #endif 351afe6d6adSToby Isaac } 352afe6d6adSToby Isaac if (debug > 1) {ierr = PetscPrintf(PETSC_COMM_SELF, " quad point %d\n", q);CHKERRQ(ierr);} 353ef0bb6c7SMatthew G. Knepley ierr = PetscFEEvaluateFieldJets_Internal(ds, Nf, face, q, Tf, &cgeom, &coefficients[cOffset], NULL, u, u_x, NULL);CHKERRQ(ierr); 354ef0bb6c7SMatthew G. Knepley if (dsAux) {ierr = PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, face, q, TfAux, &cgeom, &coefficientsAux[cOffsetAux], NULL, a, a_x, NULL);CHKERRQ(ierr);} 3554bee2e38SMatthew 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); 3564bee2e38SMatthew G. Knepley integrand *= w; 357afe6d6adSToby Isaac integral[e*Nf+field] += integrand; 358afe6d6adSToby Isaac if (debug > 1) {ierr = PetscPrintf(PETSC_COMM_SELF, " int: %g %g\n", (double) PetscRealPart(integrand), (double) PetscRealPart(integral[e*Nf+field]));CHKERRQ(ierr);} 359afe6d6adSToby Isaac } 360afe6d6adSToby Isaac cOffset += totDim; 361afe6d6adSToby Isaac cOffsetAux += totDimAux; 362afe6d6adSToby Isaac } 363afe6d6adSToby Isaac PetscFunctionReturn(0); 364afe6d6adSToby Isaac } 365afe6d6adSToby Isaac 3664bee2e38SMatthew G. Knepley PetscErrorCode PetscFEIntegrateResidual_Basic(PetscDS ds, PetscInt field, PetscInt Ne, PetscFEGeom *cgeom, 3674bee2e38SMatthew G. Knepley const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscReal t, PetscScalar elemVec[]) 36820cf1dd8SToby Isaac { 36920cf1dd8SToby Isaac const PetscInt debug = 0; 3704bee2e38SMatthew G. Knepley PetscFE fe; 37120cf1dd8SToby Isaac PetscPointFunc f0_func; 37220cf1dd8SToby Isaac PetscPointFunc f1_func; 37320cf1dd8SToby Isaac PetscQuadrature quad; 374ef0bb6c7SMatthew G. Knepley PetscTabulation *T, *TAux = NULL; 3754bee2e38SMatthew G. Knepley PetscScalar *f0, *f1, *u, *u_t = NULL, *u_x, *a, *a_x, *basisReal, *basisDerReal; 37620cf1dd8SToby Isaac const PetscScalar *constants; 37720cf1dd8SToby Isaac PetscReal *x; 378ef0bb6c7SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL; 379ef0bb6c7SMatthew G. Knepley PetscInt dim, numConstants, Nf, NfAux = 0, totDim, totDimAux = 0, cOffset = 0, cOffsetAux = 0, fOffset, e; 38020cf1dd8SToby Isaac PetscBool isAffine; 38120cf1dd8SToby Isaac const PetscReal *quadPoints, *quadWeights; 3824bee2e38SMatthew G. Knepley PetscInt qNc, Nq, q, Np, dE; 38320cf1dd8SToby Isaac PetscErrorCode ierr; 38420cf1dd8SToby Isaac 38520cf1dd8SToby Isaac PetscFunctionBegin; 3864bee2e38SMatthew G. Knepley ierr = PetscDSGetDiscretization(ds, field, (PetscObject *) &fe);CHKERRQ(ierr); 3874bee2e38SMatthew G. Knepley ierr = PetscFEGetSpatialDimension(fe, &dim);CHKERRQ(ierr); 3884bee2e38SMatthew G. Knepley ierr = PetscFEGetQuadrature(fe, &quad);CHKERRQ(ierr); 3894bee2e38SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 3904bee2e38SMatthew G. Knepley ierr = PetscDSGetTotalDimension(ds, &totDim);CHKERRQ(ierr); 3914bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(ds, &uOff);CHKERRQ(ierr); 3924bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(ds, &uOff_x);CHKERRQ(ierr); 3934bee2e38SMatthew G. Knepley ierr = PetscDSGetFieldOffset(ds, field, &fOffset);CHKERRQ(ierr); 3944bee2e38SMatthew G. Knepley ierr = PetscDSGetResidual(ds, field, &f0_func, &f1_func);CHKERRQ(ierr); 3954bee2e38SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(ds, &u, coefficients_t ? &u_t : NULL, &u_x);CHKERRQ(ierr); 3964bee2e38SMatthew G. Knepley ierr = PetscDSGetWorkspace(ds, &x, &basisReal, &basisDerReal, NULL, NULL);CHKERRQ(ierr); 3974bee2e38SMatthew G. Knepley ierr = PetscDSGetWeakFormArrays(ds, &f0, &f1, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 3984bee2e38SMatthew G. Knepley if (!f0_func && !f1_func) PetscFunctionReturn(0); 399ef0bb6c7SMatthew G. Knepley ierr = PetscDSGetTabulation(ds, &T);CHKERRQ(ierr); 4004bee2e38SMatthew G. Knepley ierr = PetscDSGetConstants(ds, &numConstants, &constants);CHKERRQ(ierr); 4014bee2e38SMatthew G. Knepley if (dsAux) { 4024bee2e38SMatthew G. Knepley ierr = PetscDSGetNumFields(dsAux, &NfAux);CHKERRQ(ierr); 4034bee2e38SMatthew G. Knepley ierr = PetscDSGetTotalDimension(dsAux, &totDimAux);CHKERRQ(ierr); 4044bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(dsAux, &aOff);CHKERRQ(ierr); 4054bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x);CHKERRQ(ierr); 4064bee2e38SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(dsAux, &a, NULL, &a_x);CHKERRQ(ierr); 407ef0bb6c7SMatthew G. Knepley ierr = PetscDSGetTabulation(dsAux, &TAux);CHKERRQ(ierr); 40820cf1dd8SToby Isaac } 40920cf1dd8SToby Isaac ierr = PetscQuadratureGetData(quad, NULL, &qNc, &Nq, &quadPoints, &quadWeights);CHKERRQ(ierr); 4104bee2e38SMatthew G. Knepley if (qNc != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supports scalar quadrature, not %D components\n", qNc); 41120cf1dd8SToby Isaac Np = cgeom->numPoints; 41220cf1dd8SToby Isaac dE = cgeom->dimEmbed; 41320cf1dd8SToby Isaac isAffine = cgeom->isAffine; 41420cf1dd8SToby Isaac for (e = 0; e < Ne; ++e) { 4154bee2e38SMatthew G. Knepley PetscFEGeom fegeom; 41620cf1dd8SToby Isaac 41727f02ce8SMatthew G. Knepley fegeom.dim = cgeom->dim; 41827f02ce8SMatthew G. Knepley fegeom.dimEmbed = cgeom->dimEmbed; 4194bee2e38SMatthew G. Knepley if (isAffine) { 4204bee2e38SMatthew G. Knepley fegeom.v = x; 4214bee2e38SMatthew G. Knepley fegeom.xi = cgeom->xi; 4227132c3f7SMatthew G. Knepley fegeom.J = &cgeom->J[e*Np*dE*dE]; 4237132c3f7SMatthew G. Knepley fegeom.invJ = &cgeom->invJ[e*Np*dE*dE]; 4247132c3f7SMatthew G. Knepley fegeom.detJ = &cgeom->detJ[e*Np]; 4254bee2e38SMatthew G. Knepley } 426ef0bb6c7SMatthew G. Knepley ierr = PetscArrayzero(f0, Nq*T[field]->Nc);CHKERRQ(ierr); 42727f02ce8SMatthew G. Knepley ierr = PetscArrayzero(f1, Nq*T[field]->Nc*dE);CHKERRQ(ierr); 42820cf1dd8SToby Isaac for (q = 0; q < Nq; ++q) { 4294bee2e38SMatthew G. Knepley PetscReal w; 4304bee2e38SMatthew G. Knepley PetscInt c, d; 43120cf1dd8SToby Isaac 43220cf1dd8SToby Isaac if (isAffine) { 4337132c3f7SMatthew G. Knepley CoordinatesRefToReal(dE, dim, fegeom.xi, &cgeom->v[e*Np*dE], fegeom.J, &quadPoints[q*dim], x); 43420cf1dd8SToby Isaac } else { 4354bee2e38SMatthew G. Knepley fegeom.v = &cgeom->v[(e*Np+q)*dE]; 4364bee2e38SMatthew G. Knepley fegeom.J = &cgeom->J[(e*Np+q)*dE*dE]; 4374bee2e38SMatthew G. Knepley fegeom.invJ = &cgeom->invJ[(e*Np+q)*dE*dE]; 4384bee2e38SMatthew G. Knepley fegeom.detJ = &cgeom->detJ[e*Np+q]; 43920cf1dd8SToby Isaac } 4404bee2e38SMatthew G. Knepley w = fegeom.detJ[0]*quadWeights[q]; 44120cf1dd8SToby Isaac if (debug > 1 && q < Np) { 4424bee2e38SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " detJ: %g\n", fegeom.detJ[0]);CHKERRQ(ierr); 4437be5e748SToby Isaac #if !defined(PETSC_USE_COMPLEX) 4444bee2e38SMatthew G. Knepley ierr = DMPrintCellMatrix(e, "invJ", dim, dim, fegeom.invJ);CHKERRQ(ierr); 44520cf1dd8SToby Isaac #endif 44620cf1dd8SToby Isaac } 44720cf1dd8SToby Isaac if (debug) {ierr = PetscPrintf(PETSC_COMM_SELF, " quad point %d\n", q);CHKERRQ(ierr);} 448ef0bb6c7SMatthew G. Knepley ierr = PetscFEEvaluateFieldJets_Internal(ds, Nf, 0, q, T, &fegeom, &coefficients[cOffset], &coefficients_t[cOffset], u, u_x, u_t);CHKERRQ(ierr); 449ef0bb6c7SMatthew G. Knepley if (dsAux) {ierr = PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, 0, q, TAux, &fegeom, &coefficientsAux[cOffsetAux], NULL, a, a_x, NULL);CHKERRQ(ierr);} 4504bee2e38SMatthew G. Knepley if (f0_func) { 451ef0bb6c7SMatthew G. Knepley f0_func(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]); 452ef0bb6c7SMatthew G. Knepley for (c = 0; c < T[field]->Nc; ++c) f0[q*T[field]->Nc+c] *= w; 4534bee2e38SMatthew G. Knepley } 45420cf1dd8SToby Isaac if (f1_func) { 455ef0bb6c7SMatthew G. Knepley f1_func(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]); 456ef0bb6c7SMatthew 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; 45720cf1dd8SToby Isaac } 45820cf1dd8SToby Isaac } 459ef0bb6c7SMatthew G. Knepley ierr = PetscFEUpdateElementVec_Internal(fe, T[field], 0, basisReal, basisDerReal, &fegeom, f0, f1, &elemVec[cOffset+fOffset]);CHKERRQ(ierr); 46020cf1dd8SToby Isaac cOffset += totDim; 46120cf1dd8SToby Isaac cOffsetAux += totDimAux; 46220cf1dd8SToby Isaac } 46320cf1dd8SToby Isaac PetscFunctionReturn(0); 46420cf1dd8SToby Isaac } 46520cf1dd8SToby Isaac 4664bee2e38SMatthew G. Knepley PetscErrorCode PetscFEIntegrateBdResidual_Basic(PetscDS ds, PetscInt field, PetscInt Ne, PetscFEGeom *fgeom, 4674bee2e38SMatthew G. Knepley const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscReal t, PetscScalar elemVec[]) 46820cf1dd8SToby Isaac { 46920cf1dd8SToby Isaac const PetscInt debug = 0; 4704bee2e38SMatthew G. Knepley PetscFE fe; 47120cf1dd8SToby Isaac PetscBdPointFunc f0_func; 47220cf1dd8SToby Isaac PetscBdPointFunc f1_func; 47320cf1dd8SToby Isaac PetscQuadrature quad; 474ef0bb6c7SMatthew G. Knepley PetscTabulation *Tf, *TfAux = NULL; 4754bee2e38SMatthew G. Knepley PetscScalar *f0, *f1, *u, *u_t = NULL, *u_x, *a, *a_x, *basisReal, *basisDerReal; 47620cf1dd8SToby Isaac const PetscScalar *constants; 47720cf1dd8SToby Isaac PetscReal *x; 478ef0bb6c7SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL; 479ef0bb6c7SMatthew G. Knepley PetscInt dim, dimAux, numConstants, Nf, NfAux = 0, totDim, totDimAux = 0, cOffset = 0, cOffsetAux = 0, fOffset, e, NcI; 480b07bd890SMatthew G. Knepley PetscBool isAffine, auxOnBd = PETSC_FALSE; 48120cf1dd8SToby Isaac const PetscReal *quadPoints, *quadWeights; 48220cf1dd8SToby Isaac PetscInt qNc, Nq, q, Np, dE; 48320cf1dd8SToby Isaac PetscErrorCode ierr; 48420cf1dd8SToby Isaac 48520cf1dd8SToby Isaac PetscFunctionBegin; 4864bee2e38SMatthew G. Knepley ierr = PetscDSGetDiscretization(ds, field, (PetscObject *) &fe);CHKERRQ(ierr); 4874bee2e38SMatthew G. Knepley ierr = PetscFEGetSpatialDimension(fe, &dim);CHKERRQ(ierr); 4884bee2e38SMatthew G. Knepley ierr = PetscFEGetFaceQuadrature(fe, &quad);CHKERRQ(ierr); 4894bee2e38SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 4904bee2e38SMatthew G. Knepley ierr = PetscDSGetTotalDimension(ds, &totDim);CHKERRQ(ierr); 4914bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(ds, &uOff);CHKERRQ(ierr); 4924bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(ds, &uOff_x);CHKERRQ(ierr); 4934bee2e38SMatthew G. Knepley ierr = PetscDSGetFieldOffset(ds, field, &fOffset);CHKERRQ(ierr); 4944bee2e38SMatthew G. Knepley ierr = PetscDSGetBdResidual(ds, field, &f0_func, &f1_func);CHKERRQ(ierr); 49520cf1dd8SToby Isaac if (!f0_func && !f1_func) PetscFunctionReturn(0); 4964bee2e38SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(ds, &u, coefficients_t ? &u_t : NULL, &u_x);CHKERRQ(ierr); 4974bee2e38SMatthew G. Knepley ierr = PetscDSGetWorkspace(ds, &x, &basisReal, &basisDerReal, NULL, NULL);CHKERRQ(ierr); 4984bee2e38SMatthew G. Knepley ierr = PetscDSGetWeakFormArrays(ds, &f0, &f1, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 499ef0bb6c7SMatthew G. Knepley ierr = PetscDSGetFaceTabulation(ds, &Tf);CHKERRQ(ierr); 5004bee2e38SMatthew G. Knepley ierr = PetscDSGetConstants(ds, &numConstants, &constants);CHKERRQ(ierr); 5014bee2e38SMatthew G. Knepley if (dsAux) { 5024bee2e38SMatthew G. Knepley ierr = PetscDSGetSpatialDimension(dsAux, &dimAux);CHKERRQ(ierr); 5034bee2e38SMatthew G. Knepley ierr = PetscDSGetNumFields(dsAux, &NfAux);CHKERRQ(ierr); 5044bee2e38SMatthew G. Knepley ierr = PetscDSGetTotalDimension(dsAux, &totDimAux);CHKERRQ(ierr); 5054bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(dsAux, &aOff);CHKERRQ(ierr); 5064bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x);CHKERRQ(ierr); 5074bee2e38SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(dsAux, &a, NULL, &a_x);CHKERRQ(ierr); 5087be5e748SToby Isaac auxOnBd = dimAux < dim ? PETSC_TRUE : PETSC_FALSE; 509ef0bb6c7SMatthew G. Knepley if (auxOnBd) {ierr = PetscDSGetTabulation(dsAux, &TfAux);CHKERRQ(ierr);} 510ef0bb6c7SMatthew G. Knepley else {ierr = PetscDSGetFaceTabulation(dsAux, &TfAux);CHKERRQ(ierr);} 51120cf1dd8SToby Isaac } 512ef0bb6c7SMatthew G. Knepley NcI = Tf[field]->Nc; 51320cf1dd8SToby Isaac ierr = PetscQuadratureGetData(quad, NULL, &qNc, &Nq, &quadPoints, &quadWeights);CHKERRQ(ierr); 514afe6d6adSToby Isaac if (qNc != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supports scalar quadrature, not %D components\n", qNc); 51520cf1dd8SToby Isaac Np = fgeom->numPoints; 51620cf1dd8SToby Isaac dE = fgeom->dimEmbed; 51720cf1dd8SToby Isaac isAffine = fgeom->isAffine; 51820cf1dd8SToby Isaac for (e = 0; e < Ne; ++e) { 5199f209ee4SMatthew G. Knepley PetscFEGeom fegeom, cgeom; 52020cf1dd8SToby Isaac const PetscInt face = fgeom->face[e][0]; 5214dcf62a8SSatish Balay fegeom.n = 0; 5224dcf62a8SSatish Balay fegeom.v = 0; 5234dcf62a8SSatish Balay fegeom.J = 0; 5244dcf62a8SSatish Balay fegeom.detJ = 0; 52527f02ce8SMatthew G. Knepley fegeom.dim = fgeom->dim; 52627f02ce8SMatthew G. Knepley fegeom.dimEmbed = fgeom->dimEmbed; 52727f02ce8SMatthew G. Knepley cgeom.dim = fgeom->dim; 52827f02ce8SMatthew G. Knepley cgeom.dimEmbed = fgeom->dimEmbed; 5294bee2e38SMatthew G. Knepley if (isAffine) { 5304bee2e38SMatthew G. Knepley fegeom.v = x; 5314bee2e38SMatthew G. Knepley fegeom.xi = fgeom->xi; 5327132c3f7SMatthew G. Knepley fegeom.J = &fgeom->J[e*Np*dE*dE]; 5337132c3f7SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[e*Np*dE*dE]; 5347132c3f7SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e*Np]; 5357132c3f7SMatthew G. Knepley fegeom.n = &fgeom->n[e*Np*dE]; 5369f209ee4SMatthew G. Knepley 5377132c3f7SMatthew G. Knepley cgeom.J = &fgeom->suppJ[0][e*Np*dE*dE]; 5387132c3f7SMatthew G. Knepley cgeom.invJ = &fgeom->suppInvJ[0][e*Np*dE*dE]; 5397132c3f7SMatthew G. Knepley cgeom.detJ = &fgeom->suppDetJ[0][e*Np]; 5404bee2e38SMatthew G. Knepley } 541580bdb30SBarry Smith ierr = PetscArrayzero(f0, Nq*NcI);CHKERRQ(ierr); 54227f02ce8SMatthew G. Knepley ierr = PetscArrayzero(f1, Nq*NcI*dE);CHKERRQ(ierr); 54320cf1dd8SToby Isaac for (q = 0; q < Nq; ++q) { 5444bee2e38SMatthew G. Knepley PetscReal w; 5454bee2e38SMatthew G. Knepley PetscInt c, d; 5464bee2e38SMatthew G. Knepley 54720cf1dd8SToby Isaac if (isAffine) { 5487132c3f7SMatthew G. Knepley CoordinatesRefToReal(dE, dim-1, fegeom.xi, &fgeom->v[e*Np*dE], fegeom.J, &quadPoints[q*(dim-1)], x); 54920cf1dd8SToby Isaac } else { 5503fe841f2SMatthew G. Knepley fegeom.v = &fgeom->v[(e*Np+q)*dE]; 5519f209ee4SMatthew G. Knepley fegeom.J = &fgeom->J[(e*Np+q)*dE*dE]; 5529f209ee4SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[(e*Np+q)*dE*dE]; 5534bee2e38SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e*Np+q]; 5544bee2e38SMatthew G. Knepley fegeom.n = &fgeom->n[(e*Np+q)*dE]; 5559f209ee4SMatthew G. Knepley 5569f209ee4SMatthew G. Knepley cgeom.J = &fgeom->suppJ[0][(e*Np+q)*dE*dE]; 5579f209ee4SMatthew G. Knepley cgeom.invJ = &fgeom->suppInvJ[0][(e*Np+q)*dE*dE]; 5589f209ee4SMatthew G. Knepley cgeom.detJ = &fgeom->suppDetJ[0][e*Np+q]; 55920cf1dd8SToby Isaac } 5604bee2e38SMatthew G. Knepley w = fegeom.detJ[0]*quadWeights[q]; 56120cf1dd8SToby Isaac if (debug > 1 && q < Np) { 5624bee2e38SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " detJ: %g\n", fegeom.detJ[0]);CHKERRQ(ierr); 5637be5e748SToby Isaac #if !defined(PETSC_USE_COMPLEX) 5644bee2e38SMatthew G. Knepley ierr = DMPrintCellMatrix(e, "invJ", dim, dim, fegeom.invJ);CHKERRQ(ierr); 56520cf1dd8SToby Isaac #endif 56620cf1dd8SToby Isaac } 56720cf1dd8SToby Isaac if (debug) {ierr = PetscPrintf(PETSC_COMM_SELF, " quad point %d\n", q);CHKERRQ(ierr);} 568ef0bb6c7SMatthew G. Knepley ierr = PetscFEEvaluateFieldJets_Internal(ds, Nf, face, q, Tf, &cgeom, &coefficients[cOffset], &coefficients_t[cOffset], u, u_x, u_t);CHKERRQ(ierr); 569ef0bb6c7SMatthew G. Knepley if (dsAux) {ierr = PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, auxOnBd ? 0 : face, q, TfAux, &cgeom, &coefficientsAux[cOffsetAux], NULL, a, a_x, NULL);CHKERRQ(ierr);} 5704bee2e38SMatthew G. Knepley if (f0_func) { 5714bee2e38SMatthew G. Knepley f0_func(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]); 5724bee2e38SMatthew G. Knepley for (c = 0; c < NcI; ++c) f0[q*NcI+c] *= w; 5734bee2e38SMatthew G. Knepley } 57420cf1dd8SToby Isaac if (f1_func) { 5754bee2e38SMatthew G. Knepley f1_func(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]); 5764bee2e38SMatthew G. Knepley for (c = 0; c < NcI; ++c) for (d = 0; d < dim; ++d) f1[(q*NcI+c)*dim+d] *= w; 57720cf1dd8SToby Isaac } 57820cf1dd8SToby Isaac } 579ef0bb6c7SMatthew G. Knepley ierr = PetscFEUpdateElementVec_Internal(fe, Tf[field], face, basisReal, basisDerReal, &cgeom, f0, f1, &elemVec[cOffset+fOffset]);CHKERRQ(ierr); 58020cf1dd8SToby Isaac cOffset += totDim; 58120cf1dd8SToby Isaac cOffsetAux += totDimAux; 58220cf1dd8SToby Isaac } 58320cf1dd8SToby Isaac PetscFunctionReturn(0); 58420cf1dd8SToby Isaac } 58520cf1dd8SToby Isaac 58627f02ce8SMatthew G. Knepley /* 58727f02ce8SMatthew 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 58827f02ce8SMatthew G. Knepley all transforms operate in the full space and are square. 58927f02ce8SMatthew G. Knepley 59027f02ce8SMatthew G. Knepley HybridIntegral: The discretization is lower dimensional. That means the transforms are non-square. 59127f02ce8SMatthew G. Knepley 1) DMPlexGetCellFields() retrieves from the hybrid cell, so it gets fields from both faces 59227f02ce8SMatthew G. Knepley 2) We need to assume that the orientation is 0 for both 59327f02ce8SMatthew 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() 59427f02ce8SMatthew G. Knepley */ 59527f02ce8SMatthew G. Knepley static PetscErrorCode PetscFEIntegrateHybridResidual_Basic(PetscDS ds, PetscInt field, PetscInt Ne, PetscFEGeom *fgeom, 59627f02ce8SMatthew G. Knepley const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscReal t, PetscScalar elemVec[]) 59727f02ce8SMatthew G. Knepley { 59827f02ce8SMatthew G. Knepley const PetscInt debug = 0; 59927f02ce8SMatthew G. Knepley PetscFE fe; 60027f02ce8SMatthew G. Knepley PetscBdPointFunc f0_func; 60127f02ce8SMatthew G. Knepley PetscBdPointFunc f1_func; 60227f02ce8SMatthew G. Knepley PetscQuadrature quad; 603*665f567fSMatthew G. Knepley PetscTabulation *Tf, *TfAux = NULL; 60427f02ce8SMatthew G. Knepley PetscScalar *f0, *f1, *u, *u_t = NULL, *u_x, *a, *a_x, *basisReal, *basisDerReal; 60527f02ce8SMatthew G. Knepley const PetscScalar *constants; 60627f02ce8SMatthew G. Knepley PetscReal *x; 607*665f567fSMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL; 608*665f567fSMatthew G. Knepley PetscInt dim, dimAux, numConstants, Nf, NfAux = 0, totDim, totDimAux = 0, cOffset = 0, cOffsetAux = 0, fOffset, e, NcI, NcS; 609*665f567fSMatthew G. Knepley PetscBool isCohesiveField, isAffine, auxOnBd = PETSC_FALSE; 61027f02ce8SMatthew G. Knepley const PetscReal *quadPoints, *quadWeights; 61127f02ce8SMatthew G. Knepley PetscInt qNc, Nq, q, Np, dE; 61227f02ce8SMatthew G. Knepley PetscErrorCode ierr; 61327f02ce8SMatthew G. Knepley 61427f02ce8SMatthew G. Knepley PetscFunctionBegin; 61527f02ce8SMatthew G. Knepley /* Hybrid discretization is posed directly on faces */ 61627f02ce8SMatthew G. Knepley ierr = PetscDSGetDiscretization(ds, field, (PetscObject *) &fe);CHKERRQ(ierr); 61727f02ce8SMatthew G. Knepley ierr = PetscFEGetSpatialDimension(fe, &dim);CHKERRQ(ierr); 61827f02ce8SMatthew G. Knepley ierr = PetscFEGetQuadrature(fe, &quad);CHKERRQ(ierr); 61927f02ce8SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 62027f02ce8SMatthew G. Knepley ierr = PetscDSGetTotalDimension(ds, &totDim);CHKERRQ(ierr); 62127f02ce8SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(ds, &uOff);CHKERRQ(ierr); 62227f02ce8SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(ds, &uOff_x);CHKERRQ(ierr); 62327f02ce8SMatthew G. Knepley ierr = PetscDSGetFieldOffset(ds, field, &fOffset);CHKERRQ(ierr); 62427f02ce8SMatthew G. Knepley ierr = PetscDSGetBdResidual(ds, field, &f0_func, &f1_func);CHKERRQ(ierr); 62527f02ce8SMatthew G. Knepley if (!f0_func && !f1_func) PetscFunctionReturn(0); 62627f02ce8SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(ds, &u, coefficients_t ? &u_t : NULL, &u_x);CHKERRQ(ierr); 62727f02ce8SMatthew G. Knepley ierr = PetscDSGetWorkspace(ds, &x, &basisReal, &basisDerReal, NULL, NULL);CHKERRQ(ierr); 62827f02ce8SMatthew G. Knepley ierr = PetscDSGetWeakFormArrays(ds, &f0, &f1, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 62927f02ce8SMatthew G. Knepley /* NOTE This is a bulk tabulation because the DS is a face discretization */ 630*665f567fSMatthew G. Knepley ierr = PetscDSGetTabulation(ds, &Tf);CHKERRQ(ierr); 63127f02ce8SMatthew G. Knepley ierr = PetscDSGetConstants(ds, &numConstants, &constants);CHKERRQ(ierr); 63227f02ce8SMatthew G. Knepley if (dsAux) { 63327f02ce8SMatthew G. Knepley ierr = PetscDSGetSpatialDimension(dsAux, &dimAux);CHKERRQ(ierr); 63427f02ce8SMatthew G. Knepley ierr = PetscDSGetNumFields(dsAux, &NfAux);CHKERRQ(ierr); 63527f02ce8SMatthew G. Knepley ierr = PetscDSGetTotalDimension(dsAux, &totDimAux);CHKERRQ(ierr); 63627f02ce8SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(dsAux, &aOff);CHKERRQ(ierr); 63727f02ce8SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x);CHKERRQ(ierr); 63827f02ce8SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(dsAux, &a, NULL, &a_x);CHKERRQ(ierr); 63927f02ce8SMatthew G. Knepley auxOnBd = dimAux < dim ? PETSC_TRUE : PETSC_FALSE; 640*665f567fSMatthew G. Knepley if (auxOnBd) {ierr = PetscDSGetTabulation(dsAux, &TfAux);CHKERRQ(ierr);} 641*665f567fSMatthew G. Knepley else {ierr = PetscDSGetFaceTabulation(dsAux, &TfAux);CHKERRQ(ierr);} 64227f02ce8SMatthew G. Knepley } 64327f02ce8SMatthew G. Knepley isCohesiveField = field == Nf-1 ? PETSC_TRUE : PETSC_FALSE; 644*665f567fSMatthew G. Knepley NcI = Tf[field]->Nc; 64527f02ce8SMatthew G. Knepley NcS = isCohesiveField ? NcI : 2*NcI; 64627f02ce8SMatthew G. Knepley ierr = PetscQuadratureGetData(quad, NULL, &qNc, &Nq, &quadPoints, &quadWeights);CHKERRQ(ierr); 64727f02ce8SMatthew G. Knepley if (qNc != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supports scalar quadrature, not %D components\n", qNc); 64827f02ce8SMatthew G. Knepley Np = fgeom->numPoints; 64927f02ce8SMatthew G. Knepley dE = fgeom->dimEmbed; 65027f02ce8SMatthew G. Knepley isAffine = fgeom->isAffine; 65127f02ce8SMatthew G. Knepley for (e = 0; e < Ne; ++e) { 65227f02ce8SMatthew G. Knepley PetscFEGeom fegeom; 65327f02ce8SMatthew G. Knepley const PetscInt face = fgeom->face[e][0]; 65427f02ce8SMatthew G. Knepley 65527f02ce8SMatthew G. Knepley fegeom.dim = fgeom->dim; 65627f02ce8SMatthew G. Knepley fegeom.dimEmbed = fgeom->dimEmbed; 65727f02ce8SMatthew G. Knepley if (isAffine) { 65827f02ce8SMatthew G. Knepley fegeom.v = x; 65927f02ce8SMatthew G. Knepley fegeom.xi = fgeom->xi; 66027f02ce8SMatthew G. Knepley fegeom.J = &fgeom->J[e*dE*dE]; 66127f02ce8SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[e*dE*dE]; 66227f02ce8SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e]; 66327f02ce8SMatthew G. Knepley fegeom.n = &fgeom->n[e*dE]; 66427f02ce8SMatthew G. Knepley } 66527f02ce8SMatthew G. Knepley ierr = PetscArrayzero(f0, Nq*NcS);CHKERRQ(ierr); 66627f02ce8SMatthew G. Knepley ierr = PetscArrayzero(f1, Nq*NcS*dE);CHKERRQ(ierr); 66727f02ce8SMatthew G. Knepley for (q = 0; q < Nq; ++q) { 66827f02ce8SMatthew G. Knepley PetscReal w; 66927f02ce8SMatthew G. Knepley PetscInt c, d; 67027f02ce8SMatthew G. Knepley 67127f02ce8SMatthew G. Knepley if (isAffine) { 67227f02ce8SMatthew G. Knepley CoordinatesRefToReal(dE, dim, fegeom.xi, &fgeom->v[e*dE], fegeom.J, &quadPoints[q*dim], x); 67327f02ce8SMatthew G. Knepley } else { 67427f02ce8SMatthew G. Knepley fegeom.v = &fgeom->v[(e*Np+q)*dE]; 67527f02ce8SMatthew G. Knepley fegeom.J = &fgeom->J[(e*Np+q)*dE*dE]; 67627f02ce8SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[(e*Np+q)*dE*dE]; 67727f02ce8SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e*Np+q]; 67827f02ce8SMatthew G. Knepley fegeom.n = &fgeom->n[(e*Np+q)*dE]; 67927f02ce8SMatthew G. Knepley } 68027f02ce8SMatthew G. Knepley w = fegeom.detJ[0]*quadWeights[q]; 68127f02ce8SMatthew G. Knepley if (debug > 1 && q < Np) { 68227f02ce8SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " detJ: %g\n", fegeom.detJ[0]);CHKERRQ(ierr); 68327f02ce8SMatthew G. Knepley #if !defined(PETSC_USE_COMPLEX) 68427f02ce8SMatthew G. Knepley ierr = DMPrintCellMatrix(e, "invJ", dim, dE, fegeom.invJ);CHKERRQ(ierr); 68527f02ce8SMatthew G. Knepley #endif 68627f02ce8SMatthew G. Knepley } 68727f02ce8SMatthew G. Knepley if (debug) {ierr = PetscPrintf(PETSC_COMM_SELF, " quad point %d\n", q);CHKERRQ(ierr);} 68827f02ce8SMatthew G. Knepley /* TODO Is this cell or face quadrature, meaning should we use 'q' or 'face*Nq+q' */ 689*665f567fSMatthew G. Knepley ierr = PetscFEEvaluateFieldJets_Hybrid_Internal(ds, Nf, 0, q, Tf, &fegeom, &coefficients[cOffset], &coefficients_t[cOffset], u, u_x, u_t);CHKERRQ(ierr); 690*665f567fSMatthew G. Knepley if (dsAux) {ierr = PetscFEEvaluateFieldJets_Hybrid_Internal(dsAux, NfAux, 0, auxOnBd ? q : face*Nq+q, TfAux, &fegeom, &coefficientsAux[cOffsetAux], NULL, a, a_x, NULL);CHKERRQ(ierr);} 69127f02ce8SMatthew G. Knepley if (f0_func) { 69227f02ce8SMatthew G. Knepley f0_func(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]); 69327f02ce8SMatthew G. Knepley for (c = 0; c < NcS; ++c) f0[q*NcS+c] *= w; 69427f02ce8SMatthew G. Knepley } 69527f02ce8SMatthew G. Knepley if (f1_func) { 69627f02ce8SMatthew G. Knepley f1_func(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*dim]); 69727f02ce8SMatthew G. Knepley for (c = 0; c < NcS; ++c) for (d = 0; d < dim; ++d) f1[(q*NcS+c)*dim+d] *= w; 69827f02ce8SMatthew G. Knepley } 69927f02ce8SMatthew G. Knepley } 700*665f567fSMatthew G. Knepley if (isCohesiveField) {PetscFEUpdateElementVec_Internal(fe, Tf[field], 0, basisReal, basisDerReal, &fegeom, f0, f1, &elemVec[cOffset+fOffset*2]);} 701*665f567fSMatthew G. Knepley else {PetscFEUpdateElementVec_Hybrid_Internal(fe, Tf[field], 0, basisReal, basisDerReal, &fegeom, f0, f1, &elemVec[cOffset+fOffset*2]);} 70227f02ce8SMatthew G. Knepley cOffset += totDim; 70327f02ce8SMatthew G. Knepley cOffsetAux += totDimAux; 70427f02ce8SMatthew G. Knepley } 70527f02ce8SMatthew G. Knepley PetscFunctionReturn(0); 70627f02ce8SMatthew G. Knepley } 70727f02ce8SMatthew G. Knepley 7084bee2e38SMatthew G. Knepley PetscErrorCode PetscFEIntegrateJacobian_Basic(PetscDS ds, PetscFEJacobianType jtype, PetscInt fieldI, PetscInt fieldJ, PetscInt Ne, PetscFEGeom *cgeom, 7094bee2e38SMatthew G. Knepley const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscReal t, PetscReal u_tshift, PetscScalar elemMat[]) 71020cf1dd8SToby Isaac { 71120cf1dd8SToby Isaac const PetscInt debug = 0; 7124bee2e38SMatthew G. Knepley PetscFE feI, feJ; 7134bee2e38SMatthew G. Knepley PetscPointJac g0_func, g1_func, g2_func, g3_func; 71420cf1dd8SToby Isaac PetscInt cOffset = 0; /* Offset into coefficients[] for element e */ 71520cf1dd8SToby Isaac PetscInt cOffsetAux = 0; /* Offset into coefficientsAux[] for element e */ 71620cf1dd8SToby Isaac PetscInt eOffset = 0; /* Offset into elemMat[] for element e */ 71720cf1dd8SToby Isaac PetscInt offsetI = 0; /* Offset into an element vector for fieldI */ 71820cf1dd8SToby Isaac PetscInt offsetJ = 0; /* Offset into an element vector for fieldJ */ 71920cf1dd8SToby Isaac PetscQuadrature quad; 720ef0bb6c7SMatthew G. Knepley PetscTabulation *T, *TAux = NULL; 7214bee2e38SMatthew G. Knepley PetscScalar *g0, *g1, *g2, *g3, *u, *u_t = NULL, *u_x, *a, *a_x, *basisReal, *basisDerReal, *testReal, *testDerReal; 72220cf1dd8SToby Isaac const PetscScalar *constants; 72320cf1dd8SToby Isaac PetscReal *x; 724ef0bb6c7SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL; 725ef0bb6c7SMatthew G. Knepley PetscInt NcI = 0, NcJ = 0; 72620cf1dd8SToby Isaac PetscInt dim, numConstants, Nf, NfAux = 0, totDim, totDimAux = 0, e; 72720cf1dd8SToby Isaac PetscInt dE, Np; 72820cf1dd8SToby Isaac PetscBool isAffine; 72920cf1dd8SToby Isaac const PetscReal *quadPoints, *quadWeights; 73020cf1dd8SToby Isaac PetscInt qNc, Nq, q; 73120cf1dd8SToby Isaac PetscErrorCode ierr; 73220cf1dd8SToby Isaac 73320cf1dd8SToby Isaac PetscFunctionBegin; 7344bee2e38SMatthew G. Knepley ierr = PetscDSGetDiscretization(ds, fieldI, (PetscObject *) &feI);CHKERRQ(ierr); 7354bee2e38SMatthew G. Knepley ierr = PetscDSGetDiscretization(ds, fieldJ, (PetscObject *) &feJ);CHKERRQ(ierr); 7364bee2e38SMatthew G. Knepley ierr = PetscFEGetSpatialDimension(feI, &dim);CHKERRQ(ierr); 7374bee2e38SMatthew G. Knepley ierr = PetscFEGetQuadrature(feI, &quad);CHKERRQ(ierr); 7384bee2e38SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 7394bee2e38SMatthew G. Knepley ierr = PetscDSGetTotalDimension(ds, &totDim);CHKERRQ(ierr); 7404bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(ds, &uOff);CHKERRQ(ierr); 7414bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(ds, &uOff_x);CHKERRQ(ierr); 74220cf1dd8SToby Isaac switch(jtype) { 7434bee2e38SMatthew G. Knepley case PETSCFE_JACOBIAN_DYN: ierr = PetscDSGetDynamicJacobian(ds, fieldI, fieldJ, &g0_func, &g1_func, &g2_func, &g3_func);CHKERRQ(ierr);break; 7444bee2e38SMatthew G. Knepley case PETSCFE_JACOBIAN_PRE: ierr = PetscDSGetJacobianPreconditioner(ds, fieldI, fieldJ, &g0_func, &g1_func, &g2_func, &g3_func);CHKERRQ(ierr);break; 7454bee2e38SMatthew G. Knepley case PETSCFE_JACOBIAN: ierr = PetscDSGetJacobian(ds, fieldI, fieldJ, &g0_func, &g1_func, &g2_func, &g3_func);CHKERRQ(ierr);break; 74620cf1dd8SToby Isaac } 74720cf1dd8SToby Isaac if (!g0_func && !g1_func && !g2_func && !g3_func) PetscFunctionReturn(0); 7484bee2e38SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(ds, &u, coefficients_t ? &u_t : NULL, &u_x);CHKERRQ(ierr); 7494bee2e38SMatthew G. Knepley ierr = PetscDSGetWorkspace(ds, &x, &basisReal, &basisDerReal, &testReal, &testDerReal);CHKERRQ(ierr); 7504bee2e38SMatthew G. Knepley ierr = PetscDSGetWeakFormArrays(ds, NULL, NULL, &g0, &g1, &g2, &g3);CHKERRQ(ierr); 751ef0bb6c7SMatthew G. Knepley ierr = PetscDSGetTabulation(ds, &T);CHKERRQ(ierr); 7524bee2e38SMatthew G. Knepley ierr = PetscDSGetFieldOffset(ds, fieldI, &offsetI);CHKERRQ(ierr); 7534bee2e38SMatthew G. Knepley ierr = PetscDSGetFieldOffset(ds, fieldJ, &offsetJ);CHKERRQ(ierr); 7544bee2e38SMatthew G. Knepley ierr = PetscDSGetConstants(ds, &numConstants, &constants);CHKERRQ(ierr); 7554bee2e38SMatthew G. Knepley if (dsAux) { 7564bee2e38SMatthew G. Knepley ierr = PetscDSGetNumFields(dsAux, &NfAux);CHKERRQ(ierr); 7574bee2e38SMatthew G. Knepley ierr = PetscDSGetTotalDimension(dsAux, &totDimAux);CHKERRQ(ierr); 7584bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(dsAux, &aOff);CHKERRQ(ierr); 7594bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x);CHKERRQ(ierr); 7604bee2e38SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(dsAux, &a, NULL, &a_x);CHKERRQ(ierr); 761ef0bb6c7SMatthew G. Knepley ierr = PetscDSGetTabulation(dsAux, &TAux);CHKERRQ(ierr); 76220cf1dd8SToby Isaac } 76327f02ce8SMatthew G. Knepley NcI = T[fieldI]->Nc; 76427f02ce8SMatthew G. Knepley NcJ = T[fieldJ]->Nc; 7654bee2e38SMatthew G. Knepley Np = cgeom->numPoints; 7664bee2e38SMatthew G. Knepley dE = cgeom->dimEmbed; 7674bee2e38SMatthew G. Knepley isAffine = cgeom->isAffine; 76827f02ce8SMatthew G. Knepley /* Initialize here in case the function is not defined */ 76927f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g0, NcI*NcJ);CHKERRQ(ierr); 77027f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g1, NcI*NcJ*dE);CHKERRQ(ierr); 77127f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g2, NcI*NcJ*dE);CHKERRQ(ierr); 77227f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g3, NcI*NcJ*dE*dE);CHKERRQ(ierr); 77327f02ce8SMatthew G. Knepley ierr = PetscQuadratureGetData(quad, NULL, &qNc, &Nq, &quadPoints, &quadWeights);CHKERRQ(ierr); 77427f02ce8SMatthew G. Knepley if (qNc != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supports scalar quadrature, not %D components\n", qNc); 7754bee2e38SMatthew G. Knepley for (e = 0; e < Ne; ++e) { 7764bee2e38SMatthew G. Knepley PetscFEGeom fegeom; 7774bee2e38SMatthew G. Knepley 77827f02ce8SMatthew G. Knepley fegeom.dim = cgeom->dim; 77927f02ce8SMatthew G. Knepley fegeom.dimEmbed = cgeom->dimEmbed; 7804bee2e38SMatthew G. Knepley if (isAffine) { 7814bee2e38SMatthew G. Knepley fegeom.v = x; 7824bee2e38SMatthew G. Knepley fegeom.xi = cgeom->xi; 7837132c3f7SMatthew G. Knepley fegeom.J = &cgeom->J[e*Np*dE*dE]; 7847132c3f7SMatthew G. Knepley fegeom.invJ = &cgeom->invJ[e*Np*dE*dE]; 7857132c3f7SMatthew G. Knepley fegeom.detJ = &cgeom->detJ[e*Np]; 7864bee2e38SMatthew G. Knepley } 78720cf1dd8SToby Isaac for (q = 0; q < Nq; ++q) { 78820cf1dd8SToby Isaac PetscReal w; 7894bee2e38SMatthew G. Knepley PetscInt c; 79020cf1dd8SToby Isaac 79120cf1dd8SToby Isaac if (debug) {ierr = PetscPrintf(PETSC_COMM_SELF, " quad point %d\n", q);CHKERRQ(ierr);} 79220cf1dd8SToby Isaac if (isAffine) { 7937132c3f7SMatthew G. Knepley CoordinatesRefToReal(dE, dim, fegeom.xi, &cgeom->v[e*Np*dE], fegeom.J, &quadPoints[q*dim], x); 79420cf1dd8SToby Isaac } else { 7954bee2e38SMatthew G. Knepley fegeom.v = &cgeom->v[(e*Np+q)*dE]; 7964bee2e38SMatthew G. Knepley fegeom.J = &cgeom->J[(e*Np+q)*dE*dE]; 7974bee2e38SMatthew G. Knepley fegeom.invJ = &cgeom->invJ[(e*Np+q)*dE*dE]; 7984bee2e38SMatthew G. Knepley fegeom.detJ = &cgeom->detJ[e*Np+q]; 79920cf1dd8SToby Isaac } 8004bee2e38SMatthew G. Knepley w = fegeom.detJ[0]*quadWeights[q]; 801ef0bb6c7SMatthew G. Knepley if (coefficients) {ierr = PetscFEEvaluateFieldJets_Internal(ds, Nf, 0, q, T, &fegeom, &coefficients[cOffset], &coefficients_t[cOffset], u, u_x, u_t);CHKERRQ(ierr);} 802ef0bb6c7SMatthew G. Knepley if (dsAux) {ierr = PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, 0, q, TAux, &fegeom, &coefficientsAux[cOffsetAux], NULL, a, a_x, NULL);CHKERRQ(ierr);} 80320cf1dd8SToby Isaac if (g0_func) { 804580bdb30SBarry Smith ierr = PetscArrayzero(g0, NcI*NcJ);CHKERRQ(ierr); 8054bee2e38SMatthew G. Knepley g0_func(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); 80620cf1dd8SToby Isaac for (c = 0; c < NcI*NcJ; ++c) g0[c] *= w; 80720cf1dd8SToby Isaac } 80820cf1dd8SToby Isaac if (g1_func) { 80927f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g1, NcI*NcJ*dE);CHKERRQ(ierr); 8104bee2e38SMatthew G. Knepley g1_func(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); 8114bee2e38SMatthew G. Knepley for (c = 0; c < NcI*NcJ*dim; ++c) g1[c] *= w; 81220cf1dd8SToby Isaac } 81320cf1dd8SToby Isaac if (g2_func) { 81427f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g2, NcI*NcJ*dE);CHKERRQ(ierr); 8154bee2e38SMatthew G. Knepley g2_func(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); 8164bee2e38SMatthew G. Knepley for (c = 0; c < NcI*NcJ*dim; ++c) g2[c] *= w; 81720cf1dd8SToby Isaac } 81820cf1dd8SToby Isaac if (g3_func) { 81927f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g3, NcI*NcJ*dE*dE);CHKERRQ(ierr); 8204bee2e38SMatthew G. Knepley g3_func(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); 8214bee2e38SMatthew G. Knepley for (c = 0; c < NcI*NcJ*dim*dim; ++c) g3[c] *= w; 82220cf1dd8SToby Isaac } 82320cf1dd8SToby Isaac 824ef0bb6c7SMatthew G. Knepley ierr = PetscFEUpdateElementMat_Internal(feI, feJ, 0, q, T[fieldI], basisReal, basisDerReal, T[fieldJ], testReal, testDerReal, &fegeom, g0, g1, g2, g3, eOffset, totDim, offsetI, offsetJ, elemMat);CHKERRQ(ierr); 82520cf1dd8SToby Isaac } 82620cf1dd8SToby Isaac if (debug > 1) { 82720cf1dd8SToby Isaac PetscInt fc, f, gc, g; 82820cf1dd8SToby Isaac 82920cf1dd8SToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "Element matrix for fields %d and %d\n", fieldI, fieldJ);CHKERRQ(ierr); 830ef0bb6c7SMatthew G. Knepley for (fc = 0; fc < T[fieldI]->Nc; ++fc) { 831ef0bb6c7SMatthew G. Knepley for (f = 0; f < T[fieldI]->Nb; ++f) { 832ef0bb6c7SMatthew G. Knepley const PetscInt i = offsetI + f*T[fieldI]->Nc+fc; 833ef0bb6c7SMatthew G. Knepley for (gc = 0; gc < T[fieldJ]->Nc; ++gc) { 834ef0bb6c7SMatthew G. Knepley for (g = 0; g < T[fieldJ]->Nb; ++g) { 835ef0bb6c7SMatthew G. Knepley const PetscInt j = offsetJ + g*T[fieldJ]->Nc+gc; 83620cf1dd8SToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, " elemMat[%d,%d,%d,%d]: %g\n", f, fc, g, gc, PetscRealPart(elemMat[eOffset+i*totDim+j]));CHKERRQ(ierr); 83720cf1dd8SToby Isaac } 83820cf1dd8SToby Isaac } 83920cf1dd8SToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 84020cf1dd8SToby Isaac } 84120cf1dd8SToby Isaac } 84220cf1dd8SToby Isaac } 84320cf1dd8SToby Isaac cOffset += totDim; 84420cf1dd8SToby Isaac cOffsetAux += totDimAux; 84520cf1dd8SToby Isaac eOffset += PetscSqr(totDim); 84620cf1dd8SToby Isaac } 84720cf1dd8SToby Isaac PetscFunctionReturn(0); 84820cf1dd8SToby Isaac } 84920cf1dd8SToby Isaac 8502b99622eSMatthew G. Knepley static PetscErrorCode PetscFEIntegrateBdJacobian_Basic(PetscDS ds, PetscInt fieldI, PetscInt fieldJ, PetscInt Ne, PetscFEGeom *fgeom, 8514bee2e38SMatthew G. Knepley const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscReal t, PetscReal u_tshift, PetscScalar elemMat[]) 85220cf1dd8SToby Isaac { 85320cf1dd8SToby Isaac const PetscInt debug = 0; 8544bee2e38SMatthew G. Knepley PetscFE feI, feJ; 8554bee2e38SMatthew G. Knepley PetscBdPointJac g0_func, g1_func, g2_func, g3_func; 85620cf1dd8SToby Isaac PetscInt cOffset = 0; /* Offset into coefficients[] for element e */ 85720cf1dd8SToby Isaac PetscInt cOffsetAux = 0; /* Offset into coefficientsAux[] for element e */ 85820cf1dd8SToby Isaac PetscInt eOffset = 0; /* Offset into elemMat[] for element e */ 85920cf1dd8SToby Isaac PetscInt offsetI = 0; /* Offset into an element vector for fieldI */ 86020cf1dd8SToby Isaac PetscInt offsetJ = 0; /* Offset into an element vector for fieldJ */ 86120cf1dd8SToby Isaac PetscQuadrature quad; 862ef0bb6c7SMatthew G. Knepley PetscTabulation *T, *TAux = NULL; 8634bee2e38SMatthew G. Knepley PetscScalar *g0, *g1, *g2, *g3, *u, *u_t = NULL, *u_x, *a, *a_x, *basisReal, *basisDerReal, *testReal, *testDerReal; 86420cf1dd8SToby Isaac const PetscScalar *constants; 86520cf1dd8SToby Isaac PetscReal *x; 866ef0bb6c7SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL; 867ef0bb6c7SMatthew G. Knepley PetscInt NcI = 0, NcJ = 0; 86820cf1dd8SToby Isaac PetscInt dim, numConstants, Nf, NfAux = 0, totDim, totDimAux = 0, e; 86920cf1dd8SToby Isaac PetscBool isAffine; 87020cf1dd8SToby Isaac const PetscReal *quadPoints, *quadWeights; 87120cf1dd8SToby Isaac PetscInt qNc, Nq, q, Np, dE; 87220cf1dd8SToby Isaac PetscErrorCode ierr; 87320cf1dd8SToby Isaac 87420cf1dd8SToby Isaac PetscFunctionBegin; 8754bee2e38SMatthew G. Knepley ierr = PetscDSGetDiscretization(ds, fieldI, (PetscObject *) &feI);CHKERRQ(ierr); 8764bee2e38SMatthew G. Knepley ierr = PetscDSGetDiscretization(ds, fieldJ, (PetscObject *) &feJ);CHKERRQ(ierr); 8774bee2e38SMatthew G. Knepley ierr = PetscFEGetSpatialDimension(feI, &dim);CHKERRQ(ierr); 8784bee2e38SMatthew G. Knepley ierr = PetscFEGetFaceQuadrature(feI, &quad);CHKERRQ(ierr); 8794bee2e38SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 8804bee2e38SMatthew G. Knepley ierr = PetscDSGetTotalDimension(ds, &totDim);CHKERRQ(ierr); 8814bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(ds, &uOff);CHKERRQ(ierr); 8824bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(ds, &uOff_x);CHKERRQ(ierr); 8834bee2e38SMatthew G. Knepley ierr = PetscDSGetFieldOffset(ds, fieldI, &offsetI);CHKERRQ(ierr); 8844bee2e38SMatthew G. Knepley ierr = PetscDSGetFieldOffset(ds, fieldJ, &offsetJ);CHKERRQ(ierr); 8854bee2e38SMatthew G. Knepley ierr = PetscDSGetBdJacobian(ds, fieldI, fieldJ, &g0_func, &g1_func, &g2_func, &g3_func);CHKERRQ(ierr); 88631f073d7SMatthew G. Knepley if (!g0_func && !g1_func && !g2_func && !g3_func) PetscFunctionReturn(0); 8874bee2e38SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(ds, &u, coefficients_t ? &u_t : NULL, &u_x);CHKERRQ(ierr); 8884bee2e38SMatthew G. Knepley ierr = PetscDSGetWorkspace(ds, &x, &basisReal, &basisDerReal, &testReal, &testDerReal);CHKERRQ(ierr); 8894bee2e38SMatthew G. Knepley ierr = PetscDSGetWeakFormArrays(ds, NULL, NULL, &g0, &g1, &g2, &g3);CHKERRQ(ierr); 890ef0bb6c7SMatthew G. Knepley ierr = PetscDSGetFaceTabulation(ds, &T);CHKERRQ(ierr); 8914bee2e38SMatthew G. Knepley ierr = PetscDSGetConstants(ds, &numConstants, &constants);CHKERRQ(ierr); 8924bee2e38SMatthew G. Knepley if (dsAux) { 8934bee2e38SMatthew G. Knepley ierr = PetscDSGetNumFields(dsAux, &NfAux);CHKERRQ(ierr); 8944bee2e38SMatthew G. Knepley ierr = PetscDSGetTotalDimension(dsAux, &totDimAux);CHKERRQ(ierr); 8954bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(dsAux, &aOff);CHKERRQ(ierr); 8964bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x);CHKERRQ(ierr); 8974bee2e38SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(dsAux, &a, NULL, &a_x);CHKERRQ(ierr); 898ef0bb6c7SMatthew G. Knepley ierr = PetscDSGetFaceTabulation(dsAux, &TAux);CHKERRQ(ierr); 89920cf1dd8SToby Isaac } 900ef0bb6c7SMatthew G. Knepley NcI = T[fieldI]->Nc, NcJ = T[fieldJ]->Nc; 90120cf1dd8SToby Isaac Np = fgeom->numPoints; 90220cf1dd8SToby Isaac dE = fgeom->dimEmbed; 90320cf1dd8SToby Isaac isAffine = fgeom->isAffine; 90427f02ce8SMatthew G. Knepley /* Initialize here in case the function is not defined */ 90531f073d7SMatthew G. Knepley ierr = PetscArrayzero(g0, NcI*NcJ);CHKERRQ(ierr); 90627f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g1, NcI*NcJ*dE);CHKERRQ(ierr); 90727f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g2, NcI*NcJ*dE);CHKERRQ(ierr); 90827f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g3, NcI*NcJ*dE*dE);CHKERRQ(ierr); 90927f02ce8SMatthew G. Knepley ierr = PetscQuadratureGetData(quad, NULL, &qNc, &Nq, &quadPoints, &quadWeights);CHKERRQ(ierr); 91027f02ce8SMatthew G. Knepley if (qNc != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supports scalar quadrature, not %D components\n", qNc); 91120cf1dd8SToby Isaac for (e = 0; e < Ne; ++e) { 9129f209ee4SMatthew G. Knepley PetscFEGeom fegeom, cgeom; 91320cf1dd8SToby Isaac const PetscInt face = fgeom->face[e][0]; 9144dcf62a8SSatish Balay fegeom.n = 0; 9154dcf62a8SSatish Balay fegeom.v = 0; 9164dcf62a8SSatish Balay fegeom.J = 0; 9174dcf62a8SSatish Balay fegeom.detJ = 0; 91827f02ce8SMatthew G. Knepley fegeom.dim = fgeom->dim; 91927f02ce8SMatthew G. Knepley fegeom.dimEmbed = fgeom->dimEmbed; 92027f02ce8SMatthew G. Knepley cgeom.dim = fgeom->dim; 92127f02ce8SMatthew G. Knepley cgeom.dimEmbed = fgeom->dimEmbed; 9224bee2e38SMatthew G. Knepley if (isAffine) { 9234bee2e38SMatthew G. Knepley fegeom.v = x; 9244bee2e38SMatthew G. Knepley fegeom.xi = fgeom->xi; 9257132c3f7SMatthew G. Knepley fegeom.J = &fgeom->J[e*Np*dE*dE]; 9267132c3f7SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[e*Np*dE*dE]; 9277132c3f7SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e*Np]; 9287132c3f7SMatthew G. Knepley fegeom.n = &fgeom->n[e*Np*dE]; 9299f209ee4SMatthew G. Knepley 9307132c3f7SMatthew G. Knepley cgeom.J = &fgeom->suppJ[0][e*Np*dE*dE]; 9317132c3f7SMatthew G. Knepley cgeom.invJ = &fgeom->suppInvJ[0][e*Np*dE*dE]; 9327132c3f7SMatthew G. Knepley cgeom.detJ = &fgeom->suppDetJ[0][e*Np]; 9334bee2e38SMatthew G. Knepley } 93420cf1dd8SToby Isaac for (q = 0; q < Nq; ++q) { 93520cf1dd8SToby Isaac PetscReal w; 9364bee2e38SMatthew G. Knepley PetscInt c; 93720cf1dd8SToby Isaac 93820cf1dd8SToby Isaac if (debug) {ierr = PetscPrintf(PETSC_COMM_SELF, " quad point %d\n", q);CHKERRQ(ierr);} 93920cf1dd8SToby Isaac if (isAffine) { 9407132c3f7SMatthew G. Knepley CoordinatesRefToReal(dE, dim-1, fegeom.xi, &fgeom->v[e*Np*dE], fegeom.J, &quadPoints[q*(dim-1)], x); 94120cf1dd8SToby Isaac } else { 9423fe841f2SMatthew G. Knepley fegeom.v = &fgeom->v[(e*Np+q)*dE]; 9439f209ee4SMatthew G. Knepley fegeom.J = &fgeom->J[(e*Np+q)*dE*dE]; 9449f209ee4SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[(e*Np+q)*dE*dE]; 9454bee2e38SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e*Np+q]; 9464bee2e38SMatthew G. Knepley fegeom.n = &fgeom->n[(e*Np+q)*dE]; 9479f209ee4SMatthew G. Knepley 9489f209ee4SMatthew G. Knepley cgeom.J = &fgeom->suppJ[0][(e*Np+q)*dE*dE]; 9499f209ee4SMatthew G. Knepley cgeom.invJ = &fgeom->suppInvJ[0][(e*Np+q)*dE*dE]; 9509f209ee4SMatthew G. Knepley cgeom.detJ = &fgeom->suppDetJ[0][e*Np+q]; 95120cf1dd8SToby Isaac } 9524bee2e38SMatthew G. Knepley w = fegeom.detJ[0]*quadWeights[q]; 953ef0bb6c7SMatthew G. Knepley if (coefficients) {ierr = PetscFEEvaluateFieldJets_Internal(ds, Nf, face, q, T, &cgeom, &coefficients[cOffset], &coefficients_t[cOffset], u, u_x, u_t);CHKERRQ(ierr);} 954ef0bb6c7SMatthew G. Knepley if (dsAux) {ierr = PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, face, q, TAux, &cgeom, &coefficientsAux[cOffsetAux], NULL, a, a_x, NULL);CHKERRQ(ierr);} 95520cf1dd8SToby Isaac if (g0_func) { 956580bdb30SBarry Smith ierr = PetscArrayzero(g0, NcI*NcJ);CHKERRQ(ierr); 9574bee2e38SMatthew G. Knepley g0_func(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); 95820cf1dd8SToby Isaac for (c = 0; c < NcI*NcJ; ++c) g0[c] *= w; 95920cf1dd8SToby Isaac } 96020cf1dd8SToby Isaac if (g1_func) { 96127f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g1, NcI*NcJ*dE);CHKERRQ(ierr); 9624bee2e38SMatthew G. Knepley g1_func(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); 9634bee2e38SMatthew G. Knepley for (c = 0; c < NcI*NcJ*dim; ++c) g1[c] *= w; 96420cf1dd8SToby Isaac } 96520cf1dd8SToby Isaac if (g2_func) { 96627f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g2, NcI*NcJ*dE);CHKERRQ(ierr); 9674bee2e38SMatthew G. Knepley g2_func(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); 9684bee2e38SMatthew G. Knepley for (c = 0; c < NcI*NcJ*dim; ++c) g2[c] *= w; 96920cf1dd8SToby Isaac } 97020cf1dd8SToby Isaac if (g3_func) { 97127f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g3, NcI*NcJ*dE*dE);CHKERRQ(ierr); 9724bee2e38SMatthew G. Knepley g3_func(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); 9734bee2e38SMatthew G. Knepley for (c = 0; c < NcI*NcJ*dim*dim; ++c) g3[c] *= w; 97420cf1dd8SToby Isaac } 97520cf1dd8SToby Isaac 976ef0bb6c7SMatthew G. Knepley ierr = PetscFEUpdateElementMat_Internal(feI, feJ, face, q, T[fieldI], basisReal, basisDerReal, T[fieldJ], testReal, testDerReal, &cgeom, g0, g1, g2, g3, eOffset, totDim, offsetI, offsetJ, elemMat);CHKERRQ(ierr); 97720cf1dd8SToby Isaac } 97820cf1dd8SToby Isaac if (debug > 1) { 97920cf1dd8SToby Isaac PetscInt fc, f, gc, g; 98020cf1dd8SToby Isaac 98120cf1dd8SToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "Element matrix for fields %d and %d\n", fieldI, fieldJ);CHKERRQ(ierr); 982ef0bb6c7SMatthew G. Knepley for (fc = 0; fc < T[fieldI]->Nc; ++fc) { 983ef0bb6c7SMatthew G. Knepley for (f = 0; f < T[fieldI]->Nb; ++f) { 984ef0bb6c7SMatthew G. Knepley const PetscInt i = offsetI + f*T[fieldI]->Nc+fc; 985ef0bb6c7SMatthew G. Knepley for (gc = 0; gc < T[fieldJ]->Nc; ++gc) { 986ef0bb6c7SMatthew G. Knepley for (g = 0; g < T[fieldJ]->Nb; ++g) { 987ef0bb6c7SMatthew G. Knepley const PetscInt j = offsetJ + g*T[fieldJ]->Nc+gc; 98820cf1dd8SToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, " elemMat[%d,%d,%d,%d]: %g\n", f, fc, g, gc, PetscRealPart(elemMat[eOffset+i*totDim+j]));CHKERRQ(ierr); 98920cf1dd8SToby Isaac } 99020cf1dd8SToby Isaac } 99120cf1dd8SToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 99220cf1dd8SToby Isaac } 99320cf1dd8SToby Isaac } 99420cf1dd8SToby Isaac } 99520cf1dd8SToby Isaac cOffset += totDim; 99620cf1dd8SToby Isaac cOffsetAux += totDimAux; 99720cf1dd8SToby Isaac eOffset += PetscSqr(totDim); 99820cf1dd8SToby Isaac } 99920cf1dd8SToby Isaac PetscFunctionReturn(0); 100020cf1dd8SToby Isaac } 100120cf1dd8SToby Isaac 100227f02ce8SMatthew G. Knepley PetscErrorCode PetscFEIntegrateHybridJacobian_Basic(PetscDS ds, PetscFEJacobianType jtype, PetscInt fieldI, PetscInt fieldJ, PetscInt Ne, PetscFEGeom *fgeom, 100327f02ce8SMatthew G. Knepley const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscReal t, PetscReal u_tshift, PetscScalar elemMat[]) 100427f02ce8SMatthew G. Knepley { 100527f02ce8SMatthew G. Knepley const PetscInt debug = 0; 100627f02ce8SMatthew G. Knepley PetscFE feI, feJ; 1007*665f567fSMatthew G. Knepley PetscBdPointJac g0_func, g1_func, g2_func, g3_func; 100827f02ce8SMatthew G. Knepley PetscInt cOffset = 0; /* Offset into coefficients[] for element e */ 100927f02ce8SMatthew G. Knepley PetscInt cOffsetAux = 0; /* Offset into coefficientsAux[] for element e */ 101027f02ce8SMatthew G. Knepley PetscInt eOffset = 0; /* Offset into elemMat[] for element e */ 101127f02ce8SMatthew G. Knepley PetscInt offsetI = 0; /* Offset into an element vector for fieldI */ 101227f02ce8SMatthew G. Knepley PetscInt offsetJ = 0; /* Offset into an element vector for fieldJ */ 1013*665f567fSMatthew G. Knepley PetscQuadrature quad; 1014*665f567fSMatthew G. Knepley PetscTabulation *T, *TAux = NULL; 101527f02ce8SMatthew G. Knepley PetscScalar *g0, *g1, *g2, *g3, *u, *u_t = NULL, *u_x, *a, *a_x, *basisReal, *basisDerReal, *testReal, *testDerReal; 101627f02ce8SMatthew G. Knepley const PetscScalar *constants; 101727f02ce8SMatthew G. Knepley PetscReal *x; 1018*665f567fSMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL; 1019*665f567fSMatthew G. Knepley PetscInt NcI = 0, NcJ = 0, NcS, NcT; 102027f02ce8SMatthew G. Knepley PetscInt dim, dimAux, numConstants, Nf, NfAux = 0, totDim, totDimAux = 0, e; 1021*665f567fSMatthew G. Knepley PetscBool isCohesiveFieldI, isCohesiveFieldJ, isAffine, auxOnBd = PETSC_FALSE; 102227f02ce8SMatthew G. Knepley const PetscReal *quadPoints, *quadWeights; 102327f02ce8SMatthew G. Knepley PetscInt qNc, Nq, q, Np, dE; 102427f02ce8SMatthew G. Knepley PetscErrorCode ierr; 102527f02ce8SMatthew G. Knepley 102627f02ce8SMatthew G. Knepley PetscFunctionBegin; 102727f02ce8SMatthew G. Knepley /* Hybrid discretization is posed directly on faces */ 102827f02ce8SMatthew G. Knepley ierr = PetscDSGetDiscretization(ds, fieldI, (PetscObject *) &feI);CHKERRQ(ierr); 102927f02ce8SMatthew G. Knepley ierr = PetscDSGetDiscretization(ds, fieldJ, (PetscObject *) &feJ);CHKERRQ(ierr); 103027f02ce8SMatthew G. Knepley ierr = PetscFEGetSpatialDimension(feI, &dim);CHKERRQ(ierr); 103127f02ce8SMatthew G. Knepley ierr = PetscFEGetQuadrature(feI, &quad);CHKERRQ(ierr); 103227f02ce8SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 103327f02ce8SMatthew G. Knepley ierr = PetscDSGetTotalDimension(ds, &totDim);CHKERRQ(ierr); 103427f02ce8SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(ds, &uOff);CHKERRQ(ierr); 103527f02ce8SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(ds, &uOff_x);CHKERRQ(ierr); 103627f02ce8SMatthew G. Knepley switch(jtype) { 103727f02ce8SMatthew G. Knepley case PETSCFE_JACOBIAN_PRE: ierr = PetscDSGetBdJacobianPreconditioner(ds, fieldI, fieldJ, &g0_func, &g1_func, &g2_func, &g3_func);CHKERRQ(ierr);break; 103827f02ce8SMatthew G. Knepley case PETSCFE_JACOBIAN: ierr = PetscDSGetBdJacobian(ds, fieldI, fieldJ, &g0_func, &g1_func, &g2_func, &g3_func);CHKERRQ(ierr);break; 1039*665f567fSMatthew G. Knepley case PETSCFE_JACOBIAN_DYN: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No boundary hybrid Jacobians :)"); 104027f02ce8SMatthew G. Knepley } 104127f02ce8SMatthew G. Knepley if (!g0_func && !g1_func && !g2_func && !g3_func) PetscFunctionReturn(0); 104227f02ce8SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(ds, &u, coefficients_t ? &u_t : NULL, &u_x);CHKERRQ(ierr); 104327f02ce8SMatthew G. Knepley ierr = PetscDSGetWorkspace(ds, &x, &basisReal, &basisDerReal, &testReal, &testDerReal);CHKERRQ(ierr); 104427f02ce8SMatthew G. Knepley ierr = PetscDSGetWeakFormArrays(ds, NULL, NULL, &g0, &g1, &g2, &g3);CHKERRQ(ierr); 1045*665f567fSMatthew G. Knepley ierr = PetscDSGetTabulation(ds, &T);CHKERRQ(ierr); 1046*665f567fSMatthew G. Knepley ierr = PetscDSGetFieldOffset(ds, fieldI, &offsetI);CHKERRQ(ierr); 1047*665f567fSMatthew G. Knepley ierr = PetscDSGetFieldOffset(ds, fieldJ, &offsetJ);CHKERRQ(ierr); 104827f02ce8SMatthew G. Knepley ierr = PetscDSGetConstants(ds, &numConstants, &constants);CHKERRQ(ierr); 104927f02ce8SMatthew G. Knepley if (dsAux) { 105027f02ce8SMatthew G. Knepley ierr = PetscDSGetSpatialDimension(dsAux, &dimAux);CHKERRQ(ierr); 105127f02ce8SMatthew G. Knepley ierr = PetscDSGetNumFields(dsAux, &NfAux);CHKERRQ(ierr); 105227f02ce8SMatthew G. Knepley ierr = PetscDSGetTotalDimension(dsAux, &totDimAux);CHKERRQ(ierr); 105327f02ce8SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(dsAux, &aOff);CHKERRQ(ierr); 105427f02ce8SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x);CHKERRQ(ierr); 105527f02ce8SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(dsAux, &a, NULL, &a_x);CHKERRQ(ierr); 105627f02ce8SMatthew G. Knepley auxOnBd = dimAux < dim ? PETSC_TRUE : PETSC_FALSE; 1057*665f567fSMatthew G. Knepley if (auxOnBd) {ierr = PetscDSGetTabulation(dsAux, &TAux);CHKERRQ(ierr);} 1058*665f567fSMatthew G. Knepley else {ierr = PetscDSGetFaceTabulation(dsAux, &TAux);CHKERRQ(ierr);} 105927f02ce8SMatthew G. Knepley } 106027f02ce8SMatthew G. Knepley isCohesiveFieldI = fieldI == Nf-1 ? PETSC_TRUE : PETSC_FALSE; 106127f02ce8SMatthew G. Knepley isCohesiveFieldJ = fieldJ == Nf-1 ? PETSC_TRUE : PETSC_FALSE; 1062*665f567fSMatthew G. Knepley NcI = T[fieldI]->Nc; 1063*665f567fSMatthew G. Knepley NcJ = T[fieldJ]->Nc; 106427f02ce8SMatthew G. Knepley NcS = isCohesiveFieldI ? NcI : 2*NcI; 106527f02ce8SMatthew G. Knepley NcT = isCohesiveFieldJ ? NcJ : 2*NcJ; 106627f02ce8SMatthew G. Knepley Np = fgeom->numPoints; 106727f02ce8SMatthew G. Knepley dE = fgeom->dimEmbed; 106827f02ce8SMatthew G. Knepley isAffine = fgeom->isAffine; 106927f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g0, NcS*NcT);CHKERRQ(ierr); 107027f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g1, NcS*NcT*dE);CHKERRQ(ierr); 107127f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g2, NcS*NcT*dE);CHKERRQ(ierr); 107227f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g3, NcS*NcT*dE*dE);CHKERRQ(ierr); 1073*665f567fSMatthew G. Knepley ierr = PetscQuadratureGetData(quad, NULL, &qNc, &Nq, &quadPoints, &quadWeights);CHKERRQ(ierr); 1074*665f567fSMatthew G. Knepley if (qNc != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supports scalar quadrature, not %D components\n", qNc); 107527f02ce8SMatthew G. Knepley for (e = 0; e < Ne; ++e) { 107627f02ce8SMatthew G. Knepley PetscFEGeom fegeom; 107727f02ce8SMatthew G. Knepley const PetscInt face = fgeom->face[e][0]; 107827f02ce8SMatthew G. Knepley 107927f02ce8SMatthew G. Knepley fegeom.dim = fgeom->dim; 108027f02ce8SMatthew G. Knepley fegeom.dimEmbed = fgeom->dimEmbed; 108127f02ce8SMatthew G. Knepley if (isAffine) { 108227f02ce8SMatthew G. Knepley fegeom.v = x; 108327f02ce8SMatthew G. Knepley fegeom.xi = fgeom->xi; 108427f02ce8SMatthew G. Knepley fegeom.J = &fgeom->J[e*dE*dE]; 108527f02ce8SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[e*dE*dE]; 108627f02ce8SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e]; 108727f02ce8SMatthew G. Knepley fegeom.n = &fgeom->n[e*dE]; 108827f02ce8SMatthew G. Knepley } 108927f02ce8SMatthew G. Knepley for (q = 0; q < Nq; ++q) { 109027f02ce8SMatthew G. Knepley PetscReal w; 109127f02ce8SMatthew G. Knepley PetscInt c; 109227f02ce8SMatthew G. Knepley 109327f02ce8SMatthew G. Knepley if (isAffine) { 109427f02ce8SMatthew G. Knepley /* TODO Is it correct to have 'dim' here, or should it be 'dim-1'? */ 109527f02ce8SMatthew G. Knepley CoordinatesRefToReal(dE, dim, fegeom.xi, &fgeom->v[e*dE], fegeom.J, &quadPoints[q*dim], x); 109627f02ce8SMatthew G. Knepley } else { 109727f02ce8SMatthew G. Knepley fegeom.v = &fegeom.v[(e*Np+q)*dE]; 109827f02ce8SMatthew G. Knepley fegeom.J = &fgeom->J[(e*Np+q)*dE*dE]; 109927f02ce8SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[(e*Np+q)*dE*dE]; 110027f02ce8SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e*Np+q]; 110127f02ce8SMatthew G. Knepley fegeom.n = &fgeom->n[(e*Np+q)*dE]; 110227f02ce8SMatthew G. Knepley } 110327f02ce8SMatthew G. Knepley w = fegeom.detJ[0]*quadWeights[q]; 110427f02ce8SMatthew G. Knepley if (debug > 1 && q < Np) { 110527f02ce8SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " detJ: %g\n", fegeom.detJ[0]);CHKERRQ(ierr); 110627f02ce8SMatthew G. Knepley #if !defined(PETSC_USE_COMPLEX) 110727f02ce8SMatthew G. Knepley ierr = DMPrintCellMatrix(e, "invJ", dim, dim, fegeom.invJ);CHKERRQ(ierr); 110827f02ce8SMatthew G. Knepley #endif 110927f02ce8SMatthew G. Knepley } 111027f02ce8SMatthew G. Knepley if (debug) {ierr = PetscPrintf(PETSC_COMM_SELF, " quad point %d\n", q);CHKERRQ(ierr);} 1111*665f567fSMatthew G. Knepley if (coefficients) {ierr = PetscFEEvaluateFieldJets_Hybrid_Internal(ds, Nf, 0, q, T, &fegeom, &coefficients[cOffset], &coefficients_t[cOffset], u, u_x, u_t);CHKERRQ(ierr);} 1112*665f567fSMatthew G. Knepley if (dsAux) {ierr = PetscFEEvaluateFieldJets_Hybrid_Internal(dsAux, NfAux, 0, auxOnBd ? q : face*Nq+q, TAux, &fegeom, &coefficientsAux[cOffsetAux], NULL, a, a_x, NULL);CHKERRQ(ierr);} 111327f02ce8SMatthew G. Knepley if (g0_func) { 111427f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g0, NcS*NcT);CHKERRQ(ierr); 111527f02ce8SMatthew G. Knepley g0_func(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); 111627f02ce8SMatthew G. Knepley for (c = 0; c < NcS*NcT; ++c) g0[c] *= w; 111727f02ce8SMatthew G. Knepley } 111827f02ce8SMatthew G. Knepley if (g1_func) { 111927f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g1, NcS*NcT*dE);CHKERRQ(ierr); 112027f02ce8SMatthew G. Knepley g1_func(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); 112127f02ce8SMatthew G. Knepley for (c = 0; c < NcS*NcT*dE; ++c) g1[c] *= w; 112227f02ce8SMatthew G. Knepley } 112327f02ce8SMatthew G. Knepley if (g2_func) { 112427f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g2, NcS*NcT*dE);CHKERRQ(ierr); 112527f02ce8SMatthew G. Knepley g2_func(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); 112627f02ce8SMatthew G. Knepley for (c = 0; c < NcS*NcT*dE; ++c) g2[c] *= w; 112727f02ce8SMatthew G. Knepley } 112827f02ce8SMatthew G. Knepley if (g3_func) { 112927f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g3, NcS*NcT*dE*dE);CHKERRQ(ierr); 113027f02ce8SMatthew G. Knepley g3_func(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); 113127f02ce8SMatthew G. Knepley for (c = 0; c < NcS*NcT*dE*dE; ++c) g3[c] *= w; 113227f02ce8SMatthew G. Knepley } 113327f02ce8SMatthew G. Knepley 113427f02ce8SMatthew G. Knepley if (isCohesiveFieldI && isCohesiveFieldJ) { 1135*665f567fSMatthew G. Knepley ierr = PetscFEUpdateElementMat_Internal(feI, feJ, 0, q, T[fieldI], basisReal, basisDerReal, T[fieldJ], testReal, testDerReal, &fegeom, g0, g1, g2, g3, eOffset, totDim, offsetI*2, offsetJ*2, elemMat);CHKERRQ(ierr); 113627f02ce8SMatthew G. Knepley } else { 1137*665f567fSMatthew G. Knepley ierr = PetscFEUpdateElementMat_Hybrid_Internal(feI, isCohesiveFieldI, feJ, isCohesiveFieldJ, 0, q, T[fieldI], basisReal, basisDerReal, T[fieldJ], testReal, testDerReal, &fegeom, g0, g1, g2, g3, eOffset, totDim, offsetI*2, offsetJ*2, elemMat);CHKERRQ(ierr); 113827f02ce8SMatthew G. Knepley } 113927f02ce8SMatthew G. Knepley } 114027f02ce8SMatthew G. Knepley if (debug > 1) { 114127f02ce8SMatthew G. Knepley PetscInt fc, f, gc, g; 114227f02ce8SMatthew G. Knepley 114327f02ce8SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "Element matrix for fields %d and %d\n", fieldI, fieldJ);CHKERRQ(ierr); 114427f02ce8SMatthew G. Knepley for (fc = 0; fc < NcI; ++fc) { 1145*665f567fSMatthew G. Knepley for (f = 0; f < T[fieldI]->Nb; ++f) { 114627f02ce8SMatthew G. Knepley const PetscInt i = offsetI + f*NcI+fc; 114727f02ce8SMatthew G. Knepley for (gc = 0; gc < NcJ; ++gc) { 1148*665f567fSMatthew G. Knepley for (g = 0; g < T[fieldJ]->Nb; ++g) { 114927f02ce8SMatthew G. Knepley const PetscInt j = offsetJ + g*NcJ+gc; 115027f02ce8SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " elemMat[%d,%d,%d,%d]: %g\n", f, fc, g, gc, PetscRealPart(elemMat[eOffset+i*totDim+j]));CHKERRQ(ierr); 115127f02ce8SMatthew G. Knepley } 115227f02ce8SMatthew G. Knepley } 115327f02ce8SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 115427f02ce8SMatthew G. Knepley } 115527f02ce8SMatthew G. Knepley } 115627f02ce8SMatthew G. Knepley } 115727f02ce8SMatthew G. Knepley cOffset += totDim; 115827f02ce8SMatthew G. Knepley cOffsetAux += totDimAux; 115927f02ce8SMatthew G. Knepley eOffset += PetscSqr(totDim); 116027f02ce8SMatthew G. Knepley } 116127f02ce8SMatthew G. Knepley PetscFunctionReturn(0); 116227f02ce8SMatthew G. Knepley } 116327f02ce8SMatthew G. Knepley 11642b99622eSMatthew G. Knepley static PetscErrorCode PetscFEInitialize_Basic(PetscFE fem) 116520cf1dd8SToby Isaac { 116620cf1dd8SToby Isaac PetscFunctionBegin; 116720cf1dd8SToby Isaac fem->ops->setfromoptions = NULL; 116820cf1dd8SToby Isaac fem->ops->setup = PetscFESetUp_Basic; 116920cf1dd8SToby Isaac fem->ops->view = PetscFEView_Basic; 117020cf1dd8SToby Isaac fem->ops->destroy = PetscFEDestroy_Basic; 117120cf1dd8SToby Isaac fem->ops->getdimension = PetscFEGetDimension_Basic; 1172ef0bb6c7SMatthew G. Knepley fem->ops->createtabulation = PetscFECreateTabulation_Basic; 117320cf1dd8SToby Isaac fem->ops->integrate = PetscFEIntegrate_Basic; 1174afe6d6adSToby Isaac fem->ops->integratebd = PetscFEIntegrateBd_Basic; 117520cf1dd8SToby Isaac fem->ops->integrateresidual = PetscFEIntegrateResidual_Basic; 117620cf1dd8SToby Isaac fem->ops->integratebdresidual = PetscFEIntegrateBdResidual_Basic; 117727f02ce8SMatthew G. Knepley fem->ops->integratehybridresidual = PetscFEIntegrateHybridResidual_Basic; 117820cf1dd8SToby Isaac fem->ops->integratejacobianaction = NULL/* PetscFEIntegrateJacobianAction_Basic */; 117920cf1dd8SToby Isaac fem->ops->integratejacobian = PetscFEIntegrateJacobian_Basic; 118020cf1dd8SToby Isaac fem->ops->integratebdjacobian = PetscFEIntegrateBdJacobian_Basic; 118127f02ce8SMatthew G. Knepley fem->ops->integratehybridjacobian = PetscFEIntegrateHybridJacobian_Basic; 118220cf1dd8SToby Isaac PetscFunctionReturn(0); 118320cf1dd8SToby Isaac } 118420cf1dd8SToby Isaac 118520cf1dd8SToby Isaac /*MC 118620cf1dd8SToby Isaac PETSCFEBASIC = "basic" - A PetscFE object that integrates with basic tiling and no vectorization 118720cf1dd8SToby Isaac 118820cf1dd8SToby Isaac Level: intermediate 118920cf1dd8SToby Isaac 119020cf1dd8SToby Isaac .seealso: PetscFEType, PetscFECreate(), PetscFESetType() 119120cf1dd8SToby Isaac M*/ 119220cf1dd8SToby Isaac 119320cf1dd8SToby Isaac PETSC_EXTERN PetscErrorCode PetscFECreate_Basic(PetscFE fem) 119420cf1dd8SToby Isaac { 119520cf1dd8SToby Isaac PetscFE_Basic *b; 119620cf1dd8SToby Isaac PetscErrorCode ierr; 119720cf1dd8SToby Isaac 119820cf1dd8SToby Isaac PetscFunctionBegin; 119920cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 120020cf1dd8SToby Isaac ierr = PetscNewLog(fem,&b);CHKERRQ(ierr); 120120cf1dd8SToby Isaac fem->data = b; 120220cf1dd8SToby Isaac 120320cf1dd8SToby Isaac ierr = PetscFEInitialize_Basic(fem);CHKERRQ(ierr); 120420cf1dd8SToby Isaac PetscFunctionReturn(0); 120520cf1dd8SToby Isaac } 1206