// $Header: /home/eschnett/C/carpet/Carpet/Carpet/CarpetLib/src/dh.cc,v 1.57 2004/09/17 16:37:26 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 bool do_prolongate) { DECLARE_CCTK_PARAMETERS; CHECKPOINT; boxes.clear(); boxes.resize(h.reflevels()); for (int rl=0; rl0) { const int csm1 = h.components(rl-1); boxes.at(rl).at(c).at(ml).send_ref_coarse.resize(csm1); boxes.at(rl).at(c).at(ml).recv_ref_coarse.resize(csm1); boxes.at(rl).at(c).at(ml).recv_ref_bnd_coarse.resize(csm1); } if (rl0) { const ibbox intrf = boxes.at(rl).at(c).at(ml-1).interior; const ibbox extrf = boxes.at(rl).at(c).at(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 (intr.empty() || ! recv.empty()); const ibbox send = recv.expanded_for(extrf); assert (intr.empty() || ! send.empty()); // TODO: put the check back in, taking outer boundaries // into account #if 0 assert (send.is_contained_in(extrf)); #endif boxes.at(rl).at(c).at(ml-1).send_mg_coarse.push_back(send); boxes.at(rl).at(c).at(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 (intr.empty() || ! recv.empty()); const ibbox send = recv.expanded_for(extr); assert (intr.empty() || ! send.empty()); boxes.at(rl).at(c).at(ml-1).recv_mg_coarse.push_back(recv); boxes.at(rl).at(c).at(ml ).send_mg_fine .push_back(send); } } // if not finest multigrid level } // for ml } // for c } // for rl for (int rl=0; rlbegin(); li!=lvi->end(); ++li) { recvs -= *li; } } recvs.normalize(); 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.at(rl+1).at(cc).at(ml).recv_ref_coarse.at(c ) .push_back(recv); boxes.at(rl ).at(c ).at(ml).send_ref_fine .at(cc) .push_back(send); } } } // for cc } // if not finest refinement level } // for ml } // for c } // for rl for (int rl=0; rlbegin(); li!=lvi->end(); ++li) { pbndsf -= *li; } } pbndsf.normalize(); } // Buffer zones ibset buffers; { for (typename ibset::const_iterator pbi=pbndsf.begin(); pbi!=pbndsf.end(); ++pbi) { buffers |= (*pbi).expand(buffer_width, buffer_width) & extrf; } buffers.normalize(); } // Add boundaries const ibbox maxrecvs = extr.expand(-pss,-pss).contracted_for(extrf); ibset recvs = buffers & maxrecvs; recvs.normalize(); { // Do not prolongate what is already prolongated const iblistvect& rrbc = boxes.at(rl+1).at(cc).at(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 ri = recvs.begin(); ri != recvs.end(); ++ri) { const ibbox & recv = *ri; const ibbox send = recv.expanded_for(extr); assert (! send.empty()); assert (send.is_contained_in(extr)); assert (send.is_contained_in(extr.expand(-pss,-pss))); boxes.at(rl+1).at(cc).at(ml).recv_ref_bnd_coarse.at(c ) .push_back(recv); boxes.at(rl ).at(c ).at(ml).send_ref_bnd_fine .at(cc) .push_back(send); } } } } // for cc } // if not finest refinement level } // for ml } // for c } // for rl for (int rl=0; rlbegin(); li!=lvi->end(); ++li) { sync_not -= *li; recv_not -= *li; } } // Subtract boxes received during prolongation const iblistvect& recv_ref_bnd_coarse = boxes.at(rl).at(c).at(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>;