45 calculations_started(false),
47 calculate_dxyz(false),
48 calculate_d2xyz(false)
58 return libmesh_make_unique<FEXYZMap>();
61 return libmesh_make_unique<FEMap>();
67 template<
unsigned int Dim>
72 LOG_SCOPE(
"init_reference_to_physical_map()",
"FEMap");
77 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 82 libmesh_not_implemented();
87 const std::size_t n_qp = qp.size();
96 const unsigned int n_mapping_shape_functions =
101 this->
phi_map.resize (n_mapping_shape_functions);
105 this->
dphidxi_map.resize (n_mapping_shape_functions);
106 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 109 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 116 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 122 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 129 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 136 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 140 for (
unsigned int i=0; i<n_mapping_shape_functions; i++)
143 this->
phi_map[i].resize (n_qp);
148 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 164 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 185 for (
unsigned int i=0; i<n_mapping_shape_functions; i++)
186 for (std::size_t p=0; p<n_qp; p++)
200 for (
unsigned int i=0; i<n_mapping_shape_functions; i++)
217 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 225 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 226 for (std::size_t p=1; p<n_qp; p++)
232 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 235 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 240 for (
unsigned int i=0; i<n_mapping_shape_functions; i++)
241 for (std::size_t p=0; p<n_qp; p++)
247 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 250 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 263 for (
unsigned int i=0; i<n_mapping_shape_functions; i++)
272 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 279 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 280 for (std::size_t p=1; p<n_qp; p++)
289 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 296 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 301 for (
unsigned int i=0; i<n_mapping_shape_functions; i++)
302 for (std::size_t p=0; p<n_qp; p++)
311 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 318 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 332 for (
unsigned int i=0; i<n_mapping_shape_functions; i++)
342 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 352 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 353 for (std::size_t p=1; p<n_qp; p++)
363 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 373 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 378 for (
unsigned int i=0; i<n_mapping_shape_functions; i++)
379 for (std::size_t p=0; p<n_qp; p++)
389 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 399 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 406 libmesh_error_msg(
"Invalid Dim = " << Dim);
413 const std::vector<Real> & qw,
416 const std::vector<const Node *> & elem_nodes,
417 bool compute_second_derivatives)
419 libmesh_assert(elem);
423 libmesh_assert_equal_to(
phi_map.size(), elem_nodes.size());
431 libmesh_assert(elem_nodes[0]);
433 xyz[p] = *elem_nodes[0];
451 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 465 libmesh_assert(elem_nodes[i]);
466 const Point & elem_point = *elem_nodes[i];
469 xyz[p].add_scaled (elem_point,
phi_map[i][p] );
472 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 505 static bool failing =
false;
512 libmesh_error_msg(
"ERROR: negative Jacobian " \
523 libmesh_error_msg(
"ERROR: negative Jacobian " \
525 <<
" at point index " \
555 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 562 #elif LIBMESH_DIM == 2 581 static bool failing =
false;
586 libmesh_error_msg(
"Encountered invalid 1D element!");
606 #elif LIBMESH_DIM == 3 627 static bool failing =
false;
632 libmesh_error_msg(
"Encountered invalid 1D element!");
663 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES 686 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 704 libmesh_assert(elem_nodes[i]);
705 const Point & elem_point = *elem_nodes[i];
708 xyz[p].add_scaled (elem_point,
phi_map[i][p] );
715 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 743 jac[p] = (dx_dxi*dy_deta - dx_deta*dy_dxi);
750 static bool failing =
false;
757 libmesh_error_msg(
"ERROR: negative Jacobian " \
768 libmesh_error_msg(
"ERROR: negative Jacobian " \
770 <<
" at point index " \
789 const Real inv_jac = 1./
jac[p];
798 if (compute_second_derivatives)
801 #else // LIBMESH_DIM == 3 828 const Real g11 = (dx_dxi*dx_dxi +
832 const Real g12 = (dx_dxi*dx_deta +
836 const Real g21 = g12;
838 const Real g22 = (dx_deta*dx_deta +
842 const Real det = (g11*g22 - g12*g21);
849 static bool failing =
false;
856 libmesh_error_msg(
"ERROR: negative Jacobian " \
867 libmesh_error_msg(
"ERROR: negative Jacobian " \
869 <<
" at point index " \
884 const Real inv_det = 1./det;
885 jac[p] = std::sqrt(det);
889 const Real g11inv = g22*inv_det;
890 const Real g12inv = -g12*inv_det;
891 const Real g21inv = -g21*inv_det;
892 const Real g22inv = g11*inv_det;
894 dxidx_map[p] = g11inv*dx_dxi + g12inv*dx_deta;
895 dxidy_map[p] = g11inv*dy_dxi + g12inv*dy_deta;
896 dxidz_map[p] = g11inv*dz_dxi + g12inv*dz_deta;
898 detadx_map[p] = g21inv*dx_dxi + g22inv*dx_deta;
899 detady_map[p] = g21inv*dy_dxi + g22inv*dy_deta;
900 detadz_map[p] = g21inv*dz_dxi + g22inv*dz_deta;
902 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 921 JT(0,0) = dx_dxi; JT(0,1) = dy_dxi; JT(0,2) = dz_dxi;
922 JT(1,0) = dx_deta; JT(1,1) = dy_deta; JT(1,2) = dz_deta;
926 JTJinv(0,0) = g11inv; JTJinv(0,1) = g12inv;
927 JTJinv(1,0) = g21inv; JTJinv(1,1) = g22inv;
942 for (
unsigned s=0; s<3; ++s)
943 for (
unsigned t=s; t<3; ++t)
946 tmp1(0) = dxi(s)*dxi(t);
947 tmp1(1) = deta(s)*deta(t);
950 A.vector_mult(tmp2, tmp1);
953 Real alpha = dxi(s)*deta(t) + deta(s)*dxi(t);
956 for (
unsigned i=0; i<3; ++i)
960 JT.vector_mult(tmp3, tmp2);
974 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES 976 #endif // LIBMESH_DIM == 3 1001 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 1026 libmesh_assert(elem_nodes[i]);
1027 const Point & elem_point = *elem_nodes[i];
1030 xyz[p].add_scaled (elem_point,
phi_map[i][p] );
1037 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 1074 jac[p] = (dx_dxi*(dy_deta*dz_dzeta - dz_deta*dy_dzeta) +
1075 dy_dxi*(dz_deta*dx_dzeta - dx_deta*dz_dzeta) +
1076 dz_dxi*(dx_deta*dy_dzeta - dy_deta*dx_dzeta));
1083 static bool failing =
false;
1090 libmesh_error_msg(
"ERROR: negative Jacobian " \
1101 libmesh_error_msg(
"ERROR: negative Jacobian " \
1103 <<
" at point index " \
1122 const Real inv_jac = 1./
jac[p];
1124 dxidx_map[p] = (dy_deta*dz_dzeta - dz_deta*dy_dzeta)*inv_jac;
1125 dxidy_map[p] = (dz_deta*dx_dzeta - dx_deta*dz_dzeta)*inv_jac;
1126 dxidz_map[p] = (dx_deta*dy_dzeta - dy_deta*dx_dzeta)*inv_jac;
1128 detadx_map[p] = (dz_dxi*dy_dzeta - dy_dxi*dz_dzeta )*inv_jac;
1129 detady_map[p] = (dx_dxi*dz_dzeta - dz_dxi*dx_dzeta )*inv_jac;
1130 detadz_map[p] = (dy_dxi*dx_dzeta - dx_dxi*dy_dzeta )*inv_jac;
1132 dzetadx_map[p] = (dy_dxi*dz_deta - dz_dxi*dy_deta )*inv_jac;
1133 dzetady_map[p] = (dz_dxi*dx_deta - dx_dxi*dz_deta )*inv_jac;
1134 dzetadz_map[p] = (dx_dxi*dy_deta - dy_dxi*dx_deta )*inv_jac;
1137 if (compute_second_derivatives)
1145 libmesh_error_msg(
"Invalid dim = " << dim);
1166 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 1186 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 1207 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 1233 const std::vector<Real> & qw,
1237 LOG_SCOPE(
"compute_affine_map()",
"FEMap");
1239 libmesh_assert(elem);
1241 const unsigned int n_qp = cast_int<unsigned int>(qw.size());
1249 for (
unsigned int i=0; i<
n_nodes; i++)
1257 for (
unsigned int p=1; p<n_qp; p++)
1266 for (
unsigned int p=1; p<n_qp; p++)
1272 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 1283 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 1296 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 1307 JxW[p] =
JxW[0] / qw[0] * qw[p];
1314 const std::vector<Real> & qw)
1317 LOG_SCOPE(
"compute_null_map()",
"FEMap");
1319 const unsigned int n_qp = cast_int<unsigned int>(qw.size());
1325 for (
unsigned int p=1; p<n_qp; p++)
1337 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 1352 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 1368 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 1389 const std::vector<Real> & qw,
1391 bool calculate_d2phi)
1406 LOG_SCOPE(
"compute_map()",
"FEMap");
1408 libmesh_assert(elem);
1410 const unsigned int n_qp = cast_int<unsigned int>(qw.size());
1419 libmesh_assert_equal_to (dim, 2);
1427 for (
unsigned int i=0; i<elem->
n_nodes(); i++)
1432 for (
unsigned int p=0; p!=n_qp; p++)
1441 os <<
" [" << i <<
"]: " <<
JxW[i] << std::endl;
1449 os <<
" [" << i <<
"]: " <<
xyz[i];
1456 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 1459 std::set<unsigned> valid_indices;
1483 valid_indices.insert(0);
1485 #elif LIBMESH_DIM==2 1505 const unsigned tmp[3] = {0,1,3};
1506 valid_indices.insert(tmp, tmp+3);
1508 #elif LIBMESH_DIM==3 1528 const unsigned tmp[6] = {0,1,2,3,4,5};
1529 valid_indices.insert(tmp, tmp+6);
1536 for (
unsigned s=0; s<3; ++s)
1537 for (
unsigned t=s; t<3; ++t)
1539 if (valid_indices.count(ctr))
1546 v2(dxi(s)*deta(t) + deta(s)*dxi(t),
1547 dxi(s)*dzeta(t) + dzeta(s)*dxi(t),
1548 deta(s)*dzeta(t) + dzeta(s)*deta(t));
1556 if (LIBMESH_DIM > 1)
1559 if (LIBMESH_DIM > 2)
1569 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES 1575 template <
unsigned int Dim, FEFamily T>
1577 const Point & physical_point,
1578 const Real tolerance,
1581 libmesh_assert(elem);
1582 libmesh_assert_greater_equal (tolerance, 0.);
1586 LOG_SCOPE(
"inverse_map()",
"FE");
1590 Real inverse_map_error = 0.;
1603 unsigned int cnt = 0;
1607 const unsigned int max_cnt = 10;
1622 const Point delta = physical_point - physical_guess;
1665 const Real G = dxi*dxi;
1668 libmesh_assert_greater (G, 0.);
1670 const Real Ginv = 1./G;
1672 const Real dxidelta = dxi*delta;
1674 dp(0) = Ginv*dxidelta;
1714 G11 = dxi*dxi, G12 = dxi*deta,
1715 G21 = dxi*deta, G22 = deta*deta;
1718 const Real det = (G11*G22 - G12*G21);
1721 libmesh_assert_not_equal_to (det, 0.);
1723 const Real inv_det = 1./det;
1726 Ginv11 = G22*inv_det,
1727 Ginv12 = -G12*inv_det,
1729 Ginv21 = -G21*inv_det,
1730 Ginv22 = G11*inv_det;
1733 const Real dxidelta = dxi*delta;
1734 const Real detadelta = deta*delta;
1736 dp(0) = (Ginv11*dxidelta + Ginv12*detadelta);
1737 dp(1) = (Ginv21*dxidelta + Ginv22*detadelta);
1778 dxi(1), deta(1), dzeta(1),
1779 dxi(2), deta(2), dzeta(2)).solve(delta, dp);
1794 libMesh::err <<
"ERROR: Newton scheme encountered a singular Jacobian in element: " 1800 libmesh_error_msg(
"Exiting...");
1804 for (
unsigned int i=0; i != Dim; ++i)
1821 libmesh_error_msg(
"Invalid Dim = " << Dim);
1827 inverse_map_error = dp.
norm();
1856 libMesh::err <<
"WARNING: Newton scheme has not converged in " 1857 << cnt <<
" iterations:" << std::endl
1858 <<
" physical_point=" 1860 <<
" physical_guess=" 1866 <<
" error=" << inverse_map_error
1867 <<
" in element " << elem->
id()
1874 libmesh_do_once(
libMesh::err <<
"WARNING: At least one element took more than " 1876 <<
" iterations to converge in inverse_map()...\n" 1877 <<
"Rerun in devel/dbg mode for more details." 1882 if (cnt > 2*max_cnt)
1884 libMesh::err <<
"ERROR: Newton scheme FAILED to converge in " 1886 <<
" iterations in element " 1888 <<
" for physical point = " 1894 libmesh_error_msg(
"Exiting...");
1902 for (
unsigned int i=0; i != Dim; ++i)
1909 while (inverse_map_error > tolerance);
1922 const Point diff = physical_point - check;
1924 if (diff.
norm() > tolerance)
1944 libMesh::err <<
"WARNING: inverse_map of physical point " 1946 <<
" is not on element." <<
'\n';
1959 template <
unsigned int Dim, FEFamily T>
1961 const std::vector<Point> & physical_points,
1962 std::vector<Point> & reference_points,
1963 const Real tolerance,
1968 const std::size_t n_points = physical_points.
size();
1972 reference_points.resize(n_points);
1976 for (std::size_t p=0; p<n_points; p++)
1977 reference_points[p] =
1984 template <
unsigned int Dim, FEFamily T>
1986 const Point & reference_point)
1988 libmesh_assert(elem);
1997 for (
unsigned int i=0; i<n_sf; i++)
2011 template <
unsigned int Dim, FEFamily T>
2013 const Point & reference_point)
2015 libmesh_assert(elem);
2024 for (
unsigned int i=0; i<n_sf; i++)
2039 template <
unsigned int Dim, FEFamily T>
2041 const Point & reference_point)
2043 libmesh_assert(elem);
2052 for (
unsigned int i=0; i<n_sf; i++)
2067 template <
unsigned int Dim, FEFamily T>
2069 const Point & reference_point)
2071 libmesh_assert(elem);
2080 for (
unsigned int i=0; i<n_sf; i++)
2095 template void FEMap::init_reference_to_physical_map<0>(
const std::vector<Point> &,
const Elem *);
2096 template void FEMap::init_reference_to_physical_map<1>(
const std::vector<Point> &,
const Elem *);
2097 template void FEMap::init_reference_to_physical_map<2>(
const std::vector<Point> &,
const Elem *);
2098 template void FEMap::init_reference_to_physical_map<3>(
const std::vector<Point> &,
const Elem *);
Manages the family, order, etc. parameters for a given FE.
virtual void compute_affine_map(const unsigned int dim, const std::vector< Real > &qw, const Elem *elem)
Real dzdeta_map(const unsigned int p) const
void print_info(std::ostream &os=libMesh::out) const
static Point map_zeta(const Elem *elem, const Point &reference_point)
std::vector< std::vector< Real > > dphidzeta_map
static OutputShape shape(const ElemType t, const Order o, const unsigned int i, const Point &p)
void compute_inverse_map_second_derivs(unsigned p)
virtual void compute_map(const unsigned int dim, const std::vector< Real > &qw, const Elem *elem, bool calculate_d2phi)
std::vector< std::vector< Real > > dphidxi_map
std::vector< std::vector< Real > > d2etadxyz2_map
static Point map_xi(const Elem *elem, const Point &reference_point)
void add_scaled(const TypeVector< T2 > &, const T)
static std::unique_ptr< FEMap > build(FEType fe_type)
std::vector< RealGradient > d2xyzdzeta2_map
std::vector< Real > dzetady_map
std::vector< std::vector< Real > > d2xidxyz2_map
void init_reference_to_physical_map(const std::vector< Point > &qp, const Elem *elem)
virtual bool has_affine_map() const
Real dxdeta_map(const unsigned int p) const
Real dzdxi_map(const unsigned int p) const
The base class for all geometric element types.
std::vector< std::vector< Real > > d2phideta2_map
IntRange< std::size_t > index_range(const std::vector< T > &vec)
std::vector< std::vector< Real > > d2phidxidzeta_map
static OutputShape shape_deriv(const ElemType t, const Order o, const unsigned int i, const unsigned int j, const Point &p)
std::vector< Real > dxidz_map
std::vector< std::vector< Real > > phi_map
virtual bool is_linear() const
std::vector< std::vector< Real > > d2phidetadzeta_map
static bool on_reference_element(const Point &p, const ElemType t, const Real eps=TOLERANCE)
void add(const TypeVector< T2 > &)
std::vector< RealGradient > d2xyzdxideta_map
std::vector< RealGradient > dxyzdzeta_map
std::vector< Real > dzetadx_map
std::vector< RealGradient > dxyzdxi_map
virtual unsigned int n_shape_functions() const override
Template class which generates the different FE families and orders.
TensorValue< Real > RealTensorValue
void libmesh_ignore(const Args &...)
static Point map(const Elem *elem, const Point &reference_point)
const dof_id_type n_nodes
std::vector< RealGradient > d2xyzdeta2_map
virtual unsigned int n_nodes() const =0
std::vector< RealGradient > d2xyzdxi2_map
std::vector< Real > dzetadz_map
Real dzdzeta_map(const unsigned int p) const
std::vector< std::vector< Real > > d2zetadxyz2_map
bool calculations_started
std::vector< RealGradient > d2xyzdetadzeta_map
std::vector< Real > dxidx_map
A surface shell element used in mechanics calculations.
Real dxdzeta_map(const unsigned int p) const
std::vector< Real > dxidy_map
INSTANTIATE_SUBDIVISION_MAPS
OStreamProxy err(std::cerr)
Real dydzeta_map(const unsigned int p) const
std::vector< const Node * > _elem_nodes
std::vector< std::vector< Real > > d2phidxideta_map
static Point map_eta(const Elem *elem, const Point &reference_point)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Real dydeta_map(const unsigned int p) const
const Node * node_ptr(const unsigned int i) const
static PetscErrorCode Mat * A
virtual void compute_null_map(const unsigned int dim, const std::vector< Real > &qw)
std::vector< Real > detady_map
void print_xyz(std::ostream &os) const
std::vector< RealGradient > dxyzdeta_map
void resize_quadrature_map_vectors(const unsigned int dim, unsigned int n_qp)
Real dxdxi_map(const unsigned int p) const
void determine_calculations()
Real dydxi_map(const unsigned int p) const
virtual bool infinite() const =0
std::vector< Real > detadz_map
std::vector< std::vector< Real > > d2phidzeta2_map
void print_JxW(std::ostream &os) const
virtual Order default_order() const =0
std::vector< std::vector< Real > > d2phidxi2_map
A matrix object used for finite element assembly and numerics.
virtual ElemType type() const =0
A geometric point in (x,y,z) space.
std::vector< Real > detadx_map
const Point & point(const unsigned int i) const
void compute_single_point_map(const unsigned int dim, const std::vector< Real > &qw, const Elem *elem, unsigned int p, const std::vector< const Node *> &elem_nodes, bool compute_second_derivatives)
std::vector< std::vector< Real > > dphideta_map
static OutputShape shape_second_deriv(const ElemType t, const Order o, const unsigned int i, const unsigned int j, const Point &p)
void vector_mult(DenseVector< T > &dest, const DenseVector< T > &arg) const
static Point inverse_map(const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true)
std::vector< RealGradient > d2xyzdxidzeta_map