535 lines
14 KiB
C++
535 lines
14 KiB
C++
// 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;
|
||
}
|
||
} |