added: NURBS support in LRSplineField(s)2D(mx)

This commit is contained in:
Arne Morten Kvarving
2023-05-23 15:32:05 +02:00
parent 84badbb8c8
commit 6a227741d6
8 changed files with 75 additions and 39 deletions

View File

@@ -2469,7 +2469,7 @@ bool ASMu2D::separateProjectionBasis () const
Field* ASMu2D::getProjectedField (const Vector& coefs) const
{
if (coefs.size() == this->getNoProjectionNodes())
return new LRSplineField2D(projBasis.get(),coefs);
return new LRSplineField2D(projBasis.get(),coefs,is_rational);
std::cerr <<" *** ASMu2D::getProjectedFields: Non-matching coefficent array,"
<<" size="<< coefs.size() <<" nnod="<< this->getNoProjectionNodes()
@@ -2485,7 +2485,7 @@ Fields* ASMu2D::getProjectedFields (const Vector& coefs, size_t) const
size_t ncmp = coefs.size() / this->getNoProjectionNodes();
if (ncmp*this->getNoProjectionNodes() == coefs.size())
return new LRSplineFields2D(projBasis.get(),coefs,ncmp);
return new LRSplineFields2D(projBasis.get(),coefs,ncmp,is_rational);
std::cerr <<" *** ASMu2D::getProjectedFields: Non-matching coefficent array,"
<<" size="<< coefs.size() <<" nnod="<< this->getNoProjectionNodes()

View File

@@ -14,6 +14,7 @@
#include "LRSpline/LRSplineSurface.h"
#include "LRSpline/LRSplineVolume.h"
#include "ASMu2D.h"
#include "LRSplineField.h"
#include "CoordinateMapping.h"
#include "ItgPoint.h"
@@ -26,6 +27,7 @@ bool LRSplineField::evalMapping (const LR::LRSplineSurface& surf,
Matrix& Xnod,
Matrix& Jac,
Matrix& dNdX,
bool is_rational,
Matrix3D* d2NdX2,
Matrix3D* Hess)
{
@@ -36,21 +38,21 @@ bool LRSplineField::evalMapping (const LR::LRSplineSurface& surf,
Matrix3D d2Ndu2;
if (Hess) {
Go::BasisDerivsSf2 spline2;
surf.computeBasis(x.u,x.v,spline2,iel);
if (is_rational)
ASMu2D::computeBasisNurbs(x.u,x.v,spline2,iel,surf);
else
surf.computeBasis(x.u,x.v,spline2,iel);
SplineUtils::extractBasis(spline2, N, dNdu, d2Ndu2);
} else {
Go::BasisDerivsSf spline;
surf.computeBasis(x.u,x.v,spline,iel);
if (is_rational)
ASMu2D::computeBasisNurbs(x.u,x.v,spline,iel,surf);
else
surf.computeBasis(x.u,x.v,spline,iel);
SplineUtils::extractBasis(spline, N, dNdu);
}
Xnod.resize(2,elm->nBasisFunctions());
size_t i = 1;
for (const LR::Basisfunction* f : elm->support()) {
for (size_t j = 1; j <= 2; ++j)
Xnod(j,i) = f->cp(j-1);
++i;
}
ASMu2D::getCoordinates(Xnod,surf.dimension()-is_rational,surf,iel+1);
// Evaluate the Jacobian inverse
if (!utl::Jacobian(Jac,dNdX,Xnod,dNdu))
@@ -66,6 +68,7 @@ bool LRSplineField::evalBasis (const LR::LRSplineSurface& surf,
const Matrix& Xnod,
const Matrix& Jac,
Matrix& dNdX,
bool is_rational,
Matrix3D* d2NdX2,
Matrix3D* Hess)
{
@@ -76,11 +79,17 @@ bool LRSplineField::evalBasis (const LR::LRSplineSurface& surf,
Matrix3D d2Ndu2;
if (Hess) {
Go::BasisDerivsSf2 spline2;
surf.computeBasis(x.u,x.v,spline2,iel);
if (is_rational)
ASMu2D::computeBasisNurbs(x.u,x.v,spline2,iel,surf);
else
surf.computeBasis(x.u,x.v,spline2,iel);
SplineUtils::extractBasis(spline2, N, dNdu, d2Ndu2);
} else {
Go::BasisDerivsSf spline;
surf.computeBasis(x.u,x.v,spline,iel);
if (is_rational)
ASMu2D::computeBasisNurbs(x.u,x.v,spline,iel,surf);
else
surf.computeBasis(x.u,x.v,spline,iel);
SplineUtils::extractBasis(spline, N, dNdu);
}

View File

@@ -42,6 +42,7 @@ public:
//! \param Xnod Geometry coefficients in point
//! \param Jac Jacobian of geometry mapping in point
//! \param dNdX Derivatives of basis functions in point
//! \param is_rational True if surface is rational
//! \param d2NdX2 Second derivatives of basis functions in point
//! \param Hess Hessian of geometry mapping in point
static bool evalMapping(const LR::LRSplineSurface& surf,
@@ -50,6 +51,7 @@ public:
Matrix& Xnod,
Matrix& Jac,
Matrix& dNdX,
bool is_rational,
Matrix3D* d2NdX2 = nullptr,
Matrix3D* Hess = nullptr);
@@ -60,6 +62,7 @@ public:
//! \param Xnod Geometry coefficients in point
//! \param Jac Jacobian of geometry mapping in point
//! \param dNdX Derivatives of basis functions in point
//! \param is_rational True if surface is rational
//! \param d2NdX2 Second derivatives of basis functions in point
//! \param Hess Hessian of geometry mapping in point
static bool evalBasis(const LR::LRSplineSurface& surf,
@@ -68,6 +71,7 @@ public:
const Matrix& Xnod,
const Matrix& Jac,
Matrix& dNdX,
bool is_rational,
Matrix3D* d2NdX2 = nullptr,
Matrix3D* Hess = nullptr);

View File

@@ -18,14 +18,16 @@
#include "ASMu2D.h"
#include "ItgPoint.h"
#include "SplineUtils.h"
#include "Vec3.h"
LRSplineField2D::LRSplineField2D (const ASMu2D* patch,
const RealArray& v, char nbasis,
char cmp, const char* name)
: FieldBase(name), basis(patch->getBasis(nbasis)), surf(patch->getSurface())
: FieldBase(name),
basis(patch->getBasis(nbasis)),
surf(patch->getSurface()),
is_rational(patch->rational())
{
nno = basis->nBasisFunctions();
nelm = basis->nElements();
@@ -50,8 +52,9 @@ LRSplineField2D::LRSplineField2D (const ASMu2D* patch,
LRSplineField2D::LRSplineField2D (const LR::LRSplineSurface* srf,
const RealArray& v, const char* name)
: FieldBase(name), basis(srf), surf(srf)
const RealArray& v, bool rational,
const char* name)
: FieldBase(name), basis(srf), surf(srf), is_rational(rational)
{
values = v;
}
@@ -71,7 +74,10 @@ double LRSplineField2D::valueFE (const ItgPoint& x) const
int iel = basis->getElementContaining(x.u,x.v);
auto elm = basis->getElement(iel);
Go::BasisPtsSf spline;
basis->computeBasis(x.u,x.v,spline,iel);
if (is_rational)
ASMu2D::computeBasisNurbs(x.u,x.v,spline,iel,*basis);
else
basis->computeBasis(x.u,x.v,spline,iel);
Vector Vnod;
Vnod.reserve(elm->nBasisFunctions());
@@ -103,13 +109,13 @@ bool LRSplineField2D::gradFE (const ItgPoint& x, Vector& grad) const
// Evaluate the basis functions at the given point
Matrix Xnod, Jac, dNdX;
const LR::Element* elm;
if (!LRSplineField::evalMapping(*surf,x,elm,Xnod,Jac,dNdX))
if (!LRSplineField::evalMapping(*surf,x,elm,Xnod,Jac,dNdX,is_rational))
return false;
// Evaluate the gradient of the solution field at the given point
Vector Vnod;
if (basis != surf)
if (!LRSplineField::evalBasis(*basis,x,elm,Xnod,Jac,dNdX))
if (!LRSplineField::evalBasis(*basis,x,elm,Xnod,Jac,dNdX,is_rational))
return false;
Vnod.reserve(elm->nBasisFunctions());
@@ -129,11 +135,11 @@ bool LRSplineField2D::hessianFE (const ItgPoint& x, Matrix& H) const
Matrix Xnod, Jac, dNdX;
const LR::Element* elm;
Matrix3D d2NdX2, Hess;
if (!LRSplineField::evalMapping(*surf,x,elm,Xnod,Jac,dNdX,&d2NdX2,&Hess))
if (!LRSplineField::evalMapping(*surf,x,elm,Xnod,Jac,dNdX,is_rational,&d2NdX2,&Hess))
return false;
if (surf != basis)
if (!LRSplineField::evalBasis(*basis,x,elm,Xnod,Jac,dNdX,&d2NdX2,&Hess))
if (!LRSplineField::evalBasis(*basis,x,elm,Xnod,Jac,dNdX,is_rational,&d2NdX2,&Hess))
return false;
Matrix Vnod(1,elm->nBasisFunctions());

View File

@@ -46,9 +46,10 @@ public:
//! \brief Construct directly from surface.
//! \param[in] srf The spline surface to use
//! \param[in] v Array of control point field values
//! \param is_rational True if surface is rational
//! \param[in] name Name of spline field
LRSplineField2D(const LR::LRSplineSurface* srf, const RealArray& v,
const char* name = nullptr);
bool is_rational, const char* name = nullptr);
//! \brief Empty destructor.
virtual ~LRSplineField2D() {}
@@ -80,6 +81,8 @@ public:
protected:
const LR::LRSplineSurface* basis; //!< Spline basis description
const LR::LRSplineSurface* surf; //!< Spline geometry description
bool is_rational; //!< Whether or not surfaces are rational.
};
#endif

View File

@@ -18,14 +18,16 @@
#include "ASMu2D.h"
#include "ItgPoint.h"
#include "SplineUtils.h"
#include "Vec3.h"
LRSplineFields2D::LRSplineFields2D (const ASMu2D* patch,
const RealArray& v, char nbasis,
int nnf, const char* name)
: Fields(name), basis(patch->getBasis(nbasis)), surf(patch->getSurface())
: Fields(name),
basis(patch->getBasis(nbasis)),
surf(patch->getSurface()),
is_rational(patch->rational())
{
nno = basis->nBasisFunctions();
nelm = basis->nElements();
@@ -54,8 +56,9 @@ LRSplineFields2D::LRSplineFields2D (const ASMu2D* patch,
LRSplineFields2D::LRSplineFields2D (const LR::LRSplineSurface* srf,
const RealArray& v, int cmp, const char* name)
: Fields(name), basis(srf), surf(srf)
const RealArray& v, int cmp,
bool rational, const char* name)
: Fields(name), basis(srf), surf(srf), is_rational(rational)
{
values = v;
nf = cmp;
@@ -81,7 +84,10 @@ bool LRSplineFields2D::valueFE (const ItgPoint& x, Vector& vals) const
auto elm = basis->getElement(iel);
Go::BasisPtsSf spline;
basis->computeBasis(x.u,x.v,spline,iel);
if (is_rational)
ASMu2D::computeBasisNurbs(x.u,x.v,spline,iel,*basis);
else
basis->computeBasis(x.u,x.v,spline,iel);
// Evaluate the solution field at the given point
Matrix Vnod(nf, elm->nBasisFunctions());
@@ -115,13 +121,13 @@ bool LRSplineFields2D::gradFE (const ItgPoint& x, Matrix& grad) const
// Evaluate the basis functions at the given point
Matrix Xnod, Jac, dNdX;
const LR::Element* elm;
if (!LRSplineField::evalMapping(*surf,x,elm,Xnod,Jac,dNdX))
if (!LRSplineField::evalMapping(*surf,x,elm,Xnod,Jac,dNdX,is_rational))
return false;
// Evaluate the gradient of the solution field at the given point
Matrix Vnod;
if (basis != surf)
if (!LRSplineField::evalBasis(*surf,x,elm,Xnod,Jac,dNdX))
if (!LRSplineField::evalBasis(*surf,x,elm,Xnod,Jac,dNdX,is_rational))
return false;
Vnod.resize(nf, elm->nBasisFunctions());
@@ -145,12 +151,12 @@ bool LRSplineFields2D::hessianFE (const ItgPoint& x, Matrix3D& H) const
Matrix Xnod, Jac, dNdX;
const LR::Element* elm;
Matrix3D d2NdX2, Hess;
if (!LRSplineField::evalMapping(*surf,x,elm,Xnod,Jac,dNdX,&d2NdX2,&Hess))
if (!LRSplineField::evalMapping(*surf,x,elm,Xnod,Jac,dNdX,is_rational,&d2NdX2,&Hess))
return false;
// Evaluate the gradient of the solution field at the given point
if (surf != basis)
if (!LRSplineField::evalBasis(*surf,x,elm,Xnod,Jac,dNdX,&d2NdX2,&Hess))
if (!LRSplineField::evalBasis(*surf,x,elm,Xnod,Jac,dNdX,is_rational,&d2NdX2,&Hess))
return false;
Matrix Vnod(nf, elm->nBasisFunctions());

View File

@@ -47,8 +47,10 @@ public:
//! \param[in] srf The spline surface to use
//! \param[in] v Array of control point field values
//! \param[in] ncmp Number of field components
//! \param[in] rational Whether or not surface is rational
//! \param[in] name Name of spline field
LRSplineFields2D(const LR::LRSplineSurface* srf, const RealArray& v, int ncmp,
LRSplineFields2D(const LR::LRSplineSurface* srf, const RealArray& v,
int ncmp, bool rational,
const char* name = nullptr);
//! \brief Empty destructor.
@@ -85,6 +87,8 @@ public:
protected:
const LR::LRSplineSurface* basis; //!< Spline basis description
const LR::LRSplineSurface* surf; //!< Spline geometry description
bool is_rational; //!< Whether or not surfaces are rational.
};
#endif

View File

@@ -18,7 +18,6 @@
#include "ASMu2Dmx.h"
#include "ItgPoint.h"
#include "SplineUtils.h"
#include "Utilities.h"
#include "Vec3.h"
@@ -78,7 +77,10 @@ bool LRSplineFields2Dmx::valueFE (const ItgPoint& x, Vector& vals) const
int iel = basis->getElementContaining(x.u,x.v);
const LR::Element* elm = basis->getElement(iel);
Go::BasisPtsSf spline;
basis->computeBasis(x.u,x.v,spline,iel);
if (surf->rational())
ASMu2D::computeBasisNurbs(x.u,x.v,spline,iel,*basis);
else
basis->computeBasis(x.u,x.v,spline,iel);
// Evaluate the solution field at the given point
size_t i = 1;
@@ -104,7 +106,7 @@ bool LRSplineFields2Dmx::gradFE (const ItgPoint& x, Matrix& grad) const
const LR::LRSplineSurface* geo = surf->getBasis(ASMmxBase::geoBasis);
if (!geo)
geo = surf->getBasis(1);
if (!LRSplineField::evalMapping(*geo,x,elm,Xnod,Jac,dNdX))
if (!LRSplineField::evalMapping(*geo,x,elm,Xnod,Jac,dNdX,surf->rational()))
return false;
// Evaluate the gradient of the solution field at the given point
@@ -113,7 +115,7 @@ bool LRSplineFields2Dmx::gradFE (const ItgPoint& x, Matrix& grad) const
grad.resize(2,2);
for (int b : bases) {
const LR::LRSplineSurface* basis = surf->getBasis(b);
if (!LRSplineField::evalBasis(*basis,x,elm,Xnod,Jac,dNdX))
if (!LRSplineField::evalBasis(*basis,x,elm,Xnod,Jac,dNdX,surf->rational()))
return false;
size_t i = 1;
@@ -143,14 +145,16 @@ bool LRSplineFields2Dmx::hessianFE (const ItgPoint& x, Matrix3D& H) const
const LR::LRSplineSurface* geo = surf->getBasis(ASMmxBase::geoBasis);
if (!geo)
geo = surf->getBasis(1);
if (!LRSplineField::evalMapping(*geo,x,elm,Xnod,Jac,dNdX,&d2NdX2,&Hess))
if (!LRSplineField::evalMapping(*geo,x,elm,Xnod,Jac,
dNdX,surf->rational(),&d2NdX2,&Hess))
return false;
H.resize(2,2,2);
size_t ofs = 0;
for (int b : bases) {
const LR::LRSplineSurface* basis = surf->getBasis(b);
if (!LRSplineField::evalBasis(*basis,x,elm,Xnod,Jac,dNdX,&d2NdX2,&Hess))
if (!LRSplineField::evalBasis(*basis,x,elm,Xnod,Jac,
dNdX,surf->rational(),&d2NdX2,&Hess))
return false;
size_t i = 1;