/* * 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 #include "operator.h" #include "engine.h" #include "extensions/operator_extension.h" #include "extensions/operator_ext_excitation.h" #include "Common/processfields.h" #include "tools/array_ops.h" #include "fparser.hh" Operator* Operator::New() { cout << "Create FDTD operator" << endl; Operator* op = new Operator(); op->Init(); return op; } Operator::Operator() : Operator_Base() { Exc = 0; m_InvaildTimestep = false; m_TimeStepVar = 3; } Operator::~Operator() { for (size_t n=0; n2)) return 0.0; if (pos>=numLines[n]) return 0.0; if (dualMesh==false) return discLines[n][pos]; // return dual mesh node if (pos=numLines[ny]-1) return false; } else //dual grid { int nP = (ny+1)%3; int nPP = (ny+2)%3; coords[nP] +=0.5*fabs(GetRawDiscDelta(nP ,pos[nP] )); coords[nPP]+=0.5*fabs(GetRawDiscDelta(nPP,pos[nPP])); if ((pos[nP]>=numLines[nP]-1) || (pos[nPP]>=numLines[nPP]-1)) return false; } return true; } double Operator::GetEdgeLength(int n, const unsigned int* pos, bool dualMesh) const { if ((n<0) || (n>2)) return 0.0; if (pos[n]>=numLines[n]) return 0.0; double delta=0; if (dualMesh==false) { if (pos[n]0) delta = GetDiscLine(n,pos[n],true) - GetDiscLine(n,pos[n]-1,true); else delta = GetDiscLine(n,1,false) - GetDiscLine(n,0,false); return delta*gridDelta; } } double Operator::GetNodeArea(int ny, const unsigned int pos[3], bool dualMesh) const { int nyP = (ny+1)%3; int nyPP = (ny+2)%3; return GetNodeWidth(nyP,pos,dualMesh) * GetNodeWidth(nyPP,pos,dualMesh); } bool Operator::SnapToMesh(const double* dcoord, unsigned int* uicoord, bool lower, bool* inside) const { bool ok=true; unsigned int numLines[3]; for (int n=0; n<3; ++n) { numLines[n] = GetNumberOfLines(n); if (inside) //set defaults inside[n] = true; uicoord[n]=0; if (dcoord[n]discLines[n][numLines[n]-1]) { ok=false; uicoord[n]=numLines[n]-1; if (lower) uicoord[n]=numLines[n]-2; if (inside) inside[n] = false; } else if (dcoord[n]==discLines[n][numLines[n]-1]) { uicoord[n]=numLines[n]-1; if (lower) uicoord[n]=numLines[n]-2; } else for (unsigned int i=1; i=0) { P[n] = discLines[n][currPos[n]-1]; Point_Line_Distance(P,start,stop,foot,dist); if ((foot>currFoot) && (distcurrFoot) && (distuiStop[n]) { --currPos[n]; path.posPath[0].push_back(currPos[0]); path.posPath[1].push_back(currPos[1]); path.posPath[2].push_back(currPos[2]); path.dir.push_back(n); } else if (currPos[n]GetNyquistNum() << endl; cout << "Nyquist criteria (s)\t: " << Exc->GetNyquistNum()*dT << endl; cout << "-----------------------------------" << endl; } void Operator::ShowExtStat() const { if (m_Op_exts.size()==0) return; cout << "-----------------------------------" << endl; for (size_t n=0; nShowStat(cout); cout << "-----------------------------------" << endl; } void Operator::DumpOperator2File(string filename) { #ifdef OUTPUT_IN_DRAWINGUNITS double discLines_scaling = 1; #else double discLines_scaling = GetGridDelta(); #endif ofstream file(filename.c_str(),ios_base::out); if (!file.is_open()) { cerr << "Operator::DumpOperator2File(): Can't open file: " << filename << endl; return; } cout << "Operator: Dumping FDTD operator information to vtk file: " << filename << " ..." << flush; FDTD_FLOAT**** exc = Create_N_3DArray(numLines); if (Exc) { for (unsigned int n=0; nVolt_Count; ++n) exc[Exc->Volt_dir[n]][Exc->Volt_index[0][n]][Exc->Volt_index[1][n]][Exc->Volt_index[2][n]] = Exc->Volt_amp[n]; } FDTD_FLOAT**** vv_temp = Create_N_3DArray(numLines); FDTD_FLOAT**** vi_temp = Create_N_3DArray(numLines); FDTD_FLOAT**** iv_temp = Create_N_3DArray(numLines); FDTD_FLOAT**** ii_temp = Create_N_3DArray(numLines); unsigned int pos[3], n; for (n=0; n<3; n++) for (pos[0]=0; pos[0]( numLines ); unsigned int pos[3]; #ifdef OUTPUT_IN_DRAWINGUNITS double scaling = 1.0/GetGridDelta(); #else double scaling = 1; #endif for (pos[0]=0; pos[0](numLines); FDTD_FLOAT**** mue = Create_N_3DArray(numLines); FDTD_FLOAT**** kappa = Create_N_3DArray(numLines); FDTD_FLOAT**** sigma = Create_N_3DArray(numLines); unsigned int pos[3]; for (pos[0]=0; pos[0]GetGrid(); for (int n=0; n<3; ++n) { discLines[n] = grid->GetLines(n,discLines[n],numLines[n],true); if (n==1) if (numLines[n]<3) { cerr << "CartOperator::SetGeometryCSX: you need at least 3 disc-lines in every direction (3D!)!!!" << endl; Reset(); return false; } } MainOp = new AdrOp(numLines[0],numLines[1],numLines[2]); MainOp->SetGrid(discLines[0],discLines[1],discLines[2]); if (grid->GetDeltaUnit()<=0) { cerr << "CartOperator::SetGeometryCSX: grid delta unit must not be <=0 !!!" << endl; Reset(); return false; } else gridDelta=grid->GetDeltaUnit(); MainOp->SetGridDelta(1); MainOp->AddCellAdrOp(); return true; } void Operator::InitOperator() { Delete_N_3DArray(vv,numLines); Delete_N_3DArray(vi,numLines); Delete_N_3DArray(iv,numLines); Delete_N_3DArray(ii,numLines); vv = Create_N_3DArray(numLines); vi = Create_N_3DArray(numLines); iv = Create_N_3DArray(numLines); ii = Create_N_3DArray(numLines); } void Operator::InitDataStorage() { if (m_StoreMaterial[0]) { if (g_settings.GetVerboseLevel()>0) cerr << "Operator::InitDataStorage(): Storing epsR material data..." << endl; Delete_N_3DArray(m_epsR,numLines); m_epsR = Create_N_3DArray(numLines); } if (m_StoreMaterial[1]) { if (g_settings.GetVerboseLevel()>0) cerr << "Operator::InitDataStorage(): Storing kappa material data..." << endl; Delete_N_3DArray(m_kappa,numLines); m_kappa = Create_N_3DArray(numLines); } if (m_StoreMaterial[2]) { if (g_settings.GetVerboseLevel()>0) cerr << "Operator::InitDataStorage(): Storing muR material data..." << endl; Delete_N_3DArray(m_mueR,numLines); m_mueR = Create_N_3DArray(numLines); } if (m_StoreMaterial[3]) { if (g_settings.GetVerboseLevel()>0) cerr << "Operator::InitDataStorage(): Storing sigma material data..." << endl; Delete_N_3DArray(m_sigma,numLines); m_sigma = Create_N_3DArray(numLines); } } void Operator::CleanupMaterialStorage() { if (!m_StoreMaterial[0] && m_epsR) { if (g_settings.GetVerboseLevel()>0) cerr << "Operator::CleanupMaterialStorage(): Delete epsR material data..." << endl; Delete_N_3DArray(m_epsR,numLines); m_epsR = NULL; } if (!m_StoreMaterial[1] && m_kappa) { if (g_settings.GetVerboseLevel()>0) cerr << "Operator::CleanupMaterialStorage(): Delete kappa material data..." << endl; Delete_N_3DArray(m_kappa,numLines); m_kappa = NULL; } if (!m_StoreMaterial[2] && m_mueR) { if (g_settings.GetVerboseLevel()>0) cerr << "Operator::CleanupMaterialStorage(): Delete mueR material data..." << endl; Delete_N_3DArray(m_mueR,numLines); m_mueR = NULL; } if (!m_StoreMaterial[3] && m_sigma) { if (g_settings.GetVerboseLevel()>0) cerr << "Operator::CleanupMaterialStorage(): Delete sigma material data..." << endl; Delete_N_3DArray(m_sigma,numLines); m_sigma = NULL; } } double Operator::GetDiscMaterial(int type, int n, const unsigned int pos[3]) const { switch (type) { case 0: if (m_epsR==0) return 0; return m_epsR[n][pos[0]][pos[1]][pos[2]]; case 1: if (m_kappa==0) return 0; return m_kappa[n][pos[0]][pos[1]][pos[2]]; case 2: if (m_mueR==0) return 0; return m_mueR[n][pos[0]][pos[1]][pos[2]]; case 3: if (m_sigma==0) return 0; return m_sigma[n][pos[0]][pos[1]][pos[2]]; } return 0; } void Operator::InitExcitation() { delete Exc; Exc = new Excitation( dT ); this->AddExtension(new Operator_Ext_Excitation(this,Exc)); } void Operator::Calc_ECOperatorPos(int n, unsigned int* pos) { unsigned int i = MainOp->SetPos(pos[0],pos[1],pos[2]); if (EC_C[n][i]>0) { SetVV(n,pos[0],pos[1],pos[2], (1-dT*EC_G[n][i]/2/EC_C[n][i])/(1+dT*EC_G[n][i]/2/EC_C[n][i]) ); SetVI(n,pos[0],pos[1],pos[2], (dT/EC_C[n][i])/(1+dT*EC_G[n][i]/2/EC_C[n][i]) ); } else { SetVV(n,pos[0],pos[1],pos[2], 0 ); SetVI(n,pos[0],pos[1],pos[2], 0 ); } if (EC_L[n][i]>0) { SetII(n,pos[0],pos[1],pos[2], (1-dT*EC_R[n][i]/2/EC_L[n][i])/(1+dT*EC_R[n][i]/2/EC_L[n][i]) ); SetIV(n,pos[0],pos[1],pos[2], (dT/EC_L[n][i])/(1+dT*EC_R[n][i]/2/EC_L[n][i]) ); } else { SetII(n,pos[0],pos[1],pos[2], 0 ); SetIV(n,pos[0],pos[1],pos[2], 0 ); } } int Operator::CalcECOperator( DebugFlags debugFlags ) { Init_EC(); InitDataStorage(); if (Calc_EC()==0) return -1; m_InvaildTimestep = false; opt_dT = 0; if (dT>0) { double save_dT = dT; CalcTimestep(); opt_dT = dT; if (dTBuildExtension(); if (debugFlags & debugMaterial) DumpMaterial2File( "material_dump.vtk" ); if (debugFlags & debugOperator) DumpOperator2File( "operator_dump.vtk" ); if (debugFlags & debugPEC) DumpPEC2File( "PEC_dump.vtk" ); //cleanup for (int n=0; n<3; ++n) { delete[] EC_C[n]; EC_C[n]=NULL; delete[] EC_G[n]; EC_G[n]=NULL; delete[] EC_L[n]; EC_L[n]=NULL; delete[] EC_R[n]; EC_R[n]=NULL; } return 0; } void Operator::ApplyElectricBC(bool* dirs) { if (!dirs) return; unsigned int pos[3]; for (int n=0; n<3; ++n) { int nP = (n+1)%3; int nPP = (n+2)%3; for (pos[nP]=0; pos[nP]=(int)numLines[ny]-1) return (discLines[ny][numLines[ny]-2] - discLines[ny][numLines[ny]-1]); return (discLines[ny][pos+1] - discLines[ny][pos]); } bool Operator::Calc_EffMatPos(int ny, const unsigned int* pos, double* EffMat) const { int n=ny; double coord[3]; double shiftCoord[3]; int nP = (n+1)%3; int nPP = (n+2)%3; coord[0] = discLines[0][pos[0]]; coord[1] = discLines[1][pos[1]]; coord[2] = discLines[2][pos[2]]; double delta=GetRawDiscDelta(n,pos[n]); double deltaP=GetRawDiscDelta(nP,pos[nP]); double deltaPP=GetRawDiscDelta(nPP,pos[nPP]); double delta_M=GetRawDiscDelta(n,pos[n]-1); double deltaP_M=GetRawDiscDelta(nP,pos[nP]-1); double deltaPP_M=GetRawDiscDelta(nPP,pos[nPP]-1); int loc_pos[3]={pos[0],pos[1],pos[2]}; double A_n; double area = 0; //******************************* epsilon,kappa averaging *****************************// //shift up-right shiftCoord[n] = coord[n]+delta*0.5; shiftCoord[nP] = coord[nP]+deltaP*0.25; shiftCoord[nPP] = coord[nPP]+deltaPP*0.25; A_n = GetNodeArea(ny,(unsigned int*)loc_pos,true); // { // cerr << ny << " " << pos[0] << " " << pos[1] << " " << pos[2] << ": " << A_n << endl; // exit(0); // } CSProperties* prop = CSX->GetPropertyByCoordPriority(shiftCoord,CSProperties::MATERIAL,true); if (prop) { CSPropMaterial* mat = prop->ToMaterial(); EffMat[0] = mat->GetEpsilonWeighted(n,shiftCoord)*A_n; EffMat[1] = mat->GetKappaWeighted(n,shiftCoord)*A_n; } else { EffMat[0] = 1*A_n; EffMat[1] = 0; } area+=A_n; //shift up-left shiftCoord[n] = coord[n]+delta*0.5; shiftCoord[nP] = coord[nP]-deltaP_M*0.25; shiftCoord[nPP] = coord[nPP]+deltaPP*0.25; --loc_pos[nP]; A_n = GetNodeArea(ny,(unsigned int*)loc_pos,true); // cerr << A_n << endl; prop = CSX->GetPropertyByCoordPriority(shiftCoord,CSProperties::MATERIAL,true); if (prop) { CSPropMaterial* mat = prop->ToMaterial(); EffMat[0] += mat->GetEpsilonWeighted(n,shiftCoord)*A_n; EffMat[1] += mat->GetKappaWeighted(n,shiftCoord)*A_n; } else { EffMat[0] += 1*A_n; EffMat[1] += 0; } area+=A_n; //shift down-right shiftCoord[n] = coord[n]+delta*0.5; shiftCoord[nP] = coord[nP]+deltaP*0.25; shiftCoord[nPP] = coord[nPP]-deltaPP_M*0.25; ++loc_pos[nP]; --loc_pos[nPP]; A_n = GetNodeArea(ny,(unsigned int*)loc_pos,true); prop = CSX->GetPropertyByCoordPriority(shiftCoord,CSProperties::MATERIAL,true); if (prop) { CSPropMaterial* mat = prop->ToMaterial(); EffMat[0] += mat->GetEpsilonWeighted(n,shiftCoord)*A_n; EffMat[1] += mat->GetKappaWeighted(n,shiftCoord)*A_n; } else { EffMat[0] += 1*A_n; EffMat[1] += 0; } area+=A_n; //shift down-left shiftCoord[n] = coord[n]+delta*0.5; shiftCoord[nP] = coord[nP]-deltaP_M*0.25; shiftCoord[nPP] = coord[nPP]-deltaPP_M*0.25; --loc_pos[nP]; A_n = GetNodeArea(ny,(unsigned int*)loc_pos,true); prop = CSX->GetPropertyByCoordPriority(shiftCoord,CSProperties::MATERIAL,true); if (prop) { CSPropMaterial* mat = prop->ToMaterial(); EffMat[0] += mat->GetEpsilonWeighted(n,shiftCoord)*A_n; EffMat[1] += mat->GetKappaWeighted(n,shiftCoord)*A_n; } else { EffMat[0] += 1*A_n; EffMat[1] += 0; } area+=A_n; EffMat[0]*=__EPS0__/area; EffMat[1]/=area; //******************************* mu,sigma averaging *****************************// loc_pos[0]=pos[0]; loc_pos[1]=pos[1]; loc_pos[2]=pos[2]; double length=0; //shift down shiftCoord[n] = coord[n]-delta_M*0.25; shiftCoord[nP] = coord[nP]+deltaP*0.5; shiftCoord[nPP] = coord[nPP]+deltaPP*0.5; --loc_pos[n]; double delta_ny = GetNodeWidth(n,(unsigned int*)loc_pos,true); prop = CSX->GetPropertyByCoordPriority(shiftCoord,CSProperties::MATERIAL,true); if (prop) { CSPropMaterial* mat = prop->ToMaterial(); EffMat[2] = delta_ny / mat->GetMueWeighted(n,shiftCoord); if (mat->GetSigmaWeighted(n,shiftCoord)) EffMat[3] = delta_ny / mat->GetSigmaWeighted(n,shiftCoord); else EffMat[3] = 0; } else { EffMat[2] = delta_ny; EffMat[3] = 0; } length=delta_ny; //shift up shiftCoord[n] = coord[n]+delta*0.25; shiftCoord[nP] = coord[nP]+deltaP*0.5; shiftCoord[nPP] = coord[nPP]+deltaPP*0.5; ++loc_pos[n]; delta_ny = GetNodeWidth(n,(unsigned int*)loc_pos,true); prop = CSX->GetPropertyByCoordPriority(shiftCoord,CSProperties::MATERIAL,true); if (prop) { CSPropMaterial* mat = prop->ToMaterial(); EffMat[2] += delta_ny / mat->GetMueWeighted(n,shiftCoord); if (mat->GetSigmaWeighted(n,shiftCoord)) EffMat[3] += delta_ny/mat->GetSigmaWeighted(n,shiftCoord); else EffMat[3] = 0; } else { EffMat[2] += 1*delta_ny; EffMat[3] = 0; } length+=delta_ny; EffMat[2] = length * __MUE0__ / EffMat[2]; if (EffMat[3]) EffMat[3]=length / EffMat[3]; for (int n=0; n<4; ++n) if (isnan(EffMat[n]) || isinf(EffMat[n])) { cerr << "Operator::Calc_EffMatPos: An effective material parameter is not a valid result, this should NOT have happend... exit..." << endl; exit(0); } return true; } void Operator::DumpExciationSignals() { Exc->DumpVoltageExcite("et"); Exc->DumpCurrentExcite("ht"); } void Operator::Init_EC() { for (int n=0; n<3; ++n) { //init x-cell-array delete[] EC_C[n]; delete[] EC_G[n]; delete[] EC_L[n]; delete[] EC_R[n]; EC_C[n] = new double[MainOp->GetSize()]; EC_G[n] = new double[MainOp->GetSize()]; EC_L[n] = new double[MainOp->GetSize()]; EC_R[n] = new double[MainOp->GetSize()]; for (unsigned int i=0; iGetSize(); i++) //init all { EC_C[n][i]=0; EC_G[n][i]=0; EC_L[n][i]=0; EC_R[n][i]=0; } } } bool Operator::Calc_EC() { if (CSX==NULL) { cerr << "CartOperator::Calc_EC: CSX not given or invalid!!!" << endl; return false; } unsigned int ipos; unsigned int pos[3]; double inEC[4]; for (int n=0; n<3; ++n) { for (pos[2]=0; pos[2]SetPos(pos[0],pos[1],pos[2]); EC_C[n][ipos]=inEC[0]; EC_G[n][ipos]=inEC[1]; EC_L[n][ipos]=inEC[2]; EC_R[n][ipos]=inEC[3]; } } } } return true; } double Operator::CalcTimestep() { if (m_TimeStepVar==3) return CalcTimestep_Var3(); //the biggest one for cartesian meshes //variant 1 is default return CalcTimestep_Var1(); } ////Berechnung nach Andreas Rennings Dissertation 2008, Seite 66, Formel 4.52 double Operator::CalcTimestep_Var1() { m_Used_TS_Name = string("Rennings_1"); // cout << "Operator::CalcTimestep(): Using timestep algorithm by Andreas Rennings, Dissertation @ University Duisburg-Essen, 2008, pp. 66, eq. 4.52" << endl; dT=1e200; double newT; unsigned int pos[3]; unsigned int ipos; unsigned int ipos_PM; unsigned int ipos_PPM; MainOp->SetReflection2Cell(); for (int n=0; n<3; ++n) { int nP = (n+1)%3; int nPP = (n+2)%3; for (pos[2]=0; pos[2]SetPos(pos[0],pos[1],pos[2]); ipos_PM = MainOp->Shift(nP,-1); MainOp->ResetShift(); ipos_PPM= MainOp->Shift(nPP,-1); MainOp->ResetShift(); newT = 2/sqrt( ( 4/EC_L[nP][ipos] + 4/EC_L[nP][ipos_PPM] + 4/EC_L[nPP][ipos] + 4/EC_L[nPP][ipos_PM]) / EC_C[n][ipos] ); if ((newT0.0)) dT=newT; } } } } if (dT==0) { cerr << "Operator::CalcTimestep: Timestep is zero... this is not supposed to happen!!! exit!" << endl; exit(3); } // cerr << "Operator Timestep: " << dT << endl; return 0; } double min(double* val, unsigned int count) { if (count==0) return 0.0; double min = val[0]; for (unsigned int n=1; nSetReflection2Cell(); for (int n=0; n<3; ++n) { int nP = (n+1)%3; int nPP = (n+2)%3; for (pos[2]=0; pos[2]ResetShift(); ipos = MainOp->SetPos(pos[0],pos[1],pos[2]); wqp = 1/(EC_L[nPP][ipos]*EC_C[n][MainOp->GetShiftedPos(nP ,1)]) + 1/(EC_L[nPP][ipos]*EC_C[n][ipos]); wqp += 1/(EC_L[nP ][ipos]*EC_C[n][MainOp->GetShiftedPos(nPP,1)]) + 1/(EC_L[nP ][ipos]*EC_C[n][ipos]); ipos = MainOp->Shift(nP,-1); wqp += 1/(EC_L[nPP][ipos]*EC_C[n][MainOp->GetShiftedPos(nP ,1)]) + 1/(EC_L[nPP][ipos]*EC_C[n][ipos]); ipos = MainOp->Shift(nPP,-1); wqp += 1/(EC_L[nP ][ipos]*EC_C[n][MainOp->GetShiftedPos(nPP,1)]) + 1/(EC_L[nP ][ipos]*EC_C[n][ipos]); MainOp->ResetShift(); ipos = MainOp->SetPos(pos[0],pos[1],pos[2]); wt_4[0] = 1/(EC_L[nPP][ipos] *EC_C[nP ][ipos]); wt_4[1] = 1/(EC_L[nPP][MainOp->GetShiftedPos(nP ,-1)] *EC_C[nP ][ipos]); wt_4[2] = 1/(EC_L[nP ][ipos] *EC_C[nPP][ipos]); wt_4[3] = 1/(EC_L[nP ][MainOp->GetShiftedPos(nPP,-1)] *EC_C[nPP][ipos]); wt1 = wt_4[0]+wt_4[1]+wt_4[2]+wt_4[3] - 2*min(wt_4,4); MainOp->ResetShift(); ipos = MainOp->SetPos(pos[0],pos[1],pos[2]); wt_4[0] = 1/(EC_L[nPP][ipos] *EC_C[nP ][MainOp->GetShiftedPos(n,1)]); wt_4[1] = 1/(EC_L[nPP][MainOp->GetShiftedPos(nP ,-1)] *EC_C[nP ][MainOp->GetShiftedPos(n,1)]); wt_4[2] = 1/(EC_L[nP ][ipos] *EC_C[nPP][MainOp->GetShiftedPos(n,1)]); wt_4[3] = 1/(EC_L[nP ][MainOp->GetShiftedPos(nPP,-1)] *EC_C[nPP][MainOp->GetShiftedPos(n,1)]); wt2 = wt_4[0]+wt_4[1]+wt_4[2]+wt_4[3] - 2*min(wt_4,4); w_total = wqp + wt1 + wt2; newT = 2/sqrt( w_total ); if ((newT0.0)) dT=newT; } } } } if (dT==0) { cerr << "Operator::CalcTimestep: Timestep is zero... this is not supposed to happen!!! exit!" << endl; exit(3); } // cerr << "Operator Timestep: " << dT << endl; return 0; } bool Operator::CalcPEC() { m_Nr_PEC[0]=0; m_Nr_PEC[1]=0; m_Nr_PEC[2]=0; CalcPEC_Range(0,numLines[0]-1,m_Nr_PEC); CalcPEC_Curves(); return true; } void Operator::CalcPEC_Range(unsigned int startX, unsigned int stopX, unsigned int* counter) { double coord[3]; unsigned int pos[3]; for (pos[0]=startX; pos[0]<=stopX; ++pos[0]) { for (pos[1]=0; pos[1]GetPropertyByCoordPriority(coord, (CSProperties::PropertyType)(CSProperties::MATERIAL | CSProperties::METAL), true); if (prop) { if (prop->GetType()==CSProperties::METAL) //set to PEC { SetVV(n,pos[0],pos[1],pos[2], 0 ); SetVI(n,pos[0],pos[1],pos[2], 0 ); ++counter[n]; } } } } } } } void Operator::CalcPEC_Curves() { //special treatment for primitives of type curve (treated as wires) double p1[3]; double p2[3]; struct Grid_Path path; vector vec_prop = CSX->GetPropertyByType(CSProperties::METAL); for (size_t p=0; pGetQtyPrimitives(); ++n) { CSPrimitives* prim = prop->GetPrimitive(n); CSPrimCurve* curv = prim->ToCurve(); if (curv) { for (size_t i=1; iGetNumberOfPoints(); ++i) { curv->GetPoint(i-1,p1); curv->GetPoint(i,p2); path = FindPath(p1,p2); if (path.dir.size()>0) prim->SetPrimitiveUsed(true); for (size_t t=0; t