changed: move 3D mixed establishment code to ASMmxBase
mirrors the 2D code
This commit is contained in:
committed by
Knut Morten Okstad
parent
8cc0e0e300
commit
3001e5fdf6
@@ -14,6 +14,8 @@
|
||||
#include "ASMmxBase.h"
|
||||
#include "GoTools/geometry/SplineSurface.h"
|
||||
#include "GoTools/geometry/SurfaceInterpolator.h"
|
||||
#include "GoTools/trivariate/SplineVolume.h"
|
||||
#include "GoTools/trivariate/VolumeInterpolator.h"
|
||||
|
||||
char ASMmxBase::geoBasis = 2;
|
||||
ASMmxBase::MixedType ASMmxBase::Type = ASMmxBase::FULL_CONT_RAISE_BASIS1;
|
||||
@@ -184,3 +186,59 @@ ASMmxBase::SurfaceVec ASMmxBase::establishBases(Go::SplineSurface* surf,
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
ASMmxBase::VolumeVec ASMmxBase::establishBases(Go::SplineVolume* svol,
|
||||
MixedType type)
|
||||
{
|
||||
VolumeVec result(2);
|
||||
// With mixed methods we need two separate spline spaces
|
||||
if (type == FULL_CONT_RAISE_BASIS1 || type == FULL_CONT_RAISE_BASIS2)
|
||||
{
|
||||
// basis1 should be one degree higher than basis2 and C^p-1 continuous
|
||||
int ndim = svol->dimension();
|
||||
Go::BsplineBasis b1 = svol->basis(0).extendedBasis(svol->order(0)+1);
|
||||
Go::BsplineBasis b2 = svol->basis(1).extendedBasis(svol->order(1)+1);
|
||||
Go::BsplineBasis b3 = svol->basis(2).extendedBasis(svol->order(2)+1);
|
||||
/* To lower order and regularity this can be used instead
|
||||
std::vector<double>::const_iterator first = ++surf->basis(0).begin();
|
||||
std::vector<double>::const_iterator last = --surf->basis(0).end();
|
||||
Go::BsplineBasis b1 = Go::BsplineBasis(surf->order_u()-1,first,last);
|
||||
first = ++surf->basis(1).begin();
|
||||
last = --surf->basis(1).end();
|
||||
Go::BsplineBasis b2 = Go::BsplineBasis(surf->order_v()-1,first,last);
|
||||
*/
|
||||
|
||||
// Compute parameter values of the Greville points
|
||||
size_t i;
|
||||
RealArray ug(b1.numCoefs()), vg(b2.numCoefs()), wg(b3.numCoefs());
|
||||
for (i = 0; i < ug.size(); i++)
|
||||
ug[i] = b1.grevilleParameter(i);
|
||||
for (i = 0; i < vg.size(); i++)
|
||||
vg[i] = b2.grevilleParameter(i);
|
||||
for (i = 0; i < wg.size(); i++)
|
||||
wg[i] = b3.grevilleParameter(i);
|
||||
|
||||
RealArray XYZ(ndim*ug.size()*vg.size()*wg.size());
|
||||
// Evaluate the spline surface at all points
|
||||
svol->gridEvaluator(XYZ,ug,vg,wg);
|
||||
|
||||
// Project the coordinates onto the new basis (the 2nd XYZ is dummy here)
|
||||
result[0].reset(Go::VolumeInterpolator::regularInterpolation(b1,b2,b3,
|
||||
ug,vg,wg,XYZ,ndim,
|
||||
false,XYZ));
|
||||
}
|
||||
else if (type == REDUCED_CONT_RAISE_BASIS1 || type == REDUCED_CONT_RAISE_BASIS2)
|
||||
{
|
||||
// Order-elevate basis1 such that it is of one degree higher than basis2
|
||||
// but only C^p-2 continuous
|
||||
result[0].reset(new Go::SplineVolume(*svol));
|
||||
result[0]->raiseOrder(1,1,1);
|
||||
}
|
||||
result[1].reset(new Go::SplineVolume(*svol));
|
||||
|
||||
if (type == FULL_CONT_RAISE_BASIS2 || type == REDUCED_CONT_RAISE_BASIS2)
|
||||
std::swap(result[0], result[1]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
namespace Go {
|
||||
class SplineSurface;
|
||||
class SplineVolume;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +75,7 @@ public:
|
||||
static MixedType Type; //!< Type of mixed formulation used
|
||||
|
||||
typedef std::vector<std::shared_ptr<Go::SplineSurface>> SurfaceVec; //!< Convenience type
|
||||
typedef std::vector<std::shared_ptr<Go::SplineVolume>> VolumeVec; //!< Convenience type
|
||||
|
||||
//! \brief Establish mixed bases
|
||||
//! \param[in] surf The base basis to use.
|
||||
@@ -81,6 +83,12 @@ public:
|
||||
//! \return Vector with bases.
|
||||
static SurfaceVec establishBases(Go::SplineSurface* surf, MixedType type);
|
||||
|
||||
//! \brief Establish mixed bases
|
||||
//! \param[in] vol The base basis to use.
|
||||
//! \param[in] type The type of bases to establish.
|
||||
//! \return Vector with bases.
|
||||
static VolumeVec establishBases(Go::SplineVolume* vol, MixedType type);
|
||||
|
||||
private:
|
||||
std::vector<int> MADOF; //!< Matrix of accumulated DOFs for this patch
|
||||
|
||||
|
||||
@@ -175,73 +175,7 @@ bool ASMs3Dmx::generateFEMTopology ()
|
||||
if (!svol) return false;
|
||||
|
||||
if (m_basis.empty())
|
||||
{
|
||||
m_basis.resize(2);
|
||||
// With mixed methods we need two separate spline spaces
|
||||
if (ASMmxBase::Type == FULL_CONT_RAISE_BASIS1 ||
|
||||
ASMmxBase::Type == FULL_CONT_RAISE_BASIS2)
|
||||
{
|
||||
// basis1 should be one degree higher than basis2 and C^p-1 continuous
|
||||
int ndim = svol->dimension();
|
||||
Go::BsplineBasis b1 = svol->basis(0).extendedBasis(svol->order(0)+1);
|
||||
Go::BsplineBasis b2 = svol->basis(1).extendedBasis(svol->order(1)+1);
|
||||
Go::BsplineBasis b3 = svol->basis(2).extendedBasis(svol->order(2)+1);
|
||||
/* To lower order and regularity this can be used instead
|
||||
std::vector<double>::const_iterator first = ++svol->basis(0).begin();
|
||||
std::vector<double>::const_iterator last = --svol->basis(0).end();
|
||||
Go::BsplineBasis b1 = Go::BsplineBasis(svol->order(0)-1,first,last);
|
||||
first = ++svol->basis(1).begin();
|
||||
last = --svol->basis(1).end();
|
||||
Go::BsplineBasis b2 = Go::BsplineBasis(svol->order(1)-1,first,last);
|
||||
first = ++svol->basis(2).begin();
|
||||
last = --svol->basis(2).end();
|
||||
Go::BsplineBasis b3 = Go::BsplineBasis(svol->order(2)-1,first,last);
|
||||
*/
|
||||
|
||||
// Note: Currently this is implemented for non-rational splines only.
|
||||
// TODO: Ask the splines people how to fix this properly, that is, how
|
||||
// may we obtain the correct weights for basis1 when *svol is a NURBS?
|
||||
if (svol->rational())
|
||||
std::cout <<"WARNING: The geometry basis is rational (using NURBS).\n"
|
||||
<<" The basis for the unknown fields of one degree"
|
||||
<<" higher will however be non-rational.\n"
|
||||
<<" This may affect accuracy.\n"<< std::endl;
|
||||
|
||||
// Compute parameter values of the Greville points of the new basis
|
||||
size_t i;
|
||||
RealArray ug(b1.numCoefs()), vg(b2.numCoefs()), wg(b3.numCoefs());
|
||||
for (i = 0; i < ug.size(); i++)
|
||||
ug[i] = b1.grevilleParameter(i);
|
||||
for (i = 0; i < vg.size(); i++)
|
||||
vg[i] = b2.grevilleParameter(i);
|
||||
for (i = 0; i < wg.size(); i++)
|
||||
wg[i] = b3.grevilleParameter(i);
|
||||
|
||||
// Evaluate the spline volume at all points
|
||||
RealArray XYZ(ndim*ug.size()*vg.size()*wg.size());
|
||||
svol->gridEvaluator(ug,vg,wg,XYZ);
|
||||
|
||||
// Project the coordinates onto the new basis (the 2nd XYZ is dummy here)
|
||||
m_basis[0].reset(Go::VolumeInterpolator::regularInterpolation(b1,b2,b3,
|
||||
ug,vg,wg,XYZ,ndim,
|
||||
false,XYZ));
|
||||
}
|
||||
else if (ASMmxBase::Type == REDUCED_CONT_RAISE_BASIS1 ||
|
||||
ASMmxBase::Type == REDUCED_CONT_RAISE_BASIS2)
|
||||
{
|
||||
// Order-elevate basis1 such that it is of one degree higher than basis2
|
||||
// but only C^p-2 continuous
|
||||
m_basis[0].reset(new Go::SplineVolume(*svol));
|
||||
m_basis[0]->raiseOrder(1,1,1);
|
||||
}
|
||||
m_basis[1].reset(new Go::SplineVolume(*svol));
|
||||
|
||||
if (ASMmxBase::Type == FULL_CONT_RAISE_BASIS2 ||
|
||||
ASMmxBase::Type == REDUCED_CONT_RAISE_BASIS2) {
|
||||
std::swap(m_basis[0], m_basis[1]);
|
||||
svol = m_basis[0].get();
|
||||
}
|
||||
}
|
||||
m_basis = ASMmxBase::establishBases(svol, ASMmxBase::Type);
|
||||
|
||||
nb.clear();
|
||||
for (auto it : m_basis)
|
||||
|
||||
Reference in New Issue
Block a user