LaxFriedrichsMPIOverlap Class Reference

#include <laxfriedrichsmpioverlap.h>

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

List of all members.

Public Member Functions

 LaxFriedrichsMPIOverlap (OrthoMesh &mesh, Function3D &fInitU, const VecDouble &cPor, Function3D &fPrescribedU, FaceFluxFunction &flux, double CFL, int mesh_overlap)
virtual ~LaxFriedrichsMethodMPI ()
virtual void iterate (double t, double tEnd)
void updateGhostCells ()
void updateDeadZone ()
void unitTest ()
double negotiateTimeStep (double dt)

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)

Protected Attributes

VecTag fDeadZone

Private Attributes

VecIndex cLDeadZoneRcvMap
VecDouble cLDeadZoneRcv
VecIndex cLDeadZoneSndMap
VecDouble cLDeadZoneSnd
VecIndex LGhostCellRcvMap
VecDouble LGhostCellRcv
VecIndex LGhostCellSndMap
VecDouble LGhostCellSnd
VecIndex cRDeadZoneRcvMap
VecDouble cRDeadZoneRcv
VecIndex cRDeadZoneSndMap
VecDouble cRDeadZoneSnd
VecIndex RGhostCellRcvMap
VecDouble RGhostCellRcv
VecIndex RGhostCellSndMap
VecDouble 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.

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

Definition at line 20 of file laxfriedrichsmpioverlap.h.


Member Enumeration Documentation

Enumerator:
ACTIVE_ZONE 
LEFT_DEAD_ZONE 
RIGHT_DEAD_ZONE 

Definition at line 44 of file laxfriedrichsmpioverlap.h.


Constructor & Destructor Documentation

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

Definition at line 96 of file laxfriedrichsmpioverlap.cpp.

00097    :LaxFriedrichsMethod(mesh,fInitU,cPor,fPrescribedU,flux,CFL)
00098  {
00099    NetMPI::trace("Entering Communication Buffers ");
00100    setCommunicationBuffers(mesh,mesh_overlap);
00101    NetMPI::trace("End");
00102    
00103 }

virtual LaxFriedrichsMPIOverlap::~LaxFriedrichsMethodMPI (  )  [virtual]

Member Function Documentation

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

Reimplemented in RussanovMPIOverlap.

Definition at line 106 of file laxfriedrichsmpioverlap.cpp.

00107 {
00108   unsigned posCell,negCell;
00109   VecReq _req(4);
00110   double timeInterval = tEnd-t;
00111   double localDt = this->calculateTimeStep(m_mesh,timeInterval,m_CFL,getPorosity(),m_flux);
00112   double dt=negotiateTimeStep(localDt);
00113   NetMPI::trace("Lax Negotiating dt: Sent %g, got %g",localDt,dt); 
00114   
00115   //Get the number of iterations
00116   int nIteraction = (int) round(timeInterval/dt); //number of iteractions
00117 
00118   //For each time step
00119   for (int count = 0; count < nIteraction; count++)
00120   {
00121     //Get the face iterator and the number of faces.
00122     OrthoMesh::Face_It face = m_mesh.begin_face();
00123     unsigned nFaces = m_mesh.numFaces();
00124     
00125     m_cValuesPrev=m_cValues;
00126 
00127     //For each face
00128     VecTag::iterator itDZ = fDeadZone.begin();
00129     for (unsigned faceIndex=0;faceIndex < nFaces; faceIndex++,face++,itDZ++)
00130     {
00131       //Check if the face is in active zone
00132       if (*itDZ != ACTIVE_ZONE)
00133         continue;
00134       
00135       //Get the values of the previous solution in the right and left of the face
00136       double SwPos,SwNeg;
00137       this->getValuesOfTheFaceCells(m_mesh,m_fValues,m_cValuesPrev,face,SwNeg,SwPos);
00138 
00139       //Get the values of the cells that contain the face.
00140       //If the face is at boundary, it has just one cell.
00141       //In this case the method getAdjCells() return posCell == negCell
00142       face->getValidCellIndices(posCell,negCell);
00143 
00144       //Get the porsity
00145       double posPor = getPorosity()(posCell);
00146       double negPor = getPorosity()(negCell);
00147 
00148       //
00149       double mPor = (posPor + negPor)/2.0;
00150       
00151       //See if the face has prescribed boundary condition BC      
00152       double flux;
00153       double bc = (getBC(faceIndex));
00154       if (bc == INFINITY)    
00155       {
00156         /*
00157           The face doesnt have boundary condition BC
00158         proceed to the usual computation of the flux
00159         to calculate the amount of the mass passed through
00160         the face and divide it by the cell volume
00161         */
00162         flux = dt*face->areaPerCellVol() * m_flux.fluxAtFace(face,faceIndex,posCell,negCell,SwPos,SwNeg) - mPor*(SwNeg-SwPos)/6.0;
00163       }
00164       else //the face has BC, so dont add the stability term
00165       {
00166         flux = dt*face->areaPerCellVol() * m_flux.fluxAtFace(face,faceIndex,posCell,negCell,bc,bc);
00167       }
00168 
00169       
00170       
00171       //printf("face %d = %g,Pos: %d,Neg %d, SwPos = %g,SwNeg = %g \n",faceIndex,flux,face->getPosCellIndex(),face->getNegCellIndex(),SwPos,SwNeg);
00172       if (face->hasPosCell())
00173         m_cValues(face->getPosCell()) +=  - flux/posPor;
00174 
00175       if (face->hasNegCell())
00176         m_cValues(face->getNegCell()) +=  + flux/negPor;
00177     }
00178     updateGhostCells();
00179     
00180   }
00181   updateDeadZone();
00182 }

