/* * 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 "tinyxml.h" #include "excitation.h" using namespace std; Excitation::Excitation() { Signal_volt = 0; Signal_curr = 0; this->Reset(0); m_Excite_Elem = NULL; m_Excit_Type = -1; 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::setupExcitation( TiXmlElement* Excite) { if (!Excite) { cerr << "Excitation::setupExcitation: Error, can't read openEMS excitation settings... " << endl; return false; } 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) { if (dT<=0) { cerr << "Excitation::setupExcitation: Error, invalid timestep... " << endl; return false; } double f0=0; double fc=0; switch (m_Excit_Type) { case 0: m_Excite_Elem->QueryDoubleAttribute("f0",&f0); m_Excite_Elem->QueryDoubleAttribute("fc",&fc); CalcGaussianPulsExcitation(f0,fc,maxTS); break; case 1: m_Excite_Elem->QueryDoubleAttribute("f0",&f0); CalcSinusExcitation(f0,maxTS); break; case 2: CalcDiracPulsExcitation(); break; case 3: CalcStepExcitation(); break; case 10: m_Excite_Elem->QueryDoubleAttribute("f0",&f0); CalcCustomExcitation(f0,maxTS,m_Excite_Elem->Attribute("Function")); break; default: cerr << "Excitation::buildExcitationSignal: Unknown excitation type: \"" << m_Excit_Type<< "\" !!" << endl; m_Excit_Type = -1; 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