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 216*27f02ce8SMatthew G. Knepley fegeom.dim = cgeom->dim; 217*27f02ce8SMatthew 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; 312*27f02ce8SMatthew G. Knepley fegeom.dim = fgeom->dim; 313*27f02ce8SMatthew G. Knepley fegeom.dimEmbed = fgeom->dimEmbed; 314*27f02ce8SMatthew G. Knepley cgeom.dim = fgeom->dim; 315*27f02ce8SMatthew 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 417*27f02ce8SMatthew G. Knepley fegeom.dim = cgeom->dim; 418*27f02ce8SMatthew 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); 427*27f02ce8SMatthew 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; 525*27f02ce8SMatthew G. Knepley fegeom.dim = fgeom->dim; 526*27f02ce8SMatthew G. Knepley fegeom.dimEmbed = fgeom->dimEmbed; 527*27f02ce8SMatthew G. Knepley cgeom.dim = fgeom->dim; 528*27f02ce8SMatthew 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); 542*27f02ce8SMatthew 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 586*27f02ce8SMatthew G. Knepley /* 587*27f02ce8SMatthew 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 588*27f02ce8SMatthew G. Knepley all transforms operate in the full space and are square. 589*27f02ce8SMatthew G. Knepley 590*27f02ce8SMatthew G. Knepley HybridIntegral: The discretization is lower dimensional. That means the transforms are non-square. 591*27f02ce8SMatthew G. Knepley 1) DMPlexGetCellFields() retrieves from the hybrid cell, so it gets fields from both faces 592*27f02ce8SMatthew G. Knepley 2) We need to assume that the orientation is 0 for both 593*27f02ce8SMatthew 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() 594*27f02ce8SMatthew G. Knepley */ 595*27f02ce8SMatthew G. Knepley static PetscErrorCode PetscFEIntegrateHybridResidual_Basic(PetscDS ds, PetscInt field, PetscInt Ne, PetscFEGeom *fgeom, 596*27f02ce8SMatthew G. Knepley const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscReal t, PetscScalar elemVec[]) 597*27f02ce8SMatthew G. Knepley { 598*27f02ce8SMatthew G. Knepley const PetscInt debug = 0; 599*27f02ce8SMatthew G. Knepley PetscFE fe; 600*27f02ce8SMatthew G. Knepley PetscBdPointFunc f0_func; 601*27f02ce8SMatthew G. Knepley PetscBdPointFunc f1_func; 602*27f02ce8SMatthew G. Knepley PetscQuadrature quad; 603*27f02ce8SMatthew G. Knepley PetscScalar *f0, *f1, *u, *u_t = NULL, *u_x, *a, *a_x, *basisReal, *basisDerReal; 604*27f02ce8SMatthew G. Knepley const PetscScalar *constants; 605*27f02ce8SMatthew G. Knepley PetscReal *x; 606*27f02ce8SMatthew G. Knepley PetscReal **B, **D, **BAux = NULL, **DAux = NULL, *BI, *DI; 607*27f02ce8SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL, *Nb, *Nc, *NbAux = NULL, *NcAux = NULL; 608*27f02ce8SMatthew G. Knepley PetscInt dim, dimAux, numConstants, Nf, NfAux = 0, totDim, totDimAux = 0, cOffset = 0, cOffsetAux = 0, fOffset, e, NbI, NcI, NcS; 609*27f02ce8SMatthew G. Knepley PetscBool isCohesiveField, isAffine, auxOnBd; 610*27f02ce8SMatthew G. Knepley const PetscReal *quadPoints, *quadWeights; 611*27f02ce8SMatthew G. Knepley PetscInt qNc, Nq, q, Np, dE; 612*27f02ce8SMatthew G. Knepley PetscErrorCode ierr; 613*27f02ce8SMatthew G. Knepley 614*27f02ce8SMatthew G. Knepley PetscFunctionBegin; 615*27f02ce8SMatthew G. Knepley /* Hybrid discretization is posed directly on faces */ 616*27f02ce8SMatthew G. Knepley ierr = PetscDSGetDiscretization(ds, field, (PetscObject *) &fe);CHKERRQ(ierr); 617*27f02ce8SMatthew G. Knepley ierr = PetscFEGetSpatialDimension(fe, &dim);CHKERRQ(ierr); 618*27f02ce8SMatthew G. Knepley ierr = PetscFEGetQuadrature(fe, &quad);CHKERRQ(ierr); 619*27f02ce8SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 620*27f02ce8SMatthew G. Knepley ierr = PetscDSGetTotalDimension(ds, &totDim);CHKERRQ(ierr); 621*27f02ce8SMatthew G. Knepley ierr = PetscDSGetDimensions(ds, &Nb);CHKERRQ(ierr); 622*27f02ce8SMatthew G. Knepley ierr = PetscDSGetComponents(ds, &Nc);CHKERRQ(ierr); 623*27f02ce8SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(ds, &uOff);CHKERRQ(ierr); 624*27f02ce8SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(ds, &uOff_x);CHKERRQ(ierr); 625*27f02ce8SMatthew G. Knepley ierr = PetscDSGetFieldOffset(ds, field, &fOffset);CHKERRQ(ierr); 626*27f02ce8SMatthew G. Knepley ierr = PetscDSGetBdResidual(ds, field, &f0_func, &f1_func);CHKERRQ(ierr); 627*27f02ce8SMatthew G. Knepley if (!f0_func && !f1_func) PetscFunctionReturn(0); 628*27f02ce8SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(ds, &u, coefficients_t ? &u_t : NULL, &u_x);CHKERRQ(ierr); 629*27f02ce8SMatthew G. Knepley ierr = PetscDSGetWorkspace(ds, &x, &basisReal, &basisDerReal, NULL, NULL);CHKERRQ(ierr); 630*27f02ce8SMatthew G. Knepley ierr = PetscDSGetWeakFormArrays(ds, &f0, &f1, NULL, NULL, NULL, NULL);CHKERRQ(ierr); 631*27f02ce8SMatthew G. Knepley /* NOTE This is a bulk tabulation because the DS is a face discretization */ 632*27f02ce8SMatthew G. Knepley ierr = PetscDSGetTabulation(ds, &B, &D);CHKERRQ(ierr); 633*27f02ce8SMatthew G. Knepley ierr = PetscDSGetConstants(ds, &numConstants, &constants);CHKERRQ(ierr); 634*27f02ce8SMatthew G. Knepley if (dsAux) { 635*27f02ce8SMatthew G. Knepley ierr = PetscDSGetSpatialDimension(dsAux, &dimAux);CHKERRQ(ierr); 636*27f02ce8SMatthew G. Knepley ierr = PetscDSGetNumFields(dsAux, &NfAux);CHKERRQ(ierr); 637*27f02ce8SMatthew G. Knepley ierr = PetscDSGetTotalDimension(dsAux, &totDimAux);CHKERRQ(ierr); 638*27f02ce8SMatthew G. Knepley ierr = PetscDSGetDimensions(dsAux, &NbAux);CHKERRQ(ierr); 639*27f02ce8SMatthew G. Knepley ierr = PetscDSGetComponents(dsAux, &NcAux);CHKERRQ(ierr); 640*27f02ce8SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(dsAux, &aOff);CHKERRQ(ierr); 641*27f02ce8SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x);CHKERRQ(ierr); 642*27f02ce8SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(dsAux, &a, NULL, &a_x);CHKERRQ(ierr); 643*27f02ce8SMatthew G. Knepley auxOnBd = dimAux < dim ? PETSC_TRUE : PETSC_FALSE; 644*27f02ce8SMatthew G. Knepley if (auxOnBd) {ierr = PetscDSGetTabulation(dsAux, &BAux, &DAux);CHKERRQ(ierr);} 645*27f02ce8SMatthew G. Knepley else {ierr = PetscDSGetFaceTabulation(dsAux, &BAux, &DAux);CHKERRQ(ierr);} 646*27f02ce8SMatthew G. Knepley } 647*27f02ce8SMatthew G. Knepley isCohesiveField = field == Nf-1 ? PETSC_TRUE : PETSC_FALSE; 648*27f02ce8SMatthew G. Knepley NbI = Nb[field]; 649*27f02ce8SMatthew G. Knepley NcI = Nc[field]; 650*27f02ce8SMatthew G. Knepley NcS = isCohesiveField ? NcI : 2*NcI; 651*27f02ce8SMatthew G. Knepley BI = B[field]; 652*27f02ce8SMatthew G. Knepley DI = D[field]; 653*27f02ce8SMatthew G. Knepley ierr = PetscQuadratureGetData(quad, NULL, &qNc, &Nq, &quadPoints, &quadWeights);CHKERRQ(ierr); 654*27f02ce8SMatthew G. Knepley if (qNc != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supports scalar quadrature, not %D components\n", qNc); 655*27f02ce8SMatthew G. Knepley Np = fgeom->numPoints; 656*27f02ce8SMatthew G. Knepley dE = fgeom->dimEmbed; 657*27f02ce8SMatthew G. Knepley isAffine = fgeom->isAffine; 658*27f02ce8SMatthew G. Knepley for (e = 0; e < Ne; ++e) { 659*27f02ce8SMatthew G. Knepley PetscFEGeom fegeom; 660*27f02ce8SMatthew G. Knepley const PetscInt face = fgeom->face[e][0]; 661*27f02ce8SMatthew G. Knepley 662*27f02ce8SMatthew G. Knepley fegeom.dim = fgeom->dim; 663*27f02ce8SMatthew G. Knepley fegeom.dimEmbed = fgeom->dimEmbed; 664*27f02ce8SMatthew G. Knepley if (isAffine) { 665*27f02ce8SMatthew G. Knepley fegeom.v = x; 666*27f02ce8SMatthew G. Knepley fegeom.xi = fgeom->xi; 667*27f02ce8SMatthew G. Knepley fegeom.J = &fgeom->J[e*dE*dE]; 668*27f02ce8SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[e*dE*dE]; 669*27f02ce8SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e]; 670*27f02ce8SMatthew G. Knepley fegeom.n = &fgeom->n[e*dE]; 671*27f02ce8SMatthew G. Knepley } 672*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(f0, Nq*NcS);CHKERRQ(ierr); 673*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(f1, Nq*NcS*dE);CHKERRQ(ierr); 674*27f02ce8SMatthew G. Knepley for (q = 0; q < Nq; ++q) { 675*27f02ce8SMatthew G. Knepley PetscReal w; 676*27f02ce8SMatthew G. Knepley PetscInt c, d; 677*27f02ce8SMatthew G. Knepley 678*27f02ce8SMatthew G. Knepley if (isAffine) { 679*27f02ce8SMatthew G. Knepley CoordinatesRefToReal(dE, dim, fegeom.xi, &fgeom->v[e*dE], fegeom.J, &quadPoints[q*dim], x); 680*27f02ce8SMatthew G. Knepley } else { 681*27f02ce8SMatthew G. Knepley fegeom.v = &fgeom->v[(e*Np+q)*dE]; 682*27f02ce8SMatthew G. Knepley fegeom.J = &fgeom->J[(e*Np+q)*dE*dE]; 683*27f02ce8SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[(e*Np+q)*dE*dE]; 684*27f02ce8SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e*Np+q]; 685*27f02ce8SMatthew G. Knepley fegeom.n = &fgeom->n[(e*Np+q)*dE]; 686*27f02ce8SMatthew G. Knepley } 687*27f02ce8SMatthew G. Knepley w = fegeom.detJ[0]*quadWeights[q]; 688*27f02ce8SMatthew G. Knepley if (debug > 1 && q < Np) { 689*27f02ce8SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " detJ: %g\n", fegeom.detJ[0]);CHKERRQ(ierr); 690*27f02ce8SMatthew G. Knepley #if !defined(PETSC_USE_COMPLEX) 691*27f02ce8SMatthew G. Knepley ierr = DMPrintCellMatrix(e, "invJ", dim, dE, fegeom.invJ);CHKERRQ(ierr); 692*27f02ce8SMatthew G. Knepley #endif 693*27f02ce8SMatthew G. Knepley } 694*27f02ce8SMatthew G. Knepley if (debug) {ierr = PetscPrintf(PETSC_COMM_SELF, " quad point %d\n", q);CHKERRQ(ierr);} 695*27f02ce8SMatthew G. Knepley /* TODO Is this cell or face quadrature, meaning should we use 'q' or 'face*Nq+q' */ 696*27f02ce8SMatthew G. Knepley ierr = PetscFEEvaluateFieldJets_Hybrid_Internal(ds, dim, Nf, Nb, Nc, q, B, D, &fegeom, &coefficients[cOffset], &coefficients_t[cOffset], u, u_x, u_t);CHKERRQ(ierr); 697*27f02ce8SMatthew G. Knepley if (dsAux) {ierr = PetscFEEvaluateFieldJets_Hybrid_Internal(dsAux, dimAux, NfAux, NbAux, NcAux, auxOnBd ? q : face*Nq+q, BAux, DAux, &fegeom, &coefficientsAux[cOffsetAux], NULL, a, a_x, NULL);CHKERRQ(ierr);} 698*27f02ce8SMatthew G. Knepley if (f0_func) { 699*27f02ce8SMatthew 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]); 700*27f02ce8SMatthew G. Knepley for (c = 0; c < NcS; ++c) f0[q*NcS+c] *= w; 701*27f02ce8SMatthew G. Knepley } 702*27f02ce8SMatthew G. Knepley if (f1_func) { 703*27f02ce8SMatthew 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]); 704*27f02ce8SMatthew G. Knepley for (c = 0; c < NcS; ++c) for (d = 0; d < dim; ++d) f1[(q*NcS+c)*dim+d] *= w; 705*27f02ce8SMatthew G. Knepley } 706*27f02ce8SMatthew G. Knepley } 707*27f02ce8SMatthew G. Knepley /* TODO These are tabulations. Shouldn;t they be face tabulations? &BI[face*Nq*NbI*NcI], &DI[face*Nq*NbI*NcI*dim] */ 708*27f02ce8SMatthew G. Knepley if (isCohesiveField) {PetscFEUpdateElementVec_Internal(fe, dim, Nq, NbI, NcI, BI, DI, basisReal, basisDerReal, &fegeom, f0, f1, &elemVec[cOffset+fOffset*2]);} 709*27f02ce8SMatthew G. Knepley else {PetscFEUpdateElementVec_Hybrid_Internal(fe, dim, Nq, NbI, NcI, BI, DI, basisReal, basisDerReal, &fegeom, f0, f1, &elemVec[cOffset+fOffset*2]);} 710*27f02ce8SMatthew G. Knepley cOffset += totDim; 711*27f02ce8SMatthew G. Knepley cOffsetAux += totDimAux; 712*27f02ce8SMatthew G. Knepley } 713*27f02ce8SMatthew G. Knepley PetscFunctionReturn(0); 714*27f02ce8SMatthew G. Knepley } 715*27f02ce8SMatthew G. Knepley 7164bee2e38SMatthew G. Knepley PetscErrorCode PetscFEIntegrateJacobian_Basic(PetscDS ds, PetscFEJacobianType jtype, PetscInt fieldI, PetscInt fieldJ, PetscInt Ne, PetscFEGeom *cgeom, 7174bee2e38SMatthew G. Knepley const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscReal t, PetscReal u_tshift, PetscScalar elemMat[]) 71820cf1dd8SToby Isaac { 71920cf1dd8SToby Isaac const PetscInt debug = 0; 7204bee2e38SMatthew G. Knepley PetscFE feI, feJ; 7214bee2e38SMatthew G. Knepley PetscPointJac g0_func, g1_func, g2_func, g3_func; 72220cf1dd8SToby Isaac PetscInt cOffset = 0; /* Offset into coefficients[] for element e */ 72320cf1dd8SToby Isaac PetscInt cOffsetAux = 0; /* Offset into coefficientsAux[] for element e */ 72420cf1dd8SToby Isaac PetscInt eOffset = 0; /* Offset into elemMat[] for element e */ 72520cf1dd8SToby Isaac PetscInt offsetI = 0; /* Offset into an element vector for fieldI */ 72620cf1dd8SToby Isaac PetscInt offsetJ = 0; /* Offset into an element vector for fieldJ */ 72720cf1dd8SToby Isaac PetscQuadrature quad; 728ef0bb6c7SMatthew G. Knepley PetscTabulation *T, *TAux = NULL; 7294bee2e38SMatthew G. Knepley PetscScalar *g0, *g1, *g2, *g3, *u, *u_t = NULL, *u_x, *a, *a_x, *basisReal, *basisDerReal, *testReal, *testDerReal; 73020cf1dd8SToby Isaac const PetscScalar *constants; 73120cf1dd8SToby Isaac PetscReal *x; 732ef0bb6c7SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL; 733ef0bb6c7SMatthew G. Knepley PetscInt NcI = 0, NcJ = 0; 73420cf1dd8SToby Isaac PetscInt dim, numConstants, Nf, NfAux = 0, totDim, totDimAux = 0, e; 73520cf1dd8SToby Isaac PetscInt dE, Np; 73620cf1dd8SToby Isaac PetscBool isAffine; 73720cf1dd8SToby Isaac const PetscReal *quadPoints, *quadWeights; 73820cf1dd8SToby Isaac PetscInt qNc, Nq, q; 73920cf1dd8SToby Isaac PetscErrorCode ierr; 74020cf1dd8SToby Isaac 74120cf1dd8SToby Isaac PetscFunctionBegin; 7424bee2e38SMatthew G. Knepley ierr = PetscDSGetDiscretization(ds, fieldI, (PetscObject *) &feI);CHKERRQ(ierr); 7434bee2e38SMatthew G. Knepley ierr = PetscDSGetDiscretization(ds, fieldJ, (PetscObject *) &feJ);CHKERRQ(ierr); 7444bee2e38SMatthew G. Knepley ierr = PetscFEGetSpatialDimension(feI, &dim);CHKERRQ(ierr); 7454bee2e38SMatthew G. Knepley ierr = PetscFEGetQuadrature(feI, &quad);CHKERRQ(ierr); 7464bee2e38SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 7474bee2e38SMatthew G. Knepley ierr = PetscDSGetTotalDimension(ds, &totDim);CHKERRQ(ierr); 7484bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(ds, &uOff);CHKERRQ(ierr); 7494bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(ds, &uOff_x);CHKERRQ(ierr); 75020cf1dd8SToby Isaac switch(jtype) { 7514bee2e38SMatthew G. Knepley case PETSCFE_JACOBIAN_DYN: ierr = PetscDSGetDynamicJacobian(ds, fieldI, fieldJ, &g0_func, &g1_func, &g2_func, &g3_func);CHKERRQ(ierr);break; 7524bee2e38SMatthew G. Knepley case PETSCFE_JACOBIAN_PRE: ierr = PetscDSGetJacobianPreconditioner(ds, fieldI, fieldJ, &g0_func, &g1_func, &g2_func, &g3_func);CHKERRQ(ierr);break; 7534bee2e38SMatthew G. Knepley case PETSCFE_JACOBIAN: ierr = PetscDSGetJacobian(ds, fieldI, fieldJ, &g0_func, &g1_func, &g2_func, &g3_func);CHKERRQ(ierr);break; 75420cf1dd8SToby Isaac } 75520cf1dd8SToby Isaac if (!g0_func && !g1_func && !g2_func && !g3_func) PetscFunctionReturn(0); 7564bee2e38SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(ds, &u, coefficients_t ? &u_t : NULL, &u_x);CHKERRQ(ierr); 7574bee2e38SMatthew G. Knepley ierr = PetscDSGetWorkspace(ds, &x, &basisReal, &basisDerReal, &testReal, &testDerReal);CHKERRQ(ierr); 7584bee2e38SMatthew G. Knepley ierr = PetscDSGetWeakFormArrays(ds, NULL, NULL, &g0, &g1, &g2, &g3);CHKERRQ(ierr); 759ef0bb6c7SMatthew G. Knepley ierr = PetscDSGetTabulation(ds, &T);CHKERRQ(ierr); 7604bee2e38SMatthew G. Knepley ierr = PetscDSGetFieldOffset(ds, fieldI, &offsetI);CHKERRQ(ierr); 7614bee2e38SMatthew G. Knepley ierr = PetscDSGetFieldOffset(ds, fieldJ, &offsetJ);CHKERRQ(ierr); 7624bee2e38SMatthew G. Knepley ierr = PetscDSGetConstants(ds, &numConstants, &constants);CHKERRQ(ierr); 7634bee2e38SMatthew G. Knepley if (dsAux) { 7644bee2e38SMatthew G. Knepley ierr = PetscDSGetNumFields(dsAux, &NfAux);CHKERRQ(ierr); 7654bee2e38SMatthew G. Knepley ierr = PetscDSGetTotalDimension(dsAux, &totDimAux);CHKERRQ(ierr); 7664bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(dsAux, &aOff);CHKERRQ(ierr); 7674bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x);CHKERRQ(ierr); 7684bee2e38SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(dsAux, &a, NULL, &a_x);CHKERRQ(ierr); 769ef0bb6c7SMatthew G. Knepley ierr = PetscDSGetTabulation(dsAux, &TAux);CHKERRQ(ierr); 77020cf1dd8SToby Isaac } 771*27f02ce8SMatthew G. Knepley NcI = T[fieldI]->Nc; 772*27f02ce8SMatthew G. Knepley NcJ = T[fieldJ]->Nc; 7734bee2e38SMatthew G. Knepley Np = cgeom->numPoints; 7744bee2e38SMatthew G. Knepley dE = cgeom->dimEmbed; 7754bee2e38SMatthew G. Knepley isAffine = cgeom->isAffine; 776*27f02ce8SMatthew G. Knepley /* Initialize here in case the function is not defined */ 777*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g0, NcI*NcJ);CHKERRQ(ierr); 778*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g1, NcI*NcJ*dE);CHKERRQ(ierr); 779*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g2, NcI*NcJ*dE);CHKERRQ(ierr); 780*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g3, NcI*NcJ*dE*dE);CHKERRQ(ierr); 781*27f02ce8SMatthew G. Knepley ierr = PetscQuadratureGetData(quad, NULL, &qNc, &Nq, &quadPoints, &quadWeights);CHKERRQ(ierr); 782*27f02ce8SMatthew G. Knepley if (qNc != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supports scalar quadrature, not %D components\n", qNc); 7834bee2e38SMatthew G. Knepley for (e = 0; e < Ne; ++e) { 7844bee2e38SMatthew G. Knepley PetscFEGeom fegeom; 7854bee2e38SMatthew G. Knepley 786*27f02ce8SMatthew G. Knepley fegeom.dim = cgeom->dim; 787*27f02ce8SMatthew G. Knepley fegeom.dimEmbed = cgeom->dimEmbed; 7884bee2e38SMatthew G. Knepley if (isAffine) { 7894bee2e38SMatthew G. Knepley fegeom.v = x; 7904bee2e38SMatthew G. Knepley fegeom.xi = cgeom->xi; 7917132c3f7SMatthew G. Knepley fegeom.J = &cgeom->J[e*Np*dE*dE]; 7927132c3f7SMatthew G. Knepley fegeom.invJ = &cgeom->invJ[e*Np*dE*dE]; 7937132c3f7SMatthew G. Knepley fegeom.detJ = &cgeom->detJ[e*Np]; 7944bee2e38SMatthew G. Knepley } 79520cf1dd8SToby Isaac for (q = 0; q < Nq; ++q) { 79620cf1dd8SToby Isaac PetscReal w; 7974bee2e38SMatthew G. Knepley PetscInt c; 79820cf1dd8SToby Isaac 79920cf1dd8SToby Isaac if (debug) {ierr = PetscPrintf(PETSC_COMM_SELF, " quad point %d\n", q);CHKERRQ(ierr);} 80020cf1dd8SToby Isaac if (isAffine) { 8017132c3f7SMatthew G. Knepley CoordinatesRefToReal(dE, dim, fegeom.xi, &cgeom->v[e*Np*dE], fegeom.J, &quadPoints[q*dim], x); 80220cf1dd8SToby Isaac } else { 8034bee2e38SMatthew G. Knepley fegeom.v = &cgeom->v[(e*Np+q)*dE]; 8044bee2e38SMatthew G. Knepley fegeom.J = &cgeom->J[(e*Np+q)*dE*dE]; 8054bee2e38SMatthew G. Knepley fegeom.invJ = &cgeom->invJ[(e*Np+q)*dE*dE]; 8064bee2e38SMatthew G. Knepley fegeom.detJ = &cgeom->detJ[e*Np+q]; 80720cf1dd8SToby Isaac } 8084bee2e38SMatthew G. Knepley w = fegeom.detJ[0]*quadWeights[q]; 809ef0bb6c7SMatthew 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);} 810ef0bb6c7SMatthew G. Knepley if (dsAux) {ierr = PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, 0, q, TAux, &fegeom, &coefficientsAux[cOffsetAux], NULL, a, a_x, NULL);CHKERRQ(ierr);} 81120cf1dd8SToby Isaac if (g0_func) { 812580bdb30SBarry Smith ierr = PetscArrayzero(g0, NcI*NcJ);CHKERRQ(ierr); 8134bee2e38SMatthew 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); 81420cf1dd8SToby Isaac for (c = 0; c < NcI*NcJ; ++c) g0[c] *= w; 81520cf1dd8SToby Isaac } 81620cf1dd8SToby Isaac if (g1_func) { 817*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g1, NcI*NcJ*dE);CHKERRQ(ierr); 8184bee2e38SMatthew 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); 8194bee2e38SMatthew G. Knepley for (c = 0; c < NcI*NcJ*dim; ++c) g1[c] *= w; 82020cf1dd8SToby Isaac } 82120cf1dd8SToby Isaac if (g2_func) { 822*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g2, NcI*NcJ*dE);CHKERRQ(ierr); 8234bee2e38SMatthew 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); 8244bee2e38SMatthew G. Knepley for (c = 0; c < NcI*NcJ*dim; ++c) g2[c] *= w; 82520cf1dd8SToby Isaac } 82620cf1dd8SToby Isaac if (g3_func) { 827*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g3, NcI*NcJ*dE*dE);CHKERRQ(ierr); 8284bee2e38SMatthew 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); 8294bee2e38SMatthew G. Knepley for (c = 0; c < NcI*NcJ*dim*dim; ++c) g3[c] *= w; 83020cf1dd8SToby Isaac } 83120cf1dd8SToby Isaac 832ef0bb6c7SMatthew 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); 83320cf1dd8SToby Isaac } 83420cf1dd8SToby Isaac if (debug > 1) { 83520cf1dd8SToby Isaac PetscInt fc, f, gc, g; 83620cf1dd8SToby Isaac 83720cf1dd8SToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "Element matrix for fields %d and %d\n", fieldI, fieldJ);CHKERRQ(ierr); 838ef0bb6c7SMatthew G. Knepley for (fc = 0; fc < T[fieldI]->Nc; ++fc) { 839ef0bb6c7SMatthew G. Knepley for (f = 0; f < T[fieldI]->Nb; ++f) { 840ef0bb6c7SMatthew G. Knepley const PetscInt i = offsetI + f*T[fieldI]->Nc+fc; 841ef0bb6c7SMatthew G. Knepley for (gc = 0; gc < T[fieldJ]->Nc; ++gc) { 842ef0bb6c7SMatthew G. Knepley for (g = 0; g < T[fieldJ]->Nb; ++g) { 843ef0bb6c7SMatthew G. Knepley const PetscInt j = offsetJ + g*T[fieldJ]->Nc+gc; 84420cf1dd8SToby 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); 84520cf1dd8SToby Isaac } 84620cf1dd8SToby Isaac } 84720cf1dd8SToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 84820cf1dd8SToby Isaac } 84920cf1dd8SToby Isaac } 85020cf1dd8SToby Isaac } 85120cf1dd8SToby Isaac cOffset += totDim; 85220cf1dd8SToby Isaac cOffsetAux += totDimAux; 85320cf1dd8SToby Isaac eOffset += PetscSqr(totDim); 85420cf1dd8SToby Isaac } 85520cf1dd8SToby Isaac PetscFunctionReturn(0); 85620cf1dd8SToby Isaac } 85720cf1dd8SToby Isaac 8582b99622eSMatthew G. Knepley static PetscErrorCode PetscFEIntegrateBdJacobian_Basic(PetscDS ds, PetscInt fieldI, PetscInt fieldJ, PetscInt Ne, PetscFEGeom *fgeom, 8594bee2e38SMatthew G. Knepley const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscReal t, PetscReal u_tshift, PetscScalar elemMat[]) 86020cf1dd8SToby Isaac { 86120cf1dd8SToby Isaac const PetscInt debug = 0; 8624bee2e38SMatthew G. Knepley PetscFE feI, feJ; 8634bee2e38SMatthew G. Knepley PetscBdPointJac g0_func, g1_func, g2_func, g3_func; 86420cf1dd8SToby Isaac PetscInt cOffset = 0; /* Offset into coefficients[] for element e */ 86520cf1dd8SToby Isaac PetscInt cOffsetAux = 0; /* Offset into coefficientsAux[] for element e */ 86620cf1dd8SToby Isaac PetscInt eOffset = 0; /* Offset into elemMat[] for element e */ 86720cf1dd8SToby Isaac PetscInt offsetI = 0; /* Offset into an element vector for fieldI */ 86820cf1dd8SToby Isaac PetscInt offsetJ = 0; /* Offset into an element vector for fieldJ */ 86920cf1dd8SToby Isaac PetscQuadrature quad; 870ef0bb6c7SMatthew G. Knepley PetscTabulation *T, *TAux = NULL; 8714bee2e38SMatthew G. Knepley PetscScalar *g0, *g1, *g2, *g3, *u, *u_t = NULL, *u_x, *a, *a_x, *basisReal, *basisDerReal, *testReal, *testDerReal; 87220cf1dd8SToby Isaac const PetscScalar *constants; 87320cf1dd8SToby Isaac PetscReal *x; 874ef0bb6c7SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL; 875ef0bb6c7SMatthew G. Knepley PetscInt NcI = 0, NcJ = 0; 87620cf1dd8SToby Isaac PetscInt dim, numConstants, Nf, NfAux = 0, totDim, totDimAux = 0, e; 87720cf1dd8SToby Isaac PetscBool isAffine; 87820cf1dd8SToby Isaac const PetscReal *quadPoints, *quadWeights; 87920cf1dd8SToby Isaac PetscInt qNc, Nq, q, Np, dE; 88020cf1dd8SToby Isaac PetscErrorCode ierr; 88120cf1dd8SToby Isaac 88220cf1dd8SToby Isaac PetscFunctionBegin; 8834bee2e38SMatthew G. Knepley ierr = PetscDSGetDiscretization(ds, fieldI, (PetscObject *) &feI);CHKERRQ(ierr); 8844bee2e38SMatthew G. Knepley ierr = PetscDSGetDiscretization(ds, fieldJ, (PetscObject *) &feJ);CHKERRQ(ierr); 8854bee2e38SMatthew G. Knepley ierr = PetscFEGetSpatialDimension(feI, &dim);CHKERRQ(ierr); 8864bee2e38SMatthew G. Knepley ierr = PetscFEGetFaceQuadrature(feI, &quad);CHKERRQ(ierr); 8874bee2e38SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 8884bee2e38SMatthew G. Knepley ierr = PetscDSGetTotalDimension(ds, &totDim);CHKERRQ(ierr); 8894bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(ds, &uOff);CHKERRQ(ierr); 8904bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(ds, &uOff_x);CHKERRQ(ierr); 8914bee2e38SMatthew G. Knepley ierr = PetscDSGetFieldOffset(ds, fieldI, &offsetI);CHKERRQ(ierr); 8924bee2e38SMatthew G. Knepley ierr = PetscDSGetFieldOffset(ds, fieldJ, &offsetJ);CHKERRQ(ierr); 8934bee2e38SMatthew G. Knepley ierr = PetscDSGetBdJacobian(ds, fieldI, fieldJ, &g0_func, &g1_func, &g2_func, &g3_func);CHKERRQ(ierr); 89431f073d7SMatthew G. Knepley if (!g0_func && !g1_func && !g2_func && !g3_func) PetscFunctionReturn(0); 8954bee2e38SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(ds, &u, coefficients_t ? &u_t : NULL, &u_x);CHKERRQ(ierr); 8964bee2e38SMatthew G. Knepley ierr = PetscDSGetWorkspace(ds, &x, &basisReal, &basisDerReal, &testReal, &testDerReal);CHKERRQ(ierr); 8974bee2e38SMatthew G. Knepley ierr = PetscDSGetWeakFormArrays(ds, NULL, NULL, &g0, &g1, &g2, &g3);CHKERRQ(ierr); 898ef0bb6c7SMatthew G. Knepley ierr = PetscDSGetFaceTabulation(ds, &T);CHKERRQ(ierr); 8994bee2e38SMatthew G. Knepley ierr = PetscDSGetConstants(ds, &numConstants, &constants);CHKERRQ(ierr); 9004bee2e38SMatthew G. Knepley if (dsAux) { 9014bee2e38SMatthew G. Knepley ierr = PetscDSGetNumFields(dsAux, &NfAux);CHKERRQ(ierr); 9024bee2e38SMatthew G. Knepley ierr = PetscDSGetTotalDimension(dsAux, &totDimAux);CHKERRQ(ierr); 9034bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(dsAux, &aOff);CHKERRQ(ierr); 9044bee2e38SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x);CHKERRQ(ierr); 9054bee2e38SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(dsAux, &a, NULL, &a_x);CHKERRQ(ierr); 906ef0bb6c7SMatthew G. Knepley ierr = PetscDSGetFaceTabulation(dsAux, &TAux);CHKERRQ(ierr); 90720cf1dd8SToby Isaac } 908ef0bb6c7SMatthew G. Knepley NcI = T[fieldI]->Nc, NcJ = T[fieldJ]->Nc; 90920cf1dd8SToby Isaac Np = fgeom->numPoints; 91020cf1dd8SToby Isaac dE = fgeom->dimEmbed; 91120cf1dd8SToby Isaac isAffine = fgeom->isAffine; 912*27f02ce8SMatthew G. Knepley /* Initialize here in case the function is not defined */ 91331f073d7SMatthew G. Knepley ierr = PetscArrayzero(g0, NcI*NcJ);CHKERRQ(ierr); 914*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g1, NcI*NcJ*dE);CHKERRQ(ierr); 915*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g2, NcI*NcJ*dE);CHKERRQ(ierr); 916*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g3, NcI*NcJ*dE*dE);CHKERRQ(ierr); 917*27f02ce8SMatthew G. Knepley ierr = PetscQuadratureGetData(quad, NULL, &qNc, &Nq, &quadPoints, &quadWeights);CHKERRQ(ierr); 918*27f02ce8SMatthew G. Knepley if (qNc != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supports scalar quadrature, not %D components\n", qNc); 91920cf1dd8SToby Isaac for (e = 0; e < Ne; ++e) { 9209f209ee4SMatthew G. Knepley PetscFEGeom fegeom, cgeom; 92120cf1dd8SToby Isaac const PetscInt face = fgeom->face[e][0]; 9224dcf62a8SSatish Balay fegeom.n = 0; 9234dcf62a8SSatish Balay fegeom.v = 0; 9244dcf62a8SSatish Balay fegeom.J = 0; 9254dcf62a8SSatish Balay fegeom.detJ = 0; 926*27f02ce8SMatthew G. Knepley fegeom.dim = fgeom->dim; 927*27f02ce8SMatthew G. Knepley fegeom.dimEmbed = fgeom->dimEmbed; 928*27f02ce8SMatthew G. Knepley cgeom.dim = fgeom->dim; 929*27f02ce8SMatthew G. Knepley cgeom.dimEmbed = fgeom->dimEmbed; 9304bee2e38SMatthew G. Knepley if (isAffine) { 9314bee2e38SMatthew G. Knepley fegeom.v = x; 9324bee2e38SMatthew G. Knepley fegeom.xi = fgeom->xi; 9337132c3f7SMatthew G. Knepley fegeom.J = &fgeom->J[e*Np*dE*dE]; 9347132c3f7SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[e*Np*dE*dE]; 9357132c3f7SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e*Np]; 9367132c3f7SMatthew G. Knepley fegeom.n = &fgeom->n[e*Np*dE]; 9379f209ee4SMatthew G. Knepley 9387132c3f7SMatthew G. Knepley cgeom.J = &fgeom->suppJ[0][e*Np*dE*dE]; 9397132c3f7SMatthew G. Knepley cgeom.invJ = &fgeom->suppInvJ[0][e*Np*dE*dE]; 9407132c3f7SMatthew G. Knepley cgeom.detJ = &fgeom->suppDetJ[0][e*Np]; 9414bee2e38SMatthew G. Knepley } 94220cf1dd8SToby Isaac for (q = 0; q < Nq; ++q) { 94320cf1dd8SToby Isaac PetscReal w; 9444bee2e38SMatthew G. Knepley PetscInt c; 94520cf1dd8SToby Isaac 94620cf1dd8SToby Isaac if (debug) {ierr = PetscPrintf(PETSC_COMM_SELF, " quad point %d\n", q);CHKERRQ(ierr);} 94720cf1dd8SToby Isaac if (isAffine) { 9487132c3f7SMatthew G. Knepley CoordinatesRefToReal(dE, dim-1, fegeom.xi, &fgeom->v[e*Np*dE], fegeom.J, &quadPoints[q*(dim-1)], x); 94920cf1dd8SToby Isaac } else { 9503fe841f2SMatthew G. Knepley fegeom.v = &fgeom->v[(e*Np+q)*dE]; 9519f209ee4SMatthew G. Knepley fegeom.J = &fgeom->J[(e*Np+q)*dE*dE]; 9529f209ee4SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[(e*Np+q)*dE*dE]; 9534bee2e38SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e*Np+q]; 9544bee2e38SMatthew G. Knepley fegeom.n = &fgeom->n[(e*Np+q)*dE]; 9559f209ee4SMatthew G. Knepley 9569f209ee4SMatthew G. Knepley cgeom.J = &fgeom->suppJ[0][(e*Np+q)*dE*dE]; 9579f209ee4SMatthew G. Knepley cgeom.invJ = &fgeom->suppInvJ[0][(e*Np+q)*dE*dE]; 9589f209ee4SMatthew G. Knepley cgeom.detJ = &fgeom->suppDetJ[0][e*Np+q]; 95920cf1dd8SToby Isaac } 9604bee2e38SMatthew G. Knepley w = fegeom.detJ[0]*quadWeights[q]; 961ef0bb6c7SMatthew 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);} 962ef0bb6c7SMatthew G. Knepley if (dsAux) {ierr = PetscFEEvaluateFieldJets_Internal(dsAux, NfAux, face, q, TAux, &cgeom, &coefficientsAux[cOffsetAux], NULL, a, a_x, NULL);CHKERRQ(ierr);} 96320cf1dd8SToby Isaac if (g0_func) { 964580bdb30SBarry Smith ierr = PetscArrayzero(g0, NcI*NcJ);CHKERRQ(ierr); 9654bee2e38SMatthew 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); 96620cf1dd8SToby Isaac for (c = 0; c < NcI*NcJ; ++c) g0[c] *= w; 96720cf1dd8SToby Isaac } 96820cf1dd8SToby Isaac if (g1_func) { 969*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g1, NcI*NcJ*dE);CHKERRQ(ierr); 9704bee2e38SMatthew 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); 9714bee2e38SMatthew G. Knepley for (c = 0; c < NcI*NcJ*dim; ++c) g1[c] *= w; 97220cf1dd8SToby Isaac } 97320cf1dd8SToby Isaac if (g2_func) { 974*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g2, NcI*NcJ*dE);CHKERRQ(ierr); 9754bee2e38SMatthew 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); 9764bee2e38SMatthew G. Knepley for (c = 0; c < NcI*NcJ*dim; ++c) g2[c] *= w; 97720cf1dd8SToby Isaac } 97820cf1dd8SToby Isaac if (g3_func) { 979*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g3, NcI*NcJ*dE*dE);CHKERRQ(ierr); 9804bee2e38SMatthew 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); 9814bee2e38SMatthew G. Knepley for (c = 0; c < NcI*NcJ*dim*dim; ++c) g3[c] *= w; 98220cf1dd8SToby Isaac } 98320cf1dd8SToby Isaac 984ef0bb6c7SMatthew 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); 98520cf1dd8SToby Isaac } 98620cf1dd8SToby Isaac if (debug > 1) { 98720cf1dd8SToby Isaac PetscInt fc, f, gc, g; 98820cf1dd8SToby Isaac 98920cf1dd8SToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "Element matrix for fields %d and %d\n", fieldI, fieldJ);CHKERRQ(ierr); 990ef0bb6c7SMatthew G. Knepley for (fc = 0; fc < T[fieldI]->Nc; ++fc) { 991ef0bb6c7SMatthew G. Knepley for (f = 0; f < T[fieldI]->Nb; ++f) { 992ef0bb6c7SMatthew G. Knepley const PetscInt i = offsetI + f*T[fieldI]->Nc+fc; 993ef0bb6c7SMatthew G. Knepley for (gc = 0; gc < T[fieldJ]->Nc; ++gc) { 994ef0bb6c7SMatthew G. Knepley for (g = 0; g < T[fieldJ]->Nb; ++g) { 995ef0bb6c7SMatthew G. Knepley const PetscInt j = offsetJ + g*T[fieldJ]->Nc+gc; 99620cf1dd8SToby 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); 99720cf1dd8SToby Isaac } 99820cf1dd8SToby Isaac } 99920cf1dd8SToby Isaac ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 100020cf1dd8SToby Isaac } 100120cf1dd8SToby Isaac } 100220cf1dd8SToby Isaac } 100320cf1dd8SToby Isaac cOffset += totDim; 100420cf1dd8SToby Isaac cOffsetAux += totDimAux; 100520cf1dd8SToby Isaac eOffset += PetscSqr(totDim); 100620cf1dd8SToby Isaac } 100720cf1dd8SToby Isaac PetscFunctionReturn(0); 100820cf1dd8SToby Isaac } 100920cf1dd8SToby Isaac 1010*27f02ce8SMatthew G. Knepley PetscErrorCode PetscFEIntegrateHybridJacobian_Basic(PetscDS ds, PetscFEJacobianType jtype, PetscInt fieldI, PetscInt fieldJ, PetscInt Ne, PetscFEGeom *fgeom, 1011*27f02ce8SMatthew G. Knepley const PetscScalar coefficients[], const PetscScalar coefficients_t[], PetscDS dsAux, const PetscScalar coefficientsAux[], PetscReal t, PetscReal u_tshift, PetscScalar elemMat[]) 1012*27f02ce8SMatthew G. Knepley { 1013*27f02ce8SMatthew G. Knepley const PetscInt debug = 0; 1014*27f02ce8SMatthew G. Knepley PetscFE feI, feJ; 1015*27f02ce8SMatthew G. Knepley PetscBdPointJac g0_func; 1016*27f02ce8SMatthew G. Knepley PetscBdPointJac g1_func; 1017*27f02ce8SMatthew G. Knepley PetscBdPointJac g2_func; 1018*27f02ce8SMatthew G. Knepley PetscBdPointJac g3_func; 1019*27f02ce8SMatthew G. Knepley PetscQuadrature quad; 1020*27f02ce8SMatthew G. Knepley PetscInt cOffset = 0; /* Offset into coefficients[] for element e */ 1021*27f02ce8SMatthew G. Knepley PetscInt cOffsetAux = 0; /* Offset into coefficientsAux[] for element e */ 1022*27f02ce8SMatthew G. Knepley PetscInt eOffset = 0; /* Offset into elemMat[] for element e */ 1023*27f02ce8SMatthew G. Knepley PetscInt offsetI = 0; /* Offset into an element vector for fieldI */ 1024*27f02ce8SMatthew G. Knepley PetscInt offsetJ = 0; /* Offset into an element vector for fieldJ */ 1025*27f02ce8SMatthew G. Knepley PetscScalar *g0, *g1, *g2, *g3, *u, *u_t = NULL, *u_x, *a, *a_x, *basisReal, *basisDerReal, *testReal, *testDerReal; 1026*27f02ce8SMatthew G. Knepley const PetscScalar *constants; 1027*27f02ce8SMatthew G. Knepley PetscReal *x; 1028*27f02ce8SMatthew G. Knepley PetscReal **B, **D, **BAux = NULL, **DAux = NULL, *BI, *DI, *BJ, *DJ; 1029*27f02ce8SMatthew G. Knepley PetscInt *uOff, *uOff_x, *aOff = NULL, *aOff_x = NULL, *Nb, *Nc, *NbAux = NULL, *NcAux = NULL; 1030*27f02ce8SMatthew G. Knepley PetscInt NbI = 0, NcI = 0, NbJ = 0, NcJ = 0, NcS, NcT; 1031*27f02ce8SMatthew G. Knepley PetscInt dim, dimAux, numConstants, Nf, NfAux = 0, totDim, totDimAux = 0, e; 1032*27f02ce8SMatthew G. Knepley PetscBool isCohesiveFieldI, isCohesiveFieldJ, isAffine, auxOnBd; 1033*27f02ce8SMatthew G. Knepley const PetscReal *quadPoints, *quadWeights; 1034*27f02ce8SMatthew G. Knepley PetscInt qNc, Nq, q, Np, dE; 1035*27f02ce8SMatthew G. Knepley PetscErrorCode ierr; 1036*27f02ce8SMatthew G. Knepley 1037*27f02ce8SMatthew G. Knepley PetscFunctionBegin; 1038*27f02ce8SMatthew G. Knepley /* Hybrid discretization is posed directly on faces */ 1039*27f02ce8SMatthew G. Knepley ierr = PetscDSGetDiscretization(ds, fieldI, (PetscObject *) &feI);CHKERRQ(ierr); 1040*27f02ce8SMatthew G. Knepley ierr = PetscDSGetDiscretization(ds, fieldJ, (PetscObject *) &feJ);CHKERRQ(ierr); 1041*27f02ce8SMatthew G. Knepley ierr = PetscFEGetSpatialDimension(feI, &dim);CHKERRQ(ierr); 1042*27f02ce8SMatthew G. Knepley ierr = PetscFEGetQuadrature(feI, &quad);CHKERRQ(ierr); 1043*27f02ce8SMatthew G. Knepley ierr = PetscDSGetNumFields(ds, &Nf);CHKERRQ(ierr); 1044*27f02ce8SMatthew G. Knepley ierr = PetscDSGetTotalDimension(ds, &totDim);CHKERRQ(ierr); 1045*27f02ce8SMatthew G. Knepley ierr = PetscDSGetDimensions(ds, &Nb);CHKERRQ(ierr); 1046*27f02ce8SMatthew G. Knepley ierr = PetscDSGetComponents(ds, &Nc);CHKERRQ(ierr); 1047*27f02ce8SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(ds, &uOff);CHKERRQ(ierr); 1048*27f02ce8SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(ds, &uOff_x);CHKERRQ(ierr); 1049*27f02ce8SMatthew G. Knepley ierr = PetscDSGetFieldOffset(ds, fieldI, &offsetI);CHKERRQ(ierr); 1050*27f02ce8SMatthew G. Knepley ierr = PetscDSGetFieldOffset(ds, fieldJ, &offsetJ);CHKERRQ(ierr); 1051*27f02ce8SMatthew G. Knepley switch(jtype) { 1052*27f02ce8SMatthew G. Knepley case PETSCFE_JACOBIAN_PRE: ierr = PetscDSGetBdJacobianPreconditioner(ds, fieldI, fieldJ, &g0_func, &g1_func, &g2_func, &g3_func);CHKERRQ(ierr);break; 1053*27f02ce8SMatthew G. Knepley case PETSCFE_JACOBIAN: ierr = PetscDSGetBdJacobian(ds, fieldI, fieldJ, &g0_func, &g1_func, &g2_func, &g3_func);CHKERRQ(ierr);break; 1054*27f02ce8SMatthew G. Knepley case PETSCFE_JACOBIAN_DYN: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "No dynamic boundary hybrid Jacobians :)"); 1055*27f02ce8SMatthew G. Knepley } 1056*27f02ce8SMatthew G. Knepley if (!g0_func && !g1_func && !g2_func && !g3_func) PetscFunctionReturn(0); 1057*27f02ce8SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(ds, &u, coefficients_t ? &u_t : NULL, &u_x);CHKERRQ(ierr); 1058*27f02ce8SMatthew G. Knepley ierr = PetscDSGetWorkspace(ds, &x, &basisReal, &basisDerReal, &testReal, &testDerReal);CHKERRQ(ierr); 1059*27f02ce8SMatthew G. Knepley ierr = PetscDSGetWeakFormArrays(ds, NULL, NULL, &g0, &g1, &g2, &g3);CHKERRQ(ierr); 1060*27f02ce8SMatthew G. Knepley ierr = PetscDSGetTabulation(ds, &B, &D);CHKERRQ(ierr); 1061*27f02ce8SMatthew G. Knepley ierr = PetscDSGetConstants(ds, &numConstants, &constants);CHKERRQ(ierr); 1062*27f02ce8SMatthew G. Knepley if (dsAux) { 1063*27f02ce8SMatthew G. Knepley ierr = PetscDSGetSpatialDimension(dsAux, &dimAux);CHKERRQ(ierr); 1064*27f02ce8SMatthew G. Knepley ierr = PetscDSGetNumFields(dsAux, &NfAux);CHKERRQ(ierr); 1065*27f02ce8SMatthew G. Knepley ierr = PetscDSGetTotalDimension(dsAux, &totDimAux);CHKERRQ(ierr); 1066*27f02ce8SMatthew G. Knepley ierr = PetscDSGetDimensions(dsAux, &NbAux);CHKERRQ(ierr); 1067*27f02ce8SMatthew G. Knepley ierr = PetscDSGetComponents(dsAux, &NcAux);CHKERRQ(ierr); 1068*27f02ce8SMatthew G. Knepley ierr = PetscDSGetComponentOffsets(dsAux, &aOff);CHKERRQ(ierr); 1069*27f02ce8SMatthew G. Knepley ierr = PetscDSGetComponentDerivativeOffsets(dsAux, &aOff_x);CHKERRQ(ierr); 1070*27f02ce8SMatthew G. Knepley ierr = PetscDSGetEvaluationArrays(dsAux, &a, NULL, &a_x);CHKERRQ(ierr); 1071*27f02ce8SMatthew G. Knepley auxOnBd = dimAux < dim ? PETSC_TRUE : PETSC_FALSE; 1072*27f02ce8SMatthew G. Knepley if (auxOnBd) {ierr = PetscDSGetTabulation(dsAux, &BAux, &DAux);CHKERRQ(ierr);} 1073*27f02ce8SMatthew G. Knepley else {ierr = PetscDSGetFaceTabulation(dsAux, &BAux, &DAux);CHKERRQ(ierr);} 1074*27f02ce8SMatthew G. Knepley } 1075*27f02ce8SMatthew G. Knepley isCohesiveFieldI = fieldI == Nf-1 ? PETSC_TRUE : PETSC_FALSE; 1076*27f02ce8SMatthew G. Knepley isCohesiveFieldJ = fieldJ == Nf-1 ? PETSC_TRUE : PETSC_FALSE; 1077*27f02ce8SMatthew G. Knepley NbI = Nb[fieldI], NbJ = Nb[fieldJ]; 1078*27f02ce8SMatthew G. Knepley NcI = Nc[fieldI], NcJ = Nc[fieldJ]; 1079*27f02ce8SMatthew G. Knepley NcS = isCohesiveFieldI ? NcI : 2*NcI; 1080*27f02ce8SMatthew G. Knepley NcT = isCohesiveFieldJ ? NcJ : 2*NcJ; 1081*27f02ce8SMatthew G. Knepley BI = B[fieldI], BJ = B[fieldJ]; 1082*27f02ce8SMatthew G. Knepley DI = D[fieldI], DJ = D[fieldJ]; 1083*27f02ce8SMatthew G. Knepley ierr = PetscQuadratureGetData(quad, NULL, &qNc, &Nq, &quadPoints, &quadWeights);CHKERRQ(ierr); 1084*27f02ce8SMatthew G. Knepley if (qNc != 1) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_SUP, "Only supports scalar quadrature, not %D components\n", qNc); 1085*27f02ce8SMatthew G. Knepley Np = fgeom->numPoints; 1086*27f02ce8SMatthew G. Knepley dE = fgeom->dimEmbed; 1087*27f02ce8SMatthew G. Knepley isAffine = fgeom->isAffine; 1088*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g0, NcS*NcT);CHKERRQ(ierr); 1089*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g1, NcS*NcT*dE);CHKERRQ(ierr); 1090*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g2, NcS*NcT*dE);CHKERRQ(ierr); 1091*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g3, NcS*NcT*dE*dE);CHKERRQ(ierr); 1092*27f02ce8SMatthew G. Knepley for (e = 0; e < Ne; ++e) { 1093*27f02ce8SMatthew G. Knepley PetscFEGeom fegeom; 1094*27f02ce8SMatthew G. Knepley const PetscInt face = fgeom->face[e][0]; 1095*27f02ce8SMatthew G. Knepley 1096*27f02ce8SMatthew G. Knepley fegeom.dim = fgeom->dim; 1097*27f02ce8SMatthew G. Knepley fegeom.dimEmbed = fgeom->dimEmbed; 1098*27f02ce8SMatthew G. Knepley if (isAffine) { 1099*27f02ce8SMatthew G. Knepley fegeom.v = x; 1100*27f02ce8SMatthew G. Knepley fegeom.xi = fgeom->xi; 1101*27f02ce8SMatthew G. Knepley fegeom.J = &fgeom->J[e*dE*dE]; 1102*27f02ce8SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[e*dE*dE]; 1103*27f02ce8SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e]; 1104*27f02ce8SMatthew G. Knepley fegeom.n = &fgeom->n[e*dE]; 1105*27f02ce8SMatthew G. Knepley } 1106*27f02ce8SMatthew G. Knepley for (q = 0; q < Nq; ++q) { 1107*27f02ce8SMatthew G. Knepley const PetscReal *BIq = &BI[q*NbI*NcI], *BJq = &BJ[q*NbJ*NcJ]; 1108*27f02ce8SMatthew G. Knepley const PetscReal *DIq = &DI[q*NbI*NcI*dim], *DJq = &DJ[q*NbJ*NcJ*dim]; 1109*27f02ce8SMatthew G. Knepley PetscReal w; 1110*27f02ce8SMatthew G. Knepley PetscInt c; 1111*27f02ce8SMatthew G. Knepley 1112*27f02ce8SMatthew G. Knepley if (isAffine) { 1113*27f02ce8SMatthew G. Knepley /* TODO Is it correct to have 'dim' here, or should it be 'dim-1'? */ 1114*27f02ce8SMatthew G. Knepley CoordinatesRefToReal(dE, dim, fegeom.xi, &fgeom->v[e*dE], fegeom.J, &quadPoints[q*dim], x); 1115*27f02ce8SMatthew G. Knepley } else { 1116*27f02ce8SMatthew G. Knepley fegeom.v = &fegeom.v[(e*Np+q)*dE]; 1117*27f02ce8SMatthew G. Knepley fegeom.J = &fgeom->J[(e*Np+q)*dE*dE]; 1118*27f02ce8SMatthew G. Knepley fegeom.invJ = &fgeom->invJ[(e*Np+q)*dE*dE]; 1119*27f02ce8SMatthew G. Knepley fegeom.detJ = &fgeom->detJ[e*Np+q]; 1120*27f02ce8SMatthew G. Knepley fegeom.n = &fgeom->n[(e*Np+q)*dE]; 1121*27f02ce8SMatthew G. Knepley } 1122*27f02ce8SMatthew G. Knepley w = fegeom.detJ[0]*quadWeights[q]; 1123*27f02ce8SMatthew G. Knepley if (debug > 1 && q < Np) { 1124*27f02ce8SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, " detJ: %g\n", fegeom.detJ[0]);CHKERRQ(ierr); 1125*27f02ce8SMatthew G. Knepley #if !defined(PETSC_USE_COMPLEX) 1126*27f02ce8SMatthew G. Knepley ierr = DMPrintCellMatrix(e, "invJ", dim, dim, fegeom.invJ);CHKERRQ(ierr); 1127*27f02ce8SMatthew G. Knepley #endif 1128*27f02ce8SMatthew G. Knepley } 1129*27f02ce8SMatthew G. Knepley if (debug) {ierr = PetscPrintf(PETSC_COMM_SELF, " quad point %d\n", q);CHKERRQ(ierr);} 1130*27f02ce8SMatthew G. Knepley if (coefficients) {ierr = PetscFEEvaluateFieldJets_Hybrid_Internal(ds, dim, Nf, Nb, Nc, q, B, D, &fegeom, &coefficients[cOffset], &coefficients_t[cOffset], u, u_x, u_t);CHKERRQ(ierr);} 1131*27f02ce8SMatthew G. Knepley if (dsAux) {ierr = PetscFEEvaluateFieldJets_Hybrid_Internal(dsAux, dimAux, NfAux, NbAux, NcAux, auxOnBd ? q : face*Nq+q, BAux, DAux, &fegeom, &coefficientsAux[cOffsetAux], NULL, a, a_x, NULL);CHKERRQ(ierr);} 1132*27f02ce8SMatthew G. Knepley if (g0_func) { 1133*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g0, NcS*NcT);CHKERRQ(ierr); 1134*27f02ce8SMatthew 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); 1135*27f02ce8SMatthew G. Knepley for (c = 0; c < NcS*NcT; ++c) g0[c] *= w; 1136*27f02ce8SMatthew G. Knepley } 1137*27f02ce8SMatthew G. Knepley if (g1_func) { 1138*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g1, NcS*NcT*dE);CHKERRQ(ierr); 1139*27f02ce8SMatthew 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); 1140*27f02ce8SMatthew G. Knepley for (c = 0; c < NcS*NcT*dE; ++c) g1[c] *= w; 1141*27f02ce8SMatthew G. Knepley } 1142*27f02ce8SMatthew G. Knepley if (g2_func) { 1143*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g2, NcS*NcT*dE);CHKERRQ(ierr); 1144*27f02ce8SMatthew 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); 1145*27f02ce8SMatthew G. Knepley for (c = 0; c < NcS*NcT*dE; ++c) g2[c] *= w; 1146*27f02ce8SMatthew G. Knepley } 1147*27f02ce8SMatthew G. Knepley if (g3_func) { 1148*27f02ce8SMatthew G. Knepley ierr = PetscArrayzero(g3, NcS*NcT*dE*dE);CHKERRQ(ierr); 1149*27f02ce8SMatthew 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); 1150*27f02ce8SMatthew G. Knepley for (c = 0; c < NcS*NcT*dE*dE; ++c) g3[c] *= w; 1151*27f02ce8SMatthew G. Knepley } 1152*27f02ce8SMatthew G. Knepley 1153*27f02ce8SMatthew G. Knepley if (isCohesiveFieldI && isCohesiveFieldJ) { 1154*27f02ce8SMatthew G. Knepley ierr = PetscFEUpdateElementMat_Internal(feI, feJ, dim, NbI, NcI, BIq, DIq, basisReal, basisDerReal, NbJ, NcJ, BJq, DJq, testReal, testDerReal, &fegeom, g0, g1, g2, g3, eOffset, totDim, offsetI*2, offsetJ*2, elemMat);CHKERRQ(ierr); 1155*27f02ce8SMatthew G. Knepley } else { 1156*27f02ce8SMatthew G. Knepley ierr = PetscFEUpdateElementMat_Hybrid_Internal(feI, isCohesiveFieldI, feJ, isCohesiveFieldJ, dim, NbI, NcI, BIq, DIq, basisReal, basisDerReal, NbJ, NcJ, BJq, DJq, testReal, testDerReal, &fegeom, g0, g1, g2, g3, eOffset, totDim, offsetI*2, offsetJ*2, elemMat);CHKERRQ(ierr); 1157*27f02ce8SMatthew G. Knepley } 1158*27f02ce8SMatthew G. Knepley } 1159*27f02ce8SMatthew G. Knepley if (debug > 1) { 1160*27f02ce8SMatthew G. Knepley PetscInt fc, f, gc, g; 1161*27f02ce8SMatthew G. Knepley 1162*27f02ce8SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "Element matrix for fields %d and %d\n", fieldI, fieldJ);CHKERRQ(ierr); 1163*27f02ce8SMatthew G. Knepley for (fc = 0; fc < NcI; ++fc) { 1164*27f02ce8SMatthew G. Knepley for (f = 0; f < NbI; ++f) { 1165*27f02ce8SMatthew G. Knepley const PetscInt i = offsetI + f*NcI+fc; 1166*27f02ce8SMatthew G. Knepley for (gc = 0; gc < NcJ; ++gc) { 1167*27f02ce8SMatthew G. Knepley for (g = 0; g < NbJ; ++g) { 1168*27f02ce8SMatthew G. Knepley const PetscInt j = offsetJ + g*NcJ+gc; 1169*27f02ce8SMatthew 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); 1170*27f02ce8SMatthew G. Knepley } 1171*27f02ce8SMatthew G. Knepley } 1172*27f02ce8SMatthew G. Knepley ierr = PetscPrintf(PETSC_COMM_SELF, "\n");CHKERRQ(ierr); 1173*27f02ce8SMatthew G. Knepley } 1174*27f02ce8SMatthew G. Knepley } 1175*27f02ce8SMatthew G. Knepley } 1176*27f02ce8SMatthew G. Knepley cOffset += totDim; 1177*27f02ce8SMatthew G. Knepley cOffsetAux += totDimAux; 1178*27f02ce8SMatthew G. Knepley eOffset += PetscSqr(totDim); 1179*27f02ce8SMatthew G. Knepley } 1180*27f02ce8SMatthew G. Knepley PetscFunctionReturn(0); 1181*27f02ce8SMatthew G. Knepley } 1182*27f02ce8SMatthew G. Knepley 11832b99622eSMatthew G. Knepley static PetscErrorCode PetscFEInitialize_Basic(PetscFE fem) 118420cf1dd8SToby Isaac { 118520cf1dd8SToby Isaac PetscFunctionBegin; 118620cf1dd8SToby Isaac fem->ops->setfromoptions = NULL; 118720cf1dd8SToby Isaac fem->ops->setup = PetscFESetUp_Basic; 118820cf1dd8SToby Isaac fem->ops->view = PetscFEView_Basic; 118920cf1dd8SToby Isaac fem->ops->destroy = PetscFEDestroy_Basic; 119020cf1dd8SToby Isaac fem->ops->getdimension = PetscFEGetDimension_Basic; 1191ef0bb6c7SMatthew G. Knepley fem->ops->createtabulation = PetscFECreateTabulation_Basic; 119220cf1dd8SToby Isaac fem->ops->integrate = PetscFEIntegrate_Basic; 1193afe6d6adSToby Isaac fem->ops->integratebd = PetscFEIntegrateBd_Basic; 119420cf1dd8SToby Isaac fem->ops->integrateresidual = PetscFEIntegrateResidual_Basic; 119520cf1dd8SToby Isaac fem->ops->integratebdresidual = PetscFEIntegrateBdResidual_Basic; 1196*27f02ce8SMatthew G. Knepley fem->ops->integratehybridresidual = PetscFEIntegrateHybridResidual_Basic; 119720cf1dd8SToby Isaac fem->ops->integratejacobianaction = NULL/* PetscFEIntegrateJacobianAction_Basic */; 119820cf1dd8SToby Isaac fem->ops->integratejacobian = PetscFEIntegrateJacobian_Basic; 119920cf1dd8SToby Isaac fem->ops->integratebdjacobian = PetscFEIntegrateBdJacobian_Basic; 1200*27f02ce8SMatthew G. Knepley fem->ops->integratehybridjacobian = PetscFEIntegrateHybridJacobian_Basic; 120120cf1dd8SToby Isaac PetscFunctionReturn(0); 120220cf1dd8SToby Isaac } 120320cf1dd8SToby Isaac 120420cf1dd8SToby Isaac /*MC 120520cf1dd8SToby Isaac PETSCFEBASIC = "basic" - A PetscFE object that integrates with basic tiling and no vectorization 120620cf1dd8SToby Isaac 120720cf1dd8SToby Isaac Level: intermediate 120820cf1dd8SToby Isaac 120920cf1dd8SToby Isaac .seealso: PetscFEType, PetscFECreate(), PetscFESetType() 121020cf1dd8SToby Isaac M*/ 121120cf1dd8SToby Isaac 121220cf1dd8SToby Isaac PETSC_EXTERN PetscErrorCode PetscFECreate_Basic(PetscFE fem) 121320cf1dd8SToby Isaac { 121420cf1dd8SToby Isaac PetscFE_Basic *b; 121520cf1dd8SToby Isaac PetscErrorCode ierr; 121620cf1dd8SToby Isaac 121720cf1dd8SToby Isaac PetscFunctionBegin; 121820cf1dd8SToby Isaac PetscValidHeaderSpecific(fem, PETSCFE_CLASSID, 1); 121920cf1dd8SToby Isaac ierr = PetscNewLog(fem,&b);CHKERRQ(ierr); 122020cf1dd8SToby Isaac fem->data = b; 122120cf1dd8SToby Isaac 122220cf1dd8SToby Isaac ierr = PetscFEInitialize_Basic(fem);CHKERRQ(ierr); 122320cf1dd8SToby Isaac PetscFunctionReturn(0); 122420cf1dd8SToby Isaac } 1225