SheafSystem  0.0.0.0
mesh_partition.cc
1 
2 //
3 // Copyright (c) 2014 Limit Point Systems, Inc.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 
18 // Implementation for class mesh_partition
19 
20 #include "SheafSystem/mesh_partition.h"
21 
22 #include "SheafSystem/assert_contract.h"
23 #include "SheafSystem/base_space_member.h"
24 #include "SheafSystem/error_message.h"
25 #include "SheafSystem/hash_index_space_state.h"
26 #include "SheafSystem/id_block.h"
27 #include "SheafSystem/index_iterator.h"
28 #include "SheafSystem/preorder_iterator.h"
29 #include "SheafSystem/std_set.h"
30 #include "SheafSystem/std_sstream.h"
31 #include "SheafSystem/tern.h"
32 
33 
34 using namespace fiber_bundle; // Workaround for MS C++ bug.
35 
36 // =============================================================================
37 // MESH_PARTITION FACET
38 // =============================================================================
39 
43 {
44 
45  // Preconditions:
46 
47 
48  // Body:
49 
50  _part_ct = 0;
51  _mesh = 0;
52 
53  //$$SCRIBBLE: Adding a nonempty string to keep
54  // invariant() from blowing an assertion.
55 
56  _name = "unknown";
57 
58  // Postconditions:
59 
60  ensure(!name().empty());
61  ensure(invariant());
62  ensure(part_ct() == 0);
63 
64  // Exit:
65 
66  return;
67 }
68 
69 
73 {
74 
75  // Preconditions:
76 
77  // Body:
78 
79  (*this) = xother;
80 
81  // Postconditions:
82 
83  ensure(invariant());
84 
85  // Exit:
86 
87  return;
88 }
89 
93 {
94  // Preconditions:
95 
96 
97  // Body:
98 
99  _parts.detach_from_state();
100 
101  // Postconditions:
102 
103  // Exit:
104 
105  return;
106 }
107 
108 // NEW HANDLE, NEW STATE CONSTRUCTORS
109 
112 mesh_partition(const base_space_poset& xmesh, const std::string& xname)
113 {
114  // Preconditions:
115 
116  require(is_valid_name(xname));
117  require(xmesh.includes_subposet(xname) ?
118  xmesh.state_is_read_accessible() :
120 
121  // Body:
122 
123  bool old_xmesh_includes_mesh_partition_xname = xmesh.includes_subposet(xname);
124 
125  _mesh = const_cast<base_space_poset*>(&xmesh);
126  _name = xname;
127 
128 
129  initialize_parts_set();
130 
131  _part_ct = (old_xmesh_includes_mesh_partition_xname ? _parts.member_ct() : 0);
132 
133  // Postconditions:
134 
135  ensure(mesh().is_same_state(&xmesh));
136  ensure(name() == xname);
137  ensure(xmesh.includes_subposet(xname));
138  ensure(part_ct() == (old_xmesh_includes_mesh_partition_xname ? parts().member_ct() : 0));
139 
140 
141  return;
142 }
143 
144 
146 const std::string&
148 name() const
149 {
150  return _name;
151 }
152 
153 
157 mesh() const
158 {
159  return *_mesh;
160 }
161 
163 const sheaf::subposet&
165 parts() const
166 {
167  return _parts;
168 }
169 
171 int
173 part_ct() const
174 {
175  return _part_ct;
176 }
177 
178 
180 string
182 part_name(const scoped_index& xp_id) const
183 {
184  // Preconditions:
185 
186 
187  // Body:
188 
189  stringstream lstream;
190  lstream << _name << "::part_" << xp_id;
191 
192  // Postconditions:
193 
194 
195  // Exit:
196 
197  return lstream.str();
198 }
199 
200 
202 void
204 part(const scoped_index& xp_id, id_block& xresult) const
205 {
206  // Preconditions:
207 
208  require(mesh().state_is_read_accessible());
209  require(mesh().contains_member(part_name(xp_id)));
210  require(xresult.is_member_hub_id_space());
211 
212  // Body:
213 
214  xresult.set_ct(0);
215  xresult.reserve(1024); // Arbitrary, avoids many small reallocations.
216 
217  mesh_partition* cthis = const_cast<mesh_partition*>(this);
218  base_space_member lpart(cthis->_mesh, part_name(xp_id));
219  preorder_iterator litr(static_cast<abstract_poset_member&>(lpart), cthis->_mesh->elements(), DOWN, NOT_STRICT);
220  while(!litr.is_done())
221  {
222  xresult.push_back(litr.index());
223 
224  litr.truncate();
225  }
226 
227  lpart.detach_from_state();
228 
229  // Postconditions:
230 
231 
232  // Exit:
233 
234  return;
235 }
236 
238 const sheaf::scoped_index&
240 put_part(const scoped_index& xp_id, id_block& xzones)
241 {
242  // Preconditions:
243 
244  require(mesh().state_is_read_write_accessible());
245  require(!mesh().contains_member(part_name(xp_id)));
246  require(xzones.is_member_hub_id_space());
247 
248  require_for_all(i, 0, xzones.ct(), mesh().contains_member(xzones[i]));
249 
250  // Body:
251 
252  base_space_member lpart(_mesh, xzones.base(), xzones.ct(), tern::TRUE, false);
253 
254  lpart.put_name(part_name(xp_id), true, false);
255  const scoped_index& result = lpart.index();
256  _parts.insert_member(result);
257 
258  _parts.id_space().insert(xp_id, result);
259 
260  lpart.detach_from_state();
261 
262  // Postconditions:
263 
264  ensure(mesh().contains_member(result));
265  ensure(mesh().member_name(result) == part_name(xp_id));
266  ensure(parts().contains_member(result));
267 
268  // Exit:
269 
270  return result;
271 }
272 
273 
277 part_id(const std::string& xname) const
278 {
279  // Preconditions:
280 
281 
282  // Body:
283 
284  string::size_type lidx1;
285 
286  lidx1 = xname.find("::part_") + 7;
287  string lpart_id_str(xname.substr(lidx1));
288 
289  stringstream lstream(lpart_id_str);
290 
291  pod_index_type result;
292 
293  lstream >> result;
294 
295  // Postconditions:
296 
297 
298  // Exit:
299 
300  return result;
301 }
302 
303 
305 bool
307 is_valid_name(const std::string& xname)
308 {
309  bool result;
310 
311  // Preconditions:
312 
313 
314  // Body:
315 
316  result = (xname.find(name_prefix()) == 0);
317 
318  // Postconditions:
319 
320 
321  // Exit:
322 
323  return result;
324 }
325 
327 string
330 {
331 
332  // Preconditions:
333 
334 
335  // Body:
336 
337  string result(poset_path::reserved_prefix() + "p_");
338 
339  // Postconditions:
340 
341 
342  // Exit:
343 
344  return result;
345 }
346 
347 // =============================================================================
348 // ANY FACET
349 // =============================================================================
350 
352 bool
354 is_ancestor_of(const any* other) const
355 {
356 
357  // Preconditions:
358 
359  require(other != 0);
360 
361  // Body:
362 
363  // True if other conforms to this
364 
365  bool result = dynamic_cast<const mesh_partition*>(other) != 0;
366 
367  // Postconditions:
368 
369  return result;
370 }
371 
375 clone() const
376 {
377  mesh_partition* result;
378 
379  // Preconditions:
380 
381  // Body:
382 
383  result = new mesh_partition();
384 
385  // Postconditions:
386 
387  ensure(result != 0);
388  ensure(is_same_type(result));
389 
390  // Exit:
391 
392  return result;
393 }
394 
395 
399 operator=(const mesh_partition& xother)
400 {
401 
402  // Preconditions:
403 
404 
405  // Body:
406 
407  _name = xother._name;
408  _mesh = xother._mesh;
409  _parts = xother._parts;
410  _part_ct = xother._part_ct;
411 
412  // Postconditions:
413 
414  ensure(invariant());
415 
416  // Exit
417 
418  return *this;
419 }
420 
422 bool
424 invariant() const
425 {
426  bool result = true;
427 
428  if(invariant_check())
429  {
430  // Prevent recursive calls to invariant
431 
432  disable_invariant_check();
433 
434  // Must satisfy base class invariant
435 
436  invariance(any::invariant());
437 
438  // Invariances for this class:
439 
440  invariance(part_ct() >= 0);
441  invariance(!name().empty());
442 
443  // Finished, turn invariant checking back on.
444 
445  enable_invariant_check();
446  }
447 
448  // Exit
449 
450  return result;
451 }
452 
453 
454 
455 // =============================================================================
456 // PRIVATE MEMBER FUNCTIONS FACET
457 // =============================================================================
458 
460 void
461 fiber_bundle::mesh_partition::
462 initialize_parts_set()
463 {
464  // Preconditions:
465 
466  require(mesh().includes_subposet(name()) ?
467  mesh().state_is_read_accessible() :
468  mesh().state_is_read_write_accessible());
469 
470  // Body:
471 
472  if(mesh().includes_subposet(_name))
473  {
474  // Parts set already exists; just attach to it.
475 
476  _parts.attach_to_state(_mesh, _name);
477  }
478  else
479  {
480  // Parts set doesn't exist yet; create it.
481 
482  _parts.new_state(_mesh, true, false);
483  _parts.put_name(_name, true, false);
484  _parts.new_id_space("hash_index_space_state",
485  hash_index_space_state::make_arg_list(0));
486  }
487 
488 
489  // Postconditions:
490 
491  ensure(mesh().includes_subposet(name()));
492  ensure(parts().has_id_space());
493 
494  // Exit:
495 
496  return;
497 }
498 
499 // =============================================================================
500 // NON-MEMBER FUNCTIONS
501 // =============================================================================
502 
static bool is_valid_name(const std::string &xname)
True if xname is a valid decomposition name.
virtual bool invariant() const
Class invariant, intended to be redefined in each descendant. See below for template for invariant in...
Definition: any.cc:153
A client handle for a subposet.
Definition: subposet.h:86
size_type ct() const
The number of items currently in use.
mesh_partition()
Default constructor.
void part(const scoped_index &xp_id, id_block &xresult) const
The zones in the part with client id xp_id.
bool state_is_read_accessible() const
True if this is attached and if the state is accessible for read or access control is disabled...
virtual bool includes_subposet(pod_index_type xsubposet_hub_id, bool xauto_access=true) const
True if this poset includes subposet with hub id xsubposet_hub_id.
void reserve(index_type xub)
Makes ub() at least xub; if new storage is allocated, it is uninitialized.
const scoped_index & put_part(const scoped_index &xp_id, id_block &xzones)
Creates a part with client id xp_id containing zones xzones.
A decomposition of a mesh into non-overlapping scopes.
A client handle for a member of a base space poset.
virtual ~mesh_partition()
Destructor.
Abstract base class with useful features for all objects.
Definition: any.h:39
The lattice of closed cells of a cellular space; a lattice representation of a computational mesh...
const bool NOT_STRICT
Iteration strictness control.
Definition: sheaf.h:102
const bool DOWN
Iteration directions.
Definition: sheaf.h:77
void push_back(const_reference_type item)
Insert item at the end of the items in the auto_block.
bool state_is_read_write_accessible() const
True if this is attached and if the state is accessible for read and write or access control is disab...
pointer_type base() const
The underlying storage array.
void set_ct(size_type xct)
Sets ct() == xct.
An index within the external ("client") scope of a given id space.
Definition: scoped_index.h:116
static std::string reserved_prefix()
Prefix for identifying member names reserved by the sheaf system.
Definition: poset_path.cc:883
virtual bool is_ancestor_of(const any *other) const
Conformance test; true if other conforms to this.
virtual void put_name(const std::string &xname, bool xunique, bool xauto_access)
Make xname a name for this; if xunique, make xname the only name.
mesh_partition & operator=(const mesh_partition &xother)
Assignment operator.
const std::string & name() const
The name of this mesh_partition.
static string name_prefix()
The prefix for valid mesh_partition names.
virtual void detach_from_state()
Detach this handle from its state, if any.
string part_name(const scoped_index &xp_id) const
The name for the part associated with client id xp_id.
const subposet & parts() const
The set of processor read scope members.
bool is_member_hub_id_space() const
True if space() == host().member_hub_id_space().
Definition: id_block.cc:328
int_type pod_index_type
The plain old data index type.
Definition: pod_types.h:49
virtual mesh_partition * clone() const
Virtual constructor, makes a new instance of the same type as this.
subposet & elements()
The subposet containing the elements or zones, that is, the cells of maximal dimension.
pod_index_type part_id(const std::string &xname) const
Extracts the part id from part name xname.
int part_ct() const
The number of parts in this mesh_partition.
const base_space_poset & mesh() const
The mesh poset containing this mesh_partition.
Namespace for the fiber_bundles component of the sheaf system.
A block of ids all in the same id space.
Definition: id_block.h:48
virtual bool invariant() const
Class invariant.