432 lines
12 KiB
C++
432 lines
12 KiB
C++
#include "../nlohmann/json.hpp"
|
|
#include"../common/define.h"
|
|
#include"Solver_Base.h"
|
|
#include"eigen_solver.h"
|
|
#include"interface.h"
|
|
|
|
#include <complex>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
|
|
using json = nlohmann::json;
|
|
using namespace std;
|
|
|
|
void Solver_EigenMode::GetSolver(std::string input)
|
|
{
|
|
json temp = nlohmann::json::parse(input);
|
|
_mNbrMode = temp.at("NbrMode");//模式数目
|
|
_mSearchValue = temp.at("searchValue");//搜索值-有效折射率
|
|
_mLda0 = temp.at("lambda0");//真空波长
|
|
_mPreproType = 0;//重排序类型
|
|
}
|
|
|
|
void Solver_EigenMode::GetRealFlag(bool flag)
|
|
{
|
|
_mIsReal = flag;
|
|
}
|
|
|
|
void Solver_EigenMode::SetParam(Eigen::SparseMatrix<double, Eigen::RowMajor>* A_real,
|
|
Eigen::SparseMatrix<double, Eigen::RowMajor>* B_real,
|
|
Eigen::SparseMatrix<double, Eigen::RowMajor>* P_real, double target)
|
|
{
|
|
if (_mIsReal == true)
|
|
{
|
|
_mA_real = A_real;
|
|
_mB_real = B_real;
|
|
_mP_real = P_real;
|
|
_mParam.A_n = _mA_real->rows();
|
|
_mParam.B_n = _mB_real->rows();
|
|
_mParam.A_nzero = _mA_real->nonZeros();
|
|
_mParam.B_nzero = _mB_real->nonZeros();
|
|
_mParam.target = target;
|
|
}
|
|
}
|
|
|
|
void Solver_EigenMode::SetParam(Eigen::SparseMatrix<std::complex<double>, Eigen::RowMajor>* A_complex,
|
|
Eigen::SparseMatrix<std::complex<double>, Eigen::RowMajor>* B_complex,
|
|
Eigen::SparseMatrix<std::complex<double>, Eigen::RowMajor>* P_complex, double target)
|
|
{
|
|
if (_mIsReal == false)
|
|
{
|
|
_mA_complex = A_complex;
|
|
_mB_complex = B_complex;
|
|
_mP_complex = P_complex;
|
|
_mParam.A_n = A_complex->rows();
|
|
_mParam.B_n = B_complex->rows();
|
|
_mParam.A_nzero = A_complex->nonZeros();
|
|
_mParam.B_nzero = B_complex->nonZeros();
|
|
_mParam.target = target;
|
|
}
|
|
}
|
|
|
|
|
|
void Solver_EigenMode::Run(Eigen::MatrixXcd* x, Eigen::VectorXcd* lambda)
|
|
{
|
|
double k0 = 2. * Pi / _mLda0;
|
|
if (_mIsReal == true)
|
|
{
|
|
x[0] = Eigen::MatrixXcd::Zero(_mP_real->rows(), _mNbrMode);
|
|
lambda[0] = Eigen::VectorXcd::Zero(_mNbrMode);
|
|
|
|
//init
|
|
double* A_real, * B_real;
|
|
int* A_Roffsets, * A_Colindices, * B_Roffsets, * B_Colindices;
|
|
double** x_real, * eigenValues;
|
|
x_real = new double* [_mNbrMode];
|
|
for (int i = 0; i < _mNbrMode; i++)
|
|
{
|
|
x_real[i] = new double[_mParam.A_n];
|
|
}
|
|
eigenValues = new double[_mNbrMode];
|
|
//getdata
|
|
A_real = _mA_real->valuePtr();
|
|
B_real = _mB_real->valuePtr();
|
|
A_Colindices = _mA_real->innerIndexPtr();
|
|
A_Roffsets = _mA_real->outerIndexPtr();
|
|
B_Colindices = _mB_real->innerIndexPtr();
|
|
B_Roffsets = _mB_real->outerIndexPtr();
|
|
|
|
realEigenSolver(A_Roffsets, A_Colindices, A_real,B_Roffsets, B_Colindices, B_real,
|
|
_mParam.A_n, _mParam.B_n, _mParam.A_nzero, _mParam.B_nzero, _mParam.target, 0, _mNbrMode,
|
|
eigenValues, x_real);
|
|
|
|
Eigen::MatrixXd tempX(_mParam.A_n, _mNbrMode);
|
|
for (int i = 0; i < _mNbrMode; i++)
|
|
{
|
|
lambda[0](i) = sqrt(-eigenValues[i]) / k0;
|
|
for (int j = 0; j < _mParam.A_n; j++)
|
|
tempX(j, i) = x_real[i][j];
|
|
}
|
|
tempX = _mP_real[0] * tempX;
|
|
|
|
//output
|
|
for (int i = 0; i < _mNbrMode; i++)
|
|
{
|
|
for (int j = 0; j < _mP_real->rows(); j++)
|
|
{
|
|
x[0](j, i) = tempX(j, i);
|
|
}
|
|
}
|
|
|
|
for(int i=0;i<_mNbrMode;i++)
|
|
delete[] x_real[i];
|
|
delete[] x_real,eigenValues;
|
|
}
|
|
else
|
|
{
|
|
x[0] = Eigen::MatrixXcd::Zero(_mP_complex->rows(), _mNbrMode);
|
|
lambda[0] = Eigen::VectorXcd::Zero(_mNbrMode);
|
|
|
|
//init
|
|
complex<double>* A_complex, * B_complex;
|
|
int* A_Roffsets, * A_Colindices, * B_Roffsets, * B_Colindices;
|
|
complex<double>** x_complex, * eigenValues;
|
|
x_complex = new complex<double>* [_mNbrMode];
|
|
for (int i = 0; i < _mNbrMode; i++)
|
|
{
|
|
x_complex[i] = new complex<double>[_mParam.A_n];
|
|
}
|
|
eigenValues = new complex<double>[_mNbrMode];
|
|
//getdata
|
|
A_complex = _mA_complex->valuePtr();
|
|
B_complex = _mB_complex->valuePtr();
|
|
A_Colindices = _mA_complex->innerIndexPtr();
|
|
A_Roffsets = _mA_complex->outerIndexPtr();
|
|
B_Colindices = _mB_complex->innerIndexPtr();
|
|
B_Roffsets = _mB_complex->outerIndexPtr();
|
|
|
|
complexEigenSolver(A_Roffsets, A_Colindices, A_complex, B_Roffsets, B_Colindices, B_complex,
|
|
_mParam.A_n, _mParam.B_n, _mParam.A_nzero, _mParam.B_nzero, _mParam.target,0., 0, _mNbrMode,
|
|
eigenValues, x_complex);
|
|
|
|
Eigen::MatrixXcd tempX(_mParam.A_n, _mNbrMode);
|
|
for (int i = 0; i < _mNbrMode; i++)
|
|
{
|
|
lambda[0](i) = sqrt(-eigenValues[i]) / k0;
|
|
cout << lambda[0](i) << endl;//测试用
|
|
for (int j = 0; j < _mParam.A_n; j++)
|
|
tempX(j, i) = x_complex[i][j];
|
|
}
|
|
tempX = _mP_complex[0] * tempX;
|
|
|
|
//output
|
|
for (int i = 0; i < _mNbrMode; i++)
|
|
{
|
|
for (int j = 0; j < _mP_complex->rows(); j++)
|
|
{
|
|
x[0](j, i) = tempX(j, i);
|
|
}
|
|
}
|
|
|
|
for(int i=0;i<_mNbrMode;i++)
|
|
delete[] x_complex[i];
|
|
delete[] x_complex,eigenValues;
|
|
}
|
|
}
|
|
|
|
void Solver_EigenFreq::GetSolver(std::string input)
|
|
{
|
|
json temp = nlohmann::json::parse(input);
|
|
_mNbrMode = temp.at("NbrMode");//模式数目
|
|
_mSearchValue = temp.at("searchValue");//搜索值-本征频率
|
|
_mPreproType = 0; //重排序类型
|
|
_mElectricType = temp.at("EletricType"); //求解电场类型 0-Et 1-Ez 2-E
|
|
}
|
|
|
|
void Solver_EigenFreq::GetRealFlag(bool flag)
|
|
{
|
|
_mIsReal = flag;
|
|
}
|
|
|
|
void Solver_EigenFreq::SetParam(Eigen::SparseMatrix<double, Eigen::RowMajor>* A_real,
|
|
Eigen::SparseMatrix<double, Eigen::RowMajor>* B_real,
|
|
Eigen::SparseMatrix<double, Eigen::RowMajor>* P_real, double target)
|
|
{
|
|
if (_mIsReal == true)
|
|
{
|
|
_mA_real = A_real;
|
|
_mB_real = B_real;
|
|
_mP_real = P_real;
|
|
_mParam.A_n = _mA_real->rows();
|
|
_mParam.B_n = _mB_real->rows();
|
|
_mParam.A_nzero = _mA_real->nonZeros();
|
|
_mParam.B_nzero = _mB_real->nonZeros();
|
|
_mParam.target = target;
|
|
}
|
|
}
|
|
|
|
void Solver_EigenFreq::SetParam(Eigen::SparseMatrix<std::complex<double>, Eigen::RowMajor>* A_complex,
|
|
Eigen::SparseMatrix<std::complex<double>, Eigen::RowMajor>* B_complex,
|
|
Eigen::SparseMatrix<std::complex<double>, Eigen::RowMajor>* P_complex, double target)
|
|
{
|
|
if (_mIsReal == false)
|
|
{
|
|
_mA_complex = A_complex;
|
|
_mB_complex = B_complex;
|
|
_mP_complex = P_complex;
|
|
_mParam.A_n = A_complex->rows();
|
|
_mParam.B_n = B_complex->rows();
|
|
_mParam.A_nzero = A_complex->nonZeros();
|
|
_mParam.B_nzero = B_complex->nonZeros();
|
|
_mParam.target = target;
|
|
}
|
|
}
|
|
|
|
|
|
void Solver_EigenFreq::Run(Eigen::MatrixXcd* x, Eigen::VectorXcd* lambda)
|
|
{
|
|
if (_mIsReal == true)
|
|
{
|
|
x[0] = Eigen::MatrixXcd::Zero(_mP_real->rows(), _mNbrMode);
|
|
lambda[0] = Eigen::VectorXcd::Zero(_mNbrMode);
|
|
|
|
//init
|
|
double* A_real, * B_real;
|
|
int* A_Roffsets, * A_Colindices, * B_Roffsets, * B_Colindices;
|
|
double** x_real, * eigenValues;
|
|
x_real = new double* [_mNbrMode];
|
|
for (int i = 0; i < _mNbrMode; i++)
|
|
{
|
|
x_real[i] = new double[_mParam.A_n];
|
|
}
|
|
eigenValues = new double[_mNbrMode];
|
|
//getdata
|
|
A_real = _mA_real->valuePtr();
|
|
B_real = _mB_real->valuePtr();
|
|
A_Colindices = _mA_real->innerIndexPtr();
|
|
A_Roffsets = _mA_real->outerIndexPtr();
|
|
B_Colindices = _mB_real->innerIndexPtr();
|
|
B_Roffsets = _mB_real->outerIndexPtr();
|
|
|
|
realEigenSolver(A_Roffsets, A_Colindices, A_real, B_Roffsets, B_Colindices, B_real,
|
|
_mParam.A_n, _mParam.B_n, _mParam.A_nzero, _mParam.B_nzero, _mParam.target, 0, _mNbrMode,
|
|
eigenValues, x_real);
|
|
|
|
Eigen::MatrixXd tempX(_mParam.A_n, _mNbrMode);
|
|
for (int i = 0; i < _mNbrMode; i++)
|
|
{
|
|
lambda[0](i) = c_const / (2. * Pi / sqrt(eigenValues[i]));
|
|
for (int j = 0; j < _mParam.A_n; j++)
|
|
tempX(j, i) = x_real[i][j];
|
|
}
|
|
tempX = _mP_real[0] * tempX;
|
|
|
|
//output
|
|
for (int i = 0; i < _mNbrMode; i++)
|
|
{
|
|
for (int j = 0; j < _mP_real->rows(); j++)
|
|
{
|
|
x[0](j, i) = tempX(j, i);
|
|
}
|
|
}
|
|
|
|
for(int i=0;i<_mNbrMode;i++)
|
|
delete[] x_real[i];
|
|
delete[] x_real,eigenValues;
|
|
}
|
|
else
|
|
{
|
|
x[0] = Eigen::MatrixXcd::Zero(_mP_complex->rows(), _mNbrMode);
|
|
lambda[0] = Eigen::VectorXcd::Zero(_mNbrMode);
|
|
|
|
//init
|
|
complex<double>* A_complex, * B_complex;
|
|
int* A_Roffsets, * A_Colindices, * B_Roffsets, * B_Colindices;
|
|
complex<double>** x_complex, * eigenValues;
|
|
x_complex = new complex<double>*[_mNbrMode];
|
|
for (int i = 0; i < _mNbrMode; i++)
|
|
{
|
|
x_complex[i] = new complex<double>[_mParam.A_n];
|
|
}
|
|
eigenValues = new complex<double>[_mNbrMode];
|
|
//getdata
|
|
A_complex = _mA_complex->valuePtr();
|
|
B_complex = _mB_complex->valuePtr();
|
|
A_Colindices = _mA_complex->innerIndexPtr();
|
|
A_Roffsets = _mA_complex->outerIndexPtr();
|
|
B_Colindices = _mB_complex->innerIndexPtr();
|
|
B_Roffsets = _mB_complex->outerIndexPtr();
|
|
|
|
complexEigenSolver(A_Roffsets, A_Colindices, A_complex, B_Roffsets, B_Colindices, B_complex,
|
|
_mParam.A_n, _mParam.B_n, _mParam.A_nzero, _mParam.B_nzero, _mParam.target, 0., 0, _mNbrMode,
|
|
eigenValues, x_complex);
|
|
|
|
Eigen::MatrixXcd tempX(_mParam.A_n, _mNbrMode);
|
|
for (int i = 0; i < _mNbrMode; i++)
|
|
{
|
|
lambda[0](i) = c_const / (2. * Pi / sqrt(eigenValues[i]));
|
|
for (int j = 0; j < _mParam.A_n; j++)
|
|
tempX(j, i) = x_complex[i][j];
|
|
}
|
|
tempX = _mP_complex[0] * tempX;
|
|
|
|
//output
|
|
for (int i = 0; i < _mNbrMode; i++)
|
|
{
|
|
for (int j = 0; j < _mP_complex->rows(); j++)
|
|
{
|
|
x[0](j, i) = tempX(j, i);
|
|
}
|
|
}
|
|
|
|
for(int i=0;i<_mNbrMode;i++)
|
|
delete[] x_complex[i];
|
|
delete[] x_complex,eigenValues;
|
|
}
|
|
}
|
|
|
|
void Solver_LdaDom::GetSolver(std::string input)
|
|
{
|
|
json temp = nlohmann::json::parse(input);
|
|
_mLda0 = temp.at("lambda");//真空波长
|
|
_mElectricType = temp.at("EletricType");//求解电场类型 0-Et 1-Ez 2-E
|
|
}
|
|
|
|
void Solver_LdaDom::GetSolver2(std::string input)
|
|
{
|
|
json temp = nlohmann::json::parse(input);
|
|
_mLda0 = 0.299792458/(double)temp.at("freq");//真空波长
|
|
_mElectricType = temp.at("EletricType");//求解电场类型 0-Et 1-Ez 2-E
|
|
}
|
|
|
|
|
|
void Solver_LdaDom::GetRealFlag(bool flag)
|
|
{
|
|
_mIsReal = flag;
|
|
}
|
|
|
|
void Solver_LdaDom::SetParam(Eigen::SparseMatrix<double, Eigen::RowMajor>* A_real,
|
|
Eigen::VectorXd* B_real, Eigen::SparseMatrix<double, Eigen::RowMajor>* P_real)
|
|
{
|
|
if (_mIsReal == true)
|
|
{
|
|
_mA_real = A_real;
|
|
_mB_real = B_real;
|
|
_mP_real = P_real;
|
|
_mParam.A_n = _mA_real->rows();
|
|
_mParam.A_nzero = _mA_real->nonZeros();
|
|
}
|
|
}
|
|
|
|
void Solver_LdaDom::SetParam(Eigen::SparseMatrix<std::complex<double>, Eigen::RowMajor>* A_complex,
|
|
Eigen::VectorXcd* B_complex, Eigen::SparseMatrix<std::complex<double>, Eigen::RowMajor>* P_complex)
|
|
{
|
|
if (_mIsReal == false)
|
|
{
|
|
_mA_complex = A_complex;
|
|
_mB_complex = B_complex;
|
|
_mP_complex = P_complex;
|
|
_mParam.A_n = A_complex->rows();
|
|
_mParam.A_nzero = A_complex->nonZeros();
|
|
}
|
|
}
|
|
|
|
void Solver_LdaDom::Run(Eigen::VectorXcd* x)
|
|
{
|
|
if (_mIsReal == true)
|
|
{
|
|
x[0] = Eigen::VectorXcd::Zero(_mP_real->rows());
|
|
//init
|
|
double* A_real, * b_real, * x_real;
|
|
int* A_Roffsets, * A_Colindices;
|
|
x_real = new double[_mParam.A_n];
|
|
//getdata
|
|
A_real = _mA_real->valuePtr();
|
|
A_Roffsets = _mA_real->outerIndexPtr();
|
|
A_Colindices = _mA_real->innerIndexPtr();
|
|
b_real = new double[_mParam.A_n];
|
|
for (int i = 0; i < _mParam.A_n; i++)
|
|
b_real[i] = _mB_real[0](i);
|
|
|
|
double para[6] = { 0.0, 0, 1e-3, 2.0456e+08 * 1e-3, 0, -1 };
|
|
|
|
solveRealLinearEqu(A_Roffsets, A_Colindices, A_real, b_real, x_real, _mParam.A_n, _mParam.A_nzero, para);
|
|
|
|
Eigen::VectorXd temp(_mParam.A_n);
|
|
for(int i=0;i<_mParam.A_n;i++)
|
|
{
|
|
temp(i)=x_real[i];
|
|
}
|
|
temp=_mP_real[0]*temp;
|
|
for(int i=0;i<_mP_real->rows();i++)
|
|
{
|
|
x[0](i)=temp(i);
|
|
}
|
|
this->Test_OutputX(x);
|
|
delete[] x_real;
|
|
}
|
|
else
|
|
{
|
|
x[0] = Eigen::VectorXcd::Zero(_mP_complex->rows());
|
|
//init
|
|
complex<double>* A_compl, * b_compl, * x_compl;
|
|
int* A_Roffsets, * A_Colindices;
|
|
x_compl = new complex<double>[_mParam.A_n];
|
|
//getdata
|
|
A_compl = _mA_complex->valuePtr();
|
|
A_Roffsets = _mA_complex->outerIndexPtr();
|
|
A_Colindices = _mA_complex->innerIndexPtr();
|
|
b_compl = new complex<double>[_mParam.A_n];
|
|
for (int i = 0; i < _mParam.A_n; i++)
|
|
b_compl[i] = _mB_complex[0](i);
|
|
|
|
|
|
double para[6] = { 0.0, 0, 1e-3, 2.0456e+08 * 1e-3, 0, -1 };
|
|
solveComplexLinearEqu(A_Roffsets, A_Colindices, A_compl, b_compl, x_compl, _mParam.A_n, _mParam.A_nzero, para);
|
|
|
|
Eigen::VectorXcd temp(_mParam.A_n);
|
|
for(int i=0;i<_mParam.A_n;i++)
|
|
{
|
|
temp(i)=x_compl[i];
|
|
}
|
|
temp=_mP_complex[0]*temp;
|
|
for(int i=0;i<_mP_complex->rows();i++)
|
|
{
|
|
x[0](i)=temp(i);
|
|
}
|
|
|
|
delete[] x_compl;
|
|
}
|
|
}
|