#include "../nlohmann/json.hpp" #include"../common/define.h" #include"Solver_Base.h" #include"eigen_solver.h" #include"interface.h" #include #include #include #include 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* A_real, Eigen::SparseMatrix* B_real, Eigen::SparseMatrix* 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, Eigen::RowMajor>* A_complex, Eigen::SparseMatrix, Eigen::RowMajor>* B_complex, Eigen::SparseMatrix, 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* A_complex, * B_complex; int* A_Roffsets, * A_Colindices, * B_Roffsets, * B_Colindices; complex** x_complex, * eigenValues; x_complex = new complex* [_mNbrMode]; for (int i = 0; i < _mNbrMode; i++) { x_complex[i] = new complex[_mParam.A_n]; } eigenValues = new complex[_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* A_real, Eigen::SparseMatrix* B_real, Eigen::SparseMatrix* 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, Eigen::RowMajor>* A_complex, Eigen::SparseMatrix, Eigen::RowMajor>* B_complex, Eigen::SparseMatrix, 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* A_complex, * B_complex; int* A_Roffsets, * A_Colindices, * B_Roffsets, * B_Colindices; complex** x_complex, * eigenValues; x_complex = new complex*[_mNbrMode]; for (int i = 0; i < _mNbrMode; i++) { x_complex[i] = new complex[_mParam.A_n]; } eigenValues = new complex[_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* A_real, Eigen::VectorXd* B_real, Eigen::SparseMatrix* 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, Eigen::RowMajor>* A_complex, Eigen::VectorXcd* B_complex, Eigen::SparseMatrix, 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* A_compl, * b_compl, * x_compl; int* A_Roffsets, * A_Colindices; x_compl = new complex[_mParam.A_n]; //getdata A_compl = _mA_complex->valuePtr(); A_Roffsets = _mA_complex->outerIndexPtr(); A_Colindices = _mA_complex->innerIndexPtr(); b_compl = new complex[_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; } }