-
Notifications
You must be signed in to change notification settings - Fork 1.2k
MOOSE FMU interface development #30912
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: next
Are you sure you want to change the base?
Changes from all commits
bc92ab5
bc50c46
648aa13
8db6700
361b2f6
7392e33
75ea062
dd21cdf
f7c198b
f251691
4549e6e
5857503
d0bccfe
ef99198
f88136a
b342f1f
22df305
d1b0d77
18bf06a
afb834d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,145 @@ | ||||||
| # MOOSE FMU Interface | ||||||
|
|
||||||
| The `MOOSEFMU` defines the `Moose2FMU` base class which contains the boilerplate needed to wrap a MOOSE simulation as a Functional Mock-up Unit (FMU). Users only need to implement their own `__init__` and `do_step` methods when deriving from `Moose2FMU`. | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what standard did you implement for FMU ? 2? 3? do we have the whole standard implemented or partiaL? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We support FMU 2 standard. The whole standard is implemented by pythonFMU and we use that to build MOOSE FMU |
||||||
|
|
||||||
| ### Initialization Parameters | ||||||
|
|
||||||
| `Moose2FMU` accepts a number of keyword arguments that configure how the | ||||||
| underlying MOOSE simulation is launched and interacted with: | ||||||
|
|
||||||
| - `flag`: Optional flag that is forwarded to the MOOSE input deck. | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how to pass multiple? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is the rules for spaces same as for CLI args? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, this is just pass CLI args to MOOSE control. I can add an example here to show it. I keep all the examples in moose_fmu folder. I can refer that here |
||||||
| - `moose_mpi` / `mpi_num`: Configure MPI launching when running distributed | ||||||
| MOOSE executables. | ||||||
| - `moose_executable` / `moose_inputfile`: Path to the simulation binary and the | ||||||
| input file that should be executed inside the FMU. | ||||||
| - `server_name`: Name of the `MooseControl` server block to connect to. | ||||||
| - `max_retries`: Number of times helper utilities will poll the control server | ||||||
| before aborting. | ||||||
| - `dt_tolerance`: Permitted synchronization tolerance between FMU time and the | ||||||
| MOOSE simulation clock. | ||||||
|
|
||||||
| The class also exposes a ``default_experiment`` that can be customized if the | ||||||
| FMU should advertise a different start/stop time or nominal step size. | ||||||
|
|
||||||
|
|
||||||
| ### Runtime helpers | ||||||
|
|
||||||
| `Moose2FMU` provides a small collection of convenience methods that simplify | ||||||
| interacting with a running MOOSE simulation: | ||||||
|
|
||||||
| - `set_controllable_real` and `set_controllable_vector` push new controllable | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. vectors are controllable now? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In MOOSE web server control, controllable_vector is supported so I just include the option here. Not quiet sure if controllable vector actually used anywhere in the code. Maybe under stochastic tools? Here I just provide APIs we have in MOOSE web server control There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should check, let's get a test |
||||||
| values to the `WebServerControl` system. Values are cached to avoid | ||||||
| redundant updates; pass ``force=True`` to resend a value that was already | ||||||
| applied. | ||||||
| - `sync_with_moose` advances the FMU time until it matches the simulation time | ||||||
| within `dt_tolerance`. Additional synchronization flags can be supplied via | ||||||
| the optional `allowed_flags` argument. | ||||||
| - `ensure_control_listening` verifies the control socket is ready before any | ||||||
| postprocessors or reporters are queried. | ||||||
| - `get_postprocessor_value` and `get_reporter_value` wait for a specific | ||||||
| synchronization flag and return the requested quantity. | ||||||
| - `get_flag_with_retries` normalizes retry logic when polling MOOSE for the | ||||||
| next synchronization flag. | ||||||
|
|
||||||
| Together these helpers reduce the boilerplate needed inside a custom | ||||||
| `do_step` implementation and make it easier to write robust coupling logic. | ||||||
|
|
||||||
| ### Synchronization and data retrieval flags | ||||||
|
|
||||||
| `Moose2FMU` coordinates with the running MOOSE simulation through named | ||||||
| `MooseControl` flags. To simplify typical multiapp workflows the base class | ||||||
| waits for a set of synchronization signals by default: | ||||||
|
|
||||||
| - `INITIAL` and `MULTIAPP_FIXED_POINT_BEGIN` are consumed before attempting to | ||||||
| advance the coupled simulation. `MULTIAPP_FIXED_POINT_BEGIN` is the first flag | ||||||
| raised immediately after the new time step has been computed, so listening | ||||||
| for it gives the FMU the earliest opportunity to synchronize clocks. | ||||||
| - `MULTIAPP_FIXED_POINT_END` is consumed before any reporter or postprocessor | ||||||
| values are retrieved. In a typical execution order controls run ahead of | ||||||
| reporters and postprocessors, and those objects usually execute at | ||||||
| `TIMESTEP_END`. The `MULTIAPP_FIXED_POINT_END` flag fires right after | ||||||
| `TIMESTEP_END`, ensuring the data pulled from MOOSE reflects the updated state | ||||||
| of the current time step. | ||||||
|
|
||||||
| Any flag string supplied through the `flag` initialization argument is merged | ||||||
| into these defaults, and the higher-level helpers such as | ||||||
| `set_controllable_real`, `set_controllable_vector`, `get_reporter_value`, and | ||||||
| `get_postprocessor_value` also accept per-call `flag` arguments. Passing custom | ||||||
| flags in these locations allows FMUs to react to user-defined synchronization | ||||||
| points while still benefiting from the built-in defaults. Refer to | ||||||
| [SetupInterface.md]for additional details on | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| MOOSE execute flags. | ||||||
|
|
||||||
| ### Creating a Custom FMU | ||||||
|
|
||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is there a script you could use a listing from instead? |
||||||
| ```python | ||||||
| from MooseFMU import Moose2FMU | ||||||
|
|
||||||
|
|
||||||
| class CustomMoose(Moose2FMU): | ||||||
| def __init__(self, **kwargs): | ||||||
| super().__init__(**kwargs) | ||||||
| # register additional inputs/outputs here | ||||||
|
|
||||||
| def do_step( | ||||||
| self, | ||||||
| current_time: float, | ||||||
| step_size: float, | ||||||
| no_set_fmu_state_prior: bool = False, | ||||||
| ) -> bool: | ||||||
| # advance the MOOSE simulation and update outputs | ||||||
| return True | ||||||
| ``` | ||||||
|
|
||||||
| A typical step method will synchronize with MOOSE and make use of the helper | ||||||
| utilities described above: | ||||||
|
|
||||||
| ```python | ||||||
| def do_step(self, current_time: float, step_size: float, **_kwargs) -> bool: | ||||||
| moose_time, signal = self.sync_with_moose(current_time, step_size) | ||||||
| if moose_time is None: | ||||||
| return False | ||||||
|
|
||||||
| if signal == "MULTIAPP_FIXED_POINT_END": | ||||||
| diffused = self.get_postprocessor_value(signal, "diffused", current_time) | ||||||
| if diffused is None: | ||||||
| return False | ||||||
| self.diffused = diffused | ||||||
|
|
||||||
| self.set_controllable_real("BCs/boundary", 1.0) | ||||||
| return True | ||||||
| ``` | ||||||
|
|
||||||
| ### Building the FMU | ||||||
|
|
||||||
| Save the custom class in a Python file and use [`pythonfmu`](https://github.com/NTNU-IHB/PythonFMU) to build the FMU: | ||||||
|
|
||||||
| ```bash | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so we dont include this package in our conda distrib? not through fmpy? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We include pythonfmu in conda, but to build a MOOSE fmu customized fmu input, output, you still use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I dont see a pythonfmu new package in conda? |
||||||
| pythonfmu build custom_moose.py | ||||||
| ``` | ||||||
|
|
||||||
| The resulting `.fmu` file can then be imported into any compliant co-simulation environment. | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| ### Testing the FMU | ||||||
|
|
||||||
| Sample helper scripts in `test/tests/controls/moose_fmu` demonstrate how to exercise a | ||||||
| generated FMU with [`fmpy`](https://github.com/CATIA-Systems/FMPy): | ||||||
|
|
||||||
| - `run_fmu.py` runs `MooseTest.fmu` in a stand-alone mode using `simulate_fmu` and | ||||||
| prints the time, `moose_time` and `diffused` outputs. | ||||||
| - `run_fmu_connection.py` shows how to couple `MooseTest.fmu` with another FMU (e.g., | ||||||
| `Dahlquist.fmu`) and change boundary conditions during the simulation. | ||||||
|
|
||||||
| To try the examples: | ||||||
|
|
||||||
| ```bash | ||||||
| cd test/tests/controls/moose_fmu | ||||||
| python run_fmu.py # stand‑alone Moose FMU | ||||||
| python run_fmu_connection.py # coupled FMUs example | ||||||
| ``` | ||||||
|
|
||||||
| !syntax parameters /Controls/MOOSEFMU | ||||||
|
|
||||||
| !syntax inputs /Controls/MOOSEFMU | ||||||
|
|
||||||
|
Comment on lines
+141
to
+144
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I dont see a MOOSEFMU class registered? this shouldt work, what am I missing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch, I'll fix it |
||||||
| !syntax children /Controls/MOOSEFMU | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.