XIAN-FEM-2026June/opticsfem-master/solver/Solver_Interface.cpp

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;
}
}