/*
FEMSuite - (C) 2018 Fady Kamel
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.
FEMSuite 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 FEMSuite. If not, see .
*/
#pragma once
#include "Types.h"
class Yee;
/// Helper class to compute Update equations and coefficients.
class YeeUpdateHelper
{
#pragma region Current Address
public:
Address GetAddress() const { return m_Address; }
void SetAddress( const Address address ) { m_Address = address; }
private:
/// Address at which the equations will be computed.
Address m_Address;
#pragma endregion
#pragma region Caching
public:
/// A container for all M coefficients
struct MCoeffContainer
{
Complex m0;
Complex m1;
Complex m2;
Complex m3;
Complex m4;
}; // MCoeffContainer
private:
#pragma endregion
#pragma region Computing Update Equations for the H field.
public:
/// Computes all H field equations for a given dimention
MCoeffContainer Compute_mH( const size_t dimension );
/// mH0 - Computes mH0 for a given dimension.
/// Based on Lecture 14 of FDTD Course( UTEP ) offered at :
/// http ://emlab.utep.edu/ee5390fdtd/Lecture%2014%20--%203D%20Update%20Equations%20with%20PML.pdf (Slide 36)
///
Complex Compute_mH0( const size_t dimension );
/// Computes mH1 for a given dimension.
Complex Compute_mH1( const size_t dimension, const Complex& mH0 );
/// Computes mH2 for a given dimension.
Complex Compute_mH2( const size_t dimension, const Complex& mH0 );
/// Computes mH3 for a given dimension.
Complex Compute_mH3( const size_t dimension, const Complex& mH2 );
/// Computes mH4 for a given dimension.
Complex Compute_mH4( const size_t dimension, const Complex& mH0 );
void SetCachedHCoefficients( const size_t dimension, const MCoeffContainer& mH ) { m_CachedHCoefficients[dimension] = mH; }
private:
/// H-Field coefficients are stored in this container
DimensionArray m_CachedHCoefficients;
#pragma endregion
#pragma region Computing Update Equations for the D field.
public:
/// Computes all H field equations for a given dimention
MCoeffContainer Compute_mD( const size_t dimension );
/// Computes mD0 for a given dimension.
/// Note that this i essentially identical to mH0
Complex Compute_mD0( const size_t dimension );
/// Computes mD1 for a given dimension.
Complex Compute_mD1( const size_t dimension, const Complex& mD0 );
/// Computes mD2 for a given dimension.
Complex Compute_mD2( const size_t dimension, const Complex& mD0 );
/// Computes mD3 for a given dimension.
Complex Compute_mD3( const size_t dimension, const Complex& mD2 );
/// Computes mD4 for a given dimension.
Complex Compute_mD4( const size_t dimension, const Complex& mD0 );
void SetCachedDCoefficients( const size_t dimension, const MCoeffContainer& mD ) { m_CachedDCoefficients[dimension] = mD; }
private:
/// D-Field coefficients are stored in this container
DimensionArray m_CachedDCoefficients;
#pragma endregion
#pragma region Computing Update Equation for the E field
public:
/// Computes mE1 for a given dimension.
Complex Compute_mE1( const size_t dimension );
void SetCachedECoefficient( const size_t dimension, const Complex& mEi ) { m_CachedECoefficient[dimension] = mEi; }
private:
/// The E-Field coefficient is stored in this container
DimensionArray m_CachedECoefficient;
#pragma endregion
// TODO: move to same place as geomery functions in yee grid
#pragma region Misc Geometry
public:
///
/// Returs the expression C( E, d ) or C( H, d ) at a given timeBoardIndex.
/// whichField is either 'E' or 'H'.
/// Based on the FDTD lectures at UTEP, at
/// http ://emlab.utep.edu/ee5390fdtd/Lecture%2014%20--%203D%20Update%20Equations%20with%20PML.pdf
/// NOTE : this assumes 3 dimensions.
/// TODO : investigate exterior curl :
/// https ://en.wikipedia.org/wiki/Exterior_derivative#Curl
///
Complex Curl_EorH( const size_t dimension, const TimeBoardIndex timeBoardIndex, const char whichField );
///
/// computes the sum of th curl field for a specified
/// field, from t = 0 until t = timeBoardIndex.
/// NOTE: it is preferred to determine the first time board used and
/// make sure t starts at this time.
///
Complex SumCurl( const size_t dimension, const TimeBoardIndex timeBoardIndex, const char whichField );
#pragma endregion
#pragma region Field value computation
public:
///
/// Computes the H field for a given axis at a given time board index from E.
///
Complex ComputeH( const size_t dimension, const TimeBoardIndex timeBoardIndex );
///
/// Computes the D field for a given axis at a given time board index from H.
///
Complex ComputeD( const size_t dimension, const TimeBoardIndex timeBoardIndex );
///
/// Computes the E field for a given location
///
Complex ComputeE( const size_t dimension, const TimeBoardIndex timeBoardIndex );
#pragma endregion
#pragma region PML Attenutation
public:
///
/// Computes the PML attenuation matrix( Sigma prime ) in order to
/// attenuate the PML medium properly.
///
PMLAttenuation ComputePMLAttenuation();
void SetPMLAttenuation( const PMLAttenuation& pA ) { m_PMLAttenuation = pA; }
private:
/// This is the PML attenuation matrix( Sigma prime ) in order to
/// attenuate the PML medium properly.
PMLAttenuation m_PMLAttenuation;
#pragma endregion
#pragma region Imaginary conductances
public:
///
/// Returns the imaginary conductance at the proper e field
///
// TODO: Optimize by eliminating the need to compute the conductances for all dimension
// at once.
DimensionArray< Complex > GetSigmaD() const;
///
/// Returns the imaginary conductance at the proper H field location
///
// TODO: Optimize by eliminating the need to compute the conductances for all dimension
// at once.
DimensionArray< Complex > GetSigmaH() const;
#pragma endregion
#pragma region Overall update
public:
///
/// Updates the grid based on current dimension count
///
void Update();
///
/// Updates a 2d display
///
void Update2D();
private:
Yee* m_Grid;
#pragma endregion
};