Skip to content

Commit

Permalink
SimConf now knows abour RBCs and have a special builder for that
Browse files Browse the repository at this point in the history
  • Loading branch information
rupertnash committed Jan 31, 2023
1 parent 517b91c commit 48f1f8c
Show file tree
Hide file tree
Showing 73 changed files with 2,161 additions and 2,252 deletions.
2 changes: 1 addition & 1 deletion Code/SimulationMaster.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ namespace hemelb
std::shared_ptr<reporting::Reporter> reporter;
reporting::BuildInfo build_info;

std::optional<lb::SimulationState> simulationState;
std::shared_ptr<lb::SimulationState> simulationState;

/** Struct containing the configuration of various checkers/testers */
std::shared_ptr<lb::StabilityTester<latticeType>> stabilityTester;
Expand Down
7 changes: 0 additions & 7 deletions Code/SimulationMaster.impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,6 @@
# include "colloids/ColloidController.h"
#endif

#ifdef HEMELB_BUILD_RBC
# include "redblood/CellController.h"
# include "redblood/FaderCell.h"
# include "redblood/MeshIO.h"
# include "redblood/RBCConfig.h"
#endif

namespace hemelb
{
/**
Expand Down
137 changes: 38 additions & 99 deletions Code/configuration/SimBuilder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "geometry/GeometryReader.h"
#include "lb/InitialCondition.h"
#include "redblood/FlowExtension.h"
#include "reporting/Reporter.h"
#include "util/variant.h"

Expand All @@ -23,20 +24,21 @@ namespace hemelb::configuration {
);
}

SimBuilder::SimBuilder(configuration::SimConfig const& conf) :
config(conf),
unit_converter(build_unit_converter(conf.sim_info))
SimBuilder::SimBuilder(configuration::SimConfig const& conf, bool construct_unit_converter) :
config(conf)
{

if (construct_unit_converter)
unit_converter = build_unit_converter(conf.sim_info);
}

util::UnitConverter const& SimBuilder::GetUnitConverter() const {
return *unit_converter;
std::shared_ptr<util::UnitConverter const> SimBuilder::GetUnitConverter() const {
return unit_converter;
}

lb::SimulationState SimBuilder::BuildSimulationState() const {
return {config.GetTimeStepLength(), config.GetTotalTimeSteps()};
std::shared_ptr<lb::SimulationState> SimBuilder::BuildSimulationState() const {
return std::make_shared<lb::SimulationState>(config.GetTimeStepLength(), config.GetTotalTimeSteps());
}

geometry::GmyReadResult SimBuilder::ReadGmy(lb::lattices::LatticeInfo const& lat_info, reporting::Timers& timings, net::IOCommunicator& ioComms) const {
geometry::GeometryReader reader(lat_info,
timings,
Expand Down Expand Up @@ -157,6 +159,19 @@ namespace hemelb::configuration {
{
obj->SetPosition(unit_converter->ConvertPositionToLatticeUnits(conf.position));
obj->SetNormal(conf.normal);
if (conf.flow_extension.has_value()) {
obj->SetFlowExtension(BuildFlowExtension(conf.flow_extension.value()));
}
}

std::shared_ptr<redblood::FlowExtension> SimBuilder::BuildFlowExtension(FlowExtensionConfig const& conf) const {
return std::make_shared<redblood::FlowExtension>(
conf.normal,
unit_converter->ConvertPositionToLatticeUnits(conf.origin_m),
unit_converter->ConvertDistanceToLatticeUnits(conf.length_m),
unit_converter->ConvertDistanceToLatticeUnits(conf.radius_m),
unit_converter->ConvertDistanceToLatticeUnits(conf.fadelength_m)
);
}

std::shared_ptr<hemelb::net::IteratedAction> SimBuilder::BuildColloidController() const {
Expand Down Expand Up @@ -192,97 +207,21 @@ namespace hemelb::configuration {
return {};
}

std::shared_ptr<net::IteratedAction> SimBuilder::BuildCellController() const {
if (config.HasRBCSection())
{
#ifdef HEMELB_BUILD_RBC
auto rbcConfig = simConfig->GetRBCConfig();
hemelb::redblood::CellContainer cells;
typedef hemelb::redblood::CellController<Traits> Controller;
auto const controller = std::make_shared<Controller>(*fieldData,
cells,
rbcConfig->GetRBCMeshes(),
timings,
rbcConfig->GetBoxSize(),
rbcConfig->GetCell2Cell(),
rbcConfig->GetCell2Wall(),
ioComms);
controller->SetCellInsertion(rbcConfig->GetInserter());
controller->SetOutlets(*rbcConfig->GetRBCOutlets());
cellController = std::static_pointer_cast<hemelb::net::IteratedAction>(controller);

auto output_callback =
[this](const hemelb::redblood::CellContainer & cells)
{
auto rbcConfig = simConfig->GetRBCConfig();
auto timestep = simulationState->Get0IndexedTimeStep();
if ((timestep % rbcConfig->GetRBCOutputPeriod()) == 0)
{
log::Logger::Log<log::Info, log::OnePerCore>("printstep %d, num cells %d", timestep, cells.size());

// Create output directory for current writing step. Requires syncing to
// ensure no process goes ahead before directory is created.
std::string rbcOutputDir;
try
{
rbcOutputDir = fileManager->GetRBCOutputPathWithSubdir(std::to_string(timestep));
}
catch(Exception& e)
{
std::stringstream message;
message << e.what() << std::endl
<< "Error " << errno << ": " << std::strerror(errno);
log::Logger::Log<log::Critical, log::OnePerCore>(message.str());
ioComms.Abort(-1);
exit(-1);
}
ioComms.Barrier();

for (auto cell : cells)
{
std::stringstream filename;
filename << rbcOutputDir << cell->GetTag() << "_t_" << timestep << ".vtp";

std::shared_ptr<redblood::CellBase> cell_base;
auto fader_cell_cast = std::dynamic_pointer_cast<redblood::FaderCell>(cell);
if(fader_cell_cast)
{
cell_base = fader_cell_cast->GetWrapeeCell();
}
else
{
cell_base = cell;
}
auto cell_cast = std::dynamic_pointer_cast<redblood::Cell>(cell_base);
assert(cell_cast);
auto meshio = redblood::VTKMeshIO{};
meshio.writeFile(filename.str(), *cell_cast, *unitConverter);
}
}
};
controller->AddCellChangeListener(output_callback);
#else
throw hemelb::Exception() << "Trying to create red blood cell controller with HEMELB_BUILD_RBC=OFF";
#endif
}
return {};
}

template <typename F>
struct transformer {
F func;

transformer(F&& f) : func{f} {}

template <template <typename...> class ContainerT, typename V, typename... ARGS>
//requires std::invocable<F, V const&>
auto operator()(ContainerT<V, ARGS...>const & c) {
using R = std::invoke_result_t<F, V const&>;
ContainerT<R> ans;
std::transform(c.begin(), c.end(), std::back_inserter(ans), func);
return ans;
}
};
// template <typename F>
// struct transformer {
// F func;
//
// transformer(F&& f) : func{f} {}
//
// template <template <typename...> class ContainerT, typename V, typename... ARGS>
// //requires std::invocable<F, V const&>
// auto operator()(ContainerT<V, ARGS...>const & c) {
// using R = std::invoke_result_t<F, V const&>;
// ContainerT<R> ans;
// std::transform(c.begin(), c.end(), std::back_inserter(ans), func);
// return ans;
// }
// };

std::shared_ptr<extraction::PropertyActor> SimBuilder::BuildPropertyExtraction(
std::filesystem::path const& xtr_path,
Expand Down
82 changes: 66 additions & 16 deletions Code/configuration/SimBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,20 @@
#include "lb/InitialCondition.h"
#include "lb/StabilityTester.h"
#include "lb/IncompressibilityChecker.hpp"
#include "lb/iolets/BoundaryValues.h"
#include "net/PhasedBroadcastRegular.h"
#include "net/phased/StepManager.h"
#include "net/phased/NetConcern.h"
#include "reporting/Timers.h"
#include "util/clone_ptr.h"
#include "util/UnitConverter.h"

#ifdef HEMELB_BUILD_RBC
#include "redblood/CellControllerBuilder.h"
#endif

namespace hemelb::extraction { class PropertyActor; }
namespace hemelb::lb::iolets {
class BoundaryValues;
class InOutLet;
}
namespace hemelb::net {
Expand All @@ -36,23 +40,20 @@ namespace hemelb::reporting {

namespace hemelb::configuration {

class LbmBuilder {

};
// This class converters the SimConfig into a ready-to-run simulation.
class SimBuilder {
public:
using IoletPtr = util::clone_ptr<lb::iolets::InOutLet>;

protected:
configuration::SimConfig config;
SimConfig config;
std::shared_ptr<util::UnitConverter> unit_converter;

public:
explicit SimBuilder(SimConfig const& conf);
explicit SimBuilder(SimConfig const& conf, bool construct_unit_converter = true);
virtual ~SimBuilder() = default;

util::UnitConverter const& GetUnitConverter() const;
[[nodiscard]] std::shared_ptr<util::UnitConverter const> GetUnitConverter() const;

template<typename T>
void GetDimensionalValueInLatticeUnits(const io::xml::Element& elem,
Expand All @@ -68,12 +69,12 @@ namespace hemelb::configuration {
return unit_converter->template ConvertToLatticeUnits(units, val);
}

// Fully build the SimulationMaster<T> from the configuration.
// Fully build the T = SimulationMaster<Traits> from the configuration.
template <typename T>
void operator()(T & sim_controller) const;
void operator()(T & control) const;

// The below could probably be protected/private, but handy for testing.
[[nodiscard]] lb::SimulationState BuildSimulationState() const;
[[nodiscard]] std::shared_ptr<lb::SimulationState> BuildSimulationState() const;
[[nodiscard]] geometry::GmyReadResult ReadGmy(
lb::lattices::LatticeInfo const& lat_info,
reporting::Timers& timings,
Expand All @@ -91,9 +92,11 @@ namespace hemelb::configuration {
[[nodiscard]] IoletPtr BuildWomersleyVelocityIolet(WomersleyVelocityIoletConfig const&) const;
[[nodiscard]] IoletPtr BuildFileVelocityIolet(FileVelocityIoletConfig const&) const;
void BuildBaseIolet(IoletConfigBase const& conf, lb::iolets::InOutLet* obj) const;
[[nodiscard]] std::shared_ptr<redblood::FlowExtension> BuildFlowExtension(FlowExtensionConfig const& conf) const;

[[nodiscard]] std::shared_ptr<net::IteratedAction> BuildColloidController() const;
[[nodiscard]] std::shared_ptr<net::IteratedAction> BuildCellController() const;
template <typename T>
[[nodiscard]] std::shared_ptr<net::IteratedAction> BuildCellController(T const& control, reporting::Timers& timings) const;
[[nodiscard]] lb::InitialCondition BuildInitialCondition() const;
[[nodiscard]] std::shared_ptr<extraction::PropertyActor> BuildPropertyExtraction(
std::filesystem::path const& xtr_path,
Expand All @@ -111,9 +114,11 @@ namespace hemelb::configuration {

template <typename T>
void SimBuilder::operator()(T& control) const {
using traitsType = typename T::Traits;
using latticeType = typename T::latticeType;

auto& timings = control.timings;
auto& ioComms = control.ioComms;
using latticeType = typename T::latticeType;
auto& lat_info = latticeType::GetLatticeInfo();

control.unitConverter = unit_converter;
Expand Down Expand Up @@ -155,7 +160,7 @@ namespace hemelb::configuration {
log::Logger::Log<log::Info, log::Singleton>("Initialising LBM.");
auto lbm =
control.latticeBoltzmannModel =
std::make_shared<lb::LBM<typename T::Traits>>(
std::make_shared<lb::LBM<traitsType>>(
BuildLbmParams(),
&control.communicationNet,
control.fieldData.get(),
Expand All @@ -165,13 +170,12 @@ namespace hemelb::configuration {
);

maybe_register_actor(control.colloidController = BuildColloidController(), 1);
maybe_register_actor(control.cellController = BuildCellController(), 1);

maybe_register_actor(lbm, 1);

control.inletValues = std::make_shared<lb::iolets::BoundaryValues>(
geometry::INLET_TYPE,
control.domainData.get(),
*control.domainData,
BuildIolets(config.GetInlets()),
&*control.simulationState,
ioComms,
Expand All @@ -181,14 +185,16 @@ namespace hemelb::configuration {

control.outletValues = std::make_shared<lb::iolets::BoundaryValues>(
geometry::OUTLET_TYPE,
control.domainData.get(),
*control.domainData,
BuildIolets(config.GetOutlets()),
&*control.simulationState,
ioComms,
*unit_converter
);
maybe_register_actor(control.outletValues, 1);

maybe_register_actor(control.cellController = BuildCellController<T>(control, timings), 1);

// Copy cos about to scale to lattice units.
auto mon_conf = config.GetMonitoringConfiguration();
if (std::holds_alternative<extraction::source::Velocity>(mon_conf.convergenceVariable)) {
Expand Down Expand Up @@ -259,5 +265,49 @@ namespace hemelb::configuration {
}
control.stepManager->RegisterCommsForAllPhases(*control.netConcern);
}

#ifdef HEMELB_BUILD_RBC
inline redblood::CountedIoletView MakeCountedIoletView(lb::iolets::BoundaryValues const& iolets) {
return {
[&]() { return iolets.GetGlobalIoletCount(); },
[&](unsigned i) { return iolets.GetGlobalIolet(i); }
};
}
inline redblood::CountedIoletView MakeCountedIoletView(std::vector<SimBuilder::IoletPtr> const& iolets) {
return {
[&]() { return iolets.size(); },
[&](unsigned i) { return iolets[i].get(); }
};
}
#endif

template <typename T>
[[nodiscard]] std::shared_ptr<net::IteratedAction> SimBuilder::BuildCellController(T const& control, reporting::Timers& timings) const {
if (config.HasRBCSection()) {
#ifdef HEMELB_BUILD_RBC
using traitsType = typename T::Traits;

auto ccb = redblood::CellControllerBuilder(unit_converter);

auto& ioComms = control.ioComms;

auto inlets = MakeCountedIoletView(*control.inletValues);
auto outlets = MakeCountedIoletView(*control.outletValues);

return ccb.build<traitsType>(
config,
timings, ioComms,
control.fieldData,
inlets,
outlets,
control.simulationState,
control.fileManager
);
#else
throw hemelb::Exception() << "Trying to create red blood cell controller with HEMELB_BUILD_RBC=OFF";
#endif
}
return {};
}
}
#endif
Loading

0 comments on commit 48f1f8c

Please sign in to comment.