📄 fe_clough_shape_1d.c
字号:
// $Id: fe_clough_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"// 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;Real clough_raw_shape_second_deriv(const unsigned int basis_num, const unsigned int deriv_type, const Point& p);Real clough_raw_shape_deriv(const unsigned int basis_num, const unsigned int deriv_type, const Point& p);Real clough_raw_shape(const unsigned int basis_num, const Point& p);// Compute the static coefficients for an elementvoid clough_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(0)); 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) { 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] += dofpt[p](0) * ddxi; } } // Calculate derivative scaling factors d1xd1x = dxdxi[0]; d2xd2x = dxdxi[1];} // Return shape function second derivatives on the unit intervalReal clough_raw_shape_second_deriv(const unsigned int basis_num, const unsigned int deriv_type, const Point& p){ Real xi = p(0); switch (deriv_type) { // second derivative in xi-xi direction case 0: switch (basis_num) { case 0: return -6 + 12*xi; case 1: return 6 - 12*xi; case 2: return -4 + 6*xi; case 3: return -2 + 6*xi; } } libmesh_error(); return 0.;}Real clough_raw_shape_deriv(const unsigned int basis_num, const unsigned int deriv_type, const Point& p){ Real xi = p(0); switch (deriv_type) { case 0: switch (basis_num) { case 0: return -6*xi + 6*xi*xi; case 1: return 6*xi - 6*xi*xi; case 2: return 1 - 4*xi + 3*xi*xi; case 3: return -2*xi + 3*xi*xi; } } libmesh_error(); return 0.;}Real clough_raw_shape(const unsigned int basis_num, const Point& p){ Real xi = p(0); switch (basis_num) { case 0: return 1 - 3*xi*xi + 2*xi*xi*xi; case 1: return 3*xi*xi - 2*xi*xi*xi; case 2: return xi - 2*xi*xi + xi*xi*xi; case 3: return -xi*xi + xi*xi*xi; } libmesh_error(); return 0.;} } // end anonymous namespacetemplate <>Real FE<1,CLOUGH>::shape(const ElemType, const Order, const unsigned int, const Point&){ std::cerr << "Clough-Tocher elements require the real element\n" << "to construct gradient-based degrees of freedom." << std::endl; libmesh_error(); return 0.;}template <>Real FE<1,CLOUGH>::shape(const Elem* elem, const Order order, const unsigned int i, const Point& p){ libmesh_assert (elem != NULL); clough_compute_coefs(elem); const ElemType type = elem->type(); const Order totalorder = static_cast<Order>(order + elem->p_level()); switch (totalorder) { // 3rd-order C1 cubic element case THIRD: { switch (type) { // C1 functions on the C1 cubic edge case EDGE2: case EDGE3: { libmesh_assert (i<4); switch (i) { case 0: return clough_raw_shape(0, p); case 1: return clough_raw_shape(1, p); case 2: return d1xd1x * clough_raw_shape(2, p); case 3: return d2xd2x * clough_raw_shape(3, p); default: libmesh_error(); } } 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,CLOUGH>::shape_deriv(const ElemType, const Order, const unsigned int, const unsigned int, const Point&){ std::cerr << "Clough-Tocher elements require the real element\n" << "to construct gradient-based degrees of freedom." << std::endl; libmesh_error(); return 0.;}template <>Real FE<1,CLOUGH>::shape_deriv(const Elem* elem, const Order order, const unsigned int i, const unsigned int j, const Point& p){ libmesh_assert (elem != NULL); clough_compute_coefs(elem); const ElemType type = elem->type(); const Order totalorder = static_cast<Order>(order + elem->p_level()); switch (totalorder) { // 3rd-order C1 cubic element case THIRD: { switch (type) { // C1 functions on the C1 cubic edge case EDGE2: case EDGE3: { switch (i) { case 0: return clough_raw_shape_deriv(0, j, p); case 1: return clough_raw_shape_deriv(1, j, p); case 2: return d1xd1x * clough_raw_shape_deriv(2, j, p); case 3: return d2xd2x * clough_raw_shape_deriv(3, j, p); default: libmesh_error(); } } 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,CLOUGH>::shape_second_deriv(const Elem* elem, const Order order, const unsigned int i, const unsigned int j, const Point& p){ libmesh_assert (elem != NULL); clough_compute_coefs(elem); const ElemType type = elem->type(); const Order totalorder = static_cast<Order>(order + elem->p_level()); switch (totalorder) { // 3rd-order C1 cubic element case THIRD: { switch (type) { // C1 functions on the C1 cubic edge case EDGE2: case EDGE3: { switch (i) { case 0: return clough_raw_shape_second_deriv(0, j, p); case 1: return clough_raw_shape_second_deriv(1, j, p); case 2: return d1xd1x * clough_raw_shape_second_deriv(2, j, p); case 3: return d2xd2x * clough_raw_shape_second_deriv(3, j, p); default: libmesh_error(); } } 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 + -