"""
Run a simulation - Step by step
===============================

With interactive execution, OpenGeoSys provides a Python interface that lets you
advance a simulation one step at a time, inspect intermediate results, and react before continuing.
This mechanism underlies what we mean by Co-simulation: the simulation can exchange information with
external analyses or tools during runtime—for example, by dynamically adjusting boundary conditions.
In this guide, we will show how to:

- Step-by-step simulation control
- Inspect simulation status and intermediate results
- Prepare for mesh manipulation examples
  - :ref:`sphx_glr_auto_examples_howto_simulation_plot_200_ogs_interactive_meshes_from_simulator.py`.
  - :ref:`sphx_glr_auto_examples_howto_simulation_plot_250_ogs_interactive_mesh_native.py`.




"""

# %%
# Imports and definitions
# =======================
from ogs import OGSMesh

from ogstools.examples import load_model_liquid_flow_simple

# %%
# Select a Project
# ================
# We will start with a simple liquid flow example and set the OGS execution to interactive.

model = load_model_liquid_flow_simple()
model.execution.interactive = True


# %%
# Initialize the simulation and first step
# ========================================
# Use the same arguments as when calling OGS from command line, a list of
# possible argument are documented under
# https://www.opengeosys.org/docs/userguide/basics/cli-arguments/


# %%
# By constructing a SimulationController object we start OpenGeoSys and it (only!) runs time step 0.
simc_1 = model.controller()

# %%
print(f"The current simulation time is: {simc_1.current_time} s.")
print(f"The end time defined is: {simc_1.end_time} s.")


# %%
# Advance the simulation by a one step
# ====================================
status = simc_1.execute_time_step()
print(f"The current simulation time is: {simc_1.current_time} s.")

# %%
# Basic simulation loop
# =====================
#
# The simulation runs step-by-step until a user specified condition is met.
# This further allows you to **manipulate data arrays associated with the mesh or adapt the logic** inside the loop.

while (
    # Here, the condition is when simulation reaches the end time:
    simc_1.current_time
    < simc_1.end_time
):

    # Add here your specific code with mesh manipulation:
    my_mesh: OGSMesh = simc_1.mesh("domain")
    simc_1.execute_time_step()


# %%
sim = simc_1.run()
print(sim)


# %%
# Advance examples with mesh manipulation
# =======================================
#
# Manipulate the mesh with either
#
# - :ref:`sphx_glr_auto_examples_howto_simulation_plot_200_ogs_interactive_meshes_from_simulator.py`.
# - :ref:`sphx_glr_auto_examples_howto_simulation_plot_250_ogs_interactive_mesh_native.py`.
