SheafSystem  0.0.0.0
zone_centered_triangle_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/zone_centered_triangle_refiner.h"
22 
23 #include "SheafSystem/assert_contract.h"
24 #include "SheafSystem/base_space_poset.h"
25 #include "SheafSystem/block.impl.h"
26 #include "SheafSystem/error_message.h"
27 #include "SheafSystem/field_refinement_buffer.h"
28 #include "SheafSystem/section_evaluator.h"
29 #include "SheafSystem/sec_ed_invertible.h"
30 #include "SheafSystem/field_vd.h"
31 
32 using namespace std;
33 using namespace fields; // Workaround for MS C++ bug.
34 
35 // ===========================================================
36 // ZONE_CENTERED_TRIANGLE_REFINER FACET
37 // ===========================================================
38 
39 // PUBLIC MEMBER FUNCTIONS
40 
43  : local_field_refiner(xpolicy)
44 {
45  // Preconditions:
46 
47  // Body:
48 
49  // Postconditions:
50 
51  ensure(invariant());
52  ensure(&policy() == &xpolicy);
53 
54  return;
55 }
56 
57 
60 {
61  // Preconditions:
62 
63  // Body:
64 
65  not_implemented();
66 
67  // Postconditions:
68 
69  ensure(invariant());
70 
71  return;
72 }
73 
74 
75 // PROTECTED MEMBERS FUNCTIONS
76 
79 {
80  // Preconditions:
81 
82  // Body:
83 
84  not_implemented();
85 
86  // Postconditions:
87 
88  ensure(invariant());
89 
90  return;
91 }
92 
93 void
96 {
97  // Preconditions:
98 
99  require(xbuffer.base_space != 0);
100  require(xbuffer.base_space->in_jim_edit_mode());
101 
102  // Body:
103 
104  // Modify the cover relation graph.
105 
106  modify_crg(xbuffer);
107 
108  // Modify the subposets.
109 
110  modify_subposets(xbuffer);
111 
112  // Put the new zones in the refined zone ids buffer
113 
118 
119  // Postconditions:
120 
121  // Exit:
122 
123  return;
124 }
125 
126 void
129 {
130  // Preconditions:
131 
132  require(xbuffer.base_space != 0);
133  require(xbuffer.base_space->in_jim_edit_mode());
134 
135  // Body:
136 
137  base_space_poset* lbase = xbuffer.base_space;
138  scoped_index lzone_id = xbuffer.zone_id;
139  int lzone_depth = lbase->refinement_depth(lzone_id);
140  int lnew_depth = lzone_depth + 1;
141 
142  assertion(lzone_id.same_scope(lbase->member_hub_id_space(false)));
143 
146 
147  // Unlink the lower cover of the current zone.
148 
149  pod_index_type lpoint0_id = lbase->first_cover_member(LOWER, lzone_id.pod());
150  lbase->delete_link(lzone_id.pod(), lpoint0_id);
151 
152  pod_index_type lpoint1_id = lbase->first_cover_member(LOWER, lzone_id.pod());
153  lbase->delete_link(lzone_id.pod(), lpoint1_id);
154 
155  pod_index_type lpoint2_id = lbase->first_cover_member(LOWER, lzone_id.pod());
156  lbase->delete_link(lzone_id.pod(), lpoint2_id);
157 
158 
159  // Create a new point.
160 
161  _new_point_id = lbase->member_id(create_vertex(*lbase, lnew_depth), false);
162 
163  // Create a first new triangle.
164 
165  _new_tri_0_id = lbase->member_id(create_zone(*lbase, lnew_depth), false);
166 
167  // Link the first new triangle to disc ids 0, 1, new..
168 
169  lbase->new_link(_new_tri_0_id.pod(), lpoint0_id);
170  lbase->new_link(_new_tri_0_id.pod(), lpoint1_id);
171  lbase->new_link(_new_tri_0_id.pod(), _new_point_id.pod());
172 
173  // Link the current zone to the first new triangle.
174 
175  lbase->new_link(lzone_id.pod(), _new_tri_0_id.pod());
176 
177  // Create a second new triangle.
178 
179  _new_tri_1_id = lbase->member_id(create_zone(*lbase, lnew_depth), false);
180 
181  // Link the second new triangle to disc ids 1, 2, new.
182 
183  lbase->new_link(_new_tri_1_id.pod(), lpoint1_id);
184  lbase->new_link(_new_tri_1_id.pod(), lpoint2_id);
185  lbase->new_link(_new_tri_1_id.pod(), _new_point_id.pod());
186 
187  // Link the current zone to the second new triangle.
188 
189  lbase->new_link(lzone_id.pod(), _new_tri_1_id.pod());
190 
191  // Create a third new triangle.
192 
193  _new_tri_2_id = lbase->member_id(create_zone(*lbase, lnew_depth), false);
194 
195  // Link the second new triangle to disc ids 2, 0, new..
196 
197  lbase->new_link(_new_tri_2_id.pod(), lpoint2_id);
198  lbase->new_link(_new_tri_2_id.pod(), lpoint0_id);
199  lbase->new_link(_new_tri_2_id.pod(), _new_point_id.pod());
200 
201  // Link the current zone to the second new triangle.
202 
203  lbase->new_link(lzone_id.pod(), _new_tri_2_id.pod());
204 
205  // Postconditions:
206 
207  // Exit:
208 
209  return;
210 }
211 
212 void
215 {
216  // Preconditions:
217 
218  require(xbuffer.base_space != 0);
219 
220  // Body:
221 
222  base_space_poset* lbase = xbuffer.base_space;
223  scoped_index lzone_id = xbuffer.zone_id;
224  subposet& lvertices = lbase->vertices();
225  subposet& lelements = lbase->elements();
226 
227  // More efficient to get id spaces from buffer than directly from subposets
228  // because latter uses lookup by name.
229 
230  scattered_insertion_index_space_handle* lvertices_id_space = xbuffer.vertices_id_space;
231  scattered_insertion_index_space_handle* lcoord_disc_seq_id_space = xbuffer.coord_disc_seq_id_space;
232  scattered_insertion_index_space_handle* lelements_id_space = xbuffer.elements_id_space;
233 
234  // Put the new point in the vertices subposet and extend the sequence id space.
235 
236  lvertices.insert_member(_new_point_id);
237  lvertices_id_space->push_back(_new_point_id);
238  lcoord_disc_seq_id_space->push_back(_new_point_id);
239 
240  // The refined zone is no longer an element;
241  // remove it from the elements subposet.
242 
250 
251  // When removing the member, we have to be careful to reuse its
252  // sequence id, so the sequence id stays sequential.
253 
256 
257  pod_index_type lseq_id = lelements_id_space->pod(lzone_id);
258 
259  lelements_id_space->remove(lzone_id, true);
260  lelements.remove_member(lzone_id);
261 
262  // Put the first new triangle in the elements subposet,
263  // reusing the sequence id of the old triangle.
264 
265  lelements.insert_member(_new_tri_0_id);
266  lelements_id_space->insert(lseq_id, _new_tri_0_id);
267 
268  // Put the other new triangles on the elements subposet,
269  // extending the sequence id space.
270 
271  lelements.insert_member(_new_tri_1_id);
272  lelements.id_space().push_back(_new_tri_1_id);
273 
274  lelements.insert_member(_new_tri_2_id);
275  lelements.id_space().push_back(_new_tri_2_id);
276 
277  // Postconditions:
278 
279  // Exit:
280 
281  return;
282 }
283 
284 
285 void
288 {
289  // Preconditions:
290 
291 
292  // Body:
293 
294  scoped_index lzone_id = xbuffer.zone_id;
295 
296 
297  // Set the local coordinates buffer to the center of the zone.
298 
299  xbuffer.coord_evaluator->center(xbuffer.local_coords);
300 
301  // Evaluate the global coordinates at the local coordinates.
302 
303  xbuffer.coord_evaluator->value_at_coord(xbuffer.coord_dofs,
304  xbuffer.local_coords,
305  xbuffer.coord_value);
306 
307  // Make sure the coordinates dof map has enough capacity for the new point.
308 
310 
311  // Insert the value in the coordinates section.
312 
314  xbuffer.coord_value.base(),
315  xbuffer.coord_value.ct()*sizeof(sec_vd_dof_type),
316  false);
317 
318  // Postconditions:
319 
320 
321  // Exit:
322 
323  return;
324 }
325 
326 
327 // PRIVATE MEMBERS
328 
329 //const sheaf::size_type
330 //fields::zone_centered_triangle_refiner::
331 //REFINED_ZONE_CT;
332 
333 
334 // ===========================================================
335 // LOCAL_FIELD_REFINER FACET
336 // ===========================================================
337 
338 // PUBLIC MEMBER FUNCTIONS
339 
340 int
342 db() const
343 {
344  int result;
345 
346  // Preconditions:
347 
348 
349  // Body:
350 
351  result = 2;
352 
353  // Postconditions:
354 
355  ensure(result == 2);
356 
357  // Exit:
358 
359  return result;
360 }
361 
362 const std::string&
365 {
366  // Preconditions:
367 
368 
369  // Body:
370 
371  static const string result("triangle_nodes");
372 
373  // Postconditions:
374 
375  ensure(!result.empty());
376 
377  // Exit:
378 
379  return result;
380 }
381 
385 {
386  size_type result;
387 
388  // Preconditions:
389 
390 
391  // Body:
392 
393  result = REFINED_ZONE_CT;
394 
395  // Postconditions:
396 
397  ensure(result > 1);
398 
399  // Exit:
400 
401  return result;
402 }
403 
407 {
408  // Preconditions:
409 
410  require(xi < refined_zone_ct());
411 
412  // Body:
413 
414  // Affine transformation u'[i] = T[i][j]*u[j] + T[i][db];
415  // with sum convention over 0 <= j < db.
416 
417  // Specifically:
418  //
419  // u' = a*u +b*v + c;
420  // v' = d*u _e*v + f.
421  //
422  // map = {a, b, c, d, e, f}
423  // One such map for each refined zone.
424 
425  // 6 = db*(db+1)
426 
427  static const chart_point_coord_type lmap[REFINED_ZONE_CT][6] =
428  {
429  {
430  2.0/3.0, -1.0/3.0, 1.0/3.0, -1.0/3.0, 2.0/3.0, 1.0/3.0
431  },
432  {-1.0/3.0, -1.0/3.0, 1.0/3.0, 2.0/3.0, -1.0/3.0, 1.0/3.0},
433  {-1.0/3.0, 2.0/3.0, 1.0/3.0, -1.0/3.0, -1.0/3.0, 1.0/3.0}
434  };
435 
436 
437  const chart_point_coord_type* result = lmap[xi];
438 
439  // Postconditions:
440 
441  // Exit:
442 
443  return result;
444 }
445 
446 
447 // ===========================================================
448 // ANY FACET
449 // ===========================================================
450 
451 // PUBLIC MEMBER FUNCTIONS
452 
455 clone() const
456 {
458 
459  // Preconditions:
460 
461  // Body:
462 
463  result = new zone_centered_triangle_refiner();
464 
465  // Postconditions:
466 
467  ensure(result != 0);
468  ensure(invariant());
469  ensure(result->invariant());
470  ensure(is_same_type(result));
471 
472  return result;
473 }
474 
478 {
479  // Preconditions:
480 
481  require(is_ancestor_of(&xother));
482 
483  // Body:
484 
485  not_implemented();
486 
487  // Postconditions:
488 
489  ensure(invariant());
490 
491  return *this;
492 }
493 
498 {
499 
500  // Preconditions:
501 
502  require(is_ancestor_of(&xother));
503 
504  // Body:
505 
506  not_implemented();
507 
508  // Postconditions:
509 
510  ensure(invariant());
511 
512  // Exit:
513 
514  return *this;
515 }
516 
519 {
520  // Preconditions:
521 
522  // Body:
523 
524  // Postconditions:
525 
526  ensure(invariant());
527 
528  return;
529 }
530 
531 
532 bool
534 invariant() const
535 {
536  bool result = true;
537 
538  // Preconditions:
539 
540  // Body:
541 
542  // Must satisfy base class invariant.
543 
544  result = result && local_field_refiner::invariant();
545 
546  if(invariant_check())
547  {
548  // Prevent recursive calls to invariant.
549 
551 
552  // Finished, turn invariant checking back on.
553 
555  }
556 
557  // Postconditions:
558 
559  return result;
560 }
561 
562 bool
564 is_ancestor_of(const any* xother) const
565 {
566 
567  // Preconditions:
568 
569  require(xother != 0);
570 
571  // Body:
572 
573  // True if other conforms to this
574 
575  bool result = dynamic_cast<const zone_centered_triangle_refiner*>(xother) != 0;
576 
577  // Postconditions:
578 
579  return result;
580 
581 }
582 
583 
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
virtual bool invariant() const
Class invariant.
A client handle for a subposet.
Definition: subposet.h:86
A field refiner that introduces a new vertex in the center of a triangle, but not in the edges...
section_evaluator * coord_evaluator
The section evaluator for the coordinates section of the target.
virtual bool is_ancestor_of(const any *xother) const
Conformance test; true if other conforms to this.
size_type ct() const
The number of items currently in use.
scoped_index _new_tri_1_id
The index of the second triangle added by the current base space refinement.
zone_centered_triangle_refiner()
Default constructor; disabled.
const pod_type & pod() const
The "plain old data" storage of this; the value in the external id space.
Definition: scoped_index.h:672
virtual int db() const
The base dimension; the dimension of the local coordinates (independent variable).
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.
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.
virtual void refine_base_space(field_refinement_buffer &xbuffer)
Refines the base space or the target.
pod_index_type create_vertex(base_space_poset &xbase, int xdepth)
Creates a new vertex at depth xdepth.
STL namespace.
const chart_point_coord_type * local_coordinates_map(size_type xi) const
The map from the local coordinates of refined zone xi the the local coordinates of the parent zone...
block< sec_vd_value_type > coord_value
A buffer for computing coordinates at a point.
virtual zone_centered_triangle_refiner * clone() const
Virtual constructor, creates a new instance of the same type as this.
scoped_index _new_tri_0_id
The index of the first triangle added by the current base space refinement.
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
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
The lattice of closed cells of a cellular space; a lattice representation of a computational mesh...
scoped_index _new_tri_2_id
The index of the tird triangle added by the current base space refinement.
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.
scoped_index zone_id
The id of the current zone.
scattered_insertion_index_space_handle * elements_id_space
The sequence id space used by the elements subposet.
virtual bool invariant() const
Class invariant.
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
virtual void refine_coordinates(field_refinement_buffer &xbuffer)
Refines the coordinates of the target.
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
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 center(coord_type xresult[], size_type xresult_ub) const
The local coordinates at the center of the evaluator.
virtual size_type refined_zone_ct() const
The number of refined zones created by this.
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.
virtual const std::string & zone_type_name() const
The name of the type of zone this creates during refinement.
scattered_insertion_index_space_handle * vertices_id_space
The sequence id space used by the vertices subposet.
void modify_crg(field_refinement_buffer &xbuffer)
Modifies the cover relation graph of the base space.
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 zone_centered_triangle_refiner & operator=(const local_field_refiner &xother)
Assignment operator.
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
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
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.
void modify_subposets(field_refinement_buffer &xbuffer)
Modifies subposets in the base space.
scoped_index _new_point_id
The index of the point added by the current base space refinement.
block< chart_point_coord_type > local_coords
A buffer for the local coordinates of a point.
pod_index_type create_zone(base_space_poset &xbase, int xdepth)
Creates a new quadrangle in base space xbase, with refinement depth xdepth.
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.
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
block< scoped_index > _refined_zone_ids
The member ids of the zones created by the most recent execution of refine().