diff --git a/Common/operator_base.cpp b/Common/operator_base.cpp new file mode 100644 index 0000000..09b98e8 --- /dev/null +++ b/Common/operator_base.cpp @@ -0,0 +1,53 @@ +/* +* Copyright (C) 2010 Thorsten Liebig (Thorsten.Liebig@gmx.de) +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ + +#include "operator_base.h" + +Operator_Base::Operator_Base() +{ + Init(); + m_MeshType = Processing::CARTESIAN_MESH; +} + +Operator_Base::~Operator_Base() +{ + +} + +std::string Operator_Base::GetDirName(int ny) const +{ + if (ny==0) return "x"; + if (ny==1) return "y"; + if (ny==2) return "z"; + return ""; +} + +void Operator_Base::Init() +{ + dT = 0; + for (int n=0;n<3;++n) + discLines[n]=NULL; + for (int n=0;n<6;++n) + m_BC[n]=0; +} + +void Operator_Base::Reset() +{ + for (int n=0;n<3;++n) + delete[] discLines[n]; + Init(); +} diff --git a/Common/operator_base.h b/Common/operator_base.h new file mode 100644 index 0000000..50cd306 --- /dev/null +++ b/Common/operator_base.h @@ -0,0 +1,93 @@ +/* +* Copyright (C) 2010 Thorsten Liebig (Thorsten.Liebig@gmx.de) +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ + +#ifndef OPERATOR_BASE_H +#define OPERATOR_BASE_H + +#include "tools/global.h" +#include "FDTD/processing.h" +#include "string" + +class Operator_Base +{ +public: + //! Get the timestep used by this operator + double GetTimestep() const {return dT;}; + + //! Get the number of cells or nodes defined by this operator + virtual double GetNumberCells() const {return 0;} + + //! Get the number of timesteps satisfying the nyquist condition (may depend on the excitation) + unsigned int GetNumberOfNyquistTimesteps() const {return 0;} + + //! Returns the number of lines as needed for post-processing etc. (for the engine, use GetOriginalNumLines()) + virtual unsigned int GetNumberOfLines(int ny) const {return numLines[ny];} + + //! Get the name for the given direction: 0 -> x, 1 -> y, 2 -> z + virtual std::string GetDirName(int ny) const; + + //! Get the grid drawing unit in m + virtual double GetGridDelta() const {return 0;} + + //! Get the mesh delta times the grid delta for a 3D position (unit is meter) + virtual double GetMeshDelta(int n, const unsigned int* pos, bool dualMesh=false) const {UNUSED(n);UNUSED(pos);UNUSED(dualMesh);return 0.0;} + + //! Get the disc line in \a n direction (in drawing units) + virtual double GetDiscLine(int n, unsigned int pos, bool dualMesh=false) const {UNUSED(n);UNUSED(pos);UNUSED(dualMesh);return 0.0;} + + //! Get the node width for a given direction \a n and a given mesh position \a pos + virtual double GetNodeWidth(int ny, const unsigned int pos[3], bool dualMesh = false) const {UNUSED(ny);UNUSED(pos);UNUSED(dualMesh);return 0.0;} + + //! Get the node area for a given direction \a n and a given mesh position \a pos + virtual double GetNodeArea(int ny, const unsigned int pos[3], bool dualMesh = false) const {UNUSED(ny);UNUSED(pos);UNUSED(dualMesh);return 0.0;} + + //! Get the length of an FDTD edge (unit is meter). + virtual double GetEdgeLength(int ny, const unsigned int pos[3], bool dualMesh = false) const {UNUSED(ny);UNUSED(pos);UNUSED(dualMesh);return 0.0;} + + //! Get the area around an edge for a given direction \a n and a given mesh posisition \a pos + /*! + This will return the area around an edge with a given direction, measured at the middle of the edge. + In a cartesian mesh this is equal to the NodeArea, may be different in other coordinate systems. + */ + virtual double GetEdgeArea(int ny, const unsigned int pos[3], bool dualMesh = false) const {UNUSED(ny);UNUSED(pos);UNUSED(dualMesh);return 0.0;} + + //! Snap the given coodinates to mesh indices + virtual bool SnapToMesh(double* coord, unsigned int* uicoord, bool lower=false, bool* inside=NULL) {UNUSED(coord);UNUSED(uicoord);UNUSED(lower);UNUSED(inside);return false;}; + + //! Set the boundary conditions + virtual void SetBoundaryCondition(int* BCs) {for (int n=0;n<6;++n) m_BC[n]=BCs[n];} + +protected: + Operator_Base(); + virtual ~Operator_Base(); + + virtual void Init(); + virtual void Reset(); + + //! boundary conditions + int m_BC[6]; + + //! The operator timestep + double dT; + + Processing::MeshType m_MeshType; + unsigned int numLines[3]; + double* discLines[3]; + double gridDelta; +}; + +#endif // OPERATOR_BASE_H diff --git a/Common/readme.txt b/Common/readme.txt index 89192f3..37e9a22 100644 --- a/Common/readme.txt +++ b/Common/readme.txt @@ -1,5 +1,6 @@ readme for openEMS/Commen - This folder contains all classes common for all numerical solver included in openEMS (currently only FDTD) + - Operator-Base class - Engine-Interface classes - Commen processing classes diff --git a/FDTD/operator.cpp b/FDTD/operator.cpp index ecef166..0e96dd3 100644 --- a/FDTD/operator.cpp +++ b/FDTD/operator.cpp @@ -31,11 +31,9 @@ Operator* Operator::New() return op; } -Operator::Operator() +Operator::Operator() : Operator_Base() { - m_MeshType = ProcessFields::CARTESIAN_MESH; Exc = 0; - dT = 0; m_InvaildTimestep = false; } @@ -55,14 +53,14 @@ Engine* Operator::CreateEngine() const void Operator::Init() { + Operator_Base::Init(); + CSX = NULL; vv=NULL; vi=NULL; iv=NULL; ii=NULL; - for (int n=0;n<3;++n) - discLines[n]=NULL; MainOp=NULL; DualOp=NULL; @@ -75,11 +73,7 @@ void Operator::Init() EC_R[n]=NULL; } - for (int n=0;n<6;++n) - m_BC[n]=0; - Exc = 0; - dT = 0; } void Operator::Reset() @@ -88,8 +82,6 @@ void Operator::Reset() Delete_N_3DArray(vi,numLines); Delete_N_3DArray(iv,numLines); Delete_N_3DArray(ii,numLines); - for (int n=0;n<3;++n) - delete[] discLines[n]; delete MainOp; delete DualOp; for (int n=0;n<3;++n) @@ -102,15 +94,7 @@ void Operator::Reset() delete Exc; - Init(); -} - -string Operator::GetDirName(int ny) const -{ - if (ny==0) return "x"; - if (ny==1) return "y"; - if (ny==2) return "z"; - return ""; + Operator_Base::Reset(); } double Operator::GetMeshDelta(int n, const unsigned int* pos, bool dualMesh) const diff --git a/FDTD/operator.h b/FDTD/operator.h index 55a01cf..f4e27e4 100644 --- a/FDTD/operator.h +++ b/FDTD/operator.h @@ -22,13 +22,14 @@ #include "tools/AdrOp.h" #include "tools/constants.h" #include "excitation.h" +#include "Common/operator_base.h" class Operator_Extension; class Engine; class TiXmlElement; //! Abstract base-class for the FDTD-operator -class Operator +class Operator : public Operator_Base { friend class Engine; friend class Operator_Ext_LorentzMaterial; //we need to find a way around this... friend class Operator_Extension only would be nice @@ -73,27 +74,22 @@ public: inline virtual void SetII( unsigned int n, unsigned int x, unsigned int y, unsigned int z, FDTD_FLOAT value ) { ii[n][x][y][z] = value; } inline virtual void SetIV( unsigned int n, unsigned int x, unsigned int y, unsigned int z, FDTD_FLOAT value ) { iv[n][x][y][z] = value; } - virtual void SetBoundaryCondition(int* BCs) {for (int n=0;n<6;++n) m_BC[n]=BCs[n];} virtual void ApplyElectricBC(bool* dirs); //applied by default to all boundaries virtual void ApplyMagneticBC(bool* dirs); //! Set a forced timestep to use by the operator virtual void SetTimestep(double ts) {dT = ts;} - double GetTimestep() const {return dT;}; bool GetTimestepValid() const {return !m_InvaildTimestep;} virtual double GetNumberCells() const; - //! Returns the number of lines as needed for post-processing etc. (for the engine, use GetOriginalNumLines()) - virtual unsigned int GetNumberOfLines(int ny) const {return numLines[ny];} - //! Returns the number of lines as needed for the engine etc. (for post-processing etc, use GetOriginalNumLines()) + unsigned int GetNumberOfNyquistTimesteps() const {return Exc->GetNyquistNum();} + + //! Returns the number of lines as needed for the engine etc. (for post-processing etc, use GetNumLines()) virtual unsigned int GetOriginalNumLines(int ny) const {return numLines[ny];} virtual void ShowStat() const; virtual void ShowExtStat() const; - //! Get the name for the given direction: 0 -> x, 1 -> y, 2 -> z - virtual string GetDirName(int ny) const; - virtual double GetGridDelta() const {return gridDelta;} //! Get the mesh delta times the grid delta for a 3D position (unit is meter) virtual double GetMeshDelta(int n, const unsigned int* pos, bool dualMesh=false) const; @@ -141,8 +137,6 @@ protected: ContinuousStructure* CSX; - int m_BC[6]; - //! Calculate the field excitations. virtual bool CalcFieldExcitation(); @@ -158,7 +152,6 @@ protected: //Calc timestep only internal use virtual double CalcTimestep(); - double dT; //FDTD timestep! double opt_dT; bool m_InvaildTimestep; string m_Used_TS_Name; @@ -177,10 +170,6 @@ protected: double* EC_L[3]; double* EC_R[3]; - int m_MeshType; - unsigned int numLines[3]; - double* discLines[3]; - double gridDelta; AdrOp* MainOp; AdrOp* DualOp; diff --git a/FDTD/process_efield.cpp b/FDTD/process_efield.cpp index dc91a54..f65b7b7 100644 --- a/FDTD/process_efield.cpp +++ b/FDTD/process_efield.cpp @@ -19,7 +19,7 @@ #include "time.h" #include "process_efield.h" -ProcessEField::ProcessEField(Operator* op, Engine* eng) : Processing(op) +ProcessEField::ProcessEField(Operator_Base* op, Engine* eng) : Processing(op) { Eng = eng; } diff --git a/FDTD/process_efield.h b/FDTD/process_efield.h index 9f01315..bf1d9f2 100644 --- a/FDTD/process_efield.h +++ b/FDTD/process_efield.h @@ -19,6 +19,7 @@ #define PROCESS_EFIELD_H #include "processing.h" +#include "engine.h" /*! \brief Process E-field at a point @@ -28,7 +29,7 @@ class ProcessEField : public Processing { public: - ProcessEField(Operator* op, Engine* eng); + ProcessEField(Operator_Base* op, Engine* eng); virtual ~ProcessEField(); virtual void InitProcess(); diff --git a/FDTD/process_hfield.cpp b/FDTD/process_hfield.cpp index df8acf9..55cac59 100644 --- a/FDTD/process_hfield.cpp +++ b/FDTD/process_hfield.cpp @@ -19,7 +19,7 @@ #include "tools/global.h" #include "process_hfield.h" -ProcessHField::ProcessHField(Operator* op, Engine* eng) : ProcessEField(op, eng) +ProcessHField::ProcessHField(Operator_Base* op, Engine* eng) : ProcessEField(op, eng) { } diff --git a/FDTD/process_hfield.h b/FDTD/process_hfield.h index f089b11..22e00ce 100644 --- a/FDTD/process_hfield.h +++ b/FDTD/process_hfield.h @@ -28,7 +28,7 @@ class ProcessHField : public ProcessEField { public: - ProcessHField(Operator* op, Engine* eng); + ProcessHField(Operator_Base* op, Engine* eng); virtual ~ProcessHField(); virtual void InitProcess(); diff --git a/FDTD/processcurrent.cpp b/FDTD/processcurrent.cpp index 864b6a1..2ebe466 100644 --- a/FDTD/processcurrent.cpp +++ b/FDTD/processcurrent.cpp @@ -20,7 +20,7 @@ #include "engine_interface_fdtd.h" #include -ProcessCurrent::ProcessCurrent(Operator* op) : ProcessIntegral(op) +ProcessCurrent::ProcessCurrent(Operator_Base* op) : ProcessIntegral(op) { m_TimeShift = op->GetTimestep()/2.0; m_dualMesh = true; diff --git a/FDTD/processcurrent.h b/FDTD/processcurrent.h index e0ce15e..224eeca 100644 --- a/FDTD/processcurrent.h +++ b/FDTD/processcurrent.h @@ -23,7 +23,7 @@ class ProcessCurrent : public ProcessIntegral { public: - ProcessCurrent(Operator* op); + ProcessCurrent(Operator_Base* op); virtual ~ProcessCurrent(); //! Integrate currents flowing through an area diff --git a/FDTD/processfields.cpp b/FDTD/processfields.cpp index dc39a37..b35ce96 100644 --- a/FDTD/processfields.cpp +++ b/FDTD/processfields.cpp @@ -21,7 +21,7 @@ #include "processfields.h" #include "engine_interface_fdtd.h" -ProcessFields::ProcessFields(Operator* op) : Processing(op) +ProcessFields::ProcessFields(Operator_Base* op) : Processing(op) { m_DumpType = E_FIELD_DUMP; // vtk-file is default diff --git a/FDTD/processfields.h b/FDTD/processfields.h index 83ae51d..22321fc 100644 --- a/FDTD/processfields.h +++ b/FDTD/processfields.h @@ -26,7 +26,7 @@ class ProcessFields : public Processing { public: - ProcessFields(Operator* op); + ProcessFields(Operator_Base* op); virtual ~ProcessFields(); enum FileType { VTK_FILETYPE, HDF5_FILETYPE}; diff --git a/FDTD/processfields_td.cpp b/FDTD/processfields_td.cpp index 42edd7c..7c6277c 100644 --- a/FDTD/processfields_td.cpp +++ b/FDTD/processfields_td.cpp @@ -16,11 +16,12 @@ */ #include "processfields_td.h" +#include "Common/operator_base.h" #include #include #include -ProcessFieldsTD::ProcessFieldsTD(Operator* op) : ProcessFields(op) +ProcessFieldsTD::ProcessFieldsTD(Operator_Base* op) : ProcessFields(op) { pad_length = 8; } diff --git a/FDTD/processfields_td.h b/FDTD/processfields_td.h index 36e86ef..cc57ca1 100644 --- a/FDTD/processfields_td.h +++ b/FDTD/processfields_td.h @@ -23,7 +23,7 @@ class ProcessFieldsTD : public ProcessFields { public: - ProcessFieldsTD(Operator* op); + ProcessFieldsTD(Operator_Base* op); virtual ~ProcessFieldsTD(); virtual int Process(); diff --git a/FDTD/processing.cpp b/FDTD/processing.cpp index e952f83..916fe78 100644 --- a/FDTD/processing.cpp +++ b/FDTD/processing.cpp @@ -17,11 +17,13 @@ #include "tools/global.h" #include "tools/useful.h" +#include "Common/operator_base.h" +#include #include "processing.h" #include "time.h" #include -Processing::Processing(Operator* op) +Processing::Processing(Operator_Base* op) { Op=op; Enabled = true; @@ -126,13 +128,13 @@ void Processing::AddFrequency(double freq) cerr << "Processing::AddFrequency: Requested frequency " << freq << " is too high for the current timestep used... skipping..." << endl; return; } - else if (nyquistTSExc->GetNyquistNum()) + else if (nyquistTSGetNumberOfNyquistTimesteps()) { cerr << "Processing::AddFrequency: Warning: Requested frequency " << freq << " is higher than maximum excited frequency..." << endl; } if (m_FD_Interval==0) - m_FD_Interval = Op->Exc->GetNyquistNum(); + m_FD_Interval = Op->GetNumberOfNyquistTimesteps(); if (m_FD_Interval>nyquistTS) m_FD_Interval = nyquistTS; diff --git a/FDTD/processing.h b/FDTD/processing.h index bd74c99..9faa538 100644 --- a/FDTD/processing.h +++ b/FDTD/processing.h @@ -25,22 +25,29 @@ typedef std::complex double_complex; #include #include #include -#include "Common/engine_interface_base.h" -#include "operator.h" -#include "engine.h" +#include +#include +#include +#include +#include +#include "Common/engine_interface_base.h" + +class Operator_Base; + +using namespace std; class Processing { public: - Processing(Operator* op); + Processing(Operator_Base* op); virtual ~Processing(); + enum MeshType { CARTESIAN_MESH, CYLINDRICAL_MESH}; + //! Set the interface to the engine. Each processing needs its own engine interface. This class will take ownership and cleanup the interface on deletion! void SetEngineInterface(Engine_Interface_Base* eng_if); - enum MeshType { CARTESIAN_MESH, CYLINDRICAL_MESH}; - virtual void SetName(string val) {m_Name=val;} virtual void InitProcess() {}; @@ -84,7 +91,7 @@ public: protected: Engine_Interface_Base* m_Eng_Interface; - Operator* Op; + Operator_Base* Op; MeshType m_Mesh_Type; unsigned int m_precision; diff --git a/FDTD/processintegral.cpp b/FDTD/processintegral.cpp index 1944166..f9ded38 100644 --- a/FDTD/processintegral.cpp +++ b/FDTD/processintegral.cpp @@ -18,7 +18,7 @@ #include "processintegral.h" #include -ProcessIntegral::ProcessIntegral(Operator* op) : Processing(op) +ProcessIntegral::ProcessIntegral(Operator_Base* op) : Processing(op) { m_TimeShift = 0.0; m_Results=NULL; diff --git a/FDTD/processintegral.h b/FDTD/processintegral.h index 961e706..5a43372 100644 --- a/FDTD/processintegral.h +++ b/FDTD/processintegral.h @@ -51,12 +51,12 @@ public: virtual int Process(); protected: - ProcessIntegral(Operator* op); + ProcessIntegral(Operator_Base* op); //! timeshift to be used in TD and FD data, e.g. 0.5*dT in case of current based parameter double m_TimeShift; - vector TD_Values; + vector TD_Values; vector FD_Values; double *m_Results; diff --git a/FDTD/processmodematch.cpp b/FDTD/processmodematch.cpp index 69b80ea..b04b3e6 100644 --- a/FDTD/processmodematch.cpp +++ b/FDTD/processmodematch.cpp @@ -17,9 +17,10 @@ #include "processmodematch.h" #include "CSFunctionParser.h" +#include "Common/operator_base.h" #include "tools/array_ops.h" -ProcessModeMatch::ProcessModeMatch(Operator* op) : ProcessIntegral(op) +ProcessModeMatch::ProcessModeMatch(Operator_Base* op) : ProcessIntegral(op) { for (int n=0;n<2;++n) { diff --git a/FDTD/processmodematch.h b/FDTD/processmodematch.h index 4104f7e..f68b10d 100644 --- a/FDTD/processmodematch.h +++ b/FDTD/processmodematch.h @@ -25,7 +25,7 @@ class CSFunctionParser; class ProcessModeMatch : public ProcessIntegral { public: - ProcessModeMatch(Operator* op); + ProcessModeMatch(Operator_Base* op); virtual ~ProcessModeMatch(); virtual void InitProcess(); diff --git a/FDTD/processvoltage.cpp b/FDTD/processvoltage.cpp index 72f0ff0..8d94b6b 100644 --- a/FDTD/processvoltage.cpp +++ b/FDTD/processvoltage.cpp @@ -18,7 +18,7 @@ #include "processvoltage.h" #include -ProcessVoltage::ProcessVoltage(Operator* op) : ProcessIntegral(op) +ProcessVoltage::ProcessVoltage(Operator_Base* op) : ProcessIntegral(op) { } diff --git a/FDTD/processvoltage.h b/FDTD/processvoltage.h index 4bec349..91768ce 100644 --- a/FDTD/processvoltage.h +++ b/FDTD/processvoltage.h @@ -24,7 +24,7 @@ class ProcessVoltage : public ProcessIntegral { public: - ProcessVoltage(Operator* op); + ProcessVoltage(Operator_Base* op); virtual ~ProcessVoltage(); virtual double CalcIntegral(); diff --git a/openEMS.pro b/openEMS.pro index c556a8b..6f00cd4 100644 --- a/openEMS.pro +++ b/openEMS.pro @@ -86,9 +86,10 @@ SOURCES += main.cpp \ FDTD/engine_cylindermultigrid.cpp \ FDTD/engine_ext_cylindermultigrid.cpp \ FDTD/operator_ext_upml.cpp \ - FDTD/engine_ext_upml.cpp \ + FDTD/engine_ext_upml.cpp \ Common/engine_interface_base.cpp \ - FDTD/engine_interface_fdtd.cpp + FDTD/engine_interface_fdtd.cpp \ + Common/operator_base.cpp HEADERS += tools/ErrorMsg.h \ tools/AdrOp.h \ tools/constants.h \ @@ -132,9 +133,10 @@ HEADERS += tools/ErrorMsg.h \ FDTD/engine_ext_cylindermultigrid.h \ tools/aligned_allocator.h \ FDTD/operator_ext_upml.h \ - FDTD/engine_ext_upml.h \ + FDTD/engine_ext_upml.h \ Common/engine_interface_base.h \ - FDTD/engine_interface_fdtd.h + FDTD/engine_interface_fdtd.h \ + Common/operator_base.h QMAKE_CXXFLAGS_RELEASE = -O3 \ -g \ -march=native