diff --git a/Geo/MElement.cpp b/Geo/MElement.cpp index 5f0d00f67fba8fcbfe5efa42e42f7414ebcd4a67..7a89cdff8c44fa5cf6574a4bb57640f3d1db82c2 100644 --- a/Geo/MElement.cpp +++ b/Geo/MElement.cpp @@ -112,28 +112,22 @@ void MElement::scaledJacRange(double &jmin, double &jmax) { jmin = jmax = 1.0; #if defined(HAVE_MESH) - extern double mesh_functional_distorsion_2D(MElement*,double,double); - extern double mesh_functional_distorsion_3D(MElement*,double,double,double); if (getPolynomialOrder() == 1) return; - const bezierBasis *jac = getJacobianFuncSpace()->bezier; - fullVector<double>Ji(jac->points.size1()); - for (int i=0;i<jac->points.size1();i++){ - double u = jac->points(i,0); - double v = jac->points(i,1); - if (getDim() == 2) { - if (getType() == TYPE_QUA) { - u = -1 + 2*u; - v = -1 + 2*v; - } - Ji(i) = mesh_functional_distorsion_2D(this,u,v); - } - else { - double w = jac->points(i,2); - Ji(i) = mesh_functional_distorsion_3D(this,u,v,w); - } - } - fullVector<double> Bi( jac->matrixLag2Bez.size1() ); - jac->matrixLag2Bez.mult(Ji,Bi); + const JacobianBasis *jac = getJacobianFuncSpace(); // Calc signed Jacobian + const bezierBasis *bez = jac->bezier; + const int numJacNodes = bez->points.size1(); + fullVector<double> Ji(numJacNodes); + jac->getSignedJacobian(this,Ji); + const JacobianBasis *jac1 = getJacobianFuncSpace(1); // Calc signed primary Jacobian + const int numJac1Nodes = jac1->bezier->points.size1(); + fullVector<double> J1i(numJac1Nodes), J1Ji(numJacNodes); + jac1->getSignedJacobian(this,J1i); + for (int i=0; i<numJac1Nodes; i++) if (J1i(i) == 0) std::cout << "DBGTT: el " << getNum() << ", Ji1(" << i << ") == 0!\n"; + jac->primJac2Jac.mult(J1i,J1Ji); + fullVector<double> SJi(numJacNodes); // Calc scaled Jacobian + for (int i=0; i<numJacNodes; i++) SJi(i) = Ji(i)/J1Ji(i); + fullVector<double> Bi(numJacNodes); // Transform to Bezier basis + bez->matrixLag2Bez.mult(SJi,Bi); jmin = *std::min_element(Bi.getDataPtr(),Bi.getDataPtr()+Bi.size()); jmax = *std::max_element(Bi.getDataPtr(),Bi.getDataPtr()+Bi.size()); #endif diff --git a/Geo/MElement.h b/Geo/MElement.h index 9029b64772a471e223c2cb82f842d81f1b9cf73c..c6f3a61af706a66e862f80d6dfb5f43d0ba5673b 100644 --- a/Geo/MElement.h +++ b/Geo/MElement.h @@ -182,7 +182,7 @@ class MElement virtual double rhoShapeMeasure(); virtual double gammaShapeMeasure(){ return 0.; } virtual double etaShapeMeasure(){ return 0.; } - virtual double distoShapeMeasure(){ return 1.0; } + virtual double distoShapeMeasure(){ double jmin,jmax; scaledJacRange(jmin,jmax); return jmin; } virtual double angleShapeMeasure() { return 1.0; } virtual void scaledJacRange(double &jmin, double &jmax); diff --git a/Geo/MPyramid.cpp b/Geo/MPyramid.cpp index f4e42ef6ca7a4fb60502618e5476fce80723cfd7..b8b1ab8373ed42df18bef44668f9a2832885c7d0 100644 --- a/Geo/MPyramid.cpp +++ b/Geo/MPyramid.cpp @@ -82,16 +82,6 @@ const JacobianBasis* MPyramid::getJacobianFuncSpace(int o) const MPyramidN::~MPyramidN() {} -double MPyramidN::distoShapeMeasure() -{ -#if defined(HAVE_MESH) - _disto = 0.0; //qmDistorsionOfMapping(this); -#else - _disto = 0.; -#endif - return _disto; -} - int MPyramidN::getNumEdgesRep(){ return 8 * CTX::instance()->mesh.numSubEdges; } void MPyramidN::getEdgeRep(int num, double *x, double *y, double *z, SVector3 *n) diff --git a/Geo/MPyramid.h b/Geo/MPyramid.h index 836bff3b3595ff38e601f70904edd91f7e8efeb0..ffae41f7d1cfd15a0983c2339711bb155be5446d 100644 --- a/Geo/MPyramid.h +++ b/Geo/MPyramid.h @@ -436,7 +436,6 @@ class MPyramidN : public MPyramid { ~MPyramidN(); - virtual double distoShapeMeasure(); virtual int getPolynomialOrder() const { return _order; } virtual int getNumVertices() const { return 5 + _vs.size(); } virtual MVertex *getVertex(int num){ return num < 5 ? _v[num] : _vs[num - 5]; } diff --git a/Geo/MTetrahedron.cpp b/Geo/MTetrahedron.cpp index 1dde8a9e9a5cd385dfd67fde9dc7241e74948d00..6265eb91fe33eab526a17eaaf100ec0350d1803b 100644 --- a/Geo/MTetrahedron.cpp +++ b/Geo/MTetrahedron.cpp @@ -119,16 +119,6 @@ double MTetrahedron::distoShapeMeasure() #endif } -double MTetrahedronN::distoShapeMeasure() -{ -#if defined(HAVE_MESH) - _disto = qmDistorsionOfMapping(this); -#else - _disto = 0.; -#endif - return _disto; -} - double MTetrahedron::getInnerRadius() { // radius of inscribed sphere = 3 * Volume / sum(Area_i) diff --git a/Geo/MTetrahedron.h b/Geo/MTetrahedron.h index 2df127b1640bc3c12d7ebd9bae6fd3b709705576..d0e5e9cae82f934bf64b3baa9be8ccbfd10d7066 100644 --- a/Geo/MTetrahedron.h +++ b/Geo/MTetrahedron.h @@ -213,7 +213,6 @@ class MTetrahedron10 : public MTetrahedron { for(int i = 0; i < 6; i++) _vs[i]->setPolynomialOrder(2); } ~MTetrahedron10(){} - virtual double distoShapeMeasure() {double jmin,jmax; scaledJacRange(jmin,jmax); return jmin;} virtual void scaledJacRange(double &jmin, double &jmax); virtual int getPolynomialOrder() const { return 2; } virtual int getNumVertices() const { return 10; } @@ -315,22 +314,20 @@ class MTetrahedronN : public MTetrahedron { protected: std::vector<MVertex *> _vs; const char _order; - double _disto; public: MTetrahedronN(MVertex *v0, MVertex *v1, MVertex *v2, MVertex *v3, const std::vector<MVertex*> &v, char order, int num=0, int part=0) - : MTetrahedron(v0, v1, v2, v3, num, part) , _vs (v), _order(order),_disto(-1.e22) + : MTetrahedron(v0, v1, v2, v3, num, part) , _vs (v), _order(order) { for(unsigned int i = 0; i < _vs.size(); i++) _vs[i]->setPolynomialOrder(_order); } MTetrahedronN(const std::vector<MVertex*> &v, char order, int num=0, int part=0) - : MTetrahedron(v[0], v[1], v[2], v[3], num, part) , _order(order),_disto(-1.e22) + : MTetrahedron(v[0], v[1], v[2], v[3], num, part) , _order(order) { for(unsigned int i = 4; i < v.size(); i++) _vs.push_back(v[i]); for(unsigned int i = 0; i < _vs.size(); i++) _vs[i]->setPolynomialOrder(_order); } ~MTetrahedronN(){} - virtual double distoShapeMeasure(); virtual int getPolynomialOrder() const { return _order; } virtual int getNumVertices() const { return 4 + _vs.size(); } virtual MVertex *getVertex(int num){ return num < 4 ? _v[num] : _vs[num - 4]; } diff --git a/Numeric/BergotBasis.h b/Numeric/BergotBasis.h index e62e43828269978a4c19217870fbafc74294e2c0..95dacaf44036590871acc8a43a32e4c2d3c1a647 100644 --- a/Numeric/BergotBasis.h +++ b/Numeric/BergotBasis.h @@ -11,6 +11,11 @@ #include "jacobiPolynomials.h" #include "legendrePolynomials.h" + +// Basis functios for pyramidal elements +// cf. M. Bergot, G. Cohen, M. Durufle, HIGHER-ORDER FINITE ELEMENTS FOR HYBRID MESHES USING NEW +// NODAL PYRAMIDAL ELEMENTS, J. Sci. Comput. 42, 3 (2010) 345-381", DOI: 10.1007/s10915-009-9334-9 + class BergotBasis { public: diff --git a/Numeric/JacobianBasis.cpp b/Numeric/JacobianBasis.cpp index ab0b938ec0bdf6a8d56668d65f325fa823a3f852..2a37328a38e4fa3e95fe220c64cb47fe0363db6e 100644 --- a/Numeric/JacobianBasis.cpp +++ b/Numeric/JacobianBasis.cpp @@ -11,6 +11,7 @@ #include "pyramidalBasis.h" #include "pointsGenerators.h" #include "BasisFactory.h" +#include "MElement.h" // Bezier Exponents static fullMatrix<double> generate1DExponents(int order) @@ -934,98 +935,7 @@ static fullMatrix<double> generateSubDivisor -static void generateGradShapes(JacobianBasis &jfs, const fullMatrix<double> &points, - const fullMatrix<double> &monomials, const fullMatrix<double> &coefficients) -{ - - int nbPts = points.size1(); - int nbDofs = monomials.size1(); - int dim = points.size2(); - - switch (dim) { - case 3 : - jfs.gradShapeMatZ.resize(nbPts, nbDofs, true); - case 2 : - jfs.gradShapeMatY.resize(nbPts, nbDofs, true); - case 1 : - jfs.gradShapeMatX.resize(nbPts, nbDofs, true); - break; - default : - return; - } - - double dx, dy, dz; - - switch (dim) { - case 3 : - for (int i = 0; i < nbDofs; i++) { - for (int k = 0; k < nbPts; k++) { - - if ((int) monomials(i, 0) > 0) { - dx = pow( points(k, 0), monomials(i, 0)-1 ) * monomials(i, 0) - * pow( points(k, 1), monomials(i, 1) ) - * pow( points(k, 2), monomials(i, 2) ); - for (int j = 0; j < nbDofs; j++) - jfs.gradShapeMatX(k, j) += coefficients(j, i) * dx; - } - if ((int) monomials(i, 1) > 0.) { - dy = pow( points(k, 0), monomials(i, 0) ) - * pow( points(k, 1), monomials(i, 1)-1 ) * monomials(i, 1) - * pow( points(k, 2), monomials(i, 2) ); - for (int j = 0; j < nbDofs; j++) - jfs.gradShapeMatY(k, j) += coefficients(j, i) * dy; - } - if ((int) monomials(i, 2) > 0.) { - dz = pow( points(k, 0), monomials(i, 0) ) - * pow( points(k, 1), monomials(i, 1) ) - * pow( points(k, 2), monomials(i, 2)-1 ) * monomials(i, 2); - for (int j = 0; j < nbDofs; j++) - jfs.gradShapeMatZ(k, j) += coefficients(j, i) * dz; - } - } - } - return; - - case 2 : - for (int i = 0; i < nbDofs; i++) { - for (int k = 0; k < nbPts; k++) { - - if ((int) monomials(i, 0) > 0) { - dx = pow( points(k, 0), (int) monomials(i, 0)-1 ) * monomials(i, 0) - * pow( points(k, 1), (int) monomials(i, 1) ); - for (int j = 0; j < nbDofs; j++) - jfs.gradShapeMatX(k, j) += coefficients(j, i) * dx; - } - if ((int) monomials(i, 1) > 0) { - dy = pow( points(k, 0), (int) monomials(i, 0) ) - * pow( points(k, 1), (int) monomials(i, 1)-1 ) * monomials(i, 1); - for (int j = 0; j < nbDofs; j++) - jfs.gradShapeMatY(k, j) += coefficients(j, i) * dy; - } - } - } - return; - - case 1 : - for (int i = 0; i < nbDofs; i++) { - for (int k = 0; k < nbPts; k++) { - - if ((int) monomials(i, 0) > 0) { - dx = pow( points(k, 0), (int) monomials(i, 0)-1 ) * monomials(i, 0); - for (int j = 0; j < nbDofs; j++) - jfs.gradShapeMatX(k, j) += coefficients(j, i) * dx; - } - } - } - break; - } - return; - -} - - - -static void generateGradShapesPyramid(JacobianBasis &jfs, const fullMatrix<double> &points, const pyramidalBasis *F) +static void generateGradShapes(JacobianBasis &jfs, const fullMatrix<double> &points, const nodalBasis *F) { fullMatrix<double> allDPsi; @@ -1045,6 +955,7 @@ static void generateGradShapesPyramid(JacobianBasis &jfs, const fullMatrix<doubl } + std::map<int, bezierBasis> bezierBasis::_bbs; const bezierBasis *bezierBasis::find(int tag) { @@ -1064,14 +975,12 @@ const bezierBasis *bezierBasis::find(int tag) B.matrixLag2Bez(i,i) = 1.; B.matrixBez2Lag(i,i) = 1.; } -// B.subDivisor = generateSubDivisor(B.exponents, subPoints, B.matrixLag2Bez, F->order, dimSimplex); -// B.numDivisions = (int) pow(2., (int) B.points.size2()); + // TODO: Implement subdidivsor } else { - const polynomialBasis *F = (polynomialBasis*)BasisFactory::create(tag); int dimSimplex; std::vector< fullMatrix<double> > subPoints; - switch (F->parentType) { + switch (MElement::ParentTypeFromTag(tag)) { case TYPE_PNT : B.numLagPts = 1; B.exponents = generate1DExponents(0); @@ -1080,51 +989,51 @@ const bezierBasis *bezierBasis::find(int tag) break; case TYPE_LIN : { B.numLagPts = 2; - B.exponents = generate1DExponents(F->order); - B.points = generate1DPoints(F->order); + B.exponents = generate1DExponents(B.order); + B.points = generate1DPoints(B.order); dimSimplex = 0; subPoints = generateSubPointsLine(0); break; } case TYPE_TRI : { B.numLagPts = 3; - B.exponents = generateExponentsTriangle(F->order); - B.points = gmshGeneratePointsTriangle(F->order,false); + B.exponents = generateExponentsTriangle(B.order); + B.points = gmshGeneratePointsTriangle(B.order,false); dimSimplex = 2; - subPoints = generateSubPointsTriangle(F->order); + subPoints = generateSubPointsTriangle(B.order); break; } case TYPE_QUA : { B.numLagPts = 4; - B.exponents = generateExponentsQuad(F->order); - B.points = generatePointsQuad(F->order,false); + B.exponents = generateExponentsQuad(B.order); + B.points = generatePointsQuad(B.order,false); dimSimplex = 0; - subPoints = generateSubPointsQuad(F->order); + subPoints = generateSubPointsQuad(B.order); // B.points.print("points"); break; } case TYPE_TET : { B.numLagPts = 4; - B.exponents = generateExponentsTetrahedron(F->order); - B.points = gmshGeneratePointsTetrahedron(F->order,false); + B.exponents = generateExponentsTetrahedron(B.order); + B.points = gmshGeneratePointsTetrahedron(B.order,false); dimSimplex = 3; - subPoints = generateSubPointsTetrahedron(F->order); + subPoints = generateSubPointsTetrahedron(B.order); break; } case TYPE_PRI : { B.numLagPts = 6; - B.exponents = generateExponentsPrism(F->order); - B.points = generatePointsPrism(F->order, false); + B.exponents = generateExponentsPrism(B.order); + B.points = generatePointsPrism(B.order, false); dimSimplex = 2; - subPoints = generateSubPointsPrism(F->order); + subPoints = generateSubPointsPrism(B.order); break; } case TYPE_HEX : { B.numLagPts = 8; - B.exponents = generateExponentsHex(F->order); - B.points = generatePointsHex(F->order, false); + B.exponents = generateExponentsHex(B.order); + B.points = generatePointsHex(B.order, false); dimSimplex = 0; - subPoints = generateSubPointsHex(F->order); + subPoints = generateSubPointsHex(B.order); break; } default : { @@ -1137,53 +1046,125 @@ const bezierBasis *bezierBasis::find(int tag) break; } } - B.matrixBez2Lag = generateBez2LagMatrix(B.exponents, B.points, F->order, dimSimplex); + B.matrixBez2Lag = generateBez2LagMatrix(B.exponents, B.points, B.order, dimSimplex); B.matrixBez2Lag.invert(B.matrixLag2Bez); - B.subDivisor = generateSubDivisor(B.exponents, subPoints, B.matrixLag2Bez, F->order, dimSimplex); + B.subDivisor = generateSubDivisor(B.exponents, subPoints, B.matrixLag2Bez, B.order, dimSimplex); B.numDivisions = (int) pow(2., (int) B.points.size2()); } return &B; } + + +static void generatePrimJac2Jac(JacobianBasis &jfs, const nodalBasis *primJacBasis) +{ + const int numJacNodes = jfs.bezier->points.size1(), numPrimJacSF = primJacBasis->getNumShapeFunctions(); + jfs.primJac2Jac.resize(numJacNodes,numPrimJacSF); + primJacBasis->f(jfs.bezier->points,jfs.primJac2Jac); +} + + + std::map<int, JacobianBasis> JacobianBasis::_fs; const JacobianBasis *JacobianBasis::find(int tag) { std::map<int, JacobianBasis>::const_iterator it = _fs.find(tag); if (it != _fs.end()) return &it->second; JacobianBasis &J = _fs[tag]; + int jacType, primJacType; if (MElement::ParentTypeFromTag(tag) == TYPE_PYR) { switch (tag) { - case MSH_PYR_5 : J.bezier = bezierBasis::find(MSH_PYR_14); break; // TODO: Order 1, Jac. "order" 2, check this - case MSH_PYR_14 : J.bezier = bezierBasis::find(MSH_PYR_91); break; // TODO: Order 2, Jac. "order" 5, check this - case MSH_PYR_30 : J.bezier = bezierBasis::find(MSH_PYR_285); break; // TODO: Order 3, Jac. "order" 8, check this + case MSH_PYR_5 : jacType = MSH_PYR_14; primJacType = MSH_PYR_14; break; // TODO: Order 1, Jac. "order" 2, check this + case MSH_PYR_14 : jacType = MSH_PYR_91; primJacType = MSH_PYR_14; break; // TODO: Order 2, Jac. "order" 5, check this + case MSH_PYR_30 : jacType = MSH_PYR_285; primJacType = MSH_PYR_14; break; // TODO: Order 3, Jac. "order" 8, check this default : Msg::Error("Unknown Jacobian function space for element type %d: reverting to PYR_5", tag); J.bezier = bezierBasis::find(MSH_PYR_14); break; } - pyramidalBasis *F = (pyramidalBasis*)BasisFactory::create(tag); - generateGradShapesPyramid(J, J.bezier->points, F); } else { const int parentType = MElement::ParentTypeFromTag(tag), order = MElement::OrderFromTag(tag); - int jacobianOrder; + int jacobianOrder, primJacobianOrder; switch (parentType) { - case TYPE_PNT : jacobianOrder = 0; break; - case TYPE_LIN : jacobianOrder = order - 1; break; - case TYPE_TRI : jacobianOrder = 2 * (order - 1); break; - case TYPE_QUA : jacobianOrder = 2 * order - 1; break; - case TYPE_TET : jacobianOrder = 3 * (order - 1); break; - case TYPE_PRI : jacobianOrder = 3 * order - 1; break; - case TYPE_HEX : jacobianOrder = 3 * order - 1; break; + case TYPE_PNT : jacobianOrder = 0; primJacobianOrder = 0; break; + case TYPE_LIN : jacobianOrder = order - 1; primJacobianOrder = 0; break; + case TYPE_TRI : jacobianOrder = 2 * (order - 1); primJacobianOrder = 0; break; + case TYPE_QUA : jacobianOrder = 2 * order - 1; primJacobianOrder = 1; break; + case TYPE_TET : jacobianOrder = 3 * (order - 1); primJacobianOrder = 0; break; + case TYPE_PRI : jacobianOrder = 3 * order - 1; primJacobianOrder = 2; break; + case TYPE_HEX : jacobianOrder = 3 * order - 1; primJacobianOrder = 2; break; default : - Msg::Error("Unknown Jacobian function space for element type %d: reverting to TET_4", tag); + Msg::Error("Unknown Jacobian function space for element type %d", tag); jacobianOrder = 0; break; } - J.bezier = bezierBasis::find(polynomialBasis::getTag(parentType, jacobianOrder, false)); - polynomialBasis *F = (polynomialBasis*)BasisFactory::create(tag); - generateGradShapes(J, J.bezier->points, F->monomials, F->coefficients); + jacType = polynomialBasis::getTag(parentType, jacobianOrder, false); + primJacType = polynomialBasis::getTag(parentType, primJacobianOrder, false); } + J.bezier = bezierBasis::find(jacType); + const nodalBasis *mapBasis = BasisFactory::create(tag); + generateGradShapes(J, J.bezier->points, mapBasis); + const nodalBasis *primJacBasis = BasisFactory::create(primJacType); + generatePrimJac2Jac(J, primJacBasis); return &J; } + + + +void JacobianBasis::getSignedJacobian(MElement *el, fullVector<double> &jacobian) const +{ + + const int numVertices = gradShapeMatX.size2(), numJacNodes = gradShapeMatX.size1(); + + switch (el->getDim()) { + + case 1 : { + fullVector<double> nodesX(numVertices); + for (int i = 0; i < numVertices; i++) { + nodesX(i) = el->getShapeFunctionNode(i)->x(); + } + gradShapeMatX.mult(nodesX, jacobian); + break; + } + + case 2 : { + fullMatrix<double> nodesXY(numVertices,2); + for (int i = 0; i < numVertices; i++) { + MVertex *v = el->getShapeFunctionNode(i); + nodesXY(i,0) = v->x(); + nodesXY(i,1) = v->y(); + } + fullMatrix<double> dxydX(numJacNodes,2), dxydY(numJacNodes,2); + gradShapeMatX.mult(nodesXY, dxydX); + gradShapeMatY.mult(nodesXY, dxydY); + for (int i = 0; i < numJacNodes; i++) jacobian(i) = dxydX(i,0)*dxydY(i,1)-dxydX(i,1)*dxydY(i,0); + break; + } + + case 3 : { + fullMatrix<double> nodesXYZ(numVertices,3); + for (int i = 0; i < numVertices; i++) { + MVertex *v = el->getShapeFunctionNode(i); + nodesXYZ(i,0) = v->x(); + nodesXYZ(i,1) = v->y(); + nodesXYZ(i,2) = v->z(); + } + fullMatrix<double> dxyzdX(numJacNodes,3), dxyzdY(numJacNodes,3), dxyzdZ(numJacNodes,3); + gradShapeMatX.mult(nodesXYZ, dxyzdX); + gradShapeMatY.mult(nodesXYZ, dxyzdY); + gradShapeMatZ.mult(nodesXYZ, dxyzdZ); + for (int i = 0; i < numJacNodes; 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) = dxdX*dydY*dzdZ + dxdY*dydZ*dzdX + dydX*dzdY*dxdZ + - dxdZ*dydY*dzdX - dxdY*dydX*dzdZ - dydZ*dzdY*dxdX; + } + break; + } + + } + +} diff --git a/Numeric/JacobianBasis.h b/Numeric/JacobianBasis.h index af8326a968153c54ea6a901bd7db55b7b4995da2..c7cf23c4785deb236ece3673edfdffac2937f93a 100644 --- a/Numeric/JacobianBasis.h +++ b/Numeric/JacobianBasis.h @@ -9,6 +9,9 @@ #include <map> #include <vector> #include "fullMatrix.h" + +class MElement; + class bezierBasis { private : static std::map<int, bezierBasis> _bbs; @@ -29,10 +32,10 @@ class JacobianBasis { static std::map<int, JacobianBasis> _fs; public : const bezierBasis *bezier; - fullMatrix<double> gradShapeMatX; - fullMatrix<double> gradShapeMatY; - fullMatrix<double> gradShapeMatZ; + fullMatrix<double> gradShapeMatX, gradShapeMatY, gradShapeMatZ; + fullMatrix<double> primJac2Jac; // Lifts Lagrange basis of primary Jac. to Lagrange basis of Jac. static const JacobianBasis *find(int); + void getSignedJacobian(MElement *el, fullVector<double> &jacobian) const; }; #endif diff --git a/Numeric/polynomialBasis.cpp b/Numeric/polynomialBasis.cpp index 9334222f53aa690a80db01cf9e42737905645849..b50a8e78938e9cbcddc4213737fa047867da7c60 100644 --- a/Numeric/polynomialBasis.cpp +++ b/Numeric/polynomialBasis.cpp @@ -410,9 +410,10 @@ void polynomialBasis::f(const fullMatrix<double> &coord, fullMatrix<double> &sf) sf.resize (coord.size1(), coefficients.size1()); for (int iPoint=0; iPoint< coord.size1(); iPoint++) { evaluateMonomials(coord(iPoint,0), coord(iPoint,1), coord(iPoint,2), p); - for (int i = 0; i < coefficients.size1(); i++) - for (int j = 0; j < coefficients.size2(); j++) - sf(iPoint,i) += coefficients(i, j) * p[j]; + for (int i = 0; i < coefficients.size1(); i++) { + sf(iPoint,i) = 0.; + for (int j = 0; j < coefficients.size2(); j++) sf(iPoint,i) += coefficients(i, j) * p[j]; + } } } diff --git a/Plugin/AnalyseCurvedMesh.cpp b/Plugin/AnalyseCurvedMesh.cpp index d577c875011df05742a858089cf3365cd1ea3efd..87036b090cb269966054012fee95fef3cdb3ded4 100644 --- a/Plugin/AnalyseCurvedMesh.cpp +++ b/Plugin/AnalyseCurvedMesh.cpp @@ -75,102 +75,6 @@ std::string GMSH_AnalyseCurvedMeshPlugin::getHelp() const "Tolerance = R+ , << 1 : tolerance (relatively to J_min and J_max) used during the computation of J_min and J_max"; } -// Miscellaneous method -static void setJacobian(MElement *el, const JacobianBasis *jfs, fullVector<double> &jacobian) -{ - int numVertices = el->getNumVertices(); - fullVector<double> nodesX(numVertices); - fullVector<double> nodesY; - fullVector<double> nodesZ; - fullVector<double> interm1; - fullVector<double> interm2; - - switch (el->getDim()) { - - case 1 : - for (int i = 0; i < numVertices; i++) { - nodesX(i) = el->getVertex(i)->x(); - } - jfs->gradShapeMatX.mult(nodesX, jacobian); - break; - - case 2 : - nodesY.resize(numVertices); - interm1.resize(jacobian.size()); - interm2.resize(jacobian.size()); - - for (int i = 0; i < numVertices; i++) { - nodesX(i) = el->getVertex(i)->x(); - nodesY(i) = el->getVertex(i)->y(); - } - - jfs->gradShapeMatX.mult(nodesX, jacobian); - jfs->gradShapeMatY.mult(nodesY, interm2); - jacobian.multTByT(interm2); - - jfs->gradShapeMatY.mult(nodesX, interm1); - jfs->gradShapeMatX.mult(nodesY, interm2); - interm1.multTByT(interm2); - - jacobian.axpy(interm1, -1); - break; - - case 3 : - nodesY.resize(numVertices); - nodesZ.resize(numVertices); - interm1.resize(jacobian.size()); - interm2.resize(jacobian.size()); - - for (int i = 0; i < numVertices; i++) { - nodesX(i) = el->getVertex(i)->x(); - nodesY(i) = el->getVertex(i)->y(); - nodesZ(i) = el->getVertex(i)->z(); - } - - jfs->gradShapeMatX.mult(nodesX, jacobian); - jfs->gradShapeMatY.mult(nodesY, interm2); - jacobian.multTByT(interm2); - jfs->gradShapeMatZ.mult(nodesZ, interm2); - jacobian.multTByT(interm2); - - jfs->gradShapeMatX.mult(nodesY, interm1); - jfs->gradShapeMatY.mult(nodesZ, interm2); - interm1.multTByT(interm2); - jfs->gradShapeMatZ.mult(nodesX, interm2); - interm1.multTByT(interm2); - jacobian.axpy(interm1, 1); - - jfs->gradShapeMatX.mult(nodesZ, interm1); - jfs->gradShapeMatY.mult(nodesX, interm2); - interm1.multTByT(interm2); - jfs->gradShapeMatZ.mult(nodesY, interm2); - interm1.multTByT(interm2); - jacobian.axpy(interm1, 1); - - - jfs->gradShapeMatX.mult(nodesY, interm1); - jfs->gradShapeMatY.mult(nodesX, interm2); - interm1.multTByT(interm2); - jfs->gradShapeMatZ.mult(nodesZ, interm2); - interm1.multTByT(interm2); - jacobian.axpy(interm1, -1); - - jfs->gradShapeMatX.mult(nodesZ, interm1); - jfs->gradShapeMatY.mult(nodesY, interm2); - interm1.multTByT(interm2); - jfs->gradShapeMatZ.mult(nodesX, interm2); - interm1.multTByT(interm2); - jacobian.axpy(interm1, -1); - - jfs->gradShapeMatX.mult(nodesX, interm1); - jfs->gradShapeMatY.mult(nodesZ, interm2); - interm1.multTByT(interm2); - jfs->gradShapeMatZ.mult(nodesY, interm2); - interm1.multTByT(interm2); - jacobian.axpy(interm1, -1); - } -} - static double sum(fullVector<double> &v) { double sum = .0; @@ -334,8 +238,8 @@ void GMSH_AnalyseCurvedMeshPlugin::checkValidity(MElement *const*el, fullVector<double> jac1B(jfs1->bezier->points.size1(), numEl); fullVector<double> jacBez, jacobian, jac1; - setJacobian(el, jfs, jacobianB); - setJacobian(el, jfs1, jac1B); + jfs->getSignedJacobian(el, jacobianB); + jfs1->getSignedJacobian(el, jac1B); bb->matrixLag2Bez.mult(jacobianB, jacBezB); #else fullVector<double> jacobian(numSamplingPt); @@ -350,8 +254,8 @@ void GMSH_AnalyseCurvedMeshPlugin::checkValidity(MElement *const*el, jacobian.setAsProxy(jacobianB, k); jac1.setAsProxy(jac1B, k); #else - setJacobian(el[k], jfs, jacobian); - setJacobian(el[k], jfs1, jac1); + jfs->getSignedJacobian(el[k], jacobian); + jfs1->getSignedJacobian(el[k], jac1); #endif // AmJ : avgJ is not the average Jac for quad, prism or hex @@ -539,8 +443,8 @@ void GMSH_AnalyseCurvedMeshPlugin::computeMinMax(MElement *const*el, int numEl, fullVector<double> jac1B(jfs1->bezier->points.size1(), numEl); fullVector<double> jacBez, jacobian, jac1; - setJacobian(el, jfs, jacobianB); - setJacobian(el, jfs1, jac1B); + jfs->getSignedJacobian(el, jacobianB); + jfs1->getSignedJacobian(el, jac1B); bb->matrixLag2Bez.mult(jacobianB, jacBezB); #else fullVector<double> jacobian(numSamplingPt); @@ -564,8 +468,8 @@ void GMSH_AnalyseCurvedMeshPlugin::computeMinMax(MElement *const*el, int numEl, jacobian.setAsProxy(jacobianB, k); jac1.setAsProxy(jac1B, k); #else - setJacobian(el[k], jfs, jacobian); - setJacobian(el[k], jfs1, jac1); + jfs->getSignedJacobian(el[k], jacobian); + jfs1->getSignedJacobian(el[k], jac1); bb->matrixLag2Bez.mult(jacobian, jacBez); #endif