SheafSystem  0.0.0.0
quadratic_3d.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 quadratic_3d
19 
20 #include "SheafSystem/quadratic_3d.h"
21 #include "SheafSystem/assert_contract.h"
22 #include "SheafSystem/std_cmath.h"
23 #include "SheafSystem/std_iostream.h"
24 #include "SheafSystem/std_limits.h"
25 
26 using namespace std;
27 using namespace fiber_bundle; // Workaround for MS C++ bug.
28 
29 // ===========================================================
30 // QUADRATIC_3D FACET
31 // ===========================================================
32 
36 {
37  // Preconditions:
38 
39  // Body:
40 
41  _basis_values = _basis_value_buffer;
42  _basis_deriv_values = _basis_deriv_value_buffer;
43  _jacobian_values = _jacobian_value_buffer;
44 
45  // Postconditions:
46 
47  ensure(invariant());
48 
49  return;
50 }
51 
54 quadratic_3d(const quadratic_3d& xother)
55 {
56  // Preconditions:
57 
58  // Body:
59 
60  _basis_values = _basis_value_buffer;
61  _basis_deriv_values = _basis_deriv_value_buffer;
62  _jacobian_values = _jacobian_value_buffer;
63 
64  // Postconditions:
65 
66  ensure(invariant());
67 
68  return;
69 }
70 
74 {
75  // Preconditions:
76 
77  // Body:
78 
79  // Postconditions:
80 
81  ensure(invariant());
82 
83  return;
84 }
85 
87 // LINEAR_FCN_SPACE FACET
88 // ===========================================================
89 
91 int
93 dl() const
94 {
95  int result;
96 
97  // Preconditions:
98 
99 
100  // Body:
101 
102  result = DL;
103 
104  // Postconditions:
105 
106  ensure(result == 10);
107 
108  // Exit:
109 
110  return result;
111 }
112 
113 void
115 basis_at_coord(const dof_type xlocal_coord[], size_type xlocal_coord_ub)
116 {
117  // Preconditions:
118 
119  require(xlocal_coord != 0);
120  require(xlocal_coord_ub >= db());
121 
122  // Body:
123  // Evaluate the interpolation functions.
124 
125  double L0 = xlocal_coord[0];
126  double L1 = xlocal_coord[1];
127  double L2 = xlocal_coord[2];
128  double L3 = 1.0 - (L0 + L1 + L2);
129 
130  // Corner nodes:
131 
132  _basis_values[0] = (2.0*L0-1.0)*L0;
133  _basis_values[1] = (2.0*L1-1.0)*L1;
134  _basis_values[2] = (2.0*L2-1.0)*L2;
135  _basis_values[3] = (2.0*L3-1.0)*L3;
136 
137  // Midside nodes:
138 
139  _basis_values[4] = 4.0*L0*L1;
140  _basis_values[5] = 4.0*L0*L2;
141  _basis_values[6] = 4.0*L0*L3;
142  _basis_values[7] = 4.0*L1*L2;
143  _basis_values[8] = 4.0*L2*L3;
144  _basis_values[9] = 4.0*L3*L1;
145 
146  // Postconditions:
147 
148  ensure(invariant());
149 }
150 
152 void
154 basis_derivs_at_coord(const dof_type xlocal_coord[], size_type xlocal_coord_ub)
155 {
156  // Preconditions:
157 
158  require(xlocal_coord != 0);
159  require(xlocal_coord_ub >= db());
160  require(basis_deriv_values() != 0);
161 
162  // Body:
163 
165 
166  not_implemented();
167 
168  // Postconditions:
169 
170  ensure(invariant());
171 
172  // Exit:
173 
174  return;
175 }
176 
177 // ===========================================================
178 // INTEGRABLE_SECTION_EVALUATOR FACET
179 // ===========================================================
180 
184 jacobian_determinant(const dof_type xcoord_dofs[],
185  size_type xcoord_dofs_ub,
186  size_type xdf,
187  const coord_type xlocal_coords[],
188  size_type xlocal_coords_ub)
189 {
190  // Preconditions:
191 
192  require(xcoord_dofs != 0);
193  require(xcoord_dofs_ub >= db()*dl());
194  require(xlocal_coords != 0);
195  require(xlocal_coords_ub >= db());
196  //require(jacobian_values() != 0);
197 
198  // Body:
199 
200  not_implemented();
201 
203 
204  value_type result = 0.0;
205 
206  // Postconditions:
207 
208  ensure(invariant());
209 
210  // Exit:
211 
212  return result;
213 }
214 
218 volume(const dof_type xcoord_dofs[], size_type xcoord_dofs_ub, size_type xdf)
219 {
220  // Preconditions:
221 
222  require(xcoord_dofs != 0);
223  require(xcoord_dofs_ub >= dl()*db());
224  require(xdf == 2 || xdf == 3);
225 
226  // Body:
227 
229 
230  not_implemented();
231 
232  value_type result = 0.0;
233 
234  // Postconditions:
235 
236  ensure(invariant());
237 
238  // Exit:
239 
240  return result;
241 }
242 
244 void
246 integrate(const dof_type xcoord_dofs[],
247  size_type xcoord_dofs_ub,
248  size_type xdf,
249  const dof_type xintegrands[],
250  size_type xintegrands_ub,
251  value_type xresult_integrals[],
252  size_type xresult_integrals_ub)
253 {
255 
256  // Preconditions:
257 
258  require(xcoord_dofs != 0);
259  require(xcoord_dofs_ub >= dl()*db());
260  require(xintegrands != 0);
261  require(xintegrands_ub >= dl());
262  require(xresult_integrals != 0);
263  require(xresult_integrals_ub > 0);
264 
265  // Body:
266 
267  not_implemented();
268 
270 
271  // Postconditions:
272 
273  ensure(invariant());
274 
275  // Exit:
276 
277  return;
278 }
279 
281 void
283 integrate(const dof_type xcoord_dofs[],
284  size_type xcoord_dofs_ub,
285  size_type xdf,
286  const dof_type xintegrand,
287  value_type xresult_integrals[],
288  size_type xresult_integrals_ub)
289 {
291 
292  // Preconditions:
293 
294  require(xcoord_dofs != 0);
295  require(xcoord_dofs_ub >= dl()*db());
296  require(xresult_integrals != 0);
297  require(xresult_integrals_ub >= dl());
298 
299  // Body:
300 
301  not_implemented();
302 
304 
305  // Postconditions:
306 
307  ensure(invariant());
308 
309  // Exit:
310 
311  return;
312 }
313 
315 void
318  coord_type xresult[],
319  size_type xresult_ub)
320 {
321  // Preconditions:
322 
323  require((0 <= xindex) && (xindex < dof_ct()));
324  require(xresult_ub >= db());
325 
326  // Body:
327 
328  not_implemented();
329 
331 
332  // Postconditions:
333 
334  ensure(in_standard_domain(xresult, xresult_ub));
335  ensure(invariant());
336 
337  // Exit:
338 
339  return;
340 }
341 
342 // ===========================================================
343 // DIFFERENTIABLE_SECTION_EVALUATOR FACET
344 // ===========================================================
345 
347 void
349 dxi_local(size_type xlocal_coord_index,
350  const dof_type xsource_dofs[],
351  size_type xsource_dofs_ub,
352  dof_type xresult_dofs[],
353  size_type xresult_dofs_ub) const
354 {
355  // Preconditions:
356 
357  require(xlocal_coord_index < db());
358  require(xsource_dofs != 0);
359  //require(xsource_dofs_ub >= dof_ct());
360  require(xresult_dofs != 0);
361  //require(xresult_dofs_ub >= dof_ct());
362 
363  // Body:
364 
365  // The 1st derivatives are constant for linear 3d.
366 
367  dof_type derivative = xsource_dofs[xlocal_coord_index] - xsource_dofs[3];
368 
369  for(int i=0; i<4; ++i)
370  xresult_dofs[i] = derivative;
371 
372  // Postconditions:
373 
374  // Exit:
375 
376  return;
377 }
378 
380 void
382 jacobian(const dof_type xcoord_dofs[],
383  size_type xcoord_dofs_ub,
384  size_type xdf,
385  const dof_type xlocal_coords[],
386  size_type xlocal_coords_ub)
387 {
388  // Preconditions:
389 
390  require(xcoord_dofs != 0);
391  require(xcoord_dofs_ub >= db()*dl());
392  require(xlocal_coords != 0);
393  require(xlocal_coords_ub >= db());
394  require(jacobian_values() != 0);
395 
396  // Body:
397 
398  not_implemented();
399 
401 
402  // Postconditions:
403 
404  ensure(invariant());
405 
406  // Exit:
407 
408  return;
409 }
410 
411 // ===========================================================
412 // DOMAIN FACET
413 // ===========================================================
414 
416 int
418 db() const
419 {
420  int result;
421 
422  // Preconditions:
423 
424 
425  // Body:
426 
427  result = 3;
428 
429  // Postconditions:
430 
431  ensure(result == 3);
432 
433  // Exit:
434 
435  return result;
436 }
437 
438 
440 void
442 local_coordinates(pod_index_type xindex, coord_type xresult[], size_type xresult_ub) const
443 {
444  // Preconditions:
445 
446  require((0 <= xindex) && (xindex < dof_ct()));
447  require(xresult_ub >= db());
448 
449  // Body:
450 
451  static const coord_type lcoords[10][3] =
452  {
453  // Corner nodes:
454 
455  {1.0, 0.0, 0.0},
456  {0.0, 1.0, 0.0},
457  {0.0, 0.0, 1.0},
458  {0.0, 0.0, 0.0},
459 
460  // Mid-side nodes
461 
462  {0.5, 0.5, 0.0},
463  {0.5, 0.0, 0.5},
464  {0.5, 0.0, 0.0},
465  {0.0, 0.5, 0.5},
466  {0.0, 0.0, 0.5},
467  {0.0, 0.5, 0.0}
468  };
469 
470  xresult[0] = lcoords[xindex][0];
471  xresult[1] = lcoords[xindex][1];
472  xresult[2] = lcoords[xindex][2];
473 
474  // Postconditions:
475 
476  ensure(in_standard_domain(xresult, xresult_ub));
477 
478  // Exit:
479 
480  return;
481 }
482 
484 bool
486 in_standard_domain(const dof_type xlocal_coords[],
487  size_type xlocal_coords_ub) const
488 {
489  // Preconditions:
490 
491  require(xlocal_coords != 0);
492  require(xlocal_coords_ub >= 3);
493 
494  // Body:
495 
496  dof_type u = xlocal_coords[0];
497  dof_type v = xlocal_coords[1];
498  dof_type w = xlocal_coords[2];
499 
500  // "Extend" the bounds by the dof type epsilon (attempting
501  // to ensure that the boundary is included in the domain).
502 
503  dof_type zero = 0.0 - 1000.0*numeric_limits<dof_type>::epsilon();
504  dof_type one = 1.0 + 1000.0*numeric_limits<dof_type>::epsilon();
505 
506  bool result = (u >= zero) && (u <= one) &&
507  (v >= zero) && (v <= one) &&
508  (w >= zero) && (w <= one);
509 
510  // Postconditions:
511 
512  // Exit:
513 
514  return result;
515 
516 }
517 
518 // ===========================================================
519 // EVALUATION FACET
520 // ===========================================================
521 
523 void
525 coord_at_value(const dof_type xdofs[],
526  size_type xdofs_ub,
527  const dof_type xglobal_coords[],
528  size_type xglobal_coord_ub,
529  dof_type xlocal_coords[],
530  size_type xlocal_coords_ub) const
531 {
532  // Preconditions:
533 
534  require(xdofs != 0);
535  require(xdofs_ub >= 30);
536  require(xglobal_coords != 0);
537  require(xglobal_coord_ub >= 3);
538  require(xlocal_coords != 0);
539  require(xlocal_coords_ub >= 3);
540 
541  // Body:
542 
543  cout << "quadratic_3d::coord_at_value()" << endl;
544 
545 
546  // Dofs are assumed to be interleaved (x0, y0,z0, x1, y1, z1, ...).
547 
550 
551  // Note: The local ids for the corner nodes is (0, 1, 2, 3)
552  // and for the midside nodes (3, 4, 5, 6, 7, 8, 9)
553 
554  // Corner nodes:
555 
556  dof_type x0 = xdofs[0];
557  dof_type x1 = xdofs[3];
558  dof_type x2 = xdofs[6];
559  dof_type x3 = xdofs[9];
560 
561  dof_type y0 = xdofs[1];
562  dof_type y1 = xdofs[4];
563  dof_type y2 = xdofs[7];
564  dof_type y3 = xdofs[10];
565 
566  dof_type z0 = xdofs[2];
567  dof_type z1 = xdofs[5];
568  dof_type z2 = xdofs[8];
569  dof_type z3 = xdofs[11];
570 
571  // Midside nodes:
572 
575 
576  // dof_type x4 = xdofs[12];
577  // dof_type x5 = xdofs[15];
578  // dof_type x6 = xdofs[18];
579  // dof_type x7 = xdofs[21];
580  // dof_type x8 = xdofs[24];
581  // dof_type x9 = xdofs[27];
582 
583  // dof_type y4 = xdofs[12];
584  // dof_type y5 = xdofs[16];
585  // dof_type y6 = xdofs[19];
586  // dof_type y7 = xdofs[22];
587  // dof_type y8 = xdofs[25];
588  // dof_type y9 = xdofs[28];
589 
590  // dof_type z4 = xdofs[13];
591  // dof_type z5 = xdofs[17];
592  // dof_type z6 = xdofs[20];
593  // dof_type z7 = xdofs[23];
594  // dof_type z8 = xdofs[26];
595  // dof_type z9 = xdofs[29];
596 
597  dof_type x_global = xglobal_coords[0];
598  dof_type y_global = xglobal_coords[1];
599  dof_type z_global = xglobal_coords[2];
600 
602 
604 
605  double a01 = x0*y1-x1*y0;
606  double a02 = x0*y2-x2*y0;
607  double a03 = x0*y3-x3*y0;
608  double a12 = x1*y2-x2*y1;
609  double a13 = x1*y3-x3*y1;
610  double a23 = x2*y3-x3*y2;
611 
612  double a10 = -a01;
613  double a20 = -a02;
614  double a30 = -a03;
615  double a21 = -a12;
616  double a31 = -a13;
617  double a32 = -a23;
618 
620 
621  double b01 = y0-y1;
622  double b02 = y0-y2;
623  double b12 = y1-y2;
624  double b23 = y2-y3;
625  double b30 = y3-y0;
626  double b31 = y3-y1;
627 
630 
631  // double b10 = -b01;
632  double b20 = -b02;
633  // double b21 = -b12;
634  double b32 = -b23;
635  double b03 = -b30;
636  double b13 = -b31;
637 
638  double c01 = x0-x1;
639  double c02 = x0-x2;
640  double c12 = x1-x2;
641  double c23 = x2-x3;
642  double c30 = x3-x0;
643  double c31 = x3-x1;
644 
645  double c10 = -c01;
646  // double c20 = -c02;
647  double c21 = -c12;
648  double c03 = -c30;
649  double c13 = -c31;
650  double c32 = -c23;
651 
653 
654  // The following z## values represent the adjoint of the matrix:
655  //
656  // 1 1 1 1
657  // x0 x2 x3 x4
658  // y0 y2 y3 y4
659  // z0 z2 z3 z4
660  //
661  // (Dividing by the determinant gives the inverse).
662 
663  double z00 = a23*z1 + a31*z2 + a12*z3;
664  double z01 = b23*z1 + b31*z2 + b12*z3;
665  double z02 = c32*z1 + c13*z2 + c21*z3;
666  double z03 = a32 + a21 + a13;
667 
668  double z10 = a32*z0 + a03*z2 + a20*z3;
669  double z11 = b32*z0 + b03*z2 + b20*z3;
670  double z12 = c23*z0 + c30*z2 + c02*z3;
671  double z13 = a23 + a02 + a30;
672 
673  double z20 = a13*z0 + a30*z1 + a01*z3;
674  double z21 = b13*z0 + b30*z1 + b01*z3;
675  double z22 = c31*z0 + c03*z1 + c10*z3;
676  double z23 = a31 + a10 + a03;
677 
678  double z30 = a21*z0 + a02*z1 + a10*z2;
679  // double z31 = b21*z0 + b02*z1 + b10*z2;
680  // double z32 = c12*z0 + c20*z1 + c01*z2;
681  // double z33 = a12 + a01 + a20;
682 
684 
685  // The determinant (which is 6 times the volume of the tetraherdon)
686  // can be calcluated as:
687  // double det = a01*(z3-z2) + a02*(z1-z3) + a03*(z2-z1)
688  // + a12*(z3-z0) + a13*(z0-z2) + a23*(z1-z0);
689 
690  // However, the following is more efficient:
691  double det = z00 + z10 + z20 + z30;
692 
693  cout << " det = " << det << endl;
694 
695  double shape0 = (z00 + z01*x_global + z02*y_global + z03*z_global) / det;
696  double shape1 = (z10 + z11*x_global + z12*y_global + z13*z_global) / det;
697  double shape2 = (z20 + z21*x_global + z22*y_global + z23*z_global) / det;
698 
699  //double shape3 = (z30 + z31*x_global + z32*y_global + z33*z_global) / det;
700  double shape3 = 1.0 - (shape0 + shape1 + shape2);
701 
702  cout << "shape0 = " << shape0 << endl;
703  cout << "shape1 = " << shape1 << endl;
704  cout << "shape2 = " << shape2 << endl;
705  cout << "shape3 = " << shape3 << endl;
706 
708 
709  // Return 3 local (area) coordinates and later generate the fourth from
710  // the fact that they sum to 1 (ie: shape0 + shape1 + shape2 + shape3 = 1).
711 
712  xlocal_coords[0] = shape0;
713  xlocal_coords[1] = shape1;
714  xlocal_coords[2] = shape1;
715 
716  // Return non null only if the search point is inside the element
717  // or on the element boundary.
718 
719  //if((shape0 >= 0.0) && (shape1 >= 0.0) && (shape2 >= 0.0) && (shape3 >= 0.0))
720  // result = xlocal_coords;
721 
722  // Postconditions:
723 
724  ensure(invariant());
725 
726  //ensure(result != 0 ? result == xlocal_coords : true);
727 
729 
730  // ensure(unexecutable(result != 0
731  // ? value_at_coord_ua(xdofs, xdofs_ub, xcoords, xcoords_ub) == xvalue
732  // : true));
733 
734  //return result;
735 
736 }
737 
738 // ===========================================================
739 // ANY FACET
740 // ===========================================================
741 
745 clone() const
746 {
747  quadratic_3d* result;
748 
749  // Preconditions:
750 
751  // Body:
752 
753  result = new quadratic_3d();
754 
755  // Postconditions:
756 
757  ensure(result != 0);
758  ensure(is_same_type(result));
759  //ensure(invariant());
760  ensure(result->invariant());
761 
762  return result;
763 }
764 
769 {
770  // Preconditions:
771 
772  require(is_ancestor_of(&xother));
773 
774  // Body:
775 
776  not_implemented();
777 
778  // Postconditions:
779 
780  ensure(invariant());
781 
782  return *this;
783 }
784 
788 operator=(const quadratic_3d& xother)
789 {
790 
791  // Preconditions:
792 
793  require(is_ancestor_of(&xother));
794 
795  // Body:
796 
797  not_implemented();
798 
799  // Postconditions:
800 
801  ensure(invariant());
802 
803  // Exit:
804 
805  return *this;
806 }
807 
809 bool
811 invariant() const
812 {
813  bool result = true;
814 
815  // Preconditions:
816 
817  // Body:
818 
819  // Must satisfy base class invariant.
820 
821  result = result && linear_fcn_space::invariant();
822 
823  if(invariant_check())
824  {
825  // Prevent recursive calls to invariant.
826 
827  disable_invariant_check();
828 
829  invariance(basis_values() != 0);
830 
831  // Finished, turn invariant checking back on.
832 
833  enable_invariant_check();
834  }
835 
836  // Postconditions:
837 
838  return result;
839 }
840 
842 bool
844 is_ancestor_of(const any* xother) const
845 {
846 
847  // Preconditions:
848 
849  require(xother != 0);
850 
851  // Body:
852 
853  // True if other conforms to this
854 
855  bool result = dynamic_cast<const quadratic_3d*>(xother) != 0;
856 
857  // Postconditions:
858 
859  return result;
860 
861 }
862 
863 // ===========================================================
864 // PRIVATE MEMBERS
865 // ===========================================================
866 
867 
868 
virtual quadratic_3d & operator=(const section_evaluator &xother)
Assignment operator.
virtual ~quadratic_3d()
Destructor.
Definition: quadratic_3d.cc:73
A section evaluator using quadratic interpolation over a tetrahedral 3D domain.
Definition: quadratic_3d.h:37
virtual value_type jacobian_determinant(const dof_type xcoord_dofs[], size_type xcoord_dofs_ub, size_type xdf, const coord_type xlocal_coords[], size_type xlocal_coords_ub)
Computes the the determinant of the jacobian matrix at local coordinates xlocal_coords with coordinat...
virtual void gauss_point(pod_index_type xindex, coord_type xresult[], size_type xresult_ub)
The local coordinates of the gauss point with index xindex.
virtual bool is_ancestor_of(const any *xother) const
Conformance test; true if other conforms to this.
STL namespace.
sec_vd_dof_type dof_type
The type of degree of freedom.
Abstract base class with useful features for all objects.
Definition: any.h:39
virtual void local_coordinates(pod_index_type xindex, coord_type xresult[], size_type xresult_ub) const
The local coordinates of the dof with local index xindex.
virtual int dl() const
The dimension of this function space.
Definition: quadratic_3d.cc:93
virtual void basis_derivs_at_coord(const dof_type xlocal_coords[], size_type xlocal_coords_ub)
Computes the value of the derivatives of each basis function at local coordinates xlocal_coords...
unsigned long size_type
An unsigned integral type used to represent sizes and capacities.
Definition: sheaf.h:52
virtual quadratic_3d * clone() const
Virtual constructor, creates a new instance of the same type as this.
chart_point_coord_type coord_type
The type of local coordinate; the scalar type for the local coordinate vector space.
vd_value_type value_type
The type of component in the value; the scalar type in the range vector space.
An abstract local section evaluator; a map from {local coordinates x dofs} to section value...
virtual int db() const
The base dimension; the dimension of the local coordinates (independent variable).
virtual bool invariant() const
Class invariant.
virtual void jacobian(const dof_type xcoord_dofs[], size_type xcoord_dofs_ub, size_type xdf, const dof_type xlocal_coords[], size_type xlocal_coords_ub)
Computes the the jacobian matrix at local coordinates xlocal_coords with coordinate dofs xcoord_dofs...
virtual void basis_at_coord(const dof_type xlocal_coord[], size_type xlocal_coord_ub)
Computes the value of each basis function at local coordinates xlocal_coord.
int_type pod_index_type
The plain old data index type.
Definition: pod_types.h:49
quadratic_3d()
Default constructor.
Definition: quadratic_3d.cc:35
virtual bool in_standard_domain(const dof_type xlocal_coords[], size_type xlocal_coords_ub) const
Return true if the specified local coordinates are in the "standard" domain; otherwise return false...
virtual void dxi_local(size_type xcrd, const dof_type xsource_dofs[], size_type xsource_dofs_ub, dof_type xresult_dofs[], size_type xresult_dofs_ub) const
1st partial derivative of this with respect to local coordinate xcrd.
virtual value_type volume(const dof_type xcoord_dofs[], size_type xcoord_dofs_ub, size_type xdf)
Volume for specified coordinate dofs xcoord_dofs and fiber space dimension xdf.
Namespace for the fiber_bundles component of the sheaf system.
virtual void coord_at_value(const dof_type xdofs[], size_type xdofs_ub, const dof_type xglobal_coords[], size_type xglobal_coord_ub, dof_type xlocal_coords[], size_type xlocal_coords_ub) const
The local coordinates of a point at which the field has the value xvalue. The dofs are assumed to be ...
virtual void integrate(const dof_type xcoord_dofs[], size_type xcoord_dofs_ub, size_type xdf, const dof_type xintegrands[], size_type xintegrands_ub, value_type xresult_integrals[], size_type xresult_integrals_ub)
Computes the value of the integral of the integrand array...