/*
* 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 "tools/array_ops.h"
#include "tools/useful.h"
#include
#include
#include "fparser.hh"
#include "excitation.h"
using namespace std;
Excitation::Excitation()
{
Signal_volt = 0;
Signal_curr = 0;
this->Reset(0);
m_Excit_Type = Excitation::UNDEFINED;
m_SignalPeriod = 0;
}
Excitation::~Excitation()
{
this->Reset(0);
}
void Excitation::Reset( double timestep )
{
delete[] Signal_volt;
Signal_volt = 0;
delete[] Signal_curr;
Signal_curr = 0;
dT = timestep;
m_nyquistTS = 0;
m_f_max = 0;
m_foi = 0;
}
bool Excitation::SetupGaussianPulse(double f0, double fc)
{
m_Excit_Type = Excitation::GaissianPulse;
m_f0 = f0;
m_fc = fc;
m_f_max = f0+fc;
m_SignalPeriod = 0;
}
bool Excitation::SetupSinusoidal(double f0)
{
m_Excit_Type = Excitation::Sinusoidal;
m_f0 = f0;
m_f_max = f0;
m_SignalPeriod = 1/f0;
}
bool Excitation::SetupDiracPulse(double fmax)
{
m_Excit_Type = Excitation::DiracPulse;
m_SignalPeriod = 0;
m_f_max = fmax;
}
bool Excitation::SetupStepExcite(double fmax)
{
m_Excit_Type = Excitation::Step;
m_SignalPeriod = 0;
m_f_max = fmax;
}
bool Excitation::SetupCustomExcite(string str, double f0, double fmax)
{
m_Excit_Type = Excitation::CustomExcite;
m_CustomExc_Str = str;
m_f0 = f0;
m_SignalPeriod = 0;
m_f_max = fmax;
}
bool Excitation::buildExcitationSignal(unsigned int maxTS)
{
if (dT<=0)
{
cerr << "Excitation::setupExcitation: Error, invalid timestep... " << endl;
return false;
}
switch (m_Excit_Type)
{
case Excitation::GaissianPulse:
CalcGaussianPulsExcitation(m_f0,m_fc,maxTS);
break;
case Excitation::Sinusoidal:
CalcSinusExcitation(m_f0,maxTS);
break;
case Excitation::DiracPulse:
CalcDiracPulsExcitation();
break;
case Excitation::Step:
CalcStepExcitation();
break;
case Excitation::CustomExcite:
CalcCustomExcitation(m_f0,maxTS,m_CustomExc_Str);
break;
default:
cerr << "Excitation::buildExcitationSignal: Unknown excitation type: \"" << m_Excit_Type<< "\" !!" << endl;
m_Excit_Type = Excitation::UNDEFINED;
return false;
}
if (GetNyquistNum() == 0)
{
cerr << "Excitation::buildExcitationSignal: Unknown error... excitation setup failed!!" << endl;
return false;
}
return true;
}
unsigned int Excitation::GetMaxExcitationTimestep() const
{
FDTD_FLOAT maxAmp=0;
unsigned int maxStep=0;
for (unsigned int n=1; nmaxAmp)
{
maxAmp = fabs(Signal_volt[n]);
maxStep = n;
}
}
return maxStep;
}
void Excitation::CalcGaussianPulsExcitation(double f0, double fc, int nTS)
{
if (dT==0) return;
Length = (unsigned int)(2.0 * 9.0/(2.0*PI*fc) / dT);
if (Length>(unsigned int)nTS)
{
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;
}
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;
for (unsigned int n=1; n