int main(int argc,char *argv[]) { /** MPI Initialises...*/ MPI_Init(&argc,&argv); int comm_size,my_rank,data; /**Communication processes size...*/ MPI_Comm_size(MPI_COMM_WORLD,&comm_size); /**Communication process rank...*/ MPI_Comm_rank(MPI_COMM_WORLD,&my_rank); /** If rank is 0 means its the first process...*/ if(my_rank == 0) { data = 1; bcast(&data,1,MPI_INT,0,MPI_COMM_WORLD); } else { bcast(&data,1,MPI_INT,0,MPI_COMM_WORLD); printf("%d\n",data ); } /** MPI Deallocates...*/ MPI_Finalize(); return 0; }
template<> bool Communicator::bcast(std::string& v, int origin_rank) { unsigned int length = 0; if (origin_rank == getRank()) { length = v.length(); } if (!bcast(length, origin_rank)) { std::cerr << "Failed to bcast string length." << std::endl; return false; } if (0 == length) { v = ""; return true; } if (origin_rank == getRank()) { if (!bcast(v.c_str(), length, origin_rank)) { std::cerr << "Failed to bcast string contents." << std::endl; return false; } } else { char* buf = new char[length]; if (!bcast(buf, length, origin_rank)) { std::cerr << "Failed to bcast string contents (recv)." << std::endl; delete [] buf; return false; } v = std::string(buf, length); delete [] buf; } return true; }
void GenericCommunicator::SendThread::runEventLoop() { SendItem item; bool done = false; do { // Wait for next item in the queue: m_sendQueue.pop( item ); /* * Distinguish four cases: * * ser != 0, rcver >= 0 ==> Send * ser != 0, rcver == -1 ==> Bcast * ser == 0, rcver >= 0 ==> SendTerminationRequest * ser == 0, rcver == -1 ==> local finish request */ // Send/bcast this item: if ( item.m_ser && item.m_rcverLocalId != -1 ) { CNC_ASSERT( item.m_rcverArr == 0 ); #ifdef PRE_SEND_MSGS m_channel.wait( &item.m_rcverLocalId, 1 ); #else send( item.m_ser, item.m_rcverLocalId ); #endif } else if ( item.m_ser != 0 ) { CNC_ASSERT( item.m_rcverLocalId == -1 ); if ( item.m_rcverArr == 0 ) { bcast( item.m_ser ); } else { #ifdef PRE_SEND_MSGS m_channel.wait( &item.m_rcverArr->front(), item.m_rcverArr->size() ); #else bcast( item.m_ser, *item.m_rcverArr ); #endif } } else if ( item.m_rcverLocalId >= 0 ) { CNC_ASSERT( item.m_rcverArr == 0 ); sendTerminationRequest( item.m_rcverLocalId, item.m_indicator ); // if nonzero, item.m_indicator will be set to true // if the message has been sent successfully. } else { CNC_ASSERT( item.m_rcverArr == 0 ); CNC_ASSERT( item.m_rcverLocalId == -1 ); done = true; } // Delete corresponding serializer: cleanupItemData( item ); } while ( ! done ); }
void GenericCommunicator::SendThread::pushForBcast( serializer * ser ) { # ifdef PRE_SEND_MSGS pushForBcast( ser, NULL, m_channel.numProcs(), 0 ); // FIXME m_globalIdShift ); #else CNC_ASSERT( ser != 0 ); # ifdef CNC_WITH_ITAC // ITAC logging of bcast messages: for ( int rcver = 0; rcver < m_channel.numProcs(); ++rcver ) { // skip inactive clients (especailly myself): if ( ! m_channel.isActive( rcver ) ) continue; # ifdef WITHOUT_SENDER_THREAD_TRACING VT_SEND( rcver, (int)ser->get_total_size(), ITC_TAG_EXTERNAL ); # else VT_SEND( m_channel.localId(), (int)ser->get_total_size(), ITC_TAG_INTERNAL ); # endif } # endif // CNC_WITH_ITAC # ifdef WITHOUT_SENDER_THREAD bcast( ser ); cleanupSerializer( ser ); # else m_sendQueue.push( SendItem( ser, -1 ) ); // nonzero ser and rcver id == -1 indicate Bcast # endif #endif // PRE_SEND_MSGS }
void ccmd_bcast(t_data *data, int cs, char **cmd, t_timeval **t) { t_tlist *team; t_plist *plist; t_player *player; player = &data->fds[cs].player; if (!(*t)) timer_init(data, t); else { player->msg = split_join(cmd + 1); gui_broadcast(data, gui_pbc, player); team = data->teams; while (team) { plist = team->list; while (plist) { if (plist->player != player) bcast(data, player, plist->player); plist = plist->next; } team = team->next; } dprintf(cs, "ok\n"); } }
int main( int argc, char *argv[] ) { int root = -1, minsize = -1, maxsize = -1, repeats = -1; int c; MPI_Init( &argc, &argv ); while( ( c = getopt( argc, argv, "i:a:r:" ) ) != -1 ) { switch( c ) { case 'i': if( sscanf( optarg, "%d", &minsize ) != 1 ) exit( EXIT_FAILURE ); break; case 'a': if( sscanf( optarg, "%d", &maxsize ) != 1 ) exit( EXIT_FAILURE ); break; case 'r': if( sscanf( optarg, "%d", &repeats ) != 1 ) exit( EXIT_FAILURE ); break; } } bcast( minsize, maxsize, repeats ); MPI_Finalize(); exit( EXIT_SUCCESS ); }
/// MPI_BCast of a single value: overload for std::string // FIXME: what is exception safety status? // FIXME: inline to have it header-only. A tad too complex to be inlined? inline int bcast(std::string& val, int root, MPI_Comm comm) { std::size_t root_sz=val.size(); int rc=bcast(root_sz, root, comm); if (rc!=0) return rc; int myrank=rank(comm); if (myrank==root) { // NOTE: at root rank the value being broadcast does not change, so const cast is safe rc=bcast(const_cast<char*>(val.data()), root_sz, root, comm); } else { // FIXME: not very efficient --- any better way without heap alloc? // Note, there is no guarantee in C++03 that modifying *(&val[0]+i) is safe! boost::scoped_array<char> buf(new char[root_sz]); rc=bcast(buf.get(), root_sz, root, comm); if (rc==0) val.assign(buf.get(), root_sz); } return rc; }
void Comm::bcast_string(std::string& s) const { #ifdef OMEGA_H_USE_MPI I32 len = static_cast<I32>(s.length()); bcast(len); s.resize(static_cast<std::size_t>(len)); CALL(MPI_Bcast(&s[0], len, MPI_CHAR, 0, impl_)); #else (void)s; #endif }
static void process_file(char * filename, char * PREFIX) { char path[1024]; int nc = 0; if(ThisTask == 0) { FILE * fp = fopen(filename, "r"); if(fp == NULL) { fprintf(stderr, "failed to open package list %s.\n", filename); MPI_Abort(MPI_COMM_WORLD, 1); } while(!feof(fp)) { fgets(path, 1020, fp); nc = strlen(path); char * p = path + nc; for(p = path + nc - 1; p >= path; p --) { if(isspace(*p)) *p = 0; else break; } for(p = path; *p; p ++) { if(!isspace(*p)) break; } nc = strlen(p) + 1; if(nc == 1) continue; if(p[0] == '#') continue; /* fix \n */ MPI_Bcast(&nc, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(p, nc, MPI_BYTE, 0, MPI_COMM_WORLD); bcast(p, PREFIX); } fclose(fp); nc = 0; MPI_Bcast(&nc, 1, MPI_INT, 0, MPI_COMM_WORLD); } else { while(1) { MPI_Bcast(&nc, 1, MPI_INT, 0, MPI_COMM_WORLD); if(nc == 0) break; MPI_Bcast(path, nc, MPI_BYTE, 0, MPI_COMM_WORLD); bcast(path, PREFIX); } } }
bool Communicator::syncState(bool my_state) { bool result = my_state; if (getRank() == 0) { for (int i = 1; i < getNumProcesses(); ++i) { result &= recvState(i); } } else if (my_state) { sendValid(0); } else { sendInvalid(0); } bcast(result, 0); return result; }
bool GenericCommunicator::SendThread::pushForBcast( serializer * ser, const int * rcverArr, int n, int globalIdShift ) { CNC_ASSERT( ser != 0 ); // Allocate copy of the given rcverArr. Note that rcverArr // still contains global ids. They must be transformed into local ones // (using globalIdShift). RcverArray* myRcverArr = new RcverArray( n ); RcverArray::iterator it = myRcverArr->begin(); int _new_n = n; bool _self = false; for( int i = 0; i < n; ++ i ) { // Transform global id to local id: int localRecvId = rcverArr != NULL ? rcverArr[i] - globalIdShift : i; CNC_ASSERT( 0 <= localRecvId && localRecvId < m_channel.numProcs() ); // Skip inactive clients (especailly myself): if ( ! m_channel.isActive( localRecvId ) ) { if( localRecvId == m_channel.localId() && rcverArr != NULL ) _self = true; --_new_n; continue; } // ITAC tracing: #ifdef WITHOUT_SENDER_THREAD_TRACING VT_SEND( localRecvId, (int)ser->get_total_size(), ITC_TAG_EXTERNAL ); #else VT_SEND( m_channel.localId(), (int)ser->get_total_size(), ITC_TAG_INTERNAL ); #endif #ifdef PRE_SEND_MSGS *it = send( ser, localRecvId ); #else *it = localRecvId; #endif ++it; } myRcverArr->resize( _new_n ); #ifdef WITHOUT_SENDER_THREAD bcast( ser, *myRcverArr ); cleanupSerializer( ser ); delete myRcverArr; #else m_sendQueue.push( SendItem( ser, -1, 0, myRcverArr ) ); // nonzero ser and rcver id == -1 indicate Bcast // myRcverArr will be deleted after bcast on the sender thread #endif return _self; }
void LatticeMinimizer::step(const matrix3<>& dir, double alpha) { //Project wavefunctions to atomic orbitals: std::vector<matrix> coeff(e.eInfo.nStates); //best fit coefficients int nAtomic = e.iInfo.nAtomicOrbitals(); if(e.cntrl.dragWavefunctions && nAtomic) for(int q=e.eInfo.qStart; q<e.eInfo.qStop; q++) { //Get atomic orbitals for old lattice: e.eVars.Y[q].free(); ColumnBundle psi = e.iInfo.getAtomicOrbitals(q, false); //Fit the wavefunctions to atomic orbitals (minimize C0^OC0 where C0 is the remainder) ColumnBundle Opsi = O(psi); //non-trivial cost for uspp coeff[q] = inv(psi^Opsi) * (Opsi^e.eVars.C[q]); Opsi.free(); e.eVars.C[q] -= psi * coeff[q]; //now contains residual } //Change lattice: strain += alpha * dir; e.gInfo.R = Rorig + Rorig*strain; // Updates the lattice vectors to current strain bcast(e.gInfo.R); //ensure consistency to numerical precision updateLatticeDependent(true); // Updates lattice information but does not touch electronic state / calc electronic energy for(int q=e.eInfo.qStart; q<e.eInfo.qStop; q++) { //Restore wavefunctions from atomic orbitals: if(e.cntrl.dragWavefunctions && nAtomic) { //Get atomic orbitals for new lattice: ColumnBundle psi = e.iInfo.getAtomicOrbitals(q, false); //Reconstitute wavefunctions: e.eVars.C[q] += psi * coeff[q]; } //Reorthonormalize wavefunctions: e.eVars.VdagC[q].clear(); matrix orthoMat = invsqrt(e.eVars.C[q]^O(e.eVars.C[q], &e.eVars.VdagC[q])); e.eVars.Y[q] = e.eVars.C[q] * orthoMat; e.eVars.C[q] = e.eVars.Y[q]; e.iInfo.project(e.eVars.C[q], e.eVars.VdagC[q], &orthoMat); } }
InterfaceT)::ProjectNodes_SlavetoMaster_Orthogonal() { if (!IsComplete()) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_SlavetoMaster_Orthogonal:\n" << "***ERR*** Complete() not called on interface " << Id() << "\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } if (lcomm_ == Teuchos::null) return true; int mside = MortarSide(); int sside = OtherSide(mside); // iterate over all nodes of the slave side and project those belonging to me std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>::iterator scurr; for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = scurr->second; #if 0 std::cout << "now projecting\n " << *snode; #endif if (NodePID(snode->Id()) != lcomm_->getRank()) continue; const double* sx = snode->XCoords(); double mindist = 1.0e+20; Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> closenode = Teuchos::null; // find a node on the master side, that is closest to me std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>:: iterator mcurr; for (mcurr = rnode_[mside].begin(); mcurr != rnode_[mside].end(); ++mcurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode = mcurr->second; const double* mx = mnode->XCoords(); // build distance | mnode->XCoords() - snode->XCoords() | double dist = 0.0; for (int i = 0; i < 3; ++i) dist += (mx[i] - sx[i]) * (mx[i] - sx[i]); dist = sqrt(dist); if (dist <= mindist) { mindist = dist; closenode = mnode; } // std::cout << "snode " << snode->Id() << " mnode " << mnode->Id() << " // mindist " << mindist << " dist " << dist << std::endl; } if (closenode == Teuchos::null) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_SlavetoMaster_Orthogonal:\n" << "***ERR*** Weired: for slave node " << snode->Id() << " no closest master node found\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } // get segments attached to closest node cnode int nmseg = closenode->Nseg(); MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)** msegs = closenode->Segments(); // create a projection-iterator MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectorT) projector(IsOneDimensional(), OutLevel()); // loop segments and find all projections onto them int nsseg = snode->Nseg(); MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)** ssegs = snode->Segments(); for (int i = 0; i < nmseg; ++i) { // loop all segments that are adjacent to the slave node for (int j = 0; j < nsseg; ++j) { // project the slave node onto that master segment double xi[2]; xi[0] = xi[1] = 0.0; double gap; projector.ProjectNodetoSegment_Orthogonal_to_Slave( *snode, *(msegs[i]), xi, gap, *(ssegs[j])); // check whether this projection is good bool ok = false; if (IsOneDimensional()) { if (abs(xi[0]) < 1.01) ok = true; } else { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_SlavetoMaster_Orthogonal:\n" << "***ERR*** not impl. for 3D\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } if (ok) // the projection is good { // create a projected node and store it in snode MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode = new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)( *snode, xi, msegs[i], ssegs[j]->Id()); snode->SetProjectedNode(pnode); snode->SetGap(gap); #if 0 std::cout << " snode id: " << pnode->Id() << " projects on mseg: " << msegs[i]->Id() << " orth to sseg " << ssegs[j]->Id() << std::endl; #endif } } // for (int j=0; j<nsseg; ++j) } // for (int i=0; i<nmseg; ++i) } // for (scurr=rnode_[sside].begin(); scurr!=rnode_[sside].end(); ++scurr) // loop all slave nodes again and make projections redundant if (lcomm_->getSize() > 1) { std::vector<double> bcast(10 * rnode_[sside].size()); for (int proc = 0; proc < lcomm_->getSize(); ++proc) { int blength = 0; if (proc == lcomm_->getRank()) { for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = scurr->second; if (proc != NodePID(snode->Id())) continue; // cannot have a projection on a node i don't own int npnode = 0; Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)>* pnode = snode->GetProjectedNode(npnode); if (!pnode) continue; // no projection on this one bcast[blength] = (double)snode->Id(); ++blength; bcast[blength] = (double)npnode; ++blength; for (int j = 0; j < npnode; ++j) { bcast[blength] = (double)pnode[j]->Segment()->Id(); ++blength; const double* xi = pnode[j]->Xi(); bcast[blength] = xi[0]; ++blength; bcast[blength] = xi[1]; ++blength; bcast[blength] = pnode[j]->OrthoSegment(); ++blength; bcast[blength] = pnode[j]->Gap(); ++blength; } if ((int)bcast.size() < blength + 20) bcast.resize(bcast.size() + 40); } // for (mcurr=rnode_[mside].begin(); mcurr!=rnode_[mside].end(); // ++mcurr) if (blength >= (int)bcast.size()) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_SlavetoMaster_Orthogonal:\n" << "***ERR*** Overflow in communication buffer occured\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } } // if (proc==lComm()->MyPID()) Teuchos::broadcast<LO, int>(*lcomm_, proc, 1, &blength); if (proc != lcomm_->getRank()) bcast.resize(blength); Teuchos::broadcast<LO, double>(*lcomm_, proc, blength, &bcast[0]); if (proc != lcomm_->getRank()) { int i; for (i = 0; i < blength;) { int nid = (int)bcast[i]; ++i; Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = GetNodeView(nid); int npnode = (int)bcast[i]; ++i; for (int j = 0; j < npnode; ++j) { int sid = (int)bcast[i]; ++i; double* xi = &bcast[i]; ++i; ++i; int orthseg = (int)bcast[i]; ++i; double gap = bcast[i]; ++i; Teuchos::RCP<MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)> seg = GetSegmentView(sid); MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode = new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)( *snode, xi, seg.get(), orthseg); snode->SetProjectedNode(pnode); snode->SetGap(gap); } } if (i != blength) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_SlavetoMaster_Orthogonal:\n" << "***ERR*** Mismatch in dimension of recv buffer: " << i << " != " << blength << "\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } } // if (proc!=lComm()->MyPID()) } // for (int proc=0; proc<lComm()->NumProc(); ++proc) bcast.clear(); } // if (lComm()->NumProc()>1) #if 1 // Postprocess the projections // The slave side of the interface might be larger then the master side // of the interface so not all slave nodes have a projection. // For those slave nodes without a projection attached to a slave segment // which overlaps with the master side, Lagrange multipliers have to be // introduced. This is done by checking all nodes without a projection // whether they are attached to some slave segment on which another node // HAS a projection. If this case is found, a pseudo ProjectedNode is // introduced for that node. for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = scurr->second; // do only my own nodes // don't do anything on nodes that already have a projection if (snode->GetProjectedNode() != Teuchos::null) continue; // get segments adjacent to this node int nseg = snode->Nseg(); MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)** segs = snode->Segments(); // loop segments and check for other nodes with projection bool foundit = false; for (int i = 0; i < nseg; ++i) { int nnode = segs[i]->Nnode(); MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)** nodes = segs[i]->Nodes(); for (int j = 0; j < nnode; ++j) if (nodes[j]->GetProjectedNode() != Teuchos::null) if (nodes[j]->GetProjectedNode()->Segment()) { foundit = true; break; } if (foundit) break; } if (foundit) { #if 0 std::cout << "Node without projection:\n" << *snode; std::cout << "...get's lagrange multipliers\n\n"; #endif MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode = new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)( *snode, NULL, NULL); snode->SetProjectedNode(pnode); snode->SetGap(0.); } } #endif return true; }
///Returns the value of the future (requires communication) T get(){ std::cout<<"In get from "<<Rank_<<std::endl; T NewData; bcast((empty()?NewData:*Data_),Scheduler_->mpi_comm(),Rank_); return (empty()? NewData : *Data_); }
InterfaceT)::ProjectNodes_MastertoSlave_NormalField() { if (!IsComplete()) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_NormalField:\n" << "***ERR*** Complete() not called on interface " << Id() << "\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } if (lcomm_ == Teuchos::null) return true; int mside = MortarSide(); int sside = OtherSide(mside); // iterate over all nodes of the master side and project those belonging to me std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>::iterator mcurr; for (mcurr = rnode_[mside].begin(); mcurr != rnode_[mside].end(); ++mcurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode = mcurr->second; if (NodePID(mnode->Id()) != lcomm_->getRank()) continue; const double* mx = mnode->XCoords(); double mindist = 1.0e+20; Teuchos::RCP<MoertelT::(NodeT)> closenode = Teuchos::null; // find a node on the slave side that is closest to me std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>:: iterator scurr; for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = scurr->second; const double* sx = snode->XCoords(); // build distance | snode->XCoords() - mnode->XCoords() | double dist = 0.0; for (int i = 0; i < 3; ++i) dist += (mx[i] - sx[i]) * (mx[i] - sx[i]); dist = sqrt(dist); if (dist < mindist) { mindist = dist; closenode = snode; } } if (closenode == Teuchos::null) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_NormalField:\n" << "***ERR*** Weired: for master node " << mnode->Id() << " no closest master node found\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } #if 0 std::cout << "snode " << *mnode; std::cout << "closenode " << *closenode; #endif // get segments attached to closest node closenode int nseg = closenode->Nseg(); MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)** segs = closenode->Segments(); // create a projection operator MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectorT) projector(IsOneDimensional(), OutLevel()); // loop these segments and find best projection double bestdist[2]; const double tol = 0.2; double bestgap = 0.0, gap; bestdist[0] = bestdist[1] = 1.0e+20; MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)* bestseg = NULL; for (int i = 0; i < nseg; ++i) { // project the master node on the slave segment along the segments // interpolated normal field double xi[2]; xi[0] = xi[1] = 0.0; projector.ProjectNodetoSegment_SegmentNormal(*mnode, *(segs[i]), xi, gap); // check whether xi is better then previous projections if (IsOneDimensional()) { if (abs(xi[0]) < abs(bestdist[0])) { bestdist[0] = xi[0]; bestdist[1] = xi[1]; bestseg = segs[i]; bestgap = gap; } } else { double third = 1. / 3.; // it's 'inside' with some tolerance if (xi[0] <= 1. + tol && xi[1] <= abs(1. - xi[0]) + tol && xi[0] >= 0. - tol && xi[1] >= 0. - tol) { // it's better in both directions if (sqrt((xi[0] - third) * (xi[0] - third)) < sqrt((bestdist[0] - third) * (bestdist[0] - third)) && sqrt((xi[1] - third) * (xi[1] - third)) < sqrt((bestdist[1] - third) * (bestdist[1] - third))) { bestdist[0] = xi[0]; bestdist[1] = xi[1]; bestseg = segs[i]; bestgap = gap; } // it's better in one direction and 'in' in the other else if ( (sqrt((xi[0] - third) * (xi[0] - third)) < sqrt((bestdist[0] - third) * (bestdist[0] - third)) && xi[1] <= abs(1. - xi[0]) + tol && xi[1] >= 0. - tol) || (sqrt((xi[1] - third) * (xi[1] - third)) < sqrt((bestdist[1] - third) * (bestdist[1] - third)) && xi[0] <= 1. + tol && xi[0] >= 0. - tol)) { bestdist[0] = xi[0]; bestdist[1] = xi[1]; bestseg = segs[i]; bestgap = gap; } } } } // for (int i=0; i<nseg; ++i) // check whether the bestseg/bestdist are inside that segment // (with some tolerance of 20%) bool ok = false; if (IsOneDimensional()) { if (abs(bestdist[0]) < 1.1) ok = true; } else { if (bestdist[0] <= 1. + tol && bestdist[1] <= abs(1. - bestdist[0]) + tol && bestdist[0] >= 0. - tol && bestdist[1] >= 0. - tol) ok = true; } if (ok) // the projection is good { // build the interpolated normal and overwrite the mnode normal with -n int nsnode = bestseg->Nnode(); MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)** snodes = bestseg->Nodes(); std::vector<double> val(nsnode); bestseg->EvaluateFunction(0, bestdist, &val[0], nsnode, NULL); double NN[3]; NN[0] = NN[1] = NN[2] = 0.0; for (int i = 0; i < nsnode; ++i) { const double* Normal = snodes[i]->Normal(); for (int j = 0; j < 3; ++j) NN[j] -= val[i] * Normal[j]; } val.clear(); mnode->SetN(NN); // create projected node and store it in mnode MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode = new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)( *mnode, bestdist, bestseg); mnode->SetProjectedNode(pnode); mnode->SetGap(bestgap); } else // this mnode does not have a valid projection { if (OutLevel() > 6) std::cout << "MoertelT: ***WRN***: Projection m->s: Node " << mnode->Id() << " does not have projection\n"; mnode->SetProjectedNode(NULL); } } // for (scurr=rnode_[mside].begin(); scurr!=rnode_[mside].end(); ++scurr) // loop all master nodes again and make the projection and the new normal // redundant int bsize = 7 * rnode_[mside].size(); std::vector<double> bcast(bsize); for (int proc = 0; proc < lcomm_->getSize(); ++proc) { int blength = 0; if (proc == lcomm_->getRank()) { for (mcurr = rnode_[mside].begin(); mcurr != rnode_[mside].end(); ++mcurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode = mcurr->second; if (proc != NodePID(mnode->Id())) continue; // cannot have a projection on a node i don't own Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)> pnode = mnode->GetProjectedNode(); if (pnode == Teuchos::null) continue; // this node does not have a projection const double* xi = pnode->Xi(); const double* Normal = mnode->Normal(); bcast[blength] = (double)pnode->Id(); ++blength; if (pnode->Segment()) bcast[blength] = (double)pnode->Segment()->Id(); else bcast[blength] = -0.1; ++blength; bcast[blength] = xi[0]; ++blength; bcast[blength] = xi[1]; ++blength; bcast[blength] = Normal[0]; ++blength; bcast[blength] = Normal[1]; ++blength; bcast[blength] = Normal[2]; ++blength; bcast[blength] = pnode->Gap(); ++blength; } if (blength > bsize) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_NormalField:\n" << "***ERR*** Overflow in communication buffer occured\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } } Teuchos::broadcast<LO, int>(*lcomm_, proc, 1, &blength); Teuchos::broadcast<LO, double>(*lcomm_, proc, blength, &bcast[0]); if (proc != lcomm_->getRank()) { int i; for (i = 0; i < blength;) { int nid = (int)bcast[i]; ++i; double sid = bcast[i]; ++i; double* xi = &bcast[i]; ++i; ++i; double* n = &bcast[i]; ++i; ++i; ++i; double gap = bcast[i]; ++i; Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode = GetNodeView(nid); Teuchos::RCP<MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)> seg = Teuchos::null; if (sid != -0.1) seg = GetSegmentView((int)sid); if (mnode == Teuchos::null) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_NormalField:" "\n" << "***ERR*** Cannot get view of node\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } mnode->SetN(n); MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode = new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)( *mnode, xi, seg.get()); mnode->SetProjectedNode(pnode); mnode->SetGap(gap); } if (i != blength) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_NormalField:\n" << "***ERR*** Mismatch in dimension of recv buffer\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } } } // for (int proc=0; proc<lComm()->NumProc(); ++proc) bcast.clear(); return true; }
InterfaceT)::ProjectNodes_MastertoSlave_Orthogonal() { if (!IsComplete()) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_Orthogonal:\n" << "***ERR*** Complete() not called on interface " << Id() << "\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } if (lcomm_ == Teuchos::null) return true; int mside = MortarSide(); int sside = OtherSide(mside); // iterate over all master nodes and project those belonging to me std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>::iterator mcurr; for (mcurr = rnode_[mside].begin(); mcurr != rnode_[mside].end(); ++mcurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode = mcurr->second; if (NodePID(mnode->Id()) != lcomm_->getRank()) continue; const double* mx = mnode->XCoords(); double mindist = 1.0e+20; Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> closenode = Teuchos::null; // find a node on the slave side that is closest to me std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>:: iterator scurr; for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = scurr->second; const double* sx = snode->XCoords(); // build distance | snode->XCoords() - mnode->XCoords() | double dist = 0.0; for (int i = 0; i < 3; ++i) dist += (mx[i] - sx[i]) * (mx[i] - sx[i]); dist = sqrt(dist); if (dist < mindist) { mindist = dist; closenode = snode; } } if (closenode == Teuchos::null) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_Orthogonal:\n" << "***ERR*** Weired: for master node " << mnode->Id() << " no closest master node found\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } // get segments attached to closest node closenode int nseg = closenode->Nseg(); MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)** segs = closenode->Segments(); // create a projection operator MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectorT) projector(IsOneDimensional(), OutLevel()); // loop these segments and find best projection double bestdist[2]; double bestgap = 0.0, gap; bestdist[0] = bestdist[1] = 1.0e+20; MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)* bestseg = NULL; for (int i = 0; i < nseg; ++i) { // project the master node orthogonally on the slave segment double xi[2]; xi[0] = xi[1] = 0.0; projector.ProjectNodetoSegment_SegmentOrthogonal( *mnode, *(segs[i]), xi, gap); // check whether xi is better than previous projection if (IsOneDimensional()) { if (abs(xi[0]) < abs(bestdist[0])) { bestdist[0] = xi[0]; bestdist[1] = xi[1]; bestseg = segs[i]; bestgap = gap; } } else { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_Orthogonal:\n" << "***ERR*** not impl. for 3D\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } } // for (int i=0; i<nseg; ++i) // check whether this best projection is good bool ok = false; if (IsOneDimensional()) { if (abs(bestdist[0]) < 1.01) ok = true; } else { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_Orthogonal:\n" << "***ERR*** not impl. for 3D\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } if (ok) // the projection is good { // create a projected node and store it in mnode MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode = new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)( *mnode, bestdist, bestseg); mnode->SetProjectedNode(pnode); mnode->SetGap(bestgap); } else // this mnode does not have a valid projection { if (OutLevel() > 6) std::cout << "MoertelT: ***WRN***: Node " << mnode->Id() << " does not have projection\n\n"; // mnode->SetProjectedNode(NULL); } } // for (mcurr=rnode_[mside].begin(); mcurr!=rnode_[mside].end(); ++mcurr) // loop all master nodes again and make projection redundant int bsize = 4 * rnode_[mside].size(); std::vector<double> bcast(bsize); for (int proc = 0; proc < lcomm_->getSize(); ++proc) { int blength = 0; if (proc == lcomm_->getRank()) { for (mcurr = rnode_[mside].begin(); mcurr != rnode_[mside].end(); ++mcurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode = mcurr->second; if (proc != NodePID(mnode->Id())) continue; // cannot have a projection on a node i don't own Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)> pnode = mnode->GetProjectedNode(); if (pnode == Teuchos::null) continue; // this node does not have a projection const double* xi = pnode->Xi(); bcast[blength] = (double)pnode->Id(); ++blength; bcast[blength] = (double)pnode->Segment()->Id(); ++blength; bcast[blength] = xi[0]; ++blength; bcast[blength] = xi[1]; ++blength; bcast[blength] = pnode->Gap(); ++blength; } // for (mcurr=rnode_[mside].begin(); mcurr!=rnode_[mside].end(); // ++mcurr) if (blength > bsize) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_Orthogonal:\n" << "***ERR*** Overflow in communication buffer occured\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } } // if (proc==lComm()->MyPID()) Teuchos::broadcast<LO, int>(*lcomm_, proc, 1, &blength); Teuchos::broadcast<LO, double>(*lcomm_, proc, blength, &bcast[0]); if (proc != lcomm_->getRank()) { int i; for (i = 0; i < blength;) { int nid = (int)bcast[i]; ++i; int sid = (int)bcast[i]; ++i; double* xi = &bcast[i]; ++i; ++i; double gap = bcast[i]; ++i; Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode = GetNodeView(nid); Teuchos::RCP<MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)> seg = GetSegmentView(sid); if (mnode == Teuchos::null || seg == Teuchos::null) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_Orthogonal:\n" << "***ERR*** Cannot get view of node or segment\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode = new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)( *mnode, xi, seg.get()); mnode->SetProjectedNode(pnode); mnode->SetGap(gap); } if (i != blength) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_MastertoSlave_Orthogonal:\n" << "***ERR*** Mismatch in dimension of recv buffer: " << i << " != " << blength << "\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } } // if (proc!=lComm()->MyPID()) } // for (int proc=0; proc<lComm()->NumProc(); ++proc) bcast.clear(); return true; }
InterfaceT)::ProjectNodes_SlavetoMaster_NormalField() { if (!IsComplete()) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_SlavetoMaster_NormalField:\n" << "***ERR*** Complete() not called on interface " << Id() << "\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } if (lcomm_ == Teuchos::null) return true; int mside = MortarSide(); int sside = OtherSide(mside); // iterate over all nodes of the slave side and project those belonging to me std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>::iterator scurr; for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = scurr->second; if (NodePID(snode->Id()) != lcomm_->getRank()) continue; const double* sx = snode->XCoords(); double mindist = 1.0e+20; Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> closenode = Teuchos::null; // find a node on the master side, that is closest to me std::map<int, Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)>>:: iterator mcurr; for (mcurr = rnode_[mside].begin(); mcurr != rnode_[mside].end(); ++mcurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> mnode = mcurr->second; const double* mx = mnode->XCoords(); // build distance | mnode->XCoords() - snode->XCoords() | double dist = 0.0; for (int i = 0; i < 3; ++i) dist += (mx[i] - sx[i]) * (mx[i] - sx[i]); dist = sqrt(dist); if (dist <= mindist) { mindist = dist; closenode = mnode; } std::cout << "snode " << snode->Id() << " mnode " << mnode->Id() << " mindist " << mindist << " dist " << dist << std::endl; } if (closenode == Teuchos::null) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_SlavetoMaster_NormalField:\n" << "***ERR*** Weired: for slave node " << snode->Id() << " no closest master node found\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } #if 0 std::cout << "snode " << *snode; std::cout << "closenode " << *closenode; #endif // get segments attached to closest node cnode int nseg = closenode->Nseg(); MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)** segs = closenode->Segments(); // create a projection-iterator MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectorT) projector(IsOneDimensional(), OutLevel()); // finding a good geometric projection is somehow // critical. We work with some tolerance here and pick the 'best' // out of all acceptable projections made // loop these segments and project onto them along snode's normal vector double bestdist[2]; double gap, bestgap = 0.0; const double tol = 0.2; bestdist[0] = bestdist[1] = 1.0e+20; MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)* bestseg = NULL; for (int i = 0; i < nseg; ++i) { // project the slave node onto that master segment double xi[2]; xi[0] = xi[1] = 0.0; projector.ProjectNodetoSegment_NodalNormal(*snode, *(segs[i]), xi, gap); // check whether xi is better then previous projections if (IsOneDimensional()) // 2D case { if (abs(xi[0]) < abs(bestdist[0])) { bestdist[0] = xi[0]; bestdist[1] = xi[1]; bestseg = segs[i]; bestgap = gap; } } else // 3D case { double third = 1. / 3.; // it's 'inside' with some tolerance if (xi[0] <= 1. + tol && xi[1] <= abs(1. - xi[0]) + tol && xi[0] >= 0. - tol && xi[1] >= 0. - tol) { // it's better in both directions if (sqrt((xi[0] - third) * (xi[0] - third)) < sqrt((bestdist[0] - third) * (bestdist[0] - third)) && sqrt((xi[1] - third) * (xi[1] - third)) < sqrt((bestdist[1] - third) * (bestdist[1] - third))) { bestdist[0] = xi[0]; bestdist[1] = xi[1]; bestseg = segs[i]; bestgap = gap; } // it's better in one direction and 'in' in the other else if ( (sqrt((xi[0] - third) * (xi[0] - third)) < sqrt((bestdist[0] - third) * (bestdist[0] - third)) && xi[1] <= abs(1. - xi[0]) + tol && xi[1] >= 0. - tol) || (sqrt((xi[1] - third) * (xi[1] - third)) < sqrt((bestdist[1] - third) * (bestdist[1] - third)) && xi[0] <= 1. + tol && xi[0] >= 0. - tol)) { bestdist[0] = xi[0]; bestdist[1] = xi[1]; bestseg = segs[i]; bestgap = gap; } } } } // for (int i=0; i<nseg; ++i) // check whether the bestseg and bestdist are inside the segment // (with some tolerance of 20%) bool ok = false; if (IsOneDimensional()) { if (abs(bestdist[0]) < 1.2) ok = true; } else { if (bestdist[0] <= 1. + tol && bestdist[1] <= abs(1. - bestdist[0]) + tol && bestdist[0] >= 0. - tol && bestdist[1] >= 0. - tol) ok = true; } if (ok) // the projection is good { // create a projected node and store it in snode MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode = new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)( *snode, bestdist, bestseg); snode->SetProjectedNode(pnode); snode->SetGap(bestgap); } else { if (OutLevel() > 6) std::cout << "MoertelT: ***WRN***: Projection s->m: Node " << snode->Id() << " does not have projection\n"; snode->SetProjectedNode(NULL); } } // for (scurr=rnode_[sside].begin(); scurr!=rnode_[sside].end(); ++scurr) lcomm_->barrier(); // loop all slave nodes again and make the projections redundant std::vector<double> bcast(4 * rnode_[sside].size()); for (int proc = 0; proc < lcomm_->getSize(); ++proc) { int blength = 0; if (proc == lcomm_->getRank()) { for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = scurr->second; if (proc != NodePID(snode->Id())) continue; // I cannot have a projection on a node not owned by me Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)> pnode = snode->GetProjectedNode(); if (pnode == Teuchos::null) continue; // this node does not have a projection const double* xi = pnode->Xi(); bcast[blength] = (double)pnode->Id(); ++blength; if (pnode->Segment()) bcast[blength] = (double)pnode->Segment()->Id(); else bcast[blength] = -0.1; // indicating this node does not have // projection but lagrange multipliers ++blength; bcast[blength] = xi[0]; ++blength; bcast[blength] = xi[1]; ++blength; bcast[blength] = pnode->Gap(); ++blength; } if (blength > (int)(4 * rnode_[sside].size())) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_SlavetoMaster_NormalField:\n" << "***ERR*** Overflow in communication buffer occured\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } } Teuchos::broadcast<LO, int>(*lcomm_, proc, 1, &blength); Teuchos::broadcast<LO, double>(*lcomm_, proc, blength, &bcast[0]); if (proc != lcomm_->getRank()) { int i; for (i = 0; i < blength;) { int nid = (int)bcast[i]; ++i; double sid = bcast[i]; ++i; double* xi = &bcast[i]; ++i; ++i; double gap = bcast[i]; ++i; Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = GetNodeView(nid); Teuchos::RCP<MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)> seg = Teuchos::null; if (sid != -0.1) seg = GetSegmentView((int)sid); if (snode == Teuchos::null) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_SlavetoMaster_NormalField:" "\n" << "***ERR*** Cannot get view of node\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode = new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)( *snode, xi, seg.get()); snode->SetProjectedNode(pnode); snode->SetGap(gap); } if (i != blength) { std::stringstream oss; oss << "***ERR*** " "MoertelT::Interface::ProjectNodes_SlavetoMaster_NormalField:\n" << "***ERR*** Mismatch in dimension of recv buffer\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw MoertelT::ReportError(oss); } } } // for (int proc=0; proc<lComm()->NumProc(); ++proc) bcast.clear(); lcomm_->barrier(); #if 1 // Postprocess the projections // The slave side of the interface might be larger then the master side // of the interface so not all slave nodes have a projection. // For those slave nodes without a projection attached to a slave segment // which overlaps with the master side, Lagrange multipliers have to be // introduced. This is done by checking all nodes without a projection // whether they are attached to some slave segment on which another node // HAS a projection. If this case is found, a pseudo ProjectedNode is // introduced for that node. for (scurr = rnode_[sside].begin(); scurr != rnode_[sside].end(); ++scurr) { Teuchos::RCP<MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)> snode = scurr->second; // don't do anything on nodes that already have a projection if (snode->GetProjectedNode() != Teuchos::null) continue; // get segments adjacent to this node int nseg = snode->Nseg(); MoertelT::SEGMENT_TEMPLATE_CLASS(SegmentT)** segs = snode->Segments(); // loop segments and check for other nodes with projection bool foundit = false; for (int i = 0; i < nseg; ++i) { int nnode = segs[i]->Nnode(); MoertelT::MOERTEL_TEMPLATE_CLASS(NodeT)** nodes = segs[i]->Nodes(); for (int j = 0; j < nnode; ++j) if (nodes[j]->GetProjectedNode() != Teuchos::null) if (nodes[j]->GetProjectedNode()->Segment()) { foundit = true; break; } if (foundit) break; } if (foundit) { #if 1 std::cout << "Node without projection:\n" << *snode; std::cout << "...get's lagrange multipliers\n\n"; #endif MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)* pnode = new MoertelT::MOERTEL_TEMPLATE_CLASS(ProjectedNodeT)( *snode, NULL, NULL); snode->SetProjectedNode(pnode); snode->SetGap(0.); } } // for (scurr=rnode_[sside].begin(); scurr!=rnode_[sside].end(); ++scurr) #endif return true; }
/* 3 2 1 0 X 3 2 1 0 ---------------------------- 0.3 0.2 0.1 0.0 1.3 1.2 1.1 1.0 2.3 2.2 2.1 2.0 3.3 3.2 3.1 3.0 ---------------------------- |3.3|1.3|0.2|0.0| A |2.3|0.3|0.1| B |3.2|1.2|1.0| C |2.2|1.1| D |3.1|2.0| E |2.1| F |3.0| G |-------> only this side 32 x 32 -> 32 */ long _mullong (long a, long b) { union bil t; t.i.hi = bcast(a)->b.b0 * bcast(b)->b.b2; // A t.i.lo = bcast(a)->b.b0 * bcast(b)->b.b0; // A t.b.b3 += bcast(a)->b.b3 * bcast(b)->b.b0; // G t.b.b3 += bcast(a)->b.b2 * bcast(b)->b.b1; // F t.i.hi += bcast(a)->b.b2 * bcast(b)->b.b0; // E <- b lost in .lst // bcast(a)->i.hi is free ! t.i.hi += bcast(a)->b.b1 * bcast(b)->b.b1; // D <- b lost in .lst bcast(a)->bi.b3 = bcast(a)->b.b1 * bcast(b)->b.b2; bcast(a)->bi.i12 = bcast(a)->b.b1 * bcast(b)->b.b0; // C bcast(b)->bi.b3 = bcast(a)->b.b0 * bcast(b)->b.b3; bcast(b)->bi.i12 = bcast(a)->b.b0 * bcast(b)->b.b1; // B bcast(b)->bi.b0 = 0; // B bcast(a)->bi.b0 = 0; // C t.l += a; return t.l + b; }
int main(int argc, char **argv) { int i; int *target; int *source; int me, npes, elements=N_ELEMENTS, loops=DFLT_LOOPS; char *pgm; shmem_init(); me = shmem_my_pe(); npes = shmem_n_pes(); if ((pgm=strrchr(argv[0],'/'))) pgm++; else pgm = argv[0]; /* lower-case switch enable only a specific test; otherwise run all tests */ while ((i = getopt (argc, argv, "hvqe:l:abcmn")) != EOF) { switch (i) { case 'a': All2++; break; case 'b': Bcast++; break; case 'c': Collect++; break; case 'm': Many++; break; case 'n': Neighbor++; break; case 'q': Verbose=0; break; case 'v': Verbose++; break; case 'e': if ((elements = atoi_scaled(optarg)) <= 0) { fprintf(stderr,"ERR: Bad elements count %d\n",elements); shmem_finalize(); return 1; } break; case 'l': if ((loops = atoi_scaled(optarg)) <= 0) { fprintf(stderr,"ERR: Bad loop count %d\n",loops); shmem_finalize(); return 1; } break; case 'h': if (me == 0) usage(pgm); shmem_finalize(); return 0; default: if (me == 0) { fprintf(stderr,"%s: unknown switch '-%c'?\n",pgm,i); usage(pgm); } shmem_finalize(); return 1; } } if (All2==0 && Bcast==0 && Collect==0 && Many==0 && Neighbor==0) All2 = Bcast = Collect = Many = Neighbor = 1; source = (int *) shmem_malloc( elements * sizeof(*source) ); target = (int *) shmem_malloc( elements * sizeof(*target) ); for (i = 0; i < elements; i += 1) { source[i] = i + 1; target[i] = -90; } shmem_barrier_all(); if (Neighbor) { neighbor_put( target, source, elements, me, npes, loops ); neighbor_get( target, source, elements, me, npes, loops ); } if (All2) { all2all_put( target, source, elements, me, npes, loops ); all2all_get( target, source, elements, me, npes, loops ); } if (Many) { one2many_put( target, source, elements, me, npes, loops ); many2one_get( target, source, elements, me, npes, loops ); } if (Bcast) bcast( target, source, elements, me, npes, loops ); if (Collect) { collect( NULL, source, elements, me, npes, loops ); fcollect( NULL, source, elements, me, npes, loops ); } shmem_barrier_all(); shmem_free(target); shmem_free(source); shmem_finalize(); return 0; }
int main(int argc, char **argv) { /* first allow everyone to purge files created by me */ umask(0); MPI_Init(&argc, &argv); double t0 = MPI_Wtime(); t_bcast = 0; t_tar = 0; t_init = 0; int nid = getnid(); initialize(nid); t_init = MPI_Wtime() - t0; t0 = MPI_Wtime(); int ch; extern char * optarg; extern int optind; char * PREFIX = "/dev/shm/python"; fnlist.next = NULL; while((ch = getopt(argc, argv, "vtf:p:")) != -1) { switch(ch) { case 'v': VERBOSE = 1; break; case 't': TIME = 1; break; case 'p': PREFIX = optarg; break; case 'f': { struct fnlist * p = malloc(sizeof(fnlist)); p->next = fnlist.next; fnlist.next = p; p->path = strdup(optarg); } break; case '?': if(ThisTask == 0) { fprintf(stderr, "usage: bcast [-v] [-f filelist] [-p /dev/shm/python] [packages ...]\n"); } goto quit; } } if(ThisTask == 0) { if(VERBOSE) { printf("tmpdir:%s\n", PREFIX); fflush(stdout); } } if(NodeRank == 0) { _mkdir(PREFIX); } MPI_Barrier(MPI_COMM_WORLD); struct fnlist * p; for(p = fnlist.next; p ; p = p->next) { process_file(p->path, PREFIX); } int i; for(i = optind; i < argc; i ++) { bcast(argv[i], PREFIX); } if(ThisTask == 0) if(TIME) { printf("Time : %g in init\n", t_init); printf("Time : %g in bcast\n", t_bcast); printf("Time : %g in tar\n", t_tar); printf("Time : %g in total \n", MPI_Wtime() - t0); } quit: MPI_Barrier(MPI_COMM_WORLD); MPI_Finalize(); return 0; }
int bcast(T& val, int root, MPI_Comm comm) { return bcast(&val, 1, root, comm); }