#include <laxfriedrichsmpioverlap.h>
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.
enum LaxFriedrichsMPIOverlap::FACES_ZONE [protected] |
Definition at line 44 of file laxfriedrichsmpioverlap.h.
00044 {ACTIVE_ZONE=0,LEFT_DEAD_ZONE=1,RIGHT_DEAD_ZONE=2};
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] |
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.
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 | ( | ) |
Definition at line 198 of file laxfriedrichsmpioverlap.cpp.
00199 { 00200 NetMPI::exchangeDataRedBlack(cLDeadZoneSndMap,cLDeadZoneSnd,cLDeadZoneRcvMap,cLDeadZoneRcv, 00201 cRDeadZoneSndMap,cRDeadZoneSnd,cRDeadZoneRcvMap,cRDeadZoneRcv, 00202 m_cValues,DEAD_ZONE_VALUE); 00203 00204 }
void LaxFriedrichsMPIOverlap::updateGhostCells | ( | ) |
Definition at line 190 of file laxfriedrichsmpioverlap.cpp.
00191 { 00192 NetMPI::exchangeDataRedBlack(LGhostCellSndMap,LGhostCellSnd,LGhostCellRcvMap,LGhostCellRcv, 00193 RGhostCellSndMap,RGhostCellSnd,RGhostCellRcvMap,RGhostCellRcv, 00194 m_cValues,SEND_GHOSTCELL); 00195 00196 }
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.
VecTag LaxFriedrichsMPIOverlap::fDeadZone [protected] |
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.