LaxFriedrichsSystemMPI Class Reference

#include <laxfriedrichssystemmpi.h>

Inheritance diagram for LaxFriedrichsSystemMPI:
Inheritance graph
[legend]
Collaboration diagram for LaxFriedrichsSystemMPI:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 LaxFriedrichsSystemMPI (OrthoMesh &mesh, Function3D &fInitU, const VecDouble &cPor, Function3D &fPrescribedU, FaceFluxFunction &flux, double CFL, int mesh_overlap)
virtual ~LaxFriedrichsSystemMPI ()
virtual void iterateN (unsigned nSteps, double dt)
virtual void iterate (double t, double tEnd)
virtual void updateDataForDynamicModule ()
virtual double getDt (double t, double tEnd)

Protected Types

enum  FACES_ZONE { ACTIVE_ZONE = 0, LEFT_DEAD_ZONE = 1, RIGHT_DEAD_ZONE = 2 }

Protected Member Functions

void setCommunicationBuffers (OrthoMesh &mesh, int mesh_overlap)
void updateDeadZone ()
void updateGhostCells ()

Protected Attributes

VecTag fDeadZone

Private Attributes

VecIndex cLDeadZoneRcvMap
VecIndex cLDeadZoneSndMap
VecIndex LGhostCellRcvMap
VecIndex LGhostCellSndMap
ArrayOfVecDouble cLDeadZoneRcv
ArrayOfVecDouble cLDeadZoneSnd
ArrayOfVecDouble LGhostCellRcv
ArrayOfVecDouble LGhostCellSnd
VecIndex cRDeadZoneRcvMap
VecIndex cRDeadZoneSndMap
VecIndex RGhostCellRcvMap
VecIndex RGhostCellSndMap
ArrayOfVecDouble cRDeadZoneRcv
ArrayOfVecDouble cRDeadZoneSnd
ArrayOfVecDouble RGhostCellRcv
ArrayOfVecDouble RGhostCellSnd

Detailed Description

This class implements the Lax Fridrichs method in parallel. Each process has a subdomain. The subdomains have intersection (mesh overllaping) because of the Dynamic module alghorithm, but the conservative method consider the region that extend into the other subdomain as a "Dead Zone". No computations are made in Dead Zone. In the sketch above, DZ1 is the deadzone of the domain Omega 1 and DZ2 is the dead zone of the process in domain Omega 2. When all the processes finish to iterate the solution, each process receives the correct values of its dead zones from the neighbors.Note that generally we need just the values of the boundaries of the dead zone to iterate the transport. The cells that belong to the dead zone and are at the boundary of the active zone are called here Ghost Cells. The other values of the dead zone are needed only when the process need to pass the value of the saturations to the dynamic module and the processes commute these values only when it is time to run the dynamic module. During the iteration of the transport we dont need to update all the cells in the dead zone, just the cells in the interface of dead zones. In the sketch bellow the process in Omega 1 need only the information of the left most cells in DZ1 while Omega 2 need the right most cells of Dz2 The Ghost Cells in Omega 1 are sent by the process in Omega 2 and the Ghost Cells in Omega 2 are sent by the process in Omega 1.

--------|----|----| |Dz2 | DZ1| --------|--- |----| Omega 1 |-----------------| Omega 2 |-------------------|

Definition at line 16 of file laxfriedrichssystemmpi.h.


Member Enumeration Documentation

Enumerator:
ACTIVE_ZONE 
LEFT_DEAD_ZONE 
RIGHT_DEAD_ZONE 

Definition at line 44 of file laxfriedrichssystemmpi.h.


Constructor & Destructor Documentation

LaxFriedrichsSystemMPI::LaxFriedrichsSystemMPI ( OrthoMesh mesh,
Function3D fInitU,
const VecDouble cPor,
Function3D fPrescribedU,
FaceFluxFunction flux,
double  CFL,
int  mesh_overlap 
)

Definition at line 9 of file laxfriedrichssystemmpi.cpp.

