20 #include "SheafSystem/bilinear_2d.h" 21 #include "SheafSystem/assert_contract.h" 22 #include "SheafSystem/std_cfloat.h" 23 #include "SheafSystem/std_cmath.h" 24 #include "SheafSystem/std_limits.h" 41 _basis_values = _basis_value_buffer;
42 _basis_deriv_values = _basis_deriv_value_buffer;
43 _jacobian_values = _jacobian_value_buffer;
61 _basis_values = _basis_value_buffer;
62 _basis_deriv_values = _basis_deriv_value_buffer;
63 _jacobian_values = _jacobian_value_buffer;
89 fiber_bundle::bilinear_2d::
90 inverse_jacobian(
const double xjacobian[2][2],
91 double xinverse_jacobian[2][2])
93 double j00 = xjacobian[0][0];
94 double j01 = xjacobian[0][1];
95 double j10 = xjacobian[1][0];
96 double j11 = xjacobian[1][1];
115 fiber_bundle::bilinear_2d::
116 solve_quadratic(
double xcoefficients[])
120 int num_roots = solve_quadratic(xcoefficients, xcoefficients);
129 u = (
fabs(xcoefficients[0]) <= (1.0 + DBL_EPSILON))
130 ? xcoefficients[0] : xcoefficients[1];
137 u = xcoefficients[0];
147 fiber_bundle::bilinear_2d::
148 solve_quadratic(
double xcoefficients[],
double xresult[])
150 double a = xcoefficients[0];
151 double b = xcoefficients[1];
152 double c = xcoefficients[2];
167 xresult[num_roots++] = -c/b;
174 double d = b*b - 4.0*a* c;
197 double q = (b + d)/(-2.0);
201 xresult[num_roots++] = q/a;
205 xresult[num_roots++] = c/q;
248 require(xlocal_coord != 0);
249 require(xlocal_coord_ub >= db());
258 _basis_values[0] = 0.25*(1.0 - r)*(1.0 - s);
259 _basis_values[1] = 0.25*(1.0 + r)*(1.0 - s);
260 _basis_values[2] = 0.25*(1.0 + r)*(1.0 + s);
261 _basis_values[3] = 0.25*(1.0 - r)*(1.0 + s);
280 require(xlocal_coords != 0);
281 require(xlocal_coords_ub >= db());
288 double r = xlocal_coords[0];
289 double s = xlocal_coords[1];
291 double quartr = 0.25 * r;
292 double quarts = 0.25 * s;
294 double rp = 0.25 + quartr;
295 double rm = 0.25 - quartr;
296 double sp = 0.25 + quarts;
297 double sm = 0.25 - quarts;
301 _basis_deriv_value_buffer[0] = -sm;
302 _basis_deriv_value_buffer[2] = sm;
303 _basis_deriv_value_buffer[4] = sp;
304 _basis_deriv_value_buffer[6] = -sp;
308 _basis_deriv_value_buffer[1] = -rm;
309 _basis_deriv_value_buffer[3] = -rp;
310 _basis_deriv_value_buffer[5] = rp;
311 _basis_deriv_value_buffer[7] = rm;
339 require(xcoord_dofs != 0);
340 require(xcoord_dofs_ub >= dl()*db());
341 require(xdf == 2 || xdf == 3);
345 jacobian(xcoord_dofs, xcoord_dofs_ub, xdf, xlocal_coords, xlocal_coords_ub);
346 const value_type* jvalues = jacobian_values();
359 for(
int i=0; i<xdf; ++i)
391 require(xcoord_dofs != 0);
392 require(xcoord_dofs_ub >= dl()*db());
393 require(xdf == 2 || xdf == 3);
399 static int NUM_GAUSS_POINTS = 4;
403 for(
int n=0; n<NUM_GAUSS_POINTS; ++n)
406 gauss_point(n, local_coords, 2);
408 value_type det = jacobian_determinant(xcoord_dofs, xcoord_dofs_ub, xdf,
441 require(xcoord_dofs != 0);
442 require(xcoord_dofs_ub >= dl()*db());
443 require(xintegrands != 0);
444 require(xintegrands_ub >= dl());
445 require(xresult_integrals != 0);
446 require(xresult_integrals_ub > 0);
453 int integrands_per_node = xintegrands_ub/xresult_integrals_ub;
457 for(
int i=0; i<xresult_integrals_ub; ++i)
459 xresult_integrals[i] = 0.0;
464 static int NUM_GAUSS_POINTS = 4;
466 for(
int n=0; n<NUM_GAUSS_POINTS; ++n)
469 gauss_point(n, local_coords, 2);
471 double det = jacobian_determinant(xcoord_dofs, xcoord_dofs_ub, xdf,
476 basis_at_coord(local_coords, 2);
479 for(
int i=0; i<xresult_integrals_ub; ++i)
483 const dof_type* integrands_n = xintegrands+(i*integrands_per_node);
485 for(
int k=0; k<4; ++k)
487 fn += basis[k]*integrands_n[k];
490 xresult_integrals[i] += det*fn;
517 require(xcoord_dofs != 0);
518 require(xcoord_dofs_ub >= dl()*db());
519 require(xresult_integrals != 0);
520 require(xresult_integrals_ub >= dl());
526 for(
int i=0; i<xresult_integrals_ub; ++i)
528 xresult_integrals[i] = 0.0;
533 static int NUM_GAUSS_POINTS = 4;
535 for(
int n=0; n<NUM_GAUSS_POINTS; ++n)
538 gauss_point(n, local_coords, 2);
540 double det = jacobian_determinant(xcoord_dofs, xcoord_dofs_ub, xdf,
545 basis_at_coord(local_coords, 2);
548 for(
int i=0; i<4; ++i)
550 xresult_integrals[i] += basis[i] * xintegrand * det;
573 require((0 <= xindex) && (xindex < dof_ct()));
574 require(xresult_ub >= db());
580 static const double d = 1.0 /
sqrt(3.0);
586 , {d, -d}, {d, d}, {-d, d}
589 xresult[0] = gauss_coords[xindex][0];
590 xresult[1] = gauss_coords[xindex][1];
594 ensure(in_standard_domain(xresult, xresult_ub));
616 require(xlocal_coord_index < db());
617 require(xsource_dofs != 0);
619 require(xresult_dofs != 0);
624 if(xlocal_coord_index == 0)
626 dof_type d_minus = 0.5 * (xsource_dofs[1] - xsource_dofs[0]);
627 dof_type d_plus = 0.5 * (xsource_dofs[2] - xsource_dofs[3]);
629 xresult_dofs[0] = d_minus;
630 xresult_dofs[1] = d_minus;
632 xresult_dofs[2] = d_plus;
633 xresult_dofs[3] = d_plus;
637 dof_type d_minus = 0.5 * (xsource_dofs[3] - xsource_dofs[0]);
638 dof_type d_plus = 0.5 * (xsource_dofs[2] - xsource_dofs[1]);
640 xresult_dofs[0] = d_minus;
641 xresult_dofs[3] = d_minus;
643 xresult_dofs[1] = d_plus;
644 xresult_dofs[2] = d_plus;
667 require(xcoord_dofs != 0);
668 require(xcoord_dofs_ub >= xdf*dl());
669 require(xdf == 2 || xdf == 3);
670 require(xlocal_coords != 0);
671 require(xlocal_coords_ub >= 2);
680 int local_coords_ct = 2;
682 basis_derivs_at_coord(xlocal_coords, local_coords_ct);
683 const value_type* derivs = basis_deriv_values();
728 for(
int i=0; i<local_coords_ct; ++i)
733 for(
int j=0; j<xdf; ++j)
740 for(
int k=0; k<dl(); ++k)
744 value_type deriv = derivs[local_coords_ct*k+i];
758 int ij = local_coords_ct*j+i;
759 _jacobian_values[ij] = sum;
911 require((0 <= xindex) && (xindex < dof_ct()));
912 require(xresult_ub >= db());
921 , {1.0, -1.0}, {1.0, 1.0}, {-1.0, 1.0}
924 xresult[0] = lcoords[xindex][0];
925 xresult[1] = lcoords[xindex][1];
929 ensure(in_standard_domain(xresult, xresult_ub));
943 require(xresult != 0);
944 require(xresult_ub >= db());
971 xresult[0] = lcoords[xi][0];
972 xresult[1] = lcoords[xi][1];
989 require(precondition_of(center(xresult.
base(), xresult.
ub())));
993 edge_center(xi, xresult.
base(), xresult.
ub());
998 ensure(postcondition_of(edge_center(xresult.
base(), xresult.
ub())));
999 ensure(xresult.
ct() == db());
1014 require(xlocal_coords != 0);
1015 require(xlocal_coords_ub >= 2);
1025 dof_type one = 1.0 + 1000.0*numeric_limits<dof_type>::epsilon();
1027 bool result = (u >= -one) && (u <= one) && (v >= -one) && (v <= one);
1053 require(xdofs != 0);
1054 require(xdofs_ub >= 8);
1055 require(xglobal_coords != 0);
1056 require(xglobal_coord_ub >= 2);
1057 require(xlocal_coords != 0);
1058 require(xlocal_coords_ub >= 2);
1059 require(unexecutable(xdofs must be interleaved));
1075 dof_type x_global = xglobal_coords[0];
1076 dof_type y_global = xglobal_coords[1];
1078 double x20 = x2 - x0;
1079 double y20 = y2 - y0;
1080 double x13 = x1 - x3;
1081 double y13 = y1 - y3;
1083 double a0 = 4*x_global - (x0+x1+x2+x3);
1084 double a1 = x20 + x13;
1085 double a2 = x20 - x13;
1086 double a3 = x0 - x1 + x2 - x3;
1088 double b0 = 4*y_global - (y0+y1+y2+y3);
1089 double b1 = y20 + y13;
1090 double b2 = y20 - y13;
1091 double b3 = y0 - y1 + y2 - y3;
1093 double coefficients[3];
1099 coefficients[0] = a1*b3 - b1*a3;
1100 coefficients[1] = a1*b2 - b1*a2 + b0*a3 - a0*b3;
1101 coefficients[2] = b0*a2 - a0*b2;
1102 xlocal_coords[0] = cthis->solve_quadratic(coefficients);
1106 coefficients[0] = a3*b2 - a2*b3;
1107 coefficients[1] = a0*b3 - a3*b0 + a1*b2 - a2*b1;
1108 coefficients[2] = a0*b1 - a1*b0;
1109 xlocal_coords[1] = cthis->solve_quadratic(coefficients);
1113 ensure(invariant());
1136 ensure(result != 0);
1137 ensure(is_same_type(result));
1152 require(is_ancestor_of(&xother));
1160 ensure(invariant());
1173 require(is_ancestor_of(&xother));
1181 ensure(invariant());
1203 result = result && linear_fcn_space::invariant();
1205 if(invariant_check())
1209 disable_invariant_check();
1211 invariance(basis_values() != 0);
1215 enable_invariant_check();
1231 require(xother != 0);
1237 bool result =
dynamic_cast<const bilinear_2d*
>(xother) != 0;
virtual int db() const
The base dimension; the dimension of the local coordinates (independent variable).
SHEAF_DLL_SPEC void sqrt(const sec_at0 &x0, sec_at0 &xresult, bool xauto_access)
Compute sqrt of x0 (sqrt(x0)) (pre-allocated version).
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.
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.
index_type ub() const
The upper bound on the storage array. The number of items current allocated in the storage array...
size_type ct() const
The number of items currently in use.
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 bilinear_2d * clone() const
Virtual constructor, creates a new instance of the same type as this.
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.
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).
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 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...
Abstract base class with useful features for all objects.
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 ~bilinear_2d()
Destructor.
pointer_type base() const
The underlying storage array.
void set_ct(size_type xct)
Sets ct() == xct.
virtual bool invariant() const
Class invariant.
void edge_center(pod_index_type xi, coord_type xresult[], size_type xresult_ub) const
The local cordinates of the xi-th edge.
unsigned long size_type
An unsigned integral type used to represent sizes and capacities.
const value_type * jacobian_values() const
The result of the preceding call to jacobian.
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 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.
An abstract local section evaluator; a map from {local coordinates x dofs} to section value...
bilinear_2d()
Default constructor.
virtual bool is_ancestor_of(const any *xother) const
Conformance test; true if other conforms to this.
int_type pod_index_type
The plain old data index type.
virtual bilinear_2d & operator=(const section_evaluator &xother)
Assignment operator.
An auto_block with a no-initialization initialization policy.
Namespace for the fiber_bundles component of the sheaf system.
A section evaluator using bilinear interpolation over a square 2D domain.
virtual int dl() const
The dimension of this function space.
virtual void basis_derivs_at_coord(const dof_type xlocal_coords[], size_type xlocal_coords_ub)
Computes the value of the derivatives each basis function at local coordinates xlocal_coord.
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 ...