Hermes2D  2.0
weakforms_maxwell.cpp
1 // This file is part of Hermes2D.
2 //
3 // Hermes2D is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 2 of the License, or
6 // (at your option) any later version.
7 //
8 // Hermes2D is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with Hermes2D. If not, see <http://www.gnu.org/licenses/>.
15 
16 #include "weakforms_maxwell.h"
17 namespace Hermes
18 {
19  namespace Hermes2D
20  {
21  namespace WeakFormsMaxwell
22  {
23  template<typename Scalar>
24  DefaultJacobianMagnetostatics<Scalar>::DefaultJacobianMagnetostatics(int i, int j, std::string area, Scalar const_coeff,
25  CubicSpline* c_spline,
26  SymFlag sym,
27  GeomType gt,
28  int order_increase)
29  : MatrixFormVol<Scalar>(i, j), idx_j(j), const_coeff(const_coeff),
30  spline_coeff(c_spline), gt(gt),
31  order_increase(order_increase)
32  {
33  this->set_area(area);
34  this->setSymFlag(sym);
35 
36  // If spline is HERMES_DEFAULT_SPLINE, initialize it to be constant 1.0.
37  if(c_spline == HERMES_DEFAULT_SPLINE) this->spline_coeff = new CubicSpline(1.0);
38  }
39  template<typename Scalar>
40  DefaultJacobianMagnetostatics<Scalar>::DefaultJacobianMagnetostatics(int i, int j, Hermes::vector<std::string> areas,
41  Scalar const_coeff,
42  CubicSpline* c_spline,
43  SymFlag sym,
44  GeomType gt,
45  int order_increase)
46  : MatrixFormVol<Scalar>(i, j), idx_j(j), const_coeff(const_coeff),
47  spline_coeff(c_spline), gt(gt),
48  order_increase(order_increase)
49  {
50  this->set_areas(areas);
51  this->setSymFlag(sym);
52 
53  // If spline is HERMES_DEFAULT_SPLINE, initialize it to be constant 1.0.
54  if(c_spline == HERMES_DEFAULT_SPLINE) this->spline_coeff = new CubicSpline(1.0);
55  }
56 
57  template<typename Scalar>
58  Scalar DefaultJacobianMagnetostatics<Scalar>::value(int n, double *wt, Func<Scalar> *u_ext[], Func<double> *u,
59  Func<double> *v, Geom<double> *e, Func<Scalar> **ext) const
60  {
61  Scalar planar_part = 0;
62  Scalar axisym_part = 0;
63  for (int i = 0; i < n; i++)
64  {
65  Scalar B_i = sqrt(sqr(u_ext[idx_j]->dx[i]) + sqr(u_ext[idx_j]->dy[i]));
66  if(std::abs(B_i) > 1e-12)
67  {
68  planar_part += wt[i] * const_coeff*spline_coeff->derivative(B_i) / B_i
69  * (u_ext[idx_j]->dx[i] * u->dx[i] + u_ext[idx_j]->dy[i] * u->dy[i])
70  * (u_ext[idx_j]->dx[i] * v->dx[i] + u_ext[idx_j]->dy[i] * v->dy[i]);
71  if(gt == HERMES_AXISYM_X)
72  {
73  axisym_part += wt[i] * const_coeff*spline_coeff->derivative(B_i) / B_i / e->y[i]
74  * (u_ext[idx_j]->dx[i] * u->dx[i] + u_ext[idx_j]->dy[i] * u->dy[i])
75  * u_ext[idx_j]->val[i] * v->dy[i];
76  }
77  else if(gt == HERMES_AXISYM_Y)
78  {
79  axisym_part += wt[i] * const_coeff*spline_coeff->derivative(B_i) / B_i / e->x[i]
80  * (u_ext[idx_j]->dx[i] * u->dx[i] + u_ext[idx_j]->dy[i] * u->dy[i])
81  * u_ext[idx_j]->val[i] * v->dx[i];
82  }
83  }
84  planar_part += wt[i] * const_coeff*spline_coeff->value(B_i)
85  * (u->dx[i] * v->dx[i] + u->dy[i] * v->dy[i]);
86  if(gt == HERMES_AXISYM_X)
87  {
88  axisym_part += wt[i] * const_coeff*spline_coeff->value(B_i) / e->y[i]
89  * u->val[i] * v->dy[i];
90  }
91  else if(gt == HERMES_AXISYM_Y)
92  {
93  axisym_part += wt[i] * const_coeff*spline_coeff->value(B_i) / e->x[i]
94  * u->val[i] * v->dx[i];
95  }
96  }
97 
98  return planar_part + axisym_part;
99  }
100 
101  template<typename Scalar>
102  Ord DefaultJacobianMagnetostatics<Scalar>::ord(int n, double *wt, Func<Ord> *u_ext[], Func<Ord> *u, Func<Ord> *v,
103  Geom<Ord> *e, Func<Ord> **ext) const
104  {
105  Ord planar_part(0);
106  for (int i = 0; i < n; i++)
107  {
108  Ord B_i = sqrt(sqr(u_ext[idx_j]->dx[i]) + sqr(u_ext[idx_j]->dy[i]));
109  planar_part += wt[i] * const_coeff*spline_coeff->derivative(B_i) / B_i
110  * (u_ext[idx_j]->dx[i] * u->dx[i] + u_ext[idx_j]->dy[i] * u->dy[i])
111  * (u_ext[idx_j]->dx[i] * v->dx[i] + u_ext[idx_j]->dy[i] * v->dy[i]);
112  planar_part += wt[i] * const_coeff*spline_coeff->value(B_i)
113  * (u->dx[i] * v->dx[i] + u->dy[i] * v->dy[i]);
114  }
115 
116  // This increase is for the axisymmetric part. We are not letting the
117  // Ord class do it since it would automatically choose the highest order
118  // due to the nonpolynomial 1/r term.
119  return planar_part * Ord(order_increase);
120  }
121 
122  template<typename Scalar>
123  MatrixFormVol<Scalar>* DefaultJacobianMagnetostatics<Scalar>::clone() const
124  {
125  return new DefaultJacobianMagnetostatics(*this);
126  }
127 
128  template<typename Scalar>
129  DefaultResidualMagnetostatics<Scalar>::DefaultResidualMagnetostatics(int i, std::string area, Scalar const_coeff,
130  CubicSpline* c_spline,
131  GeomType gt,
132  int order_increase)
133  : VectorFormVol<Scalar>(i), idx_i(i), const_coeff(const_coeff), spline_coeff(c_spline),
134  gt(gt), order_increase(order_increase)
135  {
136  this->set_area(area);
137  // If spline is HERMES_DEFAULT_SPLINE, initialize it to be constant 1.0.
138  if(c_spline == HERMES_DEFAULT_SPLINE) this->spline_coeff = new CubicSpline(1.0);
139  }
140 
141  template<typename Scalar>
142  DefaultResidualMagnetostatics<Scalar>::DefaultResidualMagnetostatics(int i, Hermes::vector<std::string> areas, Scalar const_coeff,
143  CubicSpline* c_spline,
144  GeomType gt, int order_increase)
145  : VectorFormVol<Scalar>(i), idx_i(i), const_coeff(const_coeff), spline_coeff(c_spline), gt(gt),
146  order_increase(order_increase)
147  {
148  this->set_areas(areas);
149 
150  // If spline is HERMES_DEFAULT_SPLINE, initialize it to be constant 1.0.
151  if(c_spline == HERMES_DEFAULT_SPLINE) this->spline_coeff = new CubicSpline(1.0);
152  }
153 
154  template<typename Scalar>
155  Scalar DefaultResidualMagnetostatics<Scalar>::value(int n, double *wt, Func<Scalar> *u_ext[], Func<double> *v,
156  Geom<double> *e, Func<Scalar> **ext) const
157  {
158  Scalar planar_part = 0;
159  Scalar axisym_part = 0;
160  for (int i = 0; i < n; i++)
161  {
162  Scalar B_i = sqrt(sqr(u_ext[idx_i]->dx[i]) + sqr(u_ext[idx_i]->dy[i]));
163  planar_part += wt[i] * const_coeff*spline_coeff->value(B_i) *
164  (u_ext[idx_i]->dx[i] * v->dx[i] + u_ext[idx_i]->dy[i] * v->dy[i]);
165  if(gt == HERMES_AXISYM_X) axisym_part += wt[i] * const_coeff*spline_coeff->value(B_i) / e->y[i]
166  * u_ext[idx_i]->val[i] * v->dy[i];
167  else if(gt == HERMES_AXISYM_Y) axisym_part += wt[i] * const_coeff*spline_coeff->value(B_i) / e->x[i]
168  * u_ext[idx_i]->val[i] * v->dx[i];
169  }
170  return planar_part + axisym_part;
171  }
172 
173  template<typename Scalar>
174  Ord DefaultResidualMagnetostatics<Scalar>::ord(int n, double *wt, Func<Ord> *u_ext[], Func<Ord> *v,
175  Geom<Ord> *e, Func<Ord> **ext) const
176  {
177  Ord planar_part(0);
178  for (int i = 0; i < n; i++)
179  {
180  Ord B_i = sqrt(sqr(u_ext[idx_i]->dx[i]) + sqr(u_ext[idx_i]->dy[i]));
181  planar_part += wt[i] * const_coeff*spline_coeff->value(B_i) *
182  (u_ext[idx_i]->dx[i] * v->dx[i] + u_ext[idx_i]->dy[i] * v->dy[i]);
183  }
184  return planar_part * Ord(order_increase);
185  }
186 
187  // This is to make the form usable in rk_time_step_newton().
188  template<typename Scalar>
189  VectorFormVol<Scalar>* DefaultResidualMagnetostatics<Scalar>::clone() const
190  {
191  return new DefaultResidualMagnetostatics(*this);
192  }
193 
194  template class HERMES_API DefaultJacobianMagnetostatics<double>;
195  template class HERMES_API DefaultResidualMagnetostatics<double>;
196  }
197  }
198 }