00010   :LaxFriedrichsForSystem(mesh,fInitU,cPor,fPrescribedU,flux,CFL)
00011 {
00012   cLDeadZoneRcv.resize(n_components);
00013   cLDeadZoneSnd.resize(n_components);
00014   LGhostCellRcv.resize(n_components);
00015   LGhostCellSnd.resize(n_components);
00016   cRDeadZoneRcv.resize(n_components);
00017   cRDeadZoneSnd.resize(n_components);
00018   RGhostCellRcv.resize(n_components);
00019   RGhostCellSnd.resize(n_components);
00020 
00021   NetMPI::trace("System:: set Communication\n");
00022   //  if (NetMPI::rank() != 0)
00023   //  NetMPI::debugPoint();
00024   LaxFriedrichsSystemMPI::setCommunicationBuffers(mesh,mesh_overlap);
00025   NetMPI::trace("System:: end set Communication\n");
00026    
00027 }

LaxFriedrichsSystemMPI::~LaxFriedrichsSystemMPI (  )  [virtual]

Definition at line 30 of file laxfriedrichssystemmpi.cpp.

00031 {
00032 
00033 }


Member Function Documentation

double LaxFriedrichsSystemMPI::getDt ( double  t,
double  tEnd 
) [virtual]

Reimplemented from LaxFriedrichsForSystem.

Definition at line 247 of file laxfriedrichssystemmpi.cpp.

00248 {
00249   assert(tEnd >= t);
00250   double timeInterval = tEnd-t;
00251   double dt = this->calculateTimeStep(m_mesh,timeInterval,m_CFL,getPorosity(),m_flux);
00252   return NetMPI::getMinValue(dt);
00253 }

void LaxFriedrichsSystemMPI::iterate ( double  t,
double  tEnd 
) [virtual]

Definition at line 125 of file laxfriedrichssystemmpi.cpp.

00126 {
00127   ConservativeMethodForSystem::iterate(t,tEnd);
00128   updateDeadZone();
00129 }

void LaxFriedrichsSystemMPI::iterateN ( unsigned  nSteps,
double  dt 
) [virtual]

Reimplemented from LaxFriedrichsForSystem.

Reimplemented in RussanovSystemMPI.

Definition at line 155 of file laxfriedrichssystemmpi.cpp.

00156 {
00157   unsigned posCell,negCell;
00158 
00159   //We iterate the method along faces, so 
00160   //alloc the vectors to contain the solutions in neg
00161   //and pos cells of the faces.  Remeber that the solution
00162   //in a cell is vector with a value for each component
00163   static VecDouble  vQPos(n_components),vQNeg(n_components),vBC(n_components);
00164 
00165 
00166   //For each time step
00167   for (unsigned count = 0; count < nSteps; count++)
00168   {
00169     //Get the face iterator and the number of faces.
00170     OrthoMesh::Face_It face = m_mesh.begin_face();
00171     unsigned nFaces = m_mesh.numFaces();
00172 
00173     //m_solAnt receives the solution in time tn since
00174     //m_sol will contain the solution in tn+1. 
00175     m_solAnt = m_sol;
00176 
00177     //For each face
00178     VecTag::iterator itDZ = fDeadZone.begin();
00179     for (unsigned faceIndex=0;faceIndex < nFaces; faceIndex++,face++,itDZ++)
00180     {
00181       if (*itDZ != ACTIVE_ZONE)
00182         continue;
00183 
00184       //Get the values of the previous solution in the right and left of the face
00185       this->getValuesOfTheFaceCells(m_mesh,m_fBC,m_solAnt,face,vQNeg,vQPos);
00186 
00187       //Get the boundary conditions in that face.
00188       //If the face doesnt have boundary condition for the ith
00189       //componente, then vBC == infinity.
00190       getBC(faceIndex,vBC);
00191 
00192       
00193       //Get the indices of the cells that contain the face.
00194       //If the face is at boundary, it has just one cell.
00195       //In this case the method getAdjCells() return posCell == negCell
00196       face->getValidCellIndices(posCell,negCell);
00197 
00198       //Get the porsity
00199       double posPor = getPorosity()(posCell);
00200       double negPor = getPorosity()(negCell);
00201       double mPor = (posPor + negPor)/2.0;
00202 
00203       //Now get the flux component by component
00204       for (unsigned cmp=0;cmp<n_components;cmp++)
00205       {
00206         
00207         //See if the face has prescribed boundary condition BC      
00208         double flux;
00209         if (vBC(cmp) == INFINITY)    
00210         {
00211           /*
00212             The face doesnt have boundary condition BC
00213             proceed to the usual computation of the flux
00214             to calculate the amount of the mass passed through
00215             the face and divide it by the cell volume
00216           */
00217           
00218           flux = dt*face->areaPerCellVol() * m_flux.fluxAtFace(face,faceIndex,posCell,negCell,vQPos,vQNeg,cmp) - mPor*(vQNeg(cmp)-vQPos(cmp))/6.0;
00219         }
00220         else //the face has BC, so dont add the stability term
00221         {
00222           flux = dt*face->areaPerCellVol() * m_flux.fluxAtFace(face,faceIndex,posCell,negCell,vBC,vBC,cmp);
00223         }
00224 
00225       
00226       
00227         //printf("face %d = %g,Pos: %d,Neg %d, SwPos = %g,SwNeg = %g \n",faceIndex,flux,face->getPosCellIndex(),face->getNegCellIndex(),SwPos,SwNeg);
00228         if (face->hasPosCell())
00229           m_sol[cmp](face->getPosCell()) +=  - flux/posPor;
00230 
00231         if (face->hasNegCell())
00232           m_sol[cmp](face->getNegCell()) +=  + flux/negPor;
00233         
00234       } //end for each component
00235     } //end for each face
00236     updateGhostCells();
00237   } //end for each time step
00238 }

