$extrastylesheet
fe_l2_hierarchic.C
Go to the documentation of this file.
00001 // The libMesh Finite Element Library.
00002 // Copyright (C) 2002-2014 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 #include "libmesh/string_to_enum.h"
00025 
00026 namespace libMesh
00027 {
00028 
00029 // ------------------------------------------------------------
00030 // Hierarchic-specific implementations
00031 
00032 // Anonymous namespace for local helper functions
00033 namespace {
00034 
00035 void l2_hierarchic_nodal_soln(const Elem* elem,
00036                               const Order order,
00037                               const std::vector<Number>& elem_soln,
00038                               std::vector<Number>&       nodal_soln,
00039                               unsigned Dim)
00040 {
00041   const unsigned int n_nodes = elem->n_nodes();
00042 
00043   const ElemType elem_type = elem->type();
00044 
00045   nodal_soln.resize(n_nodes);
00046 
00047   const Order totalorder = static_cast<Order>(order + elem->p_level());
00048 
00049   // FEType object to be passed to various FEInterface functions below.
00050   FEType fe_type(totalorder, L2_HIERARCHIC);
00051 
00052   switch (totalorder)
00053     {
00054       // Constant shape functions
00055     case CONSTANT:
00056       {
00057         libmesh_assert_equal_to (elem_soln.size(), 1);
00058 
00059         const Number val = elem_soln[0];
00060 
00061         for (unsigned int n=0; n<n_nodes; n++)
00062           nodal_soln[n] = val;
00063 
00064         return;
00065       }
00066 
00067 
00068       // For other orders do interpolation at the nodes
00069       // explicitly.
00070     default:
00071       {
00072 
00073         const unsigned int n_sf =
00074           // FE<Dim,T>::n_shape_functions(elem_type, totalorder);
00075           FEInterface::n_shape_functions(Dim, fe_type, elem_type);
00076 
00077         std::vector<Point> refspace_nodes;
00078         FEBase::get_refspace_nodes(elem_type,refspace_nodes);
00079         libmesh_assert_equal_to (refspace_nodes.size(), n_nodes);
00080 
00081         for (unsigned int n=0; n<n_nodes; n++)
00082           {
00083             libmesh_assert_equal_to (elem_soln.size(), n_sf);
00084 
00085             // Zero before summation
00086             nodal_soln[n] = 0;
00087 
00088             // u_i = Sum (alpha_i phi_i)
00089             for (unsigned int i=0; i<n_sf; i++)
00090               nodal_soln[n] += elem_soln[i] *
00091                 // FE<Dim,T>::shape(elem, order, i, mapped_point);
00092                 FEInterface::shape(Dim, fe_type, elem, i, refspace_nodes[n]);
00093           }
00094 
00095         return;
00096       }
00097     }
00098 } // l2_hierarchic_nodal_soln()
00099 
00100 
00101 
00102 
00103 unsigned int l2_hierarchic_n_dofs(const ElemType t, const Order o)
00104 {
00105   libmesh_assert_greater (o, 0);
00106   switch (t)
00107     {
00108     case NODEELEM:
00109       return 1;
00110     case EDGE2:
00111     case EDGE3:
00112       return (o+1);
00113     case QUAD4:
00114     case QUAD8:
00115     case QUAD9:
00116       return ((o+1)*(o+1));
00117     case HEX8:
00118     case HEX20:
00119     case HEX27:
00120       return ((o+1)*(o+1)*(o+1));
00121     case TRI6:
00122       return ((o+1)*(o+2)/2);
00123     case INVALID_ELEM:
00124       return 0;
00125     default:
00126       libmesh_error_msg("ERROR: Invalid ElemType " << Utility::enum_to_string(t) << " selected for L2_HIERARCHIC FE family!");
00127     }
00128 
00129   libmesh_error_msg("We'll never get here!");
00130   return 0;
00131 } // l2_hierarchic_n_dofs()
00132 
00133 
00134 } // anonymous namespace
00135 
00136 
00137 
00138 
00139   // Do full-specialization of nodal_soln() function for every
00140   // dimension, instead of explicit instantiation at the end of this
00141   // file.
00142   // This could be macro-ified so that it fits on one line...
00143 template <>
00144 void FE<0,L2_HIERARCHIC>::nodal_soln(const Elem* elem,
00145                                      const Order order,
00146                                      const std::vector<Number>& elem_soln,
00147                                      std::vector<Number>& nodal_soln)
00148 { l2_hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/0); }
00149 
00150 template <>
00151 void FE<1,L2_HIERARCHIC>::nodal_soln(const Elem* elem,
00152                                      const Order order,
00153                                      const std::vector<Number>& elem_soln,
00154                                      std::vector<Number>& nodal_soln)
00155 { l2_hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/1); }
00156 
00157 template <>
00158 void FE<2,L2_HIERARCHIC>::nodal_soln(const Elem* elem,
00159                                      const Order order,
00160                                      const std::vector<Number>& elem_soln,
00161                                      std::vector<Number>& nodal_soln)
00162 { l2_hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/2); }
00163 
00164 template <>
00165 void FE<3,L2_HIERARCHIC>::nodal_soln(const Elem* elem,
00166                                      const Order order,
00167                                      const std::vector<Number>& elem_soln,
00168                                      std::vector<Number>& nodal_soln)
00169 { l2_hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/3); }
00170 
00171 // Full specialization of n_dofs() function for every dimension
00172 template <> unsigned int FE<0,L2_HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
00173 template <> unsigned int FE<1,L2_HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
00174 template <> unsigned int FE<2,L2_HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
00175 template <> unsigned int FE<3,L2_HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
00176 
00177 // Full specialization of n_dofs_at_node() function for every dimension.
00178 // Discontinuous L2 elements only have interior nodes
00179 template <> unsigned int FE<0,L2_HIERARCHIC>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
00180 template <> unsigned int FE<1,L2_HIERARCHIC>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
00181 template <> unsigned int FE<2,L2_HIERARCHIC>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
00182 template <> unsigned int FE<3,L2_HIERARCHIC>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
00183 
00184 // Full specialization of n_dofs_per_elem() function for every dimension.
00185 template <> unsigned int FE<0,L2_HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
00186 template <> unsigned int FE<1,L2_HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
00187 template <> unsigned int FE<2,L2_HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
00188 template <> unsigned int FE<3,L2_HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
00189 
00190 // L2 Hierarchic FEMs are C^0 continuous
00191 template <> FEContinuity FE<0,L2_HIERARCHIC>::get_continuity() const { return DISCONTINUOUS; }
00192 template <> FEContinuity FE<1,L2_HIERARCHIC>::get_continuity() const { return DISCONTINUOUS; }
00193 template <> FEContinuity FE<2,L2_HIERARCHIC>::get_continuity() const { return DISCONTINUOUS; }
00194 template <> FEContinuity FE<3,L2_HIERARCHIC>::get_continuity() const { return DISCONTINUOUS; }
00195 
00196 // L2 Hierarchic FEMs are hierarchic (duh!)
00197 template <> bool FE<0,L2_HIERARCHIC>::is_hierarchic() const { return true; }
00198 template <> bool FE<1,L2_HIERARCHIC>::is_hierarchic() const { return true; }
00199 template <> bool FE<2,L2_HIERARCHIC>::is_hierarchic() const { return true; }
00200 template <> bool FE<3,L2_HIERARCHIC>::is_hierarchic() const { return true; }
00201 
00202 #ifdef LIBMESH_ENABLE_AMR
00203 // compute_constraints() is a NOOP for DISCONTINOUS FE's
00204 template <>
00205 void FE<2,L2_HIERARCHIC>::compute_constraints (DofConstraints &,
00206                                                DofMap &,
00207                                                const unsigned int,
00208                                                const Elem*)
00209 { }
00210 
00211 template <>
00212 void FE<3,L2_HIERARCHIC>::compute_constraints (DofConstraints &,
00213                                                DofMap &,
00214                                                const unsigned int,
00215                                                const Elem*)
00216 { }
00217 #endif // #ifdef LIBMESH_ENABLE_AMR
00218 
00219 // L2-Hierarchic FEM shapes need reinit
00220 template <> bool FE<0,L2_HIERARCHIC>::shapes_need_reinit() const { return true; }
00221 template <> bool FE<1,L2_HIERARCHIC>::shapes_need_reinit() const { return true; }
00222 template <> bool FE<2,L2_HIERARCHIC>::shapes_need_reinit() const { return true; }
00223 template <> bool FE<3,L2_HIERARCHIC>::shapes_need_reinit() const { return true; }
00224 
00225 } // namespace libMesh