changed: fold ASMu2Dnurbs into ASMu2D

this so we get access to NURBS in ASMu2Dmx.
remove ASM::LRNurbs and option -LRn as we now detect
rational from the underlying tensor spline
This commit is contained in:
Arne Morten Kvarving
2023-05-16 12:23:20 +02:00
parent 81b341d03f
commit bb7d87efb9
11 changed files with 108 additions and 213 deletions

View File

@@ -81,7 +81,7 @@ std::string MultiPatchModelGenerator1D::createG2 (int nsd, bool rational) const
bool MultiPatchModelGenerator1D::createGeometry (SIMinput& sim) const
{
bool rational = sim.opt.discretization == ASM::LRNurbs;
bool rational = false;
utl::getAttribute(geo,"rational",rational);
std::istringstream line(this->createG2(sim.getNoSpaceDim(),rational));
@@ -309,7 +309,7 @@ std::string MultiPatchModelGenerator2D::createG2 (int nsd, bool rational) const
bool MultiPatchModelGenerator2D::createGeometry (SIMinput& sim) const
{
bool rational = sim.opt.discretization == ASM::LRNurbs;
bool rational = false;
utl::getAttribute(geo,"rational",rational);
std::istringstream rect(this->createG2(sim.getNoSpaceDim(),rational));
if (!subdivision)
@@ -615,7 +615,7 @@ std::string MultiPatchModelGenerator3D::createG2 (int, bool rational) const
bool MultiPatchModelGenerator3D::createGeometry (SIMinput& sim) const
{
bool rational = sim.opt.discretization == ASM::LRNurbs;
bool rational = false;
utl::getAttribute(geo,"rational",rational);
std::istringstream cube(this->createG2(sim.getNoSpaceDim(),rational));
if (!subdivision)

View File

@@ -23,7 +23,6 @@
#include "LR/ASMu2DIB.h"
#include "LR/ASMu2DC1.h"
#include "LR/ASMu2Dmx.h"
#include "ASMu2Dnurbs.h"
#endif
#include "Vec3Oper.h"
@@ -65,8 +64,6 @@ ASMbase* ASM2D::create (ASM::Discretization discretization,
return new ASMu2Dmx(nd,nf);
else
return new ASMu2D(nd,nf.front());
case ASM::LRNurbs:
return new ASMu2Dnurbs(nd,nf.front());
#endif
default:

View File

@@ -27,8 +27,7 @@ namespace ASM //! Assembly scope
// The spline entries need to be at the end and successively numbered
Spline = 2,
SplineC1 = 3,
LRSpline = 4,
LRNurbs = 5
LRSpline = 4
};
//! \brief Operations to be applied after summing norm element contributions.

View File

@@ -57,6 +57,7 @@ ASMu2D::ASMu2D (const ASMu2D& patch, unsigned char n_f)
aMin = 0.0;
tensorspline = tensorPrjBas = nullptr;
projBasis = patch.projBasis;
is_rational = patch.is_rational;
// Need to set nnod here,
// as hasXNodes might be invoked before the FE data is generated
@@ -406,6 +407,9 @@ bool ASMu2D::createProjectionBasis (bool init)
bool ASMu2D::evaluateBasis (int iel, FiniteElement& fe, int derivs) const
{
if (is_rational)
return this->evaluateBasisNurbs(iel, fe, derivs);
PROFILE3("ASMu2D::evalBasis");
#ifdef INDEX_CHECK
if (iel < 0 || iel >= lrspline->nElements())
@@ -496,9 +500,18 @@ LR::LRSplineSurface* ASMu2D::createLRfromTensor ()
{
if (tensorspline->rational())
{
std::cerr <<" *** ASMu2D::createLRfromTensor: Cannot convert from a"
<<" rational spline, use LRnurbs instead."<< std::endl;
lrspline.reset();
// Creates a dim+1 dimensional LRSplineSurface from a tensor NURBS surface.
auto&& createLRnurbs = [](const Go::SplineSurface* srf)
{
return new LR::LRSplineSurface(srf->numCoefs_u(), srf->numCoefs_v(),
srf->order_u(), srf->order_v(),
srf->basis_u().begin(),
srf->basis_v().begin(),
srf->rcoefs_begin(),
srf->dimension()+1);
};
lrspline.reset(createLRnurbs(tensorspline));
is_rational = true;
}
else if (tensorspline->dimension() > nsd)
{
@@ -2835,6 +2848,11 @@ void ASMu2D::generateBezierExtraction ()
void ASMu2D::computeBasis (double u, double v, Go::BasisPtsSf& bas,
int iel, const LR::LRSplineSurface* spline) const
{
if (is_rational) {
this->computeBasisNurbs(u, v, bas, iel, spline);
return;
}
PROFILE3("ASMu2D::compBasis(0)");
if (spline)
@@ -2847,6 +2865,10 @@ void ASMu2D::computeBasis (double u, double v, Go::BasisPtsSf& bas,
void ASMu2D::computeBasis (double u, double v, Go::BasisDerivsSf& bas,
int iel, const LR::LRSplineSurface* spline) const
{
if (is_rational) {
this->computeBasisNurbs(u, v, bas, iel, spline);
return;
}
PROFILE3("ASMu2D::compBasis(1)");
if (spline)
@@ -2859,6 +2881,10 @@ void ASMu2D::computeBasis (double u, double v, Go::BasisDerivsSf& bas,
void ASMu2D::computeBasis (double u, double v, Go::BasisDerivsSf2& bas,
int iel) const
{
if (is_rational) {
this->computeBasisNurbs(u, v, bas, iel);
return;
}
PROFILE3("ASMu2D::compBasis(2)");
lrspline->computeBasis(u,v,bas,iel);
@@ -2868,6 +2894,10 @@ void ASMu2D::computeBasis (double u, double v, Go::BasisDerivsSf2& bas,
void ASMu2D::computeBasis (double u, double v, Go::BasisDerivsSf3& bas,
int iel) const
{
if (is_rational) {
this->computeBasisNurbs(u, v, bas, iel);
return;
}
PROFILE3("ASMu2D::compBasis(3)");
lrspline->computeBasis(u,v,bas,iel);

View File

@@ -589,23 +589,22 @@ protected:
//! \param[in] iel 0-based element index
//! \param fe Integration point data for current element
//! \param[in] derivs Derivative order of the basis functions
virtual bool evaluateBasis(int iel, FiniteElement& fe, int derivs = 0) const;
bool evaluateBasis(int iel, FiniteElement& fe, int derivs = 0) const;
//! \brief Evaluate basis functions in a point.
virtual void computeBasis(double u, double v,
Go::BasisPtsSf& bas, int iel,
const LR::LRSplineSurface* spline = nullptr) const;
void computeBasis(double u, double v,
Go::BasisPtsSf& bas, int iel,
const LR::LRSplineSurface* spline = nullptr) const;
//! \brief Evaluate basis functions and first derivatives in a point.
virtual void computeBasis(double u, double v,
Go::BasisDerivsSf& bas, int iel,
const LR::LRSplineSurface* spline = nullptr) const;
void computeBasis(double u, double v,
Go::BasisDerivsSf& bas, int iel,
const LR::LRSplineSurface* spline = nullptr) const;
//! \brief Evaluate basis functions and two derivatives in a point.
virtual void computeBasis(double u, double v,
Go::BasisDerivsSf2& bas, int iel) const;
void computeBasis(double u, double v,
Go::BasisDerivsSf2& bas, int iel) const;
//! \brief Evaluate basis functions and three derivatives in a point.
virtual void computeBasis(double u, double v,
Go::BasisDerivsSf3& bas, int iel) const;
void computeBasis(double u, double v,
Go::BasisDerivsSf3& bas, int iel) const;
//! \brief Evaluates the geometry at a specified point.
//! \param[in] iel 0-based local element index
@@ -640,7 +639,7 @@ protected:
const IntSet& neighborIndices) const;
//! \brief Converts current tensor spline object to LR-spline.
virtual LR::LRSplineSurface* createLRfromTensor();
LR::LRSplineSurface* createLRfromTensor();
//! \brief Generate bezier basis.
void generateBezierBasis();
@@ -661,6 +660,8 @@ protected:
std::shared_ptr<LR::LRSplineSurface> lrspline; //!< Pointer to the LR-spline surface object
std::shared_ptr<LR::LRSplineSurface> projBasis; //!< Basis to project onto
bool is_rational = false; //!< True if basis is rational
Go::SplineSurface* tensorspline; //!< Pointer to original tensor spline object
Go::SplineSurface* tensorPrjBas; //!< Pointer to tensor spline projection base
// The tensor spline object is kept for backward compatability with the REFINE
@@ -682,6 +683,28 @@ protected:
private:
mutable double aMin; //!< Minimum element area for adaptive refinement
//! \brief Evaluates the NURBS basis functions and derivatives of an element.
//! \param[in] iel 0-based element index
//! \param fe Integration point data for current element
//! \param[in] derivs Derivative order of the basis functions
bool evaluateBasisNurbs(int iel, FiniteElement& fe,
int derivs) const;
//! \brief Evaluate NURBS basis functions in a point.
void computeBasisNurbs(double u, double v,
Go::BasisPtsSf& bas, int iel,
const LR::LRSplineSurface* spline = nullptr) const;
//! \brief Evaluate NURBS basis functions and first derivatives in a point.
void computeBasisNurbs(double u, double v,
Go::BasisDerivsSf& bas, int iel,
const LR::LRSplineSurface* spline) const;
//! \brief Evaluate NURBS basis functions and two derivatives in a point.
void computeBasisNurbs(double u, double v,
Go::BasisDerivsSf2& bas, int iel) const;
//! \brief Evaluate NURBS basis functions and three derivatives in a point.
void computeBasisNurbs(double u, double v,
Go::BasisDerivsSf3& bas, int iel) const;
};
#endif

View File

@@ -17,42 +17,15 @@
#include "LRSpline/Element.h"
#include "LRSpline/Basisfunction.h"
#include "ASMu2Dnurbs.h"
#include "ASMu2D.h"
#include "FiniteElement.h"
#include "CoordinateMapping.h"
#include "Profiler.h"
ASMu2Dnurbs::ASMu2Dnurbs (unsigned char n_s, unsigned char n_f)
: ASMu2DC1(n_s, n_f)
{
noNurbs = false;
}
ASMu2Dnurbs::ASMu2Dnurbs (const ASMu2Dnurbs& patch, unsigned char n_f)
: ASMu2DC1(patch, n_f)
{
noNurbs = patch.noNurbs;
}
bool ASMu2Dnurbs::read (std::istream& is, int)
{
bool ok = this->ASMu2DC1::read(is);
if (ok && !(tensorspline && tensorspline->rational()))
std::cout <<" ** LR-nurbs requested but input is a spline."<< std::endl;
return ok;
}
bool ASMu2Dnurbs::evaluateBasis (int iel, FiniteElement& fe,
bool ASMu2D::evaluateBasisNurbs (int iel, FiniteElement& fe,
int derivs) const
{
if (noNurbs)
return this->ASMu2DC1::evaluateBasis(iel,fe,derivs);
const LR::Element* el = lrspline->getElement(iel);
if (!el) return false;
@@ -153,14 +126,11 @@ bool ASMu2Dnurbs::evaluateBasis (int iel, FiniteElement& fe,
}
void ASMu2Dnurbs::computeBasis (double u, double v,
void ASMu2D::computeBasisNurbs (double u, double v,
Go::BasisPtsSf& bas, int iel,
const LR::LRSplineSurface* spline) const
{
if (noNurbs)
return this->ASMu2DC1::computeBasis(u,v,bas,iel,spline);
PROFILE3("ASMu2Dn::compBasis(0)");
PROFILE3("ASMu2D::compBasisN(0)");
if (!spline)
spline = lrspline.get();
@@ -181,14 +151,11 @@ void ASMu2Dnurbs::computeBasis (double u, double v,
}
void ASMu2Dnurbs::computeBasis (double u, double v,
void ASMu2D::computeBasisNurbs (double u, double v,
Go::BasisDerivsSf& bas, int iel,
const LR::LRSplineSurface* spline) const
{
if (noNurbs)
return this->ASMu2DC1::computeBasis(u,v,bas,iel,spline);
PROFILE3("ASMu2Dn::compBasis(1)");
PROFILE3("ASMu2D::compBasisN(1)");
if (!spline)
spline = lrspline.get();
@@ -215,13 +182,10 @@ void ASMu2Dnurbs::computeBasis (double u, double v,
}
void ASMu2Dnurbs::computeBasis (double u, double v,
void ASMu2D::computeBasisNurbs (double u, double v,
Go::BasisDerivsSf2& bas, int iel) const
{
if (noNurbs)
return this->ASMu2DC1::computeBasis(u,v,bas,iel);
PROFILE3("ASMu2Dn::compBasis(2)");
PROFILE3("ASMu2D::compBasisN(2)");
const LR::Element* el = lrspline->getElement(iel);
@@ -259,13 +223,10 @@ void ASMu2Dnurbs::computeBasis (double u, double v,
}
void ASMu2Dnurbs::computeBasis (double u, double v,
void ASMu2D::computeBasisNurbs (double u, double v,
Go::BasisDerivsSf3& bas, int iel) const
{
if (noNurbs)
return this->ASMu2DC1::computeBasis(u,v,bas,iel);
PROFILE3("ASMu2Dn::compBasis(3)");
PROFILE3("ASMu2D::compBasisN(3)");
const LR::Element* el = lrspline->getElement(iel);
@@ -328,30 +289,3 @@ void ASMu2Dnurbs::computeBasis (double u, double v,
bas.basisDerivs_uvv[i] = (G2x*W - 3.0*G2*Wx)*w[i]/(W*W*W*W);
}
}
LR::LRSplineSurface* ASMu2Dnurbs::createLRfromTensor ()
{
// Creates a dim+1 dimensional LRSplineSurface from a tensor NURBS surface.
auto&& createLRnurbs = [](const Go::SplineSurface* srf)
{
return new LR::LRSplineSurface(srf->numCoefs_u(), srf->numCoefs_v(),
srf->order_u(), srf->order_v(),
srf->basis_u().begin(),
srf->basis_v().begin(),
srf->rcoefs_begin(),
srf->dimension()+1);
};
if (tensorspline)
{
if ((noNurbs = !tensorspline->rational()))
lrspline.reset(new LR::LRSplineSurface(tensorspline));
else
lrspline.reset(createLRnurbs(tensorspline));
delete tensorspline;
tensorspline = nullptr;
}
return lrspline.get();
}

View File

@@ -1,66 +0,0 @@
// $Id$
//==============================================================================
//!
//! \file ASMu2Dnurbs.h
//!
//! \date Nov 28 2018
//!
//! \author Arne Morten Kvarving / SINTEF
//!
//! \brief Driver for assembly of unstructured 2D NURBS FE models.
//!
//==============================================================================
#ifndef _ASM_U2D_NURBS_H
#define _ASM_U2D_NURBS_H
#include "ASMu2DC1.h"
/*!
\brief Driver for assembly of unstructured 2D NURBS FE models.
\details This class contains methods common for 2D LR-NURBS patches.
*/
class ASMu2Dnurbs : public ASMu2DC1
{
public:
//! \brief Default constructor.
ASMu2Dnurbs(unsigned char n_s = 2, unsigned char n_f = 2);
//! \brief Copy constructor.
ASMu2Dnurbs(const ASMu2Dnurbs& patch, unsigned char n_f = 0);
//! \brief Empty destructor.
virtual ~ASMu2Dnurbs() {}
//! \brief Creates an instance by reading the given input stream.
virtual bool read(std::istream& is, int = 0);
protected:
//! \brief Evaluates the basis functions and derivatives of an element.
virtual bool evaluateBasis(int iel, FiniteElement& fe, int derivs) const;
//! \brief Evaluate basis functions in a point.
virtual void computeBasis(double u, double v,
Go::BasisPtsSf& bas, int iel,
const LR::LRSplineSurface* spline) const;
//! \brief Evaluate basis functions and first derivatives in a point.
virtual void computeBasis(double u, double v,
Go::BasisDerivsSf& bas, int iel,
const LR::LRSplineSurface* spline) const;
//! \brief Evaluate basis functions and two derivatives in a point.
virtual void computeBasis(double u, double v,
Go::BasisDerivsSf2& bas, int iel) const;
//! \brief Evaluate basis functions and two derivatives in a point.
virtual void computeBasis(double u, double v,
Go::BasisDerivsSf3& bas, int iel) const;
//! \brief Converts current tensor spline object to LR-spline.
virtual LR::LRSplineSurface* createLRfromTensor();
private:
bool noNurbs; //!< If \e true, we read a spline and thus forward to ASMu2D
};
#endif

View File

@@ -11,11 +11,13 @@
//==============================================================================
#include "ASMu2D.h"
#include "ASMs2D.h"
#include "GaussQuadrature.h"
#include "SIM2D.h"
#include "LRSpline/LRSplineSurface.h"
#include "gtest/gtest.h"
#include <fstream>
#include <numeric>
@@ -293,3 +295,25 @@ TEST(TestASMu2D, ElementConnectivities)
EXPECT_EQ(neigh[n][i], ref[n][i]);
}
}
TEST(TestASMu2D, EvalPointNurbs)
{
ASMu2D u2Dpch(2, 1);
std::ifstream g2file("src/ASM/LR/Test/refdata/hole2D.g2");
std::ifstream g2file2("src/ASM/LR/Test/refdata/hole2D.g2");
ASMs2D s2Dpch(2,1);
ASSERT_TRUE(u2Dpch.read(g2file));
ASSERT_TRUE(s2Dpch.read(g2file2));
ASSERT_TRUE(u2Dpch.generateFEMTopology());
ASSERT_TRUE(s2Dpch.generateFEMTopology());
double xi[2] = {0.1, 0.1};
double param1[2], param2[2];
Vec3 x1, x2;
s2Dpch.evalPoint(xi,param1,x1);
u2Dpch.evalPoint(xi,param2,x2);
EXPECT_FLOAT_EQ(param1[0], param2[0]);
EXPECT_FLOAT_EQ(param1[1], param2[1]);
EXPECT_FLOAT_EQ(x1[0], x2[0]);
EXPECT_FLOAT_EQ(x1[1], x2[1]);
}

View File

@@ -1,42 +0,0 @@
//==============================================================================
//!
//! \file TestASMu2Dnurbs.C
//!
//! \date Feb 8 2019
//!
//! \author Arne Morten Kvarving / SINTEF
//!
//! \brief Tests for driver for assembly of unstructured 2D NURBS FE models.
//!
//==============================================================================
#include "ASMs2D.h"
#include "ASMu2Dnurbs.h"
#include "Vec3.h"
#include <LRSpline/LRSplineSurface.h>
#include "gtest/gtest.h"
#include <fstream>
TEST(TestASMu2Dnurbs, EvalPoint)
{
ASMu2Dnurbs u2Dpch(2, 1);
std::ifstream g2file("src/ASM/LR/Test/refdata/hole2D.g2");
std::ifstream g2file2("src/ASM/LR/Test/refdata/hole2D.g2");
ASMs2D s2Dpch(2,1);
ASSERT_TRUE(u2Dpch.read(g2file));
ASSERT_TRUE(s2Dpch.read(g2file2));
ASSERT_TRUE(u2Dpch.generateFEMTopology());
ASSERT_TRUE(s2Dpch.generateFEMTopology());
double xi[2] = {0.1, 0.1};
double param1[2], param2[2];
Vec3 x1, x2;
s2Dpch.evalPoint(xi,param1,x1);
u2Dpch.evalPoint(xi,param2,x2);
EXPECT_FLOAT_EQ(param1[0], param2[0]);
EXPECT_FLOAT_EQ(param1[1], param2[1]);
EXPECT_FLOAT_EQ(x1[0], x2[0]);
EXPECT_FLOAT_EQ(x1[1], x2[1]);
}

View File

@@ -52,7 +52,7 @@ bool ModelGenerator::topologySets () const
bool ModelGenerator::createGeometry (SIMinput& sim) const
{
bool rational = sim.opt.discretization == ASM::LRNurbs;
bool rational = false;
utl::getAttribute(geo,"rational",rational);
std::istringstream g2(this->createG2(sim.getNoSpaceDim(),rational));

View File

@@ -303,8 +303,6 @@ bool SIMoptions::parseOldOptions (int argc, char** argv, int& i)
discretization = ASM::Triangle;
else if (!strncmp(argv[i],"-spec",5))
discretization = ASM::Spectral;
else if (!strncmp(argv[i],"-LRn",4))
discretization = ASM::LRNurbs;
else if (!strncmp(argv[i],"-LR",3))
discretization = ASM::LRSpline;
else if (!strcmp(argv[i],"-nGauss") && i < argc-1)
@@ -436,8 +434,6 @@ utl::LogStream& SIMoptions::print (utl::LogStream& os, bool addBlankLine) const
os <<"\nSpectral basis functions are used"; break;
case ASM::LRSpline:
os <<"\nLR-spline basis functions are used"; break;
case ASM::LRNurbs:
os <<"\nLR-NURBS basis functions are used"; break;
case ASM::SplineC1:
os <<"\nSpline basis with C1-continuous patch interfaces is used"; break;
default: break;