double LaxFriedrichsMPIOverlap::negotiateTimeStep ( double  dt  ) 

Negotiate which time step each node will use

Definition at line 222 of file laxfriedrichsmpioverlap.cpp.

00223 {
00224   double dd;
00225   MPI_Allreduce(&dt,&dd,1,MPI_DOUBLE,MPI_MIN,MPI_COMM_WORLD);
00226   return dd;
00227 }

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

Definition at line 8 of file laxfriedrichsmpioverlap.cpp.

00009 {
00010   //Set communication buffers
00011   unsigned elemsInXY = mesh.numElemY()*mesh.numElemZ();
00012   double dx = mesh.get_dx();
00013   double tol = dx/4.0;
00014   
00015   
00016   fDeadZone.resize(mesh.numFaces(),ACTIVE_ZONE);
00017   if (NetMPI::rank() != 0)
00018   {
00019     double X0 = mesh.getP()[0];
00020     double X1 = X0 + mesh_overlap*dx;
00021     double X2 = X0 + 2*mesh_overlap*dx;
00022 
00023     cLDeadZoneRcvMap.reserve(mesh_overlap*elemsInXY);
00024     cLDeadZoneSndMap.reserve(mesh_overlap*elemsInXY);
00025     FXYSlabId fRcv(X0,X1,tol);
00026     FXYSlabId fSnd(X1,X2,tol);
00027     mesh.getCellsInFunctionDomain(fRcv,cLDeadZoneRcvMap);
00028     mesh.getCellsInFunctionDomain(fSnd,cLDeadZoneSndMap);
00029     cLDeadZoneRcv.reinit(cLDeadZoneRcvMap.size());
00030     cLDeadZoneSnd.reinit(cLDeadZoneSndMap.size());
00031 
00032     LGhostCellRcvMap.reserve(elemsInXY);
00033     LGhostCellSndMap.reserve(elemsInXY);
00034     FXYSlabId f2Rcv(X1-dx,X1,tol);
00035     FXYSlabId f2Snd(X1,X1+dx,tol);
00036     mesh.getCellsInFunctionDomain(f2Rcv,LGhostCellRcvMap);
00037     mesh.getCellsInFunctionDomain(f2Snd,LGhostCellSndMap);
00038     LGhostCellRcv.reinit(LGhostCellRcvMap.size());
00039     LGhostCellSnd.reinit(LGhostCellSndMap.size());
00040     assert(LGhostCellRcvMap.size() == elemsInXY);
00041     assert(LGhostCellSndMap.size() == elemsInXY);
00042 
00043     FXYSlabId fLFaces(X0,X1-dx,tol);
00044     mesh.tagFacesInDomain(fLFaces,fDeadZone, LEFT_DEAD_ZONE);
00045 
00046 
00047   }
00048   if (!NetMPI::isLastProcess())
00049   {
00050     double X2 = mesh.getQ()[0];
00051     double X1 = X2 - mesh_overlap*dx;
00052     double X0 = X2 -  2*mesh_overlap*dx;
00053 
00054     cRDeadZoneRcvMap.reserve(mesh_overlap*elemsInXY);
00055     cRDeadZoneSndMap.reserve(mesh_overlap*elemsInXY);
00056     FXYSlabId fRcv(X1,X2,tol);
00057     FXYSlabId fSnd(X0,X1,tol);
00058     mesh.getCellsInFunctionDomain(fRcv,cRDeadZoneRcvMap);
00059     mesh.getCellsInFunctionDomain(fSnd,cRDeadZoneSndMap);
00060     cRDeadZoneRcv.reinit(cRDeadZoneRcvMap.size());
00061     cRDeadZoneSnd.reinit(cRDeadZoneSndMap.size());
00062 
00063     RGhostCellRcvMap.reserve(elemsInXY);
00064     RGhostCellSndMap.reserve(elemsInXY);
00065     FXYSlabId f2Rcv(X1,X1+dx,tol);
00066     FXYSlabId f2Snd(X1-dx,X1,tol);
00067     mesh.getCellsInFunctionDomain(f2Rcv,RGhostCellRcvMap);
00068     mesh.getCellsInFunctionDomain(f2Snd,RGhostCellSndMap);
00069     RGhostCellRcv.reinit(RGhostCellRcvMap.size());
00070     RGhostCellSnd.reinit(RGhostCellSndMap.size());
00071     assert(RGhostCellRcvMap.size() == elemsInXY);
00072     assert(RGhostCellSndMap.size() == elemsInXY);
00073 
00074     FXYSlabId fRFaces(X1+dx,X2,tol);
00075     mesh.tagFacesInDomain(fRFaces,fDeadZone,RIGHT_DEAD_ZONE);
00076 
00077 
00078 
00079   }
00080 
00081 }

