OpenCAEPoro  v0.5.0
A simulator for multicomponent porous media flow
LinearSystem.hpp
Go to the documentation of this file.
1 
12 #ifndef __LINEARSYSTEM_HEADER__
13 #define __LINEARSYSTEM_HEADER__
14 
15 // Standard header files
16 #include <cmath>
17 #include <fstream>
18 #include <iostream>
19 #include <string>
20 
21 // OpenCAEPoro header files
22 #include "DenseMat.hpp"
23 #include "FaspSolver.hpp"
24 #include "OCPConst.hpp"
25 
26 using namespace std;
27 
29 // Note: The matrix is stored in the form of row-segmented CSR internally
31 {
32 
33 public:
35  void AllocateRowMem(const OCP_USI& dimMax, const USI& nb);
37  void AllocateColMem(const vector<USI>& bulk2bulk,
38  const vector<vector<OCP_USI>> well2bulk);
40  void ClearData();
41 
43  vector<OCP_DBL>& GetSolution() { return u; }
45  void CheckEquation() const;
47  void CheckSolution() const;
49  void OutputLinearSystem(const string& fileA, const string& fileb) const;
51  void OutputSolution(const string& filename) const;
52 
53  // Linear Solver
55  void SetupLinearSolver(const USI& i, const string& dir, const string& file);
57  void AssembleMatLinearSolver() { LS->AssembleMat(colId, val, dim, blockDim, b, u); }
59  OCP_INT Solve() { return LS->Solve(); }
60 
63  {
64  dim += n;
65  return dim;
66  }
67 
68  // Scalar
70  void NewDiag(const OCP_USI& n, const OCP_DBL& v)
71  {
72  OCP_ASSERT(colId[n].size() == 0, "Wrong Diag");
73  colId[n].push_back(n);
74  val[n].push_back(v);
75  }
77  void AddDiag(const OCP_USI& n, const OCP_DBL& v)
78  {
79  OCP_ASSERT(colId[n].size() > 0, "Wrong Diag");
80  val[n][0] += v;
81  }
83  void NewOffDiag(const OCP_USI& bId, const OCP_USI& eId, const OCP_DBL& v)
84  {
85  OCP_ASSERT(colId[bId].size() > 0, "Wrong Diag");
86  colId[bId].push_back(eId);
87  val[bId].push_back(v);
88  }
90  void AddRhs(const OCP_USI& n, const OCP_DBL& v) { b[n] += v; }
92  void AssignGuess(const OCP_USI& n, const OCP_DBL& v) { u[n] = v; }
93 
94  // Vector
95  void NewDiag(const OCP_USI& n, const vector<OCP_DBL>& v)
96  {
97  OCP_ASSERT(colId[n].size() == 0, "Wrong Diag");
98  colId[n].push_back(n);
99  val[n].insert(val[n].begin(), v.begin(), v.end());
100  }
101  void AddDiag(const OCP_USI& n, const vector<OCP_DBL>& v)
102  {
103  OCP_ASSERT(colId[n].size() > 0, "Wrong Diag");
104  for (USI i = 0; i < blockSize; i++) {
105  val[n][i] += v[i];
106  }
107  }
108  void NewOffDiag(const OCP_USI& bId, const OCP_USI& eId, const vector<OCP_DBL>& v)
109  {
110  OCP_ASSERT(colId[bId].size() > 0, "Wrong Diag");
111  colId[bId].push_back(eId);
112  val[bId].insert(val[bId].end(), v.begin(), v.end());
113  }
115  void AddRhs(const OCP_USI& n, const vector<OCP_DBL>& v)
116  {
117  for (USI i = 0; i < blockDim; i++) {
118  b[n * blockDim + i] += v[i];
119  }
120  }
121 
123  void AssembleRhsAccumulate(const vector<OCP_DBL>& rhs);
125  void AssembleRhsCopy(const vector<OCP_DBL>& rhs);
127  USI GetNumIters() { return LS->GetNumIters(); }
128 
129 private:
130  // Used for internal mat structure.
131  USI blockDim;
132  USI blockSize;
133 
134  // maxDim: fixed and used to allocate memory at the beginning of simulation;
135  // dim: might change during simulation but always less than maxDim.
136  OCP_USI maxDim;
137  OCP_USI dim;
138 
139  // The following values are stored for each row. Among them, rowCapacity is the max
140  // possible capacity of each row of the matrix. It is just a little bigger than the
141  // actual size and is used to allocate memory at the beginning of simulation.
142  // diagVal is an auxiliary variable used to help setup entries in diagonal line and
143  // it will only be used when matrix is assembled.
144  vector<USI> rowCapacity;
145  vector<vector<OCP_USI>> colId;
146  vector<vector<OCP_DBL>> val;
147  vector<OCP_DBL> b;
148  vector<OCP_DBL> u;
149 
150  string solveDir;
151 
152  LinearSolver* LS;
153 };
154 
155 #endif /* end if __LINEARSOLVER_HEADER__ */
156 
157 /*----------------------------------------------------------------------------*/
158 /* Brief Change History of This File */
159 /*----------------------------------------------------------------------------*/
160 /* Author Date Actions */
161 /*----------------------------------------------------------------------------*/
162 /* Shizhe Li Oct/01/2021 Create file */
163 /* Chensong Zhang Oct/15/2021 Format file */
164 /* Chensong Zhang Nov/09/2021 Remove decoupling methods */
165 /* Chensong Zhang Nov/22/2021 renamed to LinearSystem */
166 /*----------------------------------------------------------------------------*/
Operations about small dense mat.
Declaration of classes interfacing to the FASP solvers.
Definition of build-in datatypes and consts.
unsigned int USI
Generic unsigned integer.
Definition: OCPConst.hpp:23
double OCP_DBL
Double precision.
Definition: OCPConst.hpp:27
unsigned int OCP_USI
Long unsigned integer.
Definition: OCPConst.hpp:25
int OCP_INT
Long integer.
Definition: OCPConst.hpp:26
#define OCP_ASSERT(cond, msg)
Assert condition and log user messages in DEBUG mode.
Definition: UtilError.hpp:58
Virtual base class for linear solvers.
Linear solvers for discrete systems.
USI GetNumIters()
Return the number of iterations.
void AddRhs(const OCP_USI &n, const vector< OCP_DBL > &v)
Add a value at b[n].
void AssembleMatLinearSolver()
Assemble Mat for Linear Solver.
void AddDiag(const OCP_USI &n, const OCP_DBL &v)
Add a value at diagonal value.
void NewDiag(const OCP_USI &n, const OCP_DBL &v)
Push back a diagonal val, which is always at the first location.
void AssignGuess(const OCP_USI &n, const OCP_DBL &v)
Assign an initial value at u[n].
void AddRhs(const OCP_USI &n, const OCP_DBL &v)
Add a value at b[n].
void NewOffDiag(const OCP_USI &bId, const OCP_USI &eId, const OCP_DBL &v)
Push back a off-diagonal value.
OCP_INT Solve()
Solve the Linear System.
OCP_USI AddDim(const OCP_USI &n)
Setup dimensions.
vector< OCP_DBL > & GetSolution()
Return the solution.