1 // Copyright (C) 2015-2021 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "BagPoint.hxx"
21 #include "Exception.hxx"
22 #include "LinkedBlocPoint.hxx"
23 #include "ForkBlocPoint.hxx"
24 #include "NotSimpleCasePoint.hxx"
27 #include "LinkInfo.hxx"
32 using namespace YACS::ENGINE;
34 BagPoint::BagPoint(const std::list<AbstractPoint *>& nodes, AbstractPoint *father):BlocPoint(nodes,father)
38 void BagPoint::accept(PointVisitor *pv)
43 throw YACS::Exception("BagPoint::accept : Ooops !");
48 AbstractPoint *BagPoint::expandNonSimpleCaseOn(NotSimpleCasePoint *pathologicalPt, const std::set<Node *>& uncatchedNodes)
50 throw YACS::Exception("BagPoint::expandNonSimpleCaseOn : Ooops !");
53 AbstractPoint *BagPoint::deepCopy(AbstractPoint *father) const
55 BagPoint *ret(new BagPoint);
56 ret->deepCopyFrom(*this);
57 ret->setFather(father);
61 Node *BagPoint::getFirstNode()
63 return getUnique()->getFirstNode();
66 Node *BagPoint::getLastNode()
68 return getUnique()->getLastNode();
71 int BagPoint::getMaxLevelOfParallelism() const
73 return getUnique()->getMaxLevelOfParallelism();
76 void BagPoint::getWeightRegardingDPL(ComplexWeight *weight)
78 getUnique()->getWeightRegardingDPL(weight);
81 void BagPoint::partitionRegardingDPL(const PartDefinition *pd, std::map<ComposedNode *, YACS::BASES::AutoRefCnt<PartDefinition> >& zeMap) const
83 getUnique()->partitionRegardingDPL(pd,zeMap);
86 std::string BagPoint::getRepr() const
88 std::ostringstream oss;
89 for(std::list<AbstractPoint *>::const_iterator it=_nodes.begin();it!=_nodes.end();it++)
90 oss << (*it)->getRepr() << " - ";
96 void BagPoint::replaceInMe(BlocPoint *aSet)
98 const std::list<AbstractPoint *>& pts(aSet->getListOfPoints());
99 for(std::list<AbstractPoint *>::const_iterator it0=pts.begin();it0!=pts.end();it0++)
101 std::list<AbstractPoint *>::iterator it1(std::find(_nodes.begin(),_nodes.end(),*it0));
102 if(it1==_nodes.end())
103 throw Exception("SetOfPoints::replaceInMe : internal error !");
106 _nodes.push_back(aSet);
109 void BagPoint::deal1(bool& somethingDone)
112 for(std::list<AbstractPoint *>::iterator it=_nodes.begin();it!=_nodes.end();it++)
114 if(!(*it)->isSimplyLinkedBeforeAfter(this))
115 if(!(*it)->isSimplyLinkedAfterNullBefore(this) && !(*it)->isSimplyLinkedBeforeNullAfter(this))
117 LinkedBlocPoint *try0((*it)->tryAsLink(this));
127 void BagPoint::deal2(bool& somethingDone)
130 for(std::list<AbstractPoint *>::iterator it=_nodes.begin();it!=_nodes.end();it++)
132 if(!(*it)->isSimplyLinkedBeforeAfter(this))
134 ForkBlocPoint *try1((*it)->tryAsFork(this));
144 void BagPoint::deal2Bis(bool& somethingDone)
147 for(std::list<AbstractPoint *>::iterator it=_nodes.begin();it!=_nodes.end();it++)
149 if(!(*it)->isSimplyLinkedAfterNullBefore(this))
151 ForkBlocPoint *try1((*it)->tryAsForkBis(this));
161 void BagPoint::deal2Ter(bool& somethingDone)
164 for(std::list<AbstractPoint *>::iterator it=_nodes.begin();it!=_nodes.end();it++)
166 if(!(*it)->isSimplyLinkedBeforeNullAfter(this))
168 ForkBlocPoint *try1((*it)->tryAsForkTer(this));
178 void BagPoint::deal2Quatro(bool& somethingDone)
181 for(std::list<AbstractPoint *>::iterator it=_nodes.begin();it!=_nodes.end();it++)
183 if(!(*it)->isNullBeforeNullAfter(this))
185 ForkBlocPoint *try1((*it)->tryAsForkQuatro(this));
196 * This method remove 1, 2 or 3 points from this by flagging them as pathological nodes.
197 * By doing so, we hope to simplify enough to have a standart case.
199 void BagPoint::dealNotSimpleCase(bool& somethingDone)
202 for(auto it=_nodes.begin();it!=_nodes.end();it++)
204 std::vector<AbstractPoint *> v{*it};
205 AbstractPoint::TryAsNotSimpleCase((*it)->getFather(),v,_nodes,somethingDone);
212 for(auto it=_nodes.cbegin();it!=_nodes.cend();it++)
215 for(;it2!=_nodes.cend();it2++)
217 std::vector<AbstractPoint *> v{*it,*it2};
218 AbstractPoint::TryAsNotSimpleCase((*it)->getFather(),v,_nodes,somethingDone);
226 for(auto it=_nodes.cbegin();it!=_nodes.cend();it++)
229 for(;it2!=_nodes.cend();it2++)
231 auto it3(it2); it3++;
232 for(;it3!=_nodes.cend();it3++)
234 std::vector<AbstractPoint *> v{*it,*it2,*it3};
235 AbstractPoint::TryAsNotSimpleCase((*it)->getFather(),v,_nodes,somethingDone);
244 * Append a single pathologicalPt point instance to AbstractPoint instances contained in \a this.
245 * To do that we start to locate in graph dependancy in \a this with ENGINE::Node cannot run in parallel with \a pathologicalPt. These nodes stored in \a nodesBeforeAfter.
247 * By walking across Points in \a this if a Point has no intersection with \a nodesBeforeAfter this Point is converted to a ForkBlocPoint.
249 void BagPoint::expandNonSimpleCaseOn(AbstractPoint *pathologicalPt)
251 NotSimpleCasePoint *pathologicalPt2(dynamic_cast<NotSimpleCasePoint *>(pathologicalPt));
253 throw YACS::Exception("BagPoint::expandNonSimpleCaseOn : pathologicalPt is expected to be a NotSimpleCasePoint !");
254 std::list<AbstractPoint *> nodes2;
255 std::for_each(_nodes.begin(),_nodes.end(),[&nodes2](AbstractPoint *elt) { if(!dynamic_cast<NotSimpleCasePoint *>(elt)) nodes2.push_back(elt); });
257 throw YACS::Exception("BagPoint::expandNonSimpleCaseOn : Internal error only one AbstractPoint is expected !");
259 Node *firstNode(pathologicalPt->getFirstNode()),*lastNode(pathologicalPt->getLastNode());
261 ComposedNode *parent(firstNode->getFather());
262 Bloc *parentc(dynamic_cast<Bloc *>(parent));
264 throw YACS::Exception("BagPoint::expandNonSimpleCaseOn : internal error, Bloc expected");
266 std::set<Node *> nodesBefore, nodesAfter;
268 std::map<Node *, std::set<Node *> > accelStr;
269 LinkInfo info(E_ALL);
270 parentc->findAllNodesStartingFrom<false>(firstNode,nodesBefore,accelStr,info);
273 std::map<Node *, std::set<Node *> > accelStr;
274 LinkInfo info(E_ALL);
275 parentc->findAllNodesStartingFrom<true>(lastNode,nodesAfter,accelStr,info);
278 std::set<Node *> nodesBeforeAfter(nodesBefore.begin(),nodesBefore.end());
279 nodesBeforeAfter.insert(nodesAfter.begin(),nodesAfter.end());
280 //std::for_each(nodesBeforeAfter.begin(),nodesBeforeAfter.end(),[](Node *elt) { std::cerr << elt->getName() << " "; }); std::cerr << std::endl;
282 AbstractPoint *onlyOne(*nodes2.begin());
283 AbstractPoint *res(onlyOne->expandNonSimpleCaseOn(pathologicalPt2,nodesBeforeAfter));
285 throw YACS::Exception("BagPoint::expandNonSimpleCaseOn : unexpected situation !");// impossible because by construction pathologicalPt cannot be merged to this. If it were possible, algo in simplify would be simply it !
286 {// remove delete pathologicalPt and remove it from this->_nodes
287 std::list<AbstractPoint *> nodes3;
288 std::for_each(_nodes.begin(),_nodes.end(),[&nodes3,pathologicalPt](AbstractPoint *elt) { if(elt!=pathologicalPt) nodes3.push_back(elt); else delete elt; });
294 * All NotSimpleCasePoint instances in this->_nodes are going to be scanned recursively accross this->_nodes.
295 * To do that NotSimpleCasePoint instance are added incrementaly.
297 void BagPoint::expandNonSimpleCase()
299 std::vector<AbstractPoint *> pathologicalPt;
300 std::for_each(_nodes.begin(),_nodes.end(),[&pathologicalPt](AbstractPoint *elt) { if(dynamic_cast<NotSimpleCasePoint *>(elt)) pathologicalPt.push_back(elt); });
301 if(pathologicalPt.empty())
302 throw YACS::Exception("BagPoint::expandNonSimpleCase : Not found any pathological case !");
303 for(auto it : pathologicalPt)
304 this->expandNonSimpleCaseOn(it);