Skip to content

Commit

Permalink
Manually test Wflow.jl model
Browse files Browse the repository at this point in the history
  • Loading branch information
sverhoeven committed Oct 15, 2024
1 parent c368b84 commit 873f117
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 9 deletions.
2 changes: 2 additions & 0 deletions RemoteBMI.jl/example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
data
sbm_config.toml
110 changes: 107 additions & 3 deletions RemoteBMI.jl/example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,10 @@ Interact with it using the Python client.
```python
from remotebmi.client.client import RemoteBmiClient
from remotebmi.reserve import reserve_values
import os

client = RemoteBmiClient('http://localhost:50555')
# TODO use placeholder for path
# client.initialize('<absolute path>/heat.toml')
client.initialize('/home/stefanv/git/eWaterCycle/remotebmi/python/heat.toml')
client.initialize(os.getcwd() + '/heat.toml')
client.get_component_name()
'The 2D Heat Equation'
client.update()
Expand All @@ -50,3 +49,108 @@ r = client.get_value('plate_surface__temperature', dest)
r
client.finalize()
```

# Run Wflow.jl

```shell
julia --project=.
]
add Wflow
# Install RemoteBMI
dev ..
<backspace>

# Download a parameter set
# From https://deltares.github.io/Wflow.jl/stable/user_guide/sample_data/#wflow_sbm_data
# with *nc moved to data/input
toml_url = "https://raw.githubusercontent.com/Deltares/Wflow.jl/master/test/sbm_config.toml"
staticmaps = "https://github.com/visr/wflow-artifacts/releases/download/v0.2.9/staticmaps-moselle.nc"
forcing = "https://github.com/visr/wflow-artifacts/releases/download/v0.2.6/forcing-moselle.nc"
instates = "https://github.com/visr/wflow-artifacts/releases/download/v0.2.6/instates-moselle.nc"
# create a "data" directory in the current directory
datadir = joinpath(@__DIR__, "data")
mkpath(datadir)
inputDir = joinpath(datadir, "input")
mkpath(inputDir)
toml_path = joinpath(@__DIR__, "sbm_config.toml")
# download resources to current and data dirs
download(staticmaps, joinpath(inputDir, "staticmaps-moselle.nc"))
download(forcing, joinpath(datadir, "forcing-moselle.nc"))
download(instates, joinpath(inputDir, "instates-moselle.nc"))
download(toml_url, toml_path)

# Run server
using Wflow
import RemoteBMI
port = parse(Int, get(ENV, "BMI_PORT", "50051"))
RemoteBMI.run(Wflow.Model, "0.0.0.0", port)
```

Interact with it using the Python client.

```python
from remotebmi.client.client import RemoteBmiClient
from remotebmi.reserve import reserve_values, reserve_grid_nodes, reserve_grid_edge_nodes, reserve_grid_nodes_per_face, reserve_grid_face_
import numpy as np
import os

client = RemoteBmiClient('http://localhost:50051')
# Change to location of sbm_config.toml
os.chdir('../RemoteBMI.jl/example')
%time client.initialize(os.getcwd() + '/sbm_config.toml')
CPU times: user 3.08 ms, sys: 8 μs, total: 3.09 ms
Wall time: 18.7 s
%time client.update()
CPU times: user 1.45 ms, sys: 78 μs, total: 1.53 ms
Wall time: 7.78 s
%time client.update()
CPU times: user 596 μs, sys: 980 μs, total: 1.58 ms
Wall time: 227 ms
client.get_component_name()
'sbm'
client.get_current_time()
172800.0
client.get_time_units()
's'
client.get_output_var_names()
['vertical.nlayers',
'vertical.n_unsatlayers',
...
'lateral.river.q',
...
'lateral.river.reservoir.evaporation',
'lateral.river.reservoir.actevap']
client.get_var_location('lateral.river.q')
'node'
client.get_var_type('lateral.river.q')
numpy.float64
client.get_var_grid('lateral.river.q')
3
client.get_grid_type(3)
'unstructured'
client.get_grid_rank(3)
2
client.get_grid_size(3)
5809
client.get_grid_shape(3, np.empty(2))
# Method does not exist, which is ok for this grid type
x = client.get_grid_x(3, reserve_grid_nodes(client, 3))
len(x)
5809
y = client.get_grid_y(3, reserve_grid_nodes(client, 3))
len(y)
5809
value = client.get_value('lateral.river.q', reserve_values(client, 'lateral.river.q'))
len(value)
5809
client.get_grid_node_count(3)
5809
client.get_grid_edge_count(3)
5808
client.get_grid_face_count(3)
# Method does not exist, which is ok for this var location
edge_nodes = client.get_grid_edge_nodes(3, reserve_grid_edge_nodes(client, 3))
len(edge_nodes)
11616
client.finalize()
```
6 changes: 3 additions & 3 deletions RemoteBMI.jl/src/RemoteBMI.jl
Original file line number Diff line number Diff line change
Expand Up @@ -124,17 +124,17 @@ function reserve_grid_coords(m, grid::Int64, dim_index::Int8)::Vector{Float64}
end

function get_grid_x(req::HTTP.Request, grid::Int64;)::Vector{Float64}
x = reserve_grid_coords(m, grid, 1)
x = reserve_grid_coords(m, grid, Int8(1))
return BMI.get_grid_x(m, grid, x)
end

function get_grid_y(req::HTTP.Request, grid::Int64;)::Vector{Float64}
y = reserve_grid_coords(m, grid, 2)
y = reserve_grid_coords(m, grid, Int8(2))
return BMI.get_grid_y(m, grid, y)
end

function get_grid_z(req::HTTP.Request, grid::Int64;)::Vector{Float64}
z = reserve_grid_coords(m, grid, 3)
z = reserve_grid_coords(m, grid, Int8(3))
return BMI.get_grid_z(m, grid, z)
end

Expand Down
11 changes: 9 additions & 2 deletions python/remotebmi/client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,15 @@


class RemoteBmiClient(Bmi):
def __init__(self, base_url):
self.client = Client(base_url=base_url)
def __init__(self, base_url, timeout=60 * 60 * 24):
"""RemoteBmiClient constructor
Args:
base_url: Where the remote BMI server is running.
timeout: How long a response can take.
Defaults to 1 day. Set to None to disable timeout.
"""
self.client = Client(base_url=base_url, timeout=timeout)

def __del__(self):
self.client.close()
Expand Down
2 changes: 1 addition & 1 deletion python/remotebmi/reserve.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def reserve_grid_padding(model: Bmi, grid_id: int) -> np.ndarray:
return np.empty(model.get_grid_rank(grid_id), dtype=np.float64)


def reserve_grid_nodes(model: Bmi, grid_id: int, dim_index: int) -> np.ndarray:
def reserve_grid_nodes(model: Bmi, grid_id: int, dim_index: int = 0) -> np.ndarray:
"""Reserve dest for :func:`bmipy.Bmi.get_grid_x`, :func:`bmipy.Bmi.get_grid_y` and :func:`bmipy.Bmi.get_grid_z`
The dim_index goes x,y,z and model.get_grid_shape goes z,y,x or y,x so index is inverted
Expand Down

0 comments on commit 873f117

Please sign in to comment.