void Mesh::metricMinAndGradients(int iEl, std::vector<double> &lambda, std::vector<double> &gradLambda) { const JacobianBasis *jacBasis = _el[iEl]->getJacobianFuncSpace(); const int &numJacNodes = jacBasis->getNumJacNodes(); const int &numMapNodes = jacBasis->getNumMapNodes(); const int &numPrimMapNodes = jacBasis->getNumPrimMapNodes(); fullVector<double> lambdaJ(numJacNodes), lambdaB(numJacNodes); fullMatrix<double> gradLambdaJ(numJacNodes, 2 * numMapNodes); fullMatrix<double> gradLambdaB(numJacNodes, 2 * numMapNodes); // Coordinates of nodes fullMatrix<double> nodesXYZ(numMapNodes,3), nodesXYZStraight(numPrimMapNodes,3); for (int i = 0; i < numMapNodes; i++) { int &iVi = _el2V[iEl][i]; nodesXYZ(i,0) = _xyz[iVi].x(); nodesXYZ(i,1) = _xyz[iVi].y(); nodesXYZ(i,2) = _xyz[iVi].z(); if (i < numPrimMapNodes) { nodesXYZStraight(i,0) = _ixyz[iVi].x(); nodesXYZStraight(i,1) = _ixyz[iVi].y(); nodesXYZStraight(i,2) = _ixyz[iVi].z(); } } jacBasis->getMetricMinAndGradients(nodesXYZ,nodesXYZStraight,lambdaJ,gradLambdaJ); //l2b.mult(lambdaJ, lambdaB); //l2b.mult(gradLambdaJ, gradLambdaB); lambdaB = lambdaJ; gradLambdaB = gradLambdaJ; int iPC = 0; std::vector<SPoint3> gXyzV(numJacNodes); std::vector<SPoint3> gUvwV(numJacNodes); for (int l = 0; l < numJacNodes; l++) { lambda[l] = lambdaB(l); } for (int i = 0; i < numMapNodes; i++) { int &iFVi = _el2FV[iEl][i]; if (iFVi >= 0) { for (int l = 0; l < numJacNodes; l++) { gXyzV [l] = SPoint3(gradLambdaB(l,i+0*numMapNodes), gradLambdaB(l,i+1*numMapNodes),/*BDB(l,i+2*nbNod)*/ 0.); } _paramFV[iFVi]->gXyz2gUvw(_uvw[iFVi],gXyzV,gUvwV); for (int l = 0; l < numJacNodes; l++) { gradLambda[indGSJ(iEl,l,iPC)] = gUvwV[l][0]; if (_nPCFV[iFVi] >= 2) gradLambda[indGSJ(iEl,l,iPC+1)] = gUvwV[l][1]; if (_nPCFV[iFVi] == 3) gradLambda[indGSJ(iEl,l,iPC+2)] = gUvwV[l][2]; } iPC += _nPCFV[iFVi]; } } }
void Mesh::scaledJacAndGradients(int iEl, std::vector<double> &sJ, std::vector<double> &gSJ) { const JacobianBasis *jacBasis = _el[iEl]->getJacobianFuncSpace(); const int &numJacNodes = _nBezEl[iEl]; const int &numMapNodes = _nNodEl[iEl]; fullMatrix<double> JDJ(numJacNodes,3*numMapNodes+1), BDB(numJacNodes,3*numMapNodes+1); // Coordinates of nodes fullMatrix<double> nodesXYZ(numMapNodes,3), normals(_dim,3); for (int i = 0; i < numMapNodes; i++) { int &iVi = _el2V[iEl][i]; nodesXYZ(i,0) = _xyz[iVi].x(); nodesXYZ(i,1) = _xyz[iVi].y(); nodesXYZ(i,2) = _xyz[iVi].z(); } // Calculate Jacobian and gradients, scale if 3D (already scaled by // regularization normals in 2D) if (_fastJacEval) jacBasis->getSignedJacAndGradientsFast(nodesXYZ,_scaledNormEl[iEl],JDJ); else jacBasis->getSignedJacAndGradients(nodesXYZ,_scaledNormEl[iEl],JDJ); if (_dim == 3) JDJ.scale(_invStraightJac[iEl]); // Transform Jacobian and gradients from Lagrangian to Bezier basis if (_fastJacEval) BDB = JDJ; else jacBasis->lag2Bez(JDJ,BDB); // Scaled jacobian for (int l = 0; l < numJacNodes; l++) sJ [l] = BDB (l,3*numMapNodes); // Gradients of the scaled jacobian int iPC = 0; std::vector<SPoint3> gXyzV(numJacNodes); std::vector<SPoint3> gUvwV(numJacNodes); for (int i = 0; i < numMapNodes; i++) { int &iFVi = _el2FV[iEl][i]; if (iFVi >= 0) { for (int l = 0; l < numJacNodes; l++) gXyzV [l] = SPoint3(BDB(l,i+0*numMapNodes), BDB(l,i+1*numMapNodes), BDB(l,i+2*numMapNodes)); _paramFV[iFVi]->gXyz2gUvw(_uvw[iFVi],gXyzV,gUvwV); for (int l = 0; l < numJacNodes; l++) { gSJ[indGSJ(iEl,l,iPC)] = gUvwV[l][0]; if (_nPCFV[iFVi] >= 2) gSJ[indGSJ(iEl,l,iPC+1)] = gUvwV[l][1]; if (_nPCFV[iFVi] == 3) gSJ[indGSJ(iEl,l,iPC+2)] = gUvwV[l][2]; } iPC += _nPCFV[iFVi]; } } }
double taylorDistanceFace(MElement *el, GFace *gf) { const int nV = el->getNumVertices(); const GradientBasis *gb = BasisFactory::getGradientBasis(FuncSpaceData(el)); // Coordinates of vertices fullMatrix<double> nodesXYZ(nV, 3); el->getNodesCoord(nodesXYZ); // Normal to CAD at vertices std::vector<SVector3> normCAD(nV); for (int i=0; i<nV; i++) { SPoint2 pCAD; reparamMeshVertexOnFace(el->getVertex(i), gf, pCAD); normCAD[i] = gf->normal(pCAD); normCAD[i].normalize(); } // Compute distance return sqrt(taylorDistanceSq2D(gb, nodesXYZ, normCAD)); }
double taylorDistanceEdge(MLine *l, GEdge *ge) { const int nV = l->getNumVertices(); const GradientBasis *gb = BasisFactory::getGradientBasis(FuncSpaceData(l)); // Coordinates of vertices fullMatrix<double> nodesXYZ(nV, 3); l->getNodesCoord(nodesXYZ); // Tangent to CAD at vertices std::vector<SVector3> tanCAD(nV); for (int i=0; i<nV; i++) { double tCAD; reparamMeshVertexOnEdge(l->getVertex(i), ge, tCAD); tanCAD[i] = ge->firstDer(tCAD); tanCAD[i].normalize(); } // Compute distance return sqrt(taylorDistanceSq1D(gb, nodesXYZ, tanCAD)); }
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; } } }