Plugins
nedelec_aux_cmd_impl.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014: G-CSC, Goethe University Frankfurt
3  * Author: Dmitry Logashenko
4  *
5  * This file is part of UG4.
6  *
7  * UG4 is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License version 3 (as published by the
9  * Free Software Foundation) with the following additional attribution
10  * requirements (according to LGPL/GPL v3 §7):
11  *
12  * (1) The following notice must be displayed in the Appropriate Legal Notices
13  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14  *
15  * (2) The following notice must be displayed at a prominent place in the
16  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17  *
18  * (3) The following bibliography is recommended for citation and must be
19  * preserved in all covered files:
20  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21  * parallel geometric multigrid solver on hierarchically distributed grids.
22  * Computing and visualization in science 16, 4 (2013), 151-164"
23  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24  * flexible software system for simulating pde based models on high performance
25  * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26  *
27  * This program is distributed in the hope that it will be useful,
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  * GNU Lesser General Public License for more details.
31  */
32 
33 /*
34  * Implementation of the functions and the commands for the Whitney-1 (Nedelec) elements.
35  */
36 
37 // basic ug4 headers
38 #include "common/common.h"
39 #ifdef UG_FOR_LUA
41 #endif
42 
43 /* Discretization's headers: */
44 #include "nedelec_local_ass.h"
45 
46 namespace ug{
47 namespace Electromagnetism{
48 
50 template <typename TGridFunc, typename TElem>
52 {
53 private:
56  (
57  TGridFunc * pGF,
58  size_t fct,
59  TElem * pElem,
60  SubsetGroup & faceSSG
61  )
62  {
63  typedef typename TGridFunc::domain_type domain_type;
64  static const int dim = domain_type::dim;
65  typedef typename reference_element_traits<TElem>::reference_element_type ref_elem_type;
66  typedef typename domain_traits<dim>::side_type side_type;
67 
68  number flux = 0;
69 
70  // loop the sides
71  const ISubsetHandler * pIsh = pGF->subset_handler().get ();
72  for (size_t i = 0; i < (size_t) ref_elem_type::numSides; i++)
73  {
74  // check whether that is a side on the face
75  side_type * pSide = pIsh->grid()->get_side (pElem, i);
76  if (! faceSSG.contains (pIsh->get_subset_index (pSide)))
77  continue;
78 
79  //---- There is typically only one side on the surface, and not for every
80  //---- element. So we put the following section into the loop although it
81  //---- does not depend on the side. This allows to skip getting coordinates
82  //---- and dofs for elements that have no sides on the surface.
83 
84  const ref_elem_type & rRefElem = Provider<ref_elem_type>::get ();
85 
86  // get position accessor and corner coordinates of the element
87  const typename domain_type::position_accessor_type & aaPos
88  = pGF->domain()->position_accessor();
89  typename domain_type::position_type corners [ref_elem_type::numCorners];
90  for (size_t co = 0; co < (size_t) ref_elem_type::numCorners; co++)
91  corners[co] = aaPos [pElem->vertex (co)];
92 
93  // get the dof values of the function in the element
94  std::vector<DoFIndex> ind;
95  if (pGF->dof_indices (pElem, fct, ind) != (size_t) ref_elem_type::numEdges)
96  UG_THROW ("Grid function type mismatch.");
97  number dofValues [ref_elem_type::numEdges];
98  for (size_t dof = 0; dof < (size_t) ref_elem_type::numEdges; dof++)
99  dofValues[dof] = DoFRef (*pGF, ind[dof]);
100 
101  //----
102 
103  // get the integration point
104  MathVector<dim> loc_center;
105  loc_center = 0.0;
106  size_t co;
107  for (co = 0; co < pSide->num_vertices (); co++)
108  {
109  int elem_co = rRefElem.id (dim-1, i, 0, co);
110  UG_ASSERT (elem_co >= 0, "Index mismatch.");
111  loc_center += rRefElem.corner (elem_co);
112  }
113  loc_center /= co;
114 
115  // compute the value of the function at the ip
116  MathVector<dim> val;
118  (pGF->domain().get (), pElem, corners, dofValues, &loc_center, 1, &val);
119 
120  // get the normal to the side (its length is the area of the side)
122  SideNormal<ref_elem_type, dim> (normal, i, corners);
123 
124  // update the flux
125  flux += VecDot (val, normal);
126  }
127 
128  return flux;
129  }
130 
131 public:
134  (
135  TGridFunc * pGF,
136  size_t fct,
137  SubsetGroup & volSSG,
138  SubsetGroup & faceSSG
139  )
140  {
141  typedef typename TGridFunc::template traits<TElem>::const_iterator t_elem_iterator;
142 
143  number flux = 0;
144 
145  // loop all volume subsets
146  for (size_t i = 0; i < volSSG.size (); i++)
147  {
148  int si = volSSG[i];
149  // loop all the elements
150  t_elem_iterator elem_iter = pGF->template begin<TElem> (si);
151  t_elem_iterator end_iter = pGF->template end<TElem> (si);
152  for (; elem_iter != end_iter; ++elem_iter)
153  flux += compute_elem_flux (pGF, fct, *elem_iter, faceSSG);
154  }
155 
156  return flux;
157  }
158 };
159 
161 template <typename TGridFunc>
163 {
164 public:
167  (
168  TGridFunc * pGF,
169  size_t fct,
170  SubsetGroup & volSSG,
171  SubsetGroup & faceSSG
172  )
173  {
174  UG_THROW ("ComputeFlux: No flux computations in 1d.");
175  }
176 };
177 
179 template <typename TGridFunc>
181 {
182  TGridFunc * m_pGF;
183  size_t m_fct;
187 
188 public:
189 
192  (
193  TGridFunc * pGF,
194  size_t fct,
195  SubsetGroup & volSSG,
196  SubsetGroup & faceSSG,
197  number & flux
198  )
199  : m_pGF (pGF), m_fct (fct), m_volSSG (volSSG), m_faceSSG (faceSSG), m_flux (flux)
200  {
201  flux = 0;
202  }
203 
204  template <typename TElem> void operator() (TElem &)
205  {
207  }
208 };
209 
211 template <typename TGridFunc>
213 (
214  TGridFunc * pGF,
215  size_t fct,
216  SubsetGroup & volSSG,
217  SubsetGroup & faceSSG
218 )
219 {
220  typedef typename TGridFunc::domain_type domain_type;
221  static const int dim = domain_type::dim;
222  typedef typename domain_traits<dim>::DimElemList ElemList;
223 
224  if (pGF->local_finite_element_id (fct).type () != LFEID::NEDELEC)
225  UG_THROW ("ComputeFlux: Not a Nedelec-element-based grid function specified.");
226 
227  number flux;
228  boost::mpl::for_each<ElemList>
229  (ComputeFluxHelper<TGridFunc> (pGF, fct, volSSG, faceSSG, flux));
230  return flux;
231 }
232 
234 template <typename TGridFunc>
236 (
237  SmartPtr<TGridFunc> spGF,
238  const char * fct_names,
239  const char * vol_subsets,
240  const char * face_subsets
241 )
242 {
243  FunctionGroup fctGrp;
244  try
245  {
246  fctGrp = spGF->fct_grp_by_name (fct_names);
247  }
248  UG_CATCH_THROW ("ComputeFlux: Functions '" << fct_names <<
249  "' not all contained in the edge approximation space.");
250  if (fctGrp.size () != 1)
251  UG_THROW ("ComputeFlux: Only one function component per call supported");
252 
253  SubsetGroup volSSG, faceSSG;
254  std::vector<std::string> vssNames;
255 
256  TokenizeString (vol_subsets, vssNames);
257  for (size_t i = 0; i < vssNames.size(); i++)
258  RemoveWhitespaceFromString (vssNames [i]);
259  volSSG.set_subset_handler (spGF->subset_handler ());
260  volSSG.add (vssNames);
261 
262  TokenizeString (face_subsets, vssNames);
263  for (size_t i = 0; i < vssNames.size(); i++)
264  RemoveWhitespaceFromString (vssNames [i]);
265  faceSSG.set_subset_handler (spGF->subset_handler ());
266  faceSSG.add (vssNames);
267 
268  number flux = ComputeFlux (spGF.get(), fctGrp[0], volSSG, faceSSG);
269  UG_LOG ("--> Flux: " << flux << '\n');
270 }
271 
272 } // end namespace Electromagnetism
273 } // end namespace ug
274 
275 /* End of File */
T * get()
static number compute_flux(TGridFunc *pGF, size_t fct, SubsetGroup &volSSG, SubsetGroup &faceSSG)
Computation of the flux through the sides of all elements of one type.
Definition: nedelec_aux_cmd_impl.h:167
Helper class for computation of the flux in elements. (Helper for ComputeFlux.)
Definition: nedelec_aux_cmd_impl.h:52
static number compute_elem_flux(TGridFunc *pGF, size_t fct, TElem *pElem, SubsetGroup &faceSSG)
Computation of the flux through sides of an element.
Definition: nedelec_aux_cmd_impl.h:56
static number compute_flux(TGridFunc *pGF, size_t fct, SubsetGroup &volSSG, SubsetGroup &faceSSG)
Computation of the flux through the sides of all elements of one type.
Definition: nedelec_aux_cmd_impl.h:134
Helper class for the loop over all the elements in the computation of the flux. (Helper for ComputeFl...
Definition: nedelec_aux_cmd_impl.h:181
ComputeFluxHelper(TGridFunc *pGF, size_t fct, SubsetGroup &volSSG, SubsetGroup &faceSSG, number &flux)
class constructor
Definition: nedelec_aux_cmd_impl.h:192
number & m_flux
Definition: nedelec_aux_cmd_impl.h:186
TGridFunc * m_pGF
Definition: nedelec_aux_cmd_impl.h:182
void operator()(TElem &)
Definition: nedelec_aux_cmd_impl.h:204
SubsetGroup & m_volSSG
Definition: nedelec_aux_cmd_impl.h:184
size_t m_fct
Definition: nedelec_aux_cmd_impl.h:183
SubsetGroup & m_faceSSG
Definition: nedelec_aux_cmd_impl.h:185
static void value(const TDomain *domain, GridObject *elem, const position_type corners[], const number dofs[], const MathVector< refDim > local[], const size_t n_pnt, MathVector< WDim > values[])
computes the values at given points
Definition: nedelec_local_ass.h:411
size_t size() const
Edge::side * get_side(Edge *obj, size_t side)
int get_subset_index(const char *name) const
Grid * grid() const
static TClass & get()
bool contains(const char *name) const
void add(const char *name)
size_t size() const
void set_subset_handler(ConstSmartPtr< ISubsetHandler > sh)
Grid::VertexAttachmentAccessor< position_attachment_type > position_accessor_type
MathVector< dim > position_type
static const int dim
normal
vector< string > TokenizeString(const char *str, const char delimiter=',')
void RemoveWhitespaceFromString(std::string &string)
#define UG_ASSERT(expr, msg)
#define UG_CATCH_THROW(msg)
#define UG_THROW(msg)
#define UG_LOG(msg)
double number
vector_t::value_type VecDot(const vector_t &v1, const vector_t &v2)
number ComputeFlux(TGridFunc *pGF, size_t fct, SubsetGroup &volSSG, SubsetGroup &faceSSG)
returns the flux through a given surface
Definition: nedelec_aux_cmd_impl.h:213
const number & DoFRef(const TMatrix &mat, const DoFIndex &iInd, const DoFIndex &jInd)
geometry_traits< TElem >::const_iterator const_iterator