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

201 lines
7.3 KiB
C++

#include "eigen_solver.h"
#include <algorithm>
#include <cstdio>
#include <fstream>
static void rfilewrite(const char *name, int *data, int Norf);
static void cfilewrite(const char *name, int *data, int nzero);
static void datafilewrite(const char *name, double *data, int nzero);
EIGENSOLVER_API void complexEigenSolver(int *A_Roffsets, int *A_Cindices, std::complex<double> *A_complex, int *B_Roffsets, int *B_Cindices, std::complex<double> *B_complex, int A_n, int B_n, int A_nzero, int B_nzero, double target_real, double target_imag, int option, int nums, std::complex<double> *eigenValues, std::complex<double> **eigenVectors) {
// 将参数写入文件 canshu.txt
std::ofstream ofs;
ofs.open("./complex_solver/canshu.txt", std::ios::out);
ofs << A_n << std::endl
<< B_n << std::endl
<< target_real << std::endl
<< target_imag << std::endl
<< option << std::endl
<< nums << std::endl;
ofs.close();
// 将complex数据写入double中
double *A_real = new double[A_nzero];
double *A_imag = new double[A_nzero];
for (size_t i = 0; i < A_nzero; ++i) {
A_real[i] = A_complex[i].real();
A_imag[i] = A_complex[i].imag();
}
double *B_real = new double[B_nzero];
double *B_imag = new double[B_nzero];
for (size_t i = 0; i < B_nzero; ++i) {
B_real[i] = B_complex[i].real();
B_imag[i] = B_complex[i].imag();
}
// A
rfilewrite("./complex_solver/A_Roffsets.dat", A_Roffsets, A_n);
cfilewrite("./complex_solver/A_Cindices.dat", A_Cindices, A_nzero);
datafilewrite("./complex_solver/A_real.dat", A_real, A_nzero);
datafilewrite("./complex_solver/A_imag.dat", A_imag, A_nzero);
delete[] A_real;
delete[] A_imag;
// B
rfilewrite("./complex_solver/B_Roffsets.dat", B_Roffsets, B_n);
cfilewrite("./complex_solver/B_Cindices.dat", B_Cindices, B_nzero);
datafilewrite("./complex_solver/B_real.dat", B_real, B_nzero);
datafilewrite("./complex_solver/B_imag.dat", B_imag, B_nzero);
delete[] B_real;
delete[] B_imag;
system("cd ./complex_solver && ./complex");
// 读取特征值文件
double *eigenValues_real = new double[nums];
double *eigenValues_imag = new double[nums];
std::ifstream ifs_EigenValues_real, ifs_EigenValues_imag;
ifs_EigenValues_real.open("./complex_solver/eigenValues_real.txt", std::ios::in);
ifs_EigenValues_imag.open("./complex_solver/eigenValues_imag.txt", std::ios::in);
for (int i = 0; i < nums; i++) {
ifs_EigenValues_real >> eigenValues_real[i];
ifs_EigenValues_imag >> eigenValues_imag[i];
eigenValues[i].real(eigenValues_real[i]);
eigenValues[i].imag(eigenValues_imag[i]);
}
ifs_EigenValues_real.close();
ifs_EigenValues_imag.close();
delete[] eigenValues_real;
delete[] eigenValues_imag;
// 读取特征向量文件
double **eigenVectors_real = new double *[nums];
double **eigenVectors_imag = new double *[nums];
for (size_t i = 0; i < nums; ++i) {
eigenVectors_real[i] = new double[B_n];
eigenVectors_imag[i] = new double[B_n];
}
std::ifstream ifs_EigenVectors_real, ifs_EigenVectors_imag;
ifs_EigenVectors_real.open("./complex_solver/eigenVectors_real.txt", std::ios::in);
ifs_EigenVectors_imag.open("./complex_solver/eigenVectors_imag.txt", std::ios::in);
for (int i = 0; i < nums; i++) {
for (int j = 0; j < B_n; j++) {
ifs_EigenVectors_real >> eigenVectors_real[i][j];
ifs_EigenVectors_imag >> eigenVectors_imag[i][j];
eigenVectors[i][j].real(eigenVectors_real[i][j]);
eigenVectors[i][j].imag(eigenVectors_imag[i][j]);
}
}
ifs_EigenVectors_real.close();
ifs_EigenVectors_imag.close();
for (size_t i = 0; i < nums; ++i) {
delete[] eigenVectors_real[i];
delete[] eigenVectors_imag[i];
}
delete[] eigenVectors_real;
delete[] eigenVectors_imag;
// 清理文件
remove("./complex_solver/A_Roffsets.dat");
remove("./complex_solver/A_Cindices.dat");
remove("./complex_solver/A_real.dat");
remove("./complex_solver/A_imag.dat");
remove("./complex_solver/B_Roffsets.dat");
remove("./complex_solver/B_Cindices.dat");
remove("./complex_solver/B_real.dat");
remove("./complex_solver/B_imag.dat");
remove("./complex_solver/canshu.txt");
remove("./complex_solver/eigenValues_real.txt");
remove("./complex_solver/eigenValues_imag.txt");
remove("./complex_solver/eigenVectors_real.txt");
remove("./complex_solver/eigenVectors_imag.txt");
}
EIGENSOLVER_API void realEigenSolver(int *A_Roffsets, int *A_Cindices, double *A_real, int *B_Roffsets, int *B_Cindices, double *B_real, int A_n, int B_n, int A_nzero, int B_nzero, double target, int option, int nums, double *eigenValues, double **eigenVectors) {
//将参数写入文件 canshu.txt
std::ofstream ofs;
ofs.open("./real_solver/canshu.txt", std::ios::out);
ofs << A_n << std::endl
<< B_n << std::endl
<< target << std::endl
<< option << std::endl
<< nums << std::endl;
ofs.close();
double *d_A_real = new double[A_nzero];
double *d_B_real = new double[B_nzero];
std::transform(A_real, A_real + A_nzero, d_A_real, [](double f) { return static_cast<double>(f); });
std::transform(B_real, B_real + B_nzero, d_B_real, [](double f) { return static_cast<double>(f); });
// A
rfilewrite("./real_solver/A_Roffsets.dat", A_Roffsets, A_n);
cfilewrite("./real_solver/A_Cindices.dat", A_Cindices, A_nzero);
datafilewrite("./real_solver/A_real.dat", d_A_real, A_nzero);
// B
rfilewrite("./real_solver/B_Roffsets.dat", B_Roffsets, B_n);
cfilewrite("./real_solver/B_Cindices.dat", B_Cindices, B_nzero);
datafilewrite("./real_solver/B_real.dat", d_B_real, B_nzero);
system("cd ./real_solver && ./real");
//读取特征值文件
std::ifstream ifs_EigenValues;
ifs_EigenValues.open("./real_solver/eigenValues.txt", std::ios::in);
for (int i = 0; i < nums; i++) {
ifs_EigenValues >> eigenValues[i];
}
ifs_EigenValues.close();
//读取特征向量文件
std::ifstream ifs_EigenVectors;
ifs_EigenVectors.open("./real_solver/eigenVectors.txt", std::ios::in);
for (int i = 0; i < nums; i++) {
for (int j = 0; j < B_n; j++) {
ifs_EigenVectors >> eigenVectors[i][j];
}
}
ifs_EigenVectors.close();
//清理文件
remove("./real_solver/eigenValues.txt");
remove("./real_solver/eigenVectors.txt");
remove("./real_solver/A_Roffsets.dat");
remove("./real_solver/A_Cindices.dat");
remove("./real_solver/A_real.dat");
remove("./real_solver/B_Roffsets.dat");
remove("./real_solver/B_Cindices.dat");
remove("./real_solver/B_real.dat");
remove("./real_solver/canshu.txt");
}
static void rfilewrite(const char *name, int *data, int Norf) {
FILE *fid1;
fid1 = fopen(name, "wb");
fwrite(data, sizeof(int), Norf + 1, fid1);
fclose(fid1);
}
static void cfilewrite(const char *name, int *data, int nzero) {
FILE *fid1;
fid1 = fopen(name, "wb");
fwrite(data, sizeof(int), nzero, fid1);
fclose(fid1);
}
static void datafilewrite(const char *name, double *data, int nzero) {
FILE *fid1;
fid1 = fopen(name, "wb");
fwrite(data, sizeof(double), nzero, fid1);
fclose(fid1);
}