void LaxFriedrichsSystemMPI::setCommunicationBuffers ( OrthoMesh mesh,
int  mesh_overlap 
) [protected]

Definition at line 36 of file laxfriedrichssystemmpi.cpp.

00037 {
00038   //Set communication buffers
00039   unsigned elemsInXY = mesh.numElemY()*mesh.numElemZ();
00040   double dx = mesh.get_dx();
00041   double tol = dx/4.0;
00042 
00043   fDeadZone.resize(mesh.numFaces(),ACTIVE_ZONE);
00044 
00045   if (NetMPI::rank() != 0)
00046   {
00047     double X0 = mesh.getP()[0];
00048     double X1 = X0 + mesh_overlap*dx;
00049     double X2 = X0 + 2*mesh_overlap*dx;
00050     
00051     cLDeadZoneRcvMap.reserve(mesh_overlap*elemsInXY);
00052     cLDeadZoneSndMap.reserve(mesh_overlap*elemsInXY);
00053     FXYSlabId fRcv(X0,X1,tol);
00054     FXYSlabId fSnd(X1,X2,tol);
00055     mesh.getCellsIndicesInDomain(fRcv,cLDeadZoneRcvMap);
00056     mesh.getCellsIndicesInDomain(fSnd,cLDeadZoneSndMap);
00057 
00058 
00059     LGhostCellRcvMap.reserve(elemsInXY);
00060     LGhostCellSndMap.reserve(elemsInXY);
00061     FXYSlabId f2Rcv(X1-dx,X1,tol);
00062     FXYSlabId f2Snd(X1,X1+dx,tol);
00063     mesh.getCellsIndicesInDomain(f2Rcv,LGhostCellRcvMap);
00064     mesh.getCellsIndicesInDomain(f2Snd,LGhostCellSndMap);
00065     NetMPI::trace("Start");
00066 
00067     assert(LGhostCellRcvMap.size() == elemsInXY);
00068     assert(LGhostCellSndMap.size() == elemsInXY);
00069 
00070 
00071 
00072     for (unsigned i=0;i<n_components;i++)
00073     {
00074       cLDeadZoneRcv[i].reinit(cLDeadZoneRcvMap.size());
00075       cLDeadZoneSnd[i].reinit(cLDeadZoneSndMap.size());
00076       LGhostCellRcv[i].reinit(LGhostCellRcvMap.size());
00077       LGhostCellSnd[i].reinit(LGhostCellSndMap.size());
00078     }
00079 
00080     FXYSlabId fLFaces(X0,X1-dx,tol);
00081     mesh.tagFacesInDomain(fLFaces,fDeadZone, LEFT_DEAD_ZONE);
00082 
00083 
00084   }
00085   if (!NetMPI::isLastProcess())
00086   {
00087     double X2 = mesh.getQ()[0];
00088     double X1 = X2 - mesh_overlap*dx;
00089     double X0 = X2 -  2*mesh_overlap*dx;
00090 
00091     cRDeadZoneRcvMap.reserve(mesh_overlap*elemsInXY);
00092     cRDeadZoneSndMap.reserve(mesh_overlap*elemsInXY);
00093     FXYSlabId fRcv(X1,X2,tol);
00094     FXYSlabId fSnd(X0,X1,tol);
00095     mesh.getCellsIndicesInDomain(fRcv,cRDeadZoneRcvMap);
00096     mesh.getCellsIndicesInDomain(fSnd,cRDeadZoneSndMap);
00097 
00098     RGhostCellRcvMap.reserve(elemsInXY);
00099     RGhostCellSndMap.reserve(elemsInXY);
00100     FXYSlabId f2Rcv(X1,X1+dx,tol);
00101     FXYSlabId f2Snd(X1-dx,X1,tol);
00102     mesh.getCellsIndicesInDomain(f2Rcv,RGhostCellRcvMap);
00103     mesh.getCellsIndicesInDomain(f2Snd,RGhostCellSndMap);
00104     NetMPI::trace("Start");
00105     assert(RGhostCellRcvMap.size() == elemsInXY);
00106     assert(RGhostCellSndMap.size() == elemsInXY);
00107 
00108     
00109     for (unsigned i=0;i<n_components;i++)
00110     {
00111       cRDeadZoneRcv[i].reinit(cRDeadZoneRcvMap.size());
00112       cRDeadZoneSnd[i].reinit(cRDeadZoneSndMap.size());
00113       RGhostCellRcv[i].reinit(RGhostCellRcvMap.size());
00114       RGhostCellSnd[i].reinit(RGhostCellSndMap.size());
00115     }
00116 
00117     FXYSlabId fRFaces(X1+dx,X2,tol);
00118     mesh.tagFacesInDomain(fRFaces,fDeadZone,RIGHT_DEAD_ZONE);
00119 
00120   }
00121   
00122 }

