#include <laxfriedrichssystemmpi.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. 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.
enum LaxFriedrichsSystemMPI::FACES_ZONE [protected] |
Definition at line 44 of file laxfriedrichssystemmpi.h.
00044 {ACTIVE_ZONE=0,LEFT_DEAD_ZONE=1,RIGHT_DEAD_ZONE=2};
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.
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.
00145 { 00146 for (unsigned i=0;i<n_components;i++) 00147 { 00148 NetMPI::exchangeDataRedBlack(cLDeadZoneSndMap,cLDeadZoneSnd[i],cLDeadZoneRcvMap,cLDeadZoneRcv[i], 00149 cRDeadZoneSndMap,cRDeadZoneSnd[i],cRDeadZoneRcvMap,cRDeadZoneRcv[i], 00150 m_sol[i],DEAD_ZONE_VALUE); 00151 } 00152 }
void LaxFriedrichsSystemMPI::updateGhostCells | ( | ) | [protected] |
Definition at line 131 of file laxfriedrichssystemmpi.cpp.
00132 { 00133 for (unsigned i=0;i<n_components;i++) 00134 { 00135 NetMPI::exchangeDataRedBlack(LGhostCellSndMap,LGhostCellSnd[i],LGhostCellRcvMap,LGhostCellRcv[i], 00136 RGhostCellSndMap,RGhostCellSnd[i],RGhostCellRcvMap,RGhostCellRcv[i], 00137 m_sol[i],SEND_GHOSTCELL); 00138 } 00139 }
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.
VecTag LaxFriedrichsSystemMPI::fDeadZone [protected] |
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.