00001 #include "doubleporositydiff.h"
00002 #include "hdf5orthowriter.h"
00003
00004
00005
00006
00007
00008 DoublePorosityDiff::DoublePorosityDiff(OrthoMesh &mesh,const VecDouble &K,const VecDouble &por, Function1D &fmob, Function1D & dPC,Function1D &PC, BlockMatrixModule& blockMatrix)
00009 :mesh(mesh),_por(por),_K(K),_fmob(fmob),_dPC(dPC),_PC(PC),_blockMatrix(blockMatrix)
00010 {
00011 _S_oldTime.reinit(mesh.numCells(),0);
00012 _S_oldTime= 0.023883;
00013 q_mf = 0.0;
00014 dq_mf = 0.0;
00015 _numTimeStep=0;
00016 }
00017
00018
00019 void DoublePorosityDiff::iterate(double dt)
00020 {
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 _numTimeStep=_numTimeStep+1;
00033 printf("Number of time steps for diffusive step= %u\n", _numTimeStep);
00034
00035
00036
00037 VecDouble deltaS_oldIt(mesh.numCells());
00038 deltaS_oldIt=0.0;
00039 VecDouble deltaS_new(mesh.numCells());
00040
00041 S_new.setRef(&(this->getTransport().getSolutionAtCells()(0,0)),mesh.numCells());
00042
00043 VecDouble S_oldIt(mesh.numCells());
00044 S_oldIt = S_new;
00045
00046 VecDouble S_transp(mesh.numCells());
00047 S_transp=S_new;
00048
00049
00050 double dS=0.001;
00051
00052 double S_tol=1.e-3, dS_tol=1.e-3, S_error=0.0, deltaS_error=0.0;
00053 unsigned numIt=0;
00054
00055 VecDouble tmp(mesh.numCells());
00056
00057
00058 for (unsigned u=0;u<_S_oldTime.size();u++)
00059 {
00060
00061 _S_oldTime(u) =_PC(_S_oldTime(u));
00062 }
00063 _blockMatrix.construct_bases(_S_oldTime,dt);
00064
00065 do
00066 {
00067 S_error=0.0;
00068 deltaS_error=0.0;
00069
00070
00071 for (OrthoMesh::Cell_It cell=mesh.begin_cell(); cell!=mesh.end_cell(); cell++)
00072 {
00073 double H=pow(cell->volume(),1/3.0);
00074 double sumXIsb=0.0,sumVb=0.0;
00075 for (unsigned neigID=0;neigID<6;neigID++)
00076 {
00077 if(cell->neighbor_index(neigID)==-1)
00078 {
00079 continue;
00080 }
00081 double Lsb=0.0,DiffCoef,effDiffCoef_F,KIsb, XIsb, effK;
00082
00083
00084 Lsb=(_K(cell->index())*S_transp(cell->index())+_K(cell->neighbor_index(neigID))*S_transp(cell->neighbor_index(neigID)))/(_K(cell->index())+_K(cell->neighbor_index(neigID)));
00085
00086 effK=2*_K(cell->index())*_K(cell->neighbor_index(neigID))/(_K(cell->index())+_K(cell->neighbor_index(neigID)));
00087 effDiffCoef_F=effK*_fmob(Lsb)*_dPC(Lsb);
00088 DiffCoef=_K(cell->index())*_fmob(Lsb)*_dPC(Lsb);
00089
00090 assert(effDiffCoef_F <=0);
00091 KIsb=1.0e-15;
00092
00093 XIsb=2*DiffCoef/H;
00094
00095 sumXIsb = sumXIsb + XIsb/(1-KIsb*XIsb);
00096 sumVb = sumVb + XIsb/(1-KIsb*XIsb)*(S_new(cell->index())-S_oldIt(cell->index())-deltaS_oldIt(cell->index())+(_K(cell->neighbor_index(neigID))/(_K(cell->index())+_K(cell->neighbor_index(neigID)))-KIsb*effDiffCoef_F/H)*(S_oldIt(cell->index())+deltaS_oldIt(cell->index())-S_oldIt(cell->neighbor_index(neigID))-deltaS_oldIt(cell->neighbor_index(neigID)) ));
00097 }
00098
00099
00100 deltaS_new(cell->index())=pow(_por(cell->index())/dt-sumXIsb/H-dq_mf,-1.0)*(-_por(cell->index())*(S_new(cell->index())-S_transp(cell->index()))/dt+sumVb/H + q_mf);
00101
00102 S_new(cell->index())=S_new(cell->index())+deltaS_new(cell->index());
00103 S_error = S_error + pow(S_new(cell->index())-S_oldIt(cell->index()),2.0);
00104 deltaS_error = deltaS_error + pow(deltaS_new(cell->index()),2.0);
00105
00106 q_mf=_blockMatrix.get_source(cell->index(),_PC(S_new(cell->index())));
00107
00108
00109
00110
00111
00112 }
00113
00114 S_error = pow(S_error,0.5);
00115 deltaS_error = pow(deltaS_error,0.5);
00116 deltaS_oldIt = deltaS_new;
00117 S_oldIt = S_new;
00118
00119 numIt = numIt + 1;
00120 printf("Iteration=%u S_error=%.10g deltaS_error=%.10g \n",numIt, S_error,deltaS_error);
00121
00122 } while(S_error > S_tol || deltaS_error >dS_tol);
00123 printf("END OF THE NEWTON'S ITERATE: THE SATURATION CONVERGES \n");
00124
00125 _S_oldTime = S_new;
00126 }
00127
00128 #include "fpcsquare.h"
00129
00130 void DoublePorosityDiff::iterate_linear(double dt)
00131 {
00132
00133
00134
00135
00136
00137 _numTimeStep=_numTimeStep+1;
00138 printf("Number of time steps for diffusive step= %u\n", _numTimeStep);
00139
00140 S_new.setRef(&(this->getTransport().getSolutionAtCells()(0,0)),mesh.numCells());
00141
00142 VecDouble S_oldIt(mesh.numCells());
00143 S_oldIt = S_new;
00144
00145
00146 VecDouble S_transp(mesh.numCells());
00147 S_transp=S_new;
00148
00149
00150
00151 double S_tol=1.e-3, S_error=0;
00152 unsigned numIt=0;
00153
00154 do
00155 {
00156 S_error=0;
00157
00158 for (OrthoMesh::Cell_It cell=mesh.begin_cell(); cell!=mesh.end_cell(); cell++)
00159 {
00160 double H=pow(cell->volume(),1/3.0);
00161
00162 double sumXIsb=0.0,sumVb=0.0;
00163 for (unsigned neigID=0;neigID<6;neigID++)
00164 {
00165 if(cell->neighbor_index(neigID)==-1)
00166 {
00167 continue;
00168 }
00169 double Lsb=0.0,DiffCoef,effDiffCoef_F,KIsb, XIsb, effK;
00170
00171
00172 Lsb=(_K(cell->index())*S_transp(cell->index())+_K(cell->neighbor_index(neigID))*S_transp(cell->neighbor_index(neigID)))/(_K(cell->index())+_K(cell->neighbor_index(neigID)));
00173
00174
00175 effK=2*_K(cell->index())*_K(cell->neighbor_index(neigID))/(_K(cell->index())+_K(cell->neighbor_index(neigID)));
00176
00177
00178
00179 effDiffCoef_F=effK*_fmob(Lsb)*_dPC(Lsb);
00180 DiffCoef=_K(cell->index())*_fmob(Lsb)*_dPC(Lsb);
00181
00182
00183 assert(effDiffCoef_F <=0);
00184
00185
00186 KIsb=1.0e-5;
00187
00188
00189 XIsb=2*DiffCoef/H;
00190
00191 sumXIsb = sumXIsb + XIsb/(1-KIsb*XIsb);
00192 sumVb = sumVb + XIsb/(1-KIsb*XIsb)*(-S_oldIt(cell->index())+(_K(cell->neighbor_index(neigID))/(_K(cell->index())+_K(cell->neighbor_index(neigID)))-KIsb*effDiffCoef_F/H)*(S_oldIt(cell->index())-S_oldIt(cell->neighbor_index(neigID))));
00193 }
00194
00195
00196
00197
00198 q_mf=0.0000;
00199 S_new(cell->index())=pow(_por(cell->index())/dt-sumXIsb/H,-1.0)*(_por(cell->index())*S_transp(cell->index())/dt+sumVb/H + q_mf);
00200
00201
00202 S_error = S_error + pow(S_new(cell->index())-S_oldIt(cell->index()),2.0);
00203
00204 }
00205
00206 S_error = pow(S_error,0.5);
00207 S_oldIt = S_new;
00208 numIt = numIt + 1;
00209 _S_oldTime = S_new;
00210 printf("Iteration=%u Error=%.10g \n",numIt, S_error);
00211
00212 } while(S_error > S_tol);
00213 printf("WARNING: THIS IS NOT THE NEWTON'S ITERATION \n");
00214 printf("done, the saturation converges \n");
00215
00216 }
00217
00218
00219 double DoublePorosityDiff::fracturePc(double sat)
00220 {
00221 double gamma=20000, theta=100;
00222
00223 if (sat<=0)
00224 return 1;
00225 else if (sat>1)
00226 return 0;
00227 else
00228 return (1-sat)*(gamma/sat-gamma+theta);
00229 }
00230
00231
00232 VecDouble& DoublePorosityDiff::fracturePot(const VecDouble &sat,VecDouble &C)
00233 {
00234 double rho_o = 1.8, rho_w=1, gravity=9.8, depht=0;
00235 _vPot=C;
00236 for (int u=0;u<sat.size();u++)
00237 {
00238 _vPot(u)=_PC(sat(u))-(rho_o-rho_w)*gravity*depht;
00239 }
00240 return _vPot;
00241 }
00242
00243
00244 void DoublePorosityDiff::printOutput()
00245 {
00246 VecDouble vValues(mesh.numVertices());
00247 this->mesh.projectCentralValuesAtVertices(S_new,vValues);
00248 HDF5OrthoWriter &hdf5 = HDF5OrthoWriter::getHDF5OrthoWriter();
00249 hdf5.writeScalarField(vValues,"SDiff");
00250 }
00251