void LaxFriedrichsSystemMPI::updateDataForDynamicModule (  )  [virtual]

Event that runs imediately before the Dynamic Module

Reimplemented from TransportBase.

Definition at line 241 of file laxfriedrichssystemmpi.cpp.

00242 {
00243   updateDeadZone();
00244 }

void LaxFriedrichsSystemMPI::updateDeadZone (  )  [protected]

Definition at line 144 of file laxfriedrichssystemmpi.cpp.

void LaxFriedrichsSystemMPI::updateGhostCells (  )  [protected]

Definition at line 131 of file laxfriedrichssystemmpi.cpp.


Member Data Documentation

Definition at line 24 of file laxfriedrichssystemmpi.h.

Indices of cells in the left dead zone to be received to the other domain

Definition at line 19 of file laxfriedrichssystemmpi.h.

Definition at line 25 of file laxfriedrichssystemmpi.h.

Indices of cells in the left dead zone to be sent to the other domainc

Definition at line 20 of file laxfriedrichssystemmpi.h.

Definition at line 34 of file laxfriedrichssystemmpi.h.

Definition at line 29 of file laxfriedrichssystemmpi.h.

Definition at line 35 of file laxfriedrichssystemmpi.h.

Definition at line 30 of file laxfriedrichssystemmpi.h.

Check if a face is in a Dead Zone

Definition at line 41 of file laxfriedrichssystemmpi.h.

Definition at line 26 of file laxfriedrichssystemmpi.h.

Indices of ghost cells in the left dead zone to be received to the other domain

Definition at line 21 of file laxfriedrichssystemmpi.h.

Definition at line 27 of file laxfriedrichssystemmpi.h.

Indices of ghost cells in the left dead zone to be sent to the other domain

Definition at line 22 of file laxfriedrichssystemmpi.h.

Definition at line 36 of file laxfriedrichssystemmpi.h.

Definition at line 31 of file laxfriedrichssystemmpi.h.

Definition at line 37 of file laxfriedrichssystemmpi.h.

Definition at line 32 of file laxfriedrichssystemmpi.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Sun Apr 8 23:13:15 2012 for CO2INJECTION by  doxygen 1.6.3