diff --git a/Numeric/CMakeLists.txt b/Numeric/CMakeLists.txt index 8abf9bc3f3749692942d81cd77b6232bae92901b..d7a0f85162762cad918498d8e384a620a25851f9 100644 --- a/Numeric/CMakeLists.txt +++ b/Numeric/CMakeLists.txt @@ -16,6 +16,7 @@ set(SRC legendrePolynomials.cpp bezierBasis.cpp JacobianBasis.cpp + MetricBasis.cpp pointsGenerators.cpp ElementType.cpp GaussIntegration.cpp diff --git a/Numeric/JacobianBasis.cpp b/Numeric/JacobianBasis.cpp index 20af53c78f1f85203916b7a58c3c8eb028e2d4a6..40a18eac4f094244fabcbc4ef391f32c79797050 100644 --- a/Numeric/JacobianBasis.cpp +++ b/Numeric/JacobianBasis.cpp @@ -605,6 +605,17 @@ void JacobianBasis::getMetricMinAndGradients(const fullMatrix<double> &nodesXYZ, } +void JacobianBasis::interpolate(const fullVector<double> &jacobian, + const fullMatrix<double> &uvw, + fullMatrix<double> &result) const +{ + fullMatrix<double> bezM(jacobian.size(), 1); + fullVector<double> bez; + bez.setAsProxy(bezM, 0); + lag2Bez(jacobian, bez); + bezier->interpolate(bezM, uvw, result); +} + fullMatrix<double> JacobianBasis::generateJacMonomialsPyramid(int order) { int nbMonomials = (order+3)*((order+3)+1)*(2*(order+3)+1)/6 - 5; diff --git a/Numeric/JacobianBasis.h b/Numeric/JacobianBasis.h index 8a08f18e69ef38e11b2d73acaca3d1b8cfff4b95..2c71d649bdc8dec293988bc80b94b7f2e4a6a857 100644 --- a/Numeric/JacobianBasis.h +++ b/Numeric/JacobianBasis.h @@ -72,22 +72,22 @@ class JacobianBasis { inline void getSignedJacobian(const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const { getSignedJacobianGeneral(numJacNodes,gradShapeMatX,gradShapeMatY,gradShapeMatZ,nodesXYZ,jacobian); } - inline void getSignedJacobianFast(const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const { - getSignedJacobianGeneral(numJacNodesFast,gradShapeMatXFast,gradShapeMatYFast,gradShapeMatZFast,nodesXYZ,jacobian); - } inline void getSignedJacobian(const fullMatrix<double> &nodesX, const fullMatrix<double> &nodesY, const fullMatrix<double> &nodesZ, fullMatrix<double> &jacobian) const { getSignedJacobianGeneral(numJacNodes,gradShapeMatX,gradShapeMatY, gradShapeMatZ,nodesX,nodesY,nodesZ,jacobian); } + inline void getScaledJacobian(const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const { + getScaledJacobianGeneral(numJacNodes,gradShapeMatX,gradShapeMatY,gradShapeMatZ,nodesXYZ,jacobian); + } + inline void getSignedJacobianFast(const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const { + getSignedJacobianGeneral(numJacNodesFast,gradShapeMatXFast,gradShapeMatYFast,gradShapeMatZFast,nodesXYZ,jacobian); + } inline void getSignedJacobianFast(const fullMatrix<double> &nodesX, const fullMatrix<double> &nodesY, const fullMatrix<double> &nodesZ, fullMatrix<double> &jacobian) const { getSignedJacobianGeneral(numJacNodesFast,gradShapeMatXFast,gradShapeMatYFast, gradShapeMatZFast,nodesX,nodesY,nodesZ,jacobian); } - inline void getScaledJacobian(const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const { - getScaledJacobianGeneral(numJacNodes,gradShapeMatX,gradShapeMatY,gradShapeMatZ,nodesXYZ,jacobian); - } inline void getScaledJacobianFast(const fullMatrix<double> &nodesXYZ, fullVector<double> &jacobian) const { getScaledJacobianGeneral(numJacNodesFast,gradShapeMatXFast,gradShapeMatYFast,gradShapeMatZFast,nodesXYZ,jacobian); } @@ -104,6 +104,10 @@ class JacobianBasis { inline void subdivideBezierCoeff(const fullVector<double> &bez, fullVector<double> &result) const { bezier->subDivisor.mult(bez,result); } + // + void interpolate(const fullVector<double> &jacobian, + const fullMatrix<double> &uvw, + fullMatrix<double> &result) const; // Jacobian basis order and pyramidal basis void getGradientsFromNodes(const fullMatrix<double> &nodes, diff --git a/Numeric/MetricBasis.cpp b/Numeric/MetricBasis.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f1b2292d8a06f296ab9b342158f60e4286e1a48c --- /dev/null +++ b/Numeric/MetricBasis.cpp @@ -0,0 +1,333 @@ +// Gmsh - Copyright (C) 1997-2013 C. Geuzaine, J.-F. Remacle +// +// See the LICENSE.txt file for license information. Please report all +// bugs and problems to the public mailing list <gmsh@geuz.org>. + +#include "MetricBasis.h" +//#include "GmshDefines.h" +#include "BasisFactory.h" +#include "pointsGenerators.h" +#include <cmath> + +MetricCoefficient::MetricCoefficient(MElement *el) : _element(el) +{ + _jacobian = BasisFactory::getJacobianBasis(el->getTypeForMSH()); + + int nJac = _jacobian->getNumJacNodes(); + int nMapping = _jacobian->getNumMapNodes(); + fullMatrix<double> nodesXYZ(nMapping, 3); + el->getNodesCoord(nodesXYZ); + + switch (el->getDim()) { + case 0 : + return; + + case 1 : + { + Msg::Fatal("not implemented"); + } + break; + + case 2 : + { + Msg::Fatal("not implemented"); + } + break; + + case 3 : + { + fullMatrix<double> dxyzdX(nJac,3), dxyzdY(nJac,3), dxyzdZ(nJac,3); + _jacobian->getGradientsFromNodes(nodesXYZ, &dxyzdX, &dxyzdY, &dxyzdZ); + + _coefficientsLag.resize(nJac, 7); + for (int i = 0; i < nJac; 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); + const double dvxdX = dxdX*dxdX + dydX*dydX + dzdX*dzdX; + const double dvxdY = dxdY*dxdY + dydY*dydY + dzdY*dzdY; + const double dvxdZ = dxdZ*dxdZ + dydZ*dydZ + dzdZ*dzdZ; + _coefficientsLag(i, 0) = (dvxdX + dvxdY + dvxdZ) / 3; + _coefficientsLag(i, 1) = dvxdX - _coefficientsLag(i, 0); + _coefficientsLag(i, 2) = dvxdY - _coefficientsLag(i, 0); + _coefficientsLag(i, 3) = dvxdZ - _coefficientsLag(i, 0); + _coefficientsLag(i, 4) = dxdX*dxdY + dydX*dydY + dzdX*dzdY; + _coefficientsLag(i, 5) = dxdZ*dxdY + dydZ*dydY + dzdZ*dzdY; + _coefficientsLag(i, 6) = dxdX*dxdZ + dydX*dydZ + dzdX*dzdZ; + } + } + break; + } +} + +void MetricCoefficient::getCoefficients(fullMatrix<double> &coeff, bool bezier) +{ + fullMatrix<double> *ref; + switch (_coefficientsLag.size2()) { + case 1: + if (!bezier) coeff = _coefficientsLag; + else { + if (_coefficientsBez.size2() != 1) _computeBezCoeff(); + coeff = _coefficientsBez; + } + break; + + case 3: + if (!bezier) ref = &_coefficientsLag; + else { + if (_coefficientsBez.size2() != 3) _computeBezCoeff(); + ref = &_coefficientsBez; + } + coeff.resize(ref->size1(), 2); + for (int i = 0; i < ref->size1(); ++i) { + double tmp = pow((*ref)(i, 1), 2); + tmp += pow((*ref)(i, 2), 2); + tmp = std::sqrt(tmp); + coeff(i, 0) = (*ref)(i, 0) - tmp; + coeff(i, 1) = (*ref)(i, 0) + tmp; + } + break; + + case 7: + if (!bezier) ref = &_coefficientsLag; + else { + if (_coefficientsBez.size2() != 7) _computeBezCoeff(); + ref = &_coefficientsBez; + } + coeff.resize(ref->size1(), 2); + for (int i = 0; i < ref->size1(); ++i) { + double tmp = pow((*ref)(i, 1), 2); + tmp += pow((*ref)(i, 2), 2); + tmp += pow((*ref)(i, 3), 2); + tmp += 2 * pow((*ref)(i, 4), 2); + tmp += 2 * pow((*ref)(i, 5), 2); + tmp += 2 * pow((*ref)(i, 6), 2); + tmp = std::sqrt(tmp); + double factor = std::sqrt(6)/3; + coeff(i, 0) = (*ref)(i, 0) - factor * tmp; + coeff(i, 1) = (*ref)(i, 0) + factor * tmp; + } + break; + + default: + Msg::Error("Wrong number of functions for metric: %d", + _coefficientsLag.size2()); + } +} + +static int nChoosek(int n, int k) +{ + if (n < k || k < 0) { + Msg::Error("Wrong argument for combination."); + 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; +} + +void MetricCoefficient::interpolate(const double *uvw, double *minmaxQ) +{ + if (minmaxQ == NULL) { + Msg::Error("Cannot write solution of interpolation"); + return; + } + + int order = _jacobian->bezier->getOrder(); + + int dimSimplex; + fullMatrix<double> exponents; + double bezuvw[3]; + switch (_element->getType()) { + case TYPE_PYR: + bezuvw[0] = .5 * (1 + uvw[0]); + bezuvw[1] = .5 * (1 + uvw[1]); + bezuvw[2] = uvw[2]; + _interpolateBezierPyramid(uvw, minmaxQ); + return; + + case TYPE_HEX: + bezuvw[0] = .5 * (1 + uvw[0]); + bezuvw[1] = .5 * (1 + uvw[1]); + bezuvw[2] = .5 * (1 + uvw[2]); + dimSimplex = 0; + exponents = gmshGenerateMonomialsHexahedron(order); + break; + + case TYPE_TET: + bezuvw[0] = uvw[0]; + bezuvw[1] = uvw[1]; + bezuvw[2] = uvw[2]; + dimSimplex = 3; + exponents = gmshGenerateMonomialsTetrahedron(order); + break; + + case TYPE_PRI: + bezuvw[0] = uvw[0]; + bezuvw[1] = uvw[1]; + bezuvw[2] = .5 * (1 + uvw[2]); + dimSimplex = 2; + exponents = gmshGenerateMonomialsPrism(order); + break; + } + + int numCoeff = exponents.size1(); + int dim = exponents.size2(); + + if (_coefficientsBez.size2() == 0) _computeBezCoeff(); + + double *terms = new double[_coefficientsBez.size2()]; + for (int t = 0; t < _coefficientsBez.size2(); ++t) { + terms[t] = 0; + for (int i = 0; i < numCoeff; i++) { + double dd = 1; + double pointCompl = 1.; + int exponentCompl = order; + for (int k = 0; k < dimSimplex; k++) { + dd *= nChoosek(exponentCompl, (int) exponents(i, k)) + * pow(bezuvw[k], exponents(i, k)); + pointCompl -= bezuvw[k]; + exponentCompl -= (int) exponents(i, k); + } + dd *= pow(pointCompl, exponentCompl); + + for (int k = dimSimplex; k < dim; k++) + dd *= nChoosek(order, (int) exponents(i, k)) + * pow(bezuvw[k], exponents(i, k)) + * pow(1. - bezuvw[k], order - exponents(i, k)); + terms[t] += _coefficientsBez(i, t) * dd; + } + } + + switch (_coefficientsBez.size2()) { + case 1: + minmaxQ[0] = terms[0]; + minmaxQ[1] = terms[0]; + break; + + case 3: + { + double tmp = pow(terms[1], 2); + tmp += pow(terms[2], 2); + tmp = std::sqrt(tmp); + minmaxQ[0] = terms[0] - tmp; + minmaxQ[1] = terms[0] + tmp; + } + break; + + case 7: + { + double tmp = pow(terms[1], 2); + tmp += pow(terms[2], 2); + tmp += pow(terms[3], 2); + tmp += 2 * pow(terms[4], 2); + tmp += 2 * pow(terms[5], 2); + tmp += 2 * pow(terms[6], 2); + tmp = std::sqrt(tmp); + double factor = std::sqrt(6)/3; + if (tmp < 1e-3*terms[0]) { + static int aa = 0; + Msg::Info("%d", ++aa); + minmaxQ[0] = terms[0] - factor * tmp; + minmaxQ[1] = terms[0] + factor * tmp; + } + else { + double phi; + { + fullMatrix<double> nodes(_jacobian->getNumMapNodes(),3); + _element->getNodesCoord(nodes); + fullVector<double> jac(_jacobian->getNumJacNodes()); + _jacobian->getSignedJacobian(nodes, jac); + + nodes.resize(1, 3); + nodes(0, 0) = uvw[0]; + nodes(0, 1) = uvw[1]; + nodes(0, 2) = uvw[2]; + + fullMatrix<double> result; + _jacobian->interpolate(jac, nodes, result); + phi = result(0, 0)*result(0, 0); + } + phi -= terms[0]*terms[0]*terms[0]; + phi += .5*terms[0]*tmp*tmp; + phi /= tmp*tmp*tmp; + phi *= 3*std::sqrt(6); + phi = std::acos(phi)/3; + minmaxQ[0] = terms[0] + factor * tmp * std::cos(phi + 2*M_PI/3); + minmaxQ[1] = terms[0] + factor * tmp * std::cos(phi); + } + } + break; + + default: + Msg::Error("Wrong number of functions for metric: %d", + _coefficientsLag.size2()); + } +} + +void MetricCoefficient::_interpolateBezierPyramid(const double *uvw, double *minmaxQ) +{ + int order = _jacobian->bezier->getOrder(); + + fullMatrix<double> exponents = JacobianBasis::generateJacMonomialsPyramid(order); + int numCoeff = exponents.size1(); + + if (_coefficientsBez.size2() == 0) _computeBezCoeff(); + + static int aa = 0; + if (++aa == 1) { + fullMatrix<double> val; + getCoefficients(val, true); + for (int i = 0; i < val.size2(); ++i) { + Msg::Info("--------- column %d", i); + for (int j = 0; j < val.size1(); ++j) { + Msg::Info("%.2e", val(j, i)); + } + } + } + double terms[7]; + for (int t = 0; t < _coefficientsBez.size2(); ++t) { + terms[t] = 0; + for (int j = 0; j < numCoeff; j++) { + double dd = + nChoosek(order, exponents(j, 2)) + * pow(uvw[2], exponents(j, 2)) + * pow(1. - uvw[2], order - exponents(j, 2)); + + double p = order + 2 - exponents(j, 2); + double denom = 1. - uvw[2]; + dd *= nChoosek(p, exponents(j, 0)) + * nChoosek(p, exponents(j, 1)) + * pow(uvw[0] / denom, exponents(j, 0)) + * pow(uvw[1] / denom, exponents(j, 1)) + * pow(1. - uvw[0] / denom, p - exponents(j, 0)) + * pow(1. - uvw[1] / denom, p - exponents(j, 1)); + terms[t] += _coefficientsBez(j, t) * dd; + } + } + + double tmp = pow(terms[1], 2); + tmp += pow(terms[2], 2); + tmp += pow(terms[3], 2); + tmp += 2 * pow(terms[4], 2); + tmp += 2 * pow(terms[5], 2); + tmp += 2 * pow(terms[6], 2); + tmp = std::sqrt(tmp); + double factor = std::sqrt(6)/3; + minmaxQ[0] = terms[0] - factor * tmp; + minmaxQ[1] = terms[0] + factor * tmp; +} + +void MetricCoefficient::_computeBezCoeff() +{ + _coefficientsBez.resize(_coefficientsLag.size1(), + _coefficientsLag.size2()); + _jacobian->lag2Bez(_coefficientsLag, _coefficientsBez); +} diff --git a/Numeric/MetricBasis.h b/Numeric/MetricBasis.h new file mode 100644 index 0000000000000000000000000000000000000000..5c2ee6da791719262d2163a184dbc6084e485637 --- /dev/null +++ b/Numeric/MetricBasis.h @@ -0,0 +1,30 @@ +// Gmsh - Copyright (C) 1997-2013 C. Geuzaine, J.-F. Remacle +// +// See the LICENSE.txt file for license information. Please report all +// bugs and problems to the public mailing list <gmsh@geuz.org>. + +#ifndef _METRIC_BASIS_H_ +#define _METRIC_BASIS_H_ + +#include "MElement.h" +#include "JacobianBasis.h" +#include "fullMatrix.h" + +class MetricCoefficient { + private: + MElement *_element; + const JacobianBasis *_jacobian; + fullMatrix<double> _coefficientsLag, _coefficientsBez; + + public: + MetricCoefficient(MElement*); + void getCoefficients(fullMatrix<double>&, bool bezier = true); + void interpolate(const double *uvw, double *minmaxQ); + void getBound(double tol); + + private: + void _computeBezCoeff(); + void _interpolateBezierPyramid(const double *uvw, double *minmaxQ); +}; + +#endif diff --git a/Numeric/bezierBasis.cpp b/Numeric/bezierBasis.cpp index 054fdaa958ddff38f2f7265284e44e1dd11ae5fe..3bc3f9c50c6aa2196deb00ac6fda6f9f475299ee 100644 --- a/Numeric/bezierBasis.cpp +++ b/Numeric/bezierBasis.cpp @@ -453,16 +453,84 @@ namespace { } } +void bezierBasis::interpolate(const fullMatrix<double> &coeffs, + const fullMatrix<double> &uvw, + fullMatrix<double> &result, + bool bezCoord) const +{ + result.resize(uvw.size1(), coeffs.size2()); + int dimSimplex; + fullMatrix<double> bezuvw = uvw; + switch (type) { + case TYPE_HEX: + if (!bezCoord) { + bezuvw.add(1); + bezuvw.scale(.5); + } + dimSimplex = 0; + break; + + case TYPE_TET: + dimSimplex = 3; + break; + + case TYPE_PRI: + if (!bezCoord) { + fullMatrix<double> tmp; + tmp.setAsProxy(bezuvw, 3, 1); + tmp.add(1); + tmp.scale(.5); + } + dimSimplex = 2; + break; + + default: + case TYPE_PYR: + Msg::Error("Bezier interpolation not implemented for type of element %d", type); + /*bezuvw[0] = .5 * (1 + uvw[0]); + bezuvw[1] = .5 * (1 + uvw[1]); + bezuvw[2] = uvw[2]; + _interpolateBezierPyramid(uvw, minmaxQ);*/ + return; + } + + int numCoeff = _exponents.size1(); + + for (int m = 0; m < uvw.size1(); ++m) { + for (int n = 0; n < coeffs.size2(); ++n) result(m, n) = 0; + for (int i = 0; i < numCoeff; i++) { + double dd = 1; + double pointCompl = 1.; + int exponentCompl = order; + for (int k = 0; k < dimSimplex; k++) { + dd *= nChoosek(exponentCompl, (int) _exponents(i, k)) + * pow(bezuvw(m, k), _exponents(i, k)); + pointCompl -= bezuvw(m, k); + exponentCompl -= (int) _exponents(i, k); + } + dd *= pow_int(pointCompl, exponentCompl); + + for (int k = dimSimplex; k < dim; k++) { + dd *= nChoosek(order, (int) _exponents(i, k)) + * pow_int(bezuvw(m, k), _exponents(i, k)) + * pow_int(1. - bezuvw(m, k), order - _exponents(i, k)); + } + for (int n = 0; n < coeffs.size2(); ++n) + result(m, n) += coeffs(i, n) * dd; + } + } +} + void bezierBasis::_construct(int parentType, int p) { order = p; - fullMatrix<double> exponents; + type = parentType; std::vector< fullMatrix<double> > subPoints; if (parentType == TYPE_PYR) { dim = 3; numLagCoeff = 8; - exponents = JacobianBasis::generateJacMonomialsPyramid(order); + _exponents = JacobianBasis::generateJacMonomialsPyramid(order); if (order < 2) { subPoints = generateSubPointsPyr(order); numDivisions = static_cast<int>(subPoints.size()); @@ -473,13 +541,13 @@ void bezierBasis::_construct(int parentType, int p) if (++a == 1) Msg::Warning("Subdivision not available for pyramid p>1"); } - fullMatrix<double> bezierPoints = exponents; + fullMatrix<double> bezierPoints = _exponents; bezierPoints.scale(1. / (order + 2)); - matrixBez2Lag = generateBez2LagMatrixPyramid(exponents, bezierPoints, order); + matrixBez2Lag = generateBez2LagMatrixPyramid(_exponents, bezierPoints, order); matrixBez2Lag.invert(matrixLag2Bez); if (order < 2) - subDivisor = generateSubDivisorPyramid(exponents, subPoints, matrixLag2Bez, order); + subDivisor = generateSubDivisorPyramid(_exponents, subPoints, matrixLag2Bez, order); return; } @@ -489,14 +557,14 @@ void bezierBasis::_construct(int parentType, int p) dim = 0; numLagCoeff = 1; dimSimplex = 0; - exponents = gmshGenerateMonomialsLine(0); + _exponents = gmshGenerateMonomialsLine(0); subPoints.push_back(gmshGeneratePointsLine(0)); break; case TYPE_LIN : { dim = 1; numLagCoeff = 2; dimSimplex = 0; - exponents = gmshGenerateMonomialsLine(order); + _exponents = gmshGenerateMonomialsLine(order); subPoints = generateSubPointsLine(order); break; } @@ -504,7 +572,7 @@ void bezierBasis::_construct(int parentType, int p) dim = 2; numLagCoeff = 3; dimSimplex = 2; - exponents = gmshGenerateMonomialsTriangle(order); + _exponents = gmshGenerateMonomialsTriangle(order); subPoints = generateSubPointsTriangle(order); break; } @@ -512,7 +580,7 @@ void bezierBasis::_construct(int parentType, int p) dim = 2; numLagCoeff = 4; dimSimplex = 0; - exponents = gmshGenerateMonomialsQuadrangle(order); + _exponents = gmshGenerateMonomialsQuadrangle(order); subPoints = generateSubPointsQuad(order); break; } @@ -520,7 +588,7 @@ void bezierBasis::_construct(int parentType, int p) dim = 3; numLagCoeff = 4; dimSimplex = 3; - exponents = gmshGenerateMonomialsTetrahedron(order); + _exponents = gmshGenerateMonomialsTetrahedron(order); subPoints = generateSubPointsTetrahedron(order); break; } @@ -528,7 +596,7 @@ void bezierBasis::_construct(int parentType, int p) dim = 3; numLagCoeff = 6; dimSimplex = 2; - exponents = gmshGenerateMonomialsPrism(order); + _exponents = gmshGenerateMonomialsPrism(order); subPoints = generateSubPointsPrism(order); break; } @@ -536,7 +604,7 @@ void bezierBasis::_construct(int parentType, int p) dim = 3; numLagCoeff = 8; dimSimplex = 0; - exponents = gmshGenerateMonomialsHexahedron(order); + _exponents = gmshGenerateMonomialsHexahedron(order); subPoints = generateSubPointsHex(order); break; } @@ -547,17 +615,17 @@ void bezierBasis::_construct(int parentType, int p) order = 0; numLagCoeff = 4; dimSimplex = 3; - exponents = gmshGenerateMonomialsTetrahedron(order); + _exponents = gmshGenerateMonomialsTetrahedron(order); subPoints = generateSubPointsTetrahedron(order); break; } } numDivisions = static_cast<int>(subPoints.size()); - fullMatrix<double> bezierPoints = exponents; + fullMatrix<double> bezierPoints = _exponents; bezierPoints.scale(1./order); - matrixBez2Lag = generateBez2LagMatrix(exponents, bezierPoints, order, dimSimplex); + matrixBez2Lag = generateBez2LagMatrix(_exponents, bezierPoints, order, dimSimplex); matrixBez2Lag.invert(matrixLag2Bez); - subDivisor = generateSubDivisor(exponents, subPoints, matrixLag2Bez, order, dimSimplex); + subDivisor = generateSubDivisor(_exponents, subPoints, matrixLag2Bez, order, dimSimplex); } diff --git a/Numeric/bezierBasis.h b/Numeric/bezierBasis.h index 3ecc1784801d08453b443e5f76b1a5d7e353f153..3e236f1aae2ca2a0724bc8d35bec42686b533d29 100644 --- a/Numeric/bezierBasis.h +++ b/Numeric/bezierBasis.h @@ -17,8 +17,9 @@ class bezierBasis { private : // the 'numLagCoeff' first exponents are related to 'Lagrangian' values int numLagCoeff; - int dim, order; + int dim, type, order; int numDivisions; + fullMatrix<double> _exponents; public : fullMatrix<double> matrixLag2Bez; @@ -39,6 +40,14 @@ class bezierBasis { inline int getNumLagCoeff() const {return numLagCoeff;} inline int getNumDivision() const {return numDivisions;} + // Interpolation of n functions on N points : + // coeffs(numCoeff, n) and uvw(N, dim) + // => result(N, n) + void interpolate(const fullMatrix<double> &coeffs, + const fullMatrix<double> &uvw, + fullMatrix<double> &result, + bool bezCoord = false) const; + private : void _construct(int parendtType, int order); };