diff --git a/Geo/MElement.cpp b/Geo/MElement.cpp index 9e2390629535053bbac9bcd13fe8fe6e61ab75c5..bccac6128cf1806a20507a7bf9a5fa79317f6865 100644 --- a/Geo/MElement.cpp +++ b/Geo/MElement.cpp @@ -263,8 +263,7 @@ double MElement::getJacobianDeterminant(double u, double v, double w) { return getJacobian(u,v,w,jac); } - -double MElement::getJacobian(double gsf[][3], double jac[3][3]) +double MElement::getJacobian(const fullMatrix<double> &gsf, double jac[3][3]) { jac[0][0] = jac[0][1] = jac[0][2] = 0.; jac[1][0] = jac[1][1] = jac[1][2] = 0.; @@ -272,11 +271,10 @@ double MElement::getJacobian(double gsf[][3], double jac[3][3]) for (int i = 0; i < getNumVertices(); i++) { const MVertex* v = getVertex(i); - double* gg = gsf[i]; for (int j = 0; j < 3; j++) { - jac[j][0] += v->x() * gg[j]; - jac[j][1] += v->y() * gg[j]; - jac[j][2] += v->z() * gg[j]; + jac[j][0] += v->x() * gsf(i, j); + jac[j][1] += v->y() * gsf(i, j); + jac[j][2] += v->z() * gsf(i, j); } } @@ -1039,6 +1037,64 @@ MElement *MElementFactory::create(int type, std::vector<MVertex*> &v, } } +/*const fullMatrix<double> &MElement::getShapeFunctionsAtIntegrationPoints (int integrationOrder, int functionSpaceOrder) { + static std::map <std::pair<int,int>, fullMatrix<double> > F; + const polynomialBasis *fs = getFunctionSpace (functionSpaceOrder); + fullMatrix<double> &mat = F [std::make_pair(fs->type, integrationOrder)]; + if (mat.size1()!=0) return mat; + int npts; + IntPt *pts; + getIntegrationPoints (integrationOrder, &npts, &pts); + mat.resize (fs->points.size1(), npts); + double f[512]; + for (int i = 0; i < npts; i++) { + fs->f (pts[i].pt[0], pts[i].pt[1], pts[i].pt[2], f); + for (int j = 0; j < fs->points.size1(); j++) { + mat (i, j) = f[j]; + } + } + return mat; +}*/ + +const fullMatrix<double> &MElement::getGradShapeFunctionsAtIntegrationPoints (int integrationOrder, int functionSpaceOrder) { + static std::map <std::pair<int,int>, fullMatrix<double> > DF; + const polynomialBasis *fs = getFunctionSpace (functionSpaceOrder); + fullMatrix<double> &mat = DF [std::make_pair(fs->type, integrationOrder)]; + if (mat.size1()!=0) return mat; + int npts; + IntPt *pts; + getIntegrationPoints (integrationOrder, &npts, &pts); + mat.resize (fs->points.size1(), npts*3); + double df[512][3]; + for (int i = 0; i < npts; i++) { + fs->df (pts[i].pt[0], pts[i].pt[1], pts[i].pt[2], df); + for (int j = 0; j < fs->points.size1(); j++) { + mat (j, i*3+0) = df[j][0]; + mat (j, i*3+1) = df[j][1]; + mat (j, i*3+2) = df[j][2]; + } + } + return mat; +} +const fullMatrix<double> &MElement::getGradShapeFunctionsAtNodes (int functionSpaceOrder) { + static std::map <int, fullMatrix<double> > DF; + const polynomialBasis *fs = getFunctionSpace (functionSpaceOrder); + fullMatrix<double> &mat = DF [fs->type]; + if (mat.size1()!=0) return mat; + const fullMatrix<double> &points = fs->points; + mat.resize (points.size1(), points.size1()*3); + double df[512][3]; + for (int i = 0; i < points.size1(); i++) { + fs->df (points(i,0), points(i,1), points(i,2), df); + for (int j = 0; j < points.size1(); j++) { + mat (j, i*3+0) = df[j][0]; + mat (j, i*3+1) = df[j][1]; + mat (j, i*3+2) = df[j][2]; + } + } + return mat; +} + #include "Bindings.h" void MElement::registerBindings(binding *b) diff --git a/Geo/MElement.h b/Geo/MElement.h index ee26dfce960c6121cb0f42ae4e45de6305f058d0..0d5ac4bc74bcbdb69afb5e33b186823fb4fc8f28 100644 --- a/Geo/MElement.h +++ b/Geo/MElement.h @@ -88,8 +88,7 @@ class MElement // get the vertex using the VTK ordering virtual MVertex *getVertexVTK(int num){ return getVertex(num); } - - // get the vertex using the Nastran BDF ordering +// get the vertex using the Nastran BDF ordering virtual MVertex *getVertexBDF(int num){ return getVertex(num); } // get the vertex using MED ordering @@ -223,9 +222,12 @@ class MElement int order=-1); virtual void getHessShapeFunctions(double u, double v, double w, double s[][3][3], int order=-1); + //const fullMatrix<double> &getShapeFunctionsAtIntegrationPoints (int integrationOrder, int functionSpaceOrder=-1); + const fullMatrix<double> &getGradShapeFunctionsAtIntegrationPoints (int integrationOrder, int functionSpaceOrder=-1); + const fullMatrix<double> &getGradShapeFunctionsAtNodes (int functionSpaceOrder=-1); // return the Jacobian of the element evaluated at point (u,v,w) in // parametric coordinates - double getJacobian(double gsf[][3], double jac[3][3]); + double getJacobian(const fullMatrix<double> &gsf, double jac[3][3]); double getJacobian(double u, double v, double w, double jac[3][3]); double getPrimaryJacobian(double u, double v, double w, double jac[3][3]); //bindings : double[3][3] is not easy to bind, we could use fullMatrix instead diff --git a/Geo/MTetrahedron.h b/Geo/MTetrahedron.h index 6ae19d0f941320fb773ff3cae557f509519afc14..fb735a6cc261e24c1dfd57e5d7cea837b13b64c6 100644 --- a/Geo/MTetrahedron.h +++ b/Geo/MTetrahedron.h @@ -308,44 +308,6 @@ class MTetrahedron10 : public MTetrahedron { * */ -static int reverseTet20[20] = {0,2,1,3, // principal vertices - 9,8, // E0 switches with E2 - 7,6, // E1 inverts direction - 5,4, // E2 switches with E0 - 10,11, // E3 pure w edge > remains the same - 14,15, // E4 uw edge swithes with v/w edge E5 - 12,13, // E5 switches with E4 - 16, // F0 is uv plane, reverts normal - 18, // F1 is uw plane, switches with F2 - 17, // F2 is vw plane, switches with F1 - 19}; // F3 is uvw plane, reverts normal - -static int reverseTet35[35] = {0,2,1,3, // principal vertices - - 12,11,10, // E0 switches with E2 - 9,8,7, // E1 inverts direction - 6,5,4, // E2 switches with E0 - 13,14,15, // E3 pure w edge > remains the same - 19,20,21, // E4 uw edge swithes with v/w edge E5 - 16,17,18, // E5 switches with E4 - 22,24,23, // F0 is uv plane, reverts normal - 28,30,29, // F1 is uw plane, switches with F2, orientation is different - 25,27,26, // F2 is vw plane, switches with F1 - 31,33,32, // F3 is uvw plane, reverts normal - 34}; // central node remains - -static int reverseTet34[34] = {0,2,1,3, // principal vertices - 12,11,10, // E0 switches with E2 - 9,8,7, // E1 inverts direction - 6,5,4, // E2 switches with E0 - 13,14,15, // E3 pure w edge > remains the same - 19,20,21, // E4 uw edge swithes with v/w edge E5 - 16,17,18, // E5 switches with E4 - 22,24,23, // F0 is uv plane, reverts normal - 28,29,30, // F1 is uw plane, switches with F2 - 25,26,27, // F2 is vw plane, switches with F1 - 31,33,32};// F3 is uvw plane, reverts normal - class MTetrahedronN : public MTetrahedron { const static std::vector<int> &_getReverseIndices(int order); protected: diff --git a/Mesh/HighOrder.cpp b/Mesh/HighOrder.cpp index d10ff18ba3ccc980486a131d8635ef82745fce74..c95bf5618af3d4af2c5e23ef7b7070fc170e6406 100644 --- a/Mesh/HighOrder.cpp +++ b/Mesh/HighOrder.cpp @@ -27,36 +27,31 @@ static bool mappingIsInvertible(MTetrahedron *e) { - if (e->getPolynomialOrder() == 1) return 1.0; + if (e->getPolynomialOrder() == 1) return true; double mat[3][3]; e->getPrimaryJacobian(0., 0., 0., mat); double det0 = det3x3(mat); - - IntPt *pts; - int npts; - e->getIntegrationPoints(e->getPolynomialOrder(), &npts, &pts); - for (int i = 0; i < npts; i++){ - const double u = pts[i].pt[0]; - const double v = pts[i].pt[1]; - const double w = pts[i].pt[2]; - e->getJacobian(u, v, w, mat); - double detN = det3x3(mat); - if (det0 * detN <= 0.) return false; + fullMatrix<double> df; + { + const fullMatrix<double> &alldf = e->getGradShapeFunctionsAtIntegrationPoints(e->getPolynomialOrder()); + for (int i = 0; i < alldf.size2()/3; i++){ + df.setAsProxy(alldf, 3*i, 3); + e->getJacobian(df, mat); + if (det0 * det3x3(mat) <= 0.) return false; + } } - - const fullMatrix<double> &points = e->getFunctionSpace()->points; - - for (int i = 0; i < e->getNumPrimaryVertices(); i++) { - const double u = points(i,0); - const double v = points(i,1); - const double w = points(i,2); - e->getJacobian(u, v, w, mat); - double detN = det3x3(mat); - if (det0 * detN <= 0.) return false; + { + const fullMatrix<double> &points = e->getFunctionSpace()->points; + const fullMatrix<double> &alldf = e->getGradShapeFunctionsAtNodes(e->getPolynomialOrder()); + double gradShapeFunctions[300][3]; + for (int i = 0; i < alldf.size2()/3; i++){ + df.setAsProxy(alldf, 3*i, 3); + e->getJacobian(df, mat); + if (det0 * det3x3(mat) <= 0.) return false; + } } - return true; } diff --git a/Numeric/polynomialBasis.cpp b/Numeric/polynomialBasis.cpp index 629060dedd1fb5ab1f6438974d3fc755aee3f061..7a6ea597a99faf3ac191465bc7ec59270f012eb9 100644 --- a/Numeric/polynomialBasis.cpp +++ b/Numeric/polynomialBasis.cpp @@ -1354,6 +1354,7 @@ const polynomialBasis *polynomialBases::find(int tag) generate3dFaceClosure(F.closures, 1); break; } + F.type = tag; F.coefficients = generateLagrangeMonomialCoefficients(F.monomials, F.points); // printf("Case: %d coeffs:\n",tag); diff --git a/Numeric/polynomialBasis.h b/Numeric/polynomialBasis.h index 805df454d6da187b55d144275ab9aefcfe89d101..3779c6716aa73fcba9622598b5ec0401a4acf0d1 100644 --- a/Numeric/polynomialBasis.h +++ b/Numeric/polynomialBasis.h @@ -70,6 +70,8 @@ class binding; class polynomialBasis { public: + //for now the only implemented polynomial basis are nodal poly basis, we use the type of the corresponding gmsh element as type + int type; typedef std::vector<std::vector<int> > clCont; clCont closures; fullMatrix<double> points;