SheafSystem  0.0.0.0
unstructured_block_builder.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 unstructured_block_builder
19 
20 #include "SheafSystem/unstructured_block_builder.h"
21 
22 #include "SheafSystem/error_message.h"
23 #include "SheafSystem/index_space_iterator.h"
24 #include "SheafSystem/poset.h"
25 #include "SheafSystem/poset_path.h"
26 #include "SheafSystem/postorder_iterator.h"
27 #include "SheafSystem/preorder_iterator.h"
28 #include "SheafSystem/ragged_array.h"
29 #include "SheafSystem/assert_contract.h"
30 #include "SheafSystem/sheaves_namespace.h"
31 #include "SheafSystem/std_iostream.h"
32 #include "SheafSystem/std_iomanip.h"
33 #include "SheafSystem/subposet.h"
34 #include "SheafSystem/triorder_iterator.h"
35 #include "SheafSystem/unstructured_block.h"
36 #include "SheafSystem/tern.h"
37 
38 using namespace std;
39 using namespace unordered;
40 using namespace fiber_bundle; // Workaround for MS C++ bug.
41 
42 //#define DIAGNOSTIC_OUTPUT
43 //#undef DIAGNOSTIC_OUTPUT
44 
45 using namespace sheaf;
46 
47 namespace
48 {
49 
50 bool
51 lower_cover_is_equal(base_space_poset& xblock_host,
52  pod_index_type xmbr_id,
54 {
55  // Preconditions:
56 
57  require(xblock_host.contains_member(xmbr_id));
58 
59  // Body:
60 
61  set<pod_index_type> lcover0;
62  index_space_iterator& litr0 = xblock_host.get_cover_id_space_iterator(LOWER, xmbr_id);
63  while(!litr0.is_done())
64  {
65  lcover0.insert(litr0.hub_pod());
66 
67  litr0.next();
68  }
69  xblock_host.release_cover_id_space_iterator(litr0);
70 
71  set<pod_index_type> lcover1;
72  unstructured_block_builder::list_type::const_iterator litr1 = xcover.begin();
73  while(litr1 != xcover.end())
74  {
75  lcover1.insert(*litr1);
76 
77  ++litr1;
78  }
79 
80  bool result = (lcover0 == lcover1);
81 
82  // Postconditions:
83 
84  // Exit:
85 
86  return result;
87 }
88 
89 }; // end unnamed namespace
90 
92 bool
94 invariant() const
95 {
96  bool result = true;
97  return result;
98 }
99 
100 
101 bool
102 fiber_bundle::unstructured_block_builder::
103 _name_mode = false;
104 
108 {
109  // Preconditions:
110 
111  // Body:
112 
113  _template = 0;
114  _glue = 0;
115  _glue_ub = 0;
116  _glue_index = sheaf::invalid_pod_index();
117  _block = 0;
118  _template_db = 0;
119  _boundary_db = -1;
120  _template_has_boundary = false;
121  //_name_mode = false;
122 
123  // Postconditions:
124 
125  ensure(invariant());
126 }
127 
128 
132 {
133 
134  // Preconditions:
135 
136  // Body:
137 
138  while(!_free_covers.empty())
139  {
140  delete (_free_covers.top());
141  _free_covers.pop();
142  }
143 
144  while(!_used_covers.empty())
145  {
146  delete (_used_covers.top());
147  _used_covers.pop();
148  }
149 
150  _boundary_jims.detach_from_state();
151  _block_boundaries.detach_from_state();
152 
153  // Postconditions:
154 
155  // Exit:
156 
157  return;
158 }
159 
161 void
164  const int* xglue,
165  size_type xglue_ub,
166  unstructured_block* result,
167  bool xcompute_upper_cover,
168  bool xauto_access)
169 {
170 
171  // Preconditions:
172 
173  require(xtemplate != 0);
174  require(xtemplate->state_is_read_accessible());
175  require(xtemplate->name_space()->state_is_read_accessible());
176  require(xtemplate->is_jim());
177  require(xtemplate->schema().row_conforms_to(result->schema()));
178  require(xtemplate->atom_ct() > 0);
179 
180  require(xglue != 0);
181  require(xglue_ub > 0);
182  require((xglue_ub % xtemplate->atom_ct()) == 0);
183 
184  require(result != 0);
185  require(xauto_access || result->host()->in_jim_edit_mode());
186 
187  if(xauto_access)
188  {
189  result->get_read_write_access();
190  }
191 
194 
195  require(unexecutable("result host is base space poset"));
196 
197  require(result->schema().row_conforms_to(unstructured_block::standard_schema_path()));
198 
228 
229  // require(result->is_jim() ? result->is_atom() : true);
230  // require(!result->is_jim() ? result->lower_cover_state().empty() : true);
231  // require(!result->is_jim() ? result->upper_cover_state().empty() : true);
232 
237 
238  require(result->is_jim());
239  require(result->is_atom());
240 
241  // Body:
242 
243  if(xauto_access)
244  {
245  result->host()->begin_jim_edit_mode(false);
246  }
247 
248 
249  // Initialize.
250 
251  initialize_template(xtemplate);
252  initialize_glue(xglue, xglue_ub);
253  initialize_block(result);
254  initialize_boundary();
255  initialize_dof_maps();
256 
257  // Make the block itself.
258 
259  make_block(xcompute_upper_cover);
260 
261  if(xauto_access)
262  {
263  // Exit jim edit mode but do not ensure lattice invariant
264  // because it is expensive and we don't need to do it -
265  // the block building routine has properly hooked up everything.
266  // Don't release access because we still need it below.
267 
268  result->host()->end_jim_edit_mode(false, false);
269  }
270 
271 
272  if(_template_has_boundary)
273  {
274  make_boundary();
275  }
276 
277  // Clean up.
278 
279  clean_up();
280 
281  // Postconditions:
282 
283  ensure(unexecutable("result->host()->blocks().contains_member(result)"));
284  ensure(!result->name().empty());
285  ensure(!result->is_jim());
286 
287  if(xauto_access)
288  {
289  result->release_access();
290  }
291 
292  // Exit
293 
294  return;
295 }
296 
298 void
301  const scoped_index* xglue,
302  size_type xglue_ub,
303  unstructured_block* result,
304  bool xcompute_upper_cover,
305  bool xauto_access)
306 {
307  //Preconditions:
308 
309  //$$TYPE_SAFE_IDS_ISSUE:
310  // We need to replace the function build_block_pa
311  // which takes an int* xglue with this one. Need to
312  // move the actual implementation here. This requires
313  // that we change data member _glue to type scoped_index
314 
315  // Body:
316 
317  int* lint_glue = new int[xglue_ub];
318  for(int i=0; i<xglue_ub; ++i)
319  {
320  lint_glue[i] = xglue[i].pod();
321  }
322 
323  build_block_pa(xtemplate,
324  lint_glue,
325  xglue_ub,
326  result,
327  xcompute_upper_cover,
328  xauto_access);
329 
330  delete [] lint_glue;
331 
332  // Postconditions:
333 
334 
335  // Exit
336 
337  return;
338 }
339 
341 void
344  const block<int>& xblock_ids,
345  const block<int>& xblock_dbs,
346  const block<poset_path>& xblock_local_cell_paths,
347  const ragged_array<int>& xblock_nbrs,
348  bool xauto_access)
349 {
350  // Preconditions:
351 
352  require(xmesh != 0);
353  require(xauto_access ? xmesh->is_attached() : xmesh->state_is_read_write_accessible());
354  require(xauto_access || xmesh->name_space()->state_is_read_accessible());
355 
356  require(xblock_dbs.ct() == xblock_ids.ct());
357  require(xblock_local_cell_paths.ct() == xblock_ids.ct());
358 
359  require_for_all(i, 0, xblock_dbs.ct(), xblock_dbs[i] >= 0);
360 
361  require_for_all(i, 0, xblock_local_cell_paths.ct(),
362  xmesh->name_space()->contains_poset_member(xblock_local_cell_paths[i]));
363 
364  require_for_all(i, 0, xblock_local_cell_paths.ct(),
365  xauto_access || xmesh->name_space()->member_poset(xblock_local_cell_paths[i], true).state_is_read_accessible());
366 
367  // Body:
368 
369  // Create the blocks as jims to be refined later.
370 
371  unstructured_block lblock;
372 
373  subposet& lblock_sp(xmesh->blocks());
374  scattered_insertion_index_space_handle& lid_space = lblock_sp.id_space();
375 
376  xmesh->begin_jim_edit_mode(false);
377  for(int i=0; i<xblock_ids.ct(); i++)
378  {
379  if(xauto_access)
380  {
381  xmesh->name_space()->member_poset(xblock_local_cell_paths[i], true).get_read_access();
382  }
383 
384  lblock.new_state(xmesh, xblock_local_cell_paths[i].member_name(), false);
385 
386  if(xauto_access)
387  {
388  xmesh->name_space()->member_poset(xblock_local_cell_paths[i], true).release_access();
389  }
390 
391  lblock_sp.insert_member(&lblock);
392 
393  lid_space.insert(xblock_ids[i], lblock.index());
394 
395  lblock.put_name(poset_path::block_name(xblock_ids[i]), true, false);
396  }
397 
398  lblock.detach_from_state();
399  lblock_sp.detach_from_state();
400  xmesh->end_jim_edit_mode(true, false);
401 
402  // Create the block neighborhoods.
403 
404  make_block_neighborhoods(xmesh, xblock_ids, xblock_nbrs, lid_space);
405 
406 
407 #ifdef DIAGNOSTIC_OUTPUT
408 
409  cout << endl << "after creating block decomposition:" << endl;
410  cout << *xmesh << endl;
411 #endif
412 
413  // Postconditions:
414 
415  ensure(xmesh->includes_subposet("__neighborhoods"));
416 
417  // Exit:
418 
419  return;
420 }
421 
423 void
426  const block<int>& xblock_ids,
427  int xblock_db,
428  const poset_path& xblock_local_cell_path,
429  const ragged_array<int>& xblock_nbrs,
430  bool xauto_access)
431 {
432  // Preconditions:
433 
434  require(xmesh != 0);
435  require(xauto_access ? xmesh->is_attached() : xmesh->state_is_read_write_accessible());
436  require(xblock_db >= 0);
437  require(xauto_access || xmesh->name_space()->state_is_read_accessible());
438  require(xmesh->name_space()->contains_poset_member(xblock_local_cell_path, true));
439  require(xauto_access || xmesh->name_space()->member_poset(xblock_local_cell_path, true).state_is_read_accessible());
440 
441  // Body:
442 
443  if(xauto_access)
444  {
445  xmesh->get_read_write_access();
446  xmesh->name_space()->get_read_access();
447  xmesh->name_space()->member_poset(xblock_local_cell_path, false).get_read_access();
448  }
449 
450  // Create the blocks as jims to be refined later.
451 
452  unstructured_block lblock;
453 
454  subposet& lblock_sp = xmesh->blocks();
455  scattered_insertion_index_space_handle& lid_space = lblock_sp.id_space();
456 
457  scoped_index lblock_dof_tuple_id;
458 
459  xmesh->begin_jim_edit_mode(false);
460 
461  for(int i=0; i<xblock_ids.ct(); i++)
462  {
463  if(i == 0)
464  {
465  // This is the first block;
466  // create the block and initialize the block dof tuple.
467 
468  lblock.new_state(xmesh, xblock_local_cell_path.member_name(), false);
469  lblock.dof_tuple_id(lblock_dof_tuple_id, false);
470  }
471  else
472  {
473  // This is a subsequent block;
474  // create the block using the block dof tuple id.
475 
476  lblock.new_jim_state(lblock_dof_tuple_id, false);
477  }
478 
479  lblock_sp.insert_member(&lblock);
480 
481  lid_space.insert(xblock_ids[i], lblock.index());
482 
483  lblock.put_name(poset_path::block_name(xblock_ids[i]), true, false);
484  }
485 
486  lblock.detach_from_state();
487  lblock_sp.detach_from_state();
488  xmesh->end_jim_edit_mode(true, false);
489 
490  // Create the block neighborhoods.
491 
492  make_block_neighborhoods(xmesh, xblock_ids, xblock_nbrs, lid_space);
493 
494 
495 #ifdef DIAGNOSTIC_OUTPUT
496 
497  cout << endl << "after creating block decomposition:" << endl;
498  cout << *xmesh << endl;
499 #endif
500 
501  // Postconditions:
502 
503  ensure(xmesh->includes_subposet("__neighborhoods"));
504 
505  if(xauto_access)
506  {
507  xmesh->release_access();
508  xmesh->name_space()->release_access();
509  xmesh->name_space()->member_poset(xblock_local_cell_path, false).release_access();
510  }
511 
512  // Exit:
513 
514  return;
515 }
516 
517 
519 bool
522 {
523  bool result;
524 
525  // Preconditions:
526 
527 
528  // Body:
529 
530  result = _name_mode;
531 
532  // Postconditions:
533 
534 
535  // Exit:
536 
537  return result;
538 }
539 
541 void
543 put_name_mode(bool xmode)
544 {
545  // Preconditions:
546 
547 
548  // Body:
549 
550  _name_mode = xmode;
551 
552  // Postconditions:
553 
554  ensure(name_mode() == xmode);
555 
556  // Exit:
557 
558  return;
559 }
560 
561 
563 void
564 fiber_bundle::unstructured_block_builder::
565 initialize_template(const base_space_member* xtemplate)
566 {
567  // Preconditions:
568 
569  require(xtemplate != 0);
570  require(xtemplate->state_is_read_accessible());
571  require(xtemplate->schema().row_conforms_to(base_space_member::standard_schema_path()));
572  require(unexecutable("template contains atoms"));
573 
574  // Body:
575 
576  _template = const_cast<base_space_member*>(xtemplate);
577  _template_host.attach_to_state(xtemplate->host());
578  _template_map.clear();
579  _template_db = _template->db();
580 
581 
582  // Postconditions:
583 
584  ensure(_template == xtemplate);
585  ensure(_template_map.empty());
586  ensure(_template_db >= 0);
587 
588  // Exit:
589 
590  return;
591 }
592 
594 void
595 fiber_bundle::unstructured_block_builder::
596 initialize_glue(const int* xglue, int xglue_ub)
597 {
598  // Preconditions:
599 
600  require(xglue != 0);
601  require(xglue_ub > 0);
602 
603  // Body:
604 
605  _glue = const_cast<int*>(xglue);
606  _glue_ub = xglue_ub;
607  _glue_index = 0;
608 
609  // Postconditions:
610 
611  ensure(_glue == xglue);
612  ensure(_glue_ub == xglue_ub);
613  ensure(_glue_index == 0);
614 
615  // Exit:
616 
617  return;
618 }
619 
621 void
622 fiber_bundle::unstructured_block_builder::
623 initialize_block(unstructured_block* result)
624 {
625  // Preconditions:
626 
627  require(result != 0);
628  require(result->state_is_read_write_accessible());
629  require(result->host()->in_jim_edit_mode());
630  require(result->schema().row_conforms_to(base_space_member::standard_schema_path()));
631  require(result->is_jim());
632  require(result->is_atom());
633 
634  // Body:
635 
636  _block = result;
637 
638  // We're going to redefine the lower cover, so disconnect it from bottom.
639 
640  _block->delete_cover_link(&(_block->host()->bottom()));
641 
642  // Initialize a handle for the block host and block mbrs subposet.
643 
644  _block_host.attach_to_state(result->host());
645  _block_mbrs_sp.new_state(&_block_host);
646 
647  // Allocate space for the block mbrs array.
648 
649  _block_mbrs.reserve(_glue_ub/_template->atom_ct());
650 
651  // Postconditions:
652 
653  ensure(_block == result);
654  ensure(_block_host.is_same_state(result->host()));
655 
656  // Exit:
657 
658  return;
659 }
660 
662 void
663 fiber_bundle::unstructured_block_builder::
664 initialize_boundary()
665 {
666  // Preconditions:
667 
668  require(_template_db >= 0);
669  require(_template != 0);
670  require(_template->state_is_read_accessible());
671  require(_block_host.state_is_read_write_accessible());
672 
673  // Body:
674 
675  // The dimension of the boundary is one less than the dimension
676  // of the host and if the dimension of the lower cover of _template
677  // is the boundary dimension, then the template includes its boundary.
678 
684 
685 
686  _boundary_db = _block_host.max_db() - 1;
687  if(_boundary_db >= 0)
688  {
689  int lc_dim = _template_host.db(_template->first_cover_member(LOWER));
690  _template_has_boundary = ( lc_dim == _boundary_db);
691  }
692  else
693  {
694  _template_has_boundary = false;
695  }
696 
697  _boundary_jims.detach_from_state();
698  if(_block_host.includes_subposet("__boundary_jims"))
699  {
700  _boundary_jims.attach_to_state(&_block_host, "__boundary_jims");
701  }
702  else
703  {
704  _boundary_jims.new_state(&_block_host);
705  _boundary_jims.put_name("__boundary_jims", true, false);
706  }
707 
708  _block_boundaries.detach_from_state();
709  if(_block_host.includes_subposet("__block_boundaries"))
710  {
711  _block_boundaries.attach_to_state(&_block_host, "__block_boundaries");
712  }
713  else
714  {
715  _block_boundaries.new_state(&_block_host);
716  _block_boundaries.put_name("__block_boundaries", true, false);
717  }
718 
719  // Postconditions:
720 
721  ensure(_boundary_db == _block_host.max_db() - 1);
722  ensure(_template_has_boundary ? _boundary_db >= 0 : true);
723  ensure(_block_host.includes_subposet("__boundary_jims"));
724  ensure(_boundary_jims.is_attached());
725  ensure(_boundary_jims.host()->is_same_state(&_block_host));
726  ensure(_block_host.includes_subposet("__block_boundaries"));
727  ensure(_block_boundaries.is_attached());
728  ensure(_block_boundaries.host()->is_same_state(&_block_host));
729 
730  // Exit:
731 
732  return;
733 }
734 
735 
737 void
738 fiber_bundle::unstructured_block_builder::
739 initialize_dof_maps()
740 {
741  // Preconditions:
742 
743  require(_template->schema().row_conforms_to(_block_host.schema()));
744  require(_template->name_space()->state_is_read_accessible());
745  require(_block_host.state_is_read_write_accessible());
746 
747  // Body:
748 
749  // We want the block to have exactly one copy of the dof map for each cell type.
750  // It is efficient in the construction loop to have a map from template member
751  // index to block dof tuple id. We will construct that map here. To ensure
752  // that there is a single copy for each cell type, we first need to construct
753  // a map form cell type to block dof tuple id.
754 
755  // Allocate a map from cell types to block dof tuple ids.
756  // need enough capacity to store any cell type,
757  // i.e. any member index from prototypes poset.
758 
759  poset& lprototypes =
760  _template->name_space()->member_poset<poset>(base_space_member::prototypes_poset_name(), false);
761 
762  scoped_index ltype_id_ub = lprototypes.member_index_ub();
763 
764  block<scoped_index> ltype_map(ltype_id_ub.pod());
765 
766  ltype_map.set_ct(ltype_id_ub.pod());
767 
768  ltype_map.assign(_block_host.dof_tuple_id(invalid_pod_index(), false));
769 
770  // Insert all the existing dof tuples.
771 
772  for(pod_index_type i = 0; i<_block_host.row_dof_tuple_ct(); ++i)
773  {
774  void* ltuple_ptr = _block_host.row_dof_map(i).dof_tuple();
775 
776  base_space_poset::row_dof_tuple_type* lrow_tuple_ptr =
777  reinterpret_cast<base_space_poset::row_dof_tuple_type*>(ltuple_ptr);
778 
779  ltype_map[lrow_tuple_ptr->type_id] = i;
780  }
781 
782  // Initialize the template index to block dof tuple id map.
783 
784  _dof_tuple_id_map.reserve(_template_host.member_index_ub().pod());
785 
786  _dof_tuple_id_map.set_ct(_dof_tuple_id_map.ub());
787 
788  _dof_tuple_id_map.assign(scoped_index::INVALID());
789 
790  // Populate the template index to block dof tuple id map.
791  // Copy the dof tuples of any cell types that are in the
792  // template but not yet in the block.
793 
794  postorder_iterator itr(*_template, DOWN, NOT_STRICT);
795  while(!itr.is_done())
796  {
797  scoped_index lblk_tuple_id = _block_host.dof_tuple_id(false);
798  scoped_index lindex = itr.index();
799  pod_index_type ltmp_tuple_id =
800  _template_host.member_dof_tuple_id(lindex.pod(), false);
801 
802  if(is_valid(ltmp_tuple_id))
803  {
804  // Template member has a dof tuple; get the cell type.
805 
806  pod_index_type ltype_id = _template_host.type_id(lindex);
807  lblk_tuple_id = ltype_map[ltype_id];
808 
809  if(!lblk_tuple_id.is_valid())
810  {
811  // The cell type is not in the map yet;
812  // copy the dof tuple into the block and insert the cell type in the map.
813  // Note that preconditions guarantee template tuple is at least
814  // as long as block tuple, but may be longer. Make sure block tuple
815  // controls transfer so correct number of bytes get copied.
816 
817 
818  lblk_tuple_id = _block_host.new_row_dof_map();
819 
820  poset_dof_map& lblk_dof_map = _block_host.row_dof_map(lblk_tuple_id, true);
821  poset_dof_map& ltmp_dof_map = _template->host()->row_dof_map(ltmp_tuple_id);
822  lblk_dof_map.put_dof_tuple(ltmp_dof_map.dof_tuple(), ltmp_dof_map.dof_tuple_ub());
823 
824  // Insert cell type and block tuple id in map.
825 
826  ltype_map[ltype_id] = lblk_tuple_id;
827  }
828  }
829  else
830  {
831  // Template member does not have a dof tuple.
832 
833  lblk_tuple_id.invalidate();
834  }
835 
836  // Insert the template member id and block dof tuple id in the map.
837 
838  _dof_tuple_id_map[lindex.pod()] = lblk_tuple_id;
839 
840  itr.next();
841  }
842 
843  // Postconditions:
844 
845  ensure(unexecutable("template dof maps duplicated in block host"));
846  ensure(unexecutable("_dof_tuple_id_map initialized"));
847 
848  // Exit
849 
850  return;
851 }
852 
853 
855 void
856 fiber_bundle::unstructured_block_builder::
857 make_block(bool xcompute_upper_cover)
858 {
859  // Preconditions:
860 
861  require(_block->is_jim());
862  require(unexecutable("all data members initialized"));
863 
864  // Body:
865 
866  // Repeatedly traverse the template, making copies of it
867  // and gluing them together with the equivalences in _glue.
868 
869  size_type lblk_size = 0;
870 
871  triorder_iterator ltmplt_itr(*_template, DOWN, NOT_STRICT);
872  bool ltruncate = false;
873 
874  while(_glue_index < _glue_ub)
875  {
876  // Copy the template.
877 
878  while(!ltmplt_itr.is_done())
879  {
880  switch(ltmplt_itr.action())
881  {
882  case triorder_iterator::PREVISIT_ACTION:
883  previsit_action(ltmplt_itr, ltruncate);
884  break;
885  case triorder_iterator::LINK_ACTION:
886  link_action(ltmplt_itr);
887  ltruncate = false;
888  break;
889  case triorder_iterator::POSTVISIT_ACTION:
890  postvisit_action(ltmplt_itr);
891  ltruncate = false;
892  break;
893  default:
894  // Should be unreachable.
895  post_fatal_error_message("Unrecognized iterator action.");
896  break;
897  }
898  ltmplt_itr.next(ltruncate);
899  }
900 
901  // Count the cells in the block.
902 
903  lblk_size++;
904 
905  // Reset for next copy of template
906 
907  _template_map.clear();
908  ltmplt_itr.reset();
909  }
910 
911  if(xcompute_upper_cover)
912  {
913  // Compute the block as the join of its members.
914  // Ensures proper lower and upper cover.
915 
919 
920  poset* lhost = _block->host();
921 
924 
927 
928  pod_index_type ltuple_id = _block->dof_tuple_id(false);
929  _block->delete_state();
930 
931  // block members have an empty upper cover.
932  // Link them to the top, this is what ensure_lattice_invariant would do.
933 
934  size_type lct = _block_mbrs.ct();
935  for(size_type i=0; i<lct; ++i)
936  {
937  lhost->new_link(TOP_INDEX, _block_mbrs[i].hub_pod());
938  }
939 
940  // Now join them.
941 
942  _block->new_jrm_state(lhost, _block_mbrs.base(), _block_mbrs.ct(), tern::TRUE, false);
943 
944  // Restore the dof tuple.
945 
946  _block->put_dof_tuple_id(lhost->dof_tuple_id(ltuple_id, false), false);
947  }
948  else
949  {
950  // Just assume the upper cover is correct and
951  // the block covers its members.
952 
953  const scoped_index& lblk_id = _block->index();
954  size_type lct = _block_mbrs.ct();
955  for(size_type i=0; i<lct; ++i)
956  {
957  _block_host.new_link(lblk_id, _block_mbrs[i]);
958  }
959  }
960 
961  // Update the number of cells in the block.
962 
963  _block->put_size(lblk_size);
964 
965  // The block member is no longer a jim.
966 
967  _block_host.jims().remove_member(_block);
968 
969  // Make sure the block is in the blocks subposet.
970 
971  subposet& lblocks_sp = _block_host.blocks();
972  if(!lblocks_sp.contains_member(_block))
973  {
974  lblocks_sp.insert_member(_block);
975  lblocks_sp.id_space().push_back(_block->index());
976  }
977 
978  // Make sure the block has a name.
979 
980  if(_block->name().empty())
981  {
982  scoped_index lseq_id(_block_host.blocks().id_space(), _block->index());
983 
984  _block->put_name(poset_path::make_name("__block_", lseq_id.pod(), ""), true, false);
985  }
986 
987 
988  // Postconditions:
989 
990  ensure(_block->db() == _template_db);
991  ensure(_block->local_cell_type_id() == _template->type_id());
992  ensure(_block->size() > 0);
993  ensure(!_block->is_jim());
994  ensure(_block_host.blocks().contains_member(_block));
995  ensure(!_block->name().empty());
996 
997  // Exit:
998 
999  return;
1000 }
1001 
1002 
1004 void
1005 fiber_bundle::unstructured_block_builder::
1006 previsit_action(const triorder_iterator& xtmplt_itr, bool& xtruncate)
1007 {
1008  // Preconditions:
1009 
1010  // Body:
1011 
1012  if(_template_host.is_atom(xtmplt_itr.index()))
1013  {
1014  // The current item is an atom, its lower cover contains only the bottom;
1015  // don't want to visit the bottom.
1016 
1017  xtruncate = true;
1018  }
1019  else
1020  {
1021  // The current item is not an atom;
1022  // get a lower cover set.
1023 
1024  list_type* lcover;
1025 
1026  if(_free_covers.empty())
1027  {
1028  // No free iterators, have to make one.
1029 
1030  lcover = new list_type;
1031  }
1032  else
1033  {
1034  // Just get one from the free stack.
1035 
1036  lcover = _free_covers.top();
1037  _free_covers.pop();
1038  }
1039 
1040  _used_covers.push(lcover);
1041 
1042  // Continue descent of template.
1043 
1044  xtruncate = false;
1045  }
1046 
1047  // Postconditions:
1048 
1049  // Exit
1050 
1051  return;
1052 }
1053 
1055 void
1056 fiber_bundle::unstructured_block_builder::
1057 link_action(const triorder_iterator& xtmplt_itr)
1058 {
1059  // Preconditions:
1060 
1061  // Body:
1062 
1063  unordered_map<int,int>::iterator itr = _template_map.find(xtmplt_itr.lesser_index().pod());
1064 
1065  // Find must succeed.
1066 
1067  assertion(itr != _template_map.end());
1068 
1069  // Put the found index into the cover on the top of the stack.
1070 
1071  _used_covers.top()->push_back(itr->second);
1072 
1073  // Postconditions:
1074 
1075  // Exit
1076 
1077  return;
1078 }
1079 
1081 void
1082 fiber_bundle::unstructured_block_builder::
1083 postvisit_action(const triorder_iterator& xtmplt_itr)
1084 {
1085 
1086  // Preconditions:
1087 
1088  require(xtmplt_itr.index() != BOTTOM_INDEX);
1089 
1090  // Body:
1091 
1092  const scoped_index& ltmplt_mbr_id = xtmplt_itr.index();
1093  int lmbr_db = _template_host.db(ltmplt_mbr_id);
1094 
1095  scoped_index lblk_mbr_id(_block_host.member_hub_id_space(false));
1096 
1097  int glue_id;
1098 
1099  if(_template_host.is_atom(ltmplt_mbr_id))
1100  {
1101  // Template member is an atom.
1102 
1103  // Get the next id from the glue array and increment the glue index.
1104 
1105  glue_id = _glue[_glue_index];
1106  _glue_index++;
1107 
1108  // If the id has been used before, get the block member index associated with it;
1109  // otherwise, create a new member.
1110 
1111  scattered_insertion_index_space_handle& lid_space = _block_host.d_cells_id_space(lmbr_db);
1112 
1113  lblk_mbr_id = lid_space.hub_pod(glue_id);
1114 
1115  if(!lblk_mbr_id.is_valid())
1116  {
1117  // Current glue id has not been used before; create a new member
1118  // using the block's copy of the template member's dof tuple.
1119 
1120  const scoped_index& lblk_tuple_id =
1121  _dof_tuple_id_map[ltmplt_mbr_id.pod()];
1122 
1123  _block_host.new_member(_template_host.is_jim(ltmplt_mbr_id.pod()),
1124  lblk_tuple_id,
1125  lblk_mbr_id);
1126 
1127  // The new member is an atom, link it to the bottom.
1128 
1129  _block_host.new_link(lblk_mbr_id.pod(), BOTTOM_INDEX);
1130 
1131  // The new member is a member of this block.
1132 
1133  _block_mbrs_sp.insert_member(lblk_mbr_id.pod());
1134 
1135  if(_template_has_boundary && (_boundary_db == 0))
1136  {
1137  // The new member is the same dimension as the boundary.
1138  // Assume it is in the boundary, it will be removed later if not.
1139 
1140  _boundary_jims.insert_member(lblk_mbr_id.pod());
1141  }
1142 
1143  // Insert it in the vertices subposet and client id map
1144 
1145  _block_host.d_cells(lmbr_db).insert_member(lblk_mbr_id.pod());
1146 
1147  lid_space.insert(glue_id, lblk_mbr_id.pod());
1148 
1149  _block_host.cells().insert_member(lblk_mbr_id);
1150 
1151  scattered_insertion_index_space_handle& lid_space2 = _block_host.cells().id_space();
1152  lid_space2.push_back(lblk_mbr_id);
1153 
1154  if(_name_mode)
1155  {
1156  // Give the cell a name.
1157 
1158  string lsp_name(_block_host.d_cells(lmbr_db).name());
1159  string lname(poset_path::make_name(lsp_name, glue_id, ""));
1160  _block_host.put_member_name(lblk_mbr_id.pod(), lname, true, false);
1161  }
1162  }
1163 
1164  // Now we have the member associated with the glue id;
1165  // put it in the template map.
1166 
1167  _template_map.insert(unordered_map<int, int>::value_type(ltmplt_mbr_id.pod(), lblk_mbr_id.pod()));
1168 
1169  } // end xmbr is an atom
1170  else
1171  {
1172  // Temaplate member is not an atom.
1173 
1174  // Check to see if any members already in the block have
1175  // a lower cover identical to whats currently on the stack
1176  // If there are any such members, they must be in the upper cover
1177  // of every member of the cover on the stack, hence they must be
1178  // in the upper cover of the first member. Check the lower cover of
1179  // every member of the upper cover of the first member of the cover
1180  // on the stack.
1181 
1182  list_type* lc = _used_covers.top();
1183 
1184  // Lc can not be empty at this point.
1185 
1186  assertion(!lc->empty());
1187 
1188  index_space_iterator& uc_itr =
1189  _block_host.get_cover_id_space_iterator(UPPER, *(lc->begin()));
1190 
1191  while(!uc_itr.is_done())
1192  {
1193  lblk_mbr_id = uc_itr.hub_pod();
1194  if(lower_cover_is_equal(_block_host, lblk_mbr_id.pod(), *lc))
1195  {
1196  break;
1197  }
1198 
1199  uc_itr.next();
1200  }
1201 
1202  if(uc_itr.is_done())
1203  {
1204  // Couldn't find an existing member; have to create one
1205  // using the block's copy of the template member's dof tuple.
1206 
1207  scoped_index lblk_tuple_id = _dof_tuple_id_map[ltmplt_mbr_id.pod()];
1208 
1209  _block_host.new_member(_template_host.is_jim(ltmplt_mbr_id),
1210  lblk_tuple_id,
1211  lblk_mbr_id);
1212 
1213  // New member is a member of this block.
1214 
1215  _block_mbrs_sp.insert_member(lblk_mbr_id.pod());
1216 
1217  // Insert the new member in the appropriate cells subposet and client id map.
1218 
1219  _block_host.d_cells(lmbr_db).insert_member(lblk_mbr_id.pod());
1220 
1221  scattered_insertion_index_space_handle& lid_space = _block_host.d_cells_id_space(lmbr_db);
1222  lid_space.push_back(lblk_mbr_id.pod());
1223 
1224  _block_host.cells().insert_member(lblk_mbr_id);
1225 
1226  scattered_insertion_index_space_handle& lid_space2 = _block_host.cells().id_space();
1227  lid_space2.push_back(lblk_mbr_id);
1228 
1229  if(_name_mode)
1230  {
1231  // Give the cell a name.
1232 
1233  pod_index_type lclient_id = lid_space.pod(lblk_mbr_id.pod());
1234 
1235  string lname = _block_host.d_cells(lmbr_db).name();
1236 
1237  lname = poset_path::make_name(lname, lclient_id, "");
1238 
1239  _block_host.put_member_name(lblk_mbr_id.pod(), lname, true, false);
1240  }
1241 
1242 
1243  if(_template_has_boundary && (lmbr_db == _boundary_db))
1244  {
1245  // The new member is the same dimension as the boundary.
1246  // Assume it is in the boundary, it will be removed later if not.
1247 
1248  _boundary_jims.insert_member(lblk_mbr_id.pod());
1249  }
1250 
1251  // Link the new member to the members in the lower cover on
1252  // the top of the stack.
1253 
1254  if(_template_has_boundary && lmbr_db == _template_db)
1255  {
1256  // The new member has the same dimension as the template, so
1257  // its lower cover must have the same dimension as the boundary.
1258  // Link the new member and then update the boundary status of
1259  // each lower cover member.
1260 
1261  list_type::iterator lc_itr = lc->begin();
1262  while(lc_itr != lc->end())
1263  {
1264  pod_index_type lc_mbr_id = *lc_itr;
1265  _block_host.new_link(lblk_mbr_id.pod(), lc_mbr_id);
1266  update_boundary(lc_mbr_id);
1267  lc_itr++;
1268  }
1269 
1270  }
1271  else
1272  {
1273  // The lower cover can not be the boundary.
1274  // Just link the new member to the lower cover.
1275 
1276  list_type::iterator lc_itr = lc->begin();
1277  while(lc_itr != lc->end())
1278  {
1279  _block_host.new_link(lblk_mbr_id.pod(), *lc_itr);
1280  lc_itr++;
1281  }
1282  }
1283 
1284  } // end create new member
1285  else
1286  {
1287  // Member already exists;
1288  // just terminate the iterator to be safe.
1289 
1290  uc_itr.force_is_done();
1291  }
1292 
1293  _block_host.release_cover_id_space_iterator(uc_itr);
1294 
1295  // Put the block member index into the template map
1296  // so we can retrieve it in link_action.
1297 
1298  _template_map.insert(unordered_map<int, int>::value_type(ltmplt_mbr_id.pod(), lblk_mbr_id.pod()));
1299 
1300  // Finished with the cover on top of the stack;
1301  // empty it and push it on to the free stack for reuse.
1302 
1303  list_type* cover = _used_covers.top();
1304  _used_covers.pop();
1305  cover->clear();
1306  _free_covers.push(cover);
1307 
1308  } // end xmbr is not an atoom
1309 
1310 
1311 #ifdef DIAGNOSTIC_OUTPUT
1312  cout << "mbr: " << setw(2) << lblk_mbr_id;
1313  cout << " lower cover: ";
1314  cover_set_iterator litr = _block_host.cover_iterator(LOWER, lblk_mbr_id.pod());
1315  while(!litr.is_done())
1316  {
1317  cout << litr.item() << " ";
1318  litr.next();
1319  }
1320  cout << endl;
1321 #endif
1322 
1323  if(ltmplt_mbr_id ==~ _template->index())
1324  {
1325  // We're finished.
1326 
1327  // Store the member.
1328 
1329  _block_mbrs.push_back(lblk_mbr_id);
1330 
1334 
1335  // // Link the block to the current local cell.
1336 
1337  // _block_host.new_link(_block->index(), lblk_mbr_id);
1338  }
1339 
1340  // Postconditions:
1341 
1342  // Exit:
1343 
1344  return;
1345 }
1346 
1348 void
1349 fiber_bundle::unstructured_block_builder::
1350 make_boundary()
1351 {
1352  // Preconditions:
1353 
1354  require(_template_has_boundary);
1355 
1356  // Body:
1357 
1358  // Allocate some storage for the boundary jims;
1359  // initial size is arbitrary but large enough to
1360  // prevent many small reallocations.
1361 
1362  block<scoped_index> lblock_bdy_jims(1024);
1363 
1364  // Find the boundary jims of this block.
1365 
1366  preorder_iterator itr(*_block, _boundary_jims, DOWN, NOT_STRICT);
1367  while(!itr.is_done())
1368  {
1369  lblock_bdy_jims.push_back(itr.index());
1370  itr.truncate();
1371  }
1372 
1373  if(lblock_bdy_jims.ct() > 0)
1374  {
1375  // The boundary of the block is not empty; join its members.
1376 
1377  total_poset_member lbdy(&_block_host,
1378  lblock_bdy_jims.base(),
1379  lblock_bdy_jims.ct(),
1380  tern::TRUE,
1381  false);
1382  lbdy.put_name(poset_path::boundary_prefix() + _block->name(), true, false);
1383  _block_boundaries.insert_member(&lbdy);
1384  lbdy.detach_from_state();
1385  }
1386 
1387  // Postconditions:
1388 
1389 
1390  // Exit:
1391 
1392  return;
1393 }
1394 
1395 
1397 void
1398 fiber_bundle::unstructured_block_builder::
1399 clean_up()
1400 {
1401  // Preconditions:
1402 
1403  // Body:
1404 
1405  _template = 0;
1406  _template_host.detach_from_state();
1407  _template_map.clear();
1408  _template_db = 0;
1409 
1410 
1411  _glue = 0;
1412  _glue_ub = 0;
1413  _glue_index = sheaf::invalid_pod_index();
1414 
1415  _block = 0;
1416  _block_mbrs_sp.delete_state();
1417 
1418 
1419  _boundary_db = -1;
1420  _template_has_boundary = false;
1421 
1422 
1423  _dof_tuple_id_map.set_ct(0);
1424 
1425  _block_host.detach_from_state();
1426 
1427  // Postconditions:
1428 
1429 
1430  // Exit:
1431 
1432  return;
1433 }
1434 
1435 void
1436 fiber_bundle::unstructured_block_builder::
1437 update_boundary(pod_index_type xhub_id)
1438 {
1439  // Preconditions:
1440 
1441  require(_block_host.contains_member(xhub_id));
1442  require(!_block_host.cover_is_empty(UPPER, xhub_id));
1443  require(_block_host.is_jim(xhub_id));
1444  require(_block_host.db(xhub_id) == _boundary_db);
1445 
1446  // Body:
1447 
1448  // Since xhub_id is a jim with same dimension as boundary,
1449  // it can have at most 2 members in its upper over when
1450  // construction is complete. If it has 2 members and both
1451  // are members of this block, then it is internal to the block.
1452  // If it has only 1, or it has two, one in this block and
1453  // one not in this block, then it is in the boundary.
1454  //
1455  // All members with the boundary dimension are inserted in
1456  // _boundary_jims when they are created. We have just inserted
1457  // another member in the upper cover of this member.
1458  // Since scattered_insertion_index_space::push_back ensures the member is
1459  // at the back of the list, if the upper cover contains a member
1460  // not in this block, it must be the first member of the upper cover.
1461 
1462  if(!_block_host.cover_is_singleton(UPPER, xhub_id) &&
1463  _block_mbrs_sp.contains_member(_block_host.first_cover_member(UPPER, xhub_id)))
1464  {
1465  _boundary_jims.remove_member(xhub_id);
1466  }
1467 
1468  // Postconditions:
1469 
1470 
1471  // Exit:
1472 
1473  return;
1474 }
1475 
1476 void
1477 fiber_bundle::unstructured_block_builder::
1478 update_boundary(const scoped_index& xid)
1479 {
1480  // Preconditions:
1481 
1482  require(_block_host.contains_member(xid));
1483  require(!_block_host.cover_is_empty(UPPER, xid));
1484  require(_block_host.is_jim(xid));
1485  require(_block_host.db(xid) == _boundary_db);
1486 
1487  // Body:
1488 
1489  update_boundary(xid.hub_pod());
1490 
1491  // Postconditions:
1492 
1493 
1494  // Exit:
1495 
1496  return;
1497 }
1498 
1500 void
1501 fiber_bundle::unstructured_block_builder::
1502 make_block_neighborhoods(base_space_poset* xmesh,
1503  const block<int>& xblock_ids,
1504  const ragged_array<int>& xblock_nbrs,
1505  const index_space_handle& xid_space)
1506 {
1507  // Preconditions:
1508 
1509  require(xmesh != 0);
1510  require(xmesh->state_is_read_write_accessible());
1511 
1512  // Body:
1513 
1514  total_poset_member lnbrhd;
1515  subposet lnbrhd_sp(xmesh);
1516  lnbrhd_sp.put_name("__neighborhoods", true, false);
1517  block<scoped_index> lnbrs(32); // arbitrary, avoids many small reallocations.
1518 
1519  for(int i=0; i<xblock_nbrs.row_ct(); i++)
1520  {
1521  // Convert the neighbor ids to poset ids.
1522 
1523  lnbrs.set_ct(0);
1524  scoped_index lid(xmesh->member_hub_id_space(false));
1525  for(int j=0; j<xblock_nbrs.col_ct(i); j++)
1526  {
1527  lid = xid_space.hub_pod(xblock_nbrs[i][j]);
1528  lnbrs.push_back(lid);
1529  }
1530 
1531  // The neighborhood member is the join of the neighbors.
1532 
1533  lnbrhd.new_jrm_state(xmesh, lnbrs.base(), lnbrs.ct(), tern::TRUE, false);
1534 
1535  // Name it after the current member.
1536 
1537  lnbrhd.put_name(poset_path::block_neighborhood_name(xblock_ids[i]), true, false);
1538 
1539  // Put it in the subposet of neighborhoods.
1540 
1541  lnbrhd_sp.insert_member(&lnbrhd);
1542  }
1543  lnbrhd.detach_from_state();
1544  lnbrhd_sp.detach_from_state();
1545 
1546  // Postconditions:
1547 
1548  ensure(xmesh->includes_subposet("__neighborhoods"));
1549 
1550  // Exit:
1551 
1552  return;
1553 }
virtual void get_read_write_access(bool xrelease_read_only_access=false)
Get read write access to the state associated with this. If release_read_only_access is requested...
virtual bool is_jim(bool xin_current_version=true) const
True if this member is join irreducible in the current version of the host (xin_current_version == tr...
A client handle for a subposet.
Definition: subposet.h:86
void truncate()
Makes this the next member of the subset which is not less than old this, i.e. the depth-first descen...
bool is_valid() const
True if this is a valid id.
Definition: scoped_index.h:832
pod_index_type dof_tuple_id(bool xauto_access) const
The dof tuple index of this member.
virtual void new_link(pod_index_type xgreater, pod_index_type xlesser)
Insert a cover link from greater to lesser (that is, hub id xgreater covers hub id xlesser)...
static void build_block_decomposition(base_space_poset *xmesh, const block< int > &xblock_ids, const block< int > &xblock_dbs, const block< poset_path > &xblock_local_cell_paths, const ragged_array< int > &xblock_nbrs, bool xauto_access)
Creates in xmesh the unrefined blocks and block neighborhoods described by the client ids in xblock_i...
size_type ct() const
The number of items currently in use.
virtual void new_jim_state(poset_dof_map *xdof_map=0, bool xcopy_dof_map=false, bool xauto_access=true)
Creates a new jim (join-irreducible member) state in host() and attaches this to it. If xdof_map == 0 a new dof map is created. If xdof_map != 0 and xcopy_dof_map == false, xdof_map is used as the dof map. If xdof_map != 0 and xcopy_dof_map is true, a copy of xdof_map is used.
const pod_type & pod() const
The "plain old data" storage of this; the value in the external id space.
Definition: scoped_index.h:672
std::list< pod_index_type > list_type
The type of the temporary cover set lists.
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...
action_type action() const
The type of action the client should take when the iterator returns control to the client...
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 & blocks()
The subposet containing all the blocks, const ver (mutable version).
bool contains_poset_member(pod_index_type xposet_hub_id, pod_index_type xmember_hub_id, bool xauto_access=true) const
True if this contains a poset with hub id xposet_hub_id which contains a member with hub id xmember_h...
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.
virtual int atom_ct() const
The number of members in the set of atoms contained in the down set of this member.
virtual void * dof_tuple()=0
The dof tuple (mutable version).
A path defined by a poset name and a member name separated by a forward slash (&#39;/&#39;). For example: "cell_definitions/triangle".
Definition: poset_path.h:48
virtual const scoped_index & dof_tuple_id(bool xauto_access) const
An id in the dof tuple hub id space; intended for copying to initialize ids to the dof tuple id space...
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 bool invariant() const
Class invariant.
An abstract handle to a space of alternate integer identifiers (aliases) for a subset of a hub set of...
poset_state_handle & member_poset(pod_index_type xhub_id, bool xauto_access=true) const
The poset_state_handle object referred to by hub id xhub_id.
void invalidate()
Make this id invalid.
Definition: scoped_index.h:852
virtual namespace_poset * name_space() const
The namespace of host()
const scoped_index & index() const
The index of the component state this handle is attached to.
virtual void next()=0
Makes id() the next id in the iteration.
std::string name() const
A name for this.
OBSOLETE: use zone_nodes_block or point_block_*d. A client handle for a base space member which repre...
The general, abstract map from dof ids to dof values.
Definition: poset_dof_map.h:59
namespace_poset * host() const
The namespace this poset resides in. Obsolete; use name_space() instead.
static bool name_mode()
True if cells should be given unique names.
Dperecated. Use postorder_itr. Specialization of the filtered depth-first iterator which exposes the ...
virtual pod_type pod(pod_type xid) const
The pod index in this space equivalent to xid in the hub id space.
A client handle for a member of a base space poset.
virtual void release_access(bool xall=false) const
Release access. If xall is true, release all levels of access. Otherwise, release one level of access...
The lattice of closed cells of a cellular space; a lattice representation of a computational mesh...
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.
Definition: subposet.cc:2782
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 is_done() const
True if iteration is finished.
A client handle for a mutable partially ordered set.
Definition: poset.h:40
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...
poset * host() const
The poset which this is a handle to a member of.
pointer_type base() const
The underlying storage array.
size_t dof_tuple_ub() const
The size of the dof tuple in bytes.
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
virtual void get_read_access() const
Get read access to the state associated with this.
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
index_type row_ct() const
The number of rows.
virtual bool contains_member(pod_index_type xmbr_hub_id, bool xauto_access=true) const
True if some version of this poset contains poset member with hub id xmbr_hub_id. ...
const bool UPPER
Selector for upper cover.
Definition: sheaf.h:72
void insert(pod_type xid, const scoped_index &xhub_id)
Make id xid in this id space equivalent to xhub_id in the hub id space. synonym for insert(xid...
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.
void next()
Makes this the next member of the subset.
virtual void release_access(bool xall=false) const
Release access. If xall is true, release all levels of access. Otherwise, release one level of access...
const scoped_index & lesser_index() const
The index of the lesser member of the current link.
const hub_index_space_handle & member_hub_id_space(bool xauto_access) const
The member hub id space.
bool is_done() const
True if iteration finished.
virtual bool is_atom() const
True if this member covers the bottom.
const bool LOWER
Selector for lower cover.
Definition: sheaf.h:67
const scattered_insertion_index_space_handle & id_space() const
The id space for the members of with this (const version).
Definition: subposet.cc:508
virtual void detach_from_state()
Detach this handle from its state, if any.
pod_type hub_pod(pod_type xid) const
The pod index in the unglued hub id space equivalent to xid in this id space; synonym for unglued_hub...
virtual poset_dof_map & row_dof_map(pod_index_type xtuple_hub_id, bool xrequire_write_access=false) const
The map from row dof client_ids to row dof values for dof tuple hub id xtuple_hub_id.
namespace_poset * name_space() const
The namespace this poset resides in.
virtual bool is_attached() const
True if this is attached to a state.
virtual void get_read_write_access(bool xrelease_read_only_access=false)
Get read write access to the state associated with this. If release_read_only_access is requested...
virtual poset_state_handle * host() const
The poset which owns this.
virtual void reset(bool xreset_markers=true)
Restarts the iteration over the down set of anchor().
int_type pod_index_type
The plain old data index type.
Definition: pod_types.h:49
std::string member_name() const
The member name part of the path.
Definition: poset_path.cc:511
A handle for a scattered_insertion_index_space_state.
Namespace for the sheaves component of the sheaf system.
void push_back(const scoped_index &xhub_id)
Make the next id in this space equivalent to xhub_id in the hub id space. synonym for push_back(xhub_...
virtual void new_state(poset *xhost, const std::string &xlocal_cell_prototype_name, bool xauto_access)
Creates a new unrefined (jim) unstructured block state in xhost and attaches this to it...
virtual void end_jim_edit_mode(bool xensure_lattice_invariant=true, bool xauto_access=true)
Prevent editing of jims and jim order relation.
Definition: poset.cc:253
virtual void put_dof_tuple(const void *xbuf, size_t xbuflen)=0
Copies the entire dof tuple from xbuf into internal storage.
void attach_to_state(const namespace_poset *xns, const poset_path &xpath, bool xauto_access=true)
Attach to the state specified by path xpath in the namespace xns.
virtual void get_read_access() const
Get read access to the state associated with this.
A two index array with variable length rows.
bool row_conforms_to(const schema_poset_member &xother) const
True if the row dofs defined by this agree in type and in order with the dofs defined by xother...
The type of row dof tuple for base_space_member.
bool in_jim_edit_mode() const
True if editing jims and jim order relation is allowed.
virtual schema_poset_member & schema()
The schema for this member (mutable version).
virtual void delete_cover_link(abstract_poset_member *lesser)
Delete the link from this to lesser; make lesser incomparable to this.
SHEAF_DLL_SPEC bool is_valid(pod_index_type xpod_index)
True if an only if xpod_index is valid.
Definition: pod_types.cc:37
Namespace for the fiber_bundles component of the sheaf system.
SHEAF_DLL_SPEC pod_index_type invalid_pod_index()
The invalid pod index value.
Definition: pod_types.cc:31
void build_block_pa(const base_space_member *xtemplate, const int *xglue, size_type xglue_ub, unstructured_block *result, bool xcompute_upper_cover, bool xauto_access)
Build the unstructured block result using local cell template xtemplate and the atomic equivalences (...
index_type col_ct(const index_type xrow_index) const
The number of columns for the xrow_index-th row.
void release_cover_id_space_iterator(index_space_iterator &xcover_itr) const
Returns xcover_itr to the pool of id space iterators.
virtual void release_access(bool xall=false) const
Release access. If xall is true, release all levels of access. Otherwise, release one level of access...
pod_type hub_pod() const
The current unglued hub id in the iteration. synonym for unglued_hub_pod().
A client handle for an unrestricted member of a poset. A total_poset_member is guaranteed not to be r...
static void put_name_mode(bool xmode)
Sets name_mode to xmode. Warning: creating meshes with large numbers of names may exceed limits impos...
pod_type hub_pod() const
The pod value of this mapped to the unglued hub id space.
Definition: scoped_index.h:710
const scoped_index & index() const
The index of the current member of the iteration.
virtual void begin_jim_edit_mode(bool xauto_access=true)
Allow editing of jims and jim order relation.
Definition: poset.cc:230