/* * 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 . */ #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; }