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 18:35:28 +00:00
# include <fstream>
2011-07-22 07:58:02 +00:00
# include <algorithm>
2010-03-01 08:19:39 +00:00
# include "operator.h"
2010-05-08 16:12:44 +00:00
# include "engine.h"
2010-12-06 14:30:47 +00:00
# include "extensions/operator_extension.h"
2011-03-16 15:26:01 +00:00
# include "extensions/operator_ext_excitation.h"
2010-12-06 09:44:25 +00:00
# include "Common/processfields.h"
2010-03-01 13:56:27 +00:00
# include "tools/array_ops.h"
2012-02-02 09:20:49 +00:00
# include "tools/vtk_file_writer.h"
2010-04-07 14:31:23 +00:00
# include "fparser.hh"
2012-07-16 15:15:10 +00:00
# include "extensions/operator_ext_excitation.h"
2010-03-01 08:19:39 +00:00
2013-02-06 15:42:03 +00:00
# include "vtkPolyData.h"
# include "vtkCellArray.h"
# include "vtkPoints.h"
# include "vtkXMLPolyDataWriter.h"
2012-12-03 12:59:39 +00:00
# include "CSPrimBox.h"
# include "CSPrimCurve.h"
# include "CSPropMaterial.h"
# include "CSPropLumpedElement.h"
2010-04-09 13:51:37 +00:00
Operator * Operator : : New ( )
{
2010-05-19 19:25:15 +00:00
cout < < " Create FDTD operator " < < endl ;
2010-04-09 13:51:37 +00:00
Operator * op = new Operator ( ) ;
op - > Init ( ) ;
return op ;
}
2010-12-06 08:59:42 +00:00
Operator : : Operator ( ) : Operator_Base ( )
2010-03-01 08:19:39 +00:00
{
2012-07-16 15:15:10 +00:00
m_Exc = 0 ;
2010-09-08 14:07:28 +00:00
m_InvaildTimestep = false ;
2011-02-16 14:28:14 +00:00
m_TimeStepVar = 3 ;
2010-03-01 08:19:39 +00:00
}
Operator : : ~ Operator ( )
{
2010-12-06 12:04:37 +00:00
for ( size_t n = 0 ; n < m_Op_exts . size ( ) ; + + n )
2010-04-27 21:06:42 +00:00
delete m_Op_exts . at ( n ) ;
m_Op_exts . clear ( ) ;
2011-01-24 10:11:45 +00:00
Delete ( ) ;
2010-03-01 08:19:39 +00:00
}
2014-01-06 14:40:39 +00:00
Engine * Operator : : CreateEngine ( )
2010-05-08 16:12:44 +00:00
{
2014-01-06 14:40:39 +00:00
m_Engine = Engine : : New ( this ) ;
return m_Engine ;
2010-05-08 16:12:44 +00:00
}
2010-03-01 08:19:39 +00:00
void Operator : : Init ( )
{
2011-03-18 13:17:09 +00:00
CSX = NULL ;
2014-01-06 14:40:39 +00:00
m_Engine = NULL ;
2011-03-18 13:17:09 +00:00
2010-12-06 08:59:42 +00:00
Operator_Base : : Init ( ) ;
2010-03-01 13:56:27 +00:00
vv = NULL ;
vi = NULL ;
iv = NULL ;
ii = NULL ;
2010-03-05 13:20:25 +00:00
2011-01-07 09:45:26 +00:00
m_epsR = NULL ;
m_kappa = NULL ;
m_mueR = NULL ;
m_sigma = NULL ;
2010-03-05 13:20:25 +00:00
MainOp = NULL ;
2010-12-06 12:04:37 +00:00
for ( int n = 0 ; n < 3 ; + + n )
2010-03-05 13:20:25 +00:00
{
EC_C [ n ] = NULL ;
EC_G [ n ] = NULL ;
EC_L [ n ] = NULL ;
EC_R [ n ] = NULL ;
}
2010-04-28 20:01:03 +00:00
2012-07-16 15:15:10 +00:00
m_Exc = 0 ;
2012-09-27 12:20:20 +00:00
m_TimeStepFactor = 1 ;
2013-12-28 20:02:49 +00:00
SetMaterialAvgMethod ( QuarterCell ) ;
2010-03-01 08:19:39 +00:00
}
2011-01-24 10:11:45 +00:00
void Operator : : Delete ( )
2010-03-01 08:19:39 +00:00
{
2011-01-24 10:11:45 +00:00
CSX = NULL ;
2010-03-01 13:56:27 +00:00
Delete_N_3DArray ( vv , numLines ) ;
Delete_N_3DArray ( vi , numLines ) ;
Delete_N_3DArray ( iv , numLines ) ;
Delete_N_3DArray ( ii , numLines ) ;
2011-01-24 10:11:45 +00:00
vv = vi = iv = ii = 0 ;
delete MainOp ; MainOp = 0 ;
2010-12-06 12:04:37 +00:00
for ( int n = 0 ; n < 3 ; + + n )
2010-03-05 13:20:25 +00:00
{
2011-01-24 10:11:45 +00:00
delete [ ] EC_C [ n ] ; EC_C [ n ] = 0 ;
delete [ ] EC_G [ n ] ; EC_G [ n ] = 0 ;
delete [ ] EC_L [ n ] ; EC_L [ n ] = 0 ;
delete [ ] EC_R [ n ] ; EC_R [ n ] = 0 ;
2010-03-05 13:20:25 +00:00
}
2011-01-07 09:45:26 +00:00
Delete_N_3DArray ( m_epsR , numLines ) ;
2011-01-24 10:11:45 +00:00
m_epsR = 0 ;
2011-01-07 09:45:26 +00:00
Delete_N_3DArray ( m_kappa , numLines ) ;
2011-01-24 10:11:45 +00:00
m_kappa = 0 ;
2011-01-07 09:45:26 +00:00
Delete_N_3DArray ( m_mueR , numLines ) ;
2011-01-24 10:11:45 +00:00
m_mueR = 0 ;
2011-01-07 09:45:26 +00:00
Delete_N_3DArray ( m_sigma , numLines ) ;
2011-01-24 10:11:45 +00:00
m_sigma = 0 ;
}
2011-01-07 09:45:26 +00:00
2011-01-24 10:11:45 +00:00
void Operator : : Reset ( )
{
Delete ( ) ;
2010-12-06 08:59:42 +00:00
Operator_Base : : Reset ( ) ;
2010-04-23 06:17:42 +00:00
}
2010-12-08 15:55:27 +00:00
double Operator : : GetDiscLine ( int n , unsigned int pos , bool dualMesh ) const
2010-04-13 16:40:43 +00:00
{
if ( ( n < 0 ) | | ( n > 2 ) ) return 0.0 ;
2010-12-08 15:55:27 +00:00
if ( pos > = numLines [ n ] ) return 0.0 ;
2010-04-13 16:40:43 +00:00
if ( dualMesh = = false )
2010-12-08 15:55:27 +00:00
return discLines [ n ] [ pos ] ;
// return dual mesh node
if ( pos < numLines [ n ] - 1 )
return 0.5 * ( discLines [ n ] [ pos ] + discLines [ n ] [ pos + 1 ] ) ;
// dual node for the last line (outside the field domain)
return discLines [ n ] [ pos ] + 0.5 * ( discLines [ n ] [ pos ] - discLines [ n ] [ pos - 1 ] ) ;
2011-03-16 11:26:41 +00:00
}
2010-12-08 15:55:27 +00:00
2012-06-25 11:20:04 +00:00
double Operator : : GetDiscDelta ( int n , unsigned int pos , bool dualMesh ) const
{
if ( ( n < 0 ) | | ( n > 2 ) ) return 0.0 ;
if ( pos > = numLines [ n ] ) return 0.0 ;
double delta = 0 ;
if ( dualMesh = = false )
{
if ( pos < numLines [ n ] - 1 )
delta = GetDiscLine ( n , pos + 1 , false ) - GetDiscLine ( n , pos , false ) ;
else
delta = GetDiscLine ( n , pos , false ) - GetDiscLine ( n , pos - 1 , false ) ;
return delta ;
}
else
{
if ( pos > 0 )
delta = GetDiscLine ( n , pos , true ) - GetDiscLine ( n , pos - 1 , true ) ;
else
delta = GetDiscLine ( n , 1 , false ) - GetDiscLine ( n , 0 , false ) ;
return delta ;
}
}
2011-03-16 11:26:41 +00:00
bool Operator : : GetYeeCoords ( int ny , unsigned int pos [ 3 ] , double * coords , bool dualMesh ) const
{
for ( int n = 0 ; n < 3 ; + + n )
coords [ n ] = GetDiscLine ( n , pos [ n ] , dualMesh ) ;
2012-06-06 08:19:30 +00:00
coords [ ny ] = GetDiscLine ( ny , pos [ ny ] , ! dualMesh ) ;
//check if position is inside the FDTD domain
2011-03-16 11:26:41 +00:00
if ( dualMesh = = false ) //main grid
{
if ( pos [ ny ] > = numLines [ ny ] - 1 )
return false ;
}
else //dual grid
{
int nP = ( ny + 1 ) % 3 ;
int nPP = ( ny + 2 ) % 3 ;
if ( ( pos [ nP ] > = numLines [ nP ] - 1 ) | | ( pos [ nPP ] > = numLines [ nPP ] - 1 ) )
return false ;
}
return true ;
2010-04-13 16:40:43 +00:00
}
2013-12-20 14:48:04 +00:00
bool Operator : : GetNodeCoords ( const unsigned int pos [ 3 ] , double * coords , bool dualMesh , CoordinateSystem c_system ) const
2013-02-06 15:40:32 +00:00
{
for ( int n = 0 ; n < 3 ; + + n )
coords [ n ] = GetDiscLine ( n , pos [ n ] , dualMesh ) ;
TransformCoordSystem ( coords , coords , m_MeshType , c_system ) ;
return true ;
}
2010-12-08 15:55:27 +00:00
double Operator : : GetEdgeLength ( int n , const unsigned int * pos , bool dualMesh ) const
2010-04-13 16:40:43 +00:00
{
2012-06-25 11:20:04 +00:00
return GetDiscDelta ( n , pos [ n ] , dualMesh ) * gridDelta ;
2010-07-29 16:30:50 +00:00
}
2012-04-27 14:31:36 +00:00
double Operator : : GetCellVolume ( const unsigned int pos [ 3 ] , bool dualMesh ) const
{
double vol = 1 ;
for ( int n = 0 ; n < 3 ; + + n )
vol * = GetEdgeLength ( n , pos , dualMesh ) ;
return vol ;
}
2011-03-18 13:17:09 +00:00
double Operator : : GetNodeWidth ( int ny , const int pos [ 3 ] , bool dualMesh ) const
{
if ( ( pos [ 0 ] < 0 ) | | ( pos [ 1 ] < 0 ) | | ( pos [ 2 ] < 0 ) )
return 0.0 ;
2012-11-21 15:18:06 +00:00
//call the unsigned int version of GetNodeWidth
unsigned int uiPos [ ] = { ( unsigned int ) pos [ 0 ] , ( unsigned int ) pos [ 1 ] , ( unsigned int ) pos [ 2 ] } ;
return GetNodeWidth ( ny , uiPos , dualMesh ) ;
2011-03-18 13:17:09 +00:00
}
2010-09-17 12:51:07 +00:00
double Operator : : GetNodeArea ( int ny , const unsigned int pos [ 3 ] , bool dualMesh ) const
2010-07-29 16:30:50 +00:00
{
int nyP = ( ny + 1 ) % 3 ;
int nyPP = ( ny + 2 ) % 3 ;
2010-09-02 13:35:13 +00:00
return GetNodeWidth ( nyP , pos , dualMesh ) * GetNodeWidth ( nyPP , pos , dualMesh ) ;
2010-04-13 16:40:43 +00:00
}
2011-03-18 13:17:09 +00:00
double Operator : : GetNodeArea ( int ny , const int pos [ 3 ] , bool dualMesh ) const
{
if ( ( pos [ 0 ] < 0 ) | | ( pos [ 1 ] < 0 ) | | ( pos [ 2 ] < 0 ) )
return 0.0 ;
2012-11-21 15:18:06 +00:00
//call the unsigned int version of GetNodeArea
unsigned int uiPos [ ] = { ( unsigned int ) pos [ 0 ] , ( unsigned int ) pos [ 1 ] , ( unsigned int ) pos [ 2 ] } ;
return GetNodeArea ( ny , uiPos , dualMesh ) ;
2011-03-18 13:17:09 +00:00
}
2013-02-06 15:33:12 +00:00
unsigned int Operator : : SnapToMeshLine ( int ny , double coord , bool & inside , bool dualMesh , bool fullMesh ) const
2010-03-01 18:35:28 +00:00
{
2011-04-27 11:01:02 +00:00
inside = false ;
if ( ( ny < 0 ) | | ( ny > 2 ) )
return 0 ;
if ( coord < GetDiscLine ( ny , 0 ) )
return 0 ;
2013-02-06 15:33:12 +00:00
unsigned int numLines = GetNumberOfLines ( ny , fullMesh ) ;
2011-04-27 11:01:02 +00:00
if ( coord > GetDiscLine ( ny , numLines - 1 ) )
return numLines - 1 ;
inside = true ;
if ( dualMesh = = false )
2010-03-01 18:35:28 +00:00
{
2011-04-27 11:01:02 +00:00
for ( unsigned int n = 0 ; n < numLines ; + + n )
2010-04-11 21:42:54 +00:00
{
2011-04-27 11:01:02 +00:00
if ( coord < = GetDiscLine ( ny , n , true ) )
return n ;
2010-04-11 21:42:54 +00:00
}
2011-04-27 11:01:02 +00:00
}
else
{
for ( unsigned int n = 1 ; n < numLines ; + + n )
2010-04-11 21:42:54 +00:00
{
2011-04-27 11:01:02 +00:00
if ( coord < = GetDiscLine ( ny , n , false ) )
return n - 1 ;
2010-04-11 21:42:54 +00:00
}
2011-04-27 11:01:02 +00:00
}
//should not happen
return 0 ;
}
2013-02-06 15:33:12 +00:00
bool Operator : : SnapToMesh ( const double * dcoord , unsigned int * uicoord , bool dualMesh , bool fullMesh , bool * inside ) const
2011-04-27 11:01:02 +00:00
{
2011-07-13 07:32:44 +00:00
bool meshInside = false ;
2011-04-27 11:01:02 +00:00
bool ok = true ;
for ( int n = 0 ; n < 3 ; + + n )
{
2013-02-06 15:33:12 +00:00
uicoord [ n ] = SnapToMeshLine ( n , dcoord [ n ] , meshInside , dualMesh , fullMesh ) ;
2011-07-13 07:32:44 +00:00
ok & = meshInside ;
if ( inside )
inside [ n ] = meshInside ;
2010-03-01 18:35:28 +00:00
}
return ok ;
}
2013-02-06 15:33:12 +00:00
int Operator : : SnapBox2Mesh ( const double * start , const double * stop , unsigned int * uiStart , unsigned int * uiStop , bool dualMesh , bool fullMesh , int SnapMethod , bool * bStartIn , bool * bStopIn ) const
2011-07-22 07:58:02 +00:00
{
double l_start [ 3 ] , l_stop [ 3 ] ;
for ( int n = 0 ; n < 3 ; + + n )
{
l_start [ n ] = fmin ( start [ n ] , stop [ n ] ) ;
l_stop [ n ] = fmax ( start [ n ] , stop [ n ] ) ;
double min = GetDiscLine ( n , 0 ) ;
2013-02-06 15:33:12 +00:00
double max = GetDiscLine ( n , GetNumberOfLines ( n , fullMesh ) - 1 ) ;
2011-07-22 07:58:02 +00:00
if ( ( ( l_start [ n ] < min ) & & ( l_stop [ n ] < min ) ) | | ( ( l_start [ n ] > max ) & & ( l_stop [ n ] > max ) ) )
{
2011-11-16 10:30:21 +00:00
return - 2 ;
2011-07-22 07:58:02 +00:00
}
}
2013-02-06 15:33:12 +00:00
SnapToMesh ( l_start , uiStart , dualMesh , fullMesh , bStartIn ) ;
SnapToMesh ( l_stop , uiStop , dualMesh , fullMesh , bStopIn ) ;
2011-07-22 07:58:02 +00:00
int iDim = 0 ;
if ( SnapMethod = = 0 )
{
for ( int n = 0 ; n < 3 ; + + n )
if ( uiStop [ n ] > uiStart [ n ] )
+ + iDim ;
return iDim ;
}
else if ( SnapMethod = = 1 )
{
for ( int n = 0 ; n < 3 ; + + n )
{
if ( uiStop [ n ] > uiStart [ n ] )
{
if ( ( GetDiscLine ( n , uiStart [ n ] , dualMesh ) > l_start [ n ] ) & & ( uiStart [ n ] > 0 ) )
- - uiStart [ n ] ;
2013-02-06 15:33:12 +00:00
if ( ( GetDiscLine ( n , uiStop [ n ] , dualMesh ) < l_stop [ n ] ) & & ( uiStop [ n ] < GetNumberOfLines ( n , fullMesh ) - 1 ) )
2011-07-22 07:58:02 +00:00
+ + uiStop [ n ] ;
}
if ( uiStop [ n ] > uiStart [ n ] )
+ + iDim ;
}
return iDim ;
}
else if ( SnapMethod = = 2 )
{
for ( int n = 0 ; n < 3 ; + + n )
{
if ( uiStop [ n ] > uiStart [ n ] )
{
2013-02-06 15:33:12 +00:00
if ( ( GetDiscLine ( n , uiStart [ n ] , dualMesh ) < l_start [ n ] ) & & ( uiStart [ n ] < GetNumberOfLines ( n , fullMesh ) - 1 ) )
2011-07-22 07:58:02 +00:00
+ + uiStart [ n ] ;
if ( ( GetDiscLine ( n , uiStop [ n ] , dualMesh ) > l_stop [ n ] ) & & ( uiStop [ n ] > 0 ) )
- - uiStop [ n ] ;
}
if ( uiStop [ n ] > uiStart [ n ] )
+ + iDim ;
}
return iDim ;
}
else
cerr < < " Operator::SnapBox2Mesh: Unknown snapping method! " < < endl ;
return - 1 ;
}
2013-06-05 12:56:34 +00:00
int Operator : : SnapLine2Mesh ( const double * start , const double * stop , unsigned int * uiStart , unsigned int * uiStop , bool dualMesh , bool fullMesh ) const
{
bool bStartIn [ 3 ] ;
bool bStopIn [ 3 ] ;
SnapToMesh ( start , uiStart , dualMesh , fullMesh , bStartIn ) ;
SnapToMesh ( stop , uiStop , dualMesh , fullMesh , bStopIn ) ;
2013-06-10 08:13:58 +00:00
for ( int n = 0 ; n < 3 ; + + n )
{
if ( ( start [ n ] < GetDiscLine ( n , 0 ) ) & & ( stop [ n ] < GetDiscLine ( n , 0 ) ) )
return - 1 ; //lower bound violation
if ( ( start [ n ] > GetDiscLine ( n , GetNumberOfLines ( n , true ) - 1 ) ) & & ( stop [ n ] > GetDiscLine ( n , GetNumberOfLines ( n , true ) - 1 ) ) )
return - 1 ; //upper bound violation
}
2013-06-05 12:56:34 +00:00
int ret = 0 ;
if ( ! ( bStartIn [ 0 ] & & bStartIn [ 1 ] & & bStartIn [ 2 ] ) )
ret = ret + 1 ;
if ( ! ( bStopIn [ 0 ] & & bStopIn [ 1 ] & & bStopIn [ 2 ] ) )
ret = ret + 2 ;
if ( ret = = 0 )
return ret ;
//fixme, do we need to do something about start or stop being outside the field domain?
//maybe caclulate the intersection point and snap to that?
//it seems to work like this as well...
return ret ;
}
2013-08-16 11:19:12 +00:00
Grid_Path Operator : : FindPath ( double start [ ] , double stop [ ] )
2010-03-22 07:19:17 +00:00
{
2013-08-16 11:19:12 +00:00
Grid_Path path ;
2010-04-13 16:51:44 +00:00
unsigned int uiStart [ 3 ] , uiStop [ 3 ] , currPos [ 3 ] ;
2013-02-06 15:33:12 +00:00
2013-06-10 08:13:58 +00:00
int ret = SnapLine2Mesh ( start , stop , uiStart , uiStop , false , true ) ;
if ( ret < 0 )
return path ;
2010-03-22 07:19:17 +00:00
currPos [ 0 ] = uiStart [ 0 ] ;
currPos [ 1 ] = uiStart [ 1 ] ;
currPos [ 2 ] = uiStart [ 2 ] ;
2013-02-06 15:33:12 +00:00
double meshStart [ 3 ] = { discLines [ 0 ] [ uiStart [ 0 ] ] , discLines [ 1 ] [ uiStart [ 1 ] ] , discLines [ 2 ] [ uiStart [ 2 ] ] } ;
double meshStop [ 3 ] = { discLines [ 0 ] [ uiStop [ 0 ] ] , discLines [ 1 ] [ uiStop [ 1 ] ] , discLines [ 2 ] [ uiStop [ 2 ] ] } ;
2010-04-13 16:51:44 +00:00
bool UpDir = false ;
2010-03-26 18:51:09 +00:00
double foot = 0 , dist = 0 , minFoot = 0 , minDist = 0 ;
int minDir = 0 ;
2010-03-22 07:19:17 +00:00
unsigned int minPos [ 3 ] ;
double startFoot , stopFoot , currFoot ;
2013-02-06 15:33:12 +00:00
Point_Line_Distance ( meshStart , start , stop , startFoot , dist , m_MeshType ) ;
Point_Line_Distance ( meshStop , start , stop , stopFoot , dist , m_MeshType ) ;
2010-03-22 07:19:17 +00:00
currFoot = startFoot ;
2010-03-26 18:33:44 +00:00
minFoot = startFoot ;
2010-03-22 07:19:17 +00:00
double P [ 3 ] ;
while ( minFoot < stopFoot )
{
minDist = 1e300 ;
2010-12-06 12:04:37 +00:00
for ( int n = 0 ; n < 3 ; + + n ) //check all 6 surrounding points
2010-03-22 07:19:17 +00:00
{
P [ 0 ] = discLines [ 0 ] [ currPos [ 0 ] ] ;
P [ 1 ] = discLines [ 1 ] [ currPos [ 1 ] ] ;
P [ 2 ] = discLines [ 2 ] [ currPos [ 2 ] ] ;
2010-03-26 18:51:09 +00:00
if ( ( ( int ) currPos [ n ] - 1 ) > = 0 )
2010-03-22 07:19:17 +00:00
{
P [ n ] = discLines [ n ] [ currPos [ n ] - 1 ] ;
2013-02-06 15:33:12 +00:00
Point_Line_Distance ( P , start , stop , foot , dist , m_MeshType ) ;
2010-03-22 07:19:17 +00:00
if ( ( foot > currFoot ) & & ( dist < minDist ) )
{
minFoot = foot ;
minDist = dist ;
minDir = n ;
2010-03-26 18:33:44 +00:00
UpDir = false ;
2010-03-22 07:19:17 +00:00
}
}
if ( ( currPos [ n ] + 1 ) < numLines [ n ] )
{
P [ n ] = discLines [ n ] [ currPos [ n ] + 1 ] ;
2013-02-06 15:33:12 +00:00
Point_Line_Distance ( P , start , stop , foot , dist , m_MeshType ) ;
2010-03-22 07:19:17 +00:00
if ( ( foot > currFoot ) & & ( dist < minDist ) )
{
minFoot = foot ;
minDist = dist ;
minDir = n ;
2010-03-26 18:33:44 +00:00
UpDir = true ;
2010-03-22 07:19:17 +00:00
}
}
}
2010-03-26 18:33:44 +00:00
minPos [ 0 ] = currPos [ 0 ] ;
minPos [ 1 ] = currPos [ 1 ] ;
minPos [ 2 ] = currPos [ 2 ] ;
if ( UpDir )
{
currPos [ minDir ] + = 1 ;
}
else
{
currPos [ minDir ] + = - 1 ;
minPos [ minDir ] - = 1 ;
}
2013-02-06 15:33:12 +00:00
//check validity of current postion
for ( int n = 0 ; n < 3 ; + + n )
if ( currPos [ n ] > = numLines [ n ] )
{
cerr < < __func__ < < " : Error, path went out of simulation domain, skipping path! " < < endl ;
Grid_Path empty ;
return empty ;
}
2010-03-22 07:19:17 +00:00
path . posPath [ 0 ] . push_back ( minPos [ 0 ] ) ;
path . posPath [ 1 ] . push_back ( minPos [ 1 ] ) ;
path . posPath [ 2 ] . push_back ( minPos [ 2 ] ) ;
2010-03-26 18:33:44 +00:00
currFoot = minFoot ;
path . dir . push_back ( minDir ) ;
2010-03-22 07:19:17 +00:00
}
2010-10-12 10:49:44 +00:00
//close missing edges, if currPos is not equal to uiStopPos
2010-12-06 12:04:37 +00:00
for ( int n = 0 ; n < 3 ; + + n )
2010-10-12 10:49:44 +00:00
{
if ( currPos [ n ] > uiStop [ n ] )
{
- - currPos [ n ] ;
path . posPath [ 0 ] . push_back ( currPos [ 0 ] ) ;
path . posPath [ 1 ] . push_back ( currPos [ 1 ] ) ;
path . posPath [ 2 ] . push_back ( currPos [ 2 ] ) ;
path . dir . push_back ( n ) ;
}
else if ( currPos [ n ] < uiStop [ n ] )
{
path . posPath [ 0 ] . push_back ( currPos [ 0 ] ) ;
path . posPath [ 1 ] . push_back ( currPos [ 1 ] ) ;
path . posPath [ 2 ] . push_back ( currPos [ 2 ] ) ;
path . dir . push_back ( n ) ;
}
}
2010-03-22 07:19:17 +00:00
return path ;
}
2013-12-28 20:02:49 +00:00
void Operator : : SetMaterialAvgMethod ( MatAverageMethods method )
{
switch ( method )
{
default :
case QuarterCell :
return SetQuarterCellMaterialAvg ( ) ;
case CentralCell :
return SetCellConstantMaterial ( ) ;
}
}
2010-03-31 14:35:43 +00:00
double Operator : : GetNumberCells ( ) const
2010-03-01 13:56:27 +00:00
{
if ( numLines )
2010-03-29 20:11:24 +00:00
return ( numLines [ 0 ] ) * ( numLines [ 1 ] ) * ( numLines [ 2 ] ) ; //it's more like number of nodes???
2010-03-01 13:56:27 +00:00
return 0 ;
}
2010-03-31 14:35:43 +00:00
void Operator : : ShowStat ( ) const
2010-03-01 13:56:27 +00:00
{
unsigned int OpSize = 12 * numLines [ 0 ] * numLines [ 1 ] * numLines [ 2 ] * sizeof ( FDTD_FLOAT ) ;
unsigned int FieldSize = 6 * numLines [ 0 ] * numLines [ 1 ] * numLines [ 2 ] * sizeof ( FDTD_FLOAT ) ;
double MBdiff = 1024 * 1024 ;
2010-03-29 20:11:24 +00:00
cout < < " ------- Stat: FDTD Operator ------- " < < endl ;
2010-05-10 07:14:29 +00:00
cout < < " Dimensions \t \t : " < < numLines [ 0 ] < < " x " < < numLines [ 1 ] < < " x " < < numLines [ 2 ] < < " = " < < numLines [ 0 ] * numLines [ 1 ] * numLines [ 2 ] < < " Cells ( " < < numLines [ 0 ] * numLines [ 1 ] * numLines [ 2 ] / 1e6 < < " MCells) " < < endl ;
2010-05-21 08:14:09 +00:00
cout < < " Size of Operator \t : " < < OpSize < < " Byte ( " < < ( double ) OpSize / MBdiff < < " MiB) " < < endl ;
cout < < " Size of Field-Data \t : " < < FieldSize < < " Byte ( " < < ( double ) FieldSize / MBdiff < < " MiB) " < < endl ;
2010-03-29 20:11:24 +00:00
cout < < " ----------------------------------- " < < endl ;
2013-12-03 15:01:00 +00:00
cout < < " Background materials (epsR/mueR/kappa/sigma): " < < GetBackgroundEpsR ( ) < < " / " < < GetBackgroundMueR ( ) < < " / " < < GetBackgroundKappa ( ) < < " / " < < GetBackgroundSigma ( ) < < endl ;
cout < < " ----------------------------------- " < < endl ;
2010-05-10 07:14:29 +00:00
cout < < " Number of PEC edges \t : " < < m_Nr_PEC [ 0 ] + m_Nr_PEC [ 1 ] + m_Nr_PEC [ 2 ] < < endl ;
cout < < " in " < < GetDirName ( 0 ) < < " direction \t \t : " < < m_Nr_PEC [ 0 ] < < endl ;
cout < < " in " < < GetDirName ( 1 ) < < " direction \t \t : " < < m_Nr_PEC [ 1 ] < < endl ;
cout < < " in " < < GetDirName ( 2 ) < < " direction \t \t : " < < m_Nr_PEC [ 2 ] < < endl ;
cout < < " ----------------------------------- " < < endl ;
2010-09-02 20:12:03 +00:00
cout < < " Timestep (s) \t \t : " < < dT ;
if ( opt_dT )
cout < < " \t ( " < < opt_dT < < " ) " ;
cout < < endl ;
2010-07-13 13:37:56 +00:00
cout < < " Timestep method name \t : " < < m_Used_TS_Name < < endl ;
2012-07-16 15:15:10 +00:00
cout < < " Nyquist criteria (TS) \t : " < < m_Exc - > GetNyquistNum ( ) < < endl ;
cout < < " Nyquist criteria (s) \t : " < < m_Exc - > GetNyquistNum ( ) * dT < < endl ;
2010-03-29 20:11:24 +00:00
cout < < " ----------------------------------- " < < endl ;
2010-03-01 13:56:27 +00:00
}
2010-07-11 21:45:41 +00:00
void Operator : : ShowExtStat ( ) const
{
2010-07-13 13:37:56 +00:00
if ( m_Op_exts . size ( ) = = 0 ) return ;
2010-07-11 21:45:41 +00:00
cout < < " ----------------------------------- " < < endl ;
2010-12-06 12:04:37 +00:00
for ( size_t n = 0 ; n < m_Op_exts . size ( ) ; + + n )
2010-07-11 21:45:41 +00:00
m_Op_exts . at ( n ) - > ShowStat ( cout ) ;
cout < < " ----------------------------------- " < < endl ;
}
2010-03-09 20:34:23 +00:00
2010-03-01 18:35:28 +00:00
void Operator : : DumpOperator2File ( string filename )
{
2010-07-15 10:58:48 +00:00
# ifdef OUTPUT_IN_DRAWINGUNITS
double discLines_scaling = 1 ;
# else
double discLines_scaling = GetGridDelta ( ) ;
# endif
2010-10-27 09:17:58 +00:00
cout < < " Operator: Dumping FDTD operator information to vtk file: " < < filename < < " ... " < < flush ;
2010-06-07 21:08:38 +00:00
2012-07-16 15:15:10 +00:00
VTK_File_Writer * vtk_Writer = new VTK_File_Writer ( filename . c_str ( ) , m_MeshType ) ;
vtk_Writer - > SetMeshLines ( discLines , numLines , discLines_scaling ) ;
vtk_Writer - > SetHeader ( " openEMS - Operator dump " ) ;
vtk_Writer - > SetNativeDump ( true ) ;
2012-07-17 11:23:00 +00:00
//find excitation extension
Operator_Ext_Excitation * Op_Ext_Exc = GetExcitationExtension ( ) ;
if ( Op_Ext_Exc )
2010-10-27 09:17:58 +00:00
{
2012-07-16 15:15:10 +00:00
FDTD_FLOAT * * * * exc = NULL ;
2012-07-17 11:23:00 +00:00
if ( Op_Ext_Exc - > Volt_Count > 0 )
2012-07-16 15:15:10 +00:00
{
exc = Create_N_3DArray < FDTD_FLOAT > ( numLines ) ;
2012-07-17 11:23:00 +00:00
for ( unsigned int n = 0 ; n < Op_Ext_Exc - > Volt_Count ; + + n )
exc [ Op_Ext_Exc - > Volt_dir [ n ] ] [ Op_Ext_Exc - > Volt_index [ 0 ] [ n ] ] [ Op_Ext_Exc - > Volt_index [ 1 ] [ n ] ] [ Op_Ext_Exc - > Volt_index [ 2 ] [ n ] ] = Op_Ext_Exc - > Volt_amp [ n ] ;
2012-07-16 15:15:10 +00:00
vtk_Writer - > AddVectorField ( " exc_volt " , exc ) ;
Delete_N_3DArray ( exc , numLines ) ;
}
2012-07-17 11:23:00 +00:00
if ( Op_Ext_Exc - > Curr_Count > 0 )
2012-07-16 15:15:10 +00:00
{
exc = Create_N_3DArray < FDTD_FLOAT > ( numLines ) ;
2012-07-17 11:23:00 +00:00
for ( unsigned int n = 0 ; n < Op_Ext_Exc - > Curr_Count ; + + n )
exc [ Op_Ext_Exc - > Curr_dir [ n ] ] [ Op_Ext_Exc - > Curr_index [ 0 ] [ n ] ] [ Op_Ext_Exc - > Curr_index [ 1 ] [ n ] ] [ Op_Ext_Exc - > Curr_index [ 2 ] [ n ] ] = Op_Ext_Exc - > Curr_amp [ n ] ;
2012-07-16 15:15:10 +00:00
vtk_Writer - > AddVectorField ( " exc_curr " , exc ) ;
Delete_N_3DArray ( exc , numLines ) ;
}
2010-03-27 22:05:45 +00:00
}
2010-10-27 09:17:58 +00:00
FDTD_FLOAT * * * * vv_temp = Create_N_3DArray < FDTD_FLOAT > ( numLines ) ;
FDTD_FLOAT * * * * vi_temp = Create_N_3DArray < FDTD_FLOAT > ( numLines ) ;
FDTD_FLOAT * * * * iv_temp = Create_N_3DArray < FDTD_FLOAT > ( numLines ) ;
FDTD_FLOAT * * * * ii_temp = Create_N_3DArray < FDTD_FLOAT > ( numLines ) ;
unsigned int pos [ 3 ] , n ;
for ( n = 0 ; n < 3 ; n + + )
for ( pos [ 0 ] = 0 ; pos [ 0 ] < numLines [ 0 ] ; pos [ 0 ] + + )
for ( pos [ 1 ] = 0 ; pos [ 1 ] < numLines [ 1 ] ; pos [ 1 ] + + )
for ( pos [ 2 ] = 0 ; pos [ 2 ] < numLines [ 2 ] ; pos [ 2 ] + + )
{
vv_temp [ n ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] = GetVV ( n , pos ) ;
vi_temp [ n ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] = GetVI ( n , pos ) ;
iv_temp [ n ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] = GetIV ( n , pos ) ;
ii_temp [ n ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] = GetII ( n , pos ) ;
}
2011-07-14 11:42:33 +00:00
2012-02-02 09:20:49 +00:00
vtk_Writer - > AddVectorField ( " vv " , vv_temp ) ;
2010-10-27 09:17:58 +00:00
Delete_N_3DArray ( vv_temp , numLines ) ;
2012-02-02 09:20:49 +00:00
vtk_Writer - > AddVectorField ( " vi " , vi_temp ) ;
2011-04-13 11:56:01 +00:00
Delete_N_3DArray ( vi_temp , numLines ) ;
2012-02-02 09:20:49 +00:00
vtk_Writer - > AddVectorField ( " iv " , iv_temp ) ;
2011-04-13 11:56:01 +00:00
Delete_N_3DArray ( iv_temp , numLines ) ;
2012-02-02 09:20:49 +00:00
vtk_Writer - > AddVectorField ( " ii " , ii_temp ) ;
2011-04-13 11:56:01 +00:00
Delete_N_3DArray ( ii_temp , numLines ) ;
2010-03-01 18:35:28 +00:00
2012-02-02 09:20:49 +00:00
if ( vtk_Writer - > Write ( ) = = false )
2011-04-13 11:56:01 +00:00
cerr < < " Operator::DumpOperator2File: Error: Can't write file... skipping! " < < endl ;
2010-06-04 12:08:42 +00:00
2012-07-16 15:15:10 +00:00
delete vtk_Writer ;
2010-03-01 18:35:28 +00:00
}
2010-03-05 13:20:25 +00:00
2010-06-02 14:37:21 +00:00
//! \brief dump PEC (perfect electric conductor) information (into VTK-file)
//! visualization via paraview
//! visualize only one component (x, y or z)
2013-03-27 11:02:08 +00:00
void Operator : : DumpPEC2File ( string filename , unsigned int * range )
2010-06-02 14:37:21 +00:00
{
2010-10-27 09:17:58 +00:00
cout < < " Operator: Dumping PEC information to vtk file: " < < filename < < " ... " < < flush ;
2010-06-04 12:08:42 +00:00
2010-09-17 08:50:06 +00:00
# ifdef OUTPUT_IN_DRAWINGUNITS
2013-02-06 15:42:03 +00:00
double scaling = 1.0 ;
2010-09-17 08:50:06 +00:00
# else
2013-02-06 15:42:03 +00:00
double scaling = GetGridDelta ( ) ; ;
2010-09-17 08:50:06 +00:00
# endif
2013-03-27 11:02:08 +00:00
unsigned int start [ 3 ] = { 0 , 0 , 0 } ;
unsigned int stop [ 3 ] = { numLines [ 0 ] - 1 , numLines [ 1 ] - 1 , numLines [ 2 ] - 1 } ;
if ( range ! = NULL )
for ( int n = 0 ; n < 3 ; + + n )
{
start [ n ] = range [ 2 * n ] ;
stop [ n ] = range [ 2 * n + 1 ] ;
}
2013-02-06 15:42:03 +00:00
vtkPolyData * polydata = vtkPolyData : : New ( ) ;
vtkCellArray * poly = vtkCellArray : : New ( ) ;
vtkPoints * points = vtkPoints : : New ( ) ;
int * pointIdx [ 2 ] ;
pointIdx [ 0 ] = new int [ numLines [ 0 ] * numLines [ 1 ] ] ;
pointIdx [ 1 ] = new int [ numLines [ 0 ] * numLines [ 1 ] ] ;
// init point idx
for ( unsigned int n = 0 ; n < numLines [ 0 ] * numLines [ 1 ] ; + + n )
2010-12-06 12:04:37 +00:00
{
2013-02-06 15:42:03 +00:00
pointIdx [ 0 ] [ n ] = - 1 ;
pointIdx [ 1 ] [ n ] = - 1 ;
2010-10-20 07:25:50 +00:00
}
2013-02-06 15:42:03 +00:00
int nP , nPP ;
double coord [ 3 ] ;
unsigned int pos [ 3 ] , rpos [ 3 ] ;
unsigned int mesh_idx = 0 ;
2013-03-27 11:02:08 +00:00
for ( pos [ 2 ] = start [ 2 ] ; pos [ 2 ] < stop [ 2 ] ; + + pos [ 2 ] )
2013-02-06 15:42:03 +00:00
{ // each xy-plane
for ( unsigned int n = 0 ; n < numLines [ 0 ] * numLines [ 1 ] ; + + n )
2010-10-20 07:25:50 +00:00
{
2013-02-06 15:42:03 +00:00
pointIdx [ 0 ] [ n ] = pointIdx [ 1 ] [ n ] ;
pointIdx [ 1 ] [ n ] = - 1 ;
}
2013-03-27 11:02:08 +00:00
for ( pos [ 0 ] = start [ 0 ] ; pos [ 0 ] < stop [ 0 ] ; + + pos [ 0 ] )
for ( pos [ 1 ] = start [ 1 ] ; pos [ 1 ] < stop [ 1 ] ; + + pos [ 1 ] )
2010-10-20 07:25:50 +00:00
{
2013-02-06 15:42:03 +00:00
for ( int n = 0 ; n < 3 ; + + n )
{
nP = ( n + 1 ) % 3 ;
nPP = ( n + 2 ) % 3 ;
if ( ( GetVV ( n , pos ) = = 0 ) & & ( GetVI ( n , pos ) = = 0 ) & & ( pos [ nP ] > 0 ) & & ( pos [ nPP ] > 0 ) )
{
rpos [ 0 ] = pos [ 0 ] ;
rpos [ 1 ] = pos [ 1 ] ;
rpos [ 2 ] = pos [ 2 ] ;
poly - > InsertNextCell ( 2 ) ;
mesh_idx = rpos [ 0 ] + rpos [ 1 ] * numLines [ 0 ] ;
if ( pointIdx [ 0 ] [ mesh_idx ] < 0 )
{
for ( int m = 0 ; m < 3 ; + + m )
coord [ m ] = discLines [ m ] [ rpos [ m ] ] ;
TransformCoordSystem ( coord , coord , m_MeshType , CARTESIAN ) ;
for ( int m = 0 ; m < 3 ; + + m )
coord [ m ] * = scaling ;
pointIdx [ 0 ] [ mesh_idx ] = ( int ) points - > InsertNextPoint ( coord ) ;
}
poly - > InsertCellPoint ( pointIdx [ 0 ] [ mesh_idx ] ) ;
+ + rpos [ n ] ;
mesh_idx = rpos [ 0 ] + rpos [ 1 ] * numLines [ 0 ] ;
if ( pointIdx [ n = = 2 ] [ mesh_idx ] < 0 )
{
for ( int m = 0 ; m < 3 ; + + m )
coord [ m ] = discLines [ m ] [ rpos [ m ] ] ;
TransformCoordSystem ( coord , coord , m_MeshType , CARTESIAN ) ;
for ( int m = 0 ; m < 3 ; + + m )
coord [ m ] * = scaling ;
pointIdx [ n = = 2 ] [ mesh_idx ] = ( int ) points - > InsertNextPoint ( coord ) ;
}
poly - > InsertCellPoint ( pointIdx [ n = = 2 ] [ mesh_idx ] ) ;
}
}
2010-06-02 14:37:21 +00:00
}
}
2013-02-06 15:42:03 +00:00
delete [ ] pointIdx [ 0 ] ;
delete [ ] pointIdx [ 1 ] ;
2010-06-02 14:37:21 +00:00
2013-02-06 15:42:03 +00:00
polydata - > SetPoints ( points ) ;
points - > Delete ( ) ;
polydata - > SetLines ( poly ) ;
poly - > Delete ( ) ;
2010-06-02 14:37:21 +00:00
2013-02-06 15:42:03 +00:00
vtkXMLPolyDataWriter * writer = vtkXMLPolyDataWriter : : New ( ) ;
filename + = " .vtp " ;
writer - > SetFileName ( filename . c_str ( ) ) ;
2011-07-14 11:42:33 +00:00
2016-03-21 08:35:36 +00:00
# if VTK_MAJOR_VERSION>=6
2014-01-29 13:51:00 +00:00
writer - > SetInputData ( polydata ) ;
# else
2013-02-06 15:42:03 +00:00
writer - > SetInput ( polydata ) ;
2014-01-29 13:51:00 +00:00
# endif
2013-02-06 15:42:03 +00:00
writer - > Write ( ) ;
2011-04-13 11:56:01 +00:00
2013-02-06 15:42:03 +00:00
writer - > Delete ( ) ;
polydata - > Delete ( ) ;
2013-03-27 11:02:08 +00:00
cout < < " done. " < < endl ;
2010-06-02 14:37:21 +00:00
}
2010-03-12 19:39:04 +00:00
void Operator : : DumpMaterial2File ( string filename )
{
2010-07-15 10:58:48 +00:00
# ifdef OUTPUT_IN_DRAWINGUNITS
double discLines_scaling = 1 ;
# else
double discLines_scaling = GetGridDelta ( ) ;
# endif
2010-10-27 09:17:58 +00:00
cout < < " Operator: Dumping material information to vtk file: " < < filename < < " ... " < < flush ;
2010-06-04 12:08:42 +00:00
2010-10-27 09:17:58 +00:00
FDTD_FLOAT * * * * epsilon = Create_N_3DArray < FDTD_FLOAT > ( numLines ) ;
FDTD_FLOAT * * * * mue = Create_N_3DArray < FDTD_FLOAT > ( numLines ) ;
FDTD_FLOAT * * * * kappa = Create_N_3DArray < FDTD_FLOAT > ( numLines ) ;
FDTD_FLOAT * * * * sigma = Create_N_3DArray < FDTD_FLOAT > ( numLines ) ;
2010-03-12 19:39:04 +00:00
2010-10-27 09:17:58 +00:00
unsigned int pos [ 3 ] ;
2010-12-06 12:04:37 +00:00
for ( pos [ 0 ] = 0 ; pos [ 0 ] < numLines [ 0 ] ; + + pos [ 0 ] )
2010-03-12 19:39:04 +00:00
{
2010-12-06 12:04:37 +00:00
for ( pos [ 1 ] = 0 ; pos [ 1 ] < numLines [ 1 ] ; + + pos [ 1 ] )
2010-03-12 19:39:04 +00:00
{
2014-10-19 19:59:39 +00:00
vector < CSPrimitives * > vPrims = this - > GetPrimitivesBoundBox ( pos [ 0 ] , pos [ 1 ] , - 1 , CSProperties : : MATERIAL ) ;
2010-12-06 12:04:37 +00:00
for ( pos [ 2 ] = 0 ; pos [ 2 ] < numLines [ 2 ] ; + + pos [ 2 ] )
2010-03-12 19:39:04 +00:00
{
2010-12-06 12:04:37 +00:00
for ( int n = 0 ; n < 3 ; + + n )
2010-03-12 19:39:04 +00:00
{
2010-10-27 09:17:58 +00:00
double inMat [ 4 ] ;
2014-10-19 19:59:39 +00:00
Calc_EffMatPos ( n , pos , inMat , vPrims ) ;
2010-10-27 09:17:58 +00:00
epsilon [ n ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] = inMat [ 0 ] / __EPS0__ ;
mue [ n ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] = inMat [ 2 ] / __MUE0__ ;
kappa [ n ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] = inMat [ 1 ] ;
sigma [ n ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] = inMat [ 3 ] ;
2010-03-12 19:39:04 +00:00
}
}
}
}
2012-02-02 09:20:49 +00:00
VTK_File_Writer * vtk_Writer = new VTK_File_Writer ( filename . c_str ( ) , m_MeshType ) ;
vtk_Writer - > SetMeshLines ( discLines , numLines , discLines_scaling ) ;
vtk_Writer - > SetHeader ( " openEMS - material dump " ) ;
2010-10-27 09:17:58 +00:00
2012-02-02 09:20:49 +00:00
vtk_Writer - > SetNativeDump ( true ) ;
2011-07-14 11:42:33 +00:00
2012-02-02 09:20:49 +00:00
vtk_Writer - > AddVectorField ( " epsilon " , epsilon ) ;
2010-09-02 13:35:57 +00:00
Delete_N_3DArray ( epsilon , numLines ) ;
2012-02-02 09:20:49 +00:00
vtk_Writer - > AddVectorField ( " mue " , mue ) ;
2010-09-02 13:35:57 +00:00
Delete_N_3DArray ( mue , numLines ) ;
2012-02-02 09:20:49 +00:00
vtk_Writer - > AddVectorField ( " kappa " , kappa ) ;
2010-09-02 13:35:57 +00:00
Delete_N_3DArray ( kappa , numLines ) ;
2012-02-02 09:20:49 +00:00
vtk_Writer - > AddVectorField ( " sigma " , sigma ) ;
2010-09-02 13:35:57 +00:00
Delete_N_3DArray ( sigma , numLines ) ;
2010-10-27 09:17:58 +00:00
2012-02-02 09:20:49 +00:00
if ( vtk_Writer - > Write ( ) = = false )
2011-04-13 11:56:01 +00:00
cerr < < " Operator::DumpMaterial2File: Error: Can't write file... skipping! " < < endl ;
2010-06-04 12:08:42 +00:00
2012-07-16 15:15:10 +00:00
delete vtk_Writer ;
2010-03-12 19:39:04 +00:00
}
2011-03-18 13:17:09 +00:00
bool Operator : : SetupCSXGrid ( CSRectGrid * grid )
{
for ( int n = 0 ; n < 3 ; + + n )
{
discLines [ n ] = grid - > GetLines ( n , discLines [ n ] , numLines [ n ] , true ) ;
if ( numLines [ n ] < 3 )
{
cerr < < " CartOperator::SetupCSXGrid: you need at least 3 disc-lines in every direction (3D!)!!! " < < endl ;
Reset ( ) ;
return false ;
}
}
MainOp = new AdrOp ( numLines [ 0 ] , numLines [ 1 ] , numLines [ 2 ] ) ;
MainOp - > SetGrid ( discLines [ 0 ] , discLines [ 1 ] , discLines [ 2 ] ) ;
if ( grid - > GetDeltaUnit ( ) < = 0 )
{
cerr < < " CartOperator::SetupCSXGrid: grid delta unit must not be <=0 !!! " < < endl ;
Reset ( ) ;
return false ;
}
else gridDelta = grid - > GetDeltaUnit ( ) ;
MainOp - > SetGridDelta ( 1 ) ;
MainOp - > AddCellAdrOp ( ) ;
//delete the grid clone...
delete grid ;
return true ;
}
2010-03-11 09:48:47 +00:00
bool Operator : : SetGeometryCSX ( ContinuousStructure * geo )
2010-03-05 13:20:25 +00:00
{
2010-03-11 09:48:47 +00:00
if ( geo = = NULL ) return false ;
2010-03-05 13:20:25 +00:00
CSX = geo ;
2013-12-03 15:01:00 +00:00
CSBackgroundMaterial * bg_mat = CSX - > GetBackgroundMaterial ( ) ;
SetBackgroundEpsR ( bg_mat - > GetEpsilon ( ) ) ;
SetBackgroundMueR ( bg_mat - > GetMue ( ) ) ;
SetBackgroundKappa ( bg_mat - > GetKappa ( ) ) ;
SetBackgroundSigma ( bg_mat - > GetSigma ( ) ) ;
2013-12-20 14:47:28 +00:00
SetBackgroundDensity ( 0 ) ;
2011-03-18 13:17:09 +00:00
2013-12-03 15:01:00 +00:00
CSRectGrid * grid = CSX - > GetGrid ( ) ;
2011-03-18 13:17:09 +00:00
return SetupCSXGrid ( CSRectGrid : : Clone ( grid ) ) ;
2010-03-05 13:20:25 +00:00
}
void Operator : : InitOperator ( )
{
Delete_N_3DArray ( vv , numLines ) ;
Delete_N_3DArray ( vi , numLines ) ;
Delete_N_3DArray ( iv , numLines ) ;
Delete_N_3DArray ( ii , numLines ) ;
2010-06-06 18:00:24 +00:00
vv = Create_N_3DArray < FDTD_FLOAT > ( numLines ) ;
vi = Create_N_3DArray < FDTD_FLOAT > ( numLines ) ;
iv = Create_N_3DArray < FDTD_FLOAT > ( numLines ) ;
ii = Create_N_3DArray < FDTD_FLOAT > ( numLines ) ;
2010-03-05 13:20:25 +00:00
}
2011-01-07 09:45:26 +00:00
void Operator : : InitDataStorage ( )
{
if ( m_StoreMaterial [ 0 ] )
{
if ( g_settings . GetVerboseLevel ( ) > 0 )
cerr < < " Operator::InitDataStorage(): Storing epsR material data... " < < endl ;
Delete_N_3DArray ( m_epsR , numLines ) ;
m_epsR = Create_N_3DArray < float > ( numLines ) ;
}
if ( m_StoreMaterial [ 1 ] )
{
if ( g_settings . GetVerboseLevel ( ) > 0 )
cerr < < " Operator::InitDataStorage(): Storing kappa material data... " < < endl ;
Delete_N_3DArray ( m_kappa , numLines ) ;
m_kappa = Create_N_3DArray < float > ( numLines ) ;
}
if ( m_StoreMaterial [ 2 ] )
{
if ( g_settings . GetVerboseLevel ( ) > 0 )
cerr < < " Operator::InitDataStorage(): Storing muR material data... " < < endl ;
Delete_N_3DArray ( m_mueR , numLines ) ;
m_mueR = Create_N_3DArray < float > ( numLines ) ;
}
if ( m_StoreMaterial [ 3 ] )
{
if ( g_settings . GetVerboseLevel ( ) > 0 )
cerr < < " Operator::InitDataStorage(): Storing sigma material data... " < < endl ;
Delete_N_3DArray ( m_sigma , numLines ) ;
m_sigma = Create_N_3DArray < float > ( numLines ) ;
}
}
void Operator : : CleanupMaterialStorage ( )
{
if ( ! m_StoreMaterial [ 0 ] & & m_epsR )
{
if ( g_settings . GetVerboseLevel ( ) > 0 )
cerr < < " Operator::CleanupMaterialStorage(): Delete epsR material data... " < < endl ;
Delete_N_3DArray ( m_epsR , numLines ) ;
m_epsR = NULL ;
}
if ( ! m_StoreMaterial [ 1 ] & & m_kappa )
{
if ( g_settings . GetVerboseLevel ( ) > 0 )
cerr < < " Operator::CleanupMaterialStorage(): Delete kappa material data... " < < endl ;
Delete_N_3DArray ( m_kappa , numLines ) ;
m_kappa = NULL ;
}
if ( ! m_StoreMaterial [ 2 ] & & m_mueR )
{
if ( g_settings . GetVerboseLevel ( ) > 0 )
cerr < < " Operator::CleanupMaterialStorage(): Delete mueR material data... " < < endl ;
Delete_N_3DArray ( m_mueR , numLines ) ;
m_mueR = NULL ;
}
if ( ! m_StoreMaterial [ 3 ] & & m_sigma )
{
if ( g_settings . GetVerboseLevel ( ) > 0 )
cerr < < " Operator::CleanupMaterialStorage(): Delete sigma material data... " < < endl ;
Delete_N_3DArray ( m_sigma , numLines ) ;
m_sigma = NULL ;
}
}
2011-01-31 11:22:21 +00:00
double Operator : : GetDiscMaterial ( int type , int n , const unsigned int pos [ 3 ] ) const
{
switch ( type )
{
case 0 :
if ( m_epsR = = 0 )
return 0 ;
return m_epsR [ n ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] ;
case 1 :
if ( m_kappa = = 0 )
return 0 ;
return m_kappa [ n ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] ;
case 2 :
if ( m_mueR = = 0 )
return 0 ;
return m_mueR [ n ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] ;
case 3 :
if ( m_sigma = = 0 )
return 0 ;
return m_sigma [ n ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] ;
}
return 0 ;
}
2012-07-17 11:23:00 +00:00
void Operator : : SetExcitationSignal ( Excitation * exc )
2010-05-03 16:33:14 +00:00
{
2012-07-17 11:23:00 +00:00
m_Exc = exc ;
2010-05-03 16:33:14 +00:00
}
2010-04-21 13:43:39 +00:00
void Operator : : Calc_ECOperatorPos ( int n , unsigned int * pos )
2010-04-09 13:51:37 +00:00
{
unsigned int i = MainOp - > SetPos ( pos [ 0 ] , pos [ 1 ] , pos [ 2 ] ) ;
2012-07-12 08:06:13 +00:00
double C = EC_C [ n ] [ i ] ;
double G = EC_G [ n ] [ i ] ;
if ( C > 0 )
2010-05-03 20:36:04 +00:00
{
2012-07-12 08:06:13 +00:00
SetVV ( n , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , ( 1.0 - dT * G / 2.0 / C ) / ( 1.0 + dT * G / 2.0 / C ) ) ;
SetVI ( n , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , ( dT / C ) / ( 1.0 + dT * G / 2.0 / C ) ) ;
2010-05-03 20:36:04 +00:00
}
else
{
2010-10-20 05:26:16 +00:00
SetVV ( n , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetVI ( n , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
2010-05-03 20:36:04 +00:00
}
2012-07-12 08:06:13 +00:00
double L = EC_L [ n ] [ i ] ;
double R = EC_R [ n ] [ i ] ;
if ( L > 0 )
2010-05-03 20:36:04 +00:00
{
2012-07-12 08:06:13 +00:00
SetII ( n , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , ( 1.0 - dT * R / 2.0 / L ) / ( 1.0 + dT * R / 2.0 / L ) ) ;
SetIV ( n , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , ( dT / L ) / ( 1.0 + dT * R / 2.0 / L ) ) ;
2010-05-03 20:36:04 +00:00
}
else
{
2010-10-20 05:26:16 +00:00
SetII ( n , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetIV ( n , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
2010-05-03 20:36:04 +00:00
}
2010-04-09 13:51:37 +00:00
}
2010-10-27 09:17:58 +00:00
int Operator : : CalcECOperator ( DebugFlags debugFlags )
2010-03-05 13:20:25 +00:00
{
2010-06-05 09:47:21 +00:00
Init_EC ( ) ;
2011-01-07 09:45:26 +00:00
InitDataStorage ( ) ;
2010-06-05 09:47:21 +00:00
2010-03-05 13:20:25 +00:00
if ( Calc_EC ( ) = = 0 )
return - 1 ;
2010-09-08 14:07:28 +00:00
m_InvaildTimestep = false ;
2010-09-02 20:12:03 +00:00
opt_dT = 0 ;
2010-08-19 08:12:09 +00:00
if ( dT > 0 )
{
double save_dT = dT ;
CalcTimestep ( ) ;
2010-09-02 20:12:03 +00:00
opt_dT = dT ;
2010-08-19 08:12:09 +00:00
if ( dT < save_dT )
2010-09-08 14:07:28 +00:00
{
2010-08-19 08:12:09 +00:00
cerr < < " Operator::CalcECOperator: Warning, forced timestep: " < < save_dT < < " s is larger than calculated timestep: " < < dT < < " s! It is not recommended using this timestep!! " < < endl ;
2010-09-08 14:07:28 +00:00
m_InvaildTimestep = true ;
}
2010-08-19 08:12:09 +00:00
dT = save_dT ;
}
else
CalcTimestep ( ) ;
2010-03-05 13:20:25 +00:00
2012-09-27 12:20:20 +00:00
dT * = m_TimeStepFactor ;
2015-05-04 18:47:19 +00:00
if ( m_Exc - > GetSignalPeriod ( ) > 0 )
{
2015-09-03 19:25:49 +00:00
unsigned int TS = ceil ( m_Exc - > GetSignalPeriod ( ) / dT ) ;
2015-05-04 18:47:19 +00:00
double new_dT = m_Exc - > GetSignalPeriod ( ) / TS ;
2015-09-03 19:25:49 +00:00
cout < < " Operartor::CalcECOperator: Decreasing timestep by " < < round ( ( dT - new_dT ) / dT * 1000 ) / 10.0 < < " % to " < < new_dT < < " ( " < < dT < < " ) to match periodic signal " < < endl ;
2015-05-04 18:47:19 +00:00
dT = new_dT ;
}
2012-07-17 11:23:00 +00:00
m_Exc - > Reset ( dT ) ;
2010-03-05 13:20:25 +00:00
InitOperator ( ) ;
unsigned int pos [ 3 ] ;
2010-12-06 12:04:37 +00:00
for ( int n = 0 ; n < 3 ; + + n )
2010-03-05 13:20:25 +00:00
{
2010-12-06 12:04:37 +00:00
for ( pos [ 0 ] = 0 ; pos [ 0 ] < numLines [ 0 ] ; + + pos [ 0 ] )
2010-03-05 13:20:25 +00:00
{
2010-12-06 12:04:37 +00:00
for ( pos [ 1 ] = 0 ; pos [ 1 ] < numLines [ 1 ] ; + + pos [ 1 ] )
2010-03-05 13:20:25 +00:00
{
2010-12-06 12:04:37 +00:00
for ( pos [ 2 ] = 0 ; pos [ 2 ] < numLines [ 2 ] ; + + pos [ 2 ] )
2010-03-05 13:20:25 +00:00
{
2010-04-09 13:51:37 +00:00
Calc_ECOperatorPos ( n , pos ) ;
2010-03-05 13:20:25 +00:00
}
}
}
}
2010-07-16 15:25:32 +00:00
//Apply PEC to all boundary's
2010-03-05 13:20:25 +00:00
bool PEC [ 6 ] = { 1 , 1 , 1 , 1 , 1 , 1 } ;
2010-10-04 09:52:39 +00:00
//make an exception for BC == -1
2010-12-06 12:04:37 +00:00
for ( int n = 0 ; n < 6 ; + + n )
2010-10-04 09:52:39 +00:00
if ( ( m_BC [ n ] = = - 1 ) )
2010-09-08 05:36:32 +00:00
PEC [ n ] = false ;
2010-03-05 13:20:25 +00:00
ApplyElectricBC ( PEC ) ;
CalcPEC ( ) ;
2011-04-08 07:59:48 +00:00
Calc_LumpedElements ( ) ;
2010-04-28 20:01:03 +00:00
bool PMC [ 6 ] ;
2010-12-06 12:04:37 +00:00
for ( int n = 0 ; n < 6 ; + + n )
2010-04-28 20:01:03 +00:00
PMC [ n ] = m_BC [ n ] = = 1 ;
ApplyMagneticBC ( PMC ) ;
2010-10-04 09:52:39 +00:00
//all information available for extension... create now...
2010-12-06 12:04:37 +00:00
for ( size_t n = 0 ; n < m_Op_exts . size ( ) ; + + n )
2010-10-04 09:52:39 +00:00
m_Op_exts . at ( n ) - > BuildExtension ( ) ;
2012-07-17 11:23:00 +00:00
//remove inactive extensions
vector < Operator_Extension * > : : iterator it = m_Op_exts . begin ( ) ;
while ( it ! = m_Op_exts . end ( ) )
{
if ( ( * it ) - > IsActive ( ) = = false )
{
2013-03-27 10:55:39 +00:00
DeleteExtension ( ( * it ) ) ;
2012-07-17 11:23:00 +00:00
it = m_Op_exts . begin ( ) ; //restart search for inactive extension
}
else
+ + it ;
}
2010-10-27 09:17:58 +00:00
if ( debugFlags & debugMaterial )
2011-04-13 11:56:01 +00:00
DumpMaterial2File ( " material_dump " ) ;
2010-10-27 09:17:58 +00:00
if ( debugFlags & debugOperator )
2011-04-13 11:56:01 +00:00
DumpOperator2File ( " operator_dump " ) ;
2010-10-27 09:17:58 +00:00
if ( debugFlags & debugPEC )
2011-04-13 11:56:01 +00:00
DumpPEC2File ( " PEC_dump " ) ;
2010-10-27 09:17:58 +00:00
2010-10-04 09:52:39 +00:00
//cleanup
2010-12-06 12:04:37 +00:00
for ( int n = 0 ; n < 3 ; + + n )
2010-10-04 09:52:39 +00:00
{
2010-12-06 12:04:37 +00:00
delete [ ] EC_C [ n ] ;
EC_C [ n ] = NULL ;
delete [ ] EC_G [ n ] ;
EC_G [ n ] = NULL ;
delete [ ] EC_L [ n ] ;
EC_L [ n ] = NULL ;
delete [ ] EC_R [ n ] ;
EC_R [ n ] = NULL ;
2010-10-04 09:52:39 +00:00
}
2010-03-05 13:20:25 +00:00
return 0 ;
}
void Operator : : ApplyElectricBC ( bool * dirs )
{
2010-11-03 14:04:33 +00:00
if ( ! dirs )
return ;
2010-03-05 13:20:25 +00:00
unsigned int pos [ 3 ] ;
2010-12-06 12:04:37 +00:00
for ( int n = 0 ; n < 3 ; + + n )
2010-03-05 13:20:25 +00:00
{
int nP = ( n + 1 ) % 3 ;
int nPP = ( n + 2 ) % 3 ;
2010-12-06 12:04:37 +00:00
for ( pos [ nP ] = 0 ; pos [ nP ] < numLines [ nP ] ; + + pos [ nP ] )
2010-03-05 13:20:25 +00:00
{
2010-12-06 12:04:37 +00:00
for ( pos [ nPP ] = 0 ; pos [ nPP ] < numLines [ nPP ] ; + + pos [ nPP ] )
2010-03-05 13:20:25 +00:00
{
2010-11-03 14:04:33 +00:00
if ( dirs [ 2 * n ] )
{
// set to PEC
pos [ n ] = 0 ;
SetVV ( nP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetVI ( nP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetVV ( nPP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetVI ( nPP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
}
if ( dirs [ 2 * n + 1 ] )
{
// set to PEC
pos [ n ] = numLines [ n ] - 1 ;
SetVV ( n , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ; // these are outside the FDTD-domain as defined by the main disc
SetVI ( n , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ; // these are outside the FDTD-domain as defined by the main disc
SetVV ( nP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetVI ( nP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetVV ( nPP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetVI ( nPP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
}
2010-03-05 13:20:25 +00:00
}
}
}
}
void Operator : : ApplyMagneticBC ( bool * dirs )
{
2010-11-03 14:04:33 +00:00
if ( ! dirs )
return ;
2010-03-05 13:20:25 +00:00
unsigned int pos [ 3 ] ;
2010-12-06 12:04:37 +00:00
for ( int n = 0 ; n < 3 ; + + n )
2010-03-05 13:20:25 +00:00
{
int nP = ( n + 1 ) % 3 ;
int nPP = ( n + 2 ) % 3 ;
2010-12-06 12:04:37 +00:00
for ( pos [ nP ] = 0 ; pos [ nP ] < numLines [ nP ] ; + + pos [ nP ] )
2010-03-05 13:20:25 +00:00
{
2010-12-06 12:04:37 +00:00
for ( pos [ nPP ] = 0 ; pos [ nPP ] < numLines [ nPP ] ; + + pos [ nPP ] )
2010-03-05 13:20:25 +00:00
{
2010-11-03 14:04:33 +00:00
if ( dirs [ 2 * n ] )
{
// set to PMC
pos [ n ] = 0 ;
SetII ( n , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetIV ( n , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetII ( nP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetIV ( nP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetII ( nPP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetIV ( nPP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
}
if ( dirs [ 2 * n + 1 ] )
{
// set to PMC
pos [ n ] = numLines [ n ] - 2 ;
SetII ( nP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetIV ( nP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetII ( nPP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetIV ( nPP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
}
2010-10-04 09:52:39 +00:00
2010-10-20 05:26:16 +00:00
// the last current lines are outside the FDTD domain and cannot be iterated by the FDTD engine
2010-11-03 14:04:33 +00:00
pos [ n ] = numLines [ n ] - 1 ;
2010-10-20 05:26:16 +00:00
SetII ( n , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetIV ( n , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetII ( nP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetIV ( nP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetII ( nPP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetIV ( nPP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
2010-03-05 13:20:25 +00:00
}
}
}
}
2014-10-19 19:59:39 +00:00
bool Operator : : Calc_ECPos ( int ny , const unsigned int * pos , double * EC , vector < CSPrimitives * > vPrims ) const
2010-09-02 13:35:13 +00:00
{
double EffMat [ 4 ] ;
2014-10-19 19:59:39 +00:00
Calc_EffMatPos ( ny , pos , EffMat , vPrims ) ;
2010-09-02 13:35:13 +00:00
2011-01-07 09:45:26 +00:00
if ( m_epsR )
m_epsR [ ny ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] = EffMat [ 0 ] ;
if ( m_kappa )
m_kappa [ ny ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] = EffMat [ 1 ] ;
if ( m_mueR )
m_mueR [ ny ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] = EffMat [ 2 ] ;
if ( m_sigma )
m_sigma [ ny ] [ pos [ 0 ] ] [ pos [ 1 ] ] [ pos [ 2 ] ] = EffMat [ 3 ] ;
2010-09-02 13:35:13 +00:00
double delta = GetEdgeLength ( ny , pos ) ;
double area = GetEdgeArea ( ny , pos ) ;
// if (isnan(EffMat[0]))
// {
// cerr << ny << " " << pos[0] << " " << pos[1] << " " << pos[2] << " : " << EffMat[0] << endl;
// }
if ( delta )
{
EC [ 0 ] = EffMat [ 0 ] * area / delta ;
EC [ 1 ] = EffMat [ 1 ] * area / delta ;
}
else
{
EC [ 0 ] = 0 ;
EC [ 1 ] = 0 ;
}
delta = GetEdgeLength ( ny , pos , true ) ;
area = GetEdgeArea ( ny , pos , true ) ;
if ( delta )
{
EC [ 2 ] = EffMat [ 2 ] * area / delta ;
EC [ 3 ] = EffMat [ 3 ] * area / delta ;
}
else
{
EC [ 2 ] = 0 ;
EC [ 3 ] = 0 ;
}
2010-03-05 13:20:25 +00:00
2010-09-02 13:35:13 +00:00
return true ;
}
2011-03-14 14:58:38 +00:00
double Operator : : GetRawDiscDelta ( int ny , const int pos ) const
{
//numLines[ny] is expected to be larger then 1 !
if ( pos < 0 )
return ( discLines [ ny ] [ 0 ] - discLines [ ny ] [ 1 ] ) ;
if ( pos > = ( int ) numLines [ ny ] - 1 )
return ( discLines [ ny ] [ numLines [ ny ] - 2 ] - discLines [ ny ] [ numLines [ ny ] - 1 ] ) ;
return ( discLines [ ny ] [ pos + 1 ] - discLines [ ny ] [ pos ] ) ;
}
2013-12-28 19:57:31 +00:00
bool Operator : : GetCellCenterMaterialAvgCoord ( const int pos [ ] , double coord [ 3 ] ) const
2013-12-20 14:48:04 +00:00
{
2013-12-28 19:57:31 +00:00
unsigned int ui_pos [ 3 ] ;
2013-12-20 14:48:04 +00:00
for ( int n = 0 ; n < 3 ; + + n )
{
2013-12-28 19:57:31 +00:00
if ( ( pos [ n ] < 0 ) | | ( pos [ n ] > = ( int ) numLines [ n ] ) )
2013-12-20 14:48:04 +00:00
return false ;
2013-12-28 19:57:31 +00:00
ui_pos [ n ] = pos [ n ] ;
2013-12-20 14:48:04 +00:00
}
2013-12-28 19:57:31 +00:00
GetNodeCoords ( ui_pos , coord , true ) ;
2013-12-20 14:48:04 +00:00
return true ;
}
2014-10-19 19:59:39 +00:00
double Operator : : GetMaterial ( int ny , const double * coords , int MatType , vector < CSPrimitives * > vPrims , bool markAsUsed ) const
2011-03-18 13:17:09 +00:00
{
2014-10-19 19:59:39 +00:00
CSProperties * prop = CSX - > GetPropertyByCoordPriority ( coords , vPrims , markAsUsed ) ;
// CSProperties* old_prop = CSX->GetPropertyByCoordPriority(coords,CSProperties::MATERIAL,markAsUsed);
// if (old_prop!=prop)
// {
// cerr << "ERROR: Unequal properties!" << endl;
// exit(-1);
// }
2011-03-18 13:17:09 +00:00
CSPropMaterial * mat = dynamic_cast < CSPropMaterial * > ( prop ) ;
if ( mat )
{
switch ( MatType )
{
case 0 :
return mat - > GetEpsilonWeighted ( ny , coords ) ;
case 1 :
return mat - > GetKappaWeighted ( ny , coords ) ;
case 2 :
return mat - > GetMueWeighted ( ny , coords ) ;
case 3 :
return mat - > GetSigmaWeighted ( ny , coords ) ;
2013-12-20 14:47:28 +00:00
case 4 :
return mat - > GetDensityWeighted ( coords ) ;
2011-03-18 13:17:09 +00:00
default :
cerr < < " Operator::GetMaterial: Error: unknown material type " < < endl ;
return 0 ;
}
}
switch ( MatType )
{
case 0 :
2013-12-03 15:01:00 +00:00
return GetBackgroundEpsR ( ) ;
2011-03-18 13:17:09 +00:00
case 1 :
2013-12-03 15:01:00 +00:00
return GetBackgroundKappa ( ) ;
2011-03-18 13:17:09 +00:00
case 2 :
2013-12-03 15:01:00 +00:00
return GetBackgroundMueR ( ) ;
2011-03-18 13:17:09 +00:00
case 3 :
2013-12-03 15:01:00 +00:00
return GetBackgroundSigma ( ) ;
2013-12-20 14:47:28 +00:00
case 4 :
return GetBackgroundDensity ( ) ;
2011-03-18 13:17:09 +00:00
default :
cerr < < " Operator::GetMaterial: Error: unknown material type " < < endl ;
return 0 ;
}
}
2014-10-19 19:59:39 +00:00
bool Operator : : AverageMatCellCenter ( int ny , const unsigned int * pos , double * EffMat , vector < CSPrimitives * > vPrims ) const
2013-12-28 20:02:49 +00:00
{
int n = ny ;
double coord [ 3 ] ;
int nP = ( n + 1 ) % 3 ;
int nPP = ( n + 2 ) % 3 ;
int loc_pos [ 3 ] = { ( int ) pos [ 0 ] , ( int ) pos [ 1 ] , ( int ) pos [ 2 ] } ;
double A_n ;
double area = 0 ;
EffMat [ 0 ] = 0 ;
EffMat [ 1 ] = 0 ;
EffMat [ 2 ] = 0 ;
EffMat [ 3 ] = 0 ;
//******************************* epsilon,kappa averaging *****************************//
//shift up-right
if ( GetCellCenterMaterialAvgCoord ( loc_pos , coord ) )
{
A_n = GetNodeArea ( ny , loc_pos , true ) ;
2014-10-19 19:59:39 +00:00
EffMat [ 0 ] + = GetMaterial ( n , coord , 0 , vPrims ) * A_n ;
EffMat [ 1 ] + = GetMaterial ( n , coord , 1 , vPrims ) * A_n ;
2013-12-28 20:02:49 +00:00
area + = A_n ;
}
//shift up-left
- - loc_pos [ nP ] ;
if ( GetCellCenterMaterialAvgCoord ( loc_pos , coord ) )
{
A_n = GetNodeArea ( ny , loc_pos , true ) ;
2014-10-19 19:59:39 +00:00
EffMat [ 0 ] + = GetMaterial ( n , coord , 0 , vPrims ) * A_n ;
EffMat [ 1 ] + = GetMaterial ( n , coord , 1 , vPrims ) * A_n ;
2013-12-28 20:02:49 +00:00
area + = A_n ;
}
//shift down-right
+ + loc_pos [ nP ] ;
- - loc_pos [ nPP ] ;
if ( GetCellCenterMaterialAvgCoord ( loc_pos , coord ) )
{
A_n = GetNodeArea ( ny , loc_pos , true ) ;
2014-10-19 19:59:39 +00:00
EffMat [ 0 ] + = GetMaterial ( n , coord , 0 , vPrims ) * A_n ;
EffMat [ 1 ] + = GetMaterial ( n , coord , 1 , vPrims ) * A_n ;
2013-12-28 20:02:49 +00:00
area + = A_n ;
}
//shift down-left
- - loc_pos [ nP ] ;
if ( GetCellCenterMaterialAvgCoord ( loc_pos , coord ) )
{
A_n = GetNodeArea ( ny , loc_pos , true ) ;
2014-10-19 19:59:39 +00:00
EffMat [ 0 ] + = GetMaterial ( n , coord , 0 , vPrims ) * A_n ;
EffMat [ 1 ] + = GetMaterial ( n , coord , 1 , vPrims ) * A_n ;
2013-12-28 20:02:49 +00:00
area + = A_n ;
}
EffMat [ 0 ] * = __EPS0__ / area ;
EffMat [ 1 ] / = area ;
//******************************* mu,sigma averaging *****************************//
loc_pos [ 0 ] = pos [ 0 ] ;
loc_pos [ 1 ] = pos [ 1 ] ;
loc_pos [ 2 ] = pos [ 2 ] ;
double length = 0 ;
double delta_ny , sigma ;
//shift down
- - loc_pos [ n ] ;
if ( GetCellCenterMaterialAvgCoord ( loc_pos , coord ) )
{
delta_ny = GetNodeWidth ( n , loc_pos , true ) ;
2014-10-19 19:59:39 +00:00
EffMat [ 2 ] + = delta_ny / GetMaterial ( n , coord , 2 , vPrims ) ;
sigma = GetMaterial ( n , coord , 3 , vPrims ) ;
2013-12-28 20:02:49 +00:00
if ( sigma )
EffMat [ 3 ] + = delta_ny / sigma ;
else
EffMat [ 3 ] = 0 ;
length + = delta_ny ;
}
//shift up
+ + loc_pos [ n ] ;
if ( GetCellCenterMaterialAvgCoord ( loc_pos , coord ) )
{
delta_ny = GetNodeWidth ( n , loc_pos , true ) ;
2014-10-19 19:59:39 +00:00
EffMat [ 2 ] + = delta_ny / GetMaterial ( n , coord , 2 , vPrims ) ;
sigma = GetMaterial ( n , coord , 3 , vPrims ) ;
2013-12-28 20:02:49 +00:00
if ( sigma )
EffMat [ 3 ] + = delta_ny / sigma ;
else
EffMat [ 3 ] = 0 ;
length + = delta_ny ;
}
EffMat [ 2 ] = length * __MUE0__ / EffMat [ 2 ] ;
if ( EffMat [ 3 ] ) EffMat [ 3 ] = length / EffMat [ 3 ] ;
for ( int n = 0 ; n < 4 ; + + n )
2018-03-27 00:10:18 +00:00
if ( std : : isnan ( EffMat [ n ] ) | | std : : isinf ( EffMat [ n ] ) )
2013-12-28 20:02:49 +00:00
{
cerr < < " Operator:: " < < __func__ < < " : Error, an effective material parameter is not a valid result, this should NOT have happend... exit... " < < endl ;
cerr < < ny < < " @ " < < n < < " : " < < pos [ 0 ] < < " , " < < pos [ 1 ] < < " , " < < pos [ 2 ] < < endl ;
exit ( 0 ) ;
}
return true ;
}
2014-10-19 19:59:39 +00:00
bool Operator : : AverageMatQuarterCell ( int ny , const unsigned int * pos , double * EffMat , vector < CSPrimitives * > vPrims ) const
2010-03-05 13:20:25 +00:00
{
2010-09-02 13:35:13 +00:00
int n = ny ;
2010-03-05 13:20:25 +00:00
double coord [ 3 ] ;
double shiftCoord [ 3 ] ;
int nP = ( n + 1 ) % 3 ;
int nPP = ( n + 2 ) % 3 ;
coord [ 0 ] = discLines [ 0 ] [ pos [ 0 ] ] ;
coord [ 1 ] = discLines [ 1 ] [ pos [ 1 ] ] ;
coord [ 2 ] = discLines [ 2 ] [ pos [ 2 ] ] ;
2011-03-14 14:58:38 +00:00
double delta = GetRawDiscDelta ( n , pos [ n ] ) ;
double deltaP = GetRawDiscDelta ( nP , pos [ nP ] ) ;
double deltaPP = GetRawDiscDelta ( nPP , pos [ nPP ] ) ;
double delta_M = GetRawDiscDelta ( n , pos [ n ] - 1 ) ;
double deltaP_M = GetRawDiscDelta ( nP , pos [ nP ] - 1 ) ;
double deltaPP_M = GetRawDiscDelta ( nPP , pos [ nPP ] - 1 ) ;
2010-03-05 13:20:25 +00:00
2012-11-15 20:44:43 +00:00
int loc_pos [ 3 ] = { ( int ) pos [ 0 ] , ( int ) pos [ 1 ] , ( int ) pos [ 2 ] } ;
2010-09-02 13:35:13 +00:00
double A_n ;
double area = 0 ;
2010-03-05 13:20:25 +00:00
//******************************* epsilon,kappa averaging *****************************//
//shift up-right
shiftCoord [ n ] = coord [ n ] + delta * 0.5 ;
2013-12-28 20:02:49 +00:00
shiftCoord [ nP ] = coord [ nP ] + deltaP * 0.25 ;
shiftCoord [ nPP ] = coord [ nPP ] + deltaPP * 0.25 ;
2011-03-18 13:17:09 +00:00
A_n = GetNodeArea ( ny , loc_pos , true ) ;
2014-10-19 19:59:39 +00:00
EffMat [ 0 ] = GetMaterial ( n , shiftCoord , 0 , vPrims ) * A_n ;
EffMat [ 1 ] = GetMaterial ( n , shiftCoord , 1 , vPrims ) * A_n ;
2010-09-02 13:35:13 +00:00
area + = A_n ;
2010-03-05 13:20:25 +00:00
//shift up-left
shiftCoord [ n ] = coord [ n ] + delta * 0.5 ;
2013-12-28 20:02:49 +00:00
shiftCoord [ nP ] = coord [ nP ] - deltaP_M * 0.25 ;
shiftCoord [ nPP ] = coord [ nPP ] + deltaPP * 0.25 ;
2010-09-02 13:35:13 +00:00
- - loc_pos [ nP ] ;
2011-03-18 13:17:09 +00:00
A_n = GetNodeArea ( ny , loc_pos , true ) ;
2014-10-19 19:59:39 +00:00
EffMat [ 0 ] + = GetMaterial ( n , shiftCoord , 0 , vPrims ) * A_n ;
EffMat [ 1 ] + = GetMaterial ( n , shiftCoord , 1 , vPrims ) * A_n ;
2010-09-02 13:35:13 +00:00
area + = A_n ;
2010-03-05 13:20:25 +00:00
//shift down-right
shiftCoord [ n ] = coord [ n ] + delta * 0.5 ;
2013-12-28 20:02:49 +00:00
shiftCoord [ nP ] = coord [ nP ] + deltaP * 0.25 ;
shiftCoord [ nPP ] = coord [ nPP ] - deltaPP_M * 0.25 ;
2010-09-02 13:35:13 +00:00
+ + loc_pos [ nP ] ;
- - loc_pos [ nPP ] ;
2011-03-18 13:17:09 +00:00
A_n = GetNodeArea ( ny , loc_pos , true ) ;
2014-10-19 19:59:39 +00:00
EffMat [ 0 ] + = GetMaterial ( n , shiftCoord , 0 , vPrims ) * A_n ;
EffMat [ 1 ] + = GetMaterial ( n , shiftCoord , 1 , vPrims ) * A_n ;
2010-09-02 13:35:13 +00:00
area + = A_n ;
2010-03-05 13:20:25 +00:00
//shift down-left
shiftCoord [ n ] = coord [ n ] + delta * 0.5 ;
2013-12-28 20:02:49 +00:00
shiftCoord [ nP ] = coord [ nP ] - deltaP_M * 0.25 ;
shiftCoord [ nPP ] = coord [ nPP ] - deltaPP_M * 0.25 ;
2010-09-02 13:35:13 +00:00
- - loc_pos [ nP ] ;
2011-03-18 13:17:09 +00:00
A_n = GetNodeArea ( ny , loc_pos , true ) ;
2014-10-19 19:59:39 +00:00
EffMat [ 0 ] + = GetMaterial ( n , shiftCoord , 0 , vPrims ) * A_n ;
EffMat [ 1 ] + = GetMaterial ( n , shiftCoord , 1 , vPrims ) * A_n ;
2010-09-02 13:35:13 +00:00
area + = A_n ;
2010-03-05 13:20:25 +00:00
2010-09-02 13:35:13 +00:00
EffMat [ 0 ] * = __EPS0__ / area ;
EffMat [ 1 ] / = area ;
2010-03-05 13:20:25 +00:00
//******************************* mu,sigma averaging *****************************//
2010-12-06 12:04:37 +00:00
loc_pos [ 0 ] = pos [ 0 ] ;
loc_pos [ 1 ] = pos [ 1 ] ;
loc_pos [ 2 ] = pos [ 2 ] ;
2010-09-02 13:35:13 +00:00
double length = 0 ;
2011-03-18 13:17:09 +00:00
2010-03-05 13:20:25 +00:00
//shift down
2013-12-28 20:02:49 +00:00
shiftCoord [ n ] = coord [ n ] - delta_M * 0.25 ;
2010-03-05 13:20:25 +00:00
shiftCoord [ nP ] = coord [ nP ] + deltaP * 0.5 ;
shiftCoord [ nPP ] = coord [ nPP ] + deltaPP * 0.5 ;
2010-09-02 13:35:13 +00:00
- - loc_pos [ n ] ;
2011-03-18 13:17:09 +00:00
double delta_ny = GetNodeWidth ( n , loc_pos , true ) ;
2014-10-19 19:59:39 +00:00
EffMat [ 2 ] = delta_ny / GetMaterial ( n , shiftCoord , 2 , vPrims ) ;
double sigma = GetMaterial ( n , shiftCoord , 3 , vPrims ) ;
2011-03-18 13:17:09 +00:00
if ( sigma )
EffMat [ 3 ] = delta_ny / sigma ;
2010-03-05 13:20:25 +00:00
else
2010-09-02 13:35:13 +00:00
EffMat [ 3 ] = 0 ;
length = delta_ny ;
2010-03-05 13:20:25 +00:00
//shift up
2013-12-28 20:02:49 +00:00
shiftCoord [ n ] = coord [ n ] + delta * 0.25 ;
2010-03-05 13:20:25 +00:00
shiftCoord [ nP ] = coord [ nP ] + deltaP * 0.5 ;
shiftCoord [ nPP ] = coord [ nPP ] + deltaPP * 0.5 ;
2010-09-02 13:35:13 +00:00
+ + loc_pos [ n ] ;
2011-03-18 13:17:09 +00:00
delta_ny = GetNodeWidth ( n , loc_pos , true ) ;
2014-10-19 19:59:39 +00:00
EffMat [ 2 ] + = delta_ny / GetMaterial ( n , shiftCoord , 2 , vPrims ) ;
sigma = GetMaterial ( n , shiftCoord , 3 , vPrims ) ;
2011-03-18 13:17:09 +00:00
if ( sigma )
EffMat [ 3 ] + = delta_ny / sigma ;
2010-03-05 13:20:25 +00:00
else
2010-09-02 13:35:13 +00:00
EffMat [ 3 ] = 0 ;
length + = delta_ny ;
2010-03-05 13:20:25 +00:00
2010-09-02 13:35:13 +00:00
EffMat [ 2 ] = length * __MUE0__ / EffMat [ 2 ] ;
if ( EffMat [ 3 ] ) EffMat [ 3 ] = length / EffMat [ 3 ] ;
2010-03-05 13:20:25 +00:00
2010-12-06 12:04:37 +00:00
for ( int n = 0 ; n < 4 ; + + n )
2018-03-27 00:10:18 +00:00
if ( std : : isnan ( EffMat [ n ] ) | | std : : isinf ( EffMat [ n ] ) )
2010-09-02 13:35:13 +00:00
{
2013-12-28 20:02:49 +00:00
cerr < < " Operator:: " < < __func__ < < " : Error, An effective material parameter is not a valid result, this should NOT have happend... exit... " < < endl ;
cerr < < ny < < " @ " < < n < < " : " < < pos [ 0 ] < < " , " < < pos [ 1 ] < < " , " < < pos [ 2 ] < < endl ;
2010-09-02 13:35:13 +00:00
exit ( 0 ) ;
}
2010-03-05 13:20:25 +00:00
return true ;
}
2014-10-19 19:59:39 +00:00
bool Operator : : Calc_EffMatPos ( int ny , const unsigned int * pos , double * EffMat , vector < CSPrimitives * > vPrims ) const
2013-12-28 20:02:49 +00:00
{
switch ( m_MatAverageMethod )
{
case QuarterCell :
2014-10-19 19:59:39 +00:00
return AverageMatQuarterCell ( ny , pos , EffMat , vPrims ) ;
2013-12-28 20:02:49 +00:00
case CentralCell :
2014-10-19 19:59:39 +00:00
return AverageMatCellCenter ( ny , pos , EffMat , vPrims ) ;
2013-12-28 20:02:49 +00:00
default :
cerr < < " Operator:: " < < __func__ < < " : Error, unknown material averaging method... exit " < < endl ;
exit ( 1 ) ;
}
return false ;
}
2011-04-08 07:59:48 +00:00
bool Operator : : Calc_LumpedElements ( )
{
vector < CSProperties * > props = CSX - > GetPropertyByType ( CSProperties : : LUMPED_ELEMENT ) ;
for ( size_t i = 0 ; i < props . size ( ) ; + + i )
{
CSPropLumpedElement * PLE = dynamic_cast < CSPropLumpedElement * > ( props . at ( i ) ) ;
if ( PLE = = NULL )
return false ; //sanity check: this should never happen!
vector < CSPrimitives * > prims = PLE - > GetAllPrimitives ( ) ;
for ( size_t bn = 0 ; bn < prims . size ( ) ; + + bn )
{
CSPrimBox * box = dynamic_cast < CSPrimBox * > ( prims . at ( bn ) ) ;
if ( box )
{ //calculate lumped element parameter
double C = PLE - > GetCapacity ( ) ;
if ( C < = 0 )
C = NAN ;
double R = PLE - > GetResistance ( ) ;
if ( R < 0 )
R = NAN ;
2018-03-27 00:10:18 +00:00
if ( ( std : : isnan ( R ) ) & & ( std : : isnan ( C ) ) )
2011-04-08 07:59:48 +00:00
{
cerr < < " Operator::Calc_LumpedElements(): Warning: Lumped Element R or C not specified! skipping. "
< < " ID: " < < prims . at ( bn ) - > GetID ( ) < < " @ Property: " < < PLE - > GetName ( ) < < endl ;
2011-11-16 10:30:21 +00:00
continue ;
2011-04-08 07:59:48 +00:00
}
int ny = PLE - > GetDirection ( ) ;
if ( ( ny < 0 ) | | ( ny > 2 ) )
{
cerr < < " Operator::Calc_LumpedElements(): Warning: Lumped Element direction is invalid! skipping. "
< < " ID: " < < prims . at ( bn ) - > GetID ( ) < < " @ Property: " < < PLE - > GetName ( ) < < endl ;
2011-11-16 10:30:21 +00:00
continue ;
2011-04-08 07:59:48 +00:00
}
int nyP = ( ny + 1 ) % 3 ;
int nyPP = ( ny + 2 ) % 3 ;
unsigned int uiStart [ 3 ] ;
unsigned int uiStop [ 3 ] ;
// snap to the native coordinate system
2013-02-06 15:33:12 +00:00
int Snap_Dimension = Operator : : SnapBox2Mesh ( box - > GetStartCoord ( ) - > GetCoords ( m_MeshType ) , box - > GetStopCoord ( ) - > GetCoords ( m_MeshType ) , uiStart , uiStop , false , true ) ;
2011-08-16 15:04:16 +00:00
if ( Snap_Dimension < = 0 )
{
2011-11-16 10:30:21 +00:00
if ( Snap_Dimension > = - 1 )
2011-08-16 15:04:16 +00:00
cerr < < " Operator::Calc_LumpedElements(): Warning: Lumped Element snapping failed! Dimension is: " < < Snap_Dimension < < " skipping. "
< < " ID: " < < prims . at ( bn ) - > GetID ( ) < < " @ Property: " < < PLE - > GetName ( ) < < endl ;
2011-11-16 10:30:21 +00:00
// Snap_Dimension == -2 means outside the simulation domain --> no special warning, but box probably marked as unused!
continue ;
2011-08-16 15:04:16 +00:00
}
2011-04-08 07:59:48 +00:00
if ( uiStart [ ny ] = = uiStop [ ny ] )
{
cerr < < " Operator::Calc_LumpedElements(): Warning: Lumped Element with zero (snapped) length is invalid! skipping. "
< < " ID: " < < prims . at ( bn ) - > GetID ( ) < < " @ Property: " < < PLE - > GetName ( ) < < endl ;
2011-11-16 10:30:21 +00:00
continue ;
2011-04-08 07:59:48 +00:00
}
//calculate geometric property for this lumped element
unsigned int pos [ 3 ] ;
double unitGC = 0 ;
int ipos = 0 ;
for ( pos [ ny ] = uiStart [ ny ] ; pos [ ny ] < uiStop [ ny ] ; + + pos [ ny ] )
{
double unitGC_Plane = 0 ;
for ( pos [ nyP ] = uiStart [ nyP ] ; pos [ nyP ] < = uiStop [ nyP ] ; + + pos [ nyP ] )
{
for ( pos [ nyPP ] = uiStart [ nyPP ] ; pos [ nyPP ] < = uiStop [ nyPP ] ; + + pos [ nyPP ] )
{
// capacity/conductivity in parallel: add values
unitGC_Plane + = GetEdgeArea ( ny , pos ) / GetEdgeLength ( ny , pos ) ;
}
}
//capacity/conductivity in series: add reciprocal values
unitGC + = 1 / unitGC_Plane ;
}
unitGC = 1 / unitGC ;
bool caps = PLE - > GetCaps ( ) ;
double kappa = 0 ;
double epsilon = 0 ;
if ( R > 0 )
kappa = 1 / R / unitGC ;
if ( C > 0 )
2011-07-13 07:32:44 +00:00
{
2011-04-08 07:59:48 +00:00
epsilon = C / unitGC ;
2011-07-13 07:32:44 +00:00
if ( epsilon < __EPS0__ )
{
cerr < < " Operator::Calc_LumpedElements(): Warning: Lumped Element capacity is too small for its size! skipping. "
< < " ID: " < < prims . at ( bn ) - > GetID ( ) < < " @ Property: " < < PLE - > GetName ( ) < < endl ;
C = 0 ;
}
2011-04-08 07:59:48 +00:00
}
for ( pos [ ny ] = uiStart [ ny ] ; pos [ ny ] < uiStop [ ny ] ; + + pos [ ny ] )
{
for ( pos [ nyP ] = uiStart [ nyP ] ; pos [ nyP ] < = uiStop [ nyP ] ; + + pos [ nyP ] )
{
for ( pos [ nyPP ] = uiStart [ nyPP ] ; pos [ nyPP ] < = uiStop [ nyPP ] ; + + pos [ nyPP ] )
{
ipos = MainOp - > SetPos ( pos [ 0 ] , pos [ 1 ] , pos [ 2 ] ) ;
if ( C > 0 )
EC_C [ ny ] [ ipos ] = epsilon * GetEdgeArea ( ny , pos ) / GetEdgeLength ( ny , pos ) ;
if ( R > 0 )
EC_G [ ny ] [ ipos ] = kappa * GetEdgeArea ( ny , pos ) / GetEdgeLength ( ny , pos ) ;
2012-04-27 14:31:36 +00:00
2011-04-08 07:59:48 +00:00
if ( R = = 0 ) //make lumped element a PEC if resistance is zero
{
SetVV ( ny , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetVI ( ny , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
}
else //recalculate operator inside the lumped element
Calc_ECOperatorPos ( ny , pos ) ;
}
}
}
// setup metal caps
if ( caps )
{
for ( pos [ nyP ] = uiStart [ nyP ] ; pos [ nyP ] < = uiStop [ nyP ] ; + + pos [ nyP ] )
{
for ( pos [ nyPP ] = uiStart [ nyPP ] ; pos [ nyPP ] < = uiStop [ nyPP ] ; + + pos [ nyPP ] )
{
pos [ ny ] = uiStart [ ny ] ;
2013-08-22 10:55:27 +00:00
if ( pos [ nyP ] < uiStop [ nyP ] )
{
SetVV ( nyP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetVI ( nyP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
+ + m_Nr_PEC [ nyP ] ;
}
2011-04-08 07:59:48 +00:00
2013-08-22 10:55:27 +00:00
if ( pos [ nyPP ] < uiStop [ nyPP ] )
{
SetVV ( nyPP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetVI ( nyPP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
+ + m_Nr_PEC [ nyPP ] ;
}
2011-04-08 07:59:48 +00:00
pos [ ny ] = uiStop [ ny ] ;
2013-08-22 10:55:27 +00:00
if ( pos [ nyP ] < uiStop [ nyP ] )
{
SetVV ( nyP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetVI ( nyP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
+ + m_Nr_PEC [ nyP ] ;
}
2011-04-08 07:59:48 +00:00
2013-08-22 10:55:27 +00:00
if ( pos [ nyPP ] < uiStop [ nyPP ] )
{
SetVV ( nyPP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetVI ( nyPP , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
+ + m_Nr_PEC [ nyPP ] ;
}
2011-04-08 07:59:48 +00:00
}
}
}
2011-07-13 07:32:44 +00:00
box - > SetPrimitiveUsed ( true ) ;
2011-04-08 07:59:48 +00:00
}
else
cerr < < " Operator::Calc_LumpedElements(): Warning: Primitves other than boxes are not supported for lumped elements! skipping "
< < prims . at ( bn ) - > GetTypeName ( ) < < " ID: " < < prims . at ( bn ) - > GetID ( ) < < " @ Property: " < < PLE - > GetName ( ) < < endl ;
}
}
return true ;
}
2010-06-05 09:47:21 +00:00
void Operator : : Init_EC ( )
2010-03-05 13:20:25 +00:00
{
2010-12-06 12:04:37 +00:00
for ( int n = 0 ; n < 3 ; + + n )
2010-03-05 13:20:25 +00:00
{
//init x-cell-array
delete [ ] EC_C [ n ] ;
delete [ ] EC_G [ n ] ;
delete [ ] EC_L [ n ] ;
delete [ ] EC_R [ n ] ;
2012-07-12 08:06:13 +00:00
EC_C [ n ] = new FDTD_FLOAT [ MainOp - > GetSize ( ) ] ;
EC_G [ n ] = new FDTD_FLOAT [ MainOp - > GetSize ( ) ] ;
EC_L [ n ] = new FDTD_FLOAT [ MainOp - > GetSize ( ) ] ;
EC_R [ n ] = new FDTD_FLOAT [ MainOp - > GetSize ( ) ] ;
2010-12-06 12:04:37 +00:00
for ( unsigned int i = 0 ; i < MainOp - > GetSize ( ) ; i + + ) //init all
2010-03-05 13:20:25 +00:00
{
EC_C [ n ] [ i ] = 0 ;
EC_G [ n ] [ i ] = 0 ;
EC_L [ n ] [ i ] = 0 ;
EC_R [ n ] [ i ] = 0 ;
}
2010-06-05 09:47:21 +00:00
}
}
bool Operator : : Calc_EC ( )
{
2010-12-06 12:04:37 +00:00
if ( CSX = = NULL )
{
cerr < < " CartOperator::Calc_EC: CSX not given or invalid!!! " < < endl ;
return false ;
}
2014-10-19 19:59:39 +00:00
MainOp - > SetPos ( 0 , 0 , 0 ) ;
Calc_EC_Range ( 0 , numLines [ 0 ] - 1 ) ;
return true ;
}
vector < CSPrimitives * > Operator : : GetPrimitivesBoundBox ( int posX , int posY , int posZ , CSProperties : : PropertyType type ) const
{
double boundBox [ 6 ] ;
int BBpos [ 3 ] = { posX , posY , posZ } ;
for ( int n = 0 ; n < 3 ; + + n )
{
if ( BBpos [ n ] < 0 )
{
boundBox [ 2 * n ] = this - > GetDiscLine ( n , 0 ) ;
boundBox [ 2 * n + 1 ] = this - > GetDiscLine ( n , numLines [ n ] - 1 ) ;
}
else
{
boundBox [ 2 * n ] = this - > GetDiscLine ( n , max ( 0 , BBpos [ n ] - 1 ) ) ;
boundBox [ 2 * n + 1 ] = this - > GetDiscLine ( n , min ( int ( numLines [ n ] ) - 1 , BBpos [ n ] + 1 ) ) ;
}
}
vector < CSPrimitives * > vPrim = this - > CSX - > GetPrimitivesByBoundBox ( boundBox , true , type ) ;
return vPrim ;
}
void Operator : : Calc_EC_Range ( unsigned int xStart , unsigned int xStop )
{
// vector<CSPrimitives*> vPrims = this->CSX->GetAllPrimitives(true, CSProperties::MATERIAL);
2010-06-05 09:47:21 +00:00
unsigned int ipos ;
unsigned int pos [ 3 ] ;
double inEC [ 4 ] ;
2014-10-19 19:59:39 +00:00
for ( pos [ 0 ] = xStart ; pos [ 0 ] < = xStop ; + + pos [ 0 ] )
2010-06-05 09:47:21 +00:00
{
2014-10-19 19:59:39 +00:00
for ( pos [ 1 ] = 0 ; pos [ 1 ] < numLines [ 1 ] ; + + pos [ 1 ] )
2010-03-05 13:20:25 +00:00
{
2014-10-19 19:59:39 +00:00
vector < CSPrimitives * > vPrims = this - > GetPrimitivesBoundBox ( pos [ 0 ] , pos [ 1 ] , - 1 , CSProperties : : MATERIAL ) ;
for ( pos [ 2 ] = 0 ; pos [ 2 ] < numLines [ 2 ] ; + + pos [ 2 ] )
2010-03-05 13:20:25 +00:00
{
2014-10-19 19:59:39 +00:00
ipos = MainOp - > GetPos ( pos [ 0 ] , pos [ 1 ] , pos [ 2 ] ) ;
for ( int n = 0 ; n < 3 ; + + n )
2010-03-05 13:20:25 +00:00
{
2014-10-19 19:59:39 +00:00
Calc_ECPos ( n , pos , inEC , vPrims ) ;
2010-03-05 13:20:25 +00:00
EC_C [ n ] [ ipos ] = inEC [ 0 ] ;
EC_G [ n ] [ ipos ] = inEC [ 1 ] ;
EC_L [ n ] [ ipos ] = inEC [ 2 ] ;
EC_R [ n ] [ ipos ] = inEC [ 3 ] ;
}
}
}
}
}
2012-09-27 12:20:20 +00:00
void Operator : : SetTimestepFactor ( double factor )
{
if ( ( factor < = 0 ) | | ( factor > 1 ) )
{
cerr < < " Operator::SetTimestepFactor: Warning, invalid timestep factor, skipping! " < < endl ;
return ;
}
cout < < " Operator::SetTimestepFactor: Setting timestep factor to " < < factor < < endl ;
m_TimeStepFactor = factor ;
}
2010-03-05 13:20:25 +00:00
double Operator : : CalcTimestep ( )
{
2011-02-16 14:28:14 +00:00
if ( m_TimeStepVar = = 3 )
return CalcTimestep_Var3 ( ) ; //the biggest one for cartesian meshes
//variant 1 is default
2010-06-22 10:49:51 +00:00
return CalcTimestep_Var1 ( ) ;
}
////Berechnung nach Andreas Rennings Dissertation 2008, Seite 66, Formel 4.52
double Operator : : CalcTimestep_Var1 ( )
{
2010-07-13 13:37:56 +00:00
m_Used_TS_Name = string ( " Rennings_1 " ) ;
// cout << "Operator::CalcTimestep(): Using timestep algorithm by Andreas Rennings, Dissertation @ University Duisburg-Essen, 2008, pp. 66, eq. 4.52" << endl;
2010-03-05 13:20:25 +00:00
dT = 1e200 ;
double newT ;
unsigned int pos [ 3 ] ;
2011-11-16 11:50:22 +00:00
unsigned int smallest_pos [ 3 ] = { 0 , 0 , 0 } ;
unsigned int smallest_n = 0 ;
2010-03-05 13:20:25 +00:00
unsigned int ipos ;
unsigned int ipos_PM ;
unsigned int ipos_PPM ;
MainOp - > SetReflection2Cell ( ) ;
2010-12-06 12:04:37 +00:00
for ( int n = 0 ; n < 3 ; + + n )
2010-03-05 13:20:25 +00:00
{
int nP = ( n + 1 ) % 3 ;
int nPP = ( n + 2 ) % 3 ;
2010-12-06 12:04:37 +00:00
for ( pos [ 2 ] = 0 ; pos [ 2 ] < numLines [ 2 ] ; + + pos [ 2 ] )
2010-03-05 13:20:25 +00:00
{
2010-12-06 12:04:37 +00:00
for ( pos [ 1 ] = 0 ; pos [ 1 ] < numLines [ 1 ] ; + + pos [ 1 ] )
2010-03-05 13:20:25 +00:00
{
2010-12-06 12:04:37 +00:00
for ( pos [ 0 ] = 0 ; pos [ 0 ] < numLines [ 0 ] ; + + pos [ 0 ] )
2010-03-05 13:20:25 +00:00
{
ipos = MainOp - > SetPos ( pos [ 0 ] , pos [ 1 ] , pos [ 2 ] ) ;
ipos_PM = MainOp - > Shift ( nP , - 1 ) ;
MainOp - > ResetShift ( ) ;
ipos_PPM = MainOp - > Shift ( nPP , - 1 ) ;
MainOp - > ResetShift ( ) ;
newT = 2 / sqrt ( ( 4 / EC_L [ nP ] [ ipos ] + 4 / EC_L [ nP ] [ ipos_PPM ] + 4 / EC_L [ nPP ] [ ipos ] + 4 / EC_L [ nPP ] [ ipos_PM ] ) / EC_C [ n ] [ ipos ] ) ;
2011-11-16 10:26:10 +00:00
if ( ( newT < dT ) & & ( newT > 0.0 ) )
{
dT = newT ;
smallest_pos [ 0 ] = pos [ 0 ] ; smallest_pos [ 1 ] = pos [ 1 ] ; smallest_pos [ 2 ] = pos [ 2 ] ;
smallest_n = n ;
}
2010-03-05 13:20:25 +00:00
}
}
}
}
2010-04-13 16:40:43 +00:00
if ( dT = = 0 )
{
cerr < < " Operator::CalcTimestep: Timestep is zero... this is not supposed to happen!!! exit! " < < endl ;
exit ( 3 ) ;
}
2011-11-16 10:26:10 +00:00
if ( g_settings . GetVerboseLevel ( ) > 1 )
{
cout < < " Operator::CalcTimestep_Var1: Smallest timestep ( " < < dT < < " s) found at position: " < < smallest_n < < " : " < < smallest_pos [ 0 ] < < " ; " < < smallest_pos [ 1 ] < < " ; " < < smallest_pos [ 2 ] < < endl ;
}
2010-03-05 13:20:25 +00:00
return 0 ;
}
2010-06-18 10:37:37 +00:00
double min ( double * val , unsigned int count )
{
if ( count = = 0 )
return 0.0 ;
double min = val [ 0 ] ;
2010-12-06 12:04:37 +00:00
for ( unsigned int n = 1 ; n < count ; + + n )
2010-06-18 10:37:37 +00:00
if ( val [ n ] < min )
min = val [ n ] ;
return min ;
}
//Berechnung nach Andreas Rennings Dissertation 2008, Seite 76 ff, Formel 4.77 ff
2010-06-22 10:49:51 +00:00
double Operator : : CalcTimestep_Var3 ( )
2010-06-18 10:37:37 +00:00
{
dT = 1e200 ;
2010-07-13 13:37:56 +00:00
m_Used_TS_Name = string ( " Rennings_2 " ) ;
// cout << "Operator::CalcTimestep(): Using timestep algorithm by Andreas Rennings, Dissertation @ University Duisburg-Essen, 2008, pp. 76, eq. 4.77 ff." << endl;
2010-06-18 10:37:37 +00:00
double newT ;
unsigned int pos [ 3 ] ;
2011-11-16 11:50:22 +00:00
unsigned int smallest_pos [ 3 ] = { 0 , 0 , 0 } ;
unsigned int smallest_n = 0 ;
2010-06-18 10:37:37 +00:00
unsigned int ipos ;
double w_total = 0 ;
double wqp = 0 , wt1 = 0 , wt2 = 0 ;
double wt_4 [ 4 ] = { 0 , 0 , 0 , 0 } ;
MainOp - > SetReflection2Cell ( ) ;
2010-12-06 12:04:37 +00:00
for ( int n = 0 ; n < 3 ; + + n )
2010-06-18 10:37:37 +00:00
{
int nP = ( n + 1 ) % 3 ;
int nPP = ( n + 2 ) % 3 ;
2010-12-06 12:04:37 +00:00
for ( pos [ 2 ] = 0 ; pos [ 2 ] < numLines [ 2 ] ; + + pos [ 2 ] )
2010-06-18 10:37:37 +00:00
{
2010-12-06 12:04:37 +00:00
for ( pos [ 1 ] = 0 ; pos [ 1 ] < numLines [ 1 ] ; + + pos [ 1 ] )
2010-06-18 10:37:37 +00:00
{
2010-12-06 12:04:37 +00:00
for ( pos [ 0 ] = 0 ; pos [ 0 ] < numLines [ 0 ] ; + + pos [ 0 ] )
2010-06-18 10:37:37 +00:00
{
MainOp - > ResetShift ( ) ;
ipos = MainOp - > SetPos ( pos [ 0 ] , pos [ 1 ] , pos [ 2 ] ) ;
wqp = 1 / ( EC_L [ nPP ] [ ipos ] * EC_C [ n ] [ MainOp - > GetShiftedPos ( nP , 1 ) ] ) + 1 / ( EC_L [ nPP ] [ ipos ] * EC_C [ n ] [ ipos ] ) ;
wqp + = 1 / ( EC_L [ nP ] [ ipos ] * EC_C [ n ] [ MainOp - > GetShiftedPos ( nPP , 1 ) ] ) + 1 / ( EC_L [ nP ] [ ipos ] * EC_C [ n ] [ ipos ] ) ;
ipos = MainOp - > Shift ( nP , - 1 ) ;
wqp + = 1 / ( EC_L [ nPP ] [ ipos ] * EC_C [ n ] [ MainOp - > GetShiftedPos ( nP , 1 ) ] ) + 1 / ( EC_L [ nPP ] [ ipos ] * EC_C [ n ] [ ipos ] ) ;
ipos = MainOp - > Shift ( nPP , - 1 ) ;
wqp + = 1 / ( EC_L [ nP ] [ ipos ] * EC_C [ n ] [ MainOp - > GetShiftedPos ( nPP , 1 ) ] ) + 1 / ( EC_L [ nP ] [ ipos ] * EC_C [ n ] [ ipos ] ) ;
MainOp - > ResetShift ( ) ;
ipos = MainOp - > SetPos ( pos [ 0 ] , pos [ 1 ] , pos [ 2 ] ) ;
wt_4 [ 0 ] = 1 / ( EC_L [ nPP ] [ ipos ] * EC_C [ nP ] [ ipos ] ) ;
wt_4 [ 1 ] = 1 / ( EC_L [ nPP ] [ MainOp - > GetShiftedPos ( nP , - 1 ) ] * EC_C [ nP ] [ ipos ] ) ;
wt_4 [ 2 ] = 1 / ( EC_L [ nP ] [ ipos ] * EC_C [ nPP ] [ ipos ] ) ;
wt_4 [ 3 ] = 1 / ( EC_L [ nP ] [ MainOp - > GetShiftedPos ( nPP , - 1 ) ] * EC_C [ nPP ] [ ipos ] ) ;
wt1 = wt_4 [ 0 ] + wt_4 [ 1 ] + wt_4 [ 2 ] + wt_4 [ 3 ] - 2 * min ( wt_4 , 4 ) ;
MainOp - > ResetShift ( ) ;
ipos = MainOp - > SetPos ( pos [ 0 ] , pos [ 1 ] , pos [ 2 ] ) ;
wt_4 [ 0 ] = 1 / ( EC_L [ nPP ] [ ipos ] * EC_C [ nP ] [ MainOp - > GetShiftedPos ( n , 1 ) ] ) ;
wt_4 [ 1 ] = 1 / ( EC_L [ nPP ] [ MainOp - > GetShiftedPos ( nP , - 1 ) ] * EC_C [ nP ] [ MainOp - > GetShiftedPos ( n , 1 ) ] ) ;
wt_4 [ 2 ] = 1 / ( EC_L [ nP ] [ ipos ] * EC_C [ nPP ] [ MainOp - > GetShiftedPos ( n , 1 ) ] ) ;
wt_4 [ 3 ] = 1 / ( EC_L [ nP ] [ MainOp - > GetShiftedPos ( nPP , - 1 ) ] * EC_C [ nPP ] [ MainOp - > GetShiftedPos ( n , 1 ) ] ) ;
wt2 = wt_4 [ 0 ] + wt_4 [ 1 ] + wt_4 [ 2 ] + wt_4 [ 3 ] - 2 * min ( wt_4 , 4 ) ;
w_total = wqp + wt1 + wt2 ;
newT = 2 / sqrt ( w_total ) ;
if ( ( newT < dT ) & & ( newT > 0.0 ) )
2011-11-16 10:26:10 +00:00
{
2010-06-18 10:37:37 +00:00
dT = newT ;
2011-11-16 10:26:10 +00:00
smallest_pos [ 0 ] = pos [ 0 ] ; smallest_pos [ 1 ] = pos [ 1 ] ; smallest_pos [ 2 ] = pos [ 2 ] ;
smallest_n = n ;
}
2010-06-18 10:37:37 +00:00
}
}
}
}
if ( dT = = 0 )
{
cerr < < " Operator::CalcTimestep: Timestep is zero... this is not supposed to happen!!! exit! " < < endl ;
exit ( 3 ) ;
}
2011-11-16 10:26:10 +00:00
if ( g_settings . GetVerboseLevel ( ) > 1 )
{
cout < < " Operator::CalcTimestep_Var3: Smallest timestep ( " < < dT < < " s) found at position: " < < smallest_n < < " : " < < smallest_pos [ 0 ] < < " ; " < < smallest_pos [ 1 ] < < " ; " < < smallest_pos [ 2 ] < < endl ;
}
2010-06-18 10:37:37 +00:00
return 0 ;
}
2010-06-05 22:53:05 +00:00
bool Operator : : CalcPEC ( )
{
2010-12-06 12:04:37 +00:00
m_Nr_PEC [ 0 ] = 0 ;
m_Nr_PEC [ 1 ] = 0 ;
m_Nr_PEC [ 2 ] = 0 ;
2010-05-03 16:33:14 +00:00
2010-06-05 23:47:32 +00:00
CalcPEC_Range ( 0 , numLines [ 0 ] - 1 , m_Nr_PEC ) ;
2010-05-03 16:33:14 +00:00
2010-06-05 22:53:05 +00:00
CalcPEC_Curves ( ) ;
return true ;
}
2010-06-05 23:47:32 +00:00
void Operator : : CalcPEC_Range ( unsigned int startX , unsigned int stopX , unsigned int * counter )
2010-03-05 13:20:25 +00:00
{
double coord [ 3 ] ;
2010-06-05 22:53:05 +00:00
unsigned int pos [ 3 ] ;
2010-12-06 12:04:37 +00:00
for ( pos [ 0 ] = startX ; pos [ 0 ] < = stopX ; + + pos [ 0 ] )
2010-03-05 13:20:25 +00:00
{
2010-12-06 12:04:37 +00:00
for ( pos [ 1 ] = 0 ; pos [ 1 ] < numLines [ 1 ] ; + + pos [ 1 ] )
2010-03-05 13:20:25 +00:00
{
2014-10-19 19:59:39 +00:00
vector < CSPrimitives * > vPrims = this - > GetPrimitivesBoundBox ( pos [ 0 ] , pos [ 1 ] , - 1 , ( CSProperties : : PropertyType ) ( CSProperties : : MATERIAL | CSProperties : : METAL ) ) ;
2010-12-06 12:04:37 +00:00
for ( pos [ 2 ] = 0 ; pos [ 2 ] < numLines [ 2 ] ; + + pos [ 2 ] )
2010-03-05 13:20:25 +00:00
{
2010-12-06 12:04:37 +00:00
for ( int n = 0 ; n < 3 ; + + n )
2010-03-05 13:20:25 +00:00
{
2011-03-16 11:26:41 +00:00
GetYeeCoords ( n , pos , coord , false ) ;
2014-10-19 19:59:39 +00:00
CSProperties * prop = CSX - > GetPropertyByCoordPriority ( coord , vPrims , true ) ;
// CSProperties* old_prop = CSX->GetPropertyByCoordPriority(coord, (CSProperties::PropertyType)(CSProperties::MATERIAL | CSProperties::METAL), true);
// if (old_prop!=prop)
// {
// cerr << "CalcPEC_Range: " << old_prop << " vs " << prop << endl;
// exit(-1);
// }
2010-03-05 13:20:25 +00:00
if ( prop )
{
if ( prop - > GetType ( ) = = CSProperties : : METAL ) //set to PEC
{
2010-10-20 05:26:16 +00:00
SetVV ( n , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
SetVI ( n , pos [ 0 ] , pos [ 1 ] , pos [ 2 ] , 0 ) ;
2010-06-05 23:47:32 +00:00
+ + counter [ n ] ;
2010-03-05 13:20:25 +00:00
}
}
}
}
}
}
2010-06-05 22:53:05 +00:00
}
2010-03-22 07:19:17 +00:00
2010-06-05 22:53:05 +00:00
void Operator : : CalcPEC_Curves ( )
{
2010-03-22 07:19:17 +00:00
//special treatment for primitives of type curve (treated as wires)
double p1 [ 3 ] ;
double p2 [ 3 ] ;
2013-08-16 11:19:12 +00:00
Grid_Path path ;
2010-03-22 07:19:17 +00:00
vector < CSProperties * > vec_prop = CSX - > GetPropertyByType ( CSProperties : : METAL ) ;
2010-12-06 12:04:37 +00:00
for ( size_t p = 0 ; p < vec_prop . size ( ) ; + + p )
2010-03-22 07:19:17 +00:00
{
CSProperties * prop = vec_prop . at ( p ) ;
2010-12-06 12:04:37 +00:00
for ( size_t n = 0 ; n < prop - > GetQtyPrimitives ( ) ; + + n )
2010-03-22 07:19:17 +00:00
{
CSPrimitives * prim = prop - > GetPrimitive ( n ) ;
CSPrimCurve * curv = prim - > ToCurve ( ) ;
if ( curv )
{
2010-12-06 12:04:37 +00:00
for ( size_t i = 1 ; i < curv - > GetNumberOfPoints ( ) ; + + i )
2010-03-22 07:19:17 +00:00
{
2013-02-06 15:33:12 +00:00
curv - > GetPoint ( i - 1 , p1 , m_MeshType ) ;
curv - > GetPoint ( i , p2 , m_MeshType ) ;
2010-03-22 07:19:17 +00:00
path = FindPath ( p1 , p2 ) ;
2010-05-29 15:40:18 +00:00
if ( path . dir . size ( ) > 0 )
prim - > SetPrimitiveUsed ( true ) ;
2010-12-06 12:04:37 +00:00
for ( size_t t = 0 ; t < path . dir . size ( ) ; + + t )
2010-03-22 07:19:17 +00:00
{
2010-10-20 05:26:16 +00:00
SetVV ( path . dir . at ( t ) , path . posPath [ 0 ] . at ( t ) , path . posPath [ 1 ] . at ( t ) , path . posPath [ 2 ] . at ( t ) , 0 ) ;
SetVI ( path . dir . at ( t ) , path . posPath [ 0 ] . at ( t ) , path . posPath [ 1 ] . at ( t ) , path . posPath [ 2 ] . at ( t ) , 0 ) ;
2010-05-10 07:14:29 +00:00
+ + m_Nr_PEC [ path . dir . at ( t ) ] ;
2010-05-29 15:40:18 +00:00
}
2010-03-22 07:19:17 +00:00
}
}
}
}
2010-03-05 13:20:25 +00:00
}
2012-07-17 11:23:00 +00:00
Operator_Ext_Excitation * Operator : : GetExcitationExtension ( ) const
{
//search for excitation extension
Operator_Ext_Excitation * Op_Ext_Exc = 0 ;
for ( size_t n = 0 ; n < m_Op_exts . size ( ) ; + + n )
{
Op_Ext_Exc = dynamic_cast < Operator_Ext_Excitation * > ( m_Op_exts . at ( n ) ) ;
if ( Op_Ext_Exc )
break ;
}
return Op_Ext_Exc ;
}
2010-04-25 19:59:05 +00:00
void Operator : : AddExtension ( Operator_Extension * op_ext )
{
m_Op_exts . push_back ( op_ext ) ;
}
2011-07-25 12:57:09 +00:00
void Operator : : DeleteExtension ( Operator_Extension * op_ext )
{
for ( size_t n = 0 ; n < m_Op_exts . size ( ) ; + + n )
{
if ( m_Op_exts . at ( n ) = = op_ext )
{
m_Op_exts . erase ( m_Op_exts . begin ( ) + n ) ;
return ;
}
}
}
2012-07-23 10:10:35 +00:00
double Operator : : CalcNumericPhaseVelocity ( unsigned int start [ 3 ] , unsigned int stop [ 3 ] , double propDir [ 3 ] , float freq ) const
{
double average_mesh_disc [ 3 ] ;
2013-12-03 15:01:00 +00:00
double c0 = __C0__ / sqrt ( GetBackgroundEpsR ( ) * GetBackgroundMueR ( ) ) ;
2012-07-25 07:41:30 +00:00
//calculate average mesh deltas
2012-07-23 10:10:35 +00:00
for ( int n = 0 ; n < 3 ; + + n )
{
average_mesh_disc [ n ] = fabs ( GetDiscLine ( n , start [ n ] ) - GetDiscLine ( n , stop [ n ] ) ) * GetGridDelta ( ) / ( fabs ( stop [ n ] - start [ n ] ) ) ;
}
2012-07-25 07:41:30 +00:00
// if propagation is in a Cartesian direction, return analytic solution
2012-07-23 10:10:35 +00:00
for ( int n = 0 ; n < 3 ; + + n )
{
int nP = ( n + 1 ) % 3 ;
int nPP = ( n + 2 ) % 3 ;
if ( ( fabs ( propDir [ n ] ) = = 1 ) & & ( propDir [ nP ] = = 0 ) & & ( propDir [ nPP ] = = 0 ) )
{
2013-12-03 15:01:00 +00:00
double kx = asin ( average_mesh_disc [ 0 ] / c0 / dT * sin ( 2 * PI * freq * dT / 2 ) ) * 2 / average_mesh_disc [ 0 ] ;
2012-07-23 10:10:35 +00:00
return 2 * PI * freq / kx ;
}
}
2012-07-25 07:41:30 +00:00
// else, do an newton iterative estimation
2013-12-03 15:01:00 +00:00
double k0 = 2 * PI * freq / c0 ;
2012-07-25 07:41:30 +00:00
double k = k0 ;
2013-12-03 15:01:00 +00:00
double RHS = pow ( sin ( 2 * PI * freq * dT / 2 ) / c0 / dT , 2 ) ;
2012-07-25 07:41:30 +00:00
double fk = 1 , fdk = 0 ;
double old_phv = 0 ;
2013-12-03 15:01:00 +00:00
double phv = c0 ;
2012-07-25 07:41:30 +00:00
double err_est = 1e-6 ;
int it_count = 0 ;
while ( fabs ( old_phv - phv ) > err_est )
{
+ + it_count ;
old_phv = phv ;
fk = 0 ;
fdk = 0 ;
for ( int n = 0 ; n < 3 ; + + n )
{
fk + = pow ( sin ( propDir [ n ] * k * average_mesh_disc [ n ] / 2 ) / average_mesh_disc [ n ] , 2 ) ;
fdk + = propDir [ n ] * sin ( propDir [ n ] * k * average_mesh_disc [ n ] / 2 ) * cos ( propDir [ n ] * k * average_mesh_disc [ n ] / 2 ) / average_mesh_disc [ n ] ;
}
fk - = RHS ;
k - = fk / fdk ;
// do not allow a speed greater than c0 due to a numerical inaccuracy
if ( k < k0 )
k = k0 ;
phv = 2 * PI * freq / k ;
//abort if iteration count is getting to high!
if ( it_count > 99 )
{
cerr < < " Operator::CalcNumericPhaseVelocity: Error, newton iteration estimation can't find a solution!! " < < endl ;
break ;
}
}
if ( g_settings . GetVerboseLevel ( ) > 1 )
cerr < < " Operator::CalcNumericPhaseVelocity: Newton iteration estimated solution: " < < phv / __C0__ < < " *c0 in " < < it_count < < " iterations. " < < endl ;
2012-07-23 10:10:35 +00:00
return phv ;
}