OpenCAEPoro  v0.5.0
A simulator for multicomponent porous media flow
BulkConn.cpp
Go to the documentation of this file.
1 
12 // Standard header files
13 #include <cassert>
14 #include <cmath>
15 #include <ctime>
16 
17 // OpenCAEPoro header files
18 #include "BulkConn.hpp"
19 
21 // General
23 
24 void BulkConn::SetupIsoT(const Grid& myGrid, const Bulk& myBulk)
25 {
26  Setup(myGrid);
27  CalAkd(myBulk);
28 }
29 
31 void BulkConn::Setup(const Grid& myGrid)
32 {
34 
35  numConn = 0;
36  numBulk = myGrid.activeGridNum;
37 
38  neighbor.resize(numBulk);
39  selfPtr.resize(numBulk);
40  neighborNum.resize(numBulk);
41 
42  vector<GPair> tmp1, tmp2;
43  USI len;
44  OCP_USI bIdb;
45 
46  for (OCP_USI n = 0; n < myGrid.numGrid; n++) {
47  const GB_Pair& GBtmp = myGrid.map_All2Act[n];
48 
49  if (GBtmp.IsAct()) {
50  bIdb = GBtmp.GetId();
51 
52  // Get rid of inactive neighbor
53  tmp1 = myGrid.gNeighbor[n];
54  len = tmp1.size();
55  tmp2.clear();
56  for (USI i = 0; i < len; i++) {
57  const GB_Pair& GBtmp2 = myGrid.map_All2Act[tmp1[i].id];
58 
59  if (GBtmp2.IsAct()) {
60  tmp1[i].id = GBtmp2.GetId();
61  tmp2.push_back(tmp1[i]);
62  }
63  }
64  // Add Self
65  tmp2.push_back(GPair(bIdb, 0, 0.0, 0.0));
66  // Sort: Ascending
67  sort(tmp2.begin(), tmp2.end(), GPair::lessG);
68  // Find SelfPtr and Assign to neighbor and area
69  len = tmp2.size();
70  for (USI i = 0; i < len; i++) {
71  neighbor[bIdb].push_back(tmp2[i].id);
72  if (tmp2[i].id == bIdb) {
73  selfPtr[bIdb] = i;
74  }
75  }
76  for (USI j = selfPtr[bIdb] + 1; j < len; j++) {
77  iteratorConn.push_back(BulkPair(bIdb, tmp2[j].id, tmp2[j].direction,
78  tmp2[j].areaB, tmp2[j].areaE));
79  }
80  neighborNum[bIdb] = len;
81  }
82  }
83 
84  numConn = iteratorConn.size();
85 
86  // PrintConnectionInfoCoor(myGrid);
87 }
88 
89 void BulkConn::CalAkd(const Bulk& myBulk)
90 {
91  OCP_USI bId, eId;
92  OCP_DBL areaB, areaE;
93  OCP_DBL T1, T2;
94  for (OCP_USI c = 0; c < numConn; c++) {
95  bId = iteratorConn[c].bId;
96  eId = iteratorConn[c].eId;
97  areaB = iteratorConn[c].areaB;
98  areaE = iteratorConn[c].areaE;
99  switch (iteratorConn[c].direction) {
100  case 1:
101  T1 = myBulk.ntg[bId] * myBulk.rockKx[bId] * areaB;
102  T2 = myBulk.ntg[eId] * myBulk.rockKx[eId] * areaE;
103  break;
104  case 2:
105  T1 = myBulk.ntg[bId] * myBulk.rockKy[bId] * areaB;
106  T2 = myBulk.ntg[eId] * myBulk.rockKy[eId] * areaE;
107  break;
108  case 3:
109  T1 = myBulk.rockKz[bId] * areaB;
110  T2 = myBulk.rockKz[eId] * areaE;
111  break;
112  default:
113  OCP_ABORT("Wrong Direction!");
114  }
115  iteratorConn[c].area = 1 / (1 / T1 + 1 / T2);
116  }
117 }
118 
119 void BulkConn::PrintConnectionInfo(const Grid& myGrid) const
120 {
121  for (OCP_USI i = 0; i < numBulk; i++) {
122  cout << "(" << myGrid.map_Act2All[i] << ")"
123  << "\t";
124 
125  for (auto& v : neighbor[i]) {
126  cout << myGrid.map_Act2All[v] << "\t";
127  }
128  cout << "[" << selfPtr[i] << "]";
129  cout << "\t" << neighborNum[i];
130  cout << "\n";
131  }
132 
133  for (OCP_USI i = 0; i < numConn; i++) {
134  cout << myGrid.map_Act2All[iteratorConn[i].bId] << "\t"
135  << myGrid.map_Act2All[iteratorConn[i].eId] << "\n";
136  }
137 }
138 
139 void BulkConn::PrintConnectionInfoCoor(const Grid& myGrid) const
140 {
141  OCP_USI bIdg, eIdg;
142  OCP_USI bIdb, eIdb;
143  USI I, J, K;
144  USI sp = myGrid.GetNumDigitIJK();
145  cout << "BulkConn : " << numConn << endl;
146  for (OCP_USI c = 0; c < numConn; c++) {
147  bIdb = iteratorConn[c].bId;
148  eIdb = iteratorConn[c].eId;
149  bIdg = myGrid.map_Act2All[bIdb];
150  eIdg = myGrid.map_Act2All[eIdb];
151  myGrid.GetIJKGrid(I, J, K, bIdg);
152  cout << GetIJKformat(I, J, K, sp) << " ";
153  cout << setw(6) << bIdg;
154  cout << " ";
155  cout << setw(6) << bIdb;
156  cout << " ";
157  myGrid.GetIJKGrid(I, J, K, eIdg);
158  cout << GetIJKformat(I, J, K, sp) << " ";
159  cout << setw(6) << eIdg;
160  cout << " ";
161  cout << setw(6) << eIdb;
162  cout << setw(20) << setprecision(8) << fixed << iteratorConn[c].area * CONV2;
163 
164  cout << endl;
165  }
166 }
167 
169 void BulkConn::CalFluxFIMS(const Grid& myGrid, const Bulk& myBulk)
170 {
171  OCP_FUNCNAME;
172 
173  const USI np = myBulk.numPhase;
174  OCP_USI bId, eId, uId;
175  OCP_USI bId_np_j, eId_np_j;
176  OCP_DBL Pbegin, Pend, rho;
177 
178  for (OCP_USI c = 0; c < numConn; c++) {
179  bId = iteratorConn[c].bId;
180  eId = iteratorConn[c].eId;
181 
182  for (USI j = 0; j < np; j++) {
183  bId_np_j = bId * np + j;
184  eId_np_j = eId * np + j;
185 
186  OCP_BOOL exbegin = myBulk.phaseExist[bId_np_j];
187  OCP_BOOL exend = myBulk.phaseExist[eId_np_j];
188 
189  if ((exbegin) && (exend)) {
190  rho = (myBulk.rho[bId_np_j] * myBulk.S[bId_np_j] +
191  myBulk.rho[eId_np_j] * myBulk.S[eId_np_j]) /
192  (myBulk.S[bId_np_j] + myBulk.S[eId_np_j]);
193  } else if (exbegin && (!exend)) {
194  rho = myBulk.rho[bId_np_j];
195  } else if ((!exbegin) && (exend)) {
196  rho = myBulk.rho[eId_np_j];
197  } else {
198  upblock[c * np + j] = bId;
199  upblock_Rho[c * np + j] = 0;
200  continue;
201  }
202  Pbegin = myBulk.Pj[bId_np_j];
203  Pend = myBulk.Pj[eId_np_j];
204  uId = bId;
205  OCP_DBL dP = (Pbegin - GRAVITY_FACTOR * rho * myBulk.depth[bId]) -
206  (Pend - GRAVITY_FACTOR * rho * myBulk.depth[eId]);
207  if (dP < 0) {
208  uId = eId;
209  }
210  upblock[c * np + j] = uId;
211  upblock_Rho[c * np + j] = rho;
212  }
213  }
214 }
215 
216 void BulkConn::CalResFIMS(vector<OCP_DBL>& res, const Bulk& myBulk, const OCP_DBL& dt)
217 {
218  OCP_FUNCNAME;
219 
220  const USI np = myBulk.numPhase;
221  const USI nc = myBulk.numCom;
222  const USI len = nc + 1;
223  OCP_USI bId, eId, uId, bIdb;
224 
225  // Accumalation Term
226  for (OCP_USI n = 0; n < numBulk; n++) {
227 
228  bId = n * len;
229  bIdb = n * nc;
230 
231  res[bId] = myBulk.rockVp[n] - myBulk.vf[n];
232  for (USI i = 0; i < nc; i++) {
233  res[bId + 1 + i] = myBulk.Ni[bIdb + i] - myBulk.lNi[bIdb + i];
234  }
235  }
236 
237  OCP_USI bId_np_j, eId_np_j, uId_np_j;
238  OCP_DBL Pbegin, Pend, rho, dP;
239  OCP_DBL tmp, dNi;
240  OCP_DBL Akd;
241  // Flux Term
242  // Calculate the upblock at the same time.
243  for (OCP_USI c = 0; c < numConn; c++) {
244  bId = iteratorConn[c].bId;
245  eId = iteratorConn[c].eId;
246  Akd = CONV1 * CONV2 * iteratorConn[c].area;
247 
248  for (USI j = 0; j < np; j++) {
249  bId_np_j = bId * np + j;
250  eId_np_j = eId * np + j;
251 
252  OCP_BOOL exbegin = myBulk.phaseExist[bId_np_j];
253  OCP_BOOL exend = myBulk.phaseExist[eId_np_j];
254 
255  if ((exbegin) && (exend)) {
256  rho = (myBulk.rho[bId_np_j] * myBulk.S[bId_np_j] +
257  myBulk.rho[eId_np_j] * myBulk.S[eId_np_j]) /
258  (myBulk.S[bId_np_j] + myBulk.S[eId_np_j]);
259  } else if (exbegin && (!exend)) {
260  rho = myBulk.rho[bId_np_j];
261  } else if ((!exbegin) && (exend)) {
262  rho = myBulk.rho[eId_np_j];
263  } else {
264  upblock[c * np + j] = bId;
265  upblock_Rho[c * np + j] = 0;
266  continue;
267  }
268  Pbegin = myBulk.Pj[bId_np_j];
269  Pend = myBulk.Pj[eId_np_j];
270  uId = bId;
271  dP = (Pbegin - GRAVITY_FACTOR * rho * myBulk.depth[bId]) -
272  (Pend - GRAVITY_FACTOR * rho * myBulk.depth[eId]);
273  if (dP < 0) {
274  uId = eId;
275  }
276  upblock_Rho[c * np + j] = rho;
277  upblock[c * np + j] = uId;
278 
279  uId_np_j = uId * np + j;
280  if (!myBulk.phaseExist[uId_np_j]) continue;
281  tmp = dt * Akd * myBulk.xi[uId_np_j] * myBulk.kr[uId_np_j] /
282  myBulk.mu[uId_np_j] * dP;
283 
284  for (USI i = 0; i < nc; i++) {
285  dNi = tmp * myBulk.xij[uId_np_j * nc + i];
286  res[bId * len + 1 + i] += dNi;
287  res[eId * len + 1 + i] -= dNi;
288  }
289  }
290  }
291 }
292 
293 /*----------------------------------------------------------------------------*/
294 /* Brief Change History of This File */
295 /*----------------------------------------------------------------------------*/
296 /* Author Date Actions */
297 /*----------------------------------------------------------------------------*/
298 /* Shizhe Li Oct/01/2021 Create file */
299 /* Chensong Zhang Oct/15/2021 Format file */
300 /*----------------------------------------------------------------------------*/
BulkConn class declaration.
unsigned int USI
Generic unsigned integer.
Definition: OCPConst.hpp:23
double OCP_DBL
Double precision.
Definition: OCPConst.hpp:27
const OCP_DBL CONV1
1 bbl = CONV1 ft3
Definition: OCPConst.hpp:63
const OCP_DBL GRAVITY_FACTOR
0.00694444 ft2 psi / lb
Definition: OCPConst.hpp:56
unsigned int OCP_USI
Long unsigned integer.
Definition: OCPConst.hpp:25
unsigned int OCP_BOOL
OCP_BOOL in OCP.
Definition: OCPConst.hpp:29
const OCP_DBL CONV2
Darcy constant in field unit.
Definition: OCPConst.hpp:64
#define OCP_FUNCNAME
Print Function Name.
Definition: UtilError.hpp:73
#define OCP_ABORT(msg)
Abort if critical error happens.
Definition: UtilError.hpp:47
OCP_USI numConn
Number of connections between bulks.
Definition: BulkConn.hpp:108
vector< OCP_USI > upblock
Index of upwinding bulk of connections : numConn * numPhase.
Definition: BulkConn.hpp:133
vector< OCP_DBL > upblock_Rho
Mass density of phase from upblock: numConn * numPhase.
Definition: BulkConn.hpp:135
OCP_USI numBulk
Number of bulks (active grid cells).
Definition: BulkConn.hpp:107
void CalFluxFIMS(const Grid &myGrid, const Bulk &myBulk)
rho = (S1*rho1 + S2*rho2)/(S1+S2)
Definition: BulkConn.cpp:169
void CalAkd(const Bulk &myBulk)
Calculate the effective area used for flow.
Definition: BulkConn.cpp:89
void PrintConnectionInfo(const Grid &myGrid) const
Print information of connections on screen.
Definition: BulkConn.cpp:119
vector< USI > selfPtr
Self-pointer, the indices of the i-th bulk in neighbor[i]: numBulk.
Definition: BulkConn.hpp:116
void Setup(const Grid &myGrid)
It should be called after Grid and Bulk Setup.
Definition: BulkConn.cpp:31
vector< vector< OCP_USI > > neighbor
Neighboring information of each bulk: activeGridNum.
Definition: BulkConn.hpp:113
void SetupIsoT(const Grid &myGrid, const Bulk &myBulk)
Setup active connections.
Definition: BulkConn.cpp:24
vector< BulkPair > iteratorConn
All connections (pair of indices) between bulks: numConn.
Definition: BulkConn.hpp:124
vector< USI > neighborNum
Number of neighbors of the i-th bulk: numBulk, self-included.
Definition: BulkConn.hpp:119
Connection between two bulks (bId, eId); usually, indices bId > eId.
Definition: BulkConn.hpp:30
Physical information of each active reservoir bulk.
Definition: Bulk.hpp:104
vector< OCP_DBL > mu
Viscosity of phase: numPhase*numBulk.
Definition: Bulk.hpp:320
USI numPhase
Number of phase.
Definition: Bulk.hpp:154
vector< OCP_DBL > S
Saturation of phase: numPhase*numBulk.
Definition: Bulk.hpp:314
vector< OCP_DBL > rho
Mass density of phase: numPhase*numBulk.
Definition: Bulk.hpp:318
vector< OCP_DBL > ntg
net to gross of bulk.
Definition: Bulk.hpp:243
vector< OCP_DBL > xij
Nij / Nj: numPhase*numCom*numBulk.
Definition: Bulk.hpp:317
vector< OCP_DBL > kr
Relative permeability of phase: numPhase*numBulk.
Definition: Bulk.hpp:321
vector< OCP_DBL > depth
Depth of center of grid cells: activeGridNum.
Definition: Bulk.hpp:241
vector< OCP_DBL > rockVp
pore volume = Vgrid * ntg * poro.
Definition: Bulk.hpp:246
vector< OCP_DBL > Ni
Moles of component: numCom*numBulk.
Definition: Bulk.hpp:306
vector< OCP_DBL > Pj
Pressure of phase: numPhase*numBulk.
Definition: Bulk.hpp:311
vector< OCP_BOOL > phaseExist
Existence of phase: numPhase*numBulk.
Definition: Bulk.hpp:313
vector< OCP_DBL > xi
Moles density of phase: numPhase*numBulk.
Definition: Bulk.hpp:319
vector< OCP_DBL > vf
Total fluid volume: numBulk.
Definition: Bulk.hpp:307
vector< OCP_DBL > rockKz
current rock permeability along the z direction.
Definition: Bulk.hpp:249
vector< OCP_DBL > rockKx
current rock permeability along the x direction.
Definition: Bulk.hpp:247
vector< OCP_DBL > rockKy
current rock permeability along the y direction.
Definition: Bulk.hpp:248
vector< OCP_DBL > lNi
last Ni
Definition: Bulk.hpp:329
USI numCom
Number of component.
Definition: Bulk.hpp:155
Active cell indicator and its index among active cells.
Definition: Grid.hpp:32
OCP_BOOL IsAct() const
Return whether this cell is active or not.
Definition: Grid.hpp:42
OCP_USI GetId() const
Return the index of this cell among active cells.
Definition: Grid.hpp:44
Effective area of intersection surfaces with neighboring cells.
Definition: Grid.hpp:53
Definition: Grid.hpp:89
vector< OCP_USI > map_Act2All
Mapping from active grid to all grid: activeGridNum.
Definition: Grid.hpp:192
OCP_USI activeGridNum
Num of active grid.
Definition: Grid.hpp:190
USI GetNumDigitIJK() const
Return numDigutIJK.
Definition: Grid.hpp:216
vector< GB_Pair > map_All2Act
Mapping from grid to active all grid: numGrid.
Definition: Grid.hpp:193
OCP_USI numGrid
Number of all cells.
Definition: Grid.hpp:142
vector< vector< GPair > > gNeighbor
Neighboring information of grid.
Definition: Grid.hpp:187