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 1263d025dbSVijay Mahadevan static inline PetscErrorCode DMatrix_Invert_2x2_Internal (const PetscReal *inmat, PetscReal *outmat, PetscReal *determinant) 1363d025dbSVijay Mahadevan { 1463d025dbSVijay Mahadevan if (!inmat) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_POINTER, "Invalid input matrix specified for 2x2 inversion."); 1563d025dbSVijay Mahadevan PetscReal det = DMatrix_Determinant_2x2_Internal(inmat); 1663d025dbSVijay Mahadevan if (outmat) { 1763d025dbSVijay Mahadevan outmat[0] = inmat[3] / det; 1863d025dbSVijay Mahadevan outmat[1] = -inmat[1] / det; 1963d025dbSVijay Mahadevan outmat[2] = -inmat[2] / det; 2063d025dbSVijay Mahadevan outmat[3] = inmat[0] / det; 2163d025dbSVijay Mahadevan } 2263d025dbSVijay Mahadevan if (determinant) *determinant = det; 2363d025dbSVijay Mahadevan PetscFunctionReturn(0); 2463d025dbSVijay Mahadevan } 2563d025dbSVijay Mahadevan 26181f196bSVijay Mahadevan static inline PetscReal DMatrix_Determinant_3x3_Internal ( const PetscReal inmat[3 * 3] ) 2763d025dbSVijay Mahadevan { 2863d025dbSVijay Mahadevan return inmat[0] * (inmat[8] * inmat[4] - inmat[7] * inmat[5]) 2963d025dbSVijay Mahadevan - inmat[3] * (inmat[8] * inmat[1] - inmat[7] * inmat[2]) 3063d025dbSVijay Mahadevan + inmat[6] * (inmat[5] * inmat[1] - inmat[4] * inmat[2]); 3163d025dbSVijay Mahadevan } 3263d025dbSVijay Mahadevan 3363d025dbSVijay Mahadevan static inline PetscErrorCode DMatrix_Invert_3x3_Internal (const PetscReal *inmat, PetscReal *outmat, PetscScalar *determinant) 3463d025dbSVijay Mahadevan { 3563d025dbSVijay Mahadevan if (!inmat) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_POINTER, "Invalid input matrix specified for 3x3 inversion."); 36181f196bSVijay Mahadevan PetscReal det = DMatrix_Determinant_3x3_Internal(inmat); 3763d025dbSVijay Mahadevan if (outmat) { 3863d025dbSVijay Mahadevan outmat[0] = (inmat[8] * inmat[4] - inmat[7] * inmat[5]) / det; 3963d025dbSVijay Mahadevan outmat[1] = -(inmat[8] * inmat[1] - inmat[7] * inmat[2]) / det; 4063d025dbSVijay Mahadevan outmat[2] = (inmat[5] * inmat[1] - inmat[4] * inmat[2]) / det; 4163d025dbSVijay Mahadevan outmat[3] = -(inmat[8] * inmat[3] - inmat[6] * inmat[5]) / det; 4263d025dbSVijay Mahadevan outmat[4] = (inmat[8] * inmat[0] - inmat[6] * inmat[2]) / det; 4363d025dbSVijay Mahadevan outmat[5] = -(inmat[5] * inmat[0] - inmat[3] * inmat[2]) / det; 4463d025dbSVijay Mahadevan outmat[6] = (inmat[7] * inmat[3] - inmat[6] * inmat[4]) / det; 4563d025dbSVijay Mahadevan outmat[7] = -(inmat[7] * inmat[0] - inmat[6] * inmat[1]) / det; 4663d025dbSVijay Mahadevan outmat[8] = (inmat[4] * inmat[0] - inmat[3] * inmat[1]) / det; 4763d025dbSVijay Mahadevan } 4863d025dbSVijay Mahadevan if (determinant) *determinant = det; 4963d025dbSVijay Mahadevan PetscFunctionReturn(0); 5063d025dbSVijay Mahadevan } 5163d025dbSVijay Mahadevan 52181f196bSVijay Mahadevan inline PetscReal DMatrix_Determinant_4x4_Internal ( PetscReal inmat[4 * 4] ) 53181f196bSVijay Mahadevan { 54181f196bSVijay Mahadevan return 55181f196bSVijay Mahadevan inmat[0 + 0 * 4] * ( 56181f196bSVijay Mahadevan inmat[1 + 1 * 4] * ( inmat[2 + 2 * 4] * inmat[3 + 3 * 4] - inmat[2 + 3 * 4] * inmat[3 + 2 * 4] ) 57181f196bSVijay Mahadevan - inmat[1 + 2 * 4] * ( inmat[2 + 1 * 4] * inmat[3 + 3 * 4] - inmat[2 + 3 * 4] * inmat[3 + 1 * 4] ) 58181f196bSVijay Mahadevan + inmat[1 + 3 * 4] * ( inmat[2 + 1 * 4] * inmat[3 + 2 * 4] - inmat[2 + 2 * 4] * inmat[3 + 1 * 4] ) ) 59181f196bSVijay Mahadevan - inmat[0 + 1 * 4] * ( 60181f196bSVijay Mahadevan inmat[1 + 0 * 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 + 0 * 4] * inmat[3 + 3 * 4] - inmat[2 + 3 * 4] * inmat[3 + 0 * 4] ) 62181f196bSVijay Mahadevan + inmat[1 + 3 * 4] * ( inmat[2 + 0 * 4] * inmat[3 + 2 * 4] - inmat[2 + 2 * 4] * inmat[3 + 0 * 4] ) ) 63181f196bSVijay Mahadevan + inmat[0 + 2 * 4] * ( 64181f196bSVijay Mahadevan inmat[1 + 0 * 4] * ( inmat[2 + 1 * 4] * inmat[3 + 3 * 4] - inmat[2 + 3 * 4] * inmat[3 + 1 * 4] ) 65181f196bSVijay Mahadevan - inmat[1 + 1 * 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 + 1 * 4] - inmat[2 + 1 * 4] * inmat[3 + 0 * 4] ) ) 67181f196bSVijay Mahadevan - inmat[0 + 3 * 4] * ( 68181f196bSVijay Mahadevan inmat[1 + 0 * 4] * ( inmat[2 + 1 * 4] * inmat[3 + 2 * 4] - inmat[2 + 2 * 4] * inmat[3 + 1 * 4] ) 69181f196bSVijay Mahadevan - inmat[1 + 1 * 4] * ( inmat[2 + 0 * 4] * inmat[3 + 2 * 4] - inmat[2 + 2 * 4] * inmat[3 + 0 * 4] ) 70181f196bSVijay Mahadevan + inmat[1 + 2 * 4] * ( inmat[2 + 0 * 4] * inmat[3 + 1 * 4] - inmat[2 + 1 * 4] * inmat[3 + 0 * 4] ) ); 71181f196bSVijay Mahadevan } 72181f196bSVijay Mahadevan 73181f196bSVijay Mahadevan inline PetscErrorCode DMatrix_Invert_4x4_Internal (PetscReal *inmat, PetscReal *outmat, PetscScalar *determinant) 74181f196bSVijay Mahadevan { 75181f196bSVijay Mahadevan if (!inmat) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_POINTER, "Invalid input matrix specified for 4x4 inversion."); 76181f196bSVijay Mahadevan PetscReal det = DMatrix_Determinant_4x4_Internal(inmat); 77181f196bSVijay Mahadevan if (outmat) { 78181f196bSVijay 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; 79181f196bSVijay 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; 80181f196bSVijay 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; 81181f196bSVijay 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; 82181f196bSVijay 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; 83181f196bSVijay 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; 84181f196bSVijay 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; 85181f196bSVijay 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; 86181f196bSVijay 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; 87181f196bSVijay 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; 88181f196bSVijay 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; 89181f196bSVijay 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; 90181f196bSVijay 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; 91181f196bSVijay 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; 92181f196bSVijay 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; 93181f196bSVijay 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; 94181f196bSVijay Mahadevan } 95181f196bSVijay Mahadevan if (determinant) *determinant = det; 96181f196bSVijay Mahadevan PetscFunctionReturn(0); 97181f196bSVijay Mahadevan } 98181f196bSVijay Mahadevan 9963d025dbSVijay Mahadevan 10063d025dbSVijay Mahadevan /*@ 10197b73a88SSatish Balay Compute_Lagrange_Basis_1D_Internal - Evaluate bases and derivatives at quadrature points for a EDGE2 or EDGE3 element. 10263d025dbSVijay Mahadevan 10363d025dbSVijay Mahadevan The routine is given the coordinates of the vertices of a linear or quadratic edge element. 10463d025dbSVijay Mahadevan 10563d025dbSVijay Mahadevan The routine evaluates the basis functions associated with each quadrature point provided, 10663d025dbSVijay Mahadevan and their derivatives with respect to X. 10763d025dbSVijay Mahadevan 10863d025dbSVijay Mahadevan Notes: 10963d025dbSVijay Mahadevan 11063d025dbSVijay Mahadevan Example Physical Element 11163d025dbSVijay Mahadevan 11263d025dbSVijay Mahadevan 1-------2 1----3----2 11363d025dbSVijay Mahadevan EDGE2 EDGE3 11463d025dbSVijay Mahadevan 11563d025dbSVijay Mahadevan Input Parameter: 11663d025dbSVijay Mahadevan 11763d025dbSVijay Mahadevan . PetscInt nverts, the number of element vertices 11863d025dbSVijay Mahadevan . PetscReal coords[3*nverts], the physical coordinates of the vertices (in canonical numbering) 11963d025dbSVijay Mahadevan . PetscInt npts, the number of evaluation points (quadrature points) 12063d025dbSVijay Mahadevan . PetscReal quad[3*npts], the evaluation points (quadrature points) in the reference space 12163d025dbSVijay Mahadevan 12263d025dbSVijay Mahadevan Output Parameter: 12363d025dbSVijay Mahadevan . PetscReal phypts[3*npts], the evaluation points (quadrature points) transformed to the physical space 12463d025dbSVijay Mahadevan . PetscReal jxw[npts], the jacobian determinant * quadrature weight necessary for assembling discrete contributions 12563d025dbSVijay Mahadevan . PetscReal phi[npts], the bases evaluated at the specified quadrature points 12663d025dbSVijay Mahadevan . PetscReal dphidx[npts], the derivative of the bases wrt X-direction evaluated at the specified quadrature points 12763d025dbSVijay Mahadevan 128edc382c3SSatish Balay Level: advanced 129edc382c3SSatish Balay 13063d025dbSVijay Mahadevan @*/ 13163d025dbSVijay Mahadevan PetscErrorCode Compute_Lagrange_Basis_1D_Internal ( const PetscInt nverts, const PetscReal *coords, const PetscInt npts, const PetscReal *quad, PetscReal *phypts, 132181f196bSVijay Mahadevan PetscReal *jxw, PetscReal *phi, PetscReal *dphidx, 133181f196bSVijay Mahadevan PetscReal *jacobian, PetscReal *ijacobian, PetscReal *volume) 13463d025dbSVijay Mahadevan { 13563d025dbSVijay Mahadevan int i, j; 13663d025dbSVijay Mahadevan PetscErrorCode ierr; 13763d025dbSVijay Mahadevan 138181f196bSVijay Mahadevan PetscFunctionBegin; 139181f196bSVijay Mahadevan PetscValidPointer(jacobian, 9); 140181f196bSVijay Mahadevan PetscValidPointer(ijacobian, 10); 141181f196bSVijay Mahadevan PetscValidPointer(volume, 11); 142181f196bSVijay Mahadevan if (phypts) { 143*580bdb30SBarry Smith ierr = PetscArrayzero(phypts, npts * 3);CHKERRQ(ierr); 144181f196bSVijay Mahadevan } 14563d025dbSVijay Mahadevan if (dphidx) { /* Reset arrays. */ 146*580bdb30SBarry Smith ierr = PetscArrayzero(dphidx, npts * nverts);CHKERRQ(ierr); 14763d025dbSVijay Mahadevan } 14863d025dbSVijay Mahadevan if (nverts == 2) { /* Linear Edge */ 14963d025dbSVijay Mahadevan 15063d025dbSVijay Mahadevan for (j = 0; j < npts; j++) 15163d025dbSVijay Mahadevan { 152a86ed394SVijay Mahadevan const PetscInt offset = j * nverts; 153181f196bSVijay Mahadevan const PetscReal r = quad[j]; 15463d025dbSVijay Mahadevan 155181f196bSVijay Mahadevan phi[0 + offset] = ( 1.0 - r ); 156181f196bSVijay Mahadevan phi[1 + offset] = ( r ); 15763d025dbSVijay Mahadevan 158181f196bSVijay Mahadevan const PetscReal dNi_dxi[2] = { -1.0, 1.0 }; 15963d025dbSVijay Mahadevan 160181f196bSVijay Mahadevan jacobian[0] = ijacobian[0] = volume[0] = 0.0; 16163d025dbSVijay Mahadevan for (i = 0; i < nverts; ++i) { 162181f196bSVijay Mahadevan const PetscReal* vertices = coords + i * 3; 163181f196bSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertices[0]; 164181f196bSVijay Mahadevan if (phypts) { 165181f196bSVijay Mahadevan phypts[3 * j + 0] += phi[i + offset] * vertices[0]; 166181f196bSVijay Mahadevan } 16763d025dbSVijay Mahadevan } 16863d025dbSVijay Mahadevan 16963d025dbSVijay Mahadevan /* invert the jacobian */ 170181f196bSVijay Mahadevan *volume = jacobian[0]; 171181f196bSVijay Mahadevan ijacobian[0] = 1.0 / jacobian[0]; 172181f196bSVijay Mahadevan jxw[j] *= *volume; 17363d025dbSVijay Mahadevan 17463d025dbSVijay Mahadevan /* Divide by element jacobian. */ 17563d025dbSVijay Mahadevan for ( i = 0; i < nverts; i++ ) { 176181f196bSVijay Mahadevan if (dphidx) dphidx[i + offset] += dNi_dxi[i] * ijacobian[0]; 17763d025dbSVijay Mahadevan } 17863d025dbSVijay Mahadevan 17963d025dbSVijay Mahadevan } 18063d025dbSVijay Mahadevan } 18163d025dbSVijay Mahadevan else if (nverts == 3) { /* Quadratic Edge */ 18263d025dbSVijay Mahadevan 18363d025dbSVijay Mahadevan for (j = 0; j < npts; j++) 18463d025dbSVijay Mahadevan { 185a86ed394SVijay Mahadevan const PetscInt offset = j * nverts; 186181f196bSVijay Mahadevan const PetscReal r = quad[j]; 18763d025dbSVijay Mahadevan 188181f196bSVijay Mahadevan phi[0 + offset] = 1.0 + r * ( 2.0 * r - 3.0 ); 189181f196bSVijay Mahadevan phi[1 + offset] = 4.0 * r * ( 1.0 - r ); 190181f196bSVijay Mahadevan phi[2 + offset] = r * ( 2.0 * r - 1.0 ); 19163d025dbSVijay Mahadevan 192181f196bSVijay Mahadevan const PetscReal dNi_dxi[3] = { 4 * r - 3.0, 4 * ( 1.0 - 2.0 * r ), 4.0 * r - 1.0}; 19363d025dbSVijay Mahadevan 194181f196bSVijay Mahadevan jacobian[0] = ijacobian[0] = volume[0] = 0.0; 19563d025dbSVijay Mahadevan for (i = 0; i < nverts; ++i) { 196181f196bSVijay Mahadevan const PetscReal* vertices = coords + i * 3; 197181f196bSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertices[0]; 198181f196bSVijay Mahadevan if (phypts) { 199181f196bSVijay Mahadevan phypts[3 * j + 0] += phi[i + offset] * vertices[0]; 200181f196bSVijay Mahadevan } 20163d025dbSVijay Mahadevan } 20263d025dbSVijay Mahadevan 20363d025dbSVijay Mahadevan /* invert the jacobian */ 204181f196bSVijay Mahadevan *volume = jacobian[0]; 205181f196bSVijay Mahadevan ijacobian[0] = 1.0 / jacobian[0]; 206181f196bSVijay Mahadevan if (jxw) jxw[j] *= *volume; 20763d025dbSVijay Mahadevan 20863d025dbSVijay Mahadevan /* Divide by element jacobian. */ 20963d025dbSVijay Mahadevan for ( i = 0; i < nverts; i++ ) { 210181f196bSVijay Mahadevan if (dphidx) dphidx[i + offset] += dNi_dxi[i] * ijacobian[0]; 21163d025dbSVijay Mahadevan } 21263d025dbSVijay Mahadevan } 21363d025dbSVijay Mahadevan } 21463d025dbSVijay Mahadevan else { 21563d025dbSVijay 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); 21663d025dbSVijay Mahadevan } 21763d025dbSVijay Mahadevan #if 0 21863d025dbSVijay Mahadevan /* verify if the computed basis functions are consistent */ 21963d025dbSVijay Mahadevan for ( j = 0; j < npts; j++ ) { 22063d025dbSVijay Mahadevan PetscScalar phisum = 0, dphixsum = 0; 22163d025dbSVijay Mahadevan for ( i = 0; i < nverts; i++ ) { 22263d025dbSVijay Mahadevan phisum += phi[i + j * nverts]; 22363d025dbSVijay Mahadevan if (dphidx) dphixsum += dphidx[i + j * nverts]; 22463d025dbSVijay Mahadevan } 22563d025dbSVijay Mahadevan PetscPrintf(PETSC_COMM_WORLD, "Sum of basis at quadrature point %D = %g, %g, %g\n", j, phisum, dphixsum); 22663d025dbSVijay Mahadevan } 22763d025dbSVijay Mahadevan #endif 22863d025dbSVijay Mahadevan PetscFunctionReturn(0); 22963d025dbSVijay Mahadevan } 23063d025dbSVijay Mahadevan 23163d025dbSVijay Mahadevan 23263d025dbSVijay Mahadevan /*@ 23397b73a88SSatish Balay Compute_Lagrange_Basis_2D_Internal - Evaluate bases and derivatives at quadrature points for a QUAD4 or TRI3 element. 23463d025dbSVijay Mahadevan 23563d025dbSVijay Mahadevan The routine is given the coordinates of the vertices of a quadrangle or triangle. 23663d025dbSVijay Mahadevan 23763d025dbSVijay Mahadevan The routine evaluates the basis functions associated with each quadrature point provided, 23863d025dbSVijay Mahadevan and their derivatives with respect to X and Y. 23963d025dbSVijay Mahadevan 24063d025dbSVijay Mahadevan Notes: 24163d025dbSVijay Mahadevan 24263d025dbSVijay Mahadevan Example Physical Element (QUAD4) 24363d025dbSVijay Mahadevan 24463d025dbSVijay Mahadevan 4------3 s 24563d025dbSVijay Mahadevan | | | 24663d025dbSVijay Mahadevan | | | 24763d025dbSVijay Mahadevan | | | 24863d025dbSVijay Mahadevan 1------2 0-------r 24963d025dbSVijay Mahadevan 25063d025dbSVijay Mahadevan Input Parameter: 25163d025dbSVijay Mahadevan 25263d025dbSVijay Mahadevan . PetscInt nverts, the number of element vertices 25363d025dbSVijay Mahadevan . PetscReal coords[3*nverts], the physical coordinates of the vertices (in canonical numbering) 25463d025dbSVijay Mahadevan . PetscInt npts, the number of evaluation points (quadrature points) 25563d025dbSVijay Mahadevan . PetscReal quad[3*npts], the evaluation points (quadrature points) in the reference space 25663d025dbSVijay Mahadevan 25763d025dbSVijay Mahadevan Output Parameter: 25863d025dbSVijay Mahadevan . PetscReal phypts[3*npts], the evaluation points (quadrature points) transformed to the physical space 25963d025dbSVijay Mahadevan . PetscReal jxw[npts], the jacobian determinant * quadrature weight necessary for assembling discrete contributions 26063d025dbSVijay Mahadevan . PetscReal phi[npts], the bases evaluated at the specified quadrature points 26163d025dbSVijay Mahadevan . PetscReal dphidx[npts], the derivative of the bases wrt X-direction evaluated at the specified quadrature points 26263d025dbSVijay Mahadevan . PetscReal dphidy[npts], the derivative of the bases wrt Y-direction evaluated at the specified quadrature points 26363d025dbSVijay Mahadevan 264edc382c3SSatish Balay Level: advanced 265edc382c3SSatish Balay 26663d025dbSVijay Mahadevan @*/ 26763d025dbSVijay Mahadevan PetscErrorCode Compute_Lagrange_Basis_2D_Internal ( const PetscInt nverts, const PetscReal *coords, const PetscInt npts, const PetscReal *quad, PetscReal *phypts, 268181f196bSVijay Mahadevan PetscReal *jxw, PetscReal *phi, PetscReal *dphidx, PetscReal *dphidy, 269181f196bSVijay Mahadevan PetscReal *jacobian, PetscReal *ijacobian, PetscReal *volume) 27063d025dbSVijay Mahadevan { 271a86ed394SVijay Mahadevan PetscInt i, j, k; 27263d025dbSVijay Mahadevan PetscErrorCode ierr; 27363d025dbSVijay Mahadevan 27463d025dbSVijay Mahadevan PetscFunctionBegin; 275181f196bSVijay Mahadevan PetscValidPointer(jacobian, 10); 276181f196bSVijay Mahadevan PetscValidPointer(ijacobian, 11); 277181f196bSVijay Mahadevan PetscValidPointer(volume, 12); 278*580bdb30SBarry Smith ierr = PetscArrayzero(phi, npts);CHKERRQ(ierr); 279181f196bSVijay Mahadevan if (phypts) { 280*580bdb30SBarry Smith ierr = PetscArrayzero(phypts, npts * 3);CHKERRQ(ierr); 281181f196bSVijay Mahadevan } 28263d025dbSVijay Mahadevan if (dphidx) { /* Reset arrays. */ 283*580bdb30SBarry Smith ierr = PetscArrayzero(dphidx, npts * nverts);CHKERRQ(ierr); 284*580bdb30SBarry Smith ierr = PetscArrayzero(dphidy, npts * nverts);CHKERRQ(ierr); 28563d025dbSVijay Mahadevan } 28663d025dbSVijay Mahadevan if (nverts == 4) { /* Linear Quadrangle */ 28763d025dbSVijay Mahadevan 28863d025dbSVijay Mahadevan for (j = 0; j < npts; j++) 28963d025dbSVijay Mahadevan { 290a86ed394SVijay Mahadevan const PetscInt offset = j * nverts; 291181f196bSVijay Mahadevan const PetscReal r = quad[0 + j * 2]; 292181f196bSVijay Mahadevan const PetscReal s = quad[1 + j * 2]; 29363d025dbSVijay Mahadevan 29463d025dbSVijay Mahadevan phi[0 + offset] = ( 1.0 - r ) * ( 1.0 - s ); 29563d025dbSVijay Mahadevan phi[1 + offset] = r * ( 1.0 - s ); 29663d025dbSVijay Mahadevan phi[2 + offset] = r * s; 29763d025dbSVijay Mahadevan phi[3 + offset] = ( 1.0 - r ) * s; 29863d025dbSVijay Mahadevan 299181f196bSVijay Mahadevan const PetscReal dNi_dxi[4] = { -1.0 + s, 1.0 - s, s, -s }; 300181f196bSVijay Mahadevan const PetscReal dNi_deta[4] = { -1.0 + r, -r, r, 1.0 - r }; 30163d025dbSVijay Mahadevan 302*580bdb30SBarry Smith ierr = PetscArrayzero(jacobian, 4);CHKERRQ(ierr); 303*580bdb30SBarry Smith ierr = PetscArrayzero(ijacobian, 4);CHKERRQ(ierr); 30463d025dbSVijay Mahadevan for (i = 0; i < nverts; ++i) { 305181f196bSVijay Mahadevan const PetscReal* vertices = coords + i * 3; 30663d025dbSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertices[0]; 30763d025dbSVijay Mahadevan jacobian[2] += dNi_dxi[i] * vertices[1]; 30863d025dbSVijay Mahadevan jacobian[1] += dNi_deta[i] * vertices[0]; 30963d025dbSVijay Mahadevan jacobian[3] += dNi_deta[i] * vertices[1]; 310181f196bSVijay Mahadevan if (phypts) { 311181f196bSVijay Mahadevan phypts[3 * j + 0] += phi[i + offset] * vertices[0]; 312181f196bSVijay Mahadevan phypts[3 * j + 1] += phi[i + offset] * vertices[1]; 313181f196bSVijay Mahadevan phypts[3 * j + 2] += phi[i + offset] * vertices[2]; 314181f196bSVijay Mahadevan } 31563d025dbSVijay Mahadevan } 31663d025dbSVijay Mahadevan 31763d025dbSVijay Mahadevan /* invert the jacobian */ 318181f196bSVijay Mahadevan ierr = DMatrix_Invert_2x2_Internal(jacobian, ijacobian, volume);CHKERRQ(ierr); 319181f196bSVijay 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); 32063d025dbSVijay Mahadevan 321181f196bSVijay Mahadevan if (jxw) jxw[j] *= *volume; 32263d025dbSVijay Mahadevan 323181f196bSVijay Mahadevan /* Let us compute the bases derivatives by scaling with inverse jacobian. */ 324181f196bSVijay Mahadevan if (dphidx) { 32563d025dbSVijay Mahadevan for ( i = 0; i < nverts; i++ ) { 326a86ed394SVijay Mahadevan for ( k = 0; k < 2; ++k) { 32763d025dbSVijay Mahadevan if (dphidx) dphidx[i + offset] += dNi_dxi[i] * ijacobian[k * 2 + 0]; 32863d025dbSVijay Mahadevan if (dphidy) dphidy[i + offset] += dNi_deta[i] * ijacobian[k * 2 + 1]; 329181f196bSVijay Mahadevan } /* for k=[0..2) */ 330181f196bSVijay Mahadevan } /* for i=[0..nverts) */ 331181f196bSVijay Mahadevan } /* if (dphidx) */ 33263d025dbSVijay Mahadevan } 33363d025dbSVijay Mahadevan } 33463d025dbSVijay Mahadevan else if (nverts == 3) { /* Linear triangle */ 33563d025dbSVijay Mahadevan 336*580bdb30SBarry Smith ierr = PetscArrayzero(jacobian, 4);CHKERRQ(ierr); 337*580bdb30SBarry Smith ierr = PetscArrayzero(ijacobian, 4);CHKERRQ(ierr); 33863d025dbSVijay Mahadevan 339181f196bSVijay Mahadevan const PetscReal x2 = coords[2 * 3 + 0], y2 = coords[2 * 3 + 1]; 340181f196bSVijay Mahadevan 34163d025dbSVijay Mahadevan /* Jacobian is constant */ 342181f196bSVijay Mahadevan jacobian[0] = (coords[0 * 3 + 0] - x2); jacobian[1] = (coords[1 * 3 + 0] - x2); 343181f196bSVijay Mahadevan jacobian[2] = (coords[0 * 3 + 1] - y2); jacobian[3] = (coords[1 * 3 + 1] - y2); 34463d025dbSVijay Mahadevan 34563d025dbSVijay Mahadevan /* invert the jacobian */ 346181f196bSVijay Mahadevan ierr = DMatrix_Invert_2x2_Internal(jacobian, ijacobian, volume);CHKERRQ(ierr); 347181f196bSVijay 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); 348181f196bSVijay Mahadevan 349181f196bSVijay Mahadevan const PetscReal Dx[3] = { ijacobian[0], ijacobian[2], - ijacobian[0] - ijacobian[2] }; 350181f196bSVijay Mahadevan const PetscReal Dy[3] = { ijacobian[1], ijacobian[3], - ijacobian[1] - ijacobian[3] }; 35163d025dbSVijay Mahadevan 35263d025dbSVijay Mahadevan for (j = 0; j < npts; j++) 35363d025dbSVijay Mahadevan { 354a86ed394SVijay Mahadevan const PetscInt offset = j * nverts; 355181f196bSVijay Mahadevan const PetscReal r = quad[0 + j * 2]; 356181f196bSVijay Mahadevan const PetscReal s = quad[1 + j * 2]; 35763d025dbSVijay Mahadevan 358181f196bSVijay Mahadevan if (jxw) jxw[j] *= 0.5; 35963d025dbSVijay Mahadevan 360181f196bSVijay Mahadevan /* const PetscReal Ni[3] = { r, s, 1.0 - r - s }; */ 361181f196bSVijay Mahadevan const PetscReal phipts_x = coords[2 * 3 + 0] + jacobian[0] * r + jacobian[1] * s; 362181f196bSVijay Mahadevan const PetscReal phipts_y = coords[2 * 3 + 1] + jacobian[2] * r + jacobian[3] * s; 363181f196bSVijay Mahadevan if (phypts) { 364181f196bSVijay Mahadevan phypts[offset + 0] = phipts_x; 365181f196bSVijay Mahadevan phypts[offset + 1] = phipts_y; 366181f196bSVijay Mahadevan } 36763d025dbSVijay Mahadevan 368181f196bSVijay Mahadevan /* \phi_0 = (b.y − c.y) x + (b.x − c.x) y + c.x b.y − b.x c.y */ 369181f196bSVijay Mahadevan phi[0 + offset] = ( ijacobian[0] * (phipts_x - x2) + ijacobian[1] * (phipts_y - y2) ); 370181f196bSVijay Mahadevan /* \phi_1 = (c.y − a.y) x + (a.x − c.x) y + c.x a.y − a.x c.y */ 371181f196bSVijay Mahadevan phi[1 + offset] = ( ijacobian[2] * (phipts_x - x2) + ijacobian[3] * (phipts_y - y2) ); 37263d025dbSVijay Mahadevan phi[2 + offset] = 1.0 - phi[0 + offset] - phi[1 + offset]; 37363d025dbSVijay Mahadevan 37463d025dbSVijay Mahadevan if (dphidx) { 375181f196bSVijay Mahadevan dphidx[0 + offset] = Dx[0]; 376181f196bSVijay Mahadevan dphidx[1 + offset] = Dx[1]; 377181f196bSVijay Mahadevan dphidx[2 + offset] = Dx[2]; 37863d025dbSVijay Mahadevan } 37963d025dbSVijay Mahadevan 38063d025dbSVijay Mahadevan if (dphidy) { 381181f196bSVijay Mahadevan dphidy[0 + offset] = Dy[0]; 382181f196bSVijay Mahadevan dphidy[1 + offset] = Dy[1]; 383181f196bSVijay Mahadevan dphidy[2 + offset] = Dy[2]; 38463d025dbSVijay Mahadevan } 38563d025dbSVijay Mahadevan 38663d025dbSVijay Mahadevan } 38763d025dbSVijay Mahadevan } 38863d025dbSVijay Mahadevan else { 38963d025dbSVijay 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); 39063d025dbSVijay Mahadevan } 39163d025dbSVijay Mahadevan #if 0 39263d025dbSVijay Mahadevan /* verify if the computed basis functions are consistent */ 39363d025dbSVijay Mahadevan for ( j = 0; j < npts; j++ ) { 39463d025dbSVijay Mahadevan PetscScalar phisum = 0, dphixsum = 0, dphiysum = 0; 39563d025dbSVijay Mahadevan for ( i = 0; i < nverts; i++ ) { 39663d025dbSVijay Mahadevan phisum += phi[i + j * nverts]; 39763d025dbSVijay Mahadevan if (dphidx) dphixsum += dphidx[i + j * nverts]; 39863d025dbSVijay Mahadevan if (dphidy) dphiysum += dphidy[i + j * nverts]; 39963d025dbSVijay Mahadevan } 40063d025dbSVijay Mahadevan PetscPrintf(PETSC_COMM_WORLD, "Sum of basis at quadrature point %D = %g, %g, %g\n", j, phisum, dphixsum, dphiysum); 40163d025dbSVijay Mahadevan } 40263d025dbSVijay Mahadevan #endif 40363d025dbSVijay Mahadevan PetscFunctionReturn(0); 40463d025dbSVijay Mahadevan } 40563d025dbSVijay Mahadevan 40663d025dbSVijay Mahadevan 40763d025dbSVijay Mahadevan /*@ 40897b73a88SSatish Balay Compute_Lagrange_Basis_3D_Internal - Evaluate bases and derivatives at quadrature points for a HEX8 or TET4 element. 40963d025dbSVijay Mahadevan 41063d025dbSVijay Mahadevan The routine is given the coordinates of the vertices of a hexahedra or tetrahedra. 41163d025dbSVijay Mahadevan 41263d025dbSVijay Mahadevan The routine evaluates the basis functions associated with each quadrature point provided, 41363d025dbSVijay Mahadevan and their derivatives with respect to X, Y and Z. 41463d025dbSVijay Mahadevan 41563d025dbSVijay Mahadevan Notes: 41663d025dbSVijay Mahadevan 41763d025dbSVijay Mahadevan Example Physical Element (HEX8) 41863d025dbSVijay Mahadevan 41963d025dbSVijay Mahadevan 8------7 42063d025dbSVijay Mahadevan /| /| t s 42163d025dbSVijay Mahadevan 5------6 | | / 42263d025dbSVijay Mahadevan | | | | |/ 42363d025dbSVijay Mahadevan | 4----|-3 0-------r 42463d025dbSVijay Mahadevan |/ |/ 42563d025dbSVijay Mahadevan 1------2 42663d025dbSVijay Mahadevan 42763d025dbSVijay Mahadevan Input Parameter: 42863d025dbSVijay Mahadevan 42963d025dbSVijay Mahadevan . PetscInt nverts, the number of element vertices 43063d025dbSVijay Mahadevan . PetscReal coords[3*nverts], the physical coordinates of the vertices (in canonical numbering) 43163d025dbSVijay Mahadevan . PetscInt npts, the number of evaluation points (quadrature points) 43263d025dbSVijay Mahadevan . PetscReal quad[3*npts], the evaluation points (quadrature points) in the reference space 43363d025dbSVijay Mahadevan 43463d025dbSVijay Mahadevan Output Parameter: 43563d025dbSVijay Mahadevan . PetscReal phypts[3*npts], the evaluation points (quadrature points) transformed to the physical space 43663d025dbSVijay Mahadevan . PetscReal jxw[npts], the jacobian determinant * quadrature weight necessary for assembling discrete contributions 43763d025dbSVijay Mahadevan . PetscReal phi[npts], the bases evaluated at the specified quadrature points 43863d025dbSVijay Mahadevan . PetscReal dphidx[npts], the derivative of the bases wrt X-direction evaluated at the specified quadrature points 43963d025dbSVijay Mahadevan . PetscReal dphidy[npts], the derivative of the bases wrt Y-direction evaluated at the specified quadrature points 44063d025dbSVijay Mahadevan . PetscReal dphidz[npts], the derivative of the bases wrt Z-direction evaluated at the specified quadrature points 44163d025dbSVijay Mahadevan 442edc382c3SSatish Balay Level: advanced 443edc382c3SSatish Balay 44463d025dbSVijay Mahadevan @*/ 44563d025dbSVijay Mahadevan PetscErrorCode Compute_Lagrange_Basis_3D_Internal ( const PetscInt nverts, const PetscReal *coords, const PetscInt npts, const PetscReal *quad, PetscReal *phypts, 446181f196bSVijay Mahadevan PetscReal *jxw, PetscReal *phi, PetscReal *dphidx, PetscReal *dphidy, PetscReal *dphidz, 447181f196bSVijay Mahadevan PetscReal *jacobian, PetscReal *ijacobian, PetscReal *volume) 44863d025dbSVijay Mahadevan { 449a86ed394SVijay Mahadevan PetscInt i, j, k; 45063d025dbSVijay Mahadevan PetscErrorCode ierr; 45163d025dbSVijay Mahadevan 45263d025dbSVijay Mahadevan PetscFunctionBegin; 453181f196bSVijay Mahadevan PetscValidPointer(jacobian, 11); 454181f196bSVijay Mahadevan PetscValidPointer(ijacobian, 12); 455181f196bSVijay Mahadevan PetscValidPointer(volume, 13); 45663d025dbSVijay Mahadevan /* Reset arrays. */ 457*580bdb30SBarry Smith ierr = PetscArrayzero(phi, npts);CHKERRQ(ierr); 458181f196bSVijay Mahadevan if (phypts) { 459*580bdb30SBarry Smith ierr = PetscArrayzero(phypts, npts * 3);CHKERRQ(ierr); 460181f196bSVijay Mahadevan } 46163d025dbSVijay Mahadevan if (dphidx) { 462*580bdb30SBarry Smith ierr = PetscArrayzero(dphidx, npts * nverts);CHKERRQ(ierr); 463*580bdb30SBarry Smith ierr = PetscArrayzero(dphidy, npts * nverts);CHKERRQ(ierr); 464*580bdb30SBarry Smith ierr = PetscArrayzero(dphidz, npts * nverts);CHKERRQ(ierr); 46563d025dbSVijay Mahadevan } 46663d025dbSVijay Mahadevan 46763d025dbSVijay Mahadevan if (nverts == 8) { /* Linear Hexahedra */ 46863d025dbSVijay Mahadevan 46963d025dbSVijay Mahadevan for (j = 0; j < npts; j++) 47063d025dbSVijay Mahadevan { 471a86ed394SVijay Mahadevan const PetscInt offset = j * nverts; 472181f196bSVijay Mahadevan const PetscReal& r = quad[j * 3 + 0]; 473181f196bSVijay Mahadevan const PetscReal& s = quad[j * 3 + 1]; 474181f196bSVijay Mahadevan const PetscReal& t = quad[j * 3 + 2]; 47563d025dbSVijay Mahadevan 476a86ed394SVijay Mahadevan phi[offset + 0] = ( 1.0 - r ) * ( 1.0 - s ) * ( 1.0 - t ); /* 0,0,0 */ 477a86ed394SVijay Mahadevan phi[offset + 1] = ( r ) * ( 1.0 - s ) * ( 1.0 - t ); /* 1,0,0 */ 478a86ed394SVijay Mahadevan phi[offset + 2] = ( r ) * ( s ) * ( 1.0 - t ); /* 1,1,0 */ 479a86ed394SVijay Mahadevan phi[offset + 3] = ( 1.0 - r ) * ( s ) * ( 1.0 - t ); /* 0,1,0 */ 480a86ed394SVijay Mahadevan phi[offset + 4] = ( 1.0 - r ) * ( 1.0 - s ) * ( t ); /* 0,0,1 */ 481a86ed394SVijay Mahadevan phi[offset + 5] = ( r ) * ( 1.0 - s ) * ( t ); /* 1,0,1 */ 482a86ed394SVijay Mahadevan phi[offset + 6] = ( r ) * ( s ) * ( t ); /* 1,1,1 */ 483a86ed394SVijay Mahadevan phi[offset + 7] = ( 1.0 - r ) * ( s ) * ( t ); /* 0,1,1 */ 48463d025dbSVijay Mahadevan 485181f196bSVijay Mahadevan const PetscReal dNi_dxi[8] = {- ( 1.0 - s ) * ( 1.0 - t ), 48663d025dbSVijay Mahadevan ( 1.0 - s ) * ( 1.0 - t ), 487a86ed394SVijay Mahadevan ( s ) * ( 1.0 - t ), 488a86ed394SVijay Mahadevan - ( s ) * ( 1.0 - t ), 489a86ed394SVijay Mahadevan - ( 1.0 - s ) * ( t ), 490a86ed394SVijay Mahadevan ( 1.0 - s ) * ( t ), 491a86ed394SVijay Mahadevan ( s ) * ( t ), 492a86ed394SVijay Mahadevan - ( s ) * ( t ) 49363d025dbSVijay Mahadevan }; 49463d025dbSVijay Mahadevan 495181f196bSVijay Mahadevan const PetscReal dNi_deta[8] = { - ( 1.0 - r ) * ( 1.0 - t ), 496a86ed394SVijay Mahadevan - ( r ) * ( 1.0 - t ), 497a86ed394SVijay Mahadevan ( r ) * ( 1.0 - t ), 49863d025dbSVijay Mahadevan ( 1.0 - r ) * ( 1.0 - t ), 499a86ed394SVijay Mahadevan - ( 1.0 - r ) * ( t ), 500a86ed394SVijay Mahadevan - ( r ) * ( t ), 501a86ed394SVijay Mahadevan ( r ) * ( t ), 502a86ed394SVijay Mahadevan ( 1.0 - r ) * ( t ) 50363d025dbSVijay Mahadevan }; 50463d025dbSVijay Mahadevan 505181f196bSVijay Mahadevan const PetscReal dNi_dzeta[8] = { - ( 1.0 - r ) * ( 1.0 - s ), 506a86ed394SVijay Mahadevan - ( r ) * ( 1.0 - s ), 507a86ed394SVijay Mahadevan - ( r ) * ( s ), 508a86ed394SVijay Mahadevan - ( 1.0 - r ) * ( s ), 50963d025dbSVijay Mahadevan ( 1.0 - r ) * ( 1.0 - s ), 510a86ed394SVijay Mahadevan ( r ) * ( 1.0 - s ), 511a86ed394SVijay Mahadevan ( r ) * ( s ), 512a86ed394SVijay Mahadevan ( 1.0 - r ) * ( s ) 51363d025dbSVijay Mahadevan }; 51463d025dbSVijay Mahadevan 515*580bdb30SBarry Smith ierr = PetscArrayzero(jacobian, 9);CHKERRQ(ierr); 516*580bdb30SBarry Smith ierr = PetscArrayzero(ijacobian, 9);CHKERRQ(ierr); 51763d025dbSVijay Mahadevan for (i = 0; i < nverts; ++i) { 518181f196bSVijay Mahadevan const PetscReal* vertex = coords + i * 3; 51963d025dbSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertex[0]; 52063d025dbSVijay Mahadevan jacobian[3] += dNi_dxi[i] * vertex[1]; 52163d025dbSVijay Mahadevan jacobian[6] += dNi_dxi[i] * vertex[2]; 52263d025dbSVijay Mahadevan jacobian[1] += dNi_deta[i] * vertex[0]; 52363d025dbSVijay Mahadevan jacobian[4] += dNi_deta[i] * vertex[1]; 52463d025dbSVijay Mahadevan jacobian[7] += dNi_deta[i] * vertex[2]; 52563d025dbSVijay Mahadevan jacobian[2] += dNi_dzeta[i] * vertex[0]; 52663d025dbSVijay Mahadevan jacobian[5] += dNi_dzeta[i] * vertex[1]; 52763d025dbSVijay Mahadevan jacobian[8] += dNi_dzeta[i] * vertex[2]; 528181f196bSVijay Mahadevan if (phypts) { 529181f196bSVijay Mahadevan phypts[3 * j + 0] += phi[i + offset] * vertex[0]; 530181f196bSVijay Mahadevan phypts[3 * j + 1] += phi[i + offset] * vertex[1]; 531181f196bSVijay Mahadevan phypts[3 * j + 2] += phi[i + offset] * vertex[2]; 532181f196bSVijay Mahadevan } 53363d025dbSVijay Mahadevan } 53463d025dbSVijay Mahadevan 53563d025dbSVijay Mahadevan /* invert the jacobian */ 536181f196bSVijay Mahadevan ierr = DMatrix_Invert_3x3_Internal(jacobian, ijacobian, volume);CHKERRQ(ierr); 537a86ed394SVijay 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); 53863d025dbSVijay Mahadevan 539a86ed394SVijay Mahadevan if (jxw) jxw[j] *= (*volume); 54063d025dbSVijay Mahadevan 54163d025dbSVijay Mahadevan /* Divide by element jacobian. */ 54263d025dbSVijay Mahadevan for ( i = 0; i < nverts; ++i ) { 543a86ed394SVijay Mahadevan for ( k = 0; k < 3; ++k) { 54463d025dbSVijay Mahadevan if (dphidx) dphidx[i + offset] += dNi_dxi[i] * ijacobian[0 * 3 + k]; 54563d025dbSVijay Mahadevan if (dphidy) dphidy[i + offset] += dNi_deta[i] * ijacobian[1 * 3 + k]; 54663d025dbSVijay Mahadevan if (dphidz) dphidz[i + offset] += dNi_dzeta[i] * ijacobian[2 * 3 + k]; 54763d025dbSVijay Mahadevan } 54863d025dbSVijay Mahadevan } 54963d025dbSVijay Mahadevan } 55063d025dbSVijay Mahadevan } 55163d025dbSVijay Mahadevan else if (nverts == 4) { /* Linear Tetrahedra */ 55263d025dbSVijay Mahadevan 553*580bdb30SBarry Smith ierr = PetscArrayzero(jacobian, 9);CHKERRQ(ierr); 554*580bdb30SBarry Smith ierr = PetscArrayzero(ijacobian, 9);CHKERRQ(ierr); 55563d025dbSVijay Mahadevan 556181f196bSVijay Mahadevan const PetscReal x0 = coords[/*0 * 3 +*/ 0], y0 = coords[/*0 * 3 +*/ 1], z0 = coords[/*0 * 3 +*/ 2]; 557181f196bSVijay Mahadevan 558181f196bSVijay Mahadevan /* compute the jacobian */ 559181f196bSVijay Mahadevan jacobian[0] = coords[1 * 3 + 0] - x0; jacobian[1] = coords[2 * 3 + 0] - x0; jacobian[2] = coords[3 * 3 + 0] - x0; 560181f196bSVijay Mahadevan jacobian[3] = coords[1 * 3 + 1] - y0; jacobian[4] = coords[2 * 3 + 1] - y0; jacobian[5] = coords[3 * 3 + 1] - y0; 561181f196bSVijay Mahadevan jacobian[6] = coords[1 * 3 + 2] - z0; jacobian[7] = coords[2 * 3 + 2] - z0; jacobian[8] = coords[3 * 3 + 2] - z0; 56263d025dbSVijay Mahadevan 56363d025dbSVijay Mahadevan /* invert the jacobian */ 564181f196bSVijay Mahadevan ierr = DMatrix_Invert_3x3_Internal(jacobian, ijacobian, volume);CHKERRQ(ierr); 565a86ed394SVijay 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); 56663d025dbSVijay Mahadevan 5676ea892caSVijay Mahadevan PetscReal Dx[4]={0,0,0,0}, Dy[4]={0,0,0,0}, Dz[4]={0,0,0,0}; 568181f196bSVijay Mahadevan if (dphidx) { 569181f196bSVijay Mahadevan Dx[0] = ( coords[1 + 2 * 3] * ( coords[2 + 1 * 3] - coords[2 + 3 * 3] ) 570181f196bSVijay Mahadevan - coords[1 + 1 * 3] * ( coords[2 + 2 * 3] - coords[2 + 3 * 3] ) 571181f196bSVijay Mahadevan - coords[1 + 3 * 3] * ( coords[2 + 1 * 3] - coords[2 + 2 * 3] ) 572181f196bSVijay Mahadevan ) / *volume; 573181f196bSVijay Mahadevan Dx[1] = - ( coords[1 + 2 * 3] * ( coords[2 + 0 * 3] - coords[2 + 3 * 3] ) 574181f196bSVijay Mahadevan - coords[1 + 0 * 3] * ( coords[2 + 2 * 3] - coords[2 + 3 * 3] ) 575181f196bSVijay Mahadevan - coords[1 + 3 * 3] * ( coords[2 + 0 * 3] - coords[2 + 2 * 3] ) 576181f196bSVijay Mahadevan ) / *volume; 577181f196bSVijay Mahadevan Dx[2] = ( coords[1 + 1 * 3] * ( coords[2 + 0 * 3] - coords[2 + 3 * 3] ) 578181f196bSVijay Mahadevan - coords[1 + 0 * 3] * ( coords[2 + 1 * 3] - coords[2 + 3 * 3] ) 579181f196bSVijay Mahadevan - coords[1 + 3 * 3] * ( coords[2 + 0 * 3] - coords[2 + 1 * 3] ) 580181f196bSVijay Mahadevan ) / *volume; 581181f196bSVijay Mahadevan Dx[3] = - ( Dx[0] + Dx[1] + Dx[2] ); 582181f196bSVijay Mahadevan Dy[0] = ( coords[0 + 1 * 3] * ( coords[2 + 2 * 3] - coords[2 + 3 * 3] ) 583181f196bSVijay Mahadevan - coords[0 + 2 * 3] * ( coords[2 + 1 * 3] - coords[2 + 3 * 3] ) 584181f196bSVijay Mahadevan + coords[0 + 3 * 3] * ( coords[2 + 1 * 3] - coords[2 + 2 * 3] ) 585181f196bSVijay Mahadevan ) / *volume; 586181f196bSVijay Mahadevan Dy[1] = - ( coords[0 + 0 * 3] * ( coords[2 + 2 * 3] - coords[2 + 3 * 3] ) 587181f196bSVijay Mahadevan - coords[0 + 2 * 3] * ( coords[2 + 0 * 3] - coords[2 + 3 * 3] ) 588181f196bSVijay Mahadevan + coords[0 + 3 * 3] * ( coords[2 + 0 * 3] - coords[2 + 2 * 3] ) 589181f196bSVijay Mahadevan ) / *volume; 590181f196bSVijay Mahadevan Dy[2] = ( coords[0 + 0 * 3] * ( coords[2 + 1 * 3] - coords[2 + 3 * 3] ) 591181f196bSVijay Mahadevan - coords[0 + 1 * 3] * ( coords[2 + 0 * 3] - coords[2 + 3 * 3] ) 592181f196bSVijay Mahadevan + coords[0 + 3 * 3] * ( coords[2 + 0 * 3] - coords[2 + 1 * 3] ) 593181f196bSVijay Mahadevan ) / *volume; 594181f196bSVijay Mahadevan Dy[3] = - ( Dy[0] + Dy[1] + Dy[2] ); 595181f196bSVijay Mahadevan Dz[0] = ( coords[0 + 1 * 3] * (coords[1 + 3 * 3] - coords[1 + 2 * 3] ) 596181f196bSVijay Mahadevan - coords[0 + 2 * 3] * (coords[1 + 3 * 3] - coords[1 + 1 * 3] ) 597181f196bSVijay Mahadevan + coords[0 + 3 * 3] * (coords[1 + 2 * 3] - coords[1 + 1 * 3] ) 598181f196bSVijay Mahadevan ) / *volume; 599181f196bSVijay Mahadevan Dz[1] = - ( coords[0 + 0 * 3] * (coords[1 + 3 * 3] - coords[1 + 2 * 3] ) 600181f196bSVijay Mahadevan + coords[0 + 2 * 3] * (coords[1 + 0 * 3] - coords[1 + 3 * 3] ) 601181f196bSVijay Mahadevan - coords[0 + 3 * 3] * (coords[1 + 0 * 3] - coords[1 + 2 * 3] ) 602181f196bSVijay Mahadevan ) / *volume; 603181f196bSVijay Mahadevan Dz[2] = ( coords[0 + 0 * 3] * (coords[1 + 3 * 3] - coords[1 + 1 * 3] ) 604181f196bSVijay Mahadevan + coords[0 + 1 * 3] * (coords[1 + 0 * 3] - coords[1 + 3 * 3] ) 605181f196bSVijay Mahadevan - coords[0 + 3 * 3] * (coords[1 + 0 * 3] - coords[1 + 1 * 3] ) 606181f196bSVijay Mahadevan ) / *volume; 607181f196bSVijay Mahadevan Dz[3] = - ( Dz[0] + Dz[1] + Dz[2] ); 608181f196bSVijay Mahadevan } 60963d025dbSVijay Mahadevan 61063d025dbSVijay Mahadevan for ( j = 0; j < npts; j++ ) 61163d025dbSVijay Mahadevan { 612a86ed394SVijay Mahadevan const PetscInt offset = j * nverts; 613181f196bSVijay Mahadevan const PetscReal& r = quad[j * 3 + 0]; 614181f196bSVijay Mahadevan const PetscReal& s = quad[j * 3 + 1]; 615181f196bSVijay Mahadevan const PetscReal& t = quad[j * 3 + 2]; 61663d025dbSVijay Mahadevan 617181f196bSVijay Mahadevan if (jxw) jxw[j] *= *volume; 61863d025dbSVijay Mahadevan 61963d025dbSVijay Mahadevan phi[offset + 0] = 1.0 - r - s - t; 62063d025dbSVijay Mahadevan phi[offset + 1] = r; 62163d025dbSVijay Mahadevan phi[offset + 2] = s; 62263d025dbSVijay Mahadevan phi[offset + 3] = t; 62363d025dbSVijay Mahadevan 624181f196bSVijay Mahadevan if (phypts) { 625181f196bSVijay Mahadevan for (i = 0; i < nverts; ++i) { 626181f196bSVijay Mahadevan const PetscScalar* vertices = coords + i * 3; 627181f196bSVijay Mahadevan phypts[3 * j + 0] += phi[i + offset] * vertices[0]; 628181f196bSVijay Mahadevan phypts[3 * j + 1] += phi[i + offset] * vertices[1]; 629181f196bSVijay Mahadevan phypts[3 * j + 2] += phi[i + offset] * vertices[2]; 630181f196bSVijay Mahadevan } 631181f196bSVijay Mahadevan } 632181f196bSVijay Mahadevan 633181f196bSVijay Mahadevan /* Now set the derivatives */ 63463d025dbSVijay Mahadevan if (dphidx) { 635181f196bSVijay Mahadevan dphidx[0 + offset] = Dx[0]; 636181f196bSVijay Mahadevan dphidx[1 + offset] = Dx[1]; 637181f196bSVijay Mahadevan dphidx[2 + offset] = Dx[2]; 638181f196bSVijay Mahadevan dphidx[3 + offset] = Dx[3]; 63963d025dbSVijay Mahadevan 640181f196bSVijay Mahadevan dphidy[0 + offset] = Dy[0]; 641181f196bSVijay Mahadevan dphidy[1 + offset] = Dy[1]; 642181f196bSVijay Mahadevan dphidy[2 + offset] = Dy[2]; 643181f196bSVijay Mahadevan dphidy[3 + offset] = Dy[3]; 64463d025dbSVijay Mahadevan 645181f196bSVijay Mahadevan dphidz[0 + offset] = Dz[0]; 646181f196bSVijay Mahadevan dphidz[1 + offset] = Dz[1]; 647181f196bSVijay Mahadevan dphidz[2 + offset] = Dz[2]; 648181f196bSVijay Mahadevan dphidz[3 + offset] = Dz[3]; 64963d025dbSVijay Mahadevan } 65063d025dbSVijay Mahadevan 65163d025dbSVijay Mahadevan } /* Tetrahedra -- ends */ 65263d025dbSVijay Mahadevan } 65363d025dbSVijay Mahadevan else 65463d025dbSVijay Mahadevan { 65563d025dbSVijay 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); 65663d025dbSVijay Mahadevan } 65763d025dbSVijay Mahadevan #if 0 65863d025dbSVijay Mahadevan /* verify if the computed basis functions are consistent */ 65963d025dbSVijay Mahadevan for ( j = 0; j < npts; j++ ) { 66063d025dbSVijay Mahadevan PetscScalar phisum = 0, dphixsum = 0, dphiysum = 0, dphizsum = 0; 66163d025dbSVijay Mahadevan const int offset = j * nverts; 66263d025dbSVijay Mahadevan for ( i = 0; i < nverts; i++ ) { 66363d025dbSVijay Mahadevan phisum += phi[i + offset]; 66463d025dbSVijay Mahadevan if (dphidx) dphixsum += dphidx[i + offset]; 66563d025dbSVijay Mahadevan if (dphidy) dphiysum += dphidy[i + offset]; 66663d025dbSVijay Mahadevan if (dphidz) dphizsum += dphidz[i + offset]; 66763d025dbSVijay 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]); 66863d025dbSVijay Mahadevan } 66963d025dbSVijay 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); 67063d025dbSVijay Mahadevan } 67163d025dbSVijay Mahadevan #endif 67263d025dbSVijay Mahadevan PetscFunctionReturn(0); 67363d025dbSVijay Mahadevan } 67463d025dbSVijay Mahadevan 67563d025dbSVijay Mahadevan 67663d025dbSVijay Mahadevan 67763d025dbSVijay Mahadevan /*@ 67897b73a88SSatish Balay DMMoabFEMComputeBasis - Evaluate bases and derivatives at quadrature points for a linear EDGE/QUAD/TRI/HEX/TET element. 67963d025dbSVijay Mahadevan 68063d025dbSVijay Mahadevan The routine takes the coordinates of the vertices of an element and computes basis functions associated with 68163d025dbSVijay Mahadevan each quadrature point provided, and their derivatives with respect to X, Y and Z as appropriate. 68263d025dbSVijay Mahadevan 68363d025dbSVijay Mahadevan Input Parameter: 68463d025dbSVijay Mahadevan 68563d025dbSVijay Mahadevan . PetscInt nverts, the number of element vertices 68663d025dbSVijay Mahadevan . PetscReal coords[3*nverts], the physical coordinates of the vertices (in canonical numbering) 68763d025dbSVijay Mahadevan . PetscInt npts, the number of evaluation points (quadrature points) 68863d025dbSVijay Mahadevan . PetscReal quad[3*npts], the evaluation points (quadrature points) in the reference space 68963d025dbSVijay Mahadevan 69063d025dbSVijay Mahadevan Output Parameter: 69163d025dbSVijay Mahadevan . PetscReal phypts[3*npts], the evaluation points (quadrature points) transformed to the physical space 69263d025dbSVijay Mahadevan . PetscReal jxw[npts], the jacobian determinant * quadrature weight necessary for assembling discrete contributions 69363d025dbSVijay Mahadevan . PetscReal fe_basis[npts], the bases values evaluated at the specified quadrature points 69463d025dbSVijay 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 69563d025dbSVijay Mahadevan 696edc382c3SSatish Balay Level: advanced 697edc382c3SSatish Balay 69863d025dbSVijay Mahadevan @*/ 699181f196bSVijay Mahadevan PetscErrorCode DMMoabFEMComputeBasis ( const PetscInt dim, const PetscInt nverts, const PetscReal *coordinates, const PetscQuadrature quadrature, 700181f196bSVijay Mahadevan PetscReal *phypts, PetscReal *jacobian_quadrature_weight_product, 701181f196bSVijay Mahadevan PetscReal *fe_basis, PetscReal **fe_basis_derivatives) 70263d025dbSVijay Mahadevan { 70363d025dbSVijay Mahadevan PetscErrorCode ierr; 704b21a1e88SVijay Mahadevan PetscInt npoints,idim; 70563d025dbSVijay Mahadevan bool compute_der; 70663d025dbSVijay Mahadevan const PetscReal *quadpts, *quadwts; 707181f196bSVijay Mahadevan PetscReal jacobian[9], ijacobian[9], volume; 70863d025dbSVijay Mahadevan 70963d025dbSVijay Mahadevan PetscFunctionBegin; 71063d025dbSVijay Mahadevan PetscValidPointer(coordinates, 3); 71163d025dbSVijay Mahadevan PetscValidHeaderSpecific(quadrature, PETSC_OBJECT_CLASSID, 4); 71263d025dbSVijay Mahadevan PetscValidPointer(fe_basis, 7); 71363d025dbSVijay Mahadevan compute_der = (fe_basis_derivatives != NULL); 71463d025dbSVijay Mahadevan 71563d025dbSVijay Mahadevan /* Get the quadrature points and weights for the given quadrature rule */ 716b21a1e88SVijay Mahadevan ierr = PetscQuadratureGetData(quadrature, &idim, NULL, &npoints, &quadpts, &quadwts);CHKERRQ(ierr); 717b21a1e88SVijay Mahadevan if (idim != dim) SETERRQ2(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Dimension mismatch: provided (%D) vs quadrature (%D)\n",idim,dim); 718181f196bSVijay Mahadevan if (jacobian_quadrature_weight_product) { 719*580bdb30SBarry Smith ierr = PetscArraycpy(jacobian_quadrature_weight_product, quadwts, npoints);CHKERRQ(ierr); 720181f196bSVijay Mahadevan } 72163d025dbSVijay Mahadevan 72263d025dbSVijay Mahadevan switch (dim) { 72363d025dbSVijay Mahadevan case 1: 72463d025dbSVijay Mahadevan ierr = Compute_Lagrange_Basis_1D_Internal(nverts, coordinates, npoints, quadpts, phypts, 72563d025dbSVijay Mahadevan jacobian_quadrature_weight_product, fe_basis, 726181f196bSVijay Mahadevan (compute_der ? fe_basis_derivatives[0] : NULL), 727181f196bSVijay Mahadevan jacobian, ijacobian, &volume);CHKERRQ(ierr); 72863d025dbSVijay Mahadevan break; 72963d025dbSVijay Mahadevan case 2: 73063d025dbSVijay Mahadevan ierr = Compute_Lagrange_Basis_2D_Internal(nverts, coordinates, npoints, quadpts, phypts, 73163d025dbSVijay Mahadevan jacobian_quadrature_weight_product, fe_basis, 73263d025dbSVijay Mahadevan (compute_der ? fe_basis_derivatives[0] : NULL), 733181f196bSVijay Mahadevan (compute_der ? fe_basis_derivatives[1] : NULL), 734181f196bSVijay Mahadevan jacobian, ijacobian, &volume);CHKERRQ(ierr); 73563d025dbSVijay Mahadevan break; 73663d025dbSVijay Mahadevan case 3: 73763d025dbSVijay Mahadevan ierr = Compute_Lagrange_Basis_3D_Internal(nverts, coordinates, npoints, quadpts, phypts, 73863d025dbSVijay Mahadevan jacobian_quadrature_weight_product, fe_basis, 73963d025dbSVijay Mahadevan (compute_der ? fe_basis_derivatives[0] : NULL), 74063d025dbSVijay Mahadevan (compute_der ? fe_basis_derivatives[1] : NULL), 741181f196bSVijay Mahadevan (compute_der ? fe_basis_derivatives[2] : NULL), 742181f196bSVijay Mahadevan jacobian, ijacobian, &volume);CHKERRQ(ierr); 74363d025dbSVijay Mahadevan break; 74463d025dbSVijay Mahadevan default: 74563d025dbSVijay Mahadevan SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension; should be in [1,3] : %D", dim); 74663d025dbSVijay Mahadevan } 74763d025dbSVijay Mahadevan PetscFunctionReturn(0); 74863d025dbSVijay Mahadevan } 74963d025dbSVijay Mahadevan 75063d025dbSVijay Mahadevan 75163d025dbSVijay Mahadevan 75263d025dbSVijay Mahadevan /*@ 75397b73a88SSatish Balay DMMoabFEMCreateQuadratureDefault - Create default quadrature rules for integration over an element with a given 75463d025dbSVijay Mahadevan dimension and polynomial order (deciphered from number of element vertices). 75563d025dbSVijay Mahadevan 75663d025dbSVijay Mahadevan Input Parameter: 75763d025dbSVijay Mahadevan 75863d025dbSVijay Mahadevan . PetscInt dim, the element dimension (1=EDGE, 2=QUAD/TRI, 3=HEX/TET) 75963d025dbSVijay Mahadevan . PetscInt nverts, the number of vertices in the physical element 76063d025dbSVijay Mahadevan 76163d025dbSVijay Mahadevan Output Parameter: 76263d025dbSVijay Mahadevan . PetscQuadrature quadrature, the quadrature object with default settings to integrate polynomials defined over the element 76363d025dbSVijay Mahadevan 764edc382c3SSatish Balay Level: advanced 765edc382c3SSatish Balay 76663d025dbSVijay Mahadevan @*/ 767181f196bSVijay Mahadevan PetscErrorCode DMMoabFEMCreateQuadratureDefault ( const PetscInt dim, const PetscInt nverts, PetscQuadrature *quadrature ) 76863d025dbSVijay Mahadevan { 76963d025dbSVijay Mahadevan PetscReal *w, *x; 770b21a1e88SVijay Mahadevan PetscInt nc=1; 77163d025dbSVijay Mahadevan PetscErrorCode ierr; 77263d025dbSVijay Mahadevan 77363d025dbSVijay Mahadevan PetscFunctionBegin; 77463d025dbSVijay Mahadevan /* Create an appropriate quadrature rule to sample basis */ 77563d025dbSVijay Mahadevan switch (dim) 77663d025dbSVijay Mahadevan { 77763d025dbSVijay Mahadevan case 1: 77863d025dbSVijay Mahadevan /* Create Gauss quadrature rules with <order = nverts> in the span [-1, 1] */ 779b21a1e88SVijay Mahadevan ierr = PetscDTGaussJacobiQuadrature(1, nc, nverts, 0, 1.0, quadrature);CHKERRQ(ierr); 78063d025dbSVijay Mahadevan break; 78163d025dbSVijay Mahadevan case 2: 78263d025dbSVijay Mahadevan /* Create Gauss quadrature rules with <order = nverts> in the span [-1, 1] */ 78363d025dbSVijay Mahadevan if (nverts == 3) { 784a86ed394SVijay Mahadevan const PetscInt order = 2; 785a86ed394SVijay Mahadevan const PetscInt npoints = (order == 2 ? 3 : 6); 78663d025dbSVijay Mahadevan ierr = PetscMalloc2(npoints * 2, &x, npoints, &w);CHKERRQ(ierr); 787181f196bSVijay Mahadevan if (npoints == 3) { 78863d025dbSVijay Mahadevan x[0] = x[1] = x[2] = x[5] = 1.0 / 6.0; 78963d025dbSVijay Mahadevan x[3] = x[4] = 2.0 / 3.0; 79063d025dbSVijay Mahadevan w[0] = w[1] = w[2] = 1.0 / 3.0; 791181f196bSVijay Mahadevan } 792181f196bSVijay Mahadevan else if (npoints == 6) { 79363d025dbSVijay Mahadevan x[0] = x[1] = x[2] = 0.44594849091597; 79463d025dbSVijay Mahadevan x[3] = x[4] = 0.10810301816807; 79563d025dbSVijay Mahadevan x[5] = 0.44594849091597; 79663d025dbSVijay Mahadevan x[6] = x[7] = x[8] = 0.09157621350977; 79763d025dbSVijay Mahadevan x[9] = x[10] = 0.81684757298046; 79863d025dbSVijay Mahadevan x[11] = 0.09157621350977; 79963d025dbSVijay Mahadevan w[0] = w[1] = w[2] = 0.22338158967801; 800181f196bSVijay Mahadevan w[3] = w[4] = w[5] = 0.10995174365532; 801181f196bSVijay Mahadevan } 802181f196bSVijay Mahadevan else { 803181f196bSVijay Mahadevan SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Triangle quadrature rules for points 3 and 6 supported; npoints : %D", npoints); 80463d025dbSVijay Mahadevan } 80563d025dbSVijay Mahadevan ierr = PetscQuadratureCreate(PETSC_COMM_SELF, quadrature);CHKERRQ(ierr); 80663d025dbSVijay Mahadevan ierr = PetscQuadratureSetOrder(*quadrature, order);CHKERRQ(ierr); 807b21a1e88SVijay Mahadevan ierr = PetscQuadratureSetData(*quadrature, dim, nc, npoints, x, w);CHKERRQ(ierr); 808181f196bSVijay Mahadevan /* ierr = PetscDTGaussJacobiQuadrature(dim, nverts, 0.0, 1.0, quadrature);CHKERRQ(ierr); */ 80963d025dbSVijay Mahadevan } 81063d025dbSVijay Mahadevan else { 811b21a1e88SVijay Mahadevan ierr = PetscDTGaussTensorQuadrature(dim, nc, nverts, 0.0, 1.0, quadrature);CHKERRQ(ierr); 81263d025dbSVijay Mahadevan } 81363d025dbSVijay Mahadevan break; 81463d025dbSVijay Mahadevan case 3: 81563d025dbSVijay Mahadevan /* Create Gauss quadrature rules with <order = nverts> in the span [-1, 1] */ 81663d025dbSVijay Mahadevan if (nverts == 4) { 817a86ed394SVijay Mahadevan PetscInt order; 818a86ed394SVijay Mahadevan const PetscInt npoints = 4; // Choose between 4 and 10 819181f196bSVijay Mahadevan ierr = PetscMalloc2(npoints * 3, &x, npoints, &w);CHKERRQ(ierr); 820181f196bSVijay Mahadevan if (npoints == 4) { /* KEAST1, K1, N=4, O=4 */ 821181f196bSVijay Mahadevan const PetscReal x_4[12] = { 0.5854101966249685, 0.1381966011250105, 0.1381966011250105, 822181f196bSVijay Mahadevan 0.1381966011250105, 0.1381966011250105, 0.1381966011250105, 823181f196bSVijay Mahadevan 0.1381966011250105, 0.1381966011250105, 0.5854101966249685, 824181f196bSVijay Mahadevan 0.1381966011250105, 0.5854101966249685, 0.1381966011250105 825181f196bSVijay Mahadevan }; 826*580bdb30SBarry Smith ierr = PetscArraycpy(x, x_4, 12);CHKERRQ(ierr); 827181f196bSVijay Mahadevan 828181f196bSVijay Mahadevan w[0] = w[1] = w[2] = w[3] = 1.0 / 24.0; 829181f196bSVijay Mahadevan order = 4; 830181f196bSVijay Mahadevan } 831181f196bSVijay Mahadevan else if (npoints == 10) { /* KEAST3, K3 N=10, O=10 */ 832181f196bSVijay Mahadevan const PetscReal x_10[30] = { 0.5684305841968444, 0.1438564719343852, 0.1438564719343852, 833181f196bSVijay Mahadevan 0.1438564719343852, 0.1438564719343852, 0.1438564719343852, 834181f196bSVijay Mahadevan 0.1438564719343852, 0.1438564719343852, 0.5684305841968444, 835181f196bSVijay Mahadevan 0.1438564719343852, 0.5684305841968444, 0.1438564719343852, 836181f196bSVijay Mahadevan 0.0000000000000000, 0.5000000000000000, 0.5000000000000000, 837181f196bSVijay Mahadevan 0.5000000000000000, 0.0000000000000000, 0.5000000000000000, 838181f196bSVijay Mahadevan 0.5000000000000000, 0.5000000000000000, 0.0000000000000000, 839181f196bSVijay Mahadevan 0.5000000000000000, 0.0000000000000000, 0.0000000000000000, 840181f196bSVijay Mahadevan 0.0000000000000000, 0.5000000000000000, 0.0000000000000000, 841181f196bSVijay Mahadevan 0.0000000000000000, 0.0000000000000000, 0.5000000000000000 842181f196bSVijay Mahadevan }; 843*580bdb30SBarry Smith ierr = PetscArraycpy(x, x_10, 30);CHKERRQ(ierr); 844181f196bSVijay Mahadevan 845181f196bSVijay Mahadevan w[0] = w[1] = w[2] = w[3] = 0.2177650698804054; 846181f196bSVijay Mahadevan w[4] = w[5] = w[6] = w[7] = w[8] = w[9] = 0.0214899534130631; 847181f196bSVijay Mahadevan order = 10; 848181f196bSVijay Mahadevan } 849181f196bSVijay Mahadevan else { 850181f196bSVijay Mahadevan SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Tetrahedral quadrature rules for points 4 and 10 supported; npoints : %D", npoints); 851181f196bSVijay Mahadevan } 852181f196bSVijay Mahadevan ierr = PetscQuadratureCreate(PETSC_COMM_SELF, quadrature);CHKERRQ(ierr); 853181f196bSVijay Mahadevan ierr = PetscQuadratureSetOrder(*quadrature, order);CHKERRQ(ierr); 854b21a1e88SVijay Mahadevan ierr = PetscQuadratureSetData(*quadrature, dim, nc, npoints, x, w);CHKERRQ(ierr); 855181f196bSVijay Mahadevan /* ierr = PetscDTGaussJacobiQuadrature(dim, nverts, 0.0, 1.0, quadrature);CHKERRQ(ierr); */ 85663d025dbSVijay Mahadevan } 85763d025dbSVijay Mahadevan else { 858b21a1e88SVijay Mahadevan ierr = PetscDTGaussTensorQuadrature(dim, nc, nverts, 0.0, 1.0, quadrature);CHKERRQ(ierr); 85963d025dbSVijay Mahadevan } 86063d025dbSVijay Mahadevan break; 86163d025dbSVijay Mahadevan default: 86263d025dbSVijay Mahadevan SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension; should be in [1,3] : %D", dim); 86363d025dbSVijay Mahadevan } 86463d025dbSVijay Mahadevan PetscFunctionReturn(0); 86563d025dbSVijay Mahadevan } 86663d025dbSVijay Mahadevan 867181f196bSVijay Mahadevan /* Compute Jacobians */ 868181f196bSVijay Mahadevan PetscErrorCode ComputeJacobian_Internal ( const PetscInt dim, const PetscInt nverts, const PetscReal *coordinates, const PetscReal *quad, PetscReal *phypts, 869a86ed394SVijay Mahadevan PetscReal *jacobian, PetscReal *ijacobian, PetscReal* dvolume) 870181f196bSVijay Mahadevan { 871a86ed394SVijay Mahadevan PetscInt i; 8722417220eSVijay Mahadevan PetscReal volume=1.0; 873181f196bSVijay Mahadevan PetscErrorCode ierr; 874181f196bSVijay Mahadevan 875181f196bSVijay Mahadevan PetscFunctionBegin; 876181f196bSVijay Mahadevan PetscValidPointer(coordinates, 3); 877181f196bSVijay Mahadevan PetscValidPointer(quad, 4); 878181f196bSVijay Mahadevan PetscValidPointer(jacobian, 5); 879*580bdb30SBarry Smith ierr = PetscArrayzero(jacobian, dim * dim);CHKERRQ(ierr); 880181f196bSVijay Mahadevan if (ijacobian) { 881*580bdb30SBarry Smith ierr = PetscArrayzero(ijacobian, dim * dim);CHKERRQ(ierr); 882181f196bSVijay Mahadevan } 883181f196bSVijay Mahadevan if (phypts) { 884*580bdb30SBarry Smith ierr = PetscArrayzero(phypts, /*npts=1 * */ 3);CHKERRQ(ierr); 885181f196bSVijay Mahadevan } 886181f196bSVijay Mahadevan 887181f196bSVijay Mahadevan if (dim == 1) { 888181f196bSVijay Mahadevan 889181f196bSVijay Mahadevan const PetscReal& r = quad[0]; 890181f196bSVijay Mahadevan if (nverts == 2) { /* Linear Edge */ 891181f196bSVijay Mahadevan const PetscReal dNi_dxi[2] = { -1.0, 1.0 }; 892181f196bSVijay Mahadevan 893181f196bSVijay Mahadevan for (i = 0; i < nverts; ++i) { 894181f196bSVijay Mahadevan const PetscReal* vertices = coordinates + i * 3; 895181f196bSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertices[0]; 896181f196bSVijay Mahadevan } 897181f196bSVijay Mahadevan } 898181f196bSVijay Mahadevan else if (nverts == 3) { /* Quadratic Edge */ 899181f196bSVijay Mahadevan const PetscReal dNi_dxi[3] = { 4 * r - 3.0, 4 * ( 1.0 - 2.0 * r ), 4.0 * r - 1.0}; 900181f196bSVijay Mahadevan 901181f196bSVijay Mahadevan for (i = 0; i < nverts; ++i) { 902181f196bSVijay Mahadevan const PetscReal* vertices = coordinates + i * 3; 903181f196bSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertices[0]; 904181f196bSVijay Mahadevan } 905181f196bSVijay Mahadevan } 906181f196bSVijay Mahadevan else { 907181f196bSVijay 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); 908181f196bSVijay Mahadevan } 909181f196bSVijay Mahadevan 910181f196bSVijay Mahadevan if (ijacobian) { 911181f196bSVijay Mahadevan /* invert the jacobian */ 912181f196bSVijay Mahadevan ijacobian[0] = 1.0 / jacobian[0]; 913181f196bSVijay Mahadevan } 914181f196bSVijay Mahadevan 915181f196bSVijay Mahadevan } 916181f196bSVijay Mahadevan else if (dim == 2) { 917181f196bSVijay Mahadevan 918181f196bSVijay Mahadevan if (nverts == 4) { /* Linear Quadrangle */ 919181f196bSVijay Mahadevan const PetscReal& r = quad[0]; 920181f196bSVijay Mahadevan const PetscReal& s = quad[1]; 921181f196bSVijay Mahadevan 922181f196bSVijay Mahadevan const PetscReal dNi_dxi[4] = { -1.0 + s, 1.0 - s, s, -s }; 923181f196bSVijay Mahadevan const PetscReal dNi_deta[4] = { -1.0 + r, -r, r, 1.0 - r }; 924181f196bSVijay Mahadevan 925181f196bSVijay Mahadevan for (i = 0; i < nverts; ++i) { 926181f196bSVijay Mahadevan const PetscReal* vertices = coordinates + i * 3; 927181f196bSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertices[0]; 928181f196bSVijay Mahadevan jacobian[2] += dNi_dxi[i] * vertices[1]; 929181f196bSVijay Mahadevan jacobian[1] += dNi_deta[i] * vertices[0]; 930181f196bSVijay Mahadevan jacobian[3] += dNi_deta[i] * vertices[1]; 931181f196bSVijay Mahadevan } 932181f196bSVijay Mahadevan } 933181f196bSVijay Mahadevan else if (nverts == 3) { /* Linear triangle */ 934181f196bSVijay Mahadevan const PetscReal x2 = coordinates[2 * 3 + 0], y2 = coordinates[2 * 3 + 1]; 935181f196bSVijay Mahadevan 936181f196bSVijay Mahadevan /* Jacobian is constant */ 937181f196bSVijay Mahadevan jacobian[0] = (coordinates[0 * 3 + 0] - x2); jacobian[1] = (coordinates[1 * 3 + 0] - x2); 938181f196bSVijay Mahadevan jacobian[2] = (coordinates[0 * 3 + 1] - y2); jacobian[3] = (coordinates[1 * 3 + 1] - y2); 939181f196bSVijay Mahadevan } 940181f196bSVijay Mahadevan else { 941181f196bSVijay 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); 942181f196bSVijay Mahadevan } 943181f196bSVijay Mahadevan 944181f196bSVijay Mahadevan /* invert the jacobian */ 945181f196bSVijay Mahadevan if (ijacobian) { 946a86ed394SVijay Mahadevan ierr = DMatrix_Invert_2x2_Internal(jacobian, ijacobian, &volume);CHKERRQ(ierr); 947181f196bSVijay Mahadevan } 948181f196bSVijay Mahadevan 949181f196bSVijay Mahadevan } 950181f196bSVijay Mahadevan else { 951181f196bSVijay Mahadevan 952181f196bSVijay Mahadevan if (nverts == 8) { /* Linear Hexahedra */ 953181f196bSVijay Mahadevan const PetscReal& r = quad[0]; 954181f196bSVijay Mahadevan const PetscReal& s = quad[1]; 955181f196bSVijay Mahadevan const PetscReal& t = quad[2]; 956181f196bSVijay Mahadevan const PetscReal dNi_dxi[8] = {- ( 1.0 - s ) * ( 1.0 - t ), 957181f196bSVijay Mahadevan ( 1.0 - s ) * ( 1.0 - t ), 958a86ed394SVijay Mahadevan ( s ) * ( 1.0 - t ), 959a86ed394SVijay Mahadevan - ( s ) * ( 1.0 - t ), 960a86ed394SVijay Mahadevan - ( 1.0 - s ) * ( t ), 961a86ed394SVijay Mahadevan ( 1.0 - s ) * ( t ), 962a86ed394SVijay Mahadevan ( s ) * ( t ), 963a86ed394SVijay Mahadevan - ( s ) * ( t ) 964181f196bSVijay Mahadevan }; 965181f196bSVijay Mahadevan 966181f196bSVijay Mahadevan const PetscReal dNi_deta[8] = { - ( 1.0 - r ) * ( 1.0 - t ), 967a86ed394SVijay Mahadevan - ( r ) * ( 1.0 - t ), 968a86ed394SVijay Mahadevan ( r ) * ( 1.0 - t ), 969181f196bSVijay Mahadevan ( 1.0 - r ) * ( 1.0 - t ), 970a86ed394SVijay Mahadevan - ( 1.0 - r ) * ( t ), 971a86ed394SVijay Mahadevan - ( r ) * ( t ), 972a86ed394SVijay Mahadevan ( r ) * ( t ), 973a86ed394SVijay Mahadevan ( 1.0 - r ) * ( t ) 974181f196bSVijay Mahadevan }; 975181f196bSVijay Mahadevan 976181f196bSVijay Mahadevan const PetscReal dNi_dzeta[8] = { - ( 1.0 - r ) * ( 1.0 - s ), 977a86ed394SVijay Mahadevan - ( r ) * ( 1.0 - s ), 978a86ed394SVijay Mahadevan - ( r ) * ( s ), 979a86ed394SVijay Mahadevan - ( 1.0 - r ) * ( s ), 980181f196bSVijay Mahadevan ( 1.0 - r ) * ( 1.0 - s ), 981a86ed394SVijay Mahadevan ( r ) * ( 1.0 - s ), 982a86ed394SVijay Mahadevan ( r ) * ( s ), 983a86ed394SVijay Mahadevan ( 1.0 - r ) * ( s ) 984181f196bSVijay Mahadevan }; 985a86ed394SVijay Mahadevan 986181f196bSVijay Mahadevan for (i = 0; i < nverts; ++i) { 987181f196bSVijay Mahadevan const PetscReal* vertex = coordinates + i * 3; 988181f196bSVijay Mahadevan jacobian[0] += dNi_dxi[i] * vertex[0]; 989181f196bSVijay Mahadevan jacobian[3] += dNi_dxi[i] * vertex[1]; 990181f196bSVijay Mahadevan jacobian[6] += dNi_dxi[i] * vertex[2]; 991181f196bSVijay Mahadevan jacobian[1] += dNi_deta[i] * vertex[0]; 992181f196bSVijay Mahadevan jacobian[4] += dNi_deta[i] * vertex[1]; 993181f196bSVijay Mahadevan jacobian[7] += dNi_deta[i] * vertex[2]; 994181f196bSVijay Mahadevan jacobian[2] += dNi_dzeta[i] * vertex[0]; 995181f196bSVijay Mahadevan jacobian[5] += dNi_dzeta[i] * vertex[1]; 996181f196bSVijay Mahadevan jacobian[8] += dNi_dzeta[i] * vertex[2]; 997181f196bSVijay Mahadevan } 998181f196bSVijay Mahadevan 999181f196bSVijay Mahadevan } 1000181f196bSVijay Mahadevan else if (nverts == 4) { /* Linear Tetrahedra */ 1001181f196bSVijay Mahadevan const PetscReal x0 = coordinates[/*0 * 3 +*/ 0], y0 = coordinates[/*0 * 3 +*/ 1], z0 = coordinates[/*0 * 3 +*/ 2]; 1002181f196bSVijay Mahadevan 1003181f196bSVijay Mahadevan /* compute the jacobian */ 1004181f196bSVijay Mahadevan jacobian[0] = coordinates[1 * 3 + 0] - x0; jacobian[1] = coordinates[2 * 3 + 0] - x0; jacobian[2] = coordinates[3 * 3 + 0] - x0; 1005181f196bSVijay Mahadevan jacobian[3] = coordinates[1 * 3 + 1] - y0; jacobian[4] = coordinates[2 * 3 + 1] - y0; jacobian[5] = coordinates[3 * 3 + 1] - y0; 1006181f196bSVijay Mahadevan jacobian[6] = coordinates[1 * 3 + 2] - z0; jacobian[7] = coordinates[2 * 3 + 2] - z0; jacobian[8] = coordinates[3 * 3 + 2] - z0; 1007181f196bSVijay Mahadevan } /* Tetrahedra -- ends */ 1008181f196bSVijay Mahadevan else 1009181f196bSVijay Mahadevan { 1010181f196bSVijay 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); 1011181f196bSVijay Mahadevan } 1012181f196bSVijay Mahadevan 1013181f196bSVijay Mahadevan if (ijacobian) { 1014181f196bSVijay Mahadevan /* invert the jacobian */ 1015a86ed394SVijay Mahadevan ierr = DMatrix_Invert_3x3_Internal(jacobian, ijacobian, &volume);CHKERRQ(ierr); 1016181f196bSVijay Mahadevan } 1017181f196bSVijay Mahadevan 1018181f196bSVijay Mahadevan } 1019a86ed394SVijay 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); 1020a86ed394SVijay Mahadevan if (dvolume) *dvolume = volume; 1021181f196bSVijay Mahadevan PetscFunctionReturn(0); 1022181f196bSVijay Mahadevan } 1023181f196bSVijay Mahadevan 1024181f196bSVijay Mahadevan 1025181f196bSVijay Mahadevan PetscErrorCode FEMComputeBasis_JandF ( const PetscInt dim, const PetscInt nverts, const PetscReal *coordinates, const PetscReal *quadrature, PetscReal *phypts, 1026181f196bSVijay Mahadevan PetscReal *phibasis, PetscReal *jacobian, PetscReal *ijacobian, PetscReal* volume ) 1027181f196bSVijay Mahadevan { 1028181f196bSVijay Mahadevan PetscErrorCode ierr; 1029181f196bSVijay Mahadevan 1030181f196bSVijay Mahadevan PetscFunctionBegin; 1031181f196bSVijay Mahadevan switch (dim) { 1032181f196bSVijay Mahadevan case 1: 1033181f196bSVijay Mahadevan ierr = Compute_Lagrange_Basis_1D_Internal(nverts, coordinates, 1, quadrature, phypts, 1034181f196bSVijay Mahadevan NULL, phibasis, NULL, jacobian, ijacobian, volume);CHKERRQ(ierr); 1035181f196bSVijay Mahadevan break; 1036181f196bSVijay Mahadevan case 2: 1037181f196bSVijay Mahadevan ierr = Compute_Lagrange_Basis_2D_Internal(nverts, coordinates, 1, quadrature, phypts, 1038181f196bSVijay Mahadevan NULL, phibasis, NULL, NULL, jacobian, ijacobian, volume);CHKERRQ(ierr); 1039181f196bSVijay Mahadevan break; 1040181f196bSVijay Mahadevan case 3: 1041181f196bSVijay Mahadevan ierr = Compute_Lagrange_Basis_3D_Internal(nverts, coordinates, 1, quadrature, phypts, 1042181f196bSVijay Mahadevan NULL, phibasis, NULL, NULL, NULL, jacobian, ijacobian, volume);CHKERRQ(ierr); 1043181f196bSVijay Mahadevan break; 1044181f196bSVijay Mahadevan default: 1045181f196bSVijay Mahadevan SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Invalid dimension; should be in [1,3] : %D", dim); 1046181f196bSVijay Mahadevan } 1047181f196bSVijay Mahadevan PetscFunctionReturn(0); 1048181f196bSVijay Mahadevan } 1049181f196bSVijay Mahadevan 1050181f196bSVijay Mahadevan 1051181f196bSVijay Mahadevan 1052a86ed394SVijay Mahadevan /*@ 105397b73a88SSatish Balay DMMoabPToRMapping - Compute the mapping from the physical coordinate system for a given element to the 1054a86ed394SVijay Mahadevan canonical reference element. In addition to finding the inverse mapping evaluation through Newton iteration, 1055a86ed394SVijay Mahadevan the basis function at the parametric point is also evaluated optionally. 1056a86ed394SVijay Mahadevan 1057a86ed394SVijay Mahadevan Input Parameter: 1058a86ed394SVijay Mahadevan 1059a86ed394SVijay Mahadevan . PetscInt dim, the element dimension (1=EDGE, 2=QUAD/TRI, 3=HEX/TET) 1060a86ed394SVijay Mahadevan . PetscInt nverts, the number of vertices in the physical element 1061a86ed394SVijay Mahadevan . PetscReal coordinates, the coordinates of vertices in the physical element 1062a86ed394SVijay Mahadevan . PetscReal[3] xphy, the coordinates of physical point for which natural coordinates (in reference frame) are sought 1063a86ed394SVijay Mahadevan 1064a86ed394SVijay Mahadevan Output Parameter: 1065a86ed394SVijay Mahadevan . PetscReal[3] natparam, the natural coordinates (in reference frame) corresponding to xphy 1066a86ed394SVijay Mahadevan . PetscReal[nverts] phi, the basis functions evaluated at the natural coordinates (natparam) 1067a86ed394SVijay Mahadevan 1068edc382c3SSatish Balay Level: advanced 1069edc382c3SSatish Balay 1070a86ed394SVijay Mahadevan @*/ 1071181f196bSVijay Mahadevan PetscErrorCode DMMoabPToRMapping( const PetscInt dim, const PetscInt nverts, const PetscReal *coordinates, const PetscReal* xphy, PetscReal* natparam, PetscReal* phi) 1072181f196bSVijay Mahadevan { 1073a86ed394SVijay Mahadevan /* Perform inverse evaluation for the mapping with use of Newton Raphson iteration */ 1074181f196bSVijay Mahadevan const PetscReal tol = 1.0e-10; 1075181f196bSVijay Mahadevan const PetscInt max_iterations = 10; 1076181f196bSVijay Mahadevan const PetscReal error_tol_sqr = tol*tol; 1077181f196bSVijay Mahadevan PetscReal phibasis[8], jacobian[9], ijacobian[9], volume; 1078181f196bSVijay Mahadevan PetscReal phypts[3] = {0.0, 0.0, 0.0}; 1079181f196bSVijay Mahadevan PetscReal delta[3] = {0.0, 0.0, 0.0}; 1080181f196bSVijay Mahadevan PetscErrorCode ierr; 1081181f196bSVijay Mahadevan PetscInt iters=0; 1082181f196bSVijay Mahadevan PetscReal error=1.0; 1083181f196bSVijay Mahadevan 1084181f196bSVijay Mahadevan PetscFunctionBegin; 1085181f196bSVijay Mahadevan PetscValidPointer(coordinates, 3); 1086181f196bSVijay Mahadevan PetscValidPointer(xphy, 4); 1087181f196bSVijay Mahadevan PetscValidPointer(natparam, 5); 1088181f196bSVijay Mahadevan 1089*580bdb30SBarry Smith ierr = PetscArrayzero(jacobian, dim * dim);CHKERRQ(ierr); 1090*580bdb30SBarry Smith ierr = PetscArrayzero(ijacobian, dim * dim);CHKERRQ(ierr); 1091*580bdb30SBarry Smith ierr = PetscArrayzero(phibasis, nverts);CHKERRQ(ierr); 1092181f196bSVijay Mahadevan 1093a86ed394SVijay Mahadevan /* zero initial guess */ 1094a86ed394SVijay Mahadevan natparam[0] = natparam[1] = natparam[2] = 0.0; 1095181f196bSVijay Mahadevan 1096a86ed394SVijay Mahadevan /* Compute delta = evaluate( xi ) - x */ 1097a86ed394SVijay Mahadevan ierr = FEMComputeBasis_JandF ( dim, nverts, coordinates, natparam, phypts, phibasis, jacobian, ijacobian, &volume );CHKERRQ(ierr); 1098a86ed394SVijay Mahadevan 1099a86ed394SVijay Mahadevan error = 0.0; 1100a86ed394SVijay Mahadevan switch(dim) { 1101a86ed394SVijay Mahadevan case 3: 1102181f196bSVijay Mahadevan delta[2] = phypts[2] - xphy[2]; 1103a86ed394SVijay Mahadevan error += (delta[2]*delta[2]); 1104a86ed394SVijay Mahadevan case 2: 1105a86ed394SVijay Mahadevan delta[1] = phypts[1] - xphy[1]; 1106a86ed394SVijay Mahadevan error += (delta[1]*delta[1]); 1107a86ed394SVijay Mahadevan case 1: 1108a86ed394SVijay Mahadevan delta[0] = phypts[0] - xphy[0]; 1109a86ed394SVijay Mahadevan error += (delta[0]*delta[0]); 1110a86ed394SVijay Mahadevan break; 1111a86ed394SVijay Mahadevan } 1112a86ed394SVijay Mahadevan 1113a86ed394SVijay Mahadevan #if 0 1114a86ed394SVijay Mahadevan PetscInfo4(NULL, "Current point in physical space : (%g, %g, %g) and error : %g\n", xphy[0], xphy[1], xphy[2], error); 1115a86ed394SVijay Mahadevan #endif 1116181f196bSVijay Mahadevan 1117181f196bSVijay Mahadevan while (error > error_tol_sqr) { 1118181f196bSVijay Mahadevan 1119181f196bSVijay Mahadevan if(++iters > max_iterations) 1120181f196bSVijay 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]); 1121181f196bSVijay Mahadevan 1122181f196bSVijay Mahadevan /* Compute natparam -= J.inverse() * delta */ 1123181f196bSVijay Mahadevan switch(dim) { 1124181f196bSVijay Mahadevan case 1: 1125181f196bSVijay Mahadevan natparam[0] -= ijacobian[0] * delta[0]; 1126181f196bSVijay Mahadevan break; 1127181f196bSVijay Mahadevan case 2: 1128181f196bSVijay Mahadevan natparam[0] -= ijacobian[0] * delta[0] + ijacobian[1] * delta[1]; 1129181f196bSVijay Mahadevan natparam[1] -= ijacobian[2] * delta[0] + ijacobian[3] * delta[1]; 1130181f196bSVijay Mahadevan break; 1131181f196bSVijay Mahadevan case 3: 1132181f196bSVijay Mahadevan natparam[0] -= ijacobian[0] * delta[0] + ijacobian[1] * delta[1] + ijacobian[2] * delta[2]; 1133181f196bSVijay Mahadevan natparam[1] -= ijacobian[3] * delta[0] + ijacobian[4] * delta[1] + ijacobian[5] * delta[2]; 1134181f196bSVijay Mahadevan natparam[2] -= ijacobian[6] * delta[0] + ijacobian[7] * delta[1] + ijacobian[8] * delta[2]; 1135181f196bSVijay Mahadevan break; 1136181f196bSVijay Mahadevan } 1137181f196bSVijay Mahadevan 1138181f196bSVijay Mahadevan /* Compute delta = evaluate( xi ) - x */ 1139a86ed394SVijay Mahadevan ierr = FEMComputeBasis_JandF ( dim, nverts, coordinates, natparam, phypts, phibasis, jacobian, ijacobian, &volume );CHKERRQ(ierr); 1140181f196bSVijay Mahadevan 1141a86ed394SVijay Mahadevan error = 0.0; 1142a86ed394SVijay Mahadevan switch(dim) { 1143a86ed394SVijay Mahadevan case 3: 1144181f196bSVijay Mahadevan delta[2] = phypts[2] - xphy[2]; 1145a86ed394SVijay Mahadevan error += (delta[2]*delta[2]); 1146a86ed394SVijay Mahadevan case 2: 1147a86ed394SVijay Mahadevan delta[1] = phypts[1] - xphy[1]; 1148a86ed394SVijay Mahadevan error += (delta[1]*delta[1]); 1149a86ed394SVijay Mahadevan case 1: 1150a86ed394SVijay Mahadevan delta[0] = phypts[0] - xphy[0]; 1151a86ed394SVijay Mahadevan error += (delta[0]*delta[0]); 1152a86ed394SVijay Mahadevan break; 1153a86ed394SVijay Mahadevan } 1154a86ed394SVijay Mahadevan #if 0 1155a86ed394SVijay 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); 1156a86ed394SVijay Mahadevan #endif 1157181f196bSVijay Mahadevan } 1158181f196bSVijay Mahadevan if (phi) { 1159*580bdb30SBarry Smith ierr = PetscArraycpy(phi, phibasis, nverts);CHKERRQ(ierr); 1160181f196bSVijay Mahadevan } 1161181f196bSVijay Mahadevan PetscFunctionReturn(0); 1162181f196bSVijay Mahadevan } 1163181f196bSVijay Mahadevan 1164