G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsHBoxContainer.hpp
Go to the documentation of this file.
1 
14 #pragma once
15 
16 #include <gsIO/gsXml.h>
17 
18 namespace gismo
19 {
20 
21 template <short_t d, class T>
22 gsHBoxContainer<d, T>::gsHBoxContainer()
23 :
24 m_NHtype(gsHNeighborhood::None)
25 { }
26 
27 template <short_t d, class T>
28 gsHBoxContainer<d, T>::gsHBoxContainer(const gsHBox<d,T> & box)
29 {
30  this->_makeLevel(box.level());
31  m_boxes[box.level()].push_back(box);
32 }
33 
42 template <short_t d, class T>
44 {
45  for (cIterator it=boxes.begin(); it!=boxes.end(); it++)
46  {
47  this->_makeLevel(it->level());
48  m_boxes[it->level()].push_back(*it);
49  }
50 
51  m_NHtype = boxes.size()!=0 ? gsHBoxUtils<d,T>::neighborhoodType(boxes.front()) : gsHNeighborhood::None;
52 }
53 
54 template <short_t d, class T>
55 gsHBoxContainer<d, T>::gsHBoxContainer(const HContainer & boxes)
56 {
57  if (_check(boxes)) // if the container is well-defined
58  {
59  m_boxes = boxes;
60  }
61  else
62  {
63  for (cHIterator hit = boxes.begin(); hit!=boxes.end(); hit++)
64  {
65  for (cIterator it = hit->begin(); it!=hit->end(); it++)
66  {
67  this->_makeLevel(it->level());
68  m_boxes[it->level()].push_back(*it);
69  }
70  }
71 
72  // Find the basis type of the neighborhood in the first non-empty level
73  m_NHtype = gsHNeighborhood::None;
74  for (cHIterator hit = boxes.begin(); hit!=boxes.end(); hit++)
75  {
76  if (hit->size()!=0)
77  {
78  m_NHtype = gsHBoxUtils<d,T>::neighborhoodType(hit->front());
79  break;
80  }
81  }
82  }
83 }
84 
85 template <short_t d, class T>
87 {
88  std::function<size_t(const size_t &, const Container &)> size_sum = [](const size_t & sum, const Container & a)
89  {
90  return sum+a.size();
91  };
92  return std::accumulate(m_boxes.begin(), m_boxes.end(), 0, size_sum);
93 }
94 
95 template <short_t d, class T>
97 {
98  for (HIterator hit = m_boxes.begin(); hit!=m_boxes.end(); hit++)
99  hit->clear();
100  m_boxes.clear();
101 }
102 
109 template <short_t d, class T>
110 bool gsHBoxContainer<d, T>::_check(const HContainer & boxes)
111 {
112  bool result = true;
113  for (size_t l = 0; l!=boxes.size(); l++)
114  for (cIterator it = boxes[l].begin(); it!=boxes[l].end(); it++)
115  result &= ( (size_t) it->level()==l);
116  return result;
117 }
118 
119 
120 template <short_t d, class T>
122 {
123  this->_makeLevel(box.level());
124  m_boxes[box.level()].push_back(box);
125 
126  if (m_NHtype==gsHNeighborhood::None)
127  m_NHtype = gsHBoxUtils<d,T>::neighborhoodType(box);
128 }
129 
130 template <short_t d, class T>
131 void gsHBoxContainer<d, T>::add(const Container & boxes)
132 {
133  for (cIterator it = boxes.begin(); it!=boxes.end(); it++)
134  this->add(*it);
135 }
136 
137 template <short_t d, class T>
138 void gsHBoxContainer<d, T>::add(const HContainer & boxes)
139 {
140  for (cHIterator hit = boxes.begin(); hit!=boxes.end(); hit++)
141  this->add(*hit);
142 }
143 
144 template <short_t d, class T>
146 {
147  this->add(boxes.boxes());
148 }
149 
150 template <short_t d, class T>
152 {
153  gsHBoxContainer<d,T> result;
154  for (cHIterator hit = m_boxes.begin(); hit!=m_boxes.end(); hit++)
155  for (cIterator it = hit->begin(); it!=hit->end(); it++)
156  if (it->patch()==patchID || it->patch()==-1)
157  result.add(*it);
158  return result;
159 }
160 
161 // template <short_t d, class T>
162 // gsHBoxContainer<d,T> gsHBoxContainer<d, T>::_boxUnion(const gsHBoxContainer<d,T> & other) const
163 // {
164 // return _boxUnion(*this,other);
165 // }
166 
167 // template <short_t d, class T>
168 // gsHBoxContainer<d,T> gsHBoxContainer<d, T>::_boxUnion(const gsHBoxContainer<d,T> & container1, const gsHBoxContainer<d,T> & container2) const
169 // {
170 // HContainer result;
171 // HContainer region1(container1.boxes());
172 // HContainer region2(container2.boxes());
173 
174 // index_t lmax = std::max(region1.size(),region2.size());
175 // region1.resize(lmax);
176 // region2.resize(lmax);
177 // result.resize(lmax);
178 
179 // for (index_t l = 0; l!=lmax; l++)
180 // result[l] = __boxUnion(region1[l],region2[l]);
181 
182 // return gsHBoxContainer<d,T>(result);
183 // }
184 
185 // template <short_t d, class T>
186 // typename gsHBoxContainer<d,T>::HContainer gsHBoxContainer<d, T>::_boxUnion(const HContainer & container1, const HContainer & container2) const
187 // {
188 // HContainer result, region1, region2;
189 
190 // region1 = container1;
191 // region2 = container2;
192 
193 // index_t lmax = std::max(region1.size(),region2.size());
194 // region1.resize(lmax);
195 // region2.resize(lmax);
196 // result.resize(lmax);
197 
198 // for (index_t l = 0; l!=lmax; l++)
199 // result[l] = __boxUnion(region1[l],region2[l]);
200 
201 // return result;
202 // }
203 
204 // template <short_t d, class T>
205 // typename gsHBoxContainer<d, T>::Container gsHBoxContainer<d, T>::__boxUnion(const Container & container1, const Container & container2) const
206 // {
207 // // SortedContainer sortedResult;
208 
209 // // SortedContainer scontainer1 = gsHBoxUtils<d,T>::Sort(container1);
210 // // SortedContainer scontainer2 = gsHBoxUtils<d,T>::Sort(container2);
211 
212 // // sortedResult.reserve(scontainer1.size() + scontainer2.size());
213 // // if (scontainer1.size()!=0 && scontainer2.size()!=0)
214 // // {
215 // // std::set_union( scontainer1.begin(),scontainer1.end(),
216 // // scontainer2.begin(),scontainer2.end(),
217 // // std::inserter(sortedResult,sortedResult.begin()),
218 // // gsHBoxCompare<d,T>());
219 // // }
220 // // else if (scontainer1.size()!=0 && container2.size()==0)
221 // // sortedResult.insert(sortedResult.end(),scontainer1.begin(),scontainer1.end());
222 // // else if (scontainer1.size()==0 && container2.size()!=0)
223 // // sortedResult.insert(sortedResult.end(),scontainer2.begin(),scontainer2.end());
224 // // else { /* Do nothing */ }
225 
226 // Container result = gsHBoxUtils<d,T>::Union(container1,container2);
227 
228 // return result;
229 // }
230 
231 // template <short_t d, class T>
232 // void gsHBoxContainer<d, T>::makeUnique()
233 // {
234 // auto comp = [](const gsHBox<d,T> & a, const gsHBox<d,T> & b)
235 // {
236 // return a.isSame(b);
237 // };
238 
239 // std::unique( this->begin(),this->end(),comp);
240 // }
241 
242 
243 // template <short_t d, class T>
244 // typename gsHBoxContainer<d, T>::Container & gsHBoxContainer<d, T>::getActives() const
245 // {
246 // HContainer boxes(m_boxes.size());
247 // for (index_t lvl = 0; lvl != m_boxes.size(); lvl++)
248 // boxes[lvl] = this->getActivesOnLevel(lvl);
249 
250 // return boxes;
251 // }
252 
253 // template <short_t d, class T>
254 // void gsHBoxContainer<d, T>::filterActives()
255 // {
256 // m_boxes = getActives();
257 // }
258 
259 // template <short_t d, class T>
260 // typename gsHBoxContainer<d, T>::Container & gsHBoxContainer<d, T>::getActivesOnLevel(index_t lvl) const
261 // {
262 // Container boxes;
263 // for (cIterator it=m_boxes[lvl].begin(); it!=m_boxes[lvl].end(); it++)
264 // if (it->isActive())
265 // boxes.push_back(*it);
266 
267 // return boxes;
268 // }
269 
270 
271 template <short_t d, class T>
272 typename gsHBoxContainer<d, T>::Container & gsHBoxContainer<d, T>::getActivesOnLevel(index_t lvl)
273 {
274  return m_boxes[lvl];
275 }
276 
277 template <short_t d, class T>
278 const typename gsHBoxContainer<d, T>::Container & gsHBoxContainer<d, T>::getActivesOnLevel(index_t lvl) const
279 {
280  return m_boxes[lvl];
281 }
282 
283 template <short_t d, class T>
284 typename gsHBoxContainer<d, T>::Container gsHBoxContainer<d, T>::getParents() const
285 {
286  Container result;
287  // result.reserve(this->boxes().size()-1);
288 
289  // Handle level 0 separately (operation cannot be performed on level 0)
290  GISMO_ASSERT(m_boxes[0].size()==0,"Boxes at level 0 cannot have a parent. Did something go wrong? You can run check() to see if the boxes are allocated coorectly");
291 
292  for (cHIterator hit = std::next(m_boxes.begin()); hit!=m_boxes.end(); hit++)
293  for (cIterator it=hit->begin(); it!=hit->end(); it++)
294  result.push_back(it->getParent());
295 
296  return result;
297 }
298 
299 template <short_t d, class T>
300 typename gsHBoxContainer<d, T>::Container gsHBoxContainer<d, T>::getChildren() const
301 {
302  Container result, children;
303 
304  for (cHIterator hit = m_boxes.begin(); hit!=m_boxes.end(); hit++)
305  for (cIterator it=hit->begin(); it!=hit->end(); it++)
306  {
307  children = it->getChildren();
308  for (cIterator cit=children.begin(); cit!=children.end(); cit++)
309  result.push_back(*cit);
310  }
311 
312  return result;
313 }
314 
315 template <short_t d, class T>
317 {
318  m_boxes = gsHBoxUtils<d,T>::markTadmissible(m_boxes,m);
319 }
320 
321 template <short_t d, class T>
323 {
324  m_boxes = gsHBoxUtils<d,T>::markHadmissible(m_boxes,m);
325 }
326 
327 template <short_t d, class T>
329 {
330  if (m_NHtype==gsHNeighborhood::T)
331  m_boxes = gsHBoxUtils<d,T>::markTadmissible(m_boxes,m);
332  else if (m_NHtype==gsHNeighborhood::H)
333  m_boxes = gsHBoxUtils<d,T>::markHadmissible(m_boxes,m);
334  else
335  GISMO_ERROR("Neighborhood type not understood");
336 }
337 
338 template <short_t d, class T>
340 {
341  if (m_boxes.size() < static_cast<unsigned>(lvl + 1))
342  m_boxes.resize(lvl+1);
343 }
344 
345 template <short_t d, class T>
346 std::ostream& gsHBoxContainer<d, T>::print( std::ostream& os ) const
347 {
348  for (cHIterator hit = m_boxes.begin(); hit!=m_boxes.end(); hit++)
349  for (cIterator it = hit->begin(); it!=hit->end(); it++)
350  os<<*it<<"\n";
351  return os;
352 }
353 
354 template <short_t d, class T>
355 typename gsHBoxContainer<d,T>::RefBox gsHBoxContainer<d, T>::toBoxes(const index_t patchID) const
356 {
357  size_t N = this->totalSize();
358  RefBox result;
359  result.reserve(( N * (2*d+1) ));
360  RefBox box;
361  gsHBoxContainer<d,T> patchBoxes = this->patch(patchID);
362  for (cHIterator hit = patchBoxes.begin(); hit!=patchBoxes.end(); hit++)
363  for (cIterator it = hit->begin(); it!=hit->end(); it++)
364  {
365  box = it->toBox();
366  for (typename RefBox::const_iterator boxIt = box.begin(); boxIt != box.end(); boxIt++)
367  result.push_back(*boxIt);
368  }
369 
370  return result;
371 }
372 
373 template <short_t d, class T>
374 typename gsHBoxContainer<d,T>::RefBox gsHBoxContainer<d, T>::toRefBoxes(const index_t patchID) const
375 {
376  gsHBoxContainer<d,T> patchBoxes = this->patch(patchID);
377  size_t N = patchBoxes.totalSize();
378  RefBox result;
379  result.reserve(( N * (2*d+1) ));
380  RefBox box;
381  for (cHIterator hit = patchBoxes.begin(); hit!=patchBoxes.end(); hit++)
382  for (cIterator it = hit->begin(); it!=hit->end(); it++)
383  {
384  box = it->toRefBox();
385  for (typename RefBox::const_iterator boxIt = box.begin(); boxIt != box.end(); boxIt++)
386  result.push_back(*boxIt);
387  }
388 
389  return result;
390 }
391 
392 template <short_t d, class T>
393 typename gsHBoxContainer<d,T>::RefBox gsHBoxContainer<d, T>::toCrsBoxes(const index_t patchID) const
394 {
395  gsHBoxContainer<d,T> patchBoxes = this->patch(patchID);
396  size_t N = patchBoxes.totalSize();
397  RefBox result;
398  result.reserve(( N * (2*d+1) ));
399  RefBox box;
400  for (cHIterator hit = patchBoxes.begin(); hit!=patchBoxes.end(); hit++)
401  for (cIterator it = hit->begin(); it!=hit->end(); it++)
402  {
403  box = it->toCrsBox();
404  for (typename RefBox::const_iterator boxIt = box.begin(); boxIt != box.end(); boxIt++)
405  result.push_back(*boxIt);
406  }
407 
408  return result;
409 }
410 
411 template <short_t d, class T>
413 {
414  gsHBoxContainer<d,T> patchBoxes = this->patch(patchID);
415  size_t N = patchBoxes.totalSize();
416  gsMatrix<T> boxes(d,2*N);
417  index_t boxCount = 0;
418  for (HIterator hit = patchBoxes.begin(); hit!=patchBoxes.end(); hit++)
419  for (Iterator it = hit->begin(); it!=hit->end(); it++)
420  {
421  boxes.block(0,2*boxCount,d,2) = it->getCoordinates();
422  boxCount++;
423  }
424 
425  return boxes;
426 }
427 
428 template <short_t d, class T>
430 {
431  this->m_boxes = this->toUnitHBoxes();
432 }
433 
434 namespace internal
435 {
436 
438 template<short_t d, class T>
439 class gsXml< gsHBoxContainer<d,T> >
440 {
441 private:
442  gsXml() { }
443  typedef gsHBoxContainer<d,T> Object;
444 public:
445  GSXML_COMMON_FUNCTIONS(Object);
446  static std::string tag () { return "HBoxContainer"; }
447  static std::string type () { return "HBoxContainer"+std::to_string(d); }
448 
449  GSXML_GET_POINTER(Object);
450 
451  static void get_into (gsXmlNode * node, Object & obj)
452  {
453  gsXmlNode * boxNode;
454  for (boxNode = node->first_node("HBox");
455  boxNode; boxNode = boxNode->next_sibling("HBox"))
456  {
457  gsHBox<d,T> * box = gsXml<gsHBox<d,T> >::get(boxNode);
458  obj.add(*box);
459  }
460  }
461 
462  static gsXmlNode * put (const Object & obj,
463  gsXmlTree & data )
464  {
465  gsXmlNode * container = makeNode("HBoxContainer", data);
466  container->append_attribute( makeAttribute("type",internal::gsXml<Object>::type().c_str(), data) );
467  container->append_attribute(makeAttribute("size", obj.totalSize(), data));
468 
469  for (typename Object::cHIterator hit = obj.cbegin(); hit!=obj.cend(); hit++)
470  for (typename Object::cIterator it = hit->begin(); it!=hit->end(); it++)
471  {
472  gsXmlNode * box = gsXml< gsHBox<d,T> >::put(*it,data);
473  container->append_node(box);
474  }
475  return container;
476  }
477 };
478 
479 } // internal
480 
481 } // namespace gismo
size_t size(index_t level) const
Returns the size of the container on level.
Definition: gsHBoxContainer.h:68
This class provides a Hierarchical Box (gsHBox)
Definition: gsHBox.h:54
index_t level() const
Gets the level of the object.
Definition: gsHBox.hpp:287
#define index_t
Definition: gsConfig.h:32
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
HContainer & boxes()
Returns a heirarchical container with the boxes stored in the container.
Definition: gsHBoxContainer.h:123
The Hierarchical Box Container provides a container for gsHBox objects.
Definition: gsHBoxContainer.h:39
size_t totalSize() const
Returns the total number of boxes.
Definition: gsHBoxContainer.hpp:86
std::string to_string(const unsigned &i)
Helper to convert small unsigned to string.
Definition: gsXml.cpp:74
gsXmlAttribute * makeAttribute(const std::string &name, const std::string &value, gsXmlTree &data)
Helper to allocate XML attribute.
Definition: gsXml.cpp:37
void add(const gsHBox< d, T > &box)
Adds a single box.
Definition: gsHBoxContainer.hpp:121
gsXmlNode * makeNode(const std::string &name, gsXmlTree &data)
Helper to allocate XML node.
Definition: gsXml.cpp:54
gsHNeighborhood
The gsHNeighborhood is a struct that classifies the type of admissible refinement.
Definition: gsHBoxUtils.h:25
Container getChildren() const
Gives a hierarchical container with all the children of the boxes stored in this. ...
Definition: gsHBoxContainer.hpp:300
#define GISMO_ERROR(message)
Definition: gsDebug.h:118
The gsHBoxUtils provide basic utilities to modify HBoxes.
Definition: gsHBoxUtils.h:45
Provides declaration of input/output XML utilities struct.