2010-03-11 15:47:40 +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/>.
*/
2010-03-01 08:19:39 +00:00
# include "engine.h"
2010-04-25 19:59:05 +00:00
# include "engine_extension.h"
2010-04-27 21:06:42 +00:00
# include "operator_extension.h"
2010-03-01 13:56:27 +00:00
# include "tools/array_ops.h"
2010-03-01 08:19:39 +00:00
2010-03-26 16:24:43 +00:00
//! \brief construct an Engine instance
//! it's the responsibility of the caller to free the returned pointer
2010-04-09 13:51:37 +00:00
Engine * Engine : : New ( const Operator * op )
2010-03-26 16:24:43 +00:00
{
2010-05-19 19:25:15 +00:00
cout < < " Create FDTD engine " < < endl ;
2010-03-26 16:24:43 +00:00
Engine * e = new Engine ( op ) ;
e - > Init ( ) ;
return e ;
}
2010-03-31 14:35:43 +00:00
Engine : : Engine ( const Operator * op )
2010-03-01 08:19:39 +00:00
{
2010-05-17 11:08:27 +00:00
m_type = BASIC ;
2010-05-17 11:05:41 +00:00
numTS = 0 ;
2010-03-01 13:56:27 +00:00
Op = op ;
2010-04-11 21:42:54 +00:00
for ( int n = 0 ; n < 3 ; + + n )
2010-05-09 18:27:17 +00:00
numLines [ n ] = Op - > GetOriginalNumLines ( n ) ;
volt = NULL ;
curr = NULL ;
2010-03-01 08:19:39 +00:00
}
Engine : : ~ Engine ( )
{
2010-04-11 21:42:54 +00:00
this - > Reset ( ) ;
2010-03-01 13:56:27 +00:00
}
void Engine : : Init ( )
{
2010-05-09 18:27:17 +00:00
Reset ( ) ;
2010-03-01 13:56:27 +00:00
numTS = 0 ;
2010-06-06 18:00:24 +00:00
volt = Create_N_3DArray < FDTD_FLOAT > ( numLines ) ;
curr = Create_N_3DArray < FDTD_FLOAT > ( numLines ) ;
2010-04-21 09:16:30 +00:00
2010-05-11 17:06:07 +00:00
file_et . open ( " et " ) ;
2010-07-16 08:33:54 +00:00
file_ht . open ( " ht " ) ;
2010-05-09 18:27:17 +00:00
InitExtensions ( ) ;
}
void Engine : : InitExtensions ( )
{
for ( size_t n = 0 ; n < Op - > GetNumberOfExtentions ( ) ; + + n )
{
Operator_Extension * op_ext = Op - > GetExtension ( n ) ;
Engine_Extension * eng_ext = op_ext - > CreateEngineExtention ( ) ;
if ( eng_ext )
{
eng_ext - > SetEngine ( this ) ;
m_Eng_exts . push_back ( eng_ext ) ;
}
}
2010-03-01 13:56:27 +00:00
}
void Engine : : Reset ( )
{
2010-04-11 21:42:54 +00:00
Delete_N_3DArray ( volt , numLines ) ;
2010-03-01 13:56:27 +00:00
volt = NULL ;
2010-04-11 21:42:54 +00:00
Delete_N_3DArray ( curr , numLines ) ;
2010-03-01 13:56:27 +00:00
curr = NULL ;
2010-04-21 09:16:30 +00:00
2010-05-11 17:06:07 +00:00
file_et . close ( ) ;
2010-07-16 08:33:54 +00:00
file_ht . close ( ) ;
2010-05-09 18:27:17 +00:00
for ( size_t n = 0 ; n < m_Eng_exts . size ( ) ; + + n )
delete m_Eng_exts . at ( n ) ;
m_Eng_exts . clear ( ) ;
2010-03-01 13:56:27 +00:00
}
2010-05-09 18:27:17 +00:00
void Engine : : UpdateVoltages ( unsigned int startX , unsigned int numX )
2010-03-01 13:56:27 +00:00
{
unsigned int pos [ 3 ] ;
2010-03-02 18:01:03 +00:00
bool shift [ 3 ] ;
2010-03-01 13:56:27 +00:00
2010-05-09 18:27:17 +00:00
pos [ 0 ] = startX ;
2010-04-09 13:51:37 +00:00
//voltage updates
2010-05-09 18:27:17 +00:00
for ( unsigned int posX = 0 ; posX < numX ; + + posX )
2010-03-01 13:56:27 +00:00
{
2010-04-09 13:51:37 +00:00
shift [ 0 ] = pos [ 0 ] ;
2010-04-11 21:42:54 +00:00
for ( pos [ 1 ] = 0 ; pos [ 1 ] < numLines [ 1 ] ; + + pos [ 1 ] )
2010-03-01 13:56:27 +00:00
{
2010-04-09 13:51:37 +00:00
shift [ 1 ] = pos [ 1 ] ;
2010-04-11 21:42:54 +00:00
for ( pos [ 2 ] = 0 ; pos [ 2 ] < numLines [ 2 ] ; + + pos [ 2 ] )
2010-03-01 13:56:27 +00:00
{
2010-04-09 13:51:37 +00:00
shift [ 2 ] = pos [ 2 ] ;
//do the updates here
//for x
volt [ 0 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] * = Op - > vv [ 0 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] ;
volt [ 0 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] + = Op - > vi [ 0 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] * ( curr [ 2 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] - curr [ 2 ] [ pos [ 0 ] ] [ pos [ 1 ] - shift [ 1 ] ] [ pos [ 2 ] ] - curr [ 1 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] + curr [ 1 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] - shift [ 2 ] ] ) ;
//for y
volt [ 1 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] * = Op - > vv [ 1 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] ;
volt [ 1 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] + = Op - > vi [ 1 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] * ( curr [ 0 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] - curr [ 0 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] - shift [ 2 ] ] - curr [ 2 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] + curr [ 2 ] [ pos [ 0 ] - shift [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] ) ;
//for z
volt [ 2 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] * = Op - > vv [ 2 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] ;
volt [ 2 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] + = Op - > vi [ 2 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] * ( curr [ 1 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] - curr [ 1 ] [ pos [ 0 ] - shift [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] - curr [ 0 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] + curr [ 0 ] [ pos [ 0 ] ] [ pos [ 1 ] - shift [ 1 ] ] [ pos [ 2 ] ] ) ;
2010-03-01 13:56:27 +00:00
}
}
2010-05-09 18:27:17 +00:00
+ + pos [ 0 ] ;
2010-04-09 13:51:37 +00:00
}
}
2010-03-01 13:56:27 +00:00
2010-04-13 16:28:46 +00:00
void Engine : : ApplyVoltageExcite ( )
2010-04-09 13:51:37 +00:00
{
int exc_pos ;
//soft voltage excitation here (E-field excite)
2010-05-03 16:33:14 +00:00
for ( unsigned int n = 0 ; n < Op - > Exc - > E_Count ; + + n )
2010-04-09 13:51:37 +00:00
{
2010-05-03 16:33:14 +00:00
exc_pos = ( int ) numTS - ( int ) Op - > Exc - > E_delay [ n ] ;
exc_pos * = ( exc_pos > 0 & & exc_pos < = ( int ) Op - > Exc - > Length ) ;
2010-03-02 13:54:50 +00:00
// if (n==0) cerr << numTS << " => " << Op->ExciteSignal[exc_pos] << endl;
2010-05-03 16:33:14 +00:00
GetVolt ( Op - > Exc - > E_dir [ n ] , Op - > Exc - > E_index [ 0 ] [ n ] , Op - > Exc - > E_index [ 1 ] [ n ] , Op - > Exc - > E_index [ 2 ] [ n ] ) + = Op - > Exc - > E_amp [ n ] * Op - > Exc - > Signal_volt [ exc_pos ] ;
2010-04-09 13:51:37 +00:00
}
2010-04-21 09:16:30 +00:00
2010-07-16 08:33:54 +00:00
// write the first excitation into the file "et"
2010-05-11 17:06:07 +00:00
if ( numTS < Op - > Exc - > Length )
file_et < < numTS * Op - > GetTimestep ( ) < < " \t " < < Op - > Exc - > Signal_volt [ numTS ] < < " \n " ; // do not use std::endl here, because it will do an implicit flush
else
file_et < < numTS * Op - > GetTimestep ( ) < < " \t 0 " < < " \n " ; // do not use std::endl here, because it will do an implicit flush
2010-04-09 13:51:37 +00:00
}
2010-03-01 13:56:27 +00:00
2010-05-09 18:27:17 +00:00
void Engine : : UpdateCurrents ( unsigned int startX , unsigned int numX )
2010-04-09 13:51:37 +00:00
{
unsigned int pos [ 3 ] ;
2010-05-09 18:27:17 +00:00
pos [ 0 ] = startX ;
for ( unsigned int posX = 0 ; posX < numX ; + + posX )
2010-04-09 13:51:37 +00:00
{
2010-04-11 21:42:54 +00:00
for ( pos [ 1 ] = 0 ; pos [ 1 ] < numLines [ 1 ] - 1 ; + + pos [ 1 ] )
2010-03-01 13:56:27 +00:00
{
2010-04-11 21:42:54 +00:00
for ( pos [ 2 ] = 0 ; pos [ 2 ] < numLines [ 2 ] - 1 ; + + pos [ 2 ] )
2010-03-01 13:56:27 +00:00
{
2010-04-09 13:51:37 +00:00
//do the updates here
//for x
curr [ 0 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] * = Op - > ii [ 0 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] ;
curr [ 0 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] + = Op - > iv [ 0 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] * ( volt [ 2 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] - volt [ 2 ] [ pos [ 0 ] ] [ pos [ 1 ] + 1 ] [ pos [ 2 ] ] - volt [ 1 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] + volt [ 1 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] + 1 ] ) ;
//for y
curr [ 1 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] * = Op - > ii [ 1 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] ;
curr [ 1 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] + = Op - > iv [ 1 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] * ( volt [ 0 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] - volt [ 0 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] + 1 ] - volt [ 2 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] + volt [ 2 ] [ pos [ 0 ] + 1 ] [ pos [ 1 ] ] [ pos [ 2 ] ] ) ;
//for z
curr [ 2 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] * = Op - > ii [ 2 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] ;
curr [ 2 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] + = Op - > iv [ 2 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] * ( volt [ 1 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] - volt [ 1 ] [ pos [ 0 ] + 1 ] [ pos [ 1 ] ] [ pos [ 2 ] ] - volt [ 0 ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] + volt [ 0 ] [ pos [ 0 ] ] [ pos [ 1 ] + 1 ] [ pos [ 2 ] ] ) ;
2010-03-01 13:56:27 +00:00
}
}
2010-05-09 18:27:17 +00:00
+ + pos [ 0 ] ;
2010-04-09 13:51:37 +00:00
}
}
2010-04-13 16:28:46 +00:00
void Engine : : ApplyCurrentExcite ( )
2010-04-09 13:51:37 +00:00
{
2010-04-28 22:28:07 +00:00
int exc_pos ;
//soft current excitation here (H-field excite)
2010-05-03 16:33:14 +00:00
for ( unsigned int n = 0 ; n < Op - > Exc - > Curr_Count ; + + n )
2010-04-28 22:28:07 +00:00
{
2010-05-03 16:33:14 +00:00
exc_pos = ( int ) numTS - ( int ) Op - > Exc - > Curr_delay [ n ] ;
exc_pos * = ( exc_pos > 0 & & exc_pos < = ( int ) Op - > Exc - > Length ) ;
2010-04-28 22:28:07 +00:00
// if (n==0) cerr << numTS << " => " << Op->ExciteSignal[exc_pos] << endl;
2010-05-03 16:33:14 +00:00
GetCurr ( Op - > Exc - > Curr_dir [ n ] , Op - > Exc - > Curr_index [ 0 ] [ n ] , Op - > Exc - > Curr_index [ 1 ] [ n ] , Op - > Exc - > Curr_index [ 2 ] [ n ] ) + = Op - > Exc - > Curr_amp [ n ] * Op - > Exc - > Signal_curr [ exc_pos ] ;
2010-07-16 08:33:54 +00:00
if ( numTS = = 0 )
cout < < " Engine::ApplyCurrentExcite(): n= " < < n < < " dir= " < < Op - > Exc - > Curr_dir [ n ] < < " coords= " < < Op - > Exc - > Curr_index [ 0 ] [ n ] < < " , " < < Op - > Exc - > Curr_index [ 1 ] [ n ] < < " , " < < Op - > Exc - > Curr_index [ 2 ] [ n ] < < " amp= " < < Op - > Exc - > Curr_amp [ n ] < < endl ;
2010-04-28 22:28:07 +00:00
}
2010-07-16 08:33:54 +00:00
// write the first excitation into the file "ht"
if ( numTS < Op - > Exc - > Length )
file_ht < < ( numTS + 0.5 ) * Op - > GetTimestep ( ) < < " \t " < < Op - > Exc - > Curr_amp [ 0 ] * Op - > Exc - > Signal_curr [ numTS ] < < " \n " ; // do not use std::endl here, because it will do an implicit flush
else
file_ht < < ( numTS + 0.5 ) * Op - > GetTimestep ( ) < < " \t 0 " < < " \n " ; // do not use std::endl here, because it will do an implicit flush
2010-04-09 13:51:37 +00:00
}
2010-03-01 13:56:27 +00:00
2010-04-09 13:51:37 +00:00
bool Engine : : IterateTS ( unsigned int iterTS )
{
for ( unsigned int iter = 0 ; iter < iterTS ; + + iter )
{
2010-04-25 19:59:05 +00:00
//voltage updates with extensions
for ( size_t n = 0 ; n < m_Eng_exts . size ( ) ; + + n )
m_Eng_exts . at ( n ) - > DoPreVoltageUpdates ( ) ;
2010-05-09 18:27:17 +00:00
UpdateVoltages ( 0 , numLines [ 0 ] ) ;
2010-04-25 19:59:05 +00:00
for ( size_t n = 0 ; n < m_Eng_exts . size ( ) ; + + n )
m_Eng_exts . at ( n ) - > DoPostVoltageUpdates ( ) ;
for ( size_t n = 0 ; n < m_Eng_exts . size ( ) ; + + n )
m_Eng_exts . at ( n ) - > Apply2Voltages ( ) ;
2010-04-09 13:51:37 +00:00
ApplyVoltageExcite ( ) ;
2010-04-25 19:59:05 +00:00
//current updates with extensions
for ( size_t n = 0 ; n < m_Eng_exts . size ( ) ; + + n )
m_Eng_exts . at ( n ) - > DoPreCurrentUpdates ( ) ;
2010-05-09 18:27:17 +00:00
UpdateCurrents ( 0 , numLines [ 0 ] - 1 ) ;
2010-04-25 19:59:05 +00:00
for ( size_t n = 0 ; n < m_Eng_exts . size ( ) ; + + n )
m_Eng_exts . at ( n ) - > DoPostCurrentUpdates ( ) ;
for ( size_t n = 0 ; n < m_Eng_exts . size ( ) ; + + n )
m_Eng_exts . at ( n ) - > Apply2Current ( ) ;
2010-04-09 13:51:37 +00:00
ApplyCurrentExcite ( ) ;
2010-04-25 19:59:05 +00:00
2010-03-01 13:56:27 +00:00
+ + numTS ;
}
return true ;
2010-03-01 08:19:39 +00:00
}