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

432 lines
12 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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");//ģʽ<C4A3><CABD>Ŀ
_mSearchValue = temp.at("searchValue");//<2F><><EFBFBD><EFBFBD>ֵ-<2D><>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
_mLda0 = temp.at("lambda0");//<2F><>ղ<EFBFBD><D5B2><EFBFBD>
_mPreproType = 0;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
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;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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");//ģʽ<C4A3><CABD>Ŀ
_mSearchValue = temp.at("searchValue");//<2F><><EFBFBD><EFBFBD>ֵ-<2D><><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5>
_mPreproType = 0; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
_mElectricType = temp.at("EletricType"); //<2F><><EFBFBD><EFBFBD><E7B3A1><EFBFBD><EFBFBD> 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");//<2F><>ղ<EFBFBD><D5B2><EFBFBD>
_mElectricType = temp.at("EletricType");//<2F><><EFBFBD><EFBFBD><E7B3A1><EFBFBD><EFBFBD> 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");//<2F><>ղ<EFBFBD><D5B2><EFBFBD>
_mElectricType = temp.at("EletricType");//<2F><><EFBFBD><EFBFBD><E7B3A1><EFBFBD><EFBFBD> 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;
}
}