Leaky and Albedo Boundary Conditions Implementation (#2724)

Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
This commit is contained in:
Yuvraj Jain 2023-10-30 20:51:31 +00:00 committed by GitHub
parent 2c1e304892
commit 693314d097
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 376 additions and 82 deletions

View file

@ -28,6 +28,9 @@ void ReflectiveBC::handle_particle(Particle& p, const Surface& surf) const
Direction u = surf.reflect(p.r(), p.u(), &p);
u /= u.norm();
// Handle the effects of the surface albedo on the particle's weight.
BoundaryCondition::handle_albedo(p, surf);
p.cross_reflective_bc(surf, u);
}
@ -40,6 +43,9 @@ void WhiteBC::handle_particle(Particle& p, const Surface& surf) const
Direction u = surf.diffuse_reflect(p.r(), p.u(), p.current_seed());
u /= u.norm();
// Handle the effects of the surface albedo on the particle's weight.
BoundaryCondition::handle_albedo(p, surf);
p.cross_reflective_bc(surf, u);
}
@ -130,6 +136,9 @@ void TranslationalPeriodicBC::handle_particle(
"hitting a surface, but that surface is not recognized by the BC.");
}
// Handle the effects of the surface albedo on the particle's weight.
BoundaryCondition::handle_albedo(p, surf);
// Pass the new location and surface to the particle.
p.cross_periodic_bc(surf, new_r, p.u(), new_surface);
}
@ -264,6 +273,9 @@ void RotationalPeriodicBC::handle_particle(
Direction new_u = {
cos_theta * u.x - sin_theta * u.y, sin_theta * u.x + cos_theta * u.y, u.z};
// Handle the effects of the surface albedo on the particle's weight.
BoundaryCondition::handle_albedo(p, surf);
// Pass the new location, direction, and surface to the particle.
p.cross_periodic_bc(surf, new_r, new_u, new_surface);
}

View file

@ -289,10 +289,10 @@ void DAGUniverse::init_geometry()
bc_value == "transmission") {
// set to transmission by default (nullptr)
} else if (bc_value == "vacuum") {
s->bc_ = std::make_shared<VacuumBC>();
s->bc_ = make_unique<VacuumBC>();
} else if (bc_value == "reflective" || bc_value == "reflect" ||
bc_value == "reflecting") {
s->bc_ = std::make_shared<ReflectiveBC>();
s->bc_ = make_unique<ReflectiveBC>();
} else if (bc_value == "periodic") {
fatal_error("Periodic boundary condition not supported in DAGMC.");
} else {
@ -310,7 +310,7 @@ void DAGUniverse::init_geometry()
// if this surface belongs to the graveyard
if (graveyard && parent_vols.find(graveyard) != parent_vols.end()) {
// set graveyard surface BC's to vacuum
s->bc_ = std::make_shared<VacuumBC>();
s->bc_ = make_unique<VacuumBC>();
}
// add to global array and map

View file

@ -80,19 +80,36 @@ Surface::Surface(pugi::xml_node surf_node)
if (surf_bc == "transmission" || surf_bc == "transmit" || surf_bc.empty()) {
// Leave the bc_ a nullptr
} else if (surf_bc == "vacuum") {
bc_ = std::make_shared<VacuumBC>();
bc_ = make_unique<VacuumBC>();
} else if (surf_bc == "reflective" || surf_bc == "reflect" ||
surf_bc == "reflecting") {
bc_ = std::make_shared<ReflectiveBC>();
bc_ = make_unique<ReflectiveBC>();
} else if (surf_bc == "white") {
bc_ = std::make_shared<WhiteBC>();
bc_ = make_unique<WhiteBC>();
} else if (surf_bc == "periodic") {
// periodic BC's are handled separately
// Periodic BCs are handled separately
} else {
fatal_error(fmt::format("Unknown boundary condition \"{}\" specified "
"on surface {}",
surf_bc, id_));
}
if (check_for_node(surf_node, "albedo") && bc_) {
double surf_alb = std::stod(get_node_value(surf_node, "albedo"));
if (surf_alb < 0.0)
fatal_error(fmt::format("Surface {} has an albedo of {}. "
"Albedo values must be positive.",
id_, surf_alb));
if (surf_alb > 1.0)
warning(fmt::format("Surface {} has an albedo of {}. "
"Albedos greater than 1 may cause "
"unphysical behaviour.",
id_, surf_alb));
bc_->set_albedo(surf_alb);
}
}
}
@ -154,6 +171,7 @@ void Surface::to_hdf5(hid_t group_id) const
if (bc_) {
write_string(surf_group, "boundary_type", bc_->type(), false);
bc_->to_hdf5(surf_group);
} else {
write_string(surf_group, "boundary_type", "transmission", false);
}
@ -1156,9 +1174,10 @@ void read_surfaces(pugi::xml_node node)
}
// Loop over XML surface elements and populate the array. Keep track of
// periodic surfaces.
// periodic surfaces and their albedos.
model::surfaces.reserve(n_surfaces);
std::set<std::pair<int, int>> periodic_pairs;
std::unordered_map<int, double> albedo_map;
{
pugi::xml_node surf_node;
int i_surf;
@ -1221,6 +1240,12 @@ void read_surfaces(pugi::xml_node node)
if (check_for_node(surf_node, "boundary")) {
std::string surf_bc = get_node_value(surf_node, "boundary", true, true);
if (surf_bc == "periodic") {
// Check for surface albedo. Skip sanity check as it is already done
// in the Surface class's constructor.
if (check_for_node(surf_node, "albedo")) {
albedo_map[model::surfaces.back()->id_] =
std::stod(get_node_value(surf_node, "albedo"));
}
if (check_for_node(surf_node, "periodic_surface_id")) {
int i_periodic =
std::stoi(get_node_value(surf_node, "periodic_surface_id"));
@ -1284,7 +1309,7 @@ void read_surfaces(pugi::xml_node node)
periodic_pairs.erase(second_unresolved);
}
// Assign the periodic boundary conditions
// Assign the periodic boundary conditions with albedos
for (auto periodic_pair : periodic_pairs) {
int i_surf = model::surface_map[periodic_pair.first];
int j_surf = model::surface_map[periodic_pair.second];
@ -1302,11 +1327,19 @@ void read_surfaces(pugi::xml_node node)
// planes are parallel which indicates a translational periodic boundary
// condition. Otherwise, it is a rotational periodic BC.
if (std::abs(1.0 - dot_prod) < FP_PRECISION) {
surf1.bc_ = std::make_shared<TranslationalPeriodicBC>(i_surf, j_surf);
surf2.bc_ = surf1.bc_;
surf1.bc_ = make_unique<TranslationalPeriodicBC>(i_surf, j_surf);
surf2.bc_ = make_unique<TranslationalPeriodicBC>(i_surf, j_surf);
} else {
surf1.bc_ = std::make_shared<RotationalPeriodicBC>(i_surf, j_surf);
surf2.bc_ = surf1.bc_;
surf1.bc_ = make_unique<RotationalPeriodicBC>(i_surf, j_surf);
surf2.bc_ = make_unique<RotationalPeriodicBC>(i_surf, j_surf);
}
// If albedo data is present in albedo map, set the boundary albedo.
if (albedo_map.count(surf1.id_)) {
surf1.bc_->set_albedo(albedo_map[surf1.id_]);
}
if (albedo_map.count(surf2.id_)) {
surf2.bc_->set_albedo(albedo_map[surf2.id_]);
}
}
}