00001 #include "hybridpressionmodulempi.h"
00002 #include "netmpi.h"
00003 #include "transportbase.h"
00004 #include "numericmethods.h"
00005 #include "hdf5dealwriter.h"
00006 #include "hdf5orthowriter.h"
00007
00008 #define BLACK_TO_RED 103
00009 #define RED_TO_BLACK 104
00010 #define B_PARAMETER 101
00011 #define BC_MESSAGE 102
00012 #define ROBIN_BC_MESSAGE 107
00013
00014
00015 HybridPressionModuleMPI::HybridPressionModuleMPI(OrthoMesh &mesh,Function3D &fPrescribedVelocities, Function3D &fPrescribedPression, Function3D &K,Function1D &fMobT,FunctionOfCellFields &fGravSource,double Xsize,double b,double theta,int meshOverlap,double maxTol, int debugLevel,std::ostream &out)
00016 :HybridPressionModule(mesh,fPrescribedVelocities,fPrescribedPression,K,fMobT,fGravSource,debugLevel,false),
00017 m_out(out)
00018 {
00019 assert(m_theta >= 0.0 && m_theta <=1.0);
00020 m_max_tol = maxTol;
00021 m_meshOverlap = meshOverlap;
00022 setCommunication();
00023 m_xSize = Xsize;
00024 m_b=b;
00025 m_sol=0.0;
00026 m_solPrev=m_sol;
00027 m_theta=theta;
00028 if (meshOverlap<=0)
00029 throw new Exception("Invalid meshOverlap parameter");
00030
00031 #ifdef DEBUG
00032 checkBC(fPrescribedVelocities,fPrescribedPression);
00033 #endif
00034
00035
00036 VecDouble Vv(m_mesh.numVertices());
00037 HDF5OrthoWriter &hdf5 = HDF5OrthoWriter::getHDF5OrthoWriter();
00038
00039
00040 }
00041
00042 void HybridPressionModuleMPI::setCommunication()
00043 {
00044 if (NetMPI::rank()!=0)
00045 {
00046 m_mesh.getFacesInYZSlab(m_mesh.getP()[0],fLeftBCRcvMap);
00047 m_mesh.getFacesInYZSlab(m_mesh.getP()[0]+2*m_meshOverlap*m_mesh.getDX()[0],fLeftBCSndMap);
00048
00049
00050 BL_Snd.reinit(fLeftBCRcvMap.size());
00051 BL_Rcv.reinit(fLeftBCRcvMap.size());
00052 LBC_Snd.reinit(fLeftBCRcvMap.size());
00053 LBC_Rcv.reinit(fLeftBCRcvMap.size());
00054 LBC_Prev.reinit(fLeftBCRcvMap.size());
00055
00056 LBC_Rcv=0.0;
00057 LBC_Prev=0.0;
00058
00059 }
00060 if (!NetMPI::isLastProcess())
00061 {
00062 m_mesh.getFacesInYZSlab(m_mesh.getQ()[0],fRightBCRcvMap);
00063 m_mesh.getFacesInYZSlab(m_mesh.getQ()[0]-2*m_meshOverlap*m_mesh.getDX()[0],fRightBCSndMap);
00064
00065
00066 BR_Snd.reinit(fRightBCRcvMap.size());
00067 BR_Rcv.reinit(fRightBCRcvMap.size());
00068 RBC_Snd.reinit(fRightBCRcvMap.size());
00069 RBC_Rcv.reinit(fRightBCRcvMap.size());
00070 RBC_Prev.reinit(fRightBCRcvMap.size());
00071 RBC_Rcv=0.0;
00072 RBC_Prev=0.0;
00073 }
00074 if (NetMPI::rank() == 0)
00075 {
00076 m_vTol.reinit(NetMPI::nProcess());
00077 }
00078
00079
00080
00081 }
00082
00083
00084
00085
00088 void HybridPressionModuleMPI::checkBC(Function3D &fPrescribedVelocities, Function3D &fPrescribedPression)
00089 {
00090 Point3D p;
00091
00092 OrthoMesh::Cell_It cell = m_mesh.begin_cell(),
00093 endc = m_mesh.end_cell();
00094
00095
00096
00097 for(;cell != endc;cell++)
00098 {
00099
00100 for (unsigned int face_no = 0; face_no < GeometryInfo<DIM>::faces_per_cell;++face_no)
00101 {
00102 FaceDirection3D fDir = (FaceDirection3D) face_no;
00103 OrthoMesh::Face_It face = cell->face(fDir);
00104 if (face->at_boundary())
00105 {
00106 bool found=false;
00107 face->barycenter(p);
00108 if (fPrescribedPression.isInDomain(p))
00109 {
00110 found=true;
00111 }
00112 if (fPrescribedVelocities.isInDomain(p))
00113 {
00114 if (found)
00115 throw new Exception("Boundary conditions clash");
00116 else
00117 found=true;
00118 }
00119 if ( (std::find(fLeftBCRcvMap.begin(),fLeftBCRcvMap.end(),face->index()) !=fLeftBCRcvMap.end()) ||
00120 (std::find(fRightBCRcvMap.begin(),fRightBCRcvMap.end(),face->index()) !=fRightBCRcvMap.end()))
00121 {
00122 if (found)
00123 throw new Exception("Boundary conditions clash");
00124 else
00125 found=true;
00126 }
00127 if (!found)
00128 {
00129 Point3D p;
00130 face->barycenter(p);
00131 throw new Exception("Found face I %d N %u (%u,%u,%u)-%g,%g,%g without boundary condition",face->index(),static_cast<unsigned>(face->getNormalOrientation()),face->getI(),face->getJ(),face->getK(),p[0],p[1],p[2]);
00132 }
00133
00134 }
00135 }
00136 }
00137 }
00138
00139
00145 void HybridPressionModuleMPI::iterateRed(TransportBase &trans)
00146 {
00147
00148 MPI_Request _req[4];
00149 MPI_Status stats[4];
00150 _req[0]=_req[1]=_req[2]=_req[3]=MPI_REQUEST_NULL;
00151
00152 double tol;
00153 int rank = NetMPI::rank();
00154 int next = rank+1;
00155 int prev = rank-1;
00156
00157
00158 const VecDouble &S1 = trans.getSolutionAtCells(0);
00159
00160 assemblySystem(trans,m_A,m_B,m_K,S1,m_fMobT,m_fMobGrav);
00161 initIteration();
00162
00163
00164 m_itCnt=0;
00165 do {
00166 m_RHS = m_B;
00167 addRobinBC(LBC_Rcv,BL_Rcv,fLeftBCRcvMap,m_K,S1,m_fMobT,m_RHS);
00168 addRobinBC(RBC_Rcv,BR_Rcv,fRightBCRcvMap,m_K,S1,m_fMobT,m_RHS);
00169 m_solPrev=m_sol;
00170 solve();
00171
00172
00173 getRobinBC(LBC_Snd,m_K,m_sol,S1,m_fMobT,fLeftBCSndMap,true);
00174 NetMPI::Isend(LBC_Snd,prev,ROBIN_BC_MESSAGE,_req[0]);
00175 getRobinBC(RBC_Snd,m_K,m_sol,S1,m_fMobT,fRightBCSndMap,false);
00176 NetMPI::Isend(RBC_Snd,next,ROBIN_BC_MESSAGE,_req[1]);
00177
00178
00179 RBC_Prev.swap(RBC_Rcv);
00180 LBC_Prev.swap(LBC_Rcv);
00181 NetMPI::Irecv(LBC_Rcv,prev,ROBIN_BC_MESSAGE,_req[2]);
00182 NetMPI::Irecv(RBC_Rcv,next,ROBIN_BC_MESSAGE,_req[3]);
00183 MPI_Waitall(4,_req,stats);
00184
00185 if (rank != 0)
00186 LBC_Rcv.sadd((1.0-m_theta),m_theta,LBC_Prev);
00187 if (!NetMPI::isLastProcess())
00188 RBC_Rcv.sadd((1.0-m_theta),m_theta,RBC_Prev);
00189
00190
00191
00192 tol = NumericMethods::relError(m_solPrev,m_sol);
00193 } while (checkConvergence(tol));
00194
00195 getNormalVelocitiesFromPressure(m_Vq,m_K,m_sol,S1,m_fMobT,m_fMobGrav,LBC_Prev,RBC_Prev);
00196
00197 }
00198
00199
00200
00206 void HybridPressionModuleMPI::iterateBlack(TransportBase &trans)
00207 {
00208
00209 MPI_Request _req[4];
00210 MPI_Status stats[4];
00211 _req[0]=_req[1]=_req[2]=_req[3]=MPI_REQUEST_NULL;
00212
00213 double tol;
00214 int rank = NetMPI::rank();
00215 int next = rank+1;
00216 int prev = rank-1;
00217
00218 const VecDouble &S1 = trans.getSolutionAtCells(0);
00219 assemblySystem(trans,m_A,m_B,m_K,S1,m_fMobT,m_fMobGrav);
00220 initIteration();
00221 do {
00222
00223 m_RHS = m_B;
00224 addRobinBC(LBC_Rcv,BL_Rcv,fLeftBCRcvMap,m_K,S1,m_fMobT,m_RHS);
00225 addRobinBC(RBC_Rcv,BR_Rcv,fRightBCRcvMap,m_K,S1,m_fMobT,m_RHS);
00226 m_solPrev=m_sol;
00227 solve();
00228
00229
00230 RBC_Prev.swap(RBC_Rcv);
00231 LBC_Prev.swap(LBC_Rcv);
00232 NetMPI::Irecv(RBC_Rcv,next,ROBIN_BC_MESSAGE,_req[0]);
00233 NetMPI::Irecv(LBC_Rcv,prev,ROBIN_BC_MESSAGE,_req[1]);
00234
00235
00236 getRobinBC(RBC_Snd,m_K,m_sol,S1,m_fMobT,fRightBCSndMap,false);
00237 NetMPI::Isend(RBC_Snd,next,ROBIN_BC_MESSAGE,_req[3]);
00238 getRobinBC(LBC_Snd,m_K,m_sol,S1,m_fMobT,fLeftBCSndMap,true);
00239 NetMPI::Isend(LBC_Snd,prev,ROBIN_BC_MESSAGE,_req[4]);
00240 MPI_Waitall(4,_req,stats);
00241
00242
00243 if (rank != 0)
00244 LBC_Rcv.sadd((1.0-m_theta),m_theta,LBC_Prev);
00245 if (!NetMPI::isLastProcess())
00246 RBC_Rcv.sadd((1.0-m_theta),m_theta,RBC_Prev);
00247
00248
00249
00250
00251 tol = NumericMethods::relError(m_solPrev,m_sol);
00252
00253
00254 }while (checkConvergence(tol));
00255
00256 getNormalVelocitiesFromPressure(m_Vq,m_K,m_sol,S1,m_fMobT,m_fMobGrav,LBC_Rcv,RBC_Rcv);
00257
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 HybridPressionModuleMPI::~HybridPressionModuleMPI()
00272 {
00273
00274 }
00275
00283 void HybridPressionModuleMPI::exchangeData(VecDouble &lSnd,VecDouble &lRcv,VecDouble &rSnd,VecDouble &rRcv)
00284 {
00285
00286
00287 int rank = NetMPI::rank();
00288 int next=rank+1;
00289 int prev=rank-1;
00290 MPI_Request reqs[4];
00291 reqs[0]=reqs[1]=reqs[2]=reqs[3]=MPI_REQUEST_NULL;
00292
00293 MPI_Status stats;
00294
00295 assert(!(rank == 0 && lSnd.size() != 0));
00296 assert(!(NetMPI::isLastProcess() && rSnd.size() != 0));
00297
00298 if (rank%2 == 0)
00299 {
00300 if (rank!= 0)
00301 MPI_Send(&(lSnd(0)),lSnd.size(),MPI_DOUBLE,prev,BLACK_TO_RED,MPI_COMM_WORLD);
00302 if (!NetMPI::isLastProcess())
00303 MPI_Send(&(rSnd(0)),rSnd.size(),MPI_DOUBLE,next,BLACK_TO_RED,MPI_COMM_WORLD);
00304
00305 if (rank!=0)
00306 MPI_Recv(&(lRcv(0)),lRcv.size(),MPI_DOUBLE,prev,RED_TO_BLACK,MPI_COMM_WORLD,&stats);
00307 if (!NetMPI::isLastProcess())
00308 MPI_Recv(&(rRcv(0)),rRcv.size(),MPI_DOUBLE,next,RED_TO_BLACK,MPI_COMM_WORLD,&stats);
00309 }
00310 else
00311 {
00312 if (!NetMPI::isLastProcess())
00313 MPI_Recv(&(rRcv(0)),rRcv.size(),MPI_DOUBLE,next,BLACK_TO_RED,MPI_COMM_WORLD,&stats);
00314 MPI_Recv(&(lRcv(0)),lRcv.size(),MPI_DOUBLE,prev,BLACK_TO_RED,MPI_COMM_WORLD,&stats);
00315
00316 if (!NetMPI::isLastProcess())
00317 MPI_Send(&(rSnd(0)),rSnd.size(),MPI_DOUBLE,next,BLACK_TO_RED,MPI_COMM_WORLD);
00318 MPI_Send(&(lSnd(0)),lSnd.size(),MPI_DOUBLE,prev,BLACK_TO_RED,MPI_COMM_WORLD);
00319
00320
00321
00322 }
00323
00324 }
00325
00326
00327 void HybridPressionModuleMPI::getBParameter(VecDouble &vB, const VecDouble &K,const VecDouble &S1,Function1D &fMobT,const VecIndex &fI)
00328 {
00329 assert(vB.size() == fI.size());
00330 for (unsigned i=0;i<vB.size();i++)
00331 {
00332 OrthoMesh::Face_It face = m_mesh.get_face(fI[i]);
00333 assert(!face->at_boundary());
00334 unsigned c1,c2;
00335 face->getAdjCellIndices(c1,c2);
00336
00337 double K1 = K(c1)*fMobT(S1(c1));
00338 double K2 = K(c2)*fMobT(S1(c2));
00339
00340 double Keff = 2*K1*K2/(K1 + K2);
00341 vB(i)=m_b*m_xSize/Keff;
00342 }
00343
00344 }
00345
00346
00347 void HybridPressionModuleMPI::getRobinBC(VecDouble &vRobin,const VecDouble &K,const VecDouble &vP,const VecDouble &S1,Function1D &fMobT,const VecIndex &fI, bool bNegateB)
00348 {
00349 assert(vRobin.size() == fI.size());
00350 double b = bNegateB ? -m_b*m_xSize : m_b*m_xSize;
00351 for (unsigned i=0;i<vRobin.size();i++)
00352 {
00353 OrthoMesh::Face_It face = m_mesh.get_face(fI[i]);
00354 assert(!face->at_boundary());
00355 unsigned c1,c2;
00356 face->getAdjCellIndices(c1,c2);
00357 double p1 = vP(c1);
00358 double p2 = vP(c2);
00359 double K1 = K(c1)*fMobT(S1(c1));
00360 double K2 = K(c2)*fMobT(S1(c2));
00361 vRobin(i) = +b*(p2-p1)*face->areaPerCellVol() + (K1*p1 + K2*p2)/(K1 + K2);
00362 }
00363 }
00364
00365
00366 void HybridPressionModuleMPI::addRobinBC(const VecDouble &v1,const VecDouble &vB,const VecIndex &fI, const VecDouble &vK,const VecDouble &S1,Function1D &fMobT,VecDouble &vRHS)
00367 {
00368 assert(vB.size() == fI.size());
00369 assert(v1.size() == fI.size());
00370 assert(vK.size() == m_mesh.numCells());
00371 assert(S1.size() == m_mesh.numCells());
00372 assert(vRHS.size() == m_mesh.numCells());
00373
00374 for (unsigned i=0;i<vB.size();i++)
00375 {
00376 OrthoMesh::Face_It face = m_mesh.get_face(fI[i]);
00377 if (!face->at_boundary())
00378 {
00379 std::cout << "throw exception\n" << std::endl;
00380 throw new Exception("Problem at face %d",fI[i]);
00381
00382 }
00383 assert(face->at_boundary());
00384 assert(face->getNormalOrientation() == OrthoMesh::NORMAL_X);
00385 unsigned c1,c2;
00386 face->getAdjCellIndices(c1,c2);
00387 double fArea = face->area();
00388 if (c2 != OrthoMesh::INVALID_INDEX)
00389 {
00390 double K = vK(c2)*fMobT(S1(c2));
00391 vRHS(c2)+= K*2*v1(i)*fArea/(m_mesh.get_dx() + 2*K*vB(i));
00392 }
00393 if (c1 != OrthoMesh::INVALID_INDEX)
00394 {
00395 double K = vK(c1)*fMobT(S1(c1));
00396 vRHS(c1)+= K*2*v1(i)*fArea/(m_mesh.get_dx() + 2*K*vB(i));
00397 }
00398
00399
00400 }
00401 }
00402
00403
00404 void HybridPressionModuleMPI::addRobinBC(const VecDouble &vB,const VecIndex &fI, const VecDouble &vK,const VecDouble &S1,Function1D &fMobT,SparseMatrix<double> &A)
00405 {
00406 assert(vB.size() == fI.size());
00407 assert(vK.size() == m_mesh.numCells());
00408 assert(S1.size() == m_mesh.numCells());
00409 assert(A.m() == A.n() && A.m() == m_mesh.numCells());
00410
00411
00412 for (unsigned i=0;i<vB.size();i++)
00413 {
00414 OrthoMesh::Face_It face = m_mesh.get_face(fI[i]);
00415 assert(face->at_boundary());
00416 assert(face->getNormalOrientation() == OrthoMesh::NORMAL_X);
00417 unsigned c1,c2;
00418 face->getAdjCellIndices(c1,c2);
00419 double fArea = face->area();
00420 if (c2 != OrthoMesh::INVALID_INDEX)
00421 {
00422 double K = vK(c2)*fMobT(S1(c2));
00423 double BC = 2*K*fArea/(m_mesh.get_dx() + 2*K*vB(i));
00424 A.add(c2,c2,BC);
00425 }
00426 if (c1 != OrthoMesh::INVALID_INDEX)
00427 {
00428 double K = vK(c1)*fMobT(S1(c1));
00429 double BC = 2*K*fArea/(m_mesh.get_dx() + 2*K*vB(i));
00430 A.add(c1,c1,BC);
00431 }
00432
00433
00434 }
00435
00436 }
00437
00438
00439 void HybridPressionModuleMPI::iterate(TransportBase &trans)
00440 {
00441 int rank = NetMPI::rank();
00442
00443 if (rank%2 == 0)
00444 {
00445 iterateRed(trans);
00446
00447 }
00448 else if (rank%2 == 1)
00449 {
00450 iterateBlack(trans);
00451 }
00452
00453 }
00454
00455
00456
00457
00458 void HybridPressionModuleMPI::printOutput()
00459 {
00460 if (_debugLevel > 0)
00461 {
00462 VecDouble v(m_mesh.numCells());
00463 VecDouble Vv(m_mesh.numVertices());
00464 HDF5OrthoWriter &hdf5 = HDF5OrthoWriter::getHDF5OrthoWriter();
00465
00466 this->getPressionAtCells(v);
00467 m_mesh.projectCentralValuesAtVertices(v,Vv);
00468 hdf5.writeScalarField(Vv,"P");
00469
00470
00471
00472
00473
00474
00475 if (_debugLevel > 1)
00476 {
00477 Matrix Mvel(m_mesh.numCells(),3);
00478 this->getVelocitiesAtCells(Mvel);
00479 if (_debugLevel > 2)
00480 {
00481 printf("\nVelocities at cells' barycenters\n\n");
00482 Mvel.print_formatted(m_out,3,true,0,"0");
00483 }
00484 VecDouble v(m_mesh.numCells());
00485 for (unsigned i=0;i<v.size();i++)
00486 {
00487 v(i) = Mvel(i,0);
00488 }
00489 VecDouble minVel(3);
00490 VecDouble maxVel(3);
00491 NumericMethods::getMinMaxValueByColumn(Mvel,minVel,maxVel);
00492 printf("Min Vel <%g,%g,%g> - Max Vel <%g,%g,%g>\n",minVel(0),minVel(1),minVel(2),maxVel(0),maxVel(1),maxVel(2));
00493
00494 m_mesh.projectCentralValuesAtVertices(v,Vv);
00495 hdf5.writeScalarField(Vv,"Vel");
00496 }
00497 }
00498
00499 }
00500
00501
00502 void HybridPressionModuleMPI::getNormalVelocitiesFromPressure(VecDouble &Vq,const VecDouble &K,const VecDouble &vP,const VecDouble &S1,Function1D &fMobT,FunctionOfCellFields &fMobGrav,const VecDouble &LRobinBC,const VecDouble &RRobinBC)
00503 {
00504 HybridPressionModule::getNormalVelocitiesFromPressure(Vq,K,vP,S1,fMobT,fMobGrav);
00505 assert(RRobinBC.size() ==0 || RRobinBC.size() == fRightBCRcvMap.size());
00506 assert(LRobinBC.size() ==0 || LRobinBC.size() == fLeftBCRcvMap.size());
00507
00508 for (unsigned i=0;i<LRobinBC.size();i++)
00509 {
00510 int faceIndex = fLeftBCRcvMap[i];
00511 OrthoMesh::Face_It face = m_mesh.get_face(faceIndex);
00512 unsigned c2 = face->getNegCell();
00513 assert(face->at_boundary());
00514 assert(face->getNormalOrientation() == OrthoMesh::NORMAL_X);
00515 assert(c2!=OrthoMesh::INVALID_INDEX);
00516 double k = K(c2)*fMobT(S1(c2));
00517 double p = vP(c2);
00518 Vq(faceIndex) = - 2*k*(p-LRobinBC(i))/(m_mesh.get_dx() + 2*k*BL_Rcv(i));
00519 }
00520
00521 for (unsigned i=0;i<RRobinBC.size();i++)
00522 {
00523 int faceIndex = fRightBCRcvMap[i];
00524 OrthoMesh::Face_It face = m_mesh.get_face(faceIndex);
00525 unsigned c1 = face->getPosCell();
00526 assert(face->at_boundary());
00527 assert(face->getNormalOrientation() == OrthoMesh::NORMAL_X);
00528 assert(c1!=OrthoMesh::INVALID_INDEX);
00529 double k = K(c1)*fMobT(S1(c1));
00530 double p = vP(c1);
00531 Vq(faceIndex) = - 2*k*(RRobinBC(i)-p)/(m_mesh.get_dx() + 2*k*BR_Rcv(i));
00532 }
00533 }
00534
00535
00536 void HybridPressionModuleMPI::assemblySystem(TransportBase &trans,SparseMatrix<double> &A,VecDouble &B,VecDouble &K,const VecDouble &S1, Function1D &fMobT, FunctionOfCellFields &fMobGrav)
00537 {
00538
00539 MPI_Request req[4];
00540 MPI_Status stats[4];
00541 req[0]=req[1]=req[2]=req[3]=MPI_REQUEST_NULL;
00542
00543 int rank = NetMPI::rank();
00544 int next = rank+1;
00545 int prev = rank-1;
00546
00547
00548 if (rank%2 == 0)
00549 {
00550
00551
00552
00553
00554 getBParameter(BL_Snd,K,S1,fMobT,fLeftBCSndMap);
00555 NetMPI::Isend(BL_Snd,prev,B_PARAMETER,req[0]);
00556 getBParameter(BR_Snd,K,S1,fMobT,fRightBCSndMap);
00557 NetMPI::Isend(BR_Snd,next,B_PARAMETER,req[1]);
00558
00559
00560 NetMPI::Irecv(BL_Rcv,prev,B_PARAMETER,req[2]);
00561 NetMPI::Irecv(BR_Rcv,next,B_PARAMETER,req[3]);
00562
00563
00564
00565 for (unsigned fieldId=0;fieldId<fMobGrav.numFields();fieldId++)
00566 fMobGrav.setField(trans.getSolutionAtCells(fieldId),fieldId);
00567
00568
00569 HybridPressionModule::assemblySystem(A,B,K,S1,fMobT,fMobGrav);
00570
00571
00572
00573
00574 MPI_Waitall(4,req,stats);
00575
00576 addRobinBC(BL_Rcv,fLeftBCRcvMap,K,S1,fMobT,A);
00577 addRobinBC(BR_Rcv,fRightBCRcvMap,K,S1,fMobT,A);
00578
00579
00580 }
00581 else if (rank%2 == 1)
00582 {
00583
00584
00585
00586
00587 NetMPI::Irecv(BR_Rcv,next,B_PARAMETER,req[0]);
00588 NetMPI::Irecv(BL_Rcv,prev,B_PARAMETER,req[1]);
00589
00590
00591 getBParameter(BR_Snd,K,S1,fMobT,fRightBCSndMap);
00592 NetMPI::Isend(BR_Snd,next,B_PARAMETER,req[3]);
00593 getBParameter(BL_Snd,K,S1,fMobT,fLeftBCSndMap);
00594 NetMPI::Isend(BL_Snd,prev,B_PARAMETER,req[2]);
00595
00596
00597
00598 for (unsigned fieldId=0;fieldId<fMobGrav.numFields();fieldId++)
00599 fMobGrav.setField(trans.getSolutionAtCells(fieldId),fieldId);
00600
00601
00602 HybridPressionModule::assemblySystem(A,B,K,S1,fMobT,fMobGrav);
00603
00604
00605
00606
00607 MPI_Waitall(4,req,stats);
00608
00609
00610 addRobinBC(BL_Rcv,fLeftBCRcvMap,K,S1,fMobT,A);
00611 addRobinBC(BR_Rcv,fRightBCRcvMap,K,S1,fMobT,A);
00612 }
00613 }
00614
00615 int HybridPressionModuleMPI::checkConvergence(double tol)
00616 {
00617 int bContinue;
00618 HDF5OrthoWriter::getHDF5OrthoWriter().setVariable("ItCnt",static_cast<double>(m_itCnt));
00619
00620 if (NetMPI::rank() != 0)
00621 {
00622 MPI_Gather(&tol,1,MPI_DOUBLE,NULL,1,MPI_DOUBLE,0,MPI_COMM_WORLD);
00623 MPI_Bcast(&bContinue,1,MPI_INT,0,MPI_COMM_WORLD);
00624 }
00625 else
00626 {
00627 m_vTol(0)=tol;
00628 MPI_Gather(&tol,1,MPI_DOUBLE,&(m_vTol(0)),1,MPI_DOUBLE,0,MPI_COMM_WORLD);
00629 bContinue=false;
00630 printf("%d Tolerance: ",m_itCnt++);
00631 for (unsigned i=0;i<m_vTol.size();i++)
00632 {
00633 printf("%g ",m_vTol(i));
00634 if (m_vTol(i) >= m_max_tol)
00635 {
00636 bContinue = true;
00637 break;
00638 }
00639 }
00640 printf("\n");
00641 MPI_Bcast(&bContinue,1,MPI_INT,0,MPI_COMM_WORLD);
00642 }
00643 return bContinue;
00644 }