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 12181f196bSVijay Mahadevan #undef __FUNCT__ 13181f196bSVijay 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 28181f196bSVijay 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 35181f196bSVijay Mahadevan #undef __FUNCT__ 36181f196bSVijay 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."); 40181f196bSVijay 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 56181f196bSVijay Mahadevan inline PetscReal DMatrix_Determinant_4x4_Internal ( PetscReal inmat[4 * 4] ) 57181f196bSVijay Mahadevan { 58181f196bSVijay Mahadevan return 59181f196bSVijay Mahadevan inmat[0 + 0 * 4] * ( 60181f196bSVijay Mahadevan inmat[1 + 1 * 4] * ( inmat[2 + 2 * 4] * inmat[3 + 3 * 4] - inmat[2 + 3 * 4] * inmat[3 + 2 * 4] ) 61181f196bSVijay Mahadevan - inmat[1 + 2 * 4] * ( inmat[2 + 1 * 4] * inmat[3 + 3 * 4] - inmat[2 + 3 * 4] * inmat[3 + 1 * 4] ) 62181f196bSVijay Mahadevan + inmat[1 + 3 * 4] * ( inmat[2 + 1 * 4] * inmat[3 + 2 * 4] - inmat[2 + 2 * 4] * inmat[3 + 1 * 4] ) ) 63181f196bSVijay Mahadevan - inmat[0 + 1 * 4] * ( 64181f196bSVijay Mahadevan inmat[1 + 0 * 4] * ( inmat[2 + 2 * 4] * inmat[3 + 3 * 4] - inmat[2 + 3 * 4] * inmat[3 + 2 * 4] ) 65181f196bSVijay Mahadevan - inmat[1 + 2 * 4] * ( inmat[2 + 0 * 4] * inmat[3 + 3 * 4] - inmat[2 + 3 * 4] * inmat[3 + 0 * 4] ) 66181f196bSVijay Mahadevan + inmat[1 + 3 * 4] * ( inmat[2 + 0 * 4] * inmat[3 + 2 * 4] - inmat[2 + 2 * 4] * inmat[3 + 0 * 4] ) ) 67181f196bSVijay Mahadevan + inmat[0 + 2 * 4] * ( 68181f196bSVijay Mahadevan inmat[1 + 0 * 4] * ( inmat[2 + 1 * 4] * inmat[3 + 3 * 4] - inmat[2 + 3 * 4] * inmat[3 + 1 * 4] ) 69181f196bSVijay Mahadevan - inmat[1 + 1 * 4] * ( inmat[2 + 0 * 4] * inmat[3 + 3 * 4] - inmat[2 + 3 * 4] * inmat[3 + 0 * 4] ) 70181f196bSVijay Mahadevan + inmat[1 + 3 * 4] * ( inmat[2 + 0 * 4] * inmat[3 + 1 * 4] - inmat[2 + 1 * 4] * inmat[3 + 0 * 4] ) ) 71181f196bSVijay Mahadevan - inmat[0 + 3 * 4] * ( 72181f196bSVijay Mahadevan inmat[1 + 0 * 4] * ( inmat[2 + 1 * 4] * inmat[3 + 2 * 4] - inmat[2 + 2 * 4] * inmat[3 + 1 * 4] ) 73181f196bSVijay Mahadevan - inmat[1 + 1 * 4] * ( inmat[2 + 0 * 4] * inmat[3 + 2 * 4] - inmat[2 + 2 * 4] * inmat[3 + 0 * 4] ) 74181f196bSVijay Mahadevan + inmat[1 + 2 * 4] * ( inmat[2 + 0 * 4] * inmat[3 + 1 * 4] - inmat[2 + 1 * 4] * inmat[3 + 0 * 4] ) ); 75181f196bSVijay Mahadevan } 76181f196bSVijay Mahadevan 77181f196bSVijay Mahadevan #undef __FUNCT__ 78181f196bSVijay Mahadevan #define __FUNCT__ "DMatrix_Invert_4x4_Internal" 79181f196bSVijay Mahadevan inline PetscErrorCode DMatrix_Invert_4x4_Internal (PetscReal *inmat, PetscReal *outmat, PetscScalar *determinant) 80181f196bSVijay Mahadevan { 81181f196bSVijay Mahadevan if (!inmat) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_POINTER, "Invalid input matrix specified for 4x4 inversion."); 82181f196bSVijay Mahadevan PetscReal det = DMatrix_Determinant_4x4_Internal(inmat); 83181f196bSVijay Mahadevan if (outmat) { 84181f196bSVijay 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; 85181f196bSVijay 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; 86181f196bSVijay 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; 87181f196bSVijay 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; 88181f196bSVijay 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; 89181f196bSVijay 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; 90181f196bSVijay 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; 91181f196bSVijay 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; 92181f196bSVijay 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; 93181f196bSVijay 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; 94181f196bSVijay 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; 95181f196bSVijay 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; 96181f196bSVijay 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; 97181f196bSVijay 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; 98181f196bSVijay 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; 99181f196bSVijay 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; 100181f196bSVijay Mahadevan } 101181f196bSVijay Mahadevan if (determinant) *determinant = det; 102181f196bSVijay Mahadevan PetscFunctionReturn(0); 103181f196bSVijay Mahadevan } 104181f196bSVijay 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, 139181f196bSVijay Mahadevan PetscReal *jxw, PetscReal *phi, PetscReal *dphidx, 140181f196bSVijay Mahadevan PetscReal *jacobian, PetscReal *ijacobian, PetscReal *volume) 14163d025dbSVijay Mahadevan { 14263d025dbSVijay Mahadevan int i, j; 14363d025dbSVijay Mahadevan PetscErrorCode ierr; 14463d025dbSVijay Mahadevan 145181f196bSVijay Mahadevan PetscFunctionBegin; 146181f196bSVijay Mahadevan PetscValidPointer(jacobian, 9); 147181f196bSVijay Mahadevan PetscValidPointer(ijacobian, 10); 148181f196bSVijay Mahadevan PetscValidPointer(volume, 11); 149181f196bSVijay Mahadevan if (phypts) { 15063d025dbSVijay Mahadevan ierr = PetscMemzero(phypts, npts * 3 * sizeof(PetscReal));CHKERRQ(ierr); 151181f196bSVijay 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 { 159a86ed394SVijay Mahadevan const PetscInt offset = j * nverts; 160181f196bSVijay Mahadevan const PetscReal r = quad[j]; 16163d025dbSVijay Mahadevan 162181f196bSVijay Mahadevan phi[0 + offset] = ( 1.0 - r ); 163181f196bSVijay Mahadevan phi[1 + offset] = ( r ); 16463d025dbSVijay Mahadevan 165181f196bSVijay Mahadevan const PetscReal dNi_dxi[2] = { -1.0, 1.0 }; 16663d025dbSVijay Mahadevan 167181f196bSVijay Mahadevan jacobian[0] = ijacobian[0] = volume[0] = 0.0; 16863d025dbSVijay Mahadevan for (i = 0; i < nverts; ++i) { 169181f196bSVijay Mahadevan const PetscReal* vertices = coords + i * 3; 170181f196bSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertices[0]; 171181f196bSVijay Mahadevan if (phypts) { 172181f196bSVijay Mahadevan phypts[3 * j + 0] += phi[i + offset] * vertices[0]; 173181f196bSVijay Mahadevan } 17463d025dbSVijay Mahadevan } 17563d025dbSVijay Mahadevan 17663d025dbSVijay Mahadevan /* invert the jacobian */ 177181f196bSVijay Mahadevan *volume = jacobian[0]; 178181f196bSVijay Mahadevan ijacobian[0] = 1.0 / jacobian[0]; 179181f196bSVijay Mahadevan jxw[j] *= *volume; 18063d025dbSVijay Mahadevan 18163d025dbSVijay Mahadevan /* Divide by element jacobian. */ 18263d025dbSVijay Mahadevan for ( i = 0; i < nverts; i++ ) { 183181f196bSVijay 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 { 192a86ed394SVijay Mahadevan const PetscInt offset = j * nverts; 193181f196bSVijay Mahadevan const PetscReal r = quad[j]; 19463d025dbSVijay Mahadevan 195181f196bSVijay Mahadevan phi[0 + offset] = 1.0 + r * ( 2.0 * r - 3.0 ); 196181f196bSVijay Mahadevan phi[1 + offset] = 4.0 * r * ( 1.0 - r ); 197181f196bSVijay Mahadevan phi[2 + offset] = r * ( 2.0 * r - 1.0 ); 19863d025dbSVijay Mahadevan 199181f196bSVijay Mahadevan const PetscReal dNi_dxi[3] = { 4 * r - 3.0, 4 * ( 1.0 - 2.0 * r ), 4.0 * r - 1.0}; 20063d025dbSVijay Mahadevan 201181f196bSVijay Mahadevan jacobian[0] = ijacobian[0] = volume[0] = 0.0; 20263d025dbSVijay Mahadevan for (i = 0; i < nverts; ++i) { 203181f196bSVijay Mahadevan const PetscReal* vertices = coords + i * 3; 204181f196bSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertices[0]; 205181f196bSVijay Mahadevan if (phypts) { 206181f196bSVijay Mahadevan phypts[3 * j + 0] += phi[i + offset] * vertices[0]; 207181f196bSVijay Mahadevan } 20863d025dbSVijay Mahadevan } 20963d025dbSVijay Mahadevan 21063d025dbSVijay Mahadevan /* invert the jacobian */ 211181f196bSVijay Mahadevan *volume = jacobian[0]; 212181f196bSVijay Mahadevan ijacobian[0] = 1.0 / jacobian[0]; 213181f196bSVijay Mahadevan if (jxw) jxw[j] *= *volume; 21463d025dbSVijay Mahadevan 21563d025dbSVijay Mahadevan /* Divide by element jacobian. */ 21663d025dbSVijay Mahadevan for ( i = 0; i < nverts; i++ ) { 217181f196bSVijay 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, 276181f196bSVijay Mahadevan PetscReal *jxw, PetscReal *phi, PetscReal *dphidx, PetscReal *dphidy, 277181f196bSVijay Mahadevan PetscReal *jacobian, PetscReal *ijacobian, PetscReal *volume) 27863d025dbSVijay Mahadevan { 279a86ed394SVijay Mahadevan PetscInt i, j, k; 28063d025dbSVijay Mahadevan PetscErrorCode ierr; 28163d025dbSVijay Mahadevan 28263d025dbSVijay Mahadevan PetscFunctionBegin; 283181f196bSVijay Mahadevan PetscValidPointer(jacobian, 10); 284181f196bSVijay Mahadevan PetscValidPointer(ijacobian, 11); 285181f196bSVijay Mahadevan PetscValidPointer(volume, 12); 28663d025dbSVijay Mahadevan ierr = PetscMemzero(phi, npts * sizeof(PetscReal));CHKERRQ(ierr); 287181f196bSVijay Mahadevan if (phypts) { 28863d025dbSVijay Mahadevan ierr = PetscMemzero(phypts, npts * 3 * sizeof(PetscReal));CHKERRQ(ierr); 289181f196bSVijay 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 { 298a86ed394SVijay Mahadevan const PetscInt offset = j * nverts; 299181f196bSVijay Mahadevan const PetscReal r = quad[0 + j * 2]; 300181f196bSVijay 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 307181f196bSVijay Mahadevan const PetscReal dNi_dxi[4] = { -1.0 + s, 1.0 - s, s, -s }; 308181f196bSVijay 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) { 313181f196bSVijay 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]; 318181f196bSVijay Mahadevan if (phypts) { 319181f196bSVijay Mahadevan phypts[3 * j + 0] += phi[i + offset] * vertices[0]; 320181f196bSVijay Mahadevan phypts[3 * j + 1] += phi[i + offset] * vertices[1]; 321181f196bSVijay Mahadevan phypts[3 * j + 2] += phi[i + offset] * vertices[2]; 322181f196bSVijay Mahadevan } 32363d025dbSVijay Mahadevan } 32463d025dbSVijay Mahadevan 32563d025dbSVijay Mahadevan /* invert the jacobian */ 326181f196bSVijay Mahadevan ierr = DMatrix_Invert_2x2_Internal(jacobian, ijacobian, volume);CHKERRQ(ierr); 327181f196bSVijay 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 329181f196bSVijay Mahadevan if (jxw) jxw[j] *= *volume; 33063d025dbSVijay Mahadevan 331181f196bSVijay Mahadevan /* Let us compute the bases derivatives by scaling with inverse jacobian. */ 332181f196bSVijay Mahadevan if (dphidx) { 33363d025dbSVijay Mahadevan for ( i = 0; i < nverts; i++ ) { 334a86ed394SVijay Mahadevan for ( 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]; 337181f196bSVijay Mahadevan } /* for k=[0..2) */ 338181f196bSVijay Mahadevan } /* for i=[0..nverts) */ 339181f196bSVijay 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 347181f196bSVijay Mahadevan const PetscReal x2 = coords[2 * 3 + 0], y2 = coords[2 * 3 + 1]; 348181f196bSVijay Mahadevan 34963d025dbSVijay Mahadevan /* Jacobian is constant */ 350181f196bSVijay Mahadevan jacobian[0] = (coords[0 * 3 + 0] - x2); jacobian[1] = (coords[1 * 3 + 0] - x2); 351181f196bSVijay Mahadevan jacobian[2] = (coords[0 * 3 + 1] - y2); jacobian[3] = (coords[1 * 3 + 1] - y2); 35263d025dbSVijay Mahadevan 35363d025dbSVijay Mahadevan /* invert the jacobian */ 354181f196bSVijay Mahadevan ierr = DMatrix_Invert_2x2_Internal(jacobian, ijacobian, volume);CHKERRQ(ierr); 355181f196bSVijay 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); 356181f196bSVijay Mahadevan 357181f196bSVijay Mahadevan const PetscReal Dx[3] = { ijacobian[0], ijacobian[2], - ijacobian[0] - ijacobian[2] }; 358181f196bSVijay 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 { 362a86ed394SVijay Mahadevan const PetscInt offset = j * nverts; 363181f196bSVijay Mahadevan const PetscReal r = quad[0 + j * 2]; 364181f196bSVijay Mahadevan const PetscReal s = quad[1 + j * 2]; 36563d025dbSVijay Mahadevan 366181f196bSVijay Mahadevan if (jxw) jxw[j] *= 0.5; 36763d025dbSVijay Mahadevan 368181f196bSVijay Mahadevan /* const PetscReal Ni[3] = { r, s, 1.0 - r - s }; */ 369181f196bSVijay Mahadevan const PetscReal phipts_x = coords[2 * 3 + 0] + jacobian[0] * r + jacobian[1] * s; 370181f196bSVijay Mahadevan const PetscReal phipts_y = coords[2 * 3 + 1] + jacobian[2] * r + jacobian[3] * s; 371181f196bSVijay Mahadevan if (phypts) { 372181f196bSVijay Mahadevan phypts[offset + 0] = phipts_x; 373181f196bSVijay Mahadevan phypts[offset + 1] = phipts_y; 374181f196bSVijay Mahadevan } 37563d025dbSVijay Mahadevan 376181f196bSVijay Mahadevan /* \phi_0 = (b.y − c.y) x + (b.x − c.x) y + c.x b.y − b.x c.y */ 377181f196bSVijay Mahadevan phi[0 + offset] = ( ijacobian[0] * (phipts_x - x2) + ijacobian[1] * (phipts_y - y2) ); 378181f196bSVijay Mahadevan /* \phi_1 = (c.y − a.y) x + (a.x − c.x) y + c.x a.y − a.x c.y */ 379181f196bSVijay 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) { 383181f196bSVijay Mahadevan dphidx[0 + offset] = Dx[0]; 384181f196bSVijay Mahadevan dphidx[1 + offset] = Dx[1]; 385181f196bSVijay Mahadevan dphidx[2 + offset] = Dx[2]; 38663d025dbSVijay Mahadevan } 38763d025dbSVijay Mahadevan 38863d025dbSVijay Mahadevan if (dphidy) { 389181f196bSVijay Mahadevan dphidy[0 + offset] = Dy[0]; 390181f196bSVijay Mahadevan dphidy[1 + offset] = Dy[1]; 391181f196bSVijay 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, 455181f196bSVijay Mahadevan PetscReal *jxw, PetscReal *phi, PetscReal *dphidx, PetscReal *dphidy, PetscReal *dphidz, 456181f196bSVijay Mahadevan PetscReal *jacobian, PetscReal *ijacobian, PetscReal *volume) 45763d025dbSVijay Mahadevan { 458a86ed394SVijay Mahadevan PetscInt i, j, k; 45963d025dbSVijay Mahadevan PetscErrorCode ierr; 46063d025dbSVijay Mahadevan 46163d025dbSVijay Mahadevan PetscFunctionBegin; 462181f196bSVijay Mahadevan PetscValidPointer(jacobian, 11); 463181f196bSVijay Mahadevan PetscValidPointer(ijacobian, 12); 464181f196bSVijay Mahadevan PetscValidPointer(volume, 13); 46563d025dbSVijay Mahadevan /* Reset arrays. */ 46663d025dbSVijay Mahadevan ierr = PetscMemzero(phi, npts * sizeof(PetscReal));CHKERRQ(ierr); 467181f196bSVijay Mahadevan if (phypts) { 46863d025dbSVijay Mahadevan ierr = PetscMemzero(phypts, npts * 3 * sizeof(PetscReal));CHKERRQ(ierr); 469181f196bSVijay 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 { 480a86ed394SVijay Mahadevan const PetscInt offset = j * nverts; 481181f196bSVijay Mahadevan const PetscReal& r = quad[j * 3 + 0]; 482181f196bSVijay Mahadevan const PetscReal& s = quad[j * 3 + 1]; 483181f196bSVijay Mahadevan const PetscReal& t = quad[j * 3 + 2]; 48463d025dbSVijay Mahadevan 485a86ed394SVijay Mahadevan phi[offset + 0] = ( 1.0 - r ) * ( 1.0 - s ) * ( 1.0 - t ); /* 0,0,0 */ 486a86ed394SVijay Mahadevan phi[offset + 1] = ( r ) * ( 1.0 - s ) * ( 1.0 - t ); /* 1,0,0 */ 487a86ed394SVijay Mahadevan phi[offset + 2] = ( r ) * ( s ) * ( 1.0 - t ); /* 1,1,0 */ 488a86ed394SVijay Mahadevan phi[offset + 3] = ( 1.0 - r ) * ( s ) * ( 1.0 - t ); /* 0,1,0 */ 489a86ed394SVijay Mahadevan phi[offset + 4] = ( 1.0 - r ) * ( 1.0 - s ) * ( t ); /* 0,0,1 */ 490a86ed394SVijay Mahadevan phi[offset + 5] = ( r ) * ( 1.0 - s ) * ( t ); /* 1,0,1 */ 491a86ed394SVijay Mahadevan phi[offset + 6] = ( r ) * ( s ) * ( t ); /* 1,1,1 */ 492a86ed394SVijay Mahadevan phi[offset + 7] = ( 1.0 - r ) * ( s ) * ( t ); /* 0,1,1 */ 49363d025dbSVijay Mahadevan 494181f196bSVijay Mahadevan const PetscReal dNi_dxi[8] = {- ( 1.0 - s ) * ( 1.0 - t ), 49563d025dbSVijay Mahadevan ( 1.0 - s ) * ( 1.0 - t ), 496a86ed394SVijay Mahadevan ( s ) * ( 1.0 - t ), 497a86ed394SVijay Mahadevan - ( s ) * ( 1.0 - t ), 498a86ed394SVijay Mahadevan - ( 1.0 - s ) * ( t ), 499a86ed394SVijay Mahadevan ( 1.0 - s ) * ( t ), 500a86ed394SVijay Mahadevan ( s ) * ( t ), 501a86ed394SVijay Mahadevan - ( s ) * ( t ) 50263d025dbSVijay Mahadevan }; 50363d025dbSVijay Mahadevan 504181f196bSVijay Mahadevan const PetscReal dNi_deta[8] = { - ( 1.0 - r ) * ( 1.0 - t ), 505a86ed394SVijay Mahadevan - ( r ) * ( 1.0 - t ), 506a86ed394SVijay Mahadevan ( r ) * ( 1.0 - t ), 50763d025dbSVijay Mahadevan ( 1.0 - r ) * ( 1.0 - t ), 508a86ed394SVijay Mahadevan - ( 1.0 - r ) * ( t ), 509a86ed394SVijay Mahadevan - ( r ) * ( t ), 510a86ed394SVijay Mahadevan ( r ) * ( t ), 511a86ed394SVijay Mahadevan ( 1.0 - r ) * ( t ) 51263d025dbSVijay Mahadevan }; 51363d025dbSVijay Mahadevan 514181f196bSVijay Mahadevan const PetscReal dNi_dzeta[8] = { - ( 1.0 - r ) * ( 1.0 - s ), 515a86ed394SVijay Mahadevan - ( r ) * ( 1.0 - s ), 516a86ed394SVijay Mahadevan - ( r ) * ( s ), 517a86ed394SVijay Mahadevan - ( 1.0 - r ) * ( s ), 51863d025dbSVijay Mahadevan ( 1.0 - r ) * ( 1.0 - s ), 519a86ed394SVijay Mahadevan ( r ) * ( 1.0 - s ), 520a86ed394SVijay Mahadevan ( r ) * ( s ), 521a86ed394SVijay Mahadevan ( 1.0 - r ) * ( 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) { 527181f196bSVijay 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]; 537181f196bSVijay Mahadevan if (phypts) { 538181f196bSVijay Mahadevan phypts[3 * j + 0] += phi[i + offset] * vertex[0]; 539181f196bSVijay Mahadevan phypts[3 * j + 1] += phi[i + offset] * vertex[1]; 540181f196bSVijay Mahadevan phypts[3 * j + 2] += phi[i + offset] * vertex[2]; 541181f196bSVijay Mahadevan } 54263d025dbSVijay Mahadevan } 54363d025dbSVijay Mahadevan 54463d025dbSVijay Mahadevan /* invert the jacobian */ 545181f196bSVijay Mahadevan ierr = DMatrix_Invert_3x3_Internal(jacobian, ijacobian, volume);CHKERRQ(ierr); 546a86ed394SVijay 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 548a86ed394SVijay Mahadevan if (jxw) jxw[j] *= (*volume); 54963d025dbSVijay Mahadevan 55063d025dbSVijay Mahadevan /* Divide by element jacobian. */ 55163d025dbSVijay Mahadevan for ( i = 0; i < nverts; ++i ) { 552a86ed394SVijay Mahadevan for ( k = 0; k < 3; ++k) { 55363d025dbSVijay Mahadevan if (dphidx) dphidx[i + offset] += dNi_dxi[i] * ijacobian[0 * 3 + k]; 55463d025dbSVijay Mahadevan if (dphidy) dphidy[i + offset] += dNi_deta[i] * ijacobian[1 * 3 + k]; 55563d025dbSVijay Mahadevan if (dphidz) dphidz[i + offset] += dNi_dzeta[i] * ijacobian[2 * 3 + k]; 55663d025dbSVijay Mahadevan } 55763d025dbSVijay Mahadevan } 55863d025dbSVijay Mahadevan } 55963d025dbSVijay Mahadevan } 56063d025dbSVijay Mahadevan else if (nverts == 4) { /* Linear Tetrahedra */ 56163d025dbSVijay Mahadevan 56263d025dbSVijay Mahadevan ierr = PetscMemzero(jacobian, 9 * sizeof(PetscReal));CHKERRQ(ierr); 56363d025dbSVijay Mahadevan ierr = PetscMemzero(ijacobian, 9 * sizeof(PetscReal));CHKERRQ(ierr); 56463d025dbSVijay Mahadevan 565181f196bSVijay Mahadevan const PetscReal x0 = coords[/*0 * 3 +*/ 0], y0 = coords[/*0 * 3 +*/ 1], z0 = coords[/*0 * 3 +*/ 2]; 566181f196bSVijay Mahadevan 567181f196bSVijay Mahadevan /* compute the jacobian */ 568181f196bSVijay Mahadevan jacobian[0] = coords[1 * 3 + 0] - x0; jacobian[1] = coords[2 * 3 + 0] - x0; jacobian[2] = coords[3 * 3 + 0] - x0; 569181f196bSVijay Mahadevan jacobian[3] = coords[1 * 3 + 1] - y0; jacobian[4] = coords[2 * 3 + 1] - y0; jacobian[5] = coords[3 * 3 + 1] - y0; 570181f196bSVijay Mahadevan jacobian[6] = coords[1 * 3 + 2] - z0; jacobian[7] = coords[2 * 3 + 2] - z0; jacobian[8] = coords[3 * 3 + 2] - z0; 57163d025dbSVijay Mahadevan 57263d025dbSVijay Mahadevan /* invert the jacobian */ 573181f196bSVijay Mahadevan ierr = DMatrix_Invert_3x3_Internal(jacobian, ijacobian, volume);CHKERRQ(ierr); 574a86ed394SVijay 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); 57563d025dbSVijay Mahadevan 5766ea892caSVijay Mahadevan PetscReal Dx[4]={0,0,0,0}, Dy[4]={0,0,0,0}, Dz[4]={0,0,0,0}; 577181f196bSVijay Mahadevan if (dphidx) { 578181f196bSVijay Mahadevan Dx[0] = ( coords[1 + 2 * 3] * ( coords[2 + 1 * 3] - coords[2 + 3 * 3] ) 579181f196bSVijay Mahadevan - coords[1 + 1 * 3] * ( coords[2 + 2 * 3] - coords[2 + 3 * 3] ) 580181f196bSVijay Mahadevan - coords[1 + 3 * 3] * ( coords[2 + 1 * 3] - coords[2 + 2 * 3] ) 581181f196bSVijay Mahadevan ) / *volume; 582181f196bSVijay Mahadevan Dx[1] = - ( coords[1 + 2 * 3] * ( coords[2 + 0 * 3] - coords[2 + 3 * 3] ) 583181f196bSVijay Mahadevan - coords[1 + 0 * 3] * ( coords[2 + 2 * 3] - coords[2 + 3 * 3] ) 584181f196bSVijay Mahadevan - coords[1 + 3 * 3] * ( coords[2 + 0 * 3] - coords[2 + 2 * 3] ) 585181f196bSVijay Mahadevan ) / *volume; 586181f196bSVijay Mahadevan Dx[2] = ( coords[1 + 1 * 3] * ( coords[2 + 0 * 3] - coords[2 + 3 * 3] ) 587181f196bSVijay Mahadevan - coords[1 + 0 * 3] * ( coords[2 + 1 * 3] - coords[2 + 3 * 3] ) 588181f196bSVijay Mahadevan - coords[1 + 3 * 3] * ( coords[2 + 0 * 3] - coords[2 + 1 * 3] ) 589181f196bSVijay Mahadevan ) / *volume; 590181f196bSVijay Mahadevan Dx[3] = - ( Dx[0] + Dx[1] + Dx[2] ); 591181f196bSVijay Mahadevan Dy[0] = ( coords[0 + 1 * 3] * ( coords[2 + 2 * 3] - coords[2 + 3 * 3] ) 592181f196bSVijay Mahadevan - coords[0 + 2 * 3] * ( coords[2 + 1 * 3] - coords[2 + 3 * 3] ) 593181f196bSVijay Mahadevan + coords[0 + 3 * 3] * ( coords[2 + 1 * 3] - coords[2 + 2 * 3] ) 594181f196bSVijay Mahadevan ) / *volume; 595181f196bSVijay Mahadevan Dy[1] = - ( coords[0 + 0 * 3] * ( coords[2 + 2 * 3] - coords[2 + 3 * 3] ) 596181f196bSVijay Mahadevan - coords[0 + 2 * 3] * ( coords[2 + 0 * 3] - coords[2 + 3 * 3] ) 597181f196bSVijay Mahadevan + coords[0 + 3 * 3] * ( coords[2 + 0 * 3] - coords[2 + 2 * 3] ) 598181f196bSVijay Mahadevan ) / *volume; 599181f196bSVijay Mahadevan Dy[2] = ( coords[0 + 0 * 3] * ( coords[2 + 1 * 3] - coords[2 + 3 * 3] ) 600181f196bSVijay Mahadevan - coords[0 + 1 * 3] * ( coords[2 + 0 * 3] - coords[2 + 3 * 3] ) 601181f196bSVijay Mahadevan + coords[0 + 3 * 3] * ( coords[2 + 0 * 3] - coords[2 + 1 * 3] ) 602181f196bSVijay Mahadevan ) / *volume; 603181f196bSVijay Mahadevan Dy[3] = - ( Dy[0] + Dy[1] + Dy[2] ); 604181f196bSVijay Mahadevan Dz[0] = ( coords[0 + 1 * 3] * (coords[1 + 3 * 3] - coords[1 + 2 * 3] ) 605181f196bSVijay Mahadevan - coords[0 + 2 * 3] * (coords[1 + 3 * 3] - coords[1 + 1 * 3] ) 606181f196bSVijay Mahadevan + coords[0 + 3 * 3] * (coords[1 + 2 * 3] - coords[1 + 1 * 3] ) 607181f196bSVijay Mahadevan ) / *volume; 608181f196bSVijay Mahadevan Dz[1] = - ( coords[0 + 0 * 3] * (coords[1 + 3 * 3] - coords[1 + 2 * 3] ) 609181f196bSVijay Mahadevan + coords[0 + 2 * 3] * (coords[1 + 0 * 3] - coords[1 + 3 * 3] ) 610181f196bSVijay Mahadevan - coords[0 + 3 * 3] * (coords[1 + 0 * 3] - coords[1 + 2 * 3] ) 611181f196bSVijay Mahadevan ) / *volume; 612181f196bSVijay Mahadevan Dz[2] = ( coords[0 + 0 * 3] * (coords[1 + 3 * 3] - coords[1 + 1 * 3] ) 613181f196bSVijay Mahadevan + coords[0 + 1 * 3] * (coords[1 + 0 * 3] - coords[1 + 3 * 3] ) 614181f196bSVijay Mahadevan - coords[0 + 3 * 3] * (coords[1 + 0 * 3] - coords[1 + 1 * 3] ) 615181f196bSVijay Mahadevan ) / *volume; 616181f196bSVijay Mahadevan Dz[3] = - ( Dz[0] + Dz[1] + Dz[2] ); 617181f196bSVijay Mahadevan } 61863d025dbSVijay Mahadevan 61963d025dbSVijay Mahadevan for ( j = 0; j < npts; j++ ) 62063d025dbSVijay Mahadevan { 621a86ed394SVijay Mahadevan const PetscInt offset = j * nverts; 622181f196bSVijay Mahadevan const PetscReal& r = quad[j * 3 + 0]; 623181f196bSVijay Mahadevan const PetscReal& s = quad[j * 3 + 1]; 624181f196bSVijay Mahadevan const PetscReal& t = quad[j * 3 + 2]; 62563d025dbSVijay Mahadevan 626181f196bSVijay Mahadevan if (jxw) jxw[j] *= *volume; 62763d025dbSVijay Mahadevan 62863d025dbSVijay Mahadevan phi[offset + 0] = 1.0 - r - s - t; 62963d025dbSVijay Mahadevan phi[offset + 1] = r; 63063d025dbSVijay Mahadevan phi[offset + 2] = s; 63163d025dbSVijay Mahadevan phi[offset + 3] = t; 63263d025dbSVijay Mahadevan 633181f196bSVijay Mahadevan if (phypts) { 634181f196bSVijay Mahadevan for (i = 0; i < nverts; ++i) { 635181f196bSVijay Mahadevan const PetscScalar* vertices = coords + i * 3; 636181f196bSVijay Mahadevan phypts[3 * j + 0] += phi[i + offset] * vertices[0]; 637181f196bSVijay Mahadevan phypts[3 * j + 1] += phi[i + offset] * vertices[1]; 638181f196bSVijay Mahadevan phypts[3 * j + 2] += phi[i + offset] * vertices[2]; 639181f196bSVijay Mahadevan } 640181f196bSVijay Mahadevan } 641181f196bSVijay Mahadevan 642181f196bSVijay Mahadevan /* Now set the derivatives */ 64363d025dbSVijay Mahadevan if (dphidx) { 644181f196bSVijay Mahadevan dphidx[0 + offset] = Dx[0]; 645181f196bSVijay Mahadevan dphidx[1 + offset] = Dx[1]; 646181f196bSVijay Mahadevan dphidx[2 + offset] = Dx[2]; 647181f196bSVijay Mahadevan dphidx[3 + offset] = Dx[3]; 64863d025dbSVijay Mahadevan 649181f196bSVijay Mahadevan dphidy[0 + offset] = Dy[0]; 650181f196bSVijay Mahadevan dphidy[1 + offset] = Dy[1]; 651181f196bSVijay Mahadevan dphidy[2 + offset] = Dy[2]; 652181f196bSVijay Mahadevan dphidy[3 + offset] = Dy[3]; 65363d025dbSVijay Mahadevan 654181f196bSVijay Mahadevan dphidz[0 + offset] = Dz[0]; 655181f196bSVijay Mahadevan dphidz[1 + offset] = Dz[1]; 656181f196bSVijay Mahadevan dphidz[2 + offset] = Dz[2]; 657181f196bSVijay Mahadevan dphidz[3 + offset] = Dz[3]; 65863d025dbSVijay Mahadevan } 65963d025dbSVijay Mahadevan 66063d025dbSVijay Mahadevan } /* Tetrahedra -- ends */ 66163d025dbSVijay Mahadevan } 66263d025dbSVijay Mahadevan else 66363d025dbSVijay Mahadevan { 66463d025dbSVijay 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); 66563d025dbSVijay Mahadevan } 66663d025dbSVijay Mahadevan #if 0 66763d025dbSVijay Mahadevan /* verify if the computed basis functions are consistent */ 66863d025dbSVijay Mahadevan for ( j = 0; j < npts; j++ ) { 66963d025dbSVijay Mahadevan PetscScalar phisum = 0, dphixsum = 0, dphiysum = 0, dphizsum = 0; 67063d025dbSVijay Mahadevan const int offset = j * nverts; 67163d025dbSVijay Mahadevan for ( i = 0; i < nverts; i++ ) { 67263d025dbSVijay Mahadevan phisum += phi[i + offset]; 67363d025dbSVijay Mahadevan if (dphidx) dphixsum += dphidx[i + offset]; 67463d025dbSVijay Mahadevan if (dphidy) dphiysum += dphidy[i + offset]; 67563d025dbSVijay Mahadevan if (dphidz) dphizsum += dphidz[i + offset]; 67663d025dbSVijay 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]); 67763d025dbSVijay Mahadevan } 67863d025dbSVijay 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); 67963d025dbSVijay Mahadevan } 68063d025dbSVijay Mahadevan #endif 68163d025dbSVijay Mahadevan PetscFunctionReturn(0); 68263d025dbSVijay Mahadevan } 68363d025dbSVijay Mahadevan 68463d025dbSVijay Mahadevan 68563d025dbSVijay Mahadevan 68663d025dbSVijay Mahadevan /*@ 68763d025dbSVijay Mahadevan DMMoabFEMComputeBasis: Evaluate bases and derivatives at quadrature points for a linear EDGE/QUAD/TRI/HEX/TET element. 68863d025dbSVijay Mahadevan 68963d025dbSVijay Mahadevan The routine takes the coordinates of the vertices of an element and computes basis functions associated with 69063d025dbSVijay Mahadevan each quadrature point provided, and their derivatives with respect to X, Y and Z as appropriate. 69163d025dbSVijay Mahadevan 69263d025dbSVijay Mahadevan Input Parameter: 69363d025dbSVijay Mahadevan 69463d025dbSVijay Mahadevan . PetscInt nverts, the number of element vertices 69563d025dbSVijay Mahadevan . PetscReal coords[3*nverts], the physical coordinates of the vertices (in canonical numbering) 69663d025dbSVijay Mahadevan . PetscInt npts, the number of evaluation points (quadrature points) 69763d025dbSVijay Mahadevan . PetscReal quad[3*npts], the evaluation points (quadrature points) in the reference space 69863d025dbSVijay Mahadevan 69963d025dbSVijay Mahadevan Output Parameter: 70063d025dbSVijay Mahadevan . PetscReal phypts[3*npts], the evaluation points (quadrature points) transformed to the physical space 70163d025dbSVijay Mahadevan . PetscReal jxw[npts], the jacobian determinant * quadrature weight necessary for assembling discrete contributions 70263d025dbSVijay Mahadevan . PetscReal fe_basis[npts], the bases values evaluated at the specified quadrature points 70363d025dbSVijay 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 70463d025dbSVijay Mahadevan 70563d025dbSVijay Mahadevan .keywords: DMMoab, FEM, 3-D 70663d025dbSVijay Mahadevan @*/ 70763d025dbSVijay Mahadevan #undef __FUNCT__ 70863d025dbSVijay Mahadevan #define __FUNCT__ "DMMoabFEMComputeBasis" 709181f196bSVijay Mahadevan PetscErrorCode DMMoabFEMComputeBasis ( const PetscInt dim, const PetscInt nverts, const PetscReal *coordinates, const PetscQuadrature quadrature, 710181f196bSVijay Mahadevan PetscReal *phypts, PetscReal *jacobian_quadrature_weight_product, 711181f196bSVijay Mahadevan PetscReal *fe_basis, PetscReal **fe_basis_derivatives) 71263d025dbSVijay Mahadevan { 71363d025dbSVijay Mahadevan PetscErrorCode ierr; 714*b21a1e88SVijay Mahadevan PetscInt npoints,idim; 71563d025dbSVijay Mahadevan bool compute_der; 71663d025dbSVijay Mahadevan const PetscReal *quadpts, *quadwts; 717181f196bSVijay Mahadevan PetscReal jacobian[9], ijacobian[9], volume; 71863d025dbSVijay Mahadevan 71963d025dbSVijay Mahadevan PetscFunctionBegin; 72063d025dbSVijay Mahadevan PetscValidPointer(coordinates, 3); 72163d025dbSVijay Mahadevan PetscValidHeaderSpecific(quadrature, PETSC_OBJECT_CLASSID, 4); 72263d025dbSVijay Mahadevan PetscValidPointer(fe_basis, 7); 72363d025dbSVijay Mahadevan compute_der = (fe_basis_derivatives != NULL); 72463d025dbSVijay Mahadevan 72563d025dbSVijay Mahadevan /* Get the quadrature points and weights for the given quadrature rule */ 726*b21a1e88SVijay Mahadevan ierr = PetscQuadratureGetData(quadrature, &idim, NULL, &npoints, &quadpts, &quadwts);CHKERRQ(ierr); 727*b21a1e88SVijay Mahadevan if (idim != dim) SETERRQ2(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Dimension mismatch: provided (%D) vs quadrature (%D)\n",idim,dim); 728181f196bSVijay Mahadevan if (jacobian_quadrature_weight_product) { 72963d025dbSVijay Mahadevan ierr = PetscMemcpy(jacobian_quadrature_weight_product, quadwts, npoints * sizeof(PetscReal));CHKERRQ(ierr); 730181f196bSVijay Mahadevan } 73163d025dbSVijay Mahadevan 73263d025dbSVijay Mahadevan switch (dim) { 73363d025dbSVijay Mahadevan case 1: 73463d025dbSVijay Mahadevan ierr = Compute_Lagrange_Basis_1D_Internal(nverts, coordinates, npoints, quadpts, phypts, 73563d025dbSVijay Mahadevan jacobian_quadrature_weight_product, fe_basis, 736181f196bSVijay Mahadevan (compute_der ? fe_basis_derivatives[0] : NULL), 737181f196bSVijay Mahadevan jacobian, ijacobian, &volume);CHKERRQ(ierr); 73863d025dbSVijay Mahadevan break; 73963d025dbSVijay Mahadevan case 2: 74063d025dbSVijay Mahadevan ierr = Compute_Lagrange_Basis_2D_Internal(nverts, coordinates, npoints, quadpts, phypts, 74163d025dbSVijay Mahadevan jacobian_quadrature_weight_product, fe_basis, 74263d025dbSVijay Mahadevan (compute_der ? fe_basis_derivatives[0] : NULL), 743181f196bSVijay Mahadevan (compute_der ? fe_basis_derivatives[1] : NULL), 744181f196bSVijay Mahadevan jacobian, ijacobian, &volume);CHKERRQ(ierr); 74563d025dbSVijay Mahadevan break; 74663d025dbSVijay Mahadevan case 3: 74763d025dbSVijay Mahadevan ierr = Compute_Lagrange_Basis_3D_Internal(nverts, coordinates, npoints, quadpts, phypts, 74863d025dbSVijay Mahadevan jacobian_quadrature_weight_product, fe_basis, 74963d025dbSVijay Mahadevan (compute_der ? fe_basis_derivatives[0] : NULL), 75063d025dbSVijay Mahadevan (compute_der ? fe_basis_derivatives[1] : NULL), 751181f196bSVijay Mahadevan (compute_der ? fe_basis_derivatives[2] : NULL), 752181f196bSVijay Mahadevan jacobian, ijacobian, &volume);CHKERRQ(ierr); 75363d025dbSVijay Mahadevan break; 75463d025dbSVijay Mahadevan default: 75563d025dbSVijay Mahadevan SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension; should be in [1,3] : %D", dim); 75663d025dbSVijay Mahadevan } 75763d025dbSVijay Mahadevan PetscFunctionReturn(0); 75863d025dbSVijay Mahadevan } 75963d025dbSVijay Mahadevan 76063d025dbSVijay Mahadevan 76163d025dbSVijay Mahadevan 76263d025dbSVijay Mahadevan /*@ 76363d025dbSVijay Mahadevan DMMoabFEMCreateQuadratureDefault: Create default quadrature rules for integration over an element with a given 76463d025dbSVijay Mahadevan dimension and polynomial order (deciphered from number of element vertices). 76563d025dbSVijay Mahadevan 76663d025dbSVijay Mahadevan Input Parameter: 76763d025dbSVijay Mahadevan 76863d025dbSVijay Mahadevan . PetscInt dim, the element dimension (1=EDGE, 2=QUAD/TRI, 3=HEX/TET) 76963d025dbSVijay Mahadevan . PetscInt nverts, the number of vertices in the physical element 77063d025dbSVijay Mahadevan 77163d025dbSVijay Mahadevan Output Parameter: 77263d025dbSVijay Mahadevan . PetscQuadrature quadrature, the quadrature object with default settings to integrate polynomials defined over the element 77363d025dbSVijay Mahadevan 77463d025dbSVijay Mahadevan .keywords: DMMoab, Quadrature, PetscDT 77563d025dbSVijay Mahadevan @*/ 77663d025dbSVijay Mahadevan #undef __FUNCT__ 77763d025dbSVijay Mahadevan #define __FUNCT__ "DMMoabFEMCreateQuadratureDefault" 778181f196bSVijay Mahadevan PetscErrorCode DMMoabFEMCreateQuadratureDefault ( const PetscInt dim, const PetscInt nverts, PetscQuadrature *quadrature ) 77963d025dbSVijay Mahadevan { 78063d025dbSVijay Mahadevan PetscReal *w, *x; 781*b21a1e88SVijay Mahadevan PetscInt nc=1; 78263d025dbSVijay Mahadevan PetscErrorCode ierr; 78363d025dbSVijay Mahadevan 78463d025dbSVijay Mahadevan PetscFunctionBegin; 78563d025dbSVijay Mahadevan /* Create an appropriate quadrature rule to sample basis */ 78663d025dbSVijay Mahadevan switch (dim) 78763d025dbSVijay Mahadevan { 78863d025dbSVijay Mahadevan case 1: 78963d025dbSVijay Mahadevan /* Create Gauss quadrature rules with <order = nverts> in the span [-1, 1] */ 790*b21a1e88SVijay Mahadevan ierr = PetscDTGaussJacobiQuadrature(1, nc, nverts, 0, 1.0, quadrature);CHKERRQ(ierr); 79163d025dbSVijay Mahadevan break; 79263d025dbSVijay Mahadevan case 2: 79363d025dbSVijay Mahadevan /* Create Gauss quadrature rules with <order = nverts> in the span [-1, 1] */ 79463d025dbSVijay Mahadevan if (nverts == 3) { 795a86ed394SVijay Mahadevan const PetscInt order = 2; 796a86ed394SVijay Mahadevan const PetscInt npoints = (order == 2 ? 3 : 6); 79763d025dbSVijay Mahadevan ierr = PetscMalloc2(npoints * 2, &x, npoints, &w);CHKERRQ(ierr); 798181f196bSVijay Mahadevan if (npoints == 3) { 79963d025dbSVijay Mahadevan x[0] = x[1] = x[2] = x[5] = 1.0 / 6.0; 80063d025dbSVijay Mahadevan x[3] = x[4] = 2.0 / 3.0; 80163d025dbSVijay Mahadevan w[0] = w[1] = w[2] = 1.0 / 3.0; 802181f196bSVijay Mahadevan } 803181f196bSVijay Mahadevan else if (npoints == 6) { 80463d025dbSVijay Mahadevan x[0] = x[1] = x[2] = 0.44594849091597; 80563d025dbSVijay Mahadevan x[3] = x[4] = 0.10810301816807; 80663d025dbSVijay Mahadevan x[5] = 0.44594849091597; 80763d025dbSVijay Mahadevan x[6] = x[7] = x[8] = 0.09157621350977; 80863d025dbSVijay Mahadevan x[9] = x[10] = 0.81684757298046; 80963d025dbSVijay Mahadevan x[11] = 0.09157621350977; 81063d025dbSVijay Mahadevan w[0] = w[1] = w[2] = 0.22338158967801; 811181f196bSVijay Mahadevan w[3] = w[4] = w[5] = 0.10995174365532; 812181f196bSVijay Mahadevan } 813181f196bSVijay Mahadevan else { 814181f196bSVijay Mahadevan SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Triangle quadrature rules for points 3 and 6 supported; npoints : %D", npoints); 81563d025dbSVijay Mahadevan } 81663d025dbSVijay Mahadevan ierr = PetscQuadratureCreate(PETSC_COMM_SELF, quadrature);CHKERRQ(ierr); 81763d025dbSVijay Mahadevan ierr = PetscQuadratureSetOrder(*quadrature, order);CHKERRQ(ierr); 818*b21a1e88SVijay Mahadevan ierr = PetscQuadratureSetData(*quadrature, dim, nc, npoints, x, w);CHKERRQ(ierr); 819181f196bSVijay Mahadevan /* ierr = PetscDTGaussJacobiQuadrature(dim, nverts, 0.0, 1.0, quadrature);CHKERRQ(ierr); */ 82063d025dbSVijay Mahadevan } 82163d025dbSVijay Mahadevan else { 822*b21a1e88SVijay Mahadevan ierr = PetscDTGaussTensorQuadrature(dim, nc, nverts, 0.0, 1.0, quadrature);CHKERRQ(ierr); 82363d025dbSVijay Mahadevan } 82463d025dbSVijay Mahadevan break; 82563d025dbSVijay Mahadevan case 3: 82663d025dbSVijay Mahadevan /* Create Gauss quadrature rules with <order = nverts> in the span [-1, 1] */ 82763d025dbSVijay Mahadevan if (nverts == 4) { 828a86ed394SVijay Mahadevan PetscInt order; 829a86ed394SVijay Mahadevan const PetscInt npoints = 4; // Choose between 4 and 10 830181f196bSVijay Mahadevan ierr = PetscMalloc2(npoints * 3, &x, npoints, &w);CHKERRQ(ierr); 831181f196bSVijay Mahadevan if (npoints == 4) { /* KEAST1, K1, N=4, O=4 */ 832181f196bSVijay Mahadevan const PetscReal x_4[12] = { 0.5854101966249685, 0.1381966011250105, 0.1381966011250105, 833181f196bSVijay Mahadevan 0.1381966011250105, 0.1381966011250105, 0.1381966011250105, 834181f196bSVijay Mahadevan 0.1381966011250105, 0.1381966011250105, 0.5854101966249685, 835181f196bSVijay Mahadevan 0.1381966011250105, 0.5854101966249685, 0.1381966011250105 836181f196bSVijay Mahadevan }; 837181f196bSVijay Mahadevan ierr = PetscMemcpy(x, x_4, 12 * sizeof(PetscReal));CHKERRQ(ierr); 838181f196bSVijay Mahadevan 839181f196bSVijay Mahadevan w[0] = w[1] = w[2] = w[3] = 1.0 / 24.0; 840181f196bSVijay Mahadevan order = 4; 841181f196bSVijay Mahadevan } 842181f196bSVijay Mahadevan else if (npoints == 10) { /* KEAST3, K3 N=10, O=10 */ 843181f196bSVijay Mahadevan const PetscReal x_10[30] = { 0.5684305841968444, 0.1438564719343852, 0.1438564719343852, 844181f196bSVijay Mahadevan 0.1438564719343852, 0.1438564719343852, 0.1438564719343852, 845181f196bSVijay Mahadevan 0.1438564719343852, 0.1438564719343852, 0.5684305841968444, 846181f196bSVijay Mahadevan 0.1438564719343852, 0.5684305841968444, 0.1438564719343852, 847181f196bSVijay Mahadevan 0.0000000000000000, 0.5000000000000000, 0.5000000000000000, 848181f196bSVijay Mahadevan 0.5000000000000000, 0.0000000000000000, 0.5000000000000000, 849181f196bSVijay Mahadevan 0.5000000000000000, 0.5000000000000000, 0.0000000000000000, 850181f196bSVijay Mahadevan 0.5000000000000000, 0.0000000000000000, 0.0000000000000000, 851181f196bSVijay Mahadevan 0.0000000000000000, 0.5000000000000000, 0.0000000000000000, 852181f196bSVijay Mahadevan 0.0000000000000000, 0.0000000000000000, 0.5000000000000000 853181f196bSVijay Mahadevan }; 854181f196bSVijay Mahadevan ierr = PetscMemcpy(x, x_10, 30 * sizeof(PetscReal));CHKERRQ(ierr); 855181f196bSVijay Mahadevan 856181f196bSVijay Mahadevan w[0] = w[1] = w[2] = w[3] = 0.2177650698804054; 857181f196bSVijay Mahadevan w[4] = w[5] = w[6] = w[7] = w[8] = w[9] = 0.0214899534130631; 858181f196bSVijay Mahadevan order = 10; 859181f196bSVijay Mahadevan } 860181f196bSVijay Mahadevan else { 861181f196bSVijay Mahadevan SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Tetrahedral quadrature rules for points 4 and 10 supported; npoints : %D", npoints); 862181f196bSVijay Mahadevan } 863181f196bSVijay Mahadevan ierr = PetscQuadratureCreate(PETSC_COMM_SELF, quadrature);CHKERRQ(ierr); 864181f196bSVijay Mahadevan ierr = PetscQuadratureSetOrder(*quadrature, order);CHKERRQ(ierr); 865*b21a1e88SVijay Mahadevan ierr = PetscQuadratureSetData(*quadrature, dim, nc, npoints, x, w);CHKERRQ(ierr); 866181f196bSVijay Mahadevan /* ierr = PetscDTGaussJacobiQuadrature(dim, nverts, 0.0, 1.0, quadrature);CHKERRQ(ierr); */ 86763d025dbSVijay Mahadevan } 86863d025dbSVijay Mahadevan else { 869*b21a1e88SVijay Mahadevan ierr = PetscDTGaussTensorQuadrature(dim, nc, nverts, 0.0, 1.0, quadrature);CHKERRQ(ierr); 87063d025dbSVijay Mahadevan } 87163d025dbSVijay Mahadevan break; 87263d025dbSVijay Mahadevan default: 87363d025dbSVijay Mahadevan SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension; should be in [1,3] : %D", dim); 87463d025dbSVijay Mahadevan } 87563d025dbSVijay Mahadevan PetscFunctionReturn(0); 87663d025dbSVijay Mahadevan } 87763d025dbSVijay Mahadevan 878181f196bSVijay Mahadevan /* Compute Jacobians */ 879181f196bSVijay Mahadevan #undef __FUNCT__ 880181f196bSVijay Mahadevan #define __FUNCT__ "ComputeJacobian_Internal" 881181f196bSVijay Mahadevan PetscErrorCode ComputeJacobian_Internal ( const PetscInt dim, const PetscInt nverts, const PetscReal *coordinates, const PetscReal *quad, PetscReal *phypts, 882a86ed394SVijay Mahadevan PetscReal *jacobian, PetscReal *ijacobian, PetscReal* dvolume) 883181f196bSVijay Mahadevan { 884a86ed394SVijay Mahadevan PetscInt i; 8852417220eSVijay Mahadevan PetscReal volume=1.0; 886181f196bSVijay Mahadevan PetscErrorCode ierr; 887181f196bSVijay Mahadevan 888181f196bSVijay Mahadevan PetscFunctionBegin; 889181f196bSVijay Mahadevan PetscValidPointer(coordinates, 3); 890181f196bSVijay Mahadevan PetscValidPointer(quad, 4); 891181f196bSVijay Mahadevan PetscValidPointer(jacobian, 5); 892181f196bSVijay Mahadevan ierr = PetscMemzero(jacobian, dim * dim * sizeof(PetscReal));CHKERRQ(ierr); 893181f196bSVijay Mahadevan if (ijacobian) { 894181f196bSVijay Mahadevan ierr = PetscMemzero(ijacobian, dim * dim * sizeof(PetscReal));CHKERRQ(ierr); 895181f196bSVijay Mahadevan } 896181f196bSVijay Mahadevan if (phypts) { 897181f196bSVijay Mahadevan ierr = PetscMemzero(phypts, /*npts=1 * */ 3 * sizeof(PetscReal));CHKERRQ(ierr); 898181f196bSVijay Mahadevan } 899181f196bSVijay Mahadevan 900181f196bSVijay Mahadevan if (dim == 1) { 901181f196bSVijay Mahadevan 902181f196bSVijay Mahadevan const PetscReal& r = quad[0]; 903181f196bSVijay Mahadevan if (nverts == 2) { /* Linear Edge */ 904181f196bSVijay Mahadevan const PetscReal dNi_dxi[2] = { -1.0, 1.0 }; 905181f196bSVijay Mahadevan 906181f196bSVijay Mahadevan for (i = 0; i < nverts; ++i) { 907181f196bSVijay Mahadevan const PetscReal* vertices = coordinates + i * 3; 908181f196bSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertices[0]; 909181f196bSVijay Mahadevan } 910181f196bSVijay Mahadevan } 911181f196bSVijay Mahadevan else if (nverts == 3) { /* Quadratic Edge */ 912181f196bSVijay Mahadevan const PetscReal dNi_dxi[3] = { 4 * r - 3.0, 4 * ( 1.0 - 2.0 * r ), 4.0 * r - 1.0}; 913181f196bSVijay Mahadevan 914181f196bSVijay Mahadevan for (i = 0; i < nverts; ++i) { 915181f196bSVijay Mahadevan const PetscReal* vertices = coordinates + i * 3; 916181f196bSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertices[0]; 917181f196bSVijay Mahadevan } 918181f196bSVijay Mahadevan } 919181f196bSVijay Mahadevan else { 920181f196bSVijay 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); 921181f196bSVijay Mahadevan } 922181f196bSVijay Mahadevan 923181f196bSVijay Mahadevan if (ijacobian) { 924181f196bSVijay Mahadevan /* invert the jacobian */ 925181f196bSVijay Mahadevan ijacobian[0] = 1.0 / jacobian[0]; 926181f196bSVijay Mahadevan } 927181f196bSVijay Mahadevan 928181f196bSVijay Mahadevan } 929181f196bSVijay Mahadevan else if (dim == 2) { 930181f196bSVijay Mahadevan 931181f196bSVijay Mahadevan if (nverts == 4) { /* Linear Quadrangle */ 932181f196bSVijay Mahadevan const PetscReal& r = quad[0]; 933181f196bSVijay Mahadevan const PetscReal& s = quad[1]; 934181f196bSVijay Mahadevan 935181f196bSVijay Mahadevan const PetscReal dNi_dxi[4] = { -1.0 + s, 1.0 - s, s, -s }; 936181f196bSVijay Mahadevan const PetscReal dNi_deta[4] = { -1.0 + r, -r, r, 1.0 - r }; 937181f196bSVijay Mahadevan 938181f196bSVijay Mahadevan for (i = 0; i < nverts; ++i) { 939181f196bSVijay Mahadevan const PetscReal* vertices = coordinates + i * 3; 940181f196bSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertices[0]; 941181f196bSVijay Mahadevan jacobian[2] += dNi_dxi[i] * vertices[1]; 942181f196bSVijay Mahadevan jacobian[1] += dNi_deta[i] * vertices[0]; 943181f196bSVijay Mahadevan jacobian[3] += dNi_deta[i] * vertices[1]; 944181f196bSVijay Mahadevan } 945181f196bSVijay Mahadevan } 946181f196bSVijay Mahadevan else if (nverts == 3) { /* Linear triangle */ 947181f196bSVijay Mahadevan const PetscReal x2 = coordinates[2 * 3 + 0], y2 = coordinates[2 * 3 + 1]; 948181f196bSVijay Mahadevan 949181f196bSVijay Mahadevan /* Jacobian is constant */ 950181f196bSVijay Mahadevan jacobian[0] = (coordinates[0 * 3 + 0] - x2); jacobian[1] = (coordinates[1 * 3 + 0] - x2); 951181f196bSVijay Mahadevan jacobian[2] = (coordinates[0 * 3 + 1] - y2); jacobian[3] = (coordinates[1 * 3 + 1] - y2); 952181f196bSVijay Mahadevan } 953181f196bSVijay Mahadevan else { 954181f196bSVijay 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); 955181f196bSVijay Mahadevan } 956181f196bSVijay Mahadevan 957181f196bSVijay Mahadevan /* invert the jacobian */ 958181f196bSVijay Mahadevan if (ijacobian) { 959a86ed394SVijay Mahadevan ierr = DMatrix_Invert_2x2_Internal(jacobian, ijacobian, &volume);CHKERRQ(ierr); 960181f196bSVijay Mahadevan } 961181f196bSVijay Mahadevan 962181f196bSVijay Mahadevan } 963181f196bSVijay Mahadevan else { 964181f196bSVijay Mahadevan 965181f196bSVijay Mahadevan if (nverts == 8) { /* Linear Hexahedra */ 966181f196bSVijay Mahadevan const PetscReal& r = quad[0]; 967181f196bSVijay Mahadevan const PetscReal& s = quad[1]; 968181f196bSVijay Mahadevan const PetscReal& t = quad[2]; 969181f196bSVijay Mahadevan const PetscReal dNi_dxi[8] = {- ( 1.0 - s ) * ( 1.0 - t ), 970181f196bSVijay Mahadevan ( 1.0 - s ) * ( 1.0 - t ), 971a86ed394SVijay Mahadevan ( s ) * ( 1.0 - t ), 972a86ed394SVijay Mahadevan - ( s ) * ( 1.0 - t ), 973a86ed394SVijay Mahadevan - ( 1.0 - s ) * ( t ), 974a86ed394SVijay Mahadevan ( 1.0 - s ) * ( t ), 975a86ed394SVijay Mahadevan ( s ) * ( t ), 976a86ed394SVijay Mahadevan - ( s ) * ( t ) 977181f196bSVijay Mahadevan }; 978181f196bSVijay Mahadevan 979181f196bSVijay Mahadevan const PetscReal dNi_deta[8] = { - ( 1.0 - r ) * ( 1.0 - t ), 980a86ed394SVijay Mahadevan - ( r ) * ( 1.0 - t ), 981a86ed394SVijay Mahadevan ( r ) * ( 1.0 - t ), 982181f196bSVijay Mahadevan ( 1.0 - r ) * ( 1.0 - t ), 983a86ed394SVijay Mahadevan - ( 1.0 - r ) * ( t ), 984a86ed394SVijay Mahadevan - ( r ) * ( t ), 985a86ed394SVijay Mahadevan ( r ) * ( t ), 986a86ed394SVijay Mahadevan ( 1.0 - r ) * ( t ) 987181f196bSVijay Mahadevan }; 988181f196bSVijay Mahadevan 989181f196bSVijay Mahadevan const PetscReal dNi_dzeta[8] = { - ( 1.0 - r ) * ( 1.0 - s ), 990a86ed394SVijay Mahadevan - ( r ) * ( 1.0 - s ), 991a86ed394SVijay Mahadevan - ( r ) * ( s ), 992a86ed394SVijay Mahadevan - ( 1.0 - r ) * ( s ), 993181f196bSVijay Mahadevan ( 1.0 - r ) * ( 1.0 - s ), 994a86ed394SVijay Mahadevan ( r ) * ( 1.0 - s ), 995a86ed394SVijay Mahadevan ( r ) * ( s ), 996a86ed394SVijay Mahadevan ( 1.0 - r ) * ( s ) 997181f196bSVijay Mahadevan }; 998a86ed394SVijay Mahadevan 999181f196bSVijay Mahadevan for (i = 0; i < nverts; ++i) { 1000181f196bSVijay Mahadevan const PetscReal* vertex = coordinates + i * 3; 1001181f196bSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertex[0]; 1002181f196bSVijay Mahadevan jacobian[3] += dNi_dxi[i] * vertex[1]; 1003181f196bSVijay Mahadevan jacobian[6] += dNi_dxi[i] * vertex[2]; 1004181f196bSVijay Mahadevan jacobian[1] += dNi_deta[i] * vertex[0]; 1005181f196bSVijay Mahadevan jacobian[4] += dNi_deta[i] * vertex[1]; 1006181f196bSVijay Mahadevan jacobian[7] += dNi_deta[i] * vertex[2]; 1007181f196bSVijay Mahadevan jacobian[2] += dNi_dzeta[i] * vertex[0]; 1008181f196bSVijay Mahadevan jacobian[5] += dNi_dzeta[i] * vertex[1]; 1009181f196bSVijay Mahadevan jacobian[8] += dNi_dzeta[i] * vertex[2]; 1010181f196bSVijay Mahadevan } 1011181f196bSVijay Mahadevan 1012181f196bSVijay Mahadevan } 1013181f196bSVijay Mahadevan else if (nverts == 4) { /* Linear Tetrahedra */ 1014181f196bSVijay Mahadevan const PetscReal x0 = coordinates[/*0 * 3 +*/ 0], y0 = coordinates[/*0 * 3 +*/ 1], z0 = coordinates[/*0 * 3 +*/ 2]; 1015181f196bSVijay Mahadevan 1016181f196bSVijay Mahadevan /* compute the jacobian */ 1017181f196bSVijay Mahadevan jacobian[0] = coordinates[1 * 3 + 0] - x0; jacobian[1] = coordinates[2 * 3 + 0] - x0; jacobian[2] = coordinates[3 * 3 + 0] - x0; 1018181f196bSVijay Mahadevan jacobian[3] = coordinates[1 * 3 + 1] - y0; jacobian[4] = coordinates[2 * 3 + 1] - y0; jacobian[5] = coordinates[3 * 3 + 1] - y0; 1019181f196bSVijay Mahadevan jacobian[6] = coordinates[1 * 3 + 2] - z0; jacobian[7] = coordinates[2 * 3 + 2] - z0; jacobian[8] = coordinates[3 * 3 + 2] - z0; 1020181f196bSVijay Mahadevan } /* Tetrahedra -- ends */ 1021181f196bSVijay Mahadevan else 1022181f196bSVijay Mahadevan { 1023181f196bSVijay 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); 1024181f196bSVijay Mahadevan } 1025181f196bSVijay Mahadevan 1026181f196bSVijay Mahadevan if (ijacobian) { 1027181f196bSVijay Mahadevan /* invert the jacobian */ 1028a86ed394SVijay Mahadevan ierr = DMatrix_Invert_3x3_Internal(jacobian, ijacobian, &volume);CHKERRQ(ierr); 1029181f196bSVijay Mahadevan } 1030181f196bSVijay Mahadevan 1031181f196bSVijay Mahadevan } 1032a86ed394SVijay Mahadevan if ( volume < 1e-12 ) SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Element has zero volume: %g. Degenerate element or invalid connectivity\n", volume); 1033a86ed394SVijay Mahadevan if (dvolume) *dvolume = volume; 1034181f196bSVijay Mahadevan PetscFunctionReturn(0); 1035181f196bSVijay Mahadevan } 1036181f196bSVijay Mahadevan 1037181f196bSVijay Mahadevan 1038181f196bSVijay Mahadevan #undef __FUNCT__ 1039181f196bSVijay Mahadevan #define __FUNCT__ "FEMComputeBasis_JandF" 1040181f196bSVijay Mahadevan PetscErrorCode FEMComputeBasis_JandF ( const PetscInt dim, const PetscInt nverts, const PetscReal *coordinates, const PetscReal *quadrature, PetscReal *phypts, 1041181f196bSVijay Mahadevan PetscReal *phibasis, PetscReal *jacobian, PetscReal *ijacobian, PetscReal* volume ) 1042181f196bSVijay Mahadevan { 1043181f196bSVijay Mahadevan PetscErrorCode ierr; 1044181f196bSVijay Mahadevan 1045181f196bSVijay Mahadevan PetscFunctionBegin; 1046181f196bSVijay Mahadevan switch (dim) { 1047181f196bSVijay Mahadevan case 1: 1048181f196bSVijay Mahadevan ierr = Compute_Lagrange_Basis_1D_Internal(nverts, coordinates, 1, quadrature, phypts, 1049181f196bSVijay Mahadevan NULL, phibasis, NULL, jacobian, ijacobian, volume);CHKERRQ(ierr); 1050181f196bSVijay Mahadevan break; 1051181f196bSVijay Mahadevan case 2: 1052181f196bSVijay Mahadevan ierr = Compute_Lagrange_Basis_2D_Internal(nverts, coordinates, 1, quadrature, phypts, 1053181f196bSVijay Mahadevan NULL, phibasis, NULL, NULL, jacobian, ijacobian, volume);CHKERRQ(ierr); 1054181f196bSVijay Mahadevan break; 1055181f196bSVijay Mahadevan case 3: 1056181f196bSVijay Mahadevan ierr = Compute_Lagrange_Basis_3D_Internal(nverts, coordinates, 1, quadrature, phypts, 1057181f196bSVijay Mahadevan NULL, phibasis, NULL, NULL, NULL, jacobian, ijacobian, volume);CHKERRQ(ierr); 1058181f196bSVijay Mahadevan break; 1059181f196bSVijay Mahadevan default: 1060181f196bSVijay Mahadevan SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension; should be in [1,3] : %D", dim); 1061181f196bSVijay Mahadevan } 1062181f196bSVijay Mahadevan PetscFunctionReturn(0); 1063181f196bSVijay Mahadevan } 1064181f196bSVijay Mahadevan 1065181f196bSVijay Mahadevan 1066181f196bSVijay Mahadevan 1067a86ed394SVijay Mahadevan /*@ 1068a86ed394SVijay Mahadevan DMMoabPToRMapping: Compute the mapping from the physical coordinate system for a given element to the 1069a86ed394SVijay Mahadevan canonical reference element. In addition to finding the inverse mapping evaluation through Newton iteration, 1070a86ed394SVijay Mahadevan the basis function at the parametric point is also evaluated optionally. 1071a86ed394SVijay Mahadevan 1072a86ed394SVijay Mahadevan Input Parameter: 1073a86ed394SVijay Mahadevan 1074a86ed394SVijay Mahadevan . PetscInt dim, the element dimension (1=EDGE, 2=QUAD/TRI, 3=HEX/TET) 1075a86ed394SVijay Mahadevan . PetscInt nverts, the number of vertices in the physical element 1076a86ed394SVijay Mahadevan . PetscReal coordinates, the coordinates of vertices in the physical element 1077a86ed394SVijay Mahadevan . PetscReal[3] xphy, the coordinates of physical point for which natural coordinates (in reference frame) are sought 1078a86ed394SVijay Mahadevan 1079a86ed394SVijay Mahadevan Output Parameter: 1080a86ed394SVijay Mahadevan . PetscReal[3] natparam, the natural coordinates (in reference frame) corresponding to xphy 1081a86ed394SVijay Mahadevan . PetscReal[nverts] phi, the basis functions evaluated at the natural coordinates (natparam) 1082a86ed394SVijay Mahadevan 1083a86ed394SVijay Mahadevan .keywords: DMMoab, Mapping, FEM 1084a86ed394SVijay Mahadevan @*/ 1085181f196bSVijay Mahadevan #undef __FUNCT__ 1086181f196bSVijay Mahadevan #define __FUNCT__ "DMMoabPToRMapping" 1087181f196bSVijay Mahadevan PetscErrorCode DMMoabPToRMapping( const PetscInt dim, const PetscInt nverts, const PetscReal *coordinates, const PetscReal* xphy, PetscReal* natparam, PetscReal* phi) 1088181f196bSVijay Mahadevan { 1089a86ed394SVijay Mahadevan /* Perform inverse evaluation for the mapping with use of Newton Raphson iteration */ 1090181f196bSVijay Mahadevan const PetscReal tol = 1.0e-10; 1091181f196bSVijay Mahadevan const PetscInt max_iterations = 10; 1092181f196bSVijay Mahadevan const PetscReal error_tol_sqr = tol*tol; 1093181f196bSVijay Mahadevan PetscReal phibasis[8], jacobian[9], ijacobian[9], volume; 1094181f196bSVijay Mahadevan PetscReal phypts[3] = {0.0, 0.0, 0.0}; 1095181f196bSVijay Mahadevan PetscReal delta[3] = {0.0, 0.0, 0.0}; 1096181f196bSVijay Mahadevan PetscErrorCode ierr; 1097181f196bSVijay Mahadevan PetscInt iters=0; 1098181f196bSVijay Mahadevan PetscReal error=1.0; 1099181f196bSVijay Mahadevan 1100181f196bSVijay Mahadevan PetscFunctionBegin; 1101181f196bSVijay Mahadevan PetscValidPointer(coordinates, 3); 1102181f196bSVijay Mahadevan PetscValidPointer(xphy, 4); 1103181f196bSVijay Mahadevan PetscValidPointer(natparam, 5); 1104181f196bSVijay Mahadevan 1105181f196bSVijay Mahadevan ierr = PetscMemzero(jacobian, dim * dim * sizeof(PetscReal));CHKERRQ(ierr); 1106181f196bSVijay Mahadevan ierr = PetscMemzero(ijacobian, dim * dim * sizeof(PetscReal));CHKERRQ(ierr); 1107181f196bSVijay Mahadevan ierr = PetscMemzero(phibasis, nverts * sizeof(PetscReal));CHKERRQ(ierr); 1108181f196bSVijay Mahadevan 1109a86ed394SVijay Mahadevan /* zero initial guess */ 1110a86ed394SVijay Mahadevan natparam[0] = natparam[1] = natparam[2] = 0.0; 1111181f196bSVijay Mahadevan 1112a86ed394SVijay Mahadevan /* Compute delta = evaluate( xi ) - x */ 1113a86ed394SVijay Mahadevan ierr = FEMComputeBasis_JandF ( dim, nverts, coordinates, natparam, phypts, phibasis, jacobian, ijacobian, &volume );CHKERRQ(ierr); 1114a86ed394SVijay Mahadevan 1115a86ed394SVijay Mahadevan error = 0.0; 1116a86ed394SVijay Mahadevan switch(dim) { 1117a86ed394SVijay Mahadevan case 3: 1118181f196bSVijay Mahadevan delta[2] = phypts[2] - xphy[2]; 1119a86ed394SVijay Mahadevan error += (delta[2]*delta[2]); 1120a86ed394SVijay Mahadevan case 2: 1121a86ed394SVijay Mahadevan delta[1] = phypts[1] - xphy[1]; 1122a86ed394SVijay Mahadevan error += (delta[1]*delta[1]); 1123a86ed394SVijay Mahadevan case 1: 1124a86ed394SVijay Mahadevan delta[0] = phypts[0] - xphy[0]; 1125a86ed394SVijay Mahadevan error += (delta[0]*delta[0]); 1126a86ed394SVijay Mahadevan break; 1127a86ed394SVijay Mahadevan } 1128a86ed394SVijay Mahadevan 1129a86ed394SVijay Mahadevan #if 0 1130a86ed394SVijay Mahadevan PetscInfo4(NULL, "Current point in physical space : (%g, %g, %g) and error : %g\n", xphy[0], xphy[1], xphy[2], error); 1131a86ed394SVijay Mahadevan #endif 1132181f196bSVijay Mahadevan 1133181f196bSVijay Mahadevan while (error > error_tol_sqr) { 1134181f196bSVijay Mahadevan 1135181f196bSVijay Mahadevan if(++iters > max_iterations) 1136181f196bSVijay 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]); 1137181f196bSVijay Mahadevan 1138181f196bSVijay Mahadevan /* Compute natparam -= J.inverse() * delta */ 1139181f196bSVijay Mahadevan switch(dim) { 1140181f196bSVijay Mahadevan case 1: 1141181f196bSVijay Mahadevan natparam[0] -= ijacobian[0] * delta[0]; 1142181f196bSVijay Mahadevan break; 1143181f196bSVijay Mahadevan case 2: 1144181f196bSVijay Mahadevan natparam[0] -= ijacobian[0] * delta[0] + ijacobian[1] * delta[1]; 1145181f196bSVijay Mahadevan natparam[1] -= ijacobian[2] * delta[0] + ijacobian[3] * delta[1]; 1146181f196bSVijay Mahadevan break; 1147181f196bSVijay Mahadevan case 3: 1148181f196bSVijay Mahadevan natparam[0] -= ijacobian[0] * delta[0] + ijacobian[1] * delta[1] + ijacobian[2] * delta[2]; 1149181f196bSVijay Mahadevan natparam[1] -= ijacobian[3] * delta[0] + ijacobian[4] * delta[1] + ijacobian[5] * delta[2]; 1150181f196bSVijay Mahadevan natparam[2] -= ijacobian[6] * delta[0] + ijacobian[7] * delta[1] + ijacobian[8] * delta[2]; 1151181f196bSVijay Mahadevan break; 1152181f196bSVijay Mahadevan } 1153181f196bSVijay Mahadevan 1154181f196bSVijay Mahadevan /* Compute delta = evaluate( xi ) - x */ 1155a86ed394SVijay Mahadevan ierr = FEMComputeBasis_JandF ( dim, nverts, coordinates, natparam, phypts, phibasis, jacobian, ijacobian, &volume );CHKERRQ(ierr); 1156181f196bSVijay Mahadevan 1157a86ed394SVijay Mahadevan error = 0.0; 1158a86ed394SVijay Mahadevan switch(dim) { 1159a86ed394SVijay Mahadevan case 3: 1160181f196bSVijay Mahadevan delta[2] = phypts[2] - xphy[2]; 1161a86ed394SVijay Mahadevan error += (delta[2]*delta[2]); 1162a86ed394SVijay Mahadevan case 2: 1163a86ed394SVijay Mahadevan delta[1] = phypts[1] - xphy[1]; 1164a86ed394SVijay Mahadevan error += (delta[1]*delta[1]); 1165a86ed394SVijay Mahadevan case 1: 1166a86ed394SVijay Mahadevan delta[0] = phypts[0] - xphy[0]; 1167a86ed394SVijay Mahadevan error += (delta[0]*delta[0]); 1168a86ed394SVijay Mahadevan break; 1169a86ed394SVijay Mahadevan } 1170a86ed394SVijay Mahadevan #if 0 1171a86ed394SVijay Mahadevan PetscInfo5(NULL, "Newton [%D] : Current point in reference space : (%g, %g, %g) and error : %g\n", iters, natparam[0], natparam[1], natparam[2], error); 1172a86ed394SVijay Mahadevan #endif 1173181f196bSVijay Mahadevan } 1174181f196bSVijay Mahadevan if (phi) { 1175181f196bSVijay Mahadevan ierr = PetscMemcpy(phi, phibasis, nverts * sizeof(PetscReal));CHKERRQ(ierr); 1176181f196bSVijay Mahadevan } 1177181f196bSVijay Mahadevan PetscFunctionReturn(0); 1178181f196bSVijay Mahadevan } 1179181f196bSVijay Mahadevan 1180