// $Header: /home/eschnett/C/carpet/Carpet/Carpet/CarpetLib/src/dh.cc,v 1.42 2003/09/19 16:06:41 schnetter Exp $ #include #include "cctk.h" #include "cctk_Parameters.h" #include "defs.hh" #include "dist.hh" #include "ggf.hh" #include "vect.hh" #include "dh.hh" using namespace std; // Constructors template dh::dh (gh& h, const ivect& lghosts, const ivect& ughosts, const int prolongation_order_space, const int buffer_width) : h(h), lghosts(lghosts), ughosts(ughosts), prolongation_order_space(prolongation_order_space), buffer_width(buffer_width) { assert (all(lghosts>=0 && ughosts>=0)); assert (prolongation_order_space>=0); assert (buffer_width>=0); h.add(this); CHECKPOINT; recompose(false); } // Destructors template dh::~dh () { CHECKPOINT; h.remove(this); } // Helpers template int dh::prolongation_stencil_size () const { assert (prolongation_order_space>=0); return prolongation_order_space/2; } // Modifiers template void dh::recompose (const int initialise_upto) { DECLARE_CCTK_PARAMETERS; CHECKPOINT; boxes.clear(); boxes.resize(h.reflevels()); for (int rl=0; rl0) { const int csm1 = h.components(rl-1); boxes[rl][c][ml].send_ref_coarse.resize(csm1); boxes[rl][c][ml].recv_ref_coarse.resize(csm1); boxes[rl][c][ml].recv_ref_bnd_coarse.resize(csm1); } if (rl0) { const ibbox intrf = boxes[rl][c][ml-1].interior; const ibbox extrf = boxes[rl][c][ml-1].exterior; // Restriction (interior) { // (the restriction must fill all of the interior of the // coarse grid, and may use the exterior of the fine grid) const ibbox recv = intr; assert (! recv.empty()); const ibbox send = recv.expanded_for(extrf); assert (! send.empty()); assert (send.is_contained_in(extrf)); boxes[rl][c][ml-1].send_mg_coarse.push_back(send); boxes[rl][c][ml ].recv_mg_fine .push_back(recv); } // Prolongation (interior) { // (the prolongation may use the exterior of the coarse // grid, and may fill only the interior of the fine grid, // and the bbox must be as large as possible) const ibbox recv = extr.contracted_for(intrf) & intrf; assert (! recv.empty()); const ibbox send = recv.expanded_for(extr); assert (! send.empty()); boxes[rl][c][ml-1].recv_mg_coarse.push_back(recv); boxes[rl][c][ml ].send_mg_fine .push_back(send); } } // if not finest multigrid level } // for ml } // for c } // for rl // TODO: prefer boxes from the same processor for (int rl=0; rlbegin(); li!=lvi->end(); ++li) { recvs -= *li; } } assert (recvs.setsize() <= 1); if (recvs.setsize() == 1) { const ibbox recv = *recvs.begin(); const ibbox send = recv.expanded_for(extr); assert (! send.empty()); assert (send.is_contained_in(extr)); boxes[rl+1][cc][ml].recv_ref_coarse[c ].push_back(recv); boxes[rl ][c ][ml].send_ref_fine [cc].push_back(send); } } // Prolongation (boundaries) { const int pss = prolongation_stencil_size(); const ibset& bndsf = boxes[rl+1][cc][ml].boundaries; // coarsify boundaries of fine component for (typename ibset::const_iterator bi=bndsf.begin(); bi!=bndsf.end(); ++bi) { const ibbox& bndf = *bi; // (the prolongation may use the exterior of the // coarse grid, and must fill all of the boundary of // the fine grid) const ibbox maxrecvs = (extr.expand(-pss,-pss) .contracted_for(bndf)); ibset recvs = (extr.expand(-pss,-pss).contracted_for(bndf) & bndf); { // Do not prolongate what is synced const iblistvect& rs = boxes[rl+1][cc][ml].recv_sync; for (typename iblistvect::const_iterator lvi=rs.begin(); lvi!=rs.end(); ++lvi) { for (typename iblist::const_iterator li=lvi->begin(); li!=lvi->end(); ++li) { recvs -= *li; } } recvs.normalize(); } { // TODO // Take buffer zone into account const ibset oldrecvs(recvs); recvs = ibset(); for (typename ibset::const_iterator ori=oldrecvs.begin(); ori!=oldrecvs.end(); ++ori) { recvs |= ((*ori).expand(buffer_width, buffer_width) & boxes[rl+1][cc][ml].exterior & maxrecvs); } recvs.normalize(); } { // Do not prolongate what is synced (again) const iblistvect& rs = boxes[rl+1][cc][ml].recv_sync; for (typename iblistvect::const_iterator lvi=rs.begin(); lvi!=rs.end(); ++lvi) { for (typename iblist::const_iterator li=lvi->begin(); li!=lvi->end(); ++li) { recvs -= *li; } } recvs.normalize(); } { // Do not prolongate what is already prolongated const iblistvect& rrbc = boxes[rl+1][cc][ml].recv_ref_bnd_coarse; for (typename iblistvect::const_iterator lvi=rrbc.begin(); lvi!=rrbc.end(); ++lvi) { for (typename iblist::const_iterator li=lvi->begin(); li!=lvi->end(); ++li) { recvs -= *li; } } recvs.normalize(); } { for (typename ibset::const_iterator si = recvs.begin(); si != recvs.end(); ++si) { const ibbox & recv = *si; const ibbox send = recv.expanded_for(extr); assert (! send.empty()); assert (send.is_contained_in(extr)); boxes[rl+1][cc][ml].recv_ref_bnd_coarse[c ] .push_back(recv); boxes[rl ][c ][ml].send_ref_bnd_fine [cc] .push_back(send); } } } } // Restriction (interior) { // (the restriction may fill the interior of the of the // coarse grid, and may use the interior of the fine // grid, and the bbox must be as large as possible) #if 0 // (the restriction must not fill points that are used // to prolongate the boundaries) const int pss = prolongation_stencil_size(); ibset recvs = intrf.contracted_for(intr) & intr; for (int ccc=0; cccbegin(); li!=lvi->end(); ++li) { sync_not -= *li; recv_not -= *li; } } // Subtract boxes received during prolongation const iblistvect& recv_ref_bnd_coarse = boxes[rl][c][ml].recv_ref_bnd_coarse; for (typename iblistvect::const_iterator lvi=recv_ref_bnd_coarse.begin(); lvi!=recv_ref_bnd_coarse.end(); ++lvi) { for (typename iblist::const_iterator li=lvi->begin(); li!=lvi->end(); ++li) { recv_not -= *li; } } } // for ml } // for c } // for rl // Calculate bases bases.resize(h.reflevels()); for (int rl=0; rl:" << "ghosts=[" << lghosts << "," << ughosts << "]," << "gfs={"; int cnt=0; for (typename list*>::const_iterator f = gfs.begin(); f != gfs.end(); ++f) { if (cnt++) os << ","; (*f)->output(os); } os << "}"; } template class dh<3>;