SheafSystem  0.0.0.0
property_disc_iterator_1_2.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 
22 #include "SheafSystem/property_disc_iterator_1_2.h"
23 
24 #include "SheafSystem/assert_contract.h"
25 #include "SheafSystem/base_space_member.h"
26 #include "SheafSystem/binary_section_space_schema_member.h"
27 #include "SheafSystem/eval_family.h"
28 #include "SheafSystem/sec_rep_descriptor.h"
29 #include "SheafSystem/section_evaluator.h"
30 #include "SheafSystem/section_space_schema_member.h"
31 #include "SheafSystem/sec_ed_invertible.h"
32 #include "SheafSystem/sec_vd.h"
33 #include "SheafSystem/std_limits.h"
34 #include "SheafSystem/structured_block_1d.h"
35 #include "SheafSystem/structured_block_2d.h"
36 #include "SheafSystem/structured_block_3d.h"
37 #include "SheafSystem/subposet_member_iterator.h"
38 #include "SheafSystem/uniform_eval_family.h"
39 #include "SheafSystem/field_vd.h"
40 
41 using namespace std;
42 using namespace fields; // Workaround for MS C++ bug.
43 
44 //#define DIAGNOSTIC_OUTPUT 1
45 
46 
47 // ===========================================================
48 // PROPERTY_DISC_ITERATOR_1_2 FACET
49 // ===========================================================
50 
51 // PUBLIC MEMBER FUNCTIONS
52 
53 fields::property_disc_iterator_1_2::
54 property_disc_iterator_1_2(const field_vd& xfield)
55 {
56 
57  // Preconditions:
58 
59  require(xfield.state_is_read_accessible());
60  require(xfield.base_space().schema().conforms_to(base_space_member::standard_schema_path()));
61  require(xfield.property().schema().base_space().le(&xfield.coordinates().schema().base_space()));
62  require(xfield.property().schema().evaluation().is_same_state(&xfield.coordinates().schema().evaluation()));
63  require(xfield.property().schema().rep().eval_is_above_disc());
64 
65  // Body:
66 
67  initialize_iteration(xfield, BIORDER);
68 
69  // Postconditions:
70 
71  ensure(invariant());
72  ensure(is_initialized());
73  ensure(coordinates_schema().is_same_state(&xfield.coordinates().schema()));
74  ensure(coordinates_schema().is_same_type(&xfield.coordinates().schema()));
75  ensure(coordinates_schema().version() == xfield.coordinates().schema().version());
76  ensure(property_schema().is_same_state(&xfield.property().schema()));
77  ensure(property_schema().is_same_type(&xfield.property().schema()));
78  ensure(property_schema().version() == xfield.property().schema().version());
79  ensure(descending());
80  ensure(!strict());
81  ensure(unexecutable(!is_done() implies this is first member));
82 
83  return;
84 }
85 
86 
87 fields::property_disc_iterator_1_2::
88 property_disc_iterator_1_2(
89  const section_space_schema_member& xcoordinates_schema,
90  const section_space_schema_member& xproperty_schema)
91 {
92 
93  // Preconditions:
94 
95  require(xcoordinates_schema.state_is_read_accessible());
96  require(xcoordinates_schema.base_space().schema().conforms_to(base_space_member::standard_schema_path()));
97  require(xproperty_schema.state_is_read_accessible());
98  require(xproperty_schema.base_space().le(&xcoordinates_schema.base_space()));
99  require(xproperty_schema.evaluation().is_same_state(&xcoordinates_schema.evaluation()));
100  require(xproperty_schema.rep().eval_is_above_disc());
101 
102  // Body:
103 
104  initialize_iteration(xcoordinates_schema, xproperty_schema, BIORDER);
105 
106  // Postconditions:
107 
108  ensure(invariant());
109  ensure(is_initialized());
110  ensure(coordinates_schema().is_same_state(&xcoordinates_schema));
111  ensure(coordinates_schema().is_same_type(&xcoordinates_schema));
112  ensure(coordinates_schema().version() == xcoordinates_schema.version());
113  ensure(property_schema().is_same_state(&xproperty_schema));
114  ensure(property_schema().is_same_type(&xproperty_schema));
115  ensure(property_schema().version() == xproperty_schema.version());
116  ensure(descending());
117  ensure(!strict());
118  ensure(unexecutable(!is_done() implies this is first member));
119 
120  return;
121 }
122 
123 
126 {
127  // Preconditions:
128 
129  // Body:
130 
131  // Postconditions:
132 
133 }
134 
135 
136 
137 void
140 {
141  // Preconditions:
142 
143  require(xsec.state_is_read_accessible());
144  require(xsec.schema().is_same_state(&coordinates_schema()));
145 
146  // Implementation of evaluate below only correct for binary schema.
148 
149  require(dynamic_cast<const binary_section_space_schema_member*>
150  (&xsec.schema()) != 0);
151 
153 
154  require(xsec.schema().df() <= 3);
155 
156  // Body:
157 
158  _coord_state.gather_dofs(xsec);
159 
160  int ldf = _coord_state.df;
161  block<sec_vd_dof_type>& lcoord_dofs = _coord_state.dofs;
162  section_evaluator* lcoord_eval = _coord_state.eval;
163  size_type lcoord_local_id = 0;
164 
165  section_evaluator* lprop_eval = _prop_state.eval;
166  block<discretization_context>& ldisc_mbrs = _prop_state.discretization_members;
167  size_type ldisc_ct = ldisc_mbrs.ct();
168 
169  for(size_type i=0; i<ldisc_ct; ++i)
170  {
171  discretization_context& ldisc_mbr = ldisc_mbrs[i];
172  if(_coord_state.disc_sp.contains_member(ldisc_mbr.disc_id))
173  {
174  // Don't need to evaluate, just get the coord disc.
175 
176  size_type ldof_id_begin = lcoord_local_id*ldf;
177  for(size_type c=0; c<ldf; ++c)
178  {
179  ldisc_mbr.values[c] = lcoord_dofs[ldof_id_begin+c];
180  }
181  ++lcoord_local_id;
182  }
183  else
184  {
185  // Have to evaluate the coords at the prop disc point.
186  // Get the local coordinates of the disc point.
187 
188  const int MAX_DB = 3;
189  chart_point_coord_type local_coords[MAX_DB];
190 
191  lprop_eval->local_coordinates(ldisc_mbr.local_id, local_coords, MAX_DB);
192 
193  // Evaluate the global coordinate section.
194 
195  lcoord_eval->value_at_coord(lcoord_dofs.base(),
196  lcoord_dofs.ct(),
197  local_coords,
198  MAX_DB,
199  ldisc_mbr.values,
200  ldf);
201  }
202  }
203 
204  // Postconditions:
205 
206 
207  // Exit:
208 
209  return;
210 }
211 
212 
213 // PRIVATE MEMBER FUNCTIONS
214 
215 void
216 fields::property_disc_iterator_1_2::
217 coord_eval_previsit_action()
218 {
219  // Preconditions:
220 
221  require(_at.coord_eval);
222 
223  // Body:
224 
225  _above.coord_eval = false;
226 
227  _coord_state.set_evaluation_member(_index);
228  _coord_state.initialize_order_correction();
229  _coord_state.discretization_members.set_ct(0);
230  _coord_state.down_set.set_ct(0);
231 
232  _prop_state.set_evaluation_member(_index);
233  _prop_state.initialize_order_correction();
234  _prop_state.discretization_members.set_ct(0);
235 
236  // Postconditions:
237 
238 
239  // Exit:
240 
241  return;
242 }
243 
244 void
245 fields::property_disc_iterator_1_2::
246 prop_disc_previsit_action()
247 {
248  // Preconditions:
249 
250  require(_at.prop_disc);
251 
252  // Body:
253 
254  _above.prop_disc = false;
255 
256  // We only gather prop disc members we haven't gathered before.
257 
258  if(!_prop_state.visited[_index.pod()])
259  {
260  // This member has not been visited before; gather it and mark it.
261 
262  _prop_state.gather_discretization_member(_index, greater_index());
263 
264  _prop_state.visited.put(_index.pod(), true);
265  }
266 
267  // Increment the local id every time, but after we've gathered.
268 
269  _prop_state.local_id++;
270 
271  // Postconditions:
272 
273 
274  // Exit:
275 
276  return;
277 }
278 
279 void
280 fields::property_disc_iterator_1_2::
281 coord_disc_previsit_action()
282 {
283  // Preconditions:
284 
285  require(_at.coord_disc);
286 
287  // Body:
288 
289  _above.coord_disc = false;
290 
291  _coord_state.gather_discretization_member(_index, greater_index());
292  _coord_state.local_id++;
293 
294  // Postconditions:
295 
296 
297  // Exit:
298 
299  return;
300 }
301 
302 
303 void
304 fields::property_disc_iterator_1_2::
305 coord_eval_postvisit_action()
306 {
307  // Preconditions:
308 
309  require(_at.coord_eval);
310 
311  // Body:
312 
313  block<scoped_index>& ldown_set = _coord_state.down_set;
314  size_type lct = ldown_set.ct();
315  for(size_type i=0; i<lct; ++i)
316  {
317  put_has_visited(ldown_set[i], false);
318  }
319  ldown_set.set_ct(0);
320 
321  _above.coord_eval = true;
322 
323  // Postconditions:
324 
325 
326  // Exit:
327 
328  return;
329 }
330 
331 
332 // ===========================================================
333 // DEPTH_FIRST_ITERATOR FACET
334 // ===========================================================
335 
336 // PUBLIC MEMBER FUNCTIONS
337 
338 void
340 next(bool xtruncate)
341 {
342  // Preconditions:
343 
344  require(!is_done());
345 
346  // Body:
347 
348  bool ltruncate = xtruncate;
349 
350  // Never want to see a prop disc member more than once,
351  // so always clear the buffer before we start.
352 
353  _prop_state.discretization_members.set_ct(0);
354 
355  // Traverse the graph gathering coord and prop disc members until
356  // we have enough context to evaluate the coordinates at the
357  // the property disc points or until the trversal is done.
358 
359  property_disc_iterator::next(ltruncate);
360 
361  while(!is_done())
362  {
363  if(action() == PREVISIT_ACTION)
364  {
365  if(!_above.coord_eval)
366  {
367  _coord_state.down_set.push_back(_index);
368  }
369 
370  // The coord and prop eval are both the element subposet and
371  // the coord disc is the vertices. The prop disc is strictly below
372  // the elements, but not necessarily equal to the vertices.
373 
374  _at.coord_eval = _coord_state.eval_sp.contains_member(_index);
375  _at.coord_disc = _coord_state.disc_sp.contains_member(_index);
376  _at.prop_disc = _prop_state.disc_sp.contains_member(_index);
377 
378  if(_at.coord_eval)
379  {
380  coord_eval_previsit_action();
381  }
382 
383  if(_at.prop_disc)
384  {
385  prop_disc_previsit_action();
386  }
387 
388  if(_at.coord_disc)
389  {
390  coord_disc_previsit_action();
391  ltruncate = true;
392  }
393  }
394  else if(action() == POSTVISIT_ACTION)
395  {
396  _at.coord_eval = _coord_state.eval_sp.contains_member(_index);
397 
398  if(_at.coord_eval)
399  {
400  coord_eval_postvisit_action();
401  break;
402  }
403 
404  // If we invoke property_disc_iterator::next() from the postvisit action,
405  // the truncation flag will be ignored, since you can only truncate
406  // in the previsit action. But just to be specific, we'll set it false no
407  // matter what we've done here.
408 
409  ltruncate = false;
410  }
411  else
412  {
413  post_fatal_error_message("unrecognized action");
414  }
415 
416  property_disc_iterator::next(ltruncate);
417  } // end while(!is_done())
418 
419  // Postconditions:
420 
421  ensure(invariant());
422  ensure(!is_done() ? action() == POSTVISIT_ACTION : true);
423 
424  // Exit
425 
426  return;
427 }
428 
429 void
431 reset(bool xreset_markers)
432 {
433  // Preconditions:
434 
435 
436  // Body:
437 
438  if(xreset_markers)
439  {
440  _prop_state.visited.make_false();
441  }
442 
443  // Gather buffers and control flags reset in force_is_done
444  // called from property_disc_iterator::reset
445 
446  property_disc_iterator::reset(xreset_markers);
447 
448  // Postconditions:
449 
450 
451  // Exit:
452 
453  return;
454 }
455 
456 
457 // ===========================================================
458 // ANY FACET
459 // ===========================================================
460 
461 // PUBLIC MEMBER FUNCTIONS
462 
463 bool
465 is_ancestor_of(const any* xother) const
466 {
467  // Preconditions:
468 
469  // Body:
470 
471  bool result = dynamic_cast<const property_disc_iterator_1_2*>(xother) != 0;
472 
473  // Postconditions:
474 
475  // Exit
476 
477  return result;
478 }
479 
482 clone() const
483 {
484  // Preconditions:
485 
486  // Body:
487 
489  new property_disc_iterator_1_2(coordinates_schema(), property_schema());
490 
491  // Postconditions:
492 
493  // ensure(invariant());
494  ensure(result != 0);
495 
496  // Exit
497 
498  return result;
499 }
500 
501 bool
503 invariant() const
504 {
505  bool result = true;
506 
507  // Preconditions:
508 
509  // Body:
510 
511 
512  if(invariant_check())
513  {
514  invariance(property_disc_iterator::invariant());
515 
516  disable_invariant_check();
517 
518  invariance(order() == BIORDER);
519  invariance(property_schema().evaluation().is_same_state(&coordinates_schema().evaluation()));
520  invariance(property_schema().rep().eval_is_above_disc());
521 
522  // Finished, turn invariant checking back on.
523 
524  enable_invariant_check();
525  }
526 
527  // Postconditions:
528 
529  // Exit
530 
531  return result;
532 }
533 
534 
double chart_point_coord_type
The type of local coordinate in the base space; the scalar type for the local coordinate vector space...
Definition: fiber_bundle.h:57
A context for discretization members. Intended for implementing various iterators, especially concurrent iterations over multiple sections.
scoped_index disc_id
The global index of the disc member.
A property discretization iterator for a proerty section with the same evaluation subposet as the coo...
int version(bool xunalias=true) const
The (possibly aliased) version of this component. The version of the host used when evaluating proper...
size_type ct() const
The number of items currently in use.
bool invariant() const
The class invariant.
Namespace for fields component of sheaf system.
bool conforms_to(const schema_poset_member &xother) const
True if the dofs defined by this agree in type and in order with the dofs defined by xother...
bool state_is_read_accessible() const
True if this is attached and if the state is accessible for read or access control is disabled...
subposet & evaluation()
The evaluation subposet for section spaces on this schema (mutable version).
STL namespace.
bool is_same_state(const poset_state_handle *xhost, pod_index_type xhub_id) const
True is this is attached to state with hub id xhub_id in host xhost.
virtual dof_type value_at_coord(const dof_type xdofs[], size_type xdofs_ub, const dof_type xlocal_coords[], size_type xlocal_coords_ub) const
Value at a specified local_coordinate. Single component version.
virtual bool is_ancestor_of(const any *xother) const
True if other conforms to this.
Abstract base class with useful features for all objects.
Definition: any.h:39
virtual void reset(bool xreset_markers=true)
Restarts the iteration.
bool eval_is_above_disc() const
True is the evaluation subposet is strictly above the discretization subposet.
int local_id
The local index of the disc member with respect to the eval member.
pointer_type base() const
The underlying storage array.
void set_ct(size_type xct)
Sets ct() == xct.
unsigned long size_type
An unsigned integral type used to represent sizes and capacities.
Definition: sheaf.h:52
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
bool le(pod_index_type xother_index) const
True if this is less than or equal to the member with index xother_index.
void next()
Makes this the next member of the subset.
sec_vd_value_type values[values_ub]
The values of another section (typically the global coordinates) at this disc point.
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...
A section of a fiber bundle with a d-dimensional vector space fiber.
Definition: sec_vd.h:54
virtual void get_prop_disc_values(const sec_vd &xsec)
The gets the values of xsec at the property discretization points.
total_poset_member & base_space()
The base space component of this (mutable version).
virtual section_space_schema_member & schema()
The restricted schema for this (mutable version).
virtual property_disc_iterator_1_2 * clone() const
Make a new instance of the same type as this.
A client handle for a poset member which has been prepared for use as a schema for a section space...
sec_ed_invertible & coordinates() const
The independent variable of this field.
Definition: field_vd.cc:339
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 df() const
The dimension of the fiber space component.
virtual void local_coordinates(pod_index_type xindex, coord_type xresult[], size_type xresult_ub) const =0
The local coordinates of the dof with local index xindex.
sec_rep_descriptor & rep()
The representation for section spaces on this schema (mutable version).
virtual schema_poset_member & schema()
The schema for this member (mutable version).