Class documentation of Concepts

Loading...
Searching...
No Matches
pml_formula.h
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
16namespace concepts {
17
18// ******************************************************** FormulaExpImag1D **
19
22class FormulaExpImag1D : public concepts::Formula<Cmplx> {
23public:
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 }
41protected:
42 virtual std::ostream& info(std::ostream& os) const {
43 return os << "FormulaExpImag1D(" << u_ << " * exp(i " << k_ << "(x - " << x0_ << ")))";
44 }
45private:
46 const Real k_, x0_;
47 const Cmplx u_;
48};
49
50// ******************************************************** FormulaExpImag2D **
51
54class FormulaExpImag2D : public concepts::Formula<Cmplx> {
55public:
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 }
78protected:
79 virtual std::ostream& info(std::ostream& os) const {
80 return os << "FormulaExpImag2D(" << u << " * exp(i " << k << "(x - " << x0 << ")))";
81 }
82public:
83 const Real2d k, x0;
84 const Cmplx u;
85};
86
87// *********************************************** FormulaExpImag2DRadialDer **
88
92public:
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
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 }
122protected:
123 virtual std::ostream& info(std::ostream& os) const {
124 return os << "FormulaExpImag2DRadialDer(" << u << " * exp(i " << k << "(x - " << x0 << ")))";
125 }
126public:
127 const Real2d k, x0;
128 const Cmplx u;
129};
130
131// **************************************************** FormulaExpImag2DGrad **
132
136class FormulaExpImag2DGrad : public concepts::Formula< concepts::Point<Cmplx, 2> >
137{
138public:
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 }
169protected:
170 virtual std::ostream& info(std::ostream& os) const {
171 return os << "FormulaExpImag2DGrad(" << u << " * exp(i " << k << "(x - " << x0 << ")))";
172 }
173public:
174 const Real2d k, x0;
175 const Cmplx u;
176};
177
178
179// ************************************************** FormulaNormalOuterSP2D **
180
193template< class F >
195{
196public:
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)
205 , direction(direction)
206 { }
207
208 virtual FormulaNormalOuterSP2D* clone() const {
209 return new FormulaNormalOuterSP2D(*this);
210 }
211
212 virtual F operator() (const concepts::ElementWithCell<Real>& elm,
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
242 virtual F operator() (const concepts::ElementWithCell<Real>& elm,
243 const concepts::Real2d& p, const Real t = 0.0) const
244 {
245 conceptsThrowSimpleE("FormulaNormalOuterSP2D currently only supports 1D!"); assert(false);
246 }
247
248 virtual F operator() (const concepts::ElementWithCell<Real>& elm,
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 }
253protected:
254 virtual std::ostream& info(std::ostream& os) const {
255 return os << "FormulaNormalOuterSP2D(" << vf << ", " << center << ", " << direction << ")";
256 }
257public:
259 Real2d center;
260 bool direction;
261};
262
263// **************************************************** ComposeFormulaMatVec **
264
269class ComposeFormulaMatVec : public concepts::ElementFormula< concepts::Point<F, DIM>, G >
270{
271public:
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 }
303protected:
304 virtual std::ostream& info(std::ostream& os) const {
305 return os << "ComposeFormulaMatVec(A=" << *A << ", vf="<< *vf << ")";
306 }
307public:
310};
311
312// *************************************************** ComposeFormulaVecEntry **
313
316{
317public:
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 }
347protected:
348 virtual std::ostream& info(std::ostream& os) const {
349 return os << "ComposeFormulaVecEntry(i=" << index << ", vf="<< *vf << ")";
350 }
351public:
353 int index;
354};
355
356// *********************************************** FormulaIncPlaneWaveSource **
357
359public:
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
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
417 static PiecewiseConstFormula<Cmplx> genTMCoeff(
418 const MID& attToEps);
419
420 static PiecewiseConstFormula<Cmplx> genTECoeff(
421 const MID& attToEps);
422
423protected:
424 virtual std::ostream& info(std::ostream& os) const {
425 return os << "FormulaIncPlaneWaveSource(" << coeff_a << ", " << coeff_b << ")";
426 }
427private:
429/* RCP< concepts::ElementFormula<Cmplx> > coeff_a; */
430/* RCP< concepts::ElementFormula<Cmplx> > coeff_b; */
432};
433
434PiecewiseConstFormula<Cmplx> FormulaIncPlaneWaveSource::genTMCoeff(
435 const MID& attrToEps)
436{
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
463PiecewiseConstFormula<Cmplx> FormulaIncPlaneWaveSource::genTECoeff(
464 const MID& attrToEps)
465{
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
487template<typename F=Real>
489 public:
490 FormulaPMLPowerSigma(const Real offset, const int power=2
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 {
499 return new FormulaPMLPowerSigma(offset, power, sigma0, center);
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
550template<typename F=Real>
552 public:
553 FormulaPMLPowerSigma2D(const Real offset, const int power=2,
554 const F sigma0 = 5.0, const Real2d& center=Real2d(0,0))
555 : offset(offset), center(center), power(power), sigma0(sigma0) {}
556
557 virtual FormulaPMLPowerSigma2D* clone() const {
558 return new FormulaPMLPowerSigma2D(offset, power, sigma0, center);
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
613template<typename F=Real>
615 public:
616 FormulaPMLPowerSigmaB2D(const Real offset, const int power=2,
617 const F sigma0 = 5.0, const Real2d& center=Real2d(0,0))
618 : offset(offset), center(center), power(power), sigma0(sigma0) {}
619
621 return new FormulaPMLPowerSigmaB2D(offset, power, sigma0, center);
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
674class FormulaPMLCart : public ElementFormula<Cmplx> {
675 public:
676 enum PMLMode { DXDX, DYDY, IDENT, DX, DY };
677
679 , RCP<const ElementFormula<Cmplx> > coeff_b
680 , RCP<concepts::Formula<Real> > sigma_x
681 , RCP<concepts::Formula<Real> > sigma_y
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:
751 PMLMode mode;
752 double omega;
753};
754
755// ************************************************ FormulaPMLBoxRestriction **
756
759public:
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
803 return new FormulaPMLBoxRestriction(*this);
804 }
805
806protected:
807 virtual std::ostream& info(std::ostream& os) const {
808 return os << "FormulaPMLBoxRestriction(" << formula << " :" << *sigma_x << ", " << sigma_y << ")))";
809 }
810private:
814};
815
816// ******************************************************* FormulaPMLRadia **
817
834class FormulaPMLRadia : public ElementFormula<Cmplx> {
835 public:
836 enum PMLMode { AD1, AD2, AS, IDENT};
837
850 , const ElementFormulaContainer<Cmplx> coeff_b
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:
920 const ElementFormulaContainer<Cmplx> coeff_a;
921 const ElementFormulaContainer<Cmplx> coeff_b;
927 PMLMode mode;
929 double omega;
930};
931
932} // namespace concepts
concepts::Array< F > pow(const concepts::Array< F > &a, const F e)
Returns the power of values in the array a with e.
Definition arrayOp.hh:56
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
virtual concepts::Point< F, DIM > operator()(const concepts::ElementWithCell< G > &elm, const Real p, const Real t=0.0) const
virtual ComposeFormulaMatVec * clone() const
Virtual copy constructor.
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.
virtual Cmplx operator()(const Real p, const Real t=0.0) const
Definition pml_formula.h:31
virtual FormulaExpImag1D * clone() const
Virtual copy constructor.
Definition pml_formula.h:27
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
Definition pml_formula.h:42
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
virtual Cmplx2d operator()(const Real p, const Real t=0.0) const
virtual FormulaExpImag2DGrad * clone() const
Virtual copy constructor.
virtual Cmplx operator()(const Real p, const Real t=0.0) const
virtual FormulaExpImag2DRadialDer * clone() const
Virtual copy constructor.
Definition pml_formula.h:97
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
virtual FormulaExpImag2D * clone() const
Virtual copy constructor.
Definition pml_formula.h:59
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
Definition pml_formula.h:79
virtual Cmplx operator()(const Real p, const Real t=0.0) const
Definition pml_formula.h:63
virtual FormulaIncPlaneWaveSource * clone() const
Virtual copy constructor.
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
virtual FormulaNormalOuterSP2D * clone() const
Virtual copy constructor.
virtual FormulaPMLBoxRestriction * clone() const
Virtual copy constructor.
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
virtual FormulaPMLCart * clone() const
Virtual copy constructor.
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
virtual FormulaPMLPowerSigma2D * clone() const
Virtual copy constructor.
virtual F operator()(const Real p, const Real t=0.0) const
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
virtual FormulaPMLPowerSigmaB2D * clone() const
Virtual copy constructor.
virtual F operator()(const Real p, const Real t=0.0) const
virtual FormulaPMLPowerSigma * clone() const
Virtual copy constructor.
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
virtual F operator()(const Real p, const Real t=0.0) const
virtual FormulaPMLRadia * clone() const
Virtual copy constructor.
Cmplx gamma(Real2d &p) const
Returns the parameter gamma in page 2067(no equation number) of the above article.
virtual std::ostream & info(std::ostream &os) const
Returns information in an output stream.
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)
Cmplx gammaB(Real2d &p) const
Returns the parameter gamma bar in page 2067(no equation number) of the above article.
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)
Definition debug.hh:40
#define conceptsThrowSimpleE(msg)
double Real
Definition typedefs.hh:39
Set< F > makeSet(uint n, const F &first,...)
Definition set.hh:320
std::complex< Real > Cmplx
Type for a complex number. It also depends on the setting of Real.
Definition typedefs.hh:42