20 #include "SheafSystem/trilinear_3d.h" 21 #include "SheafSystem/assert_contract.h" 22 #include "SheafSystem/error_message.h" 23 #include "SheafSystem/std_iostream.h" 24 #include "SheafSystem/std_iomanip.h" 25 #include "SheafSystem/std_limits.h" 26 #include "SheafSystem/std_cmath.h" 37 const int ITR_UB = 10;
46 const double TOLERANCE = 1.0e-9;
55 inline bool is_close_enough(
double x1,
double x2)
59 return (
fabs(x2 - x1) <= TOLERANCE);
75 _basis_values = _basis_value_buffer;
76 _basis_deriv_values = _basis_deriv_value_buffer;
77 _jacobian_values = _jacobian_value_buffer;
96 _basis_values = _basis_value_buffer;
97 _basis_deriv_values = _basis_deriv_value_buffer;
98 _jacobian_values = _jacobian_value_buffer;
128 fiber_bundle::trilinear_3d::
129 inverse_jacobian(
const double xjacobian[3][3],
130 double xinverse_jacobian[3][3])
134 double j00 = xjacobian[0][0];
135 double j01 = xjacobian[0][1];
136 double j02 = xjacobian[0][2];
137 double j10 = xjacobian[1][0];
138 double j11 = xjacobian[1][1];
139 double j12 = xjacobian[1][2];
140 double j20 = xjacobian[2][0];
141 double j21 = xjacobian[2][1];
142 double j22 = xjacobian[2][2];
144 double c00 = j11 * j22 - j12 * j21;
145 double c01 = j12 * j20 - j10 * j22;
146 double c02 = j10 * j21 - j11 * j20;
148 double c10 = j02 * j21 - j01 * j22;
149 double c11 = j00 * j22 - j02 * j20;
150 double c12 = j01 * j20 - j00 * j21;
152 double c20 = j01 * j12 - j02 * j11;
153 double c21 = j02 * j10 - j00 * j12;
154 double c22 = j00 * j11 - j01 * j10;
156 double determinant = j00 * c00 + j01 * c01 + j02 * c02;
220 require(xlocal_coord != 0);
221 require(xlocal_coord_ub >= db());
231 _basis_values[0] = 0.125*(1-r)*(1-s)*(1-t);
232 _basis_values[1] = 0.125*(1+r)*(1-s)*(1-t);
233 _basis_values[2] = 0.125*(1+r)*(1+s)*(1-t);
234 _basis_values[3] = 0.125*(1-r)*(1+s)*(1-t);
235 _basis_values[4] = 0.125*(1-r)*(1-s)*(1+t);
236 _basis_values[5] = 0.125*(1+r)*(1-s)*(1+t);
237 _basis_values[6] = 0.125*(1+r)*(1+s)*(1+t);
238 _basis_values[7] = 0.125*(1-r)*(1+s)*(1+t);
254 require(xlocal_coords != 0);
255 require(xlocal_coords_ub >= db());
263 double r = xlocal_coords[0];
264 double s = xlocal_coords[1];
265 double t = xlocal_coords[2];
274 double rmxsm = rm * sm;
275 double rpxsm = rp * sm;
276 double rpxsp = rp * sp;
277 double rmxsp = rm * sp;
279 double rmxtm = rm * tm;
280 double rpxtm = rp * tm;
281 double rpxtp = rp * tp;
282 double rmxtp = rm * tp;
284 double smxtm = sm * tm;
285 double spxtm = sp * tm;
286 double spxtp = sp * tp;
287 double smxtp = sm * tp;
291 _basis_deriv_value_buffer[ 0] = -smxtm;
292 _basis_deriv_value_buffer[ 3] = smxtm;
293 _basis_deriv_value_buffer[ 6] = spxtm;
294 _basis_deriv_value_buffer[ 9] = -spxtm;
295 _basis_deriv_value_buffer[12] = -smxtp;
296 _basis_deriv_value_buffer[15] = smxtp;
297 _basis_deriv_value_buffer[18] = spxtp;
298 _basis_deriv_value_buffer[21] = -spxtp;
302 _basis_deriv_value_buffer[ 1] = -rmxtm;
303 _basis_deriv_value_buffer[ 4] = -rpxtm;
304 _basis_deriv_value_buffer[ 7] = rpxtm;
305 _basis_deriv_value_buffer[10] = rmxtm;
306 _basis_deriv_value_buffer[13] = -rmxtp;
307 _basis_deriv_value_buffer[16] = -rpxtp;
308 _basis_deriv_value_buffer[19] = rpxtp;
309 _basis_deriv_value_buffer[22] = rmxtp;
313 _basis_deriv_value_buffer[ 2] = -rmxsm;
314 _basis_deriv_value_buffer[ 5] = -rpxsm;
315 _basis_deriv_value_buffer[ 8] = -rpxsp;
316 _basis_deriv_value_buffer[11] = -rmxsp;
317 _basis_deriv_value_buffer[14] = rmxsm;
318 _basis_deriv_value_buffer[17] = rpxsm;
319 _basis_deriv_value_buffer[20] = rpxsp;
320 _basis_deriv_value_buffer[23] = rmxsp;
322 for(
int i=0; i<24; i++)
324 _basis_deriv_value_buffer[i] *= 0.125;
353 require(xcoord_dofs != 0);
354 require(xcoord_dofs_ub >= dl()*db());
355 require(xdf == 2 || xdf == 3);
359 jacobian(xcoord_dofs, xcoord_dofs_ub, xdf, xlocal_coords, xlocal_coords_ub);
360 const value_type* jvalues = jacobian_values();
378 for(
int i=0; i<xdf; ++i)
401 - g10*(g01*g22-g02*g21)
402 + g20*(g01*g12-g02*g11);
420 require(xcoord_dofs != 0);
421 require(xcoord_dofs_ub >= dl()*db());
422 require(xdf == 2 || xdf == 3);
428 static int NUM_GAUSS_POINTS = 8;
432 for(
int n=0; n<NUM_GAUSS_POINTS; ++n)
435 gauss_point(n, local_coords, 3);
437 value_type det = jacobian_determinant(xcoord_dofs, xcoord_dofs_ub, xdf,
474 require(xcoord_dofs != 0);
475 require(xcoord_dofs_ub >= dl()*db());
476 require(xintegrands != 0);
477 require(xintegrands_ub >= dl());
478 require(xresult_integrals != 0);
479 require(xresult_integrals_ub > 0);
485 for(
int i=0; i<xresult_integrals_ub; ++i)
487 xresult_integrals[i] = 0.0;
492 static int NUM_GAUSS_POINTS = 8;
494 for(
int n=0; n<NUM_GAUSS_POINTS; ++n)
497 gauss_point(n, local_coords, 3);
500 value_type det = jacobian_determinant(xcoord_dofs, xcoord_dofs_ub, xdf,
505 basis_at_coord(local_coords, 3);
508 for(
int i=0; i<xresult_integrals_ub; ++i)
511 const dof_type* integrands_n = xintegrands+(i*8);
513 for(
int k=0; k<8; ++k)
515 fn += basis[k]*integrands_n[k];
518 xresult_integrals[i] += det*fn;
545 require(xcoord_dofs != 0);
546 require(xcoord_dofs_ub >= dl()*db());
547 require(xresult_integrals != 0);
548 require(xresult_integrals_ub >= dl());
554 for(
int i=0; i<xresult_integrals_ub; ++i)
556 xresult_integrals[i] = 0.0;
559 static int NUM_GAUSS_POINTS = 8;
561 for(
int n=0; n<NUM_GAUSS_POINTS; ++n)
564 gauss_point(n, local_coords, 3);
566 value_type det = jacobian_determinant(xcoord_dofs, xcoord_dofs_ub, xdf,
571 basis_at_coord(local_coords, 3);
574 for(
int i=0; i<8; ++i)
576 xresult_integrals[i] += basis[i] * det;
582 for(
int i=0; i<8; ++i)
584 xresult_integrals[i] *= xintegrand;
605 require((0 <= xindex) && (xindex < dof_ct()));
606 require(xresult_ub >= db());
612 static const double d = 1.0 /
sqrt(3.0);
618 , {d, -d, -d}, {d, d, -d}, {-d, d, -d},
619 {-d, -d, d}, {d, -d, d}, {d, d, d}, {-d, d, d}
622 xresult[0] = gauss_coords[xindex][0];
623 xresult[1] = gauss_coords[xindex][1];
624 xresult[2] = gauss_coords[xindex][2];
628 ensure(in_standard_domain(xresult, xresult_ub));
650 require(xlocal_coord_index < db());
651 require(xsource_dofs != 0);
653 require(xresult_dofs != 0);
658 if(xlocal_coord_index == 0)
660 dof_type d_minus_minus = 0.5 * (xsource_dofs[1] - xsource_dofs[0]);
661 dof_type d_plus_minus = 0.5 * (xsource_dofs[2] - xsource_dofs[3]);
662 dof_type d_minus_plus = 0.5 * (xsource_dofs[5] - xsource_dofs[4]);
663 dof_type d_plus_plus = 0.5 * (xsource_dofs[6] - xsource_dofs[7]);
665 xresult_dofs[0] = d_minus_minus;
666 xresult_dofs[1] = d_minus_minus;
667 xresult_dofs[2] = d_plus_minus;
668 xresult_dofs[3] = d_plus_minus;
669 xresult_dofs[4] = d_minus_plus;
670 xresult_dofs[5] = d_minus_plus;
671 xresult_dofs[6] = d_plus_plus;
672 xresult_dofs[7] = d_plus_plus;
674 else if(xlocal_coord_index == 1)
676 dof_type d_minus_minus = 0.5 * (xsource_dofs[3] - xsource_dofs[0]);
677 dof_type d_plus_minus = 0.5 * (xsource_dofs[2] - xsource_dofs[1]);
678 dof_type d_minus_plus = 0.5 * (xsource_dofs[7] - xsource_dofs[4]);
679 dof_type d_plus_plus = 0.5 * (xsource_dofs[6] - xsource_dofs[5]);
681 xresult_dofs[0] = d_minus_minus;
682 xresult_dofs[1] = d_plus_minus;
683 xresult_dofs[2] = d_plus_minus;
684 xresult_dofs[3] = d_minus_minus;
685 xresult_dofs[4] = d_minus_plus;
686 xresult_dofs[5] = d_plus_plus;
687 xresult_dofs[6] = d_plus_plus;
688 xresult_dofs[7] = d_minus_plus;
693 dof_type d_minus_minus = 0.5 * (xsource_dofs[4] - xsource_dofs[0]);
694 dof_type d_plus_minus = 0.5 * (xsource_dofs[5] - xsource_dofs[1]);
695 dof_type d_minus_plus = 0.5 * (xsource_dofs[7] - xsource_dofs[3]);
696 dof_type d_plus_plus = 0.5 * (xsource_dofs[6] - xsource_dofs[2]);
698 xresult_dofs[0] = d_minus_minus;
699 xresult_dofs[1] = d_plus_minus;
700 xresult_dofs[2] = d_plus_plus;
701 xresult_dofs[3] = d_minus_plus;
702 xresult_dofs[4] = d_minus_minus;
703 xresult_dofs[5] = d_plus_minus;
704 xresult_dofs[6] = d_plus_plus;
705 xresult_dofs[7] = d_minus_plus;
728 require(xcoord_dofs != 0);
729 require(xcoord_dofs_ub >= xdf*dl());
730 require(xdf == 2 || xdf == 3);
731 require(xlocal_coords != 0);
732 require(xlocal_coords_ub >= 2);
733 require(jacobian_values() != 0);
740 int local_coords_ct = 3;
742 basis_derivs_at_coord(xlocal_coords, local_coords_ct);
743 const value_type* derivs = basis_deriv_values();
748 for(
int i=0; i<local_coords_ct; ++i)
753 for(
int j=0; j<xdf; ++j)
760 for(
int k=0; k<dl(); ++k)
764 value_type deriv = derivs[local_coords_ct*k+i];
778 int ij = local_coords_ct*j+i;
779 _jacobian_values[ij] = sum;
909 require((0 <= xindex) && (xindex < dof_ct()));
910 require(xresult_ub >= db());
928 xresult[0] = lcoords[xindex][0];
929 xresult[1] = lcoords[xindex][1];
930 xresult[2] = lcoords[xindex][2];
934 ensure(in_standard_domain(xresult, xresult_ub));
949 require(xlocal_coords != 0);
950 require(xlocal_coords_ub >= 3);
961 dof_type one = 1.0 + 1000.0*numeric_limits<dof_type>::epsilon();
963 bool result = (u >= -one) && (u <= one) &&
964 (v >= -one) && (v <= one) &&
965 (w >= -one) && (w <= one);
1004 require(xdofs != 0);
1005 require(xdofs_ub >= 24);
1006 require(xglobal_coords != 0);
1007 require(xglobal_coord_ub >= 3);
1008 require(xlocal_coords != 0);
1009 require(xlocal_coords_ub >= 3);
1013 #ifdef DIAGNOSTIC_OUTPUT 1015 bool ldiagnostic_output =
true;
1018 bool ldiagnostic_output =
false;
1027 for(
int ipass = 0; ipass < 2; ++ipass)
1060 dof_type x_global = xglobal_coords[0];
1061 dof_type y_global = xglobal_coords[1];
1062 dof_type z_global = xglobal_coords[2];
1064 if((ipass > 0) || ldiagnostic_output)
1066 cout << endl <<
"trilinear_3d: global coords:" 1067 << setw(15) << x_global
1068 << setw(15) << y_global
1069 << setw(15) << z_global
1084 for(itr_ct=0; itr_ct < ITR_UB; ++itr_ct)
1093 double basis0 = (1-r)*(1-s)*(1-t);
1094 double basis1 = (1+r)*(1-s)*(1-t);
1095 double basis2 = (1+r)*(1+s)*(1-t);
1096 double basis3 = (1-r)*(1+s)*(1-t);
1097 double basis4 = (1-r)*(1-s)*(1+t);
1098 double basis5 = (1+r)*(1-s)*(1+t);
1099 double basis6 = (1+r)*(1+s)*(1+t);
1100 double basis7 = (1-r)*(1+s)*(1+t);
1102 double basis0_r = -(1-s)*(1-t);
1103 double basis1_r = (1-s)*(1-t);
1104 double basis2_r = (1+s)*(1-t);
1105 double basis3_r = -(1+s)*(1-t);
1106 double basis4_r = -(1-s)*(1+t);
1107 double basis5_r = (1-s)*(1+t);
1108 double basis6_r = (1+s)*(1+t);
1109 double basis7_r = -(1+s)*(1+t);
1111 double basis0_s = -(1-r)*(1-t);
1112 double basis1_s = -(1+r)*(1-t);
1113 double basis2_s = (1+r)*(1-t);
1114 double basis3_s = (1-r)*(1-t);
1115 double basis4_s = -(1-r)*(1+t);
1116 double basis5_s = -(1+r)*(1+t);
1117 double basis6_s = (1+r)*(1+t);
1118 double basis7_s = (1-r)*(1+t);
1120 double basis0_t = -(1-r)*(1-s);
1121 double basis1_t = -(1+r)*(1-s);
1122 double basis2_t = -(1+r)*(1+s);
1123 double basis3_t = -(1-r)*(1+s);
1124 double basis4_t = (1-r)*(1-s);
1125 double basis5_t = (1+r)*(1-s);
1126 double basis6_t = (1+r)*(1+s);
1127 double basis7_t = (1-r)*(1+s);
1129 double f = basis0*x0
1138 f = 0.125*f - x_global;
1140 double g = basis0*y0
1149 g = 0.125*g - y_global;
1151 double h = basis0*z0
1160 h = 0.125*h - z_global;
1165 double f_r = basis0_r*x0
1176 double g_r = basis0_r*y0
1187 double h_r = basis0_r*z0
1198 double f_s = basis0_s*x0
1209 double g_s = basis0_s*y0
1220 double h_s = basis0_s*z0
1231 double f_t = basis0_t*x0
1242 double g_t = basis0_t*y0
1253 double h_t = basis0_t*z0
1266 double det = -( f_r*(g_t*h_s - g_s*h_t)
1267 + g_r*(f_s*h_t - f_t*h_s)
1268 + h_r*(f_t*g_s - f_s*g_t) );
1270 double rnew = f*(g_t*h_s - g_s*h_t)
1271 + g*(f_s*h_t - f_t*h_s)
1272 + h*(f_t*g_s - f_s*g_t);
1274 rnew = rnew/det + r;
1276 double snew = f*(g_r*h_t - g_t*h_r)
1277 + g*(f_t*h_r - f_r*h_t)
1278 + h*(f_r*g_t - f_t*g_r);
1280 snew = snew/det + s;
1282 double tnew = f*(g_s*h_r - g_r*h_s)
1283 + g*(f_r*h_s - f_s*h_r)
1284 + h*(f_s*g_r - f_r*g_s);
1286 tnew = tnew/det + t;
1288 if((ipass > 0) || ldiagnostic_output)
1291 << setprecision(14) << setw(20) << r
1292 << setprecision(14) << setw(20) << s
1293 << setprecision(14) << setw(20) << t
1296 << setprecision(14) << setw(20) << rnew
1297 << setprecision(14) << setw(20) << snew
1298 << setprecision(14) << setw(20) << tnew
1301 cout <<
"TOLERANCE = " << TOLERANCE << endl;
1303 cout <<
"r - rnew = " 1304 << setprecision(14) << setw(20) << r - rnew
1306 cout <<
"s - snew = " 1307 << setprecision(14) << setw(20) << s - snew
1309 cout <<
"t - tnew = " 1310 << setprecision(14) << setw(20) << t - tnew
1318 if(is_close_enough(r, rnew) &&
1319 is_close_enough(s, snew) &&
1320 is_close_enough(t, tnew))
1341 post_fatal_error_message(
"inversion algorithm failed to converge");
1349 xlocal_coords[0] = r;
1350 xlocal_coords[1] = s;
1351 xlocal_coords[2] = t;
1364 ensure(invariant());
1387 ensure(result != 0);
1388 ensure(is_same_type(result));
1402 require(is_ancestor_of(&xother));
1410 ensure(invariant());
1423 require(is_ancestor_of(&xother));
1431 ensure(invariant());
1451 result = result && linear_fcn_space::invariant();
1453 if(invariant_check())
1457 disable_invariant_check();
1459 invariance(basis_values() != 0);
1463 enable_invariant_check();
1479 require(xother != 0);
1485 bool result =
dynamic_cast<const trilinear_3d*
>(xother) != 0;
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 trilinear_3d & operator=(const section_evaluator &xother)
Assignment operator.
SHEAF_DLL_SPEC void sqrt(const sec_at0 &x0, sec_at0 &xresult, bool xauto_access)
Compute sqrt of x0 (sqrt(x0)) (pre-allocated version).
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.
virtual bool is_ancestor_of(const any *xother) const
Conformance test; true if other conforms to this.
virtual int db() const
The base dimension; the dimension of the local coordinates (independent variable).
virtual int dl() const
The dimension of this function space.
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...
sec_vd_dof_type dof_type
The type of degree of freedom.
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).
A general tensor of "degree" p and given "variance" over an abstract vector space.
Abstract base class with useful features for all objects.
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.
A section evaluator using trilinear interpolation over a cubic 3D domain.
virtual bool invariant() const
Class invariant.
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)
virtual ~trilinear_3d()
Destructor.
unsigned long size_type
An unsigned integral type used to represent sizes and capacities.
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.
trilinear_3d()
Default constructor.
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.
SHEAF_DLL_SPEC void fabs(const sec_at0 &x0, sec_at0 &xresult, bool xauto_access)
Compute fabs of x0 (fabs(x0)) (pre-allocated version).
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...
An abstract local section evaluator; a map from {local coordinates x dofs} to section value...
value_type volume(const dof_type xcoord_dofs[], size_type xcoord_dofs_ub, size_type xdf)
Volume.
int_type pod_index_type
The plain old data index type.
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.
virtual trilinear_3d * clone() const
Virtual constructor, creates a new instance of the same type as this.
Namespace for the fiber_bundles component of the sheaf system.
virtual void gauss_point(pod_index_type xindex, coord_type xresult[], size_type xresult_ub)
The local gauss point coordinates of the dof with local index xindex.
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...