196 lines
4.9 KiB
C++
196 lines
4.9 KiB
C++
/*
|
|
* Additional
|
|
* Copyright (C) 2023 Gadi Lahav (gadi@rfwithcare.com)
|
|
*
|
|
* 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 "engine_ext_lumpedRLC.h"
|
|
#include "operator_ext_lumpedRLC.h"
|
|
|
|
#include "FDTD/engine_sse.h"
|
|
|
|
Engine_Ext_LumpedRLC::Engine_Ext_LumpedRLC(Operator_Ext_LumpedRLC* op_ext_RLC) : Engine_Extension(op_ext_RLC)
|
|
{
|
|
// Local pointer of the operator.
|
|
m_Op_Ext_RLC = op_ext_RLC;
|
|
|
|
v_Vdn = new FDTD_FLOAT*[3];
|
|
v_Jn = new FDTD_FLOAT*[3];
|
|
|
|
// No additional allocations are required if there are no actual lumped elements.
|
|
if (!(m_Op_Ext_RLC->RLC_count))
|
|
return;
|
|
|
|
// Initialize ADE containers for currents and voltages
|
|
v_Il = new FDTD_FLOAT[m_Op_Ext_RLC->RLC_count];
|
|
|
|
for (uint posIdx = 0 ; posIdx < m_Op_Ext_RLC->RLC_count ; ++posIdx)
|
|
v_Il[posIdx] = 0.0;
|
|
|
|
for (uint k = 0 ; k < 3 ; k++)
|
|
{
|
|
v_Vdn[k] = new FDTD_FLOAT[m_Op_Ext_RLC->RLC_count];
|
|
v_Jn[k] = new FDTD_FLOAT[m_Op_Ext_RLC->RLC_count];
|
|
|
|
for (uint posIdx = 0 ; posIdx < m_Op_Ext_RLC->RLC_count ; ++posIdx)
|
|
{
|
|
v_Jn[k][posIdx] = 0.0;
|
|
v_Vdn[k][posIdx] = 0.0;;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
Engine_Ext_LumpedRLC::~Engine_Ext_LumpedRLC()
|
|
{
|
|
// Only delete if values were allocated in the first place
|
|
if (m_Op_Ext_RLC->RLC_count)
|
|
{
|
|
delete[] v_Il;
|
|
|
|
for (uint k = 0 ; k < 3 ; k++)
|
|
{
|
|
delete[] v_Vdn[k];
|
|
delete[] v_Jn[k];
|
|
}
|
|
}
|
|
|
|
delete[] v_Vdn;
|
|
delete[] v_Jn;
|
|
|
|
v_Il = NULL;
|
|
|
|
v_Vdn = NULL;
|
|
v_Jn = NULL;
|
|
|
|
m_Op_Ext_RLC = NULL;
|
|
|
|
|
|
}
|
|
|
|
void Engine_Ext_LumpedRLC::DoPreVoltageUpdates()
|
|
{
|
|
uint **pos = m_Op_Ext_RLC->v_RLC_pos;
|
|
int *dir = m_Op_Ext_RLC->v_RLC_dir;
|
|
|
|
// Iterate Vd containers
|
|
FDTD_FLOAT *v_temp;
|
|
v_temp = v_Vdn[2];
|
|
v_Vdn[2] = v_Vdn[1];
|
|
v_Vdn[1] = v_Vdn[0];
|
|
v_Vdn[0] = v_temp;
|
|
|
|
// In pre-process, only update the parallel inductor current:
|
|
for (uint pIdx = 0 ; pIdx < m_Op_Ext_RLC->RLC_count ; pIdx++)
|
|
v_Il[pIdx] += (m_Op_Ext_RLC->v_RLC_i2v[pIdx])*(m_Op_Ext_RLC->v_RLC_ilv[pIdx])*v_Vdn[1][pIdx];
|
|
|
|
return;
|
|
}
|
|
|
|
void Engine_Ext_LumpedRLC::Apply2Voltages()
|
|
{
|
|
uint **pos = m_Op_Ext_RLC->v_RLC_pos;
|
|
int *dir = m_Op_Ext_RLC->v_RLC_dir;
|
|
|
|
// Iterate J containers
|
|
FDTD_FLOAT *v_temp;
|
|
v_temp = v_Jn[2];
|
|
v_Jn[2] = v_Jn[1];
|
|
v_Jn[1] = v_Jn[0];
|
|
v_Jn[0] = v_temp;
|
|
|
|
|
|
// Read engine calculated node voltage
|
|
switch (m_Eng->GetType())
|
|
{
|
|
case Engine::BASIC:
|
|
{
|
|
for (uint pIdx = 0 ; pIdx < m_Op_Ext_RLC->RLC_count ; pIdx++)
|
|
v_Vdn[0][pIdx] = m_Eng->Engine::GetVolt(dir[pIdx],pos[0][pIdx],pos[1][pIdx],pos[2][pIdx]);
|
|
|
|
break;
|
|
}
|
|
case Engine::SSE:
|
|
{
|
|
Engine_sse* eng_sse = (Engine_sse*)m_Eng;
|
|
for (uint pIdx = 0 ; pIdx < m_Op_Ext_RLC->RLC_count ; pIdx++)
|
|
v_Vdn[0][pIdx] = eng_sse->Engine_sse::GetVolt(dir[pIdx],pos[0][pIdx],pos[1][pIdx],pos[2][pIdx]);
|
|
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
for (uint pIdx = 0 ; pIdx < m_Op_Ext_RLC->RLC_count ; pIdx++)
|
|
v_Vdn[0][pIdx] = m_Eng->GetVolt(dir[pIdx],pos[0][pIdx],pos[1][pIdx],pos[2][pIdx]);;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Post process: Calculate node voltage with respect to the lumped RLC auxilliary quantity, J
|
|
for (uint pIdx = 0 ; pIdx < m_Op_Ext_RLC->RLC_count ; pIdx++)
|
|
{
|
|
// Calculate updated node voltage, with series and parallel additions
|
|
v_Vdn[0][pIdx] = (m_Op_Ext_RLC->v_RLC_vvd[pIdx])*(
|
|
v_Vdn[0][pIdx] - v_Il[pIdx] // Addition for Parallel inductor
|
|
+
|
|
(m_Op_Ext_RLC->v_RLC_vv2[pIdx])*v_Vdn[2][pIdx] // Vd[n-2] addition
|
|
+
|
|
(m_Op_Ext_RLC->v_RLC_vj1[pIdx])*v_Jn[1][pIdx] // J[n-1] addition
|
|
+
|
|
(m_Op_Ext_RLC->v_RLC_vj2[pIdx])*v_Jn[2][pIdx]); // J[n-2] addition
|
|
|
|
// Update J[0]
|
|
v_Jn[0][pIdx] = (m_Op_Ext_RLC->v_RLC_ib0[pIdx])*(v_Vdn[0][pIdx] - v_Vdn[2][pIdx])
|
|
-
|
|
((m_Op_Ext_RLC->v_RLC_b1[pIdx])*(m_Op_Ext_RLC->v_RLC_ib0[pIdx]))*v_Jn[1][pIdx]
|
|
-
|
|
((m_Op_Ext_RLC->v_RLC_b2[pIdx])*(m_Op_Ext_RLC->v_RLC_ib0[pIdx]))*v_Jn[2][pIdx];
|
|
}
|
|
|
|
|
|
// Update node voltage
|
|
switch (m_Eng->GetType())
|
|
{
|
|
case Engine::BASIC:
|
|
{
|
|
for (uint pIdx = 0 ; pIdx < m_Op_Ext_RLC->RLC_count ; pIdx++)
|
|
m_Eng->Engine::SetVolt(dir[pIdx],pos[0][pIdx],pos[1][pIdx],pos[2][pIdx],v_Vdn[0][pIdx]);
|
|
|
|
break;
|
|
}
|
|
case Engine::SSE:
|
|
{
|
|
Engine_sse* eng_sse = (Engine_sse*)m_Eng;
|
|
for (uint pIdx = 0 ; pIdx < m_Op_Ext_RLC->RLC_count ; pIdx++)
|
|
eng_sse->Engine_sse::SetVolt(dir[pIdx],pos[0][pIdx],pos[1][pIdx],pos[2][pIdx],v_Vdn[0][pIdx]);
|
|
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
for (uint pIdx = 0 ; pIdx < m_Op_Ext_RLC->RLC_count ; pIdx++)
|
|
m_Eng->SetVolt(dir[pIdx],pos[0][pIdx],pos[1][pIdx],pos[2][pIdx],v_Vdn[0][pIdx]);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
return;
|
|
}
|
|
|
|
|