SheafSystem  0.0.0.0
linear_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 linear_3d
19 
20 #include "SheafSystem/linear_3d.h"
21 
22 #include "SheafSystem/assert_contract.h"
23 #include "SheafSystem/std_cmath.h"
24 #include "SheafSystem/std_iostream.h"
25 #include "SheafSystem/std_limits.h"
26 
27 using namespace std;
28 using namespace fiber_bundle; // Workaround for MS C++ bug.
29 
30 // ===========================================================
31 // LINEAR_3D FACET
32 // ===========================================================
33 
37 {
38  // Preconditions:
39 
40  // Body:
41 
42  _basis_values = _basis_value_buffer;
43  _basis_deriv_values = _basis_deriv_value_buffer;
44  _jacobian_values = _jacobian_value_buffer;
45 
46  // Postconditions:
47 
48  ensure(invariant());
49 
50  // Exit:
51 
52  return;
53 }
54 
55 
58 linear_3d(const linear_3d& xother)
59 {
60  // Preconditions:
61 
62  // Body:
63 
64  _basis_values = _basis_value_buffer;
65  _basis_deriv_values = _basis_deriv_value_buffer;
66  _jacobian_values = _jacobian_value_buffer;
67 
68  // Postconditions:
69 
70  ensure(invariant());
71 
72  // Exit:
73 
74  return;
75 }
76 
77 
81 {
82  // Preconditions:
83 
84  // Body:
85 
86  // Postconditions:
87 
88  return;
89 }
90 
92 double
94 determinant_3x3(double a00, double a01, double a02,
95  double a10, double a11, double a12,
96  double a20, double a21, double a22)
97 {
98  double result = a00*(a11*a22-a12*a21)
99  - a10*(a01*a22-a02*a21)
100  + a20*(a01*a12-a02*a11);
101 
102  return result;
103 }
104 
105 // ===========================================================
106 // LINEAR_FCN_SPACE FACET
107 // ===========================================================
108 
110 int
112 dl() const
113 {
114  int result;
115 
116  // Preconditions:
117 
118 
119  // Body:
120 
121  result = DL;
122 
123  // Postconditions:
124 
125  ensure(result == 4);
126 
127  // Exit:
128 
129  return result;
130 }
131 
133 void
135 basis_at_coord(const dof_type xlocal_coord[], size_type xlocal_coord_ub)
136 {
137  // Preconditions:
138 
139  require(xlocal_coord != 0);
140  require(xlocal_coord_ub >= db());
141 
142  // Body:
143 
144  // Evaluate the interpolation functions.
145 
146  _basis_values[0] = xlocal_coord[0];
147  _basis_values[1] = xlocal_coord[1];
148  _basis_values[2] = xlocal_coord[2];
149  _basis_values[3] = 1.0 - (_basis_values[0] + _basis_values[1] + _basis_values[2]);
150 
151  // Postconditions:
152 
153  ensure(invariant());
154 
155  // Exit:
156 
157  return;
158 }
159 
161 void
163 basis_derivs_at_coord(const dof_type xlocal_coords[],
164  size_type xlocal_coords_ub)
165 {
166  // Preconditions:
167 
168  require(xlocal_coords != 0);
169  require(xlocal_coords_ub >= 3);
170 
171  // Body:
172 
173  // Evaluate the derivatives of the interpolation functions.
174  // The derivatives are interleaved (N,r[0], N,s[0], N,t[0],
175  // N,r[1], N,s[1], N,t[1], ...).
176 
177  // Here the basis functions are in terms of barycentric coordinates.
178  // given barycentric coordinates L0, L1, L2, L3 (L0+L1+L2+L3=1) where we use
179  // the the convention that L3 = 1-L0-L1-L2.
180 
181  // The basis fumctions are:
182  // N0(r, s, t) = r;
183  // N1(r, s, t) = s;
184  // N2(r, s, t) = t;
185  // N3(r, s, t) = 1-r-s-t;
186 
187  // Note that the basis functions are linear in r,s,t.
188  // Therefore the derivatives are constant and the
189  // local coordinates are not needed in their evaluation.
190 
191  // Derivatives with respect to r.
192 
193  _basis_deriv_value_buffer[ 0] = 1.0;
194  _basis_deriv_value_buffer[ 3] = 0.0;
195  _basis_deriv_value_buffer[ 6] = 0.0;
196  _basis_deriv_value_buffer[ 9] = -1.0;
197 
198  // Derivatives with respect to s.
199 
200  _basis_deriv_value_buffer[ 1] = 0.0;
201  _basis_deriv_value_buffer[ 4] = 1.0;
202  _basis_deriv_value_buffer[ 7] = 0.0;
203  _basis_deriv_value_buffer[10] = -1.0;
204 
205  // Derivative with respect to t.
206 
207  _basis_deriv_value_buffer[ 2] = 0.0;
208  _basis_deriv_value_buffer[ 5] = 0.0;
209  _basis_deriv_value_buffer[ 8] = 1.0;
210  _basis_deriv_value_buffer[11] = -1.0;
211 
212  // Postconditions:
213 
214  ensure(invariant());
215 
216  // Exit:
217 
218  return;
219 }
220 
221 // ===========================================================
222 // INTEGRABLE_SECTION_EVALUATOR FACET
223 // ===========================================================
224 
228 jacobian_determinant(const dof_type xcoord_dofs[],
229  size_type xcoord_dofs_ub,
230  size_type xdf,
231  const coord_type xlocal_coords[],
232  size_type xlocal_coords_ub)
233 {
234  // Precondition: xdf = 2 or xdf = 3 ?.
235 
236  // Preconditions:
237 
238  require(xcoord_dofs != 0);
239  require(xcoord_dofs_ub >= dl()*db());
240  require(xdf == 2 || xdf == 3);
241 
242  // Get the jacobian matrix.
243 
244  jacobian(xcoord_dofs, xcoord_dofs_ub, xdf, xlocal_coords, xlocal_coords_ub);
245  const value_type* jvalues = jacobian_values();
246 
247  //===========================================================================
248 
249  // Form the metric tensor g = [J]'*[J] (' == transpose).
250 
251  value_type g00 = 0.0;
252  value_type g01 = 0.0;
253  value_type g02 = 0.0;
254  value_type g11 = 0.0;
255  value_type g12 = 0.0;
256  value_type g22 = 0.0;
257 
258  // Jacobian matrix has dimensions xdf x 2.
259 
260  // Just do the matrix multiplication in place (for efficiency).
261 
262  int index = 0;
263  for(int i=0; i<xdf; ++i)
264  {
265  value_type Ji0 = jvalues[index++];
266  value_type Ji1 = jvalues[index++];
267  value_type Ji2 = jvalues[index++];
268 
269  g00 += Ji0*Ji0;
270  g01 += Ji0*Ji1;
271  g02 += Ji0*Ji2;
272  g11 += Ji1*Ji1;
273  g12 += Ji1*Ji2;
274  g22 += Ji2*Ji2;
275  }
276 
277  // Metric tensor is symmetric, so g10 = g01.
278 
279  value_type g10 = g01;
280  value_type g20 = g02;
281  value_type g21 = g12;
282 
283  // Evaulate the determinant of the metrix tensor
284 
285  value_type det = g00*(g11*g22-g12*g21)
286  - g10*(g01*g22-g02*g21)
287  + g20*(g01*g12-g02*g11);
288 
289  // The "jacobian determinant" is the square root of det;
290 
291  value_type result = sqrt(fabs(det));
292 
293  //===========================================================================
294 
295  return result;
296 }
297 
301 volume(const dof_type xcoord_dofs[],
302  size_type xcoord_dofs_ub, size_type xdf)
303 {
304  // Coordinates are interleaved (x0,y0,z0,x1,y1,z1,...).
305 
306  // Here we use the following equation:
307  //
308  // 6*Volume = | 1 x0 y0 z0 |
309  // | 1 x1 y1 z1 |
310  // | 1 x2 y2 z2 |
311  // | 1 x3 y3 z3 |
312 
313  dof_type x0 = xcoord_dofs[ 0];
314  dof_type x1 = xcoord_dofs[ 3];
315  dof_type x2 = xcoord_dofs[ 6];
316  dof_type x3 = xcoord_dofs[ 9];
317 
318  dof_type y0 = xcoord_dofs[ 1];
319  dof_type y1 = xcoord_dofs[ 4];
320  dof_type y2 = xcoord_dofs[ 7];
321  dof_type y3 = xcoord_dofs[10];
322 
323  dof_type z0 = xcoord_dofs[ 2];
324  dof_type z1 = xcoord_dofs[ 5];
325  dof_type z2 = xcoord_dofs[ 8];
326  dof_type z3 = xcoord_dofs[11];
327 
328  // Evaluate the 4x4 determinant using cofactors.
329 
330  value_type result = determinant_3x3(x1, y1, z1, x2, y2, z2, x3, y3, z3)
331  - determinant_3x3(x0, y0, z0, x2, y2, z2, x3, y3, z3)
332  + determinant_3x3(x0, y0, z0, x1, y1, z1, x3, y3, z3)
333  - determinant_3x3(x0, y0, z0, x1, y1, z1, x2, y2, z2);
334 
335  result /= 6.0;
336 
337  return result;
338 }
339 
341 void
343 integrate(const dof_type xcoord_dofs[],
344  size_type xcoord_dofs_ub,
345  size_type xdf,
346  const dof_type xintegrands[],
347  size_type xintegrands_ub,
348  value_type xresult_integrals[],
349  size_type xresult_integrals_ub)
350 {
352 
353  // Preconditions:
354 
355  require(xcoord_dofs != 0);
356  require(xcoord_dofs_ub >= dl()*db());
357  require(xintegrands != 0);
358  require(xintegrands_ub >= dl());
359  require(xresult_integrals != 0);
360  require(xresult_integrals_ub > 0);
361 
362  // Body:
363 
364  double vol = volume(xcoord_dofs, xcoord_dofs_ub, 3);
365  double quarter_vol = 0.25*vol;
366 
367  for(int i=0; i<xresult_integrals_ub; ++i)
368  {
369  dof_type fn = 0.0;
370  const dof_type* integrands_n = &xintegrands[i*4];
371 
372  for(int k=0; k<4; ++k)
373  {
374  fn += integrands_n[k];
375  }
376 
377  xresult_integrals[i] = fn*quarter_vol;
378  }
379 
380  //cout << " vol = " << vol << endl;
381 
383 
384  // static int NUM_GAUSS_POINTS = 4;
385 
386  // for(int n=0; n<NUM_GAUSS_POINTS; ++n)
387  // {
388  // coord_type local_coords[4];
389  // gauss_point(n, local_coords, 4);
390 
391  // //double det = determinant(xcoord_dofs, xcoord_dofs_ub, local_coords, 4);
392 
393  // basis_at_coord(local_coords, 4);
394  // const value_type* basis = basis_values();
395 
396  // for(int i=0; i<xresult_integrals_ub; ++i)
397  // {
398  // dof_type fn = 0.0;
399  // const dof_type* integrands_n = xintegrands+(i*4);
400 
401  // for(int k=0; k<4; ++k)
402  // {
403  // fn += basis[k]*integrands_n[k];
404  // }
405 
406  // xresult_integrals[i] += det*fn;
407  // }
408  // }
409 
410  // Postconditions:
411 
412  ensure(invariant());
413 
414  // Exit:
415 
416  return;
417 }
418 
420 void
422 integrate(const dof_type xcoord_dofs[],
423  size_type xcoord_dofs_ub,
424  size_type xdf,
425  const dof_type xintegrand,
426  value_type xresult_integrals[],
427  size_type xresult_integrals_ub)
428 {
430 
431  // Preconditions:
432 
433  require(xcoord_dofs != 0);
434  require(xcoord_dofs_ub >= dl()*db());
435  require(xresult_integrals != 0);
436  require(xresult_integrals_ub >= dl());
437 
438  // Body:
439 
440  double vol = volume(xcoord_dofs, xcoord_dofs_ub, 3);
441 
442  value_type value = 0.25*xintegrand*vol;
443 
444  for(int i=0; i<xresult_integrals_ub; ++i)
445  {
446  xresult_integrals[i] = value;
447  }
448 
449  // // Initialize the integrals.
450 
451  // for(int i=0; i<xresult_integrals_ub; ++i)
452  // {
453  // xresult_integrals[i] = 0.0;
454  // }
455 
456 
457  // static int NUM_GAUSS_POINTS = 8;
458 
459  // for(int n=0; n<NUM_GAUSS_POINTS; ++n)
460  // {
461  // coord_type local_coords[3];
462  // gauss_point(n, local_coords, 3);
463 
464  // double det = determinant(xcoord_dofs, xcoord_dofs_ub, local_coords, 3);
465 
466  // cout << " det = " << det << endl;
467 
468  // basis_at_coord(local_coords, 3);
469  // const value_type* basis = basis_values();
470 
471  // for(int i=0; i<8; ++i)
472  // {
473  // xresult_integrals[i] += basis[i] * det;
474  // }
475  // }
476 
477  // // Multiple by "F" for constant F case.
478 
479  // for(int i=0; i<8; ++i)
480  // {
481  // xresult_integrals[i] *= xintegrand;
482  // }
483 
484  // Postconditions:
485 
486  ensure(invariant());
487 
488  // Exit:
489 
490  return;
491 }
492 
494 void
497  coord_type xresult[],
498  size_type xresult_ub)
499 {
500  // Preconditions:
501 
502  require((0 <= xindex) && (xindex < dof_ct()));
503  require(xresult_ub >= db());
504 
505  // Body:
506 
507  // Local coordinates of the gauss points.
508 
509  static const double d = 0.25;
510 
511  xresult[0] = d;
512  xresult[1] = d;
513  xresult[2] = d;
514  xresult[3] = d;
515 
516  // Postconditions:
517 
518  ensure(in_standard_domain(xresult, xresult_ub));
519 
520  // Exit:
521 
522  return;
523 }
524 
525 // ===========================================================
526 // DIFFERENTIABLE_SECTION_EVALUATOR FACET
527 // ===========================================================
528 
530 void
532 dxi_local(size_type xlocal_coord_index,
533  const dof_type xsource_dofs[],
534  size_type xsource_dofs_ub,
535  dof_type xresult_dofs[],
536  size_type xresult_dofs_ub) const
537 {
538  // Preconditions:
539 
540  require(xlocal_coord_index < db());
541  require(xsource_dofs != 0);
542  //require(xsource_dofs_ub >= dof_ct());
543  require(xresult_dofs != 0);
544  //require(xresult_dofs_ub >= dof_ct());
545 
546  // Body:
547 
548  // The 1st derivatives are constant for linear 3d.
549 
550  dof_type derivative = xsource_dofs[xlocal_coord_index] - xsource_dofs[3];
551 
552  for(int i=0; i<4; ++i)
553  xresult_dofs[i] = derivative;
554 
555  // Postconditions:
556 
557  // Exit:
558 
559  return;
560 }
561 
563 void
565 jacobian(const dof_type xcoord_dofs[],
566  size_type xcoord_dofs_ub,
567  size_type xdf,
568  const dof_type xlocal_coords[],
569  size_type xlocal_coords_ub)
570 {
571  // Preconditions:
572 
574 
575  require(xcoord_dofs != 0);
576  require(xcoord_dofs_ub >= xdf*dl());
577  require(xdf == 2 || xdf == 3);
578  require(xlocal_coords != 0);
579  require(xlocal_coords_ub >= 2);
580  require(jacobian_values() != 0);
581 
582  // Body:
583 
584  // Get the derivatives of the basis functions at the
585  // specified local coordinates.
586 
587  int local_coords_ct = 3;
588 
589  basis_derivs_at_coord(xlocal_coords, local_coords_ct);
590  const value_type* derivs = basis_deriv_values();
591 
592  // Loop over the columns of the jacobian matrix
593  // (columns correspond to the derivatives w.r.t. the local coordinates.)
594 
595  for(int i=0; i<local_coords_ct; ++i)
596  {
597  // Loop over the rows of the jacobian matrix
598  // (rows correspond to the global coordinates.)
599 
600  for(int j=0; j<xdf; ++j)
601  {
602  // Loop over the nodes and sum the product of the derivatives and
603  // the global nodal coordinates.
604 
605  value_type sum = 0.0;
606 
607  for(int k=0; k<dl(); ++k)
608  {
609  // Derivatives and coordinate dofs are "interleaved".
610 
611  value_type deriv = derivs[local_coords_ct*k+i];
612  value_type coord = xcoord_dofs[xdf*k+j];
613 
614  sum += deriv*coord;
615 
616  cout << "++++++++++++++++++++++++++++++++++" << endl;
617  cout << " deriv = " << deriv << endl;
618  cout << " coord = " << coord << endl;
619  cout << " sum = " << sum << endl;
620  cout << "++++++++++++++++++++++++++++++++++" << endl;
621  }
622 
623  // Store the sum in the appropriate location in the Jacobian matrix.
624 
625  int ij = local_coords_ct*j+i;
626  _jacobian_values[ij] = sum;
627  }
628  }
629 
630  // Postconditions:
631 
632  ensure(invariant());
633 
634  // Exit:
635 
636  return;
637 }
638 
639 // ===========================================================
640 // DOMAIN FACET
641 // ===========================================================
642 
644 int
646 db() const
647 {
648  int result;
649 
650  // Preconditions:
651 
652 
653  // Body:
654 
655  result = 3;
656 
657  // Postconditions:
658 
659  ensure(result == 3);
660 
661  // Exit:
662 
663  return result;
664 }
665 
666 
668 void
671  coord_type xresult[],
672  size_type xresult_ub) const
673 {
674  // Preconditions:
675 
676  require((0 <= xindex) && (xindex < dof_ct()));
677  require(xresult_ub >= db());
678 
679  // Body:
680 
681  static const coord_type lcoords[4][3] =
682  {
683  {
684  1.0, 0.0, 0.0
685  }
686  , {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 0.0, 0.0}
687  } ;
688 
689  xresult[0] = lcoords[xindex][0];
690  xresult[1] = lcoords[xindex][1];
691  xresult[2] = lcoords[xindex][2];
692 
693  // Postconditions:
694 
695  ensure(in_standard_domain(xresult, xresult_ub));
696 
697  // Exit:
698 
699  return;
700 }
701 
703 void
705 center(coord_type xresult[], size_type xresult_ub) const
706 {
707  // Preconditions:
708 
709  require(xresult != 0);
710  require(xresult_ub >= db());
711 
712  // Body:
713 
714  static coord_type one_fourth =
715  static_cast<coord_type>(1.0)/static_cast<coord_type>(4.0);
716 
717  xresult[0] = one_fourth;
718  xresult[1] = one_fourth;
719  xresult[2] = one_fourth;
720 
721  // Postconditions:
722 
723 
724  // Exit:
725 
726  return;
727 }
728 
730 bool
732 in_standard_domain(const dof_type xlocal_coords[],
733  size_type xlocal_coords_ub) const
734 {
735  // Preconditions:
736 
737  require(xlocal_coords != 0);
738  require(xlocal_coords_ub >= 2);
739 
740  // Body:
741 
742  dof_type u = xlocal_coords[0];
743  dof_type v = xlocal_coords[1];
744  dof_type w = xlocal_coords[2];
745 
746  // "Extend" the bounds by the dof type epsilon (attempting
747  // to ensure that the boundary is included in the domain).
748 
749  dof_type zero = 0.0 - 1000.0*numeric_limits<dof_type>::epsilon();
750  dof_type one = 1.0 + 1000.0*numeric_limits<dof_type>::epsilon();
751 
752  bool result = (u >= zero) && (u <= one) &&
753  (v >= zero) && (v <= one) &&
754  (w >= zero) && (w <= one);
755 
756  // Postconditions:
757 
758  // Exit:
759 
760  return result;
761 
762 }
763 
764 // ===========================================================
765 // EVALUATION FACET
766 // ===========================================================
767 
769 void
771 coord_at_value(const dof_type xdofs[],
772  size_type xdofs_ub,
773  const dof_type xglobal_coords[],
774  size_type xglobal_coord_ub,
775  dof_type xlocal_coords[],
776  size_type xlocal_coords_ub) const
777 {
778  // Preconditions:
779 
780  require(xdofs != 0);
781  require(xdofs_ub >= 9);
782  require(xglobal_coords != 0);
783  require(xglobal_coord_ub >= 3);
784  require(xlocal_coords != 0);
785  require(xlocal_coords_ub >= 3);
786 
787  // Body:
788 
789  // cout << "linear_3d::coord_at_value()" << endl;
790 
791  // The dofs are assumed to be interleaved
792  // (x0, y0, z0, x1, y1, z1, x2, y2, z2).
793 
794  dof_type x0 = xdofs[0];
795  dof_type x1 = xdofs[3];
796  dof_type x2 = xdofs[6];
797  dof_type x3 = xdofs[9];
798 
799  dof_type y0 = xdofs[1];
800  dof_type y1 = xdofs[4];
801  dof_type y2 = xdofs[7];
802  dof_type y3 = xdofs[10];
803 
804  dof_type z0 = xdofs[2];
805  dof_type z1 = xdofs[5];
806  dof_type z2 = xdofs[8];
807  dof_type z3 = xdofs[11];
808 
809  dof_type x_global = xglobal_coords[0];
810  dof_type y_global = xglobal_coords[1];
811  dof_type z_global = xglobal_coords[2];
812 
814 
815  double a01 = x0*y1-x1*y0;
816  double a02 = x0*y2-x2*y0;
817  double a03 = x0*y3-x3*y0;
818  double a12 = x1*y2-x2*y1;
819  double a13 = x1*y3-x3*y1;
820  double a23 = x2*y3-x3*y2;
821 
822  double a10 = -a01;
823  double a20 = -a02;
824  double a30 = -a03;
825  double a21 = -a12;
826  double a31 = -a13;
827  double a32 = -a23;
828 
830 
831  double b01 = y0-y1;
832  double b02 = y0-y2;
833  double b12 = y1-y2;
834  double b23 = y2-y3;
835  double b30 = y3-y0;
836  double b31 = y3-y1;
837 
840 
841  // double b10 = -b01;
842  double b20 = -b02;
843  // double b21 = -b12;
844  double b32 = -b23;
845  double b03 = -b30;
846  double b13 = -b31;
847 
848  double c01 = x0-x1;
849  double c02 = x0-x2;
850  double c12 = x1-x2;
851  double c23 = x2-x3;
852  double c30 = x3-x0;
853  double c31 = x3-x1;
854 
855  double c10 = -c01;
856  // double c20 = -c02;
857  double c21 = -c12;
858  double c03 = -c30;
859  double c13 = -c31;
860  double c32 = -c23;
861 
863 
864  // The following z## values represent the adjoint of the matrix:
865  //
866  // 1 1 1 1
867  // x0 x2 x3 x4
868  // y0 y2 y3 y4
869  // z0 z2 z3 z4
870  //
871  // (Dividing by the determinant gives the inverse).
872 
873  double z00 = a23*z1 + a31*z2 + a12*z3;
874  double z01 = b23*z1 + b31*z2 + b12*z3;
875  double z02 = c32*z1 + c13*z2 + c21*z3;
876  double z03 = a32 + a21 + a13;
877 
878  double z10 = a32*z0 + a03*z2 + a20*z3;
879  double z11 = b32*z0 + b03*z2 + b20*z3;
880  double z12 = c23*z0 + c30*z2 + c02*z3;
881  double z13 = a23 + a02 + a30;
882 
883  double z20 = a13*z0 + a30*z1 + a01*z3;
884  double z21 = b13*z0 + b30*z1 + b01*z3;
885  double z22 = c31*z0 + c03*z1 + c10*z3;
886  double z23 = a31 + a10 + a03;
887 
888  double z30 = a21*z0 + a02*z1 + a10*z2;
889  // double z31 = b21*z0 + b02*z1 + b10*z2;
890  // double z32 = c12*z0 + c20*z1 + c01*z2;
891  // double z33 = a12 + a01 + a20;
892 
894 
895  // The determinant (which is 6 times the volume of the tetraherdon)
896  // can be calcluated as:
897  // double det = a01*(z3-z2) + a02*(z1-z3) + a03*(z2-z1)
898  // + a12*(z3-z0) + a13*(z0-z2) + a23*(z1-z0);
899 
900  // However, the following is more efficient:
901 
902  double det = z00 + z10 + z20 + z30;
903 
904  // cout << " det = " << det << endl;
905 
906  double shape0 = (z00 + z01*x_global + z02*y_global + z03*z_global) / det;
907  double shape1 = (z10 + z11*x_global + z12*y_global + z13*z_global) / det;
908  double shape2 = (z20 + z21*x_global + z22*y_global + z23*z_global) / det;
909 
910  // double shape3 = (z30 + z31*x_global + z32*y_global + z33*z_global) / det;
911 
912  double shape3 = 1.0 - (shape0 + shape1 + shape2);
913 
914  // cout << "shape0 = " << shape0 << endl;
915  // cout << "shape1 = " << shape1 << endl;
916  // cout << "shape2 = " << shape2 << endl;
917  // cout << "shape3 = " << shape3 << endl;
918 
920 
921  // Return 3 local (area) coordinates.
922 
923  xlocal_coords[0] = shape0;
924  xlocal_coords[1] = shape1;
925  xlocal_coords[2] = shape2;
926 
927  // Return non null only if the search point is inside the element
928  // or on the element boundary.
929 
930  // Postconditions:
931 
932  ensure(invariant());
933 
934  // Exit:
935 
936  return;
937 }
938 
939 // ===========================================================
940 // ANY FACET
941 // ===========================================================
942 
946 clone() const
947 {
948  linear_3d* result;
949 
950  // Preconditions:
951 
952  // Body:
953 
954  result = new linear_3d();
955 
956  // Postconditions:
957 
958  ensure(result != 0);
959  ensure(is_same_type(result));
960  //ensure(invariant());
961  ensure(result->invariant());
962 
963  return result;
964 }
965 
966 
971 {
972  // Preconditions:
973 
974  require(is_ancestor_of(&xother));
975 
976  // Body:
977 
978  not_implemented();
979 
980  // Postconditions:
981 
982  ensure(invariant());
983 
984  return *this;
985 }
986 
990 operator=(const linear_3d& xother)
991 {
992 
993  // Preconditions:
994 
995  require(is_ancestor_of(&xother));
996 
997  // Body:
998 
999  not_implemented();
1000 
1001  // Postconditions:
1002 
1003  ensure(invariant());
1004 
1005  // Exit:
1006 
1007  return *this;
1008 }
1009 
1011 bool
1013 invariant() const
1014 {
1015  bool result = true;
1016 
1017  // Preconditions:
1018 
1019  // Body:
1020 
1021  // Must satisfy base class invariant.
1022 
1023  result = result && linear_fcn_space::invariant();
1024 
1025  if(invariant_check())
1026  {
1027  // Prevent recursive calls to invariant.
1028 
1029  disable_invariant_check();
1030 
1031  invariance(basis_values() != 0);
1032 
1033  // Finished, turn invariant checking back on.
1034 
1035  enable_invariant_check();
1036  }
1037 
1038  // Postconditions:
1039 
1040  return result;
1041 }
1042 
1044 bool
1046 is_ancestor_of(const any* xother) const
1047 {
1048 
1049  // Preconditions:
1050 
1051  require(xother != 0);
1052 
1053  // Body:
1054 
1055  // True if other conforms to this
1056 
1057  bool result = dynamic_cast<const linear_3d*>(xother) != 0;
1058 
1059  // Postconditions:
1060 
1061  return result;
1062 
1063 }
1064 
1065 // ===========================================================
1066 // PRIVATE MEMBERS
1067 // ===========================================================
1068 
1069 
virtual linear_3d * clone() const
Virtual constructor, creates a new instance of the same type as this.
Definition: linear_3d.cc:946
SHEAF_DLL_SPEC void sqrt(const sec_at0 &x0, sec_at0 &xresult, bool xauto_access)
Compute sqrt of x0 (sqrt(x0)) (pre-allocated version).
Definition: sec_at0.cc:1556
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)
Jacobian matrix.
Definition: linear_3d.cc:565
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)
Determinant of Jacobian matrix (square)
Definition: linear_3d.cc:228
virtual bool is_ancestor_of(const any *xother) const
Conformance test; true if other conforms to this.
Definition: linear_3d.cc:1046
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...
Definition: linear_3d.cc:732
STL namespace.
sec_vd_dof_type dof_type
The type of degree of freedom.
A section evaluator using linear interpolation over a tetrahedral 3D domain.
Definition: linear_3d.h:38
virtual bool invariant() const
Class invariant.
Definition: linear_3d.cc:1013
Abstract base class with useful features for all objects.
Definition: any.h:39
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...
virtual int db() const
The base dimension; the dimension of the local coordinates (independent variable).
Definition: linear_3d.cc:646
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.
Definition: linear_3d.cc:670
unsigned long size_type
An unsigned integral type used to represent sizes and capacities.
Definition: sheaf.h:52
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.
Definition: linear_3d.cc:135
chart_point_coord_type coord_type
The type of local coordinate; the scalar type for the local coordinate vector space.
linear_3d()
Default constructor.
Definition: linear_3d.cc:36
vd_value_type value_type
The type of component in the value; the scalar type in the range vector space.
SHEAF_DLL_SPEC void fabs(const sec_at0 &x0, sec_at0 &xresult, bool xauto_access)
Compute fabs of x0 (fabs(x0)) (pre-allocated version).
Definition: sec_at0.cc:1331
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.
Definition: linear_3d.cc:532
An abstract local section evaluator; a map from {local coordinates x dofs} to section value...
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 ...
Definition: linear_3d.cc:771
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.
Definition: linear_3d.cc:301
virtual void center(coord_type xresult[], size_type xresult_ub) const
The local coordinates at the center of the evaluator.
Definition: linear_3d.cc:705
int_type pod_index_type
The plain old data index type.
Definition: pod_types.h:49
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...
Definition: linear_3d.cc:163
virtual linear_3d & operator=(const section_evaluator &xother)
Assignment operator.
Definition: linear_3d.cc:970
virtual int dl() const
The dimension of this function space.
Definition: linear_3d.cc:112
virtual ~linear_3d()
Destructor.
Definition: linear_3d.cc:80
Namespace for the fiber_bundles component of the sheaf system.
double determinant_3x3(double a00, double a01, double a02, double a10, double a11, double a12, double a20, double a21, double a22)
///
Definition: linear_3d.cc:94
void gauss_point(pod_index_type xindex, coord_type xresult[], size_type xresult_ub)
The local coordinates of the gauss point with index xindex.
Definition: linear_3d.cc:496