14#ifndef waveprop_pmlformula_hh
15#define waveprop_pmlformula_hh
38 template<
typename F=Real>
39 class FormulaPMLPowerSigma :
public Formula<F> {
41 FormulaPMLPowerSigma(
const Real offset,
const int power=2
42 ,
const F sigma0 = 5.0,
const Real center=0)
53 bool inPMLregion(
const Real p,
const Real t = 0.0)
55 Real arg =
fabs(p - center_) - offset_;
61 Real arg =
fabs(p - center_) - offset_;
64 return sigma0_ * powi(arg , power_);
68 return (*
this)(p[0], t);
72 return (*
this)(p[0], t);
74 template<
typename Real>
87 virtual std::ostream&
info(std::ostream&
os)
const {
89 <<
")| - " << offset_ <<
")_+^" << power_ <<
")))";
114 template<
typename F=Real>
115 class FormulaPMLPowerSigma2D :
public Formula<F> {
125 const F sigma0 = 5.0,
127 : offset_(offset), center_(center), power_(power), sigma0_(sigma0) {
139 inline bool inPMLregion(
const Real2d& p,
const Real t = 0.0)
const
142 Real arg = (p-center_).l2() - offset_;
146 virtual F
operator() (
const Real2d& p,
const Real t = 0.0)
const {
147 Real dist = (p-center_).l2() - offset_;
150 return sigma0_ * powi(
dist, power_);
153 virtual F
operator() (
const Real3d& p,
const Real t = 0.0)
const {
154 return (*
this)( Real2d(p[0], p[1]), t);
157 template<
typename Real>
170 virtual std::ostream&
info(std::ostream&
os)
const{
172 <<
"," << center_[1] <<
")| - " << offset_ <<
")_+^" << power_ <<
")))";
203 template<
typename F=Real>
204 class FormulaPMLPowerSigmaB2D :
public Formula<F> {
214 const F sigma0 = 5.0,
216 : offset_(offset), center_(center), power_(power), sigma0_(sigma0) {}
224 (
"FormulaPMLPowerSigmaB2D currently only supports 2D!");
assert(
false);
227 inline bool inPMLregion(
const Real2d& p,
const Real t = 0.0)
const
229 Real arg = (p-center_).l2() - offset_;
233 virtual F
operator() (
const Real2d& p,
const Real t = 0.0)
const {
234 Real rho = (p-center_).l2();
235 Real arg = rho - offset_;
238 return sigma0_ * powi( arg , power_ + 1) / (rho) / (power_ + 1);
241 virtual F
operator() (
const Real3d& p,
const Real t = 0.0)
const {
242 return (*
this)( Real2d(p[0], p[1]), t);
245 template<
typename Real>
258 virtual std::ostream&
info(std::ostream&
os)
const {
260 << center_[0] <<
"," << center_[1] <<
")| - "
261 << offset_ <<
")_+^" << power_ <<
")))";
279 class FormulaPMLCart :
public ElementFormula<Cmplx> {
281 enum PMLMode { DXDX, DYDY, IDENT, DX, DY };
283 FormulaPMLCart(
const ElementFormulaContainer<Cmplx> coeff_a
284 ,
const ElementFormulaContainer<Cmplx> coeff_b
285 , RCP<Formula<Real> > sigma_x
286 , RCP<Formula<Real> > sigma_y
305 return operator()(elm, p,
px, t);
309 Real2d
px = elm.elemMap(p);
310 return operator()(elm, p,
px, t);
314 Real2d
px = elm.elemMap(p);
315 return operator()(elm, p,
px, t);
319 return Cmplx(1, (*sigma_x_)(x) / omega_);
323 return Cmplx(1, (*sigma_y_)(y) / omega_);
326 template <
class RealNd>
328 const Real t=0.0)
const
331 case DXDX:
return gammaY(
px[1]) / gammaX(
px[0]) * coeff_a_(elm, p);
332 case DX:
return gammaY(
px[1]) * coeff_a_(elm, p);
333 case DYDY:
return gammaX(
px[0]) / gammaY(
px[1]) * coeff_a_(elm, p);
334 case DY:
return gammaX(
px[0]) * coeff_a_(elm, p);
335 case IDENT:
return gammaX(
px[0]) * gammaY(
px[1]) * coeff_b_(elm, p);
342 virtual std::ostream&
info(std::ostream&
os)
const {
344 << coeff_a_ <<
", " << coeff_b_ <<
", sigmas:"
345 << *sigma_x_ <<
", " << *sigma_y_
360 class FormulaPMLBoxRestriction :
public ElementFormula<F, G> {
362 FormulaPMLBoxRestriction(
365 , RCP<ElementFormula<F, G> > formula
374 Real2d
px = elm.elemMap(p);
375 return operator()(elm, p,
px, t);
380 Real2d
px = elm.elemMap(p);
381 return operator()(elm, p,
px, t);
386 Real2d
px = elm.elemMap(p);
387 return operator()(elm, p,
px, t);
390 template <
class RealNd>
392 const Real t=0.0)
const
394 if ( sigma_x->inPMLregion(
px[0], t) || sigma_y->inPMLregion(
px[1], t)) {
395 return formula->operator()(elm, p, t);
409 virtual std::ostream&
info(std::ostream&
os)
const {
410 return os <<
concepts::typeOf(*
this)<<
"(" << formula <<
" :" << *sigma_x <<
", " << sigma_y <<
")))";
432 class FormulaPMLRadia :
public ElementFormula<Cmplx> {
434 enum PMLMode { AD1, AD2, AS1, AS2, IDENT};
455 const Real p,
const Real t = 0.0)
const;
464 virtual std::ostream&
info(std::ostream&
os)
const;
480 return Cmplx(1, (*sigma_) (p));
486 return Cmplx(1, (*sigmaB_)(p));
507 const Real sigma0 = 5.0,
528 virtual std::ostream&
info(std::ostream&
os)
const;
555 enum PMLMode { DXDX, DYDY, IDENT, DX, DY , ZERO};
572 return operator()(elm, p,
px, t);
576 Real2d
px = elm.elemMap(p);
577 return operator()(elm, p,
px, t);
581 Real2d
px = elm.elemMap(p);
582 return operator()(elm, p,
px, t);
589 return Cmplx(1., (*sigma_x_)(x) );
593 return Cmplx(1., (*sigma_y_)(y) );
596 template <
class RealNd>
600 case DXDX:
return gammaY(
px[1]) / gammaX(
px[0]);
601 case DX:
return gammaY(
px[1]) ;
602 case DYDY:
return gammaX(
px[0]) / gammaY(
px[1]) ;
603 case DY:
return gammaX(
px[0]) ;
604 case ZERO :
return 0.0;
605 case IDENT:
return gammaX(
px[0]) * gammaY(
px[1]) ;
612 virtual std::ostream&
info(std::ostream&
os)
const {
614 << *sigma_x_ <<
", sigma y = " << *sigma_y_
652 const Real sigma0 = 5.0,
653 const Real center_x =0,
654 const Real center_y = 0);
672 friend std::ostream& operator<<(std::ostream&
out,
const CartesianPMLFormulas &ca)
674 return(ca.info(
out));
677 virtual std::ostream&
info(std::ostream&
os)
const;
689 enum PMLMode {M1, M2, M3, M4, IDENT};
695 Real center_x, center_y;
696 Real2d center_point_up, center_point_down;
702 FormulaPMLCartNew::PMLMode convert_mode_to_cart(FormulaPMLHamburger::PMLMode mode)
706 case M1:
return(FormulaPMLCartNew::DXDX);
707 case M2:
return(FormulaPMLCartNew::ZERO);
708 case M3:
return(FormulaPMLCartNew::ZERO);
709 case M4:
return(FormulaPMLCartNew::DYDY);
710 case IDENT:
return(FormulaPMLCartNew::IDENT);
712 return(FormulaPMLCartNew::IDENT);
714 FormulaPMLRadia::PMLMode convert_mode_to_radia(FormulaPMLHamburger::PMLMode mode)
718 case M1:
return(FormulaPMLRadia::AD1);
719 case M2:
return(FormulaPMLRadia::AS1);
720 case M3:
return(FormulaPMLRadia::AS2);
721 case M4:
return(FormulaPMLRadia::AD2);
722 case IDENT:
return(FormulaPMLRadia::IDENT);
724 return(FormulaPMLRadia::IDENT);
731 const Real center_x_,
732 const Real center_y_,
740 center_point_up(center_x,center_y+d/2.),
741 center_point_down(center_x,center_y-d/2.),
746 convert_mode_to_cart(mode)),
750 convert_mode_to_radia(mode),
755 convert_mode_to_radia(mode),
769 return operator()(elm, p,
px, t);
774 Real2d
px = elm.elemMap(p);
775 return operator()(elm, p,
px, t);
780 Real2d
px = elm.elemMap(p);
781 return operator()(elm, p,
px, t);
785 template <
class RealNd>
792 return RadiaUp(elm, p, t);
794 else if (
px[1]< -d/2.){
796 return(RadiaDown(elm, p, t));
800 return(Cart(elm, p,
px, t));
806 virtual std::ostream&
info(std::ostream&
os)
const {
808 << *Cart.sigmax() <<
", sigma y = " << *Cart.sigmay()
809 <<
", sigma up = "<< *RadiaUp.sigma()
810 <<
", sigma down = " << *RadiaDown.sigma() <<
")";
829 Real sigma0_, center_x_, center_y_;
855 const Real sigma0 = 5.0,
856 const Real center_x =0,
857 const Real center_y = 0);
879 virtual std::ostream&
info(std::ostream&
os)
const;
concepts::Array< F > pow(const concepts::Array< F > &a, const F e)
Returns the power of values in the array a with e.
#define conceptsThrowSimpleE(msg)
std::string typeOf(const T &t)
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.