SheafSystem  0.0.0.0
zone_centered_tet_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_tet_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_TET_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  // Postconditions:
113 
114  // Exit:
115 
116  return;
117 }
118 
119 void
122 {
123  // Preconditions:
124 
125  require(xbuffer.base_space != 0);
126  require(xbuffer.base_space->in_jim_edit_mode());
127 
128  // Body:
129 
130  base_space_poset* lbase = xbuffer.base_space;
131  scoped_index lzone_id = xbuffer.zone_id;
132  int lzone_depth = lbase->refinement_depth(lzone_id);
133  int lnew_depth = lzone_depth + 1;
134 
135  assertion(lzone_id.same_scope(lbase->member_hub_id_space(false)));
136 
138  _vertex_ids.set_ct(0);
139 
142 
143  // Unlink the lower cover of the current zone
144  // and copy the vertex ids
145 
146  scoped_index lbegin(lbase->member_hub_id_space(false));
147 
148  while(!lbase->cover_is_empty(LOWER, lzone_id))
149  {
150  lbegin = lbase->first_cover_member(LOWER, lzone_id.pod());
151  _vertex_ids.push_back(lbegin);
152  lbase->delete_link(lzone_id.pod(), lbegin.pod());
153  }
154 
155  // Create the new vertex in the center of the zone.
156 
157  _zone_ctr_id = lbase->member_id(create_vertex(*lbase, lnew_depth), false);
158 
159  static const size_type conn[REFINED_ZONE_CT][3] =
160  {
161  {
162  0, 1, 2
163  },
164  {0, 1, 3},
165  {0, 2, 3},
166  {1, 2, 3}
167  };
168 
169  for(size_type i=0; i<REFINED_ZONE_CT; ++i)
170  {
171  // Create the new tet.
172 
173  scoped_index lnew_tet_id = lbase->member_id(create_zone(*lbase, lnew_depth), false);
174 
175  // Link it to the original vertices it contains.
176 
177  for(size_type j=0; j<3; ++j)
178  {
179  lbase->new_link(lnew_tet_id, _vertex_ids[conn[i][j]]);
180  }
181 
182  // Link it to the center vertex.
183 
184  lbase->new_link(lnew_tet_id, _zone_ctr_id);
185 
186  // Link the original tet to the new tet.
187 
188  lbase->new_link(lzone_id, lnew_tet_id);
189 
190  // Store it.
191 
192  _refined_zone_ids.push_back(lnew_tet_id);
193  }
194 
195  // Postconditions:
196 
197  // Exit:
198 
199  return;
200 }
201 
202 void
205 {
206  // Preconditions:
207 
208  require(xbuffer.base_space != 0);
209 
210  // Body:
211 
212  base_space_poset* lbase = xbuffer.base_space;
213  scoped_index lzone_id = xbuffer.zone_id;
214  subposet& lvertices = lbase->vertices();
215  subposet& lelements = lbase->elements();
216 
217  // More efficient to get id maps from buffer than directly from subposets
218  // because latter uses lookup by name.
219 
220  scattered_insertion_index_space_handle* lvertices_id_space = xbuffer.vertices_id_space;
221  scattered_insertion_index_space_handle* lcoord_disc_seq_id_space = xbuffer.coord_disc_seq_id_space;
222  scattered_insertion_index_space_handle* lelements_id_space = xbuffer.elements_id_space;
223 
224  // Put the new point in the vertices subposet and extend the sequence id space.
225 
226  lvertices.insert_member(_zone_ctr_id);
227  lvertices_id_space->push_back(_zone_ctr_id);
228  lcoord_disc_seq_id_space->push_back(_zone_ctr_id);
229 
230  // The refined zone is no longer an element;
231  // remove it from the elements subposet.
232 
233  // When removing the member, we have to be careful to reuse its
234  // sequence id, so the sequence id stays sequential.
235 
236  pod_index_type lseq_id = lelements_id_space->pod(lzone_id);
237 
238  lelements_id_space->remove(lzone_id, true);
239  lelements.remove_member(lzone_id);
240 
241  // Put the first new tet in the elements subposet,
242  // reusing the sequence id of the old tet.
243 
244  lelements.insert_member(_refined_zone_ids[0]);
245  lelements_id_space->insert(lseq_id, _refined_zone_ids[0]);
246 
247  // Put the other new tets on the elements subposet,
248  // extending the sequence id space.
249 
251  for(size_type i=1; i<lct; ++i)
252  {
254  lelements.insert_member(l_id);
255  lelements.id_space().push_back(l_id);
256  }
257 
258  // Postconditions:
259 
260  // Exit:
261 
262  return;
263 }
264 
265 
266 void
269 {
270  // Preconditions:
271 
272 
273  // Body:
274 
275  scoped_index lzone_id = xbuffer.zone_id;
276 
277 
278  // Set the local coordinates buffer to the center of the zone.
279 
280  xbuffer.coord_evaluator->center(xbuffer.local_coords);
281 
282  // Evaluate the global coordinates at the local coordinates.
283 
284  xbuffer.coord_evaluator->value_at_coord(xbuffer.coord_dofs,
285  xbuffer.local_coords,
286  xbuffer.coord_value);
287 
288  // Make sure the coordinates dof map has enough capacity for the new point.
289 
291 
292  // Insert the value in the coordinates section.
293 
295  xbuffer.coord_value.base(),
296  xbuffer.coord_value.ct()*sizeof(sec_vd_dof_type),
297  false);
298 
299  // Postconditions:
300 
301 
302  // Exit:
303 
304  return;
305 }
306 
307 
308 // PRIVATE MEMBERS
309 
310 //const sheaf::size_type
311 //fields::zone_centered_tet_refiner::
312 //REFINED_ZONE_CT;
313 
314 
315 // ===========================================================
316 // LOCAL_FIELD_REFINER FACET
317 // ===========================================================
318 
319 // PUBLIC MEMBER FUNCTIONS
320 
321 int
323 db() const
324 {
325  int result;
326 
327  // Preconditions:
328 
329 
330  // Body:
331 
332  result = 2;
333 
334  // Postconditions:
335 
336  ensure(result == 2);
337 
338  // Exit:
339 
340  return result;
341 }
342 
343 const std::string&
346 {
347  // Preconditions:
348 
349 
350  // Body:
351 
352  static const string result("triangle_nodes");
353 
354  // Postconditions:
355 
356  ensure(!result.empty());
357 
358  // Exit:
359 
360  return result;
361 }
362 
366 {
367  size_type result;
368 
369  // Preconditions:
370 
371 
372  // Body:
373 
374  result = REFINED_ZONE_CT;
375 
376  // Postconditions:
377 
378  ensure(result > 1);
379 
380  // Exit:
381 
382  return result;
383 }
384 
388 {
389  // Preconditions:
390 
391  require(xi < refined_zone_ct());
392 
393  // Body:
394 
395  // Affine transformation u'[i] = T[i][j]*u[j] + T[i][db];
396  // with sum convention over 0 <= j < db.
397 
398  // Specifically:
399  //
400  // u' = a*u +b*v + c;
401  // v' = d*u _e*v + f.
402  //
403  // map = {a, b, c, d, e, f}
404  // One such map for each refined zone.
405 
406  // 12 = db*(db+1)
407 
408  not_implemented();
409 
411 
412  static const chart_point_coord_type lmap[REFINED_ZONE_CT][12] =
413  {}
414  ;
415 
416 
417  const chart_point_coord_type* result = lmap[xi];
418 
419  // Postconditions:
420 
421  // Exit:
422 
423  return result;
424 }
425 
426 
427 // ===========================================================
428 // ANY FACET
429 // ===========================================================
430 
431 // PUBLIC MEMBER FUNCTIONS
432 
435 clone() const
436 {
438 
439  // Preconditions:
440 
441  // Body:
442 
443  result = new zone_centered_tet_refiner();
444 
445  // Postconditions:
446 
447  ensure(result != 0);
448  // ensure(invariant());
449  ensure(result->invariant());
450  ensure(is_same_type(result));
451 
452  return result;
453 }
454 
458 {
459  // Preconditions:
460 
461  require(is_ancestor_of(&xother));
462 
463  // Body:
464 
465  not_implemented();
466 
467  // Postconditions:
468 
469  ensure(invariant());
470 
471  return *this;
472 }
473 
478 {
479 
480  // Preconditions:
481 
482  require(is_ancestor_of(&xother));
483 
484  // Body:
485 
486  not_implemented();
487 
488  // Postconditions:
489 
490  ensure(invariant());
491 
492  // Exit:
493 
494  return *this;
495 }
496 
499 {
500  // Preconditions:
501 
502  // Body:
503 
504  // Postconditions:
505 
506  ensure(invariant());
507 
508  return;
509 }
510 
511 bool
513 invariant() const
514 {
515  bool result = true;
516 
517  // Preconditions:
518 
519  // Body:
520 
521  // Must satisfy base class invariant.
522 
523  result = result && local_field_refiner::invariant();
524 
525  if(invariant_check())
526  {
527  // Prevent recursive calls to invariant.
528 
530 
531  // Finished, turn invariant checking back on.
532 
534  }
535 
536  // Postconditions:
537 
538  return result;
539 }
540 
541 bool
543 is_ancestor_of(const any* xother) const
544 {
545 
546  // Preconditions:
547 
548  require(xother != 0);
549 
550  // Body:
551 
552  // True if other conforms to this
553 
554  bool result = dynamic_cast<const zone_centered_tet_refiner*>(xother) != 0;
555 
556  // Postconditions:
557 
558  return result;
559 
560 }
561 
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
section_evaluator * coord_evaluator
The section evaluator for the coordinates section of the target.
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...
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.
virtual int db() const
The base dimension; the dimension of the local coordinates (independent variable).
const pod_type & pod() const
The "plain old data" storage of this; the value in the external id space.
Definition: scoped_index.h:672
void modify_subposets(field_refinement_buffer &xbuffer)
Modifies subposets in the base space.
virtual const std::string & zone_type_name() const
The name of the type of zone this creates during refinement.
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.
block< scoped_index > _vertex_ids
The ids of the original vertices.
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.
virtual void refine_coordinates(field_refinement_buffer &xbuffer)
Refines the coordinates of the target.
STL namespace.
zone_centered_tet_refiner()
Default constructor; disabled.
block< sec_vd_value_type > coord_value
A buffer for computing coordinates at a point.
virtual bool invariant() const
Class invariant.
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...
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.
virtual void refine_base_space(field_refinement_buffer &xbuffer)
Refines the base space or the target.
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
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 zone_centered_tet_refiner * clone() const
Virtual constructor, creates a new instance of the same type as 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.
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
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_tet_refiner & operator=(const local_field_refiner &xother)
Assignment operator.
scoped_index _zone_ctr_id
The index of the point added by the current base space refinement.
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.
virtual size_type refined_zone_ct() const
The number of refined zones created by this.
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.
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.
A field refiner that subdivides a tet into 4 tets by introducing a new vertex in the center...
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().
void modify_crg(field_refinement_buffer &xbuffer)
Modifies the cover relation graph of the base space.