1 /*
2 *	Copyright (C) 2010 Thorsten Liebig (Thorsten.Liebig@gmx.de)
3 *
4 *	This program is free software: you can redistribute it and/or modify
5 *	it under the terms of the GNU General Public License as published by
6 *	the Free Software Foundation, either version 3 of the License, or
7 *	(at your option) any later version.
8 *
9 *	This program is distributed in the hope that it will be useful,
10 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
11 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 *	GNU General Public License for more details.
13 *
14 *	You should have received a copy of the GNU General Public License
15 *	along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17 
18 #ifndef OPERATOR_EXT_UPML_H
19 #define OPERATOR_EXT_UPML_H
20 
21 #include "FDTD/operator.h"
22 #include "operator_extension.h"
23 
24 class FunctionParser;
25 
26 //! Operator extension implemention an uniaxial perfectly matched layer (upml)
27 /*
28   The priority for this extension should be the highest of all extensions since this operator will use the main engine to perform vital parts in the upml implementation.
29   Therefore the voltages and currents as well as the operator are replaced during these update process.
30   This extension is propably incompatible with the most other extensions operating in the same regions.
31   */
32 class Operator_Ext_UPML : public Operator_Extension
33 {
34 	friend class Engine_Ext_UPML;
35 public:
36 	virtual ~Operator_Ext_UPML();
37 
38 	//! Returns always true, Create_UPML method will take care of creating a valid pml for the cylindrical fdtd
IsCylinderCoordsSave(bool closedAlpha,bool R0_included)39 	virtual bool IsCylinderCoordsSave(bool closedAlpha, bool R0_included) const { UNUSED(closedAlpha); UNUSED(R0_included); return true;}
40 
41 	//! Returns always true if base grid, Create_UPML will create proper child pml extensions.
IsCylindricalMultiGridSave(bool child)42 	virtual bool IsCylindricalMultiGridSave(bool child) const {if (child) return false; return true;}
43 
IsMPISave()44 	virtual bool IsMPISave() const {return true;}
45 
46 	void SetBoundaryCondition(const int* BCs, const unsigned int size[6]);
47 
48 	void SetRange(const unsigned int start[3], const unsigned int stop[3]);
49 
50 	//! Set the grading function for the pml
51 	/*!
52 		Define the pml grading grading function.
53 		Predefined variables in this grading function are:
54 			D  = depth in the pml in meter
55 			dl = mesh delta inside the pml in meter
56 			W  = width (length) of the pml in meter
57 			N  = number of cells for the pml
58 			Z  = wave impedance at the current depth and position
59 		example: SetGradingFunction(" -log(1e-6)*log(2.5)/(2*dl*Z*(pow(2.5,W/dl)-1)) * pow(2.5, D/dl) ");
60 
61 		An empty function string will be ignored.
62 	*/
63 	virtual bool SetGradingFunction(string func);
64 
65 	virtual bool BuildExtension();
66 
67 	virtual Engine_Extension* CreateEngineExtention();
68 
GetExtensionName()69 	virtual string GetExtensionName() const {return string("Uniaxial PML Extension");}
70 
71 	virtual void ShowStat(ostream &ostr) const;
72 
73 	//! Create the UPML
74 	static bool Create_UPML(Operator* op, const int ui_BC[6], const unsigned int ui_size[6], const string gradFunc);
75 
76 protected:
77 	Operator_Ext_UPML(Operator* op);
78 	int m_BC[6];
79 	unsigned int m_Size[6];
80 
81 	unsigned int m_StartPos[3];
82 	unsigned int m_numLines[3];
83 
84 	string m_GradFunc;
85 	FunctionParser* m_GradingFunction;
86 
87 	void CalcGradingKappa(int ny, unsigned int pos[3], double Zm, double kappa_v[3], double kappa_i[3]);
88 
89 	void DeleteOp();
90 
GetVV(int ny,unsigned int pos[3])91 	virtual FDTD_FLOAT& GetVV(int ny, unsigned int pos[3]) {return vv[ny][pos[0]][pos[1]][pos[2]];}
GetVVFO(int ny,unsigned int pos[3])92 	virtual FDTD_FLOAT& GetVVFO(int ny, unsigned int pos[3]) {return vvfo[ny][pos[0]][pos[1]][pos[2]];}
GetVVFN(int ny,unsigned int pos[3])93 	virtual FDTD_FLOAT& GetVVFN(int ny, unsigned int pos[3]) {return vvfn[ny][pos[0]][pos[1]][pos[2]];}
GetII(int ny,unsigned int pos[3])94 	virtual FDTD_FLOAT& GetII(int ny, unsigned int pos[3]) {return ii[ny][pos[0]][pos[1]][pos[2]];}
GetIIFO(int ny,unsigned int pos[3])95 	virtual FDTD_FLOAT& GetIIFO(int ny, unsigned int pos[3]) {return iifo[ny][pos[0]][pos[1]][pos[2]];}
GetIIFN(int ny,unsigned int pos[3])96 	virtual FDTD_FLOAT& GetIIFN(int ny, unsigned int pos[3]) {return iifn[ny][pos[0]][pos[1]][pos[2]];}
97 
98 	FDTD_FLOAT**** vv;   //calc new voltage from old voltage
99 	FDTD_FLOAT**** vvfo; //calc new voltage from old voltage flux
100 	FDTD_FLOAT**** vvfn; //calc new voltage from new voltage flux
101 	FDTD_FLOAT**** ii;   //calc new current from old current
102 	FDTD_FLOAT**** iifo; //calc new current from old current flux
103 	FDTD_FLOAT**** iifn; //calc new current from new current flux
104 };
105 
106 #endif // OPERATOR_EXT_UPML_H
107