diff --git a/Numeric/JacobianBasis.cpp b/Numeric/JacobianBasis.cpp index e23bb8ca36893c3e27357e0a2cd2001a2c7d24ff..402cddd299ffd7bd3f5a361d2dd0fcf31f40d3fe 100644 --- a/Numeric/JacobianBasis.cpp +++ b/Numeric/JacobianBasis.cpp @@ -676,7 +676,7 @@ void JacobianBasis::interpolate(const fullVector<double> &jacobian, fullMatrix<double> JacobianBasis::generateJacMonomialsPyramid(int order) { - int nbMonomials = (order+3)*((order+3)+1)*(2*(order+3)+1)/6 - 5; + const int nbMonomials = (order+3)*(order+3)*(order+1); fullMatrix<double> monomials(nbMonomials, 3); if (order == 0) { @@ -706,28 +706,28 @@ fullMatrix<double> JacobianBasis::generateJacMonomialsPyramid(int order) monomials(4, 1) = 0; monomials(4, 2) = order; - monomials(5, 0) = 2; + monomials(5, 0) = order+2; monomials(5, 1) = 0; monomials(5, 2) = order; - monomials(6, 0) = 2; - monomials(6, 1) = 2; + monomials(6, 0) = order+2; + monomials(6, 1) = order+2; monomials(6, 2) = order; monomials(7, 0) = 0; - monomials(7, 1) = 2; + monomials(7, 1) = order+2; monomials(7, 2) = order; int index = 8; - static const int bottom_edges[8][2] = { + static const int bottom_edges[4][2] = { {0, 1}, {1, 2}, {2, 3}, {3, 0} }; - // bottom "edges" + // bottom & top "edges" for (int iedge = 0; iedge < 4; ++iedge) { int i0 = bottom_edges[iedge][0]; int i1 = bottom_edges[iedge][1]; @@ -740,22 +740,14 @@ fullMatrix<double> JacobianBasis::generateJacMonomialsPyramid(int order) monomials(index, 1) = monomials(i0, 1) + i * u_2; monomials(index, 2) = 0; } + for (int i = 1; i < order + 2; ++i, ++index) { + monomials(index, 0) = monomials(i0, 0) + i * u_1; + monomials(index, 1) = monomials(i0, 1) + i * u_2; + monomials(index, 2) = order; + } } - // top "edges" - for (int iedge = 0; iedge < 4; ++iedge, ++index) { - int i0 = bottom_edges[iedge][0] + 4; - int i1 = bottom_edges[iedge][1] + 4; - - int u_1 = (monomials(i1,0)-monomials(i0,0)) / 2; - int u_2 = (monomials(i1,1)-monomials(i0,1)) / 2; - - monomials(index, 0) = monomials(i0, 0) + u_1; - monomials(index, 1) = monomials(i0, 1) + u_2; - monomials(index, 2) = monomials(i0, 2); - } - - // bottom "face" + // bottom & top "face" fullMatrix<double> uv = gmshGenerateMonomialsQuadrangle(order); uv.add(1); for (int i = 0; i < uv.size1(); ++i, ++index) { @@ -763,16 +755,15 @@ fullMatrix<double> JacobianBasis::generateJacMonomialsPyramid(int order) monomials(index, 1) = uv(i, 1); monomials(index, 2) = 0; } - - // top "face" - monomials(index, 0) = 1; - monomials(index, 1) = 1; - monomials(index, 2) = order; - ++index; + for (int i = 0; i < uv.size1(); ++i, ++index) { + monomials(index, 0) = uv(i, 0); + monomials(index, 1) = uv(i, 1); + monomials(index, 2) = order; + } // other monomials + uv = gmshGenerateMonomialsQuadrangle(order + 2); for (int k = 1; k < order; ++k) { - fullMatrix<double> uv = gmshGenerateMonomialsQuadrangle(order + 2 - k); for (int i = 0; i < uv.size1(); ++i, ++index) { monomials(index, 0) = uv(i, 0); monomials(index, 1) = uv(i, 1); @@ -788,10 +779,10 @@ fullMatrix<double> JacobianBasis::generateJacPointsPyramid(int order) const double p = order + 2; for (int i = 0; i < points.size1(); ++i) { - points(i, 2) = points(i, 2) * 1. / p; - const double duv = -1. + points(i, 2); - points(i, 0) = duv + points(i, 0) * 2. / p; - points(i, 1) = duv + points(i, 1) * 2. / p; + points(i, 2) = points(i, 2) / p; + const double scale = 1. - points(i, 2); + points(i, 0) = (-1. + 2. * points(i, 0) / p) * scale; + points(i, 1) = (-1. + 2. * points(i, 1) / p) * scale; } return points; diff --git a/Numeric/MetricBasis.cpp b/Numeric/MetricBasis.cpp index 4b9aeb241729c48280988810ece9f4cf2cec5e6b..c94a3923ba6e3757b9560ef600472562944a6a5e 100644 --- a/Numeric/MetricBasis.cpp +++ b/Numeric/MetricBasis.cpp @@ -169,7 +169,7 @@ double MetricBasis::getMinR(MElement *el, MetricData *&md, int deg) const else*/ _computeRmin(*coeff, *jac, RminLag, RminBez, 0, false); - double betaOpt = beta, minaOpt, maxaOpt = 0., RminBezOpt; + double betaOpt = beta, minaOpt = mina, maxaOpt = maxa3, RminBezOpt; { /*const */double phi = std::acos(.5*(minK-maxa3*maxa3*maxa3+3*maxa3))/3; RminBezOpt = (maxa3+2*std::cos(phi+2*M_PI/3))/(maxa3+2*std::cos(phi)); diff --git a/Numeric/bezierBasis.cpp b/Numeric/bezierBasis.cpp index 9903be53515a43ea52a1cc4a661537ce164e30e8..0fd6fdb956b6d32fdee49fa54b2f6e5b3d29ad33 100644 --- a/Numeric/bezierBasis.cpp +++ b/Numeric/bezierBasis.cpp @@ -15,182 +15,222 @@ namespace { // Sub Control Points - std::vector< fullMatrix<double> > generateSubPointsLine(int order) - { - std::vector< fullMatrix<double> > subPoints(2); +std::vector< fullMatrix<double> > generateSubPointsLine(int order) +{ + std::vector< fullMatrix<double> > subPoints(2); - subPoints[0] = gmshGenerateMonomialsLine(order); - subPoints[0].scale(.5/order); + subPoints[0] = gmshGenerateMonomialsLine(order); + subPoints[0].scale(.5/order); - subPoints[1].copy(subPoints[0]); - subPoints[1].add(.5); + subPoints[1].copy(subPoints[0]); + subPoints[1].add(.5); - return subPoints; - } + return subPoints; +} - std::vector< fullMatrix<double> > generateSubPointsTriangle(int order) - { - std::vector< fullMatrix<double> > subPoints(4); - fullMatrix<double> prox; +std::vector< fullMatrix<double> > generateSubPointsTriangle(int order) +{ + std::vector< fullMatrix<double> > subPoints(4); + fullMatrix<double> prox; - subPoints[0] = gmshGenerateMonomialsTriangle(order); - subPoints[0].scale(.5/order); + subPoints[0] = gmshGenerateMonomialsTriangle(order); + subPoints[0].scale(.5/order); - subPoints[1].copy(subPoints[0]); - prox.setAsProxy(subPoints[1], 0, 1); - prox.add(.5); + subPoints[1].copy(subPoints[0]); + prox.setAsProxy(subPoints[1], 0, 1); + prox.add(.5); - subPoints[2].copy(subPoints[0]); - prox.setAsProxy(subPoints[2], 1, 1); - prox.add(.5); + subPoints[2].copy(subPoints[0]); + prox.setAsProxy(subPoints[2], 1, 1); + prox.add(.5); - subPoints[3].copy(subPoints[0]); - subPoints[3].scale(-1.); - subPoints[3].add(.5); + subPoints[3].copy(subPoints[0]); + subPoints[3].scale(-1.); + subPoints[3].add(.5); - return subPoints; - } + return subPoints; +} - std::vector< fullMatrix<double> > generateSubPointsQuad(int order) - { - std::vector< fullMatrix<double> > subPoints(4); - fullMatrix<double> prox; +std::vector< fullMatrix<double> > generateSubPointsQuad(int order) +{ + std::vector< fullMatrix<double> > subPoints(4); + fullMatrix<double> prox; - subPoints[0] = gmshGenerateMonomialsQuadrangle(order); - subPoints[0].scale(.5/order); + subPoints[0] = gmshGenerateMonomialsQuadrangle(order); + subPoints[0].scale(.5/order); - subPoints[1].copy(subPoints[0]); - prox.setAsProxy(subPoints[1], 0, 1); - prox.add(.5); + subPoints[1].copy(subPoints[0]); + prox.setAsProxy(subPoints[1], 0, 1); + prox.add(.5); - subPoints[2].copy(subPoints[0]); - prox.setAsProxy(subPoints[2], 1, 1); - prox.add(.5); + subPoints[2].copy(subPoints[0]); + prox.setAsProxy(subPoints[2], 1, 1); + prox.add(.5); - subPoints[3].copy(subPoints[1]); - prox.setAsProxy(subPoints[3], 1, 1); - prox.add(.5); + subPoints[3].copy(subPoints[1]); + prox.setAsProxy(subPoints[3], 1, 1); + prox.add(.5); - return subPoints; - } + return subPoints; +} - std::vector< fullMatrix<double> > generateSubPointsTetrahedron(int order) - { - std::vector< fullMatrix<double> > subPoints(8); - fullMatrix<double> prox1; - fullMatrix<double> prox2; +std::vector< fullMatrix<double> > generateSubPointsTetrahedron(int order) +{ + std::vector< fullMatrix<double> > subPoints(8); + fullMatrix<double> prox1; + fullMatrix<double> prox2; + + subPoints[0] = gmshGenerateMonomialsTetrahedron(order); + subPoints[0].scale(.5/order); + + subPoints[1].copy(subPoints[0]); + prox1.setAsProxy(subPoints[1], 0, 1); + prox1.add(.5); + + subPoints[2].copy(subPoints[0]); + prox1.setAsProxy(subPoints[2], 1, 1); + prox1.add(.5); + + subPoints[3].copy(subPoints[0]); + prox1.setAsProxy(subPoints[3], 2, 1); + prox1.add(.5); + + // u := .5-u-w + // v := .5-v-w + // w := w + subPoints[4].copy(subPoints[0]); + prox1.setAsProxy(subPoints[4], 0, 2); + prox1.scale(-1.); + prox1.add(.5); + prox1.setAsProxy(subPoints[4], 0, 1); + prox2.setAsProxy(subPoints[4], 2, 1); + prox1.add(prox2, -1.); + prox1.setAsProxy(subPoints[4], 1, 1); + prox1.add(prox2, -1.); + + // u := u + // v := .5-v + // w := w+v + subPoints[5].copy(subPoints[0]); + prox1.setAsProxy(subPoints[5], 2, 1); + prox2.setAsProxy(subPoints[5], 1, 1); + prox1.add(prox2); + prox2.scale(-1.); + prox2.add(.5); + + // u := .5-u + // v := v + // w := w+u + subPoints[6].copy(subPoints[0]); + prox1.setAsProxy(subPoints[6], 2, 1); + prox2.setAsProxy(subPoints[6], 0, 1); + prox1.add(prox2); + prox2.scale(-1.); + prox2.add(.5); + + // u := u+w + // v := v+w + // w := .5-w + subPoints[7].copy(subPoints[0]); + prox1.setAsProxy(subPoints[7], 0, 1); + prox2.setAsProxy(subPoints[7], 2, 1); + prox1.add(prox2); + prox1.setAsProxy(subPoints[7], 1, 1); + prox1.add(prox2); + prox2.scale(-1.); + prox2.add(.5); + + + return subPoints; +} - subPoints[0] = gmshGenerateMonomialsTetrahedron(order); - subPoints[0].scale(.5/order); +std::vector< fullMatrix<double> > generateSubPointsPrism(int order) +{ + std::vector< fullMatrix<double> > subPoints(8); + fullMatrix<double> prox; - subPoints[1].copy(subPoints[0]); - prox1.setAsProxy(subPoints[1], 0, 1); - prox1.add(.5); + subPoints[0] = gmshGenerateMonomialsPrism(order); + subPoints[0].scale(.5/order); - subPoints[2].copy(subPoints[0]); - prox1.setAsProxy(subPoints[2], 1, 1); - prox1.add(.5); + subPoints[1].copy(subPoints[0]); + prox.setAsProxy(subPoints[1], 0, 1); + prox.add(.5); - subPoints[3].copy(subPoints[0]); - prox1.setAsProxy(subPoints[3], 2, 1); - prox1.add(.5); + subPoints[2].copy(subPoints[0]); + prox.setAsProxy(subPoints[2], 1, 1); + prox.add(.5); - // u := .5-u-w - // v := .5-v-w - // w := w - subPoints[4].copy(subPoints[0]); - prox1.setAsProxy(subPoints[4], 0, 2); - prox1.scale(-1.); - prox1.add(.5); - prox1.setAsProxy(subPoints[4], 0, 1); - prox2.setAsProxy(subPoints[4], 2, 1); - prox1.add(prox2, -1.); - prox1.setAsProxy(subPoints[4], 1, 1); - prox1.add(prox2, -1.); - - // u := u - // v := .5-v - // w := w+v - subPoints[5].copy(subPoints[0]); - prox1.setAsProxy(subPoints[5], 2, 1); - prox2.setAsProxy(subPoints[5], 1, 1); - prox1.add(prox2); - prox2.scale(-1.); - prox2.add(.5); - - // u := .5-u - // v := v - // w := w+u - subPoints[6].copy(subPoints[0]); - prox1.setAsProxy(subPoints[6], 2, 1); - prox2.setAsProxy(subPoints[6], 0, 1); - prox1.add(prox2); - prox2.scale(-1.); - prox2.add(.5); - - // u := u+w - // v := v+w - // w := .5-w - subPoints[7].copy(subPoints[0]); - prox1.setAsProxy(subPoints[7], 0, 1); - prox2.setAsProxy(subPoints[7], 2, 1); - prox1.add(prox2); - prox1.setAsProxy(subPoints[7], 1, 1); - prox1.add(prox2); - prox2.scale(-1.); - prox2.add(.5); + subPoints[3].copy(subPoints[0]); + prox.setAsProxy(subPoints[3], 0, 2); + prox.scale(-1.); + prox.add(.5); + subPoints[4].copy(subPoints[0]); + prox.setAsProxy(subPoints[4], 2, 1); + prox.add(.5); - return subPoints; - } + subPoints[5].copy(subPoints[1]); + prox.setAsProxy(subPoints[5], 2, 1); + prox.add(.5); - std::vector< fullMatrix<double> > generateSubPointsPrism(int order) - { - std::vector< fullMatrix<double> > subPoints(8); - fullMatrix<double> prox; + subPoints[6].copy(subPoints[2]); + prox.setAsProxy(subPoints[6], 2, 1); + prox.add(.5); - subPoints[0] = gmshGenerateMonomialsPrism(order); - subPoints[0].scale(.5/order); + subPoints[7].copy(subPoints[3]); + prox.setAsProxy(subPoints[7], 2, 1); + prox.add(.5); - subPoints[1].copy(subPoints[0]); - prox.setAsProxy(subPoints[1], 0, 1); - prox.add(.5); + return subPoints; +} - subPoints[2].copy(subPoints[0]); - prox.setAsProxy(subPoints[2], 1, 1); - prox.add(.5); +std::vector< fullMatrix<double> > generateSubPointsHex(int order) +{ + std::vector< fullMatrix<double> > subPoints(8); + fullMatrix<double> prox; - subPoints[3].copy(subPoints[0]); - prox.setAsProxy(subPoints[3], 0, 2); - prox.scale(-1.); - prox.add(.5); + subPoints[0] = gmshGenerateMonomialsHexahedron(order); + subPoints[0].scale(.5/order); - subPoints[4].copy(subPoints[0]); - prox.setAsProxy(subPoints[4], 2, 1); - prox.add(.5); + subPoints[1].copy(subPoints[0]); + prox.setAsProxy(subPoints[1], 0, 1); + prox.add(.5); - subPoints[5].copy(subPoints[1]); - prox.setAsProxy(subPoints[5], 2, 1); - prox.add(.5); + subPoints[2].copy(subPoints[0]); + prox.setAsProxy(subPoints[2], 1, 1); + prox.add(.5); - subPoints[6].copy(subPoints[2]); - prox.setAsProxy(subPoints[6], 2, 1); - prox.add(.5); + subPoints[3].copy(subPoints[1]); + prox.setAsProxy(subPoints[3], 1, 1); + prox.add(.5); - subPoints[7].copy(subPoints[3]); - prox.setAsProxy(subPoints[7], 2, 1); - prox.add(.5); + subPoints[4].copy(subPoints[0]); + prox.setAsProxy(subPoints[4], 2, 1); + prox.add(.5); - return subPoints; - } + subPoints[5].copy(subPoints[1]); + prox.setAsProxy(subPoints[5], 2, 1); + prox.add(.5); - std::vector< fullMatrix<double> > generateSubPointsHex(int order) - { - std::vector< fullMatrix<double> > subPoints(8); + subPoints[6].copy(subPoints[2]); + prox.setAsProxy(subPoints[6], 2, 1); + prox.add(.5); + + subPoints[7].copy(subPoints[3]); + prox.setAsProxy(subPoints[7], 2, 1); + prox.add(.5); + + return subPoints; +} + +std::vector< fullMatrix<double> > generateSubPointsPyr(int order) +{ + if (order == 0) { + std::vector< fullMatrix<double> > subPoints(4); fullMatrix<double> prox; - subPoints[0] = gmshGenerateMonomialsHexahedron(order); - subPoints[0].scale(.5/order); + subPoints[0] = JacobianBasis::generateJacMonomialsPyramid(0); + subPoints[0].scale(.5/(order+2)); subPoints[1].copy(subPoints[0]); prox.setAsProxy(subPoints[1], 0, 1); @@ -204,64 +244,14 @@ namespace { prox.setAsProxy(subPoints[3], 1, 1); prox.add(.5); - subPoints[4].copy(subPoints[0]); - prox.setAsProxy(subPoints[4], 2, 1); - prox.add(.5); - - subPoints[5].copy(subPoints[1]); - prox.setAsProxy(subPoints[5], 2, 1); - prox.add(.5); - - subPoints[6].copy(subPoints[2]); - prox.setAsProxy(subPoints[6], 2, 1); - prox.add(.5); - - subPoints[7].copy(subPoints[3]); - prox.setAsProxy(subPoints[7], 2, 1); - prox.add(.5); - return subPoints; } - - std::vector< fullMatrix<double> > generateSubPointsPyr(int order) - { - if (order == 0) { - std::vector< fullMatrix<double> > subPoints(4); - fullMatrix<double> prox; - - subPoints[0] = JacobianBasis::generateJacMonomialsPyramid(order); - subPoints[0].scale(.5/(order+2)); - - subPoints[1].copy(subPoints[0]); - prox.setAsProxy(subPoints[1], 0, 1); - prox.add(.5); - - subPoints[2].copy(subPoints[0]); - prox.setAsProxy(subPoints[2], 1, 1); - prox.add(.5); - - subPoints[3].copy(subPoints[1]); - prox.setAsProxy(subPoints[3], 1, 1); - prox.add(.5); - - return subPoints; - } - - Msg::Error("Subpoints for pyramid p>1 not implemented !"); - return std::vector< fullMatrix<double> >(); - - /* + else { std::vector< fullMatrix<double> > subPoints(8); fullMatrix<double> ref, prox; subPoints[0] = JacobianBasis::generateJacMonomialsPyramid(order); - int nPts = subPoints[0].size1(); - for (int i = 0; i < nPts; ++i) { - const double factor = .5 / (order + 2 - subPoints[0](i, 2)); - subPoints[0](i, 0) = subPoints[0](i, 0) * factor; - subPoints[0](i, 1) = subPoints[0](i, 1) * factor; - subPoints[0](i, 2) = subPoints[0](i, 2) * .5 / (order + 2); - } + subPoints[0].scale(.5/(order+2)); subPoints[1].copy(subPoints[0]); prox.setAsProxy(subPoints[1], 0, 1); @@ -291,6 +281,7 @@ namespace { prox.setAsProxy(subPoints[7], 2, 1); prox.add(.5); + const int nPts = subPoints[0].size1(); for (int i = 0; i < 8; ++i) { for (int j = 0; j < nPts; ++j) { const double factor = (1. - subPoints[i](j, 2)); @@ -300,157 +291,154 @@ namespace { } return subPoints; - */ } +} - // Matrices generation - int nChoosek(int n, int k) - { - if (n < k || k < 0) { - Msg::Error("Wrong argument for combination."); - return 1; - } +// Matrices generation +int nChoosek(int n, int k) +{ + if (n < k || k < 0) { + Msg::Error("Wrong argument for combination. (%d, %d)", n, k); + return 1; + } - if (k > n/2) k = n-k; - if (k == 1) - return n; - if (k == 0) - return 1; + if (k > n/2) k = n-k; + if (k == 1) + return n; + if (k == 0) + return 1; - int c = 1; - for (int i = 1; i <= k; i++, n--) (c *= n) /= i; - return c; - } + int c = 1; + for (int i = 1; i <= k; i++, n--) (c *= n) /= i; + return c; +} - fullMatrix<double> generateBez2LagMatrix - (const fullMatrix<double> &exponent, const fullMatrix<double> &point, - int order, int dimSimplex) - { - if(exponent.size1() != point.size1() || exponent.size2() != point.size2()){ - Msg::Fatal("Wrong sizes for bez2lag matrix generation %d %d -- %d %d", - exponent.size1(),point.size1(), - exponent.size2(),point.size2()); - return fullMatrix<double>(1, 1); - } +fullMatrix<double> generateBez2LagMatrix + (const fullMatrix<double> &exponent, const fullMatrix<double> &point, + int order, int dimSimplex) +{ + if(exponent.size1() != point.size1() || exponent.size2() != point.size2()){ + Msg::Fatal("Wrong sizes for bez2lag matrix generation %d %d -- %d %d", + exponent.size1(),point.size1(), + exponent.size2(),point.size2()); + return fullMatrix<double>(1, 1); + } - int ndofs = exponent.size1(); - int dim = exponent.size2(); - - fullMatrix<double> bez2Lag(ndofs, ndofs); - for (int i = 0; i < ndofs; i++) { - for (int j = 0; j < ndofs; j++) { - double dd = 1.; - - { - double pointCompl = 1.; - int exponentCompl = order; - for (int k = 0; k < dimSimplex; k++) { - dd *= nChoosek(exponentCompl, (int) exponent(i, k)) - * pow(point(j, k), exponent(i, k)); - pointCompl -= point(j, k); - exponentCompl -= (int) exponent(i, k); - } - dd *= pow(pointCompl, exponentCompl); + int ndofs = exponent.size1(); + int dim = exponent.size2(); + + fullMatrix<double> bez2Lag(ndofs, ndofs); + for (int i = 0; i < ndofs; i++) { + for (int j = 0; j < ndofs; j++) { + double dd = 1.; + + { + double pointCompl = 1.; + int exponentCompl = order; + for (int k = 0; k < dimSimplex; k++) { + dd *= nChoosek(exponentCompl, (int) exponent(i, k)) + * pow(point(j, k), exponent(i, k)); + pointCompl -= point(j, k); + exponentCompl -= (int) exponent(i, k); } + dd *= pow(pointCompl, exponentCompl); + } - for (int k = dimSimplex; k < dim; k++) - dd *= nChoosek(order, (int) exponent(i, k)) - * pow(point(j, k), exponent(i, k)) - * pow(1. - point(j, k), order - exponent(i, k)); + for (int k = dimSimplex; k < dim; k++) + dd *= nChoosek(order, (int) exponent(i, k)) + * pow(point(j, k), exponent(i, k)) + * pow(1. - point(j, k), order - exponent(i, k)); - bez2Lag(j, i) = dd; - } + bez2Lag(j, i) = dd; } - return bez2Lag; } + return bez2Lag; +} - fullMatrix<double> generateBez2LagMatrixPyramid - (const fullMatrix<double> &exponent, const fullMatrix<double> &point, - int order) - { - if(exponent.size1() != point.size1() || exponent.size2() != point.size2() || - exponent.size2() != 3){ - Msg::Fatal("Wrong sizes for bez2lag matrix generation %d %d -- %d %d", - exponent.size1(),point.size1(), - exponent.size2(),point.size2()); - return fullMatrix<double>(1, 1); - } +fullMatrix<double> generateBez2LagMatrixPyramid + (const fullMatrix<double> &exponent, const fullMatrix<double> &point, + int order) +{ + if(exponent.size1() != point.size1() || exponent.size2() != point.size2() || + exponent.size2() != 3){ + Msg::Fatal("Wrong sizes for bez2lag matrix generation %d %d -- %d %d", + exponent.size1(),point.size1(), + exponent.size2(),point.size2()); + return fullMatrix<double>(1, 1); + } - int ndofs = exponent.size1(); - - fullMatrix<double> bez2Lag(ndofs, ndofs); - for (int i = 0; i < ndofs; i++) { - for (int j = 0; j < ndofs; j++) { - bez2Lag(i, j) = - nChoosek(order, exponent(j, 2)) - * pow_int(point(i, 2), exponent(j, 2)) - * pow_int(1. - point(i, 2), order - exponent(j, 2)); - - double p = order + 2 - exponent(j, 2); - double denom = 1. - point(i, 2); - bez2Lag(i, j) *= - nChoosek(p, exponent(j, 0)) - * nChoosek(p, exponent(j, 1)) - * pow_int(point(i, 0) / denom, exponent(j, 0)) - * pow_int(point(i, 1) / denom, exponent(j, 1)) - * pow_int(1. - point(i, 0) / denom, p - exponent(j, 0)) - * pow_int(1. - point(i, 1) / denom, p - exponent(j, 1)); - } + const int ndofs = exponent.size1(); + + fullMatrix<double> bez2Lag(ndofs, ndofs); + for (int i = 0; i < ndofs; i++) { + for (int j = 0; j < ndofs; j++) { + double denom = 1. - point(i, 2); + bez2Lag(i, j) = + nChoosek(order + 2, exponent(j, 0)) + * nChoosek(order + 2, exponent(j, 1)) + * nChoosek(order, exponent(j, 2)) + * pow_int(point(i, 0) / denom, exponent(j, 0)) + * pow_int(point(i, 1) / denom, exponent(j, 1)) + * pow_int(point(i, 2) , exponent(j, 2)) + * pow_int(1. - point(i, 0) / denom, order + 2 - exponent(j, 0)) + * pow_int(1. - point(i, 1) / denom, order + 2 - exponent(j, 1)) + * pow_int(1. - point(i, 2) , order - exponent(j, 2)); } - return bez2Lag; } + return bez2Lag; +} - fullMatrix<double> generateSubDivisor - (const fullMatrix<double> &exponents, const std::vector< fullMatrix<double> > &subPoints, - const fullMatrix<double> &lag2Bez, int order, int dimSimplex) - { - if (exponents.size1() != lag2Bez.size1() || exponents.size1() != lag2Bez.size2()){ - Msg::Fatal("Wrong sizes for Bezier Divisor %d %d -- %d %d", - exponents.size1(), lag2Bez.size1(), - exponents.size1(), lag2Bez.size2()); - return fullMatrix<double>(1, 1); - } +fullMatrix<double> generateSubDivisor + (const fullMatrix<double> &exponents, const std::vector< fullMatrix<double> > &subPoints, + const fullMatrix<double> &lag2Bez, int order, int dimSimplex) +{ + if (exponents.size1() != lag2Bez.size1() || exponents.size1() != lag2Bez.size2()){ + Msg::Fatal("Wrong sizes for Bezier Divisor %d %d -- %d %d", + exponents.size1(), lag2Bez.size1(), + exponents.size1(), lag2Bez.size2()); + return fullMatrix<double>(1, 1); + } - int nbPts = lag2Bez.size1(); - int nbSubPts = nbPts * subPoints.size(); + int nbPts = lag2Bez.size1(); + int nbSubPts = nbPts * subPoints.size(); - fullMatrix<double> intermediate2(nbPts, nbPts); - fullMatrix<double> subDivisor(nbSubPts, nbPts); + fullMatrix<double> intermediate2(nbPts, nbPts); + fullMatrix<double> subDivisor(nbSubPts, nbPts); - for (unsigned int i = 0; i < subPoints.size(); i++) { - fullMatrix<double> intermediate1 = - generateBez2LagMatrix(exponents, subPoints[i], order, dimSimplex); - lag2Bez.mult(intermediate1, intermediate2); - subDivisor.copy(intermediate2, 0, nbPts, 0, nbPts, i*nbPts, 0); - } - return subDivisor; + for (unsigned int i = 0; i < subPoints.size(); i++) { + fullMatrix<double> intermediate1 = + generateBez2LagMatrix(exponents, subPoints[i], order, dimSimplex); + lag2Bez.mult(intermediate1, intermediate2); + subDivisor.copy(intermediate2, 0, nbPts, 0, nbPts, i*nbPts, 0); } + return subDivisor; +} - fullMatrix<double> generateSubDivisorPyramid - (const fullMatrix<double> &exponents, const std::vector< fullMatrix<double> > &subPoints, - const fullMatrix<double> &lag2Bez, int order) - { - if (exponents.size1() != lag2Bez.size1() || exponents.size1() != lag2Bez.size2()){ - Msg::Fatal("Wrong sizes for Bezier Divisor %d %d -- %d %d", - exponents.size1(), lag2Bez.size1(), - exponents.size1(), lag2Bez.size2()); - return fullMatrix<double>(1, 1); - } +fullMatrix<double> generateSubDivisorPyramid + (const fullMatrix<double> &exponents, const std::vector< fullMatrix<double> > &subPoints, + const fullMatrix<double> &lag2Bez, int order) +{ + if (exponents.size1() != lag2Bez.size1() || exponents.size1() != lag2Bez.size2()){ + Msg::Fatal("Wrong sizes for Bezier Divisor %d %d -- %d %d", + exponents.size1(), lag2Bez.size1(), + exponents.size1(), lag2Bez.size2()); + return fullMatrix<double>(1, 1); + } - int nbPts = lag2Bez.size1(); - int nbSubPts = nbPts * subPoints.size(); + int nbPts = lag2Bez.size1(); + int nbSubPts = nbPts * subPoints.size(); - fullMatrix<double> intermediate2(nbPts, nbPts); - fullMatrix<double> subDivisor(nbSubPts, nbPts); + fullMatrix<double> intermediate2(nbPts, nbPts); + fullMatrix<double> subDivisor(nbSubPts, nbPts); - for (unsigned int i = 0; i < subPoints.size(); i++) { - fullMatrix<double> intermediate1 = - generateBez2LagMatrixPyramid(exponents, subPoints[i], order); - lag2Bez.mult(intermediate1, intermediate2); - subDivisor.copy(intermediate2, 0, nbPts, 0, nbPts, i*nbPts, 0); - } - return subDivisor; + for (unsigned int i = 0; i < subPoints.size(); i++) { + fullMatrix<double> intermediate1 = + generateBez2LagMatrixPyramid(exponents, subPoints[i], order); + lag2Bez.mult(intermediate1, intermediate2); + subDivisor.copy(intermediate2, 0, nbPts, 0, nbPts, i*nbPts, 0); } + return subDivisor; +} } void bezierBasis::interpolate(const fullMatrix<double> &coeffs, @@ -531,23 +519,23 @@ void bezierBasis::_construct(int parentType, int p) dim = 3; numLagCoeff = 8; _exponents = JacobianBasis::generateJacMonomialsPyramid(order); - if (order < 2) { - subPoints = generateSubPointsPyr(order); - numDivisions = static_cast<int>(subPoints.size()); - } - else { - numDivisions = 8; - static int a = 0; - if (++a == 1) Msg::Warning("Subdivision not available for pyramid p>1"); - } - fullMatrix<double> bezierPoints = _exponents; - bezierPoints.scale(1. / (order + 2)); + subPoints = generateSubPointsPyr(order); + numDivisions = static_cast<int>(subPoints.size()); + + fullMatrix<double> bezierPoints; + bezierPoints.resize(_exponents.size1(), _exponents.size2()); + const double p = order + 2; + for (int i = 0; i < bezierPoints.size1(); ++i) { + bezierPoints(i, 2) = _exponents(i, 2) / p; + const double scale = 1. - bezierPoints(i, 2); + bezierPoints(i, 0) = _exponents(i, 0) / p * scale; + bezierPoints(i, 1) = _exponents(i, 1) / p * scale; + } matrixBez2Lag = generateBez2LagMatrixPyramid(_exponents, bezierPoints, order); matrixBez2Lag.invert(matrixLag2Bez); - if (order < 2) - subDivisor = generateSubDivisorPyramid(_exponents, subPoints, matrixLag2Bez, order); + subDivisor = generateSubDivisorPyramid(_exponents, subPoints, matrixLag2Bez, order); return; } diff --git a/Plugin/AnalyseCurvedMesh.cpp b/Plugin/AnalyseCurvedMesh.cpp index c71682284a3412358353509df2e08af4515e039f..657ccbc53a1491efdd729a22f88e4f0a96e70823 100644 --- a/Plugin/AnalyseCurvedMesh.cpp +++ b/Plugin/AnalyseCurvedMesh.cpp @@ -110,7 +110,9 @@ std::string GMSH_AnalyseCurvedMeshPlugin::getHelp() const "\n" "- Recompute = {0,1}: If the mesh has changed, set to 1 to recompute the bounds.\n" "\n" - "- Tolerance = ]0, 1[: Tolerance on the computation of min(R) or min(J)"; + "- Tolerance = ]0, 1[: Tolerance on the computation of min(R) or min(J). " + "It should be at most 0.01 but it can be set to 1 to just check the validity of " + "the mesh."; } // Execution