Skip to content

Commit

Permalink
Store the binary partition in structure (NanoComp#1654)
Browse files Browse the repository at this point in the history
* Store the binary partition - whether passed in externally or generated
via `choose_chunkdivision` in `structure` and expose it via a getter.
* Remove the unused default constructor of `structure`.
* Remove a redundant copy constructor of `structure`.
* Clean up the copy constructor `structure`.
* Make `binary_partition` copyable.

Prepares for making the BinaryPartition visible in Python (NanoComp#1648).
  • Loading branch information
ahoenselaar authored Jul 2, 2021
1 parent 43353a4 commit 856f20c
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 61 deletions.
16 changes: 10 additions & 6 deletions src/meep.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -726,18 +726,16 @@ class structure {
int num_effort_volumes;

~structure();
structure();
structure(const grid_volume &gv, material_function &eps,
const boundary_region &br = boundary_region(), const symmetry &s = meep::identity(),
int num_chunks = 0, double Courant = 0.5, bool use_anisotropic_averaging = false,
double tol = DEFAULT_SUBPIXEL_TOL, int maxeval = DEFAULT_SUBPIXEL_MAXEVAL,
const binary_partition *bp = NULL);
const binary_partition *_bp = NULL);
structure(const grid_volume &gv, double eps(const vec &),
const boundary_region &br = boundary_region(), const symmetry &s = meep::identity(),
int num_chunks = 0, double Courant = 0.5, bool use_anisotropic_averaging = false,
double tol = DEFAULT_SUBPIXEL_TOL, int maxeval = DEFAULT_SUBPIXEL_MAXEVAL,
const binary_partition *bp = NULL);
structure(const structure *);
const binary_partition *_bp = NULL);
structure(const structure &);

void set_materials(material_function &mat, bool use_anisotropic_averaging = true,
Expand Down Expand Up @@ -800,19 +798,24 @@ class structure {
std::complex<double> get_mu(const vec &loc, double frequency = 0) const;
double max_eps() const;
double estimated_cost(int process = my_rank());
// Returns the binary partition that was used to partition the volume into chunks. The returned
// pointer is only valid for the lifetime of this `structure` instance.
const binary_partition *get_binary_partition() const;

friend class boundary_region;

private:
void use_pml(direction d, boundary_side b, double dx);
void add_to_effort_volumes(const grid_volume &new_effort_volume, double extra_effort);
void choose_chunkdivision(const grid_volume &gv, int num_chunks, const boundary_region &br,
const symmetry &s, const binary_partition *bp);
const symmetry &s, const binary_partition *_bp);
void check_chunks();
void changing_chunks();
// Helper methods for dumping and loading susceptibilities
void set_chiP_from_file(h5file *file, const char *dataset, field_type ft);
void write_susceptibility_params(h5file *file, const char *dname, int EorH);

std::unique_ptr<binary_partition> bp;
};

// defined in structure.cpp
Expand Down Expand Up @@ -2169,7 +2172,7 @@ struct split_plane {
};

// binary tree class for importing layout of chunk partition
// Moveable but not copyable.
// Moveable and copyable.
class binary_partition {
public:
// Constructs a new leaf node with id `_id`.
Expand All @@ -2179,6 +2182,7 @@ class binary_partition {
// Takes ownership of `left_tree` and `right_tree`.
binary_partition(const split_plane &_split_plane, std::unique_ptr<binary_partition> &&left_tree,
std::unique_ptr<binary_partition> &&right_tree);
binary_partition(const binary_partition& other);

bool is_leaf() const;
// Returns the leaf node ID iff is_leaf() == true.
Expand Down
75 changes: 20 additions & 55 deletions src/structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,46 +30,33 @@ using namespace std;

namespace meep {

structure::structure()
: Courant(0.5), v(D1) // Aaack, this is very hokey.
{
num_chunks = 0;
num_effort_volumes = 0;
effort_volumes = NULL;
effort = NULL;
outdir = ".";
S = identity();
a = 1;
dt = Courant / a;
shared_chunks = false;
}

typedef structure_chunk *structure_chunk_ptr;

structure::structure(const grid_volume &thegv, material_function &eps, const boundary_region &br,
const symmetry &s, int num, double Courant, bool use_anisotropic_averaging,
double tol, int maxeval, const binary_partition *bp)
double tol, int maxeval, const binary_partition *_bp)
: Courant(Courant), v(D1) // Aaack, this is very hokey.
{
outdir = ".";
shared_chunks = false;
if (!br.check_ok(thegv)) meep::abort("invalid boundary absorbers for this grid_volume");
double tstart = wall_time();
choose_chunkdivision(thegv, num, br, s, bp);
choose_chunkdivision(thegv, num, br, s, _bp);
if (verbosity > 0) master_printf("time for choose_chunkdivision = %g s\n", wall_time() - tstart);
set_materials(eps, use_anisotropic_averaging, tol, maxeval);
}

structure::structure(const grid_volume &thegv, double eps(const vec &), const boundary_region &br,
const symmetry &s, int num, double Courant, bool use_anisotropic_averaging,
double tol, int maxeval, const binary_partition *bp)
double tol, int maxeval, const binary_partition *_bp)
: Courant(Courant), v(D1) // Aaack, this is very hokey.
{
outdir = ".";
shared_chunks = false;
if (!br.check_ok(thegv)) meep::abort("invalid boundary absorbers for this grid_volume");
double tstart = wall_time();
choose_chunkdivision(thegv, num, br, s, bp);
choose_chunkdivision(thegv, num, br, s, _bp);
if (verbosity > 0) master_printf("time for choose_chunkdivision = %g s\n", wall_time() - tstart);
if (eps) {
simple_material_function epsilon(eps);
Expand Down Expand Up @@ -108,7 +95,7 @@ static std::unique_ptr<binary_partition> split_by_cost(int n, grid_volume gvol,

void structure::choose_chunkdivision(const grid_volume &thegv, int desired_num_chunks,
const boundary_region &br, const symmetry &s,
const binary_partition *bp) {
const binary_partition *_bp) {

if (thegv.dim == Dcyl && thegv.get_origin().r() < 0) meep::abort("r < 0 origins are not supported");

Expand All @@ -119,13 +106,16 @@ void structure::choose_chunkdivision(const grid_volume &thegv, int desired_num_c
a = gv.a;
dt = Courant / a;

std::unique_ptr<binary_partition> my_bp;
if (!bp) my_bp = meep::choose_chunkdivision(gv, v, desired_num_chunks, s);
if (_bp) {
bp.reset(new binary_partition(*_bp));
} else {
bp = meep::choose_chunkdivision(gv, v, desired_num_chunks, s);
}

// create the chunks:
std::vector<grid_volume> chunk_volumes;
std::vector<int> ids;
split_by_binarytree(gv, chunk_volumes, ids, (!bp) ? my_bp.get() : bp);
split_by_binarytree(gv, chunk_volumes, ids, bp.get());

// initialize effort volumes
num_effort_volumes = 1;
Expand All @@ -141,7 +131,7 @@ void structure::choose_chunkdivision(const grid_volume &thegv, int desired_num_c
num_chunks = 0;
chunks = new structure_chunk_ptr[chunk_volumes.size() * num_effort_volumes];
for (size_t i = 0, stop = chunk_volumes.size(); i < stop; ++i) {
const int proc = (!bp) ? i * count_processors() / chunk_volumes.size() : ids[i] % count_processors();
const int proc = (!_bp) ? i * count_processors() / chunk_volumes.size() : ids[i] % count_processors();
for (int j = 0; j < num_effort_volumes; ++j) {
grid_volume vc;
if (chunk_volumes[i].intersect_with(effort_volumes[j], &vc)) {
Expand Down Expand Up @@ -346,49 +336,21 @@ void structure::add_to_effort_volumes(const grid_volume &new_effort_volume, doub
num_effort_volumes = counter;
}

structure::structure(const structure *s) : v(s->v) {
shared_chunks = false;
num_chunks = s->num_chunks;
outdir = s->outdir;
gv = s->gv;
S = s->S;
user_volume = s->user_volume;
chunks = new structure_chunk_ptr[num_chunks];
for (int i = 0; i < num_chunks; i++)
chunks[i] = new structure_chunk(s->chunks[i]);
num_effort_volumes = s->num_effort_volumes;
effort_volumes = new grid_volume[num_effort_volumes];
effort = new double[num_effort_volumes];
for (int i = 0; i < num_effort_volumes; i++) {
effort_volumes[i] = s->effort_volumes[i];
effort[i] = s->effort[i];
}
a = s->a;
Courant = s->Courant;
dt = s->dt;
}

structure::structure(const structure &s) : v(s.v) {
shared_chunks = false;
num_chunks = s.num_chunks;
outdir = s.outdir;
gv = s.gv;
S = s.S;
user_volume = s.user_volume;
structure::structure(const structure &s)
: num_chunks{s.num_chunks}, shared_chunks{false}, gv(s.gv),
user_volume(s.user_volume), a{s.a}, Courant{s.Courant}, dt{s.dt}, v(s.v), S(s.S),
outdir(s.outdir), num_effort_volumes{s.num_effort_volumes},
bp(new binary_partition(*s.bp)) {
chunks = new structure_chunk_ptr[num_chunks];
for (int i = 0; i < num_chunks; i++) {
chunks[i] = new structure_chunk(s.chunks[i]);
}
num_effort_volumes = s.num_effort_volumes;
effort_volumes = new grid_volume[num_effort_volumes];
effort = new double[num_effort_volumes];
for (int i = 0; i < num_effort_volumes; i++) {
effort_volumes[i] = s.effort_volumes[i];
effort[i] = s.effort[i];
}
a = s.a;
Courant = s.Courant;
dt = s.dt;
}

structure::~structure() {
Expand Down Expand Up @@ -1049,4 +1011,7 @@ std::vector<int> structure::get_chunk_owners() const {
}
return result;
}

const binary_partition *structure::get_binary_partition() const { return bp.get(); }

} // namespace meep
7 changes: 7 additions & 0 deletions src/structure_dump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,13 @@ binary_partition::binary_partition(const split_plane &_split_plane,
if (!left || !right) { meep::abort("Binary partition tree is required to be full"); }
}

binary_partition::binary_partition(const binary_partition& other) : proc_id{other.proc_id}, plane{other.plane} {
if (!other.is_leaf()) {
left.reset(new binary_partition(*other.left));
right.reset(new binary_partition(*other.right));
}
}

bool binary_partition::is_leaf() const { return !left && !right; }

int binary_partition::get_proc_id() const {
Expand Down

0 comments on commit 856f20c

Please sign in to comment.