fe_l2_hierarchic.C
Go to the documentation of this file.00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2012 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 00003 00004 // This library is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public 00006 // License as published by the Free Software Foundation; either 00007 // version 2.1 of the License, or (at your option) any later version. 00008 00009 // This library is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // Lesser General Public License for more details. 00013 00014 // You should have received a copy of the GNU Lesser General Public 00015 // License along with this library; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 00019 00020 // Local includes 00021 #include "libmesh/elem.h" 00022 #include "libmesh/fe.h" 00023 #include "libmesh/fe_interface.h" 00024 00025 namespace libMesh 00026 { 00027 00028 // ------------------------------------------------------------ 00029 // Hierarchic-specific implementations 00030 00031 // Anonymous namespace for local helper functions 00032 namespace { 00033 00034 void l2_hierarchic_nodal_soln(const Elem* elem, 00035 const Order order, 00036 const std::vector<Number>& elem_soln, 00037 std::vector<Number>& nodal_soln, 00038 unsigned Dim) 00039 { 00040 const unsigned int n_nodes = elem->n_nodes(); 00041 00042 const ElemType elem_type = elem->type(); 00043 00044 nodal_soln.resize(n_nodes); 00045 00046 const Order totalorder = static_cast<Order>(order + elem->p_level()); 00047 00048 // FEType object to be passed to various FEInterface functions below. 00049 FEType fe_type(totalorder, L2_HIERARCHIC); 00050 00051 switch (totalorder) 00052 { 00053 // Constant shape functions 00054 case CONSTANT: 00055 { 00056 libmesh_assert_equal_to (elem_soln.size(), 1); 00057 00058 const Number val = elem_soln[0]; 00059 00060 for (unsigned int n=0; n<n_nodes; n++) 00061 nodal_soln[n] = val; 00062 00063 return; 00064 } 00065 00066 00067 // For other orders do interpolation at the nodes 00068 // explicitly. 00069 default: 00070 { 00071 00072 const unsigned int n_sf = 00073 // FE<Dim,T>::n_shape_functions(elem_type, totalorder); 00074 FEInterface::n_shape_functions(Dim, fe_type, elem_type); 00075 00076 std::vector<Point> refspace_nodes; 00077 FEBase::get_refspace_nodes(elem_type,refspace_nodes); 00078 libmesh_assert_equal_to (refspace_nodes.size(), n_nodes); 00079 00080 for (unsigned int n=0; n<n_nodes; n++) 00081 { 00082 libmesh_assert_equal_to (elem_soln.size(), n_sf); 00083 00084 // Zero before summation 00085 nodal_soln[n] = 0; 00086 00087 // u_i = Sum (alpha_i phi_i) 00088 for (unsigned int i=0; i<n_sf; i++) 00089 nodal_soln[n] += elem_soln[i] * 00090 // FE<Dim,T>::shape(elem, order, i, mapped_point); 00091 FEInterface::shape(Dim, fe_type, elem, i, refspace_nodes[n]); 00092 } 00093 00094 return; 00095 } 00096 } 00097 } // l2_hierarchic_nodal_soln() 00098 00099 00100 00101 00102 unsigned int l2_hierarchic_n_dofs(const ElemType t, const Order o) 00103 { 00104 libmesh_assert_greater (o, 0); 00105 switch (t) 00106 { 00107 case NODEELEM: 00108 return 1; 00109 case EDGE2: 00110 case EDGE3: 00111 return (o+1); 00112 case QUAD4: 00113 case QUAD8: 00114 case QUAD9: 00115 return ((o+1)*(o+1)); 00116 case HEX8: 00117 case HEX20: 00118 case HEX27: 00119 return ((o+1)*(o+1)*(o+1)); 00120 case TRI6: 00121 return ((o+1)*(o+2)/2); 00122 default: 00123 libmesh_error(); 00124 } 00125 00126 libmesh_error(); 00127 return 0; 00128 } // l2_hierarchic_n_dofs() 00129 00130 00131 } // anonymous namespace 00132 00133 00134 00135 00136 // Do full-specialization of nodal_soln() function for every 00137 // dimension, instead of explicit instantiation at the end of this 00138 // file. 00139 // This could be macro-ified so that it fits on one line... 00140 template <> 00141 void FE<0,L2_HIERARCHIC>::nodal_soln(const Elem* elem, 00142 const Order order, 00143 const std::vector<Number>& elem_soln, 00144 std::vector<Number>& nodal_soln) 00145 { l2_hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/0); } 00146 00147 template <> 00148 void FE<1,L2_HIERARCHIC>::nodal_soln(const Elem* elem, 00149 const Order order, 00150 const std::vector<Number>& elem_soln, 00151 std::vector<Number>& nodal_soln) 00152 { l2_hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/1); } 00153 00154 template <> 00155 void FE<2,L2_HIERARCHIC>::nodal_soln(const Elem* elem, 00156 const Order order, 00157 const std::vector<Number>& elem_soln, 00158 std::vector<Number>& nodal_soln) 00159 { l2_hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/2); } 00160 00161 template <> 00162 void FE<3,L2_HIERARCHIC>::nodal_soln(const Elem* elem, 00163 const Order order, 00164 const std::vector<Number>& elem_soln, 00165 std::vector<Number>& nodal_soln) 00166 { l2_hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/3); } 00167 00168 // Full specialization of n_dofs() function for every dimension 00169 template <> unsigned int FE<0,L2_HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); } 00170 template <> unsigned int FE<1,L2_HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); } 00171 template <> unsigned int FE<2,L2_HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); } 00172 template <> unsigned int FE<3,L2_HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); } 00173 00174 // Full specialization of n_dofs_at_node() function for every dimension. 00175 // Discontinuous L2 elements only have interior nodes 00176 template <> unsigned int FE<0,L2_HIERARCHIC>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; } 00177 template <> unsigned int FE<1,L2_HIERARCHIC>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; } 00178 template <> unsigned int FE<2,L2_HIERARCHIC>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; } 00179 template <> unsigned int FE<3,L2_HIERARCHIC>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; } 00180 00181 // Full specialization of n_dofs_per_elem() function for every dimension. 00182 template <> unsigned int FE<0,L2_HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); } 00183 template <> unsigned int FE<1,L2_HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); } 00184 template <> unsigned int FE<2,L2_HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); } 00185 template <> unsigned int FE<3,L2_HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); } 00186 00187 // L2 Hierarchic FEMs are C^0 continuous 00188 template <> FEContinuity FE<0,L2_HIERARCHIC>::get_continuity() const { return DISCONTINUOUS; } 00189 template <> FEContinuity FE<1,L2_HIERARCHIC>::get_continuity() const { return DISCONTINUOUS; } 00190 template <> FEContinuity FE<2,L2_HIERARCHIC>::get_continuity() const { return DISCONTINUOUS; } 00191 template <> FEContinuity FE<3,L2_HIERARCHIC>::get_continuity() const { return DISCONTINUOUS; } 00192 00193 // L2 Hierarchic FEMs are hierarchic (duh!) 00194 template <> bool FE<0,L2_HIERARCHIC>::is_hierarchic() const { return true; } 00195 template <> bool FE<1,L2_HIERARCHIC>::is_hierarchic() const { return true; } 00196 template <> bool FE<2,L2_HIERARCHIC>::is_hierarchic() const { return true; } 00197 template <> bool FE<3,L2_HIERARCHIC>::is_hierarchic() const { return true; } 00198 00199 #ifdef LIBMESH_ENABLE_AMR 00200 // compute_constraints() is a NOOP for DISCONTINOUS FE's 00201 template <> 00202 void FE<2,L2_HIERARCHIC>::compute_constraints (DofConstraints &, 00203 DofMap &, 00204 const unsigned int, 00205 const Elem*) 00206 { } 00207 00208 template <> 00209 void FE<3,L2_HIERARCHIC>::compute_constraints (DofConstraints &, 00210 DofMap &, 00211 const unsigned int, 00212 const Elem*) 00213 { } 00214 #endif // #ifdef LIBMESH_ENABLE_AMR 00215 00216 // L2-Hierarchic FEM shapes need reinit 00217 template <> bool FE<0,L2_HIERARCHIC>::shapes_need_reinit() const { return true; } 00218 template <> bool FE<1,L2_HIERARCHIC>::shapes_need_reinit() const { return true; } 00219 template <> bool FE<2,L2_HIERARCHIC>::shapes_need_reinit() const { return true; } 00220 template <> bool FE<3,L2_HIERARCHIC>::shapes_need_reinit() const { return true; } 00221 00222 } // namespace libMesh
Site Created By: libMesh Developers
Last modified: February 05 2013 19:54:46 UTC
Hosted By: