SheafSystem  0.0.0.0
body_builder.cc
Go to the documentation of this file.
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 
20 
21 #include "SheafSystem/body_builder.h"
22 
23 #include "SheafSystem/assert_contract.h"
24 #include "SheafSystem/base_space_member.h"
25 #include "SheafSystem/base_space_poset.h"
26 #include "SheafSystem/block.impl.h"
27 #include "SheafSystem/index_space_iterator.h"
28 #include "SheafSystem/section_eval_iterator.h"
29 #include "SheafSystem/section_evaluator.h"
30 #include "SheafSystem/subposet.h"
31 #include "SheafSystem/tern.h"
32 #include "SheafSystem/field_vd.h"
33 
34 using namespace std;
35 using namespace fields; // Workaround for MS C++ bug.
36 
37 // ===========================================================
38 // BODY_BUILDER FACET
39 // ===========================================================
40 
41 // PUBLIC MEMBER FUNCTIONS
42 
45 {
46 
47  // Preconditions:
48 
49 
50  // Body:
51 
52  // Nothing to do;
53 
54  // Postconditions:
55 
56  ensure(invariant());
57 
58  // Exit:
59 
60  return;
61 }
62 
63 
66 {
67 
68  // Preconditions:
69 
70 
71  // Body:
72 
73  // Nothing to do.;
74 
75  // Postconditions:
76 
77  ensure(invariant());
78 
79  // Exit:
80 
81  return;
82 }
83 
86 build(field_vd& xfield, value_type xlower, value_type xupper)
87 {
88  block<scoped_index>* result;
89 
90  // Preconditions:
91 
92  require(xfield.state_is_read_accessible());
93  require(xfield.base_space().state_is_read_write_accessible());
94  require(xfield.dp() == 1);
95  require(xlower < xupper);
96 
97  // Body:
98 
99  result = new block<scoped_index>;
100  build_pa(xfield, xlower, xupper, *result);
101 
102  // Postconditions:
103 
104  ensure(result != 0);
105 
106  // Exit:
107 
108  return result;
109 }
110 
111 void
114  value_type xlower,
115  value_type xupper,
116  block<scoped_index>& xresult)
117 {
118  // Preconditions:
119 
120  require(xfield.state_is_read_accessible());
121  require(xfield.base_space().state_is_read_write_accessible());
122  require(xfield.dp() == 1);
123  require(xlower < xupper);
124 
125  // Body:
126 
128 
129  base_space_poset* lbase_space =
130  dynamic_cast<base_space_poset*>(xfield.base_space().host());
131 
132  base_space_member lbody(xfield.base_space()); // Any member of base space will do.
133 
134  // Find the evaluation members that meet the threshhold criterion.
135 
136  subposet lselected(lbase_space);
137  select_evaluation_members(xfield, xlower, xupper, lselected);
138 
139  // Find all contiguous neighborhoods and join them into bodies.
140 
141  block<scoped_index> lresult(16);
142  block<scoped_index> lnbrhd(1024);
143 
144  // Can't use index_iterator because we are modifying the subposet
145  // while we are iterating.
146 
147  scoped_index i(lbase_space->member_id(0, false));
148 
149  for(; i<lbase_space->member_index_ub(); ++i)
150  {
151  if(lselected.contains_member(i))
152  {
153 
154  // Find the contiguous neighborhood of xindex.
155 
156  find_contiguous_neighborhood(*lbase_space, lselected, i, lnbrhd);
157 
158  // Join the neighborhood to form a body (member of the base space).
159 
160  lbody.new_jrm_state(lnbrhd.base(), lnbrhd.ct(), tern::NEITHER, false);
161  xresult.push_back(lbody.index());
162  }
163  }
164 
165 
166  // Clean up.
167 
168  lselected.delete_state();
169  lbody.detach_from_state();
170 
171  // Postconditions:
172 
173 
174  // Exit:
175 
176  return;
177 }
178 
179 
180 // PRIVATE MEMBER FUNCTIONS
181 
182 void
183 fields::body_builder::
184 select_evaluation_members(const field_vd& xfield,
185  value_type xlower,
186  value_type xupper,
187  subposet& xselected)
188 {
189  // Preconditions:
190 
191  require(xfield.state_is_read_accessible());
192  require(xlower < xupper);
193 
194  // Body:
195 
196  // Make a dof buffer; start with a reasonable amount of space,
197  // just to avoid many small reallocations.
198 
199  block<dof_type> ldofs(xfield.dp()*32);
200 
201  section_eval_iterator litr(xfield.property().schema());
202  while(!litr.evaluators_done())
203  {
204  ldofs.set_ct(0);
205  litr.gather_dofs(xfield.property(), ldofs);
206  if(interval_contains_field(litr.evaluator(), ldofs, xlower, xupper))
207  {
208  // The current eval member is selected by the classifier;
209  // enter it into the result.
210 
211  xselected.insert_member(litr.evaluator_id());
212  }
213 
214  litr.next_evaluator();
215  }
216 
217  // Postconditions:
218 
219 
220  // Exit:
221 
222  return;
223 }
224 
225 bool
226 fields::body_builder::
227 interval_contains_field(const section_evaluator& xeval,
228  const block<dof_type>& xdofs,
229  value_type xlower,
230  value_type xupper) const
231 {
232  bool result;
233 
234  // Preconditions:
235 
236  require(xdofs.ct() == xeval.dof_ct());
237  require(xlower < xupper);
238 
239  // Body:
240 
241  result =
242  (xlower <= xeval.min(xdofs.base(), xdofs.ct())) &&
243  (xeval.max(xdofs.base(), xdofs.ct()) <= xupper);
244 
245  // Postconditions:
246 
247 
248  // Exit:
249 
250  return result;
251 }
252 
253 void
254 fields::body_builder::
255 find_contiguous_neighborhood(const base_space_poset& xbase_space,
256  subposet& xselected,
257  const scoped_index& xindex,
258  block<scoped_index>& xresult)
259 {
260  // Preconditions:
261 
262  require(xbase_space.state_is_read_accessible());
263  require(xselected.contains_member(xindex));
264 
265  // Body:
266 
267  xresult.set_ct(0);
268  size_type lnext = 0;
269 
270  xselected.remove_member(xindex);
271  xresult.push_back(xindex);
272 
273  while(lnext < xresult.ct())
274  {
275  // Get the member at the front of the queue and pop the front.
276  // This shortens the queue; eventually we run out of new neighbors
277  // to add below, the front of the queue reaches the back of the queue,
278  // and we're done.
279 
280  scoped_index mbr_id = xresult[lnext++];
281 
282  // The definition of neighbor used here is that neighbors
283  // meet in an a member of dimension one lower than the neighbors;
284  // that is, neighboring zones share faces. We assume there are no jrms
285  // in the lower covers of zones. Then all neighbors of a given zone
286  // must be in the upper cover of the lower cover of the zone.
287  // Neighbors with lower dimensional meets can be also be handled,
288  // at the cost of more complicated traversals.
289 
290  // Iterate over the lower cover of the current member.
291 
292  index_space_iterator& lc_itr = xbase_space.get_cover_id_space_iterator(LOWER, mbr_id);
293 
294  scoped_index nbr_id(xbase_space.member_hub_id_space(false));
295 
296  while(!lc_itr.is_done())
297  {
298  // Iterate over the upper cover of the current member of the lower cover.
299 
300  index_space_iterator& uc_itr = xbase_space.get_cover_id_space_iterator(UPPER, lc_itr.hub_pod());
301 
302  while(!uc_itr.is_done())
303  {
304  // The current member of the upper cover is a neighbor.
305 
306  nbr_id = uc_itr.hub_pod();
307  if(xselected.contains_member(nbr_id.pod()))
308  {
309  // The neighbor also meets the threshhold criterion.
310  // Remove it from the selected subposet. This eventually
311  // terminates the outer loop over selected members.
313 
314  xselected.remove_member(nbr_id.pod());
315 
316  // Put it into the result/queue; this lengthens the queue.
317  // Eventually we run out of new neighbors to add.
318 
319  xresult.push_back(nbr_id);
320  }
321  uc_itr.next();
322  }
323  xbase_space.release_cover_id_space_iterator(uc_itr);
324 
325  lc_itr.next();
326  }
327  xbase_space.release_cover_id_space_iterator(lc_itr);
328  }
329 
330  // Postconditions:
331 
332  ensure(xresult.ct() > 0);
333 
334  // Exit:
335 
336  return;
337 }
338 
339 
340 // ===========================================================
341 // ANY FACET
342 // ===========================================================
343 
344 // PUBLIC MEMBER FUNCTIONS
345 
346 bool
348 is_ancestor_of(const any* xother) const
349 {
350 
351  // Preconditions:
352 
353  require(xother != 0);
354 
355  // Body:
356 
357  // True if xother conforms to this
358 
359  bool result = dynamic_cast<const body_builder*>(xother) != 0;
360 
361  // Postconditions:
362 
363  return result;
364 }
365 
368 clone() const
369 {
370  body_builder* result;
371 
372  // Preconditions:
373 
374  // Body:
375 
376  result = new body_builder();
377 
378  // Postconditions:
379 
380  ensure(result != 0);
381  ensure(is_same_type(result));
382 
383  // Exit:
384 
385  return result;
386 }
387 
388 
389 bool
391 invariant() const
392 {
393  bool result = true;
394 
395  if(invariant_check())
396  {
397  // Prevent recursive calls to invariant
398 
399  disable_invariant_check();
400 
401  // Must satisfy base class invariant
402 
403  invariance(any::invariant());
404 
405  // Invariances for this class:
406 
407  // Finished, turn invariant checking back on.
408 
409  enable_invariant_check();
410  }
411 
412  // Exit
413 
414  return result;
415 }
416 
417 
418 // ===========================================================
419 // NON-MEMBER FUNCTIONS
420 // ===========================================================
421 
A client handle for a subposet.
Definition: subposet.h:86
size_type ct() const
The number of items currently in use.
An abstract iterator over the ids of an id space.
index_space_iterator & get_cover_id_space_iterator(bool xlower, pod_index_type xmbr_hub_id) const
Allocates an iterator for the lower (xlower true) or upper (xlower false) cover id space of the membe...
void build_pa(field_vd &xfield, value_type xlower, value_type xupper, block< scoped_index > &xresult)
Builds the bodies defined by threshholds xlower and xupper in field xfield; pre_allocated.
virtual bool is_ancestor_of(const any *xother) const
Conformance test; true if other conforms to this.
Namespace for fields component of sheaf system.
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 contains_member(pod_index_type xmbr_hub_id) const
True if this poset contains poset member with hub id xmbr_hub_id.
Definition: subposet.cc:955
STL namespace.
virtual void next()=0
Makes id() the next id in the iteration.
A client handle for a member of a base space poset.
sec_vd_value_type value_type
The type of component in the value; the scalar type in the fiber space.
Definition: body_builder.h:78
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...
virtual ~body_builder()
Destructor.
Definition: body_builder.cc:65
void push_back(const_reference_type item)
Insert item at the end of the items in the auto_block.
bool is_done() const
True if iteration is finished.
virtual dof_type max(const dof_type xdofs[], size_type xdofs_ub) const
The maximum value of the scalar or component section defined by xdofs.
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...
virtual size_type dof_ct() const =0
The number of dofs required for each component of the dependent variable.
poset * host() const
The poset which this is a handle to a member of.
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
unsigned long size_type
An unsigned integral type used to represent sizes and capacities.
Definition: sheaf.h:52
virtual void insert_member(pod_index_type xmbr_hub_id)
Inserts the member of host() with hub id xmbr_hub_id.
Definition: subposet.cc:1091
A vd-valued property as a function of global coordinates.
Definition: field_vd.h:69
sec_vd & property() const
The dependent variable of this field.
Definition: field_vd.cc:357
const bool UPPER
Selector for upper cover.
Definition: sheaf.h:72
base_space_member & base_space() const
The base space of this field.
Definition: field_vd.cc:373
An abstract local section evaluator; a map from {local coordinates x dofs} to section value...
const hub_index_space_handle & member_hub_id_space(bool xauto_access) const
The member hub id space.
body_builder()
Default constructor.
Definition: body_builder.cc:44
Iterates over the evaluation members of a section space schema anchor; gathers the dof ids for each e...
const bool LOWER
Selector for lower cover.
Definition: sheaf.h:67
virtual dof_type min(const dof_type xdofs[], size_type xdofs_ub) const
The minimum value of the scalar or component section defined by xdofs.
virtual section_space_schema_member & schema()
The restricted schema for this (mutable version).
virtual void remove_member(pod_index_type xmbr_hub_id)
Removes the member of host() with hub id xmbr_hub_id.
Definition: subposet.cc:1209
virtual body_builder * clone() const
Virtual constructor, makes a new instance of the same type as this.
virtual scoped_index member_index_ub() const
The upper bound on the member_index;.
bool state_is_read_accessible() const
True if this is attached and if the coordinates and property are accessible for read or access contro...
Definition: field_vd.cc:1380
int dp() const
The dimension of the property (dependent variable) space.
Definition: field_vd.cc:278
block< scoped_index > * build(field_vd &xfield, value_type xlower, value_type xupper)
Builds the bodies defined by threshholds xlower and xupper in field xfield; auto_allocated.
Definition: body_builder.cc:86
void gather_dofs(const sec_vd &xsec, block< sec_vd::dof_type > &xdofs)
Gathers the dofs for the current evalaution member from section xsec and appends them to the back of ...
void release_cover_id_space_iterator(index_space_iterator &xcover_itr) const
Returns xcover_itr to the pool of id space iterators.
virtual bool invariant() const
Class invariant.
A simple body builder; creates base space members equivalent to subsets defined by a field classifica...
Definition: body_builder.h:58
pod_type hub_pod() const
The current unglued hub id in the iteration. synonym for unglued_hub_pod().
virtual const scoped_index & member_id(bool xauto_access) const
An id in the member hub id space; intended for copying to initialize ids to the member id space...