3#ifndef DUNE_PDELAB_LOCALOPERATOR_ELECTRODYNAMIC_HH
4#define DUNE_PDELAB_LOCALOPERATOR_ELECTRODYNAMIC_HH
16#include <dune/pdelab/common/quadraturerules.hh>
17#include <dune/pdelab/localoperator/numericalresidual.hh>
18#include <dune/pdelab/localoperator/pattern.hh>
19#include <dune/pdelab/localoperator/flags.hh>
27 namespace ElectrodynamicImpl {
34 constexpr std::size_t dimOfCurl(std::size_t dimOfSpace)
41 throw std::invalid_argument(
"Only applicable for dimensions 1-3");
45 void jacobianToCurl(FieldVector<RF, 1> &curl,
46 const FieldMatrix<RF, 2, 2> &jacobian)
48 curl[0] = jacobian[1][0] - jacobian[0][1];
51 void jacobianToCurl(FieldVector<RF, 3> &curl,
52 const FieldMatrix<RF, 3, 3> &jacobian)
54 for(
unsigned i = 0; i < 3; ++i)
55 curl[i] = jacobian[(i+2)%3][(i+1)%3] - jacobian[(i+1)%3][(i+2)%3];
70 template<
typename Eps>
80 static constexpr bool doPatternVolume =
true;
81 static constexpr bool doAlphaVolume =
true;
89 eps_(eps), qorder_(qorder)
93 eps_(
std::move(eps)), qorder_(qorder)
99 template<
typename EG,
typename LFS,
typename X,
typename M>
101 const LFS& lfsv, M& mat)
const
104 typename LFS::Traits::FiniteElementType::Traits::Basis::Traits;
107 static constexpr unsigned dimR = BasisTraits::dimRange;
108 static_assert(dimR == 3 || dimR == 2,
"Works only in 2D or 3D");
110 using ctype =
typename EG::Geometry::ctype;
111 using DF =
typename BasisTraits::DomainField;
112 static_assert(std::is_same<ctype, DF>::value,
"Grids ctype and "
113 "Finite Elements DomainFieldType must match");
115 using Range =
typename BasisTraits::Range;
116 std::vector<Range> phi(lfsu.size());
119 for(
const auto &qp : quadratureRule(eg.geometry(), qorder_))
122 lfsu.finiteElement().basis().evaluateFunction(qp.position(),phi);
125 auto factor = qp.weight()
126 * eg.geometry().integrationElement(qp.position())
127 * eps_(eg.entity(), qp.position());
129 for(
unsigned i = 0; i < lfsu.size(); ++i)
130 for(
unsigned j = 0; j < lfsu.size(); ++j)
131 mat.accumulate(lfsv,i,lfsu,j,factor * (phi[i] * phi[j]));
145 Electrodynamic_T<std::decay_t<Eps> >
148 return { std::forward<Eps>(eps), qorder };
162 template<
typename Mu>
172 static constexpr bool doPatternVolume =
true;
173 static constexpr bool doAlphaVolume =
true;
181 mu_(mu), qorder_(qorder)
185 mu_(
std::move(mu)), qorder_(qorder)
191 template<
typename EG,
typename LFS,
typename X,
typename M>
193 const LFS& lfsv, M& mat)
const
195 using ElectrodynamicImpl::dimOfCurl;
196 using ElectrodynamicImpl::jacobianToCurl;
199 typename LFS::Traits::FiniteElementType::Traits::Basis::Traits;
202 static constexpr unsigned dimR = BasisTraits::dimRange;
203 static_assert(dimR == 3 || dimR == 2,
"Works only in 2D or 3D");
205 using ctype =
typename EG::Geometry::ctype;
206 using DF =
typename BasisTraits::DomainField;
207 static_assert(std::is_same<ctype, DF>::value,
"Grids ctype and "
208 "Finite Elements DomainFieldType must match");
210 using Jacobian =
typename BasisTraits::Jacobian;
211 std::vector<Jacobian> J(lfsu.size());
213 using RF =
typename BasisTraits::RangeField;
215 std::vector<Curl> rotphi(lfsu.size());
218 for(
const auto &qp : quadratureRule(eg.geometry(), qorder_))
221 lfsu.finiteElement().basis().evaluateJacobian(qp.position(),J);
222 for(
unsigned i = 0; i < lfsu.size(); ++i)
223 jacobianToCurl(rotphi[i], J[i]);
226 auto factor = qp.weight()
227 * eg.geometry().integrationElement(qp.position())
228 / mu_(eg.entity(), qp.position());
230 for(
unsigned i = 0; i < lfsu.size(); ++i)
231 for(
unsigned j = 0; j < lfsu.size(); ++j)
232 mat.accumulate(lfsv,i,lfsu,j,factor * (rotphi[i] * rotphi[j]));
247 Electrodynamic_S<std::decay_t<Mu> >
250 return { std::forward<Mu>(mu), qorder };
vector space out of a tensor product of fields.
Definition: fvector.hh:95
Contruct matrix S for the Electrodynamic operator.
Definition: electrodynamic.hh:167
void jacobian_volume(const EG &eg, const LFS &lfsu, const X &x, const LFS &lfsv, M &mat) const
Definition: electrodynamic.hh:192
Electrodynamic_S(const Mu &mu, int qorder=2)
Construct an Electrodynamic_S localoperator.
Definition: electrodynamic.hh:180
Construct matrix T for the Electrodynamic operator.
Definition: electrodynamic.hh:75
void jacobian_volume(const EG &eg, const LFS &lfsu, const X &x, const LFS &lfsv, M &mat) const
Definition: electrodynamic.hh:100
Electrodynamic_T(const Eps &eps, int qorder=2)
Construct an Electrodynamic_T localoperator.
Definition: electrodynamic.hh:88
sparsity pattern generator
Definition: pattern.hh:14
Implement alpha_volume() based on jacobian_volume()
Definition: numericalresidual.hh:36
Default flags for all local operators.
Definition: flags.hh:19
Definition of the DUNE_DEPRECATED macro for the case that config.h is not available.
Implements a matrix constructed from a given type representing a field and compile-time given number ...
Implements a vector constructed from a given type representing a field and a compile-time given size.
Electrodynamic_S< std::decay_t< Mu > > makeLocalOperatorEdynS(Mu &&mu, int qorder=2)
construct an Electrodynamic_S operator
Definition: electrodynamic.hh:248
Electrodynamic_T< std::decay_t< Eps > > makeLocalOperatorEdynT(Eps &&eps, int qorder=2)
construct an Electrodynamic_T operator
Definition: electrodynamic.hh:146
Dune namespace.
Definition: alignedallocator.hh:11