/* * 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 . */ #include "operator_ext_lorentzmaterial.h" #include "engine_ext_lorentzmaterial.h" #include "operator_ext_cylinder.h" #include "../operator_cylinder.h" #include "CSPropLorentzMaterial.h" Operator_Ext_LorentzMaterial::Operator_Ext_LorentzMaterial(Operator* op) : Operator_Ext_Dispersive(op) { v_int_ADE = NULL; v_ext_ADE = NULL; i_int_ADE = NULL; i_ext_ADE = NULL; } Operator_Ext_LorentzMaterial::Operator_Ext_LorentzMaterial(Operator* op, Operator_Ext_LorentzMaterial* op_ext) : Operator_Ext_Dispersive(op,op_ext) { v_int_ADE = NULL; v_ext_ADE = NULL; i_int_ADE = NULL; i_ext_ADE = NULL; } Operator_Ext_LorentzMaterial::~Operator_Ext_LorentzMaterial() { for (int i=0;i(this)==NULL) return NULL; return new Operator_Ext_LorentzMaterial(op, this); } bool Operator_Ext_LorentzMaterial::BuildExtension() { double dT = m_Op->GetTimestep(); unsigned int pos[] = {0,0,0}; double coord[3]; unsigned int numLines[3] = {m_Op->GetOriginalNumLines(0),m_Op->GetOriginalNumLines(1),m_Op->GetOriginalNumLines(2)}; CSPropLorentzMaterial* mat = NULL; double w_plasma,t_relax; bool b_pos_on; double L_D[3], C_D[3]; double R_D[3], G_D[3]; vector v_int[3]; vector v_ext[3]; vector i_int[3]; vector i_ext[3]; vector v_pos[3]; m_Order = 0; vector LD_props = m_Op->CSX->GetPropertyByType(CSProperties::LORENTZMATERIAL); for (size_t n=0;n(LD_props.at(n)); if (LorMat==NULL) return false; //sanity check, this should not happen if (LorMat->GetDispersionOrder()>m_Order) m_Order=LorMat->GetDispersionOrder(); } m_volt_ADE_On = new bool[m_Order]; m_curr_ADE_On = new bool[m_Order]; m_LM_pos = new unsigned int**[m_Order]; v_int_ADE = new FDTD_FLOAT**[m_Order]; v_ext_ADE = new FDTD_FLOAT**[m_Order]; i_int_ADE = new FDTD_FLOAT**[m_Order]; i_ext_ADE = new FDTD_FLOAT**[m_Order]; for (int order=0;orderMainOp->SetPos(pos[0],pos[1],pos[2]); //calc epsilon lorentz material b_pos_on = false; for (int n=0; n<3; ++n) { L_D[n]=0; R_D[n]=0; if (m_Op->GetYeeCoords(n,pos,coord,false)==false) continue; if (m_CC_R0_included && (n==2) && (pos[0]==0)) coord[1] = m_Op->GetDiscLine(1,0); CSProperties* prop = m_Op->GetGeometryCSX()->GetPropertyByCoordPriority(coord,(CSProperties::PropertyType)(CSProperties::METAL | CSProperties::MATERIAL), true); if ((mat = prop->ToLorentzMaterial())) { w_plasma = mat->GetEpsPlasmaFreqWeighted(order,n,coord) * 2 * PI; if ((w_plasma>0) && (m_Op->EC_C[n][index]>0)) { b_pos_on = true; m_volt_ADE_On[order] = true; L_D[n] = 1/(w_plasma*w_plasma*m_Op->EC_C[n][index]); } t_relax = mat->GetEpsRelaxTimeWeighted(order,n,coord); if ((t_relax>0) && m_volt_ADE_On[order]) { R_D[n] = L_D[n]/t_relax; } } } for (int n=0; n<3; ++n) { C_D[n]=0; G_D[n]=0; if (m_Op->GetYeeCoords(n,pos,coord,true)==false) continue; CSProperties* prop = m_Op->GetGeometryCSX()->GetPropertyByCoordPriority(coord,(CSProperties::PropertyType)(CSProperties::METAL | CSProperties::MATERIAL), true); if ((mat = prop->ToLorentzMaterial())) { w_plasma = mat->GetMuePlasmaFreqWeighted(order,n,coord) * 2 * PI; if ((w_plasma>0) && (m_Op->EC_L[n][index]>0)) { b_pos_on = true; m_curr_ADE_On[order] = true; C_D[n] = 1/(w_plasma*w_plasma*m_Op->EC_L[n][index]); } t_relax = mat->GetMueRelaxTimeWeighted(order,n,coord); if ((t_relax>0) && m_curr_ADE_On[order]) { G_D[n] = C_D[n]/t_relax; } } } if (b_pos_on) //this position has active lorentz material { for (unsigned int n=0; n<3; ++n) { v_pos[n].push_back(pos[n]); if (L_D[n]>0) { v_int[n].push_back((2*L_D[n]-dT*R_D[n])/(2*L_D[n]+dT*R_D[n])); // check for r==0 in clyindrical coords and get special VI cooefficient if (m_CC_R0_included && n==2 && pos[0]==0) v_ext[n].push_back(dT/(L_D[n]+dT*R_D[n]/2)*m_Op_Cyl->m_Cyl_Ext->vi_R0[pos[2]]); else v_ext[n].push_back(dT/(L_D[n]+dT*R_D[n]/2)*m_Op->GetVI(n,pos[0],pos[1],pos[2])); } else { v_int[n].push_back(1); v_ext[n].push_back(0); } if (C_D[n]>0) { i_int[n].push_back((2*C_D[n]-dT*G_D[n])/(2*C_D[n]+dT*G_D[n])); i_ext[n].push_back(dT/(C_D[n]+dT*G_D[n]/2)*m_Op->GetIV(n,pos[0],pos[1],pos[2])); } else { i_int[n].push_back(1); i_ext[n].push_back(0); } // cerr << v_int[n].back() << " " << v_ext[n].back() << " " << i_int[n].back() << " " << i_ext[n].back() << endl; } } } } } //copy all vectors into the array's m_LM_Count.push_back(v_pos[0].size()); m_LM_pos[order] = new unsigned int*[3]; if (m_volt_ADE_On[order]) { v_int_ADE[order] = new FDTD_FLOAT*[3]; v_ext_ADE[order] = new FDTD_FLOAT*[3]; } else { v_int_ADE[order] = NULL; v_ext_ADE[order] = NULL; } if (m_curr_ADE_On[order]) { i_int_ADE[order] = new FDTD_FLOAT*[3]; i_ext_ADE[order] = new FDTD_FLOAT*[3]; } else { i_int_ADE[order] = NULL; i_ext_ADE[order] = NULL; } for (int n=0; n<3; ++n) { m_LM_pos[order][n] = new unsigned int[m_LM_Count.at(order)]; for (unsigned int i=0; i