738 lines
17 KiB
C++
738 lines
17 KiB
C++
#include"../common/define.h"
|
|
#include"Assemble_Base.h"
|
|
|
|
#include "../Eigen/SparseLU"
|
|
#include <cmath>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include <string>
|
|
|
|
#ifdef _WIN32
|
|
#include <direct.h>
|
|
static void EnsureOutputDir(const std::string& dir)
|
|
{
|
|
_mkdir(dir.c_str());
|
|
}
|
|
#else
|
|
#include <sys/stat.h>
|
|
static void EnsureOutputDir(const std::string& dir)
|
|
{
|
|
mkdir(dir.c_str(), 0755);
|
|
}
|
|
#endif
|
|
|
|
|
|
/*
|
|
2D_EigenMode
|
|
*/
|
|
void OpticsFEM_2D_EigenMode::Assemble()
|
|
{
|
|
//??????????
|
|
_mIsReal = _mMatLib->IsReal();
|
|
if (_mIsReal)
|
|
{
|
|
if (_mPhy->GetNbrPML() > 0)
|
|
_mIsReal = false;
|
|
}
|
|
if (_mIsReal)
|
|
{
|
|
for (int i = 0; i < _mPhy->GetNbrPBC(); i++)
|
|
{
|
|
if (_mPhy->GetPBCPhi(i).imag()!= 0.0)
|
|
{
|
|
_mIsReal = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//????????? ????????
|
|
_mDof = _mMesh->GetNbrVertex() + _mMesh->GetNbrEdge();
|
|
|
|
//????????
|
|
this->Assemble_WaveEquation();
|
|
|
|
if (_mIsReal)
|
|
{
|
|
_mA_real = Eigen::SparseMatrix<double, Eigen::RowMajor>(_mDof, _mDof);
|
|
_mB_real = Eigen::SparseMatrix<double, Eigen::RowMajor>(_mDof, _mDof);
|
|
_mA_real.setFromTriplets(_mTripleA_real.begin(), _mTripleA_real.end());
|
|
_mB_real.setFromTriplets(_mTripleB_real.begin(), _mTripleB_real.end());
|
|
}
|
|
else
|
|
{
|
|
_mA_complex = Eigen::SparseMatrix<std::complex<double>, Eigen::RowMajor>(_mDof, _mDof);
|
|
_mB_complex = Eigen::SparseMatrix<std::complex<double>, Eigen::RowMajor>(_mDof, _mDof);
|
|
_mA_complex.setFromTriplets(_mTripleA_complex.begin(), _mTripleA_complex.end());
|
|
_mB_complex.setFromTriplets(_mTripleB_complex.begin(), _mTripleB_complex.end());
|
|
}
|
|
//????????????????????????
|
|
if ((_mPhy->GetNbrPEC() + _mPhy->GetNbrPBC() > 0))
|
|
{
|
|
this->Assemble_PEC_PBC();
|
|
|
|
if (_mIsReal)
|
|
{
|
|
_mA_real = (_mP_real.transpose() * _mA_real) * _mP_real;
|
|
_mB_real = (_mP_real.transpose() * _mB_real) * _mP_real;
|
|
}
|
|
else
|
|
{
|
|
_mA_complex = (_mP_complex.adjoint() * _mA_complex) * _mP_complex;
|
|
_mB_complex = (_mP_complex.adjoint() * _mB_complex) * _mP_complex;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (_mIsReal)
|
|
{
|
|
_mP_real = Eigen::SparseMatrix<double, Eigen::RowMajor>(_mDof, _mDof);
|
|
_mP_real.setIdentity();
|
|
}
|
|
else
|
|
{
|
|
_mP_complex = Eigen::SparseMatrix<complex<double>, Eigen::RowMajor>(_mDof, _mDof);
|
|
_mP_complex.setIdentity();
|
|
}
|
|
}
|
|
//?????????????
|
|
/*
|
|
double k0 = 2 * Pi / _mSolver->GetLda0();
|
|
double theta2 = k0 * k0 * _mSolver->GetSearchValue() * _mSolver->GetSearchValue();
|
|
if (_mIsReal)
|
|
{
|
|
Eigen::SparseMatrix<double, Eigen::RowMajor> tempA = _mA_real;
|
|
_mA_real = _mB_real;
|
|
_mB_real = (1 / theta2) * tempA + _mB_real;
|
|
}
|
|
else
|
|
{
|
|
Eigen::SparseMatrix<std::complex<double>, Eigen::RowMajor> tempA = _mA_complex;
|
|
_mA_complex = _mB_complex;
|
|
_mB_complex = (1 / theta2) * tempA + _mB_complex;
|
|
}
|
|
*/
|
|
}
|
|
|
|
void OpticsFEM_2D_EigenMode::Run()
|
|
{
|
|
double k0 = 2. * Pi / _mSolver->GetLda0();
|
|
double search = -k0 * k0 * _mSolver->GetSearchValue() * _mSolver->GetSearchValue();
|
|
if (_mIsReal)
|
|
{
|
|
_mSolver->GetRealFlag(_mIsReal);
|
|
_mSolver->SetParam(&_mA_real, &_mB_real, &_mP_real, search);
|
|
}
|
|
else
|
|
{
|
|
_mSolver->GetRealFlag(_mIsReal);
|
|
_mSolver->SetParam(&_mA_complex, &_mB_complex, &_mP_complex, search);
|
|
}
|
|
_mSolver->Run(&_mX, &_mLambda);
|
|
}
|
|
|
|
void OpticsFEM_2D_EigenMode::Post(string file)
|
|
{
|
|
_mPost->GetMesh(_mMesh);
|
|
_mPost->GetSolver(_mSolver);
|
|
_mPost->GetResult(&_mX, &_mLambda);
|
|
_mPost->GetElectric();
|
|
_mPost->OutputData(file);
|
|
}
|
|
|
|
/*
|
|
2D_EigenFreq
|
|
*/
|
|
void OpticsFEM_2D_EigenFreq::Assemble()
|
|
{
|
|
//??????????
|
|
_mIsReal = _mMatLib->IsReal();
|
|
if (_mIsReal)
|
|
{
|
|
if (_mPhy->GetNbrPML() > 0)
|
|
_mIsReal = false;
|
|
}
|
|
if (_mIsReal)
|
|
{
|
|
for (int i = 0; i < _mPhy->GetNbrPBC(); i++)
|
|
{
|
|
if (_mPhy->GetPBCPhi(i).imag()!= 0.0)
|
|
{
|
|
_mIsReal = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//????????
|
|
this->Assemble_WaveEquation();
|
|
|
|
//?????????
|
|
if (_mIsReal)
|
|
{
|
|
int tempDof = _mMesh->GetNbrVertex() + _mMesh->GetNbrEdge();
|
|
_mA_real = Eigen::SparseMatrix<double, Eigen::RowMajor>(tempDof, tempDof);
|
|
_mB_real = Eigen::SparseMatrix<double, Eigen::RowMajor>(tempDof, tempDof);
|
|
_mA_real.setFromTriplets(_mTripleA_real.begin(), _mTripleA_real.end());
|
|
_mB_real.setFromTriplets(_mTripleB_real.begin(), _mTripleB_real.end());
|
|
}
|
|
else
|
|
{
|
|
int tempDof = _mMesh->GetNbrVertex() + _mMesh->GetNbrEdge();
|
|
_mA_complex = Eigen::SparseMatrix<std::complex<double>, Eigen::RowMajor>(tempDof, tempDof);
|
|
_mB_complex = Eigen::SparseMatrix<std::complex<double>, Eigen::RowMajor>(tempDof, tempDof);
|
|
_mA_complex.setFromTriplets(_mTripleA_complex.begin(), _mTripleA_complex.end());
|
|
_mB_complex.setFromTriplets(_mTripleB_complex.begin(), _mTripleB_complex.end());
|
|
}
|
|
|
|
//????????????????????????
|
|
_mElectricType = _mSolver->GetElectricType();
|
|
if ((_mPhy->GetNbrPEC() + _mPhy->GetNbrPBC() > 0))
|
|
{
|
|
this->Assemble_PEC_PBC();
|
|
}
|
|
else
|
|
{
|
|
//??T???????? 0-Et 1-Ez 2-E
|
|
if (_mIsReal)
|
|
{
|
|
std::vector<Eigen::Triplet<double>> tempTriple;
|
|
if (_mElectricType == 0)
|
|
{
|
|
_mDof = _mMesh->GetNbrEdge();
|
|
_mP_real = Eigen::SparseMatrix<double, Eigen::RowMajor>(_mMesh->GetNbrVertex() + _mMesh->GetNbrEdge(), _mDof);
|
|
for (int i = 0; i < _mDof; i++)
|
|
{
|
|
tempTriple.push_back(Eigen::Triplet<double>(_mMesh->GetNbrVertex() + i, i, 1.));
|
|
}
|
|
_mP_real.setFromTriplets(tempTriple.begin(), tempTriple.end());
|
|
}
|
|
else if (_mElectricType == 1)
|
|
{
|
|
_mDof = _mMesh->GetNbrVertex();
|
|
_mP_real = Eigen::SparseMatrix<double, Eigen::RowMajor>(_mMesh->GetNbrVertex() + _mMesh->GetNbrEdge(), _mDof);
|
|
for (int i = 0; i < _mDof; i++)
|
|
{
|
|
tempTriple.push_back(Eigen::Triplet<double>(i, i, 1.));
|
|
|
|
}
|
|
_mP_real.setFromTriplets(tempTriple.begin(), tempTriple.end());
|
|
}
|
|
else
|
|
{
|
|
_mDof = _mMesh->GetNbrVertex() + _mMesh->GetNbrEdge();
|
|
_mP_real = Eigen::SparseMatrix<double, Eigen::RowMajor>(_mDof, _mDof);
|
|
_mP_real.setIdentity();
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
std::vector<Eigen::Triplet<complex<double>>> tempTriple;
|
|
if (_mElectricType == 0)
|
|
{
|
|
_mDof = _mMesh->GetNbrEdge();
|
|
_mP_complex = Eigen::SparseMatrix<complex<double>, Eigen::RowMajor>(_mMesh->GetNbrVertex() + _mMesh->GetNbrEdge(), _mDof);
|
|
for (int i = 0; i < _mDof; i++)
|
|
{
|
|
/*tempTriple.push_back(Eigen::Triplet<complex<double>>(_mMesh->GetNbrVertex() + i, _mMesh->GetNbrVertex() + i, 1.));*/
|
|
tempTriple.push_back(Eigen::Triplet<complex<double>>(_mMesh->GetNbrVertex() + i, i, 1.));
|
|
}
|
|
_mP_complex.setFromTriplets(tempTriple.begin(), tempTriple.end());
|
|
}
|
|
else if (_mElectricType == 1)
|
|
{
|
|
_mDof = _mMesh->GetNbrVertex();
|
|
_mP_complex = Eigen::SparseMatrix<complex<double>, Eigen::RowMajor>(_mMesh->GetNbrVertex() + _mMesh->GetNbrEdge(), _mDof);
|
|
for (int i = 0; i < _mDof; i++)
|
|
{
|
|
tempTriple.push_back(Eigen::Triplet<complex<double>>(i, i, 1.));
|
|
|
|
}
|
|
_mP_complex.setFromTriplets(tempTriple.begin(), tempTriple.end());
|
|
}
|
|
else
|
|
{
|
|
_mDof = _mMesh->GetNbrVertex() + _mMesh->GetNbrEdge();
|
|
_mP_complex = Eigen::SparseMatrix<complex<double>, Eigen::RowMajor>(_mDof, _mDof);
|
|
_mP_complex.setIdentity();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if (_mIsReal)
|
|
{
|
|
_mA_real = (_mP_real.transpose() * _mA_real) * _mP_real;
|
|
_mB_real = (_mP_real.transpose() * _mB_real) * _mP_real;
|
|
}
|
|
else
|
|
{
|
|
_mA_complex = (_mP_complex.adjoint() * _mA_complex) * _mP_complex;
|
|
_mB_complex = (_mP_complex.adjoint() * _mB_complex) * _mP_complex;
|
|
}
|
|
}
|
|
|
|
void OpticsFEM_2D_EigenFreq::Run()
|
|
{
|
|
double k0 = 2. * Pi / (c_const / _mSolver->GetSearchValue());
|
|
double search = k0 * k0;
|
|
if (_mIsReal)
|
|
{
|
|
_mSolver->GetRealFlag(_mIsReal);
|
|
_mSolver->SetParam(&_mA_real, &_mB_real, &_mP_real, search);
|
|
}
|
|
else
|
|
{
|
|
_mSolver->GetRealFlag(_mIsReal);
|
|
_mSolver->SetParam(&_mA_complex, &_mB_complex, &_mP_complex, search);
|
|
}
|
|
_mSolver->Run(&_mX, &_mLambda);
|
|
}
|
|
|
|
void OpticsFEM_2D_EigenFreq::Post(string file)
|
|
{
|
|
_mPost->GetMesh(_mMesh);
|
|
_mPost->GetSolver(_mSolver);
|
|
_mPost->GetResult(&_mX, &_mLambda);
|
|
_mPost->GetElectric();
|
|
_mPost->OutputData(file);
|
|
}
|
|
|
|
/*
|
|
2D_Scatter
|
|
*/
|
|
void OpticsFEM_2D_Scatter::Assemble()
|
|
{
|
|
_mIsReal = _mMatLib->IsReal();
|
|
if (_mIsReal)
|
|
{
|
|
if (_mPhy->GetNbrPML() > 0)
|
|
_mIsReal = false;
|
|
}
|
|
if (_mIsReal)
|
|
{
|
|
if (_mPhy->GetNbrSBC() > 0)
|
|
_mIsReal = false;
|
|
}
|
|
if (_mIsReal)
|
|
{
|
|
/*for (int i = 0; i < _mPhy->GetNbrElE(); i++)
|
|
{
|
|
Eigen::Vector3cd E0;
|
|
_mPhy->GetE0(i, E0);
|
|
for (int j = 0; j < 3; j++)
|
|
{
|
|
if (E0(j).imag() != 0)
|
|
{
|
|
_mIsReal = false;
|
|
}
|
|
}
|
|
}*/
|
|
}
|
|
if (_mIsReal)
|
|
{
|
|
for (int i = 0; i < _mPhy->GetNbrPBC(); i++)
|
|
{
|
|
if (_mPhy->GetPBCPhi(i).imag()!= 0.0)
|
|
{
|
|
_mIsReal = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (_mIsReal)
|
|
{
|
|
if (_mPhy->GetBeamState() != 0)
|
|
_mIsReal = false;
|
|
}
|
|
|
|
//???????????
|
|
this->Assemble_WaveEquation();
|
|
|
|
if (_mIsReal)
|
|
{
|
|
int tempDof = _mMesh->GetNbrVertex() + _mMesh->GetNbrEdge();
|
|
_mB_real = Eigen::VectorXd::Zero(tempDof);
|
|
}
|
|
else
|
|
{
|
|
int tempDof = _mMesh->GetNbrVertex() + _mMesh->GetNbrEdge();
|
|
_mB_complex = Eigen::VectorXcd::Zero(tempDof);
|
|
}
|
|
|
|
//SBC
|
|
if (_mPhy->GetNbrSBC() > 0)
|
|
this->Assemble_SBC();
|
|
|
|
//BELE
|
|
if (_mPhy->GetNbrBELE())
|
|
this->Assemble_BELE();
|
|
|
|
if (_mIsReal)
|
|
{
|
|
int tempDof = _mMesh->GetNbrVertex() + _mMesh->GetNbrEdge();
|
|
_mA_real = Eigen::SparseMatrix<double, Eigen::RowMajor>(tempDof, tempDof);
|
|
_mA_real.setFromTriplets(_mTripleA_real.begin(), _mTripleA_real.end());
|
|
}
|
|
else
|
|
{
|
|
int tempDof = _mMesh->GetNbrVertex() + _mMesh->GetNbrEdge();
|
|
_mA_complex = Eigen::SparseMatrix<complex<double>, Eigen::RowMajor>(tempDof, tempDof);
|
|
_mA_complex.setFromTriplets(_mTripleA_complex.begin(), _mTripleA_complex.end());
|
|
}
|
|
|
|
//MAG
|
|
if (_mPhy->GetNbrMAG())
|
|
this->Assemble_MAG();
|
|
|
|
//SCD
|
|
if (_mPhy->GetNbrSCD())
|
|
this->Assemble_SCD();
|
|
|
|
//MPD
|
|
if (_mPhy->GetNbrMPD())
|
|
this->Assemble_MPD();
|
|
|
|
//EPD
|
|
if (_mPhy->GetNbrEPD())
|
|
this->Assemble_EPD();
|
|
|
|
//PEC+ELE
|
|
this->Assemble_PEC_ELE();
|
|
|
|
//PBC
|
|
if (_mPhy->GetNbrPBC() > 0)
|
|
{
|
|
this->Assemble_PBC();
|
|
}
|
|
else
|
|
{
|
|
if (_mIsReal)
|
|
{
|
|
std::vector<Eigen::Triplet<double>> tempTriple;
|
|
if (_mSolver->GetElectricType() == 0)
|
|
{
|
|
_mDof = _mMesh->GetNbrEdge();
|
|
_mP_real = Eigen::SparseMatrix<double, Eigen::RowMajor>(_mMesh->GetNbrVertex() + _mMesh->GetNbrEdge(), _mDof);
|
|
for (int i = 0; i < _mDof; i++)
|
|
{
|
|
tempTriple.push_back(Eigen::Triplet<double>(_mMesh->GetNbrVertex() + i, i, 1.));
|
|
}
|
|
_mP_real.setFromTriplets(tempTriple.begin(), tempTriple.end());
|
|
}
|
|
else if (_mSolver->GetElectricType() == 1)
|
|
{
|
|
_mDof = _mMesh->GetNbrVertex();
|
|
_mP_real = Eigen::SparseMatrix<double, Eigen::RowMajor>(_mMesh->GetNbrVertex() + _mMesh->GetNbrEdge(), _mDof);
|
|
for (int i = 0; i < _mDof; i++)
|
|
{
|
|
tempTriple.push_back(Eigen::Triplet<double>(i, i, 1.));
|
|
|
|
}
|
|
_mP_real.setFromTriplets(tempTriple.begin(), tempTriple.end());
|
|
}
|
|
else
|
|
{
|
|
_mDof = _mMesh->GetNbrVertex() + _mMesh->GetNbrEdge();
|
|
_mP_real = Eigen::SparseMatrix<double, Eigen::RowMajor>(_mDof, _mDof);
|
|
_mP_real.setIdentity();
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
std::vector<Eigen::Triplet<complex<double>>> tempTriple;
|
|
if (_mSolver->GetElectricType() == 0)
|
|
{
|
|
_mDof = _mMesh->GetNbrEdge();
|
|
_mP_complex = Eigen::SparseMatrix<complex<double>, Eigen::RowMajor>(_mMesh->GetNbrVertex() + _mMesh->GetNbrEdge(), _mDof);
|
|
for (int i = 0; i < _mDof; i++)
|
|
{
|
|
tempTriple.push_back(Eigen::Triplet<complex<double>>(_mMesh->GetNbrVertex() + i, i, 1.));
|
|
}
|
|
_mP_complex.setFromTriplets(tempTriple.begin(), tempTriple.end());
|
|
}
|
|
else if (_mSolver->GetElectricType() == 1)
|
|
{
|
|
_mDof = _mMesh->GetNbrVertex();
|
|
_mP_complex = Eigen::SparseMatrix<complex<double>, Eigen::RowMajor>(_mMesh->GetNbrVertex() + _mMesh->GetNbrEdge(), _mDof);
|
|
for (int i = 0; i < _mDof; i++)
|
|
{
|
|
tempTriple.push_back(Eigen::Triplet<complex<double>>(i, i, 1.));
|
|
|
|
}
|
|
_mP_complex.setFromTriplets(tempTriple.begin(), tempTriple.end());
|
|
}
|
|
else
|
|
{
|
|
_mDof = _mMesh->GetNbrVertex() + _mMesh->GetNbrEdge();
|
|
_mP_complex = Eigen::SparseMatrix<complex<double>, Eigen::RowMajor>(_mDof, _mDof);
|
|
_mP_complex.setIdentity();
|
|
}
|
|
}
|
|
}
|
|
if (_mIsReal)
|
|
{
|
|
_mA_real = (_mP_real.transpose() * _mA_real) * _mP_real;
|
|
_mB_real = _mP_real.transpose() * _mB_real;
|
|
}
|
|
else
|
|
{
|
|
_mA_complex = (_mP_complex.adjoint() * _mA_complex) * _mP_complex;
|
|
_mB_complex = _mP_complex.adjoint() * _mB_complex;
|
|
}
|
|
|
|
}
|
|
|
|
void OpticsFEM_2D_Scatter::Run()
|
|
{
|
|
if (_mIsReal)
|
|
{
|
|
_mSolver->GetRealFlag(_mIsReal);
|
|
_mSolver->SetParam(&_mA_real, &_mB_real, &_mP_real);
|
|
}
|
|
else
|
|
{
|
|
_mSolver->GetRealFlag(_mIsReal);
|
|
_mSolver->SetParam(&_mA_complex, &_mB_complex, &_mP_complex);
|
|
}
|
|
_mSolver->Run(&_mX);
|
|
}
|
|
|
|
void OpticsFEM_2D_Scatter::Post(string file)
|
|
{
|
|
_mPost->GetMesh(_mMesh);
|
|
_mPost->GetSolver(_mSolver);
|
|
_mPost->GetPhy(_mPhy);
|
|
_mPost->GetResult(&_mX);
|
|
_mPost->GetElectric();
|
|
_mPost->OutputData(file);
|
|
}
|
|
|
|
/*
|
|
3D_EigenFreq
|
|
*/
|
|
void OpticsFEM_3D_EigenFreq::Assemble()
|
|
{
|
|
_mIsReal = _mMatLib->IsReal();
|
|
if (_mIsReal)
|
|
{
|
|
for (int i = 0; i < _mPhy->GetNbrPBC(); i++)
|
|
{
|
|
if (_mPhy->GetPBCPhi(i).imag()!= 0.0)
|
|
{
|
|
_mIsReal = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
this->Assemble_WaveEquation();
|
|
|
|
if (_mIsReal)
|
|
{
|
|
_mA_real.setFromTriplets(_mTripleA_real.begin(), _mTripleA_real.end());
|
|
_mB_real.setFromTriplets(_mTripleB_real.begin(), _mTripleB_real.end());
|
|
}
|
|
else
|
|
{
|
|
_mA_complex.setFromTriplets(_mTripleA_complex.begin(), _mTripleA_complex.end());
|
|
_mB_complex.setFromTriplets(_mTripleB_complex.begin(), _mTripleB_complex.end());
|
|
}
|
|
|
|
if ((_mPhy->GetNbrPEC() + _mPhy->GetNbrPBC() > 0))
|
|
{
|
|
this->Assemble_PEC_PBC();
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
3D_Scatter - 3D first-order Nedelec scattering (assembly_equ + assembly_out + assembly_inc)
|
|
*/
|
|
void OpticsFEM_3D_Scatter::Assemble()
|
|
{
|
|
_mIsReal = _mMatLib->IsReal();
|
|
if (_mIsReal)
|
|
{
|
|
if (_mPhy->GetNbrPML() > 0)
|
|
_mIsReal = false;
|
|
}
|
|
if (_mIsReal)
|
|
{
|
|
if (_mPhy->GetNbrSBC() > 0)
|
|
_mIsReal = false;
|
|
}
|
|
if (_mIsReal)
|
|
{
|
|
for (int i = 0; i < _mPhy->GetNbrPBC(); i++)
|
|
{
|
|
if (_mPhy->GetPBCPhi(i).imag() != 0.0)
|
|
{
|
|
_mIsReal = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
_mDof = _mMesh->GetNbrEdge();
|
|
|
|
this->Assemble_WaveEquation();
|
|
|
|
if (_mIsReal)
|
|
_mB_real = Eigen::VectorXd::Zero(_mDof);
|
|
else
|
|
_mB_complex = Eigen::VectorXcd::Zero(_mDof);
|
|
|
|
if (_mPhy->GetNbrSBC() > 0)
|
|
this->Assemble_SBC();
|
|
|
|
if (_mIsReal)
|
|
{
|
|
_mA_real = Eigen::SparseMatrix<double, Eigen::RowMajor>(_mDof, _mDof);
|
|
_mA_real.setFromTriplets(_mTripleA_real.begin(), _mTripleA_real.end());
|
|
_mP_real = Eigen::SparseMatrix<double, Eigen::RowMajor>(_mDof, _mDof);
|
|
_mP_real.setIdentity();
|
|
}
|
|
else
|
|
{
|
|
_mA_complex = Eigen::SparseMatrix<std::complex<double>, Eigen::RowMajor>(_mDof, _mDof);
|
|
_mA_complex.setFromTriplets(_mTripleA_complex.begin(), _mTripleA_complex.end());
|
|
_mP_complex = Eigen::SparseMatrix<std::complex<double>, Eigen::RowMajor>(_mDof, _mDof);
|
|
_mP_complex.setIdentity();
|
|
}
|
|
}
|
|
|
|
void OpticsFEM_3D_Scatter::Run()
|
|
{
|
|
if (_mIsReal)
|
|
{
|
|
_mSolver->GetRealFlag(_mIsReal);
|
|
_mSolver->SetParam(&_mA_real, &_mB_real, &_mP_real);
|
|
}
|
|
else
|
|
{
|
|
_mSolver->GetRealFlag(_mIsReal);
|
|
_mSolver->SetParam(&_mA_complex, &_mB_complex, &_mP_complex);
|
|
}
|
|
_mSolver->Run(&_mX);
|
|
|
|
if (!_mIsReal && _mB_complex.size() > 0)
|
|
{
|
|
const double bNorm = _mB_complex.norm();
|
|
const double xNorm = _mX.norm();
|
|
if (bNorm > 0.0 && (!std::isfinite(_mX(0).real()) || xNorm < 1e-12 * bNorm))
|
|
{
|
|
Eigen::SparseLU<Eigen::SparseMatrix<std::complex<double>>> lu;
|
|
lu.compute(_mA_complex);
|
|
if (lu.info() == Eigen::Success)
|
|
_mX = lu.solve(_mB_complex);
|
|
}
|
|
}
|
|
}
|
|
|
|
void OpticsFEM_3D_Scatter::Post(string file)
|
|
{
|
|
_mPost->GetMesh(_mMesh);
|
|
_mPost->GetResult(&_mX);
|
|
_mPost->GetElectric();
|
|
this->Test_OutputMatrix(file);
|
|
_mPost->OutputData(file);
|
|
std::cout << "[OpticsFEM] post to " << file << std::endl;
|
|
}
|
|
|
|
void OpticsFEM_3D_Scatter::Test_OutputMatrix(const std::string& outDir)
|
|
{
|
|
EnsureOutputDir(outDir);
|
|
const std::string prefix = outDir + "/";
|
|
std::ofstream outAi(prefix + "Ai.txt"), outAj(prefix + "Aj.txt"), outAv(prefix + "Av.txt");
|
|
std::ofstream outBv_real(prefix + "Bv_real.txt"), outBv_imag(prefix + "Bv_imag.txt");
|
|
std::ofstream outX_real(prefix + "X_real.txt"), outX_imag(prefix + "X_imag.txt");
|
|
|
|
if (_mIsReal)
|
|
{
|
|
for (int k = 0; k < _mTripleA_real.size(); k++)
|
|
{
|
|
outAi << _mTripleA_real[k].row() << std::endl;
|
|
outAj << _mTripleA_real[k].col() << std::endl;
|
|
outAv << _mTripleA_real[k].value() << std::endl;
|
|
}
|
|
for (int i = 0; i < _mB_real.size(); i++)
|
|
outBv_real << _mB_real(i) << std::endl;
|
|
for (int i = 0; i < _mX.size(); i++)
|
|
outX_real << _mX(i).real() << std::endl;
|
|
}
|
|
else
|
|
{
|
|
for (int k = 0; k < _mTripleA_complex.size(); k++)
|
|
{
|
|
outAi << _mTripleA_complex[k].row() << std::endl;
|
|
outAj << _mTripleA_complex[k].col() << std::endl;
|
|
outAv << _mTripleA_complex[k].value() << std::endl;
|
|
}
|
|
for (int i = 0; i < _mB_complex.size(); i++)
|
|
{
|
|
outBv_real << _mB_complex(i).real() << std::endl;
|
|
outBv_imag << _mB_complex(i).imag() << std::endl;
|
|
}
|
|
for (int i = 0; i < _mX.size(); i++)
|
|
{
|
|
outX_real << _mX(i).real() << std::endl;
|
|
outX_imag << _mX(i).imag() << std::endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
3D_Scatter2
|
|
prism
|
|
*/
|
|
void OpticsFEM_3D_Scatter2::Assemble()
|
|
{
|
|
_mIsReal = _mMatLib->IsReal();
|
|
if (_mIsReal)
|
|
{
|
|
if (_mPhy->GetNbrPML() > 0)
|
|
_mIsReal = false;
|
|
}
|
|
if (_mIsReal)
|
|
{
|
|
if (_mPhy->GetNbrSBC() > 0)
|
|
_mIsReal = false;
|
|
}
|
|
if (_mIsReal)
|
|
{
|
|
/*for (int i = 0; i < _mPhy->GetNbrElE(); i++)
|
|
{
|
|
Eigen::Vector3cd E0;
|
|
_mPhy->GetE0(i, E0);
|
|
for (int j = 0; j < 3; j++)
|
|
{
|
|
if (E0(j).imag() != 0)
|
|
{
|
|
_mIsReal = false;
|
|
}
|
|
}
|
|
}*/
|
|
}
|
|
|
|
this->Assemble_WaveEquation();
|
|
|
|
//SBC
|
|
//this->Assemble_SBC();
|
|
|
|
//Port (n+m)*(n+m)
|
|
//this->Assemble_PortBC();
|
|
|
|
|
|
if (_mIsReal)
|
|
_mA_real.setFromTriplets(_mTripleA_real.begin(), _mTripleA_real.end());
|
|
else
|
|
_mA_complex.setFromTriplets(_mTripleA_complex.begin(), _mTripleA_complex.end());
|
|
|
|
//PEC+ELE
|
|
//this->Assemble_PEC_ELE();
|
|
}
|