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 "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-12-13 21:33:26 +00:00
m_Excit_Type = Excitation : : UNDEFINED ;
2015-05-04 18:47:19 +00:00
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
}
2018-06-24 08:13:28 +00:00
void Excitation : : SetupGaussianPulse ( double f0 , double fc )
2010-05-03 16:33:14 +00:00
{
2015-12-13 21:33:26 +00:00
m_Excit_Type = Excitation : : GaissianPulse ;
m_f0 = f0 ;
m_fc = fc ;
m_f_max = f0 + fc ;
m_SignalPeriod = 0 ;
}
2012-07-17 11:23:00 +00:00
2018-06-24 08:13:28 +00:00
void Excitation : : SetupSinusoidal ( double f0 )
2015-12-13 21:33:26 +00:00
{
m_Excit_Type = Excitation : : Sinusoidal ;
m_f0 = f0 ;
m_f_max = f0 ;
m_SignalPeriod = 1 / f0 ;
}
2015-05-04 18:47:19 +00:00
2018-06-24 08:13:28 +00:00
void Excitation : : SetupDiracPulse ( double fmax )
2015-12-13 21:33:26 +00:00
{
m_Excit_Type = Excitation : : DiracPulse ;
2015-05-04 18:47:19 +00:00
m_SignalPeriod = 0 ;
2015-12-13 21:33:26 +00:00
m_f_max = fmax ;
}
2018-06-24 08:13:28 +00:00
void Excitation : : SetupStepExcite ( double fmax )
2015-12-13 21:33:26 +00:00
{
m_Excit_Type = Excitation : : Step ;
m_SignalPeriod = 0 ;
m_f_max = fmax ;
}
2018-06-24 08:13:28 +00:00
void Excitation : : SetupCustomExcite ( string str , double f0 , double fmax )
2015-12-13 21:33:26 +00:00
{
m_Excit_Type = Excitation : : CustomExcite ;
m_CustomExc_Str = str ;
m_f0 = f0 ;
m_SignalPeriod = 0 ;
m_f_max = fmax ;
2015-05-04 18:47:19 +00:00
}
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 ;
}
2012-01-17 10:31:53 +00:00
switch ( m_Excit_Type )
2010-05-03 16:33:14 +00:00
{
2015-12-13 21:33:26 +00:00
case Excitation : : GaissianPulse :
CalcGaussianPulsExcitation ( m_f0 , m_fc , maxTS ) ;
2010-12-06 12:04:37 +00:00
break ;
2015-12-13 21:33:26 +00:00
case Excitation : : Sinusoidal :
CalcSinusExcitation ( m_f0 , maxTS ) ;
2010-12-06 12:04:37 +00:00
break ;
2015-12-13 21:33:26 +00:00
case Excitation : : DiracPulse :
2010-12-06 12:04:37 +00:00
CalcDiracPulsExcitation ( ) ;
break ;
2015-12-13 21:33:26 +00:00
case Excitation : : Step :
2010-12-06 12:04:37 +00:00
CalcStepExcitation ( ) ;
break ;
2015-12-13 21:33:26 +00:00
case Excitation : : CustomExcite :
CalcCustomExcitation ( m_f0 , maxTS , m_CustomExc_Str ) ;
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 ;
2015-12-13 21:33:26 +00:00
m_Excit_Type = Excitation : : UNDEFINED ;
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 ;
2017-02-11 17:17:54 +00:00
for ( unsigned int n = 0 ; n < Length ; + + 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 ;
2017-02-11 17:17:54 +00:00
Length = ( unsigned int ) ceil ( 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 ;
2017-02-11 17:17:54 +00:00
Signal_volt = new FDTD_FLOAT [ Length ] ;
Signal_curr = new FDTD_FLOAT [ Length ] ;
for ( unsigned int n = 0 ; n < Length ; + + n )
2010-05-03 16:33:14 +00:00
{
2017-02-11 17:17:54 +00:00
double t = n * dT ;
2010-05-03 16:33:14 +00:00
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 ;
2017-02-11 17:17:54 +00:00
Length = 2 ;
2010-05-03 16:33:14 +00:00
// cerr << "Operator::CalcDiracPulsExcitation: Length of the excite signal: " << ExciteLength << " timesteps" << endl;
delete [ ] Signal_volt ;
delete [ ] Signal_curr ;
2017-02-11 17:17:54 +00:00
Signal_volt = new FDTD_FLOAT [ Length ] ;
Signal_curr = new FDTD_FLOAT [ Length ] ;
2010-05-03 16:33:14 +00:00
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 ;
2017-02-11 17:17:54 +00:00
Length = 2 ;
2010-05-03 16:33:14 +00:00
delete [ ] Signal_volt ;
delete [ ] Signal_curr ;
2017-02-11 17:17:54 +00:00
Signal_volt = new FDTD_FLOAT [ Length ] ;
Signal_curr = new FDTD_FLOAT [ Length ] ;
2010-05-03 16:33:14 +00:00
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 ;
2017-02-11 17:17:54 +00:00
Signal_volt = new FDTD_FLOAT [ Length ] ;
Signal_curr = new FDTD_FLOAT [ Length ] ;
2022-05-31 17:47:44 +00:00
std : : setlocale ( LC_NUMERIC , " en_US.UTF-8 " ) ;
2010-05-03 16:33:14 +00:00
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 ] ;
2017-02-11 17:17:54 +00:00
for ( unsigned int n = 0 ; n < Length ; + + n )
2010-05-03 16:33:14 +00:00
{
2017-02-11 17:17:54 +00:00
vars [ 0 ] = n * dT ;
2010-05-03 16:33:14 +00:00
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 ;
2017-02-11 17:17:54 +00:00
Length = ( unsigned int ) round ( 2.0 / f0 / dT ) ;
2010-05-03 16:33:14 +00:00
delete [ ] Signal_volt ;
delete [ ] Signal_curr ;
2017-02-11 17:17:54 +00:00
Signal_volt = new FDTD_FLOAT [ Length ] ;
Signal_curr = new FDTD_FLOAT [ Length ] ;
2010-05-03 16:33:14 +00:00
Signal_volt [ 0 ] = 0.0 ;
Signal_curr [ 0 ] = 0.0 ;
2017-02-11 17:17:54 +00:00
for ( unsigned int n = 1 ; n < Length ; + + n )
2010-05-03 16:33:14 +00:00
{
2017-02-11 17:17:54 +00:00
double t = n * dT ;
2010-05-03 16:33:14 +00:00
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 ;
2017-02-11 17:17:54 +00:00
for ( unsigned int n = 0 ; n < Length ; + + n )
file < < n * dT < < " \t " < < Signal_volt [ n ] < < " \n " ;
2011-03-08 12:35:38 +00:00
file . close ( ) ;
}
void Excitation : : DumpCurrentExcite ( string filename )
{
ofstream file ;
file . open ( filename . c_str ( ) ) ;
if ( file . fail ( ) )
return ;
2017-02-11 17:17:54 +00:00
for ( unsigned int n = 0 ; n < Length ; + + n )
file < < n * dT + 0.5 * dT < < " \t " < < Signal_curr [ n ] < < " \n " ;
2011-03-08 12:35:38 +00:00
file . close ( ) ;
}