SheafSystem  0.0.0.0
edge_centered_polygon_refiner.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/edge_centered_polygon_refiner.h"
22 
23 #include "SheafSystem/assert_contract.h"
24 #include "SheafSystem/base_space_poset.h"
25 #include "SheafSystem/bilinear_2d.h"
26 #include "SheafSystem/block.impl.h"
27 #include "SheafSystem/error_message.h"
28 #include "SheafSystem/field_refinement_buffer.h"
29 #include "SheafSystem/index_space_iterator.h"
30 #include "SheafSystem/integrable_section_evaluator.h"
31 #include "SheafSystem/linear_2d.h"
32 #include "SheafSystem/sec_ed_invertible.h"
33 #include "SheafSystem/std_algorithm.h"
34 #include "SheafSystem/std_iostream.h"
35 #include "SheafSystem/field_vd.h"
36 
37 using namespace std;
38 using namespace fields; // Workaround for MS C++ bug.
39 
40 // #define DIAGNOSTIC_OUTPUT 1
41 
42 // ===========================================================
43 // EDGE_CENTERED_POLYGON_REFINER FACET
44 // ===========================================================
45 
46 // PROTECTED MEMBER FUNCTIONS
47 
50  : local_field_refiner(xpolicy)
51 {
52  // Preconditions:
53 
54  // Body:
55 
57 
59 
60  // Postconditions:
61 
62  ensure(invariant());
63  ensure(&policy() == &xpolicy);
64 
65  return;
66 }
67 
68 
71  : local_field_refiner(xother)
72 {
73  // Preconditions:
74 
75  // Body:
76 
77  not_implemented();
78 
79  // Postconditions:
80 
81  ensure(invariant());
82 
83  return;
84 }
85 
89 {
90  size_type result = 0;
91 
92  // Preconditions:
93 
94 
95  // Body:
96 
97  is_abstract();
98 
99  // Postconditions:
100 
101  ensure(result > 0);
102 
103  // Exit:
104 
105  return result;
106 }
107 
111 {
112 
113  // Preconditions:
114 
115 
116  // Body:
117 
118  // Since the number of refined verteices is
119  // the number of unrefined vertices plus the
120  // number of edges and the numbeer of edges
121  // is equal to the number of unrefined vertices,
122  // the number of refined vertices is always
123  // twice the number of refined vertices.
124 
125  size_type result = 2*unrefined_vertex_ct();
126 
127  // Postconditions:
128 
129  ensure(result == 2*unrefined_vertex_ct());
130 
131  // Exit:
132 
133  return result;
134 }
135 
138 edge_ct() const
139 {
140  size_type result;
141 
142  // Preconditions:
143 
144 
145  // Body:
146 
147  // Since every unrefined vertex is the first vertex of an edge,
148  // the number of edges is always equal to the number of unrefined vertices.
149 
150  result = unrefined_vertex_ct();
151 
152  // Postconditions:
153 
154  ensure(result == unrefined_vertex_ct());
155 
156  // Exit:
157 
158  return result;
159 }
160 
161 bool
164 {
165  bool result = false;
166 
167  // Preconditions:
168 
169 
170  // Body:
171 
172  is_abstract();
173 
174  // Postconditions:
175 
176 
177  // Exit:
178 
179  return result;
180 }
181 
184 {
185  // Preconditions:
186 
187  // Body:
188 
189  not_implemented();
190 
192 
193  // Postconditions:
194 
195  ensure(invariant());
196 
197  return;
198 }
199 
200 void
203 {
204  // Preconditions:
205 
206 
207  // Body:
208 
209  size_type l_ub = 16; // arbitrary, will resize as needed
210  _vertex_ids.reserve(l_ub);
211  _is_new_vertex.reserve(l_ub);
212  _vertex_pos.reserve(l_ub);
213 
214  // Postconditions:
215 
216 
217  // Exit:
218 
219  return;
220 }
221 
222 
223 void
226 {
227  // Preconditions:
228 
229  require(xbuffer.base_space != 0);
230  require(xbuffer.base_space->in_jim_edit_mode());
231 
232  // Body:
233 
234  // Modify the cover relation graph.
235 
236  modify_crg(xbuffer);
237 
238  // Modify the subposets.
239 
240  modify_subposets(xbuffer);
241 
242  // Postconditions:
243 
244  // Exit:
245 
246  return;
247 }
248 
249 void
252 {
253  // Preconditions:
254 
255  require(xbuffer.base_space != 0);
256  require(xbuffer.base_space->in_jim_edit_mode());
257 
258  // Body:
259 
260  make_new_vertices(xbuffer);
261 
262  make_new_zones(xbuffer);
263 
264  // Postconditions:
265 
266  ensure(_refined_zone_ids.ct() == refined_zone_ct());
267 
268  // Exit:
269 
270  return;
271 }
272 
273 void
276 {
277  // Preconditions:
278 
279  require(xbuffer.base_space != 0);
280 
281  // Body:
282 
283  base_space_poset* lbase = xbuffer.base_space;
284  scoped_index lzone_id = xbuffer.zone_id;
285  subposet& lvertices = lbase->vertices();
286  subposet& lelements = lbase->elements();
287 
288  // More efficient to get id spaces from buffer than directly from subposets
289  // because latter uses lookup by name.
290 
291  scattered_insertion_index_space_handle* lvertices_id_space = xbuffer.vertices_id_space;
292  scattered_insertion_index_space_handle* lcoord_disc_seq_id_space = xbuffer.coord_disc_seq_id_space;
293  scattered_insertion_index_space_handle* lelements_id_space = xbuffer.elements_id_space;
294 
295  // Put the new points in the vertices subposet and extend the sequence id space.
296 
297  for(int i=0; i < _vertex_ids.ct(); ++i)
298  {
299  scoped_index le_ctr = _vertex_ids[i];
300  if(_is_new_vertex[i])
301  {
302  lvertices.insert_member(le_ctr);
303  lvertices_id_space->push_back(le_ctr);
304  lcoord_disc_seq_id_space->push_back(le_ctr);
305  }
306  }
307 
309  {
310  lvertices.insert_member(_zone_ctr_id);
311  lvertices_id_space->push_back(_zone_ctr_id);
312  lcoord_disc_seq_id_space->push_back(_zone_ctr_id);
313  }
314 
315  // The refined zone is no longer an element;
316  // remove it from the elements subposet.
317 
325 
326  // When removing the member, we have to be careful to reuse its
327  // sequence id, so the sequence id stays sequential.
328 
331 
332  pod_index_type lseq_id = lelements_id_space->pod(lzone_id);
333 
334  lelements_id_space->remove(lzone_id, true);
335  lelements.remove_member(lzone_id);
336 
337  // Put the first new triangle in the elements subposet,
338  // reusing the sequence id of the old triangle.
339 
340  lelements.insert_member(_refined_zone_ids[0]);
341  lelements_id_space->insert(lseq_id, _refined_zone_ids[0]);
342 
343  // Put the other new triangles on the elements subposet,
344  // extending the sequence id space.
345 
346  for(int i=1; i < _refined_zone_ids.ct(); ++i)
347  {
348  lelements.insert_member(_refined_zone_ids[i]);
349  lelements_id_space->push_back(_refined_zone_ids[i]);
350  }
351 
352  // Postconditions:
353 
354  // Exit:
355 
356  return;
357 }
358 
359 
360 void
363 {
364  // Preconditions:
365 
366  require(xbuffer.base_space != 0);
367  require((dynamic_cast<bilinear_2d*>(xbuffer.coord_evaluator) != 0) ||
368  (dynamic_cast<linear_2d*>(xbuffer.coord_evaluator) != 0) );
369 
370  // Body:
371 
372  base_space_poset* lbase = xbuffer.base_space;
373  scoped_index lzone_id = xbuffer.zone_id;
374  section_evaluator* lcoord_evaluator = xbuffer.coord_evaluator;
375 
377 
378  bilinear_2d* lquad_evaluator = dynamic_cast<bilinear_2d*>(xbuffer.coord_evaluator);
379  linear_2d* ltri_evaluator = dynamic_cast<linear_2d*>(xbuffer.coord_evaluator);
380 
381  sec_vd& lcoordinates = xbuffer.target.coordinates();
382 
383  // Vertices at edge centers:
384 
385  for(int i=0; i<edge_ct(); ++i)
386  {
387  // The edges are at the odd offsets in the vertex buffers.
388 
389  int le = 2*i+1;
390 
391  if(_is_new_vertex[le])
392  {
393  // This is a new vertex; set its coordinates.
394  // Get the local coordinates:
395 
396  if(lquad_evaluator != 0)
397  {
398  lquad_evaluator->edge_center(i, xbuffer.local_coords);
399  }
400  else
401  {
402  ltri_evaluator->edge_center(i, xbuffer.local_coords);
403  }
404 
405  // Evaluate the global coordinates at the local coordinates.
406 
407  lcoord_evaluator->value_at_coord(xbuffer.coord_dofs,
408  xbuffer.local_coords,
409  xbuffer.coord_value);
410 
411 #ifdef DIAGNOSTIC_OUTPUT
412 
413  cout << "vertex: " << _vertex_ids[le] << endl
414  << " local coords: " << xbuffer.local_coords
415  << " global coords: " << xbuffer.coord_value
416  << endl;
417 #endif
418 
419  // Make sure the coordinates dof map has enough capacity for the new point.
420 
421  xbuffer.reserve_coord_fiber(_vertex_ids[le]);
422 
423  // Insert the value in the coordinates section.
424 
425  lcoordinates.put_fiber(_vertex_ids[le],
426  xbuffer.coord_value.base(),
427  xbuffer.coord_value.ct()*sizeof(sec_vd_dof_type),
428  false);
429  }
430  }
431 
432  // Vertex at zone center:
433 
435  {
436 
437  // Set the local coordinates buffer to the center of the zone.
438 
439  lcoord_evaluator->center(xbuffer.local_coords);
440 
441  // Evaluate the global coordinates at the local coordinates.
442 
443  lcoord_evaluator->value_at_coord(xbuffer.coord_dofs,
444  xbuffer.local_coords,
445  xbuffer.coord_value);
446 
447  // Make sure the coordinates dof map has enough capacity for the new point.
448 
450 
451  // Insert the value in the coordinates section.
452 
453  lcoordinates.put_fiber(_zone_ctr_id,
454  xbuffer.coord_value.base(),
455  xbuffer.coord_value.ct()*sizeof(sec_vd_dof_type),
456  false);
457  }
458 
459 
460 
461  // Postconditions:
462 
463 
464  // Exit:
465 
466  return;
467 }
468 
469 
470 // PRIVATE MEMBER FUNCTIONS
471 
475  const scoped_index& xzone_id,
476  int xdepth,
477  const scoped_index& xprev_mbr_id,
478  const scoped_index& xmbr_id)
479 {
480  // Preconditions:
481 
482  require(xbase.in_jim_edit_mode());
483  require(xbase.contains_member(xzone_id));
484  require(xzone_id.same_scope(xbase.member_hub_id_space(false)));
485  require(xprev_mbr_id.same_scope(xbase.member_hub_id_space(false)));
486  require(xmbr_id.same_scope(xbase.member_hub_id_space(false)));
487 
488  // Body:
489 
490  // Create the edge center vertex.
491 
492  pod_index_type result = create_vertex(xbase, xdepth);
493 
494  // Each edge is contained in at most 2 triangles.
495  // In the current triangle, the vertices of the current edge
496  // have local indices xid-1 and xid+1, in that order.
497  // In the other triangle, if it exists, the same vertices will
498  // occur in the opposite order. Get their global ids:
499 
500  scoped_index ledge_begin = xmbr_id;
501  scoped_index ledge_end = xprev_mbr_id;
502 
503  // Note that begin and end refer to the order in the other triangle.
504 
505  // Find the other triangle, if it exists.
506 
507  // Iterate over the upper cover of the first vertex.
508 
509  index_space_iterator& uc_itr = xbase.get_cover_id_space_iterator(UPPER, ledge_begin);
510 
511  while(!uc_itr.is_done())
512  {
513  if(uc_itr.hub_pod() == xzone_id.pod())
514  {
515  // This is the triangle we're refining; skip it.
516 
517  uc_itr.next();
518  }
519  else
520  {
521  // We know that the lower cover of the current upper cover
522  // member contains ledge_begin, find it.
523 
525 
526  while(lc_itr.hub_pod() != ledge_begin.pod())
527  {
528  lc_itr.next();
529  }
530 
531  assertion(lc_itr.hub_pod() == ledge_begin.pod());
532 
533  // Now the lower cover iterator is pointing at an occurence
534  // of ledge_begin in some edge, we need to determine
535  // whether it is the edge we are looking for.
536 
537  // Get the other end of the current edge;
538  // it is either the next member of the lower cover
539  // or the first member.
540 
541  lc_itr.next();
542 
543  pod_index_type lother_end = (!lc_itr.is_done())
544  ? lc_itr.hub_pod()
545  : xbase.first_cover_member(LOWER, uc_itr.hub_pod());
546 
547  if(lother_end == ledge_end.pod())
548  {
549  // Found the edge we're looking for; insert the
550  // new edge center vertex in the lower cover
551  // between ledge_begin and ledge_end.
552 
553  if(lc_itr.is_done())
554  {
555  // Iterator is done, insert at the end of cover.
556 
557  xbase.insert_cover_member(result, LOWER, uc_itr.hub_pod());
558  }
559  else
560  {
561  // Iterator is not done, insert at the iterator position.
562 
563  xbase.insert_cover_member(result, LOWER, uc_itr.hub_pod(), lc_itr);
564  }
565 
566  // We're done
567 
568  break;
569  }
570  else
571  {
572  // This is not the edge we are looking for;
573  // so the edge is not in this member of the upper cover.
574  // Move to the next member of the upper cover.
575 
576  uc_itr.next();
577  }
578 
579  xbase.release_cover_id_space_iterator(lc_itr);
580  }
581  }
582  xbase.release_cover_id_space_iterator(uc_itr);
583 
584  // Postconditions:
585 
586  ensure(xbase.contains_member(result));
587  ensure(xbase.refinement_depth(result) == xdepth);
588 
589  // The following is made unexecutable because it is expensive,
590  // have to search the upper cover of bottom, which is O(#vertices).
591 
592  ensure(unexecutable(xbase.contains_cover_link(result, BOTTOM_INDEX)));
593 
594  // Exit:
595 
596  return result;
597 }
598 
599 void
602 {
603  // Preconditions:
604 
605  require(xbuffer.base_space != 0);
606  require(xbuffer.base_space->in_jim_edit_mode());
607 
608  // Body:
609 
610  base_space_poset* lbase = xbuffer.base_space;
611  scoped_index lzone_id = xbuffer.zone_id;
612 
613  // The vertices in the boundary of the refinement include
614  // the original vertices and the/ vertices at the center of the edges.
615  // The boundary may also include additional vertices from adjacent,
616  // more highly refined, these appear between the desired vertices
617  // and should appear in the lower cover of the new zone which contains them.
618 
619  int lzone_depth = lbase->refinement_depth(lzone_id);
620  int lnew_depth = lzone_depth + 1;
621 
622  // Initialize the new point and new triangle buffers.
623 
624  _vertex_ids.set_ct(0);
626  _vertex_pos.set_ct(0);
627  _vertex_list.clear();
628 
629  // Copy the lower cover of the zone to the vertex buffer.
631 
632  index_space_iterator& lc_itr = lbase->get_cover_id_space_iterator(LOWER, lzone_id);
633  scoped_index lvertex_id(lbase->member_hub_id_space(false));
634  while(!lc_itr.is_done())
635  {
636  lvertex_id = lc_itr.hub_pod();
637  _vertex_list.push_back(lvertex_id);
638  lc_itr.next();
639  }
640 
641  // Duplicate the first vertex at the end;
642 
643  _vertex_list.insert(_vertex_list.end(), *_vertex_list.begin());
644 
645  // Delete all the links between the original zone and its vertices.
646  // Could call delete_link for each member of the lower cover, but
647  // more efficient to do it in the following way:
648 
649  lc_itr.reset();
650  while(!lc_itr.is_done())
651  {
652  lbase->remove_cover_member(lzone_id.pod(), UPPER, lc_itr.hub_pod());
653  lc_itr.next();
654  }
655  lbase->clear_cover(LOWER, lzone_id);
656 
657  lbase->release_cover_id_space_iterator(lc_itr);
658 
659  // Create any edge centers that aren't already there.
660  // If two vertices in sequence are unrefined, there
661  // should be an edge center between them.
662 
663  vertex_list_type::iterator litr = _vertex_list.begin();
664  scoped_index l_id = *litr;
665  bool lunrefined = (lbase->refinement_depth(l_id) < lnew_depth);
666 
667  // The first vertex must be unrefined
668 
669  assertion(lunrefined);
670 
671  // Store it and mark it not new
672 
673  _vertex_ids.push_back(l_id);
674  _is_new_vertex.push_back(false);
675  _vertex_pos.push_back(litr);
676 
677  scoped_index& lprev_id = l_id;
678  bool lprev_unrefined = lunrefined;
679  ++litr;
680 
681  scoped_index ledge_ctr(lbase->member_hub_id_space(false));
682 
683  while(litr != _vertex_list.end())
684  {
685  scoped_index& l_id = *litr;
686  int ldepth = lbase->refinement_depth(l_id);
687  lunrefined = (ldepth < lnew_depth);
688 
689  if(lunrefined && lprev_unrefined)
690  {
691  // Two unrefined vertices in sequence;
692  // create an edge center between them.
693 
694  ledge_ctr =
695  create_edge_center(*lbase, lzone_id, lnew_depth, lprev_id, l_id);
696 
697  // Insert the edge center between the two unrefined vertices.
698 
699  vertex_list_type::iterator ledge_ctr_pos = _vertex_list.insert(litr, ledge_ctr);
700 
701  // Store the edge center and mark it new
702 
703  _vertex_ids.push_back(ledge_ctr);
705  _vertex_pos.push_back(ledge_ctr_pos);
706  }
707 
708  if(ldepth <= lnew_depth)
709  {
710  // This is a previously created vertex at this refinement depth.
711  // Store it and mark it not new
712 
713  _vertex_ids.push_back(l_id);
714  _is_new_vertex.push_back(false);
715  _vertex_pos.push_back(litr);
716  }
717  else
718  {
719  // This is a previously created vertex in some more highly
720  // refined adjacent triangle; ignore it.
721  }
722 
723 
724  lprev_id = l_id;
725  lprev_unrefined = lunrefined;
726  ++litr;
727  }
728 
729  // Now we should have visited all the edge vertices in this refinement.
730  // There are refined_vertex_ct()+1 vertices in each buffer because the
731  // 1st vertex is duplicated at the end. Remove it.
732 
736 
737  // Remove the duplicate vertex at the end of the vertex buffer.
738 
739  _vertex_list.pop_back();
740 
742  {
743  // Create the vertex in the center of the zone.
744 
745  _zone_ctr_id = lbase->member_id(create_vertex(*lbase, lnew_depth), false);
746  }
747 
748 #ifdef DIAGNOSTIC_OUTPUT
749  cout << "refined_vertex_ct: " << refined_vertex_ct() << endl;
750  cout << "center vertex: " << _zone_ctr_id << endl;
751  cout << "vertex_ids:\t" << _vertex_ids << endl;
752  cout << "is_new_vertex:\t" << _is_new_vertex << endl;
753  cout << "vertex buffer:\t ";
754  copy(_vertex_list.begin(), _vertex_list.end(), ostream_iterator<scoped_index>(cout, " "));
755  cout << endl << endl;
756 #endif
757 
758  // Postconditions:
759 
760  // Now there should be refined_vertex_ct() entries in each buffer.
761 
762  ensure(_vertex_ids.ct() == refined_vertex_ct());
763  ensure(_is_new_vertex.ct() == refined_vertex_ct());
764  ensure(_vertex_pos.ct() == refined_vertex_ct());
765 
766  // Exit:
767 
768  return;
769 }
770 
774 {
775  static const block<size_type> result;
776 
777  // Preconditions:
778 
779 
780  // Body:
781 
782  is_abstract();
783 
784  // Postconditions:
785 
786  ensure(result.ct() > 1);
787 
788  // Exit:
789 
790  return result;
791 }
792 
793 void
796 {
797  // Preconditions:
798 
799  require(xbuffer.base_space != 0);
800  require(xbuffer.base_space->in_jim_edit_mode());
801 
802  // Body:
803 
804  base_space_poset* lbase = xbuffer.base_space;
805  scoped_index lzone_id = xbuffer.zone_id;
806 
807  int lzone_depth = lbase->refinement_depth(lzone_id);
808  int lnew_depth = lzone_depth + 1;
809 
811 
812  // Create the new edge-centered zones;
813  // number of edges == number of unrefined vertices.
814  // edge centers are at index 1, 3, 5, and 7 in _vertex_pos and _vertex_ids.
815 
816  scoped_index lnew_zone;
817  const block<size_type>& lfirst_vertex_index = first_vertex_index();
818 
819  // Number of zones is one less than number of entries in first_vertex_index
820  // because last entry is duplicate of first.
821 
822  size_type lzone_ct = lfirst_vertex_index.ct() - 1;
823 
824  for(size_type i=0; i<lzone_ct; ++i)
825  {
826  // Create the zone.
827 
828  lnew_zone = lbase->member_id(create_zone(*lbase, lnew_depth), false);
829  _refined_zone_ids.push_back(lnew_zone);
830 
831  // Create the upper cover of the new zone.
832 
833  lbase->new_link(lzone_id, lnew_zone);
834 
835  // Create the lower cover of the new zone.
836  // The lower cover contains all the vertices in _vertex_list
837  // between _vertex_pos[le] and _vertex_pos[le+2],
838  // with appropriate "circular" indexing taken into account.
839 
840  // Get the position of the first vertex for this zone.
841 
842  size_type lv_first = lfirst_vertex_index[i];
843  vertex_list_type::iterator litr = _vertex_pos[lv_first];
844 
845  // Get the position of the last vertex for this zone;
846  // last vertex for this zone is first vertex for next zone.
847  // Note that last entry in first_vertex_index contains duplicate
848  // of first entry so i+1 won't run off the end.
849 
850  size_type lv_last = lfirst_vertex_index[i+1];
851  vertex_list_type::iterator llast_vertex_pos = _vertex_pos[lv_last];
852 
853  // Link all the vertices between first and last, inclusive.
854 
855  while(litr != llast_vertex_pos)
856  {
857 
858  lbase->new_link(lnew_zone, *litr);
859 
860  if(++litr == _vertex_list.end())
861  {
862  // Off the end; wrap around to the beginning.
863 
864  litr = _vertex_list.begin();
865  }
866  }
867 
868  assertion(litr == llast_vertex_pos);
869 
870  lbase->new_link(lnew_zone, *litr);
871 
873  {
874  // Link the zone center vertex.
875 
876  lbase->new_link(lnew_zone, _zone_ctr_id);
877  }
878 
879 
880 #ifdef DIAGNOSTIC_OUTPUT
881 
882  cout << "zone: " << setw(6) << lnew_zone;
883  cout << " lower cover: ";
884  cover_set_state& lnew_zone_cvr = lbase->lower_cover(lnew_zone);
885  copy(lnew_zone_cvr.begin(),
886  lnew_zone_cvr.end(),
887  ostream_iterator<scoped_index>(cout, " "));
888  cout << endl;
889 #endif
890 
891  }
892 
893  // Postconditions:
894 
895  // Exit:
896 
897  return;
898 }
899 
900 
901 // ===========================================================
902 // LOCAL_FIELD_REFINER FACET
903 // ===========================================================
904 
905 // PUBLIC MEMBER FUNCTIONS
906 
907 int
909 db() const
910 {
911  int result;
912 
913  // Preconditions:
914 
915 
916  // Body:
917 
918  result = 2;
919 
920  // Postconditions:
921 
922  ensure(result == 2);
923 
924  // Exit:
925 
926  return result;
927 }
928 
929 
930 // ===========================================================
931 // ANY FACET
932 // ===========================================================
933 
934 // PUBLIC MEMBER FUNCTIONS
935 
938 clone() const
939 {
940  edge_centered_polygon_refiner* result = 0;
941 
942  // Preconditions:
943 
944  // Body:
945 
946  is_abstract();
947 
948  // Postconditions:
949 
950  ensure(result != 0);
951  // ensure(invariant());
952  ensure(result->invariant());
953  ensure(is_same_type(result));
954 
955  return result;
956 }
957 
961 {
962  // Preconditions:
963 
964  require(is_ancestor_of(&xother));
965 
966  // Body:
967 
968  not_implemented();
969 
970  // Postconditions:
971 
972  ensure(invariant());
973 
974  return *this;
975 }
976 
981 {
982 
983  // Preconditions:
984 
985  require(is_ancestor_of(&xother));
986 
987  // Body:
988 
989  not_implemented();
990 
991  // Postconditions:
992 
993  ensure(invariant());
994 
995  // Exit:
996 
997  return *this;
998 }
999 
1002 {
1003  // Preconditions:
1004 
1005  // Body:
1006 
1007  // Postconditions:
1008 
1009  ensure(invariant());
1010 
1011  return;
1012 }
1013 
1014 
1015 bool
1017 invariant() const
1018 {
1019  bool result = true;
1020 
1021  // Preconditions:
1022 
1023  // Body:
1024 
1025  // Must satisfy base class invariant.
1026 
1027  result = result && local_field_refiner::invariant();
1028 
1029  if(invariant_check())
1030  {
1031  // Prevent recursive calls to invariant.
1032 
1034 
1035  // Finished, turn invariant checking back on.
1036 
1038  }
1039 
1040  // Postconditions:
1041 
1042  return result;
1043 }
1044 
1045 bool
1047 is_ancestor_of(const any* xother) const
1048 {
1049 
1050  // Preconditions:
1051 
1052  require(xother != 0);
1053 
1054  // Body:
1055 
1056  // True if other conforms to this
1057 
1058  bool result = dynamic_cast<const edge_centered_polygon_refiner*>(xother) != 0;
1059 
1060  // Postconditions:
1061 
1062  return result;
1063 
1064 }
1065 
1066 
1067 
block< vertex_list_type::iterator > _vertex_pos
The position in _vertex_list of ids of the vertices in the currnet refinement.
vertex_list_type _vertex_list
List for processing vertices.
virtual bool invariant() const
Class invariant.
A client handle for a subposet.
Definition: subposet.h:86
section_evaluator * coord_evaluator
The section evaluator for the coordinates section of the target.
virtual void refine_base_space(field_refinement_buffer &xbuffer)
Refines the base space or the target.
void insert_cover_member(pod_index_type xother_mbr_hub_id, bool xlower, pod_index_type xmbr_hub_id)
Inserts hub id xother_mbr_hub id in the lower (xlower true) or upper (xlower false) cover set of the ...
size_type ct() const
The number of items currently in use.
const pod_type & pod() const
The "plain old data" storage of this; the value in the external id space.
Definition: scoped_index.h:672
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...
scattered_insertion_index_space_handle * coord_disc_seq_id_space
The discretization sequence id space of the target coordinates.
A buffer for data which is used by both a local_field_refiner object and its associated field_refinem...
Namespace for fields component of sheaf system.
int refinement_depth(pod_index_type xmbr_hub_id) const
The refinement depth of the member with hub id xmbr_hub_id.
An abstract field refiner that subdivides a polygon by introducing new vertices into the centers of t...
virtual size_type refined_zone_ct() const =0
The number of refined zones created by this.
virtual const block< size_type > & first_vertex_index() const =0
The index in _vertex_pos of the first vertex of each new zone; contains number of zones + 1 because f...
size_type remove(const scoped_index &xid, bool update_extrema)
Removes the equivalence associated with xid.hub_pod(). synonym for remove_hub(xid.hub_pod(), xupdate_extrema). Returns the number of entries actually removed, either 0 or 1.
pod_index_type create_vertex(base_space_poset &xbase, int xdepth)
Creates a new vertex at depth xdepth.
pod_index_type create_edge_center(base_space_poset &xbase, const scoped_index &xzone_id, int xdepth, const scoped_index &xprev_mbr_id, const scoped_index &xmbr_id)
Creates a new edge center vextex and puts it in _new_point_ids[xid].
edge_centered_polygon_refiner()
Default constructor; disabled.
STL namespace.
void reserve(index_type xub)
Makes ub() at least xub; if new storage is allocated, it is uninitialized.
void make_new_zones(field_refinement_buffer &xbuffer)
Make the new zones in the refinement.
block< bool > _is_new_vertex
True if i-th member is a new vertex.
size_type refined_vertex_ct() const
The number of boundary vertices with refinement depth <= refined zone depth; does not include center ...
block< sec_vd_value_type > coord_value
A buffer for computing coordinates at a point.
void invalidate()
Make this id invalid.
Definition: scoped_index.h:852
virtual void next()=0
Makes id() the next id in the iteration.
block< scoped_index > _vertex_ids
The ids of the vertices in boundary <= new refinement depth.
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 pod_type pod(pod_type xid) const
The pod index in this space equivalent to xid in the hub id space.
block< sec_vd_dof_type > coord_dofs
A buffer for gathering coordinate dofs.
bool same_scope(const scoped_index &xother) const
True if and only if this is in the same id space as xother.
Definition: scoped_index.h:464
virtual void reset()=0
Restarts the iteration.
const field_refinement_policy & policy() const
The refinement policy for this refiner.
Abstract base class with useful features for all objects.
Definition: any.h:39
virtual int db() const
The base dimension; the dimension of the local coordinates (independent variable).
The lattice of closed cells of a cellular space; a lattice representation of a computational mesh...
void reserve_coord_fiber(const scoped_index &xdisc_id)
Ensures the coordinate dofs have enough capacity for discretization id xdisc.
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.
scoped_index zone_id
The id of the current zone.
void pop_back()
Remove item at the back.
scattered_insertion_index_space_handle * elements_id_space
The sequence id space used by the elements subposet.
subposet & vertices()
The subposet containing all the vertices, that is, the cells of dimension 0 (mutable version)...
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
void edge_center(pod_index_type xi, coord_type xresult[], size_type xresult_ub) const
The local cordinates of the xi-th edge.
Definition: bilinear_2d.cc:939
unsigned long size_type
An unsigned integral type used to represent sizes and capacities.
Definition: sheaf.h:52
An abstract policy that determines the conditions under which a zone should be refined.
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
virtual bool is_ancestor_of(const any *xother) const
Conformance test; true if other conforms to this.
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. ...
void edge_center(pod_index_type xi, coord_type xresult[], size_type xresult_ub) const
The local cordinates of the xi-th edge.
Definition: linear_2d.cc:729
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 edge_centered_polygon_refiner * clone() const =0
Virtual constructor, creates a new instance of the same type as this.
virtual void center(coord_type xresult[], size_type xresult_ub) const
The local coordinates at the center of the evaluator.
void disable_invariant_check() const
Disable invariant check. Intended for preventing recursive calls to invariant and for suppressing inv...
Definition: any.h:97
field_vd & target
The field being refined.
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
const hub_index_space_handle & member_hub_id_space(bool xauto_access) const
The member hub id space.
scattered_insertion_index_space_handle * vertices_id_space
The sequence id space used by the vertices subposet.
const bool LOWER
Selector for lower cover.
Definition: sheaf.h:67
void reserve_vertex_buffers()
Reserves space in vertex buffers.
virtual size_type unrefined_vertex_ct() const =0
The number of vertices with refinement depth <= unrefined zone depth.
An abstract refiner for a field over a local region (primitive cell) in the base space.
bool invariant_check() const
True if invariant checking is enabled.
Definition: any.h:79
void put_fiber(pod_index_type xdisc_id, const vd_lite &xfiber)
Sets the fiber referred to by discretization id xdisc_id to xfiber.
Definition: sec_vd.cc:1144
A section evaluator using linear interpolation over a triangular 2D domain.
Definition: linear_2d.h:39
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
int_type pod_index_type
The plain old data index type.
Definition: pod_types.h:49
virtual void refine_coordinates(field_refinement_buffer &xbuffer)
Refines the coordinates of the target.
A handle for a scattered_insertion_index_space_state.
sec_ed_invertible & coordinates() const
The independent variable of this field.
Definition: field_vd.cc:339
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_...
subposet & elements()
The subposet containing the elements or zones, that is, the cells of maximal dimension.
virtual edge_centered_polygon_refiner & operator=(const local_field_refiner &xother)
Assignment operator.
block< chart_point_coord_type > local_coords
A buffer for the local coordinates of a point.
pod_index_type first_cover_member(bool xlower, pod_index_type xmbr_hub_id) const
Hub id of the first member of the lower (xlower true) or upper (xlower false) cover of the member wit...
pod_index_type create_zone(base_space_poset &xbase, int xdepth)
Creates a new quadrangle in base space xbase, with refinement depth xdepth.
size_type edge_ct() const
The number of edges in the zone.
scoped_index _zone_ctr_id
The id of the new vertex in the center of the zone.
virtual bool invariant() const
Class invariant.
void make_new_vertices(field_refinement_buffer &xbuffer)
Makes new vertices in edge centers as needed and builds the list of vertices in the boundary of the z...
base_space_poset * base_space
The current base space.
double sec_vd_dof_type
The type of degree of freedom in the section space.
Definition: fiber_bundle.h:78
bool in_jim_edit_mode() const
True if editing jims and jim order relation is allowed.
virtual bool is_zone_centered_refiner() const =0
True if this adds a vertex at the center of the zone.
An auto_block with a no-initialization initialization policy.
A section evaluator using bilinear interpolation over a square 2D domain.
Definition: bilinear_2d.h:42
bool is_same_type(const any *other) const
True if other is the same type as this.
Definition: any.cc:79
void enable_invariant_check() const
Enable invariant checking.
Definition: any.h:87
virtual void modify_crg(field_refinement_buffer &xbuffer)
Modifies the cover relation graph of the base space.
block< scoped_index > _refined_zone_ids
The member ids of the zones created by the most recent execution of refine().
void release_cover_id_space_iterator(index_space_iterator &xcover_itr) const
Returns xcover_itr to the pool of id space iterators.
pod_type hub_pod() const
The current unglued hub id in the iteration. synonym for unglued_hub_pod().
void modify_subposets(field_refinement_buffer &xbuffer)
Modifies subposets in the base space.