fe_l2_hierarchic.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 // Local includes
21 #include "libmesh/elem.h"
22 #include "libmesh/fe.h"
23 #include "libmesh/fe_interface.h"
24 
25 namespace libMesh
26 {
27 
28  // ------------------------------------------------------------
29  // Hierarchic-specific implementations
30 
31  // Anonymous namespace for local helper functions
32  namespace {
33 
34  void l2_hierarchic_nodal_soln(const Elem* elem,
35  const Order order,
36  const std::vector<Number>& elem_soln,
37  std::vector<Number>& nodal_soln,
38  unsigned Dim)
39  {
40  const unsigned int n_nodes = elem->n_nodes();
41 
42  const ElemType elem_type = elem->type();
43 
44  nodal_soln.resize(n_nodes);
45 
46  const Order totalorder = static_cast<Order>(order + elem->p_level());
47 
48  // FEType object to be passed to various FEInterface functions below.
49  FEType fe_type(totalorder, L2_HIERARCHIC);
50 
51  switch (totalorder)
52  {
53  // Constant shape functions
54  case CONSTANT:
55  {
56  libmesh_assert_equal_to (elem_soln.size(), 1);
57 
58  const Number val = elem_soln[0];
59 
60  for (unsigned int n=0; n<n_nodes; n++)
61  nodal_soln[n] = val;
62 
63  return;
64  }
65 
66 
67  // For other orders do interpolation at the nodes
68  // explicitly.
69  default:
70  {
71 
72  const unsigned int n_sf =
73  // FE<Dim,T>::n_shape_functions(elem_type, totalorder);
74  FEInterface::n_shape_functions(Dim, fe_type, elem_type);
75 
76  std::vector<Point> refspace_nodes;
77  FEBase::get_refspace_nodes(elem_type,refspace_nodes);
78  libmesh_assert_equal_to (refspace_nodes.size(), n_nodes);
79 
80  for (unsigned int n=0; n<n_nodes; n++)
81  {
82  libmesh_assert_equal_to (elem_soln.size(), n_sf);
83 
84  // Zero before summation
85  nodal_soln[n] = 0;
86 
87  // u_i = Sum (alpha_i phi_i)
88  for (unsigned int i=0; i<n_sf; i++)
89  nodal_soln[n] += elem_soln[i] *
90  // FE<Dim,T>::shape(elem, order, i, mapped_point);
91  FEInterface::shape(Dim, fe_type, elem, i, refspace_nodes[n]);
92  }
93 
94  return;
95  }
96  }
97  } // l2_hierarchic_nodal_soln()
98 
99 
100 
101 
102  unsigned int l2_hierarchic_n_dofs(const ElemType t, const Order o)
103  {
104  libmesh_assert_greater (o, 0);
105  switch (t)
106  {
107  case NODEELEM:
108  return 1;
109  case EDGE2:
110  case EDGE3:
111  return (o+1);
112  case QUAD4:
113  case QUAD8:
114  case QUAD9:
115  return ((o+1)*(o+1));
116  case HEX8:
117  case HEX20:
118  case HEX27:
119  return ((o+1)*(o+1)*(o+1));
120  case TRI6:
121  return ((o+1)*(o+2)/2);
122  default:
123  libmesh_error();
124  }
125 
126  libmesh_error();
127  return 0;
128  } // l2_hierarchic_n_dofs()
129 
130 
131  } // anonymous namespace
132 
133 
134 
135 
136  // Do full-specialization of nodal_soln() function for every
137  // dimension, instead of explicit instantiation at the end of this
138  // file.
139  // This could be macro-ified so that it fits on one line...
140  template <>
142  const Order order,
143  const std::vector<Number>& elem_soln,
144  std::vector<Number>& nodal_soln)
145  { l2_hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/0); }
146 
147  template <>
149  const Order order,
150  const std::vector<Number>& elem_soln,
151  std::vector<Number>& nodal_soln)
152  { l2_hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/1); }
153 
154  template <>
156  const Order order,
157  const std::vector<Number>& elem_soln,
158  std::vector<Number>& nodal_soln)
159  { l2_hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/2); }
160 
161  template <>
163  const Order order,
164  const std::vector<Number>& elem_soln,
165  std::vector<Number>& nodal_soln)
166  { l2_hierarchic_nodal_soln(elem, order, elem_soln, nodal_soln, /*Dim=*/3); }
167 
168  // Full specialization of n_dofs() function for every dimension
169  template <> unsigned int FE<0,L2_HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
170  template <> unsigned int FE<1,L2_HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
171  template <> unsigned int FE<2,L2_HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
172  template <> unsigned int FE<3,L2_HIERARCHIC>::n_dofs(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
173 
174  // Full specialization of n_dofs_at_node() function for every dimension.
175  // Discontinuous L2 elements only have interior nodes
176  template <> unsigned int FE<0,L2_HIERARCHIC>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
177  template <> unsigned int FE<1,L2_HIERARCHIC>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
178  template <> unsigned int FE<2,L2_HIERARCHIC>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
179  template <> unsigned int FE<3,L2_HIERARCHIC>::n_dofs_at_node(const ElemType, const Order, const unsigned int) { return 0; }
180 
181  // Full specialization of n_dofs_per_elem() function for every dimension.
182  template <> unsigned int FE<0,L2_HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
183  template <> unsigned int FE<1,L2_HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
184  template <> unsigned int FE<2,L2_HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
185  template <> unsigned int FE<3,L2_HIERARCHIC>::n_dofs_per_elem(const ElemType t, const Order o) { return l2_hierarchic_n_dofs(t, o); }
186 
187  // L2 Hierarchic FEMs are C^0 continuous
192 
193  // L2 Hierarchic FEMs are hierarchic (duh!)
194  template <> bool FE<0,L2_HIERARCHIC>::is_hierarchic() const { return true; }
195  template <> bool FE<1,L2_HIERARCHIC>::is_hierarchic() const { return true; }
196  template <> bool FE<2,L2_HIERARCHIC>::is_hierarchic() const { return true; }
197  template <> bool FE<3,L2_HIERARCHIC>::is_hierarchic() const { return true; }
198 
199 #ifdef LIBMESH_ENABLE_AMR
200  // compute_constraints() is a NOOP for DISCONTINOUS FE's
201  template <>
203  DofMap &,
204  const unsigned int,
205  const Elem*)
206  { }
207 
208  template <>
210  DofMap &,
211  const unsigned int,
212  const Elem*)
213  { }
214 #endif // #ifdef LIBMESH_ENABLE_AMR
215 
216  // L2-Hierarchic FEM shapes need reinit
217  template <> bool FE<0,L2_HIERARCHIC>::shapes_need_reinit() const { return true; }
218  template <> bool FE<1,L2_HIERARCHIC>::shapes_need_reinit() const { return true; }
219  template <> bool FE<2,L2_HIERARCHIC>::shapes_need_reinit() const { return true; }
220  template <> bool FE<3,L2_HIERARCHIC>::shapes_need_reinit() const { return true; }
221 
222 } // namespace libMesh

Site Created By: libMesh Developers
Last modified: February 07 2014 16:57:05 UTC

Hosted By:
SourceForge.net Logo