From 781dc151264908fbe6584e95784b6c44d5e63724 Mon Sep 17 00:00:00 2001 From: kmo Date: Sun, 16 Oct 2011 16:20:54 +0000 Subject: [PATCH] Added virtual method updateCoords for use in ALE-formulations of FSI-problems git-svn-id: http://svn.sintef.no/trondheim/IFEM/trunk@1264 e10b68d5-8a6e-419e-a041-bce267b0401d --- src/ASM/ASMbase.C | 18 ++------- src/ASM/ASMbase.h | 6 ++- src/ASM/ASMs1D.C | 39 ++++++++++++++++++++ src/ASM/ASMs1D.h | 4 ++ src/ASM/ASMs1DLag.C | 33 +++++++++++++---- src/ASM/ASMs1DLag.h | 10 +++-- src/ASM/ASMs2D.C | 39 ++++++++++++++++++++ src/ASM/ASMs2D.h | 4 ++ src/ASM/ASMs2DLag.C | 31 ++++++++++++---- src/ASM/ASMs2DLag.h | 4 ++ src/ASM/ASMs3D.C | 39 ++++++++++++++++++++ src/ASM/ASMs3D.h | 4 ++ src/ASM/ASMs3DLag.C | 31 ++++++++++++---- src/ASM/ASMs3DLag.h | 4 ++ src/ASM/LR/ASMu2D.C | 83 +++++++++++++----------------------------- src/ASM/LR/ASMu2D.h | 89 ++++++++------------------------------------- 16 files changed, 267 insertions(+), 171 deletions(-) diff --git a/src/ASM/ASMbase.C b/src/ASM/ASMbase.C index 6af27ab5..4be8a464 100644 --- a/src/ASM/ASMbase.C +++ b/src/ASM/ASMbase.C @@ -477,11 +477,10 @@ void ASMbase::extractElmRes (const Matrix& globRes, Matrix& elmRes) const { elmRes.resize(globRes.rows(),MLGE.size(),true); - size_t i, iel, ivel = 0; + size_t iel, ivel = 0; for (iel = 0; iel < MLGE.size(); iel++) if (MLGE[iel] > 0) - for (++ivel, i = 1; i <= globRes.rows(); i++) - elmRes(i,ivel) = globRes(i,MLGE[iel]); + elmRes.fillColumn(++ivel,globRes.getColumn(MLGE[iel])); elmRes.resize(globRes.rows(),ivel); } @@ -525,14 +524,6 @@ bool ASMbase::injectNodeVec (const Vector& nodeVec, Vector& globRes, } -bool ASMbase::tesselate (ElementBlock&, const int*) const -{ - std::cerr <<" *** ASMBase::tesselate: Must be implemented in sub-class." - << std::endl; - return false; -} - - bool ASMbase::getSolution (Matrix& sField, const Vector& locSol, const IntVec& nodes) const { @@ -545,10 +536,7 @@ bool ASMbase::getSolution (Matrix& sField, const Vector& locSol, return false; } else - { - for (unsigned char j = 0; j < nf; j++) - sField(j+1,i+1) = locSol[nf*(nodes[i]-1)+j]; - } + sField.fillColumn(i+1,locSol.ptr()+nf*nodes[i]-nf); return true; } diff --git a/src/ASM/ASMbase.h b/src/ASM/ASMbase.h index 2e3fb08a..acef1e27 100644 --- a/src/ASM/ASMbase.h +++ b/src/ASM/ASMbase.h @@ -191,6 +191,10 @@ public: bool updateDirichlet(const std::map& func, const std::map& vfunc, double time = 0.0); + //! \brief Updates the nodal coordinates for this patch. + //! \param[in] displ Incremental displacements to update the coordinates with + virtual bool updateCoords(const Vector& displ) = 0; + //! \brief Initializes the patch level MADOF array for mixed problems. virtual void initMADOF(const int*) {} @@ -242,7 +246,7 @@ public: //! \param[out] grid The generated finite element grid //! \param[in] npe Number of visualization nodes over each knot span //! \note The number of element nodes must be set in \a grid on input. - virtual bool tesselate(ElementBlock& grid, const int* npe) const; + virtual bool tesselate(ElementBlock& grid, const int* npe) const = 0; //! \brief Extract the primary solution field at the specified nodes. //! \param[out] sField Solution field diff --git a/src/ASM/ASMs1D.C b/src/ASM/ASMs1D.C index b24f099c..a0a7437d 100644 --- a/src/ASM/ASMs1D.C +++ b/src/ASM/ASMs1D.C @@ -426,6 +426,45 @@ Vec3 ASMs1D::getCoord (size_t inod) const } +bool ASMs1D::updateCoords (const Vector& displ) +{ + if (!curv) return true; // silently ignore empty patches + + if (displ.size() != nsd*MLGN.size()) + { + std::cerr <<" *** ASMs1D::updateCoords: Invalid dimension " + << displ.size() <<" on displ, should be " + << nsd*MLGN.size() << std::endl; + return false; + } + + //TODO: This should be placed in GoTools (SplineCurve::deform) + //curv->deform(displ,nsd); + RealArray::iterator cit; + int i, j, cdim = curv->dimension(); + + if (curv->rational()) + for (cit = curv->rcoefs_begin(), j = 0; cit != curv->rcoefs_end(); cit++) + { + double weight = cit[cdim]; + for (i = 0; i < cdim && i < nsd; i++) + cit[i] += displ[j+i] * weight; + cit += cdim; + j += nsd; + } + + for (cit = curv->coefs_begin(), j = 0; cit != curv->coefs_end();) + { + for (i = 0; i < cdim && i < nsd; i++) + cit[i] += displ[j+i]; + cit += cdim; + j += nsd; + } + + return true; +} + + int ASMs1D::getSize (int) const { if (!curv) return 0; diff --git a/src/ASM/ASMs1D.h b/src/ASM/ASMs1D.h index 0ffc3a36..a599ab85 100644 --- a/src/ASM/ASMs1D.h +++ b/src/ASM/ASMs1D.h @@ -54,6 +54,10 @@ public: //! \param[in] inod 1-based node index local to current patch virtual Vec3 getCoord(size_t inod) const; + //! \brief Updates the nodal coordinates for this patch. + //! \param[in] displ Incremental displacements to update the coordinates with + virtual bool updateCoords(const Vector& displ); + //! \brief Creates an instance by reading the given input stream. bool read(std::istream&); //! \brief Writes the geometry of the SplineCurve object to given stream. diff --git a/src/ASM/ASMs1DLag.C b/src/ASM/ASMs1DLag.C index 1cd620aa..81f4e3c5 100644 --- a/src/ASM/ASMs1DLag.C +++ b/src/ASM/ASMs1DLag.C @@ -7,7 +7,7 @@ //! //! \author Einar Christensen / SINTEF //! -//! \brief Driver for assembly of structured 1D Lagrange FE models. +//! \brief Driver for assembly of 1D Lagrange FE models. //! //============================================================================== @@ -104,6 +104,14 @@ bool ASMs1DLag::generateFEMTopology () } +Vec3 ASMs1DLag::getCoord (size_t inod) const +{ + if (inod < 1 || inod > coord.size()) return Vec3(); + + return coord[inod-1]; +} + + bool ASMs1DLag::getElementCoordinates (Matrix& X, int iel) const { if (iel < 1 || (size_t)iel > MNPC.size()) @@ -132,11 +140,21 @@ void ASMs1DLag::getNodalCoordinates (Matrix& X) const } -Vec3 ASMs1DLag::getCoord (size_t inod) const +bool ASMs1DLag::updateCoords (const Vector& displ) { - if (inod < 1 || inod > coord.size()) return Vec3(); + if (displ.size() != nsd*coord.size()) + { + std::cerr <<" *** ASMs1DLag::updateCoords: Invalid dimension " + << displ.size() <<" on displ, should be " + << nsd*coord.size() << std::endl; + return false; + } - return coord[inod-1]; + const double* u = displ.ptr(); + for (size_t inod = 0; inod < coord.size(); inod++, u += nsd) + coord[inod] += RealArray(u,u+nsd); + + return true; } @@ -380,11 +398,10 @@ bool ASMs1DLag::evalSolution (Matrix& sField, const Vector& locSol, if (nComp*nPoints != locSol.size()) return false; - size_t i, n, ip = 0; sField.resize(nComp,nPoints); - for (n = 1; n <= nPoints; n++) - for (i = 1; i <= nComp; i++) - sField(i,n) = locSol(++ip); + const double* u = locSol.ptr(); + for (size_t n = 1; n <= nPoints; n++, u += nComp) + sField.fillColumn(n,u); return true; } diff --git a/src/ASM/ASMs1DLag.h b/src/ASM/ASMs1DLag.h index 7146c553..6ec44e29 100644 --- a/src/ASM/ASMs1DLag.h +++ b/src/ASM/ASMs1DLag.h @@ -7,7 +7,7 @@ //! //! \author Einar Christensen / SINTEF //! -//! \brief Driver for assembly of structured 1D Lagrange FE models. +//! \brief Driver for assembly of 1D Lagrange FE models. //! //============================================================================== @@ -19,8 +19,8 @@ /*! - \brief Driver for assembly of structured 2D Lagrange FE models. - \details This class contains methods for structured 2D Lagrange patches. + \brief Driver for assembly of 1D Lagrange FE models. + \details This class contains methods for 1D Lagrange patches. */ class ASMs1DLag : public ASMs1D @@ -51,6 +51,10 @@ public: //! \param[in] inod 1-based node index local to current patch virtual Vec3 getCoord(size_t inod) const; + //! \brief Updates the nodal coordinates for this patch. + //! \param[in] displ Incremental displacements to update the coordinates with + virtual bool updateCoords(const Vector& displ); + // Methods for integration of finite element quantities. // These are the main computational methods of the ASM class hierarchy. diff --git a/src/ASM/ASMs2D.C b/src/ASM/ASMs2D.C index 311303b6..7ddf12cd 100644 --- a/src/ASM/ASMs2D.C +++ b/src/ASM/ASMs2D.C @@ -668,6 +668,45 @@ Vec3 ASMs2D::getCoord (size_t inod) const } +bool ASMs2D::updateCoords (const Vector& displ) +{ + if (!surf) return true; // silently ignore empty patches + + if (displ.size() != nsd*MLGN.size()) + { + std::cerr <<" *** ASMs2D::updateCoords: Invalid dimension " + << displ.size() <<" on displ, should be " + << nsd*MLGN.size() << std::endl; + return false; + } + + //TODO: This should be placed in GoTools (SplineSurface::deform) + //surf->deform(displ,nsd); + RealArray::iterator cit; + int i, j, cdim = surf->dimension(); + + if (surf->rational()) + for (cit = surf->rcoefs_begin(), j = 0; cit != surf->rcoefs_end(); cit++) + { + double weight = cit[cdim]; + for (i = 0; i < cdim && i < nsd; i++) + cit[i] += displ[j+i] * weight; + cit += cdim; + j += nsd; + } + + for (cit = surf->coefs_begin(), j = 0; cit != surf->coefs_end();) + { + for (i = 0; i < cdim && i < nsd; i++) + cit[i] += displ[j+i]; + cit += cdim; + j += nsd; + } + + return true; +} + + bool ASMs2D::getSize (int& n1, int& n2, int) const { if (!surf) return false; diff --git a/src/ASM/ASMs2D.h b/src/ASM/ASMs2D.h index 0acdf8d7..6dd6243f 100644 --- a/src/ASM/ASMs2D.h +++ b/src/ASM/ASMs2D.h @@ -95,6 +95,10 @@ public: //! \param[in] inod 1-based node index local to current patch virtual Vec3 getCoord(size_t inod) const; + //! \brief Updates the nodal coordinates for this patch. + //! \param[in] displ Incremental displacements to update the coordinates with + virtual bool updateCoords(const Vector& displ); + //! \brief Creates an instance by reading the given input stream. bool read(std::istream&); //! \brief Writes the geometry of the SplineSurface object to given stream. diff --git a/src/ASM/ASMs2DLag.C b/src/ASM/ASMs2DLag.C index 676c485b..56e442e6 100644 --- a/src/ASM/ASMs2DLag.C +++ b/src/ASM/ASMs2DLag.C @@ -120,6 +120,14 @@ bool ASMs2DLag::generateFEMTopology () } +Vec3 ASMs2DLag::getCoord (size_t inod) const +{ + if (inod < 1 || inod > coord.size()) return Vec3(); + + return coord[inod-1]; +} + + bool ASMs2DLag::getElementCoordinates (Matrix& X, int iel) const { if (iel < 1 || (size_t)iel > MNPC.size()) @@ -149,11 +157,21 @@ void ASMs2DLag::getNodalCoordinates (Matrix& X) const } -Vec3 ASMs2DLag::getCoord (size_t inod) const +bool ASMs2DLag::updateCoords (const Vector& displ) { - if (inod < 1 || inod > coord.size()) return Vec3(); + if (displ.size() != nsd*coord.size()) + { + std::cerr <<" *** ASMs2DLag::updateCoords: Invalid dimension " + << displ.size() <<" on displ, should be " + << nsd*coord.size() << std::endl; + return false; + } - return coord[inod-1]; + const double* u = displ.ptr(); + for (size_t inod = 0; inod < coord.size(); inod++, u += nsd) + coord[inod] += RealArray(u,u+nsd); + + return true; } @@ -497,11 +515,10 @@ bool ASMs2DLag::evalSolution (Matrix& sField, const Vector& locSol, if (nComp*nPoints != locSol.size()) return false; - size_t i, n, ip = 0; sField.resize(nComp,nPoints); - for (n = 1; n <= nPoints; n++) - for (i = 1; i <= nComp; i++) - sField(i,n) = locSol(++ip); + const double* u = locSol.ptr(); + for (size_t n = 1; n <= nPoints; n++, u += nComp) + sField.fillColumn(n,u); return true; } diff --git a/src/ASM/ASMs2DLag.h b/src/ASM/ASMs2DLag.h index 9640a33e..971a5f6b 100644 --- a/src/ASM/ASMs2DLag.h +++ b/src/ASM/ASMs2DLag.h @@ -51,6 +51,10 @@ public: //! \param[in] inod 1-based node index local to current patch virtual Vec3 getCoord(size_t inod) const; + //! \brief Updates the nodal coordinates for this patch. + //! \param[in] displ Incremental displacements to update the coordinates with + virtual bool updateCoords(const Vector& displ); + // Methods for integration of finite element quantities. // These are the main computational methods of the ASM class hierarchy. diff --git a/src/ASM/ASMs3D.C b/src/ASM/ASMs3D.C index 7d2992da..d81cafa9 100644 --- a/src/ASM/ASMs3D.C +++ b/src/ASM/ASMs3D.C @@ -974,6 +974,45 @@ Vec3 ASMs3D::getCoord (size_t inod) const } +bool ASMs3D::updateCoords (const Vector& displ) +{ + if (!svol) return true; // silently ignore empty patches + + if (displ.size() != 3*MLGN.size()) + { + std::cerr <<" *** ASMs3D::updateCoords: Invalid dimension " + << displ.size() <<" on displ, should be " + << 3*MLGN.size() << std::endl; + return false; + } + + //TODO: This should be placed in GoTools (SplineVolume::deform) + //svol->deform(displ); + RealArray::iterator cit; + int i, j, cdim = svol->dimension(); + + if (svol->rational()) + for (cit = svol->rcoefs_begin(), j = 0; cit != svol->rcoefs_end(); cit++) + { + double weight = cit[cdim]; + for (i = 0; i < cdim && i < 3; i++) + cit[i] += displ[j+i] * weight; + cit += cdim; + j += 3; + } + + for (cit = svol->coefs_begin(), j = 0; cit != svol->coefs_end();) + { + for (i = 0; i < cdim && i < 3; i++) + cit[i] += displ[j+i]; + cit += cdim; + j += 3; + } + + return true; +} + + bool ASMs3D::getSize (int& n1, int& n2, int& n3, int) const { if (!svol) return false; diff --git a/src/ASM/ASMs3D.h b/src/ASM/ASMs3D.h index 7879bb6c..fc814955 100644 --- a/src/ASM/ASMs3D.h +++ b/src/ASM/ASMs3D.h @@ -113,6 +113,10 @@ public: //! \param[in] inod 1-based node index local to current patch virtual Vec3 getCoord(size_t inod) const; + //! \brief Updates the nodal coordinates for this patch. + //! \param[in] displ Incremental displacements to update the coordinates with + virtual bool updateCoords(const Vector& displ); + //! \brief Creates an instance by reading the given input stream. bool read(std::istream&); //! \brief Writes the geometry of the SplineVolume object to given stream. diff --git a/src/ASM/ASMs3DLag.C b/src/ASM/ASMs3DLag.C index 3d44ad47..67bac036 100644 --- a/src/ASM/ASMs3DLag.C +++ b/src/ASM/ASMs3DLag.C @@ -134,6 +134,14 @@ bool ASMs3DLag::generateFEMTopology () } +Vec3 ASMs3DLag::getCoord (size_t inod) const +{ + if (inod < 1 || inod > coord.size()) return Vec3(); + + return coord[inod-1]; +} + + bool ASMs3DLag::getElementCoordinates (Matrix& X, int iel) const { if (iel < 1 || (size_t)iel > MNPC.size()) @@ -163,11 +171,21 @@ void ASMs3DLag::getNodalCoordinates (Matrix& X) const } -Vec3 ASMs3DLag::getCoord (size_t inod) const +bool ASMs3DLag::updateCoords (const Vector& displ) { - if (inod < 1 || inod > coord.size()) return Vec3(); + if (displ.size() != nsd*coord.size()) + { + std::cerr <<" *** ASMs3DLag::updateCoords: Invalid dimension " + << displ.size() <<" on displ, should be " + << nsd*coord.size() << std::endl; + return false; + } - return coord[inod-1]; + const double* u = displ.ptr(); + for (size_t inod = 0; inod < coord.size(); inod++, u += nsd) + coord[inod] += RealArray(u,u+nsd); + + return true; } @@ -673,11 +691,10 @@ bool ASMs3DLag::evalSolution (Matrix& sField, const Vector& locSol, if (nComp*nPoints != locSol.size()) return false; - size_t i, n, ip = 0; sField.resize(nComp,nPoints); - for (n = 1; n <= nPoints; n++) - for (i = 1; i <= nComp; i++) - sField(i,n) = locSol(++ip); + const double* u = locSol.ptr(); + for (size_t n = 1; n <= nPoints; n++, u += nsd) + sField.fillColumn(n,u); return true; } diff --git a/src/ASM/ASMs3DLag.h b/src/ASM/ASMs3DLag.h index 4ab22cbf..24121bd3 100644 --- a/src/ASM/ASMs3DLag.h +++ b/src/ASM/ASMs3DLag.h @@ -51,6 +51,10 @@ public: //! \param[in] inod 1-based node index local to current patch virtual Vec3 getCoord(size_t inod) const; + //! \brief Updates the nodal coordinates for this patch. + //! \param[in] displ Incremental displacements to update the coordinates with + virtual bool updateCoords(const Vector& displ); + // Methods for integration of finite element quantities. // These are the main computational methods of the ASM class hierarchy. diff --git a/src/ASM/LR/ASMu2D.C b/src/ASM/LR/ASMu2D.C index ec4f1f23..63727225 100644 --- a/src/ASM/LR/ASMu2D.C +++ b/src/ASM/LR/ASMu2D.C @@ -58,7 +58,7 @@ ASMu2D::ASMu2D (std::istream& is, unsigned char n_s, unsigned char n_f) bool ASMu2D::read (std::istream& is) { - if (lrspline) delete lrspline; + delete lrspline; // read inputfile as either an LRSpline file directly or a tensor product B-spline and convert char firstline[256]; @@ -126,8 +126,8 @@ void ASMu2D::clear (bool retainGeometry) if (!retainGeometry) { // Erase spline data - if (lrspline) delete lrspline; - if (tensorspline) delete tensorspline; + delete lrspline; + delete tensorspline; lrspline = 0; tensorspline = 0; geo = 0; @@ -138,7 +138,7 @@ void ASMu2D::clear (bool retainGeometry) } -bool ASMu2D::cornerRefine (int minBasisfunctions) +bool ASMu2D::cornerRefine (int minBasisfunctions) { if (!lrspline ) return false; @@ -150,14 +150,13 @@ bool ASMu2D::cornerRefine (int minBasisfunctions) lrspline->insert_const_v_edge(h-unif_step_h, 0, h); h -= unif_step_h; } - std::ofstream meshFile; - meshFile.open("mesh.eps"); + + std::ofstream meshFile("mesh.eps"); lrspline->writePostscriptMesh(meshFile); - meshFile.close(); return true; } -bool ASMu2D::diagonalRefine (int minBasisfunctions) +bool ASMu2D::diagonalRefine (int minBasisfunctions) { if (!lrspline ) return false; @@ -180,15 +179,13 @@ bool ASMu2D::diagonalRefine (int minBasisfunctions) v = h/2.0; } } - std::ofstream meshFile; - meshFile.open("mesh.eps"); - lrspline->writePostscriptMesh(meshFile); - meshFile.close(); + std::ofstream meshFile("mesh.eps"); + lrspline->writePostscriptMesh(meshFile); return true; } -bool ASMu2D::uniformRefine (int minBasisfunctions) +bool ASMu2D::uniformRefine (int minBasisfunctions) { if (!lrspline ) return false; @@ -216,10 +213,9 @@ bool ASMu2D::uniformRefine (int minBasisfunctions) } } } - std::ofstream meshFile; - meshFile.open("mesh.eps"); + + std::ofstream meshFile("mesh.eps"); lrspline->writePostscriptMesh(meshFile); - meshFile.close(); return true; } @@ -247,7 +243,7 @@ bool ASMu2D::uniformRefine (int dir, int nInsert) else tensorspline->insertKnot_v(extraKnots); - if(lrspline) delete lrspline; + delete lrspline; geo = lrspline = new LR::LRSplineSurface(tensorspline); return true; } @@ -278,7 +274,7 @@ bool ASMu2D::refine (int dir, const RealArray& xi) else tensorspline->insertKnot_v(extraKnots); - if(lrspline) delete lrspline; + delete lrspline; geo = lrspline = new LR::LRSplineSurface(tensorspline); return true; } @@ -288,7 +284,7 @@ bool ASMu2D::raiseOrder (int ru, int rv) if (!tensorspline) return false; tensorspline->raiseOrder(ru,rv); - if(lrspline) delete lrspline; + delete lrspline; geo = lrspline = new LR::LRSplineSurface(tensorspline); return true; } @@ -385,37 +381,6 @@ bool ASMu2D::generateFEMTopology () #if 0 -int ASMu2D::Edge::next () -{ - int ret = icnod; - icnod += incr; - - return ret; -} - - -int ASMu2D::BlockNodes::next () -{ - int ret = iinod; - iinod += inc[0]; - - if (++indxI >= nnodI-1) - { - indxI = 1; - iinod += inc[1] - inc[0]*(nnodI-2); - } - - return ret; -} - - -bool ASMu2D::assignNodeNumbers () -{ - for(size_t i=0; iconnectBasis(edge,neighbor,nedge,revers); @@ -660,9 +625,8 @@ bool ASMu2D::getElementCoordinates (Matrix& X, int iel) const X.resize(nsd,mnpc.size()); std::vector::iterator bit = lrspline->getElement(iel-1)->supportBegin(); - for (size_t n = 0; n < mnpc.size(); n++, bit++) - for (size_t i = 0; i < nsd; i++) - X(i+1,n+1) = (*bit)->controlpoint_[i]; + for (size_t n = 1; n <= mnpc.size(); n++, bit++) + X.fillColumn(n,(*bit)->controlpoint_); #if SP_DEBUG > 2 std::cout <<"\nCoordinates for element "<< iel << X << std::endl; @@ -677,10 +641,8 @@ void ASMu2D::getNodalCoordinates (Matrix& X) const X.resize(nsd,nBasis); std::vector::iterator bit = lrspline->basisBegin(); - - for(int inod=0; inodcontrolpoint_[i]; + for (int inod = 1; inod <= nBasis; inod++, bit++) + X.fillColumn(inod,(*bit)->controlpoint_); } @@ -695,6 +657,13 @@ Vec3 ASMu2D::getCoord (size_t inod) const } +bool ASMu2D::updateCoords (const Vector& displ) +{ + std::cerr <<" *** ASMu2D::updateCoords: Not implemented!"<< std::endl; + return false; +} + + void ASMu2D::getGaussPointParameters (RealArray& uGP, int dir, int nGauss, int iel, const double* xi) const { diff --git a/src/ASM/LR/ASMu2D.h b/src/ASM/LR/ASMu2D.h index db2fb99b..fc5282d6 100644 --- a/src/ASM/LR/ASMu2D.h +++ b/src/ASM/LR/ASMu2D.h @@ -34,50 +34,7 @@ namespace LR { class ASMu2D : public ASMunstruct, public ASM2D { - //! \brief Struct for nodal point data. - struct IJ - { - int I; //!< Index in first parameter direction - int J; //!< Index in second parameter direction - }; - -// topology-stuff like connecting multiple patches. Will be introduced later - -#if 0 - - //! \brief Struct for edge node definitions. - struct Edge - { - int icnod; //!< Global node number of first interior point along the edge - int incr; //!< Increment in the global numbering along the edge - - //! \brief Default constructor. - Edge() { icnod = incr = 0; } - //! \brief Returns \a icnod which then is incremented. - int next(); - }; - public: - //! \brief Struct with data for definition of global node numbers of a patch. - struct BlockNodes - { - int ibnod[4]; //!< Vertex nodes - Edge edges[4]; //!< Edge nodes - int iinod; //!< Global node number of the first interior node - int inc[2]; //!< Increment in global node numbering in each direction - int nnodI; //!< Number of nodes in parameter direction I - int indxI; //!< Running node index in the local I-direction - - //! \brief Default constructor. - BlockNodes() { iinod = inc[0] = inc[1] = 0; indxI = 1; } - //! \brief Returns \a iinod which then is incremented. - int next(); - }; - -#endif - -public: - //! \brief Constructor creating an instance by reading the given file. ASMu2D(const char* fName = 0, unsigned char n_s = 2, unsigned char n_f = 2); //! \brief Constructor creating an instance by reading the given input stream. @@ -85,13 +42,12 @@ public: //! \brief Empty destructor. virtual ~ASMu2D() {} - - // Methods to access data - // ============================ + //! \brief Returns the spline surface representing this patch. LR::LRSplineSurface* getSurface() { return lrspline; } - // Methods for model generation - // ============================ + + // Methods for model generation and refinement + // =========================================== //! \brief Generates the finite element topology data for the patch. //! \details The data generated are the element-to-node connectivity array, @@ -107,27 +63,15 @@ public: //! \param[in] inod 1-based node index local to current patch virtual Vec3 getCoord(size_t inod) const; + //! \brief Updates the nodal coordinates for this patch. + //! \param[in] displ Incremental displacements to update the coordinates with + virtual bool updateCoords(const Vector& displ); + //! \brief Creates an instance by reading the given input stream. bool read(std::istream&); //! \brief Writes the geometry of the SplineSurface object to given stream. virtual bool write(std::ostream&, int = 0) const; -#if 0 - //! \brief Assigns new global node numbers for all nodes of the patch. - //! \param nodes Object with global nodes numbers to assign to this patch - //! \param[in] basis Which basis to assign node numbers for in mixed methods - //! - //! \details The global node numbers generated by \a generateFEMTopology are - //! non-unique in the sense that a node that is shared by two (or more) - //! patches along a common interface has a different number in each patch. - //! This method therefore assigns a new global number to each node in the - //! patch. The data provided through the \a nodes argument is sufficient - //! to determine the unique global number under the assumption that they - //! are ordered in the sequence determined by the local orientation of the - //! patch and its edges. - bool assignNodeNumbers(); -#endif - //! \brief Refines along the diagonal of the LR-spline patch. //! \details Progressively refine until the LR-spline object contains at least //! \a minBasisfunctions basis functions. @@ -202,8 +146,7 @@ public: void constrainNode(double xi, double eta, int dof = 123, int code = 0); // More multipatch stuff -#if 0 - +#if 0 //! \brief Connects all matching nodes on two adjacent boundary edges. //! \param[in] edge Local edge index of this patch, in range [1,4] //! \param neighbor The neighbor patch @@ -217,9 +160,9 @@ public: //! \param[in] basis Which basis to connect (mixed methods), 0 means both //! \param[in] master 1-based index of the first master node in this basis virtual void closeEdges(int dir, int basis = 0, int master = 1); - #endif + // Methods for integration of finite element quantities. // These are the main computational methods of the ASM class hierarchy. // ==================================================================== @@ -261,7 +204,6 @@ public: //! \note The number of element nodes must be set in \a grid on input. virtual bool tesselate(ElementBlock& grid, const int* npe) const; - //! \brief Evaluates the primary solution field at all visualization points. //! \param[out] sField Solution field //! \param[in] locSol Solution vector in DOF-order @@ -385,12 +327,13 @@ protected: Vector& N, Matrix& dNdu, Matrix3D& d2Ndu2); protected: - LR::LRSplineSurface* lrspline; //!< Pointer to the actual spline surface object + LR::LRSplineSurface* lrspline; //!< Pointer to the LR-spline surface object private: - Go::SplineSurface* tensorspline; //!< Pointer to the original tensor spline object - // the tensor spline object is kept for backwards compatability with the REFINE and RAISEORDER - // key-words, although we take note that there is a possibility of optimization since all mapping - // values and jacobians may be performed on this object for increased efficiency + Go::SplineSurface* tensorspline; //!< Pointer to original tensor spline object + // The tensor spline object is kept for backward compatability with the REFINE + // and RAISEORDER key-words, although we take note that there is a possibility + // of optimization since all mapping values and Jacobians may be performed on + // this object for increased efficiency. }; #endif