Пример #1
0
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.;
}
Пример #2
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
    };
}