📄 fe_hermite_shape_1d.c
字号:
// $Id: fe_hermite_shape_1D.C 2789 2008-04-13 02:24:40Z roystgnr $// The libMesh Finite Element Library.// Copyright (C) 2002-2007 Benjamin S. Kirk, John W. Peterson // This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public// License as published by the Free Software Foundation; either// version 2.1 of the License, or (at your option) any later version. // This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// Lesser General Public License for more details. // You should have received a copy of the GNU Lesser General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA// C++ inlcludes// Local includes#include "fe.h"#include "elem.h"#include "utility.h"// Anonymous namespace for persistant variables.// This allows us to cache the global-to-local mapping transformation// This should also screw up multithreading royallynamespace{ static unsigned int old_elem_id = libMesh::invalid_uint; // Coefficient naming: d(1)d(2n) is the coefficient of the // global shape function corresponding to value 1 in terms of the // local shape function corresponding to normal derivative 2 static Real d1xd1x, d2xd2x;// Compute the static coefficients for an elementvoid hermite_compute_coefs(const Elem* elem){ // Coefficients are cached from old elements if (elem->id() == old_elem_id) return; old_elem_id = elem->id(); const Order mapping_order (elem->default_order()); const ElemType mapping_elem_type (elem->type()); const int n_mapping_shape_functions = FE<1,LAGRANGE>::n_shape_functions(mapping_elem_type, mapping_order); // Degrees of freedom are at vertices and edge midpoints std::vector<Point> dofpt; dofpt.push_back(Point(-1)); dofpt.push_back(Point(1)); // Mapping functions - first derivatives at each dofpt std::vector<Real> dxdxi(2); std::vector<Real> dxidx(2); for (int p = 0; p != 2; ++p) { dxdxi[p] = 0; for (int i = 0; i != n_mapping_shape_functions; ++i) { const Real ddxi = FE<1,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 0, dofpt[p]); dxdxi[p] += elem->point(i)(0) * ddxi; } } // Calculate derivative scaling factors d1xd1x = dxdxi[0]; d2xd2x = dxdxi[1];}} // end anonymous namespacetemplate<>Real FEHermite<1>::hermite_raw_shape_second_deriv (const unsigned int i, const Real xi){ using Utility::pow; switch (i) { case 0: return 1.5 * xi; case 1: return -1.5 * xi; case 2: return 0.5 * (-1. + 3.*xi); case 3: return 0.5 * (1. + 3.*xi); case 4: return (8.*xi*xi + 4.*(xi*xi-1.))/24.; case 5: return (8.*xi*xi*xi + 12.*xi*(xi*xi-1.))/120.;// case 6:// return (8.*pow<4>(xi) + 20.*xi*xi*(xi*xi-1.) +// 2.*(xi*xi-1)*(xi*xi-1))/720.; default: Real denominator = 720., xipower = 1.; for (unsigned n=6; n != i; ++n) { xipower *= xi; denominator *= (n+1); } return (8.*pow<4>(xi)*xipower + (8.*(i-4)+4.)*xi*xi*xipower*(xi*xi-1.) + (i-4)*(i-5)*xipower*(xi*xi-1.)*(xi*xi-1.))/denominator; } libmesh_error(); return 0.;}template<>Real FEHermite<1>::hermite_raw_shape_deriv (const unsigned int i, const Real xi){ switch (i) { case 0: return 0.75 * (-1. + xi*xi); case 1: return 0.75 * (1. - xi*xi); case 2: return 0.25 * (-1. - 2.*xi + 3.*xi*xi); case 3: return 0.25 * (-1. + 2.*xi + 3.*xi*xi); case 4: return 4.*xi * (xi*xi-1.)/24.; case 5: return (4*xi*xi*(xi*xi-1.) + (xi*xi-1.)*(xi*xi-1.))/120.;// case 6:// return (4*xi*xi*xi*(xi*xi-1.) + 2*xi*(xi*xi-1.)*(xi*xi-1.))/720.; default: Real denominator = 720., xipower = 1.; for (unsigned n=6; n != i; ++n) { xipower *= xi; denominator *= (n+1); } return (4*xi*xi*xi*xipower*(xi*xi-1.) + (i-4)*xi*xipower*(xi*xi-1.)*(xi*xi-1.))/denominator; } libmesh_error(); return 0.;}template<>Real FEHermite<1>::hermite_raw_shape (const unsigned int i, const Real xi){ switch (i) { case 0: return 0.25 * (2. - 3.*xi + xi*xi*xi); case 1: return 0.25 * (2. + 3.*xi - xi*xi*xi); case 2: return 0.25 * (1. - xi - xi*xi + xi*xi*xi); case 3: return 0.25 * (-1. - xi + xi*xi + xi*xi*xi); // All high order terms have the form x^(p-4)(x^2-1)^2/p! case 4: return (xi*xi-1.) * (xi*xi-1.)/24.; case 5: return xi * (xi*xi-1.) * (xi*xi-1.)/120.;// case 6:// return xi*xi * (xi*xi-1.) * (xi*xi-1.)/720.; default: Real denominator = 720., xipower = 1.; for (unsigned n=6; n != i; ++n) { xipower *= xi; denominator *= (n+1); } return (xi*xi*xipower*(xi*xi-1.)*(xi*xi-1.))/denominator; } libmesh_error(); return 0.;}template <>Real FE<1,HERMITE>::shape(const ElemType, const Order, const unsigned int, const Point&){ std::cerr << "Hermite elements require the real element\n" << "to construct gradient-based degrees of freedom." << std::endl; libmesh_error(); return 0.;}template <>Real FE<1,HERMITE>::shape(const Elem* elem, const Order order, const unsigned int i, const Point& p){ libmesh_assert (elem != NULL); hermite_compute_coefs(elem); const ElemType type = elem->type(); const Order totalorder = static_cast<Order>(order + elem->p_level()); switch (totalorder) { // Hermite cubic shape functions case THIRD: { switch (type) { // C1 functions on the C1 cubic edge case EDGE2: case EDGE3: { libmesh_assert (i<4); switch (i) { case 0: return FEHermite<1>::hermite_raw_shape(0, p(0)); case 1: return d1xd1x * FEHermite<1>::hermite_raw_shape(2, p(0)); case 2: return FEHermite<1>::hermite_raw_shape(1, p(0)); case 3: return d2xd2x * FEHermite<1>::hermite_raw_shape(3, p(0)); default: return FEHermite<1>::hermite_raw_shape(i, p(0)); } } default: std::cerr << "ERROR: Unsupported element type!" << std::endl; libmesh_error(); } } // by default throw an error default: std::cerr << "ERROR: Unsupported polynomial order!" << std::endl; libmesh_error(); } libmesh_error(); return 0.;}template <>Real FE<1,HERMITE>::shape_deriv(const ElemType, const Order, const unsigned int, const unsigned int, const Point&){ std::cerr << "Hermite elements require the real element\n" << "to construct gradient-based degrees of freedom." << std::endl; libmesh_error(); return 0.;}template <>Real FE<1,HERMITE>::shape_deriv(const Elem* elem, const Order order, const unsigned int i, const unsigned int, const Point& p){ libmesh_assert (elem != NULL); hermite_compute_coefs(elem); const ElemType type = elem->type(); const Order totalorder = static_cast<Order>(order + elem->p_level()); switch (totalorder) { // Hermite cubic shape functions case THIRD: { switch (type) { // C1 functions on the C1 cubic edge case EDGE2: case EDGE3: { switch (i) { case 0: return FEHermite<1>::hermite_raw_shape_deriv(0, p(0)); case 1: return d1xd1x * FEHermite<1>::hermite_raw_shape_deriv(2, p(0)); case 2: return FEHermite<1>::hermite_raw_shape_deriv(1, p(0)); case 3: return d2xd2x * FEHermite<1>::hermite_raw_shape_deriv(3, p(0)); default: return FEHermite<1>::hermite_raw_shape_deriv(i, p(0)); } } default: std::cerr << "ERROR: Unsupported element type!" << std::endl; libmesh_error(); } } // by default throw an error default: std::cerr << "ERROR: Unsupported polynomial order!" << std::endl; libmesh_error(); } libmesh_error(); return 0.;}template <>Real FE<1,HERMITE>::shape_second_deriv(const Elem* elem, const Order order, const unsigned int i, const unsigned int, const Point& p){ libmesh_assert (elem != NULL); hermite_compute_coefs(elem); const ElemType type = elem->type(); const Order totalorder = static_cast<Order>(order + elem->p_level()); switch (totalorder) { // Hermite cubic shape functions case THIRD: { switch (type) { // C1 functions on the C1 cubic edge case EDGE2: case EDGE3: { switch (i) { case 0: return FEHermite<1>::hermite_raw_shape_second_deriv(0, p(0)); case 1: return d1xd1x * FEHermite<1>::hermite_raw_shape_second_deriv(2, p(0)); case 2: return FEHermite<1>::hermite_raw_shape_second_deriv(1, p(0)); case 3: return d2xd2x * FEHermite<1>::hermite_raw_shape_second_deriv(3, p(0)); default: return FEHermite<1>::hermite_raw_shape_second_deriv(i, p(0)); } } default: std::cerr << "ERROR: Unsupported element type!" << std::endl; libmesh_error(); } } // by default throw an error default: std::cerr << "ERROR: Unsupported polynomial order!" << std::endl; libmesh_error(); } libmesh_error(); return 0.;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -