NeoPZ
pzblackoilanalysis.cpp
Go to the documentation of this file.
1 
6 #include "pzblackoilanalysis.h"
7 #include "pzblackoil2p3d.h"
8 #include "TPZSpStructMatrix.h"
9 #include "pzfstrmatrix.h"
10 #include "pzstrmatrix.h"
11 #include "pzseqsolver.h"
12 #include "checkconv.h"
13 
14 using namespace std;
15 
16 #ifdef _AUTODIFF
17 
18 TPZBlackOilAnalysis::TPZBlackOilAnalysis(TPZCompMesh *mesh, double TimeStep, std::ostream &out):TPZNonLinearAnalysis(mesh,out){
19  this->fTimeStep = TimeStep;
20  this->fSimulationTime = 0.;
21  this->SetConvergence(0, 0.);
22  this->SetNewtonConvergence(0, 0.);
23  this->SetInitialSolutionAsZero();
24  this->SetSaveFrequency(0,0);
25 }
26 
27 TPZBlackOilAnalysis::~TPZBlackOilAnalysis(){
28  //nothing to be done here
29 }
30 
31 void TPZBlackOilAnalysis::SetInitialSolution(TPZFMatrix<STATE> & InitialSol){
32  const int nrows = this->Mesh()->Solution().Rows();
33  const int ncols = this->Mesh()->Solution().Cols();
34  if ( (InitialSol.Rows() != nrows) || (InitialSol.Cols() != ncols) ){
35  PZError << "ERROR! " << __PRETTY_FUNCTION__ << " at line " << __LINE__ << std::endl;
36  }
37  else{
38  this->fSolution = InitialSol;
39  }
41 }
42 
43 void TPZBlackOilAnalysis::SetInitialSolutionAsZero(){
44  TPZFMatrix<STATE> & MeshSol = this->Mesh()->Solution();
45  this->fSolution.Redim( MeshSol.Rows(), MeshSol.Cols() );
46  this->fSolution.Zero();
47 }
48 
49 void TPZBlackOilAnalysis::AssembleResidual(){
50  this->SetCurrentState();
51  int sz = this->Mesh()->NEquations();
52  this->Rhs().Redim(sz,1);
53  this->fRhs += fLastState;
54 }//void
55 
56 void TPZBlackOilAnalysis::Run(std::ostream &out, bool linesearch){
57 
58  ofstream File("Pocos.txt");
59  File << "t(mes)\tPi(Pa)\tPp(Pa)\tQwiSC(m3/day)\tQoiSC(m3/day)\tQwpSC(m3/day)\tQopSC(m3/day)\t\tQwiFundo(m3/day)\tQoiFundo(m3/day)\tQwpFundo(m3/day)\tQopFundo(m3/day)\n";
60 
61  this->fSimulationTime = 0.;
62  this->PostProcess(this->fDXResolution);
63 
64  double nextDeltaT = this->fTimeStep;
65  this->SetAllMaterialsDeltaT();
66  const double TotalTime = fTimeStep*fNIter;
67 
68  TPZFMatrix<STATE> prevsol, lastsol;
69 
70  for(; this->fSimulationTime < TotalTime; ){
71 
72  this->fTimeStep = nextDeltaT;
73  this->SetAllMaterialsDeltaT();
74 
75  //Computing residual of last state solution
76  this->SetLastState();
77  this->Assemble();
78  fLastState = this->fRhs;
79  prevsol = fSolution;
80  lastsol = fSolution;
81  //Newton's method
82  this->SetCurrentState();
83  REAL error = this->fNewtonTol * 2. + 1.;
84  int iter = 0;
85  while(error > this->fNewtonTol && iter < this->fNewtonMaxIter){
86 
87  fSolution.Redim(0,0);
88  this->Assemble();
89  this->fRhs += fLastState;
90 
91  this->Solve();
92 
93  if (linesearch){
94  TPZFMatrix<STATE> nextSol;
95  REAL LineSearchTol = 1e-3 * Norm(fSolution);
96  const int niter = 3;
97  this->LineSearch(prevsol, fSolution, nextSol, LineSearchTol, niter);
98  fSolution = nextSol;
99  }
100  else{
101  fSolution += prevsol;
102  }
103 
104  prevsol -= fSolution;
105  REAL norm = Norm(prevsol);
106  out << "Iteracao n : " << (iter+1) << " : norma da solucao |Delta(Un)|: " << norm << endl;
107 
108  prevsol = fSolution;
110 
111  error = norm;
112  iter++;
113 
114  if((iter % 20) == 0){
115  //Computing residual of last state solution
116  fSolution = prevsol;
118  double fator = 0.1;//(sqrt(5.)-1.)/2.;
119  this->TimeStep() *= fator;
120  nextDeltaT = this->TimeStep();
121  cout << "\nMultiplicando passo de tempo por " << fator << "\n";
122  this->SetAllMaterialsDeltaT();
123  this->SetLastState();
124  this->Assemble();
125  fLastState = this->fRhs;
126  this->SetCurrentState();
127  this->fNIter = fCurrentStep + ((int)((1./fator) * (fNIter - fCurrentStep) + 0.5));
128  }
129 
130  }//Newton's iterations
131 
132  if(iter < 20){
133  nextDeltaT = fTimeStep * 5./((double)(iter));
134  }
135 
136  //DEBUG
137  this->AssembleResidual();
138  //DEBUG //
139 
140  prevsol = fSolution;
141  this->fSimulationTime += this->TimeStep();
142 
143  if (this->fSaveFrequency){
144  if (!(this->fCurrentStep % fSaveFrequency)){
145  this->PostProcess(this->fDXResolution);
146  double VazaoAguaIsc, VazaoAguaPsc, VazaoOleoIsc, VazaoOleoPsc;
147  double VazaoAguaIFundo, VazaoAguaPFundo, VazaoOleoIFundo, VazaoOleoPFundo;
148  Vazao(*this,-1,VazaoAguaIsc,VazaoOleoIsc,VazaoAguaIFundo,VazaoOleoIFundo);
149  Vazao(*this,-2,VazaoAguaPsc,VazaoOleoPsc,VazaoAguaPFundo,VazaoOleoPFundo);
150  File << this->fSimulationTime/2629743.8 << "\t" << PressaoMedia(*this,-1) << "\t" << PressaoMedia(*this,-2) << "\t"
151  << VazaoAguaIsc << "\t"
152  << VazaoOleoIsc << "\t"
153  << VazaoAguaPsc << "\t"
154  << VazaoOleoPsc << "\t" << "\t"
155  << VazaoAguaIFundo << "\t"
156  << VazaoOleoIFundo << "\t"
157  << VazaoAguaPFundo << "\t"
158  << VazaoOleoPFundo << "\n";
159  File.flush();
160  }
161  }
162 
163  prevsol -= lastsol;
164  REAL steadynorm = Norm(prevsol);
165  std::cout << "*********** Steady state error at iteration " << this->fCurrentStep << ", " << this->fSimulationTime/2629743.8 << " meses " << " = " << steadynorm << "\n\n";
166  if (!fForceAllSteps){
167  if (steadynorm < this->fSteadyTol){
168  std::cout << "Steady state solution achieved\n\n";
169  this->fNIter = this->fCurrentStep;
170  break;
171  }
172  }
173  std::cout.flush();
174 
175  }//time step iterations
176 
177 }//method
178 
179 
180 void TPZBlackOilAnalysis::SetLastState(){
181  TPZCompMesh * mesh = this->Mesh();
182  std::map<int, TPZMaterial * >::iterator matit;
183  for(matit = mesh->MaterialVec().begin(); matit != mesh->MaterialVec().end(); matit++)
184  {
185  if(!matit->second) continue;
186  TPZBlackOil2P3D * blackoilmat = dynamic_cast< TPZBlackOil2P3D *>(matit->second);
187  if (blackoilmat){
188  blackoilmat->SetLastState();
189  }
190  }
191 }
192 
193 
194 void TPZBlackOilAnalysis::SetCurrentState(){
195  TPZCompMesh * mesh = this->Mesh();
196  std::map<int, TPZMaterial * >::iterator matit;
197  for(matit = mesh->MaterialVec().begin(); matit != mesh->MaterialVec().end(); matit++)
198  {
199  if(!matit->second) continue;
200  TPZBlackOil2P3D * blackoilmat = dynamic_cast< TPZBlackOil2P3D *>(matit->second);
201  if (blackoilmat){
202  blackoilmat->SetCurrentState();
203  }
204  }
205 }
206 
207 void TPZBlackOilAnalysis::SetAllMaterialsDeltaT(){
208  TPZCompMesh * mesh = this->Mesh();
209  std::map<int, TPZMaterial * >::iterator matit;
210  for(matit = mesh->MaterialVec().begin(); matit != mesh->MaterialVec().end(); matit++)
211  {
212  if(!matit->second) continue;
213  TPZBlackOil2P3D * blackoilmat = dynamic_cast< TPZBlackOil2P3D *>(matit->second);
214  if (blackoilmat){
215  blackoilmat->SetTimeStep(this->TimeStep());
216  }
217  }
218 }
219 
220 
221 void TPZBlackOilAnalysis::PostProcess(int resolution, int dimension){
222  REAL T = this->fSimulationTime;
223  this->fTime = T;
224  TPZAnalysis::PostProcess(resolution, dimension);
225 }//method
226 
227 
228 void TPZBlackOilAnalysis::PostProcess(TPZVec<REAL> &loc, std::ostream &out){
229  REAL T = this->fSimulationTime;
230  out << "\nSOLUTION #" << this->fCurrentStep << " AT TIME = " << T << std::endl;
231  TPZAnalysis::PostProcess(loc, out);
232  out << "\n***************************************\n" << std::endl;
233 }//method
234 
235 void TPZBlackOilAnalysis::Assemble(){
236  if(!fCompMesh || !fStructMatrix || !fSolver){
237  cout << "TPZBlackOilAnalysis::Assemble lacking definition for Assemble fCompMesh "<< (void *) fCompMesh
238  << " fStructMatrix " << (bool) fStructMatrix << " fSolver " << fSolver << " at file "
239  << __FILE__ << " line " << __LINE__ << endl;
240  return;
241  }
242 
243  int sz = fCompMesh->NEquations();
244  fRhs.Redim(sz,1);
245 
246  //
247  bool exist = false;
248  if(fSolver->Matrix()) if (fSolver->Matrix()->Rows()==sz) exist = true;
249  if (exist){
250  fSolver->Matrix()->Zero();
251  }
253 }
254 
255 void TPZBlackOilAnalysis::SetConvergence(int niter, REAL eps, bool ForceAllSteps){
256  this->fNIter = niter;
257  this->fSteadyTol = eps;
258  this->fForceAllSteps = ForceAllSteps;
259 }
260 
261 void TPZBlackOilAnalysis::SetSaveFrequency(int SaveFrequency, int resolution){
262  this->fSaveFrequency = SaveFrequency;
263  this->fDXResolution = resolution;
264 }
265 
266 void TPZBlackOilAnalysis::SetNewtonConvergence(int niter, REAL eps){
267  this->fNewtonMaxIter = niter;
268  this->fNewtonTol = eps;
269 }
270 
271 REAL & TPZBlackOilAnalysis::TimeStep(){
272  return this->fTimeStep;
273 }
274 
275 void TPZBlackOilAnalysis::Solve(){
276 
277  const int n = this->Solver().Matrix()->Rows();
278  double minP = 0, maxP = 0, minS = 0, maxS = 0, p, S;
279  for(int i = 0; i < n/2; i++){
280  p = this->Solver().Matrix()->operator()(2*i,2*i);
281  S = this->Solver().Matrix()->operator()(2*i+1,2*i+1);
282  if(p > maxP) maxP = p;
283  if(p < minP) minP = p;
284  if(S > maxS) maxS = S;
285  if(S < minS) minS = S;
286  }//for i
287 
288  double ScaleP = fabs(minP+maxP)/2.;
289  double ScaleS = fabs(minS+maxS)/2.;
290  for(int j = 0; j < n/2; j++){
291  for(int i = 0; i < n; i++){
292  this->Solver().Matrix()->operator()(i,2*j) *= 1./ScaleP;
293  this->Solver().Matrix()->operator()(i,2*j+1) *= 1./ScaleS;
294  }//i
295  }//j
296 
297  {//DEBUG
298  double minP = 0, maxP = 0, minS = 0, maxS = 0, p, S;
299  for(int i = 0; i < n/2; i++){
300  p = this->Solver().Matrix()->operator()(2*i,2*i);
301  S = this->Solver().Matrix()->operator()(2*i+1,2*i+1);
302  if(p > maxP) maxP = p;
303  if(p < minP) minP = p;
304  if(S > maxS) maxS = S;
305  if(S < minS) minS = S;
306  }//for i
307  }
308 
310 
311  for(int i = 0; i < n/2; i++){
312  fSolution(2*i,0) *= 1./ScaleP;
313  fSolution(2*i+1,0) *= 1./ScaleS;
314  }//i
315 
316 }//method
317 
318 #include "TPZInterfaceEl.h"
319 double TPZBlackOilAnalysis::PressaoMedia(TPZBlackOilAnalysis &an, int matid){
320  an.LoadSolution(an.Solution());
321  TPZCompMesh * cmesh = an.Mesh();
322  const int nel = cmesh->NElements();
323  TPZVec<REAL> qsi(3);
324  TPZVec<STATE> sol(1);
325  double press = 0.;
326  double AccVol = 0.;
327  double locVol = 0.;
328  for(int iel = 0; iel < nel; iel++){
329  TPZCompEl * cel = cmesh->ElementVec()[iel];
330  if(!cel) continue;
331  if(cel->Material()->Id() != matid) continue;
332  TPZInterfaceElement * face = dynamic_cast<TPZInterfaceElement*>(cel);
333  if(!face) continue;
334  face->LeftElement()->Reference()->CenterPoint(face->LeftElement()->Reference()->NSides()-1,qsi);
335  face->LeftElement()->Solution(qsi, TPZBlackOil2P3D::EOilPressure, sol);
336  locVol = face->LeftElement()->Reference()->Volume();
337  press += sol[0] * locVol;
338  AccVol += locVol;
339  }//iel
340  double result = press/AccVol;
341  return result;
342 }//method
343 
344 #include "pzbndcond.h"
345 void TPZBlackOilAnalysis::Vazao(TPZBlackOilAnalysis &an, int matid, double & VazaoAguaSC, double & VazaoOleoSC, double & VazaoAguaFundo, double & VazaoOleoFundo){
346 
347  an.LoadSolution(an.Solution());
348  TPZCompMesh * cmesh = an.Mesh();
349  TPZVec<REAL> qsi(3);
350  TPZVec<STATE> sol(1);
351 
353 
354  const int nel = cmesh->NElements();
355  VazaoAguaSC = 0.;
356  VazaoOleoSC = 0.;
357  VazaoAguaFundo = 0.;
358  VazaoOleoFundo = 0.;
359  for(int iel = 0; iel < nel; iel++){
360  TPZCompEl * cel = cmesh->ElementVec()[iel];
361  if(!cel) continue;
362  if(cel->Material()->Id() != matid) continue;
363  TPZInterfaceElement * face = dynamic_cast<TPZInterfaceElement*>(cel);
364  if(!face) continue;
365  face->CalcStiff(ek, ef);
366 
367  face->LeftElement()->Reference()->CenterPoint(face->LeftElement()->Reference()->NSides()-1,qsi);
368  face->LeftElement()->Solution(qsi, TPZBlackOil2P3D::EOilPressure, sol);
369 
370  TPZBlackOil2P3D::BFadREAL po(sol[0],0);
371  TPZBlackOil2P3D::BFadREAL Bo;
372 
373  TPZBndCond * bc = dynamic_cast<TPZBndCond*> (face->Material());
374  TPZBlackOil2P3D * bo = dynamic_cast<TPZBlackOil2P3D *> (bc->Material());
375  bo->Bo(po, Bo);
376 
377  VazaoOleoSC += ef.fMat(0,0)*86400.;
378  VazaoAguaSC += ef.fMat(1,0)*86400.;
379 
380  VazaoOleoFundo += ef.fMat(0,0)*Bo.val()*86400.;
381  VazaoAguaFundo += ef.fMat(1,0)*bo->Bw()*86400.;
382  }//iel
383 }//method
384 
385 #endif
int64_t NElements() const
Number of computational elements allocated.
Definition: pzcmesh.h:169
TPZMatrixSolver< STATE > * fSolver
Type of solver to be applied.
Definition: pzanalysis.h:52
expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ expr_ fabs
Definition: tfadfunc.h:140
REAL Volume()
Return the volume of the element.
Definition: pzgeoel.cpp:1052
virtual void Solve()
Invert the stiffness matrix.
Definition: pzanalysis.cpp:352
TPZFMatrix< STATE > fSolution
Solution vector.
Definition: pzanalysis.h:50
clarg::argBool bc("-bc", "binary checkpoints", false)
virtual void UpdateFrom(TPZAutoPointer< TPZMatrix< TVar > > matrix) override
Updates the values of the current matrix based on the values of the matrix.
Definition: pzsolve.h:121
int64_t NEquations()
This computes the number of equations associated with non-restrained nodes.
Definition: pzcmesh.cpp:721
clarg::argInt dimension("-d", "Matrices dimension M x M", 1000)
virtual int Zero()
Zeroes the matrix.
Definition: pzmatrix.h:296
TPZCompMesh * fCompMesh
Computational mesh.
Definition: pzanalysis.h:44
virtual void Assemble()
Assemble the stiffness matrix and load vector.
Definition: pzanalysis.cpp:304
TPZCompMesh * Mesh() const
Returns the pointer to the computational mesh.
Definition: pzanalysis.h:180
virtual void CalcStiff(TPZElementMatrix &ek, TPZElementMatrix &ef) override
CalcStiff computes the element stiffness matrix and right hand side.
virtual int NSides() const =0
Returns the number of connectivities of the element.
Contains the TPZStructMatrixOR class which responsible for a interface among Matrix and Finite Elemen...
TPZMatrixSolver< STATE > & Solver()
Get the solver matrix.
Definition: pzanalysis.h:367
Contains the TPZFStructMatrix class which implements Full Structural Matrices.
void error(char *string)
Definition: testShape.cc:7
virtual void CenterPoint(int side, TPZVec< REAL > &masscent) const =0
It returns the coordinates from the center of the side of the element in the element coordinate space...
Contains the TPZBndCond class which implements a boundary condition for TPZMaterial objects...
virtual TPZMaterial * Material() const
Identify the material object associated with the element.
Definition: pzcompel.cpp:959
int Zero() override
Makes Zero all the elements.
Definition: pzfmatrix.h:651
Contains the TPZSpStructMatrix class which implements sparse structural matrices. ...
virtual void LoadSolution()
Load the solution into the computable grid.
Definition: pzanalysis.cpp:441
TVar Norm(const TPZFMatrix< TVar > &A)
Returns the norm of the matrix A.
Contains declaration of TPZInterfaceElement class which computes the contribution over an interface b...
This class defines the boundary condition for TPZMaterial objects.
Definition: pzbndcond.h:29
int64_t Rows() const
Returns number of rows.
Definition: pzmatrix.h:803
Contains TPZSequenceSolver class which defines sequence solvers.
virtual void PostProcess(int resolution)
Draw solution over mesh for all dimensions.
int Redim(const int64_t newRows, const int64_t newCols) override
Redimension a matrix and ZERO your elements.
Definition: pzfmatrix.h:616
std::map< int,TPZMaterial *> & MaterialVec()
Returns a reference to the material pointers vector.
Definition: pzcmesh.h:203
Computes the contribution over an interface between two discontinuous elements. Computational Element...
This class associates an element matrix with the coeficients of its contribution in the global stiffn...
Definition: pzelmat.h:30
TPZAutoPointer< TPZStructMatrix > fStructMatrix
Structural matrix.
Definition: pzanalysis.h:68
virtual void AssembleResidual()
Assemble the load vector.
Definition: pzanalysis.cpp:288
TPZGeoEl * Reference() const
Return a pointer to the corresponding geometric element if such exists, return 0 otherwise.
Definition: pzcompel.cpp:1137
TPZCompEl * LeftElement() const
Returns the left element from the element interface.
Implements computational mesh. Computational Mesh.
Definition: pzcmesh.h:47
TPZAdmChunkVector< TPZCompEl * > & ElementVec()
Returns a reference to the element pointers vector.
Definition: pzcmesh.h:183
TPZAutoPointer< TPZMatrix< TVar > > Matrix() const
Returns a pointer to TPZMatrix<>
Definition: pzsolve.h:138
virtual void Solution(TPZVec< REAL > &qsi, int var, TPZVec< STATE > &sol)
Calculates the solution - sol - for the variable var at point qsi, where qsi is expressed in terms of...
Definition: pzcompel.cpp:421
int Id() const
Definition: TPZMaterial.h:170
int64_t Cols() const
Returns number of cols.
Definition: pzmatrix.h:809
Derived class from TPZAnalysis implements non linear analysis (Newton&#39;s method). Analysis.
Contains the TPZBlackOil2P3D class which implements a 3D two-phase (oil-water) black-oil flow...
TPZFMatrix< STATE > & Rhs()
Returns the load vector.
Definition: pzanalysis.h:174
TPZFMatrix< STATE > fRhs
Load vector.
Definition: pzanalysis.h:48
Contains the implementation of the CheckConvergence function.
Defines the interface of a computational element. Computational Element.
Definition: pzcompel.h:59
Contains TPZBlackOilAnalysis class derived from TPZNonLinearAnalysis class.
TPZFMatrix< STATE > & Solution()
Access the solution vector.
Definition: pzcmesh.h:219
REAL fTime
Time variable which is used in dx output.
Definition: pzanalysis.h:62
#define PZError
Defines the output device to error messages and the DebugStop() function.
Definition: pzerror.h:15
TPZMaterial * Material() const
Definition: pzbndcond.h:263