From ad00202d8395889100933f17e4242dc215d6381d Mon Sep 17 00:00:00 2001 From: Knut Morten Okstad Date: Sat, 5 Oct 2024 17:26:28 +0200 Subject: [PATCH 1/3] Return C-pointers instead of iterators --- src/FFlLib/FFlLinkHandler.C | 109 ++++++++++++++++-------------------- src/FFlLib/FFlLinkHandler.H | 26 +++++---- 2 files changed, 64 insertions(+), 71 deletions(-) diff --git a/src/FFlLib/FFlLinkHandler.C b/src/FFlLib/FFlLinkHandler.C index b5b1368..4216cec 100644 --- a/src/FFlLib/FFlLinkHandler.C +++ b/src/FFlLib/FFlLinkHandler.C @@ -1350,83 +1350,79 @@ void FFlLinkHandler::getAllInternalCoordSys(std::vector& mxes) const JJS 2009.03.27 */ -NodesCIter FFlLinkHandler::findFreeNodeAtPoint(const FaVec3& point, - double tolerance, - int dofFilter) const +FFlNode* FFlLinkHandler::findFreeNodeAtPoint(const FaVec3& point, + double tol, int dofFilter) const { - NodesCIter closest = myNodes.end(); + FFlNode* closest = NULL; double closestdist = DBL_MAX; - double sqrTol = tolerance > sqrt(DBL_MAX) ? DBL_MAX : tolerance*tolerance; + double sqrTol = tol > sqrt(DBL_MAX) ? DBL_MAX : tol*tol; double sqrdist, xd, yd, zd; - for (NodesCIter nit = myNodes.begin(); nit != myNodes.end(); nit++) - if ((*nit)->hasDOFs(dofFilter) || (*nit)->isExternal() || (*nit)->isRefNode()) - { - const FaVec3& pos = (*nit)->getPos(); - if ((xd = fabs(pos.x() - point.x())) < tolerance) - if ((yd = fabs(pos.y() - point.y())) < tolerance) - if ((zd = fabs(pos.z() - point.z())) < tolerance) + for (FFlNode* node : myNodes) + if (node->hasDOFs(dofFilter) || node->isExternal() || node->isRefNode()) + if ((xd = fabs(node->getPos().x() - point.x())) < tol) + if ((yd = fabs(node->getPos().y() - point.y())) < tol) + if ((zd = fabs(node->getPos().z() - point.z())) < tol) if ((sqrdist = xd*xd+yd*yd+zd*zd) < sqrTol) { if (closestdist >= sqrTol) { - // The first matching node - closest = nit; + // This is the first matching node + closest = node; closestdist = sqrdist; } - else if (!(*closest)->isAttachable() && (*nit)->isAttachable()) + else if (node->isAttachable() && !closest->isAttachable()) { - // The previous node found was dependent, replace it with *nit - closest = nit; + // The previous node found was dependent, replace it with this + closest = node; closestdist = sqrdist; } - else if (!(*closest)->isSlaveNode() && (*nit)->isRefNode()) + else if (node->isRefNode() && !closest->isSlaveNode()) { // The previous node found was a free node (not connected to a // constraint element) whereas this node is a reference node. // Check if they are connected via an auto-added BUSH element. - if (!areBUSHconnected(*closest,*nit)) + if (!this->areBUSHconnected(closest,node)) { // Not connected, use the found reference node instead - closest = nit; + closest = node; closestdist = sqrdist; } } - else if (!(*nit)->isSlaveNode()) + else if (!node->isSlaveNode()) { - if ((*closest)->isRefNode()) + if (closest->isRefNode()) { // The previous node found was a reference node whereas this // node is a free node. Check if they are BUSH-connected. - if (areBUSHconnected(*nit,*closest)) + if (this->areBUSHconnected(node,closest)) { // They are connected, use the found free node instead - closest = nit; + closest = node; closestdist = sqrdist; } } - else if ((*nit)->getMaxDOFs() > (*closest)->getMaxDOFs()) + else if (node->getMaxDOFs() > closest->getMaxDOFs()) { // This node has 6 DOFs whereas the previous one has only 3. // Choose the node having the most DOFs. - closest = nit; + closest = node; closestdist = sqrdist; } else if (sqrdist < closestdist) - if ((*closest)->getStatus(1) == (*nit)->getStatus(1)) + if (closest->getStatus(1) == node->getStatus(1)) { // This node matches better than the previous node found - closest = nit; + closest = node; closestdist = sqrdist; } } } - } #ifdef FFL_DEBUG - if (closest == myNodes.end()) + if (!closest) std::cout <<" *** No FE node found at point ="<< point - <<", tol = "<< tolerance <<" dofFilter ="<< dofFilter << std::endl; + <<", tol = "<< tol <<" dofFilter ="<< dofFilter << std::endl; #endif return closest; @@ -1517,21 +1513,18 @@ FFlNode* FFlLinkHandler::createAttachableNode(FFlNode* fromNode, Returns the node that is closest to the given \a point. */ -NodesCIter FFlLinkHandler::findClosestNode(const FaVec3& point) const +FFlNode* FFlLinkHandler::findClosestNode(const FaVec3& point) const { - NodesCIter closest = myNodes.end(); + FFlNode* closest = NULL; double closestdist = DBL_MAX; double sqrdist; - for (NodesCIter nit = myNodes.begin(); nit != myNodes.end(); nit++) - { - sqrdist = (point - (*nit)->getPos()).sqrLength(); - if (sqrdist <= closestdist) + for (FFlNode* node : myNodes) + if ((sqrdist = (point - node->getPos()).sqrLength()) <= closestdist) { - closest = nit; + closest = node; closestdist = sqrdist; } - } return closest; } @@ -1543,27 +1536,25 @@ NodesCIter FFlLinkHandler::findClosestNode(const FaVec3& point) const If \a wantedTypes is empty, any element is accepted. */ -ElementsCIter FFlLinkHandler::findClosestElement(const FaVec3& point, - const std::vector& wantedTypes) const +FFlElementBase* FFlLinkHandler::findClosestElement(const FaVec3& point, + const CathegoryVec& wantedTypes) const { - ElementsCIter closest = myElements.end(); + FFlElementBase* closest = NULL; double closestdist = DBL_MAX; + double sqrdist; // OTHER_ELM = the total number of element cathegories std::vector typeOk(FFlTypeInfoSpec::OTHER_ELM+1,wantedTypes.empty()); for (FFlTypeInfoSpec::Cathegory type : wantedTypes) typeOk[type] = true; - for (ElementsCIter eIt = myElements.begin(); eIt != myElements.end(); eIt++) - if (typeOk[(*eIt)->getCathegory()]) - { - double sqrdist = (point - (*eIt)->getNodeCenter()).sqrLength(); - if (sqrdist <= closestdist) + for (FFlElementBase* elm : myElements) + if (typeOk[elm->getCathegory()]) + if ((sqrdist = (point - elm->getNodeCenter()).sqrLength()) <= closestdist) { - closest = eIt; + closest = elm; closestdist = sqrdist; } - } return closest; } @@ -1579,16 +1570,14 @@ FFlElementBase* FFlLinkHandler::findClosestElement(const FaVec3& point, { FFlElementBase* closest = NULL; double closestdist = DBL_MAX; + double sqrdist; for (const GroupElemRef& elm : group) - { - double sqrdist = (point - elm->getNodeCenter()).sqrLength(); - if (sqrdist <= closestdist) + if ((sqrdist = (point - elm->getNodeCenter()).sqrLength()) <= closestdist) { closest = elm.getReference(); closestdist = sqrdist; } - } return closest; } @@ -1604,10 +1593,8 @@ FFlElementBase* FFlLinkHandler::findClosestElement(const FaVec3& point, { if (group) return this->findClosestElement(point,*group); - - std::vector allTypes; - ElementsCIter closest = this->findClosestElement(point,allTypes); - return closest == myElements.end() ? NULL : *closest; + else + return this->findClosestElement(point,{}); } @@ -1641,10 +1628,10 @@ FFlElementBase* FFlLinkHandler::findPoint(const FaVec3& point, double* xi, { // The invertMapping method is implemented for shell elements only. // Filter out all other element types from the element search. - std::vector shell({FFlTypeInfoSpec::SHELL_ELM}); - ElementsCIter eit = this->findClosestElement(point,shell); - if (eit != myElements.end() && (*eit)->invertMapping(point,xi)) - return *eit; + CathegoryVec shell({ FFlTypeInfoSpec::SHELL_ELM }); + FFlElementBase* elm = this->findClosestElement(point,shell); + if (elm && elm->invertMapping(point,xi)) + return elm; // Check all shell elements with its center closer to the target point // than the size of the smallest subscriping ball of the element diff --git a/src/FFlLib/FFlLinkHandler.H b/src/FFlLib/FFlLinkHandler.H index bdbf1d4..d47720f 100644 --- a/src/FFlLib/FFlLinkHandler.H +++ b/src/FFlLib/FFlLinkHandler.H @@ -67,6 +67,8 @@ typedef std::vector VisualsVec; typedef VisualsVec::const_iterator VisualsCIter; #endif +typedef std::vector CathegoryVec; + typedef std::pair FFlrElement; typedef std::vector FFlrElementVec; typedef std::vector FFlrVxToElmMap; @@ -195,20 +197,24 @@ public: void getMassProperties(double& M, FaVec3& Xcg, FFaTensor3& I) const; - NodesCIter findFreeNodeAtPoint(const FaVec3& point, double tol, - int dofFilter = -1) const; - NodesCIter findClosestNode(const FaVec3& point) const; + FFlNode* findFreeNodeAtPoint(const FaVec3& point, double tol, + int dofFilter = -1) const; + FFlNode* findClosestNode(const FaVec3& point) const; FFlNode* createAttachableNode(FFlNode* fromNode, const FaVec3& nodePos, FFlConnectorItems* cItems = NULL); - ElementsCIter findClosestElement(const FaVec3& point, - const std::vector&) const; - FFlElementBase* findClosestElement(const FaVec3& point, const FFlGroup& group) const; - FFlElementBase* findClosestElement(const FaVec3& point, FFlGroup* group = NULL) const; - - FFlElementBase* findPoint(const FFlGroup& group, const FaVec3& point, double* xi) const; - FFlElementBase* findPoint(const FaVec3& point, double* xi, int groupID = 0) const; + FFlElementBase* findClosestElement(const FaVec3& point, + const CathegoryVec& wantedTypes) const; + FFlElementBase* findClosestElement(const FaVec3& point, + const FFlGroup& group) const; + FFlElementBase* findClosestElement(const FaVec3& point, + FFlGroup* group = NULL) const; + + FFlElementBase* findPoint(const FFlGroup& group, const FaVec3& point, + double* xi) const; + FFlElementBase* findPoint(const FaVec3& point, + double* xi, int groupID = 0) const; // Strain coat creation (these methods are defined in FFlStrainCoatCreator.C) From 6b1dac499df3f2c3ec02d32293553a183aade38b Mon Sep 17 00:00:00 2001 From: Knut Morten Okstad Date: Sat, 5 Oct 2024 22:15:07 +0200 Subject: [PATCH 2/3] Remove unused connector element property array. Add method deleteConnector() replacing two other methods for deleting the elements and nodes associated with a connector. Remove method createNodeAtPos(). --- src/FFlLib/FFlConnectorItems.C | 89 +++++++++++++------------- src/FFlLib/FFlConnectorItems.H | 44 +++---------- src/FFlLib/FFlLinkHandler.C | 110 ++++++++------------------------- src/FFlLib/FFlLinkHandler.H | 7 +-- 4 files changed, 81 insertions(+), 169 deletions(-) diff --git a/src/FFlLib/FFlConnectorItems.C b/src/FFlLib/FFlConnectorItems.C index 07b5138..3331b0a 100644 --- a/src/FFlLib/FFlConnectorItems.C +++ b/src/FFlLib/FFlConnectorItems.C @@ -13,78 +13,79 @@ bool operator== (const FFlConnectorItems& a, const FFlConnectorItems& b) { - if (&a == &b) return true; + if (&a == &b) + return true; if (a.nodes == b.nodes) if (a.elements == b.elements) - if (a.properties == b.properties) - return true; + return true; return false; } -std::ostream& -operator<< (std::ostream& s, const FFlConnectorItems& connector) +std::ostream& operator<< (std::ostream& s, const FFlConnectorItems& c) { - if (!connector.nodes.empty()) { + if (!c.nodes.empty()) + { s <<"\nNODES"; - for (int n : connector.nodes) s <<' '<< n; + for (int n : c.nodes) + s <<' '<< n; } - if (!connector.elements.empty()) { + + if (!c.elements.empty()) + { s <<"\nELEMENTS"; - for (int e : connector.elements) s <<' '<< e; - } - if (!connector.properties.empty()) { - s <<"\nPROPERTIES"; - for (int p : connector.properties) s <<' '<< p; + for (int e : c.elements) + s <<' '<< e; } - s << std::endl <<"END"; - return s; + + return s <<"\nEND"; } -std::istream& -operator>> (std::istream& s, FFlConnectorItems& connector) +std::istream& operator>> (std::istream& s, FFlConnectorItems& c) { - connector.clear(); + // Lambda function reading a vector of integers from the input stream + auto&& readStream = [&s](std::vector& data) + { + while (s) + { + char c = ' '; + while (s && isspace(c)) + s >> c; // read until next non-space character + if (s) + s.putback(c); + if (!s || !isdigit(c)) + return; // read until next non-digit character + + int i; + s >> i; + if (s) + data.push_back(i); + } + }; + + c.clear(); std::string keyWord; - while (s.good()) { + while (s.good()) + { s >> keyWord; bool isAlpha = true; for (size_t i = 0; i < keyWord.size() && isAlpha; i++) if (!isalpha(keyWord[i])) isAlpha = false; - if (isAlpha) { + if (isAlpha) + { if (keyWord == "NODES") - FFlConnectorItems::readStream(s,connector.nodes); + readStream(c.nodes); else if (keyWord == "ELEMENTS") - FFlConnectorItems::readStream(s,connector.elements); - else if (keyWord == "PROPERTIES") - FFlConnectorItems::readStream(s,connector.properties); + readStream(c.elements); else if (keyWord == "END") - break; + break; } } - return s; -} - -void FFlConnectorItems::readStream(std::istream& is, std::vector& data) -{ - while (is) { - char c = ' '; - while (isspace(c)) { - is >> c; - if (!is) return; - } - is.putback(c); - if (!isdigit(c)) return; // read until next non-digit character - - int i; - is >> i; - if (is) - data.push_back(i); - } + return s; } diff --git a/src/FFlLib/FFlConnectorItems.H b/src/FFlLib/FFlConnectorItems.H index 5ffa38f..31f4d4b 100644 --- a/src/FFlLib/FFlConnectorItems.H +++ b/src/FFlLib/FFlConnectorItems.H @@ -13,54 +13,30 @@ /*! - Class FFlConnectorItems is used by FmTriad to store spider connector - properties for reading and writing. - - Espen Medbo 2006 + \brief Storage of spider connector properties for Triads. */ class FFlConnectorItems { public: - FFlConnectorItems() {} - ~FFlConnectorItems() {} - - friend bool operator== (const FFlConnectorItems& a, - const FFlConnectorItems& b); + friend bool operator==(const FFlConnectorItems& a, const FFlConnectorItems& b); - friend std::ostream& operator<< (std::ostream& s, const FFlConnectorItems& connector); - friend std::istream& operator>> (std::istream& s, FFlConnectorItems& connector); + friend std::ostream& operator<<(std::ostream& s, const FFlConnectorItems& c); + friend std::istream& operator>>(std::istream& s, FFlConnectorItems& c); -private: - static void readStream (std::istream& is, std::vector& data); - -public: - void addNode (int nodeID) { this->nodes.push_back(nodeID); } - void addElement (int elementID) { this->elements.push_back(elementID); } - void addProperty(int propertyID) { this->properties.push_back(propertyID); } + void addNode(int nID) { this->nodes.push_back(nID); } + void addElement(int eID) { this->elements.push_back(eID); } - const std::vector& getNodes () const { return this->nodes; } - const std::vector& getElements () const { return this->elements; } - const std::vector& getProperties() const { return this->properties; } + const std::vector& getNodes() const { return this->nodes; } + const std::vector& getElements() const { return this->elements; } - bool empty() const - { - return this->nodes.empty() - && this->elements.empty() - && this->properties.empty(); - } + bool empty() const { return this->nodes.empty() && this->elements.empty(); } - void clear() - { - this->nodes.clear(); - this->elements.clear(); - this->properties.clear(); - } + void clear() { this->nodes.clear(); this->elements.clear(); } private: std::vector nodes; std::vector elements; - std::vector properties; }; #endif diff --git a/src/FFlLib/FFlLinkHandler.C b/src/FFlLib/FFlLinkHandler.C index 4216cec..de44c1a 100644 --- a/src/FFlLib/FFlLinkHandler.C +++ b/src/FFlLib/FFlLinkHandler.C @@ -2150,69 +2150,49 @@ void FFlLinkHandler::sortVisuals() const #endif -/*! - Creates a node based on the given position with the given number of \a DOFs. - Espen Medbo 2006 -*/ - -FFlNode* FFlLinkHandler::createNodeAtPoint(const FaVec3& nodePos, int DOFs) -{ - FFlNode* newNode = new FFlNode(this->getNewNodeID(),nodePos); - newNode->pushDOFs(DOFs); - ListUI <<" -> Creating FE node "<< newNode->getID() <<"\n"; - this->addNode(newNode,true); - - return newNode; -} - - #ifdef FT_USE_CONNECTORS /*! Creates a connector based on input geometry and the nodal position. - The elements, properties and nodes are returned through \a cItems. + The elements and nodes are returned through \a cItems. The \a spiderType is either: 2 - RiGiD element (RBE2) 3 - Weighted AVerage Motion element (RBE3) - Espen Medbo 2006 */ int FFlLinkHandler::createConnector(const FFaCompoundGeometry& compound, const FaVec3& nodePos, int spiderType, FFlConnectorItems& cItems) { - FFlElementBase* newElm = NULL; - if (spiderType == 2) - newElm = ElementFactory::instance()->create("RGD",this->getNewElmID()); - else if (spiderType == 3) - newElm = ElementFactory::instance()->create("WAVGM",this->getNewElmID()); - else + if (spiderType < 2 || spiderType > 3) return -1; // Invalid spider type - FFlNode* refNode = NULL; std::vector nodes; for (FFlNode* node : myNodes) if (node->hasDOFs() && node->getStatus() == FFlNode::INTERNAL) if (compound.isInside(node->getPos())) nodes.push_back(node); - if (nodes.size() > 1) - refNode = this->createNodeAtPoint(nodePos,6); - else - { - // No FE nodes on the provided geometry - delete newElm; - return 0; - } + if (nodes.size() < 2) + return 0; // No FE nodes on the provided geometry cItems.clear(); + + FFlNode* refNode = new FFlNode(this->getNewNodeID(),nodePos); + refNode->pushDOFs(6); + this->addNode(refNode,true); cItems.addNode(refNode->getID()); + ListUI <<" -> Creating FE node "<< refNode->getID() <<"\n"; nodes.insert(nodes.begin(),refNode); - newElm->setNodes(nodes); - this->addElement(newElm,true); - cItems.addElement(newElm->getID()); + + const char* spider[2] = { "RGD", "WAVGM" }; + FFlElementBase* newEl = ElementFactory::instance()->create(spider[spiderType-2], + this->getNewElmID()); + newEl->setNodes(nodes); + this->addElement(newEl,true); + cItems.addElement(newEl->getID()); ListUI <<" -> Creating "<< (spiderType == 2 ? "RGD":"WAVGM") - <<" element "<< newElm->getID() + <<" element "<< newEl->getID() <<" with reference node "<< refNode->getID() <<"\n"; if (spiderType == 3) @@ -2222,48 +2202,21 @@ int FFlLinkHandler::createConnector(const FFaCompoundGeometry& compound, // Ensure the attachable node has external status refNode->setExternal(); - // We do not need to create a property for the WAVGM element. - // The FE reducer will assign a default property with unit weights. return nodes.size(); } /*! - Delete the element properties of the connector. - Espen Medbo 2006 + Deletes the elements and nodes in the connector. */ -int FFlLinkHandler::deleteConnectorProperties(const std::vector& propertiesID) -{ - AttributeTypeMap::iterator atit = myAttributes.find("PWAVGM"); - if (atit == myAttributes.end()) - return 0; - - int nDeleted = 0; - AttributeMap::iterator ait; - for (int aid : propertiesID) - if ((ait = atit->second.find(aid)) != atit->second.end()) - { - delete ait->second; - atit->second.erase(ait); - nDeleted++; - } - - return nDeleted; -} - - -/*! - Delete the elements in the connector. - Takes the elements vector from the triad as an argument. - Espen Medbo 2006 -*/ - -int FFlLinkHandler::deleteConnectorElements(const std::vector& elementsID) +int FFlLinkHandler::deleteConnector(const FFlConnectorItems& cItems) { int nDeleted = 0; ElementsIter eit; - for (int elm : elementsID) + NodesIter nit; + + for (int elm : cItems.getElements()) if ((eit = this->getElementIter(elm)) != myElements.end()) { ListUI <<" -> Deleting "<< (*eit)->getTypeName() @@ -2275,22 +2228,7 @@ int FFlLinkHandler::deleteConnectorElements(const std::vector& elementsID) nDeleted++; } - this->sortElements(); - return nDeleted; -} - - -/*! - Delete the nodes in the connector. - Takes the nodes vector from the triad as an argument. - Espen Medbo 2006 -*/ - -int FFlLinkHandler::deleteConnectorNodes(const std::vector& nodesID) -{ - int nDeleted = 0; - NodesIter nit; - for (int node : nodesID) + for (int node : cItems.getNodes()) if ((nit = this->getNodeIter(node)) != myNodes.end()) { ListUI <<" -> Deleting FE node "<< node <<"\n"; @@ -2299,7 +2237,9 @@ int FFlLinkHandler::deleteConnectorNodes(const std::vector& nodesID) nDeleted++; } + this->sortElements(); this->sortNodes(); + return nDeleted; } #endif diff --git a/src/FFlLib/FFlLinkHandler.H b/src/FFlLib/FFlLinkHandler.H index d47720f..5cf10fd 100644 --- a/src/FFlLib/FFlLinkHandler.H +++ b/src/FFlLib/FFlLinkHandler.H @@ -274,16 +274,11 @@ public: void dump() const; - FFlNode* createNodeAtPoint(const FaVec3& nodePos, int DOFs = 0); - #ifdef FT_USE_CONNECTORS int createConnector(const FFaCompoundGeometry& compound, const FaVec3& nodePos, int spiderType, FFlConnectorItems& cItems); - - int deleteConnectorProperties(const std::vector& propertiesID); - int deleteConnectorElements(const std::vector& elementsID); - int deleteConnectorNodes(const std::vector& nodesID); + int deleteConnector(const FFlConnectorItems& cItems); #endif protected: From 0bb0830f6ccfbfc0f24ce275976af424881c38c7 Mon Sep 17 00:00:00 2001 From: Knut Morten Okstad Date: Mon, 7 Oct 2024 05:47:18 +0200 Subject: [PATCH 3/3] Remove registration of unsupported ABAQUS and ANSYS input file readers --- src/FFlLib/FFlIOAdaptors/FFlAllIOAdaptors.C | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/FFlLib/FFlIOAdaptors/FFlAllIOAdaptors.C b/src/FFlLib/FFlIOAdaptors/FFlAllIOAdaptors.C index b3e8ee8..c652161 100644 --- a/src/FFlLib/FFlIOAdaptors/FFlAllIOAdaptors.C +++ b/src/FFlLib/FFlIOAdaptors/FFlAllIOAdaptors.C @@ -20,8 +20,10 @@ void FFl::initAllReaders() FFlOldFLMReader::init(); FFlNastranReader::init(); FFlSesamReader::init(); +#ifdef FT_HAS_VKI FFlAbaqusReader::init(); FFlAnsysReader::init(); +#endif initialized = true; } @@ -29,7 +31,7 @@ void FFl::initAllReaders() void FFl::releaseAllReaders() { - FFlReaders::removeInstance (); + FFlReaders::removeInstance(); initialized = false; }