16 AllocateReservoir(rs);
17 AllocateLinearSystem(ls, rs, ctrl);
20 void T_FIM::InitReservoir(
Reservoir& rs)
const
33 UpdateLastTimeStep(rs);
47 AssembleMatBulks(ls, rs, t, dt);
48 AssembleMatWells(ls, rs, dt);
63 int status = ls.
Solve();
90 if (!ctrl.Check(rs, {
"BulkNi",
"BulkP",
"BulkT"})) {
91 ResetToLastTimeStep(rs, ctrl);
92 cout <<
"Cut time step size and repeat! current dt = " << fixed
93 << setprecision(3) << dt <<
" days\n";
103 CalThermalConduct(rs.
conn, rs.
bulk);
109 CalRes(rs, ctrl.
GetCurTime() + dt, dt, OCP_FALSE);
122 cout <<
"### NR : " + to_string(ctrl.iterNR) +
" Res: " << setprecision(2)
126 << setw(12) << fabs(NRdPmax) << setw(12) << fabs(NRdSmax) << endl;
133 (fabs(NRdPmax) <= ctrl.ctrlNR.
NRdPmin &&
134 fabs(NRdSmax) <= ctrl.ctrlNR.
NRdSmin)) {
136 if (!ctrl.Check(rs, {
"WellP"})) {
137 ResetToLastTimeStep(rs, ctrl);
143 }
else if (ctrl.iterNR >= ctrl.ctrlNR.
maxNRiter) {
144 ctrl.current_dt *= ctrl.ctrlTime.
cutFacNR;
145 ResetToLastTimeStep(rs, ctrl);
146 cout <<
"### WARNING: NR not fully converged! Cut time step size and repeat! "
148 << fixed << setprecision(3) << ctrl.current_dt <<
" days\n";
159 UpdateLastTimeStep(rs);
160 ctrl.CalNextTimeStep(rs, {
"dP",
"dS",
"iter"});
164 void T_FIM::AllocateReservoir(
Reservoir& rs)
198 bk.
Ni.resize(nb * nc);
203 bk.
Pj.resize(nb * np);
204 bk.
Pc.resize(nb * np);
206 bk.
S.resize(nb * np);
207 bk.
xij.resize(nb * np * nc);
208 bk.
rho.resize(nb * np);
209 bk.
xi.resize(nb * np);
210 bk.
mu.resize(nb * np);
211 bk.
kr.resize(nb * np);
213 bk.
H.resize(nb * np);
218 bk.
lNi.resize(nb * nc);
222 bk.
lPj.resize(nb * np);
223 bk.
lPc.resize(nb * np);
225 bk.
lS.resize(nb * np);
226 bk.
lxij.resize(nb * np * nc);
227 bk.
lrho.resize(nb * np);
228 bk.
lxi.resize(nb * np);
229 bk.
lmu.resize(nb * np);
230 bk.
lkr.resize(nb * np);
232 bk.
lH.resize(nb * np);
238 bk.
vfi.resize(nb * nc);
239 bk.
rhoP.resize(nb * np);
240 bk.
rhoT.resize(nb * np);
241 bk.
rhox.resize(nb * nc * np);
242 bk.
xiP.resize(nb * np);
243 bk.
xiT.resize(nb * np);
244 bk.
xix.resize(nb * nc * np);
245 bk.
muP.resize(nb * np);
246 bk.
muT.resize(nb * np);
247 bk.
mux.resize(nb * nc * np);
248 bk.
dPcj_dS.resize(nb * np * np);
249 bk.
dKr_dS.resize(nb * np * np);
252 bk.
Ufi.resize(nb * nc);
253 bk.
HT.resize(nb * np);
254 bk.
Hx.resize(nb * np * nc);
257 bk.
ktS.resize(nb * np);
261 bk.
lvfi.resize(nb * nc);
262 bk.
lrhoP.resize(nb * np);
263 bk.
lrhoT.resize(nb * np);
264 bk.
lrhox.resize(nb * nc * np);
265 bk.
lxiP.resize(nb * np);
266 bk.
lxiT.resize(nb * np);
267 bk.
lxix.resize(nb * nc * np);
268 bk.
lmuP.resize(nb * np);
269 bk.
lmuT.resize(nb * np);
270 bk.
lmux.resize(nb * nc * np);
272 bk.
ldKr_dS.resize(nb * np * np);
275 bk.
Ufi.resize(nb * nc);
276 bk.
HT.resize(nb * np);
277 bk.
Hx.resize(nb * np * nc);
280 bk.
ktS.resize(nb * np);
300 bk.
dSNR.resize(nb * np);
301 bk.
dSNRP.resize(nb * np);
302 bk.
dNNR.resize(nb * nc);
310 conn.
upblock.resize(numConn * np);
313 conn.
Adkt.resize(numConn);
314 conn.
AdktP.resize(numConn * 2);
315 conn.
AdktT.resize(numConn * 2);
316 conn.
AdktS.resize(numConn * 2 * np);
328 void T_FIM::InitRock(
Bulk& bk)
const
332 if (bk.
bType[n] == 0) {
345 void T_FIM::CalRock(
Bulk& bk)
const
350 for (
OCP_USI n = 0; n < nb; n++) {
351 if (bk.
bType[n] > 0) {
358 bk.
vr[n] = bk.
v[n] * vr;
359 bk.
vrP[n] = bk.
v[n] * vrP;
360 bk.
vrT[n] = bk.
v[n] * vrT;
366 void T_FIM::InitFlash(
Bulk& bk)
const
372 for (
OCP_USI n = 0; n < nb; n++) {
373 if (bk.
bType[n] > 0) {
377 for (
USI i = 0; i < nc; i++) {
380 PassFlashValue(bk, n);
385 void T_FIM::CalFlash(
Bulk& bk)
const
391 for (
OCP_USI n = 0; n < nb; n++) {
392 if (bk.
bType[n] > 0) {
395 &bk.
xij[n * np * nc], n);
396 PassFlashValue(bk, n);
401 void T_FIM::PassFlashValue(
Bulk& bk,
const OCP_USI& n)
const
413 for (
USI j = 0; j < np; j++) {
418 bk.
S[bIdp + j] = bk.
flashCal[pvtnum]->GetS(j);
419 bk.
dSNR[bIdp + j] = bk.
S[bIdp + j] - bk.
dSNR[bIdp + j];
430 bk.
xi[bIdp + j] = bk.
flashCal[pvtnum]->GetXi(j);
431 bk.
mu[bIdp + j] = bk.
flashCal[pvtnum]->GetMu(j);
432 bk.
H[bIdp + j] = bk.
flashCal[pvtnum]->GetH(j);
441 bk.
HT[bIdp + j] = bk.
flashCal[pvtnum]->GetHT(j);
443 for (
USI i = 0; i < nc; i++) {
444 bk.
xij[bIdp * nc + j * nc + i] = bk.
flashCal[pvtnum]->GetXij(j, i);
445 bk.
rhox[bIdp * nc + j * nc + i] = bk.
flashCal[pvtnum]->GetRhoX(j, i);
446 bk.
xix[bIdp * nc + j * nc + i] = bk.
flashCal[pvtnum]->GetXiX(j, i);
447 bk.
mux[bIdp * nc + j * nc + i] = bk.
flashCal[pvtnum]->GetMuX(j, i);
448 bk.
Hx[bIdp * nc + j * nc + i] = bk.
flashCal[pvtnum]->GetHx(j, i);
457 for (
USI i = 0; i < nc; i++) {
458 bk.
vfi[n * nc + i] = bk.
flashCal[pvtnum]->GetVfi(i);
459 bk.
Ufi[n * nc + i] = bk.
flashCal[pvtnum]->GetUfi(i);
463 &bk.
flashCal[pvtnum]->GetDXsDXp()[0]);
466 void T_FIM::CalKrPc(
Bulk& bk)
const
471 if (bk.
bType[n] > 0) {
473 bk.
flow[bk.
SATNUM[n]]->CalKrPcDeriv(&bk.
S[bId], &bk.
kr[bId], &bk.
Pc[bId],
476 for (
USI j = 0; j < np; j++)
477 bk.
Pj[n * np + j] = bk.
P[n] + bk.
Pc[n * np + j];
482 void T_FIM::CalThermalConduct(
BulkConn& conn,
Bulk& bk)
const
487 for (
OCP_USI n = 0; n < nb; n++) {
488 if (bk.
bType[n] > 0) {
491 for (
USI j = 0; j < np; j++) {
492 tmp += bk.
S[n * np + j] * bk.
thconp[j];
515 T1 = bk.
kt[bId] * areaB;
516 T2 = bk.
kt[eId] * areaE;
517 conn.
Adkt[c] = 1 / (1 / T1 + 1 / T2);
519 tmpB = pow(conn.
Adkt[c], 2) / pow(T1, 2) * areaB;
520 tmpE = pow(conn.
Adkt[c], 2) / pow(T2, 2) * areaE;
521 conn.
AdktP[c * 2 + 0] = tmpB * bk.
ktP[bId];
522 conn.
AdktP[c * 2 + 1] = tmpE * bk.
ktP[eId];
523 conn.
AdktT[c * 2 + 0] = tmpB * bk.
ktT[bId];
524 conn.
AdktT[c * 2 + 1] = tmpE * bk.
ktT[eId];
525 for (
USI j = 0; j < np; j++) {
526 conn.
AdktS[c * np * 2 + j] = tmpB * bk.
ktS[bId * np + j];
527 conn.
AdktS[c * np * 2 + np + j] = tmpE * bk.
ktS[eId * np + j];
599 bk.
hLoss.ResetToLastTimeStep();
622 void T_FIM::UpdateLastTimeStep(
Reservoir& rs)
const
683 bk.
hLoss.UpdateLastTimeStep();
692 rs.
allWells.UpdateLastTimeStepBHP();
705 const USI len = nc + 2;
715 for (
OCP_USI n = 0; n < nb; n++) {
716 if (bk.
bType[n] > 0) {
723 for (
USI i = 0; i < nc; i++) {
724 Res.
resAbs[n * len + 1 + i] = bk.
Ni[bIdb + i] - bk.
lNi[bIdb + i];
727 Res.
resAbs[n * len + nc + 1] =
728 (bk.
vf[n] * bk.
Uf[n] + bk.
vr[n] * bk.
Hr[n]) -
740 Res.
resAbs[n * len + nc + 1] +=
742 (2 * (bk.
T[n] - bk.
initT[n]) / sqrt(lambda * t) - bk.
hLoss.
p[n]) *
747 OCP_USI bId_np_j, eId_np_j, uId_np_j;
755 dT = bk.
T[bId] - bk.
T[eId];
756 Res.
resAbs[bId * len + 1 + nc] += conn.
Adkt[c] * dT * dt;
757 Res.
resAbs[eId * len + 1 + nc] -= conn.
Adkt[c] * dT * dt;
763 for (
USI j = 0; j < np; j++) {
764 bId_np_j = bId * np + j;
765 eId_np_j = eId * np + j;
770 if ((exbegin) && (exend)) {
771 rho = (bk.
rho[bId_np_j] + bk.
rho[eId_np_j]) / 2;
772 }
else if (exbegin && (!exend)) {
773 rho = bk.
rho[bId_np_j];
774 }
else if ((!exbegin) && (exend)) {
775 rho = bk.
rho[eId_np_j];
777 conn.
upblock[c * np + j] = bId;
789 conn.
upblock[c * np + j] = uId;
790 uId_np_j = uId * np + j;
794 Akd * bk.
kr[uId_np_j] / bk.
mu[uId_np_j] * dP;
803 for (
USI i = 0; i < nc; i++) {
804 dNi = tmpV * bk.
xij[uId_np_j * nc + i];
805 Res.
resAbs[bId * len + 1 + i] += dNi;
806 Res.
resAbs[eId * len + 1 + i] -= dNi;
808 Res.
resAbs[bId * len + 1 + nc] += tmpV * bk.
H[uId_np_j];
809 Res.
resAbs[eId * len + 1 + nc] -= tmpV * bk.
H[uId_np_j];
820 for (
USI p = 0; p < wl.PerfNum(); p++) {
821 const OCP_USI k = wl.PerfLocation(p);
823 for (
USI i = 0; i < nc; i++) {
824 Res.
resAbs[k * len + 1 + i] += wl.PerfQi_lbmol(p, i) * dt;
828 if (wl.WellType() ==
INJ) {
831 bk.
flashCal[0]->CalInjWellEnthalpy(wl.InjTemp(), &wl.InjZi()[0]);
832 for (
USI p = 0; p < wl.PerfNum(); p++) {
833 const OCP_USI k = wl.PerfLocation(p);
834 Res.
resAbs[k * len + 1 + nc] +=
835 wl.PerfInjQt_ft3(p) * wl.PerfXi(p) * Hw * dt;
839 switch (wl.OptMode()) {
841 Res.
resAbs[wId] = wl.BHP() - wl.MaxBHP();
848 Res.
resAbs[wId] = wl.MaxRate();
849 for (
USI i = 0; i < nc; i++) {
850 Res.
resAbs[wId] += wl.Qi_lbmol(i);
864 fabs(Res.
resAbs[wId] / wl.MaxRate()));
872 for (
USI p = 0; p < wl.PerfNum(); p++) {
873 const OCP_USI k = wl.PerfLocation(p);
875 for (
USI j = 0; j < np; j++) {
876 Res.
resAbs[k * len + 1 + nc] += wl.PerfProdQj_ft3(p, j) *
878 bk.
H[k * np + j] * dt;
883 switch (wl.OptMode()) {
885 Res.
resAbs[wId] = wl.BHP() - wl.MinBHP();
892 wl.CalProdWeight(bk);
893 Res.
resAbs[wId] = -wl.MaxRate();
894 for (
USI i = 0; i < nc; i++) {
895 Res.
resAbs[wId] += wl.Qi_lbmol(i) * wl.ProdWeight(i);
899 fabs(Res.
resAbs[wId] / wl.MaxRate()));
912 for (
OCP_USI n = 0; n < nb; n++) {
916 tmp = fabs(Res.
resAbs[n * len + nc + 1] / eT);
922 if (bk.
bType[n] > 0) {
924 for (
USI i = 0; i < len - 1; i++) {
932 for (
USI i = 1; i < len - 1; i++) {
933 tmp = fabs(Res.
resAbs[n * len + i] / bk.
Nt[n]);
943 if (resetRes0) Res.SetInitRes();
957 const USI ncol = nc + 2;
958 const USI ncol2 = np * nc + np;
959 const USI bsize = ncol * ncol;
960 const USI bsize2 = ncol * ncol2;
964 vector<OCP_DBL> bmat(bsize, 0);
966 for (
USI i = 1; i < nc + 1; i++) {
968 bmat[i * ncol + i] = 1;
970 vector<OCP_DBL> bmatR(bmat);
972 for (
OCP_USI n = 0; n < nb; n++) {
973 if (bk.
bType[n] > 0) {
977 bmat[0] = bk.
v[n] * bk.
poroP[n] - bk.
vfP[n];
979 for (
USI i = 0; i < nc; i++) {
980 bmat[i + 1] = -bk.
vfi[n * nc + i];
983 bmat[nc + 1] = bk.
v[n] * bk.
poroT[n] - bk.
vfT[n];
986 bmat[ncol * (ncol - 1)] =
989 for (
USI i = 0; i < nc; i++) {
990 bmat[ncol * (ncol - 1) + i + 1] =
991 bk.
vfi[n * nc + i] * bk.
Uf[n] + bk.
vf[n] * bk.
Ufi[n * nc + i];
994 bmat[ncol * ncol - 1] = bk.
vfT[n] * bk.
Uf[n] + bk.
vf[n] * bk.
UfT[n] +
1004 bmat[ncol * ncol - 1] += dt * kappa *
1005 (2 / sqrt(lambda * t) - bk.
hLoss.
pT[n]) *
1006 bk.
dx[n] * bk.
dy[n];
1014 bmatR[ncol * ncol - 1] = bk.
vrT[n] * bk.
Hr[n] + bk.
vr[n] * bk.
HrT[n];
1023 bmatR[ncol * ncol - 1] += dt * kappa *
1024 (2 / sqrt(lambda * t) - bk.
hLoss.
pT[n]) *
1025 bk.
dx[n] * bk.
dy[n];
1034 OCP_DBL transJ, transIJ, transH;
1035 vector<OCP_DBL> dFdXpB(bsize, 0);
1036 vector<OCP_DBL> dFdXpE(bsize, 0);
1037 vector<OCP_DBL> dFdXsB(bsize2, 0);
1038 vector<OCP_DBL> dFdXsE(bsize2, 0);
1045 OCP_USI bId_np_j, eId_np_j, uId_np_j, dId_np_j;
1046 OCP_BOOL phaseExistBj, phaseExistEj, phaseExistDj;
1047 OCP_DBL xi, xij, kr, mu, rhox, xiP, xiT, xix, muP, muT, mux, H, HT, Hx;
1054 fill(dFdXpB.begin(), dFdXpB.end(), 0.0);
1055 fill(dFdXpE.begin(), dFdXpE.end(), 0.0);
1056 fill(dFdXsB.begin(), dFdXsB.end(), 0.0);
1057 fill(dFdXsE.begin(), dFdXsE.end(), 0.0);
1062 if (bk.
bType[bId] > 0 && bk.
bType[eId] > 0) {
1067 for (
USI j = 0; j < np; j++) {
1068 uId = conn.
upblock[c * np + j];
1069 uId_np_j = uId * np + j;
1071 bId_np_j = bId * np + j;
1072 eId_np_j = eId * np + j;
1077 dFdXpU = &dFdXpB[0];
1078 dFdXpD = &dFdXpE[0];
1079 dFdXsU = &dFdXsB[0];
1080 dFdXsD = &dFdXsE[0];
1081 phaseExistDj = phaseExistEj;
1082 dId_np_j = eId_np_j;
1084 dFdXpU = &dFdXpE[0];
1085 dFdXpD = &dFdXpB[0];
1086 dFdXsU = &dFdXsE[0];
1087 dFdXsD = &dFdXsB[0];
1088 phaseExistDj = phaseExistBj;
1089 dId_np_j = bId_np_j;
1099 dP = bk.
Pj[bId_np_j] - bk.
Pj[eId_np_j] -
1101 dT = bk.
T[bId] - bk.
T[eId];
1102 xi = bk.
xi[uId_np_j];
1103 kr = bk.
kr[uId_np_j];
1104 mu = bk.
mu[uId_np_j];
1105 xiP = bk.
xiP[uId_np_j];
1106 xiT = bk.
xiT[uId_np_j];
1107 muP = bk.
muP[uId_np_j];
1108 muT = bk.
muT[uId_np_j];
1110 HT = bk.
HT[uId_np_j];
1111 transJ = Akd * kr / mu;
1114 for (
USI i = 0; i < nc; i++) {
1115 xij = bk.
xij[uId_np_j * nc + i];
1116 transIJ = transJ * xi * xij;
1119 dFdXpB[(i + 1) * ncol] += transIJ;
1120 dFdXpE[(i + 1) * ncol] -= transIJ;
1122 tmp = transJ * xiP * xij * dP;
1123 tmp += -transIJ * muP / mu * dP;
1124 dFdXpU[(i + 1) * ncol] +=
1125 (tmp - transIJ * rhoWghtU * bk.
rhoP[uId_np_j] * dGamma);
1126 dFdXpD[(i + 1) * ncol] +=
1127 -transIJ * rhoWghtD * bk.
rhoP[dId_np_j] * dGamma;
1130 tmp = transJ * xiT * xij * dP;
1131 tmp += -transIJ * muT / mu * dP;
1132 dFdXpU[(i + 2) * ncol - 1] +=
1133 (tmp - transIJ * rhoWghtU * bk.
rhoT[uId_np_j] * dGamma);
1134 dFdXpD[(i + 2) * ncol - 1] +=
1135 -transIJ * rhoWghtD * bk.
rhoT[dId_np_j] * dGamma;
1138 for (
USI k = 0; k < np; k++) {
1139 dFdXsB[(i + 1) * ncol2 + k] +=
1140 transIJ * bk.
dPcj_dS[bId_np_j * np + k];
1141 dFdXsE[(i + 1) * ncol2 + k] -=
1142 transIJ * bk.
dPcj_dS[eId_np_j * np + k];
1143 dFdXsU[(i + 1) * ncol2 + k] +=
1144 Akd * bk.
dKr_dS[uId_np_j * np + k] / mu * xi * xij * dP;
1147 for (
USI k = 0; k < nc; k++) {
1148 rhox = bk.
rhox[uId_np_j * nc + k];
1149 xix = bk.
xix[uId_np_j * nc + k];
1150 mux = bk.
mux[uId_np_j * nc + k];
1151 tmp = -transIJ * rhoWghtU * rhox * dGamma;
1152 tmp += transJ * xix * xij * dP;
1153 tmp += -transIJ * mux / mu * dP;
1154 dFdXsU[(i + 1) * ncol2 + np + j * nc + k] += tmp;
1155 dFdXsD[(i + 1) * ncol2 + np + j * nc + k] +=
1156 -transIJ * rhoWghtD * bk.
rhox[dId_np_j * nc + k] * dGamma;
1158 dFdXsU[(i + 1) * ncol2 + np + j * nc + i] += transJ * xi * dP;
1162 transH = transJ * xi * H;
1164 dFdXpB[(ncol - 1) * ncol] += transH;
1165 dFdXpE[(ncol - 1) * ncol] -= transH;
1167 tmp = transJ * xiP * H * dP;
1168 tmp += -transJ * xi * muP / mu * dP * H;
1169 dFdXpU[(ncol - 1) * ncol] +=
1170 (tmp - transH * rhoWghtU * bk.
rhoP[uId_np_j] * dGamma);
1171 dFdXpD[(ncol - 1) * ncol] +=
1172 -transH * rhoWghtD * bk.
rhoP[dId_np_j] * dGamma;
1175 tmp = transJ * xiT * H * dP;
1176 tmp += transJ * xi * HT * dP;
1177 tmp += -transH * muT / mu * dP;
1178 dFdXpU[ncol * ncol - 1] +=
1179 (tmp - transH * rhoWghtU * bk.
rhoT[uId_np_j] * dGamma);
1180 dFdXpD[ncol * ncol - 1] +=
1181 -transH * rhoWghtD * bk.
rhoT[dId_np_j] * dGamma;
1184 for (
USI k = 0; k < np; k++) {
1185 dFdXsB[(nc + 1) * ncol2 + k] +=
1186 transH * bk.
dPcj_dS[bId_np_j * np + k];
1187 dFdXsE[(nc + 1) * ncol2 + k] -=
1188 transH * bk.
dPcj_dS[eId_np_j * np + k];
1189 dFdXsU[(nc + 1) * ncol2 + k] +=
1190 Akd * bk.
dKr_dS[uId_np_j * np + k] / mu * xi * H * dP;
1193 for (
USI k = 0; k < nc; k++) {
1194 rhox = bk.
rhox[uId_np_j * nc + k];
1195 xix = bk.
xix[uId_np_j * nc + k];
1196 mux = bk.
mux[uId_np_j * nc + k];
1197 Hx = bk.
Hx[uId_np_j * nc + k];
1198 tmp = -transH * rhoWghtU * rhox * dGamma;
1199 tmp += transJ * xix * H * dP;
1200 tmp += transJ * xi * Hx * dP;
1201 tmp += -transH * mux / mu * dP;
1202 dFdXsU[(nc + 1) * ncol2 + np + j * nc + k] += tmp;
1203 dFdXsD[(nc + 1) * ncol2 + np + j * nc + k] +=
1204 -transH * rhoWghtD * bk.
rhox[dId_np_j * nc + k] * dGamma;
1211 dFdXpB[(ncol - 1) * ncol] += conn.
AdktP[c * 2 + 0] * dT;
1212 dFdXpE[(ncol - 1) * ncol] += conn.
AdktP[c * 2 + 1] * dT;
1214 dFdXpB[ncol * ncol - 1] += conn.
Adkt[c] + conn.
AdktT[c * 2 + 0] * dT;
1215 dFdXpE[ncol * ncol - 1] += -conn.
Adkt[c] + conn.
AdktT[c * 2 + 1] * dT;
1217 for (
OCP_USI j = 0; j < np; j++) {
1218 dFdXsB[(nc + 1) * ncol2 + j] += conn.
AdktS[c * np + j] * dT;
1219 dFdXsE[(nc + 1) * ncol2 + j] += conn.
AdktS[c * np + np + j] * dT;
1224 DaABpbC(ncol, ncol, ncol2, 1, dFdXsB.data(), &bk.
dSec_dPri[bId * bsize2], 1,
1226 Dscalar(bsize, dt, bmat.data());
1230 Dscalar(bsize, -1, bmat.data());
1234 if (!
CheckNan(bmat.size(), &bmat[0])) {
1240 DaABpbC(ncol, ncol, ncol2, 1, dFdXsE.data(), &bk.
dSec_dPri[eId * bsize2], 1,
1242 Dscalar(bsize, dt, bmat.data());
1246 Dscalar(bsize, -1, bmat.data());
1250 if (!
CheckNan(bmat.size(), &bmat[0])) {
1264 switch (wl.WellType()) {
1266 AssembleMatInjWells(ls, rs.
bulk, wl, dt);
1269 AssembleMatProdWells(ls, rs.
bulk, wl, dt);
1286 const USI ncol = nc + 2;
1287 const USI ncol2 = np * nc + np;
1288 const USI bsize = ncol * ncol;
1289 const USI bsize2 = ncol * ncol2;
1292 vector<OCP_DBL> bmat(bsize, 0);
1293 vector<OCP_DBL> bmat2(bsize, 0);
1294 vector<OCP_DBL> dQdXpB(bsize, 0);
1295 vector<OCP_DBL> dQdXpW(bsize, 0);
1296 vector<OCP_DBL> dQdXsB(bsize2, 0);
1304 Hw = bk.
flashCal[0]->CalInjWellEnthalpy(wl.InjTemp(), &wl.InjZi()[0]);
1306 for (
USI p = 0; p < wl.PerfNum(); p++) {
1307 const OCP_USI n = wl.PerfLocation(p);
1308 fill(dQdXpB.begin(), dQdXpB.end(), 0.0);
1309 fill(dQdXpW.begin(), dQdXpW.end(), 0.0);
1310 fill(dQdXsB.begin(), dQdXsB.end(), 0.0);
1312 dP = bk.
P[n] - wl.BHP() - wl.DG(p);
1314 for (
USI j = 0; j < np; j++) {
1315 n_np_j = n * np + j;
1319 muP = bk.
muP[n_np_j];
1320 muT = bk.
muT[n_np_j];
1322 for (
USI i = 0; i < nc; i++) {
1325 if (!wl.IfUseUnweight()) {
1326 transIJ = wl.PerfTransj(p, j) * wl.PerfXi(p) * wl.InjZi(i);
1328 dQdXpB[(i + 1) * ncol] += transIJ * (1 - dP * muP / mu);
1329 dQdXpW[(i + 1) * ncol] += -transIJ;
1332 dQdXpB[(i + 2) * ncol - 1] += transIJ * (-dP * muT / mu);
1333 dQdXpW[(i + 2) * ncol - 1] += 0;
1336 transIJ = wl.PerfTransInj(p) * wl.PerfXi(p) * wl.InjZi(i);
1337 dQdXpB[(i + 1) * ncol] += transIJ;
1338 dQdXpW[(i + 1) * ncol] += -transIJ;
1341 if (!wl.IfUseUnweight()) {
1343 for (
USI k = 0; k < np; k++) {
1344 dQdXsB[(i + 1) * ncol2 + k] +=
1345 CONV1 * wl.PerfWI(p) * wl.PerfMultiplier(p) * wl.PerfXi(p) *
1346 wl.InjZi(i) * bk.
dKr_dS[n_np_j * np + k] * dP / mu;
1349 for (
USI k = 0; k < nc; k++) {
1350 dQdXsB[(i + 1) * ncol2 + np + j * nc + k] +=
1351 -transIJ * dP / mu * bk.
mux[n_np_j * nc + k];
1357 if (!wl.IfUseUnweight()) {
1358 transJ = wl.PerfTransj(p, j) * wl.PerfXi(p);
1360 dQdXpB[(nc + 1) * ncol] += transJ * Hw * (1 - dP * muP / mu);
1361 dQdXpW[(nc + 1) * ncol] += -transJ * Hw;
1364 dQdXpB[(nc + 2) * ncol - 1] += transJ * Hw * (-dP * muT / mu);
1365 dQdXpW[(nc + 2) * ncol - 1] += 0;
1368 for (
USI k = 0; k < np; k++) {
1369 dQdXsB[(nc + 1) * ncol2 + k] +=
1370 CONV1 * wl.PerfWI(p) * wl.PerfMultiplier(p) * wl.PerfXi(p) *
1371 bk.
dKr_dS[n_np_j * np + k] * dP / mu * Hw;
1374 for (
USI k = 0; k < nc; k++) {
1375 dQdXsB[(nc + 1) * ncol2 + np + j * nc + k] +=
1376 -transJ * dP / mu * bk.
mux[n_np_j * nc + k] * Hw;
1379 transJ = wl.PerfTransInj(p) * wl.PerfXi(p);
1381 dQdXpB[(nc + 1) * ncol] += transJ * Hw;
1382 dQdXpW[(nc + 1) * ncol] += -transJ * Hw;
1385 if (wl.IfUseUnweight())
break;
1392 Dscalar(bsize, dt, bmat.data());
1398 Dscalar(bsize, dt, bmat.data());
1402 switch (wl.OptMode()) {
1409 fill(bmat.begin(), bmat.end(), 0.0);
1410 for (
USI i = 0; i < nc; i++) {
1411 bmat[0] += dQdXpW[(i + 1) * ncol];
1412 bmat[(i + 1) * ncol + i + 1] = 1;
1414 bmat[ncol * ncol - 1] = 1;
1421 fill(bmat2.begin(), bmat2.end(), 0.0);
1422 for (
USI i = 0; i < nc; i++) {
1423 Daxpy(ncol, 1.0, bmat.data() + (i + 1) * ncol, bmat2.data());
1430 fill(bmat.begin(), bmat.end(), 0.0);
1431 for (
USI i = 0; i < ncol; i++) {
1432 bmat[i * ncol + i] = 1;
1437 fill(bmat.begin(), bmat.end(), 0.0);
1456 const USI ncol = nc + 2;
1457 const USI ncol2 = np * nc + np;
1458 const USI bsize = ncol * ncol;
1459 const USI bsize2 = ncol * ncol2;
1462 vector<OCP_DBL> bmat(bsize, 0);
1463 vector<OCP_DBL> bmat2(bsize, 0);
1464 vector<OCP_DBL> dQdXpB(bsize, 0);
1465 vector<OCP_DBL> dQdXpW(bsize, 0);
1466 vector<OCP_DBL> dQdXsB(bsize2, 0);
1468 OCP_DBL xij, xi, xiP, xiT, mu, muP, muT, dP, transIJ, transJ, H, HT, Hx, tmp;
1476 for (
USI p = 0; p < wl.PerfNum(); p++) {
1477 const OCP_USI n = wl.PerfLocation(p);
1478 fill(dQdXpB.begin(), dQdXpB.end(), 0.0);
1479 fill(dQdXpW.begin(), dQdXpW.end(), 0.0);
1480 fill(dQdXsB.begin(), dQdXsB.end(), 0.0);
1482 for (
USI j = 0; j < np; j++) {
1483 n_np_j = n * np + j;
1486 dP = bk.
Pj[n_np_j] - wl.BHP() - wl.DG(p);
1489 xiP = bk.
xiP[n_np_j];
1490 xiT = bk.
xiT[n_np_j];
1491 muP = bk.
muP[n_np_j];
1492 muT = bk.
muT[n_np_j];
1497 for (
USI i = 0; i < nc; i++) {
1498 xij = bk.
xij[n_np_j * nc + i];
1499 Hx = bk.
Hx[n_np_j * nc + i];
1501 transIJ = wl.PerfTransj(p, j) * xi * xij;
1502 dQdXpB[(i + 1) * ncol] += transIJ * (1 - dP * muP / mu) +
1503 dP * wl.PerfTransj(p, j) * xij * xiP;
1504 dQdXpW[(i + 1) * ncol] += -transIJ;
1507 dQdXpB[(i + 2) * ncol - 1] +=
1508 transIJ * (-dP * muT / mu) + dP * wl.PerfTransj(p, j) * xij * xiT;
1509 dQdXpW[(i + 2) * ncol - 1] += 0;
1512 for (
USI k = 0; k < np; k++) {
1513 tmp =
CONV1 * wl.PerfWI(p) * wl.PerfMultiplier(p) * dP / mu * xi *
1514 xij * bk.
dKr_dS[n_np_j * np + k];
1516 tmp += transIJ * bk.
dPcj_dS[n_np_j * np + k];
1517 dQdXsB[(i + 1) * ncol2 + k] += tmp;
1520 for (
USI k = 0; k < nc; k++) {
1521 tmp = dP * wl.PerfTransj(p, j) * xij *
1522 (bk.
xix[n_np_j * nc + k] - xi / mu * bk.
mux[n_np_j * nc + k]);
1523 dQdXsB[(i + 1) * ncol2 + np + j * nc + k] += tmp;
1525 dQdXsB[(i + 1) * ncol2 + np + j * nc + i] +=
1526 wl.PerfTransj(p, j) * xi * dP;
1530 transJ = wl.PerfTransj(p, j) * xi;
1532 dQdXpB[(nc + 1) * ncol] +=
1533 transJ * (1 - dP * muP / mu) * H + dP * wl.PerfTransj(p, j) * xiP * H;
1534 dQdXpW[(nc + 1) * ncol] += -transJ * H;
1537 dQdXpB[(nc + 2) * ncol - 1] += transJ * (-dP * muT / mu) * H +
1538 dP * wl.PerfTransj(p, j) * xiT * H +
1540 dQdXpW[(nc + 2) * ncol - 1] += 0;
1543 for (
USI k = 0; k < np; k++) {
1544 tmp =
CONV1 * wl.PerfWI(p) * wl.PerfMultiplier(p) * dP / mu * xi *
1545 bk.
dKr_dS[n_np_j * np + k] * H;
1547 tmp += transJ * bk.
dPcj_dS[n_np_j * np + k] * H;
1548 dQdXsB[(nc + 1) * ncol2 + k] += tmp;
1552 for (
USI k = 0; k < nc; k++) {
1554 dP * wl.PerfTransj(p, j) *
1555 (bk.
xix[n_np_j * nc + k] - xi / mu * bk.
mux[n_np_j * nc + k]) *
1558 dQdXsB[(nc + 1) * ncol2 + np + j * nc + k] += tmp;
1566 Dscalar(bsize, dt, bmat.data());
1571 Dscalar(bsize, dt, bmat.data());
1575 switch (wl.OptMode()) {
1582 fill(bmat.begin(), bmat.end(), 0.0);
1583 for (
USI i = 0; i < nc; i++) {
1584 bmat[0] += dQdXpW[(i + 1) * ncol] * wl.ProdWeight(i);
1585 bmat[(i + 1) * ncol + i + 1] = 1;
1587 bmat[ncol * ncol - 1] = 1;
1594 fill(bmat2.begin(), bmat2.end(), 0.0);
1595 for (
USI i = 0; i < nc; i++) {
1596 Daxpy(ncol, wl.ProdWeight(i), bmat.data() + (i + 1) * ncol,
1604 fill(bmat.begin(), bmat.end(), 0.0);
1605 for (
USI i = 0; i < ncol; i++) {
1606 bmat[i * ncol + i] = 1;
1611 fill(bmat.begin(), bmat.end(), 0.0);
1624 const vector<OCP_DBL>& u,
1636 const USI row = np * (nc + 1);
1637 const USI col = nc + 2;
1638 vector<OCP_DBL> dtmp(row, 0);
1648 for (
OCP_USI n = 0; n < nb; n++) {
1651 if (bk.
bType[n] > 0) {
1656 fill(dtmp.begin(), dtmp.end(), 0.0);
1660 for (
USI j = 0; j < np; j++) {
1662 if (fabs(dtmp[j]) > dSmaxlim) {
1663 choptmp = dSmaxlim / fabs(dtmp[j]);
1664 }
else if (bk.
S[n * np + j] + dtmp[j] < 0.0) {
1665 choptmp = 0.9 * bk.
S[n * np + j] / fabs(dtmp[j]);
1667 chopmin = min(chopmin, choptmp);
1671 for (
USI j = 0; j < np; j++) {
1672 bk.
dSNRP[n * np + j] = chopmin * dtmp[j];
1673 bk.
S[n * np + j] += bk.
dSNRP[n * np + j];
1684 for (
USI i = 0; i < nc; i++) {
1685 bk.
dNNR[n * nc + i] = u[n * col + 1 + i] * chopmin;
1686 if (fabs(bk.
NRdNmax) < fabs(bk.
dNNR[n * nc + i]) / bk.
Nt[n])
1689 bk.
Ni[n * nc + i] += bk.
dNNR[n * nc + i];
1694 OCP_DBL dT = u[n * col + col - 1];
1704 wl.SetBHP(wl.BHP() + u[wId]);
void DaABpbC(const int &m, const int &n, const int &k, const double &alpha, const double *A, const double *B, const double &beta, double *C)
Computes C' = alpha B'A' + beta C', all matrices are column-major.
void Dscalar(const int &n, const double &alpha, double *x)
Scales a vector by a constant.
void DaAxpby(const int &m, const int &n, const double &a, const double *A, const double *x, const double &b, double *y)
Computes y = a A x + b y.
bool CheckNan(const int &N, const T *x)
check NaN
void Daxpy(const int &n, const double &alpha, const double *x, double *y)
Constant times a vector plus a vector.
void Dcopy(const int &N, double *dst, const double *src)
Calculate the minimal eigenvalue for symmetric matrix with mkl lapack.
const USI VECTORFASP
Use vector linear solver in Fasp.
unsigned int USI
Generic unsigned integer.
double OCP_DBL
Double precision.
const OCP_DBL CONV1
1 bbl = CONV1 ft3
const OCP_DBL GRAVITY_FACTOR
0.00694444 ft2 psi / lb
const USI LRATE_MODE
Well option = fixed fluid rate???
const USI WRATE_MODE
Well option = fixed water rate.
const USI ORATE_MODE
Well option = fixed oil rate.
const USI RATE_MODE
Well option = fixed total rate???
unsigned int OCP_USI
Long unsigned integer.
const USI PROD
Well type = producer.
const USI INJ
Well type = injector.
const USI BHP_MODE
Well option = fixed bottom-hole-pressure.
unsigned int OCP_BOOL
OCP_BOOL in OCP.
const USI GRATE_MODE
Well option = fixed gas rate.
const OCP_DBL CONV2
Darcy constant in field unit.
ThermalMethod class declaration.
#define OCP_ABORT(msg)
Abort if critical error happens.
void CalFlux(const Bulk &myBulk)
Calculate volume flow rate and moles flow rate of each perforation.
vector< Well > wells
well set.
void CalTrans(const Bulk &myBulk)
Calculate Transmissibility of Wells.
void CaldG(const Bulk &myBulk)
Calculate dG.
void InitBHP(const Bulk &myBulk)
Set the initial well pressure.
void PrepareWell(const Bulk &myBulk)
Calculate well properties at the beginning of each time step.
Properties and operations on connections between bulks (active grids).
OCP_USI numConn
Number of connections between bulks.
vector< OCP_USI > upblock
Index of upwinding bulk of connections : numConn * numPhase.
vector< OCP_DBL > upblock_Rho
Mass density of phase from upblock: numConn * numPhase.
vector< OCP_DBL > AdktP
d Adkt / d P, order: connections -> bId.P -> eId.P
vector< OCP_DBL > lAdkt
last Adkt
vector< OCP_DBL > AdktS
d Adkt / d S, order: connections -> bId.phase -> eId.phase
vector< OCP_DBL > upblock_Velocity
vector< OCP_DBL > AdktT
d Adkt / d T, order: connections -> bId.T -> eId.T
vector< OCP_DBL > lAdktS
last AdktS
vector< OCP_DBL > Adkt
Thermal conductivity between neighbors.
vector< BulkPair > iteratorConn
All connections (pair of indices) between bulks: numConn.
vector< OCP_DBL > lAdktP
last AdktP
vector< OCP_DBL > lAdktT
last AdktT
Physical information of each active reservoir bulk.
vector< OCP_DBL > mu
Viscosity of phase: numPhase*numBulk.
vector< USI > pVnumCom
num of variable components in the phase
vector< OCP_DBL > dNNR
Ni change between NR steps.
vector< OCP_DBL > lP
last P
vector< OCP_DBL > lS
last S
vector< OCP_DBL > lkt
last kt
vector< OCP_DBL > UfP
d Uf / d P: numbulk
vector< OCP_DBL > NRstep
NRstep for FIM.
vector< Rock * > rock
rock model
vector< OCP_DBL > Pc
Capillary pressure of phase: numPhase*numBulk.
vector< FlowUnit * > flow
Vector for capillary pressure, relative perm.
vector< OCP_DBL > vrP
d vr / d p, numbulk
vector< OCP_DBL > ldPcj_dS
last Pcj_dS
vector< OCP_DBL > lNt
last Nt
USI numPhase
Number of phase.
vector< OCP_DBL > lvf
last vf
vector< OCP_DBL > T
Temperature: numBulk.
vector< OCP_DBL > S
Saturation of phase: numPhase*numBulk.
vector< USI > bLocation
Location of bulk: top, bottom, side.
vector< OCP_DBL > lporoT
last poroT.
vector< OCP_DBL > rho
Mass density of phase: numPhase*numBulk.
vector< OCP_DBL > kt
Coefficient of thermal diffusivity: activeGridNum.
vector< OCP_DBL > ktP
d kt / d P: numbulk
OCPRes res
Residual for all equations.
vector< OCP_DBL > dSec_dPri
d Secondary variable / d Primary variable.
vector< OCP_DBL > lxij
last xij
vector< OCP_DBL > rhoP
d Rho / d P: numPhase*numBulk.
vector< OCP_DBL > ntg
net to gross of bulk.
vector< OCP_DBL > dy
Size of cell in y-direction: activeGridNum.
vector< OCP_DBL > lrho
last rho
vector< USI > PVTNUM
Identify PVT region in black-oil model: numBulk.
vector< USI > lphaseNum
last phaseNum
vector< OCP_DBL > vfi
d vf / d Ni: numCom*numBulk.
vector< OCP_DBL > lHrT
Last HrT.
vector< OCP_DBL > lHx
last Hx
vector< USI > lpVnumCom
last pVnumCom
vector< OCP_DBL > poro
rock porosity * ntg.
vector< OCP_DBL > xij
Nij / Nj: numPhase*numCom*numBulk.
vector< OCP_DBL > Ufi
d Uf / d Ni: numCom * numBulk
vector< OCP_DBL > lrockVp
Pore volume: numBulk.
vector< OCP_DBL > kr
Relative permeability of phase: numPhase*numBulk.
vector< USI > SATNUM
Identify SAT region: numBulk.
vector< OCP_DBL > depth
Depth of center of grid cells: activeGridNum.
vector< OCP_DBL > rockVp
pore volume = Vgrid * ntg * poro.
vector< OCP_DBL > Ni
Moles of component: numCom*numBulk.
OCP_DBL NRdPmax
Max pressure difference in an NR step.
vector< OCP_DBL > Pj
Pressure of phase: numPhase*numBulk.
vector< OCP_DBL > mux
d Muj / d xij: numPhase*numCom*numBulk.
vector< OCP_DBL > rhox
d Rhoj / d xij: numPhase*numCom*numBulk.
vector< OCP_DBL > lHr
Last Hr: activeGridNum.
vector< OCP_DBL > lporoP
last poroP.
vector< OCP_DBL > lUfP
last UfP
OCP_USI index_maxNRdSSP
index of grid which has maxNRdSSP
vector< OCP_DBL > lrhoT
last rhoT
vector< OCP_DBL > lkr
last kr
vector< OCP_DBL > dSNR
saturation change between NR steps
vector< OCP_DBL > lvfi
last vfi
vector< OCP_DBL > lporo
last poro.
OCP_DBL maxNRdSSP
max difference between dSNR and dSNRP
vector< OCP_DBL > vfT
d vf / d T, numBulk
vector< OCP_DBL > lHT
last HT
HeatLoss hLoss
Heat loss iterm.
vector< OCP_DBL > lvfT
last vfT
vector< OCP_DBL > lmuT
last muT
vector< OCP_DBL > Nt
Total moles of components in bulks: numBulk.
vector< OCP_DBL > muP
d Mu / d P: numPhase*numBulk.
vector< OCP_DBL > Hx
d Hj / d xij: numPhase * numCom * numbulk
vector< OCP_DBL > xiT
d xij / d T, numPhase * numbulk
vector< OCP_DBL > poroT
d poro / d T.
vector< OCP_DBL > thconr
Rock ifThermal conductivity: activeGridNum.
vector< OCP_DBL > dKr_dS
d Krj / d Sk: numPhase * numPhase * bulk.
vector< OCP_DBL > lT
last T
vector< OCP_DBL > lUfT
last UfT
vector< OCP_DBL > UfT
d Uf / d T: numbulk
vector< Mixture * > flashCal
Flash calculation class.
vector< OCP_BOOL > phaseExist
Existence of phase: numPhase*numBulk.
vector< OCP_DBL > lktS
last ktS
vector< OCP_DBL > lPj
last Pj
vector< OCP_DBL > lUf
last Uf
vector< OCP_DBL > lktT
last ktT
vector< OCP_DBL > xiP
d xi / d P: numPhase*numBulk.
vector< OCP_DBL > rhoT
d rhoj / d T: numPhase * numbulk
vector< OCP_DBL > poroP
d poro / d P.
vector< OCP_DBL > lvrP
last vrp.
vector< OCP_DBL > lktP
last ktP
vector< OCP_DBL > vrT
dvr / dT: activeGridNum.
vector< OCP_DBL > ldKr_dS
last dKr_dS
vector< OCP_DBL > Uf
Internal energy of fluid: numBulk.
vector< OCP_DBL > lUfi
last Ufi
vector< OCP_DBL > lrhoP
last rhoP
vector< OCP_DBL > xi
Moles density of phase: numPhase*numBulk.
vector< OCP_DBL > lxi
last xi
vector< OCP_DBL > lmux
last mux
vector< OCP_DBL > vf
Total fluid volume: numBulk.
OCP_DBL NRdTmax
Max temperature difference in an NR step.
vector< USI > phaseNum
Num of hydrocarbon phase in each bulk.
vector< USI > bRowSizedSdP
length of dSec_dPri in each bulk
vector< OCP_DBL > vfP
d vf / d P: numBulk.
OCP_DBL NRdNmax
Max Ni difference in an NR step.
vector< OCP_DBL > lxiT
last xiT
vector< OCP_DBL > lxix
last xix
vector< USI > bType
Indicate bulk type, 0: rock, 1: rock and fluid.
vector< OCP_DBL > dPNR
P change between NR steps.
vector< OCP_DBL > lmuP
last muP
vector< OCP_DBL > ktT
d kt / d T: activeGridNum.
vector< OCP_DBL > lvrT
Last vrT.
vector< OCP_DBL > ktS
d kt / d S: numPhase * numbulk
vector< OCP_DBL > muT
d muj / d T: numPhase * numbulk
vector< OCP_DBL > lvfP
last vfP
vector< OCP_DBL > Pb
Bubble point pressure: numBulk.
vector< OCP_DBL > lrhox
last rhox
vector< OCP_BOOL > lphaseExist
last phaseExist
vector< OCP_DBL > Hr
Enthalpy of rock: activeGridNum.
vector< OCP_DBL > v
Volume of grids: activeGridNum.
vector< OCP_DBL > dSNRP
predicted saturation change between NR steps
void InitPTSw(const USI &tabrow)
Calculate initial equilibrium – hydrostatic equilibration.
vector< OCP_DBL > lxiP
last xiP
vector< OCP_BOOL > lpSderExist
last pSderExist
vector< OCP_DBL > HT
d Hj / d T: numPhase * numbulk
vector< OCP_DBL > lmu
last mu
vector< OCP_BOOL > pSderExist
Existence of derivative of phase saturation.
OCP_USI numBulk
Number of bulks (active grids).
vector< USI > NRphaseNum
phaseNum in NR step
vector< OCP_DBL > poroInit
initial rock porosity * ntg.
vector< OCP_DBL > thconp
Phase thermal conductivity: numPhase.
vector< OCP_DBL > ldSec_dPri
last dSec_dPri
vector< OCP_DBL > xix
d Xi_j / d xij: numPhase*numCom*numBulk.
vector< USI > ROCKNUM
index of Rock table for each bulk
vector< OCP_DBL > dx
Size of cell in x-direction: activeGridNum.
vector< OCP_DBL > H
Enthalpy of phase: numPhase*numBulk.
vector< OCP_DBL > dTNR
T change between NR steps.
vector< OCP_DBL > dPcj_dS
d Pcj / d Sk: numPhase * numPhase * bulk.
vector< OCP_DBL > HrT
dHr / dT: activeGridNum.
vector< OCP_DBL > initT
Initial temperature of each bulk: numBulk.
vector< USI > lbRowSizedSdP
last bRowSizedSdP
vector< OCP_DBL > vr
Volume of rock: activeGridNum.
vector< OCP_DBL > P
Pressure: numBulk.
vector< OCP_DBL > lNi
last Ni
vector< OCP_DBL > lPc
last Pc
vector< OCP_DBL > lvr
Last vr: activeGridNum.
USI maxLendSdP
length of dSec_dPri.
USI numCom
Number of component.
vector< OCP_DBL > lH
last H
OCP_DBL NRtol
Maximum non-linear convergence error.
OCP_DBL NRdSmin
Minimum Saturation change in a Newton iteration.
USI maxNRiter
Maximum number of Newton iterations in a time step.
OCP_DBL NRdSmax
Maximum Saturation change in a Newton iteration.
OCP_DBL NRdPmin
Minimum Pressure change in a Newton iteration.
OCP_DBL cutFacNR
Factor by which time step is cut after convergence failure.
Get elapsed wall-time in millisecond.
__inline__ double Stop() const
Stop the timer and return duration from start() in ms.
__inline__ void Start()
Start the timer.
vector< OCP_DBL > pT
dP / dT
OCP_DBL ubD
Thermal diffusivity of underburden rock.
OCP_DBL ubK
Thermal conductivity of underburden rock.
vector< OCP_DBL > p
Auxiliary variable.
OCP_DBL obD
Thermal diffusivity of overburden rock.
OCP_DBL obK
Thermal conductivity of overburden rock.
Linear solvers for discrete systems.
USI GetNumIters()
Return the number of iterations.
void AssembleMatLinearSolver()
Assemble Mat for Linear Solver.
void AllocateColMem(const vector< USI > &bulk2bulk, const vector< vector< OCP_USI >> well2bulk)
Allocate memory for linear system with max possible number of columns.
void AddDiag(const OCP_USI &n, const OCP_DBL &v)
Add a value at diagonal value.
void AssembleRhsCopy(const vector< OCP_DBL > &rhs)
Assign Rhs by Copying.
void AllocateRowMem(const OCP_USI &dimMax, const USI &nb)
Allocate memory for linear system with max possible number of rows.
void NewDiag(const OCP_USI &n, const OCP_DBL &v)
Push back a diagonal val, which is always at the first location.
void ClearData()
Clear the internal matrix data for scalar-value problems.
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.
void CheckEquation() const
Check whether NAN or INF occurs in equations, used in debug mode.
vector< OCP_DBL > & GetSolution()
Return the solution.
void SetupLinearSolver(const USI &i, const string &dir, const string &file)
Setup LinearSolver.
void CheckSolution() const
Check whether NAN or INF occurs in solutions, used in debug mode.
All control parameters except for well controllers.
string GetWorkDir() const
Return work dir name.
OCP_DBL GetCurDt() const
Return current time step size.
void UpdateIterNR()
Update the number of Newton iterations.
void UpdateIters()
Update the number of iterations.
void ResetIterNRLS()
Reset the number of iterations.
string GetLsFile() const
Return linear solver file name.
void UpdateIterLS(const USI &num)
Update the number of linear iterations.
OCP_DBL GetCurTime() const
Return the current time.
void RecordTimeLS(const OCP_DBL &t)
Record time used for linear solver.
OCP_INT maxId_E
index of bulk who has maxRelRes_E
OCP_DBL maxRelRes_E
maximum relative residual wrt. total energy for each bulk
OCP_DBL maxWellRelRes_mol
maximum relative residual wrt. total moles for each well
OCP_INT maxId_N
index of bulk who has maxRelRes_N
OCP_INT maxId_V
index of bulk who has maxRelRes_V
vector< OCP_DBL > resAbs
residual for all equations for each bulk
OCP_DBL maxRelRes_N
maximum relative residual wrt. total moles for each bulk
BulkConn conn
Bulk's connection info.
OCP_DBL GetNRdSmax(OCP_USI &index)
Return NRdSmax.
OptionalFeatures optFeatures
optional features.
USI GetWellNum() const
Return the num of Well.
OCP_DBL GetNRdPmax()
Return NRdPmax.
void CalMaxChange()
Calculate Maximum Change of some reference variables for IMPEC.
USI GetComNum() const
Return the num of Components.
Bulk bulk
Active grid info.
AllWells allWells
Wells class info.
void CalIPRT(const OCP_DBL &dt)
Calculate num of Injection, Production.
OCP_USI GetBulkNum() const
Return the num of Bulk.
OCP_BOOL IsOpen() const
Return the state of the well, Open or Close.
void CalProdWeight(const Bulk &myBulk) const
Calculate the production weight.