void LaxFriedrichsMPIOverlap::unitTest (  ) 

Definition at line 207 of file laxfriedrichsmpioverlap.cpp.

00208 {
00209   std::ostream &out = NetMPI::getLog();
00210   out << "\n\nLeft Ghost Rcv\n";
00211   m_mesh.printCells(LGhostCellRcvMap,out);
00212   out << "\n\nLeft Ghost Snd\n";
00213   m_mesh.printCells(LGhostCellSndMap,out);
00214   out << "\n\nRight Ghost Rcv\n";
00215   m_mesh.printCells(RGhostCellRcvMap,out);
00216   out << "\n\nRight Ghost Snd\n";
00217   m_mesh.printCells(RGhostCellSndMap,out);
00218 
00219 }

void LaxFriedrichsMPIOverlap::updateDeadZone (  ) 
void LaxFriedrichsMPIOverlap::updateGhostCells (  ) 

Member Data Documentation

Definition at line 24 of file laxfriedrichsmpioverlap.h.

Indices of cells in the left dead zone

Definition at line 23 of file laxfriedrichsmpioverlap.h.

Indices of cells in the right dead zone

Definition at line 26 of file laxfriedrichsmpioverlap.h.

Definition at line 25 of file laxfriedrichsmpioverlap.h.

Definition at line 33 of file laxfriedrichsmpioverlap.h.

Indices of cells in the right dead zone to receive

Definition at line 32 of file laxfriedrichsmpioverlap.h.

Indices of cells in the right dead zone to send

Definition at line 35 of file laxfriedrichsmpioverlap.h.

Definition at line 34 of file laxfriedrichsmpioverlap.h.

Check if a face is in a Dead Zone

Definition at line 42 of file laxfriedrichsmpioverlap.h.

Definition at line 28 of file laxfriedrichsmpioverlap.h.

Definition at line 27 of file laxfriedrichsmpioverlap.h.

Definition at line 30 of file laxfriedrichsmpioverlap.h.

Definition at line 29 of file laxfriedrichsmpioverlap.h.

Definition at line 37 of file laxfriedrichsmpioverlap.h.

Definition at line 36 of file laxfriedrichsmpioverlap.h.

Definition at line 39 of file laxfriedrichsmpioverlap.h.

Definition at line 38 of file laxfriedrichsmpioverlap.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:14 2012 for CO2INJECTION by  doxygen 1.6.3