25 for (
USI i = 0; i < len; i++) {
26 solvents[i] = paramWell.
solSet[i];
29 numWell = paramWell.
well.size();
30 wells.resize(numWell);
32 vector<USI> wellCriticalTime;
33 for (
USI w = 0; w < numWell; w++) {
34 wells[w].name = paramWell.
well[w].name;
35 wells[w].group = paramWell.
well[w].group;
36 wells[w].depth = paramWell.
well[w].depth;
37 wells[w].I = paramWell.
well[w].I - 1;
38 wells[w].J = paramWell.
well[w].J - 1;
39 wells[w].InputPerfo(paramWell.
well[w]);
42 wells[w].optSet.resize(t);
43 USI n = paramWell.
well[w].optParam.size();
44 wellCriticalTime.clear();
45 wellCriticalTime.resize(n + 1);
46 for (
USI i = 0; i < n; i++) {
47 wellCriticalTime[i] = paramWell.
well[w].optParam[i].d;
49 wellCriticalTime.back() = t;
50 for (
USI i = 0; i < n; i++) {
51 for (
USI d = wellCriticalTime[i]; d < wellCriticalTime[i + 1]; d++) {
52 wells[w].optSet[d] =
WellOpt(paramWell.
well[w].optParam[i].opt);
70 for (
USI w = 0; w < numWell; w++) {
71 wells[w].Setup(myGrid, myBulk, solvents);
81 for (
USI w = 0; w < numWell; w++) {
82 wellGroup[0].wId.push_back(w);
83 if (wells[w].WellType() ==
INJ)
84 wellGroup[0].wIdINJ.push_back(w);
86 wellGroup[0].wIdPROD.push_back(w);
92 for (
USI w = 0; w < numWell; w++) {
93 for (g = 1; g < glen; g++) {
94 if (wells[w].group == wellGroup[g].name) {
96 wellGroup[g].wId.push_back(w);
97 if (wells[w].WellType() ==
INJ)
98 wellGroup[g].wIdINJ.push_back(w);
100 wellGroup[g].wIdPROD.push_back(w);
104 if (g == glen && wells[w].group !=
"Field") {
106 wellGroup.push_back(
WellGroup(wells[w].group));
107 wellGroup[glen].wId.push_back(w);
108 if (wells[w].WellType() ==
INJ) wellGroup[glen].wIdINJ.push_back(w);
109 else wellGroup[glen].wIdPROD.push_back(w);
114 numGroup = wellGroup.size();
121 wellGroup[0].reInj =
true;
122 wellGroup[0].saleRate = 1500;
123 wellGroup[0].injPhase =
GAS;
124 wellGroup[0].prodGroup = 0;
126 wellGroup[0].zi.resize(myBulk.
GetComNum());
141 myBulk.ClearWellBulkId();
142 for (
USI w = 0; w < numWell; w++) {
143 if (wells[w].WellState()) {
144 wells[w].SetupWellBulk(myBulk);
154 for (
USI w = 0; w < numWell; w++) {
155 wells[w].opt = wells[w].optSet[i];
156 if (wells[w].WellState()) {
160 if (i > 0 && wells[w].opt != wells[w].optSet[i - 1])
169 for (
USI w = 0; w < numWell; w++) {
170 wells[w].InitBHP(myBulk);
178 for (
USI w = 0; w < numWell; w++) {
179 if (wells[w].WellState()) {
181 wells[w].CalTrans(myBulk);
182 wells[w].CalFlux(myBulk,
true);
183 wells[w].CalProdWeight(myBulk);
184 wells[w].CaldG(myBulk);
187 wells[w].CheckOptMode(myBulk);
196 for (
USI w = 0; w < numWell; w++) {
197 if (wells[w].WellState()) {
198 wells[w].CalTrans(myBulk);
207 for (
USI w = 0; w < numWell; w++) {
208 if (wells[w].WellState()) {
209 wells[w].CalFlux(myBulk,
false);
218 for (
USI w = 0; w < numWell; w++) {
219 if (wells[w].WellState()) {
220 wells[w].CalProdWeight(myBulk);
229 for (
USI w = 0; w < numWell; w++) {
230 if (wells[w].WellState()) {
231 wells[w].CaldG(myBulk);
245 for (
USI w = 0; w < numWell; w++) {
252 if (wells[w].WellState()) {
253 if (wells[w].WellType() ==
PROD) {
254 wells[w].CalProdQj(myBulk, dt);
256 wells[w].CalInjQi(myBulk, dt);
259 FGIR += wells[w].WGIR;
260 FWIR += wells[w].WWIR;
261 FOPR += wells[w].WOPR;
262 FGPR += wells[w].WGPR;
263 FWPR += wells[w].WWPR;
275 for (
auto& wG : wellGroup) {
279 fill(wG.zi.begin(), wG.zi.end(), 0.0);
280 for (
auto& prod : wellGroup[wG.prodGroup].wIdPROD) {
281 Daxpy(nc, 1.0, &wells[prod].qi_lbmol[0], &wG.zi[0]);
284 if (fabs(qt) < 1E-8) {
286 fill(wG.zi.begin(), wG.zi.end(), 0.0);
287 for (
auto& prod : wellGroup[wG.prodGroup].wIdPROD) {
288 wells[prod].CalReInjFluid(myBulk, wG.zi);
290 qt =
Dnorm1(nc, &wG.zi[0]);
293 Dcopy(nc, &wG.zi[0], &flashCal[0]->xij[wG.injPhase * nc]);
294 wG.xi = flashCal[0]->xi[wG.injPhase];
295 wG.factor = wG.xi * flashCal[0]->v[wG.injPhase] / qt;
297 for (
auto& w : wG.wIdINJ) {
298 if (wells[w].WellState()) {
299 wells[w].opt.reInj =
true;
300 wells[w].opt.connWell = wG.wIdPROD;
301 wells[w].opt.injPhase = wG.injPhase;
302 wells[w].opt.zi = wG.zi;
303 wells[w].opt.xiINJ = wG.xi;
304 wells[w].opt.factor = wG.factor;
305 wells[w].opt.maxRate = -wG.saleRate * wG.xi * 1000;
323 for (
USI w = 0; w < numWell; w++) {
324 wells[w].AllocateMat(myLS);
329 void AllWells::ResetBHP()
331 for (
auto& w : wells) {
351 for (
USI w = 0; w < numWell; w++) {
352 if (wells[w].WellState()) {
354 OCP_INT flag = wells[w].CheckP(myBulk);
373 if (flag2 || flag3)
return 2;
383 for (
USI w = 0; w < numWell; w++) {
384 if (wells[w].name == name) {
394 for (
USI w = 0; w < numWell; w++) {
395 numPerf += wells[w].numPerf;
405 for (
USI w = 0; w < numWell; w++) {
406 m = max(m, wells[w].numPerf);
411 void AllWells::CalMaxBHPChange()
414 for (
USI w = 0; w < numWell; w++) {
415 if (wells[w].WellState()) {
416 dPmax = max(dPmax, fabs(wells[w].BHP - wells[w].lBHP));
424 for (
USI w = 0; w < numWell; w++) {
425 if (wells[w].WellState()) {
426 for (
auto& q : wells[w].qi_lbmol) {
443 for (
USI w = 0; w < numWell; w++) {
444 if (wells[w].WellState()) {
445 wells[w].CalCFL(myBulk, dt);
454 for (
USI w = 0; w < numWell; w++) {
455 if (wells[w].WellState()) {
456 wells[w].MassConserveIMPEC(myBulk, dt);
466 for (
USI w = 0; w < numWell; w++) {
467 if (wells[w].WellState()) {
468 switch (wells[w].WellType()) {
470 wells[w].AssembleMatINJ_IMPEC(myBulk, myLS, dt);
473 wells[w].AssembleMatPROD_IMPEC(myBulk, myLS, dt);
482 for (
auto& wG : wellGroup) {
484 for (
auto& prod : wellGroup[wG.prodGroup].wIdPROD) {
485 if (wells[prod].WellState()) {
486 wells[prod].AssembleMatReinjection_IMPEC(myBulk, myLS, dt, wells, wG.wIdINJ);
499 for (
USI w = 0; w < numWell; w++) {
500 if (wells[w].WellState()) {
501 wells[w].BHP = u[bId + wId];
502 wells[w].UpdatePerfP();
517 for (
USI w = 0; w < numWell; w++) {
518 if (wells[w].WellState()) {
520 switch (wells[w].WellType()) {
522 wells[w].AssembleMatINJ_FIM(myBulk, myLS, dt);
525 wells[w].AssembleMatPROD_FIM(myBulk, myLS, dt);
534 for (
auto& wG : wellGroup) {
536 for (
auto& prod : wellGroup[wG.prodGroup].wIdPROD) {
537 if (wells[prod].WellState()) {
538 wells[prod].AssembleMatReinjection_FIM(myBulk, myLS, dt, wells, wG.wIdINJ);
550 for (
USI w = 0; w < numWell; w++) {
551 if (wells[w].WellState()) {
552 wells[w].BHP += u[(bId + wId) * len];
553 wells[w].UpdatePerfP();
559 void AllWells::GetSol01FIM(
const vector<OCP_DBL>& u,
const OCP_USI& bId,
563 for (
USI w = 0; w < numWell; w++) {
564 if (wells[w].WellState()) {
565 wells[w].BHP += u[(bId + wId) * len] * alpha;
566 wells[w].UpdatePerfP();
577 for (
USI w = 0; w < numWell; w++) {
578 if (wells[w].WellState()) {
579 wells[w].CalResFIM(resFIM, myBulk, dt, wId, wells);
590 for (
USI w = 0; w < numWell; w++) {
591 if (wells[w].WellState()) {
593 wells[w].ShowRes(wId, res, myBulk);
611 for (
USI w = 0; w < numWell; w++) {
612 if (wells[w].WellState()) {
614 switch (wells[w].WellType()) {
616 wells[w].AssembleMatINJ_FIM_new(myBulk, myLS, dt);
619 wells[w].AssembleMatPROD_FIM_new(myBulk, myLS, dt);
634 for (
USI w = 0; w < numWell; w++) {
635 if (wells[w].WellState()) {
637 switch (wells[w].WellType()) {
639 wells[w].AssembleMatINJ_FIM_new_n(myBulk, myLS, dt);
642 wells[w].AssembleMatPROD_FIM_new_n(myBulk, myLS, dt);
660 for (
USI w = 0; w < numWell; w++) {
661 if (wells[w].WellState()) {
663 switch (wells[w].WellType()) {
665 wells[w].AssembleMatINJ_AIMt(myBulk, myLS, dt);
668 wells[w].AssembleMatPROD_AIMt(myBulk, myLS, dt);
682 for (
USI w = 0; w < numWell; w++) {
683 if (wells[w].WellState()) {
684 wells[w].CalResAIMt(resFIM, myBulk, dt, wId, wells);
697 for (
USI w = 0; w < numWell; w++) {
698 if (wells[w].WellState()) {
699 wells[w].BHP += u[(bId + wId) * len];
700 wells[w].UpdatePerfP();
709 for (
USI w = 0; w < numWell; w++) {
710 if (wells[w].WellState()) {
712 switch (wells[w].WellType()) {
714 wells[w].AssembleMatINJ_AIMs(myBulk, myLS, dt);
717 wells[w].AssembleMatPROD_AIMs(myBulk, myLS, dt);
AllWells class declaration.
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.
void Dcopy(const int &N, double *dst, const double *src)
Calculate the minimal eigenvalue for sysmetric matrix with mkl lapack.
unsigned int USI
Generic unsigned integer.
const USI GAS
Fluid type = gas.
double OCP_DBL
Double precision.
unsigned int OCP_USI
Long unsigned integer.
const USI PROD
Well type = producer.
const OCP_DBL TEMPERATURE_STD
Standard temperature.
const USI INJ
Well type = injector.
const OCP_DBL PRESSURE_STD
14.6959 psia = 1 atm
#define OCP_FUNCNAME
Print Function Name.
#define OCP_ABORT(msg)
Abort if critical error happens.
void ShowRes(const vector< OCP_DBL > &res, const Bulk &myBulk) const
Show Res.
void CalResAIMt(ResFIM &resFIM, const Bulk &myBulk, const OCP_DBL &dt) const
Calculate Resiual and relative Resiual for local FIM.
void CalFlux(const Bulk &myBulk)
Calculate volume flow rate and moles flow rate of each perforation.
void CalTrans(const Bulk &myBulk)
Calculate Transmissibility of Wells.
void AllocateMat(LinearSystem &myLS, const USI &bulknum) const
Calculate memory for Matrix.
USI GetMaxWellPerNum() const
Calculate mamimum num of perforations of all Wells.
void AssemblaMatFIM(LinearSystem &myLS, const Bulk &myBulk, const OCP_DBL &dt) const
Assemble matrix, parts related to well are included for FIM.
void SetupWell(const Grid &myGrid, const Bulk &myBulk)
complete the information of well according to Grid and Bulk.
void AssemblaMatAIMt(LinearSystem &myLS, const Bulk &myBulk, const OCP_DBL &dt) const
Assemble matrix, parts related to well are included for AIMt.
void AssemblaMatIMPEC(LinearSystem &myLS, const Bulk &myBulk, const OCP_DBL &dt) const
Assemble matrix, parts related to well are included for IMPEC.
void MassConserveIMPEC(Bulk &myBulk, OCP_DBL dt)
Update moles of components in Bulks which connects to well.
OCP_INT CheckP(const Bulk &myBulk)
Check if unreasonable well pressure or perforation pressure occurs.
void CaldG(const Bulk &myBulk)
Calculate dG.
void ApplyControl(const USI &i)
Apply the operation mode at the ith critical time.
void SetupMixture(const Bulk &myBulk)
get the mixture from bulk -— usless now
void AssemblaMatFIM_new(LinearSystem &myLS, const Bulk &myBulk, const OCP_DBL &dt) const
Assemble matrix, parts related to well are included for FIM.
USI GetWellPerfNum() const
Return the num of perforations of all wells.
void CalIPRT(const Bulk &myBulk, OCP_DBL dt)
Calculate Injection rate, total Injection, Production rate, total Production.
void SetupWellBulk(Bulk &myBulk) const
Setup bulks which are penetrated by wells.
void GetSolAIMt(const vector< OCP_DBL > &u, const OCP_USI &bId, const USI &len)
Get solution from solver class after linear system is solved for local FIM.
void GetSolFIM(const vector< OCP_DBL > &u, const OCP_USI &bId, const USI &len)
Get solution from solver class after linear system is solved for FIM.
void GetSolIMPEC(const vector< OCP_DBL > &u, const OCP_USI &bId)
Update Well P and Perforation P after linear system is solved for IMPEC.
void InitBHP(const Bulk &myBulk)
Set the initial well pressure.
void SetupWellGroup(const Bulk &myBulk)
Setup information of wellGroup.
void CalProdWeight(const Bulk &myBulk)
Calculate Prodweight.
USI GetIndex(const string &name) const
Return the index of specified well.
void Setup(const Grid &myGrid, const Bulk &myBulk)
Setup well in allWells.
void PrepareWell(const Bulk &myBulk)
Calculate well properties at the beginning of each time step.
void CalResFIM(ResFIM &resFIM, const Bulk &myBulk, const OCP_DBL &dt) const
Calculate Resiual and relative Resiual for FIM.
void CalReInjFluid(const Bulk &myBulk)
Calculate Reinjection fluid.
void InputParam(const ParamWell ¶mWell)
Input param from ParamWell.
void CalCFL(const Bulk &myBulk, const OCP_DBL &dt) const
Calculate the CFL number for each perforation and return the maximum one.
void AssemblaMatAIMs(LinearSystem &myLS, const Bulk &myBulk, const OCP_DBL &dt) const
Assemble matrix, parts related to well are included for AIMt.
Physical information of each active reservoir bulk.
const vector< Mixture * > & GetMixture() const
Return flash results (it has not been used by far).
USI GetComNum() const
Return the number of components.
Basic information of computational grid, including the rock properties.
Linear solvers for discrete systems.
void EnlargeRowCap(const OCP_USI &row, const USI &n)
Enlarge row capacity.
vector< Solvent > solSet
Sets of Solvent.
vector< OCP_DBL > criticalTime
Records the critical time given by users.
vector< WellParam > well
Contains all the information of wells.