2010-05-03 16:33:14 +00:00
/*
* 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 < http : //www.gnu.org/licenses/>.
*/
# include "tools/array_ops.h"
2010-06-28 16:05:03 +00:00
# include "tools/useful.h"
2011-03-08 12:35:38 +00:00
# include <iostream>
# include <fstream>
2010-05-03 16:33:14 +00:00
# include "fparser.hh"
# include "tinyxml.h"
# include "excitation.h"
2015-06-18 19:45:22 +00:00
using namespace std ;
2012-07-17 11:23:00 +00:00
Excitation : : Excitation ( )
2010-05-03 16:33:14 +00:00
{
Signal_volt = 0 ;
Signal_curr = 0 ;
2015-05-04 18:47:19 +00:00
this - > Reset ( 0 ) ;
2012-01-17 10:31:53 +00:00
2015-05-04 18:47:19 +00:00
m_Excite_Elem = NULL ;
m_Excit_Type = - 1 ;
m_SignalPeriod = 0 ;
2010-05-03 16:33:14 +00:00
}
Excitation : : ~ Excitation ( )
{
2015-05-04 18:47:19 +00:00
this - > Reset ( 0 ) ;
2011-07-25 12:56:27 +00:00
}
2010-05-03 16:33:14 +00:00
2011-07-25 12:56:27 +00:00
void Excitation : : Reset ( double timestep )
{
delete [ ] Signal_volt ;
Signal_volt = 0 ;
delete [ ] Signal_curr ;
Signal_curr = 0 ;
dT = timestep ;
m_nyquistTS = 0 ;
2012-07-23 10:09:16 +00:00
m_f_max = 0 ;
m_foi = 0 ;
2010-05-03 16:33:14 +00:00
}
2015-05-04 18:47:19 +00:00
bool Excitation : : setupExcitation ( TiXmlElement * Excite )
2010-05-03 16:33:14 +00:00
{
2010-12-06 12:04:37 +00:00
if ( ! Excite )
{
2012-07-17 11:23:00 +00:00
cerr < < " Excitation::setupExcitation: Error, can't read openEMS excitation settings... " < < endl ;
return false ;
}
2015-05-04 18:47:19 +00:00
m_Excite_Elem = Excite ;
double f0 = 0 ;
m_Excite_Elem - > QueryIntAttribute ( " Type " , & m_Excit_Type ) ;
m_SignalPeriod = 0 ;
switch ( m_Excit_Type )
{
case 1 : // sinusoidal excite
m_Excite_Elem - > QueryDoubleAttribute ( " f0 " , & f0 ) ;
m_SignalPeriod = 1 / f0 ;
break ;
}
return true ;
}
bool Excitation : : buildExcitationSignal ( unsigned int maxTS )
{
2012-07-17 11:23:00 +00:00
if ( dT < = 0 )
{
cerr < < " Excitation::setupExcitation: Error, invalid timestep... " < < endl ;
2010-05-03 16:33:14 +00:00
return false ;
}
double f0 = 0 ;
double fc = 0 ;
2012-01-17 10:31:53 +00:00
switch ( m_Excit_Type )
2010-05-03 16:33:14 +00:00
{
2010-12-06 12:04:37 +00:00
case 0 :
2015-05-04 18:47:19 +00:00
m_Excite_Elem - > QueryDoubleAttribute ( " f0 " , & f0 ) ;
m_Excite_Elem - > QueryDoubleAttribute ( " fc " , & fc ) ;
2010-12-06 12:04:37 +00:00
CalcGaussianPulsExcitation ( f0 , fc , maxTS ) ;
break ;
case 1 :
2015-05-04 18:47:19 +00:00
m_Excite_Elem - > QueryDoubleAttribute ( " f0 " , & f0 ) ;
2010-12-06 12:04:37 +00:00
CalcSinusExcitation ( f0 , maxTS ) ;
break ;
case 2 :
CalcDiracPulsExcitation ( ) ;
break ;
case 3 :
CalcStepExcitation ( ) ;
break ;
case 10 :
2015-05-04 18:47:19 +00:00
m_Excite_Elem - > QueryDoubleAttribute ( " f0 " , & f0 ) ;
CalcCustomExcitation ( f0 , maxTS , m_Excite_Elem - > Attribute ( " Function " ) ) ;
2010-12-06 12:04:37 +00:00
break ;
default :
2015-05-04 18:47:19 +00:00
cerr < < " Excitation::buildExcitationSignal: Unknown excitation type: \" " < < m_Excit_Type < < " \" !! " < < endl ;
2012-01-17 10:31:53 +00:00
m_Excit_Type = - 1 ;
2010-12-06 12:04:37 +00:00
return false ;
2010-05-03 16:33:14 +00:00
}
2010-08-23 20:52:08 +00:00
if ( GetNyquistNum ( ) = = 0 )
{
2015-05-04 18:47:19 +00:00
cerr < < " Excitation::buildExcitationSignal: Unknown error... excitation setup failed!! " < < endl ;
2010-05-03 16:33:14 +00:00
return false ;
}
return true ;
}
unsigned int Excitation : : GetMaxExcitationTimestep ( ) const
{
FDTD_FLOAT maxAmp = 0 ;
unsigned int maxStep = 0 ;
2010-12-06 12:04:37 +00:00
for ( unsigned int n = 1 ; n < Length + 1 ; + + n )
2010-05-03 16:33:14 +00:00
{
if ( fabs ( Signal_volt [ n ] ) > maxAmp )
{
maxAmp = fabs ( Signal_volt [ n ] ) ;
maxStep = n ;
}
}
return maxStep ;
}
2010-05-05 15:28:00 +00:00
void Excitation : : CalcGaussianPulsExcitation ( double f0 , double fc , int nTS )
2010-05-03 16:33:14 +00:00
{
if ( dT = = 0 ) return ;
Length = ( unsigned int ) ( 2.0 * 9.0 / ( 2.0 * PI * fc ) / dT ) ;
2011-03-18 09:06:28 +00:00
if ( Length > ( unsigned int ) nTS )
2010-05-05 15:28:00 +00:00
{
cerr < < " Operator::CalcGaussianPulsExcitation: Requested excitation pusle would be " < < Length < < " timesteps or " < < Length * dT < < " s long. Cutting to max number of timesteps! " < < endl ;
Length = ( unsigned int ) nTS ;
}
2010-05-03 16:33:14 +00:00
delete [ ] Signal_volt ;
delete [ ] Signal_curr ;
Signal_volt = new FDTD_FLOAT [ Length + 1 ] ;
Signal_curr = new FDTD_FLOAT [ Length + 1 ] ;
Signal_volt [ 0 ] = 0.0 ;
Signal_curr [ 0 ] = 0.0 ;
2010-12-06 12:04:37 +00:00
for ( unsigned int n = 1 ; n < Length + 1 ; + + n )
2010-05-03 16:33:14 +00:00
{
double t = ( n - 1 ) * dT ;
Signal_volt [ n ] = cos ( 2.0 * PI * f0 * ( t - 9.0 / ( 2.0 * PI * fc ) ) ) * exp ( - 1 * pow ( 2.0 * PI * fc * t / 3.0 - 3 , 2 ) ) ;
t + = 0.5 * dT ;
Signal_curr [ n ] = cos ( 2.0 * PI * f0 * ( t - 9.0 / ( 2.0 * PI * fc ) ) ) * exp ( - 1 * pow ( 2.0 * PI * fc * t / 3.0 - 3 , 2 ) ) ;
}
2012-07-23 10:09:16 +00:00
m_foi = f0 ;
m_f_max = f0 + fc ;
2010-06-28 16:05:03 +00:00
SetNyquistNum ( CalcNyquistNum ( f0 + fc , dT ) ) ;
2010-05-03 16:33:14 +00:00
}
void Excitation : : CalcDiracPulsExcitation ( )
{
if ( dT = = 0 ) return ;
Length = 1 ;
// cerr << "Operator::CalcDiracPulsExcitation: Length of the excite signal: " << ExciteLength << " timesteps" << endl;
delete [ ] Signal_volt ;
delete [ ] Signal_curr ;
Signal_volt = new FDTD_FLOAT [ Length + 1 ] ;
Signal_curr = new FDTD_FLOAT [ Length + 1 ] ;
Signal_volt [ 0 ] = 0.0 ;
Signal_volt [ 1 ] = 1.0 ;
Signal_curr [ 0 ] = 0.0 ;
Signal_curr [ 1 ] = 1.0 ;
2012-07-23 10:09:16 +00:00
m_foi = 0 ;
m_f_max = 0 ;
2010-05-03 16:33:14 +00:00
SetNyquistNum ( 1 ) ;
}
void Excitation : : CalcStepExcitation ( )
{
if ( dT = = 0 ) return ;
Length = 1 ;
delete [ ] Signal_volt ;
delete [ ] Signal_curr ;
Signal_volt = new FDTD_FLOAT [ Length + 1 ] ;
Signal_curr = new FDTD_FLOAT [ Length + 1 ] ;
Signal_volt [ 0 ] = 1.0 ;
Signal_volt [ 1 ] = 1.0 ;
Signal_curr [ 0 ] = 1.0 ;
Signal_curr [ 1 ] = 1.0 ;
2012-07-23 10:09:16 +00:00
m_foi = 0 ;
m_f_max = 0 ;
2010-05-03 16:33:14 +00:00
SetNyquistNum ( 1 ) ;
}
void Excitation : : CalcCustomExcitation ( double f0 , int nTS , string signal )
{
if ( dT = = 0 ) return ;
if ( nTS < = 0 ) return ;
Length = ( unsigned int ) ( nTS ) ;
// cerr << "Operator::CalcSinusExcitation: Length of the excite signal: " << ExciteLength << " timesteps" << endl;
delete [ ] Signal_volt ;
delete [ ] Signal_curr ;
Signal_volt = new FDTD_FLOAT [ Length + 1 ] ;
Signal_curr = new FDTD_FLOAT [ Length + 1 ] ;
Signal_volt [ 0 ] = 0.0 ;
Signal_curr [ 0 ] = 0.0 ;
FunctionParser fParse ;
fParse . AddConstant ( " pi " , 3.14159265358979323846 ) ;
fParse . AddConstant ( " e " , 2.71828182845904523536 ) ;
fParse . Parse ( signal , " t " ) ;
if ( fParse . GetParseErrorType ( ) ! = FunctionParser : : FP_NO_ERROR )
{
cerr < < " Operator::CalcCustomExcitation: Function Parser error: " < < fParse . ErrorMsg ( ) < < endl ;
exit ( 1 ) ;
}
double vars [ 1 ] ;
2010-12-06 12:04:37 +00:00
for ( unsigned int n = 1 ; n < Length + 1 ; + + n )
2010-05-03 16:33:14 +00:00
{
vars [ 0 ] = ( n - 1 ) * dT ;
Signal_volt [ n ] = fParse . Eval ( vars ) ;
vars [ 0 ] + = 0.5 * dT ;
Signal_curr [ n ] = fParse . Eval ( vars ) ;
}
2012-07-23 10:09:16 +00:00
m_f_max = f0 ;
m_foi = f0 ;
2010-06-28 16:05:03 +00:00
SetNyquistNum ( CalcNyquistNum ( f0 , dT ) ) ;
2010-05-03 16:33:14 +00:00
}
void Excitation : : CalcSinusExcitation ( double f0 , int nTS )
{
if ( dT = = 0 ) return ;
if ( nTS < = 0 ) return ;
2015-09-03 20:53:31 +00:00
Length = ( unsigned int ) ( 2.0 / f0 / dT ) ;
//cerr << "Operator::CalcSinusExcitation: Length of the excite signal: " << Length << " timesteps " << Length*dT << "s" << endl;
2010-05-03 16:33:14 +00:00
delete [ ] Signal_volt ;
delete [ ] Signal_curr ;
Signal_volt = new FDTD_FLOAT [ Length + 1 ] ;
Signal_curr = new FDTD_FLOAT [ Length + 1 ] ;
Signal_volt [ 0 ] = 0.0 ;
Signal_curr [ 0 ] = 0.0 ;
2010-12-06 12:04:37 +00:00
for ( unsigned int n = 1 ; n < Length + 1 ; + + n )
2010-05-03 16:33:14 +00:00
{
double t = ( n - 1 ) * dT ;
Signal_volt [ n ] = sin ( 2.0 * PI * f0 * t ) ;
t + = 0.5 * dT ;
Signal_curr [ n ] = sin ( 2.0 * PI * f0 * t ) ;
}
2012-07-23 10:09:16 +00:00
m_f_max = f0 ;
m_foi = f0 ;
2010-06-28 16:05:03 +00:00
SetNyquistNum ( CalcNyquistNum ( f0 , dT ) ) ;
2010-05-03 16:33:14 +00:00
}
2011-03-08 12:35:38 +00:00
void Excitation : : DumpVoltageExcite ( string filename )
{
ofstream file ;
file . open ( filename . c_str ( ) ) ;
if ( file . fail ( ) )
return ;
for ( unsigned int n = 1 ; n < Length + 1 ; + + n )
file < < ( n - 1 ) * dT < < " \t " < < Signal_volt [ n ] < < " \n " ;
file . close ( ) ;
}
void Excitation : : DumpCurrentExcite ( string filename )
{
ofstream file ;
file . open ( filename . c_str ( ) ) ;
if ( file . fail ( ) )
return ;
for ( unsigned int n = 1 ; n < Length + 1 ; + + n )
file < < ( n - 1 ) * dT + 0.5 * dT < < " \t " < < Signal_curr [ n ] < < " \n " ;
file . close ( ) ;
}