inline void JacobianBasis::getJacobianGeneral(int nJacNodes, const fullMatrix<double> &gSMatX, const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ, const fullMatrix<double> &nodesX, const fullMatrix<double> &nodesY, const fullMatrix<double> &nodesZ, fullMatrix<double> &jacobian) const { switch (_dim) { case 0 : { const int numEl = nodesX.size2(); for (int iEl = 0; iEl < numEl; iEl++) for (int i = 0; i < nJacNodes; i++) jacobian(i,iEl) = 1.; break; } case 1 : { const int numEl = nodesX.size2(); fullMatrix<double> dxdX(nJacNodes,numEl), dydX(nJacNodes,numEl), dzdX(nJacNodes,numEl); gSMatX.mult(nodesX, dxdX); gSMatX.mult(nodesY, dydX); gSMatX.mult(nodesZ, dzdX); for (int iEl = 0; iEl < numEl; iEl++) { fullMatrix<double> nodesXYZ(numPrimMapNodes,3); for (int i = 0; i < numPrimMapNodes; i++) { nodesXYZ(i,0) = nodesX(i,iEl); nodesXYZ(i,1) = nodesY(i,iEl); nodesXYZ(i,2) = nodesZ(i,iEl); } fullMatrix<double> normals(2,3); const double invScale = getPrimNormals1D(nodesXYZ,normals); if (scaling) { const double scale = 1./invScale; normals(0,0) *= scale; normals(0,1) *= scale; normals(0,2) *= scale; // Faster to scale 1 normal than afterwards } const double &dxdY = normals(0,0), &dydY = normals(0,1), &dzdY = normals(0,2); const double &dxdZ = normals(1,0), &dydZ = normals(1,1), &dzdZ = normals(1,2); for (int i = 0; i < nJacNodes; i++) jacobian(i,iEl) = calcDet3D(dxdX(i,iEl),dydX(i,iEl),dzdX(i,iEl), dxdY,dydY,dzdY, dxdZ,dydZ,dzdZ); } break; } case 2 : { const int numEl = nodesX.size2(); fullMatrix<double> dxdX(nJacNodes,numEl), dydX(nJacNodes,numEl), dzdX(nJacNodes,numEl); fullMatrix<double> dxdY(nJacNodes,numEl), dydY(nJacNodes,numEl), dzdY(nJacNodes,numEl); gSMatX.mult(nodesX, dxdX); gSMatX.mult(nodesY, dydX); gSMatX.mult(nodesZ, dzdX); gSMatY.mult(nodesX, dxdY); gSMatY.mult(nodesY, dydY); gSMatY.mult(nodesZ, dzdY); for (int iEl = 0; iEl < numEl; iEl++) { fullMatrix<double> nodesXYZ(numPrimMapNodes,3); for (int i = 0; i < numPrimMapNodes; i++) { nodesXYZ(i,0) = nodesX(i,iEl); nodesXYZ(i,1) = nodesY(i,iEl); nodesXYZ(i,2) = nodesZ(i,iEl); } fullMatrix<double> normal(1,3); const double invScale = getPrimNormal2D(nodesXYZ,normal); if (scaling) { const double scale = 1./invScale; normal(0,0) *= scale; normal(0,1) *= scale; normal(0,2) *= scale; // Faster to scale normal than afterwards } const double &dxdZ = normal(0,0), &dydZ = normal(0,1), &dzdZ = normal(0,2); for (int i = 0; i < nJacNodes; i++) jacobian(i,iEl) = calcDet3D(dxdX(i,iEl),dydX(i,iEl),dzdX(i,iEl), dxdY(i,iEl),dydY(i,iEl),dzdY(i,iEl), dxdZ,dydZ,dzdZ); } break; } case 3 : { const int numEl = nodesX.size2(); fullMatrix<double> dxdX(nJacNodes,numEl), dydX(nJacNodes,numEl), dzdX(nJacNodes,numEl); fullMatrix<double> dxdY(nJacNodes,numEl), dydY(nJacNodes,numEl), dzdY(nJacNodes,numEl); fullMatrix<double> dxdZ(nJacNodes,numEl), dydZ(nJacNodes,numEl), dzdZ(nJacNodes,numEl); gSMatX.mult(nodesX, dxdX); gSMatX.mult(nodesY, dydX); gSMatX.mult(nodesZ, dzdX); gSMatY.mult(nodesX, dxdY); gSMatY.mult(nodesY, dydY); gSMatY.mult(nodesZ, dzdY); gSMatZ.mult(nodesX, dxdZ); gSMatZ.mult(nodesY, dydZ); gSMatZ.mult(nodesZ, dzdZ); for (int iEl = 0; iEl < numEl; iEl++) { for (int i = 0; i < nJacNodes; i++) jacobian(i,iEl) = calcDet3D(dxdX(i,iEl),dydX(i,iEl),dzdX(i,iEl), dxdY(i,iEl),dydY(i,iEl),dzdY(i,iEl), dxdZ(i,iEl),dydZ(i,iEl),dzdZ(i,iEl)); if (scaling) { fullMatrix<double> nodesXYZ(numPrimMapNodes,3); for (int i = 0; i < numPrimMapNodes; i++) { nodesXYZ(i,0) = nodesX(i,iEl); nodesXYZ(i,1) = nodesY(i,iEl); nodesXYZ(i,2) = nodesZ(i,iEl); } const double scale = 1./getPrimJac3D(nodesXYZ); for (int i = 0; i < nJacNodes; i++) jacobian(i,iEl) *= scale; } } break; } } }
// Calculate (signed) Jacobian and its gradients for one element, with normal vectors to straight element // for regularization. Evaluation points depend on the given matrices for shape function gradients. void JacobianBasis::getSignedJacAndGradientsGeneral(int nJacNodes, const fullMatrix<double> &gSMatX, const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ, const fullMatrix<double> &nodesXYZ, const fullMatrix<double> &normals, fullMatrix<double> &JDJ) const { switch (_dim) { case 0 : { for (int i = 0; i < nJacNodes; i++) { for (int j = 0; j < numMapNodes; j++) { JDJ (i,j) = 0.; JDJ (i,j+1*numMapNodes) = 0.; JDJ (i,j+2*numMapNodes) = 0.; } JDJ(i,3*numMapNodes) = 1.; } break; } case 1 : { fullMatrix<double> dxyzdX(nJacNodes,3), dxyzdY(nJacNodes,3); gSMatX.mult(nodesXYZ, dxyzdX); for (int i = 0; i < nJacNodes; i++) { const double &dxdX = dxyzdX(i,0), &dydX = dxyzdX(i,1), &dzdX = dxyzdX(i,2); const double &dxdY = normals(0,0), &dydY = normals(0,1), &dzdY = normals(0,2); const double &dxdZ = normals(1,0), &dydZ = normals(1,1), &dzdZ = normals(1,2); for (int j = 0; j < numMapNodes; j++) { const double &dPhidX = gSMatX(i,j); JDJ (i,j) = dPhidX * dydY * dzdZ + dPhidX * dzdY * dydZ; JDJ (i,j+1*numMapNodes) = dPhidX * dzdY * dxdZ - dPhidX * dxdY * dzdZ; JDJ (i,j+2*numMapNodes) = dPhidX * dxdY * dydZ - dPhidX * dydY * dxdZ; } JDJ(i,3*numMapNodes) = calcDet3D(dxdX,dydX,dzdX,dxdY,dydY,dzdY,dxdZ,dydZ,dzdZ); } break; } case 2 : { fullMatrix<double> dxyzdX(nJacNodes,3), dxyzdY(nJacNodes,3); gSMatX.mult(nodesXYZ, dxyzdX); gSMatY.mult(nodesXYZ, dxyzdY); for (int i = 0; i < nJacNodes; i++) { const double &dxdX = dxyzdX(i,0), &dydX = dxyzdX(i,1), &dzdX = dxyzdX(i,2); const double &dxdY = dxyzdY(i,0), &dydY = dxyzdY(i,1), &dzdY = dxyzdY(i,2); const double &dxdZ = normals(0,0), &dydZ = normals(0,1), &dzdZ = normals(0,2); for (int j = 0; j < numMapNodes; j++) { const double &dPhidX = gSMatX(i,j); const double &dPhidY = gSMatY(i,j); JDJ (i,j) = dPhidX * dydY * dzdZ + dzdX * dPhidY * dydZ + dPhidX * dzdY * dydZ - dydX * dPhidY * dzdZ; JDJ (i,j+1*numMapNodes) = dxdX * dPhidY * dzdZ + dPhidX * dzdY * dxdZ - dzdX * dPhidY * dxdZ - dPhidX * dxdY * dzdZ; JDJ (i,j+2*numMapNodes) = dPhidX * dxdY * dydZ + dydX * dPhidY * dxdZ - dPhidX * dydY * dxdZ - dxdX * dPhidY * dydZ; } JDJ(i,3*numMapNodes) = calcDet3D(dxdX,dydX,dzdX,dxdY,dydY,dzdY,dxdZ,dydZ,dzdZ); } break; } case 3 : { fullMatrix<double> dxyzdX(nJacNodes,3), dxyzdY(nJacNodes,3), dxyzdZ(nJacNodes,3); gSMatX.mult(nodesXYZ, dxyzdX); gSMatY.mult(nodesXYZ, dxyzdY); gSMatZ.mult(nodesXYZ, dxyzdZ); for (int i = 0; i < nJacNodes; i++) { const double &dxdX = dxyzdX(i,0), &dydX = dxyzdX(i,1), &dzdX = dxyzdX(i,2); const double &dxdY = dxyzdY(i,0), &dydY = dxyzdY(i,1), &dzdY = dxyzdY(i,2); const double &dxdZ = dxyzdZ(i,0), &dydZ = dxyzdZ(i,1), &dzdZ = dxyzdZ(i,2); for (int j = 0; j < numMapNodes; j++) { const double &dPhidX = gSMatX(i,j); const double &dPhidY = gSMatY(i,j); const double &dPhidZ = gSMatZ(i,j); JDJ (i,j) = dPhidX * dydY * dzdZ + dzdX * dPhidY * dydZ + dydX * dzdY * dPhidZ - dzdX * dydY * dPhidZ - dPhidX * dzdY * dydZ - dydX * dPhidY * dzdZ; JDJ (i,j+1*numMapNodes) = dxdX * dPhidY * dzdZ + dzdX * dxdY * dPhidZ + dPhidX * dzdY * dxdZ - dzdX * dPhidY * dxdZ - dxdX * dzdY * dPhidZ - dPhidX * dxdY * dzdZ; JDJ (i,j+2*numMapNodes) = dxdX * dydY * dPhidZ + dPhidX * dxdY * dydZ + dydX * dPhidY * dxdZ - dPhidX * dydY * dxdZ - dxdX * dPhidY * dydZ - dydX * dxdY * dPhidZ; } JDJ(i,3*numMapNodes) = calcDet3D(dxdX,dydX,dzdX,dxdY,dydY,dzdY,dxdZ,dydZ,dzdZ); } break; } } }
inline void JacobianBasis::getJacobianGeneral(int nJacNodes, const fullMatrix<double> &gSMatX, const fullMatrix<double> &gSMatY, const fullMatrix<double> &gSMatZ, const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const { switch (_dim) { case 0 : { for (int i = 0; i < nJacNodes; i++) jacobian(i) = 1.; break; } case 1 : { fullMatrix<double> normals(2,3); const double invScale = getPrimNormals1D(nodesXYZ,normals); if (scaling) { const double scale = 1./invScale; normals(0,0) *= scale; normals(0,1) *= scale; normals(0,2) *= scale; // Faster to scale 1 normal than afterwards } fullMatrix<double> dxyzdX(nJacNodes,3); gSMatX.mult(nodesXYZ, dxyzdX); for (int i = 0; i < nJacNodes; i++) { const double &dxdX = dxyzdX(i,0), &dydX = dxyzdX(i,1), &dzdX = dxyzdX(i,2); const double &dxdY = normals(0,0), &dydY = normals(0,1), &dzdY = normals(0,2); const double &dxdZ = normals(1,0), &dydZ = normals(1,1), &dzdZ = normals(1,2); jacobian(i) = calcDet3D(dxdX,dydX,dzdX,dxdY,dydY,dzdY,dxdZ,dydZ,dzdZ); } break; } case 2 : { fullMatrix<double> normal(1,3); const double invScale = getPrimNormal2D(nodesXYZ,normal); if (scaling) { const double scale = 1./invScale; normal(0,0) *= scale; normal(0,1) *= scale; normal(0,2) *= scale; // Faster to scale normal than afterwards } fullMatrix<double> dxyzdX(nJacNodes,3), dxyzdY(nJacNodes,3); gSMatX.mult(nodesXYZ, dxyzdX); gSMatY.mult(nodesXYZ, dxyzdY); for (int i = 0; i < nJacNodes; i++) { const double &dxdX = dxyzdX(i,0), &dydX = dxyzdX(i,1), &dzdX = dxyzdX(i,2); const double &dxdY = dxyzdY(i,0), &dydY = dxyzdY(i,1), &dzdY = dxyzdY(i,2); const double &dxdZ = normal(0,0), &dydZ = normal(0,1), &dzdZ = normal(0,2); jacobian(i) = calcDet3D(dxdX,dydX,dzdX,dxdY,dydY,dzdY,dxdZ,dydZ,dzdZ); } break; } case 3 : { fullMatrix<double> dum; fullMatrix<double> dxyzdX(nJacNodes,3), dxyzdY(nJacNodes,3), dxyzdZ(nJacNodes,3); gSMatX.mult(nodesXYZ, dxyzdX); gSMatY.mult(nodesXYZ, dxyzdY); gSMatZ.mult(nodesXYZ, dxyzdZ); for (int i = 0; i < nJacNodes; i++) { const double &dxdX = dxyzdX(i,0), &dydX = dxyzdX(i,1), &dzdX = dxyzdX(i,2); const double &dxdY = dxyzdY(i,0), &dydY = dxyzdY(i,1), &dzdY = dxyzdY(i,2); const double &dxdZ = dxyzdZ(i,0), &dydZ = dxyzdZ(i,1), &dzdZ = dxyzdZ(i,2); jacobian(i) = calcDet3D(dxdX,dydX,dzdX,dxdY,dydY,dzdY,dxdZ,dydZ,dzdZ); } if (scaling) { const double scale = 1./getPrimJac3D(nodesXYZ); jacobian.scale(scale); } break; } } }