2010-09-08 05:36:32 +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/>.
*/
# include "operator_cylindermultigrid.h"
# include "engine_cylindermultigrid.h"
2010-12-06 14:30:47 +00:00
# include "extensions/operator_ext_cylinder.h"
2010-10-05 15:24:36 +00:00
# include "tools/useful.h"
2013-03-27 11:02:08 +00:00
# include "CSUseful.h"
2010-09-08 05:36:32 +00:00
2013-03-27 11:00:46 +00:00
Operator_CylinderMultiGrid : : Operator_CylinderMultiGrid ( vector < double > Split_Radii , unsigned int level ) : Operator_Cylinder ( )
2010-09-08 05:36:32 +00:00
{
2010-09-08 14:07:28 +00:00
m_Split_Radii = Split_Radii ;
m_Split_Rad = m_Split_Radii . back ( ) ;
m_Split_Radii . pop_back ( ) ;
2013-03-27 11:00:46 +00:00
m_MultiGridLevel = level ;
2010-09-08 05:36:32 +00:00
}
Operator_CylinderMultiGrid : : ~ Operator_CylinderMultiGrid ( )
{
2011-01-24 10:11:45 +00:00
Delete ( ) ;
2010-09-08 05:36:32 +00:00
}
2013-03-27 11:00:46 +00:00
Operator_CylinderMultiGrid * Operator_CylinderMultiGrid : : New ( vector < double > Split_Radii , unsigned int numThreads , unsigned int level )
2010-09-08 05:36:32 +00:00
{
2011-03-14 09:37:12 +00:00
if ( ( Split_Radii . size ( ) = = 0 ) | | ( Split_Radii . size ( ) > CYLIDINDERMULTIGRID_LIMIT ) )
{
cerr < < " Operator_CylinderMultiGrid::New: Warning: Number of multigrids invalid! Split-Number: " < < Split_Radii . size ( ) < < endl ;
return NULL ;
}
2010-09-08 05:36:32 +00:00
cout < < " Create cylindrical multi grid FDTD operator " < < endl ;
2013-03-27 11:00:46 +00:00
Operator_CylinderMultiGrid * op = new Operator_CylinderMultiGrid ( Split_Radii , level ) ;
2010-09-08 05:36:32 +00:00
op - > setNumThreads ( numThreads ) ;
op - > Init ( ) ;
return op ;
}
2014-01-06 14:40:39 +00:00
Engine * Operator_CylinderMultiGrid : : CreateEngine ( )
2010-09-08 05:36:32 +00:00
{
2023-01-06 19:01:07 +00:00
m_Engine = Engine_CylinderMultiGrid : : New ( this , m_orig_numThreads ) ;
2014-01-06 14:40:39 +00:00
return m_Engine ;
2010-09-08 05:36:32 +00:00
}
double Operator_CylinderMultiGrid : : GetNumberCells ( ) const
{
if ( numLines )
return ( numLines [ 0 ] - m_Split_Pos ) * ( numLines [ 1 ] ) * ( numLines [ 2 ] ) + m_InnerOp - > GetNumberCells ( ) ;
return 0 ;
}
2011-03-18 13:17:09 +00:00
bool Operator_CylinderMultiGrid : : SetupCSXGrid ( CSRectGrid * grid )
2010-09-08 05:36:32 +00:00
{
2011-03-18 13:17:09 +00:00
if ( Operator_Cylinder : : SetupCSXGrid ( grid ) = = false )
2010-09-08 05:36:32 +00:00
return false ;
2011-11-16 11:46:49 +00:00
// make this multigrid use the larger timestep by method 3, since no r==0 singularity can be part of this engine
m_TimeStepVar = 3 ;
2011-03-18 13:17:09 +00:00
if ( ( numLines [ 1 ] - CC_closedAlpha ) % 2 ! = 1 )
2010-09-08 05:36:32 +00:00
{
2011-03-18 13:17:09 +00:00
cerr < < " Operator_CylinderMultiGrid::SetupCSXGrid: Error, number of line in alpha direction must be odd... found: " < < numLines [ 1 ] < < endl ;
2010-09-08 14:07:28 +00:00
exit ( 0 ) ;
}
2010-09-08 05:36:32 +00:00
m_Split_Pos = 0 ;
2010-12-06 12:04:37 +00:00
for ( unsigned int n = 0 ; n < numLines [ 0 ] ; + + n )
2010-09-08 05:36:32 +00:00
{
if ( m_Split_Rad < discLines [ 0 ] [ n ] )
{
m_Split_Pos = n ;
2011-11-16 10:24:25 +00:00
if ( g_settings . GetVerboseLevel ( ) > 0 )
cout < < " Operator_CylinderMultiGrid::SetupCSXGrid: Found mesh split position @ " < < m_Split_Pos < < endl ;
2010-09-08 05:36:32 +00:00
m_Split_Rad = discLines [ 0 ] [ n ] ;
break ;
}
}
if ( ( m_Split_Pos < 4 ) | | ( m_Split_Pos > numLines [ 0 ] - 4 ) )
{
2011-03-18 13:17:09 +00:00
cerr < < " Operator_CylinderMultiGrid::SetupCSXGrid: Error, split invalid... " < < endl ;
2010-09-08 05:36:32 +00:00
return false ;
}
2011-03-18 13:17:09 +00:00
return true ;
}
bool Operator_CylinderMultiGrid : : SetGeometryCSX ( ContinuousStructure * geo )
{
if ( Operator_Cylinder : : SetGeometryCSX ( geo ) = = false )
return false ;
2010-09-08 05:36:32 +00:00
CSRectGrid * grid = geo - > GetGrid ( ) ;
grid - > ClearLines ( 0 ) ;
grid - > ClearLines ( 1 ) ;
2010-12-06 12:04:37 +00:00
for ( unsigned int n = 0 ; n < m_Split_Pos ; + + n )
2010-09-08 05:36:32 +00:00
grid - > AddDiscLine ( 0 , discLines [ 0 ] [ n ] ) ;
for ( unsigned int n = 0 ; n < numLines [ 1 ] ; n + = 2 )
grid - > AddDiscLine ( 1 , discLines [ 1 ] [ n ] ) ;
if ( m_InnerOp - > SetGeometryCSX ( CSX ) = = false )
return false ;
//restore grid to original mesh
grid - > ClearLines ( 0 ) ;
grid - > ClearLines ( 1 ) ;
for ( unsigned int n = 0 ; n < numLines [ 0 ] ; + + n )
grid - > AddDiscLine ( 0 , discLines [ 0 ] [ n ] ) ;
for ( unsigned int n = 0 ; n < numLines [ 1 ] ; + + n )
grid - > AddDiscLine ( 1 , discLines [ 1 ] [ n ] ) ;
return true ;
}
void Operator_CylinderMultiGrid : : Init ( )
{
Operator_Cylinder : : Init ( ) ;
2010-09-08 14:07:28 +00:00
if ( m_Split_Radii . empty ( ) )
m_InnerOp = Operator_Cylinder : : New ( m_numThreads ) ;
else
2013-03-27 11:00:46 +00:00
m_InnerOp = Operator_CylinderMultiGrid : : New ( m_Split_Radii , m_numThreads , m_MultiGridLevel + 1 ) ;
2012-06-25 11:22:34 +00:00
for ( int n = 0 ; n < 2 ; + + n )
{
m_interpol_pos_v_2p [ n ] = NULL ;
f4_interpol_v_2p [ n ] = NULL ;
m_interpol_pos_v_2pp [ n ] = NULL ;
f4_interpol_v_2pp [ n ] = NULL ;
m_interpol_pos_i_2p [ n ] = NULL ;
f4_interpol_i_2p [ n ] = NULL ;
m_interpol_pos_i_2pp [ n ] = NULL ;
f4_interpol_i_2pp [ n ] = NULL ;
}
2010-09-08 05:36:32 +00:00
}
2012-06-06 08:19:30 +00:00
bool Operator_CylinderMultiGrid : : GetYeeCoords ( int ny , unsigned int pos [ 3 ] , double * coords , bool dualMesh ) const
{
bool ret = Operator_Cylinder : : GetYeeCoords ( ny , pos , coords , dualMesh ) ;
if ( pos [ 0 ] < ( m_Split_Pos - 1 ) )
ret = false ;
return ret ;
}
2011-02-23 10:08:24 +00:00
# ifdef MPI_SUPPORT
void Operator_CylinderMultiGrid : : SetTag ( int tag )
{
m_MyTag = tag ;
m_InnerOp - > SetTag ( tag + 1 ) ;
}
void Operator_CylinderMultiGrid : : SetNeighborUp ( int ny , int id )
{
2011-03-21 14:09:33 +00:00
if ( ny = = 0 )
{
cerr < < " Operator_CylinderMultiGrid::SetNeighborUp: Error: MPI segregation in radial direction not supported for a cylindircal multigrid. Exit! " ;
MPI_Barrier ( MPI_COMM_WORLD ) ;
exit ( - 1 ) ;
}
2011-02-23 10:08:24 +00:00
Operator_Cylinder : : SetNeighborUp ( ny , id ) ;
m_InnerOp - > SetNeighborUp ( ny , id ) ;
}
void Operator_CylinderMultiGrid : : SetNeighborDown ( int ny , int id )
{
2011-03-21 14:09:33 +00:00
if ( ny = = 0 )
{
cerr < < " Operator_CylinderMultiGrid::SetNeighborDown: Error: MPI segregation in radial direction not supported for a cylindircal multigrid. Exit! " ;
MPI_Barrier ( MPI_COMM_WORLD ) ;
exit ( - 1 ) ;
}
2011-02-23 10:08:24 +00:00
Operator_Cylinder : : SetNeighborDown ( ny , id ) ;
m_InnerOp - > SetNeighborDown ( ny , id ) ;
}
# endif
2010-09-08 05:36:32 +00:00
void Operator_CylinderMultiGrid : : CalcStartStopLines ( unsigned int & numThreads , vector < unsigned int > & start , vector < unsigned int > & stop ) const
{
2010-10-05 15:24:36 +00:00
vector < unsigned int > jpt = AssignJobs2Threads ( numLines [ 0 ] - m_Split_Pos + 1 , numThreads , true ) ;
2010-09-08 05:36:32 +00:00
2010-10-05 15:24:36 +00:00
numThreads = jpt . size ( ) ;
2010-09-08 05:36:32 +00:00
start . resize ( numThreads ) ;
stop . resize ( numThreads ) ;
2010-10-05 15:24:36 +00:00
start . at ( 0 ) = m_Split_Pos - 1 ;
stop . at ( 0 ) = jpt . at ( 0 ) - 1 + m_Split_Pos - 1 ;
for ( unsigned int n = 1 ; n < numThreads ; n + + )
2010-09-08 05:36:32 +00:00
{
2010-10-05 15:24:36 +00:00
start . at ( n ) = stop . at ( n - 1 ) + 1 ;
stop . at ( n ) = start . at ( n ) + jpt . at ( n ) - 1 ;
2010-09-08 05:36:32 +00:00
}
}
2011-01-25 09:27:51 +00:00
void Operator_CylinderMultiGrid : : FillMissingDataStorage ( )
{
unsigned int pos [ 3 ] ;
double EffMat [ 4 ] ;
for ( int ny = 0 ; ny < 3 ; + + ny )
{
for ( pos [ 0 ] = 0 ; pos [ 0 ] < m_Split_Pos - 1 ; + + pos [ 0 ] )
{
for ( pos [ 1 ] = 0 ; pos [ 1 ] < numLines [ 1 ] ; + + pos [ 1 ] )
{
2014-10-19 19:59:39 +00:00
vector < CSPrimitives * > vPrims = this - > GetPrimitivesBoundBox ( pos [ 0 ] , pos [ 1 ] , - 1 , CSProperties : : MATERIAL ) ;
2011-01-25 09:27:51 +00:00
for ( pos [ 2 ] = 0 ; pos [ 2 ] < numLines [ 2 ] ; + + pos [ 2 ] )
{
2014-10-19 19:59:39 +00:00
Calc_EffMatPos ( ny , pos , EffMat , vPrims ) ;
2011-01-25 09:27:51 +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 ] ;
}
}
}
}
}
2013-12-28 19:57:31 +00:00
bool Operator_CylinderMultiGrid : : GetCellCenterMaterialAvgCoord ( const int pos [ 3 ] , double coord [ 3 ] ) const
2013-12-20 14:48:04 +00:00
{
2013-12-28 19:57:31 +00:00
if ( Operator_Cylinder : : GetCellCenterMaterialAvgCoord ( pos , coord ) = = false )
return false ;
if ( pos [ 0 ] > = ( ( int ) m_Split_Pos ) )
return true ;
2013-12-20 14:48:04 +00:00
2013-12-28 19:57:31 +00:00
int pos_a = MapAlphaIndex2Range ( pos [ 1 ] ) / 2 ;
if ( ( pos_a < 0 ) | | ( pos_a > = ( int ) m_InnerOp - > numLines [ 1 ] ) )
return false ;
coord [ 1 ] = m_InnerOp - > GetDiscLine ( 1 , pos_a , true ) ;
return true ;
2013-12-20 14:48:04 +00:00
}
2010-10-27 09:17:58 +00:00
int Operator_CylinderMultiGrid : : CalcECOperator ( DebugFlags debugFlags )
2010-09-08 05:36:32 +00:00
{
2010-09-08 14:07:28 +00:00
int retCode = 0 ;
2010-09-08 05:36:32 +00:00
if ( dT )
m_InnerOp - > SetTimestep ( dT ) ;
//calc inner child first
2010-10-27 12:49:16 +00:00
m_InnerOp - > CalcECOperator ( ) ;
2010-09-08 05:36:32 +00:00
dT = m_InnerOp - > GetTimestep ( ) ;
2010-10-27 09:17:58 +00:00
retCode = Operator_Cylinder : : CalcECOperator ( debugFlags ) ;
2010-09-08 14:07:28 +00:00
if ( GetTimestepValid ( ) = = false )
{
cerr < < " Operator_CylinderMultiGrid::CalcECOperator(): Warning, timestep invalid... resetting... " < < endl ;
dT = opt_dT ;
m_InnerOp - > SetTimestep ( dT ) ;
2010-10-27 12:49:16 +00:00
m_InnerOp - > CalcECOperator ( ) ;
2011-01-25 09:27:51 +00:00
retCode = Operator_Cylinder : : CalcECOperator ( debugFlags ) ;
2010-09-08 14:07:28 +00:00
}
2012-06-25 11:22:34 +00:00
SetupInterpolation ( ) ;
2011-01-25 09:27:51 +00:00
//the data storage will only be filled up to m_Split_Pos-1, fill the remaining area here...
FillMissingDataStorage ( ) ;
2010-09-08 14:07:28 +00:00
return retCode ;
2010-09-08 05:36:32 +00:00
}
2013-03-27 11:02:08 +00:00
void Operator_CylinderMultiGrid : : DumpPEC2File ( string filename , unsigned int * range )
{
if ( range ! = NULL )
return Operator_Cylinder : : DumpPEC2File ( filename , range ) ;
range = new unsigned int [ 6 ] ;
for ( int n = 0 ; n < 3 ; + + n )
{
range [ 2 * n ] = 0 ;
range [ 2 * n + 1 ] = numLines [ n ] - 1 ;
}
2013-12-03 10:26:31 +00:00
range [ 0 ] = m_Split_Pos - 1 ;
2013-03-27 11:02:08 +00:00
Operator_Cylinder : : DumpPEC2File ( filename + " _S " + ConvertInt ( m_MultiGridLevel ) , range ) ;
delete [ ] range ;
range = NULL ;
if ( dynamic_cast < Operator_CylinderMultiGrid * > ( m_InnerOp ) )
m_InnerOp - > DumpPEC2File ( filename ) ;
else // base cylindrical grid
m_InnerOp - > DumpPEC2File ( filename + " _S " + ConvertInt ( m_MultiGridLevel + 1 ) ) ;
}
2012-06-25 11:22:34 +00:00
void Operator_CylinderMultiGrid : : SetupInterpolation ( )
{
// n==0 --> interpolation in r&z-direction
// n==1 --> interpolation in a-direction
for ( int n = 0 ; n < 2 ; + + n )
{
delete [ ] m_interpol_pos_v_2p [ n ] ;
m_interpol_pos_v_2p [ n ] = new unsigned int [ numLines [ 1 ] ] ;
Delete1DArray_v4sf ( f4_interpol_v_2p [ n ] ) ;
f4_interpol_v_2p [ n ] = Create1DArray_v4sf ( numLines [ 1 ] ) ;
delete [ ] m_interpol_pos_v_2pp [ n ] ;
m_interpol_pos_v_2pp [ n ] = new unsigned int [ numLines [ 1 ] ] ;
Delete1DArray_v4sf ( f4_interpol_v_2pp [ n ] ) ;
f4_interpol_v_2pp [ n ] = Create1DArray_v4sf ( numLines [ 1 ] ) ;
delete [ ] m_interpol_pos_i_2p [ n ] ;
m_interpol_pos_i_2p [ n ] = new unsigned int [ numLines [ 1 ] ] ;
Delete1DArray_v4sf ( f4_interpol_i_2p [ n ] ) ;
f4_interpol_i_2p [ n ] = Create1DArray_v4sf ( numLines [ 1 ] ) ;
delete [ ] m_interpol_pos_i_2pp [ n ] ;
m_interpol_pos_i_2pp [ n ] = new unsigned int [ numLines [ 1 ] ] ;
Delete1DArray_v4sf ( f4_interpol_i_2pp [ n ] ) ;
f4_interpol_i_2pp [ n ] = Create1DArray_v4sf ( numLines [ 1 ] ) ;
}
bool isOdd , isEven ;
for ( unsigned int a_n = 0 ; a_n < numLines [ 1 ] ; + + a_n )
{
isOdd = ( a_n % 2 ) ;
isEven = ! isOdd ;
/* current interpolation position for r,z direction
this sub_grid 2 p sub_grid 2 pp
0 < - - 0 ( - 1 ) 0
1 < - - 0 1
2 < - - 1 0
3 < - - 1 2
4 < - - 2 1
5 < - - 2 3
. . .
*/
m_interpol_pos_i_2p [ 0 ] [ a_n ] = a_n / 2 ;
m_interpol_pos_i_2pp [ 0 ] [ a_n ] = a_n / 2 + isOdd - isEven ;
if ( ( a_n = = 0 ) & & CC_closedAlpha )
m_interpol_pos_i_2pp [ 0 ] [ a_n ] = m_InnerOp - > numLines [ 1 ] - 3 ;
else if ( ( a_n = = 0 ) & & ! CC_closedAlpha )
m_interpol_pos_i_2pp [ 0 ] [ a_n ] = 0 ;
//setup some special treatments for not closed alpha mesh
if ( ( a_n = = numLines [ 1 ] - 2 ) & & ! CC_closedAlpha )
m_interpol_pos_i_2pp [ 0 ] [ a_n ] = a_n / 2 - 1 ;
if ( ( a_n = = numLines [ 1 ] - 1 ) & & ! CC_closedAlpha )
m_interpol_pos_i_2p [ 0 ] [ a_n ] = m_interpol_pos_i_2pp [ 0 ] [ a_n ] = a_n / 2 ;
double dl_p = m_InnerOp - > GetDiscLine ( 1 , m_interpol_pos_i_2p [ 0 ] [ a_n ] , true ) ;
double dl_pp = m_InnerOp - > GetDiscLine ( 1 , m_interpol_pos_i_2pp [ 0 ] [ a_n ] , true ) ;
if ( ( a_n = = 0 ) & & CC_closedAlpha )
dl_pp - = 2 * PI ;
for ( int v = 0 ; v < 4 ; + + v )
{
if ( m_interpol_pos_i_2p [ 0 ] [ a_n ] = = m_interpol_pos_i_2pp [ 0 ] [ a_n ] )
f4_interpol_i_2p [ 0 ] [ a_n ] . f [ v ] = 1.0 ;
else
{
f4_interpol_i_2p [ 0 ] [ a_n ] . f [ v ] = ( dl_pp - GetDiscLine ( 1 , a_n , true ) ) / ( dl_pp - dl_p ) ;
f4_interpol_i_2pp [ 0 ] [ a_n ] . f [ v ] = ( GetDiscLine ( 1 , a_n , true ) - dl_p ) / ( dl_pp - dl_p ) ;
}
}
/* voltage interpolation position for r,z direction
this sub_grid 2 p sub_grid 2 pp
0 < - - 0 0
1 < - - 0 1
2 < - - 1 1
3 < - - 1 2
4 < - - 2 2
5 < - - 2 3
. . .
*/
m_interpol_pos_v_2p [ 0 ] [ a_n ] = a_n / 2 ;
m_interpol_pos_v_2pp [ 0 ] [ a_n ] = a_n / 2 + isOdd ;
dl_p = m_InnerOp - > GetDiscLine ( 1 , m_interpol_pos_v_2p [ 0 ] [ a_n ] , false ) ;
dl_pp = m_InnerOp - > GetDiscLine ( 1 , m_interpol_pos_v_2pp [ 0 ] [ a_n ] , false ) ;
for ( int v = 0 ; v < 4 ; + + v )
{
if ( m_interpol_pos_v_2p [ 0 ] [ a_n ] = = m_interpol_pos_v_2pp [ 0 ] [ a_n ] )
f4_interpol_v_2p [ 0 ] [ a_n ] . f [ v ] = 1.0 ;
else
{
f4_interpol_v_2p [ 0 ] [ a_n ] . f [ v ] = ( dl_pp - GetDiscLine ( 1 , a_n , false ) ) / ( dl_pp - dl_p ) ;
f4_interpol_v_2pp [ 0 ] [ a_n ] . f [ v ] = ( GetDiscLine ( 1 , a_n , false ) - dl_p ) / ( dl_pp - dl_p ) ;
}
}
/* current interpolation position for the alpha direction
this sub_grid 2 p sub_grid 2 pp
0 < - - 0 0
1 < - - 0 1
2 < - - 1 1
3 < - - 1 2
4 < - - 2 2
5 < - - 2 3
. . .
*/
m_interpol_pos_i_2p [ 1 ] [ a_n ] = a_n / 2 ;
m_interpol_pos_i_2pp [ 1 ] [ a_n ] = a_n / 2 + isOdd ;
//setup some special treatments for not closed alpha mesh
if ( ( a_n = = 1 ) & & ! CC_closedAlpha )
m_interpol_pos_i_2p [ 1 ] [ a_n ] = 2 ;
if ( ( a_n = = numLines [ 1 ] - 2 ) & & ! CC_closedAlpha )
m_interpol_pos_i_2pp [ 1 ] [ a_n ] = a_n / 2 - 1 ;
for ( int v = 0 ; v < 4 ; + + v )
{
if ( m_interpol_pos_i_2p [ 1 ] [ a_n ] = = m_interpol_pos_i_2pp [ 1 ] [ a_n ] )
f4_interpol_i_2p [ 1 ] [ a_n ] . f [ v ] = GetDiscDelta ( 1 , a_n , true ) / m_InnerOp - > GetDiscDelta ( 1 , m_interpol_pos_i_2p [ 1 ] [ a_n ] , true ) ;
else
{
f4_interpol_i_2p [ 1 ] [ a_n ] . f [ v ] = ( m_InnerOp - > GetDiscLine ( 1 , m_interpol_pos_i_2pp [ 1 ] [ a_n ] , false ) - GetDiscLine ( 1 , a_n , false ) ) /
( m_InnerOp - > GetDiscLine ( 1 , m_interpol_pos_i_2pp [ 1 ] [ a_n ] , false ) - m_InnerOp - > GetDiscLine ( 1 , m_interpol_pos_i_2p [ 1 ] [ a_n ] , false ) ) ;
f4_interpol_i_2p [ 1 ] [ a_n ] . f [ v ] * = GetDiscDelta ( 1 , a_n , true ) / m_InnerOp - > GetDiscDelta ( 1 , m_interpol_pos_i_2p [ 1 ] [ a_n ] , true ) ;
f4_interpol_i_2pp [ 1 ] [ a_n ] . f [ v ] = ( GetDiscLine ( 1 , a_n , false ) - m_InnerOp - > GetDiscLine ( 1 , m_interpol_pos_i_2p [ 1 ] [ a_n ] , false ) ) /
( m_InnerOp - > GetDiscLine ( 1 , m_interpol_pos_i_2pp [ 1 ] [ a_n ] , false ) - m_InnerOp - > GetDiscLine ( 1 , m_interpol_pos_i_2p [ 1 ] [ a_n ] , false ) ) ;
f4_interpol_i_2pp [ 1 ] [ a_n ] . f [ v ] * = GetDiscDelta ( 1 , a_n , true ) / m_InnerOp - > GetDiscDelta ( 1 , m_interpol_pos_i_2pp [ 1 ] [ a_n ] , true ) ;
}
}
/* voltage interpolation position for the alpha direction
this sub_grid 2 p sub_grid 2 pp
0 < - - 0 ( - 1 ) 0
1 < - - 0 1
2 < - - 1 0
3 < - - 1 2
4 < - - 2 1
5 < - - 2 3
. . .
*/
m_interpol_pos_v_2p [ 1 ] [ a_n ] = a_n / 2 ;
m_interpol_pos_v_2pp [ 1 ] [ a_n ] = a_n / 2 + isOdd - isEven ;
if ( ( a_n = = 0 ) & & CC_closedAlpha )
m_interpol_pos_v_2pp [ 1 ] [ a_n ] = m_InnerOp - > numLines [ 1 ] - 3 ;
else if ( ( a_n = = 0 ) & & ! CC_closedAlpha )
m_interpol_pos_v_2pp [ 1 ] [ a_n ] = 1 ;
//setup some special treatments for not closed alpha mesh
if ( ( a_n = = numLines [ 1 ] - 2 ) & & ! CC_closedAlpha )
m_interpol_pos_v_2pp [ 1 ] [ a_n ] = a_n / 2 - 1 ;
if ( ( a_n = = numLines [ 1 ] - 1 ) & & ! CC_closedAlpha )
{
m_interpol_pos_v_2p [ 1 ] [ a_n ] = 0 ;
m_interpol_pos_v_2pp [ 1 ] [ a_n ] = 0 ;
}
dl_p = m_InnerOp - > GetDiscLine ( 1 , m_interpol_pos_v_2p [ 1 ] [ a_n ] , true ) ;
dl_pp = m_InnerOp - > GetDiscLine ( 1 , m_interpol_pos_v_2pp [ 1 ] [ a_n ] , true ) ;
for ( int v = 0 ; v < 4 ; + + v )
{
if ( m_interpol_pos_v_2p [ 1 ] [ a_n ] = = m_interpol_pos_v_2pp [ 1 ] [ a_n ] )
f4_interpol_v_2p [ 1 ] [ a_n ] . f [ v ] = f4_interpol_v_2pp [ 1 ] [ a_n ] . f [ v ] = 0 ;
else
{
f4_interpol_v_2p [ 1 ] [ a_n ] . f [ v ] = ( dl_pp - GetDiscLine ( 1 , a_n , true ) ) / ( dl_pp - dl_p ) ;
f4_interpol_v_2p [ 1 ] [ a_n ] . f [ v ] * = GetDiscDelta ( 1 , a_n , false ) / m_InnerOp - > GetDiscDelta ( 1 , m_interpol_pos_v_2p [ 1 ] [ a_n ] , false ) ;
f4_interpol_v_2pp [ 1 ] [ a_n ] . f [ v ] = ( GetDiscLine ( 1 , a_n , true ) - dl_p ) / ( dl_pp - dl_p ) ;
f4_interpol_v_2pp [ 1 ] [ a_n ] . f [ v ] * = GetDiscDelta ( 1 , a_n , false ) / m_InnerOp - > GetDiscDelta ( 1 , m_interpol_pos_v_2pp [ 1 ] [ a_n ] , false ) ;
}
}
}
}
2012-07-17 11:23:00 +00:00
void Operator_CylinderMultiGrid : : SetExcitationSignal ( Excitation * exc )
2010-09-08 05:36:32 +00:00
{
2012-07-17 11:23:00 +00:00
m_InnerOp - > SetExcitationSignal ( exc ) ;
Operator_Cylinder : : SetExcitationSignal ( exc ) ;
2010-09-08 05:36:32 +00:00
}
2011-01-24 10:11:45 +00:00
void Operator_CylinderMultiGrid : : Delete ( )
{
delete m_InnerOp ;
m_InnerOp = 0 ;
2012-06-25 11:22:34 +00:00
for ( int n = 0 ; n < 2 ; + + n )
{
delete [ ] m_interpol_pos_v_2p [ n ] ;
m_interpol_pos_v_2p [ n ] = NULL ;
Delete1DArray_v4sf ( f4_interpol_v_2p [ n ] ) ;
f4_interpol_v_2p [ n ] = NULL ;
delete [ ] m_interpol_pos_v_2pp [ n ] ;
m_interpol_pos_v_2pp [ n ] = NULL ;
Delete1DArray_v4sf ( f4_interpol_v_2pp [ n ] ) ;
f4_interpol_v_2pp [ n ] = NULL ;
delete [ ] m_interpol_pos_i_2p [ n ] ;
m_interpol_pos_i_2p [ n ] = NULL ;
Delete1DArray_v4sf ( f4_interpol_i_2p [ n ] ) ;
f4_interpol_i_2p [ n ] = NULL ;
delete [ ] m_interpol_pos_i_2pp [ n ] ;
m_interpol_pos_i_2pp [ n ] = NULL ;
Delete1DArray_v4sf ( f4_interpol_i_2pp [ n ] ) ;
f4_interpol_i_2pp [ n ] = NULL ;
}
2011-01-24 10:11:45 +00:00
}
2010-09-08 05:36:32 +00:00
void Operator_CylinderMultiGrid : : Reset ( )
{
2011-01-24 10:11:45 +00:00
Delete ( ) ;
2010-09-08 05:36:32 +00:00
Operator_Cylinder : : Reset ( ) ;
}
void Operator_CylinderMultiGrid : : SetBoundaryCondition ( int * BCs )
{
Operator_Cylinder : : SetBoundaryCondition ( BCs ) ;
2010-09-22 07:58:45 +00:00
int oldBC = BCs [ 1 ] ;
2010-09-08 05:36:32 +00:00
BCs [ 1 ] = 0 ; //always PEC in +r-direction
m_InnerOp - > SetBoundaryCondition ( BCs ) ;
2010-09-22 07:58:45 +00:00
BCs [ 1 ] = oldBC ;
2010-09-08 05:36:32 +00:00
}
void Operator_CylinderMultiGrid : : AddExtension ( Operator_Extension * op_ext )
{
2010-09-22 14:08:39 +00:00
//check whether extension is save to use in multi-grid
if ( op_ext - > IsCylindricalMultiGridSave ( false ) = = false )
2010-09-08 05:36:32 +00:00
{
2010-09-22 14:08:39 +00:00
cerr < < " Operator_CylinderMultiGrid::AddExtension: Warning: Operator extension \" " < < op_ext - > GetExtensionName ( ) < < " \" is not compatible with cylindrical multi-grids!! skipping...! " < < endl ;
2012-10-29 13:51:02 +00:00
delete op_ext ;
2010-09-08 05:36:32 +00:00
return ;
}
2010-09-22 07:58:45 +00:00
2010-09-22 14:08:39 +00:00
Operator_Cylinder : : AddExtension ( op_ext ) ;
// cylinder extension does not need to be cloned, it will be created by each operator of its own...
if ( dynamic_cast < Operator_Ext_Cylinder * > ( op_ext ) )
return ;
//check whether extension is save to use in child multi-grid
2010-09-22 07:58:45 +00:00
if ( op_ext - > IsCylindricalMultiGridSave ( true ) )
2010-09-08 05:36:32 +00:00
{
2010-09-22 07:58:45 +00:00
Operator_Extension * child_Ext = op_ext - > Clone ( m_InnerOp ) ;
if ( child_Ext = = NULL )
{
cerr < < " Operator_CylinderMultiGrid::AddExtension: Warning, extension: " < < op_ext - > GetExtensionName ( ) < < " can not be cloned for the child operator. Skipping Extension... " < < endl ;
return ;
}
//give the copy to child
m_InnerOp - > AddExtension ( child_Ext ) ;
2010-09-08 05:36:32 +00:00
}
}
void Operator_CylinderMultiGrid : : ShowStat ( ) const
{
m_InnerOp - > ShowStat ( ) ;
m_InnerOp - > ShowExtStat ( ) ;
Operator_Cylinder : : ShowStat ( ) ;
}