diff --git a/Numeric/MetricBasis.cpp b/Numeric/MetricBasis.cpp index c5701a234883050525fa47de553eabad304e23ae..189a5d29535484450f424bc8b42081f5f4d79ef8 100644 --- a/Numeric/MetricBasis.cpp +++ b/Numeric/MetricBasis.cpp @@ -88,23 +88,6 @@ double MetricBasis::minRCorner(MElement *el) // Nodes fullMatrix<double> nodes(nMapping, 3); el->getNodesCoord(nodes); - fullMatrix<double> nodesMetric; - switch (el->getDim()) { - case 1: - return -1; - - case 2: - if (_paramOnPlane(nodes, nodesMetric)) return -1; - break; - - case 3: - nodesMetric.setAsProxy(nodes); - break; - - default: - Msg::Error("no metric for element of dimension %d (tag=%d)", - el->getDim(), el->getTypeForMSH()); - } // Jacobian coefficients fullVector<double> jacLag(jacobian->getNumJacNodes()); @@ -112,7 +95,7 @@ double MetricBasis::minRCorner(MElement *el) // Metric coefficients fullMatrix<double> metCoeffLag; - _fillCoeff(gradients, nodesMetric, metCoeffLag); + _fillCoeff(el->getDim(), gradients, nodes, metCoeffLag); // Compute min_corner(R) return _computeMinlagR(jacLag, metCoeffLag, nSampPnts); @@ -163,16 +146,18 @@ double MetricBasis::getMinSampledR(MElement *el, int deg) const double uvw[3]; double minmaxQ[2]; + int dim = el->getDim(); uvw[0] = samplingPoints(0, 0); uvw[1] = samplingPoints(0, 1); - uvw[2] = samplingPoints(0, 2); - + if (dim == 3) uvw[2] = samplingPoints(0, 2); + else uvw[2] = 0; interpolate(el, md, uvw, minmaxQ); + double min, max = min = std::sqrt(minmaxQ[0]/minmaxQ[1]); for (int i = 1; i < samplingPoints.size1(); ++i) { uvw[0] = samplingPoints(i, 0); uvw[1] = samplingPoints(i, 1); - uvw[2] = samplingPoints(i, 2); + if (dim == 3) uvw[2] = samplingPoints(i, 2); interpolate(el, md, uvw, minmaxQ); double tmp = std::sqrt(minmaxQ[0]/minmaxQ[1]); min = std::min(min, tmp); @@ -189,23 +174,6 @@ double MetricBasis::getBoundMinR(MElement *el) // Nodes fullMatrix<double> nodes(nMapping, 3); el->getNodesCoord(nodes); - fullMatrix<double> nodesMetric; - switch (el->getDim()) { - case 1: - return -1; - - case 2: - if (_paramOnPlane(nodes, nodesMetric)) return -1; - break; - - case 3: - nodesMetric.setAsProxy(nodes); - break; - - default: - Msg::Error("no metric for element of dimension %d (tag=%d)", - el->getDim(), el->getTypeForMSH()); - } // Jacobian coefficients fullVector<double> jacLag(_jacobian->getNumJacNodes()); @@ -215,7 +183,7 @@ double MetricBasis::getBoundMinR(MElement *el) // Metric coefficients fullMatrix<double> metCoeffLag; - _fillCoeff(_gradients, nodesMetric, metCoeffLag); + _fillCoeff(el->getDim(), _gradients, nodes, metCoeffLag); fullMatrix<double> *metCoeff; metCoeff = new fullMatrix<double>(nSampPnts, metCoeffLag.size2()); _bezier->matrixLag2Bez.mult(metCoeffLag, *metCoeff); @@ -453,6 +421,14 @@ void MetricBasis::interpolate(const MElement *el, const MetricData *md, const do dimSimplex = 2; exponents = gmshGenerateMonomialsPrism(order); break; + + case TYPE_TRI: + bezuvw[0] = uvw[0]; + bezuvw[1] = uvw[1]; + bezuvw[2] = uvw[2]; + dimSimplex = 2; + exponents = gmshGenerateMonomialsTriangle(order); + break; } int numCoeff = exponents.size1(); @@ -823,27 +799,6 @@ void MetricBasis::_getMetricData(MElement *el, MetricData *&md) const // Nodes fullMatrix<double> nodes(nMapping, 3); el->getNodesCoord(nodes); - fullMatrix<double> nodesMetric; - switch (el->getDim()) { - case 1: - md = NULL; - return; - - case 2: - if (_paramOnPlane(nodes, nodesMetric)) { - md = NULL; - return; - } - break; - - case 3: - nodesMetric.setAsProxy(nodes); - break; - - default: - Msg::Error("no metric for element of dimension %d (tag=%d)", - el->getDim(), el->getTypeForMSH()); - } // Jacobian coefficients fullVector<double> jacLag(_jacobian->getNumJacNodes()); @@ -853,7 +808,7 @@ void MetricBasis::_getMetricData(MElement *el, MetricData *&md) const // Metric coefficients fullMatrix<double> metCoeffLag; - _fillCoeff(_gradients, nodesMetric, metCoeffLag); + _fillCoeff(el->getDim(), _gradients, nodes, metCoeffLag); fullMatrix<double> *metCoeff; metCoeff = new fullMatrix<double>(nSampPnts, metCoeffLag.size2()); _bezier->matrixLag2Bez.mult(metCoeffLag, *metCoeff); @@ -861,33 +816,33 @@ void MetricBasis::_getMetricData(MElement *el, MetricData *&md) const md = new MetricData(metCoeff, jac, -1, 0, 0); } -void MetricBasis::_fillCoeff(const GradientBasis *gradients, +void MetricBasis::_fillCoeff(int dim, const GradientBasis *gradients, fullMatrix<double> &nodes, fullMatrix<double> &coeff) { const int nSampPnts = gradients->getNumSamplingPoints(); - switch (nodes.size2()) { + switch (dim) { case 0 : return; case 1 : - Msg::Fatal("not implemented"); + Msg::Fatal("Should not be here, metric for 1d not implemented"); break; case 2 : { - fullMatrix<double> dxydX(nSampPnts,2), dxydY(nSampPnts,2); + fullMatrix<double> dxydX(nSampPnts,3), dxydY(nSampPnts,3); gradients->getGradientsFromNodes(nodes, &dxydX, &dxydY, NULL); gradients->mapFromIdealElement(&dxydX, &dxydY, NULL); coeff.resize(nSampPnts, 3); for (int i = 0; i < nSampPnts; i++) { - const double &dxdX = dxydX(i,0), &dydX = dxydX(i,1); - const double &dxdY = dxydY(i,0), &dydY = dxydY(i,1); - const double dvxdX = dxdX*dxdX + dydX*dydX; - const double dvxdY = dxdY*dxdY + dydY*dydY; + const double &dxdX = dxydX(i,0), &dydX = dxydX(i,1), &dzdX = dxydX(i,2); + const double &dxdY = dxydY(i,0), &dydY = dxydY(i,1), &dzdY = dxydY(i,2); + const double dvxdX = dxdX*dxdX + dydX*dydX + dzdX*dzdX; + const double dvxdY = dxdY*dxdY + dydY*dydY + dzdY*dzdY; coeff(i, 0) = (dvxdX + dvxdY) / 2; coeff(i, 1) = dvxdX - coeff(i, 0); - coeff(i, 2) = (dxdX*dxdY + dydX*dydY); + coeff(i, 2) = (dxdX*dxdY + dydX*dydY + dzdX*dzdY); } } break; @@ -965,72 +920,6 @@ double MetricBasis::_computeMinlagR(const fullVector<double> &jac, } } -int MetricBasis::_paramOnPlane(const fullMatrix<double> &nodes3d, - fullMatrix<double> &nodes2d) -{ - // check if in xy-plane - int i = 0; - while (i < nodes3d.size1() && nodes3d(i,2) == 0) ++i; - if (i == nodes3d.size1()) { - nodes2d.setAsProxy(const_cast<double*>(nodes3d.getDataPtr()), - nodes3d.size1(), 2); - return 0; - } - - // check if coplanar and reparameterize - SVector3 vx(nodes3d(1, 0) - nodes3d(0, 0), - nodes3d(1, 1) - nodes3d(0, 1), - nodes3d(1, 2) - nodes3d(0, 2)); - SVector3 vy(nodes3d(2, 0) - nodes3d(0, 0), - nodes3d(2, 1) - nodes3d(0, 1), - nodes3d(2, 2) - nodes3d(0, 2)); - - double lx = vx.norm(), L = vy.norm() + lx; - if (norm(crossprod(vx, vy)) / L < 1e-10) { - nodes2d.resize(nodes3d.size1(), 2, true); - return 0; - } - - nodes2d.resize(nodes3d.size1(), 2, false); - nodes2d(0, 0) = 0; - nodes2d(0, 1) = 0; - - SVector3 ux = vx; - ux *= 1/lx; - nodes2d(1, 0) = lx; - nodes2d(1, 1) = 0; - - double p_vy_x = dot(vy, ux); - SVector3 uy = ux; - uy *= -p_vy_x; - uy += vy; - double n = uy.norm(); - uy.normalize(); - nodes2d(2, 0) = p_vy_x; - nodes2d(2, 1) = n; - - for (int i = 3; i < nodes3d.size1(); ++i) { - SVector3 v(nodes3d(i, 0) - nodes3d(0, 0), - nodes3d(i, 1) - nodes3d(0, 1), - nodes3d(i, 2) - nodes3d(0, 2)); - double p_v_x = dot(v, ux); - double p_v_y = dot(v, uy); - SVector3 px = ux, py = uy; - px *= -p_v_x; - py *= -p_v_y; - v -= px; - v -= py; - if (norm(v) / L < 1e-10) { - //Msg::Info("%g / %g = %g <= 1e-10", norm(v), L, norm(v)/L); - return 1; - } - nodes2d(i, 0) = p_v_x; - nodes2d(i, 1) = p_v_y; - } - - return 0; -} - void MetricBasis::_minMaxA( const fullMatrix<double> &coeff, double &min, double &max) const { diff --git a/Numeric/MetricBasis.h b/Numeric/MetricBasis.h index c126aeb3e806de58059ca4675b81c1dac6013950..bab7253e539fe6d8d2975509b8a4ef9be74759bb 100644 --- a/Numeric/MetricBasis.h +++ b/Numeric/MetricBasis.h @@ -78,14 +78,11 @@ private: void _getMetricData(MElement*, MetricData*&) const; double _subdivideForRmin(MetricData*, double RminLag, double tol) const; - static void _fillCoeff(const GradientBasis*, + static void _fillCoeff(int dim, const GradientBasis*, fullMatrix<double> &nodes, fullMatrix<double> &coeff); static double _computeMinlagR(const fullVector<double> &jac, const fullMatrix<double> &coeff, int num); - static int _paramOnPlane(const fullMatrix<double> &nodes3d, - fullMatrix<double> &nodes2d); - void _minMaxA(const fullMatrix<double>&, double &min, double &max) const; void _minK(const fullMatrix<double>&, const fullVector<double>&, double &min) const; void _maxAstKpos(const fullMatrix<double>&, const fullVector<double>&, @@ -101,6 +98,7 @@ private: const double x = .5 * (K - a*a*a + 3*a); if (x > 1+1e-13 || x < -1-1e-13) { Msg::Warning("x = %g (|1+%g|)", x, std::abs(x)-1); + Msg::Fatal("a"); } double ans; diff --git a/Plugin/AnalyseCurvedMesh.cpp b/Plugin/AnalyseCurvedMesh.cpp index e9671a2d0f82414b06fef4fa68e44df66ee0a896..636575f494caaf4ed863551a269054f4828c54bd 100644 --- a/Plugin/AnalyseCurvedMesh.cpp +++ b/Plugin/AnalyseCurvedMesh.cpp @@ -190,9 +190,8 @@ PView *GMSH_AnalyseCurvedMeshPlugin::execute(PView *v) std::map<int, std::vector<double> > dataPV; for (unsigned int i = 0; i < _data.size(); ++i) { MElement *const el = _data[i].element(); - if (el->getDim() == dim) { + if (el->getDim() == dim) dataPV[el->getNum()].push_back(_data[i].minR()); - } } std::stringstream name; name << "min R " << dim << "D";