From 22952809fa6b45377714dc1af552e1d057cc68f9 Mon Sep 17 00:00:00 2001 From: Knut Morten Okstad Date: Tue, 26 Oct 2021 06:00:10 +0200 Subject: [PATCH] Changed: The node renumbering is moved to a separate method, since this also have to done by the new readTopologyOnly method --- src/SIM/SIMbase.C | 67 +++++++++++++++++++++++++++------------------- src/SIM/SIMbase.h | 9 +++++++ src/SIM/SIMinput.C | 2 +- 3 files changed, 50 insertions(+), 28 deletions(-) diff --git a/src/SIM/SIMbase.C b/src/SIM/SIMbase.C index 07154432..9460747d 100644 --- a/src/SIM/SIMbase.C +++ b/src/SIM/SIMbase.C @@ -54,7 +54,7 @@ SIMbase::SIMbase (IntegrandBase* itg) : g2l(&myGlb2Loc) myGl2Params = nullptr; dualField = nullptr; isRefined = lagMTOK = false; - nGlPatches = 0; + nGlbNodes = nGlPatches = 0; nIntGP = nBouGP = 0; nDofS = 0; mdFlag = 0; @@ -124,6 +124,7 @@ void SIMbase::clearProperties () for (FunctionBase* f : extrFunc) delete f; + nGlbNodes = 0; myPatches.clear(); myGlb2Loc.clear(); myScalars.clear(); @@ -263,33 +264,14 @@ bool SIMbase::preprocess (const IntVec& ignored, bool fixDup) printNodalConnectivity(myModel,std::cout); #endif - // Renumber the nodes to account for overlapping nodes and erased patches. - // In parallel simulations, the resulting global-to-local node number mapping - // will map the global node numbers to local node numbers on the current - // processor. In serial simulations, the global-to-local mapping will be unity - // unless the original global node number sequence had "holes" due to - // duplicated nodes and/or erased patches. - int ngnod = 0; - int renum = 0; - if (preserveNOrder) - { - renum = ASMbase::renumberNodes(myModel,myGlb2Loc); - ngnod = g2l->size(); - } - else for (ASMbase* pch : myModel) - renum += pch->renumberNodes(myGlb2Loc,ngnod); - - if (renum > 0) - IFEM::cout <<"\nRenumbered "<< renum <<" nodes."<< std::endl; - - // Apply the old-to-new node number mapping to all node tables in the model - if (!this->renumberNodes(*g2l)) - return false; + // Renumber the nodes to account for resolved patch topology + if (!nGlbNodes) nGlbNodes = this->renumberNodes(); + if (nGlbNodes < 0) return false; // Perform specialized preprocessing before the assembly initialization. // This typically involves the system-level Lagrange multipliers, etc. - ASMbase::resetNumbering(ngnod); // to account for possibly added nodes - if (!this->preprocessBeforeAsmInit(ngnod)) + ASMbase::resetNumbering(nGlbNodes); // to account for possibly added nodes + if (!this->preprocessBeforeAsmInit(nGlbNodes)) return false; IFEM::cout <<"\nResolving Dirichlet boundary conditions"<< std::endl; @@ -325,7 +307,7 @@ bool SIMbase::preprocess (const IntVec& ignored, bool fixDup) } if (dofs > 0) - if (this->addConstraint(p.patch,p.lindx,p.ldim,dofs,code,ngnod, + if (this->addConstraint(p.patch,p.lindx,p.ldim,dofs,code,nGlbNodes, p.basis)) IFEM::cout << std::endl; else @@ -398,7 +380,7 @@ bool SIMbase::preprocess (const IntVec& ignored, bool fixDup) mySam = new SAMpatch(); #endif - if (!static_cast(mySam)->init(myModel,ngnod,dofTypes)) + if (!static_cast(mySam)->init(myModel,nGlbNodes,dofTypes)) { #ifdef SP_DEBUG for (ASMbase* pch : myModel) @@ -455,6 +437,35 @@ bool SIMbase::merge (SIMbase* that, const std::map* old2new, int poff) } +/*! + This method renumbers the nodes to account for overlapping nodes + for multi-patch models, erased patches, etc. In parallel simulations, + the resulting global-to-local node number mapping \ref myGlb2Loc will map + the global node numbers to local node numbers on the current processor. + In serial simulations, this mapping will be unity unless the original global + node number sequence had "holes" due to duplicated nodes or erased patches. +*/ + +int SIMbase::renumberNodes () +{ + int ngnod = 0; + int renum = 0; + if (preserveNOrder) + { + renum = ASMbase::renumberNodes(myModel,myGlb2Loc); + ngnod = g2l->size(); + } + else for (ASMbase* pch : myModel) + renum += pch->renumberNodes(myGlb2Loc,ngnod); + + if (renum > 0) + IFEM::cout <<"\nRenumbered "<< renum <<" nodes."<< std::endl; + + // Apply the old-to-new node number mapping to all node tables in the model + return this->renumberNodes(*g2l) ? ngnod : -ngnod; +} + + bool SIMbase::renumberNodes (const std::map& nodeMap) { bool ok = true; @@ -680,6 +691,8 @@ size_t SIMbase::getNoNodes (int basis) const } else if (myModel.size() == 1) return myModel.front()->getNoNodes(basis); + else if (basis < 1 && nGlbNodes > 0) + return nGlbNodes; std::cerr <<" *** SIMbase::getNoNodes: Number of nodes in a multi-patch model" <<" is not known at this point."<< std::endl; diff --git a/src/SIM/SIMbase.h b/src/SIM/SIMbase.h index 20f84892..5737865c 100644 --- a/src/SIM/SIMbase.h +++ b/src/SIM/SIMbase.h @@ -584,6 +584,10 @@ protected: virtual bool preprocessB() { return true; } //! \brief Preprocesses the result sampling points. virtual void preprocessResultPoints() = 0; + + //! \brief Renumbers the global node numbers after resolving patch topology. + //! \return Total number of unique nodes in the model, negative on error + int renumberNodes(); //! \brief Renumbers all global node numbers if the model. //! \param[in] nodeMap Mapping from old to new node number virtual bool renumberNodes(const std::map& nodeMap); @@ -770,6 +774,11 @@ protected: std::vector extrFunc; //!< Extraction functions for VCP + //! \brief Total number of unique nodes in the model + //! \details This variable is only used to carry the number of nodes in + //! the model, in the case that renumberNodes() is called before preprocess() + //! and until the SAMpatch::init() method is invoked. + int nGlbNodes; //!< This value will be equal to SAM::getNoNodes('A'). int isRefined; //!< Indicates if the model is adaptively refined bool lagMTOK; //!< Indicates if global multipliers is OK with multithreading diff --git a/src/SIM/SIMinput.C b/src/SIM/SIMinput.C index 8d9c96fc..d7ca1cf9 100644 --- a/src/SIM/SIMinput.C +++ b/src/SIM/SIMinput.C @@ -1006,7 +1006,7 @@ bool SIMinput::readTopologyOnly (const std::string& fileName) if (!this->parseGeometryDimTag(child)) return false; - return true; + return (nGlbNodes = this->renumberNodes()) > 0; }