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

535 lines
14 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.

// pch.cpp: 与预编译标头对应的源文件
#include "interface.h"
#define ROFFSETS 0
#define CINDICES 1
#define A_ROW 2
#define A_COL 3
#define A_REAL 4
#define A_IMAG 5
#define B_REAL 6
#define B_IMAG 7
#define OPT 8
void cootocsr_complex(int* coo_row, int* coo_col, double* coo_valr, double* coo_vali,
int nnz, int rows, int cols, int* csr_rof, int* csr_cin, double* csr_valr, double* csr_vali);
void cootocsr(int* coo_row, int* coo_col, double* coo_val,
int nnz, int rows, int cols, int* csr_rof, int* csr_cin, double* csr_val);
#define GET_ARRAY_LEN(array,len){len = _msize(array) / sizeof(*array);}
int WriteFile(double* data, int filetype, int numsize);
int WriteIntFile(int* data, int filetype, int numsize);
int ReadFile(double** data, char* name);
void DelFile(int filetype);
void DelNameFile(char* name);
// 当使用预编译的头时,需要使用此源文件,编译才能成功。
int solveRealLinearEqu(int* Roffsets, int* Cindices,
double* A_real, double* b_real, double* x_real,
int NbrDof, int Nzero ,double* para)
{
/*opt:
0矩阵维度 1预估数 2对称性 3 相对误差
4绝对误差 5重启次数 6预处理1 7迭代1
8预处理2 9迭代2 10预处理3 11迭代3
*/
char model_name[40];
int len;
double opt[12];
opt[0] = (double)NbrDof;
opt[1] = para[0]; //预估数
opt[2] = para[1]; //对称性
opt[3] = para[2]; //相对误差
opt[4] = para[3]; //绝对误差
opt[5] = 30;
if (para[5] == -1) // 模型编号
{
opt[6] = -1;
opt[7] = -1;
opt[8] = -1;
opt[9] = -1;
opt[10] = -1;
opt[11] = -1;
}
else
{
char model_name[50] = "./model_data/";
char str[30];
sprintf(str, "%d", (int)para[5]);
strcat(model_name, str);
strcat(model_name, ".txt");
FILE* fp1 = fopen(model_name, "r"); //以data.txt文件为例
int j = 0;
fscanf(fp1, "%s\n", &model_name);
while (!feof(fp1)) //feof检测一个文件是否结束即到达文件尾若结束则返回非0值否则返回0
{
fscanf(fp1, "%s\n", &str);
opt[6 + j] = atoi(str);
j++;
if (j == 6)break;
}
fclose(fp1);
}
GET_ARRAY_LEN(Roffsets, len);
WriteIntFile(Roffsets, ROFFSETS, len);
WriteFile(b_real, B_REAL, len - 1);
//printf("mat norf:%d\n", len);
GET_ARRAY_LEN(Cindices, len);
WriteIntFile(Cindices, CINDICES, len);
WriteFile(A_real, A_REAL, len);
WriteFile(opt, OPT, 12);
//printf("mat nzero:%d\n", len);
if (para[4] == 0) //并行数量
system(".\\real\\realsolver.exe");
else if (para[4] == -1)
{
SYSTEM_INFO info;
GetSystemInfo(&info);
para[4] = (info.dwNumberOfProcessors / 2) - 2;
char s_path[60] = ".\\mpi\\mpiexec.exe -n ";
char str[3];
sprintf(str, "%d", (int)para[4]);
strcat(s_path, str);
strcat(s_path, " .\\real\\realsolver.exe");
system(s_path);
}
else
{
char s_path[60] = ".\\mpi\\mpiexec.exe -n ";
char str[3];
sprintf(str, "%d", (int)para[4]);
strcat(s_path, str);
strcat(s_path, " .\\real\\realsolver.exe");
system(s_path);
}
double* x;
int idex = 0, sum = 0;
int mnum;
if (para[4] == 0)mnum = 1;
else mnum = para[4];
for (int i = 0; i < mnum; i++)
{
char name[20] = "x_real_";
char str[5] = { 0 };
sprintf(str, "%d", i);
strcat(name, str);
strcat(name, ".dat");
idex = ReadFile(&x, name);
for (int j = 0; j < idex; j++)
{
x_real[sum++] = x[j];
}
DelNameFile(name);
}
DelFile(ROFFSETS);
DelFile(CINDICES);
DelFile(A_REAL);
DelFile(B_REAL);
DelFile(OPT);
system("del res.dat");
system("del log.dat");
return 0;
}
int solveRealLinearEqu_COO(int* A_i, int* A_j,
double* A_real, double* b_real, double* x_real,
int NbrDof, int Nzero, double* para)
{
int len;
GET_ARRAY_LEN(A_real, len);
int* Roffsets = (int*)malloc(sizeof(int) * (NbrDof + 1));
int* Cindices = (int*)malloc(sizeof(int) * (len));
double* A_real_csr = (double*)malloc(sizeof(double) * (len));
cootocsr(A_i, A_j, A_real, len, NbrDof, NbrDof, Roffsets, Cindices, A_real_csr);
solveRealLinearEqu(Roffsets, Cindices, A_real_csr, b_real, x_real, NbrDof, Nzero, para);
return 0;
}
int solveComplexLinearEqu(int* Roffsets, int* Cindices,
std::complex<double>* A_complex, std::complex<double>* b_complex, std::complex<double>* x_complex,
int NbrDof, int Nzero, double* para)
{
/*opt:
0矩阵维度 1预估数 2对称性 3 相对误差
4绝对误差 5重启次数 6预处理1 7迭代1
8预处理2 9迭代2 10预处理3 11迭代3
*/
char model_name[40];
int len;
double opt[12];
opt[0] = (double)NbrDof;
opt[1] = para[0]; //预估数
opt[2] = para[1]; //对称性
opt[3] = para[2]; //相对误差
opt[4] = para[3]; //绝对误差
opt[5] = 30;
if (para[5] == -1) // 模型编号
{
opt[6] = -1;
opt[7] = -1;
opt[8] = -1;
opt[9] = -1;
opt[10] = -1;
opt[11] = -1;
}
else
{
char model_name[50] = "./model_data/";
char str[30];
sprintf(str, "%d", (int)para[5]);
strcat(model_name, str);
strcat(model_name, ".txt");
FILE* fp1 = fopen(model_name, "r"); //以data.txt文件为例
int j = 0;
fscanf(fp1, "%s\n", &model_name);
while (!feof(fp1)) //feof检测一个文件是否结束即到达文件尾若结束则返回非0值否则返回0
{
fscanf(fp1, "%s\n", &str);
opt[6+j] = atoi(str);
j++;
if (j == 6)break;
}
fclose(fp1);
}
// 将complex数据写入double中
double* A_real = new double[Nzero];
double* A_imag = new double[Nzero];
for (int i = 0; i < Nzero; ++i) {
A_real[i] = A_complex[i].real();
A_imag[i] = A_complex[i].imag();
}
double* b_real = new double[NbrDof];
double* b_imag = new double[NbrDof];
for (size_t i = 0; i < NbrDof; ++i) {
b_real[i] = b_complex[i].real();
b_imag[i] = b_complex[i].imag();
}
double* x_real = new double[NbrDof];
double* x_imag = new double[NbrDof];
GET_ARRAY_LEN(Roffsets, len);
WriteIntFile(Roffsets, ROFFSETS, len);
WriteFile(b_real, B_REAL, len - 1);
WriteFile(b_imag, B_IMAG, len - 1);
//printf("mat norf:%d\n", len);
GET_ARRAY_LEN(Cindices, len);
WriteIntFile(Cindices, CINDICES, len);
WriteFile(A_real, A_REAL, len);
WriteFile(A_imag, A_IMAG, len);
WriteFile(opt, OPT, 12);
//printf("mat nzero:%d\n", len);
if (para[4] == 0)
system(".\\complex\\complexsolver.exe");
else if (para[4] == -1)
{
SYSTEM_INFO info;
GetSystemInfo(&info);
para[4] = (info.dwNumberOfProcessors / 2) - 2;
char s_path[60] = ".\\mpi\\mpiexec.exe -n ";
char str[3];
sprintf(str, "%d", (int)para[4]);
strcat(s_path, str);
strcat(s_path, " .\\complex\\complexsolver.exe");
system(s_path);
}
else
{
char s_path[60] = ".\\mpi\\mpiexec.exe -n ";
char str[3];
sprintf(str, "%d", (int)para[4]);
strcat(s_path, str);
strcat(s_path, " .\\complex\\complexsolver.exe");
system(s_path);
}
double* a_real;
double* a_complex;
int idex = 0, realsum = 0, imagsum = 0;
int mnum;
if (para[4] == 0)mnum = 1;
else mnum = para[4];
for (int i = 0; i < mnum; i++)
{
char realname[20] = "x_real_";
char complexname[20] = "x_complex_";
char str[5] = { 0 };
sprintf(str, "%d", i);
strcat(realname, str);
strcat(complexname, str);
strcat(realname, ".dat");
strcat(complexname, ".dat");
idex = ReadFile(&a_real, realname);
for (int j = 0; j < idex; j++)
{
x_real[realsum++] = a_real[j];
}
idex = ReadFile(&a_complex, complexname);
for (int j = 0; j < idex; j++)
{
x_imag[imagsum++] = a_complex[j];
}
DelNameFile(realname);
DelNameFile(complexname);
}
for (int i = 0; i < NbrDof; i++)
{
x_complex[i].real(x_real[i]);
x_complex[i].imag(x_imag[i]);
}
DelFile(ROFFSETS);
DelFile(CINDICES);
DelFile(A_REAL);
DelFile(A_IMAG);
DelFile(B_REAL);
DelFile(B_IMAG);
DelFile(OPT);
system("del res.dat");
system("del log.dat");
return 0;
}
int solveComplexLinearEqu_COO(int* A_i, int* A_j,
double* A_real, double* A_imag, double* b_real, double* b_imag, double* x_real, double* x_imag,
int NbrDof, double* para)
{
int len;
GET_ARRAY_LEN(A_real, len);
int* Roffsets = (int*)malloc(sizeof(int)* (NbrDof+1));
int* Cindices = (int*)malloc(sizeof(int) * (len));
double* A_real_csr = (double*)malloc(sizeof(double) * (len));
double* A_imag_csr = (double*)malloc(sizeof(double) * (len));
cootocsr_complex(A_i, A_j, A_real, A_imag,len, NbrDof, NbrDof, Roffsets, Cindices, A_real_csr, A_imag_csr);
//solveComplexLinearEqu(Roffsets, Cindices, A_real_csr, A_imag_csr, b_real, b_imag, x_real, x_imag, NbrDof, para);
return 0;
}
int MumpsSolver_COO(int* A_i, int* A_j,
double* A_real, double* A_imag, double* b_real, double* b_imag, double* x_real, double* x_imag,
int NbrDof, int NNZ)
{
int opt[2];
opt[0] = NbrDof;
opt[1] = NNZ; //非零元总数
WriteIntFile(A_i, A_ROW, NNZ);
WriteIntFile(A_j, A_COL, NNZ);
WriteFile(A_real, A_REAL, NNZ);
WriteFile(A_imag, A_IMAG, NNZ);
WriteFile(b_real, B_REAL, NbrDof);
WriteFile(b_imag, B_IMAG, NbrDof);
WriteIntFile(opt, OPT, 2);
system(".\\mumps\\mumpssolver.exe");
double* a_real;
double* a_complex;
int idex = 0, realsum = 0, imagsum = 0;
int mnum = 1;
for (int i = 0; i < mnum; i++)
{
char realname[20] = "x_real_";
char complexname[20] = "x_complex_";
char str[5] = { 0 };
sprintf(str, "%d", i);
strcat(realname, str);
strcat(complexname, str);
strcat(realname, ".dat");
strcat(complexname, ".dat");
idex = ReadFile(&a_real, realname);
for (int j = 0; j < idex; j++)
{
x_real[realsum++] = a_real[j];
}
idex = ReadFile(&a_complex, complexname);
for (int j = 0; j < idex; j++)
{
x_imag[imagsum++] = a_complex[j];
}
DelNameFile(realname);
DelNameFile(complexname);
}
DelFile(A_ROW);
DelFile(A_COL);
DelFile(A_REAL);
DelFile(A_IMAG);
DelFile(B_REAL);
DelFile(B_IMAG);
DelFile(OPT);
return 0;
}
const char* Interfacefilename[11] = { "Roffsets.dat", "Cindices.dat","A_row.dat", "A_col.dat", "A_real.dat","A_imag.dat", "B_real.dat", "B_imag.dat" ,"opt.dat","x_real_","x_complex_"};
int WriteFile(double* data, int filetype, int numsize)
{
/*写出数据*/
FILE* fid;
fid = fopen(Interfacefilename[filetype], "wb");
if (fid == NULL)
{
printf("写出文件出错");
return 0;
}
fwrite(data, sizeof(double), numsize, fid);
fclose(fid);
return 0;
}
int WriteIntFile(int* data, int filetype, int numsize)
{
/*写出数据*/
FILE* fid;
fid = fopen(Interfacefilename[filetype], "wb");
if (fid == NULL)
{
printf("写出文件出错");
return 0;
}
fwrite(data, sizeof(int), numsize, fid);
fclose(fid);
return 0;
}
int ReadFile(double** data, char* name)
{
FILE* fid;
fid = fopen(name, "rb");
if (fid == NULL)
{
printf("读取文件出错");
return -1;
}
//获取文件大小
fseek(fid, 0, SEEK_END);
long lSize = ftell(fid);
rewind(fid);
//开辟存储空间
int num = lSize / sizeof(double);
*data = (double*)malloc(sizeof(double) * num);
if (*data == NULL)
{
printf("开辟空间出错");
return -1;
}
fread(*data, sizeof(double), num, fid);
//printf("%d\n", num);
fclose(fid);
return num;
}
void DelFile(int filetype)
{
struct stat buffer;
if (stat(Interfacefilename[filetype], &buffer) == 0)
{
char path1[40] = "del ";
strcat(path1, Interfacefilename[filetype]);
system(path1);
}
}
void DelNameFile(char* name)
{
struct stat buffer;
if (stat(name, &buffer) == 0)
{
char path1[40] = "del ";
strcat(path1, name);
system(path1);
}
}
void cootocsr_complex(int* coo_row, int* coo_col, double* coo_valr, double* coo_vali,
int nnz, int rows, int cols, int* csr_rof, int* csr_cin, double* csr_valr, double* csr_vali)
{
memset(csr_rof, 0, (rows) * sizeof(int));
for (int i = 0; i < nnz; i++)
{
csr_rof[coo_row[i]]++;
}
for (int i = 0, cumsum = 0; i < rows; i++) {
int temp = csr_rof[i];
csr_rof[i] = cumsum;
cumsum += temp;
}
csr_rof[rows] = nnz;
for (int n = 0; n < nnz; n++) {
int row = coo_row[n];
int dest = csr_rof[row];
csr_cin[dest] = coo_col[n];
csr_valr[dest] = coo_valr[n];
csr_vali[dest] = coo_vali[n];
csr_rof[row]++;
}
for (int i = 0, last = 0; i <= rows; i++) {
int temp = csr_rof[i];
csr_rof[i] = last;
last = temp;
}
}
void cootocsr(int* coo_row, int* coo_col, double* coo_val,
int nnz, int rows, int cols, int* csr_rof, int* csr_cin, double* csr_val)
{
memset(csr_rof, 0, (rows) * sizeof(int));
for (int i = 0; i < nnz; i++)
{
csr_rof[coo_row[i]]++;
}
for (int i = 0, cumsum = 0; i < rows; i++) {
int temp = csr_rof[i];
csr_rof[i] = cumsum;
cumsum += temp;
}
csr_rof[rows] = nnz;
for (int n = 0; n < nnz; n++) {
int row = coo_row[n];
int dest = csr_rof[row];
csr_cin[dest] = coo_col[n];
csr_val[dest] = coo_val[n];
csr_rof[row]++;
}
for (int i = 0, last = 0; i <= rows; i++) {
int temp = csr_rof[i];
csr_rof[i] = last;
last = temp;
}
}