SheafSystem  0.0.0.0
linear_1d.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_1d
19 
20 #include "SheafSystem/linear_1d.h"
21 #include "SheafSystem/assert_contract.h"
22 #include "SheafSystem/std_limits.h"
23 #include "SheafSystem/std_cmath.h"
24 
25 using namespace std;
26 using namespace fiber_bundle; // Workaround for MS C++ bug.
27 
28 // ===========================================================
29 // LINEAR_1D FACET
30 // ===========================================================
31 
35 {
36  // Preconditions:
37 
38  // Body:
39 
40  _basis_values = _basis_value_buffer;
41  _basis_deriv_values = _basis_deriv_value_buffer;
42  _jacobian_values = _jacobian_value_buffer;
43 
44  // Postconditions:
45 
46  ensure(invariant());
47 
48  return;
49 }
50 
51 
54 linear_1d(const linear_1d& 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 
86 #ifndef DOXYGEN_SKIP_UNKNOWN
87 
89 double
91 inverse_jacobian(const double xjacobian[1],
92  double xinverse_jacobian[1])
93 {
94  double j00 = xjacobian[0];
95 
96  // Calculate the determinant of the jacobian
97  // (also return it).
98 
99  double determinant = j00;
100 
101  xinverse_jacobian[0] = 1.0 / determinant;
102 
103  // Return the determinant also.
104 
105  return determinant;
106 }
107 
108 #endif // ifndef DOXYGEN_SKIP_UNKNOWN
109 
110 // ===========================================================
111 // LINEAR_FCN_SPACE FACET
112 // ===========================================================
113 
115 int
117 dl() const
118 {
119  int result;
120 
121  // Preconditions:
122 
123 
124  // Body:
125 
126  result = DL;
127 
128  // Postconditions:
129 
130  ensure(result == 2);
131 
132  // Exit:
133 
134  return result;
135 }
136 
137 void
139 basis_at_coord(const dof_type xlocal_coord[], size_type xlocal_coord_ub)
140 {
141  // Preconditions:
142 
143  require(xlocal_coord != 0);
144  require(xlocal_coord_ub >= db());
145 
146  // Body:
147 
148  // Evaluate the interpolation functions at the local coordinate.
149 
150  _basis_values[0] = 0.5*(1.0 - xlocal_coord[0]);
151  _basis_values[1] = 0.5*(1.0 + xlocal_coord[0]);
152 
153  // Postconditions:
154 
155  ensure(invariant());
156 }
157 
159 void
161 basis_derivs_at_coord(const dof_type xlocal_coords[],
162  size_type xlocal_coords_ub)
163 {
164  // Preconditions:
165 
166  //require(xlocal_coords != 0);
167  //require(xlocal_coords_ub >= db());
168 
169  // Body:
170 
171  // Evaluate the derivatives of the interpolation functions.
172  // The derivatives are interleaved (N,r[0], N,s[0], N,r[1], N,s[1], ...).
173 
174  // Note that we do not use the local coordinates here because the
175  // derivatives are constant.
176 
177  // Derivative with respect to r.
178 
179  _basis_deriv_value_buffer[0] = -0.5;
180  _basis_deriv_value_buffer[1] = 0.5;
181 
182  // Postconditions:
183 
184  ensure(invariant());
185 
186  // Exit:
187 
188  return;
189 }
190 
191 // ===========================================================
192 // INTEGRABLE_SECTION_EVALUATOR FACET
193 // ===========================================================
194 
198 jacobian_determinant(const dof_type xcoord_dofs[],
199  size_type xcoord_dofs_ub,
200  size_type xdf,
201  const coord_type xlocal_coords[],
202  size_type xlocal_coords_ub)
203 {
204  // Precondition: xdf = 2 or xdf = 3 ?.
205 
206  // Preconditions:
207 
208  require(xcoord_dofs != 0);
209  require(xcoord_dofs_ub >= dl()*db());
210  require(xdf == 2 || xdf == 3);
211 
212  // Get the jacobian matrix.
213 
214  jacobian(xcoord_dofs, xcoord_dofs_ub, xdf, xlocal_coords, xlocal_coords_ub);
215  const value_type* jvalues = jacobian_values();
216 
217  // Here the "jacobian determinant" is the of same as the jacobian;
218 
219  value_type result = jvalues[0];
220 
221  return result;
222 }
223 
227 volume(const dof_type xcoord_dofs[], size_type xcoord_dofs_ub, size_type xdf)
228 {
229  // Preconditions:
230 
232 
233  require(xcoord_dofs != 0);
234  require(xcoord_dofs_ub >= dl()*db());
235  require(xdf == 1 || xdf == 2 || xdf == 3);
236 
237  // Body:
238 
239  // Here "volume" is actually the length.
240  // We assume that the cross sectional area is unit size.
241 
242  // Sum the squares for the coordinate component differences.
243 
246 
247  double sum = 0.0;
248  int index = 0;
249  for(int i=0; i<xdf; ++i)
250  {
251  // The coordinate dofs are interlaced (x0, y0, z0, x1,...).
252 
253  double c0 = xcoord_dofs[index];
254  double c1 = xcoord_dofs[index+xdf];
255  index++;
256  double c10 = c1 - c0;
257  sum += c10*c10;
258  }
259 
260  // Length is the square root of sum.
261 
262  value_type result = sqrt(sum);
263 
264  // Postconditions:
265 
266  ensure(invariant());
267  ensure(result >= 0.0);
268 
269  // Exit:
270 
271  return result;
272 }
273 
275 void
277 integrate(const dof_type xcoord_dofs[],
278  size_type xcoord_dofs_ub,
279  size_type xdf,
280  const dof_type xintegrands[],
281  size_type xintegrands_ub,
282  value_type xresult_integrals[],
283  size_type xresult_integrals_ub)
284 {
286 
287  // Preconditions:
288 
289  require(xcoord_dofs != 0);
290  require(xcoord_dofs_ub >= dl()*db());
291  require(xintegrands != 0);
292  require(xintegrands_ub >= dl());
293  require(xresult_integrals != 0);
294  require(xresult_integrals_ub > 0);
295 
296  // Body:
297 
298  value_type length = volume(xcoord_dofs, xcoord_dofs_ub, xdf);
299  value_type half_length = 0.5*length;
300 
301  int index = 0;
302  for(int i=0; i<xresult_integrals_ub; ++i)
303  {
304  dof_type fn = 0.0;
305  const dof_type* integrands_n = &xintegrands[i*2];
306 
307  for(int k=0; k<2; ++k)
308  {
309  fn += integrands_n[k];
310  }
311 
312  xresult_integrals[i] = fn*half_length;
313  }
314 
315  // Postconditions:
316 
317  ensure(invariant());
318 
319  // Exit:
320 
321  return;
322 }
323 
325 void
327 integrate(const dof_type xcoord_dofs[],
328  size_type xcoord_dofs_ub,
329  size_type xdf,
330  const dof_type xintegrand,
331  value_type xresult_integrals[],
332  size_type xresult_integrals_ub)
333 {
335 
336  // Preconditions:
337 
338  require(xcoord_dofs != 0);
339  require(xcoord_dofs_ub >= dl()*db());
340  require(xresult_integrals != 0);
341  require(xresult_integrals_ub >= dl());
342 
343  // Body:
344 
345  // In 1d the integrations can be done exactly.
346 
347  value_type length = volume(xcoord_dofs, xcoord_dofs_ub, xdf);
348  value_type half_length = 0.5*length;
349  value_type nodal_value = xintegrand * half_length;
350  xresult_integrals[0] = nodal_value;
351  xresult_integrals[1] = nodal_value;
352 
353  // Postconditions:
354 
355  ensure(invariant());
356 
357  // Exit:
358 
359  return;
360 }
361 
363 void
366  coord_type xresult[],
367  size_type xresult_ub)
368 {
369  // Preconditions:
370 
371  require((0 <= xindex) && (xindex < dof_ct()));
372  require(xresult_ub >= 1);
373 
374  // Body:
375 
376  // Local coordinates of the gauss points.
377 
378  static const double d = 1.0 / sqrt(3.0);
379  static const coord_type gauss_coords[2] =
380  {
381  -d, d
382  };
383 
384  xresult[0] = gauss_coords[xindex];
385 
386  // Postconditions:
387 
388  ensure(in_standard_domain(xresult, xresult_ub));
389 
390  // Exit:
391 
392  return;
393 }
394 
395 // ===========================================================
396 // DIFFERENTIABLE_SECTION_EVALUATOR FACET
397 // ===========================================================
398 
400 void
402 dxi_local(size_type xlocal_coord_index,
403  const dof_type xsource_dofs[],
404  size_type xsource_dofs_ub,
405  dof_type xresult_dofs[],
406  size_type xresult_dofs_ub) const
407 {
408  // Preconditions:
409 
410  require(xlocal_coord_index < db());
411  require(xsource_dofs != 0);
412  //require(xsource_dofs_ub >= dof_ct());
413  require(xresult_dofs != 0);
414  //require(xresult_dofs_ub >= dof_ct());
415 
416  // Body:
417 
418  // The 1st derivative is constant for linear 1d.
419 
420  dof_type derivative = 0.5 * (xsource_dofs[1] - xsource_dofs[0]);
421 
422  xresult_dofs[0] = derivative;
423  xresult_dofs[1] = derivative;
424 
425  // Postconditions:
426 
427  // Exit:
428 
429  return;
430 }
431 
433 void
435 jacobian(const dof_type xcoord_dofs[],
436  size_type xcoord_dofs_ub,
437  size_type xdf,
438  const dof_type xlocal_coords[],
439  size_type xlocal_coords_ub)
440 {
441  // Preconditions:
442 
444 
445  require(xcoord_dofs != 0);
446  require(xcoord_dofs_ub >= xdf*dl());
447  require(xdf == 1 || xdf == 2 || xdf == 3);
448  require(xlocal_coords != 0);
449  require(xlocal_coords_ub >= 1);
450  require(jacobian_values() != 0);
451 
452  // Body:
453 
454  int index = 0;
455  for(int i=0; i<xdf; ++i)
456  {
457  // The coordinate dofs are interlaced (x0, y0, z0, x1,...).
458 
459  double c0 = xcoord_dofs[index];
460  double c1 = xcoord_dofs[index+xdf];
461  index++;
462  _jacobian_values[i] = 0.5*(c1-c0);
463  }
464 
465  // Postconditions:
466 
467  ensure(invariant());
468 
469  // Exit:
470 
471  return;
472 }
473 
474 // ===========================================================
475 // DOMAIN FACET
476 // ===========================================================
477 
479 int
481 db() const
482 {
483  int result;
484 
485  // Preconditions:
486 
487 
488  // Body:
489 
490  result = 1;
491 
492  // Postconditions:
493 
494  ensure(result == 1);
495 
496  // Exit:
497 
498  return result;
499 }
500 
502 void
505  coord_type xresult[],
506  size_type xresult_ub) const
507 {
508  // Preconditions:
509 
510  require((0 <= xindex) && (xindex < dof_ct()));
511  require(xresult_ub >= db());
512 
513  // Body:
514 
515  static const coord_type lcoords[2] =
516  {
517  -1.0, 1.0
518  };
519 
520  xresult[0] = lcoords[xindex];
521 
522  // Postconditions:
523 
524  ensure(in_standard_domain(xresult, xresult_ub));
525 
526  // Exit:
527 
528  return;
529 }
530 
532 bool
534 in_standard_domain(const dof_type xlocal_coords[],
535  size_type xlocal_coords_ub) const
536 {
537  // Preconditions:
538 
539  require(xlocal_coords != 0);
540  require(xlocal_coords_ub >= 1);
541 
542  // Body:
543 
544  dof_type u = xlocal_coords[0];
545 
546  // "Extend" the bounds by the dof type epsilon (attempting
547  // to ensure that the boundary is included in the domain).
548 
549  dof_type one = 1.0 + 1000.0*numeric_limits<dof_type>::epsilon();
550 
551  bool result = (u >= -one) && (u <= one);
552 
553  // Postconditions:
554 
555  // Exit:
556 
557  return result;
558 
559 }
560 
561 // ===========================================================
562 // EVALUATION FACET
563 // ===========================================================
564 
566 void
568 coord_at_value(const dof_type xdofs[],
569  size_type xdofs_ub,
570  const dof_type xglobal_coords[],
571  size_type xglobal_coord_ub,
572  dof_type xlocal_coords[],
573  size_type xlocal_coords_ub) const
574 {
575  // Preconditions:
576 
577  require(xdofs != 0);
578  require(xdofs_ub >= 2);
579  require(xglobal_coords != 0);
580  require(xglobal_coord_ub >= 1);
581  require(xlocal_coords != 0);
582  require(xlocal_coords_ub >= 1);
583 
584  // Body:
585 
586  //cout << "linear_1d::coord_at_value()" << endl;
587 
588  dof_type x0 = xdofs[0];
589  dof_type x1 = xdofs[1];
590 
591  dof_type x_global = xglobal_coords[0];
592 
593  double length = x1 - x0;
594 
595  xlocal_coords[0] = (2.0*x_global - (x0 + x1)) / length;
596 
597  // Return non null only if the search point is inside the element
598  // or on the element boundary.
599 
600  // Postconditions:
601 
602  ensure(invariant());
603 
604  // Exit:
605 
606  return;
607 
608 }
609 
610 // ===========================================================
611 // ANY FACET
612 // ===========================================================
613 
617 clone() const
618 {
619  linear_1d* result;
620 
621  // Preconditions:
622 
623  // Body:
624 
625  result = new linear_1d();
626 
627  // Postconditions:
628 
629  ensure(result != 0);
630  //ensure(invariant());
631  ensure(result->invariant());
632  ensure(is_same_type(result));
633 
634  return result;
635 }
636 
637 
642 {
643  // Preconditions:
644 
645  require(is_ancestor_of(&xother));
646 
647  // Body:
648 
649  not_implemented();
650 
651  // Postconditions:
652 
653  ensure(invariant());
654 
655  return *this;
656 }
657 
661 operator=(const linear_1d& xother)
662 {
663 
664  // Preconditions:
665 
666  require(is_ancestor_of(&xother));
667 
668  // Body:
669 
670  not_implemented();
671 
672  // Postconditions:
673 
674  ensure(invariant());
675 
676  // Exit:
677 
678  return *this;
679 }
680 
681 
683 bool
685 invariant() const
686 {
687  bool result = true;
688 
689  // Preconditions:
690 
691  // Body:
692 
693  // Must satisfy base class invariant.
694 
695  result = result && linear_fcn_space::invariant();
696 
697  if(invariant_check())
698  {
699  // Prevent recursive calls to invariant.
700 
701  disable_invariant_check();
702 
703  invariance(basis_values() != 0);
704 
705  // Finished, turn invariant checking back on.
706 
707  enable_invariant_check();
708  }
709 
710  // Postconditions:
711 
712  return result;
713 }
714 
716 bool
718 is_ancestor_of(const any* xother) const
719 {
720 
721  // Preconditions:
722 
723  require(xother != 0);
724 
725  // Body:
726 
727  // True if other conforms to this
728 
729  bool result = dynamic_cast<const linear_1d*>(xother) != 0;
730 
731  // Postconditions:
732 
733  return result;
734 
735 }
736 
737 // ===========================================================
738 // PRIVATE MEMBERS
739 // ===========================================================
740 
linear_1d()
Default constructor.
Definition: linear_1d.cc:34
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
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.
Definition: linear_1d.cc:568
virtual linear_1d & operator=(const section_evaluator &xother)
Assignment operator.
Definition: linear_1d.cc:641
STL namespace.
virtual bool is_ancestor_of(const any *xother) const
Conformance test; true if other conforms to this.
Definition: linear_1d.cc:718
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_1d.cc:435
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_1d.cc:139
sec_vd_dof_type dof_type
The type of degree of freedom.
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.
Definition: linear_1d.cc:365
virtual ~linear_1d()
Destructor.
Definition: linear_1d.cc:73
SHEAF_DLL_SPEC void determinant(const st2 &x0, vd_value_type &xresult, bool xauto_access)
The determinant of a symmetric tensor (pre-allocated version for persistent types).
Definition: st2.cc:1228
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_1d.cc:504
SHEAF_DLL_SPEC vd_value_type length(const ed &x0, bool xauto_access)
The Euclidean length (magnitude) of x0 (version for persistent types).
Definition: ed.cc:906
Abstract base class with useful features for all objects.
Definition: any.h:39
value_type volume(const dof_type xcoord_dofs[], size_type xcoord_dofs_ub, size_type xdf)
Volume...
Definition: linear_1d.cc:227
unsigned long size_type
An unsigned integral type used to represent sizes and capacities.
Definition: sheaf.h:52
virtual linear_1d * clone() const
Virtual constructor, creates a new instance of the same type as this.
Definition: linear_1d.cc:617
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.
virtual int db() const
The base dimension; the dimension of the local coordinates (independent variable).
Definition: linear_1d.cc:481
virtual int dl() const
The dimension of this function space.
Definition: linear_1d.cc:117
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_1d.cc:198
virtual bool invariant() const
Class invariant.
Definition: linear_1d.cc:685
An abstract local section evaluator; a map from {local coordinates x dofs} to section value...
virtual void dxi_local(size_type xlocal_coord_index, const dof_type xsource_dofs[], size_type xsource_dofs_ub, dof_type xresult_dofs[], size_type xresult_dofs_ub) const
First partial derivative of this with respect to local coordinate xlocal_coord_index.
Definition: linear_1d.cc:402
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_1d.cc:161
int_type pod_index_type
The plain old data index type.
Definition: pod_types.h:49
A section evaluator using linear interpolation over a 1D domain.
Definition: linear_1d.h:37
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 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_1d.cc:534
double inverse_jacobian(const double xjacobian[], double xinverse_jacobian[])
Determinant of Jacobian matrix (square)
Definition: linear_1d.cc:91
Namespace for the fiber_bundles component of the sheaf system.