/*
* Copyright (C) 2011 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_ext_excitation.h"
#include "engine_ext_excitation.h"
#include "FDTD/excitation.h"
#include "ContinuousStructure.h"
Operator_Ext_Excitation::Operator_Ext_Excitation(Operator* op) : Operator_Extension(op)
{
Init();
}
Operator_Ext_Excitation::~Operator_Ext_Excitation()
{
Reset();
}
Operator_Extension* Operator_Ext_Excitation::Clone(Operator* op)
{
Operator_Ext_Excitation* clone = new Operator_Ext_Excitation(op, this);
return clone;
}
void Operator_Ext_Excitation::Init()
{
Operator_Extension::Init();
Volt_delay = 0;
Volt_amp = 0;
Volt_dir = 0;
Volt_Count = 0;
Curr_delay = 0;
Curr_amp = 0;
Curr_dir = 0;
Curr_Count = 0;
for (int n=0; n<3; ++n)
{
Volt_index[n] = 0;
Curr_index[n] = 0;
Volt_Count_Dir[n] = 0;
Curr_Count_Dir[n] = 0;
}
m_Exc = 0;
}
void Operator_Ext_Excitation::Reset()
{
Operator_Extension::Reset();
delete[] Volt_delay;
Volt_delay = 0;
delete[] Volt_dir;
Volt_dir = 0;
delete[] Volt_amp;
Volt_amp = 0;
delete[] Curr_delay;
Curr_delay = 0;
delete[] Curr_dir;
Curr_dir = 0;
delete[] Curr_amp;
Curr_amp = 0;
Volt_Count = 0;
Curr_Count = 0;
for (int n=0; n<3; ++n)
{
delete[] Volt_index[n];
Volt_index[n] = 0;
delete[] Curr_index[n];
Curr_index[n] = 0;
Volt_Count_Dir[n] = 0;
Curr_Count_Dir[n] = 0;
}
}
Operator_Ext_Excitation::Operator_Ext_Excitation(Operator* op, Operator_Ext_Excitation* op_ext) : Operator_Extension(op, op_ext)
{
Init();
}
bool Operator_Ext_Excitation::BuildExtension()
{
m_Exc = m_Op->GetExcitationSignal();
double dT = m_Op->GetTimestep();
if (dT==0)
return false;
if (m_Exc==0)
return false;
Reset();
ContinuousStructure* CSX = m_Op->GetGeometryCSX();
unsigned int pos[3];
double amp=0;
vector volt_vIndex[3];
vector volt_vExcit;
vector volt_vDelay;
vector volt_vDir;
double volt_coord[3];
vector curr_vIndex[3];
vector curr_vExcit;
vector curr_vDelay;
vector curr_vDir;
double curr_coord[3];
vector vec_prop = CSX->GetPropertyByType(CSProperties::EXCITATION);
if (vec_prop.size()==0)
{
cerr << "Operator::CalcFieldExcitation: Warning, no excitation properties found" << endl;
return false;
}
CSPropExcitation* elec=NULL;
CSProperties* prop=NULL;
int priority=0;
unsigned int numLines[] = {m_Op->GetOriginalNumLines(0),m_Op->GetOriginalNumLines(1),m_Op->GetOriginalNumLines(2)};
for (pos[2]=0; pos[2]GetYeeCoords(n,pos,volt_coord,false)==false)
continue;
if (m_CC_R0_included && (n==2) && (pos[0]==0))
volt_coord[1] = m_Op->GetDiscLine(1,0);
if (m_CC_R0_included && (n==1) && (pos[0]==0))
continue;
for (size_t p=0; pToExcitation();
if (elec==NULL)
continue;
if (prop->CheckCoordInPrimitive(volt_coord,priority,true))
{
if ((elec->GetActiveDir(n)) && ( (elec->GetExcitType()==0) || (elec->GetExcitType()==1) ))//&& (pos[n]GetWeightedExcitation(n,volt_coord)*m_Op->GetEdgeLength(n,pos);// delta[n]*gridDelta;
if (amp!=0)
{
volt_vExcit.push_back(amp);
volt_vDelay.push_back((unsigned int)(elec->GetDelay()/dT));
volt_vDir.push_back(n);
volt_vIndex[0].push_back(pos[0]);
volt_vIndex[1].push_back(pos[1]);
volt_vIndex[2].push_back(pos[2]);
}
if (elec->GetExcitType()==1) //hard excite
{
m_Op->SetVV(n,pos[0],pos[1],pos[2], 0 );
m_Op->SetVI(n,pos[0],pos[1],pos[2], 0 );
}
}
}
}
}
//magnetic field excite
for (int n=0; n<3; ++n)
{
if ((pos[0]>=numLines[0]-1) || (pos[1]>=numLines[1]-1) || (pos[2]>=numLines[2]-1))
continue; //skip the last H-Line which is outside the FDTD-domain
if (m_Op->GetYeeCoords(n,pos,curr_coord,true)==false)
continue;
for (size_t p=0; pToExcitation();
if (elec==NULL)
continue;
if (prop->CheckCoordInPrimitive(curr_coord,priority,true))
{
if ((elec->GetActiveDir(n)) && ( (elec->GetExcitType()==2) || (elec->GetExcitType()==3) ))
{
amp = elec->GetWeightedExcitation(n,curr_coord)*m_Op->GetEdgeLength(n,pos,true);// delta[n]*gridDelta;
if (amp!=0)
{
curr_vExcit.push_back(amp);
curr_vDelay.push_back((unsigned int)(elec->GetDelay()/dT));
curr_vDir.push_back(n);
curr_vIndex[0].push_back(pos[0]);
curr_vIndex[1].push_back(pos[1]);
curr_vIndex[2].push_back(pos[2]);
}
if (elec->GetExcitType()==3) //hard excite
{
m_Op->SetII(n,pos[0],pos[1],pos[2], 0 );
m_Op->SetIV(n,pos[0],pos[1],pos[2], 0 );
}
}
}
}
}
}
}
}
//special treatment for primitives of type curve (treated as wires) see also Calc_PEC
double p1[3];
double p2[3];
struct Operator::Grid_Path path;
for (size_t p=0; pToExcitation();
for (size_t n=0; nGetQtyPrimitives(); ++n)
{
CSPrimitives* prim = prop->GetPrimitive(n);
CSPrimCurve* curv = prim->ToCurve();
if (curv)
{
for (size_t i=1; iGetNumberOfPoints(); ++i)
{
curv->GetPoint(i-1,p1);
curv->GetPoint(i,p2);
path = m_Op->FindPath(p1,p2);
if (path.dir.size()>0)
prim->SetPrimitiveUsed(true);
for (size_t t=0; tGetYeeCoords(n,pos,volt_coord,false);
if (elec!=NULL)
{
if ((elec->GetActiveDir(n)) && (pos[n]GetExcitType()==0) || (elec->GetExcitType()==1) ))
{
amp = elec->GetWeightedExcitation(n,volt_coord)*m_Op->GetEdgeLength(n,pos);
if (amp!=0)
{
volt_vExcit.push_back(amp);
volt_vDelay.push_back((unsigned int)(elec->GetDelay()/dT));
volt_vDir.push_back(n);
volt_vIndex[0].push_back(pos[0]);
volt_vIndex[1].push_back(pos[1]);
volt_vIndex[2].push_back(pos[2]);
}
if (elec->GetExcitType()==1) //hard excite
{
m_Op->SetVV(n,pos[0],pos[1],pos[2], 0 );
m_Op->SetVI(n,pos[0],pos[1],pos[2], 0 );
}
}
}
}
}
}
}
}
// set voltage excitations
setupVoltageExcitation( volt_vIndex, volt_vExcit, volt_vDelay, volt_vDir );
// set current excitations
setupCurrentExcitation( curr_vIndex, curr_vExcit, curr_vDelay, curr_vDir );
return true;
}
void Operator_Ext_Excitation::setupVoltageExcitation( vector const volt_vIndex[3], vector const& volt_vExcit,
vector const& volt_vDelay, vector const& volt_vDir )
{
Volt_Count = volt_vIndex[0].size();
for (int n=0; n<3; n++)
{
Volt_Count_Dir[n]=0;
delete[] Volt_index[n];
Volt_index[n] = new unsigned int[Volt_Count];
}
delete[] Volt_delay;
delete[] Volt_amp;
delete[] Volt_dir;
Volt_delay = new unsigned int[Volt_Count];
Volt_amp = new FDTD_FLOAT[Volt_Count];
Volt_dir = new unsigned short[Volt_Count];
// cerr << "Excitation::setupVoltageExcitation(): Number of voltage excitation points: " << Volt_Count << endl;
// if (Volt_Count==0)
// cerr << "No E-Field/voltage excitation found!" << endl;
for (int n=0; n<3; n++)
for (unsigned int i=0; i const curr_vIndex[3], vector const& curr_vExcit,
vector const& curr_vDelay, vector const& curr_vDir )
{
Curr_Count = curr_vIndex[0].size();
for (int n=0; n<3; n++)
{
Curr_Count_Dir[n]=0;
delete[] Curr_index[n];
Curr_index[n] = new unsigned int[Curr_Count];
}
delete[] Curr_delay;
delete[] Curr_amp;
delete[] Curr_dir;
Curr_delay = new unsigned int[Curr_Count];
Curr_amp = new FDTD_FLOAT[Curr_Count];
Curr_dir = new unsigned short[Curr_Count];
// cerr << "Excitation::setupCurrentExcitation(): Number of current excitation points: " << Curr_Count << endl;
// if (Curr_Count==0)
// cerr << "No H-Field/current excitation found!" << endl;
for (int n=0; n<3; ++n)
for (unsigned int i=0; iGetLength() << endl;
cout << "Excitation Length (s)\t: " << m_Exc->GetLength()*m_Op->GetTimestep() << endl;
}