00001 #include "blockmatrixmodule.h"
00002 #include <stdio.h>
00003 #include<fstream>
00004 #include "umfpacksolver.h"
00005 #include <iostream>
00006 #include "hdf5orthowriter.h"
00007 #include "xdmfwriter.h"
00008
00009 using namespace std;
00010
00011 using namespace dealii;
00012
00013 void BlockMatrixModule::iterate(TransportBase &trans)
00014 {
00015
00016
00017 VecDouble P;
00018 P.reinit(n_fracture_cells);
00019 for (unsigned i=0; i < n_fracture_cells; i++)
00020 P(i)=0.2;
00021
00022
00023 construct_bases (P, _dt);
00024
00025
00026
00027
00028 }
00029
00030 void BlockMatrixModule::buildSparsityPattern()
00031 {
00032
00033
00034
00035
00036
00037
00038 OrthoMesh::Raw_Vertex_It end = _mesh.end_raw_vertice();
00039
00040 unsigned ix, iy, iz, ver_xy, _ver_xy,ver_tol;
00041 _ver_xy=(_mesh.numElemX()+1)*(_mesh.numElemY()+1);
00042 ver_xy= (_mesh.numElemX()+1)*(_mesh.numElemY()+1)-(_mesh.numElemX()+1);
00043
00044 ver_tol = (_mesh.numElemX()+1)*(_mesh.numElemY()+1)*(_mesh.numElemY()+1);
00045
00046
00047
00048 OrthoMesh::Raw_Vertex_It vf = _mesh.begin_raw_vertice();
00049
00050 for (iz=0; iz<_mesh.numElemZ()+1; iz++)
00051 {
00052
00053 for (ix=0; ix<_mesh.numElemX()+1; ix++)
00054 {
00055 sp.add(vf->index(),vf->index());
00056 sp.add(_m+vf->index(),_m+vf->index());
00057
00058 vf++;
00059 }
00060
00061 for (unsigned k=0; k < ver_xy; k++)
00062 {
00063 vf++;
00064
00065 }
00066 }
00067
00068
00069 OrthoMesh::Raw_Vertex_It vb = _mesh.begin_raw_vertice();
00070
00071
00072 for (iz=0; iz<_mesh.numElemZ()+1; iz++)
00073 {
00074 for (unsigned k=0; k < ver_xy; k++)
00075 vb++;
00076
00077 for (ix=0; ix<_mesh.numElemX()+1; ix++)
00078 {
00079 sp.add(vb->index(),vb->index());
00080 sp.add(_m+vb->index(),_m+vb->index());
00081
00082 vb++;
00083 }
00084 }
00085
00086
00087 OrthoMesh::Raw_Vertex_It vl = _mesh.begin_raw_vertice();
00088
00089 for (iz=0; iz<_mesh.numElemZ()+1; iz++)
00090 {
00091
00092 for (iy=0; iy<_mesh.numElemY()+1; iy++)
00093 {
00094 sp.add(vl->index(),vl->index());
00095 sp.add(_m+vl->index(),_m+vl->index());
00096
00097 for (unsigned k=0; k <_mesh.numElemX()+1; k++)
00098 vl++;
00099
00100 }
00101 }
00102
00103
00104 OrthoMesh::Raw_Vertex_It vr = _mesh.begin_raw_vertice();
00105
00106 for (unsigned k=0; k <_mesh.numElemX(); k++)
00107 vr++;
00108
00109
00110 for (iz=0; iz<_mesh.numElemZ()+1; iz++)
00111 {
00112 for (iy=0; iy<_mesh.numElemY()+1; iy++)
00113 {
00114 sp.add(vr->index(),vr->index());
00115 sp.add(_m+vr->index(),_m+vr->index());
00116
00117 for (unsigned k=0; k <_mesh.numElemX()+1; k++)
00118 {
00119
00120 if (vr->index() != _m-1)
00121 {
00122 vr++;
00123
00124 }
00125 }
00126 }
00127 }
00128
00129
00130
00131 OrthoMesh::Raw_Vertex_It vbt = _mesh.begin_raw_vertice();
00132
00133 iz=0;
00134
00135 for (iy=0; iy<_mesh.numElemY()+1; iy++)
00136 {
00137 for (ix=0; ix<_mesh.numElemX()+1; ix++)
00138 {
00139 sp.add(vbt->index(),vbt->index());
00140 sp.add(_m+vbt->index(),_m+vbt->index());
00141
00142 vbt++;
00143 }
00144 }
00145
00146
00147 OrthoMesh::Raw_Vertex_It vu = _mesh.begin_raw_vertice();
00148
00149 for (unsigned k=0 ; k <_m-(_ver_xy); k++)
00150 vu++;
00151
00152
00153 iz=_mesh.numElemZ()+1;
00154
00155 for (iy=0; iy<_mesh.numElemY()+1; iy++)
00156 {
00157 for (ix=0; ix<_mesh.numElemX()+1; ix++)
00158 {
00159 sp.add(vu->index(),vu->index());
00160 sp.add(_m+vu->index(),_m+vu->index());
00161
00162 vu++;
00163 }
00164 }
00165
00166
00167 OrthoMesh::Raw_Vertex_It vc = _mesh.begin_raw_vertice();
00168
00169 for (int i=0; i < (_mesh.numElemX()+1) * (_mesh.numElemY()+1) + (_mesh.numElemX()+2); i++)
00170 {
00171 vc++;
00172 }
00173
00174
00175 for (iz=1; iz < _mesh.numElemZ(); iz++)
00176 {
00177 for (iy=1; iy < _mesh.numElemY(); iy++)
00178 {
00179 for (ix=1; ix < _mesh.numElemX(); ix++)
00180 {
00181
00182
00183 sp.add(vc->index(),vc->index());
00184
00185 sp.add(vc->index(),_m+vc->index());
00186 sp.add(vc->index(),_m+vc->index_left());
00187 sp.add(vc->index(), _m+ vc->index_right());
00188 sp.add(vc->index(),_m+vc->index_bottom());
00189 sp.add(vc->index(),_m+vc->index_up());
00190 sp.add(vc->index(),_m+ vc->index_back());
00191 sp.add(vc->index(),_m+ vc->index_front());
00192
00193 sp.add(_m+vc->index(),vc->index());
00194 sp.add(_m+vc->index(),vc->index_left());
00195 sp.add(_m+vc->index(), vc->index_right());
00196 sp.add(_m+vc->index(),vc->index_bottom());
00197 sp.add(_m+vc->index(),vc->index_up());
00198 sp.add(_m+vc->index(), vc->index_back());
00199 sp.add(_m+vc->index(), vc->index_front());
00200
00201 sp.add(_m+vc->index(),_m+vc->index());
00202 sp.add(_m+vc->index(),_m+vc->index_left());
00203 sp.add(_m+vc->index(),_m+ vc->index_right());
00204 sp.add(_m+vc->index(),_m+vc->index_bottom());
00205 sp.add(_m+vc->index(),_m+vc->index_up());
00206 sp.add(_m+vc->index(),_m+ vc->index_back());
00207 sp.add(_m+vc->index(),_m+ vc->index_front());
00208 vc++;
00209 }
00210
00211 for (unsigned i=0; i<2; i++)
00212 vc++;
00213 }
00214
00215 for (unsigned i=0; i< 2*(_mesh.numElemX()+1); i++)
00216 vc++;
00217
00218 }
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 sp.compress();
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 }
00279
00280 void BlockMatrixModule::assembleSystem(const VecDouble &sat_old, const VecDouble &Sol_old,double _k, double _por, double _bc_pc, double dt)
00281 {
00282
00283 OrthoMesh::Raw_Vertex_It vt=_mesh.begin_raw_vertice();
00284 OrthoMesh::Raw_Vertex_It vend=_mesh.end_raw_vertice();
00285
00286
00287 M.reinit(sp);
00288
00289
00290
00291
00292 while (vt != vend)
00293 {
00294
00295 OrthoVerticeAccessor ortho(_mesh,vt->index());
00296 if(ortho.at_boundary())
00297 {
00298
00299 M.add(vt->index(),vt->index(),1);
00300 M.add(_m+vt->index(),_m+vt->index(),1);
00301
00302
00303
00304 rhs_Si(vt->index())=_bc_pc;
00305 rhs_Sihom(vt->index())=1;
00306
00307
00308
00309 rhs_Si(_m+vt->index())=0;
00310 rhs_Sihom(_m+vt->index())=0;
00311
00312
00313 }
00314 else
00315 {
00316
00317
00318
00319 M.add(vt->index(),vt->index(), _por /( _fdpc(sat_old(vt->index())) *_dt ) );
00320
00321
00322
00323 double L = 0.5*( sat_old( vt->index()) + sat_old(vt->index_left()) );
00324 double R = 0.5*( sat_old( vt->index()) + sat_old(vt->index_right()) );
00325 double F = 0.5*( sat_old( vt->index()) + sat_old(vt->index_front()) );
00326 double B = 0.5*( sat_old( vt->index()) + sat_old(vt->index_back()) );
00327 double U = 0.5*( sat_old( vt->index()) + sat_old(vt->index_up()) );
00328 double Bt = 0.5*( sat_old( vt->index()) + sat_old(vt->index_bottom()) );
00329 double _Dx = _dx * _dx;
00330 double _Dy = _dy * _dy;
00331 double _Dz = _dz * _dz;
00332
00333
00334 M.add(vt->index(),_m+vt->index_left(), - _k * _fmobrW(L)/_Dx );
00335 M.add(vt->index(),_m+vt->index_right(),-_k * _fmobrW(R)/_Dx );
00336 M.add(vt->index(),_m+vt->index_front(),-_k * _fmobrW(F)/_Dy );
00337 M.add(vt->index(),_m+vt->index_back(),- _k * _fmobrW(B)/_Dy );
00338 M.add(vt->index(),_m+vt->index_bottom(),- _k * _fmobrW(Bt)/_Dz );
00339 M.add(vt->index(),_m+vt->index_up(), - _k * _fmobrW(U)/_Dz );
00340 M.add(vt->index(),_m+vt->index(), _k *( (_fmobrW(L) + _fmobrW(R))/_Dx + (_fmobrW(F) + _fmobrW(B))/_Dy + (_fmobrW(Bt) + _fmobrW(U))/_Dz ) );
00341 rhs_Si(vt->index())=_por *Sol_old(vt->index()) /( _fdpc( sat_old(vt->index()) )*_dt);
00342
00343 rhs_Sihom(vt->index())=0;
00344
00345
00346
00347 M.add(_m+vt->index(),vt->index(), _k *( (_fmobt(L)-_fmobrW(L))/_Dx + (_fmobt(R)-_fmobrW(R))/_Dx + (_fmobt(F)-_fmobrW(F))/_Dy + (_fmobt(B)-_fmobrW(B))/_Dy + (_fmobt(Bt)-_fmobrW(Bt))/_Dz + (_fmobt(U)-_fmobrW(U))/_Dz ) );
00348 M.add(_m+vt->index(),vt->index_left(),- _k * (_fmobt(L)- _fmobrW(L))/_Dx );
00349 M.add(_m+vt->index(),vt->index_right(),- _k * (_fmobt(R)- _fmobrW(R))/_Dx );
00350 M.add(_m+vt->index(),vt->index_front(), -_k * (_fmobt(F)- _fmobrW(F))/_Dy );
00351 M.add(_m+vt->index(),vt->index_back(), - _k * (_fmobt(B)- _fmobrW(B))/_Dy );
00352 M.add(_m+vt->index(),vt->index_bottom(),- _k * (_fmobt(Bt)- _fmobrW(Bt))/_Dz );
00353 M.add(_m+vt->index(),vt->index_up(), - _k * (_fmobt(U)- _fmobrW(U))/_Dz );
00354
00355
00356 M.add(_m+vt->index(),_m+vt->index(), _k *( (_fmobt(L)+_fmobt(R))/_Dx + (_fmobt(F)+_fmobt(B))/_Dy + (_fmobt(Bt)+_fmobt(U))/_Dz ));
00357 M.add(_m+vt->index(),_m+vt->index_left(), -_k *_fmobt(L)/_Dx);
00358 M.add(_m+vt->index(),_m+vt->index_right(), -_k *_fmobt(R)/_Dx );
00359 M.add(_m+vt->index(),_m+vt->index_front(), -_k *_fmobt(F)/_Dy);
00360 M.add(_m+vt->index(),_m+vt->index_back(), -_k *_fmobt(B)/_Dy );
00361 M.add(_m+vt->index(),_m+vt->index_bottom(), -_k *_fmobt(Bt)/_Dz );
00362 M.add(_m+vt->index(),_m+vt->index_up(), -_k *_fmobt(U)/_Dz );
00363
00364
00365
00366 }
00367 vt++;
00368 }
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386 Sol_Si();
00387 Sol_Sihom();
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 }
00401
00402
00403 void BlockMatrixModule::Sol_Si()
00404 {
00405
00406 UMFPACKSolver umfp;
00407 umfp.solve(M,Solution1,rhs_Si);
00408
00409
00410 for (unsigned i=0; i< _m ;i++)
00411 {
00412 Sol(i)=Solution1(i);
00413
00414 }
00415
00416
00417 }
00418
00419 void BlockMatrixModule::Sol_Sihom()
00420 {
00421 UMFPACKSolver umfp;
00422 umfp.solve(M,Solution2,rhs_Sihom);
00423 for (unsigned i=0; i< _m ; i++)
00424 Sol_hom(i)=Solution2(i);
00425
00426 }
00427
00428 void BlockMatrixModule::construct_bases(VecDouble &bc_pc,double dt)
00429 {
00430
00431 VecDouble SiPrev(_m);
00432 VecDouble SwPrev;
00433
00434
00435 for (unsigned blockId =0; blockId < n_fracture_cells ; blockId++)
00436 {
00437
00438 SiPrev.copyRow(blockId,m_MSi);
00439
00440
00441 VecDoubleRef SiHom(&(m_MHomSi(blockId,0)),_m);
00442
00443 SiPrev.sadd(1,_BcPcNew(blockId)-_BcPcOld(blockId),SiHom);
00444
00445
00446 SwPrev = SiPrev;
00447 _fpcinv.evaluate(SwPrev);
00448
00449
00450
00451 _SwIntegral(blockId)=_mesh.getIntegralAtVertices(SwPrev);
00452
00453 VecDoubleRef Si(&(m_MSi(blockId,0)),_m);
00454
00455 create_bases_functions(bc_pc(blockId),SwPrev,SiPrev,_vPor(blockId),_vK(blockId),Si,SiHom);
00456 _BcPcOld(blockId)=bc_pc(blockId);
00457
00458 HDF5OrthoWriter &hdf5 = HDF5OrthoWriter::getHDF5OrthoWriter();
00459 hdf5.writeScalarField(Si,"Psi","MBmesh");
00460
00461 }
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477 }
00478
00491 void BlockMatrixModule::create_bases_functions(double bc_pc,const VecDouble &previous_sw,const VecDouble &previous_si,double por,double k,VecDouble &newSi,VecDouble &newHomSi)
00492 {
00493
00494
00495
00496 assembleSystem(previous_sw, previous_si,k, por, bc_pc, _dt);
00497
00498 newSi=Sol;
00499 newHomSi=Sol_hom;
00500 }
00501
00502 double BlockMatrixModule::get_source(unsigned blockId,double new_bc_pc)
00503 {
00504 VecDoubleRef PSi(&(m_MSi(blockId,0)),_m);
00505 VecDoubleRef PSiHom(&(m_MHomSi(blockId,0)),_m);
00506
00507 _BcPcNew(blockId)=new_bc_pc;
00508
00509 VecDouble Sol;
00510
00511
00512 Sol=PSi;
00513
00514 Sol.sadd(1,new_bc_pc - _BcPcOld(blockId),PSiHom);
00515
00516
00517 _fpcinv.evaluate(Sol);
00518
00519
00520 double SwInt=_mesh.getIntegralAtVertices(Sol);
00521 return -(SwInt-_SwIntegral(blockId))*_vPor(blockId)/(_dt*_Bx);
00522 }
00523
00524 BlockMatrixModule::BlockMatrixModule(OrthoMesh &mesh,unsigned n_fracture_cell, VecDouble &vPcInitial,VecDouble &vPor, VecDouble &vK, Function1D &fdpc, Function1D &fpcinv, Function1D &fmobt, Function1D &fmobrW): _mesh(mesh),n_fracture_cells(n_fracture_cell),_BcPcOld(vPcInitial), _vPor(vPor), _vK(vK) ,_fdpc(fdpc), _fpcinv(fpcinv), _fmobt(fmobt), _fmobrW(fmobrW)
00525 {
00526 _dt=1.0;
00527 _dx = _mesh.get_dx();
00528 _dy = _mesh.get_dy();
00529 _dz = _mesh.get_dz();
00530
00531
00532 _m =_mesh.numRawVertices();
00533
00534 m_MSi.reinit(n_fracture_cells,_m);
00535 m_MHomSi.reinit(n_fracture_cells,_m);
00536
00537 _SwIntegral.reinit(n_fracture_cells);
00538 _BcPcNew=vPcInitial;
00539
00540 _Bx = _mesh.meshVolume();
00541 m_MHomSi=0;
00542 for (unsigned i=0; i < n_fracture_cells; i++)
00543 {
00544 m_MSi.fill_row(i,_BcPcOld(i));
00545 }
00546 sp.reinit(2*_m, 2*_m,14);
00547 rhs_Si.reinit(2*_m);
00548 rhs_Sihom.reinit(2*_m);
00549 Sol.reinit(_m);
00550 Sol_hom.reinit(_m);
00551 Sol_old.reinit(_m);
00552 Sol_hom_old.reinit(_m);
00553 sat_old.reinit(_m);
00554 Solution1.reinit(2*_m);
00555 Solution2.reinit(2*_m);
00556 buildSparsityPattern();
00557
00558 }
00559
00560
00561
00562
00563
00564