pml_formula.h

Go to the documentation of this file.
1 #pragma once
2 
3 #include <iostream>
4 #include <memory>
5 #include "stdio.h"
6 #include "basics.hh"
8 #include "formula/formula.hh"
9 #include "geometry/formula.hh"
10 #include "hp2D.hh"
11 
12 //TODO: properly expand this list
13 
14 #define pmlHolger_D 0
15 
16 namespace concepts {
17 
18 // ******************************************************** FormulaExpImag1D **
19 
22 class FormulaExpImag1D : public concepts::Formula<Cmplx> {
23 public:
24  FormulaExpImag1D(const Real k, const Cmplx u = 1.0, Real x0 = 0.0)
25  : k_(k), x0_(x0), u_(u) {}
26 
27  virtual FormulaExpImag1D* clone() const {
28  return new FormulaExpImag1D(k_, u_, x0_);
29  }
30 
31  virtual Cmplx operator() (const Real p, const Real t = 0.0) const {
32  const Real arg = k_*(p-x0_);
33  return Cmplx(cos(arg), sin(arg)) * u_;
34  }
35  virtual Cmplx operator() (const concepts::Real2d& p, const Real t = 0.0) const {
36  return (*this)(p[0], t);
37  }
38  virtual Cmplx operator() (const concepts::Real3d& p, const Real t = 0.0) const {
39  return (*this)(p[0], t);
40  }
41 protected:
42  virtual std::ostream& info(std::ostream& os) const {
43  return os << "FormulaExpImag1D(" << u_ << " * exp(i " << k_ << "(x - " << x0_ << ")))";
44  }
45 private:
46  const Real k_, x0_;
47  const Cmplx u_;
48 };
49 
50 // ******************************************************** FormulaExpImag2D **
51 
54 class FormulaExpImag2D : public concepts::Formula<Cmplx> {
55 public:
56  FormulaExpImag2D(const Real2d k, const Cmplx u = 1.0, Real2d x0 = 0.0)
57  : k(k), x0(x0), u(u) {}
58 
59  virtual FormulaExpImag2D* clone() const {
60  return new FormulaExpImag2D(k, u, x0);
61  }
62 
63  virtual Cmplx operator() (const Real p, const Real t = 0.0) const {
64  conceptsThrowSimpleE("FormulaExpImag2D currently only supports 2D!"); assert(false);
65  }
66 
67  virtual Cmplx operator() (const concepts::Real2d& p, const Real t = 0.0) const
68  {
69  const Real arg = k[0]*(p[0]-x0[0])
70  + k[1]*(p[1]-x0[1]) ;
71  //cout << "e^{i k x}: " << p << ", " << Cmplx(cos(arg), sin(arg)) * u << endl;
72  return Cmplx(cos(arg), sin(arg)) * u;
73  }
74 
75  virtual Cmplx operator() (const concepts::Real3d& p, const Real t = 0.0) const {
76  return (*this)( Real2d(p[0], p[1]), t);
77  }
78 protected:
79  virtual std::ostream& info(std::ostream& os) const {
80  return os << "FormulaExpImag2D(" << u << " * exp(i " << k << "(x - " << x0 << ")))";
81  }
82 public:
83  const Real2d k, x0;
84  const Cmplx u;
85 };
86 
87 // *********************************************** FormulaExpImag2DRadialDer **
88 
92 public:
93  //FormulaExpImag2DRadialDer(const Real2d k, const Cmplx u = 1.0, Real2d x0 = Real2d(0,0))
94  FormulaExpImag2DRadialDer(const Real2d k, const Cmplx u = 1.0)
95  : k(k), x0(0,0), u(u) {}
96 
97  virtual FormulaExpImag2DRadialDer* clone() const {
98  return new FormulaExpImag2DRadialDer(*this);
99  }
100 
101  virtual Cmplx operator() (const Real p, const Real t = 0.0) const {
102  conceptsThrowSimpleE("FormulaExpImag2DRadialDer currently only supports 2D!"); assert(false);
103  }
104 
105  virtual Cmplx operator() (const concepts::Real2d& p, const Real t = 0.0) const
106  {
107  const Cmplx imag(0,1);
108 
109  const Real arg = k[0]*(p[0]-x0[0])
110  + k[1]*(p[1]-x0[1]) ;
111  Cmplx val(cos(arg), sin(arg));
112  val *= u;
113 
114  const Real len = sqrt( p[0]*p[0] + p[1]*p[1] );
115 
116  return Cmplx(0, (k[0]*p[0] + k[1]*p[1])/len) * val;
117  }
118 
119  virtual Cmplx operator() (const concepts::Real3d& p, const Real t = 0.0) const {
120  return (*this)( Real2d(p[0], p[1]), t);
121  }
122 protected:
123  virtual std::ostream& info(std::ostream& os) const {
124  return os << "FormulaExpImag2DRadialDer(" << u << " * exp(i " << k << "(x - " << x0 << ")))";
125  }
126 public:
127  const Real2d k, x0;
128  const Cmplx u;
129 };
130 
131 // **************************************************** FormulaExpImag2DGrad **
132 
136 class FormulaExpImag2DGrad : public concepts::Formula< concepts::Point<Cmplx, 2> >
137 {
138 public:
139  FormulaExpImag2DGrad(const Real2d k, const Cmplx u = 1.0, Real2d x0 = Real2d(0,0))
140  : k(k), x0(x0), u(u)
141  { }
142 
143  virtual FormulaExpImag2DGrad* clone() const {
144  return new FormulaExpImag2DGrad(k, u, x0);
145  }
146 
147  virtual Cmplx2d operator() (const Real p, const Real t = 0.0) const {
148  conceptsThrowSimpleE("FormulaExpImag2DGrad currently only supports 2D!"); assert(false);
149  }
150 
151  virtual Cmplx2d operator() (const concepts::Real2d& p, const Real t = 0.0) const
152  {
153  const Cmplx imag(0,1);
154 
155  const Real arg = k[0]*(p[0]-x0[0])
156  + k[1]*(p[1]-x0[1]) ;
157  Cmplx val(cos(arg), sin(arg));
158  val *= u;
159 
160  //const Real len = sqrt( p[0]*p[0] + p[1]*p[1] );
161 
162  return Cmplx2d( Cmplx(0, k[0])*val, Cmplx(0, k[1])*val );
163  }
164 
165  virtual Cmplx2d operator() (const concepts::Real3d& p, const Real t = 0.0) const {
166  //conceptsThrowSimpleE("FormulaExpImag2DGrad currently only supports 2D!"); assert(false);
167  return (*this)( Real2d(p[0], p[1]), t);
168  }
169 protected:
170  virtual std::ostream& info(std::ostream& os) const {
171  return os << "FormulaExpImag2DGrad(" << u << " * exp(i " << k << "(x - " << x0 << ")))";
172  }
173 public:
174  const Real2d k, x0;
175  const Cmplx u;
176 };
177 
178 
179 // ************************************************** FormulaNormalOuterSP2D **
180 
193 template< class F >
195 {
196 public:
197  static const bool OUTER = true;
198  static const bool INNER = false;
199 
202  Real2d center = Real2d(0,0), bool direction = OUTER)
203  : vf(vf)
204  , center(center)
206  { }
207 
208  virtual FormulaNormalOuterSP2D* clone() const {
209  return new FormulaNormalOuterSP2D(*this);
210  }
211 
213  const Real p, const Real t = 0.0) const
214  {
215  const concepts::Cell& c = elm.cell();
216 
217  const Edge2d* cc = dynamic_cast<const concepts::Edge2d*> (&c);
218  assert(cc);
219 
220  Real2d normal = cc->jacobian(p);
221  normal.ortho();
222  normal /= normal.l2();
223 
224  Real2d pp = elm.elemMap(p); //pp /= pp.l2();
225  pp -= center;
226 
227  if ( ( normal.dot(pp) < 0 && direction == OUTER ) ||
228  ( normal.dot(pp) > 0 && direction == INNER )
229  )
230  {
231  normal *= -1;
232  }
233 
234  const concepts::Point<F, 2> u = vf.operator()(elm, p, t);
235 
236  //std::cout << "normal " << elm.elemMap(p) << ": " << normal
237  // << "SP: " << normal[0] * u[0] + normal[1] * u[1] << "center: " << center << std::endl;
238 
239  return normal[0] * u[0] + normal[1] * u[1];
240  }
241 
243  const concepts::Real2d& p, const Real t = 0.0) const
244  {
245  conceptsThrowSimpleE("FormulaNormalOuterSP2D currently only supports 1D!"); assert(false);
246  }
247 
249  const concepts::Real3d& p, const Real t = 0.0) const {
250  conceptsThrowSimpleE("FormulaNormalOuterSP2D currently only supports 1D!"); assert(false);
251  //return (*this)( Real2d(p[0], p[1]), t);
252  }
253 protected:
254  virtual std::ostream& info(std::ostream& os) const {
255  return os << "FormulaNormalOuterSP2D(" << vf << ", " << center << ", " << direction << ")";
256  }
257 public:
260  bool direction;
261 };
262 
263 // **************************************************** ComposeFormulaMatVec **
264 
268 template< class F, uint DIM, typename G = typename Realtype<F>::type>
269 class ComposeFormulaMatVec : public concepts::ElementFormula< concepts::Point<F, DIM>, G >
270 {
271 public:
275  )
276  : A(A)
277  , vf(vf)
278  { }
279 
280  virtual ComposeFormulaMatVec* clone() const {
281  return new ComposeFormulaMatVec(*this);
282  }
283 
285  const Real p, const Real t = 0.0) const
286  {
287  return A->operator()(elm, p, t) * vf->operator()(elm, p, t);
288  }
289 
291  const concepts::Real2d& p, const Real t = 0.0) const
292  {
293  //cout << "p: " << p << A->operator()(elm, p, t) << vf->operator()(elm, p, t)
294  // << " = " << A->operator()(elm, p, t) * vf->operator()(elm, p, t) << endl;
295  return A->operator()(elm, p, t) * vf->operator()(elm, p, t);
296  }
297 
299  const concepts::Real3d& p, const Real t = 0.0) const
300  {
301  return A->operator()(elm, p, t) * vf->operator()(elm, p, t);
302  }
303 protected:
304  virtual std::ostream& info(std::ostream& os) const {
305  return os << "ComposeFormulaMatVec(A=" << *A << ", vf="<< *vf << ")";
306  }
307 public:
310 };
311 
312 // *************************************************** ComposeFormulaVecEntry **
313 
314 template< class F, uint DIM, typename G = typename Realtype<F>::type>
316 {
317 public:
320  int index
321  )
322  : vf(vf)
323  , index(index)
324  { }
325 
326  virtual ComposeFormulaVecEntry* clone() const {
327  return new ComposeFormulaVecEntry(*this);
328  }
329 
331  const Real p, const Real t = 0.0) const
332  {
333  return vf->operator()(elm, p, t)[index];
334  }
335 
337  const concepts::Real2d& p, const Real t = 0.0) const
338  {
339  return vf->operator()(elm, p, t)[index];
340  }
341 
343  const concepts::Real3d& p, const Real t = 0.0) const
344  {
345  return vf->operator()(elm, p, t)[index];
346  }
347 protected:
348  virtual std::ostream& info(std::ostream& os) const {
349  return os << "ComposeFormulaVecEntry(i=" << index << ", vf="<< *vf << ")";
350  }
351 public:
353  int index;
354 };
355 
356 // *********************************************** FormulaIncPlaneWaveSource **
357 
359 public:
360  typedef std::map<int, double> MID;
361 
364 /* RCP< PiecewiseConstFormula<Cmplx> > coeff_a */
365 /* , RCP< PiecewiseConstFormula<Cmplx> > coeff_b */
367  : coeff_a(coeff_a) // CAN BE IMPROVED
368  , coeff_b(coeff_b)
369  , u_inc(u_inc)
370  { }
371 
372  virtual FormulaIncPlaneWaveSource* clone() const {
373  return new FormulaIncPlaneWaveSource(*this);
374  }
375 
376  virtual Cmplx operator() (const ElementWithCell< Real > &elm, const Real3d &p, const Real t=0.0) const
377  {
378  Real2d px = elm.elemMap(p);
379  return operator()(elm, p, px, t);
380  }
381 
382  virtual Cmplx operator() (const ElementWithCell< Real > &elm, const Real2d &p, const Real t=0.0) const
383  {
384  Real2d px = elm.elemMap(p);
385  return operator()(elm, p, px, t);
386  }
387 
388  virtual Cmplx operator() (const ElementWithCell< Real > &elm, const Real p, const Real t=0.0) const
389  {
390  Real2d px = elm.elemMap(p);
391  return operator()(elm, p, px, t);
392  }
393 
394  template <class RealNd>
395  Cmplx operator() (const ElementWithCell< Real > &elm, const RealNd &p, Real2d px,
396  const Real t=0.0) const
397  {
398  Real2d k = u_inc->k;
399  Cmplx k2 = k[0]*k[0] + k[1]*k[1]; // (can be complex)
400  //Attribute atr = elm.cell().connector().attrib();
401  Cmplx a = coeff_a(elm, p);
402  Cmplx b = coeff_b(elm, p);
403 
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));
408  } else {
409  //DEBUGL(1, "a,b,b-a = " << a << b << b-a);
410  }
411  // NOTE: the term k2=omega^2 is not contained in coeff_b
412  // (difference to the documentation)
413  return (b - a) * k2 * u_inc->operator()(elm.elemMap(p), t);
414  //return (b - a * k2) * u_inc->operator()(elm.elemMap(p), t);
415  }
416 
418  const MID& attToEps);
419 
421  const MID& attToEps);
422 
423 protected:
424  virtual std::ostream& info(std::ostream& os) const {
425  return os << "FormulaIncPlaneWaveSource(" << coeff_a << ", " << coeff_b << ")";
426  }
427 private:
429 /* RCP< concepts::ElementFormula<Cmplx> > coeff_a; */
430 /* RCP< concepts::ElementFormula<Cmplx> > coeff_b; */
432 };
433 
435  const MID& attrToEps)
436 {
437  PiecewiseConstFormula<Cmplx> coeffs(1.);
438  for(MID::const_iterator it = attrToEps.begin();
439  it != attrToEps.end(); ++it)
440  {
441  coeffs[it->first] = it->second;
442 
443  if(it->second < 0) {
444  double abs_fact = 1e-2;
445  printf("Adding absorbing material (%f %f) for attr %d\n",
446  -it->second, abs_fact, it->first);
447  coeffs[it->first] = -it->second;
448 #if __cplusplus >= 201103L
449  coeffs[it->first].imag(abs_fact);
450 #else
451  // imag(coeffs[it->first]) = abs_fact;
452  coeffs[it->first].imag() = abs_fact;
453 #endif
454 
455  } else {
456  printf("Adding non-absorbing material (%f %f) for attr %d\n",
457  it->second, 0., it->first);
458  }
459  }
460  return coeffs;
461 }
462 
464  const MID& attrToEps)
465 {
466  PiecewiseConstFormula<Cmplx> coeffs(1.);
467  for(MID::const_iterator it = attrToEps.begin();
468  it != attrToEps.end(); ++it)
469  {
470  coeffs[it->first] = 1. / it->second;
471 
472  if(it->second < 0) {
473  coeffs[it->first] = -it->second;
474 #if __cplusplus >= 201103L
475  coeffs[it->first].imag(1e-3);
476 #else
477  // imag(coeffs[it->first]) = 1e-3;
478  coeffs[it->first].imag() = 1e-3;
479 #endif
480  }
481  }
482  return coeffs;
483 }
484 
485 // **************************************************** FormulaPMLPowerSigma **
486 
487 template<typename F=Real>
489  public:
491  , const F sigma0 = 5.0, const Real center=0)
492  : offset(offset)
493  , center(center)
494  , power(power)
495  , sigma0(sigma0)
496  {}
497 
498  virtual FormulaPMLPowerSigma* clone() const {
500  }
501 
502  bool inPMLregion(const concepts::Real p, const Real t = 0.0)
503  {
504  Real arg = fabs(p - center) - offset;
505 
506  return arg >= 0;
507  }
508 
509  virtual F operator() (const Real p, const Real t = 0.0) const {
510  Real arg = fabs(p - center) - offset;
511  //printf("sigma(%f), arg = %f, cen %f, off %f\n", p, arg, center, offset);
512  if (arg < 0)
513  return F(0);
514  return sigma0 * powi(arg , power);
515  }
516 
517  virtual F operator() (const concepts::Real2d& p, const Real t = 0.0) const {
518  return (*this)(p[0], t);
519  }
520 
521  virtual F operator() (const concepts::Real3d& p, const Real t = 0.0) const {
522  return (*this)(p[0], t);
523  }
524  template<typename Real>
525  static inline Real powi(Real x, int power) {
526 #if 1
527  Real res(1);
528  for(int i = 0; i < power; ++i) {
529  res *= x;
530  }
531  return res;
532 #else
533  return pow(x, power);
534 #endif
535  }
536  protected:
537  virtual std::ostream& info(std::ostream& os) const {
538  return os << "FormulaPMLPowerSigma(" << sigma0 << " * ( |x - (" << center
539  << ")| - " << offset << ")_+^" << power << ")))";
540  }
541  private:
542  const Real offset;
543  const Real center;
544  const int power;
545  const F sigma0;
546 };
547 
548 // ************************************************** FormulaPMLPowerSigma2D **
549 
550 template<typename F=Real>
552  public:
554  const F sigma0 = 5.0, const Real2d& center=Real2d(0,0))
556 
557  virtual FormulaPMLPowerSigma2D* clone() const {
559  }
560 
561  virtual F operator() (const Real p, const Real t = 0.0) const {
562  conceptsThrowSimpleE("FormulaPMLPowerSigma2D currently only supports 2D!"); assert(false);
563  }
564 
565  bool inPMLregion(const concepts::Real2d& p, const Real t = 0.0)
566  {
567  Real arg = sqrt((p[0]-center[0])*(p[0]-center[0]) +
568  (p[1]-center[1])*(p[1]-center[1])) -offset;
569 
570  return arg >= 0;
571  }
572 
573  virtual F operator() (const concepts::Real2d& p, const Real t = 0.0) const {
574  Real arg = sqrt((p[0]-center[0])*(p[0]-center[0]) +
575  (p[1]-center[1])*(p[1]-center[1])) - offset;
576  if (arg<0)
577  return F(0);
578  return sigma0 * powi(arg,power);
579  }
580 
581  virtual F operator() (const concepts::Real3d& p, const Real t = 0.0) const {
582  return (*this)( Real2d(p[0], p[1]), t);
583  }
584 
585  template<typename Real>
586  static inline Real powi(Real x, int power) {
587 #if 1
588  Real res(1);
589  for (int i = 0; i < power; ++i) {
590  res *= x;
591  }
592  return res;
593 #else
594  return pow(x, power);
595 #endif
596  }
597  protected:
598  virtual std::ostream& info(std::ostream& os) const{
599  return os << "FormulaPMLPowerSigma2D(" << sigma0 << " * ( |x - (" << center[0]
600  << "," << center[1] << ")| - " << offset << ")_+^" << power << ")))";
601  }
602  private:
603  const Real offset;
604  const Real2d& center;
605  const int power;
606  const F sigma0;
607 };
608 
609 // ************************************************* FormulaPMLPowerSigmaB2D **
610 
611 // Sigma bar 2D for Ridia case, see Collino & Monk
612 
613 template<typename F=Real>
615  public:
617  const F sigma0 = 5.0, const Real2d& center=Real2d(0,0))
619 
620  virtual FormulaPMLPowerSigmaB2D* clone() const {
622  }
623 
624  virtual F operator() (const Real p, const Real t = 0.0) const {
625  conceptsThrowSimpleE("FormulaPMLPowerSigma Bar 2D currently only supports 2D!"); assert(false);
626  }
627 
628  bool inPMLregion(const concepts::Real2d& p, const Real t = 0.0)
629  {
630  Real arg = sqrt((p[0]-center[0])*(p[0]-center[0]) +
631  (p[1]-center[1])*(p[1]-center[1])) -offset;
632 
633  return arg >= 0;
634  }
635 
636  virtual F operator() (const concepts::Real2d& p, const Real t = 0.0) const {
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;
639  if (arg<0)
640  return F(0);
641  return sigma0 * powi( arg , power + 1) / (rho) / (power + 1);
642  }
643 
644  virtual F operator() (const concepts::Real3d& p, const Real t = 0.0) const {
645  return (*this)( Real2d(p[0], p[1]), t);
646  }
647 
648  template<typename Real>
649  static inline Real powi(Real x, int power) {
650 #if 1
651  Real res(1);
652  for (int i = 0; i < power; ++i) {
653  res *= x;
654  }
655  return res;
656 #else
657  return pow(x, power);
658 #endif
659  }
660  protected:
661  virtual std::ostream& info(std::ostream& os) const{
662  return os << "FormulaPMLPowerSigma2D(" << sigma0 << " * ( |x - (" << center[0]
663  << "," << center[1] << ")| - " << offset << ")_+^" << power << ")))";
664  }
665  private:
666  const Real offset;
667  const Real2d& center;
668  const int power;
669  const F sigma0;
670 };
671 
672 // ********************************************************** FormulaPMLCart **
673 
674 class FormulaPMLCart : public ElementFormula<Cmplx> {
675  public:
676  enum PMLMode { DXDX, DYDY, IDENT, DX, DY };
677 
682  , PMLMode mode
683  , double omega
684  )
685  : coeff_a(coeff_a)
686  , coeff_b(coeff_b)
687  , sigma_x(sigma_x)
688  , sigma_y(sigma_y)
689  , mode(mode)
690  , omega(omega)
691  {}
692 
693  virtual FormulaPMLCart* clone() const {
694  std::cout << "FormulaPMLCart::clone() called " << *this << std::endl;
695  return new FormulaPMLCart(*this);
696  }
697 
698  virtual Cmplx operator() (const ElementWithCell< Real > &elm, const Real3d &p, const Real t=0.0) const
699  {
700  Real2d px = elm.elemMap(p);
701  return operator()(elm, p, px, t);
702  }
703  virtual Cmplx operator() (const ElementWithCell< Real > &elm, const Real2d &p, const Real t=0.0) const
704  {
705  Real2d px = elm.elemMap(p);
706  return operator()(elm, p, px, t);
707  }
708  virtual Cmplx operator() (const ElementWithCell< Real > &elm, const Real p, const Real t=0.0) const
709  {
710  Real2d px = elm.elemMap(p);
711  return operator()(elm, p, px, t);
712  }
713 
714  Cmplx gammaX(Real x) const {
715  return Cmplx(1, (*sigma_x)(x) / omega);
716  }
717 
718  Cmplx gammaY(Real y) const {
719  //std::cout << "gamma_y(" << y << ") " << Cmplx(1, (*sigma_y)(y) / omega) << std::endl;
720 
721  return Cmplx(1, (*sigma_y)(y) / omega);
722  }
723 
724  template <class RealNd>
725  inline Cmplx operator() (const ElementWithCell< Real > &elm, const RealNd &p, Real2d px,
726  const Real t=0.0) const
727  {
728  switch(mode) {
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);
734  }
735  conceptsThrowSimpleE("FormulaPMLCart has gone mad!"); assert(false);
736  }
737 
738 
739  protected:
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
744  << ")";
745  }
746  private:
752  double omega;
753 };
754 
755 // ************************************************ FormulaPMLBoxRestriction **
756 
757 template <class F, typename G = typename Realtype<F>::type>
759 public:
764  )
765  : sigma_x(sigma_x)
766  , sigma_y(sigma_y)
767  , formula(formula)
768  { }
769 
770  virtual F operator() (const ElementWithCell< Real > &elm, const Real3d &p, const Real t=0.0) const
771  {
772  Real2d px = elm.elemMap(p);
773  return operator()(elm, p, px, t);
774  }
775 
776  virtual F operator() (const ElementWithCell< Real > &elm, const Real2d &p, const Real t=0.0) const
777  {
778  Real2d px = elm.elemMap(p);
779  return operator()(elm, p, px, t);
780  }
781 
782  virtual F operator() (const ElementWithCell< Real > &elm, const Real p, const Real t=0.0) const
783  {
784  Real2d px = elm.elemMap(p);
785  return operator()(elm, p, px, t);
786  }
787 
788  template <class RealNd>
789  F operator() (const ElementWithCell< Real > &elm, const RealNd &p, Real2d px,
790  const Real t=0.0) const
791  {
792  if ( sigma_x->inPMLregion(px[0], t) || sigma_y->inPMLregion(px[1], t)) {
793  return formula->operator()(elm, p, t);
794  } else {
795  //cout << "out: " << px << p << formula->operator()(elm, p, t) << endl;
796 
797  return F(0);
798  //return formula->operator()(elm, p, t);
799  }
800  }
801 
802  virtual FormulaPMLBoxRestriction* clone() const {
803  return new FormulaPMLBoxRestriction(*this);
804  }
805 
806 protected:
807  virtual std::ostream& info(std::ostream& os) const {
808  return os << "FormulaPMLBoxRestriction(" << formula << " :" << *sigma_x << ", " << sigma_y << ")))";
809  }
810 private:
814 };
815 
816 // ******************************************************* FormulaPMLRadia **
817 
834 class FormulaPMLRadia : public ElementFormula<Cmplx> {
835  public:
836  enum PMLMode { AD1, AD2, AS, IDENT};
837 
853  , PMLMode mode
854  , double omega
855  )
856  : coeff_a(coeff_a)
857  , coeff_b(coeff_b)
858  , sigma(sigma)
859  , sigmaB(sigmaB)
860  , mode(mode)
861  , omega(omega)
862  {}
863 
864  virtual FormulaPMLRadia* clone() const {
865  return new FormulaPMLRadia(*this);
866  }
867 
868  virtual Cmplx operator() (const ElementWithCell< Real > &elm, const Real3d &p
869  , const Real t=0.0) const
870  {
871  throw std::string("FormulaPMLRadia currently only supports 2D!");
872  }
873 
874  virtual Cmplx operator() (const ElementWithCell< Real > &elm, const Real p
875  , const Real t=0.0) const
876  {
877  throw std::string("FormulaPMLRadia currently only supports 2D!");
878  }
880  Cmplx gamma(Real2d &p) const{
881  return Cmplx(1, (*sigma )(p) / omega);
882  }
884  Cmplx gammaB(Real2d &p) const{
885  return Cmplx(1, (*sigmaB)(p) / omega);
886  }
887 
888  Real c_c(Real2d &p) const{
889  return (p[0]*p[0])/(p[0]*p[0]+p[1]*p[1]); //\f$\cos^2\theta\f$
890  }
891 
892  Real s_s(Real2d &p) const{
893  return (p[1]*p[1])/(p[0]*p[0]+p[1]*p[1]); //\f$\sin^2\theta\f$
894  }
895 
896  Real s_c(Real2d &p) const{
897  return (p[0]*p[1])/(p[0]*p[0]+p[1]*p[1]); //\f$\cos\theta*\sin\theta\f$
898  }
899 
900  virtual Cmplx operator() (const ElementWithCell< Real > &elm, const Real2d &p, const Real t = 0.0) const
901  {
902  Real2d px = elm.elemMap(p);
903 
904  switch(mode) {
905  case AD1: return (gammaB(px)/gamma(px)*c_c(px) + gamma(px)/gammaB(px)*s_s(px)) * (coeff_a)(elm, p);
906  case AD2: return (gammaB(px)/gamma(px)*s_s(px) + gamma(px)/gammaB(px)*c_c(px)) * (coeff_a)(elm, p);
907  case AS : return ((gammaB(px)/gamma(px) - gamma(px)/gammaB(px))*s_c(px)) * (coeff_a)(elm, p);
908  case IDENT: return gamma(px) * gammaB(px) * (coeff_b)(elm, p);
909  }
910  throw std::string("FormulaPMLRadia has gone mad!!");
911  }
912 
913  protected:
914  virtual std::ostream& info(std::ostream& os) const {
915  return os << "FormulaPMLRadia(coeffs: " << coeff_a << ", " << coeff_b <<
916  ", sigma" << *sigma << ")";
917  }
918  private:
929  double omega;
930 };
931 
932 } // namespace concepts
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
Definition: pml_formula.h:424
Basic class for a 2D or 3D map.
virtual ComposeFormulaMatVec * clone() const
Virtual constructor.
Definition: pml_formula.h:280
virtual std::ostream & info(std::ostream &os) const
Definition: pml_formula.h:42
#define pmlHolger_D
Definition: pml_formula.h:14
FormulaExpImag2DGrad(const Real2d k, const Cmplx u=1.0, Real2d x0=Real2d(0, 0))
Definition: pml_formula.h:139
virtual F operator()(const concepts::ElementWithCell< Real > &elm, const Real p, const Real t=0.0) const
Definition: pml_formula.h:212
PMLMode mode
The choosen mode.
Definition: pml_formula.h:927
virtual FormulaExpImag2DGrad * clone() const
Definition: pml_formula.h:143
#define conceptsThrowSimpleE(msg)
Throws a equivalent to conceptsAssert(false, exc)
Definition: exceptions.hh:411
Class for the function for radial PML, see INRIA report of Collino & Monk.
Definition: pml_formula.h:551
Cmplx gammaX(Real x) const
Definition: pml_formula.h:714
virtual std::ostream & info(std::ostream &os) const
Definition: pml_formula.h:537
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
Definition: pml_formula.h:914
Class for PML in polar coordinates.
Definition: pml_formula.h:834
Piecewise constant function defined by the attribute of a cell.
Definition: formula.hh:84
RCP< concepts::FormulaExpImag2D > u_inc
Definition: pml_formula.h:431
Formula for radial derivative of .
Definition: pml_formula.h:91
virtual F operator()(const concepts::ElementWithCell< G > &elm, const Real p, const Real t=0.0) const
Definition: pml_formula.h:330
FormulaExpImag2DRadialDer(const Real2d k, const Cmplx u=1.0)
Definition: pml_formula.h:94
Computes the scalar product <n, vf> of the normal n with a vector valued formula vf,...
Definition: pml_formula.h:195
FormulaPMLPowerSigma2D(const Real offset, const int power=2, const F sigma0=5.0, const Real2d &center=Real2d(0, 0))
Definition: pml_formula.h:553
bool inPMLregion(const concepts::Real2d &p, const Real t=0.0)
Definition: pml_formula.h:565
virtual F operator()(const Real p, const Real t=0.0) const
Application operator.
Definition: pml_formula.h:509
Point< Real, 2 > Real2d
concepts::Real arg(const concepts::Point< concepts::Real, 2 > &p)
Returns the phase angle of a real 2D vector.
const ElementFormulaContainer< Cmplx > coeff_a
globally defined material, piecewise constant dielectric
Definition: pml_formula.h:920
A cell in a mesh consist of topological information (neighbours, connectivity, orientation) and geome...
Definition: cell.hh:39
RCP< concepts::Formula< Real > > sigmaB
sigma bar function, given in the above article page 2067, the average of sigma
Definition: pml_formula.h:925
Real3d elemMap(const Real coord_local) const
Definition: element.hh:86
concepts::ElementFormulaContainer< Cmplx > coeff_a
Definition: pml_formula.h:428
Interface for a formula.
Definition: lform.hh:18
FormulaPMLPowerSigma(const Real offset, const int power=2, const F sigma0=5.0, const Real center=0)
Definition: pml_formula.h:490
virtual Cmplx operator()(const Real p, const Real t=0.0) const
Application operator.
Definition: pml_formula.h:31
A 1D cell: edge in 2D.
Definition: cell1D.hh:189
Real2d jacobian(Real x) const
Returns the Jacobian.
virtual FormulaExpImag2D * clone() const
Definition: pml_formula.h:59
virtual concepts::Point< F, DIM > operator()(const concepts::ElementWithCell< G > &elm, const Real p, const Real t=0.0) const
Definition: pml_formula.h:284
ComposeFormulaMatVec(RCP< const ElementFormula< concepts::Mapping< F, DIM >, G > > A, RCP< const ElementFormula< concepts::Point< F, DIM >, G > > vf)
Definition: pml_formula.h:272
virtual FormulaPMLBoxRestriction * clone() const
Virtual constructor.
Definition: pml_formula.h:802
FormulaIncPlaneWaveSource(ElementFormulaContainer< Cmplx > coeff_a, ElementFormulaContainer< Cmplx > coeff_b, RCP< concepts::FormulaExpImag2D > u_inc)
Definition: pml_formula.h:362
std::map< int, double > MID
Definition: pml_formula.h:360
virtual std::ostream & info(std::ostream &os) const
Definition: pml_formula.h:123
RCP< concepts::ElementFormula< F > > formula
Definition: pml_formula.h:813
#define DEBUGL(doit, msg)
virtual FormulaPMLRadia * clone() const
Virtual constructor.
Definition: pml_formula.h:864
virtual FormulaNormalOuterSP2D * clone() const
Virtual constructor.
Definition: pml_formula.h:208
RCP< const concepts::ElementFormula< Cmplx > > coeff_b
Definition: pml_formula.h:748
Real c_c(Real2d &p) const
Definition: pml_formula.h:888
virtual F operator()(const Real p, const Real t=0.0) const
Application operator.
Definition: pml_formula.h:561
double omega
The wave number.
Definition: pml_formula.h:929
bool inPMLregion(const concepts::Real2d &p, const Real t=0.0)
Definition: pml_formula.h:628
virtual std::ostream & info(std::ostream &os) const
Definition: pml_formula.h:661
FormulaPMLPowerSigmaB2D(const Real offset, const int power=2, const F sigma0=5.0, const Real2d &center=Real2d(0, 0))
Definition: pml_formula.h:616
RCP< concepts::Formula< Real > > sigma
sigma function, which takes the general form of
Definition: pml_formula.h:923
FormulaPMLBoxRestriction(RCP< concepts::FormulaPMLPowerSigma< Real > > sigma_x, RCP< concepts::FormulaPMLPowerSigma< Real > > sigma_y, RCP< concepts::ElementFormula< F, G > > formula)
Definition: pml_formula.h:760
virtual Cmplx2d operator()(const Real p, const Real t=0.0) const
Application operator.
Definition: pml_formula.h:147
RCP< concepts::Formula< Real > > sigma_x
Definition: pml_formula.h:749
virtual Cmplx operator()(const Real p, const Real t=0.0) const
Application operator.
Definition: pml_formula.h:63
FormulaPMLCart(RCP< const ElementFormula< Cmplx > > coeff_a, RCP< const ElementFormula< Cmplx > > coeff_b, RCP< concepts::Formula< Real > > sigma_x, RCP< concepts::Formula< Real > > sigma_y, PMLMode mode, double omega)
Definition: pml_formula.h:678
Real s_c(Real2d &p) const
Definition: pml_formula.h:896
Real l2() const
Returns the Euclidian norm of the vector.
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
Definition: pml_formula.h:348
Class for Cartesian PML, see Collino & Monk.
Definition: pml_formula.h:674
virtual Cmplx operator()(const ElementWithCell< Real > &elm, const Real3d &p, const Real t=0.0) const
Definition: pml_formula.h:698
virtual std::ostream & info(std::ostream &os) const
Definition: pml_formula.h:170
RCP< concepts::FormulaPMLPowerSigma< Real > > sigma_x
Definition: pml_formula.h:811
Interface for a formula defined element by element.
Real s_s(Real2d &p) const
Definition: pml_formula.h:892
concepts::ElementFormulaContainer< Cmplx > coeff_b
Definition: pml_formula.h:428
FormulaExpImag1D(const Real k, const Cmplx u=1.0, Real x0=0.0)
Definition: pml_formula.h:24
virtual F operator()(const ElementWithCell< Real > &elm, const Real3d &p, const Real t=0.0) const
Definition: pml_formula.h:770
F dot(const Point< F, dim > &b) const
Inner product, i.e. for complex arguments: this * conjugate(b)
static PiecewiseConstFormula< Cmplx > genTMCoeff(const MID &attToEps)
Definition: pml_formula.h:434
virtual FormulaIncPlaneWaveSource * clone() const
Virtual constructor.
Definition: pml_formula.h:372
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
Definition: pml_formula.h:304
ComposeFormulaVecEntry(RCP< const ElementFormula< concepts::Point< F, DIM >, G > > vf, int index)
Definition: pml_formula.h:318
virtual ComposeFormulaVecEntry * clone() const
Virtual constructor.
Definition: pml_formula.h:326
static Real powi(Real x, int power)
Definition: pml_formula.h:525
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
Definition: pml_formula.h:254
FormulaNormalOuterSP2D(const ElementFormulaContainer< concepts::Point< F, 2 > > vf, Real2d center=Real2d(0, 0), bool direction=OUTER)
Definition: pml_formula.h:200
const ElementFormulaContainer< concepts::Point< F, 2 > > vf
Definition: pml_formula.h:258
Cmplx gamma(Real2d &p) const
Returns the parameter gamma in page 2067(no equation number) of the above article.
Definition: pml_formula.h:880
std::complex< Real > Cmplx
Type for a complex number. It also depends on the setting of Real.
Definition: typedefs.hh:39
Cmplx gammaB(Real2d &p) const
Returns the parameter gamma bar in page 2067(no equation number) of the above article.
Definition: pml_formula.h:884
RCP< const ElementFormula< concepts::Point< F, DIM >, G > > vf
Definition: pml_formula.h:352
const ElementFormulaContainer< Cmplx > coeff_b
Definition: pml_formula.h:921
RCP< concepts::FormulaPMLPowerSigma< Real > > sigma_y
Definition: pml_formula.h:812
virtual FormulaPMLCart * clone() const
Virtual constructor.
Definition: pml_formula.h:693
FormulaExpImag2D(const Real2d k, const Cmplx u=1.0, Real2d x0=0.0)
Definition: pml_formula.h:56
virtual FormulaPMLPowerSigmaB2D * clone() const
Definition: pml_formula.h:620
Point< F, dim > & ortho(const Point< F, dim > &a)
Change vector to the by 90 degrees (clockwise) rotated vector a (only 2D)
Reference-counting pointer.
Definition: bf_iddiv.hh:15
Cmplx gammaY(Real y) const
Definition: pml_formula.h:718
virtual Cmplx operator()(const Real p, const Real t=0.0) const
Application operator.
Definition: pml_formula.h:101
virtual Cmplx operator()(const ElementWithCell< Real > &elm, const Real3d &p, const Real t=0.0) const
Definition: pml_formula.h:868
Computes the Matrix-vector product A * vf, where A is a matrix valued formula and vf a vector valued ...
Definition: pml_formula.h:270
Point< Cmplx, 2 > Cmplx2d
virtual FormulaPMLPowerSigma2D * clone() const
Definition: pml_formula.h:557
virtual const Cell & cell() const =0
Returns the cell on which the element is built.
static PiecewiseConstFormula< Cmplx > genTECoeff(const MID &attToEps)
Definition: pml_formula.h:463
RCP< const concepts::ElementFormula< Cmplx > > coeff_a
Definition: pml_formula.h:747
Formula for gradient of a plane wave.
Definition: pml_formula.h:137
virtual FormulaExpImag1D * clone() const
Definition: pml_formula.h:27
Class for the function for radial PML, see INRIA report of Collino & Monk.
Definition: pml_formula.h:614
bool inPMLregion(const concepts::Real p, const Real t=0.0)
Definition: pml_formula.h:502
virtual FormulaExpImag2DRadialDer * clone() const
Definition: pml_formula.h:97
virtual F operator()(const Real p, const Real t=0.0) const
Application operator.
Definition: pml_formula.h:624
virtual std::ostream & info(std::ostream &os) const
Definition: pml_formula.h:79
FormulaPMLRadia(const ElementFormulaContainer< Cmplx > coeff_a, const ElementFormulaContainer< Cmplx > coeff_b, RCP< concepts::Formula< Real > > sigma, RCP< concepts::Formula< Real > > sigmaB, PMLMode mode, double omega)
Constructor.
Definition: pml_formula.h:849
RCP< const ElementFormula< concepts::Point< F, DIM >, G > > vf
Definition: pml_formula.h:309
RCP< const ElementFormula< concepts::Mapping< F, DIM >, G > > A
Definition: pml_formula.h:308
virtual std::ostream & info(std::ostream &os) const
Definition: pml_formula.h:598
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
Definition: pml_formula.h:807
static Real powi(Real x, int power)
Definition: pml_formula.h:649
double Real
Type normally used for a floating point number.
Definition: typedefs.hh:36
RCP< concepts::Formula< Real > > sigma_y
Definition: pml_formula.h:750
virtual FormulaPMLPowerSigma * clone() const
Definition: pml_formula.h:498
virtual Cmplx operator()(const ElementWithCell< Real > &elm, const Real3d &p, const Real t=0.0) const
Definition: pml_formula.h:376
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
Definition: pml_formula.h:740
static Real powi(Real x, int power)
Definition: pml_formula.h:586
Basic namespace for Concepts-2.
Definition: pml_formula.h:16
Page URL: http://wiki.math.ethz.ch/bin/view/Concepts/WebHome
21 August 2020
© 2020 Eidgenössische Technische Hochschule Zürich