aboutsummaryrefslogtreecommitdiff
path: root/Carpet/CarpetEvolutionMask/src/evolution_mask.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Carpet/CarpetEvolutionMask/src/evolution_mask.cc')
-rw-r--r--Carpet/CarpetEvolutionMask/src/evolution_mask.cc223
1 files changed, 223 insertions, 0 deletions
diff --git a/Carpet/CarpetEvolutionMask/src/evolution_mask.cc b/Carpet/CarpetEvolutionMask/src/evolution_mask.cc
new file mode 100644
index 000000000..058fd6277
--- /dev/null
+++ b/Carpet/CarpetEvolutionMask/src/evolution_mask.cc
@@ -0,0 +1,223 @@
+#include <cassert>
+#include <sstream>
+
+#include "cctk.h"
+#include "cctk_Arguments.h"
+#include "cctk_Parameters.h"
+
+#include "carpet.hh"
+
+#include "evolution_mask.hh"
+
+
+
+namespace CarpetEvolutionMask {
+
+ using namespace std;
+ using namespace Carpet;
+
+
+ void
+ CarpetEvolutionMaskSetup (CCTK_ARGUMENTS)
+ {
+ DECLARE_CCTK_PARAMETERS;
+
+ // ask the flesh what the value of carpet::buffer_width is...
+ // this should be fixed at some point...
+
+ CCTK_INT buffer_width = *(CCTK_INT*) CCTK_ParameterGet
+ ("buffer_width","Carpet",0);
+
+ // cout << "buffer width: " << buffer_width << endl;
+
+ if (! is_singlemap_mode()) {
+ CCTK_WARN (0, "This routine may only be called in singlemap mode");
+ }
+
+ if (reflevel > 0) {
+
+ ivect const izero = ivect(0);
+ ivect const ione = ivect(1);
+
+ gh const & hh = *vhh.at(Carpet::map);
+ dh const & dd = *vdd.at(Carpet::map);
+
+ ibbox const & base = hh.bases().at(mglevel).at(reflevel).expand(100,100);
+ ibbox const & coarsebase = hh.bases().at(mglevel).at(reflevel-1).expand(100,100);
+
+ ivect const reffact
+ = spacereffacts.at(reflevel) / spacereffacts.at(reflevel-1);
+ assert (all (reffact == 2));
+
+ // cout << "base: " << base << endl;
+ // cout << "coarsebase: " << coarsebase << endl;
+
+ // Calculate the union of all refined regions
+ ibset refined;
+ for (int c=0; c<hh.components(reflevel); ++c) {
+ ibbox refcomp = hh.extents().at(mglevel).at(reflevel).at(c);;
+ bbvect outer_boundary = hh.outer_boundary(reflevel,c);
+ ivect expand_right, expand_left;
+ for (int d=0;d<dim;d++) {
+ if (outer_boundary[d][0]) {
+ expand_left[d] = 50;
+ } else {
+ expand_left[d] = 0;
+ }
+ if (outer_boundary[d][1]) {
+ expand_right[d] = 50;
+ } else {
+ expand_right[d] = 0;
+ }
+ }
+ // cout << "rl,c,expand_left,expand_right" << " " << reflevel << " " << c
+ // << " " << expand_left << " " << expand_right << endl;
+ refcomp = refcomp.expand(expand_left,expand_right);
+ refined |= refcomp;
+ }
+ refined.normalize();
+
+
+ // cout << "refined: " << refined << endl;
+
+ // calculate inverse set of refined regions on the current level
+ ibset antirefined = base - refined;
+
+
+ // cout << "antirefined: " << antirefined << endl;
+
+ // now make antibase larger
+ // make refined regions SMALLER
+ ivect antishrinkby;
+ for (int d=0; d<dim;d++) {
+ antishrinkby[d] = cctkGH->cctk_nghostzones[d] + buffer_width;
+ }
+ ibset antishrunk;
+ for (ibset::const_iterator bi = antirefined.begin();
+ bi != antirefined.end();
+ ++bi)
+ {
+ antishrunk |= (*bi).expand(antishrinkby, antishrinkby).expanded_for(coarsebase);
+ }
+ antishrunk.normalize();
+
+ // cout << "antishrunk1: " << antishrunk << endl;
+
+ // now cut away dangling edges
+ antishrunk &= coarsebase;
+
+ // cout << "antishrunk2: " << antishrunk << endl;
+
+ // cut holes into coarsebase
+ ibset shrunk = coarsebase - antishrunk;
+
+ // cout << "shrunk: " << shrunk << endl;
+
+ // Calculate the union of all coarse regions
+ ibset parent;
+ for (int c=0; c<hh.components(reflevel-1); ++c) {
+ parent |= hh.extents().at(mglevel).at(reflevel-1).at(c);
+ }
+ parent.normalize();
+
+ // cout << "parent: " << parent << endl;
+
+ // Subtract the refined region
+ ibset notrefined = parent - shrunk;
+ notrefined.normalize();
+
+ // cout << "notrefined: " << notrefined << endl;
+
+ ivect enlargeby;
+ int stencil_size = dd.prolongation_stencil_size();
+ for (int d=0; d<dim;d++) {
+ enlargeby[d] = cctkGH->cctk_nghostzones[d] + buffer_width +
+ stencil_size;
+ }
+ ibset enlarged;
+ for (ibset::const_iterator bi = notrefined.begin();
+ bi != notrefined.end();
+ ++bi)
+ {
+ enlarged |= (*bi).expand(enlargeby, enlargeby);
+ }
+ enlarged.normalize();
+
+ // cout << "enlarged: " << enlarged << endl;
+
+ // Intersect with the original union
+ ibset evolveon = parent & enlarged;
+ evolveon.normalize();
+
+ ibset notevolveon = parent - evolveon;
+ notevolveon.normalize();
+
+ // cout << "notevolveon: " << notevolveon << endl;
+
+ // Set not evolved region on next coarser level
+ {
+ int const oldreflevel = reflevel;
+ int const oldmap = Carpet::map;
+ leave_singlemap_mode (cctkGH);
+ leave_level_mode (cctkGH);
+ enter_level_mode (cctkGH, oldreflevel-1);
+ enter_singlemap_mode (cctkGH, oldmap);
+
+ BEGIN_LOCAL_COMPONENT_LOOP (cctkGH, CCTK_GF) {
+
+ DECLARE_CCTK_ARGUMENTS;
+
+ ibbox const & ext
+ = dd.boxes.at(mglevel).at(reflevel).at(component).exterior;
+
+ for (ibset::const_iterator bi = notevolveon.begin();
+ bi != notevolveon.end();
+ ++bi)
+ {
+
+ ibbox const & box = (*bi) & ext;
+ if (! box.empty()) {
+
+ assert (all ((box.lower() - ext.lower() ) >= 0));
+ assert (all ((box.upper() - ext.lower() + ext.stride()) >= 0));
+ assert (all ((box.lower() - ext.lower() ) % ext.stride() == 0));
+ assert (all ((box.upper() - ext.lower() + ext.stride()) % ext.stride() == 0));
+ ivect const imin = (box.lower() - ext.lower() ) / ext.stride();
+ ivect const imax = (box.upper() - ext.lower() + ext.stride()) / ext.stride();
+ assert (all (izero <= imin));
+ assert (box.empty() || all (imin <= imax));
+ assert (all (imax <= ivect::ref(cctk_lsh)));
+
+ if (verbose) {
+ ostringstream buf;
+ buf << "Setting restricted region on level " << reflevel << " to weight 0: " << imin << ":" << imax-ione;
+ CCTK_INFO (buf.str().c_str());
+ }
+
+ // Set mask in the restricted region to 0
+ assert (dim == 3);
+ for (int k=imin[2]; k<imax[2]; ++k) {
+ for (int j=imin[1]; j<imax[1]; ++j) {
+ for (int i=imin[0]; i<imax[0]; ++i) {
+ int const ind = CCTK_GFINDEX3D (cctkGH, i, j, k);
+ evolution_mask[ind] = 0;
+ }
+ }
+ }
+
+ } // if box not empty
+
+ } // for box
+
+ } END_LOCAL_COMPONENT_LOOP;
+
+ leave_singlemap_mode (cctkGH);
+ leave_level_mode (cctkGH);
+ enter_level_mode (cctkGH, oldreflevel);
+ enter_singlemap_mode (cctkGH, oldmap);
+ }
+
+ } // if reflevel>0
+ }
+
+} // namespace CarpetEvolutionMask