Skip to content

Commit 0fe5b2c

Browse files
UCaromelnicolasaunai
authored andcommitted
usable mhd simulator
updated + tested mhd_state, updated mhd_model revert back my typo on hybrid_tagger fixed typo in test_mhd_state preparing mhd usablevecfield new field initialisation logic Added end of file newline in field_user_initializer.hpp added mhd state fixture wrote test for mhd_state_fixtures added mhd yee grid, modified gridlayout to handle both hybrid and mhd up init_functions MHD solver solver mhd update more solver updates preparing rebase formatting riemann reconstruction quick commit fix solved conflict more solver updates initial branch commit: new architecture for reconstruction + flux computation improved test, fixed some bugs in godunov-fluxes better timing directory creation (#914) safer nu (#911) try fallback for dl on keyerror + ruffage (#916) convenient utils for mpi/hierarchies keep pyattrs on compute_from_hier nan min/max to handle possible nan ghosts (#923) * nan min/max to handle possible nan ghosts * flatten rm atefact file fixed missing template keyword for macos-12 build more explicit unwrapping in godunov fluxes with variadic arguments of unclear size fixed lambda capture problem fixed lambda capture problem added time integration added projection functions for centering, primitive/conservetive converter added projection functions for centering, primitive/conservetive converter solver ref binding in a lambda issue added template deduction guide on for macOS compile on a struct of MHDSolver New approach for template deduction for the struct in MHDSolver added usable ghost cells syntaxe fixes for Werror full boundary conditions in solver changed ghost cells function names to be more consistant with hybrid corrected dummyhierarchy in testmhdsolver (operation on nullptr) MHDMock simulator setup added pybind wrappers and first tests successful orszag-tang test fixed typo fixed typo fixed typo bug fixes (wrong usage of prevIndex nextIndex)
1 parent 7f60f05 commit 0fe5b2c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+5255
-1063
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ perf.*
2222
.vscode
2323
.phare*
2424
PHARE_REPORT.zip
25+
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import numpy as np
2+
3+
def is_scalar(arg):
4+
return not isinstance(arg, (list, tuple)) and not is_nd_array(arg)
5+
6+
def is_nd_array(arg):
7+
return isinstance(arg, np.ndarray)
8+
9+
10+
# converts scalars to array of expected size
11+
# converts lists to arrays
12+
class py_fn_wrapper:
13+
def __init__(self, fn):
14+
self.fn = fn
15+
16+
def __call__(self, *xyz):
17+
args = [np.asarray(arg) for arg in xyz]
18+
ret = self.fn(*args)
19+
if isinstance(ret, list):
20+
ret = np.asarray(ret)
21+
if is_scalar(ret):
22+
ret = np.full(len(args[-1]), ret)
23+
return ret
24+
25+
26+
# Wrap calls to user init functions to turn C++ vectors to ndarrays,
27+
# and returned ndarrays to C++ span
28+
class fn_wrapper(py_fn_wrapper):
29+
def __init__(self, fn):
30+
super().__init__(fn)
31+
32+
def __call__(self, *xyz):
33+
from pyphare.cpp import cpp_etc_lib
34+
35+
# convert numpy array to C++ SubSpan
36+
# couples vector init functions to C++
37+
return cpp_etc_lib().makePyArrayWrapper(super().__call__(*xyz))
38+
39+
40+
def clearDict():
41+
"""
42+
dict may contain dangling references from a previous simulation unless cleared
43+
"""
44+
import pybindlibs.dictator as pp
45+
46+
pp.stop()
47+
48+
def populateDict():
49+
from .global_vars import sim as simulation
50+
import pybindlibs.dictator as pp
51+
52+
def add_int(path, val):
53+
pp.add_int(path, int(val))
54+
55+
def add_double(path, val):
56+
pp.add_double(path, float(val))
57+
58+
add_string = pp.add_string
59+
addInitFunction = getattr(pp, "addInitFunction{:d}".format(simulation.ndim) + "D")
60+
61+
add_double("time_step", simulation.timestep)
62+
add_double("final_time", simulation.final_time)
63+
64+
add_int("nbr_cells/x", simulation.cells[0])
65+
add_double("mesh_size/x", simulation.dl[0])
66+
add_double("origin/x", simulation.origin[0])
67+
68+
if simulation.ndim > 1:
69+
add_int("nbr_cells/y", simulation.cells[1])
70+
add_double("mesh_size/y", simulation.dl[1])
71+
add_double("origin/y", simulation.origin[1])
72+
73+
if simulation.ndim > 2:
74+
add_int("nbr_cells/z", simulation.cells[2])
75+
add_double("mesh_size/z", simulation.dl[2])
76+
add_double("origin/z", simulation.origin[2])
77+
78+
add_double("godunov/resistivity", simulation.eta)
79+
add_double("godunov/hyper_resistivity", simulation.nu)
80+
add_double("godunov/heat_capacity_ratio", simulation.gamma)
81+
add_string("godunov/terms", simulation.terms)
82+
add_double("to_primitive/heat_capacity_ratio", simulation.gamma)
83+
add_double("to_conservative/heat_capacity_ratio", simulation.gamma)
84+
85+
d=simulation.model.model_dict
86+
87+
addInitFunction("density/initializer", fn_wrapper(d["density"]))
88+
addInitFunction("velocity/initializer/x_component", fn_wrapper(d["vx"]))
89+
addInitFunction("velocity/initializer/y_component", fn_wrapper(d["vy"]))
90+
addInitFunction("velocity/initializer/z_component", fn_wrapper(d["vz"]))
91+
addInitFunction("magnetic/initializer/x_component", fn_wrapper(d["bx"]))
92+
addInitFunction("magnetic/initializer/y_component", fn_wrapper(d["by"]))
93+
addInitFunction("magnetic/initializer/z_component", fn_wrapper(d["bz"]))
94+
addInitFunction("pressure/initializer", fn_wrapper(d["p"]))
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
sim = None
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from . import global_vars
2+
3+
class MHDModel(object):
4+
def defaulter(self, input, value):
5+
if input is not None:
6+
import inspect
7+
8+
params = list(inspect.signature(input).parameters.values())
9+
assert len(params)
10+
param_per_dim = len(params) == self.dim
11+
has_vargs = params[0].kind == inspect.Parameter.VAR_POSITIONAL
12+
assert param_per_dim or has_vargs
13+
return input
14+
if self.dim == 1:
15+
return lambda x: value + x * 0
16+
if self.dim == 2:
17+
return lambda x, y: value
18+
if self.dim == 3:
19+
return lambda x, y, z: value
20+
21+
def __init__(self, density=None, vx=None, vy=None, vz=None, bx=None, by=None, bz=None, p=None):
22+
if global_vars.sim is None:
23+
raise RuntimeError("A simulation must be declared before a model")
24+
25+
if global_vars.sim.model is not None:
26+
raise RuntimeError("A model is already created")
27+
28+
self.dim = global_vars.sim.ndim
29+
30+
density = self.defaulter(density, 1.0)
31+
vx = self.defaulter(vx, 1.0)
32+
vy = self.defaulter(vy, 0.0)
33+
vz = self.defaulter(vz, 0.0)
34+
bx = self.defaulter(bx, 1.0)
35+
by = self.defaulter(by, 0.0)
36+
bz = self.defaulter(bz, 0.0)
37+
p = self.defaulter(p, 1.0)
38+
39+
self.model_dict = {}
40+
41+
self.model_dict.update({"density": density, "vx": vx, "vy": vy, "vz": vz, "bx": bx, "by": by, "bz": bz, "p": p})
42+
43+
global_vars.sim.set_model(self)
44+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from . import global_vars
2+
3+
class Simulation(object):
4+
def __init__(self, **kwargs):
5+
if global_vars.sim is not None:
6+
raise RuntimeError("simulation is already created")
7+
8+
global_vars.sim = self
9+
10+
for k, v in kwargs.items():
11+
object.__setattr__(self, k, v)
12+
13+
self.model = None
14+
15+
def set_model(self, model):
16+
self.model = model
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
from . import clearDict
2+
from . import populateDict
3+
4+
def pyMHD():
5+
import importlib
6+
7+
return importlib.import_module("pybindlibs.pyMHD")
8+
9+
def make_cpp_simulator(dim, interp):
10+
import pybindlibs.pyMHD
11+
12+
make_sim = f"make_mhd_mock_simulator_{dim}_{interp}"
13+
return getattr(pyMHD(), make_sim)()
14+
15+
class MHDMockSimulator:
16+
def __init__(self, simulation):
17+
self.cpp_sim = None
18+
self.simulation = simulation
19+
20+
def __del__(self):
21+
self.reset()
22+
23+
def reset(self):
24+
if self.cpp_sim is not None:
25+
clearDict()
26+
self.cpp_sim = None
27+
return self
28+
29+
def initialize(self):
30+
if self.cpp_sim is not None:
31+
raise ValueError(
32+
"Simulator already initialized: requires reset to re-initialize"
33+
)
34+
35+
populateDict()
36+
self.cpp_sim = make_cpp_simulator(
37+
self.simulation.ndim,
38+
self.simulation.order,
39+
)
40+
41+
def _check_init(self):
42+
if self.cpp_sim is None:
43+
self.initialize()
44+
45+
def run(self, filename, dumpfrequency=1):
46+
self._check_init()
47+
self.cpp_sim.advance(filename, dumpfrequency)
48+
return self

res/cmake/test.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ if (test AND ${PHARE_EXEC_LEVEL_MIN} GREATER 0) # 0 = no tests
1717
add_subdirectory(tests/core/data/ion_population)
1818
add_subdirectory(tests/core/data/maxwellian_particle_initializer)
1919
add_subdirectory(tests/core/data/particle_initializer)
20+
add_subdirectory(tests/core/data/mhd_state)
2021
add_subdirectory(tests/core/utilities/box)
2122
add_subdirectory(tests/core/utilities/range)
2223
add_subdirectory(tests/core/utilities/index)

src/amr/messengers/mhd_messenger_info.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#ifndef PHARE_MHD_MESSENGER_INFO_HPP
33
#define PHARE_MHD_MESSENGER_INFO_HPP
44

5+
#include "core/data/vecfield/vecfield.hpp"
56
#include "messenger_info.hpp"
67

78

@@ -12,7 +13,9 @@ namespace amr
1213
{
1314
class MHDMessengerInfo : public IMessengerInfo
1415
{
16+
using VecFieldNames = core::VecFieldNames;
1517
public:
18+
// What is needed here ?
1619
virtual ~MHDMessengerInfo() = default;
1720
};
1821

src/amr/messengers/mhd_messenger_stategy.hpp

Whitespace-only changes.

src/amr/physical_models/mhd_model.hpp

Lines changed: 64 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,60 +16,87 @@
1616

1717

1818

19-
namespace PHARE
19+
namespace PHARE::solver
2020
{
21-
namespace solver
21+
template<typename GridLayoutT, typename VecFieldT, typename AMR_Types, typename Grid_t>
22+
class MHDModel : public IPhysicalModel<AMR_Types>
2223
{
23-
template<typename GridLayoutT, typename VecFieldT, typename AMR_Types, typename Grid_t>
24-
class MHDModel : public IPhysicalModel<AMR_Types>
25-
{
26-
public:
27-
using patch_t = typename AMR_Types::patch_t;
28-
using level_t = typename AMR_Types::level_t;
29-
using Interface = IPhysicalModel<AMR_Types>;
24+
public:
25+
using patch_t = typename AMR_Types::patch_t;
26+
using level_t = typename AMR_Types::level_t;
27+
using Interface = IPhysicalModel<AMR_Types>;
28+
29+
using field_type = typename VecFieldT::field_type;
30+
using gridlayout_type = GridLayoutT;
31+
32+
static const inline std::string model_name = "MHDModel";
33+
static constexpr auto dimension = gridlayout_type::dimension;
34+
using resources_manager_type = amr::ResourcesManager<gridlayout_type, Grid_t>;
35+
36+
core::MHDState<VecFieldT> state;
37+
std::shared_ptr<resources_manager_type> resourcesManager;
38+
39+
virtual void initialize(level_t& level) override;
40+
3041

31-
static const inline std::string model_name = "MHDModel";
32-
static constexpr auto dimension = GridLayoutT::dimension;
33-
using resources_manager_type = amr::ResourcesManager<GridLayoutT, Grid_t>;
42+
virtual void allocate(patch_t& patch, double const allocateTime) override
43+
{
44+
resourcesManager->allocate(state, patch, allocateTime);
45+
}
3446

3547

36-
explicit MHDModel(std::shared_ptr<resources_manager_type> const& _resourcesManager)
37-
: IPhysicalModel<AMR_Types>{model_name}
38-
, resourcesManager{std::move(_resourcesManager)}
39-
{
40-
}
4148

42-
virtual void initialize(level_t& /*level*/) override {}
49+
virtual void
50+
fillMessengerInfo(std::unique_ptr<amr::IMessengerInfo> const& /*info*/) const override
51+
{
52+
}
4353

54+
NO_DISCARD auto setOnPatch(patch_t& patch)
55+
{
56+
return resourcesManager->setOnPatch(patch, *this);
57+
}
58+
59+
explicit MHDModel(PHARE::initializer::PHAREDict const& dict,
60+
std::shared_ptr<resources_manager_type> const& _resourcesManager)
61+
: IPhysicalModel<AMR_Types>{model_name}
62+
, state{dict}
63+
, resourcesManager{std::move(_resourcesManager)}
64+
{
65+
}
4466

45-
virtual void allocate(patch_t& patch, double const allocateTime) override
46-
{
47-
resourcesManager->allocate(state.B, patch, allocateTime);
48-
resourcesManager->allocate(state.V, patch, allocateTime);
49-
}
67+
virtual ~MHDModel() override = default;
5068

5169

70+
//-------------------------------------------------------------------------
71+
// start the ResourcesUser interface
72+
//-------------------------------------------------------------------------
5273

53-
virtual void
54-
fillMessengerInfo(std::unique_ptr<amr::IMessengerInfo> const& /*info*/) const override
55-
{
56-
}
74+
NO_DISCARD bool isUsable() const { return state.isUsable(); }
5775

58-
NO_DISCARD auto setOnPatch(patch_t& patch)
59-
{
60-
return resourcesManager->setOnPatch(patch, *this);
61-
}
76+
NO_DISCARD bool isSettable() const { return state.isSettable(); }
6277

78+
NO_DISCARD auto getCompileTimeResourcesViewList() const { return std::forward_as_tuple(state); }
6379

64-
virtual ~MHDModel() override = default;
80+
NO_DISCARD auto getCompileTimeResourcesViewList() { return std::forward_as_tuple(state); }
6581

66-
core::MHDState<VecFieldT> state;
67-
std::shared_ptr<resources_manager_type> resourcesManager;
68-
};
82+
//-------------------------------------------------------------------------
83+
// ends the ResourcesUser interface
84+
//-------------------------------------------------------------------------
85+
};
6986

87+
template<typename GridLayoutT, typename VecFieldT, typename AMR_Types, typename Grid_t>
88+
void MHDModel<GridLayoutT, VecFieldT, AMR_Types, Grid_t>::initialize(level_t& level)
89+
{
90+
for (auto& patch : level)
91+
{
92+
auto layout = amr::layoutFromPatch<GridLayoutT>(*patch);
93+
auto _ = this->resourcesManager->setOnPatch(*patch, state);
7094

95+
state.initialize(layout);
96+
}
97+
resourcesManager->registerForRestarts(*this);
98+
}
7199

72-
} // namespace solver
73-
} // namespace PHARE
100+
} // namespace PHARE::solver
74101

75102
#endif

0 commit comments

Comments
 (0)