Loading [MathJax]/extensions/tex2jax.js
Plugins
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
eddy_current_e_nedelec_impl.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2013-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 class member functions templates of the complex-valued
35 * FE discretization of the eddy current model.
36 */
37
38/* UG4 headers: */
40#ifdef UG_FOR_LUA
42#endif
43
44namespace ug{
45namespace Electromagnetism{
46
48// check the grid and the shape functions
50
51template<typename TDomain, typename TAlgebra>
53(
54 const std::vector<LFEID> & vLfeID,
55 bool bNonRegular
56)
57{
58// check the grid
59 if (bNonRegular)
60 UG_THROW ("ERROR in EddyCurrent_E_Nedelec:"
61 " The discretization does not support hanging nodes.\n");
62
63// check number of the components
64 if (vLfeID.size () != 2)
65 UG_THROW ("EddyCurrent_E_Nedelec: The time-harmonic problem needs two components at every edge.");
66 /* one component for the real part and one for the imaginary part */
67
68// check that these are the Nedelec elements
69 if (vLfeID[0].type() != LFEID::NEDELEC || vLfeID[1].type() != LFEID::NEDELEC)
70 UG_THROW ("EddyCurrent_E_Nedelec: This discretization works with the Nedelec-elements only.");
71}
72
74// assembling
76
78template<typename TDomain, typename TAlgebra>
79template<typename TElem>
81(
83 int si
84)
85{
86// Get the data for the subset:
87 if (m_spSubsetData->get_mu_sigma (si, m_permeability, m_conductivity))
88 UG_THROW ("Cannot get material data for subset " << si << ".");
89
90// Get the source for this subset
91 m_pSsJG = NULL;
92 for (size_t i = 0; i < m_vJG.size (); i++)
93 if (m_vJG[i].m_everywhere || m_vJG[i].m_ssGrp.contains (si))
94 {
95 if (m_pSsJG != NULL)
96 UG_THROW ("More than one specification of the generator current in subset " << si << ".");
97 m_pSsJG = & (m_vJG[i]);
98 }
99}
100
102template<typename TDomain, typename TAlgebra>
103template<typename TElem>
108
110template<typename TDomain, typename TAlgebra>
111template<typename TElem>
113(
114 const LocalVector & u,
115 GridObject * elem,
116 ReferenceObjectID roid, // id of reference element used for assembling
117 const position_type vCornerCoords []
118)
119{
120/* BEGIN code essential for the numerics */
121
122// compute the local matrices of the rot-rot operator:
125 static_cast<TElem*> (elem), vCornerCoords, m_rot_rot_S, m_rot_rot_M);
126
127/* END code essential for the numerics */
128}
129
131
170template<typename TDomain, typename TAlgebra>
171template<size_t numEdges>
173(
174 number perm,
175 number cond,
176 number S [2][numEdges] [2][numEdges]
177)
178{
179/* BEGIN code essential for the numerics */
180
181 cond *= m_omega;
182
183// the lower triange (w.r.t. the edge dofs, not the Re/Im parts)
184 for (size_t e_1 = 0; e_1 < numEdges; e_1++)
185 for (size_t e_2 = 0; e_2 <= e_1; e_2++)
186 {
187 S [_Re_][e_1] [_Re_][e_2]
188 = - (S [_Im_][e_1] [_Im_][e_2]
189 = m_rot_rot_S [e_1] [e_2] / perm);
190 S [_Re_][e_1] [_Im_][e_2]
191 = S [_Im_][e_1] [_Re_][e_2]
192 = m_rot_rot_M [e_1] [e_2] * cond;
193 }
194// the upper triangle
195 for (size_t e_1 = 0; e_1 < numEdges - 1; e_1++)
196 for (size_t e_2 = e_1+1; e_2 < numEdges; e_2++)
197 {
198 S [_Re_][e_1] [_Re_][e_2] = S [_Re_][e_2] [_Re_][e_1];
199 S [_Re_][e_1] [_Im_][e_2] = S [_Re_][e_2] [_Im_][e_1];
200 S [_Im_][e_1] [_Im_][e_2] = S [_Im_][e_2] [_Im_][e_1];
201 S [_Im_][e_1] [_Re_][e_2] = S [_Im_][e_2] [_Re_][e_1];
202 }
203
204/* END code essential for the numerics */
205}
206
208template<typename TDomain, typename TAlgebra>
209template<typename TElem>
211(
212 LocalMatrix & J,
213 const LocalVector & u,
214 GridObject * elem,
215 const position_type vCornerCoords []
216)
217{
220
221 ass_elem_stiffness<NedelecT1_LDisc<TDomain, TElem>::numEdges>
222 (m_permeability, m_conductivity, S);
223
224 for (size_t e_1 = 0; e_1 < NedelecT1_LDisc<TDomain, TElem>::numEdges; e_1++)
225 for (size_t e_2 = 0; e_2 < NedelecT1_LDisc<TDomain, TElem>::numEdges; e_2++)
226 {
227 J(_Re_, e_1, _Re_, e_2) += S [_Re_][e_1] [_Re_][e_2];
228 J(_Re_, e_1, _Im_, e_2) += S [_Re_][e_1] [_Im_][e_2];
229 J(_Im_, e_1, _Im_, e_2) += S [_Im_][e_1] [_Im_][e_2];
230 J(_Im_, e_1, _Re_, e_2) += S [_Im_][e_1] [_Re_][e_2];
231 }
232}
233
235
255template<typename TDomain, typename TAlgebra>
256template<typename TElem>
258(
259 LocalVector & b,
260 GridObject * elem,
261 const position_type vCornerCoords []
262)
263{
264 if (m_pSsJG == NULL) return; // no rhs
265
266// The generator current (source) at the dofs
268
269// Get the generator current from the grid functions
270 TElem * pElem = static_cast<TElem*> (elem);
271 for (size_t part = 0; part < 2; part++) // Re and Im
272 {
273 std::vector<DoFIndex> ind;
274 m_pSsJG->m_spGf->dof_indices (pElem, m_pSsJG->m_vFct[part], ind);
275 for (size_t e = 0; e < NedelecT1_LDisc<TDomain, TElem>::numEdges; e++)
276 vJG[e][part] = DoFRef (* (m_pSsJG->m_spGf), ind[e]);
277 }
278
279/* BEGIN code essential for the numerics */
280
281// Assemble the possibly non-zero rhs:
282 for (size_t e_1 = 0; e_1 < NedelecT1_LDisc<TDomain, TElem>::numEdges; e_1++)
283 {
284 number Re_rhs = 0, Im_rhs = 0;
285 for (size_t e_2 = 0; e_2 < NedelecT1_LDisc<TDomain, TElem>::numEdges; e_2++)
286 {
287 Re_rhs -= m_rot_rot_M[e_1][e_2] * vJG[e_2][_Im_];
288 Im_rhs -= m_rot_rot_M[e_1][e_2] * vJG[e_2][_Re_];
289 }
290 b (_Re_, e_1) += m_omega * Re_rhs; b (_Im_, e_1) += m_omega * Im_rhs;
291 }
292
293/* END code essential for the numerics */
294}
295
297template<typename TDomain, typename TAlgebra>
298template<typename TElem>
300(
301 LocalVector & d, const LocalVector & u, GridObject * elem, const position_type vCornerCoords []
302)
303{}
304
306
310template<typename TDomain, typename TAlgebra>
311template<typename TElem>
313(
314 LocalMatrix & J, const LocalVector & u, GridObject * elem, const position_type vCornerCoords []
315)
316{}
317
319
323template<typename TDomain, typename TAlgebra>
324template<typename TElem>
326(
327 LocalVector & d, const LocalVector & u, GridObject * elem, const position_type vCornerCoords []
328)
329{}
330
332// register assembling functions
334
336template<typename TDomain, typename TAlgebra>
338{
339// get all grid element types in this dimension and below
340 typedef typename domain_traits<dim>::DimElemList ElemList;
341
342// switch assemble functions
343 boost::mpl::for_each<ElemList> (RegisterLocalDiscr (this));
344}
345
347template<typename TDomain, typename TAlgebra>
348template<typename TElem> // the element to register for
350{
352
353 this->clear_add_fct(id);
354
355 this->set_prep_elem_loop_fct(id, & this_type::template prepare_element_loop<TElem>);
356 this->set_prep_elem_fct (id, & this_type::template prepare_element<TElem>);
357 this->set_fsh_elem_loop_fct (id, & this_type::template finish_element_loop<TElem>);
358 this->set_add_jac_A_elem_fct(id, & this_type::template ass_JA_elem<TElem>);
359 this->set_add_jac_M_elem_fct(id, & this_type::template ass_JM_elem<TElem>);
360 this->set_add_def_A_elem_fct(id, & this_type::template ass_dA_elem<TElem>);
361 this->set_add_def_M_elem_fct(id, & this_type::template ass_dM_elem<TElem>);
362 this->set_add_rhs_elem_fct (id, & this_type::template ass_rhs_elem<TElem>);
363}
364
366// obtaining the parameters
368
375template<typename TDomain, typename TAlgebra>
377(
379 const char * cmp,
380 const char * ss_names
381)
382{
383 std::vector<std::string> tokens;
384
385 if (spgfJG.invalid ())
386 UG_THROW("EddyCurrent_E_Nedelec: Invalid grid function for the generator source");
387
388// Data to get:
389 size_t vfctJG [2];
390 bool ew;
391 SubsetGroup ssGrp (spgfJG->approx_space()->subset_handler ());
392
393// Get function names:
394 std::string fctString (cmp);
395
396// Tokenize the strings and select functions
397 TokenizeString (fctString, tokens, ',');
398
399 if ((int) tokens.size () != 2)
400 UG_THROW("EddyCurrent_E_Nedelec: Needed 2 components "
401 "in symbolic function names for the generator current (for Re and Im), "
402 "but given: " << cmp);
403
404 for (size_t i = 0; i < 2; i++)
405 RemoveWhitespaceFromString (tokens [i]);
406
407// Get function id's by names:
408 for (int i = 0; i < 2; i++)
409 try
410 {
411 vfctJG [i] = spgfJG->fct_id_by_name (tokens[i].c_str ());
412 }
413 UG_CATCH_THROW ("EddyCurrent_E_Nedelec: Cannot find symbolic function "
414 "component for the name '" << tokens[i] << "'.");
415
416// Check the function space of the grid function:
417 for (int i = 0; i < 2; i++)
418 if (spgfJG->local_finite_element_id(vfctJG[i]) != LFEID(LFEID::NEDELEC, dim, 1))
419 UG_THROW ("EddyCurrent_E_Nedelec: The function space of component "
420 << tokens[i] << " of the grid function does not correspond "
421 "to the Nedelec element.");
422
423// Get the subsets:
424 if (ss_names == NULL)
425 ew = true;
426 else
427 {
428 ew = false;
429 std::string ssString (ss_names);
430 TokenizeString (ssString, tokens, ',');
431 for (size_t i = 0; i < tokens.size (); i++)
432 RemoveWhitespaceFromString (tokens [i]);
433 try
434 {
435 ssGrp.add (tokens);
436 }
438 ("EddyCurrent_E_Nedelec: Failed to add subsets to the source");
439 }
440
441// Create the source:
442 m_vJG.push_back (tGeneratorCurrent (spgfJG, vfctJG[_Re_], vfctJG[_Im_], ssGrp, ew));
443}
444
448template<typename TDomain, typename TAlgebra>
451(
452 const char * functions,
454 number frequency
455)
456: IElemDisc<TDomain> (functions, spSubsetData->subset_names ()),
457 m_omega (frequency),
458 m_spSubsetData (spSubsetData)
459{
460// check number of functions
461 if (this->num_fct () != 2)
462 UG_THROW ("Wrong number of functions: The ElemDisc 'EddyCurrent_E_Nedelec'"
463 " needs exactly 2 symbolic functions"
464 " (one for the real part and one for the imaginary one).");
465
466// register assemble functions
468}
469
470} // end namespace Electromagnetism
471} // end namespace ug
472
473/* End of File */
bool invalid() const
Class for subdomain-dependent data for the E-based formulated problems.
Definition em_material.h:63
FE-discretization of the time-harmonic E-based formulation of the eddy current model.
Definition eddy_current_e_nedelec.h:98
void prepare_element(const LocalVector &u, GridObject *elem, ReferenceObjectID roid, const position_type vCornerCoords[])
prepares a given element for assembling: computes the discretization of the rot-rot operator
Definition eddy_current_e_nedelec_impl.h:113
void ass_rhs_elem(LocalVector &d, GridObject *elem, const position_type vCornerCoords[])
computes the right-hand side due to the generator currents
Definition eddy_current_e_nedelec_impl.h:258
void ass_dA_elem(LocalVector &d, const LocalVector &u, GridObject *elem, const position_type vCornerCoords[])
computes the local defect and transfers it to the global discretization
Definition eddy_current_e_nedelec_impl.h:300
EddyCurrent_E_Nedelec(const char *functions, ConstSmartPtr< EMaterial< domain_type > > spSubsetData, number frequency)
class constructor
Definition eddy_current_e_nedelec_impl.h:451
void register_all_loc_discr_funcs()
registers the local assembler functions for all the elements and dimensions
Definition eddy_current_e_nedelec_impl.h:337
void ass_JM_elem(LocalMatrix &J, const LocalVector &u, GridObject *elem, const position_type vCornerCoords[])
computes the mass matrix of a time-dependent problem
Definition eddy_current_e_nedelec_impl.h:313
void ass_dM_elem(LocalVector &d, const LocalVector &u, GridObject *elem, const position_type vCornerCoords[])
computes the mass part of the defect of a time-dependent problem
Definition eddy_current_e_nedelec_impl.h:326
void prepare_element_loop(ReferenceObjectID roid, int si)
prepares the loop over the elements: checks whether the parameters are set, ...
Definition eddy_current_e_nedelec_impl.h:81
void set_generator_current(SmartPtr< TGridFunction > spgfJG, const char *cmp, const char *ss_names=NULL)
adds a generator current item to the discretization
Definition eddy_current_e_nedelec_impl.h:377
void register_loc_discr_func()
registers the local assembler functions for a given element
Definition eddy_current_e_nedelec_impl.h:349
base_type::position_type position_type
position type
Definition eddy_current_e_nedelec.h:113
void finish_element_loop()
finalizes the loop over the elements: clear the source
Definition eddy_current_e_nedelec_impl.h:104
virtual void prepare_setting(const std::vector< LFEID > &vLfeID, bool bNonRegular)
check type of the grid and the trial space
Definition eddy_current_e_nedelec_impl.h:53
void ass_JA_elem(LocalMatrix &J, const LocalVector &u, GridObject *elem, const position_type vCornerCoords[])
transfers the precomputed local stiffness matrix to the global discretization
Definition eddy_current_e_nedelec_impl.h:211
void ass_elem_stiffness(number perm, number cond, number S[2][numEdges][2][numEdges])
composes the stiffness matrix of the stationary problem
Definition eddy_current_e_nedelec_impl.h:173
Tool kit for the Whitney-1 (Nedelec) based FE discretization of the rot-rot operators.
Definition nedelec_local_ass.h:85
static void local_stiffness_and_mass(const TDomain *domain, TElem *elem, const position_type *corners, number S[maxNumEdges][maxNumEdges], number M[maxNumEdges][maxNumEdges])
assembles the local stiffness and the mass matrices of the rot-rot operator
Definition nedelec_local_ass.h:119
size_t num_fct() const
void add(const char *name)
Variant::Type type()
vector< string > TokenizeString(const char *str, const char delimiter=',')
void RemoveWhitespaceFromString(std::string &string)
#define UG_CATCH_THROW(msg)
#define UG_THROW(msg)
double number
ReferenceObjectID
const number & DoFRef(const TMatrix &mat, const DoFIndex &iInd, const DoFIndex &jInd)
class for a generator current (source) in a subdomain
Definition eddy_current_e_nedelec.h:221