17 if (Optparam.
type ==
"INJ") {
19 }
else if (Optparam.
type ==
"PROD") {
27 if (fluidType ==
"WAT" || fluidType ==
"WATER") {
32 if (Optparam.
state ==
"OPEN") {
34 }
else if (Optparam.
state ==
"CLOSE") {
40 if (Optparam.
optMode ==
"RATE") {
42 }
else if (Optparam.
optMode ==
"ORAT") {
44 }
else if (Optparam.
optMode ==
"GRAT") {
46 }
else if (Optparam.
optMode ==
"WRAT") {
48 }
else if (Optparam.
optMode ==
"LRAT") {
50 }
else if (Optparam.
optMode ==
"BHP") {
56 initOptMode = optMode;
65 if (this->type != Opt.type)
return true;
66 if (this->state != Opt.state)
return true;
67 if (this->optMode != Opt.optMode)
return true;
68 if (this->initOptMode != Opt.initOptMode)
return true;
69 if (this->maxRate != Opt.maxRate)
return true;
70 if (this->maxBHP != Opt.maxBHP)
return true;
71 if (this->minBHP != Opt.minBHP)
return true;
72 for (
USI i = 0; i < zi.size(); i++) {
73 if (fabs(zi[i] - Opt.zi[i]) >
TINY)
return true;
83 numPerf = well.
I_perf.size();
85 for (
USI p = 0; p < numPerf; p++) {
86 perf[p].I = well.
I_perf[p] - 1;
87 perf[p].J = well.
J_perf[p] - 1;
88 perf[p].K = well.
K_perf[p] - 1;
89 perf[p].WI = well.
WI[p];
90 perf[p].radius = well.
diameter[p] / 2.0;
91 perf[p].kh = well.kh[p];
100 OCP_ABORT(
"Wrong direction of perforations!");
108 qi_lbmol.resize(myBulk.numCom);
109 prodWeight.resize(myBulk.numCom);
111 Mtype = myBulk.flashCal[0]->GetType();
113 if (myBulk.blackOil) {
114 for (
auto& opt : optSet) {
116 if (!opt.state)
continue;
118 opt.zi.resize(myBulk.numCom, 0);
119 if (opt.type ==
INJ) {
121 switch (myBulk.PVTmode) {
128 if (opt.fluidType ==
"GAS")
138 switch (myBulk.PVTmode) {
157 opt.zi[2] = opt.zi[0] = 1;
164 }
else if (myBulk.comps) {
166 USI len = sols.size();
168 for (
auto& opt : optSet) {
170 if (!opt.state)
continue;
172 if (opt.type ==
INJ) {
174 if (opt.fluidType ==
"WAT") {
175 opt.zi.resize(myBulk.numCom, 0);
178 for (
USI i = 0; i < len; i++) {
179 if (opt.fluidType == sols[i].name) {
180 opt.zi = sols[i].data;
181 opt.zi.resize(myBulk.numCom);
184 opt.xiINJ = myBulk.flashCal[0]->XiPhase(
207 for (
USI p = 0; p < numPerf; p++) {
209 perf[p].K * myGrid.nx * myGrid.ny + perf[p].J * myGrid.nx + perf[p].I;
210 if (myGrid.activeMap_G2B[Idg].IsAct()) {
213 perf[pp].state =
OPEN;
214 perf[pp].location = myGrid.activeMap_G2B[Idg].GetId();
215 perf[pp].depth = myBulk.depth[perf[pp].location];
216 perf[pp].multiplier = 1;
217 perf[pp].qi_lbmol.resize(myBulk.numCom);
218 perf[pp].transj.resize(myBulk.numPhase);
219 perf[pp].qj_ft3.resize(myBulk.numPhase);
226 perf.resize(numPerf);
228 dG.resize(numPerf, 0);
231 if (depth < 0) depth = perf[0].depth;
247 for (
USI p = 0; p < numPerf; p++) {
248 if (perf[p].WI > 0) {
251 OCP_USI Idb = perf[p].location;
254 OCP_DBL dz = myBulk.dz[Idb] * myBulk.ntg[Idb];
256 switch (perf[p].direction) {
258 OCP_DBL kykz = myBulk.rockKy[Idb] * myBulk.rockKz[Idb];
259 OCP_DBL ky_kz = myBulk.rockKy[Idb] / myBulk.rockKz[Idb];
263 pow((dy * dy * pow(1 / ky_kz, 0.5) + dz * dz * pow(ky_kz, 0.5)),
265 ro /= (pow(ky_kz, 0.25) + pow(1 / ky_kz, 0.25));
267 if (perf[p].kh < 0) {
268 perf[p].kh = (dx * pow(kykz, 0.5));
273 OCP_DBL kzkx = myBulk.rockKz[Idb] * myBulk.rockKx[Idb];
274 OCP_DBL kz_kx = myBulk.rockKz[Idb] / myBulk.rockKx[Idb];
278 pow((dz * dz * pow(1 / kz_kx, 0.5) + dx * dx * pow(kz_kx, 0.5)),
280 ro /= (pow(kz_kx, 0.25) + pow(1 / kz_kx, 0.25));
282 if (perf[p].kh < 0) {
283 perf[p].kh = (dy * pow(kzkx, 0.5));
288 OCP_DBL kxky = myBulk.rockKx[Idb] * myBulk.rockKy[Idb];
289 OCP_DBL kx_ky = myBulk.rockKx[Idb] / myBulk.rockKy[Idb];
293 pow((dx * dx * pow(1 / kx_ky, 0.5) + dy * dy * pow(kx_ky, 0.5)),
295 ro /= (pow(kx_ky, 0.25) + pow(1 / kx_ky, 0.25));
297 if (perf[p].kh < 0) {
298 perf[p].kh = (dz * pow(kxky, 0.5));
303 OCP_ABORT(
"Wrong direction of perforations!");
305 perf[p].WI =
CONV2 * (2 *
PI) * perf[p].kh /
306 (log(ro / perf[p].radius) + perf[p].skinFactor);
315 const USI np = myBulk.numPhase;
317 if (opt.type ==
INJ) {
318 for (
USI p = 0; p < numPerf; p++) {
319 perf[p].transINJ = 0;
324 for (
USI j = 0; j < np; j++) {
325 perf[p].transj[j] = 0;
327 if (myBulk.phaseExist[
id]) {
328 perf[p].transj[j] = temp * myBulk.kr[id] / myBulk.mu[id];
329 perf[p].transINJ += perf[p].transj[j];
334 for (
USI p = 0; p < numPerf; p++) {
339 for (
USI j = 0; j < np; j++) {
340 perf[p].transj[j] = 0;
342 if (myBulk.phaseExist[
id]) {
343 perf[p].transj[j] = temp * myBulk.kr[id] / myBulk.mu[id];
379 const USI np = myBulk.numPhase;
380 const USI nc = myBulk.numCom;
381 fill(qi_lbmol.begin(), qi_lbmol.end(), 0.0);
383 if (opt.type ==
INJ) {
385 for (
USI p = 0; p < numPerf; p++) {
386 perf[p].P = BHP + dG[p];
388 OCP_DBL dP = perf[p].P - myBulk.P[k];
391 perf[p].qt_ft3 = perf[p].transINJ * dP;
394 USI pvtnum = myBulk.PVTNUM[k];
396 myBulk.flashCal[pvtnum]->XiPhase(myBulk.P[k], myBulk.T, &opt.zi[0]);
400 for (
USI i = 0; i < nc; i++) {
401 perf[p].qi_lbmol[i] = perf[p].qt_ft3 * xi * opt.zi[i];
402 qi_lbmol[i] += perf[p].qi_lbmol[i];
407 for (
USI p = 0; p < numPerf; p++) {
408 perf[p].P = BHP + dG[p];
411 fill(perf[p].qi_lbmol.begin(), perf[p].qi_lbmol.end(), 0.0);
412 fill(perf[p].qj_ft3.begin(), perf[p].qj_ft3.end(), 0.0);
414 for (
USI j = 0; j < np; j++) {
416 if (myBulk.phaseExist[
id]) {
417 OCP_DBL dP = myBulk.Pj[id] - perf[p].P;
419 perf[p].qj_ft3[j] = perf[p].transj[j] * dP;
420 perf[p].qt_ft3 += perf[p].qj_ft3[j];
426 for (
USI i = 0; i < nc; i++) {
427 xij = myBulk.xij[
id * nc + i];
428 perf[p].qi_lbmol[i] += perf[p].qj_ft3[j] * xi * xij;
445 for (
USI i = 0; i < nc; i++) qi_lbmol[i] += perf[p].qi_lbmol[i];
465 OCP_DBL Pwell = maxBHP ? opt.maxBHP : BHP;
467 for (
USI p = 0; p < numPerf; p++) {
472 OCP_DBL dP = Pperf - myBulk.P[k];
473 qj += perf[p].transINJ * perf[p].xi * dP;
485 const USI np = myBulk.numPhase;
486 const USI nc = myBulk.numCom;
488 OCP_DBL Pwell = minBHP ? opt.minBHP : BHP;
490 for (
USI p = 0; p < numPerf; p++) {
495 for (
USI j = 0; j < np; j++) {
497 if (myBulk.phaseExist[
id]) {
499 for (
USI i = 0; i < nc; i++) {
500 temp += prodWeight[i] * myBulk.xij[
id * nc + i];
503 OCP_DBL dP = myBulk.Pj[id] - Pperf;
504 qj += perf[p].transj[j] * xi * dP * temp;
515 const USI nc = myBulk.numCom;
518 for (
USI i = 0; i < nc; i++) {
521 if (opt.fluidType ==
"WAT") {
529 WGIR = -qj / (opt.xiINJ * 1000);
550 USI nc = myBulk.numCom;
552 WOPR = qt * factor[0];
553 WGPR = qt * factor[1];
554 WWPR = qi_lbmol[nc - 1];
561 const USI nc = myBulk.numCom;
563 for (
USI i = 0; i < nc; i++) {
564 if (myBulk.index2Phase[i] ==
OIL) {
566 }
else if (myBulk.index2Phase[i] ==
GAS) {
568 }
else if (myBulk.index2Phase[i] ==
WATER) {
615 vector<OCP_DBL> dGperf(numPerf, 0);
617 if (depth <= perf.front().depth) {
619 for (
OCP_INT p = numPerf - 1; p >= 0; p--) {
621 seg_num = ceil(fabs((perf[0].depth - depth) / maxlen));
622 if (seg_num == 0)
continue;
623 seg_len = (perf[0].depth - depth) / seg_num;
625 seg_num = ceil(fabs((perf[p].depth - perf[p - 1].depth) / maxlen));
626 if (seg_num == 0)
continue;
627 seg_len = (perf[p].depth - perf[p - 1].depth) / seg_num;
630 perf[p].P = BHP + dG[p];
634 USI pvtnum = myBulk.PVTNUM[n];
635 for (
USI i = 0; i < seg_num; i++) {
637 myBulk.flashCal[pvtnum]->RhoPhase(Ptmp, myBulk.T, opt.zi.data()) *
640 dGperf[p] = Pperf - Ptmp;
643 for (
USI p = 1; p < numPerf; p++) {
644 dG[p] = dG[p - 1] + dGperf[p];
646 }
else if (depth >= perf[numPerf - 1].depth) {
648 for (
USI p = 0; p < numPerf; p++) {
649 if (p == numPerf - 1) {
650 seg_num = ceil(fabs((depth - perf[numPerf - 1].depth) / maxlen));
651 if (seg_num == 0)
continue;
652 seg_len = (depth - perf[numPerf - 1].depth) / seg_num;
654 seg_num = ceil(fabs((perf[p + 1].depth - perf[p].depth) / maxlen));
655 if (seg_num == 0)
continue;
656 seg_len = (perf[p + 1].depth - perf[p].depth) / seg_num;
659 perf[p].P = BHP + dG[p];
663 USI pvtnum = myBulk.PVTNUM[n];
664 for (
USI i = 0; i < seg_num; i++) {
666 myBulk.flashCal[pvtnum]->RhoPhase(Ptmp, myBulk.T, opt.zi.data()) *
669 dGperf[p] = Ptmp - Pperf;
671 dG[numPerf - 1] = dGperf[numPerf - 1];
672 for (
OCP_INT p = numPerf - 2; p >= 0; p--) {
673 dG[p] = dG[p + 1] + dGperf[p];
682 const USI np = myBulk.numPhase;
683 const USI nc = myBulk.numCom;
687 vector<OCP_DBL> tmpNi(nc, 0);
688 vector<OCP_DBL> dGperf(numPerf, 0);
693 if (depth <= perf.front().depth) {
697 if (perf[numPerf - 1].state ==
CLOSE) {
698 for (
OCP_INT p = numPerf - 2; p >= 0; p--) {
699 if (perf[p].state ==
OPEN) {
700 for (
USI i = 0; i < nc; i++) {
701 perf[numPerf - 1].qi_lbmol[i] = perf[p].qi_lbmol[i];
708 for (
OCP_INT p = numPerf - 1; p >= 0; p--) {
711 seg_num = ceil(fabs((perf[0].depth - depth) / maxlen));
712 if (seg_num == 0)
continue;
713 seg_len = (perf[0].depth - depth) / seg_num;
715 seg_num = ceil(fabs((perf[p].depth - perf[p - 1].depth) / maxlen));
716 if (seg_num == 0)
continue;
717 seg_len = (perf[p].depth - perf[p - 1].depth) / seg_num;
721 perf[p].P = BHP + dG[p];
725 USI pvtnum = myBulk.PVTNUM[n];
733 for (
USI i = 0; i < nc; i++) {
734 tmpNi[i] += perf[p].qi_lbmol[i];
738 for (
auto& v : tmpNi) {
742 for (
USI k = 0; k < seg_num; k++) {
743 myBulk.flashCal[pvtnum]->Flash(Ptmp, myBulk.T, tmpNi.data(), 0, 0, 0);
744 for (
USI j = 0; j < myBulk.numPhase; j++) {
745 if (myBulk.flashCal[pvtnum]->phaseExist[j]) {
746 rhotmp = myBulk.flashCal[pvtnum]->rho[j];
747 qtacc += myBulk.flashCal[pvtnum]->v[j] / seg_num;
748 rhoacc += myBulk.flashCal[pvtnum]->v[j] * rhotmp *
751 if (rhotmp <= 0 || !isfinite(rhotmp)) {
752 OCP_ABORT(
"Wrong rho " + to_string(rhotmp));
757 Ptmp -= rhoacc / qtacc * seg_len;
759 dGperf[p] = Pperf - Ptmp;
762 for (
USI p = 1; p < numPerf; p++) {
763 dG[p] = dG[p - 1] + dGperf[p];
765 }
else if (depth >= perf.back().depth) {
769 if (perf[0].state ==
CLOSE) {
770 for (
USI p = 1; p <= numPerf; p++) {
771 if (perf[p].state ==
OPEN) {
772 for (
USI i = 0; i < nc; i++) {
773 perf[numPerf - 1].qi_lbmol[i] = perf[p].qi_lbmol[i];
780 for (
USI p = 0; p < numPerf; p++) {
781 if (p == numPerf - 1) {
782 seg_num = ceil(fabs((depth - perf[numPerf - 1].depth) / maxlen));
783 if (seg_num == 0)
continue;
784 seg_len = (depth - perf[numPerf - 1].depth) / seg_num;
786 seg_num = ceil(fabs((perf[p + 1].depth - perf[p].depth) / maxlen));
787 if (seg_num == 0)
continue;
788 seg_len = (perf[p + 1].depth - perf[p].depth) / seg_num;
792 perf[p].P = BHP + dG[p];
796 USI pvtnum = myBulk.PVTNUM[n];
797 fill(tmpNi.begin(), tmpNi.end(), 0.0);
798 for (
OCP_INT p1 = numPerf - 1; p1 - p >= 0; p1--) {
799 for (
USI i = 0; i < nc; i++) {
800 tmpNi[i] += perf[p1].qi_lbmol[i];
805 for (
auto& v : tmpNi) {
809 for (
USI k = 0; k < seg_num; k++) {
810 myBulk.flashCal[pvtnum]->Flash(Ptmp, myBulk.T, tmpNi.data(), 0, 0, 0);
811 for (
USI j = 0; j < np; j++) {
812 if (myBulk.flashCal[pvtnum]->phaseExist[j]) {
813 rhotmp = myBulk.flashCal[pvtnum]->rho[j];
814 qtacc += myBulk.flashCal[pvtnum]->v[j] / seg_num;
815 rhoacc += myBulk.flashCal[pvtnum]->v[j] * rhotmp *
819 Ptmp += rhoacc / qtacc * seg_len;
821 dGperf[p] = Ptmp - Pperf;
823 dG[numPerf - 1] = dGperf[numPerf - 1];
824 for (
OCP_INT p = numPerf - 2; p >= 0; p--) {
825 dG[p] = dG[p + 1] + dGperf[p];
835 if (opt.type ==
PROD) {
849 for (
USI i = 0; i < myBulk.numCom; i++) {
852 if (fabs(qt) >
TINY && qt > 0) {
862 USI np = myBulk.numPhase;
863 USI nc = myBulk.numCom;
864 vector<OCP_DBL> tmpNi(nc, 0);
865 for (
USI p = 0; p < numPerf; p++) {
868 for (
USI j = 0; j < np; j++) {
870 if (!myBulk.phaseExist[
id])
continue;
871 for (
USI k = 0; k < nc; k++) {
872 tmpNi[k] += perf[p].transj[j] * myBulk.xi[id] *
873 myBulk.xij[
id * nc + k];
877 qt =
Dnorm1(nc, &tmpNi[0]);
900 fill(factor.begin(), factor.end(), 0);
901 if (myBulk.flashCal[0]->phaseExist[0]) {
902 OCP_DBL nuo = myBulk.flashCal[0]->xi[0] * myBulk.flashCal[0]->v[0] /
904 factor[0] = nuo / (myBulk.flashCal[0]->xi[0] *
907 if (myBulk.flashCal[0]->phaseExist[1]) {
908 OCP_DBL nug = myBulk.flashCal[0]->xi[1] * myBulk.flashCal[0]->v[1] /
910 factor[1] = nug / (myBulk.flashCal[0]->xi[1] *
913 factor[2] = factor[0];
914 if (myBulk.flashCal[0]->phaseExist[2]) {
915 OCP_DBL nuw = myBulk.flashCal[0]->xi[2] * myBulk.flashCal[0]->v[2] /
920 if (factor[pid] < 1E-12 || !isfinite(factor[pid])) {
923 fill(prodWeight.begin(), prodWeight.end(), factor[pid]);
934 USI np = myBulk.numPhase;
935 USI nc = myBulk.numCom;
936 for (
USI p = 0; p < numPerf; p++) {
939 for (
USI j = 0; j < np; j++) {
941 if (!myBulk.phaseExist[
id])
continue;
942 for (
USI k = 0; k < nc; k++) {
943 myZi[k] += perf[p].transj[j] * myBulk.xi[id] * myBulk.xij[
id * nc + k];
953 }
else if (opt.type ==
INJ && opt.optMode ==
BHP_MODE) {
963 for (
USI p = 0; p < numPerf; p++) {
964 dG[p] = (ldG[p] + dG[p]) / 2;
975 if (opt.type ==
INJ) {
980 if (opt.injPhase ==
GAS)
982 else if (opt.injPhase ==
WATER)
1012 if (opt.type ==
INJ) {
1015 OCP_DBL tarRate = opt.maxRate;
1017 if (opt.injPhase ==
GAS)
1019 else if (opt.injPhase ==
WATER)
1024 opt.optMode = opt.initOptMode;
1034 if (q > opt.maxRate) {
1035 opt.optMode = opt.initOptMode;
1054 cout <<
"### WARNING: Negative BHP " << BHP << endl;
1057 for (
USI p = 0; p < numPerf; p++) {
1058 if (perf[p].state ==
OPEN && perf[p].P < 0) {
1060 cout <<
"### WARNING: Well " << name <<
" Perf[" << p <<
"].P = " << perf[p].P
1063 cout <<
"### WARNING: Negative perforation P " << perf[p].P << endl;
1068 if (opt.type ==
INJ) {
1069 if (opt.optMode !=
BHP_MODE && BHP > opt.maxBHP) {
1071 cout <<
"### WARNING: Well " << name <<
" switch to BHPMode" << endl;
1078 if (opt.optMode !=
BHP_MODE && BHP < opt.minBHP) {
1080 cout <<
"### WARNING: Well " << name <<
" switch to BHPMode" << endl;
1098 if (opt.type ==
PROD) {
1099 for (
USI p = 0; p < numPerf; p++) {
1100 k = perf[p].location;
1102 if (perf[p].state ==
OPEN && minP < perf[p].P) {
1103 cout << std::left << std::setw(12) << name <<
" "
1104 <<
"Well P = " << perf[p].P <<
", "
1105 <<
"Bulk P = " << minP << endl;
1106 perf[p].state =
CLOSE;
1107 perf[p].multiplier = 0;
1110 }
else if (perf[p].state ==
CLOSE && minP > perf[p].P) {
1111 perf[p].state =
OPEN;
1112 perf[p].multiplier = 1;
1116 for (
USI p = 0; p < numPerf; p++) {
1117 k = perf[p].location;
1118 if (perf[p].state ==
OPEN && myBulk.P[k] > perf[p].P) {
1119 cout << std::left << std::setw(12) << name <<
" "
1120 <<
"Well P = " << perf[p].P <<
", "
1121 <<
"Bulk P = " << myBulk.P[k] << endl;
1122 perf[p].state =
CLOSE;
1123 perf[p].multiplier = 0;
1126 }
else if (perf[p].state ==
CLOSE && myBulk.P[k] < perf[p].P) {
1127 perf[p].state =
OPEN;
1128 perf[p].multiplier = 1;
1135 for (
USI p = 0; p < numPerf; p++) {
1136 if (perf[p].state ==
OPEN) {
1144 perf.back().state =
OPEN;
1145 perf.back().multiplier = 1;
1146 cout <<
"### WARNING: All perfs of " << name
1147 <<
" are closed! Open the last perf!\n";
1171 for (
USI p = 0; p < numPerf; p++) {
1172 myLS.rowCapacity[perf[p].location]++;
1179 for (
USI p = 0; p < numPerf; p++) {
1180 myBulk.wellBulkId.push_back(perf[p].location);
1189 cout <<
"----------------------------" << endl;
1190 cout << name <<
": " << opt.optMode <<
" " << setprecision(3) << BHP << endl;
1191 for (
USI p = 0; p < numPerf; p++) {
1192 vector<OCP_DBL> Qitmp(perf[p].qi_lbmol);
1195 cout << setw(3) << p <<
" " << perf[p].state <<
" " << setw(6)
1196 << perf[p].location <<
" " << setw(2) << perf[p].I + 1 <<
" " << setw(2)
1197 << perf[p].J + 1 <<
" " << setw(2) << perf[p].K + 1 <<
" " << setw(10)
1198 << setprecision(6) << perf[p].WI <<
" "
1199 << setprecision(3) << perf[p].radius <<
" "
1200 << setw(8) << setprecision(4) << perf[p].kh <<
" "
1201 << setw(8) << setprecision(2) << perf[p].depth <<
" "
1202 << setprecision(3) << perf[p].P <<
" "
1203 << setw(10) << setprecision(3) << myBulk.P[n] <<
" "
1204 << setw(6) << setprecision(3) << dG[p] <<
" "
1205 << setw(8) << perf[p].qi_lbmol[myBulk.numCom - 1] <<
" " << setw(6) << setprecision(6)
1206 << myBulk.S[n * myBulk.numPhase + 0] <<
" " << setw(6) << setprecision(6)
1207 << myBulk.S[n * myBulk.numPhase + 1] <<
" " << setw(6) << setprecision(6)
1208 << myBulk.S[n * myBulk.numPhase + 2] << endl;
1221 if (opt.type ==
PROD) {
1222 const USI np = myBulk.numPhase;
1223 for (
USI p = 0; p < numPerf; p++) {
1224 if (perf[p].state ==
OPEN) {
1227 for (
USI j = 0; j < np; j++) {
1228 myBulk.cfl[k * np + j] += fabs(perf[p].qj_ft3[j]) * dt;
1239 const USI nc = myBulk.numCom;
1241 for (
USI p = 0; p < numPerf; p++) {
1243 for (
USI i = 0; i < nc; i++) {
1244 myBulk.Ni[k * nc + i] -= perf[p].qi_lbmol[i] * dt;
1254 const USI nc = myBulk.numCom;
1259 for (
USI p = 0; p < numPerf; p++) {
1263 for (
USI i = 0; i < nc; i++) {
1264 Vfi_zi += myBulk.vfi[k * nc + i] * opt.zi[i];
1267 OCP_DBL valw = dt * perf[p].xi * perf[p].transINJ;
1275 USI ptr = myLS.diagPtr[k];
1276 myLS.val[k][ptr] += valb;
1278 myLS.colId[k].push_back(wId);
1279 myLS.val[k].push_back(-valb);
1284 switch (opt.optMode) {
1291 myLS.diagVal[wId] += valw;
1293 myLS.colId[wId].push_back(k);
1294 myLS.val[wId].push_back(-valw);
1299 myLS.colId[wId].push_back(k);
1300 myLS.val[wId].push_back(0);
1308 assert(myLS.val[wId].size() == numPerf);
1310 switch (opt.optMode) {
1317 myLS.colId[wId].push_back(wId);
1318 myLS.diagPtr[wId] = numPerf;
1319 myLS.val[wId].push_back(myLS.diagVal[wId]);
1321 myLS.b[wId] += dt * opt.maxRate;
1325 myLS.colId[wId].push_back(wId);
1326 myLS.diagPtr[wId] = numPerf;
1327 myLS.val[wId].push_back(dt);
1329 myLS.b[wId] += dt * opt.maxBHP;
1331 myLS.u[wId] = opt.maxBHP;
1343 const USI np = myBulk.numPhase;
1344 const USI nc = myBulk.numCom;
1352 for (
USI p = 0; p < numPerf; p++) {
1360 for (
USI j = 0; j < np; j++) {
1361 if (!myBulk.phaseExist[n * np + j])
continue;
1366 for (
USI i = 0; i < nc; i++) {
1367 tempb += myBulk.vfi[n * nc + i] * myBulk.xij[n * np * nc + j * nc + i];
1368 tempw += prodWeight[i] * myBulk.xij[n * np * nc + j * nc + i];
1370 OCP_DBL trans = dt * perf[p].transj[j] * myBulk.xi[n * np + j];
1371 valb += tempb * trans;
1372 valw += tempw * trans;
1374 OCP_DBL dP = dG[p] - myBulk.Pc[n * np + j];
1375 bb += tempb * trans * dP;
1376 bw += tempw * trans * dP;
1381 USI ptr = myLS.diagPtr[n];
1382 myLS.val[n][ptr] += valb;
1384 myLS.colId[n].push_back(wId);
1385 myLS.val[n].push_back(-valb);
1390 switch (opt.optMode) {
1397 myLS.diagVal[wId] -= valw;
1399 myLS.colId[wId].push_back(n);
1400 myLS.val[wId].push_back(valw);
1406 myLS.colId[wId].push_back(n);
1407 myLS.val[wId].push_back(0);
1415 assert(myLS.val[wId].size() == numPerf);
1417 switch (opt.optMode) {
1424 myLS.colId[wId].push_back(wId);
1425 myLS.diagPtr[wId] = numPerf;
1426 myLS.val[wId].push_back(myLS.diagVal[wId]);
1428 myLS.b[wId] += dt * opt.maxRate;
1432 myLS.colId[wId].push_back(wId);
1433 myLS.diagPtr[wId] = numPerf;
1434 myLS.val[wId].push_back(dt);
1436 myLS.b[wId] += dt * opt.minBHP;
1438 myLS.u[wId] = opt.minBHP;
1446 const OCP_DBL& dt,
const vector<Well>& allWell,
1447 const vector<USI>& injId)
const
1450 vector<OCP_USI> tarId;
1451 for (
USI w = 0; w < injId.size(); w++) {
1453 tarId.push_back(allWell[w].wEId + myBulk.numBulk);
1456 USI tlen = tarId.size();
1458 const OCP_DBL factor = allWell[injId[0]].opt.factor * dt;
1460 const OCP_USI prodId = wEId + myBulk.numBulk;
1461 USI np = myBulk.numPhase;
1468 for (
USI p = 0; p < numPerf; p++) {
1469 n = perf[p].location;
1472 for (
USI j = 0; j < np; j++) {
1474 if (myBulk.phaseExist[bId]) {
1475 tmp = perf[p].transj[j] * myBulk.xi[bId];
1477 rhsw += tmp * (myBulk.Pc[bId] - dG[p]);
1482 for (
USI t = 0; t < tlen; t++) {
1484 tarsize = myLS.colId[tar].size();
1486 for (i = 0; i < tarsize; i++) {
1487 if (n < myLS.colId[tar][i]) {
1490 myLS.colId[tar].insert(myLS.colId[tar].begin() + i, n);
1491 myLS.val[tar].insert(myLS.val[tar].begin() + i, -valb);
1492 myLS.diagPtr[tar]++;
1501 for (
USI t = 0; t < tlen; t++) {
1503 tarsize = myLS.colId[tar].size();
1504 myLS.b[tar] += rhsw;
1506 for (i = 0; i < tarsize; i++) {
1507 if (prodId < myLS.colId[tar][i]) {
1509 myLS.colId[tar].insert(myLS.colId[tar].begin() + i, prodId);
1510 myLS.val[tar].insert(myLS.val[tar].begin() + i, valw);
1511 if (i <= myLS.diagPtr[tar]) myLS.diagPtr[tar]++;
1517 myLS.colId[tar].push_back(prodId);
1518 myLS.val[tar].push_back(valw);
1537 const USI np = myBulk.numPhase;
1538 const USI nc = myBulk.numCom;
1539 const USI ncol = nc + 1;
1540 const USI ncol2 = np * nc + np;
1541 const USI bsize = ncol * ncol;
1542 const USI bsize2 = ncol * ncol2;
1550 vector<OCP_DBL> bmat(bsize, 0);
1551 vector<OCP_DBL> bmat2(bsize, 0);
1552 vector<OCP_DBL> dQdXpB(bsize, 0);
1553 vector<OCP_DBL> dQdXpW(bsize, 0);
1554 vector<OCP_DBL> dQdXsB(bsize2, 0);
1556 for (
USI p = 0; p < numPerf; p++) {
1557 const OCP_USI n = perf[p].location;
1558 fill(dQdXpB.begin(), dQdXpB.end(), 0.0);
1559 fill(dQdXpW.begin(), dQdXpW.end(), 0.0);
1560 fill(dQdXsB.begin(), dQdXsB.end(), 0.0);
1562 dP = myBulk.P[n] - BHP - dG[p];
1564 for (
USI j = 0; j < np; j++) {
1565 n_np_j = n * np + j;
1566 if (!myBulk.phaseExist[n_np_j])
continue;
1568 mu = myBulk.mu[n_np_j];
1569 muP = myBulk.muP[n_np_j];
1571 for (
USI i = 0; i < nc; i++) {
1573 transIJ = perf[p].transj[j] * perf[p].xi * opt.zi[i];
1574 dQdXpB[(i + 1) * ncol] += transIJ * (1 - dP * muP / mu);
1575 dQdXpW[(i + 1) * ncol] += -transIJ;
1578 for (
USI k = 0; k < np; k++) {
1579 dQdXsB[(i + 1) * ncol2 + k] +=
1580 CONV1 * perf[p].WI * perf[p].multiplier * perf[p].xi *
1581 opt.zi[i] * myBulk.dKr_dS[n_np_j * np + k] * dP / mu;
1584 for (
USI k = 0; k < nc; k++) {
1585 dQdXsB[(i + 1) * ncol2 + np + j * nc + k] +=
1586 -transIJ * dP / mu * myBulk.mux[n_np_j * nc + k];
1595 DaABpbC(ncol, ncol, ncol2, 1, dQdXsB.data(), &myBulk.dSec_dPri[n * bsize2], 1,
1597 Dscalar(bsize, dt, bmat.data());
1599 USI ptr = myLS.diagPtr[n];
1600 for (
USI i = 0; i < bsize; i++) {
1601 myLS.val[n][ptr * bsize + i] += bmat[i];
1605 Dscalar(bsize, dt, bmat.data());
1606 myLS.val[n].insert(myLS.val[n].end(), bmat.begin(), bmat.end());
1607 myLS.colId[n].push_back(wId);
1610 switch (opt.optMode) {
1617 fill(bmat.begin(), bmat.end(), 0.0);
1618 for (
USI i = 0; i < nc; i++) {
1619 bmat[0] += dQdXpW[(i + 1) * ncol];
1620 bmat[(i + 1) * ncol + i + 1] = 1;
1622 for (
USI i = 0; i < bsize; i++) {
1623 myLS.diagVal[wId * bsize + i] += bmat[i];
1631 DaABpbC(ncol, ncol, ncol2, 1, dQdXsB.data(),
1632 &myBulk.dSec_dPri[n * bsize2], 1, bmat.data());
1633 fill(bmat2.begin(), bmat2.end(), 0.0);
1634 for (
USI i = 0; i < nc; i++) {
1635 Daxpy(ncol, 1.0, bmat.data() + (i + 1) * ncol, bmat2.data());
1637 myLS.val[wId].insert(myLS.val[wId].end(), bmat2.begin(), bmat2.end());
1638 myLS.colId[wId].push_back(n);
1643 fill(bmat.begin(), bmat.end(), 0.0);
1644 for (
USI i = 0; i < nc + 1; i++) {
1645 bmat[i * ncol + i] = 1;
1648 for (
USI i = 0; i < bsize; i++) {
1649 myLS.diagVal[wId * bsize + i] += bmat[i];
1652 fill(bmat.begin(), bmat.end(), 0.0);
1654 myLS.val[wId].insert(myLS.val[wId].end(), bmat.begin(), bmat.end());
1655 myLS.colId[wId].push_back(n);
1665 assert(myLS.val[wId].size() == numPerf * bsize);
1667 myLS.colId[wId].push_back(wId);
1668 myLS.diagPtr[wId] = numPerf;
1669 myLS.val[wId].insert(myLS.val[wId].end(), myLS.diagVal.data() + wId * bsize,
1670 myLS.diagVal.data() + wId * bsize + bsize);
1682 const USI np = myBulk.numPhase;
1683 const USI nc = myBulk.numCom;
1684 const USI ncol = nc + 1;
1685 const USI ncol2 = np * nc + np;
1686 const USI bsize = ncol * ncol;
1687 const USI bsize2 = ncol * ncol2;
1689 OCP_DBL xij, xi, mu, muP, xiP;
1696 vector<OCP_DBL> bmat(bsize, 0);
1697 vector<OCP_DBL> bmat2(bsize, 0);
1698 vector<OCP_DBL> dQdXpB(bsize, 0);
1699 vector<OCP_DBL> dQdXpW(bsize, 0);
1700 vector<OCP_DBL> dQdXsB(bsize2, 0);
1706 for (
USI p = 0; p < numPerf; p++) {
1707 const OCP_USI n = perf[p].location;
1708 fill(dQdXpB.begin(), dQdXpB.end(), 0.0);
1709 fill(dQdXpW.begin(), dQdXpW.end(), 0.0);
1710 fill(dQdXsB.begin(), dQdXsB.end(), 0.0);
1712 for (
USI j = 0; j < np; j++) {
1713 n_np_j = n * np + j;
1714 if (!myBulk.phaseExist[n_np_j])
continue;
1716 dP = myBulk.Pj[n_np_j] - BHP - dG[p];
1717 xi = myBulk.xi[n_np_j];
1718 mu = myBulk.mu[n_np_j];
1719 muP = myBulk.muP[n_np_j];
1720 xiP = myBulk.xiP[n_np_j];
1722 for (
USI i = 0; i < nc; i++) {
1723 xij = myBulk.xij[n_np_j * nc + i];
1725 transIJ = perf[p].transj[j] * xi * xij;
1726 dQdXpB[(i + 1) * ncol] +=
1727 transIJ * (1 - dP * muP / mu) + dP * perf[p].transj[j] * xij * xiP;
1728 dQdXpW[(i + 1) * ncol] += -transIJ;
1735 for (
USI k = 0; k < np; k++) {
1736 tmp =
CONV1 * perf[p].WI * perf[p].multiplier * dP / mu * xi * xij *
1737 myBulk.dKr_dS[n_np_j * np + k];
1739 tmp += transIJ * myBulk.dPcj_dS[n_np_j * np + k];
1740 dQdXsB[(i + 1) * ncol2 + k] += tmp;
1743 for (
USI k = 0; k < nc; k++) {
1744 tmp = dP * perf[p].transj[j] * xij *
1745 (myBulk.xix[n_np_j * nc + k] -
1746 xi / mu * myBulk.mux[n_np_j * nc + k]);
1747 dQdXsB[(i + 1) * ncol2 + np + j * nc + k] += tmp;
1749 dQdXsB[(i + 1) * ncol2 + np + j * nc + i] += perf[p].transj[j] * xi * dP;
1757 DaABpbC(ncol, ncol, ncol2, 1, dQdXsB.data(), &myBulk.dSec_dPri[n * bsize2], 1,
1760 Dscalar(bsize, dt, bmat.data());
1762 USI ptr = myLS.diagPtr[n];
1763 for (
USI i = 0; i < bsize; i++) {
1764 myLS.val[n][ptr * bsize + i] += bmat[i];
1768 Dscalar(bsize, dt, bmat.data());
1769 myLS.val[n].insert(myLS.val[n].end(), bmat.begin(), bmat.end());
1770 myLS.colId[n].push_back(wId);
1773 switch (opt.optMode) {
1780 fill(bmat.begin(), bmat.end(), 0.0);
1781 for (
USI i = 0; i < nc; i++) {
1782 bmat[0] += dQdXpW[(i + 1) * ncol] * prodWeight[i];
1783 bmat[(i + 1) * ncol + i + 1] = 1;
1785 for (
USI i = 0; i < bsize; i++) {
1786 myLS.diagVal[wId * bsize + i] += bmat[i];
1794 DaABpbC(ncol, ncol, ncol2, 1, dQdXsB.data(),
1795 &myBulk.dSec_dPri[n * bsize2], 1, bmat.data());
1796 fill(bmat2.begin(), bmat2.end(), 0.0);
1797 for (
USI i = 0; i < nc; i++) {
1798 Daxpy(ncol, prodWeight[i], bmat.data() + (i + 1) * ncol,
1801 myLS.val[wId].insert(myLS.val[wId].end(), bmat2.begin(), bmat2.end());
1802 myLS.colId[wId].push_back(n);
1807 fill(bmat.begin(), bmat.end(), 0.0);
1808 for (
USI i = 0; i < nc + 1; i++) {
1809 bmat[i * ncol + i] = 1;
1812 for (
USI i = 0; i < bsize; i++) {
1813 myLS.diagVal[wId * bsize + i] += bmat[i];
1816 fill(bmat.begin(), bmat.end(), 0.0);
1818 myLS.val[wId].insert(myLS.val[wId].end(), bmat.begin(), bmat.end());
1819 myLS.colId[wId].push_back(n);
1829 assert(myLS.val[wId].size() == numPerf * bsize);
1831 myLS.colId[wId].push_back(wId);
1832 myLS.diagPtr[wId] = numPerf;
1833 myLS.val[wId].insert(myLS.val[wId].end(), myLS.diagVal.data() + wId * bsize,
1834 myLS.diagVal.data() + wId * bsize + bsize);
1843 const OCP_DBL& dt,
const vector<Well>& allWell,
1844 const vector<USI>& injId)
const
1847 vector<OCP_USI> tarId;
1848 for (
USI w = 0; w < injId.size(); w++) {
1850 tarId.push_back(allWell[w].wEId + myBulk.numBulk);
1853 USI tlen = tarId.size();
1857 const OCP_DBL factor = allWell[injId[0]].opt.factor;
1858 const OCP_USI prodId = wEId + myBulk.numBulk;
1862 const USI np = myBulk.numPhase;
1863 const USI nc = myBulk.numCom;
1864 const USI ncol = nc + 1;
1865 const USI ncol2 = np * nc + np;
1866 const USI bsize = ncol * ncol;
1867 const USI bsize2 = ncol * ncol2;
1869 OCP_DBL xij, xi, mu, muP, xiP, dP, transIJ, tmp;
1872 vector<OCP_DBL> bmat(bsize, 0);
1873 vector<OCP_DBL> bmat2(bsize, 0);
1874 vector<OCP_DBL> tmpMat(bsize, 0);
1875 vector<OCP_DBL> dQdXpB(bsize, 0);
1876 vector<OCP_DBL> dQdXpW(bsize, 0);
1877 vector<OCP_DBL> dQdXsB(bsize2, 0);
1879 for (
USI p = 0; p < numPerf; p++) {
1881 fill(dQdXpB.begin(), dQdXpB.end(), 0.0);
1882 fill(dQdXpW.begin(), dQdXpW.end(), 0.0);
1883 fill(dQdXsB.begin(), dQdXsB.end(), 0.0);
1885 for (
USI j = 0; j < np; j++) {
1886 n_np_j = n * np + j;
1887 if (!myBulk.phaseExist[n_np_j])
continue;
1889 dP = myBulk.Pj[n_np_j] - BHP - dG[p];
1890 xi = myBulk.xi[n_np_j];
1891 mu = myBulk.mu[n_np_j];
1892 muP = myBulk.muP[n_np_j];
1893 xiP = myBulk.xiP[n_np_j];
1895 for (
USI i = 0; i < nc; i++) {
1896 xij = myBulk.xij[n_np_j * nc + i];
1898 transIJ = perf[p].transj[j] * xi * xij;
1899 dQdXpB[(i + 1) * ncol] += transIJ * (1 - dP * muP / mu) +
1900 dP * perf[p].transj[j] * xij * xiP;
1901 dQdXpW[(i + 1) * ncol] += -transIJ;
1904 for (
USI k = 0; k < np; k++) {
1905 tmp =
CONV1 * perf[p].WI * perf[p].multiplier * dP / mu * xi *
1906 xij * myBulk.dKr_dS[n * np * np + j * np + k];
1908 tmp += transIJ * myBulk.dPcj_dS[n * np * np + j * np + k];
1909 dQdXsB[(i + 1) * ncol2 + k] += tmp;
1912 for (
USI k = 0; k < nc; k++) {
1913 tmp = dP * perf[p].transj[j] * xij *
1914 (myBulk.xix[n_np_j * nc + k] -
1915 xi / mu * myBulk.mux[n_np_j * nc + k]);
1917 tmp += perf[p].transj[j] * xi * dP;
1919 dQdXsB[(i + 1) * ncol2 + np + j * nc + k] += tmp;
1925 for (
USI i = 0; i < nc; i++) {
1927 tmpMat[0] += dQdXpW[(i + 1) * ncol] * factor;
1932 DaABpbC(ncol, ncol, ncol2, 1, dQdXsB.data(), &myBulk.dSec_dPri[n * bsize2],
1934 fill(bmat2.begin(), bmat2.end(), 0.0);
1935 for (
USI i = 0; i < nc; i++) {
1938 Daxpy(ncol, factor, bmat.data() + (i + 1) * ncol, bmat2.data());
1942 for (
USI t = 0; t < tlen; t++) {
1944 tarsize = myLS.colId[tar].size();
1946 for (i = 0; i < tarsize; i++) {
1947 if (n < myLS.colId[tar][i]) {
1950 myLS.colId[tar].insert(myLS.colId[tar].begin() + i, n);
1951 myLS.val[tar].insert(myLS.val[tar].begin() + i * bsize,
1952 bmat.begin(), bmat.end());
1953 myLS.diagPtr[tar]++;
1960 for (
USI t = 0; t < tlen; t++) {
1962 tarsize = myLS.colId[tar].size();
1964 for (i = 0; i < tarsize; i++) {
1965 if (prodId < myLS.colId[tar][i]) {
1967 myLS.colId[tar].insert(myLS.colId[tar].begin() + i, prodId);
1968 myLS.val[tar].insert(myLS.val[tar].begin() + i * bsize,
1969 tmpMat.begin(), tmpMat.end());
1970 if (i <= myLS.diagPtr[tar]) myLS.diagPtr[tar]++;
1976 myLS.colId[tar].push_back(prodId);
1977 myLS.val[tar].insert(myLS.val[tar].end(), tmpMat.begin(), tmpMat.end());
1984 const OCP_USI& wId,
const vector<Well>& allWell)
const
1989 const USI nc = myBulk.numCom;
1990 const USI len = nc + 1;
1993 for (
USI p = 0; p < numPerf; p++) {
1994 k = perf[p].location;
1995 for (
USI i = 0; i < nc; i++) {
1996 resFIM.res[k * len + 1 + i] += perf[p].qi_lbmol[i] * dt;
2001 OCP_USI bId = (myBulk.numBulk + wId) * len;
2002 if (opt.type ==
INJ) {
2004 switch (opt.optMode) {
2007 resFIM.res[bId] = BHP - opt.maxBHP;
2014 resFIM.res[bId] = opt.maxRate;
2015 for (
USI i = 0; i < nc; i++) {
2016 resFIM.res[bId] += qi_lbmol[i];
2019 for (
auto& w : opt.connWell) {
2021 for (
USI i = 0; i < nc; i++) {
2022 tmp += allWell[w].qi_lbmol[i];
2027 resFIM.res[bId] += tmp;
2034 resFIM.maxWellRelRes_mol =
2035 max(resFIM.maxWellRelRes_mol, fabs(resFIM.res[bId] / opt.maxRate));
2043 switch (opt.optMode) {
2046 resFIM.res[bId] = BHP - opt.minBHP;
2053 resFIM.res[bId] = -opt.maxRate;
2054 for (
USI i = 0; i < nc; i++) {
2055 resFIM.res[bId] += qi_lbmol[i] * prodWeight[i];
2060 resFIM.maxWellRelRes_mol =
2061 max(resFIM.maxWellRelRes_mol, fabs(resFIM.res[bId] / opt.maxRate));
2070 void Well::ShowRes(
const OCP_USI& wId,
const vector<OCP_DBL>& res,
const Bulk& myBulk)
const
2073 const USI nc = myBulk.numCom;
2074 const USI len = nc + 1;
2076 OCP_USI bId = (myBulk.numBulk + wId) * len;
2077 cout << name <<
" " << res[bId] <<
" ";
2079 if (opt.type ==
INJ) {
2081 switch (opt.optMode) {
2083 cout <<
"BHPMode" << endl;
2090 cout << opt.maxRate <<
" " << fabs(res[bId] / opt.maxRate) << endl;
2099 switch (opt.optMode) {
2101 cout <<
"BHPMode" << endl;
2108 cout << opt.maxRate <<
" " << fabs(res[bId] / opt.maxRate) << endl;
2132 const USI np = myBulk.numPhase;
2133 const USI nc = myBulk.numCom;
2134 const USI nch = nc - 1;
2135 const USI ncol = nc + 1;
2136 const USI ncol2 = np * nc + np;
2137 const USI bsize = ncol * ncol;
2138 const USI bsize2 = ncol * ncol2;
2146 vector<OCP_DBL> bmat(bsize, 0);
2147 vector<OCP_DBL> bmat2(bsize, 0);
2148 vector<OCP_DBL> dQdXpB(bsize, 0);
2149 vector<OCP_DBL> dQdXpW(bsize, 0);
2150 vector<OCP_DBL> dQdXsB(bsize2, 0);
2151 vector<bool> phaseExistB(np,
false);
2152 vector<USI> pEnumComB(np, 0);
2156 for (
USI p = 0; p < numPerf; p++) {
2157 const OCP_USI n = perf[p].location;
2158 fill(dQdXpB.begin(), dQdXpB.end(), 0.0);
2159 fill(dQdXpW.begin(), dQdXpW.end(), 0.0);
2160 fill(dQdXsB.begin(), dQdXsB.end(), 0.0);
2162 dP = myBulk.P[n] - BHP - dG[p];
2164 const USI npB = myBulk.phaseNum[n] + 1; ncolB = npB;
2165 for (
USI j = 0; j < np; j++) {
2166 phaseExistB[j] = myBulk.phaseExist[n * np + j];
2167 pEnumComB[j] = myBulk.pEnumCom[n * np + j];
2168 ncolB += pEnumComB[j];
2173 for (
USI j = 0; j < np; j++) {
2175 if (!phaseExistB[j]) {
2176 jxB += pEnumComB[j];
2180 n_np_j = n * np + j;
2181 mu = myBulk.mu[n_np_j];
2182 muP = myBulk.muP[n_np_j];
2184 for (
USI i = 0; i < nc; i++) {
2186 transIJ = perf[p].transj[j] * perf[p].xi * opt.zi[i];
2187 dQdXpB[(i + 1) * ncol] += transIJ * (1 - dP * muP / mu);
2188 dQdXpW[(i + 1) * ncol] += -transIJ;
2192 for (
USI j1 = 0; j1 < np; j1++) {
2193 if (phaseExistB[j1]) {
2194 dQdXsB[(i + 1) * ncolB + j1B] +=
2195 CONV1 * perf[p].WI * perf[p].multiplier * perf[p].xi *
2196 opt.zi[i] * myBulk.dKr_dS[n_np_j * np + j1] * dP / mu;
2202 for (
USI k = 0; k < pEnumComB[j]; k++) {
2203 dQdXsB[(i + 1) * ncolB + jxB + k] +=
2204 -transIJ * dP / mu * myBulk.mux[n_np_j * nc + k];
2207 jxB += pEnumComB[j];
2213 DaABpbC(ncol, ncol, ncolB, 1, dQdXsB.data(), &myBulk.dSec_dPri[myBulk.dSdPindex[n]], 1,
2215 Dscalar(bsize, dt, bmat.data());
2217 USI ptr = myLS.diagPtr[n];
2218 for (
USI i = 0; i < bsize; i++) {
2219 myLS.val[n][ptr * bsize + i] += bmat[i];
2223 Dscalar(bsize, dt, bmat.data());
2224 myLS.val[n].insert(myLS.val[n].end(), bmat.begin(), bmat.end());
2225 myLS.colId[n].push_back(wId);
2228 switch (opt.optMode) {
2235 fill(bmat.begin(), bmat.end(), 0.0);
2236 for (
USI i = 0; i < nc; i++) {
2237 bmat[0] += dQdXpW[(i + 1) * ncol];
2238 bmat[(i + 1) * ncol + i + 1] = 1;
2240 for (
USI i = 0; i < bsize; i++) {
2241 myLS.diagVal[wId * bsize + i] += bmat[i];
2248 DaABpbC(ncol, ncol, ncolB, 1, dQdXsB.data(),
2249 &myBulk.dSec_dPri[myBulk.dSdPindex[n]], 1, bmat.data());
2250 fill(bmat2.begin(), bmat2.end(), 0.0);
2251 for (
USI i = 0; i < nc; i++) {
2252 Daxpy(ncol, 1.0, bmat.data() + (i + 1) * ncol, bmat2.data());
2254 myLS.val[wId].insert(myLS.val[wId].end(), bmat2.begin(), bmat2.end());
2255 myLS.colId[wId].push_back(n);
2260 fill(bmat.begin(), bmat.end(), 0.0);
2261 for (
USI i = 0; i < nc + 1; i++) {
2262 bmat[i * ncol + i] = 1;
2265 for (
USI i = 0; i < bsize; i++) {
2266 myLS.diagVal[wId * bsize + i] += bmat[i];
2269 fill(bmat.begin(), bmat.end(), 0.0);
2271 myLS.val[wId].insert(myLS.val[wId].end(), bmat.begin(), bmat.end());
2272 myLS.colId[wId].push_back(n);
2282 assert(myLS.val[wId].size() == numPerf * bsize);
2284 myLS.colId[wId].push_back(wId);
2285 myLS.diagPtr[wId] = numPerf;
2286 myLS.val[wId].insert(myLS.val[wId].end(), myLS.diagVal.data() + wId * bsize,
2287 myLS.diagVal.data() + wId * bsize + bsize);
2300 const USI np = myBulk.numPhase;
2301 const USI nc = myBulk.numCom;
2302 const USI nch = nc - 1;
2303 const USI ncol = nc + 1;
2304 const USI ncol2 = np * nc + np;
2305 const USI bsize = ncol * ncol;
2306 const USI bsize2 = ncol * ncol2;
2308 OCP_DBL xij, xi, mu, muP, xiP;
2315 vector<OCP_DBL> bmat(bsize, 0);
2316 vector<OCP_DBL> bmat2(bsize, 0);
2317 vector<OCP_DBL> dQdXpB(bsize, 0);
2318 vector<OCP_DBL> dQdXpW(bsize, 0);
2319 vector<OCP_DBL> dQdXsB(bsize2, 0);
2320 vector<bool> phaseExistB(np,
false);
2321 vector<USI> pEnumComB(np, 0);
2328 for (
USI p = 0; p < numPerf; p++) {
2330 fill(dQdXpB.begin(), dQdXpB.end(), 0.0);
2331 fill(dQdXpW.begin(), dQdXpW.end(), 0.0);
2332 fill(dQdXsB.begin(), dQdXsB.end(), 0.0);
2334 const USI npB = myBulk.phaseNum[n] + 1; ncolB = npB;
2335 for (
USI j = 0; j < np; j++) {
2336 phaseExistB[j] = myBulk.phaseExist[n * np + j];
2337 pEnumComB[j] = myBulk.pEnumCom[n * np + j];
2338 ncolB += pEnumComB[j];
2343 for (
USI j = 0; j < np; j++) {
2345 if (!phaseExistB[j]) {
2346 jxB += pEnumComB[j];
2350 n_np_j = n * np + j;
2351 dP = myBulk.Pj[n_np_j] - BHP - dG[p];
2352 xi = myBulk.xi[n_np_j];
2353 mu = myBulk.mu[n_np_j];
2354 muP = myBulk.muP[n_np_j];
2355 xiP = myBulk.xiP[n_np_j];
2358 for (
USI i = 0; i < nc; i++) {
2359 xij = myBulk.xij[n_np_j * nc + i];
2361 transIJ = perf[p].transj[j] * xi * xij;
2362 dQdXpB[(i + 1) * ncol] +=
2363 transIJ * (1 - dP * muP / mu) + dP * perf[p].transj[j] * xij * xiP;
2364 dQdXpW[(i + 1) * ncol] += -transIJ;
2368 for (
USI j1 = 0; j1 < np; j1++) {
2369 if (phaseExistB[j1]) {
2370 tmp =
CONV1 * perf[p].WI * perf[p].multiplier * dP / mu * xi * xij *
2371 myBulk.dKr_dS[n_np_j * np + j1];
2373 tmp += transIJ * myBulk.dPcj_dS[n_np_j * np + j1];
2374 dQdXsB[(i + 1) * ncolB + j1B] += tmp;
2379 for (
USI k = 0; k < pEnumComB[j]; k++) {
2380 tmp = dP * perf[p].transj[j] * xij *
2381 (myBulk.xix[n_np_j * nc + k] -
2382 xi / mu * myBulk.mux[n_np_j * nc + k]);
2383 dQdXsB[(i + 1) * ncolB + jxB + k] += tmp;
2386 if (i < pEnumComB[j])
2387 dQdXsB[(i + 1) * ncolB + jxB + i] += perf[p].transj[j] * xi * dP;;
2389 jxB += pEnumComB[j];
2395 DaABpbC(ncol, ncol, ncolB, 1, dQdXsB.data(), &myBulk.dSec_dPri[myBulk.dSdPindex[n]], 1,
2398 Dscalar(bsize, dt, bmat.data());
2400 USI ptr = myLS.diagPtr[n];
2401 for (
USI i = 0; i < bsize; i++) {
2402 myLS.val[n][ptr * bsize + i] += bmat[i];
2406 Dscalar(bsize, dt, bmat.data());
2407 myLS.val[n].insert(myLS.val[n].end(), bmat.begin(), bmat.end());
2408 myLS.colId[n].push_back(wId);
2411 switch (opt.optMode) {
2418 fill(bmat.begin(), bmat.end(), 0.0);
2419 for (
USI i = 0; i < nc; i++) {
2420 bmat[0] += dQdXpW[(i + 1) * ncol] * prodWeight[i];
2421 bmat[(i + 1) * ncol + i + 1] = 1;
2423 for (
USI i = 0; i < bsize; i++) {
2424 myLS.diagVal[wId * bsize + i] += bmat[i];
2431 DaABpbC(ncol, ncol, ncolB, 1, dQdXsB.data(),
2432 &myBulk.dSec_dPri[myBulk.dSdPindex[n]], 1, bmat.data());
2433 fill(bmat2.begin(), bmat2.end(), 0.0);
2434 for (
USI i = 0; i < nc; i++) {
2435 Daxpy(ncol, prodWeight[i], bmat.data() + (i + 1) * ncol,
2438 myLS.val[wId].insert(myLS.val[wId].end(), bmat2.begin(), bmat2.end());
2439 myLS.colId[wId].push_back(n);
2444 fill(bmat.begin(), bmat.end(), 0.0);
2445 for (
USI i = 0; i < nc + 1; i++) {
2446 bmat[i * ncol + i] = 1;
2449 for (
USI i = 0; i < bsize; i++) {
2450 myLS.diagVal[wId * bsize + i] += bmat[i];
2453 fill(bmat.begin(), bmat.end(), 0.0);
2455 myLS.val[wId].insert(myLS.val[wId].end(), bmat.begin(), bmat.end());
2456 myLS.colId[wId].push_back(n);
2466 assert(myLS.val[wId].size() == numPerf * bsize);
2468 myLS.colId[wId].push_back(wId);
2469 myLS.diagPtr[wId] = numPerf;
2470 myLS.val[wId].insert(myLS.val[wId].end(), myLS.diagVal.data() + wId * bsize,
2471 myLS.diagVal.data() + wId * bsize + bsize);
2475 void Well::AssembleMatINJ_FIM_new_n(
const Bulk& myBulk,
LinearSystem& myLS,
2484 const USI np = myBulk.numPhase;
2485 const USI nc = myBulk.numCom;
2486 const USI nch = nc - 1;
2487 const USI ncol = nc + 1;
2488 const USI ncol2 = np * nc + np;
2489 const USI bsize = ncol * ncol;
2490 const USI bsize2 = ncol * ncol2;
2498 vector<OCP_DBL> bmat(bsize, 0);
2499 vector<OCP_DBL> bmat2(bsize, 0);
2500 vector<OCP_DBL> dQdXpB(bsize, 0);
2501 vector<OCP_DBL> dQdXpW(bsize, 0);
2502 vector<OCP_DBL> dQdXsB(bsize2, 0);
2503 vector<bool> phaseExistB(np,
false);
2504 vector<USI> pEnumComB(np, 0);
2508 for (
USI p = 0; p < numPerf; p++) {
2509 const OCP_USI n = perf[p].location;
2510 fill(dQdXpB.begin(), dQdXpB.end(), 0.0);
2511 fill(dQdXpW.begin(), dQdXpW.end(), 0.0);
2512 fill(dQdXsB.begin(), dQdXsB.end(), 0.0);
2514 dP = myBulk.P[n] - BHP - dG[p];
2516 const USI npB = myBulk.phaseNum[n] + 1; ncolB = npB;
2517 for (
USI j = 0; j < np; j++) {
2518 phaseExistB[j] = myBulk.phaseExist[n * np + j];
2519 pEnumComB[j] = myBulk.pEnumCom[n * np + j];
2520 ncolB += pEnumComB[j];
2525 for (
USI j = 0; j < np; j++) {
2527 if (!phaseExistB[j]) {
2528 jxB += pEnumComB[j];
2532 n_np_j = n * np + j;
2533 mu = myBulk.mu[n_np_j];
2534 muP = myBulk.muP[n_np_j];
2536 for (
USI i = 0; i < nc; i++) {
2538 transIJ = perf[p].transj[j] * perf[p].xi * opt.zi[i];
2539 dQdXpB[(i + 1) * ncol] += transIJ * (1 - dP * muP / mu);
2540 dQdXpW[(i + 1) * ncol] += -transIJ;
2544 for (
USI j1 = 0; j1 < np; j1++) {
2545 if (phaseExistB[j1]) {
2546 dQdXsB[(i + 1) * ncolB + j1B] +=
2547 CONV1 * perf[p].WI * perf[p].multiplier * perf[p].xi *
2548 opt.zi[i] * myBulk.dKr_dS[n_np_j * np + j1] * dP / mu;
2554 for (
USI k = 0; k < pEnumComB[j]; k++) {
2555 dQdXsB[(i + 1) * ncolB + jxB + k] +=
2556 -transIJ * dP / mu * myBulk.mux[n_np_j * nc + k];
2559 jxB += pEnumComB[j];
2565 DaAxpby(ncol, ncolB, -1.0, dQdXsB.data(),
2566 &myBulk.res_n[myBulk.resIndex[n]], 1.0, &myLS.b[n * ncol]);
2574 DaABpbC(ncol, ncol, ncolB, 1, dQdXsB.data(), &myBulk.dSec_dPri[myBulk.dSdPindex[n]], 1,
2576 Dscalar(bsize, dt, bmat.data());
2578 USI ptr = myLS.diagPtr[n];
2579 for (
USI i = 0; i < bsize; i++) {
2580 myLS.val[n][ptr * bsize + i] += bmat[i];
2584 Dscalar(bsize, dt, bmat.data());
2585 myLS.val[n].insert(myLS.val[n].end(), bmat.begin(), bmat.end());
2586 myLS.colId[n].push_back(wId);
2589 switch (opt.optMode) {
2596 fill(bmat.begin(), bmat.end(), 0.0);
2597 for (
USI i = 0; i < nc; i++) {
2598 bmat[0] += dQdXpW[(i + 1) * ncol];
2599 bmat[(i + 1) * ncol + i + 1] = 1;
2601 for (
USI i = 0; i < bsize; i++) {
2602 myLS.diagVal[wId * bsize + i] += bmat[i];
2609 DaABpbC(ncol, ncol, ncolB, 1, dQdXsB.data(),
2610 &myBulk.dSec_dPri[myBulk.dSdPindex[n]], 1, bmat.data());
2611 fill(bmat2.begin(), bmat2.end(), 0.0);
2612 for (
USI i = 0; i < nc; i++) {
2613 Daxpy(ncol, 1.0, bmat.data() + (i + 1) * ncol, bmat2.data());
2615 myLS.val[wId].insert(myLS.val[wId].end(), bmat2.begin(), bmat2.end());
2616 myLS.colId[wId].push_back(n);
2621 fill(bmat.begin(), bmat.end(), 0.0);
2622 for (
USI i = 0; i < nc + 1; i++) {
2623 bmat[i * ncol + i] = 1;
2626 for (
USI i = 0; i < bsize; i++) {
2627 myLS.diagVal[wId * bsize + i] += bmat[i];
2630 fill(bmat.begin(), bmat.end(), 0.0);
2632 myLS.val[wId].insert(myLS.val[wId].end(), bmat.begin(), bmat.end());
2633 myLS.colId[wId].push_back(n);
2643 assert(myLS.val[wId].size() == numPerf * bsize);
2645 myLS.colId[wId].push_back(wId);
2646 myLS.diagPtr[wId] = numPerf;
2647 myLS.val[wId].insert(myLS.val[wId].end(), myLS.diagVal.data() + wId * bsize,
2648 myLS.diagVal.data() + wId * bsize + bsize);
2652 void Well::AssembleMatPROD_FIM_new_n(
const Bulk& myBulk,
LinearSystem& myLS,
2661 const USI np = myBulk.numPhase;
2662 const USI nc = myBulk.numCom;
2663 const USI nch = nc - 1;
2664 const USI ncol = nc + 1;
2665 const USI ncol2 = np * nc + np;
2666 const USI bsize = ncol * ncol;
2667 const USI bsize2 = ncol * ncol2;
2669 OCP_DBL xij, xi, mu, muP, xiP;
2676 vector<OCP_DBL> bmat(bsize, 0);
2677 vector<OCP_DBL> bmat2(bsize, 0);
2678 vector<OCP_DBL> dQdXpB(bsize, 0);
2679 vector<OCP_DBL> dQdXpW(bsize, 0);
2680 vector<OCP_DBL> dQdXsB(bsize2, 0);
2681 vector<bool> phaseExistB(np,
false);
2682 vector<USI> pEnumComB(np, 0);
2689 for (
USI p = 0; p < numPerf; p++) {
2691 fill(dQdXpB.begin(), dQdXpB.end(), 0.0);
2692 fill(dQdXpW.begin(), dQdXpW.end(), 0.0);
2693 fill(dQdXsB.begin(), dQdXsB.end(), 0.0);
2695 const USI npB = myBulk.phaseNum[n] + 1; ncolB = npB;
2696 for (
USI j = 0; j < np; j++) {
2697 phaseExistB[j] = myBulk.phaseExist[n * np + j];
2698 pEnumComB[j] = myBulk.pEnumCom[n * np + j];
2699 ncolB += pEnumComB[j];
2704 for (
USI j = 0; j < np; j++) {
2706 if (!phaseExistB[j]) {
2707 jxB += pEnumComB[j];
2711 n_np_j = n * np + j;
2712 dP = myBulk.Pj[n_np_j] - BHP - dG[p];
2713 xi = myBulk.xi[n_np_j];
2714 mu = myBulk.mu[n_np_j];
2715 muP = myBulk.muP[n_np_j];
2716 xiP = myBulk.xiP[n_np_j];
2719 for (
USI i = 0; i < nc; i++) {
2720 xij = myBulk.xij[n_np_j * nc + i];
2722 transIJ = perf[p].transj[j] * xi * xij;
2723 dQdXpB[(i + 1) * ncol] +=
2724 transIJ * (1 - dP * muP / mu) + dP * perf[p].transj[j] * xij * xiP;
2725 dQdXpW[(i + 1) * ncol] += -transIJ;
2729 for (
USI j1 = 0; j1 < np; j1++) {
2730 if (phaseExistB[j1]) {
2731 tmp =
CONV1 * perf[p].WI * perf[p].multiplier * dP / mu * xi * xij *
2732 myBulk.dKr_dS[n_np_j * np + j1];
2734 tmp += transIJ * myBulk.dPcj_dS[n_np_j * np + j1];
2735 dQdXsB[(i + 1) * ncolB + j1B] += tmp;
2740 for (
USI k = 0; k < pEnumComB[j]; k++) {
2741 tmp = dP * perf[p].transj[j] * xij *
2742 (myBulk.xix[n_np_j * nc + k] -
2743 xi / mu * myBulk.mux[n_np_j * nc + k]);
2744 tmp -= transIJ * dP / myBulk.nj[n_np_j];
2745 dQdXsB[(i + 1) * ncolB + jxB + k] += tmp;
2748 if (i < pEnumComB[j])
2749 dQdXsB[(i + 1) * ncolB + jxB + i] += perf[p].transj[j] * xi * dP / myBulk.nj[n_np_j];
2751 jxB += pEnumComB[j];
2757 DaAxpby(ncol, ncolB, -1.0, dQdXsB.data(),
2758 &myBulk.res_n[myBulk.resIndex[n]], 1.0, &myLS.b[n * ncol]);
2766 DaABpbC(ncol, ncol, ncolB, 1, dQdXsB.data(), &myBulk.dSec_dPri[myBulk.dSdPindex[n]], 1,
2769 Dscalar(bsize, dt, bmat.data());
2771 USI ptr = myLS.diagPtr[n];
2772 for (
USI i = 0; i < bsize; i++) {
2773 myLS.val[n][ptr * bsize + i] += bmat[i];
2777 Dscalar(bsize, dt, bmat.data());
2778 myLS.val[n].insert(myLS.val[n].end(), bmat.begin(), bmat.end());
2779 myLS.colId[n].push_back(wId);
2782 switch (opt.optMode) {
2789 fill(bmat.begin(), bmat.end(), 0.0);
2790 for (
USI i = 0; i < nc; i++) {
2791 bmat[0] += dQdXpW[(i + 1) * ncol] * prodWeight[i];
2792 bmat[(i + 1) * ncol + i + 1] = 1;
2794 for (
USI i = 0; i < bsize; i++) {
2795 myLS.diagVal[wId * bsize + i] += bmat[i];
2802 DaABpbC(ncol, ncol, ncolB, 1, dQdXsB.data(),
2803 &myBulk.dSec_dPri[myBulk.dSdPindex[n]], 1, bmat.data());
2804 fill(bmat2.begin(), bmat2.end(), 0.0);
2805 for (
USI i = 0; i < nc; i++) {
2806 Daxpy(ncol, prodWeight[i], bmat.data() + (i + 1) * ncol,
2809 myLS.val[wId].insert(myLS.val[wId].end(), bmat2.begin(), bmat2.end());
2810 myLS.colId[wId].push_back(n);
2815 fill(bmat.begin(), bmat.end(), 0.0);
2816 for (
USI i = 0; i < nc + 1; i++) {
2817 bmat[i * ncol + i] = 1;
2820 for (
USI i = 0; i < bsize; i++) {
2821 myLS.diagVal[wId * bsize + i] += bmat[i];
2824 fill(bmat.begin(), bmat.end(), 0.0);
2826 myLS.val[wId].insert(myLS.val[wId].end(), bmat.begin(), bmat.end());
2827 myLS.colId[wId].push_back(n);
2837 assert(myLS.val[wId].size() == numPerf * bsize);
2839 myLS.colId[wId].push_back(wId);
2840 myLS.diagPtr[wId] = numPerf;
2841 myLS.val[wId].insert(myLS.val[wId].end(), myLS.diagVal.data() + wId * bsize,
2842 myLS.diagVal.data() + wId * bsize + bsize);
2855 const USI np = myBulk.numPhase;
2856 const USI nc = myBulk.numCom;
2857 const USI ncol = nc + 1;
2858 const USI ncol2 = np * nc + np;
2859 const USI bsize = ncol * ncol;
2860 const USI bsize2 = ncol * ncol2;
2869 vector<OCP_DBL> bmat(bsize, 0);
2870 vector<OCP_DBL> bmat2(bsize, 0);
2871 vector<OCP_DBL> dQdXpB(bsize, 0);
2872 vector<OCP_DBL> dQdXpW(bsize, 0);
2873 vector<OCP_DBL> dQdXsB(bsize2, 0);
2875 for (
USI p = 0; p < numPerf; p++) {
2877 pIde = myBulk.map_Bulk2FIM[n];
2879 fill(dQdXpB.begin(), dQdXpB.end(), 0.0);
2880 fill(dQdXpW.begin(), dQdXpW.end(), 0.0);
2881 fill(dQdXsB.begin(), dQdXsB.end(), 0.0);
2883 dP = myBulk.P[n] - BHP - dG[p];
2885 for (
USI j = 0; j < np; j++) {
2886 n_np_j = n * np + j;
2887 if (!myBulk.phaseExist[n_np_j])
continue;
2889 pIde_np_j = pIde * np + j;
2890 mu = myBulk.mu[n_np_j];
2891 muP = myBulk.muP[pIde_np_j];
2893 for (
USI i = 0; i < nc; i++) {
2895 transIJ = perf[p].transj[j] * perf[p].xi * opt.zi[i];
2896 dQdXpB[(i + 1) * ncol] += transIJ * (1 - dP * muP / mu);
2897 dQdXpW[(i + 1) * ncol] += -transIJ;
2900 for (
USI k = 0; k < np; k++) {
2901 dQdXsB[(i + 1) * ncol2 + k] +=
2902 CONV1 * perf[p].WI * perf[p].multiplier * perf[p].xi *
2903 opt.zi[i] * myBulk.dKr_dS[pIde * np * np + j * np + k] * dP / mu;
2906 for (
USI k = 0; k < nc; k++) {
2907 dQdXsB[(i + 1) * ncol2 + np + j * nc + k] +=
2908 -transIJ * dP / mu * myBulk.mux[pIde_np_j * nc + k];
2914 DaABpbC(ncol, ncol, ncol2, 1, dQdXsB.data(), &myBulk.dSec_dPri[pIde * bsize2], 1,
2916 Dscalar(bsize, dt, bmat.data());
2918 USI ptr = myLS.diagPtr[pIde];
2919 for (
USI i = 0; i < bsize; i++) {
2920 myLS.val[pIde][ptr * bsize + i] += bmat[i];
2924 Dscalar(bsize, dt, bmat.data());
2925 myLS.val[pIde].insert(myLS.val[pIde].end(), bmat.begin(), bmat.end());
2926 myLS.colId[pIde].push_back(wId);
2929 switch (opt.optMode) {
2936 fill(bmat.begin(), bmat.end(), 0.0);
2937 for (
USI i = 0; i < nc; i++) {
2938 bmat[0] += dQdXpW[(i + 1) * ncol];
2939 bmat[(i + 1) * ncol + i + 1] = 1;
2941 for (
USI i = 0; i < bsize; i++) {
2942 myLS.diagVal[wId * bsize + i] += bmat[i];
2947 DaABpbC(ncol, ncol, ncol2, 1, dQdXsB.data(),
2948 &myBulk.dSec_dPri[pIde * bsize2], 1, bmat.data());
2949 fill(bmat2.begin(), bmat2.end(), 0.0);
2950 for (
USI i = 0; i < nc; i++) {
2951 Daxpy(ncol, 1.0, bmat.data() + (i + 1) * ncol, bmat2.data());
2953 myLS.val[wId].insert(myLS.val[wId].end(), bmat2.begin(), bmat2.end());
2954 myLS.colId[wId].push_back(pIde);
2959 fill(bmat.begin(), bmat.end(), 0.0);
2960 for (
USI i = 0; i < nc + 1; i++) {
2961 bmat[i * ncol + i] = 1;
2964 for (
USI i = 0; i < bsize; i++) {
2965 myLS.diagVal[wId * bsize + i] += bmat[i];
2968 fill(bmat.begin(), bmat.end(), 0.0);
2970 myLS.val[wId].insert(myLS.val[wId].end(), bmat.begin(), bmat.end());
2971 myLS.colId[wId].push_back(pIde);
2981 assert(myLS.val[wId].size() == numPerf * bsize);
2983 myLS.colId[wId].push_back(wId);
2984 myLS.diagPtr[wId] = numPerf;
2985 myLS.val[wId].insert(myLS.val[wId].end(), myLS.diagVal.data() + wId * bsize,
2986 myLS.diagVal.data() + wId * bsize + bsize);
2999 const USI np = myBulk.numPhase;
3000 const USI nc = myBulk.numCom;
3001 const USI ncol = nc + 1;
3002 const USI ncol2 = np * nc + np;
3003 const USI bsize = ncol * ncol;
3004 const USI bsize2 = ncol * ncol2;
3006 OCP_DBL xij, xi, mu, muP, xiP;
3014 vector<OCP_DBL> bmat(bsize, 0);
3015 vector<OCP_DBL> bmat2(bsize, 0);
3016 vector<OCP_DBL> dQdXpB(bsize, 0);
3017 vector<OCP_DBL> dQdXpW(bsize, 0);
3018 vector<OCP_DBL> dQdXsB(bsize2, 0);
3023 for (
USI p = 0; p < numPerf; p++) {
3025 pIde = myBulk.map_Bulk2FIM[n];
3026 fill(dQdXpB.begin(), dQdXpB.end(), 0.0);
3027 fill(dQdXpW.begin(), dQdXpW.end(), 0.0);
3028 fill(dQdXsB.begin(), dQdXsB.end(), 0.0);
3030 for (
USI j = 0; j < np; j++) {
3031 n_np_j = n * np + j;
3032 if (!myBulk.phaseExist[n_np_j])
continue;
3034 pIde_np_j = pIde * np + j;
3035 dP = myBulk.Pj[n_np_j] - BHP - dG[p];
3036 xi = myBulk.xi[n_np_j];
3037 mu = myBulk.mu[n_np_j];
3038 muP = myBulk.muP[pIde_np_j];
3039 xiP = myBulk.xiP[pIde_np_j];
3041 for (
USI i = 0; i < nc; i++) {
3042 xij = myBulk.xij[n_np_j * nc + i];
3044 transIJ = perf[p].transj[j] * xi * xij;
3045 dQdXpB[(i + 1) * ncol] +=
3046 transIJ * (1 - dP * muP / mu) + dP * perf[p].transj[j] * xij * xiP;
3047 dQdXpW[(i + 1) * ncol] += -transIJ;
3050 for (
USI k = 0; k < np; k++) {
3051 tmp =
CONV1 * perf[p].WI * perf[p].multiplier * dP / mu * xi * xij *
3052 myBulk.dKr_dS[pIde * np * np + j * np + k];
3054 tmp += transIJ * myBulk.dPcj_dS[pIde * np * np + j * np + k];
3055 dQdXsB[(i + 1) * ncol2 + k] += tmp;
3058 for (
USI k = 0; k < nc; k++) {
3059 tmp = dP * perf[p].transj[j] * xij *
3060 (myBulk.xix[pIde_np_j * nc + k] -
3061 xi / mu * myBulk.mux[pIde_np_j * nc + k]);
3063 tmp += perf[p].transj[j] * xi * dP;
3065 dQdXsB[(i + 1) * ncol2 + np + j * nc + k] += tmp;
3071 DaABpbC(ncol, ncol, ncol2, 1, dQdXsB.data(), &myBulk.dSec_dPri[pIde * bsize2], 1,
3078 Dscalar(bsize, dt, bmat.data());
3080 USI ptr = myLS.diagPtr[pIde];
3081 for (
USI i = 0; i < bsize; i++) {
3082 myLS.val[pIde][ptr * bsize + i] += bmat[i];
3086 Dscalar(bsize, dt, bmat.data());
3087 myLS.val[pIde].insert(myLS.val[pIde].end(), bmat.begin(), bmat.end());
3088 myLS.colId[pIde].push_back(wId);
3091 switch (opt.optMode) {
3098 fill(bmat.begin(), bmat.end(), 0.0);
3099 for (
USI i = 0; i < nc; i++) {
3100 bmat[0] += dQdXpW[(i + 1) * ncol] * prodWeight[i];
3101 bmat[(i + 1) * ncol + i + 1] = 1;
3103 for (
USI i = 0; i < bsize; i++) {
3104 myLS.diagVal[wId * bsize + i] += bmat[i];
3109 DaABpbC(ncol, ncol, ncol2, 1, dQdXsB.data(),
3110 &myBulk.dSec_dPri[pIde * bsize2], 1, bmat.data());
3111 fill(bmat2.begin(), bmat2.end(), 0.0);
3112 for (
USI i = 0; i < nc; i++) {
3113 Daxpy(ncol, prodWeight[i], bmat.data() + (i + 1) * ncol,
3116 myLS.val[wId].insert(myLS.val[wId].end(), bmat2.begin(), bmat2.end());
3117 myLS.colId[wId].push_back(pIde);
3122 fill(bmat.begin(), bmat.end(), 0.0);
3123 for (
USI i = 0; i < nc + 1; i++) {
3124 bmat[i * ncol + i] = 1;
3127 for (
USI i = 0; i < bsize; i++) {
3128 myLS.diagVal[wId * bsize + i] += bmat[i];
3131 fill(bmat.begin(), bmat.end(), 0.0);
3133 myLS.val[wId].insert(myLS.val[wId].end(), bmat.begin(), bmat.end());
3134 myLS.colId[wId].push_back(pIde);
3144 assert(myLS.val[wId].size() == numPerf * bsize);
3146 myLS.colId[wId].push_back(wId);
3147 myLS.diagPtr[wId] = numPerf;
3148 myLS.val[wId].insert(myLS.val[wId].end(), myLS.diagVal.data() + wId * bsize,
3149 myLS.diagVal.data() + wId * bsize + bsize);
3158 const OCP_USI& wId,
const vector<Well>& allWell)
const
3163 const USI nc = myBulk.numCom;
3164 const USI len = nc + 1;
3167 for (
USI p = 0; p < numPerf; p++) {
3168 k = perf[p].location;
3169 bIde = myBulk.map_Bulk2FIM[k];
3170 for (
USI i = 0; i < nc; i++) {
3171 resFIM.res[bIde * len + 1 + i] += perf[p].qi_lbmol[i] * dt;
3175 OCP_USI bId = (myBulk.numFIMBulk + wId) * len;
3177 if (opt.type ==
INJ) {
3179 switch (opt.optMode) {
3182 resFIM.res[bId] = BHP - opt.maxBHP;
3189 resFIM.res[bId] = opt.maxRate;
3190 for (
USI i = 0; i < nc; i++) {
3191 resFIM.res[bId] += qi_lbmol[i];
3194 for (
auto& w : opt.connWell) {
3196 for (
USI i = 0; i < nc; i++) {
3197 tmp += allWell[w].qi_lbmol[i];
3202 resFIM.res[bId] += tmp;
3209 resFIM.maxRelRes_v =
3210 max(resFIM.maxRelRes_v, fabs(resFIM.res[bId] / opt.maxRate));
3219 switch (opt.optMode) {
3222 resFIM.res[bId] = BHP - opt.minBHP;
3229 resFIM.res[bId] = -opt.maxRate;
3230 for (
USI i = 0; i < nc; i++) {
3231 resFIM.res[bId] += qi_lbmol[i] * prodWeight[i];
3236 resFIM.maxRelRes_v =
3237 max(resFIM.maxRelRes_v, fabs(resFIM.res[bId] / opt.maxRate));
3256 const USI np = myBulk.numPhase;
3257 const USI nc = myBulk.numCom;
3258 const USI ncol = nc + 1;
3259 const USI ncol2 = np * nc + np;
3260 const USI bsize = ncol * ncol;
3261 const USI bsize2 = ncol * ncol2;
3269 vector<OCP_DBL> bmat(bsize, 0);
3270 vector<OCP_DBL> bmat2(bsize, 0);
3271 vector<OCP_DBL> dQdXpB(bsize, 0);
3272 vector<OCP_DBL> dQdXpW(bsize, 0);
3273 vector<OCP_DBL> dQdXsB(bsize2, 0);
3275 for (
USI p = 0; p < numPerf; p++) {
3277 OCP_USI pId = myBulk.map_Bulk2FIM[n];
3278 OCP_ASSERT(pId < myBulk.numFIMBulk,
"wrong FIM Bulk");
3280 fill(dQdXpB.begin(), dQdXpB.end(), 0.0);
3281 fill(dQdXpW.begin(), dQdXpW.end(), 0.0);
3282 fill(dQdXsB.begin(), dQdXsB.end(), 0.0);
3284 dP = myBulk.P[n] - BHP - dG[p];
3286 for (
USI j = 0; j < np; j++) {
3287 n_np_j = n * np + j;
3288 if (!myBulk.phaseExist[n_np_j])
continue;
3290 mu = myBulk.mu[n_np_j];
3291 muP = myBulk.muP[n_np_j];
3293 for (
USI i = 0; i < nc; i++) {
3295 transIJ = perf[p].transj[j] * perf[p].xi * opt.zi[i];
3296 dQdXpB[(i + 1) * ncol] += transIJ * (1 - dP * muP / mu);
3297 dQdXpW[(i + 1) * ncol] += -transIJ;
3300 for (
USI k = 0; k < np; k++) {
3301 dQdXsB[(i + 1) * ncol2 + k] +=
3302 CONV1 * perf[p].WI * perf[p].multiplier * perf[p].xi *
3303 opt.zi[i] * myBulk.dKr_dS[pId * np * np + j * np + k] * dP / mu;
3306 for (
USI k = 0; k < nc; k++) {
3307 dQdXsB[(i + 1) * ncol2 + np + j * nc + k] +=
3308 -transIJ * dP / mu * myBulk.mux[n_np_j * nc + k];
3314 DaABpbC(ncol, ncol, ncol2, 1, dQdXsB.data(), &myBulk.dSec_dPri[pId * bsize2], 1,
3316 Dscalar(bsize, dt, bmat.data());
3318 USI ptr = myLS.diagPtr[n];
3319 for (
USI i = 0; i < bsize; i++) {
3320 myLS.val[n][ptr * bsize + i] += bmat[i];
3324 Dscalar(bsize, dt, bmat.data());
3325 myLS.val[n].insert(myLS.val[n].end(), bmat.begin(), bmat.end());
3326 myLS.colId[n].push_back(wId);
3329 switch (opt.optMode) {
3336 fill(bmat.begin(), bmat.end(), 0.0);
3337 for (
USI i = 0; i < nc; i++) {
3338 bmat[0] += dQdXpW[(i + 1) * ncol];
3339 bmat[(i + 1) * ncol + i + 1] = 1;
3341 for (
USI i = 0; i < bsize; i++) {
3342 myLS.diagVal[wId * bsize + i] += bmat[i];
3347 DaABpbC(ncol, ncol, ncol2, 1, dQdXsB.data(),
3348 &myBulk.dSec_dPri[pId * bsize2], 1, bmat.data());
3349 fill(bmat2.begin(), bmat2.end(), 0.0);
3350 for (
USI i = 0; i < nc; i++) {
3351 Daxpy(ncol, 1.0, bmat.data() + (i + 1) * ncol, bmat2.data());
3353 myLS.val[wId].insert(myLS.val[wId].end(), bmat2.begin(), bmat2.end());
3354 myLS.colId[wId].push_back(n);
3359 fill(bmat.begin(), bmat.end(), 0.0);
3360 for (
USI i = 0; i < nc + 1; i++) {
3361 bmat[i * ncol + i] = 1;
3364 for (
USI i = 0; i < bsize; i++) {
3365 myLS.diagVal[wId * bsize + i] += bmat[i];
3368 fill(bmat.begin(), bmat.end(), 0.0);
3370 myLS.val[wId].insert(myLS.val[wId].end(), bmat.begin(), bmat.end());
3371 myLS.colId[wId].push_back(n);
3381 assert(myLS.val[wId].size() == numPerf * bsize);
3383 myLS.colId[wId].push_back(wId);
3384 myLS.diagPtr[wId] = numPerf;
3385 myLS.val[wId].insert(myLS.val[wId].end(), myLS.diagVal.data() + wId * bsize,
3386 myLS.diagVal.data() + wId * bsize + bsize);
3399 const USI np = myBulk.numPhase;
3400 const USI nc = myBulk.numCom;
3401 const USI ncol = nc + 1;
3402 const USI ncol2 = np * nc + np;
3403 const USI bsize = ncol * ncol;
3404 const USI bsize2 = ncol * ncol2;
3406 OCP_DBL xij, xi, mu, muP, xiP;
3413 vector<OCP_DBL> bmat(bsize, 0);
3414 vector<OCP_DBL> bmat2(bsize, 0);
3415 vector<OCP_DBL> dQdXpB(bsize, 0);
3416 vector<OCP_DBL> dQdXpW(bsize, 0);
3417 vector<OCP_DBL> dQdXsB(bsize2, 0);
3422 for (
USI p = 0; p < numPerf; p++) {
3424 OCP_USI pId = myBulk.map_Bulk2FIM[n];
3425 OCP_ASSERT(pId < myBulk.numFIMBulk,
"wrong FIM Bulk");
3427 fill(dQdXpB.begin(), dQdXpB.end(), 0.0);
3428 fill(dQdXpW.begin(), dQdXpW.end(), 0.0);
3429 fill(dQdXsB.begin(), dQdXsB.end(), 0.0);
3431 for (
USI j = 0; j < np; j++) {
3432 n_np_j = n * np + j;
3433 if (!myBulk.phaseExist[n_np_j])
continue;
3435 dP = myBulk.Pj[n_np_j] - BHP - dG[p];
3436 xi = myBulk.xi[n_np_j];
3437 mu = myBulk.mu[n_np_j];
3438 muP = myBulk.muP[n_np_j];
3439 xiP = myBulk.xiP[n_np_j];
3441 for (
USI i = 0; i < nc; i++) {
3442 xij = myBulk.xij[n_np_j * nc + i];
3444 transIJ = perf[p].transj[j] * xi * xij;
3445 dQdXpB[(i + 1) * ncol] +=
3446 transIJ * (1 - dP * muP / mu) + dP * perf[p].transj[j] * xij * xiP;
3447 dQdXpW[(i + 1) * ncol] += -transIJ;
3454 for (
USI k = 0; k < np; k++) {
3455 tmp =
CONV1 * perf[p].WI * perf[p].multiplier * dP / mu * xi * xij *
3456 myBulk.dKr_dS[pId * np * np + j * np + k];
3458 tmp += transIJ * myBulk.dPcj_dS[pId * np * np + j * np + k];
3459 dQdXsB[(i + 1) * ncol2 + k] += tmp;
3462 for (
USI k = 0; k < nc; k++) {
3463 tmp = dP * perf[p].transj[j] * xij *
3464 (myBulk.xix[n_np_j * nc + k] -
3465 xi / mu * myBulk.mux[n_np_j * nc + k]);
3467 tmp += perf[p].transj[j] * xi * dP;
3469 dQdXsB[(i + 1) * ncol2 + np + j * nc + k] += tmp;
3475 DaABpbC(ncol, ncol, ncol2, 1, dQdXsB.data(), &myBulk.dSec_dPri[pId * bsize2], 1,
3478 Dscalar(bsize, dt, bmat.data());
3480 USI ptr = myLS.diagPtr[n];
3481 for (
USI i = 0; i < bsize; i++) {
3482 myLS.val[n][ptr * bsize + i] += bmat[i];
3486 Dscalar(bsize, dt, bmat.data());
3487 myLS.val[n].insert(myLS.val[n].end(), bmat.begin(), bmat.end());
3488 myLS.colId[n].push_back(wId);
3491 switch (opt.optMode) {
3498 fill(bmat.begin(), bmat.end(), 0.0);
3499 for (
USI i = 0; i < nc; i++) {
3500 bmat[0] += dQdXpW[(i + 1) * ncol] * prodWeight[i];
3501 bmat[(i + 1) * ncol + i + 1] = 1;
3503 for (
USI i = 0; i < bsize; i++) {
3504 myLS.diagVal[wId * bsize + i] += bmat[i];
3509 DaABpbC(ncol, ncol, ncol2, 1, dQdXsB.data(),
3510 &myBulk.dSec_dPri[pId * bsize2], 1, bmat.data());
3511 fill(bmat2.begin(), bmat2.end(), 0.0);
3512 for (
USI i = 0; i < nc; i++) {
3513 Daxpy(ncol, prodWeight[i], bmat.data() + (i + 1) * ncol,
3516 myLS.val[wId].insert(myLS.val[wId].end(), bmat2.begin(), bmat2.end());
3517 myLS.colId[wId].push_back(n);
3522 fill(bmat.begin(), bmat.end(), 0.0);
3523 for (
USI i = 0; i < nc + 1; i++) {
3524 bmat[i * ncol + i] = 1;
3527 for (
USI i = 0; i < bsize; i++) {
3528 myLS.diagVal[wId * bsize + i] += bmat[i];
3531 fill(bmat.begin(), bmat.end(), 0.0);
3533 myLS.val[wId].insert(myLS.val[wId].end(), bmat.begin(), bmat.end());
3534 myLS.colId[wId].push_back(n);
3544 assert(myLS.val[wId].size() == numPerf * bsize);
3546 myLS.colId[wId].push_back(wId);
3547 myLS.diagPtr[wId] = numPerf;
3548 myLS.val[wId].insert(myLS.val[wId].end(), myLS.diagVal.data() + wId * bsize,
3549 myLS.diagVal.data() + wId * bsize + bsize);
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.
void Daxpy(const int &n, const double &alpha, const double *x, double *y)
Constant times a vector plus a vector.
double Dnorm1(const int &N, double *x)
Computes the L1-norm of a vector.
const USI X_DIRECTION
x-direction
const USI BLKOIL
Mixture model = black-oil.
const OCP_DBL TINY
Small constant.
const USI EOS_PVTW
Mixture model = equation-of-state.
unsigned int USI
Generic unsigned integer.
const USI GAS
Fluid type = gas.
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 WATER
Fluid type = water.
const USI PHASE_ODGW
Phase type = oil-dry gas-water.
const USI Y_DIRECTION
y-direction
const USI ORATE_MODE
Well option = fixed oil rate.
const USI OIL
Fluid type = oil.
const bool CLOSE
Well type = closed.
const USI PHASE_W
Phase type = water only.
const USI RATE_MODE
Well option = fixed total rate???
unsigned int OCP_USI
Long unsigned integer.
const bool OPEN
Well type = open.
const USI Z_DIRECTION
z-direction
const USI PHASE_OW
Phase type = oil-water.
const USI PROD
Well type = producer.
const OCP_DBL TEMPERATURE_STD
Standard temperature.
const USI PHASE_DOGW
Phase type = dead oil-gas-water.
const USI INJ
Well type = injector.
const USI BHP_MODE
Well option = fixed bottom-hole-pressure.
const USI GRATE_MODE
Well option = fixed gas rate.
const OCP_DBL PRESSURE_STD
14.6959 psia = 1 atm
const OCP_DBL CONV2
Darcy constant in field unit.
#define OCP_FUNCNAME
Print Function Name.
#define OCP_WARNING(msg)
Log warning messages.
#define OCP_ASSERT(cond, msg)
Assert condition and log user messages in DEBUG mode.
#define OCP_ABORT(msg)
Abort if critical error happens.
Physical information of each active reservoir bulk.
Basic information of computational grid, including the rock properties.
Linear solvers for discrete systems.
OCP_DBL maxBHP
Maximum allowable pressure in the injection well.
string type
Type of well, injection or production?
string fluidType
Type of fluid into the injection well. (injection well only)
OCP_DBL maxRate
Maximum allowable flow rate into/out the well.
string optMode
Mode of well, Rate or BHP?
OCP_DBL minBHP
Minimum allowable pressure in the production well.
string state
State of well, open or close?
WellOpt()=default
Default constructor.
bool operator!=(const WellOpt &Opt) const
overload inequality
vector< string > direction
Direction of perforations.
vector< OCP_DBL > diameter
Diameter of perforations.
vector< OCP_DBL > skinFactor
Skin factor.
vector< USI > I_perf
I-index of perforation in grid.
vector< OCP_DBL > WI
Transmissiblity connection factor.
vector< USI > J_perf
J-index of perforation in grid.
vector< USI > K_perf
K-index of perforation in grid.
void AssembleMatPROD_AIMt(const Bulk &myBulk, LinearSystem &myLS, const OCP_DBL &dt) const
Assemble matrix for AIMt, parts related to Production well are included.
void AssembleMatPROD_IMPEC(const Bulk &myBulk, LinearSystem &myLS, const OCP_DBL &dt) const
Assemble matrix for IMPEC, parts related to production well are included.
void AssembleMatReinjection_IMPEC(const Bulk &myBulk, LinearSystem &myLS, const OCP_DBL &dt, const vector< Well > &allWell, const vector< USI > &injId) const
void SetBHP()
Set BHP if opt mode is BHPMode.
void Setup(const Grid &myGrid, const Bulk &myBulk, const vector< SolventINJ > &sols)
Setup the well after Grid and Bulk finish setupping.
void CheckOptMode(const Bulk &myBulk)
Check if well operation mode would be changed.
void CalProdQjCOMP(const Bulk &myBulk)
Calculate flow rate of moles of phase for production well in Compositional Model.
void CalWI_Peaceman_Vertical(const Bulk &myBulk)
Calculate Well Index with Peaceman model for vertical well.
OCP_INT CheckP(const Bulk &myBulk)
Check if abnormal Pressure occurs.
void AssembleMatINJ_AIMt(const Bulk &myBulk, LinearSystem &myLS, const OCP_DBL &dt) const
Assemble matrix for AIMt, parts related to Injection well are included.
void CalInjdG(const Bulk &myBulk)
Calculate pressure difference between well and perforations for Injection.
void AssembleMatINJ_FIM(const Bulk &myBulk, LinearSystem &myLS, const OCP_DBL &dt) const
Assemble matrix for FIM, parts related to Injection well are included.
void AssembleMatPROD_FIM_new(const Bulk &myBulk, LinearSystem &myLS, const OCP_DBL &dt) const
Assemble matrix for FIM, parts related to Production well are included.
void CalProdQj(const Bulk &myBulk, const OCP_DBL &dt)
Calculate flow rate of moles of phase for production well.
void AssembleMatINJ_FIM_new(const Bulk &myBulk, LinearSystem &myLS, const OCP_DBL &dt) const
Assemble matrix for FIM, parts related to Injection well are included.
void SetupWellBulk(Bulk &myBulk) const
Setup bulks which are penetrated by wells.
void MassConserveIMPEC(Bulk &myBulk, const OCP_DBL &dt) const
Update moles of components in those bulks who connects to the well.
void CalReInjFluid(const Bulk &myBulk, vector< OCP_DBL > &myZi)
Calculate the contribution of production well to reinjection defaulted.
void InputPerfo(const WellParam &well)
Input the param of perforations.
void AssembleMatPROD_FIM(const Bulk &myBulk, LinearSystem &myLS, const OCP_DBL &dt) const
Assemble matrix for FIM, parts related to Production well are included.
void AssembleMatINJ_AIMs(const Bulk &myBulk, LinearSystem &myLS, const OCP_DBL &dt) const
Assemble matrix for AIMs, parts related to Injection well are included.
void CalProdQiBO(const Bulk &myBulk)
bool WellState() const
Return the state of the well, Open or Close.
void AssembleMatPROD_AIMs(const Bulk &myBulk, LinearSystem &myLS, const OCP_DBL &dt) const
Assemble matrix for AIMs, parts related to Production well are included.
void CalTrans(const Bulk &myBulk)
Calculate transmissibility for each phase in perforations.
void CalFlux(const Bulk &myBulk, const bool flag=false)
Calculate the flux for each perforations.
void CalProddG(const Bulk &myBulk)
Calculate pressure difference between well and perforations for Prodcution.
void AllocateMat(LinearSystem &myLS) const
Allocate memory for matrix.
void CaldG(const Bulk &myBulk)
Calculate pressure difference between well and perforations.
void AssembleMatINJ_IMPEC(const Bulk &myBulk, LinearSystem &myLS, const OCP_DBL &dt) const
Assemble matrix for IMPEC, parts related to injection well are included.
OCP_INT CheckCrossFlow(const Bulk &myBulk)
Check if crossflow happens.
void SmoothdG()
Try to smooth the dG by average it with dG at last time step.
void CalResAIMt(ResFIM &resFIM, const Bulk &myBulk, const OCP_DBL &dt, const OCP_USI &wId, const vector< Well > &allWell) const
Calculate Resiual and relative Resiual for local FIM.
void AssembleMatReinjection_FIM(const Bulk &myBulk, LinearSystem &myLS, const OCP_DBL &dt, const vector< Well > &allWell, const vector< USI > &injId) const
void ShowPerfStatus(const Bulk &myBulk) const
Display operation mode of well and state of perforations.
void InitBHP(const Bulk &myBulk)
Initialize the Well BHP.
void CalInjQi(const Bulk &myBulk, const OCP_DBL &dt)
Calculate flow rate of moles of components for injection well.
OCP_DBL CalProdRate(const Bulk &myBulk, const bool &minBHP)
calculate flow rate of moles of components for production well with minBHP
void CalProdWeight(const Bulk &myBulk) const
Calculate the Prodweight.
void CalCFL(const Bulk &myBulk, const OCP_DBL &dt) const
Calculate the CFL number, only parts related to wells are considered.
OCP_DBL CalInjRate(const Bulk &myBulk, const bool &maxBHP)
calculate flow rate of moles of components for injection well with maxBHP
void CalResFIM(ResFIM &resFIM, const Bulk &myBulk, const OCP_DBL &dt, const OCP_USI &wId, const vector< Well > &allWell) const
Calculate Resiual and relative Resiual for FIM.