StitchGeometry.cpp
1 /*---------------------------------------------------------------------------*\
2  *
3  * mimmo
4  *
5  * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6  *
7  * -------------------------------------------------------------------------
8  * License
9  * This file is part of mimmo.
10  *
11  * mimmo is free software: you can redistribute it and/or modify it
12  * under the terms of the GNU Lesser General Public License v3 (LGPL)
13  * as published by the Free Software Foundation.
14  *
15  * mimmo is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18  * License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with mimmo. If not, see <http://www.gnu.org/licenses/>.
22  *
23 \*---------------------------------------------------------------------------*/
24 
25 #include "StitchGeometry.hpp"
26 
27 namespace mimmo{
28 
36  m_name = "mimmo.StitchGeometry";
37  m_geocount = 0;
38  m_topo = std::min(1, topo);
39  if(m_topo > 4) m_topo = 1;
40  m_repid = false;
41 }
42 
47 StitchGeometry::StitchGeometry(const bitpit::Config::Section & rootXML){
48 
49  std::string fallback_name = "ClassNONE";
50  std::string fallback_topo = "-1";
51  std::string input_name = rootXML.get("ClassName", fallback_name);
52  std::string input_topo = rootXML.get("Topology", fallback_topo);
53  input_name = bitpit::utils::string::trim(input_name);
54  input_topo = bitpit::utils::string::trim(input_topo);
55 
56  int topo = std::stoi(input_topo);
57  m_topo = std::max(1,topo);
58  if (m_topo >4) m_topo = 1;
59  m_geocount = 0;
60  m_name = "mimmo.StitchGeometry";
61  m_repid = false;
62 
63  if(input_name == "mimmo.StitchGeometry"){
64  absorbSectionXML(rootXML);
65  }else{
67  };
68 }
69 
74  clear();
75 };
76 
83  m_topo = other.m_topo;
84  m_extgeo = other.m_extgeo;
85  m_geocount = other.m_geocount;
86  m_patch.reset();
87  m_repid = other.m_repid;
88 };
89 
94  swap(other);
95  return *this;
96 };
97 
98 
104 {
105  std::swap(m_topo,x.m_topo);
106  std::swap(m_extgeo, x.m_extgeo);
107  std::swap(m_geocount, x.m_geocount);
108  std::swap(m_repid, x.m_repid);
110 };
111 
112 
116 void
118  bool built = true;
119 
120  built = (built && createPortIn<mimmo::MimmoSharedPointer<MimmoObject>, StitchGeometry>(this, &mimmo::StitchGeometry::addGeometry, M_GEOM, true));
121 
122  built = (built && createPortOut<mimmo::MimmoSharedPointer<MimmoObject>, StitchGeometry>(this, &mimmo::StitchGeometry::getGeometry, M_GEOM));
123  m_arePortsBuilt = built;
124 }
125 
130 int
132  return m_topo;
133 }
134 
141  return m_patch;
142 }
143 
149 void
151  if(geo == nullptr) return;
152  if(geo->getType() != m_topo) return;
153  if(m_extgeo.count(geo) > 0) return;
154 
155  m_extgeo.insert(std::make_pair(geo,m_geocount) );
156  m_geocount++;
157 };
158 
163 bool
165  return m_patch->isEmpty();
166 }
167 
171 void
173  m_extgeo.clear();
174  m_geocount = 0;
175  m_patch.reset();
177 };
178 
183 void
185  m_repid = flag;
186 };
187 
191 void
193 
195 #if MIMMO_ENABLE_MPI
196  if(m_nprocs > 1){
197  // Warning. Uniqueness of the cell/vertex ids is not maintained stitiching partitioned meshes
198  (*m_log)<<"WARNING "<< m_name<<" : stitching partitioned meshes doesn't guarantee unique ids among processors"<<std::endl;
199  }
200 #endif
201 
202  long nCells = 0;
203  long nVerts = 0;
204 
205  for(auto &obj : m_extgeo){
206  nCells += obj.first->getNCells();
207  nVerts += obj.first->getNVertices();
208  }
209 
210  //reserving memory
211  dum->getPatch()->reserveVertices(nVerts);
212  dum->getPatch()->reserveCells(nCells);
213 
214  long cV = 0, cC = 0;
215 
216  std::unordered_map<mimmo::MimmoSharedPointer<MimmoObject>,long> map_pidstart;
217  //initialize map
218  for(auto & obj : m_extgeo){
219  map_pidstart[obj.first] = 0;
220  }
221 
222  if(m_repid){
223  long pidmax = -1;
224  for(auto & obj : m_extgeo){
225  auto pidlist = obj.first->getPIDTypeList();
226  std::vector<long> temp(pidlist.begin(), pidlist.end());
227  std::sort(temp.begin(), temp.end());
228  map_pidstart[obj.first] = pidmax + 1;
229  pidmax += (*(temp.rbegin())+1);
230  }
231  }
232 
233 
234  //start filling your stitched object.
235  {
236  //optional vars;
237  long vId, cId;
238  long PID;
239  bitpit::ElementType eltype;
240 
241  for(auto &obj : m_extgeo){
242 
243  std::unordered_map<long,long> mapVloc;
244  auto originalPidNames = obj.first->getPIDTypeListWNames();
245  std::unordered_map<long, long> newOldPid;
246  for(const auto & val : obj.first->getPIDTypeList()){
247  newOldPid[val + map_pidstart[obj.first]] = val;
248  }
249  //start extracting/reversing vertices of the current obj
250  for(const auto & vv : obj.first->getVertices()){
251  vId = vv.getId();
252  dum->addVertex(obj.first->getVertexCoords(vId), cV);
253  //update map;
254  mapVloc[vId] = cV;
255  cV++;
256  }
257 
258  //start extracting/reversing cells of the current obj
259  for(const auto & cc : obj.first->getCells()){
260  cId = cc.getId();
261  PID = cc.getPID() + map_pidstart[obj.first];
262  eltype = cc.getType();
263  //get the local connectivity and update with new vertex numbering;
264  livector1D conn = obj.first->getCellConnectivity(cId);
265  livector1D connloc(conn.size());
266 
267  if(eltype == bitpit::ElementType::POLYGON){
268  std::size_t size = conn.size();
269  connloc[0] = conn[0];
270  for(std::size_t i = 1; i < size; ++i){
271  connloc[i] = mapVloc[conn[i]];
272  }
273 
274  }else if(eltype == bitpit::ElementType::POLYHEDRON){
275  connloc[0] = conn[0];
276  for(int nF = 0; nF < conn[0]-1; ++nF){
277  int facePos = cc.getFaceStreamPosition(nF);
278  int beginVertexPos = facePos + 1;
279  int endVertexPos = facePos + 1 + conn[facePos];
280  connloc[facePos] = conn[facePos];
281  for (int i=beginVertexPos; i<endVertexPos; ++i){
282  connloc[i] = mapVloc[conn[i]];
283  }
284  }
285  }else{
286  int ic = 0;
287  for (const auto & v : conn){
288  connloc[ic] = mapVloc[v];
289  ++ic;
290  }
291  }
292  dum->addConnectedCell(connloc, eltype, PID, cC);
293  //update map;
294  cC++;
295  }
296 
297  dum->resyncPID();
298  for(const auto & val: dum->getPIDTypeList()){
299  dum->setPIDName(val, originalPidNames[newOldPid[val]]);
300  }
301  }
302  }//scope for optional vars;
303 
304  m_patch = dum;
305  m_patch->cleanGeometry();
306 
307  m_patch->update();
308 
309 }
310 
316 void StitchGeometry::absorbSectionXML(const bitpit::Config::Section & slotXML, std::string name){
317 
318  BITPIT_UNUSED(name);
319 
320  std::string input;
321 
322  //checking topology
323  if(slotXML.hasOption("Topology")){
324  std::string input = slotXML.get("Topology");
325  input = bitpit::utils::string::trim(input);
326  int temptop = -1;
327  if(!input.empty()){
328  std::stringstream ss(input);
329  ss>>temptop;
330  }
331  if(m_topo != temptop){
332  (*m_log)<<"Error in "<<m_name<<" : class Topology parameter mismatch from what is read in XML input"<<std::endl;
333  throw std::runtime_error(m_name + " : xml absorbing failed");
334  }
335  }
336 
337  BaseManipulation::absorbSectionXML(slotXML, name);
338 
339 
340  if(slotXML.hasOption("RePID")){
341  std::string input = slotXML.get("RePID");
342  input = bitpit::utils::string::trim(input);
343  bool temp = false;
344  if(!input.empty()){
345  std::stringstream ss(input);
346  ss>>temp;
347  }
348  forceRePID(temp);
349  }
350 
351 
352 };
353 
359 void StitchGeometry::flushSectionXML(bitpit::Config::Section & slotXML, std::string name){
360 
361  BITPIT_UNUSED(name);
362 
363  BaseManipulation::flushSectionXML(slotXML, name);
364  slotXML.set("Topology", m_topo);
365  slotXML.set("RePID", std::to_string(int(m_repid)));
366 
367 };
368 
372 void
374 
375  write(getGeometry());
376 
377 }
378 
379 }
MimmoObject is the basic geometry container for mimmo library.
#define M_GEOM
std::vector< long > livector1D
void warningXML(bitpit::Logger *log, std::string name)
void forceRePID(bool flag)
mimmo::MimmoSharedPointer< MimmoObject > getGeometry()
BaseManipulation is the base class of any manipulation object of the library.
StitchGeometry & operator=(StitchGeometry other)
void write(MimmoSharedPointer< MimmoObject > geometry)
virtual void absorbSectionXML(const bitpit::Config::Section &slotXML, std::string name="")
void addGeometry(mimmo::MimmoSharedPointer< MimmoObject > geo)
virtual void flushSectionXML(bitpit::Config::Section &slotXML, std::string name="")
virtual void absorbSectionXML(const bitpit::Config::Section &slotXML, std::string name="")
StitchGeometry is an executable block class capable of stitch multiple MimmoObject geometries of the ...
void swap(StitchGeometry &x) noexcept
MimmoSharedPointer is a custom implementation of shared pointer.
void swap(BaseManipulation &x) noexcept
virtual void flushSectionXML(bitpit::Config::Section &slotXML, std::string name="")