├── .gitignore ├── Project.toml ├── .github └── workflows │ ├── TagBot.yml │ └── ci.yml ├── LICENSE ├── test └── runtests.jl ├── README.md └── src └── BasicModelInterface.jl /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /Manifest.toml 3 | -------------------------------------------------------------------------------- /Project.toml: -------------------------------------------------------------------------------- 1 | name = "BasicModelInterface" 2 | uuid = "59605e27-edc0-445a-b93d-c09a3a50b330" 3 | authors = ["Martijn Visser "] 4 | version = "0.1.1" 5 | 6 | [compat] 7 | julia = "1" 8 | 9 | [extras] 10 | Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" 11 | 12 | [targets] 13 | test = ["Test"] 14 | -------------------------------------------------------------------------------- /.github/workflows/TagBot.yml: -------------------------------------------------------------------------------- 1 | name: TagBot 2 | on: 3 | issue_comment: 4 | types: 5 | - created 6 | workflow_dispatch: 7 | jobs: 8 | TagBot: 9 | if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot' 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: JuliaRegistries/TagBot@v1 13 | with: 14 | token: ${{ secrets.GITHUB_TOKEN }} 15 | ssh: ${{ secrets.DOCUMENTER_KEY }} 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Deltares 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | - push 4 | - pull_request 5 | jobs: 6 | test: 7 | name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} 8 | runs-on: ${{ matrix.os }} 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | version: 13 | - '1.0' 14 | - 'nightly' 15 | os: 16 | - ubuntu-latest 17 | - macOS-latest 18 | - windows-latest 19 | arch: 20 | - x64 21 | steps: 22 | - uses: actions/checkout@v2 23 | - uses: julia-actions/setup-julia@v1 24 | with: 25 | version: ${{ matrix.version }} 26 | arch: ${{ matrix.arch }} 27 | - uses: actions/cache@v1 28 | env: 29 | cache-name: cache-artifacts 30 | with: 31 | path: ~/.julia/artifacts 32 | key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} 33 | restore-keys: | 34 | ${{ runner.os }}-test-${{ env.cache-name }}- 35 | ${{ runner.os }}-test- 36 | ${{ runner.os }}- 37 | - uses: julia-actions/julia-buildpkg@v1 38 | - uses: julia-actions/julia-runtest@v1 39 | -------------------------------------------------------------------------------- /test/runtests.jl: -------------------------------------------------------------------------------- 1 | using Test 2 | using BasicModelInterface 3 | const BMI = BasicModelInterface 4 | 5 | # dummy model structs to test the interface 6 | struct UnknownModel end 7 | 8 | struct KnownModel 9 | waterlevel::Matrix{Float64} 10 | end 11 | 12 | struct MyModel end 13 | 14 | @testset "BasicModelInterface.jl" begin 15 | 16 | @testset "no BMI implementation" begin 17 | # test expected errors for unknown model 18 | @test_throws MethodError BMI.initialize(UnknownModel) 19 | @test_throws MethodError BMI.initialize(UnknownModel, "config_file") 20 | @test_throws MethodError BMI.initialize(UnknownModel, "config_file", "one_too_many") 21 | end 22 | 23 | @testset "some BMI implementation" begin 24 | function BMI.initialize(model::Type{KnownModel}) 25 | KnownModel(ones(3, 4)) 26 | end 27 | 28 | known_model = BMI.initialize(KnownModel) 29 | @test all(isone, known_model.waterlevel) 30 | end 31 | 32 | @testset "interface functions are defined" begin 33 | # not necessarily correct parameters 34 | # only needed to verify that the function is defined, but does not have methods yet 35 | model = MyModel() 36 | time = 1.0 37 | name = "myparam" 38 | dest = zeros(5) 39 | inds = [1, 3, 5] 40 | value = 3.0 41 | grid = 2 42 | spacing = zeros(5) 43 | origin = zeros(2, 5) 44 | x = collect(4:0.1:5) 45 | y = collect(6:0.1:9) 46 | z = collect(10:0.1:13) 47 | edge_nodes = zeros(Int, 2, 5) 48 | face_edges = zeros(Int, 5) 49 | face_nodes = zeros(Int, 5) 50 | nodes_per_face = zeros(Int, 5) 51 | 52 | @test_throws MethodError BMI.initialize(model) 53 | @test_throws MethodError BMI.update(model) 54 | @test_throws MethodError BMI.update_until(model, time) 55 | @test_throws MethodError BMI.finalize(model) 56 | @test_throws MethodError BMI.get_component_name(model) 57 | @test_throws MethodError BMI.get_input_item_count(model) 58 | @test_throws MethodError BMI.get_output_item_count(model) 59 | @test_throws MethodError BMI.get_input_var_names(model) 60 | @test_throws MethodError BMI.get_output_var_names(model) 61 | @test_throws MethodError BMI.get_var_grid(model, name) 62 | @test_throws MethodError BMI.get_var_type(model, name) 63 | @test_throws MethodError BMI.get_var_units(model, name) 64 | @test_throws MethodError BMI.get_var_itemsize(model, name) 65 | @test_throws MethodError BMI.get_var_nbytes(model, name) 66 | @test_throws MethodError BMI.get_var_location(model, name) 67 | @test_throws MethodError BMI.get_current_time(model) 68 | @test_throws MethodError BMI.get_start_time(model) 69 | @test_throws MethodError BMI.get_end_time(model) 70 | @test_throws MethodError BMI.get_time_units(model) 71 | @test_throws MethodError BMI.get_time_step(model) 72 | @test_throws MethodError BMI.get_value(model, name, dest) 73 | @test_throws MethodError BMI.get_value_ptr(model, name) 74 | @test_throws MethodError BMI.get_value_at_indices(model, name, dest, inds) 75 | @test_throws MethodError BMI.set_value(model, name, value) 76 | @test_throws MethodError BMI.set_value_at_indices(model, name, inds, value) 77 | @test_throws MethodError BMI.get_grid_rank(model, grid) 78 | @test_throws MethodError BMI.get_grid_size(model, grid) 79 | @test_throws MethodError BMI.get_grid_type(model, grid) 80 | @test_throws MethodError BMI.get_grid_shape(model, grid) 81 | @test_throws MethodError BMI.get_grid_spacing(model, grid, spacing) 82 | @test_throws MethodError BMI.get_grid_origin(model, grid, origin) 83 | @test_throws MethodError BMI.get_grid_x(model, grid, x) 84 | @test_throws MethodError BMI.get_grid_y(model, grid, y) 85 | @test_throws MethodError BMI.get_grid_z(model, grid, z) 86 | @test_throws MethodError BMI.get_grid_node_count(model, grid) 87 | @test_throws MethodError BMI.get_grid_edge_count(model, grid) 88 | @test_throws MethodError BMI.get_grid_face_count(model, grid) 89 | @test_throws MethodError BMI.get_grid_edge_nodes(model, grid, edge_nodes) 90 | @test_throws MethodError BMI.get_grid_face_edges(model, grid, face_edges) 91 | @test_throws MethodError BMI.get_grid_face_nodes(model, grid, face_nodes) 92 | @test_throws MethodError BMI.get_grid_nodes_per_face(model, grid, nodes_per_face) 93 | end 94 | 95 | end # testset "BasicModelInterface.jl" 96 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BasicModelInterface 2 | 3 | [![Build Status](https://github.com/Deltares/BasicModelInterface.jl/workflows/CI/badge.svg)](https://github.com/Deltares/BasicModelInterface.jl/actions) 4 | 5 | [Basic Model Interface](https://bmi.csdms.io/en/stable/) (BMI) specification for the 6 | [Julia programming language](https://julialang.org/). This package contains all 41 functions 7 | that are part of the BMI 2.0 specification. These functions are declared without any 8 | methods, like so: `function initialize end`. They do have documentation that shows how they 9 | should be used. 10 | 11 | It is up to model specific implementations to extend the functions defined here, adding 12 | methods for their own model type, such as: 13 | 14 | ```julia 15 | import BasicModelInterface as BMI 16 | 17 | # any type you created to represent your model 18 | struct MyModel end 19 | 20 | function BMI.update(model::MyModel)::Nothing 21 | # write MyModel update implementation here 22 | end 23 | ``` 24 | 25 | This package is currently being developed independently of 26 | [Community Surface Dynamics Modeling System](https://csdms.colorado.edu/wiki/Main_Page)(CSDMS). 27 | After it has been proven successful with several Julia BMI implementations, we should 28 | consider proposing CSDMS adoption as well, to join the existing C, C++, Fortran and Python 29 | specifications. 30 | 31 | ## Summary of BMI functions 32 | 33 | Table below taken from https://bmi.csdms.io/en/stable/bmi.spec.html. 34 | 35 | Function | Description 36 | ------------------------|---------------------------------------------------------- 37 | initialize | Perform startup tasks for the model. 38 | update | Advance model state by one time step. 39 | update_until | Advance model state until the given time. 40 | finalize | Perform tear-down tasks for the model. 41 | get_component_name | Name of the model. 42 | get_input_item_count | Count of a model's input variables. 43 | get_output_item_count | Count of a model's output variables. 44 | get_input_var_names | List of a model's input variables. 45 | get_output_var_names | List of a model's output variables. 46 | get_var_grid | Get the grid identifier for a variable. 47 | get_var_type | Get the data type of a variable. 48 | get_var_units | Get the units of a variable. 49 | get_var_itemsize | Get the size (in bytes) of one element of a variable. 50 | get_var_nbytes | Get the total size (in bytes) of a variable. 51 | get_var_location | Get the grid element type of a variable. 52 | get_current_time | Current time of the model. 53 | get_start_time | Start time of the model. 54 | get_end_time | End time of the model. 55 | get_time_units | Time units used in the model. 56 | get_time_step | Time step used in the model. 57 | get_value | Get a copy of values of a given variable. 58 | get_value_ptr | Get a reference to the values of a given variable. 59 | get_value_at_indices | Get variable values at specific locations. 60 | set_value | Set the values of a given variable. 61 | set_value_at_indices | Set the values of a variable at specific locations. 62 | get_grid_rank | Get the number of dimensions of a computational grid. 63 | get_grid_size | Get the total number of elements of a computational grid. 64 | get_grid_type | Get the grid type as a string. 65 | get_grid_shape | Get the dimensions of a computational grid. 66 | get_grid_spacing | Get the spacing between grid nodes. 67 | get_grid_origin | Get the origin of a grid. 68 | get_grid_x | Get the locations of a grid's nodes in dimension 1. 69 | get_grid_y | Get the locations of a grid's nodes in dimension 2. 70 | get_grid_z | Get the locations of a grid's nodes in dimension 3. 71 | get_grid_node_count | Get the number of nodes in the grid. 72 | get_grid_edge_count | Get the number of edges in the grid. 73 | get_grid_face_count | Get the number of faces in the grid. 74 | get_grid_edge_nodes | Get the edge-node connectivity. 75 | get_grid_face_edges | Get the face-edge connectivity. 76 | get_grid_face_nodes | Get the face-node connectivity. 77 | get_grid_nodes_per_face | Get the number of nodes for each face. 78 | 79 | ## Notes and open questions 80 | 81 | This specification is adopted from the [BMI 2.0 Python specification](https://github.com/csdms/bmi-python/blob/v2.0/bmipy/bmi.py). 82 | Instead of Python's class methods, the Julia specification expects a `model` parameter 83 | as the first argument. Julia will dispatch to the right implementation based on the type 84 | of the `model` parameter. 85 | 86 | We do not apply the Julia convention to put a ! after mutating function names, to keep 87 | the function names consistent with the other languages. 88 | 89 | - Time must be a float. 90 | - Grid is an integer grid identifier. 91 | - Units should be string. 92 | 93 | See if we can instead use richer types that keep more information, 94 | yet still convert to the right `Int64`, `Float64`, `String`, etc. 95 | 96 | `get_grid_shape`: Instead of passing in a `Vector` to fill, do not require a shape argument, 97 | and return a `Tuple`, like the `size` function. 98 | 99 | https://bmi.csdms.io/en/stable/bmi.best_practices.html 100 | 101 | > Constructs and features that are natural for the language should be used when implementing 102 | a BMI. BMI strives to be developer-friendly. 103 | 104 | > BMI functions always use flattened, one-dimensional arrays. This avoids any issues stemming 105 | from row/column-major indexing when coupling models written in different languages. It’s the 106 | developer's responsibility to ensure that array information is flattened/redimensionalized 107 | in the correct order. 108 | 109 | From the above and the [get_grid_shape](https://bmi.csdms.io/en/stable/bmi.grid_funcs.html#get-grid-shape) 110 | docs it is not quite clear yet what the correct order is. Flattening a row-array and a 111 | column-major array will result in the same size but different order array. 112 | 113 | > “ij” indexing (as opposed to “xy”) 114 | 115 | Does `i` here stand for the first dimension, regardless of row/column-major indexing? 116 | 117 | > the length of the z-dimension, nz, would be listed first. 118 | 119 | If the z-dimension needs to go first, that means different z at the same xy location will 120 | be close in memory for column-major, and far in memory for row-major. 121 | -------------------------------------------------------------------------------- /src/BasicModelInterface.jl: -------------------------------------------------------------------------------- 1 | module BasicModelInterface 2 | 3 | """ 4 | initialize(::Type{Model}, [config_file::String])::Model 5 | 6 | Perform startup tasks for the model. 7 | 8 | Perform all tasks that take place before entering the model's time 9 | loop, including opening files and initializing the model state. Model 10 | inputs are read from a text-based configuration file, specified by 11 | `config_file`. 12 | 13 | # Arguments 14 | - `Model`: the type of your model, only used for dispatch 15 | - `config_file`: String, optional 16 | The path to the model configuration file. 17 | 18 | # Returns 19 | The initialized model. 20 | 21 | # Example 22 | If your model struct is named `MyModel`, you can implement this 23 | in the following way: 24 | 25 | ```julia 26 | function BMI.initialize(::Type{MyModel}, config_file)::MyModel 27 | ... 28 | m = MyModel(...) 29 | return m 30 | end 31 | ``` 32 | 33 | # Notes 34 | Models should be refactored, if necessary, to use a 35 | configuration file. CSDMS does not impose any constraint on 36 | how configuration files are formatted, although YAML is 37 | recommended. A template of a model's configuration file 38 | with placeholder values is used by the BMI. 39 | """ 40 | function initialize end 41 | 42 | """ 43 | update(model)::Nothing 44 | 45 | Advance model state by one time step. 46 | 47 | Perform all tasks that take place within one pass through the model's 48 | time loop. This typically includes incrementing all of the model's 49 | state variables. If the model's state variables don't change in time, 50 | then they can be computed by the `initialize` method and this 51 | method can return with no action. 52 | """ 53 | function update end 54 | 55 | """ 56 | update_until(model, time::Float64)::Nothing 57 | 58 | Advance model state until the given time. 59 | 60 | The given `time` must be a model time later than the current model time. 61 | """ 62 | function update_until end 63 | 64 | """ 65 | finalize(model)::Nothing 66 | 67 | Perform tear-down tasks for the model. 68 | 69 | Perform all tasks that take place after exiting the model's time 70 | loop. This typically includes deallocating memory, closing files and 71 | printing reports. 72 | """ 73 | function finalize end 74 | 75 | """ 76 | get_component_name(model)::String 77 | 78 | Name of the component. 79 | """ 80 | function get_component_name end 81 | 82 | """ 83 | get_input_item_count(model)::Int 84 | 85 | Count of a model's input variables. 86 | """ 87 | function get_input_item_count end 88 | 89 | """ 90 | get_output_item_count(model)::Int 91 | 92 | Count of a model's output variables. 93 | """ 94 | function get_output_item_count end 95 | 96 | """ 97 | get_input_var_names(model)::Vector{String} 98 | 99 | List of a model's input variables. 100 | 101 | Input variable names must be CSDMS Standard Names, also known 102 | as *long variable names*. 103 | 104 | # Notes 105 | Standard Names enable the CSDMS framework to determine whether 106 | an input variable in one model is equivalent to, or compatible 107 | with, an output variable in another model. This allows the 108 | framework to automatically connect components. 109 | 110 | Standard Names do not have to be used within the model. 111 | """ 112 | function get_input_var_names end 113 | 114 | """ 115 | get_output_var_names(model)::Vector{String} 116 | 117 | List of a model's output variables. 118 | 119 | Output variable names must be CSDMS Standard Names, also known 120 | as *long variable names*. 121 | """ 122 | function get_output_var_names end 123 | 124 | """ 125 | get_var_grid(model, name)::Int 126 | 127 | Get grid identifier integer for the given variable. 128 | 129 | The `name` can be an input or output variable name, a CSDMS Standard Name. 130 | """ 131 | function get_var_grid end 132 | 133 | """ 134 | get_var_type(model, name)::String 135 | 136 | Get data type of the given variable. 137 | 138 | The `name` can be an input or output variable name, a CSDMS Standard Name. 139 | """ 140 | function get_var_type end 141 | 142 | """ 143 | get_var_units(model, name)::String 144 | 145 | Get units of the given variable. 146 | 147 | Standard unit names, in lower case, should be used, such as 148 | ``meters`` or ``seconds``. Standard abbreviations, like ``m`` for 149 | meters, are also supported. For variables with compound units, 150 | each unit name is separated by a single space, with exponents 151 | other than 1 placed immediately after the name, as in ``m s-1`` 152 | for velocity, ``W m-2`` for an energy flux, or ``km2`` for an 153 | area. 154 | 155 | The `name` can be an input or output variable name, a CSDMS Standard Name. 156 | 157 | # Notes 158 | CSDMS uses the [UDUNITS](http://www.unidata.ucar.edu/software/udunits) 159 | standard from Unidata. 160 | """ 161 | function get_var_units end 162 | 163 | """ 164 | get_var_itemsize(model, name)::Int 165 | 166 | Get memory use for each array element in bytes. 167 | 168 | The `name` can be an input or output variable name, a CSDMS Standard Name. 169 | """ 170 | function get_var_itemsize end 171 | 172 | """ 173 | get_var_nbytes(model, name)::Int 174 | 175 | Get size, in bytes, of the given variable. 176 | 177 | The `name` can be an input or output variable name, a CSDMS Standard Name. 178 | """ 179 | function get_var_nbytes end 180 | 181 | """ 182 | get_var_location(model, name)::String 183 | 184 | Get the grid element type that the a given variable is defined on. 185 | 186 | The grid topology can be composed of *nodes*, *edges*, and *faces*. 187 | 188 | - node: A point that has a coordinate pair or triplet: the most 189 | basic element of the topology. 190 | - edge: A line or curve bounded by two nodes. 191 | - face: A plane or surface enclosed by a set of edges. In a 2D 192 | horizontal application one may consider the word "polygon", 193 | but in the hierarchy of elements the word "face" is most common. 194 | 195 | The `name` can be an input or output variable name, a CSDMS Standard Name. 196 | 197 | # Returns 198 | The grid location on which the variable is defined. Must be one of 199 | `"node"`, `"edge"`, or `"face"`. 200 | 201 | # Notes 202 | CSDMS uses the [ugrid conventions](http://ugrid-conventions.github.io/ugrid-conventions) 203 | to define unstructured grids. 204 | """ 205 | function get_var_location end 206 | 207 | """ 208 | get_current_time(model)::Float64 209 | 210 | Current time of the model. 211 | """ 212 | function get_current_time end 213 | 214 | """ 215 | get_start_time(model)::Float64 216 | 217 | Start time of the model. 218 | """ 219 | function get_start_time end 220 | 221 | """ 222 | get_end_time(model)::Float64 223 | 224 | End time of the model. 225 | """ 226 | function get_end_time end 227 | 228 | """ 229 | get_time_units(model)::String 230 | 231 | Time units of the model; e.g., `days` or `s`. 232 | 233 | # Notes 234 | CSDMS uses the [UDUNITS](http://www.unidata.ucar.edu/software/udunits) 235 | standard from Unidata. 236 | """ 237 | function get_time_units end 238 | 239 | """ 240 | get_time_step(model)::Float64 241 | 242 | Current time step of the model. 243 | """ 244 | function get_time_step end 245 | 246 | """ 247 | get_value(model, name, dest)::DenseVector 248 | 249 | Get a copy of values of the given variable. 250 | 251 | This is a getter for the model, used to access the model's 252 | current state. It returns a *copy* of a model variable, with 253 | the return type, size and rank dependent on the variable. 254 | 255 | # Arguments 256 | - `name`: An input or output variable name, a CSDMS Standard Name. 257 | - `dest`: An array into which to place the values. 258 | 259 | # Returns 260 | The same array that was passed as an input buffer, `dest`. 261 | """ 262 | function get_value end 263 | 264 | """ 265 | get_value_ptr(model, name)::DenseVector 266 | 267 | Get a reference to values of the given variable. 268 | 269 | This is a getter for the model, used to access the model's 270 | current state. It returns a reference to a model variable, 271 | with the return type, size and rank dependent on the variable. 272 | 273 | The `name` can be an input or output variable name, a CSDMS Standard Name. 274 | """ 275 | function get_value_ptr end 276 | 277 | """ 278 | get_value_at_indices(model, name, dest, inds)::DenseVector 279 | 280 | Get values at particular indices. 281 | 282 | # Arguments 283 | - `name`: An input or output variable name, a CSDMS Standard Name. 284 | - `dest`: An array into which to place the values. 285 | - `inds`: The indices into the variable array. 286 | 287 | # Returns 288 | The same array that was passed as an input buffer, `dest`. 289 | """ 290 | function get_value_at_indices end 291 | 292 | """ 293 | set_value(model, name::String, value)::Nothing 294 | 295 | Specify a new value for a model variable. 296 | 297 | This is the setter for the model, used to change the model's 298 | current state. It accepts, through *value*, a new value for a 299 | model variable, with the type, size and rank of *value* 300 | dependent on the variable. 301 | 302 | # Arguments 303 | - `name`: An input or output variable name, a CSDMS Standard Name. 304 | - `value`: The new value for the specified variable. 305 | """ 306 | function set_value end 307 | 308 | """ 309 | set_value_at_indices(model, name::String, inds::DenseVector{Int}, value)::Nothing 310 | 311 | Specify a new value for a model variable at particular indices. 312 | 313 | # Arguments 314 | - `name`: An input or output variable name, a CSDMS Standard Name. 315 | - `inds`: The indices into the variable array. 316 | - `value`: The new value for the specified variable. 317 | """ 318 | function set_value_at_indices end 319 | 320 | # Grid information 321 | 322 | """ 323 | get_grid_rank(model, grid::Int)::Int 324 | 325 | Get number of dimensions of the computational grid. 326 | """ 327 | function get_grid_rank end 328 | 329 | """ 330 | get_grid_size(model, grid::Int)::Int 331 | 332 | Get the total number of elements in the computational grid. 333 | """ 334 | function get_grid_size end 335 | 336 | """ 337 | get_grid_type(model, grid::Int)::String 338 | 339 | Get the grid type as a string. 340 | """ 341 | function get_grid_type end 342 | 343 | # Uniform rectilinear 344 | 345 | """ 346 | get_grid_shape(model, grid::Int, shape::DenseVector{Int})::DenseVector{Int} 347 | 348 | Get dimensions of the computational grid. 349 | 350 | Returns the filled `shape` array. 351 | """ 352 | function get_grid_shape end 353 | 354 | """ 355 | get_grid_spacing(model, grid::Int, spacing::DenseVector{Float64})::DenseVector{Float64} 356 | 357 | Get distance between nodes of the computational grid. 358 | 359 | # Arguments 360 | - `grid`: A grid identifier. 361 | - `spacing`: An array to hold the spacing between grid rows and columns. 362 | 363 | Returns the filled `spacing` array. 364 | """ 365 | function get_grid_spacing end 366 | 367 | """ 368 | get_grid_origin(model, grid::Int, origin::DenseVector{Float64})::DenseVector{Float64} 369 | 370 | Get coordinates for the lower-left corner of the computational grid. 371 | 372 | # Arguments 373 | - `grid`: A grid identifier. 374 | - `origin`: An array to hold the coordinates of the lower-left corner of the grid. 375 | 376 | Returns the filled `origin` array. 377 | """ 378 | function get_grid_origin end 379 | 380 | # Non-uniform rectilinear, curvilinear 381 | 382 | """ 383 | get_grid_x(model, grid::Int, x::DenseVector{Float64})::DenseVector{Float64} 384 | 385 | Get coordinates of grid nodes in the x direction. 386 | 387 | # Arguments 388 | - `grid`: A grid identifier. 389 | - `x`: An array to hold the x-coordinates of the grid nodes. 390 | 391 | Returns the filled `x` array. 392 | """ 393 | function get_grid_x end 394 | 395 | """ 396 | get_grid_y(model, grid::Int, y::DenseVector{Float64})::DenseVector{Float64} 397 | 398 | Get coordinates of grid nodes in the y direction. 399 | 400 | # Arguments 401 | - `grid`: A grid identifier. 402 | - `y`: An array to hold the y-coordinates of the grid nodes. 403 | 404 | Returns the filled `y` array. 405 | """ 406 | function get_grid_y end 407 | 408 | """ 409 | get_grid_z(model, grid::Int, z::DenseVector{Float64})::DenseVector{Float64} 410 | 411 | Get coordinates of grid nodes in the z direction. 412 | 413 | # Arguments 414 | - `grid`: A grid identifier. 415 | - `z`: An array to hold the z-coordinates of the grid nodes. 416 | 417 | Returns the filled `z` array. 418 | """ 419 | function get_grid_z end 420 | 421 | """ 422 | get_grid_node_count(model, grid::Int)::Int 423 | 424 | Get the number of nodes in the grid. 425 | """ 426 | function get_grid_node_count end 427 | 428 | """ 429 | get_grid_edge_count(model, grid::Int)::Int 430 | 431 | Get the number of edges in the grid. 432 | """ 433 | function get_grid_edge_count end 434 | 435 | """ 436 | get_grid_face_count(model, grid::Int)::Int 437 | 438 | Get the number of faces in the grid. 439 | """ 440 | function get_grid_face_count end 441 | 442 | """ 443 | get_grid_edge_nodes(model, grid::Int, edge_nodes::DenseVector{Int})::DenseVector{Int} 444 | 445 | Get the edge-node connectivity. 446 | 447 | # Arguments 448 | - `grid`: A grid identifier. 449 | - `edge_nodes`: An array of integers to place the edge-node connectivity. 450 | For each edge, connectivity is given as node at edge tail, 451 | followed by node at edge head. Therefore this array must be twice 452 | the number of nodes long. 453 | 454 | Returns the filled `edge_nodes` array. 455 | """ 456 | function get_grid_edge_nodes end 457 | 458 | """ 459 | get_grid_face_edges(model, grid::Int, face_edges::DenseVector{Int})::DenseVector{Int} 460 | 461 | Get the face-edge connectivity. 462 | 463 | # Arguments 464 | - `grid`: A grid identifier. 465 | - `face_edges`: An array of integers in which to place the face-edge connectivity. 466 | 467 | Returns the filled `face_edges` array. 468 | """ 469 | function get_grid_face_edges end 470 | 471 | """ 472 | get_grid_face_nodes(model, grid::Int, face_nodes::DenseVector{Int})::DenseVector{Int} 473 | 474 | Get the face-node connectivity. 475 | 476 | # Arguments 477 | - `grid`: A grid identifier. 478 | - `face_nodes`: An array of integers in which to place the face-node connectivity. 479 | For each face, the nodes (listed in a counter-clockwise direction) that form the 480 | boundary of the face. 481 | 482 | Returns the filled `face_nodes` array. 483 | """ 484 | function get_grid_face_nodes end 485 | 486 | """ 487 | get_grid_nodes_per_face(model, grid::Int, nodes_per_face::DenseVector{Int})::DenseVector{Int} 488 | 489 | Get the number of nodes for each face. 490 | 491 | # Arguments 492 | - `grid`: A grid identifier. 493 | - `nodes_per_face`: An array in which to place the number of edges per face. 494 | 495 | Returns the filled `nodes_per_face` array. 496 | """ 497 | function get_grid_nodes_per_face end 498 | 499 | end # module 500 | --------------------------------------------------------------------------------