📄 spatialg.cpp
字号:
// if we have a comp. partition below us, try to make SRB if(G->neighbor[Nindex=3]!= -1) { k = 0; makingSRB=0; bcount = 0; normal = 1; for(j=0;j<=J;j++) { int BTYPE = FREESPACE; if(bc1[j][k]) BTYPE=bc1[j][k]->getBCType(); if(BTYPE == FREESPACE || BTYPE == DIELECTRIC_BOUNDARY ) { // SRB needed here. if(makingSRB==0) { //detected an up-transition Js = j; Ks = k; bcount++; makingSRB=1; } } else if(BTYPE == CONDUCTING_BOUNDARY && makingSRB!=0) { // We've detected the end of a valid SRB: // make it and add it to THE END of the BList (necessary for toNodes to work right) try{ BList->addToEnd(makeSRB(G,Js,Ks,j,k,normal,G->neighbor,Nindex,bcount)); } catch(Oops& oops2){
oops2.prepend("SpatialRegionGroup::addNeededSRBstoRegion: Error: \n");//done
throw oops2;
} Js=0; Ks=0; makingSRB=0; } else { if(makingSRB) { // this is an error codition. printf("\n%d:ERROR: SpatialRegionBoundary attempted placement on",MPI_RANK); printf("\n%d:ERROR: another SpatialRegionBoundary, a CYLINDRICAL Axis, or",MPI_RANK); printf("\n%d:ERROR: a periodic boundary. NOT ALLOWED! Exiting.",MPI_RANK); printf("\n%d:ERROR: (happened at j=%d, k=%d) Exiting.",MPI_RANK,j,k); abort(); } } } } // need to back the index up one... j--; // we've fallen through the loop entirely if(makingSRB) { try{ BList->addToEnd(makeSRB(G,Js,Ks,j,k,normal,G->neighbor,Nindex,bcount)); } catch(Oops& oops2){
oops2.prepend("SpatialRegionGroup::addNeededSRBstoRegion: Error: \n");//OK
throw oops2;
} makingSRB=0; } // if we have a comp. partition above us, try to make SRB. if(G->neighbor[Nindex=2]!= -1) { k = K; makingSRB=0; bcount = 0; normal = -1; for(j=0;j<=J;j++) { int BTYPE = FREESPACE; if(bc1[j][k]) BTYPE=bc1[j][k]->getBCType(); if(BTYPE == FREESPACE || BTYPE == DIELECTRIC_BOUNDARY ) { // SRB needed here. if(makingSRB==0) { //detected an up-transition Js = j; Ks = k; bcount++; makingSRB=1; } } else if(BTYPE == CONDUCTING_BOUNDARY && makingSRB!=0) { // We've detected the end of a valid SRB: // make it and add it to the BList try{ BList->addToEnd(makeSRB(G,Js,Ks,j,k,normal,G->neighbor,Nindex,bcount)); } catch(Oops& oops2){
oops2.prepend("SpatialRegionGroup::addNeededSRBstoRegion: Error: \n");//OK
throw oops2;
} Js=0; Ks=0; makingSRB=0; } else { if(makingSRB) { // this is an error condition printf("\n%d:ERROR: SpatialRegionBoundary attempted placement on",MPI_RANK); printf("\n%d:ERROR: another SpatialRegionBoundary, a CYLINDRICAL Axis, or",MPI_RANK); printf("\n%d:ERROR: a periodic boundary. NOT ALLOWED! Exiting.",MPI_RANK); printf("\n%d:ERROR: (happened at j=%d, k=%d) Exiting.",MPI_RANK,j,k); abort(); } } } } // need to back the index up one... j--; // we've fallen through the loop entirely if(makingSRB) { makingSRB=0; try{ BList->addToEnd(makeSRB(G,Js,Ks,j,k,normal,G->neighbor,Nindex,bcount)); } catch(Oops& oops2){
oops2.prepend("SpatialRegionGroup::addNeededSRBstoRegion: Error: \n");//OK
throw oops2;
} } // if we have a comp. partition left of us, try to make SRB. if(G->neighbor[Nindex=1]!= -1) { j = 0; makingSRB=0; bcount = 0; normal = 1; for(k=0;k<=K;k++) { int BTYPE = FREESPACE; if(bc2[j][k]) BTYPE=bc2[j][k]->getBCType(); if(BTYPE == FREESPACE || BTYPE == DIELECTRIC_BOUNDARY ) { // SRB needed here. if(makingSRB==0) { //detected an up-transition Js = j; Ks = k; bcount++; makingSRB=1; } } else if(BTYPE == CONDUCTING_BOUNDARY && makingSRB!=0) { // We've detected the end of a valid SRB: // make it and add it to the BList try{ BList->addToEnd(makeSRB(G,Js,Ks,j,k,normal,G->neighbor,Nindex,bcount)); } catch(Oops& oops2){
oops2.prepend("SpatialRegionGroup::addNeededSRBstoRegion: Error: \n");//OK
throw oops2;
} Js=0; Ks=0; makingSRB=0; } else { if(makingSRB) { // this is an error condition and shouldn't happen. printf("\n%d:ERROR: SpatialRegionBoundary attempted placement on",MPI_RANK); printf("\n%d:ERROR: another SpatialRegionBoundary, a CYLINDRICAL Axis, or",MPI_RANK); printf("\n%d:ERROR: a periodic boundary. NOT ALLOWED! Exiting.",MPI_RANK); printf("\n%d:ERROR: (happened at j=%d, k=%d) Exiting.",MPI_RANK,j,k); abort(); } } } } // need to back the index up one... k--; // we've fallen through the loop entirely if(makingSRB) { makingSRB=0; try{ BList->addToEnd(makeSRB(G,Js,Ks,j,k,normal,G->neighbor,Nindex,bcount)); } catch(Oops& oops2){
oops2.prepend("SpatialRegionGroup::addNeededSRBstoRegion: Error: \n");//OK
throw oops2;
} } // if we have a comp. partition right of us, try to make SRB. if(G->neighbor[Nindex=0]!= -1) { j = J; makingSRB=0; bcount = 0; normal = -1; for(k=0;k<=K;k++) { int BTYPE = FREESPACE; if(bc2[j][k]) BTYPE=bc2[j][k]->getBCType(); if(BTYPE == FREESPACE || BTYPE == DIELECTRIC_BOUNDARY ) { // SRB needed here. if(makingSRB==0) { //detected an up-transition Js = j; Ks = k; bcount++; makingSRB=1; } } else if(BTYPE == CONDUCTING_BOUNDARY && makingSRB!=0) { // We've detected the end of a valid SRB: // make it and add it to the BList try{ BList->addToEnd(makeSRB(G,Js,Ks,j,k,normal,G->neighbor,Nindex,bcount)); } catch(Oops& oops2){
oops2.prepend("SpatialRegionGroup::addNeededSRBstoRegion: Error: \n");//OK
throw oops2;
} Js=0; Ks=0; makingSRB=0; } else { if(makingSRB) { printf("\n%d:ERROR: SpatialRegionBoundary attempted placement on",MPI_RANK); printf("\n%d:ERROR: another SpatialRegionBoundary, a CYLINDRICAL Axis, or",MPI_RANK); printf("\n%d:ERROR: a periodic boundary. NOT ALLOWED! Exiting.",MPI_RANK); printf("\n%d:ERROR: (happened at j=%d, k=%d) Exiting.",MPI_RANK,j,k); abort(); } } } } // need to back the index up one... k--; // we've fallen through the loop entirely if(makingSRB) { makingSRB=0; try{ BList->addToEnd(makeSRB(G,Js,Ks,j,k,normal,G->neighbor,Nindex,bcount)); } catch(Oops& oops2){
oops2.prepend("SpatialRegionGroup::addNeededSRBstoRegion: Error: \n");//OK
throw oops2;
} } }Boundary *SpatialRegionGroup::makeSRB(Grid *G,int js,int ks,int je,int ke,int normal, int *neighbor, int Nindex,int bcount) throw(Oops){ oopicList <LineSegment> *segments = new oopicList<LineSegment>; char PartnerName[512]; SpatialRegionBoundary *newSRB; LineSegment *newSeg= new LineSegment(Vector2(js,ks),Vector2(je,ke),normal); segments->add(newSeg); try{ newSRB= new SpatialRegionBoundary(segments); } catch(Oops& oops){
oops.prepend("SpatialRegionGroup::makeSRB: Error:\n"); //SpatialRegionGroup::addNeededSRBstoRegion
throw oops;
}
// set up the partner name so boundary matching can happen later. // it is in the format "RXXXYYY[V|H]NN" // XXX = higher-rank, YYY = lower-rank, V means vertical, H means horizontal // NN is the section number. sprintf(PartnerName,"R%03d%03d%c%02d", MAX(MPI_RANK,neighbor[Nindex]), MIN(MPI_RANK,neighbor[Nindex]), ((js==je)?'V':'H'),bcount); newSRB->PartnerName = PartnerName; newSRB->setBoundaryName( PartnerName); addtoSpatialRegionBoundaryList(newSRB); newSRB->setBoundaryMask(*G);#ifdef MPI_DEBUG printf("\n%d: Creating new SRB: js %d ks %d je %d ke %d normal %d, %s", MPI_RANK,js,ks,je,ke,normal,PartnerName);#endif return newSRB;}void SpatialRegionGroup::linkSRB() { // It is necessary here to link pairs of SpatialRegionBoundaries // First we check for regions on the same CPU // Now we look for boundaries on other processes/CPU's oopicListIter <SpatialRegionBoundary> SRBIter(getSpatialRegionBoundaryList()); for(SRBIter.restart();!SRBIter.Done();SRBIter++) { if(SRBIter.current()->isLinked()) continue; // if this boundary is linked already, skip it. char buf[256]; // the send buffer strncpy(buf,SRBIter.current()->PartnerName.c_str(),255); // send our ID to the root process MPI_Send(buf,255,MPI_CHAR,0,SRB_ANNOUNCE_TAG,XOOPIC_COMM); } // We need to block execution until everyone has sent ID's for // all their boundaries to everyone else. MPI_Barrier(XOOPIC_COMM); // Now the root process has to receive all the ID's and then distribute // them to everyone. int tag_modifier=0; if(MPI_RANK==0 ) { oopicList <SRBdat> SRBdatList; int incoming_messagesP; MPI_Status message_status; MPI_Iprobe(MPI_ANY_SOURCE,SRB_ANNOUNCE_TAG,XOOPIC_COMM,&incoming_messagesP,&message_status); // load all the incoming SRB information into SRBdatList while(incoming_messagesP) { SRBdat *SRBtemp = new SRBdat; SRBtemp->name = new char[256]; MPI_Recv(SRBtemp->name,255,MPI_CHAR,MPI_ANY_SOURCE,SRB_ANNOUNCE_TAG,XOOPIC_COMM,&message_status); SRBtemp->index = message_status.MPI_SOURCE; SRBtemp->linkedP = 0; SRBdatList.add(SRBtemp); MPI_Iprobe(MPI_ANY_SOURCE,SRB_ANNOUNCE_TAG,XOOPIC_COMM,&incoming_messagesP,&message_status); } // Now go through the list we've created, linking any pairs we find. oopicListIter<SRBdat> SRBdatIter(SRBdatList); for(SRBdatIter.restart();!SRBdatIter.Done();SRBdatIter++) { SRBdat *SRBtmp = SRBdatIter.current(); // check and see if this boundary is linked already if(!SRBtmp->linkedP) { // search through the rest of the list for a match oopicListIter<SRBdat> SRBdatIter2(SRBdatList); for(SRBdatIter2.restart();!SRBdatIter2.Done();SRBdatIter2++) { SRBdat *SRBtmp2 = SRBdatIter2.current(); // if it's already linked, or if it is the same, it cannot be a match // also check match on name if(! (SRBtmp2->linkedP || SRBtmp2 == SRBtmp) && !strcmp(SRBtmp->name,SRBtmp2->name) ) { tag_modifier++; // message both machines, telling them their counterparts. // message has the format: (concatenated null-terminated strings) // name\0index" , "tag_modifier\0 char buf[256]; // tell SRBtmp2 about SRBtmp sprintf(buf,"%s",SRBtmp->name); sprintf(buf+strlen(SRBtmp->name) +1, "%d , %d",SRBtmp->index,tag_modifier); MPI_Send(buf,255,MPI_CHAR,SRBtmp2->index,SRB_LINK_TAG,XOOPIC_COMM); // tell SRBtmp about SRBtmp2 sprintf(buf,"%s",SRBtmp2->name); sprintf(buf+strlen(SRBtmp2->name) +1, "%d , %d",SRBtmp2->index,tag_modifier); MPI_Send(buf,255,MPI_CHAR,SRBtmp->index,SRB_LINK_TAG,XOOPIC_COMM); } } } } } if(tag_modifier > 3900) { printf("XOOPIC is unable to handle so much job distriubtion. Use fewer nodes.\n"); exit(0); //MPI_EXIT } // synchronize everone after all the link messages have been sent MPI_Barrier(XOOPIC_COMM); // begin processing the link messages MPI_Status SRBincoming_status; int incoming_SRB_P; MPI_Iprobe(0,SRB_LINK_TAG,XOOPIC_COMM,&incoming_SRB_P,&SRBincoming_status); while(incoming_SRB_P) { char buf[256]; MPI_Recv(buf,255,MPI_CHAR,0,SRB_LINK_TAG,XOOPIC_COMM,&SRBincoming_status); // look for the local matching boundary oopicListIter <SpatialRegionBoundary> SRBIter(getSpatialRegionBoundaryList()); for(SRBIter.restart();!SRBIter.Done();SRBIter++) { if(SRBIter.current()->isLinked()) continue; // if it's linked already, this isn't it. // Does the linkname match the current boundary? If so, link it. if(!strcmp(SRBIter.current()->PartnerName.c_str(),buf)) { SpatialRegionBoundary *SRB = SRBIter.current(); SPBoundLink *link = new SPBoundLink(SRB->lE,SRB->lB,SRB->lJ, SRB->getLength(),SRB->getLength(), SRB->lNGDbuf, SRB->getnumElementsNGDbuf()); link->makeLink(atoi(buf + strlen(buf) +1),atoi(strstr(buf+strlen(buf)+1,","))); SRB->LinkBoundary(link); SRB->initialize_passives(); } }#ifdef MPI_DEBUG printf("\nAdvisman: MPI init, receiving incoming link info, #%d",MPI_RANK);#endif MPI_Iprobe(0,SRB_LINK_TAG,XOOPIC_COMM,&incoming_SRB_P,&SRBincoming_status); } }#endif /* MPI_VERSION */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -