OpenCAEPoro  v0.5.0
A simulator for multicomponent porous media flow
LinearSystem.cpp
Go to the documentation of this file.
1 
11 #include "LinearSystem.hpp"
12 
13 void LinearSystem::AllocateRowMem(const OCP_USI& dimMax, const USI& nb)
14 {
15  blockSize = nb * nb;
16  blockDim = nb;
17  dim = 0;
18  maxDim = dimMax;
19  rowCapacity.resize(maxDim);
20  colId.resize(maxDim);
21  val.resize(maxDim);
22  b.resize(maxDim * blockDim);
23  u.resize(maxDim * blockDim);
24 }
25 
26 void LinearSystem::AllocateColMem(const vector<USI>& bulk2bulk,
27  const vector<vector<OCP_USI>> well2bulk)
28 {
29  // Bulk to Bulk
30  const OCP_USI bulkNum = bulk2bulk.size();
31  for (OCP_USI n = 0; n < bulkNum; n++) {
32  rowCapacity[n] = bulk2bulk[n];
33  }
34 
35  // Bulk to Well
36  const OCP_USI wellNum = well2bulk.size();
37  USI maxPerfNum = 0;
38  for (auto& w : well2bulk) {
39  for (auto& p : w) rowCapacity[p]++;
40  if (maxPerfNum < w.size()) {
41  maxPerfNum = w.size();
42  }
43  }
44 
45  // If Reinjection is considered, then more memory is needed
46  // Well to Bulk
47  for (OCP_USI w = bulkNum; w < bulkNum + wellNum; w++) {
48  rowCapacity[w] += (maxPerfNum + 1);
49  }
50 
51  for (OCP_USI n = 0; n < maxDim; n++) {
52  colId[n].reserve(rowCapacity[n]);
53  val[n].reserve(rowCapacity[n] * blockSize);
54  }
55 }
56 
58 {
59  for (OCP_USI i = 0; i < maxDim; i++) {
60  colId[i].clear(); // actually, only parts of bulks needs to be clear
61  val[i].clear();
62  }
63  // diagPtr.assign(maxDim, 0);
64  fill(b.begin(), b.end(), 0.0);
65  dim = 0;
66  // In fact, for linear system the current solution is a good initial solution for
67  // next step, so u will not be set to zero. u.assign(maxDim, 0);
68 }
69 
70 void LinearSystem::AssembleRhsAccumulate(const vector<OCP_DBL>& rhs)
71 {
72  OCP_USI nrow = dim * blockDim;
73  for (OCP_USI i = 0; i < nrow; i++) {
74  b[i] += rhs[i];
75  }
76 }
77 
78 void LinearSystem::AssembleRhsCopy(const vector<OCP_DBL>& rhs)
79 {
80  Dcopy(dim * blockDim, &b[0], &rhs[0]);
81 }
82 
83 void LinearSystem::OutputLinearSystem(const string& fileA, const string& fileb) const
84 {
85  string FileA = solveDir + fileA;
86  string Fileb = solveDir + fileb;
87 
88  // out A
89  // csr or bsr
90  ofstream outA(FileA);
91  if (!outA.is_open()) cout << "Can not open " << FileA << endl;
92  outA << dim << "\n";
93  if (blockDim != 1) {
94  outA << blockDim << "\n";
95  }
96  // IA
97  OCP_USI rowId = 1;
98  for (OCP_USI i = 0; i < dim; i++) {
99  outA << rowId << "\n";
100  rowId += colId[i].size();
101  }
102  outA << rowId << "\n";
103  // JA
104  USI rowSize = 0;
105  for (OCP_USI i = 0; i < dim; i++) {
106  rowSize = colId[i].size();
107  for (USI j = 0; j < rowSize; j++) {
108  outA << colId[i][j] + 1 << "\n";
109  }
110  }
111  // val
112  for (OCP_USI i = 0; i < dim; i++) {
113  rowSize = val[i].size();
114  for (USI j = 0; j < rowSize; j++) {
115  outA << val[i][j] << "\n";
116  }
117  }
118  outA.close();
119 
120  // out b
121  OCP_USI nRow = dim * blockDim;
122  ofstream outb(Fileb);
123  if (!outb.is_open()) cout << "Can not open " << Fileb << endl;
124  outb << dim << "\n";
125  for (OCP_USI i = 0; i < nRow; i++) {
126  outb << b[i] << "\n";
127  }
128 }
129 
130 void LinearSystem::OutputSolution(const string& fileU) const
131 {
132  string FileU = solveDir + fileU;
133  ofstream outu(FileU);
134  if (!outu.is_open()) cout << "Can not open " << FileU << endl;
135  outu << dim << "\n";
136  OCP_USI nrow = dim * blockDim;
137  for (OCP_USI i = 0; i < nrow; i++) outu << u[i] << "\n";
138  outu.close();
139 }
140 
142 {
143  // check A
144  for (OCP_USI n = 0; n < dim; n++) {
145  for (auto v : val[n]) {
146  if (!isfinite(v)) {
147  OCP_ABORT("NAN or INF in MAT");
148  }
149  }
150  }
151  // check b
152  OCP_USI len = dim * blockDim;
153  for (OCP_USI n = 0; n < len; n++) {
154  if (!isfinite(b[n])) {
155  OCP_ABORT("NAN or INF in rhs");
156  }
157  }
158 }
159 
161 {
162  OCP_USI len = dim * blockDim;
163  for (OCP_USI n = 0; n < len; n++) {
164  if (!isfinite(u[n])) {
165  OCP_ABORT("NAN or INF in u");
166  }
167  }
168 }
169 
172  const string& dir,
173  const string& file)
174 {
175  solveDir = dir;
176  switch (i) {
177  case SCALARFASP:
178  // Fasp
179  LS = new ScalarFaspSolver;
180  break;
181  case VECTORFASP:
182  // Blcok Fasp
183  LS = new VectorFaspSolver;
184  break;
185  default:
186  OCP_ABORT("Wrong Linear Solver type!");
187  break;
188  }
189  LS->SetupParam(dir, file);
190  LS->Allocate(rowCapacity, maxDim, blockDim);
191 }
192 
193 /*----------------------------------------------------------------------------*/
194 /* Brief Change History of This File */
195 /*----------------------------------------------------------------------------*/
196 /* Author Date Actions */
197 /*----------------------------------------------------------------------------*/
198 /* Shizhe Li Oct/01/2021 Create file */
199 /* Shizhe Li Nov/22/2021 renamed to LinearSystem */
200 /*----------------------------------------------------------------------------*/
void Dcopy(const int &N, double *dst, const double *src)
Calculate the minimal eigenvalue for symmetric matrix with mkl lapack.
Definition: DenseMat.cpp:36
Linear solver class declaration.
const USI VECTORFASP
Use vector linear solver in Fasp.
Definition: OCPConst.hpp:88
unsigned int USI
Generic unsigned integer.
Definition: OCPConst.hpp:23
unsigned int OCP_USI
Long unsigned integer.
Definition: OCPConst.hpp:25
const USI SCALARFASP
Use scalar linear solver in Fasp.
Definition: OCPConst.hpp:87
#define OCP_ABORT(msg)
Abort if critical error happens.
Definition: UtilError.hpp:47
virtual void Allocate(const vector< USI > &rowCapacity, const OCP_USI &maxDim, const USI &blockDim)=0
Allocate maximum memory for linear solvers.
virtual void SetupParam(const string &dir, const string &file)=0
Read the params for linear solvers from an input file.
void OutputLinearSystem(const string &fileA, const string &fileb) const
Output the mat and rhs to fileA and fileb. // TODO: output to some obj?
void AllocateColMem(const vector< USI > &bulk2bulk, const vector< vector< OCP_USI >> well2bulk)
Allocate memory for linear system with max possible number of columns.
void AssembleRhsCopy(const vector< OCP_DBL > &rhs)
Assign Rhs by Copying.
void AssembleRhsAccumulate(const vector< OCP_DBL > &rhs)
Assign Rhs by Accumulating.
void AllocateRowMem(const OCP_USI &dimMax, const USI &nb)
Allocate memory for linear system with max possible number of rows.
void ClearData()
Clear the internal matrix data for scalar-value problems.
void CheckEquation() const
Check whether NAN or INF occurs in equations, used in debug mode.
void SetupLinearSolver(const USI &i, const string &dir, const string &file)
Setup LinearSolver.
void OutputSolution(const string &filename) const
Output the solution to a disk file name.
void CheckSolution() const
Check whether NAN or INF occurs in solutions, used in debug mode.
Scalar solvers in CSR format from FASP.
Definition: FaspSolver.hpp:93
Vector solvers in BSR format from FASP.
Definition: FaspSolver.hpp:124