void H1FETransformation<OutputShape>::map_phi( const unsigned int dim, const Elem* const elem, const std::vector<Point>& qp, const FEGenericBase<OutputShape>& fe, std::vector<std::vector<OutputShape> >& phi ) const { switch(dim) { case 0: { for (unsigned int i=0; i<phi.size(); i++) { libmesh_assert_equal_to ( qp.size(), phi[i].size() ); for (unsigned int p=0; p<phi[i].size(); p++) FEInterface::shape<OutputShape>(0, fe.get_fe_type(), elem, i, qp[p], phi[i][p]); } break; } case 1: { for (unsigned int i=0; i<phi.size(); i++) { libmesh_assert_equal_to ( qp.size(), phi[i].size() ); for (unsigned int p=0; p<phi[i].size(); p++) FEInterface::shape<OutputShape>(1, fe.get_fe_type(), elem, i, qp[p], phi[i][p]); } break; } case 2: { for (unsigned int i=0; i<phi.size(); i++) { libmesh_assert_equal_to ( qp.size(), phi[i].size() ); for (unsigned int p=0; p<phi[i].size(); p++) FEInterface::shape<OutputShape>(2, fe.get_fe_type(), elem, i, qp[p], phi[i][p]); } break; } case 3: { for (unsigned int i=0; i<phi.size(); i++) { libmesh_assert_equal_to ( qp.size(), phi[i].size() ); for (unsigned int p=0; p<phi[i].size(); p++) FEInterface::shape<OutputShape>(3, fe.get_fe_type(), elem, i, qp[p], phi[i][p]); } break; } default: libmesh_error(); } return; }
void HCurlFETransformation<OutputShape>::map_phi( const unsigned int dim, const Elem* const elem, const std::vector<Point>& qp, const FEGenericBase<OutputShape>& fe, std::vector<std::vector<OutputShape> >& phi ) const { switch(dim) { // These element transformations only make sense in 2D and 3D case 0: case 1: { libmesh_error(); } case 2: { const std::vector<Real>& dxidx_map = fe.get_fe_map().get_dxidx(); const std::vector<Real>& dxidy_map = fe.get_fe_map().get_dxidy(); const std::vector<Real>& detadx_map = fe.get_fe_map().get_detadx(); const std::vector<Real>& detady_map = fe.get_fe_map().get_detady(); // FIXME: Need to update for 2D elements in 3D space /* phi = (dx/dxi)^-T * \hat{phi} In 2D: (dx/dxi)^{-1} = [ dxi/dx dxi/dy deta/dx deta/dy ] so: dxi/dx^{-T} * \hat{phi} = [ dxi/dx deta/dx [ \hat{phi}_xi dxi/dy deta/dy ] \hat{phi}_eta ] or in indicial notation: phi_j = xi_{i,j}*\hat{phi}_i */ for (unsigned int i=0; i<phi.size(); i++) for (unsigned int p=0; p<phi[i].size(); p++) { // Need to temporarily cache reference shape functions // TODO: PB: Might be worth trying to build phi_ref separately to see // if we can get vectorization OutputShape phi_ref; FEInterface::shape<OutputShape>(2, fe.get_fe_type(), elem, i, qp[p], phi_ref); phi[i][p](0) = dxidx_map[p]*phi_ref.slice(0) + detadx_map[p]*phi_ref.slice(1); phi[i][p](1) = dxidy_map[p]*phi_ref.slice(0) + detady_map[p]*phi_ref.slice(1); } break; } case 3: { const std::vector<Real>& dxidx_map = fe.get_fe_map().get_dxidx(); const std::vector<Real>& dxidy_map = fe.get_fe_map().get_dxidy(); const std::vector<Real>& dxidz_map = fe.get_fe_map().get_dxidz(); const std::vector<Real>& detadx_map = fe.get_fe_map().get_detadx(); const std::vector<Real>& detady_map = fe.get_fe_map().get_detady(); const std::vector<Real>& detadz_map = fe.get_fe_map().get_detadz(); const std::vector<Real>& dzetadx_map = fe.get_fe_map().get_dzetadx(); const std::vector<Real>& dzetady_map = fe.get_fe_map().get_dzetady(); const std::vector<Real>& dzetadz_map = fe.get_fe_map().get_dzetadz(); /* phi = (dx/dxi)^-T * \hat{phi} In 3D: dx/dxi^-1 = [ dxi/dx dxi/dy dxi/dz deta/dx deta/dy deta/dz dzeta/dx dzeta/dy dzeta/dz] so: dxi/dx^-T * \hat{phi} = [ dxi/dx deta/dx dzeta/dx [ \hat{phi}_xi dxi/dy deta/dy dzeta/dy \hat{phi}_eta dxi/dz deta/dz dzeta/dz ] \hat{phi}_zeta ] or in indicial notation: phi_j = xi_{i,j}*\hat{phi}_i */ for (unsigned int i=0; i<phi.size(); i++) for (unsigned int p=0; p<phi[i].size(); p++) { // Need to temporarily cache reference shape functions // TODO: PB: Might be worth trying to build phi_ref separately to see // if we can get vectorization OutputShape phi_ref; FEInterface::shape<OutputShape>(3, fe.get_fe_type(), elem, i, qp[p], phi_ref); phi[i][p].slice(0) = dxidx_map[p]*phi_ref.slice(0) + detadx_map[p]*phi_ref.slice(1) + dzetadx_map[p]*phi_ref.slice(2); phi[i][p].slice(1) = dxidy_map[p]*phi_ref.slice(0) + detady_map[p]*phi_ref.slice(1) + dzetady_map[p]*phi_ref.slice(2); phi[i][p].slice(2) = dxidz_map[p]*phi_ref.slice(0) + detadz_map[p]*phi_ref.slice(1) + dzetadz_map[p]*phi_ref.slice(2); } break; } default: libmesh_error(); } // switch(dim) return; }