Class documentation of Concepts

Loading...
Searching...
No Matches
domainDecomp.hh
Go to the documentation of this file.
1
6#ifndef spcDomainDecomp_hh
7#define spcDomainDecomp_hh
8
9#include "basics/debug.hh"
11#include "geometry/cellConditions.hh"
12#include "geometry/mesh.hh"
13#include "space/space.hh"
14#include "space/spaceSet.hh"
15#include "toolbox/hashMap.hh"
17#include "toolbox/sequence.hh"
18#include "toolbox/set.hh"
19
20#define DDSpaceConstr_D 0
21#define DDSpaceDestr_D 0
22#define DDSpaceRebuild_D 0
23#define DDSpaceGetIndices_D 0
24#define DDSpaceInfoIndices_D 0
25
26namespace concepts {
27
28 // *************************************************************** DDSpace **
29
30 template<class F>
31 class DDSpace : public Space<F> {
32 public:
35 virtual ~DDSpace() {}
37 const uint domains() const { return domains_; }
39 virtual const Space<F>& space(uint i) const = 0;
41 virtual const Set<IndexRange> indicesI(uint i) const = 0;
43// virtual const Sequence<Set<IndexRange> >& indicesI() const {
44// return indicesI_; }
46 virtual const Set<IndexRange> indicesB(uint i) const = 0;
48// virtual const Sequence<Set<IndexRange> >& indicesB() const {
49// return indicesB_; }
50 protected:
51 virtual std::ostream& info(std::ostream& os) const;
52
57 };
58
59 template<class F>
60 std::ostream& DDSpace<F>::info(std::ostream& os) const {
61 return os << "DDSpace(" << domains_ << " domains)";
62 }
63
64 // ********************************************************** DomainDecomp **
65
71 template<class F>
72 class DomainDecomp : public DDSpace<typename F::t_type>, public Subspace {
73 public:
80
92 template<class G>
94 BoundaryConditions* bc = 0, CellConditions* cc = 0,
95 uint spcNo = 0, uint* offset = 0);
96 virtual ~DomainDecomp();
97
99 void rebuild();
107 bool available() const;
108
109 inline virtual uint dim() const;
110 inline virtual uint nelm() const;
111 inline virtual Scan* scan() const;
112// inline Scan* scan();
113
115 virtual uint& lastIdx();
117 virtual uint offset() const;
119 virtual const F& space(uint i) const;
120 F& space(uint i);
122 virtual const Set<IndexRange> indicesI(uint i) const;
123// const Sequence<Set<IndexRange> >& indicesI() const { return indicesI_; }
125 virtual const Set<IndexRange> indicesB(uint i) const;
126// const Sequence<Set<IndexRange> >& indicesB() const { return indicesB_; }
127 protected:
128 virtual std::ostream& info(std::ostream& os) const;
129 private:
134 uint spcNo_;
136 Sequence<F*> spaces_;
138 Array<uint> spcBuild_;
141
143 HashMap<uint> attrToDomain_;
144
152 uint nelm_;
153
154 uint idx_;
155
156 template<class G, class H>
157 void getIndices_(const G& prebuild, const H& cntr,
158 Set<IndexRange>& indices);
159 };
160
161 template<class F>
162 template<class G>
165 uint spcNo, uint* offset) :
166 DDSpace<typename F::t_type>(), spcNo_(spcNo), spcBuild_(0),
167 elm_(0), nelm_(0) {
168 // collect all attributes of coarse mesh
169 Set<uint> attributes, tmp;
170 std::unique_ptr<concepts::Scan2> sc(prebuild.mesh().scan());
171 while (*sc) {
172 const Attribute& attr = (*sc)++.connector().attrib();
173 if (!cc || ((*cc)(attr).type() != CellCondition::INACTIVE))
174 attributes.insert(attr);
175 }
176 tmp = attributes;
177 DEBUGL(DDSpaceConstr_D, "attributes in mesh = " << attributes);
178
179
180 // collect all attributes and delete empty domains
181 Sequence<Set<uint> >::iterator i = domains.begin();
182 for (; i != domains.end(); ) {
183 // set difference with valid attributes
184 Set<uint> nonvalid = *i - tmp;
185 // there are only valid attributes given
186 conceptsAssert3(nonvalid.empty(), Assertion(), "non valid attributes " <<
187 nonvalid << " in given domain " << *i);
188
189 if ((*i).empty())
190 i = domains.erase(i); // delete empty domain
191 else {
192 // contribute to mapping from attribute to domain
193 for(Set<uint>::const_iterator j = (*i).begin(); j != (*i).end(); ++j)
194 attrToDomain_[*j] = this->domains_;
195 tmp = tmp - *i++; // erase attributes from set
196 ++this->domains_; // count non-empty domains
197 }
198 }
199
200 // rest of attributes to a new domain
201 if (!tmp.empty()) {
202 domains.push_back(tmp);
203 // contribute to mapping from attribute to domain
204 for(Set<uint>::const_iterator j = tmp.begin(); j != tmp.end(); ++j)
205 attrToDomain_[*j] = this->domains_;
206 ++this->domains_;
207 }
208
209 DEBUGL(DDSpaceConstr_D, "domains = " << domains);
210
211 // set the number of builds to zero
212 spcBuild_.resize(this->domains_);
213 spcBuild_.zeros();
214
215 i = domains.begin();
216 for (; i != domains.end(); ) {
217
218 // create for each domain a entrance
219 cc_.insert(cc_.end(), this->domains_, CellConditions());
220
221 i = domains.begin();
222 for (Sequence<CellConditions>::iterator j = cc_.begin(); j != cc_.end();
223 ++j, ++i) {
224 // set difference with valid attributes
225 const Set<uint> nonactiv = attributes - *i;
226 for (Set<uint>::const_iterator k = nonactiv.begin();
227 k != nonactiv.end(); ++k)
228 (*j).add(*k, CellCondition::INACTIVE);
229 }
230 }
231 DEBUGL(DDSpaceConstr_D, "cell conditions of domains = " << cc_);
232
233 // create spaces
234 uint* idx = 0;
235 F* spc;
236 for (Sequence<CellConditions>::iterator j = cc_.begin(); j != cc_.end(); ++j)
237 {
238 spaces_.push_back(spc = new F(prebuild, bc, &*j, spcNo_, offset, idx));
239 idx = &spc->lastIdx();
240 }
241 DEBUGL(DDSpaceConstr_D, "spaces of domains = " << spaces_);
242
243 // reserve space for index sets for each sub domains
244 this->indicesI_.resize(this->domains_, Set<IndexRange>());
245 this->indicesB_.resize(this->domains_, Set<IndexRange>());
246 }
247
248 template<class F>
250 // deletes in reverse order, because the first space holds the
251 // pointer to the index
252 uint k = this->domains();
253 typename Sequence<F*>::reverse_iterator i = spaces_.rbegin();
254 for (; i != spaces_.rend(); ++i) {
255 DEBUGL(DDSpaceDestr_D, "Try to delete Space(" << k-- << ") = " << **i);
256 delete *i;
257 }
259 DEBUGL(DDSpaceDestr_D, "done");
260 }
261
262 template<class F>
263 std::ostream& DomainDecomp<F>::info(std::ostream& os) const {
264 os << "DomainDecomp(" << this->domains_ << " domains, ";
265 if (!available())
266 os << "not built";
267 else {
268 os << "dim = " << dim() << ", nelm = " << nelm() << ", ";
269 for (uint i = 0; i < spaces_.size();) {
270 os << "space(" << i << ") = " << space(i);
271#if DDSpaceInfoIndices_D
272 os << ", I(" << i << ") = " << indicesI(i)
273 << ", B(" << i << ") = " << indicesB(i);
274#else
275 os << ", I(" << i << ").dim = " << indicesI(i).dim()
276 << ", B(" << i << ").dim = " << indicesB(i).dim();
277#endif
278 if (++i < spaces_.size()) os << ", ";
279 }
280 }
281 return os << ")";
282 }
283
284 template<class F>
286 DEBUGL(DDSpaceRebuild_D, "Start rebuilding");
287 // If nothing to do, do nothing
288 if (available()) {
289 DEBUGL(DDSpaceRebuild_D, "space already built - nothing to do");
290 return;
291 }
292
293 // Remove old list, but not elements. They are removed in spaces
294 // itself.
296 nelm_ = 0;
297
298 // Rebuild all spaces, but don't refresh own array of all
299 // elements. That is done in method scan(), because the
300 // rebuild()-method of the spaces could be called also directly.
301 uint k = 0;
302 typename Sequence<F*>::iterator i = spaces_.begin();
303 // reset the index counter (identical for all spaces/domains)
304 (*i)->lastIdx() = (*i)->offset();
305 // clear all indices
306 (*i)->prebuild().clearAllIndices(spcNo_);
307 uint* b = spcBuild_;
308 for (; i != spaces_.end(); ++i) {
309 (*i)->rebuild(true);
310 DEBUGL(DDSpaceRebuild_D, "Space(" << k++ << ") = " << **i);
311 // space should be available now
312 conceptsAssert((*i)->available().first, Assertion());
313 // memorize number of the build
314 *b++ = (*i)->available().second;
315 conceptsAssert(nelm_ == 0 || (*i)->nelm() == nelm_, Assertion());
316 nelm_ = (*i)->nelm();
317 DEBUGL(DDSpaceRebuild_D, "nelm = " << nelm_);
318 }
319
320 // fill list of elements
321 uint j = 0;
322 std::unique_ptr<typename Space<typename F::t_type>::Scanner> sc(nullptr);
323 for (i = spaces_.begin(); i != spaces_.end(); ++i) {
324 sc.reset((*i)->scan());
325 while (*sc) {
326 Element* elm = &(*sc)++;
327 DEBUGL(DDSpaceRebuild_D, "Element = " << elm);
328 DEBUGL(DDSpaceRebuild_D, "Element = " << *elm);
329 if (elm->T().n() > 0) {
330 DEBUGL(DDSpaceRebuild_D, "Element(" << j << ") = " << *elm);
331 elm_ = new concepts::Joiner<Element*, 1>(elm, elm_);
332 ++j;
333 }
334 }
335 }
336 conceptsAssert(j == nelm_, Assertion());
337
338 for(uint j = 0; j < this->domains_; ++j) {
339 this->indicesI_[j].clear();
340 this->indicesB_[j].clear();
341 }
342
343 // collect all index ranges into this set to determine if a index
344 // range occurs at least two times
345 Set<IndexRange> indices;
346 std::unique_ptr<concepts::Scan2> se(spaces_[0]->prebuild().mesh().scan());
347 while (*se)
348 getIndices_(spaces_[0]->prebuild(), (*se)++.connector(), indices);
349
350#if DDSpaceRebuild_D
351 for(uint j = 0; j < this->domains_; ++j) {
352 DEBUGL(1, "indicesI_[" << j << "] = " << this->indicesI_[j]);
353 DEBUGL(1, "indicesB_[" << j << "] = " << this->indicesB_[j]);
354 }
355
356 i = spaces_.begin(); k = 0;
357 for (; i != spaces_.end(); ++i)
358 DEBUGL(1, "Space(" << k++ << ") = " << **i);
359#endif
360 }
361
362 template<class F>
364// uint build;
365 const uint* b = spcBuild_;
366 typename Sequence<F*>::const_iterator i = spaces_.begin();
367 while(i != spaces_.end() && (*i)->available().first &&
368 (*i)->available().second == *b++) ++i;
369 return i == spaces_.end();
370 }
371
372 template<class F>
374 if (!available())
376 // dimension is for the spaces of all domains the same, they live
377 // on the same index range
378 return (*spaces_.begin())->dim();
379 }
380
381 template<class F>
383 if (!available())
385 return nelm_;
386 }
387
388 template<class F>
390 if (!available())
392 return new concepts::PListScan<Element>(*elm_);
393 }
394
395 template<class F>
397 return (*spaces_.begin())->lastIdx();
398 }
399
400 template<class F>
402 return (*spaces_.begin())->offset();
403 }
404
405 template<class F>
406 const F& DomainDecomp<F>::space(uint i) const {
408 return *spaces_[i];
409 }
410
411 template<class F>
414 return *spaces_[i];
415 }
416
417 template<class F>
420 if (!available())
422 return this->indicesI_[i];
423 }
424
425 template<class F>
428 if (!available())
430 return this->indicesB_[i];
431 }
432
433 template<class F>
434 template<class G, class H>
435 void DomainDecomp<F>::getIndices_(const G& prebuild, const H& cntr,
436 Set<IndexRange>& indices)
437 {
438 DEBUGL(DDSpaceGetIndices_D, "cntr = " << cntr);
439 HashMap<uint>::const_iterator i = attrToDomain_.find(cntr.attrib());
440 conceptsAssert(i != attrToDomain_.end(), Assertion());
441 // domain
442 uint d = i->second;
443 DEBUGL(DDSpaceGetIndices_D, "domain = " << d);
444
445 Set<IndexRange> &indicesB = this->indicesB_[d],
446 &indicesI = this->indicesI_[d];
447
448 uint dim = 0;
449 try {
450 while(1) {
451 // Index ranges of this cell of entities of dimension dim.
452 // Throws an exception if dimension is to high and leaves the
453 // while loop.
454 const Set<IndexRange> idx = prebuild.indices(dim, cntr, spcNo_);
455 if (!idx.empty()) {
456 DEBUGL(DDSpaceGetIndices_D,
457 cntr.key() << " - dim = " << dim << ", idx = " << idx);
458 DEBUGL(DDSpaceGetIndices_D, "indices = " << indices);
459 // Indices, which occur first time or lie the interior this domain.
460 Set<IndexRange> recent = idx - (indices - indicesI);
461 // already occured indices
463 DEBUGL(DDSpaceGetIndices_D,
464 "recent = " << recent << ", occured = " << occured);
465 if (!occured.empty()) {
466 // its on the boundary of this domain
467 indicesB = indicesB || occured;
468 DEBUGL(DDSpaceGetIndices_D, "indicesB = " << indicesB);
469 // Delete it from index set inside other domains, could be
470 // counted there
471 for(uint j = 0; j < this->domains_; ++j)
472 if (j != d) {
473 Set<IndexRange> occuredDomain = occured && this->indicesI_[j];
474 this->indicesI_[j] = this->indicesI_[j] - occuredDomain;
475 this->indicesB_[j] = this->indicesB_[j] || occuredDomain;
476 }
477 }
478 if (!recent.empty()) {
479 indicesI = indicesI || recent;
480 DEBUGL(DDSpaceGetIndices_D, "indicesI = " << indicesI);
481 }
482 indices = indices || idx;
483 // set difference with index ranges at boundary are inside domain
484 DEBUGL(DDSpaceGetIndices_D,
485 "indicesI_[" << d << "] = " << this->indicesI_[d]);
486 DEBUGL(DDSpaceGetIndices_D,
487 "indicesB_[" << d << "] = " << this->indicesB_[d]);
488 } // idx not empty
489 ++dim;
490 DEBUGL(DDSpaceGetIndices_D, "dim = " << dim);
491 } // while (1)
492 }
493 catch (concepts::MissingFeature& e) {}
494
495 DEBUGL(DDSpaceGetIndices_D, "done for " << cntr);
496 const H* chld = 0;
497 for(uint j = 0; (chld = cntr.child(j)) != 0; ++j)
498 getIndices_(prebuild, *chld, indices);
499 }
500
501} // namespace concepts
502
503#endif
#define conceptsException(exc)
void resize(const uint sz)
Definition array.hh:281
void zeros()
Fills the memory with zeros.
Definition array.hh:128
uint attrib() const
Returns the attribute.
Definition connector.hh:38
virtual const Set< IndexRange > indicesI(uint i) const =0
Returns index set for dof inside the i th domain.
Sequence< Set< IndexRange > > indicesI_
Index sets of dof inside and at the boundary for each domain/space.
uint domains_
Number of domains/spaces.
virtual const Space< F > & space(uint i) const =0
Returns space belonging to i th domain.
const uint domains() const
Returns number of domains/spaces.
virtual const Set< IndexRange > indicesB(uint i) const =0
Returns all index sets for dof inside each domain.
virtual std::ostream & info(std::ostream &os) const
Returns all index sets for dof at boundary of each domain.
DDSpace(uint domains=0)
Constructor.
virtual uint nelm() const
Returns the number of elements in the space.
void rebuild()
Rebuilds the spaces.
virtual uint & lastIdx()
Returns last global index of the space.
virtual std::ostream & info(std::ostream &os) const
Returns all index sets for dof at boundary of each domain.
virtual uint offset() const
Returns the offset, returns 0 if space is not a subspace or first one.
virtual const Set< IndexRange > indicesI(uint i) const
Returns index set for dof inside the i th domain.
concepts::Element< typename F::t_type > Element
virtual uint dim() const
Returns the dimension of the space.
DomainDecomp(G &prebuild, Sequence< Set< uint > > domains, BoundaryConditions *bc=0, CellConditions *cc=0, uint spcNo=0, uint *offset=0)
virtual const Set< IndexRange > indicesB(uint i) const
Returns index set for dof at the boundary the i th domain.
virtual const F & space(uint i) const
Returns space belonging to i th domain.
virtual Scan * scan() const
Returns a scanner to iterate over the elements of the space.
virtual const TMatrixBase< F > & T() const =0
Returns the T matrix of the element.
static void destructor(Joiner< T, nlnk > *&j, bool values=true)
#define conceptsAssert(cond, exc)
#define DEBUGL(doit, msg)
Definition debug.hh:40
#define conceptsAssert3(cond, exc, msg)
Set< F > makeSet(uint n, const F &first,...)
Definition set.hh:320