163d025dbSVijay Mahadevan 263d025dbSVijay Mahadevan #include <petscconf.h> 363d025dbSVijay Mahadevan #include <petscdt.h> /*I "petscdt.h" I*/ 463d025dbSVijay Mahadevan #include <petsc/private/dmmbimpl.h> /*I "petscdmmoab.h" I*/ 563d025dbSVijay Mahadevan 663d025dbSVijay Mahadevan /* Utility functions */ 763d025dbSVijay Mahadevan static inline PetscReal DMatrix_Determinant_2x2_Internal ( const PetscReal inmat[2 * 2] ) 863d025dbSVijay Mahadevan { 963d025dbSVijay Mahadevan return inmat[0] * inmat[3] - inmat[1] * inmat[2]; 1063d025dbSVijay Mahadevan } 1163d025dbSVijay Mahadevan 12*181f196bSVijay Mahadevan #undef __FUNCT__ 13*181f196bSVijay Mahadevan #define __FUNCT__ "DMatrix_Invert_2x2_Internal" 1463d025dbSVijay Mahadevan static inline PetscErrorCode DMatrix_Invert_2x2_Internal (const PetscReal *inmat, PetscReal *outmat, PetscReal *determinant) 1563d025dbSVijay Mahadevan { 1663d025dbSVijay Mahadevan if (!inmat) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_POINTER, "Invalid input matrix specified for 2x2 inversion."); 1763d025dbSVijay Mahadevan PetscReal det = DMatrix_Determinant_2x2_Internal(inmat); 1863d025dbSVijay Mahadevan if (outmat) { 1963d025dbSVijay Mahadevan outmat[0] = inmat[3] / det; 2063d025dbSVijay Mahadevan outmat[1] = -inmat[1] / det; 2163d025dbSVijay Mahadevan outmat[2] = -inmat[2] / det; 2263d025dbSVijay Mahadevan outmat[3] = inmat[0] / det; 2363d025dbSVijay Mahadevan } 2463d025dbSVijay Mahadevan if (determinant) *determinant = det; 2563d025dbSVijay Mahadevan PetscFunctionReturn(0); 2663d025dbSVijay Mahadevan } 2763d025dbSVijay Mahadevan 28*181f196bSVijay Mahadevan static inline PetscReal DMatrix_Determinant_3x3_Internal ( const PetscReal inmat[3 * 3] ) 2963d025dbSVijay Mahadevan { 3063d025dbSVijay Mahadevan return inmat[0] * (inmat[8] * inmat[4] - inmat[7] * inmat[5]) 3163d025dbSVijay Mahadevan - inmat[3] * (inmat[8] * inmat[1] - inmat[7] * inmat[2]) 3263d025dbSVijay Mahadevan + inmat[6] * (inmat[5] * inmat[1] - inmat[4] * inmat[2]); 3363d025dbSVijay Mahadevan } 3463d025dbSVijay Mahadevan 35*181f196bSVijay Mahadevan #undef __FUNCT__ 36*181f196bSVijay Mahadevan #define __FUNCT__ "DMatrix_Invert_3x3_Internal" 3763d025dbSVijay Mahadevan static inline PetscErrorCode DMatrix_Invert_3x3_Internal (const PetscReal *inmat, PetscReal *outmat, PetscScalar *determinant) 3863d025dbSVijay Mahadevan { 3963d025dbSVijay Mahadevan if (!inmat) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_POINTER, "Invalid input matrix specified for 3x3 inversion."); 40*181f196bSVijay Mahadevan PetscReal det = DMatrix_Determinant_3x3_Internal(inmat); 4163d025dbSVijay Mahadevan if (outmat) { 4263d025dbSVijay Mahadevan outmat[0] = (inmat[8] * inmat[4] - inmat[7] * inmat[5]) / det; 4363d025dbSVijay Mahadevan outmat[1] = -(inmat[8] * inmat[1] - inmat[7] * inmat[2]) / det; 4463d025dbSVijay Mahadevan outmat[2] = (inmat[5] * inmat[1] - inmat[4] * inmat[2]) / det; 4563d025dbSVijay Mahadevan outmat[3] = -(inmat[8] * inmat[3] - inmat[6] * inmat[5]) / det; 4663d025dbSVijay Mahadevan outmat[4] = (inmat[8] * inmat[0] - inmat[6] * inmat[2]) / det; 4763d025dbSVijay Mahadevan outmat[5] = -(inmat[5] * inmat[0] - inmat[3] * inmat[2]) / det; 4863d025dbSVijay Mahadevan outmat[6] = (inmat[7] * inmat[3] - inmat[6] * inmat[4]) / det; 4963d025dbSVijay Mahadevan outmat[7] = -(inmat[7] * inmat[0] - inmat[6] * inmat[1]) / det; 5063d025dbSVijay Mahadevan outmat[8] = (inmat[4] * inmat[0] - inmat[3] * inmat[1]) / det; 5163d025dbSVijay Mahadevan } 5263d025dbSVijay Mahadevan if (determinant) *determinant = det; 5363d025dbSVijay Mahadevan PetscFunctionReturn(0); 5463d025dbSVijay Mahadevan } 5563d025dbSVijay Mahadevan 56*181f196bSVijay Mahadevan inline PetscReal DMatrix_Determinant_4x4_Internal ( PetscReal inmat[4 * 4] ) 57*181f196bSVijay Mahadevan { 58*181f196bSVijay Mahadevan return 59*181f196bSVijay Mahadevan inmat[0 + 0 * 4] * ( 60*181f196bSVijay Mahadevan inmat[1 + 1 * 4] * ( inmat[2 + 2 * 4] * inmat[3 + 3 * 4] - inmat[2 + 3 * 4] * inmat[3 + 2 * 4] ) 61*181f196bSVijay Mahadevan - inmat[1 + 2 * 4] * ( inmat[2 + 1 * 4] * inmat[3 + 3 * 4] - inmat[2 + 3 * 4] * inmat[3 + 1 * 4] ) 62*181f196bSVijay Mahadevan + inmat[1 + 3 * 4] * ( inmat[2 + 1 * 4] * inmat[3 + 2 * 4] - inmat[2 + 2 * 4] * inmat[3 + 1 * 4] ) ) 63*181f196bSVijay Mahadevan - inmat[0 + 1 * 4] * ( 64*181f196bSVijay Mahadevan inmat[1 + 0 * 4] * ( inmat[2 + 2 * 4] * inmat[3 + 3 * 4] - inmat[2 + 3 * 4] * inmat[3 + 2 * 4] ) 65*181f196bSVijay Mahadevan - inmat[1 + 2 * 4] * ( inmat[2 + 0 * 4] * inmat[3 + 3 * 4] - inmat[2 + 3 * 4] * inmat[3 + 0 * 4] ) 66*181f196bSVijay Mahadevan + inmat[1 + 3 * 4] * ( inmat[2 + 0 * 4] * inmat[3 + 2 * 4] - inmat[2 + 2 * 4] * inmat[3 + 0 * 4] ) ) 67*181f196bSVijay Mahadevan + inmat[0 + 2 * 4] * ( 68*181f196bSVijay Mahadevan inmat[1 + 0 * 4] * ( inmat[2 + 1 * 4] * inmat[3 + 3 * 4] - inmat[2 + 3 * 4] * inmat[3 + 1 * 4] ) 69*181f196bSVijay Mahadevan - inmat[1 + 1 * 4] * ( inmat[2 + 0 * 4] * inmat[3 + 3 * 4] - inmat[2 + 3 * 4] * inmat[3 + 0 * 4] ) 70*181f196bSVijay Mahadevan + inmat[1 + 3 * 4] * ( inmat[2 + 0 * 4] * inmat[3 + 1 * 4] - inmat[2 + 1 * 4] * inmat[3 + 0 * 4] ) ) 71*181f196bSVijay Mahadevan - inmat[0 + 3 * 4] * ( 72*181f196bSVijay Mahadevan inmat[1 + 0 * 4] * ( inmat[2 + 1 * 4] * inmat[3 + 2 * 4] - inmat[2 + 2 * 4] * inmat[3 + 1 * 4] ) 73*181f196bSVijay Mahadevan - inmat[1 + 1 * 4] * ( inmat[2 + 0 * 4] * inmat[3 + 2 * 4] - inmat[2 + 2 * 4] * inmat[3 + 0 * 4] ) 74*181f196bSVijay Mahadevan + inmat[1 + 2 * 4] * ( inmat[2 + 0 * 4] * inmat[3 + 1 * 4] - inmat[2 + 1 * 4] * inmat[3 + 0 * 4] ) ); 75*181f196bSVijay Mahadevan } 76*181f196bSVijay Mahadevan 77*181f196bSVijay Mahadevan #undef __FUNCT__ 78*181f196bSVijay Mahadevan #define __FUNCT__ "DMatrix_Invert_4x4_Internal" 79*181f196bSVijay Mahadevan inline PetscErrorCode DMatrix_Invert_4x4_Internal (PetscReal *inmat, PetscReal *outmat, PetscScalar *determinant) 80*181f196bSVijay Mahadevan { 81*181f196bSVijay Mahadevan if (!inmat) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_POINTER, "Invalid input matrix specified for 4x4 inversion."); 82*181f196bSVijay Mahadevan PetscReal det = DMatrix_Determinant_4x4_Internal(inmat); 83*181f196bSVijay Mahadevan if (outmat) { 84*181f196bSVijay Mahadevan outmat[0] = (inmat[5] * inmat[10] * inmat[15] + inmat[6] * inmat[11] * inmat[13] + inmat[7] * inmat[9] * inmat[14] - inmat[5] * inmat[11] * inmat[14] - inmat[6] * inmat[9] * inmat[15] - inmat[7] * inmat[10] * inmat[13]) / det; 85*181f196bSVijay Mahadevan outmat[1] = (inmat[1] * inmat[11] * inmat[14] + inmat[2] * inmat[9] * inmat[15] + inmat[3] * inmat[10] * inmat[13] - inmat[1] * inmat[10] * inmat[15] - inmat[2] * inmat[11] * inmat[13] - inmat[3] * inmat[9] * inmat[14]) / det; 86*181f196bSVijay Mahadevan outmat[2] = (inmat[1] * inmat[6] * inmat[15] + inmat[2] * inmat[7] * inmat[13] + inmat[3] * inmat[5] * inmat[14] - inmat[1] * inmat[7] * inmat[14] - inmat[2] * inmat[5] * inmat[15] - inmat[3] * inmat[6] * inmat[13]) / det; 87*181f196bSVijay Mahadevan outmat[3] = (inmat[1] * inmat[7] * inmat[10] + inmat[2] * inmat[5] * inmat[11] + inmat[3] * inmat[6] * inmat[9] - inmat[1] * inmat[6] * inmat[11] - inmat[2] * inmat[7] * inmat[9] - inmat[3] * inmat[5] * inmat[10]) / det; 88*181f196bSVijay Mahadevan outmat[4] = (inmat[4] * inmat[11] * inmat[14] + inmat[6] * inmat[8] * inmat[15] + inmat[7] * inmat[10] * inmat[12] - inmat[4] * inmat[10] * inmat[15] - inmat[6] * inmat[11] * inmat[12] - inmat[7] * inmat[8] * inmat[14]) / det; 89*181f196bSVijay Mahadevan outmat[5] = (inmat[0] * inmat[10] * inmat[15] + inmat[2] * inmat[11] * inmat[12] + inmat[3] * inmat[8] * inmat[14] - inmat[0] * inmat[11] * inmat[14] - inmat[2] * inmat[8] * inmat[15] - inmat[3] * inmat[10] * inmat[12]) / det; 90*181f196bSVijay Mahadevan outmat[6] = (inmat[0] * inmat[7] * inmat[14] + inmat[2] * inmat[4] * inmat[15] + inmat[3] * inmat[6] * inmat[12] - inmat[0] * inmat[6] * inmat[15] - inmat[2] * inmat[7] * inmat[12] - inmat[3] * inmat[4] * inmat[14]) / det; 91*181f196bSVijay Mahadevan outmat[7] = (inmat[0] * inmat[6] * inmat[11] + inmat[2] * inmat[7] * inmat[8] + inmat[3] * inmat[4] * inmat[10] - inmat[0] * inmat[7] * inmat[10] - inmat[2] * inmat[4] * inmat[11] - inmat[3] * inmat[6] * inmat[8]) / det; 92*181f196bSVijay Mahadevan outmat[8] = (inmat[4] * inmat[9] * inmat[15] + inmat[5] * inmat[11] * inmat[12] + inmat[7] * inmat[8] * inmat[13] - inmat[4] * inmat[11] * inmat[13] - inmat[5] * inmat[8] * inmat[15] - inmat[7] * inmat[9] * inmat[12]) / det; 93*181f196bSVijay Mahadevan outmat[9] = (inmat[0] * inmat[11] * inmat[13] + inmat[1] * inmat[8] * inmat[15] + inmat[3] * inmat[9] * inmat[12] - inmat[0] * inmat[9] * inmat[15] - inmat[1] * inmat[11] * inmat[12] - inmat[3] * inmat[8] * inmat[13]) / det; 94*181f196bSVijay Mahadevan outmat[10] = (inmat[0] * inmat[5] * inmat[15] + inmat[1] * inmat[7] * inmat[12] + inmat[3] * inmat[4] * inmat[13] - inmat[0] * inmat[7] * inmat[13] - inmat[1] * inmat[4] * inmat[15] - inmat[3] * inmat[5] * inmat[12]) / det; 95*181f196bSVijay Mahadevan outmat[11] = (inmat[0] * inmat[7] * inmat[9] + inmat[1] * inmat[4] * inmat[11] + inmat[3] * inmat[5] * inmat[8] - inmat[0] * inmat[5] * inmat[11] - inmat[1] * inmat[7] * inmat[8] - inmat[3] * inmat[4] * inmat[9]) / det; 96*181f196bSVijay Mahadevan outmat[12] = (inmat[4] * inmat[10] * inmat[13] + inmat[5] * inmat[8] * inmat[14] + inmat[6] * inmat[9] * inmat[12] - inmat[4] * inmat[9] * inmat[14] - inmat[5] * inmat[10] * inmat[12] - inmat[6] * inmat[8] * inmat[13]) / det; 97*181f196bSVijay Mahadevan outmat[13] = (inmat[0] * inmat[9] * inmat[14] + inmat[1] * inmat[10] * inmat[12] + inmat[2] * inmat[8] * inmat[13] - inmat[0] * inmat[10] * inmat[13] - inmat[1] * inmat[8] * inmat[14] - inmat[2] * inmat[9] * inmat[12]) / det; 98*181f196bSVijay Mahadevan outmat[14] = (inmat[0] * inmat[6] * inmat[13] + inmat[1] * inmat[4] * inmat[14] + inmat[2] * inmat[5] * inmat[12] - inmat[0] * inmat[5] * inmat[14] - inmat[1] * inmat[6] * inmat[12] - inmat[2] * inmat[4] * inmat[13]) / det; 99*181f196bSVijay Mahadevan outmat[15] = (inmat[0] * inmat[5] * inmat[10] + inmat[1] * inmat[6] * inmat[8] + inmat[2] * inmat[4] * inmat[9] - inmat[0] * inmat[6] * inmat[9] - inmat[1] * inmat[4] * inmat[10] - inmat[2] * inmat[5] * inmat[8]) / det; 100*181f196bSVijay Mahadevan } 101*181f196bSVijay Mahadevan if (determinant) *determinant = det; 102*181f196bSVijay Mahadevan PetscFunctionReturn(0); 103*181f196bSVijay Mahadevan } 104*181f196bSVijay Mahadevan 10563d025dbSVijay Mahadevan 10663d025dbSVijay Mahadevan /*@ 10763d025dbSVijay Mahadevan Compute_Lagrange_Basis_1D_Internal: Evaluate bases and derivatives at quadrature points for a EDGE2 or EDGE3 element. 10863d025dbSVijay Mahadevan 10963d025dbSVijay Mahadevan The routine is given the coordinates of the vertices of a linear or quadratic edge element. 11063d025dbSVijay Mahadevan 11163d025dbSVijay Mahadevan The routine evaluates the basis functions associated with each quadrature point provided, 11263d025dbSVijay Mahadevan and their derivatives with respect to X. 11363d025dbSVijay Mahadevan 11463d025dbSVijay Mahadevan Notes: 11563d025dbSVijay Mahadevan 11663d025dbSVijay Mahadevan Example Physical Element 11763d025dbSVijay Mahadevan 11863d025dbSVijay Mahadevan 1-------2 1----3----2 11963d025dbSVijay Mahadevan EDGE2 EDGE3 12063d025dbSVijay Mahadevan 12163d025dbSVijay Mahadevan Input Parameter: 12263d025dbSVijay Mahadevan 12363d025dbSVijay Mahadevan . PetscInt nverts, the number of element vertices 12463d025dbSVijay Mahadevan . PetscReal coords[3*nverts], the physical coordinates of the vertices (in canonical numbering) 12563d025dbSVijay Mahadevan . PetscInt npts, the number of evaluation points (quadrature points) 12663d025dbSVijay Mahadevan . PetscReal quad[3*npts], the evaluation points (quadrature points) in the reference space 12763d025dbSVijay Mahadevan 12863d025dbSVijay Mahadevan Output Parameter: 12963d025dbSVijay Mahadevan . PetscReal phypts[3*npts], the evaluation points (quadrature points) transformed to the physical space 13063d025dbSVijay Mahadevan . PetscReal jxw[npts], the jacobian determinant * quadrature weight necessary for assembling discrete contributions 13163d025dbSVijay Mahadevan . PetscReal phi[npts], the bases evaluated at the specified quadrature points 13263d025dbSVijay Mahadevan . PetscReal dphidx[npts], the derivative of the bases wrt X-direction evaluated at the specified quadrature points 13363d025dbSVijay Mahadevan 13463d025dbSVijay Mahadevan .keywords: DMMoab, FEM, 1-D 13563d025dbSVijay Mahadevan @*/ 13663d025dbSVijay Mahadevan #undef __FUNCT__ 13763d025dbSVijay Mahadevan #define __FUNCT__ "Compute_Lagrange_Basis_1D_Internal" 13863d025dbSVijay Mahadevan PetscErrorCode Compute_Lagrange_Basis_1D_Internal ( const PetscInt nverts, const PetscReal *coords, const PetscInt npts, const PetscReal *quad, PetscReal *phypts, 139*181f196bSVijay Mahadevan PetscReal *jxw, PetscReal *phi, PetscReal *dphidx, 140*181f196bSVijay Mahadevan PetscReal *jacobian, PetscReal *ijacobian, PetscReal *volume) 14163d025dbSVijay Mahadevan { 14263d025dbSVijay Mahadevan int i, j; 14363d025dbSVijay Mahadevan PetscErrorCode ierr; 14463d025dbSVijay Mahadevan 145*181f196bSVijay Mahadevan PetscFunctionBegin; 146*181f196bSVijay Mahadevan PetscValidPointer(jacobian, 9); 147*181f196bSVijay Mahadevan PetscValidPointer(ijacobian, 10); 148*181f196bSVijay Mahadevan PetscValidPointer(volume, 11); 149*181f196bSVijay Mahadevan if (phypts) { 15063d025dbSVijay Mahadevan ierr = PetscMemzero(phypts, npts * 3 * sizeof(PetscReal));CHKERRQ(ierr); 151*181f196bSVijay Mahadevan } 15263d025dbSVijay Mahadevan if (dphidx) { /* Reset arrays. */ 15363d025dbSVijay Mahadevan ierr = PetscMemzero(dphidx, npts * nverts * sizeof(PetscReal));CHKERRQ(ierr); 15463d025dbSVijay Mahadevan } 15563d025dbSVijay Mahadevan if (nverts == 2) { /* Linear Edge */ 15663d025dbSVijay Mahadevan 15763d025dbSVijay Mahadevan for (j = 0; j < npts; j++) 15863d025dbSVijay Mahadevan { 15963d025dbSVijay Mahadevan const int offset = j * nverts; 160*181f196bSVijay Mahadevan const PetscReal r = quad[j]; 16163d025dbSVijay Mahadevan 162*181f196bSVijay Mahadevan phi[0 + offset] = ( 1.0 - r ); 163*181f196bSVijay Mahadevan phi[1 + offset] = ( r ); 16463d025dbSVijay Mahadevan 165*181f196bSVijay Mahadevan const PetscReal dNi_dxi[2] = { -1.0, 1.0 }; 16663d025dbSVijay Mahadevan 167*181f196bSVijay Mahadevan jacobian[0] = ijacobian[0] = volume[0] = 0.0; 16863d025dbSVijay Mahadevan for (i = 0; i < nverts; ++i) { 169*181f196bSVijay Mahadevan const PetscReal* vertices = coords + i * 3; 170*181f196bSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertices[0]; 171*181f196bSVijay Mahadevan if (phypts) { 172*181f196bSVijay Mahadevan phypts[3 * j + 0] += phi[i + offset] * vertices[0]; 173*181f196bSVijay Mahadevan } 17463d025dbSVijay Mahadevan } 17563d025dbSVijay Mahadevan 17663d025dbSVijay Mahadevan /* invert the jacobian */ 177*181f196bSVijay Mahadevan *volume = jacobian[0]; 178*181f196bSVijay Mahadevan ijacobian[0] = 1.0 / jacobian[0]; 179*181f196bSVijay Mahadevan jxw[j] *= *volume; 18063d025dbSVijay Mahadevan 18163d025dbSVijay Mahadevan /* Divide by element jacobian. */ 18263d025dbSVijay Mahadevan for ( i = 0; i < nverts; i++ ) { 183*181f196bSVijay Mahadevan if (dphidx) dphidx[i + offset] += dNi_dxi[i] * ijacobian[0]; 18463d025dbSVijay Mahadevan } 18563d025dbSVijay Mahadevan 18663d025dbSVijay Mahadevan } 18763d025dbSVijay Mahadevan } 18863d025dbSVijay Mahadevan else if (nverts == 3) { /* Quadratic Edge */ 18963d025dbSVijay Mahadevan 19063d025dbSVijay Mahadevan for (j = 0; j < npts; j++) 19163d025dbSVijay Mahadevan { 19263d025dbSVijay Mahadevan const int offset = j * nverts; 193*181f196bSVijay Mahadevan const PetscReal r = quad[j]; 19463d025dbSVijay Mahadevan 195*181f196bSVijay Mahadevan phi[0 + offset] = 1.0 + r * ( 2.0 * r - 3.0 ); 196*181f196bSVijay Mahadevan phi[1 + offset] = 4.0 * r * ( 1.0 - r ); 197*181f196bSVijay Mahadevan phi[2 + offset] = r * ( 2.0 * r - 1.0 ); 19863d025dbSVijay Mahadevan 199*181f196bSVijay Mahadevan const PetscReal dNi_dxi[3] = { 4 * r - 3.0, 4 * ( 1.0 - 2.0 * r ), 4.0 * r - 1.0}; 20063d025dbSVijay Mahadevan 201*181f196bSVijay Mahadevan jacobian[0] = ijacobian[0] = volume[0] = 0.0; 20263d025dbSVijay Mahadevan for (i = 0; i < nverts; ++i) { 203*181f196bSVijay Mahadevan const PetscReal* vertices = coords + i * 3; 204*181f196bSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertices[0]; 205*181f196bSVijay Mahadevan if (phypts) { 206*181f196bSVijay Mahadevan phypts[3 * j + 0] += phi[i + offset] * vertices[0]; 207*181f196bSVijay Mahadevan } 20863d025dbSVijay Mahadevan } 20963d025dbSVijay Mahadevan 21063d025dbSVijay Mahadevan /* invert the jacobian */ 211*181f196bSVijay Mahadevan *volume = jacobian[0]; 212*181f196bSVijay Mahadevan ijacobian[0] = 1.0 / jacobian[0]; 213*181f196bSVijay Mahadevan if (jxw) jxw[j] *= *volume; 21463d025dbSVijay Mahadevan 21563d025dbSVijay Mahadevan /* Divide by element jacobian. */ 21663d025dbSVijay Mahadevan for ( i = 0; i < nverts; i++ ) { 217*181f196bSVijay Mahadevan if (dphidx) dphidx[i + offset] += dNi_dxi[i] * ijacobian[0]; 21863d025dbSVijay Mahadevan } 21963d025dbSVijay Mahadevan } 22063d025dbSVijay Mahadevan } 22163d025dbSVijay Mahadevan else { 22263d025dbSVijay Mahadevan SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "The number of entity vertices are invalid. Currently only support EDGE2 and EDGE3 basis evaluations in 1-D : %D", nverts); 22363d025dbSVijay Mahadevan } 22463d025dbSVijay Mahadevan #if 0 22563d025dbSVijay Mahadevan /* verify if the computed basis functions are consistent */ 22663d025dbSVijay Mahadevan for ( j = 0; j < npts; j++ ) { 22763d025dbSVijay Mahadevan PetscScalar phisum = 0, dphixsum = 0; 22863d025dbSVijay Mahadevan for ( i = 0; i < nverts; i++ ) { 22963d025dbSVijay Mahadevan phisum += phi[i + j * nverts]; 23063d025dbSVijay Mahadevan if (dphidx) dphixsum += dphidx[i + j * nverts]; 23163d025dbSVijay Mahadevan } 23263d025dbSVijay Mahadevan PetscPrintf(PETSC_COMM_WORLD, "Sum of basis at quadrature point %D = %g, %g, %g\n", j, phisum, dphixsum); 23363d025dbSVijay Mahadevan } 23463d025dbSVijay Mahadevan #endif 23563d025dbSVijay Mahadevan PetscFunctionReturn(0); 23663d025dbSVijay Mahadevan } 23763d025dbSVijay Mahadevan 23863d025dbSVijay Mahadevan 23963d025dbSVijay Mahadevan /*@ 24063d025dbSVijay Mahadevan Compute_Lagrange_Basis_2D_Internal: Evaluate bases and derivatives at quadrature points for a QUAD4 or TRI3 element. 24163d025dbSVijay Mahadevan 24263d025dbSVijay Mahadevan The routine is given the coordinates of the vertices of a quadrangle or triangle. 24363d025dbSVijay Mahadevan 24463d025dbSVijay Mahadevan The routine evaluates the basis functions associated with each quadrature point provided, 24563d025dbSVijay Mahadevan and their derivatives with respect to X and Y. 24663d025dbSVijay Mahadevan 24763d025dbSVijay Mahadevan Notes: 24863d025dbSVijay Mahadevan 24963d025dbSVijay Mahadevan Example Physical Element (QUAD4) 25063d025dbSVijay Mahadevan 25163d025dbSVijay Mahadevan 4------3 s 25263d025dbSVijay Mahadevan | | | 25363d025dbSVijay Mahadevan | | | 25463d025dbSVijay Mahadevan | | | 25563d025dbSVijay Mahadevan 1------2 0-------r 25663d025dbSVijay Mahadevan 25763d025dbSVijay Mahadevan Input Parameter: 25863d025dbSVijay Mahadevan 25963d025dbSVijay Mahadevan . PetscInt nverts, the number of element vertices 26063d025dbSVijay Mahadevan . PetscReal coords[3*nverts], the physical coordinates of the vertices (in canonical numbering) 26163d025dbSVijay Mahadevan . PetscInt npts, the number of evaluation points (quadrature points) 26263d025dbSVijay Mahadevan . PetscReal quad[3*npts], the evaluation points (quadrature points) in the reference space 26363d025dbSVijay Mahadevan 26463d025dbSVijay Mahadevan Output Parameter: 26563d025dbSVijay Mahadevan . PetscReal phypts[3*npts], the evaluation points (quadrature points) transformed to the physical space 26663d025dbSVijay Mahadevan . PetscReal jxw[npts], the jacobian determinant * quadrature weight necessary for assembling discrete contributions 26763d025dbSVijay Mahadevan . PetscReal phi[npts], the bases evaluated at the specified quadrature points 26863d025dbSVijay Mahadevan . PetscReal dphidx[npts], the derivative of the bases wrt X-direction evaluated at the specified quadrature points 26963d025dbSVijay Mahadevan . PetscReal dphidy[npts], the derivative of the bases wrt Y-direction evaluated at the specified quadrature points 27063d025dbSVijay Mahadevan 27163d025dbSVijay Mahadevan .keywords: DMMoab, FEM, 2-D 27263d025dbSVijay Mahadevan @*/ 27363d025dbSVijay Mahadevan #undef __FUNCT__ 27463d025dbSVijay Mahadevan #define __FUNCT__ "Compute_Lagrange_Basis_2D_Internal" 27563d025dbSVijay Mahadevan PetscErrorCode Compute_Lagrange_Basis_2D_Internal ( const PetscInt nverts, const PetscReal *coords, const PetscInt npts, const PetscReal *quad, PetscReal *phypts, 276*181f196bSVijay Mahadevan PetscReal *jxw, PetscReal *phi, PetscReal *dphidx, PetscReal *dphidy, 277*181f196bSVijay Mahadevan PetscReal *jacobian, PetscReal *ijacobian, PetscReal *volume) 27863d025dbSVijay Mahadevan { 27963d025dbSVijay Mahadevan int i, j; 28063d025dbSVijay Mahadevan PetscErrorCode ierr; 28163d025dbSVijay Mahadevan 28263d025dbSVijay Mahadevan PetscFunctionBegin; 283*181f196bSVijay Mahadevan PetscValidPointer(jacobian, 10); 284*181f196bSVijay Mahadevan PetscValidPointer(ijacobian, 11); 285*181f196bSVijay Mahadevan PetscValidPointer(volume, 12); 28663d025dbSVijay Mahadevan ierr = PetscMemzero(phi, npts * sizeof(PetscReal));CHKERRQ(ierr); 287*181f196bSVijay Mahadevan if (phypts) { 28863d025dbSVijay Mahadevan ierr = PetscMemzero(phypts, npts * 3 * sizeof(PetscReal));CHKERRQ(ierr); 289*181f196bSVijay Mahadevan } 29063d025dbSVijay Mahadevan if (dphidx) { /* Reset arrays. */ 29163d025dbSVijay Mahadevan ierr = PetscMemzero(dphidx, npts * nverts * sizeof(PetscReal));CHKERRQ(ierr); 29263d025dbSVijay Mahadevan ierr = PetscMemzero(dphidy, npts * nverts * sizeof(PetscReal));CHKERRQ(ierr); 29363d025dbSVijay Mahadevan } 29463d025dbSVijay Mahadevan if (nverts == 4) { /* Linear Quadrangle */ 29563d025dbSVijay Mahadevan 29663d025dbSVijay Mahadevan for (j = 0; j < npts; j++) 29763d025dbSVijay Mahadevan { 29863d025dbSVijay Mahadevan const int offset = j * nverts; 299*181f196bSVijay Mahadevan const PetscReal r = quad[0 + j * 2]; 300*181f196bSVijay Mahadevan const PetscReal s = quad[1 + j * 2]; 30163d025dbSVijay Mahadevan 30263d025dbSVijay Mahadevan phi[0 + offset] = ( 1.0 - r ) * ( 1.0 - s ); 30363d025dbSVijay Mahadevan phi[1 + offset] = r * ( 1.0 - s ); 30463d025dbSVijay Mahadevan phi[2 + offset] = r * s; 30563d025dbSVijay Mahadevan phi[3 + offset] = ( 1.0 - r ) * s; 30663d025dbSVijay Mahadevan 307*181f196bSVijay Mahadevan const PetscReal dNi_dxi[4] = { -1.0 + s, 1.0 - s, s, -s }; 308*181f196bSVijay Mahadevan const PetscReal dNi_deta[4] = { -1.0 + r, -r, r, 1.0 - r }; 30963d025dbSVijay Mahadevan 31063d025dbSVijay Mahadevan ierr = PetscMemzero(jacobian, 4 * sizeof(PetscReal));CHKERRQ(ierr); 31163d025dbSVijay Mahadevan ierr = PetscMemzero(ijacobian, 4 * sizeof(PetscReal));CHKERRQ(ierr); 31263d025dbSVijay Mahadevan for (i = 0; i < nverts; ++i) { 313*181f196bSVijay Mahadevan const PetscReal* vertices = coords + i * 3; 31463d025dbSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertices[0]; 31563d025dbSVijay Mahadevan jacobian[2] += dNi_dxi[i] * vertices[1]; 31663d025dbSVijay Mahadevan jacobian[1] += dNi_deta[i] * vertices[0]; 31763d025dbSVijay Mahadevan jacobian[3] += dNi_deta[i] * vertices[1]; 318*181f196bSVijay Mahadevan if (phypts) { 319*181f196bSVijay Mahadevan phypts[3 * j + 0] += phi[i + offset] * vertices[0]; 320*181f196bSVijay Mahadevan phypts[3 * j + 1] += phi[i + offset] * vertices[1]; 321*181f196bSVijay Mahadevan phypts[3 * j + 2] += phi[i + offset] * vertices[2]; 322*181f196bSVijay Mahadevan } 32363d025dbSVijay Mahadevan } 32463d025dbSVijay Mahadevan 32563d025dbSVijay Mahadevan /* invert the jacobian */ 326*181f196bSVijay Mahadevan ierr = DMatrix_Invert_2x2_Internal(jacobian, ijacobian, volume);CHKERRQ(ierr); 327*181f196bSVijay Mahadevan if ( *volume < 1e-12 ) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Quadrangular element has zero volume: %g. Degenerate element or invalid connectivity\n", *volume); 32863d025dbSVijay Mahadevan 329*181f196bSVijay Mahadevan if (jxw) jxw[j] *= *volume; 33063d025dbSVijay Mahadevan 331*181f196bSVijay Mahadevan /* Let us compute the bases derivatives by scaling with inverse jacobian. */ 332*181f196bSVijay Mahadevan if (dphidx) { 33363d025dbSVijay Mahadevan for ( i = 0; i < nverts; i++ ) { 33463d025dbSVijay Mahadevan for (int k = 0; k < 2; ++k) { 33563d025dbSVijay Mahadevan if (dphidx) dphidx[i + offset] += dNi_dxi[i] * ijacobian[k * 2 + 0]; 33663d025dbSVijay Mahadevan if (dphidy) dphidy[i + offset] += dNi_deta[i] * ijacobian[k * 2 + 1]; 337*181f196bSVijay Mahadevan } /* for k=[0..2) */ 338*181f196bSVijay Mahadevan } /* for i=[0..nverts) */ 339*181f196bSVijay Mahadevan } /* if (dphidx) */ 34063d025dbSVijay Mahadevan } 34163d025dbSVijay Mahadevan } 34263d025dbSVijay Mahadevan else if (nverts == 3) { /* Linear triangle */ 34363d025dbSVijay Mahadevan 34463d025dbSVijay Mahadevan ierr = PetscMemzero(jacobian, 4 * sizeof(PetscReal));CHKERRQ(ierr); 34563d025dbSVijay Mahadevan ierr = PetscMemzero(ijacobian, 4 * sizeof(PetscReal));CHKERRQ(ierr); 34663d025dbSVijay Mahadevan 347*181f196bSVijay Mahadevan const PetscReal x2 = coords[2 * 3 + 0], y2 = coords[2 * 3 + 1]; 348*181f196bSVijay Mahadevan 34963d025dbSVijay Mahadevan /* Jacobian is constant */ 350*181f196bSVijay Mahadevan jacobian[0] = (coords[0 * 3 + 0] - x2); jacobian[1] = (coords[1 * 3 + 0] - x2); 351*181f196bSVijay Mahadevan jacobian[2] = (coords[0 * 3 + 1] - y2); jacobian[3] = (coords[1 * 3 + 1] - y2); 35263d025dbSVijay Mahadevan 35363d025dbSVijay Mahadevan /* invert the jacobian */ 354*181f196bSVijay Mahadevan ierr = DMatrix_Invert_2x2_Internal(jacobian, ijacobian, volume);CHKERRQ(ierr); 355*181f196bSVijay Mahadevan if ( *volume < 1e-12 ) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Triangular element has zero volume: %g. Degenerate element or invalid connectivity\n", *volume); 356*181f196bSVijay Mahadevan 357*181f196bSVijay Mahadevan const PetscReal Dx[3] = { ijacobian[0], ijacobian[2], - ijacobian[0] - ijacobian[2] }; 358*181f196bSVijay Mahadevan const PetscReal Dy[3] = { ijacobian[1], ijacobian[3], - ijacobian[1] - ijacobian[3] }; 35963d025dbSVijay Mahadevan 36063d025dbSVijay Mahadevan for (j = 0; j < npts; j++) 36163d025dbSVijay Mahadevan { 36263d025dbSVijay Mahadevan const int offset = j * nverts; 363*181f196bSVijay Mahadevan const PetscReal r = quad[0 + j * 2]; 364*181f196bSVijay Mahadevan const PetscReal s = quad[1 + j * 2]; 36563d025dbSVijay Mahadevan 366*181f196bSVijay Mahadevan if (jxw) jxw[j] *= 0.5; 36763d025dbSVijay Mahadevan 368*181f196bSVijay Mahadevan /* const PetscReal Ni[3] = { r, s, 1.0 - r - s }; */ 369*181f196bSVijay Mahadevan const PetscReal phipts_x = coords[2 * 3 + 0] + jacobian[0] * r + jacobian[1] * s; 370*181f196bSVijay Mahadevan const PetscReal phipts_y = coords[2 * 3 + 1] + jacobian[2] * r + jacobian[3] * s; 371*181f196bSVijay Mahadevan if (phypts) { 372*181f196bSVijay Mahadevan phypts[offset + 0] = phipts_x; 373*181f196bSVijay Mahadevan phypts[offset + 1] = phipts_y; 374*181f196bSVijay Mahadevan } 37563d025dbSVijay Mahadevan 376*181f196bSVijay Mahadevan /* \phi_0 = (b.y − c.y) x + (b.x − c.x) y + c.x b.y − b.x c.y */ 377*181f196bSVijay Mahadevan phi[0 + offset] = ( ijacobian[0] * (phipts_x - x2) + ijacobian[1] * (phipts_y - y2) ); 378*181f196bSVijay Mahadevan /* \phi_1 = (c.y − a.y) x + (a.x − c.x) y + c.x a.y − a.x c.y */ 379*181f196bSVijay Mahadevan phi[1 + offset] = ( ijacobian[2] * (phipts_x - x2) + ijacobian[3] * (phipts_y - y2) ); 38063d025dbSVijay Mahadevan phi[2 + offset] = 1.0 - phi[0 + offset] - phi[1 + offset]; 38163d025dbSVijay Mahadevan 38263d025dbSVijay Mahadevan if (dphidx) { 383*181f196bSVijay Mahadevan dphidx[0 + offset] = Dx[0]; 384*181f196bSVijay Mahadevan dphidx[1 + offset] = Dx[1]; 385*181f196bSVijay Mahadevan dphidx[2 + offset] = Dx[2]; 38663d025dbSVijay Mahadevan } 38763d025dbSVijay Mahadevan 38863d025dbSVijay Mahadevan if (dphidy) { 389*181f196bSVijay Mahadevan dphidy[0 + offset] = Dy[0]; 390*181f196bSVijay Mahadevan dphidy[1 + offset] = Dy[1]; 391*181f196bSVijay Mahadevan dphidy[2 + offset] = Dy[2]; 39263d025dbSVijay Mahadevan } 39363d025dbSVijay Mahadevan 39463d025dbSVijay Mahadevan } 39563d025dbSVijay Mahadevan } 39663d025dbSVijay Mahadevan else { 39763d025dbSVijay Mahadevan SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "The number of entity vertices are invalid. Currently only support QUAD4 and TRI3 basis evaluations in 2-D : %D", nverts); 39863d025dbSVijay Mahadevan } 39963d025dbSVijay Mahadevan #if 0 40063d025dbSVijay Mahadevan /* verify if the computed basis functions are consistent */ 40163d025dbSVijay Mahadevan for ( j = 0; j < npts; j++ ) { 40263d025dbSVijay Mahadevan PetscScalar phisum = 0, dphixsum = 0, dphiysum = 0; 40363d025dbSVijay Mahadevan for ( i = 0; i < nverts; i++ ) { 40463d025dbSVijay Mahadevan phisum += phi[i + j * nverts]; 40563d025dbSVijay Mahadevan if (dphidx) dphixsum += dphidx[i + j * nverts]; 40663d025dbSVijay Mahadevan if (dphidy) dphiysum += dphidy[i + j * nverts]; 40763d025dbSVijay Mahadevan } 40863d025dbSVijay Mahadevan PetscPrintf(PETSC_COMM_WORLD, "Sum of basis at quadrature point %D = %g, %g, %g\n", j, phisum, dphixsum, dphiysum); 40963d025dbSVijay Mahadevan } 41063d025dbSVijay Mahadevan #endif 41163d025dbSVijay Mahadevan PetscFunctionReturn(0); 41263d025dbSVijay Mahadevan } 41363d025dbSVijay Mahadevan 41463d025dbSVijay Mahadevan 41563d025dbSVijay Mahadevan /*@ 41663d025dbSVijay Mahadevan Compute_Lagrange_Basis_3D_Internal: Evaluate bases and derivatives at quadrature points for a HEX8 or TET4 element. 41763d025dbSVijay Mahadevan 41863d025dbSVijay Mahadevan The routine is given the coordinates of the vertices of a hexahedra or tetrahedra. 41963d025dbSVijay Mahadevan 42063d025dbSVijay Mahadevan The routine evaluates the basis functions associated with each quadrature point provided, 42163d025dbSVijay Mahadevan and their derivatives with respect to X, Y and Z. 42263d025dbSVijay Mahadevan 42363d025dbSVijay Mahadevan Notes: 42463d025dbSVijay Mahadevan 42563d025dbSVijay Mahadevan Example Physical Element (HEX8) 42663d025dbSVijay Mahadevan 42763d025dbSVijay Mahadevan 8------7 42863d025dbSVijay Mahadevan /| /| t s 42963d025dbSVijay Mahadevan 5------6 | | / 43063d025dbSVijay Mahadevan | | | | |/ 43163d025dbSVijay Mahadevan | 4----|-3 0-------r 43263d025dbSVijay Mahadevan |/ |/ 43363d025dbSVijay Mahadevan 1------2 43463d025dbSVijay Mahadevan 43563d025dbSVijay Mahadevan Input Parameter: 43663d025dbSVijay Mahadevan 43763d025dbSVijay Mahadevan . PetscInt nverts, the number of element vertices 43863d025dbSVijay Mahadevan . PetscReal coords[3*nverts], the physical coordinates of the vertices (in canonical numbering) 43963d025dbSVijay Mahadevan . PetscInt npts, the number of evaluation points (quadrature points) 44063d025dbSVijay Mahadevan . PetscReal quad[3*npts], the evaluation points (quadrature points) in the reference space 44163d025dbSVijay Mahadevan 44263d025dbSVijay Mahadevan Output Parameter: 44363d025dbSVijay Mahadevan . PetscReal phypts[3*npts], the evaluation points (quadrature points) transformed to the physical space 44463d025dbSVijay Mahadevan . PetscReal jxw[npts], the jacobian determinant * quadrature weight necessary for assembling discrete contributions 44563d025dbSVijay Mahadevan . PetscReal phi[npts], the bases evaluated at the specified quadrature points 44663d025dbSVijay Mahadevan . PetscReal dphidx[npts], the derivative of the bases wrt X-direction evaluated at the specified quadrature points 44763d025dbSVijay Mahadevan . PetscReal dphidy[npts], the derivative of the bases wrt Y-direction evaluated at the specified quadrature points 44863d025dbSVijay Mahadevan . PetscReal dphidz[npts], the derivative of the bases wrt Z-direction evaluated at the specified quadrature points 44963d025dbSVijay Mahadevan 45063d025dbSVijay Mahadevan .keywords: DMMoab, FEM, 3-D 45163d025dbSVijay Mahadevan @*/ 45263d025dbSVijay Mahadevan #undef __FUNCT__ 45363d025dbSVijay Mahadevan #define __FUNCT__ "Compute_Lagrange_Basis_3D_Internal" 45463d025dbSVijay Mahadevan PetscErrorCode Compute_Lagrange_Basis_3D_Internal ( const PetscInt nverts, const PetscReal *coords, const PetscInt npts, const PetscReal *quad, PetscReal *phypts, 455*181f196bSVijay Mahadevan PetscReal *jxw, PetscReal *phi, PetscReal *dphidx, PetscReal *dphidy, PetscReal *dphidz, 456*181f196bSVijay Mahadevan PetscReal *jacobian, PetscReal *ijacobian, PetscReal *volume) 45763d025dbSVijay Mahadevan { 45863d025dbSVijay Mahadevan int i, j; 45963d025dbSVijay Mahadevan PetscErrorCode ierr; 46063d025dbSVijay Mahadevan 46163d025dbSVijay Mahadevan PetscFunctionBegin; 462*181f196bSVijay Mahadevan PetscValidPointer(jacobian, 11); 463*181f196bSVijay Mahadevan PetscValidPointer(ijacobian, 12); 464*181f196bSVijay Mahadevan PetscValidPointer(volume, 13); 46563d025dbSVijay Mahadevan /* Reset arrays. */ 46663d025dbSVijay Mahadevan ierr = PetscMemzero(phi, npts * sizeof(PetscReal));CHKERRQ(ierr); 467*181f196bSVijay Mahadevan if (phypts) { 46863d025dbSVijay Mahadevan ierr = PetscMemzero(phypts, npts * 3 * sizeof(PetscReal));CHKERRQ(ierr); 469*181f196bSVijay Mahadevan } 47063d025dbSVijay Mahadevan if (dphidx) { 47163d025dbSVijay Mahadevan ierr = PetscMemzero(dphidx, npts * nverts * sizeof(PetscReal));CHKERRQ(ierr); 47263d025dbSVijay Mahadevan ierr = PetscMemzero(dphidy, npts * nverts * sizeof(PetscReal));CHKERRQ(ierr); 47363d025dbSVijay Mahadevan ierr = PetscMemzero(dphidz, npts * nverts * sizeof(PetscReal));CHKERRQ(ierr); 47463d025dbSVijay Mahadevan } 47563d025dbSVijay Mahadevan 47663d025dbSVijay Mahadevan if (nverts == 8) { /* Linear Hexahedra */ 47763d025dbSVijay Mahadevan 47863d025dbSVijay Mahadevan for (j = 0; j < npts; j++) 47963d025dbSVijay Mahadevan { 48063d025dbSVijay Mahadevan const int offset = j * nverts; 481*181f196bSVijay Mahadevan const PetscReal& r = quad[j * 3 + 0]; 482*181f196bSVijay Mahadevan const PetscReal& s = quad[j * 3 + 1]; 483*181f196bSVijay Mahadevan const PetscReal& t = quad[j * 3 + 2]; 48463d025dbSVijay Mahadevan 48563d025dbSVijay Mahadevan phi[offset + 0] = ( 1.0 - r ) * ( 1.0 - s ) * ( 1.0 - t ) / 8; 48663d025dbSVijay Mahadevan phi[offset + 1] = ( 1.0 + r ) * ( 1.0 - s ) * ( 1.0 - t ) / 8; 48763d025dbSVijay Mahadevan phi[offset + 2] = ( 1.0 + r ) * ( 1.0 + s ) * ( 1.0 - t ) / 8; 48863d025dbSVijay Mahadevan phi[offset + 3] = ( 1.0 - r ) * ( 1.0 + s ) * ( 1.0 - t ) / 8; 48963d025dbSVijay Mahadevan phi[offset + 4] = ( 1.0 - r ) * ( 1.0 - s ) * ( 1.0 + t ) / 8; 49063d025dbSVijay Mahadevan phi[offset + 5] = ( 1.0 + r ) * ( 1.0 - s ) * ( 1.0 + t ) / 8; 49163d025dbSVijay Mahadevan phi[offset + 6] = ( 1.0 + r ) * ( 1.0 + s ) * ( 1.0 + t ) / 8; 49263d025dbSVijay Mahadevan phi[offset + 7] = ( 1.0 - r ) * ( 1.0 + s ) * ( 1.0 + t ) / 8; 49363d025dbSVijay Mahadevan 494*181f196bSVijay Mahadevan const PetscReal dNi_dxi[8] = { - ( 1.0 - s ) * ( 1.0 - t ), 49563d025dbSVijay Mahadevan ( 1.0 - s ) * ( 1.0 - t ), 49663d025dbSVijay Mahadevan ( 1.0 + s ) * ( 1.0 - t ), 49763d025dbSVijay Mahadevan - ( 1.0 + s ) * ( 1.0 - t ), 49863d025dbSVijay Mahadevan - ( 1.0 - s ) * ( 1.0 + t ), 49963d025dbSVijay Mahadevan ( 1.0 - s ) * ( 1.0 + t ), 50063d025dbSVijay Mahadevan ( 1.0 + s ) * ( 1.0 + t ), 50163d025dbSVijay Mahadevan - ( 1.0 + s ) * ( 1.0 + t ) 50263d025dbSVijay Mahadevan }; 50363d025dbSVijay Mahadevan 504*181f196bSVijay Mahadevan const PetscReal dNi_deta[8] = { - ( 1.0 - r ) * ( 1.0 - t ), 50563d025dbSVijay Mahadevan - ( 1.0 + r ) * ( 1.0 - t ), 50663d025dbSVijay Mahadevan ( 1.0 + r ) * ( 1.0 - t ), 50763d025dbSVijay Mahadevan ( 1.0 - r ) * ( 1.0 - t ), 50863d025dbSVijay Mahadevan - ( 1.0 - r ) * ( 1.0 + t ), 50963d025dbSVijay Mahadevan - ( 1.0 + r ) * ( 1.0 + t ), 51063d025dbSVijay Mahadevan ( 1.0 + r ) * ( 1.0 + t ), 51163d025dbSVijay Mahadevan ( 1.0 - r ) * ( 1.0 + t ) 51263d025dbSVijay Mahadevan }; 51363d025dbSVijay Mahadevan 514*181f196bSVijay Mahadevan const PetscReal dNi_dzeta[8] = { - ( 1.0 - r ) * ( 1.0 - s ), 51563d025dbSVijay Mahadevan - ( 1.0 + r ) * ( 1.0 - s ), 51663d025dbSVijay Mahadevan - ( 1.0 + r ) * ( 1.0 + s ), 51763d025dbSVijay Mahadevan - ( 1.0 - r ) * ( 1.0 + s ), 51863d025dbSVijay Mahadevan ( 1.0 - r ) * ( 1.0 - s ), 51963d025dbSVijay Mahadevan ( 1.0 + r ) * ( 1.0 - s ), 52063d025dbSVijay Mahadevan ( 1.0 + r ) * ( 1.0 + s ), 52163d025dbSVijay Mahadevan ( 1.0 - r ) * ( 1.0 + s ) 52263d025dbSVijay Mahadevan }; 52363d025dbSVijay Mahadevan 52463d025dbSVijay Mahadevan ierr = PetscMemzero(jacobian, 9 * sizeof(PetscReal));CHKERRQ(ierr); 52563d025dbSVijay Mahadevan ierr = PetscMemzero(ijacobian, 9 * sizeof(PetscReal));CHKERRQ(ierr); 52663d025dbSVijay Mahadevan for (i = 0; i < nverts; ++i) { 527*181f196bSVijay Mahadevan const PetscReal* vertex = coords + i * 3; 52863d025dbSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertex[0]; 52963d025dbSVijay Mahadevan jacobian[3] += dNi_dxi[i] * vertex[1]; 53063d025dbSVijay Mahadevan jacobian[6] += dNi_dxi[i] * vertex[2]; 53163d025dbSVijay Mahadevan jacobian[1] += dNi_deta[i] * vertex[0]; 53263d025dbSVijay Mahadevan jacobian[4] += dNi_deta[i] * vertex[1]; 53363d025dbSVijay Mahadevan jacobian[7] += dNi_deta[i] * vertex[2]; 53463d025dbSVijay Mahadevan jacobian[2] += dNi_dzeta[i] * vertex[0]; 53563d025dbSVijay Mahadevan jacobian[5] += dNi_dzeta[i] * vertex[1]; 53663d025dbSVijay Mahadevan jacobian[8] += dNi_dzeta[i] * vertex[2]; 537*181f196bSVijay Mahadevan if (phypts) { 538*181f196bSVijay Mahadevan phypts[3 * j + 0] += phi[i + offset] * vertex[0]; 539*181f196bSVijay Mahadevan phypts[3 * j + 1] += phi[i + offset] * vertex[1]; 540*181f196bSVijay Mahadevan phypts[3 * j + 2] += phi[i + offset] * vertex[2]; 541*181f196bSVijay Mahadevan } 54263d025dbSVijay Mahadevan } 54363d025dbSVijay Mahadevan 54463d025dbSVijay Mahadevan /* invert the jacobian */ 545*181f196bSVijay Mahadevan ierr = DMatrix_Invert_3x3_Internal(jacobian, ijacobian, volume);CHKERRQ(ierr); 546*181f196bSVijay Mahadevan if ( *volume < 1e-8 ) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Hexahedral element has zero volume: %g. Degenerate element or invalid connectivity\n", volume); 54763d025dbSVijay Mahadevan 548*181f196bSVijay Mahadevan const PetscReal factor = 1.0 / 8; /* Our basis is defined on [-1 to 1]^3 */ 549*181f196bSVijay Mahadevan if (jxw) jxw[j] *= factor * (*volume); 55063d025dbSVijay Mahadevan 55163d025dbSVijay Mahadevan /* Divide by element jacobian. */ 55263d025dbSVijay Mahadevan for ( i = 0; i < nverts; ++i ) { 55363d025dbSVijay Mahadevan for (int k = 0; k < 3; ++k) { 55463d025dbSVijay Mahadevan if (dphidx) dphidx[i + offset] += dNi_dxi[i] * ijacobian[0 * 3 + k]; 55563d025dbSVijay Mahadevan if (dphidy) dphidy[i + offset] += dNi_deta[i] * ijacobian[1 * 3 + k]; 55663d025dbSVijay Mahadevan if (dphidz) dphidz[i + offset] += dNi_dzeta[i] * ijacobian[2 * 3 + k]; 55763d025dbSVijay Mahadevan } 55863d025dbSVijay Mahadevan } 55963d025dbSVijay Mahadevan } 56063d025dbSVijay Mahadevan } 56163d025dbSVijay Mahadevan else if (nverts == 4) { /* Linear Tetrahedra */ 56263d025dbSVijay Mahadevan 56363d025dbSVijay Mahadevan ierr = PetscMemzero(jacobian, 9 * sizeof(PetscReal));CHKERRQ(ierr); 56463d025dbSVijay Mahadevan ierr = PetscMemzero(ijacobian, 9 * sizeof(PetscReal));CHKERRQ(ierr); 56563d025dbSVijay Mahadevan 566*181f196bSVijay Mahadevan const PetscReal x0 = coords[/*0 * 3 +*/ 0], y0 = coords[/*0 * 3 +*/ 1], z0 = coords[/*0 * 3 +*/ 2]; 567*181f196bSVijay Mahadevan 568*181f196bSVijay Mahadevan /* compute the jacobian */ 569*181f196bSVijay Mahadevan jacobian[0] = coords[1 * 3 + 0] - x0; jacobian[1] = coords[2 * 3 + 0] - x0; jacobian[2] = coords[3 * 3 + 0] - x0; 570*181f196bSVijay Mahadevan jacobian[3] = coords[1 * 3 + 1] - y0; jacobian[4] = coords[2 * 3 + 1] - y0; jacobian[5] = coords[3 * 3 + 1] - y0; 571*181f196bSVijay Mahadevan jacobian[6] = coords[1 * 3 + 2] - z0; jacobian[7] = coords[2 * 3 + 2] - z0; jacobian[8] = coords[3 * 3 + 2] - z0; 57263d025dbSVijay Mahadevan 57363d025dbSVijay Mahadevan /* invert the jacobian */ 574*181f196bSVijay Mahadevan ierr = DMatrix_Invert_3x3_Internal(jacobian, ijacobian, volume);CHKERRQ(ierr); 575*181f196bSVijay Mahadevan if ( *volume < 1e-8 ) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Tetrahedral element has zero volume: %g. Degenerate element or invalid connectivity\n", volume); 57663d025dbSVijay Mahadevan 577*181f196bSVijay Mahadevan // const PetscReal Dx[4] = { ijacobian[0], ijacobian[3], ijacobian[6], - ijacobian[0] - ijacobian[3] - ijacobian[6] }; 578*181f196bSVijay Mahadevan // const PetscReal Dy[4] = { ijacobian[1], ijacobian[4], ijacobian[7], - ijacobian[1] - ijacobian[4] - ijacobian[7] }; 579*181f196bSVijay Mahadevan // const PetscReal Dz[4] = { ijacobian[2], ijacobian[5], ijacobian[8], - ijacobian[2] - ijacobian[5] - ijacobian[8] }; 580*181f196bSVijay Mahadevan PetscReal Dx[4], Dy[4], Dz[4]; 581*181f196bSVijay Mahadevan if (dphidx) { 582*181f196bSVijay Mahadevan Dx[0] = ( coords[1 + 2 * 3] * ( coords[2 + 1 * 3] - coords[2 + 3 * 3] ) 583*181f196bSVijay Mahadevan - coords[1 + 1 * 3] * ( coords[2 + 2 * 3] - coords[2 + 3 * 3] ) 584*181f196bSVijay Mahadevan - coords[1 + 3 * 3] * ( coords[2 + 1 * 3] - coords[2 + 2 * 3] ) 585*181f196bSVijay Mahadevan ) / *volume; 586*181f196bSVijay Mahadevan Dx[1] = - ( coords[1 + 2 * 3] * ( coords[2 + 0 * 3] - coords[2 + 3 * 3] ) 587*181f196bSVijay Mahadevan - coords[1 + 0 * 3] * ( coords[2 + 2 * 3] - coords[2 + 3 * 3] ) 588*181f196bSVijay Mahadevan - coords[1 + 3 * 3] * ( coords[2 + 0 * 3] - coords[2 + 2 * 3] ) 589*181f196bSVijay Mahadevan ) / *volume; 590*181f196bSVijay Mahadevan Dx[2] = ( coords[1 + 1 * 3] * ( coords[2 + 0 * 3] - coords[2 + 3 * 3] ) 591*181f196bSVijay Mahadevan - coords[1 + 0 * 3] * ( coords[2 + 1 * 3] - coords[2 + 3 * 3] ) 592*181f196bSVijay Mahadevan - coords[1 + 3 * 3] * ( coords[2 + 0 * 3] - coords[2 + 1 * 3] ) 593*181f196bSVijay Mahadevan ) / *volume; 594*181f196bSVijay Mahadevan Dx[3] = - ( Dx[0] + Dx[1] + Dx[2] ); 595*181f196bSVijay Mahadevan Dy[0] = ( coords[0 + 1 * 3] * ( coords[2 + 2 * 3] - coords[2 + 3 * 3] ) 596*181f196bSVijay Mahadevan - coords[0 + 2 * 3] * ( coords[2 + 1 * 3] - coords[2 + 3 * 3] ) 597*181f196bSVijay Mahadevan + coords[0 + 3 * 3] * ( coords[2 + 1 * 3] - coords[2 + 2 * 3] ) 598*181f196bSVijay Mahadevan ) / *volume; 599*181f196bSVijay Mahadevan Dy[1] = - ( coords[0 + 0 * 3] * ( coords[2 + 2 * 3] - coords[2 + 3 * 3] ) 600*181f196bSVijay Mahadevan - coords[0 + 2 * 3] * ( coords[2 + 0 * 3] - coords[2 + 3 * 3] ) 601*181f196bSVijay Mahadevan + coords[0 + 3 * 3] * ( coords[2 + 0 * 3] - coords[2 + 2 * 3] ) 602*181f196bSVijay Mahadevan ) / *volume; 603*181f196bSVijay Mahadevan Dy[2] = ( coords[0 + 0 * 3] * ( coords[2 + 1 * 3] - coords[2 + 3 * 3] ) 604*181f196bSVijay Mahadevan - coords[0 + 1 * 3] * ( coords[2 + 0 * 3] - coords[2 + 3 * 3] ) 605*181f196bSVijay Mahadevan + coords[0 + 3 * 3] * ( coords[2 + 0 * 3] - coords[2 + 1 * 3] ) 606*181f196bSVijay Mahadevan ) / *volume; 607*181f196bSVijay Mahadevan Dy[3] = - ( Dy[0] + Dy[1] + Dy[2] ); 608*181f196bSVijay Mahadevan Dz[0] = ( coords[0 + 1 * 3] * (coords[1 + 3 * 3] - coords[1 + 2 * 3] ) 609*181f196bSVijay Mahadevan - coords[0 + 2 * 3] * (coords[1 + 3 * 3] - coords[1 + 1 * 3] ) 610*181f196bSVijay Mahadevan + coords[0 + 3 * 3] * (coords[1 + 2 * 3] - coords[1 + 1 * 3] ) 611*181f196bSVijay Mahadevan ) / *volume; 612*181f196bSVijay Mahadevan Dz[1] = - ( coords[0 + 0 * 3] * (coords[1 + 3 * 3] - coords[1 + 2 * 3] ) 613*181f196bSVijay Mahadevan + coords[0 + 2 * 3] * (coords[1 + 0 * 3] - coords[1 + 3 * 3] ) 614*181f196bSVijay Mahadevan - coords[0 + 3 * 3] * (coords[1 + 0 * 3] - coords[1 + 2 * 3] ) 615*181f196bSVijay Mahadevan ) / *volume; 616*181f196bSVijay Mahadevan Dz[2] = ( coords[0 + 0 * 3] * (coords[1 + 3 * 3] - coords[1 + 1 * 3] ) 617*181f196bSVijay Mahadevan + coords[0 + 1 * 3] * (coords[1 + 0 * 3] - coords[1 + 3 * 3] ) 618*181f196bSVijay Mahadevan - coords[0 + 3 * 3] * (coords[1 + 0 * 3] - coords[1 + 1 * 3] ) 619*181f196bSVijay Mahadevan ) / *volume; 620*181f196bSVijay Mahadevan Dz[3] = - ( Dz[0] + Dz[1] + Dz[2] ); 621*181f196bSVijay Mahadevan } 62263d025dbSVijay Mahadevan 62363d025dbSVijay Mahadevan for ( j = 0; j < npts; j++ ) 62463d025dbSVijay Mahadevan { 62563d025dbSVijay Mahadevan const int offset = j * nverts; 626*181f196bSVijay Mahadevan const PetscReal& r = quad[j * 3 + 0]; 627*181f196bSVijay Mahadevan const PetscReal& s = quad[j * 3 + 1]; 628*181f196bSVijay Mahadevan const PetscReal& t = quad[j * 3 + 2]; 62963d025dbSVijay Mahadevan 630*181f196bSVijay Mahadevan if (jxw) jxw[j] *= *volume; 63163d025dbSVijay Mahadevan 63263d025dbSVijay Mahadevan phi[offset + 0] = 1.0 - r - s - t; 63363d025dbSVijay Mahadevan phi[offset + 1] = r; 63463d025dbSVijay Mahadevan phi[offset + 2] = s; 63563d025dbSVijay Mahadevan phi[offset + 3] = t; 63663d025dbSVijay Mahadevan 637*181f196bSVijay Mahadevan if (phypts) { 638*181f196bSVijay Mahadevan for (i = 0; i < nverts; ++i) { 639*181f196bSVijay Mahadevan const PetscScalar* vertices = coords + i * 3; 640*181f196bSVijay Mahadevan phypts[3 * j + 0] += phi[i + offset] * vertices[0]; 641*181f196bSVijay Mahadevan phypts[3 * j + 1] += phi[i + offset] * vertices[1]; 642*181f196bSVijay Mahadevan phypts[3 * j + 2] += phi[i + offset] * vertices[2]; 643*181f196bSVijay Mahadevan } 644*181f196bSVijay Mahadevan } 645*181f196bSVijay Mahadevan 646*181f196bSVijay Mahadevan /* Now set the derivatives */ 64763d025dbSVijay Mahadevan if (dphidx) { 648*181f196bSVijay Mahadevan dphidx[0 + offset] = Dx[0]; 649*181f196bSVijay Mahadevan dphidx[1 + offset] = Dx[1]; 650*181f196bSVijay Mahadevan dphidx[2 + offset] = Dx[2]; 651*181f196bSVijay Mahadevan dphidx[3 + offset] = Dx[3]; 65263d025dbSVijay Mahadevan } 65363d025dbSVijay Mahadevan 65463d025dbSVijay Mahadevan if (dphidy) { 655*181f196bSVijay Mahadevan dphidy[0 + offset] = Dy[0]; 656*181f196bSVijay Mahadevan dphidy[1 + offset] = Dy[1]; 657*181f196bSVijay Mahadevan dphidy[2 + offset] = Dy[2]; 658*181f196bSVijay Mahadevan dphidy[3 + offset] = Dy[3]; 65963d025dbSVijay Mahadevan } 66063d025dbSVijay Mahadevan 66163d025dbSVijay Mahadevan if (dphidz) { 662*181f196bSVijay Mahadevan dphidz[0 + offset] = Dz[0]; 663*181f196bSVijay Mahadevan dphidz[1 + offset] = Dz[1]; 664*181f196bSVijay Mahadevan dphidz[2 + offset] = Dz[2]; 665*181f196bSVijay Mahadevan dphidz[3 + offset] = Dz[3]; 66663d025dbSVijay Mahadevan } 66763d025dbSVijay Mahadevan 66863d025dbSVijay Mahadevan } /* Tetrahedra -- ends */ 66963d025dbSVijay Mahadevan } 67063d025dbSVijay Mahadevan else 67163d025dbSVijay Mahadevan { 67263d025dbSVijay Mahadevan SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "The number of entity vertices are invalid. Currently only support HEX8 and TET4 basis evaluations in 3-D : %D", nverts); 67363d025dbSVijay Mahadevan } 67463d025dbSVijay Mahadevan #if 0 67563d025dbSVijay Mahadevan /* verify if the computed basis functions are consistent */ 67663d025dbSVijay Mahadevan for ( j = 0; j < npts; j++ ) { 67763d025dbSVijay Mahadevan PetscScalar phisum = 0, dphixsum = 0, dphiysum = 0, dphizsum = 0; 67863d025dbSVijay Mahadevan const int offset = j * nverts; 67963d025dbSVijay Mahadevan for ( i = 0; i < nverts; i++ ) { 68063d025dbSVijay Mahadevan phisum += phi[i + offset]; 68163d025dbSVijay Mahadevan if (dphidx) dphixsum += dphidx[i + offset]; 68263d025dbSVijay Mahadevan if (dphidy) dphiysum += dphidy[i + offset]; 68363d025dbSVijay Mahadevan if (dphidz) dphizsum += dphidz[i + offset]; 68463d025dbSVijay Mahadevan if (dphidx) PetscPrintf(PETSC_COMM_WORLD, "\t Values [%d]: [JxW] [phi, dphidx, dphidy, dphidz] = %g, %g, %g, %g, %g\n", j, jxw[j], phi[i + offset], dphidx[i + offset], dphidy[i + offset], dphidz[i + offset]); 68563d025dbSVijay Mahadevan } 68663d025dbSVijay Mahadevan if (dphidx) PetscPrintf(PETSC_COMM_WORLD, "Sum of basis at quadrature point %D (%g, %g, %g) = %g, %g, %g, %g\n", j, quad[3 * j + 0], quad[3 * j + 1], quad[3 * j + 2], phisum, dphixsum, dphiysum, dphizsum); 68763d025dbSVijay Mahadevan } 68863d025dbSVijay Mahadevan #endif 68963d025dbSVijay Mahadevan PetscFunctionReturn(0); 69063d025dbSVijay Mahadevan } 69163d025dbSVijay Mahadevan 69263d025dbSVijay Mahadevan 69363d025dbSVijay Mahadevan 69463d025dbSVijay Mahadevan /*@ 69563d025dbSVijay Mahadevan DMMoabFEMComputeBasis: Evaluate bases and derivatives at quadrature points for a linear EDGE/QUAD/TRI/HEX/TET element. 69663d025dbSVijay Mahadevan 69763d025dbSVijay Mahadevan The routine takes the coordinates of the vertices of an element and computes basis functions associated with 69863d025dbSVijay Mahadevan each quadrature point provided, and their derivatives with respect to X, Y and Z as appropriate. 69963d025dbSVijay Mahadevan 70063d025dbSVijay Mahadevan Input Parameter: 70163d025dbSVijay Mahadevan 70263d025dbSVijay Mahadevan . PetscInt nverts, the number of element vertices 70363d025dbSVijay Mahadevan . PetscReal coords[3*nverts], the physical coordinates of the vertices (in canonical numbering) 70463d025dbSVijay Mahadevan . PetscInt npts, the number of evaluation points (quadrature points) 70563d025dbSVijay Mahadevan . PetscReal quad[3*npts], the evaluation points (quadrature points) in the reference space 70663d025dbSVijay Mahadevan 70763d025dbSVijay Mahadevan Output Parameter: 70863d025dbSVijay Mahadevan . PetscReal phypts[3*npts], the evaluation points (quadrature points) transformed to the physical space 70963d025dbSVijay Mahadevan . PetscReal jxw[npts], the jacobian determinant * quadrature weight necessary for assembling discrete contributions 71063d025dbSVijay Mahadevan . PetscReal fe_basis[npts], the bases values evaluated at the specified quadrature points 71163d025dbSVijay Mahadevan . PetscReal fe_basis_derivatives[dim][npts], the derivative of the bases wrt (X,Y,Z)-directions (depending on the dimension) evaluated at the specified quadrature points 71263d025dbSVijay Mahadevan 71363d025dbSVijay Mahadevan .keywords: DMMoab, FEM, 3-D 71463d025dbSVijay Mahadevan @*/ 71563d025dbSVijay Mahadevan #undef __FUNCT__ 71663d025dbSVijay Mahadevan #define __FUNCT__ "DMMoabFEMComputeBasis" 717*181f196bSVijay Mahadevan PetscErrorCode DMMoabFEMComputeBasis ( const PetscInt dim, const PetscInt nverts, const PetscReal *coordinates, const PetscQuadrature quadrature, 718*181f196bSVijay Mahadevan PetscReal *phypts, PetscReal *jacobian_quadrature_weight_product, 719*181f196bSVijay Mahadevan PetscReal *fe_basis, PetscReal **fe_basis_derivatives) 72063d025dbSVijay Mahadevan { 72163d025dbSVijay Mahadevan PetscErrorCode ierr; 72263d025dbSVijay Mahadevan PetscInt npoints; 72363d025dbSVijay Mahadevan bool compute_der; 72463d025dbSVijay Mahadevan const PetscReal *quadpts, *quadwts; 725*181f196bSVijay Mahadevan PetscReal jacobian[9], ijacobian[9], volume; 72663d025dbSVijay Mahadevan 72763d025dbSVijay Mahadevan PetscFunctionBegin; 72863d025dbSVijay Mahadevan PetscValidPointer(coordinates, 3); 72963d025dbSVijay Mahadevan PetscValidHeaderSpecific(quadrature, PETSC_OBJECT_CLASSID, 4); 73063d025dbSVijay Mahadevan PetscValidPointer(fe_basis, 7); 73163d025dbSVijay Mahadevan compute_der = (fe_basis_derivatives != NULL); 73263d025dbSVijay Mahadevan 73363d025dbSVijay Mahadevan /* Get the quadrature points and weights for the given quadrature rule */ 73463d025dbSVijay Mahadevan ierr = PetscQuadratureGetData(quadrature, NULL, &npoints, &quadpts, &quadwts);CHKERRQ(ierr); 735*181f196bSVijay Mahadevan if (jacobian_quadrature_weight_product) { 73663d025dbSVijay Mahadevan ierr = PetscMemcpy(jacobian_quadrature_weight_product, quadwts, npoints * sizeof(PetscReal));CHKERRQ(ierr); 737*181f196bSVijay Mahadevan } 73863d025dbSVijay Mahadevan 73963d025dbSVijay Mahadevan switch (dim) { 74063d025dbSVijay Mahadevan case 1: 74163d025dbSVijay Mahadevan ierr = Compute_Lagrange_Basis_1D_Internal(nverts, coordinates, npoints, quadpts, phypts, 74263d025dbSVijay Mahadevan jacobian_quadrature_weight_product, fe_basis, 743*181f196bSVijay Mahadevan (compute_der ? fe_basis_derivatives[0] : NULL), 744*181f196bSVijay Mahadevan jacobian, ijacobian, &volume);CHKERRQ(ierr); 74563d025dbSVijay Mahadevan break; 74663d025dbSVijay Mahadevan case 2: 74763d025dbSVijay Mahadevan ierr = Compute_Lagrange_Basis_2D_Internal(nverts, coordinates, npoints, quadpts, phypts, 74863d025dbSVijay Mahadevan jacobian_quadrature_weight_product, fe_basis, 74963d025dbSVijay Mahadevan (compute_der ? fe_basis_derivatives[0] : NULL), 750*181f196bSVijay Mahadevan (compute_der ? fe_basis_derivatives[1] : NULL), 751*181f196bSVijay Mahadevan jacobian, ijacobian, &volume);CHKERRQ(ierr); 75263d025dbSVijay Mahadevan break; 75363d025dbSVijay Mahadevan case 3: 75463d025dbSVijay Mahadevan ierr = Compute_Lagrange_Basis_3D_Internal(nverts, coordinates, npoints, quadpts, phypts, 75563d025dbSVijay Mahadevan jacobian_quadrature_weight_product, fe_basis, 75663d025dbSVijay Mahadevan (compute_der ? fe_basis_derivatives[0] : NULL), 75763d025dbSVijay Mahadevan (compute_der ? fe_basis_derivatives[1] : NULL), 758*181f196bSVijay Mahadevan (compute_der ? fe_basis_derivatives[2] : NULL), 759*181f196bSVijay Mahadevan jacobian, ijacobian, &volume);CHKERRQ(ierr); 76063d025dbSVijay Mahadevan break; 76163d025dbSVijay Mahadevan default: 76263d025dbSVijay Mahadevan SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension; should be in [1,3] : %D", dim); 76363d025dbSVijay Mahadevan } 76463d025dbSVijay Mahadevan PetscFunctionReturn(0); 76563d025dbSVijay Mahadevan } 76663d025dbSVijay Mahadevan 76763d025dbSVijay Mahadevan 76863d025dbSVijay Mahadevan 76963d025dbSVijay Mahadevan /*@ 77063d025dbSVijay Mahadevan DMMoabFEMCreateQuadratureDefault: Create default quadrature rules for integration over an element with a given 77163d025dbSVijay Mahadevan dimension and polynomial order (deciphered from number of element vertices). 77263d025dbSVijay Mahadevan 77363d025dbSVijay Mahadevan Input Parameter: 77463d025dbSVijay Mahadevan 77563d025dbSVijay Mahadevan . PetscInt dim, the element dimension (1=EDGE, 2=QUAD/TRI, 3=HEX/TET) 77663d025dbSVijay Mahadevan . PetscInt nverts, the number of vertices in the physical element 77763d025dbSVijay Mahadevan 77863d025dbSVijay Mahadevan Output Parameter: 77963d025dbSVijay Mahadevan . PetscQuadrature quadrature, the quadrature object with default settings to integrate polynomials defined over the element 78063d025dbSVijay Mahadevan 78163d025dbSVijay Mahadevan .keywords: DMMoab, Quadrature, PetscDT 78263d025dbSVijay Mahadevan @*/ 78363d025dbSVijay Mahadevan #undef __FUNCT__ 78463d025dbSVijay Mahadevan #define __FUNCT__ "DMMoabFEMCreateQuadratureDefault" 785*181f196bSVijay Mahadevan PetscErrorCode DMMoabFEMCreateQuadratureDefault ( const PetscInt dim, const PetscInt nverts, PetscQuadrature *quadrature ) 78663d025dbSVijay Mahadevan { 78763d025dbSVijay Mahadevan PetscReal *w, *x; 78863d025dbSVijay Mahadevan PetscErrorCode ierr; 78963d025dbSVijay Mahadevan 79063d025dbSVijay Mahadevan PetscFunctionBegin; 79163d025dbSVijay Mahadevan /* Create an appropriate quadrature rule to sample basis */ 79263d025dbSVijay Mahadevan switch (dim) 79363d025dbSVijay Mahadevan { 79463d025dbSVijay Mahadevan case 1: 79563d025dbSVijay Mahadevan /* Create Gauss quadrature rules with <order = nverts> in the span [-1, 1] */ 796*181f196bSVijay Mahadevan ierr = PetscDTGaussJacobiQuadrature(1, nverts, 0, 1.0, quadrature);CHKERRQ(ierr); 79763d025dbSVijay Mahadevan break; 79863d025dbSVijay Mahadevan case 2: 79963d025dbSVijay Mahadevan /* Create Gauss quadrature rules with <order = nverts> in the span [-1, 1] */ 80063d025dbSVijay Mahadevan if (nverts == 3) { 80163d025dbSVijay Mahadevan const int order = 2; 80263d025dbSVijay Mahadevan const int npoints = (order == 2 ? 3 : 6); 80363d025dbSVijay Mahadevan ierr = PetscMalloc2(npoints * 2, &x, npoints, &w);CHKERRQ(ierr); 804*181f196bSVijay Mahadevan if (npoints == 3) { 80563d025dbSVijay Mahadevan x[0] = x[1] = x[2] = x[5] = 1.0 / 6.0; 80663d025dbSVijay Mahadevan x[3] = x[4] = 2.0 / 3.0; 80763d025dbSVijay Mahadevan w[0] = w[1] = w[2] = 1.0 / 3.0; 808*181f196bSVijay Mahadevan } 809*181f196bSVijay Mahadevan else if (npoints == 6) { 81063d025dbSVijay Mahadevan x[0] = x[1] = x[2] = 0.44594849091597; 81163d025dbSVijay Mahadevan x[3] = x[4] = 0.10810301816807; 81263d025dbSVijay Mahadevan x[5] = 0.44594849091597; 81363d025dbSVijay Mahadevan x[6] = x[7] = x[8] = 0.09157621350977; 81463d025dbSVijay Mahadevan x[9] = x[10] = 0.81684757298046; 81563d025dbSVijay Mahadevan x[11] = 0.09157621350977; 81663d025dbSVijay Mahadevan w[0] = w[1] = w[2] = 0.22338158967801; 817*181f196bSVijay Mahadevan w[3] = w[4] = w[5] = 0.10995174365532; 818*181f196bSVijay Mahadevan } 819*181f196bSVijay Mahadevan else { 820*181f196bSVijay Mahadevan SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Triangle quadrature rules for points 3 and 6 supported; npoints : %D", npoints); 82163d025dbSVijay Mahadevan } 82263d025dbSVijay Mahadevan ierr = PetscQuadratureCreate(PETSC_COMM_SELF, quadrature);CHKERRQ(ierr); 82363d025dbSVijay Mahadevan ierr = PetscQuadratureSetOrder(*quadrature, order);CHKERRQ(ierr); 824*181f196bSVijay Mahadevan ierr = PetscQuadratureSetData(*quadrature, dim, npoints, x, w);CHKERRQ(ierr); 825*181f196bSVijay Mahadevan /* ierr = PetscDTGaussJacobiQuadrature(dim, nverts, 0.0, 1.0, quadrature);CHKERRQ(ierr); */ 82663d025dbSVijay Mahadevan } 82763d025dbSVijay Mahadevan else { 82863d025dbSVijay Mahadevan ierr = PetscDTGaussTensorQuadrature(dim, nverts, 0.0, 1.0, quadrature);CHKERRQ(ierr); 82963d025dbSVijay Mahadevan } 83063d025dbSVijay Mahadevan break; 83163d025dbSVijay Mahadevan case 3: 83263d025dbSVijay Mahadevan /* Create Gauss quadrature rules with <order = nverts> in the span [-1, 1] */ 83363d025dbSVijay Mahadevan if (nverts == 4) { 834*181f196bSVijay Mahadevan int order; 835*181f196bSVijay Mahadevan const int npoints = 4; // Choose between 4 and 10 836*181f196bSVijay Mahadevan ierr = PetscMalloc2(npoints * 3, &x, npoints, &w);CHKERRQ(ierr); 837*181f196bSVijay Mahadevan if (npoints == 4) { /* KEAST1, K1, N=4, O=4 */ 838*181f196bSVijay Mahadevan const PetscReal x_4[12] = { 0.5854101966249685, 0.1381966011250105, 0.1381966011250105, 839*181f196bSVijay Mahadevan 0.1381966011250105, 0.1381966011250105, 0.1381966011250105, 840*181f196bSVijay Mahadevan 0.1381966011250105, 0.1381966011250105, 0.5854101966249685, 841*181f196bSVijay Mahadevan 0.1381966011250105, 0.5854101966249685, 0.1381966011250105 842*181f196bSVijay Mahadevan }; 843*181f196bSVijay Mahadevan ierr = PetscMemcpy(x, x_4, 12 * sizeof(PetscReal));CHKERRQ(ierr); 844*181f196bSVijay Mahadevan 845*181f196bSVijay Mahadevan w[0] = w[1] = w[2] = w[3] = 1.0 / 24.0; 846*181f196bSVijay Mahadevan order = 4; 847*181f196bSVijay Mahadevan } 848*181f196bSVijay Mahadevan else if (npoints == 10) { /* KEAST3, K3 N=10, O=10 */ 849*181f196bSVijay Mahadevan const PetscReal x_10[30] = { 0.5684305841968444, 0.1438564719343852, 0.1438564719343852, 850*181f196bSVijay Mahadevan 0.1438564719343852, 0.1438564719343852, 0.1438564719343852, 851*181f196bSVijay Mahadevan 0.1438564719343852, 0.1438564719343852, 0.5684305841968444, 852*181f196bSVijay Mahadevan 0.1438564719343852, 0.5684305841968444, 0.1438564719343852, 853*181f196bSVijay Mahadevan 0.0000000000000000, 0.5000000000000000, 0.5000000000000000, 854*181f196bSVijay Mahadevan 0.5000000000000000, 0.0000000000000000, 0.5000000000000000, 855*181f196bSVijay Mahadevan 0.5000000000000000, 0.5000000000000000, 0.0000000000000000, 856*181f196bSVijay Mahadevan 0.5000000000000000, 0.0000000000000000, 0.0000000000000000, 857*181f196bSVijay Mahadevan 0.0000000000000000, 0.5000000000000000, 0.0000000000000000, 858*181f196bSVijay Mahadevan 0.0000000000000000, 0.0000000000000000, 0.5000000000000000 859*181f196bSVijay Mahadevan }; 860*181f196bSVijay Mahadevan ierr = PetscMemcpy(x, x_10, 30 * sizeof(PetscReal));CHKERRQ(ierr); 861*181f196bSVijay Mahadevan 862*181f196bSVijay Mahadevan w[0] = w[1] = w[2] = w[3] = 0.2177650698804054; 863*181f196bSVijay Mahadevan w[4] = w[5] = w[6] = w[7] = w[8] = w[9] = 0.0214899534130631; 864*181f196bSVijay Mahadevan order = 10; 865*181f196bSVijay Mahadevan } 866*181f196bSVijay Mahadevan else { 867*181f196bSVijay Mahadevan SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Tetrahedral quadrature rules for points 4 and 10 supported; npoints : %D", npoints); 868*181f196bSVijay Mahadevan } 869*181f196bSVijay Mahadevan ierr = PetscQuadratureCreate(PETSC_COMM_SELF, quadrature);CHKERRQ(ierr); 870*181f196bSVijay Mahadevan ierr = PetscQuadratureSetOrder(*quadrature, order);CHKERRQ(ierr); 871*181f196bSVijay Mahadevan ierr = PetscQuadratureSetData(*quadrature, dim, npoints, x, w);CHKERRQ(ierr); 872*181f196bSVijay Mahadevan /* ierr = PetscDTGaussJacobiQuadrature(dim, nverts, 0.0, 1.0, quadrature);CHKERRQ(ierr); */ 87363d025dbSVijay Mahadevan } 87463d025dbSVijay Mahadevan else { 87563d025dbSVijay Mahadevan ierr = PetscDTGaussTensorQuadrature(dim, nverts, 0.0, 1.0, quadrature);CHKERRQ(ierr); 87663d025dbSVijay Mahadevan } 87763d025dbSVijay Mahadevan break; 87863d025dbSVijay Mahadevan default: 87963d025dbSVijay Mahadevan SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension; should be in [1,3] : %D", dim); 88063d025dbSVijay Mahadevan } 88163d025dbSVijay Mahadevan PetscFunctionReturn(0); 88263d025dbSVijay Mahadevan } 88363d025dbSVijay Mahadevan 884*181f196bSVijay Mahadevan /* Compute Jacobians */ 885*181f196bSVijay Mahadevan #undef __FUNCT__ 886*181f196bSVijay Mahadevan #define __FUNCT__ "ComputeJacobian_Internal" 887*181f196bSVijay Mahadevan PetscErrorCode ComputeJacobian_Internal ( const PetscInt dim, const PetscInt nverts, const PetscReal *coordinates, const PetscReal *quad, PetscReal *phypts, 888*181f196bSVijay Mahadevan PetscReal *jacobian, PetscReal *ijacobian, PetscReal* volume) 889*181f196bSVijay Mahadevan { 890*181f196bSVijay Mahadevan int i; 891*181f196bSVijay Mahadevan PetscErrorCode ierr; 892*181f196bSVijay Mahadevan 893*181f196bSVijay Mahadevan PetscFunctionBegin; 894*181f196bSVijay Mahadevan PetscValidPointer(coordinates, 3); 895*181f196bSVijay Mahadevan PetscValidPointer(quad, 4); 896*181f196bSVijay Mahadevan PetscValidPointer(jacobian, 5); 897*181f196bSVijay Mahadevan ierr = PetscMemzero(jacobian, dim * dim * sizeof(PetscReal));CHKERRQ(ierr); 898*181f196bSVijay Mahadevan if (ijacobian) { 899*181f196bSVijay Mahadevan ierr = PetscMemzero(ijacobian, dim * dim * sizeof(PetscReal));CHKERRQ(ierr); 900*181f196bSVijay Mahadevan } 901*181f196bSVijay Mahadevan if (phypts) { 902*181f196bSVijay Mahadevan ierr = PetscMemzero(phypts, /*npts=1 * */ 3 * sizeof(PetscReal));CHKERRQ(ierr); 903*181f196bSVijay Mahadevan } 904*181f196bSVijay Mahadevan 905*181f196bSVijay Mahadevan if (dim == 1) { 906*181f196bSVijay Mahadevan 907*181f196bSVijay Mahadevan const PetscReal& r = quad[0]; 908*181f196bSVijay Mahadevan if (nverts == 2) { /* Linear Edge */ 909*181f196bSVijay Mahadevan const PetscReal dNi_dxi[2] = { -1.0, 1.0 }; 910*181f196bSVijay Mahadevan 911*181f196bSVijay Mahadevan for (i = 0; i < nverts; ++i) { 912*181f196bSVijay Mahadevan const PetscReal* vertices = coordinates + i * 3; 913*181f196bSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertices[0]; 914*181f196bSVijay Mahadevan } 915*181f196bSVijay Mahadevan } 916*181f196bSVijay Mahadevan else if (nverts == 3) { /* Quadratic Edge */ 917*181f196bSVijay Mahadevan const PetscReal dNi_dxi[3] = { 4 * r - 3.0, 4 * ( 1.0 - 2.0 * r ), 4.0 * r - 1.0}; 918*181f196bSVijay Mahadevan 919*181f196bSVijay Mahadevan for (i = 0; i < nverts; ++i) { 920*181f196bSVijay Mahadevan const PetscReal* vertices = coordinates + i * 3; 921*181f196bSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertices[0]; 922*181f196bSVijay Mahadevan } 923*181f196bSVijay Mahadevan } 924*181f196bSVijay Mahadevan else { 925*181f196bSVijay Mahadevan SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "The number of 1-D entity vertices are invalid. Currently only support EDGE2 and EDGE3 basis evaluations in 1-D : %D", nverts); 926*181f196bSVijay Mahadevan } 927*181f196bSVijay Mahadevan 928*181f196bSVijay Mahadevan if (ijacobian) { 929*181f196bSVijay Mahadevan /* invert the jacobian */ 930*181f196bSVijay Mahadevan ijacobian[0] = 1.0 / jacobian[0]; 931*181f196bSVijay Mahadevan } 932*181f196bSVijay Mahadevan 933*181f196bSVijay Mahadevan } 934*181f196bSVijay Mahadevan else if (dim == 2) { 935*181f196bSVijay Mahadevan 936*181f196bSVijay Mahadevan if (nverts == 4) { /* Linear Quadrangle */ 937*181f196bSVijay Mahadevan const PetscReal& r = quad[0]; 938*181f196bSVijay Mahadevan const PetscReal& s = quad[1]; 939*181f196bSVijay Mahadevan 940*181f196bSVijay Mahadevan const PetscReal dNi_dxi[4] = { -1.0 + s, 1.0 - s, s, -s }; 941*181f196bSVijay Mahadevan const PetscReal dNi_deta[4] = { -1.0 + r, -r, r, 1.0 - r }; 942*181f196bSVijay Mahadevan 943*181f196bSVijay Mahadevan for (i = 0; i < nverts; ++i) { 944*181f196bSVijay Mahadevan const PetscReal* vertices = coordinates + i * 3; 945*181f196bSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertices[0]; 946*181f196bSVijay Mahadevan jacobian[2] += dNi_dxi[i] * vertices[1]; 947*181f196bSVijay Mahadevan jacobian[1] += dNi_deta[i] * vertices[0]; 948*181f196bSVijay Mahadevan jacobian[3] += dNi_deta[i] * vertices[1]; 949*181f196bSVijay Mahadevan } 950*181f196bSVijay Mahadevan } 951*181f196bSVijay Mahadevan else if (nverts == 3) { /* Linear triangle */ 952*181f196bSVijay Mahadevan const PetscReal x2 = coordinates[2 * 3 + 0], y2 = coordinates[2 * 3 + 1]; 953*181f196bSVijay Mahadevan 954*181f196bSVijay Mahadevan /* Jacobian is constant */ 955*181f196bSVijay Mahadevan jacobian[0] = (coordinates[0 * 3 + 0] - x2); jacobian[1] = (coordinates[1 * 3 + 0] - x2); 956*181f196bSVijay Mahadevan jacobian[2] = (coordinates[0 * 3 + 1] - y2); jacobian[3] = (coordinates[1 * 3 + 1] - y2); 957*181f196bSVijay Mahadevan } 958*181f196bSVijay Mahadevan else { 959*181f196bSVijay Mahadevan SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "The number of 2-D entity vertices are invalid. Currently only support QUAD4 and TRI3 basis evaluations in 2-D : %D", nverts); 960*181f196bSVijay Mahadevan } 961*181f196bSVijay Mahadevan 962*181f196bSVijay Mahadevan /* invert the jacobian */ 963*181f196bSVijay Mahadevan if (ijacobian) { 964*181f196bSVijay Mahadevan ierr = DMatrix_Invert_2x2_Internal(jacobian, ijacobian, volume);CHKERRQ(ierr); 965*181f196bSVijay Mahadevan } 966*181f196bSVijay Mahadevan 967*181f196bSVijay Mahadevan } 968*181f196bSVijay Mahadevan else { 969*181f196bSVijay Mahadevan 970*181f196bSVijay Mahadevan if (nverts == 8) { /* Linear Hexahedra */ 971*181f196bSVijay Mahadevan const PetscReal& r = quad[0]; 972*181f196bSVijay Mahadevan const PetscReal& s = quad[1]; 973*181f196bSVijay Mahadevan const PetscReal& t = quad[2]; 974*181f196bSVijay Mahadevan const PetscReal dNi_dxi[8] = { - ( 1.0 - s ) * ( 1.0 - t ), 975*181f196bSVijay Mahadevan ( 1.0 - s ) * ( 1.0 - t ), 976*181f196bSVijay Mahadevan ( 1.0 + s ) * ( 1.0 - t ), 977*181f196bSVijay Mahadevan - ( 1.0 + s ) * ( 1.0 - t ), 978*181f196bSVijay Mahadevan - ( 1.0 - s ) * ( 1.0 + t ), 979*181f196bSVijay Mahadevan ( 1.0 - s ) * ( 1.0 + t ), 980*181f196bSVijay Mahadevan ( 1.0 + s ) * ( 1.0 + t ), 981*181f196bSVijay Mahadevan - ( 1.0 + s ) * ( 1.0 + t ) 982*181f196bSVijay Mahadevan }; 983*181f196bSVijay Mahadevan 984*181f196bSVijay Mahadevan const PetscReal dNi_deta[8] = { - ( 1.0 - r ) * ( 1.0 - t ), 985*181f196bSVijay Mahadevan - ( 1.0 + r ) * ( 1.0 - t ), 986*181f196bSVijay Mahadevan ( 1.0 + r ) * ( 1.0 - t ), 987*181f196bSVijay Mahadevan ( 1.0 - r ) * ( 1.0 - t ), 988*181f196bSVijay Mahadevan - ( 1.0 - r ) * ( 1.0 + t ), 989*181f196bSVijay Mahadevan - ( 1.0 + r ) * ( 1.0 + t ), 990*181f196bSVijay Mahadevan ( 1.0 + r ) * ( 1.0 + t ), 991*181f196bSVijay Mahadevan ( 1.0 - r ) * ( 1.0 + t ) 992*181f196bSVijay Mahadevan }; 993*181f196bSVijay Mahadevan 994*181f196bSVijay Mahadevan const PetscReal dNi_dzeta[8] = { - ( 1.0 - r ) * ( 1.0 - s ), 995*181f196bSVijay Mahadevan - ( 1.0 + r ) * ( 1.0 - s ), 996*181f196bSVijay Mahadevan - ( 1.0 + r ) * ( 1.0 + s ), 997*181f196bSVijay Mahadevan - ( 1.0 - r ) * ( 1.0 + s ), 998*181f196bSVijay Mahadevan ( 1.0 - r ) * ( 1.0 - s ), 999*181f196bSVijay Mahadevan ( 1.0 + r ) * ( 1.0 - s ), 1000*181f196bSVijay Mahadevan ( 1.0 + r ) * ( 1.0 + s ), 1001*181f196bSVijay Mahadevan ( 1.0 - r ) * ( 1.0 + s ) 1002*181f196bSVijay Mahadevan }; 1003*181f196bSVijay Mahadevan for (i = 0; i < nverts; ++i) { 1004*181f196bSVijay Mahadevan const PetscReal* vertex = coordinates + i * 3; 1005*181f196bSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertex[0]; 1006*181f196bSVijay Mahadevan jacobian[3] += dNi_dxi[i] * vertex[1]; 1007*181f196bSVijay Mahadevan jacobian[6] += dNi_dxi[i] * vertex[2]; 1008*181f196bSVijay Mahadevan jacobian[1] += dNi_deta[i] * vertex[0]; 1009*181f196bSVijay Mahadevan jacobian[4] += dNi_deta[i] * vertex[1]; 1010*181f196bSVijay Mahadevan jacobian[7] += dNi_deta[i] * vertex[2]; 1011*181f196bSVijay Mahadevan jacobian[2] += dNi_dzeta[i] * vertex[0]; 1012*181f196bSVijay Mahadevan jacobian[5] += dNi_dzeta[i] * vertex[1]; 1013*181f196bSVijay Mahadevan jacobian[8] += dNi_dzeta[i] * vertex[2]; 1014*181f196bSVijay Mahadevan } 1015*181f196bSVijay Mahadevan 1016*181f196bSVijay Mahadevan } 1017*181f196bSVijay Mahadevan else if (nverts == 4) { /* Linear Tetrahedra */ 1018*181f196bSVijay Mahadevan const PetscReal x0 = coordinates[/*0 * 3 +*/ 0], y0 = coordinates[/*0 * 3 +*/ 1], z0 = coordinates[/*0 * 3 +*/ 2]; 1019*181f196bSVijay Mahadevan 1020*181f196bSVijay Mahadevan /* compute the jacobian */ 1021*181f196bSVijay Mahadevan jacobian[0] = coordinates[1 * 3 + 0] - x0; jacobian[1] = coordinates[2 * 3 + 0] - x0; jacobian[2] = coordinates[3 * 3 + 0] - x0; 1022*181f196bSVijay Mahadevan jacobian[3] = coordinates[1 * 3 + 1] - y0; jacobian[4] = coordinates[2 * 3 + 1] - y0; jacobian[5] = coordinates[3 * 3 + 1] - y0; 1023*181f196bSVijay Mahadevan jacobian[6] = coordinates[1 * 3 + 2] - z0; jacobian[7] = coordinates[2 * 3 + 2] - z0; jacobian[8] = coordinates[3 * 3 + 2] - z0; 1024*181f196bSVijay Mahadevan } /* Tetrahedra -- ends */ 1025*181f196bSVijay Mahadevan else 1026*181f196bSVijay Mahadevan { 1027*181f196bSVijay Mahadevan SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "The number of 3-D entity vertices are invalid. Currently only support HEX8 and TET4 basis evaluations in 3-D : %D", nverts); 1028*181f196bSVijay Mahadevan } 1029*181f196bSVijay Mahadevan 1030*181f196bSVijay Mahadevan if (ijacobian) { 1031*181f196bSVijay Mahadevan /* invert the jacobian */ 1032*181f196bSVijay Mahadevan ierr = DMatrix_Invert_3x3_Internal(jacobian, ijacobian, volume);CHKERRQ(ierr); 1033*181f196bSVijay Mahadevan } 1034*181f196bSVijay Mahadevan 1035*181f196bSVijay Mahadevan } 1036*181f196bSVijay Mahadevan if ( volume && *volume < 1e-12 ) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Element has zero volume: %g. Degenerate element or invalid connectivity\n", volume); 1037*181f196bSVijay Mahadevan PetscFunctionReturn(0); 1038*181f196bSVijay Mahadevan } 1039*181f196bSVijay Mahadevan 1040*181f196bSVijay Mahadevan 1041*181f196bSVijay Mahadevan #undef __FUNCT__ 1042*181f196bSVijay Mahadevan #define __FUNCT__ "FEMComputeBasis_JandF" 1043*181f196bSVijay Mahadevan PetscErrorCode FEMComputeBasis_JandF ( const PetscInt dim, const PetscInt nverts, const PetscReal *coordinates, const PetscReal *quadrature, PetscReal *phypts, 1044*181f196bSVijay Mahadevan PetscReal *phibasis, PetscReal *jacobian, PetscReal *ijacobian, PetscReal* volume ) 1045*181f196bSVijay Mahadevan { 1046*181f196bSVijay Mahadevan PetscErrorCode ierr; 1047*181f196bSVijay Mahadevan 1048*181f196bSVijay Mahadevan PetscFunctionBegin; 1049*181f196bSVijay Mahadevan 1050*181f196bSVijay Mahadevan switch (dim) { 1051*181f196bSVijay Mahadevan case 1: 1052*181f196bSVijay Mahadevan ierr = Compute_Lagrange_Basis_1D_Internal(nverts, coordinates, 1, quadrature, phypts, 1053*181f196bSVijay Mahadevan NULL, phibasis, NULL, jacobian, ijacobian, volume);CHKERRQ(ierr); 1054*181f196bSVijay Mahadevan break; 1055*181f196bSVijay Mahadevan case 2: 1056*181f196bSVijay Mahadevan ierr = Compute_Lagrange_Basis_2D_Internal(nverts, coordinates, 1, quadrature, phypts, 1057*181f196bSVijay Mahadevan NULL, phibasis, NULL, NULL, jacobian, ijacobian, volume);CHKERRQ(ierr); 1058*181f196bSVijay Mahadevan break; 1059*181f196bSVijay Mahadevan case 3: 1060*181f196bSVijay Mahadevan ierr = Compute_Lagrange_Basis_3D_Internal(nverts, coordinates, 1, quadrature, phypts, 1061*181f196bSVijay Mahadevan NULL, phibasis, NULL, NULL, NULL, jacobian, ijacobian, volume);CHKERRQ(ierr); 1062*181f196bSVijay Mahadevan break; 1063*181f196bSVijay Mahadevan default: 1064*181f196bSVijay Mahadevan SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension; should be in [1,3] : %D", dim); 1065*181f196bSVijay Mahadevan } 1066*181f196bSVijay Mahadevan PetscFunctionReturn(0); 1067*181f196bSVijay Mahadevan } 1068*181f196bSVijay Mahadevan 1069*181f196bSVijay Mahadevan 1070*181f196bSVijay Mahadevan 1071*181f196bSVijay Mahadevan #undef __FUNCT__ 1072*181f196bSVijay Mahadevan #define __FUNCT__ "DMMoabPToRMapping" 1073*181f196bSVijay Mahadevan PetscErrorCode DMMoabPToRMapping( const PetscInt dim, const PetscInt nverts, const PetscReal *coordinates, const PetscReal* xphy, PetscReal* natparam, PetscReal* phi) 1074*181f196bSVijay Mahadevan { 1075*181f196bSVijay Mahadevan // Perform inverse evaluation for the mapping with use of Newton Raphson iteration 1076*181f196bSVijay Mahadevan const PetscReal tol = 1.0e-10; 1077*181f196bSVijay Mahadevan const PetscInt max_iterations = 10; 1078*181f196bSVijay Mahadevan const PetscReal error_tol_sqr = tol*tol; 1079*181f196bSVijay Mahadevan PetscReal phibasis[8], jacobian[9], ijacobian[9], volume; 1080*181f196bSVijay Mahadevan PetscReal phypts[3] = {0.0, 0.0, 0.0}; 1081*181f196bSVijay Mahadevan PetscReal delta[3] = {0.0, 0.0, 0.0}; 1082*181f196bSVijay Mahadevan PetscErrorCode ierr; 1083*181f196bSVijay Mahadevan PetscInt iters=0; 1084*181f196bSVijay Mahadevan PetscReal error=1.0; 1085*181f196bSVijay Mahadevan 1086*181f196bSVijay Mahadevan PetscFunctionBegin; 1087*181f196bSVijay Mahadevan PetscValidPointer(coordinates, 3); 1088*181f196bSVijay Mahadevan PetscValidPointer(xphy, 4); 1089*181f196bSVijay Mahadevan PetscValidPointer(natparam, 5); 1090*181f196bSVijay Mahadevan 1091*181f196bSVijay Mahadevan ierr = PetscMemzero(natparam, 3 * sizeof(PetscReal));CHKERRQ(ierr); 1092*181f196bSVijay Mahadevan ierr = PetscMemzero(jacobian, dim * dim * sizeof(PetscReal));CHKERRQ(ierr); 1093*181f196bSVijay Mahadevan ierr = PetscMemzero(ijacobian, dim * dim * sizeof(PetscReal));CHKERRQ(ierr); 1094*181f196bSVijay Mahadevan ierr = PetscMemzero(phibasis, nverts * sizeof(PetscReal));CHKERRQ(ierr); 1095*181f196bSVijay Mahadevan 1096*181f196bSVijay Mahadevan /* Compute delta = evaluate( xi ) - x */ 1097*181f196bSVijay Mahadevan ierr = FEMComputeBasis_JandF ( dim, nverts, coordinates, natparam, phypts, phi, jacobian, ijacobian, &volume );CHKERRQ(ierr); 1098*181f196bSVijay Mahadevan 1099*181f196bSVijay Mahadevan delta[0] = phypts[0] - xphy[0]; 1100*181f196bSVijay Mahadevan delta[1] = phypts[1] - xphy[1]; 1101*181f196bSVijay Mahadevan delta[2] = phypts[2] - xphy[2]; 1102*181f196bSVijay Mahadevan error = (delta[0]*delta[0] + delta[1]*delta[1] + delta[2]*delta[2]); 1103*181f196bSVijay Mahadevan 1104*181f196bSVijay Mahadevan while (error > error_tol_sqr) { 1105*181f196bSVijay Mahadevan 1106*181f196bSVijay Mahadevan if(++iters > max_iterations) 1107*181f196bSVijay Mahadevan SETERRQ3(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Maximum Newton iterations (10) reached. Current point in reference space : (%g, %g, %g)", natparam[0], natparam[1], natparam[2]); 1108*181f196bSVijay Mahadevan 1109*181f196bSVijay Mahadevan /* Compute natparam -= J.inverse() * delta */ 1110*181f196bSVijay Mahadevan switch(dim) { 1111*181f196bSVijay Mahadevan case 1: 1112*181f196bSVijay Mahadevan natparam[0] -= ijacobian[0] * delta[0]; 1113*181f196bSVijay Mahadevan break; 1114*181f196bSVijay Mahadevan case 2: 1115*181f196bSVijay Mahadevan natparam[0] -= ijacobian[0] * delta[0] + ijacobian[1] * delta[1]; 1116*181f196bSVijay Mahadevan natparam[1] -= ijacobian[2] * delta[0] + ijacobian[3] * delta[1]; 1117*181f196bSVijay Mahadevan break; 1118*181f196bSVijay Mahadevan case 3: 1119*181f196bSVijay Mahadevan natparam[0] -= ijacobian[0] * delta[0] + ijacobian[1] * delta[1] + ijacobian[2] * delta[2]; 1120*181f196bSVijay Mahadevan natparam[1] -= ijacobian[3] * delta[0] + ijacobian[4] * delta[1] + ijacobian[5] * delta[2]; 1121*181f196bSVijay Mahadevan natparam[2] -= ijacobian[6] * delta[0] + ijacobian[7] * delta[1] + ijacobian[8] * delta[2]; 1122*181f196bSVijay Mahadevan break; 1123*181f196bSVijay Mahadevan } 1124*181f196bSVijay Mahadevan 1125*181f196bSVijay Mahadevan /* Compute delta = evaluate( xi ) - x */ 1126*181f196bSVijay Mahadevan ierr = FEMComputeBasis_JandF ( dim, nverts, coordinates, natparam, phypts, phi, jacobian, ijacobian, &volume );CHKERRQ(ierr); 1127*181f196bSVijay Mahadevan 1128*181f196bSVijay Mahadevan delta[0] = phypts[0] - xphy[0]; 1129*181f196bSVijay Mahadevan delta[1] = phypts[1] - xphy[1]; 1130*181f196bSVijay Mahadevan delta[2] = phypts[2] - xphy[2]; 1131*181f196bSVijay Mahadevan error = (delta[0]*delta[0] + delta[1]*delta[1] + delta[2]*delta[2]); 1132*181f196bSVijay Mahadevan } 1133*181f196bSVijay Mahadevan if (phi) { 1134*181f196bSVijay Mahadevan ierr = PetscMemcpy(phi, phibasis, nverts * sizeof(PetscReal));CHKERRQ(ierr); 1135*181f196bSVijay Mahadevan } 1136*181f196bSVijay Mahadevan PetscFunctionReturn(0); 1137*181f196bSVijay Mahadevan } 1138*181f196bSVijay Mahadevan 1139