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");//ģʽ<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;
|
||
}
|
||
}
|