25 : k_(k), x0_(x0), u_(u) {}
32 const Real arg = k_*(p-x0_);
33 return Cmplx(cos(arg), sin(arg)) * u_;
36 return (*
this)(p[0], t);
39 return (*
this)(p[0], t);
42 virtual std::ostream&
info(std::ostream&
os)
const {
43 return os <<
"FormulaExpImag1D(" << u_ <<
" * exp(i " << k_ <<
"(x - " << x0_ <<
")))";
57 : k(k), x0(x0), u(u) {}
69 const Real arg = k[0]*(p[0]-x0[0])
72 return Cmplx(cos(arg), sin(arg)) * u;
76 return (*
this)( Real2d(p[0], p[1]), t);
79 virtual std::ostream&
info(std::ostream&
os)
const {
80 return os <<
"FormulaExpImag2D(" << u <<
" * exp(i " << k <<
"(x - " << x0 <<
")))";
95 : k(k), x0(0,0), u(u) {}
109 const Real arg = k[0]*(p[0]-x0[0])
110 + k[1]*(p[1]-x0[1]) ;
111 Cmplx val(cos(arg), sin(arg));
116 return Cmplx(0, (k[0]*p[0] + k[1]*p[1])/
len) * val;
120 return (*
this)( Real2d(p[0], p[1]), t);
123 virtual std::ostream&
info(std::ostream&
os)
const {
124 return os <<
"FormulaExpImag2DRadialDer(" << u <<
" * exp(i " << k <<
"(x - " << x0 <<
")))";
155 const Real arg = k[0]*(p[0]-x0[0])
156 + k[1]*(p[1]-x0[1]) ;
157 Cmplx val(cos(arg), sin(arg));
167 return (*
this)( Real2d(p[0], p[1]), t);
170 virtual std::ostream&
info(std::ostream&
os)
const {
171 return os <<
"FormulaExpImag2DGrad(" << u <<
" * exp(i " << k <<
"(x - " << x0 <<
")))";
197 static const bool OUTER =
true;
198 static const bool INNER =
false;
205 , direction(direction)
213 const Real p,
const Real t = 0.0)
const
222 normal /= normal.
l2();
227 if ( ( normal.
dot(
pp) < 0 && direction == OUTER ) ||
228 ( normal.
dot(
pp) > 0 && direction == INNER )
239 return normal[0] * u[0] + normal[1] * u[1];
254 virtual std::ostream&
info(std::ostream&
os)
const {
255 return os <<
"FormulaNormalOuterSP2D(" << vf <<
", " << center <<
", " << direction <<
")";
285 const Real p,
const Real t = 0.0)
const
287 return A->operator()(elm, p, t) * vf->operator()(elm, p, t);
295 return A->operator()(elm, p, t) * vf->operator()(elm, p, t);
301 return A->operator()(elm, p, t) * vf->operator()(elm, p, t);
304 virtual std::ostream&
info(std::ostream&
os)
const {
305 return os <<
"ComposeFormulaMatVec(A=" << *A <<
", vf="<< *vf <<
")";
331 const Real p,
const Real t = 0.0)
const
333 return vf->operator()(elm, p, t)[index];
339 return vf->operator()(elm, p, t)[index];
345 return vf->operator()(elm, p, t)[index];
348 virtual std::ostream&
info(std::ostream&
os)
const {
349 return os <<
"ComposeFormulaVecEntry(i=" << index <<
", vf="<< *vf <<
")";
360 typedef std::map<int, double> MID;
379 return operator()(elm, p,
px, t);
384 Real2d
px = elm.elemMap(p);
385 return operator()(elm, p,
px, t);
390 Real2d
px = elm.elemMap(p);
391 return operator()(elm, p,
px, t);
394 template <
class RealNd>
396 const Real t=0.0)
const
399 Cmplx k2 = k[0]*k[0] + k[1]*k[1];
401 Cmplx a = coeff_a(elm, p);
402 Cmplx b = coeff_b(elm, p);
404 if (a.real() != 1. || b.real() != 1.) {
405 DEBUGL(pmlHolger_D,
"a , b= " << a <<
", " << b);
406 DEBUGL(pmlHolger_D,
"elemFrm value = " <<
407 (b - a) *
k2 * u_inc->operator()(elm.elemMap(p), t));
413 return (b - a) *
k2 * u_inc->operator()(elm.elemMap(p), t);
424 virtual std::ostream&
info(std::ostream&
os)
const {
425 return os <<
"FormulaIncPlaneWaveSource(" << coeff_a <<
", " << coeff_b <<
")";
438 for(MID::const_iterator it =
attrToEps.begin();
441 coeffs[it->first] = it->second;
445 printf(
"Adding absorbing material (%f %f) for attr %d\n",
447 coeffs[it->first] = -it->second;
448#if __cplusplus >= 201103L
456 printf(
"Adding non-absorbing material (%f %f) for attr %d\n",
457 it->second, 0., it->first);
467 for(MID::const_iterator it =
attrToEps.begin();
470 coeffs[it->first] = 1. / it->second;
473 coeffs[it->first] = -it->second;
474#if __cplusplus >= 201103L
475 coeffs[it->first].imag(1e-3);
478 coeffs[it->first].imag() = 1e-3;
487template<
typename F=Real>
491 ,
const F sigma0 = 5.0,
const Real center=0)
504 Real arg =
fabs(p - center) - offset;
510 Real arg =
fabs(p - center) - offset;
514 return sigma0 * powi(arg , power);
518 return (*
this)(p[0], t);
522 return (*
this)(p[0], t);
524 template<
typename Real>
525 static inline Real powi(
Real x,
int power) {
528 for(
int i = 0; i < power; ++i) {
533 return pow(x, power);
537 virtual std::ostream&
info(std::ostream&
os)
const {
538 return os <<
"FormulaPMLPowerSigma(" << sigma0 <<
" * ( |x - (" << center
539 <<
")| - " << offset <<
")_+^" << power <<
")))";
550template<
typename F=Real>
555 : offset(offset), center(center), power(power), sigma0(sigma0) {}
567 Real arg =
sqrt((p[0]-center[0])*(p[0]-center[0]) +
568 (p[1]-center[1])*(p[1]-center[1])) -offset;
574 Real arg =
sqrt((p[0]-center[0])*(p[0]-center[0]) +
575 (p[1]-center[1])*(p[1]-center[1])) - offset;
578 return sigma0 * powi(arg,power);
582 return (*
this)( Real2d(p[0], p[1]), t);
585 template<
typename Real>
586 static inline Real powi(
Real x,
int power) {
589 for (
int i = 0; i < power; ++i) {
594 return pow(x, power);
598 virtual std::ostream&
info(std::ostream&
os)
const{
599 return os <<
"FormulaPMLPowerSigma2D(" << sigma0 <<
" * ( |x - (" << center[0]
600 <<
"," << center[1] <<
")| - " << offset <<
")_+^" << power <<
")))";
613template<
typename F=Real>
618 : offset(offset), center(center), power(power), sigma0(sigma0) {}
630 Real arg =
sqrt((p[0]-center[0])*(p[0]-center[0]) +
631 (p[1]-center[1])*(p[1]-center[1])) -offset;
637 Real rho =
sqrt((p[0]-center[0])*(p[0]-center[0]) + (p[1]-center[1])*(p[1]-center[1]));
638 Real arg = rho - offset;
641 return sigma0 * powi( arg , power + 1) / (rho) / (power + 1);
645 return (*
this)( Real2d(p[0], p[1]), t);
648 template<
typename Real>
649 static inline Real powi(
Real x,
int power) {
652 for (
int i = 0; i < power; ++i) {
657 return pow(x, power);
661 virtual std::ostream&
info(std::ostream&
os)
const{
662 return os <<
"FormulaPMLPowerSigma2D(" << sigma0 <<
" * ( |x - (" << center[0]
663 <<
"," << center[1] <<
")| - " << offset <<
")_+^" << power <<
")))";
676 enum PMLMode { DXDX, DYDY, IDENT, DX, DY };
694 std::cout <<
"FormulaPMLCart::clone() called " << *
this << std::endl;
701 return operator()(elm, p,
px, t);
705 Real2d
px = elm.elemMap(p);
706 return operator()(elm, p,
px, t);
710 Real2d
px = elm.elemMap(p);
711 return operator()(elm, p,
px, t);
715 return Cmplx(1, (*sigma_x)(x) / omega);
721 return Cmplx(1, (*sigma_y)(y) / omega);
724 template <
class RealNd>
726 const Real t=0.0)
const
729 case DXDX:
return gammaY(
px[1]) / gammaX(
px[0]) * (*coeff_a)(elm, p);
730 case DX:
return gammaY(
px[1]) * (*coeff_a)(elm, p);
731 case DYDY:
return gammaX(
px[0]) / gammaY(
px[1]) * (*coeff_a)(elm, p);
732 case DY:
return gammaX(
px[0]) * (*coeff_a)(elm, p);
733 case IDENT:
return gammaX(
px[0]) * gammaY(
px[1]) * (*coeff_b)(elm, p);
740 virtual std::ostream&
info(std::ostream&
os)
const {
741 return os <<
"FormulaPMLCart(coeffs: "
742 << *coeff_a <<
", " << *coeff_b <<
", sigmas:"
743 << *sigma_x <<
", " << *sigma_y
773 return operator()(elm, p,
px, t);
779 return operator()(elm, p,
px, t);
785 return operator()(elm, p,
px, t);
788 template <
class RealNd>
790 const Real t=0.0)
const
792 if ( sigma_x->inPMLregion(
px[0], t) || sigma_y->inPMLregion(
px[1], t)) {
793 return formula->operator()(elm, p, t);
807 virtual std::ostream&
info(std::ostream&
os)
const {
808 return os <<
"FormulaPMLBoxRestriction(" << formula <<
" :" << *sigma_x <<
", " << sigma_y <<
")))";
836 enum PMLMode { AD1, AD2, AS, IDENT};
869 ,
const Real t=0.0)
const
871 throw std::string(
"FormulaPMLRadia currently only supports 2D!");
875 ,
const Real t=0.0)
const
877 throw std::string(
"FormulaPMLRadia currently only supports 2D!");
881 return Cmplx(1, (*sigma )(p) / omega);
885 return Cmplx(1, (*sigmaB)(p) / omega);
889 return (p[0]*p[0])/(p[0]*p[0]+p[1]*p[1]);
892 Real s_s(Real2d &p)
const{
893 return (p[1]*p[1])/(p[0]*p[0]+p[1]*p[1]);
896 Real s_c(Real2d &p)
const{
897 return (p[0]*p[1])/(p[0]*p[0]+p[1]*p[1]);
902 Real2d
px = elm.elemMap(p);
910 throw std::string(
"FormulaPMLRadia has gone mad!!");
914 virtual std::ostream&
info(std::ostream&
os)
const {
915 return os <<
"FormulaPMLRadia(coeffs: " << coeff_a <<
", " << coeff_b <<
916 ", sigma" << *sigma <<
")";
concepts::Array< F > pow(const concepts::Array< F > &a, const F e)
Returns the power of values in the array a with e.
virtual F operator()(const concepts::ElementWithCell< G > &elm, const Real p, const Real t=0.0) const
virtual ComposeFormulaVecEntry * clone() const
Virtual copy constructor.
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
Real2d jacobian(Real x) const
virtual const Cell & cell() const =0
Returns the cell on which the element is built.
Point< F, dim > & ortho(const Point< F, dim > &a)
F dot(const Point< F, dim > &b) const
Inner product, i.e. for complex arguments: this * conjugate(b)
Real l2() const
Returns the Euclidian norm of the vector.
#define DEBUGL(doit, msg)
#define conceptsThrowSimpleE(msg)
Set< F > makeSet(uint n, const F &first,...)
std::complex< Real > Cmplx
Type for a complex number. It also depends on the setting of Real.