aboutsummaryrefslogtreecommitdiff
path: root/Carpet
diff options
context:
space:
mode:
Diffstat (limited to 'Carpet')
-rw-r--r--Carpet/CarpetLib/src/dh.cc79
-rw-r--r--Carpet/CarpetLib/src/dh.hh12
-rw-r--r--Carpet/CarpetLib/src/ggf.cc132
-rw-r--r--Carpet/CarpetLib/src/ggf.hh5
4 files changed, 142 insertions, 86 deletions
diff --git a/Carpet/CarpetLib/src/dh.cc b/Carpet/CarpetLib/src/dh.cc
index 2895ac881..08fe03722 100644
--- a/Carpet/CarpetLib/src/dh.cc
+++ b/Carpet/CarpetLib/src/dh.cc
@@ -64,8 +64,9 @@ void dh::regrid ()
static Timer total ("dh::regrid");
total.start ();
- boxes.clear();
-
+ oldboxes.clear();
+ swap (boxes, oldboxes);
+
{
static Timer timer ("dh::regrid::allocate_bboxes");
timer.start ();
@@ -125,6 +126,12 @@ void dh::regrid ()
foreach_reflevel_component_mglevel (&dh::trim_unsynced_boundaries);
timer.stop (0);
}
+ {
+ static Timer timer ("dh::regrid::setup_old2new");
+ timer.start ();
+ foreach_reflevel_component_mglevel (&dh::setup_old2new);
+ timer.stop (0);
+ }
{
static Timer timer ("dh::regrid::optimise_fields");
@@ -193,6 +200,10 @@ void dh::recompose (const int rl, const bool do_prolongate)
(*f)->recompose_free_old (rl);
timer.stop (0);
}
+ // Omit prolongation and synchronisation. This is supposed to
+ // happen in the postregrid bin as part of the boundary conditions
+ // which are applied there.
+#if 0
{
static Timer timer ("dh::recompose::bnd_prolongate");
timer.start ();
@@ -209,6 +220,7 @@ void dh::recompose (const int rl, const bool do_prolongate)
}
timer.stop (0);
}
+#endif
} // for all grid functions of same vartype
total.stop (0);
@@ -711,6 +723,62 @@ void dh::trim_unsynced_boundaries (dh::dboxes & box,
void
dh::
+setup_old2new (dh::dboxes & box,
+ int const rl, int const c, int const ml)
+{
+ // Find out which regions need to be prolongated
+ // (Copy the exterior because some variables are not prolongated)
+
+ if (oldboxes.empty()) return;
+
+ ibset work = box.exterior;
+
+ // Copy from old storage, if possible
+ // TODO: copy only from interior regions?
+ if (rl < (int)oldboxes.AT(ml).size()) {
+ for (int cc = 0; cc < (int)oldboxes.AT(ml).AT(rl).size(); ++ cc) {
+ // TODO: prefer same processor, etc.
+ ibset ovlp = work & oldboxes.AT(ml).AT(rl).AT(cc).exterior;
+ ovlp.normalize();
+ work -= ovlp;
+ for (ibset::const_iterator ri = ovlp.begin(); ri != ovlp.end(); ++ ri) {
+ box.old2new_recv_sync.AT(cc).push_back (* ri);
+ }
+ } // for cc
+ } // if rl
+
+ // Initialise from coarser level, if possible
+ if (rl>0) {
+ for (int cc=0; cc<(int)boxes.AT(ml).AT(rl-1).size(); ++cc) {
+
+ // TODO: choose larger regions first
+ // TODO: prefer regions from the same processor
+ iblist const & clist = box.recv_ref_coarse.AT(cc);
+ ibset cset;
+ for (iblist::const_iterator
+ iter = clist.begin();iter != clist.end(); ++iter)
+ {
+ cset += * iter;
+ }
+ ibset ovlp = work & cset;
+ ovlp.normalize();
+ work -= ovlp;
+ for (ibset::const_iterator ri = ovlp.begin(); ri != ovlp.end(); ++ ri) {
+ box.old2new_recv_ref_coarse.AT(cc).push_back (* ri);
+ }
+ } // for cc
+ } // if rl
+
+ // Note that work need not be empty here; in this case, not
+ // everything could be initialised. This is okay on outer
+ // boundaries.
+ // TODO: check this.
+}
+
+
+
+void
+dh::
optimise_field (dboxes & box,
iblistvect const dboxes::* const field,
pvect dboxes::* const field_fast,
@@ -737,13 +805,14 @@ optimise_field (dboxes & box,
void
dh::
-optimise_fields (dboxes & box,
- int const rl, int const c, int const ml)
+optimise_fields (dboxes & box, int const rl, int const c, int const ml)
{
optimise_field (box, &dboxes::recv_ref_fine, &dboxes::recv_ref_fine_fast, rl, c, ml);
optimise_field (box, &dboxes::recv_ref_coarse, &dboxes::recv_ref_coarse_fast, rl, c, ml);
optimise_field (box, &dboxes::recv_sync, &dboxes::recv_sync_fast, rl, c, ml);
optimise_field (box, &dboxes::recv_ref_bnd_coarse, &dboxes::recv_ref_bnd_coarse_fast, rl, c, ml);
+ optimise_field (box, &dboxes::old2new_recv_sync, &dboxes::old2new_recv_sync_fast, rl, c, ml);
+ optimise_field (box, &dboxes::old2new_recv_ref_coarse, &dboxes::old2new_recv_ref_coarse_fast, rl, c, ml);
}
void dh::do_check_bboxes (dh::dboxes & box,
@@ -1157,6 +1226,8 @@ void dh::do_output_bboxes(dh::dboxes & box,
cout << "recv_ref_bnd_coarse=" << box.recv_ref_bnd_coarse << endl;
cout << "sync_not=" << box.sync_not << endl;
cout << "recv_not=" << box.recv_not << endl;
+ cout << "old2new_recv_sync=" << box.old2new_recv_sync << endl;
+ cout << "old2new_recv_ref_coarse=" << box.old2new_recv_ref_coarse << endl;
}
void dh::output_bases ()
diff --git a/Carpet/CarpetLib/src/dh.hh b/Carpet/CarpetLib/src/dh.hh
index ad3024dc1..e0f0749c5 100644
--- a/Carpet/CarpetLib/src/dh.hh
+++ b/Carpet/CarpetLib/src/dh.hh
@@ -91,6 +91,13 @@ public:
ibset recv_not; // not received while syncing or
// prolongating (globally outer
// boundary)
+
+ // Information for regridding, i.e., for copying data from the old
+ // to the new hierarchy
+ iblistvect old2new_recv_sync;
+ pvect old2new_recv_sync_fast;
+ iblistvect old2new_recv_ref_coarse;
+ pvect old2new_recv_ref_coarse_fast;
};
private:
@@ -123,13 +130,14 @@ private:
void prepare_refinement_boundary_prolongation_boxes (dboxes & b, int rl, int c, int ml);
void setup_refinement_boundary_prolongation_boxes (dboxes & b, int rl, int c, int ml);
void setup_refinement_restriction_boxes (dboxes & b, int rl, int c, int ml);
+ void setup_old2new (dboxes & b, int rl, int c, int ml);
+ void trim_unsynced_boundaries (dboxes & b, int rl, int c, int ml);
void optimise_field (dboxes & b,
iblistvect const dboxes::* field,
pvect dboxes::* field_fast,
int rl, int c, int ml);
void optimise_fields (dboxes & b,
int rl, int c, int ml);
- void trim_unsynced_boundaries (dboxes & b, int rl, int c, int ml);
void do_output_bboxes (dboxes & b, int rl, int c, int ml);
void do_check_bboxes (dboxes & b, int rl, int c, int ml);
@@ -152,6 +160,8 @@ public: // should be readonly
mbases bases; // bounding boxes around the grid
// hierarchy
+ mboxes oldboxes; // old grid hierarchy, used during regridding
+
list<ggf*> gfs; // list of all grid functions
public:
diff --git a/Carpet/CarpetLib/src/ggf.cc b/Carpet/CarpetLib/src/ggf.cc
index 2a4e3857f..7c6ed319b 100644
--- a/Carpet/CarpetLib/src/ggf.cc
+++ b/Carpet/CarpetLib/src/ggf.cc
@@ -138,87 +138,55 @@ void ggf::recompose_allocate (const int rl)
} // for ml
}
-void ggf::recompose_fill (comm_state& state, const int rl,
- const bool do_prolongate)
+void ggf::recompose_fill (comm_state & state, int const rl,
+ bool const do_prolongate)
{
// Initialise the new storage
- for (int ml=0; ml<h.mglevels(); ++ml) {
- for (int c=0; c<h.components(rl); ++c) {
- for (int tl=0; tl<timelevels(ml,rl); ++tl) {
-
- // Find out which regions need to be prolongated
- // (Copy the exterior because some variables are not prolongated)
- // TODO: do this once in the dh instead of for each variable here
- ibset work (d.boxes.AT(ml).AT(rl).AT(c).exterior);
-
- // Copy from old storage, if possible
- // TODO: copy only from interior regions?
- if (rl<(int)oldstorage.AT(ml).size()) {
- for (int cc=0; cc<(int)oldstorage.AT(ml).AT(rl).size(); ++cc) {
- // TODO: prefer same processor, etc., see dh.cc
- ibset ovlp
- = work & oldstorage.AT(ml).AT(rl).AT(cc).AT(tl)->extent();
- ovlp.normalize();
- work -= ovlp;
- for (ibset::const_iterator r=ovlp.begin(); r!=ovlp.end(); ++r) {
- storage.AT(ml).AT(rl).AT(c).AT(tl)->copy_from
- (state, oldstorage.AT(ml).AT(rl).AT(cc).AT(tl), *r);
- }
- } // for cc
+ for (int ml = 0; ml < h.mglevels(); ++ ml) {
+
+ int const numtl = timelevels (ml, rl);
+ vector <int> tls (numtl);
+ vector <CCTK_REAL> times (numtl);
+ for (int tl = 0; tl < numtl; ++ tl) {
+ tls.AT(tl) = tl;
+ times.AT(tl) = t.time (tls.AT(tl), rl - 1, ml);
+ }
+
+ for (int c = 0; c < h.components (rl); ++c) {
+
+ // Initialise from the same level of the old hierarchy, where
+ // possible
+ if (rl < (int)oldstorage.AT(ml).size()) {
+ for (int tl = 0; tl < timelevels (ml, rl); ++tl) {
+ copycat (state,
+ tl, rl, c, ml,
+ & dh::dboxes::old2new_recv_sync_fast,
+ tl, rl, ml,
+ & oldstorage);
+ } // for tl
+ } // if rl
+
+ if (do_prolongate) {
+ // Initialise from a coarser level of the new hierarchy, where
+ // possible
+ if (rl > 0) {
+ if (transport_operator != op_none) {
+ for (int tl = 0; tl < timelevels (ml, rl); ++tl) {
+ intercat (state,
+ tl, rl, c, ml,
+ & dh::dboxes::old2new_recv_ref_coarse_fast,
+ tls, rl - 1, ml,
+ times.AT(tl));
+ } // for tl
+ } // if transport_operator
} // if rl
-
- if (do_prolongate) {
- // Initialise from coarser level, if possible
- if (rl>0) {
- if (transport_operator != op_none) {
- const int pos = d.prolongation_order_space;
- const int pot = (transport_operator != op_copy
- ? prolongation_order_time
- : 0);
- const int numtl = pot+1;
- assert (timelevels(ml,rl) >= numtl);
- vector<int> tls(numtl);
- vector<CCTK_REAL> times(numtl);
- for (int i=0; i<numtl; ++i) {
- tls.AT(i) = i;
- times.AT(i) = t.time(tls.AT(i),rl-1,ml);
- }
- for (int cc=0; cc<(int)storage.AT(ml).AT(rl-1).size(); ++cc) {
- vector<const gdata*> gsrcs(numtl);
- for (int i=0; i<numtl; ++i) {
- gsrcs.AT(i) = storage.AT(ml).AT(rl-1).AT(cc).AT(tls.AT(i));
- assert (gsrcs.AT(i)->extent() == gsrcs.AT(0)->extent());
- }
- const CCTK_REAL time = t.time(tl,rl,ml);
-
- // TODO: choose larger regions first
- // TODO: prefer regions from the same processor
- const iblist& list
- = d.boxes.AT(ml).AT(rl).AT(c).recv_ref_coarse.AT(cc);
- for (iblist::const_iterator iter=list.begin();
- iter!=list.end(); ++iter)
- {
- ibset ovlp = work & *iter;
- ovlp.normalize();
- work -= ovlp;
- for (ibset::const_iterator r=ovlp.begin();
- r!=ovlp.end(); ++r)
- {
- storage.AT(ml).AT(rl).AT(c).AT(tl)->interpolate_from
- (state, gsrcs, times, *r, time, pos, pot);
- } // for r
- } // for iter
- } // for cc
- } // if transport_operator
- } // if rl
- } // if do_prolongate
-
- // Note that work need not be empty here; in this case, not
- // everything could be initialised. This is okay on outer
- // boundaries.
- // TODO: check this.
-
- } // for tl
+ } // if do_prolongate
+
+ // Note that work need not be empty here; in this case, not
+ // everything could be initialised. This is okay on outer
+ // boundaries.
+ // TODO: check this.
+
} // for c
} // for ml
}
@@ -236,6 +204,7 @@ void ggf::recompose_free_old (const int rl)
} // for ml
}
+#if 0
void ggf::recompose_bnd_prolongate (comm_state& state, const int rl,
const bool do_prolongate)
{
@@ -273,6 +242,7 @@ void ggf::recompose_sync (comm_state& state, const int rl,
} // for ml
} // if do_prolongate
}
+#endif
@@ -402,7 +372,8 @@ void ggf::copycat (comm_state& state,
void ggf::copycat (comm_state& state,
int tl1, int rl1, int c1, int ml1,
const pvect dh::dboxes::* recv_pvect,
- int tl2, int rl2, int ml2)
+ int tl2, int rl2, int ml2,
+ mdata * const srcstorage_)
{
assert (rl1>=0 and rl1<h.reflevels());
assert (c1>=0 and c1<h.components(rl1));
@@ -411,11 +382,12 @@ void ggf::copycat (comm_state& state,
assert ( ml2<h.mglevels());
assert (rl2>=0 and rl2<h.reflevels());
assert (tl2>=0 and tl2<timelevels(ml2,rl2));
+ mdata & srcstorage = srcstorage_ ? * srcstorage_ : storage;
// walk all components
static Timer copycat1 ("copycat_pvect_1");
copycat1.start ();
gdata * const dst = storage.AT(ml1).AT(rl1).AT(c1).AT(tl1);
- cdata const & srcs = storage.AT(ml2).AT(rl2);
+ cdata const & srcs = srcstorage.AT(ml2).AT(rl2);
pvect const & prs = d.boxes.AT(ml1).AT(rl1).AT(c1).*recv_pvect;
for (pvect::const_iterator ipr=prs.begin(); ipr!=prs.end(); ++ipr) {
pseudoregion const & pr = * ipr;
diff --git a/Carpet/CarpetLib/src/ggf.hh b/Carpet/CarpetLib/src/ggf.hh
index 3e113ee01..8908c30f7 100644
--- a/Carpet/CarpetLib/src/ggf.hh
+++ b/Carpet/CarpetLib/src/ggf.hh
@@ -96,8 +96,10 @@ public:
void recompose_allocate (int rl);
void recompose_fill (comm_state& state, int rl, bool do_prolongate);
void recompose_free_old (int rl);
+#if 0
void recompose_bnd_prolongate (comm_state& state, int rl, bool do_prolongate);
void recompose_sync (comm_state& state, int rl, bool do_prolongate);
+#endif
// Cycle the time levels by rotating the data sets
void cycle (int rl, int c, int ml);
@@ -141,7 +143,8 @@ protected:
void copycat (comm_state& state,
int tl1, int rl1, int c1, int ml1,
const pvect dh::dboxes::* recv_pvect,
- int tl2, int rl2, int ml2);
+ int tl2, int rl2, int ml2,
+ mdata * srcstorage = 0);
// Interpolate a region
void intercat (comm_state& state,