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<float>(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<float>(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<float>(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<float>(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; } }
void Operator::DumpOperator2File(string filename) { #ifdef OUTPUT_IN_DRAWINGUNITS double discLines_scaling = 1; #else double discLines_scaling = GetGridDelta(); #endif cout << "Operator: Dumping FDTD operator information to vtk file: " << filename << " ..." << flush; FDTD_FLOAT**** exc = Create_N_3DArray<FDTD_FLOAT>(numLines); if (Exc) { for (unsigned int n=0; n<Exc->Volt_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<FDTD_FLOAT>(numLines); FDTD_FLOAT**** vi_temp = Create_N_3DArray<FDTD_FLOAT>(numLines); FDTD_FLOAT**** iv_temp = Create_N_3DArray<FDTD_FLOAT>(numLines); FDTD_FLOAT**** ii_temp = Create_N_3DArray<FDTD_FLOAT>(numLines); unsigned int pos[3], n; for (n=0; n<3; n++) for (pos[0]=0; pos[0]<numLines[0]; pos[0]++) for (pos[1]=0; pos[1]<numLines[1]; pos[1]++) for (pos[2]=0; pos[2]<numLines[2]; pos[2]++) { vv_temp[n][pos[0]][pos[1]][pos[2]] = GetVV(n,pos); vi_temp[n][pos[0]][pos[1]][pos[2]] = GetVI(n,pos); iv_temp[n][pos[0]][pos[1]][pos[2]] = GetIV(n,pos); ii_temp[n][pos[0]][pos[1]][pos[2]] = GetII(n,pos); } VTK_File_Writer* vtk_Writer = new VTK_File_Writer(filename.c_str(), m_MeshType); vtk_Writer->SetMeshLines(discLines,numLines,discLines_scaling); vtk_Writer->SetHeader("openEMS - Operator dump"); vtk_Writer->SetNativeDump(true); vtk_Writer->AddVectorField("vv",vv_temp); Delete_N_3DArray(vv_temp,numLines); vtk_Writer->AddVectorField("vi",vi_temp); Delete_N_3DArray(vi_temp,numLines); vtk_Writer->AddVectorField("iv",iv_temp); Delete_N_3DArray(iv_temp,numLines); vtk_Writer->AddVectorField("ii",ii_temp); Delete_N_3DArray(ii_temp,numLines); vtk_Writer->AddVectorField("exc",exc); Delete_N_3DArray(exc,numLines); if (vtk_Writer->Write()==false) cerr << "Operator::DumpOperator2File: Error: Can't write file... skipping!" << endl; cout << " done!" << endl; }
void Operator::DumpMaterial2File(string filename) { #ifdef OUTPUT_IN_DRAWINGUNITS double discLines_scaling = 1; #else double discLines_scaling = GetGridDelta(); #endif cout << "Operator: Dumping material information to vtk file: " << filename << " ..." << flush; FDTD_FLOAT**** epsilon = Create_N_3DArray<FDTD_FLOAT>(numLines); FDTD_FLOAT**** mue = Create_N_3DArray<FDTD_FLOAT>(numLines); FDTD_FLOAT**** kappa = Create_N_3DArray<FDTD_FLOAT>(numLines); FDTD_FLOAT**** sigma = Create_N_3DArray<FDTD_FLOAT>(numLines); unsigned int pos[3]; for (pos[0]=0; pos[0]<numLines[0]; ++pos[0]) { for (pos[1]=0; pos[1]<numLines[1]; ++pos[1]) { for (pos[2]=0; pos[2]<numLines[2]; ++pos[2]) { for (int n=0; n<3; ++n) { double inMat[4]; Calc_EffMatPos(n, pos, inMat); epsilon[n][pos[0]][pos[1]][pos[2]] = inMat[0]/__EPS0__; mue[n][pos[0]][pos[1]][pos[2]] = inMat[2]/__MUE0__; kappa[n][pos[0]][pos[1]][pos[2]] = inMat[1]; sigma[n][pos[0]][pos[1]][pos[2]] = inMat[3]; } } } } VTK_File_Writer* vtk_Writer = new VTK_File_Writer(filename.c_str(), m_MeshType); vtk_Writer->SetMeshLines(discLines,numLines,discLines_scaling); vtk_Writer->SetHeader("openEMS - material dump"); vtk_Writer->SetNativeDump(true); vtk_Writer->AddVectorField("epsilon",epsilon); Delete_N_3DArray(epsilon,numLines); vtk_Writer->AddVectorField("mue",mue); Delete_N_3DArray(mue,numLines); vtk_Writer->AddVectorField("kappa",kappa); Delete_N_3DArray(kappa,numLines); vtk_Writer->AddVectorField("sigma",sigma); Delete_N_3DArray(sigma,numLines); if (vtk_Writer->Write()==false) cerr << "Operator::DumpMaterial2File: Error: Can't write file... skipping!" << endl; cout << " done!" << endl; }
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<FDTD_FLOAT>(numLines); vi = Create_N_3DArray<FDTD_FLOAT>(numLines); iv = Create_N_3DArray<FDTD_FLOAT>(numLines); ii = Create_N_3DArray<FDTD_FLOAT>(numLines); }
void Operator::Delete() { CSX = NULL; Delete_N_3DArray(vv,numLines); Delete_N_3DArray(vi,numLines); Delete_N_3DArray(iv,numLines); Delete_N_3DArray(ii,numLines); vv=vi=iv=ii=0; delete MainOp; MainOp=0; for (int n=0; n<3; ++n) { delete[] EC_C[n];EC_C[n]=0; delete[] EC_G[n];EC_G[n]=0; delete[] EC_L[n];EC_L[n]=0; delete[] EC_R[n];EC_R[n]=0; } delete Exc;Exc=0; Delete_N_3DArray(m_epsR,numLines); m_epsR=0; Delete_N_3DArray(m_kappa,numLines); m_kappa=0; Delete_N_3DArray(m_mueR,numLines); m_mueR=0; Delete_N_3DArray(m_sigma,numLines); m_sigma=0; }
ProcessFieldsFD::~ProcessFieldsFD() { for (size_t n = 0; n<m_FD_Fields.size(); ++n) { Delete_N_3DArray(m_FD_Fields.at(n),numLines); } m_FD_Fields.clear(); }
void ProcessFieldsFD::DumpFDData() { if (m_fileType==VTK_FILETYPE) { unsigned int pos[3]; FDTD_FLOAT**** field = Create_N_3DArray<float>(numLines); std::complex<float>**** field_fd = NULL; double angle=0; int Nr_Ph = 21; for (size_t n = 0; n<m_FD_Samples.size(); ++n) { //dump multiple phase to vtk-files for (int p=0; p<Nr_Ph; ++p) { angle = 2.0 * M_PI * p / Nr_Ph; std::complex<float> exp_jwt = std::exp( (std::complex<float>)( _I * angle) ); field_fd = m_FD_Fields.at(n); for (pos[0]=0; pos[0]<numLines[0]; ++pos[0]) { for (pos[1]=0; pos[1]<numLines[1]; ++pos[1]) { for (pos[2]=0; pos[2]<numLines[2]; ++pos[2]) { field[0][pos[0]][pos[1]][pos[2]] = real(field_fd[0][pos[0]][pos[1]][pos[2]] * exp_jwt); field[1][pos[0]][pos[1]][pos[2]] = real(field_fd[1][pos[0]][pos[1]][pos[2]] * exp_jwt); field[2][pos[0]][pos[1]][pos[2]] = real(field_fd[2][pos[0]][pos[1]][pos[2]] * exp_jwt); } } } stringstream ss; ss << m_filename << fixed << "_f=" << m_FD_Samples.at(n) << "_p=" << std::setw( 3 ) << std::setfill( '0' ) <<(int)(angle * 180 / M_PI); m_Vtk_Dump_File->SetFilename(ss.str()); m_Vtk_Dump_File->ClearAllFields(); m_Vtk_Dump_File->AddVectorField(GetFieldNameByType(m_DumpType),field); if (m_Vtk_Dump_File->Write()==false) cerr << "ProcessFieldsFD::Process: can't dump to file... abort! " << endl; } { //dump magnitude to vtk-files for (pos[0]=0; pos[0]<numLines[0]; ++pos[0]) { for (pos[1]=0; pos[1]<numLines[1]; ++pos[1]) { for (pos[2]=0; pos[2]<numLines[2]; ++pos[2]) { field[0][pos[0]][pos[1]][pos[2]] = abs(field_fd[0][pos[0]][pos[1]][pos[2]]); field[1][pos[0]][pos[1]][pos[2]] = abs(field_fd[1][pos[0]][pos[1]][pos[2]]); field[2][pos[0]][pos[1]][pos[2]] = abs(field_fd[2][pos[0]][pos[1]][pos[2]]); } } } stringstream ss; ss << m_filename << fixed << "_f=" << m_FD_Samples.at(n) << "_abs"; m_Vtk_Dump_File->SetFilename(ss.str()); m_Vtk_Dump_File->ClearAllFields(); m_Vtk_Dump_File->AddVectorField(GetFieldNameByType(m_DumpType),field); if (m_Vtk_Dump_File->Write()==false) cerr << "ProcessFieldsFD::Process: can't dump to file... abort! " << endl; } { //dump phase to vtk-files for (pos[0]=0; pos[0]<numLines[0]; ++pos[0]) { for (pos[1]=0; pos[1]<numLines[1]; ++pos[1]) { for (pos[2]=0; pos[2]<numLines[2]; ++pos[2]) { field[0][pos[0]][pos[1]][pos[2]] = arg(field_fd[0][pos[0]][pos[1]][pos[2]]); field[1][pos[0]][pos[1]][pos[2]] = arg(field_fd[1][pos[0]][pos[1]][pos[2]]); field[2][pos[0]][pos[1]][pos[2]] = arg(field_fd[2][pos[0]][pos[1]][pos[2]]); } } } stringstream ss; ss << m_filename << fixed << "_f=" << m_FD_Samples.at(n) << "_arg"; m_Vtk_Dump_File->SetFilename(ss.str()); m_Vtk_Dump_File->ClearAllFields(); m_Vtk_Dump_File->AddVectorField(GetFieldNameByType(m_DumpType),field); if (m_Vtk_Dump_File->Write()==false) cerr << "ProcessFieldsFD::Process: can't dump to file... abort! " << endl; } } Delete_N_3DArray(field,numLines); return; } if (m_fileType==HDF5_FILETYPE) { for (size_t n = 0; n<m_FD_Samples.size(); ++n) { stringstream ss; ss << "f" << n; size_t datasize[]={numLines[0],numLines[1],numLines[2]}; if (m_HDF5_Dump_File->WriteVectorField(ss.str(), m_FD_Fields.at(n), datasize)==false) cerr << "ProcessFieldsFD::Process: can't dump to file...! " << endl; //legacy support, use /FieldData/FD frequency-Attribute in the future float freq[1] = {(float)m_FD_Samples.at(n)}; if (m_HDF5_Dump_File->WriteAtrribute("/FieldData/FD/"+ss.str()+"_real","frequency",freq,1)==false) cerr << "ProcessFieldsFD::Process: can't dump to file...! " << endl; if (m_HDF5_Dump_File->WriteAtrribute("/FieldData/FD/"+ss.str()+"_imag","frequency",freq,1)==false) cerr << "ProcessFieldsFD::Process: can't dump to file...! " << endl; } return; } cerr << "ProcessFieldsFD::Process: unknown File-Type" << endl; }
//! \brief dump PEC (perfect electric conductor) information (into VTK-file) //! visualization via paraview //! visualize only one component (x, y or z) void Operator::DumpPEC2File( string filename ) { cout << "Operator: Dumping PEC information to vtk file: " << filename << " ..." << flush; FDTD_FLOAT**** pec = Create_N_3DArray<FDTD_FLOAT>( 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[0]-1; pos[0]++) { for (pos[1]=0; pos[1]<numLines[1]-1; pos[1]++) { for (pos[2]=0; pos[2]<numLines[2]-1; pos[2]++) { if ((pos[1] != 0) && (pos[2] != 0)) { // PEC surrounds the computational area; do not output this if ((GetVV(0,pos) == 0) && (GetVI(0,pos) == 0)) pec[0][pos[0]][pos[1]][pos[2]] = GetEdgeLength( 0, pos ) * scaling; // PEC-x found } if ((pos[0] != 0) && (pos[2] != 0)) { // PEC surrounds the computational area; do not output this if ((GetVV(1,pos) == 0) && (GetVI(1,pos) == 0)) pec[1][pos[0]][pos[1]][pos[2]] = GetEdgeLength( 1, pos ) * scaling; // PEC-y found } if ((pos[0] != 0) && (pos[1] != 0)) { // PEC surrounds the computational area; do not output this if ((GetVV(2,pos) == 0) && (GetVI(2,pos) == 0)) pec[2][pos[0]][pos[1]][pos[2]] = GetEdgeLength( 2, pos ) * scaling; // PEC-z found } } } } // evaluate boundary conditions for (int n=0; n<3; n++) { int nP = (n+1)%3; int nPP = (n+2)%3; for (pos[nP]=0; pos[nP]<numLines[nP]; pos[nP]++) { for (pos[nPP]=0; pos[nPP]<numLines[nPP]; pos[nPP]++) { pos[n] = 0; if ((pos[nP] != numLines[nP]-1) && (m_BC[2*n] == 0)) pec[nP ][pos[0]][pos[1]][pos[2]] = GetEdgeLength( nP, pos ) * scaling; if ((pos[nPP] != numLines[nPP]-1) && (m_BC[2*n] == 0)) pec[nPP][pos[0]][pos[1]][pos[2]] = GetEdgeLength( nPP, pos ) * scaling; pos[n] = numLines[n]-1; if ((pos[nP] != numLines[nP]-1) && (m_BC[2*n+1] == 0)) pec[nP ][pos[0]][pos[1]][pos[2]] = GetEdgeLength( nP, pos ) * scaling; if ((pos[nPP] != numLines[nPP]-1) && (m_BC[2*n+1] == 0)) pec[nPP][pos[0]][pos[1]][pos[2]] = GetEdgeLength( nPP, pos ) * scaling; } } } #ifdef OUTPUT_IN_DRAWINGUNITS scaling = 1; #else scaling = GetGridDelta(); #endif VTK_File_Writer* vtk_Writer = new VTK_File_Writer(filename.c_str(), m_MeshType); vtk_Writer->SetMeshLines(discLines,numLines,scaling); vtk_Writer->SetHeader("openEMS - PEC dump"); vtk_Writer->SetNativeDump(true); vtk_Writer->AddVectorField("PEC",pec); Delete_N_3DArray(pec,numLines); if (vtk_Writer->Write()==false) cerr << "Operator::DumpPEC2File: Error: Can't write file... skipping!" << endl; cout << " done!" << endl; }
bool nf2ff_calc::AddPlane(float **lines, unsigned int* numLines, complex<float>**** E_field, complex<float>**** H_field, int MeshType) { //find normal direction int ny = -1; int nP,nPP; for (int n=0;n<3;++n) { nP = (n+1)%3; nPP = (n+2)%3; if ((numLines[n]==1) && (numLines[nP]>2) && (numLines[nPP]>2)) ny=n; } nP = (ny+1)%3; nPP = (ny+2)%3; if (ny<0) { cerr << "nf2ff_calc::AddPlane: Error can't determine normal direction..." << endl; return false; } complex<float>**** Js = Create_N_3DArray<complex<float> >(numLines); complex<float>**** Ms = Create_N_3DArray<complex<float> >(numLines); float normDir[3]= {0,0,0}; if (lines[ny][0]>=m_centerCoord[ny]) normDir[ny]=1; else normDir[ny]=-1; unsigned int pos[3]; float edge_length_P[numLines[nP]]; for (unsigned int n=1;n<numLines[nP]-1;++n) edge_length_P[n]=0.5*(lines[nP][n+1]-lines[nP][n-1]); edge_length_P[0]=0.5*(lines[nP][1]-lines[nP][0]); edge_length_P[numLines[nP]-1]=0.5*(lines[nP][numLines[nP]-1]-lines[nP][numLines[nP]-2]); float edge_length_PP[numLines[nPP]]; for (unsigned int n=1;n<numLines[nPP]-1;++n) edge_length_PP[n]=0.5*(lines[nPP][n+1]-lines[nPP][n-1]); edge_length_PP[0]=0.5*(lines[nPP][1]-lines[nPP][0]); edge_length_PP[numLines[nPP]-1]=0.5*(lines[nPP][numLines[nPP]-1]-lines[nPP][numLines[nPP]-2]); //check for cylindrical mesh if (MeshType==1) { if (ny==0) //surface a-z { for (unsigned int n=0;n<numLines[nP];++n) edge_length_P[n]*=lines[0][0]; //angle-width * radius } else if (ny==2) //surface r-a { //calculate: area = delta_angle * delta_radius * center_radius for (unsigned int n=1;n<numLines[nP]-1;++n) edge_length_P[n]*=lines[nP][n]; //radius-width * center-radius edge_length_P[0]*=(lines[nP][0]+0.5*edge_length_P[0]); edge_length_P[numLines[nP]-1]*=(lines[nP][numLines[nP]-1]-0.5*edge_length_P[numLines[nP]-1]); } } complex<float> power = 0; float area; for (pos[0]=0; pos[0]<numLines[0]; ++pos[0]) for (pos[1]=0; pos[1]<numLines[1]; ++pos[1]) for (pos[2]=0; pos[2]<numLines[2]; ++pos[2]) { area = edge_length_P[pos[nP]]*edge_length_PP[pos[nPP]]; power = (E_field[nP][pos[0]][pos[1]][pos[2]]*conj(H_field[nPP][pos[0]][pos[1]][pos[2]]) \ - E_field[nPP][pos[0]][pos[1]][pos[2]]*conj(H_field[nP][pos[0]][pos[1]][pos[2]])); m_radPower += 0.5*area*real(power)*normDir[ny]; } unsigned int numAngles[2] = {m_numTheta, m_numPhi}; // setup multi-threading jobs vector<unsigned int> jpt = AssignJobs2Threads(numLines[nP], m_numThreads, true); m_numThreads = jpt.size(); nf2ff_data thread_data[m_numThreads]; m_Barrier = new boost::barrier(m_numThreads+1); // numThread workers + 1 controller unsigned int start=0; unsigned int stop=jpt.at(0)-1; for (unsigned int n=0; n<m_numThreads; n++) { thread_data[n].ny=ny; thread_data[n].mesh_type = MeshType; thread_data[n].normDir=normDir; thread_data[n].numLines=numLines; thread_data[n].lines=lines; thread_data[n].edge_length_P=edge_length_P; thread_data[n].edge_length_PP=edge_length_PP; thread_data[n].E_field=E_field; thread_data[n].H_field=H_field; thread_data[n].Js=Js; thread_data[n].Ms=Ms; thread_data[n].m_Nt=Create2DArray<complex<float> >(numAngles); thread_data[n].m_Np=Create2DArray<complex<float> >(numAngles); thread_data[n].m_Lt=Create2DArray<complex<float> >(numAngles); thread_data[n].m_Lp=Create2DArray<complex<float> >(numAngles); boost::thread *t = new boost::thread( nf2ff_calc_thread(this,start,stop,n,thread_data[n]) ); m_thread_group.add_thread( t ); start = stop+1; if (n<m_numThreads-1) stop = start + jpt.at(n+1)-1; } //all threads a running and waiting for the barrier m_Barrier->wait(); //start // threads: calc Js and Ms (eq. 8.15a/b) // threads calc their local Nt,Np,Lt and Lp m_Barrier->wait(); //combine all thread local Nt,Np,Lt and Lp //cleanup E- & H-Fields Delete_N_3DArray(E_field,numLines); Delete_N_3DArray(H_field,numLines); complex<float>** Nt = Create2DArray<complex<float> >(numAngles); complex<float>** Np = Create2DArray<complex<float> >(numAngles); complex<float>** Lt = Create2DArray<complex<float> >(numAngles); complex<float>** Lp = Create2DArray<complex<float> >(numAngles); for (unsigned int n=0; n<m_numThreads; n++) { for (unsigned int tn=0;tn<m_numTheta;++tn) for (unsigned int pn=0;pn<m_numPhi;++pn) { Nt[tn][pn] += thread_data[n].m_Nt[tn][pn]; Np[tn][pn] += thread_data[n].m_Np[tn][pn]; Lt[tn][pn] += thread_data[n].m_Lt[tn][pn]; Lp[tn][pn] += thread_data[n].m_Lp[tn][pn]; } Delete2DArray(thread_data[n].m_Nt,numAngles); Delete2DArray(thread_data[n].m_Np,numAngles); Delete2DArray(thread_data[n].m_Lt,numAngles); Delete2DArray(thread_data[n].m_Lp,numAngles); } m_Barrier->wait(); //wait for termination m_thread_group.join_all(); // wait for termination delete m_Barrier; m_Barrier = NULL; //cleanup Js & Ms Delete_N_3DArray(Js,numLines); Delete_N_3DArray(Ms,numLines); // calc equations 8.23a/b and 8.24a/b float k = 2*M_PI*m_freq/__C0__; complex<float> factor(0,k/4.0/M_PI/m_radius); complex<float> f_exp(0,-1*k*m_radius); factor *= exp(f_exp); complex<float> Z0 = __Z0__; float P_max = 0; for (unsigned int tn=0;tn<m_numTheta;++tn) for (unsigned int pn=0;pn<m_numPhi;++pn) { m_E_theta[tn][pn] -= factor*(Lp[tn][pn] + Z0*Nt[tn][pn]); m_E_phi[tn][pn] += factor*(Lt[tn][pn] - Z0*Np[tn][pn]); m_H_theta[tn][pn] += factor*(Np[tn][pn] - Lt[tn][pn]/Z0); m_H_phi[tn][pn] -= factor*(Nt[tn][pn] + Lp[tn][pn]/Z0); m_P_rad[tn][pn] = m_radius*m_radius/(2*__Z0__) * abs((m_E_theta[tn][pn]*conj(m_E_theta[tn][pn])+m_E_phi[tn][pn]*conj(m_E_phi[tn][pn]))); if (m_P_rad[tn][pn]>P_max) P_max = m_P_rad[tn][pn]; } //cleanup Nx and Lx Delete2DArray(Nt,numAngles); Delete2DArray(Np,numAngles); Delete2DArray(Lt,numAngles); Delete2DArray(Lp,numAngles); m_maxDir = 4*M_PI*P_max / m_radPower; return true; }