Real FE<3,HERMITE>::shape(const Elem* elem, const Order order, const unsigned int i, const Point& p) { libmesh_assert(elem); std::vector<std::vector<Real> > dxdxi(3, std::vector<Real>(2, 0)); #ifdef DEBUG std::vector<Real> dydxi(2), dzdeta(2), dxdzeta(2); std::vector<Real> dzdxi(2), dxdeta(2), dydzeta(2); #endif //DEBUG hermite_compute_coefs(elem, dxdxi #ifdef DEBUG , dydxi, dzdeta, dxdzeta, dzdxi, dxdeta, dydzeta #endif ); const ElemType type = elem->type(); const Order totalorder = static_cast<Order>(order + elem->p_level()); switch (totalorder) { // 3rd-order tricubic Hermite functions case THIRD: { switch (type) { case HEX8: case HEX20: case HEX27: { libmesh_assert_less (i, 64); std::vector<unsigned int> bases1D; Real coef = hermite_bases_3D(bases1D, dxdxi, totalorder, i); return coef * FEHermite<1>::hermite_raw_shape(bases1D[0],p(0)) * FEHermite<1>::hermite_raw_shape(bases1D[1],p(1)) * FEHermite<1>::hermite_raw_shape(bases1D[2],p(2)); } default: libMesh::err << "ERROR: Unsupported element type!" << std::endl; libmesh_error(); } } // by default throw an error default: libMesh::err << "ERROR: Unsupported polynomial order!" << std::endl; libmesh_error(); } libmesh_error(); return 0.; }
void FEI2dTrQuad :: edgeEvaldNds(FloatArray &answer, int iedge, const FloatArray &lcoords, const FEICellGeometry &cellgeo) { // I think it at least should return both dNds and J. Both are almost always needed. // In fact, dxdxi is also needed sometimes (surface tension) #if 0 IntArray edgeNodes; FloatArray dNdxi(3); FloatArray dxdxi(2); double xi = lcoords.at(1); this->computeLocalEdgeMapping(edgeNodes, iedge); dNdxi.at(1) = xi - 0.5; dNdxi.at(2) = xi + 0.5; dNdxi.at(3) = -2 * xi; dxdxi.at(1) = dNdxi.at(1) * cellgeo.giveVertexCoordinates( edgeNodes.at(1) )->at(xind) + dNdxi.at(2) * cellgeo.giveVertexCoordinates( edgeNodes.at(2) )->at(xind) + dNdxi.at(3) * cellgeo.giveVertexCoordinates( edgeNodes.at(3) )->at(xind); dxdxi.at(2) = dNdxi.at(1) * cellgeo.giveVertexCoordinates( edgeNodes.at(1) )->at(yind) + dNdxi.at(2) * cellgeo.giveVertexCoordinates( edgeNodes.at(2) )->at(yind) + dNdxi.at(3) * cellgeo.giveVertexCoordinates( edgeNodes.at(3) )->at(yind); double J = dxdxi.computeNorm(); answer = dNdxi; answer.times(1 / J); return J; #endif double xi = lcoords.at(1); double J = edgeGiveTransformationJacobian(iedge, lcoords, cellgeo); answer = { ( xi - 0.5 ) / J, ( xi + 0.5 ) / J, -2 * xi / J }; }