MODFLOW 6  version 6.9.0.dev0
USGS Modular Hydrologic Model
mf6bmi Module Reference

This module contains the MODFLOW 6 BMI. More...

Functions/Subroutines

integer(kind=c_int) function bmi_get_component_name (name)
 
integer(kind=c_int) function bmi_initialize ()
 Initialize the computational core. More...
 
integer(kind=c_int) function bmi_update ()
 Perform a computational time step. More...
 
integer(kind=c_int) function bmi_update_until (time)
 Perform time steps until the current time reaches time. More...
 
integer(kind=c_int) function bmi_finalize ()
 Clean up the initialized simulation. More...
 
integer(kind=c_int) function get_start_time (start_time)
 Get the start time of the simulation. More...
 
integer(kind=c_int) function get_end_time (end_time)
 Get the end time of the simulation. More...
 
integer(kind=c_int) function get_current_time (current_time)
 Get the current time of the simulation. More...
 
integer(kind=c_int) function get_time_step (time_step)
 Get the time step for the simulation. More...
 
integer(kind=c_int) function get_time_units (c_time_units)
 Get the time units of the simulation. More...
 
integer(kind=c_int) function get_input_item_count (count)
 Get the number of input variables in the simulation. More...
 
integer(kind=c_int) function get_output_item_count (count)
 Get the number of output variables in the simulation. More...
 
integer(kind=c_int) function get_input_var_names (c_names)
 Returns all input variables in the simulation. More...
 
integer(kind=c_int) function get_output_var_names (c_names)
 Returns all output variables in the simulation. More...
 
integer(kind=c_int) function get_var_itemsize (c_var_address, var_size)
 Get the size (in bytes) of a single element of a variable. More...
 
integer(kind=c_int) function get_var_nbytes (c_var_address, var_nbytes)
 Get size of the variable, in bytes. More...
 
integer(kind=c_int) function get_value_double (c_var_address, c_arr_ptr)
 Copy the double precision values of a variable into the array. More...
 
integer(kind=c_int) function get_value_int (c_var_address, c_arr_ptr)
 Copy the integer values of a variable into the array. More...
 
integer(kind=c_int) function get_value_bool (c_var_address, c_arr_ptr)
 Copy the logical scalar value into the array. More...
 
integer(kind=c_int) function get_value_string (c_var_address, c_arr_ptr)
 Copy the string(s) of a variable into the array. More...
 
integer(kind=c_int) function get_value (c_var_address, c_arr_ptr)
 Copy the value of a variable into the array. More...
 
integer(kind=c_int) function get_value_ptr (c_var_address, c_arr_ptr)
 Get a pointer to an array. More...
 
integer(kind=c_int) function get_value_ptr_double (c_var_address, c_arr_ptr)
 Get a pointer to the array of double precision numbers. More...
 
integer(kind=c_int) function get_value_ptr_int (c_var_address, c_arr_ptr)
 Get a pointer to the array of integer numbers. More...
 
integer(kind=c_int) function get_value_ptr_bool (c_var_address, c_arr_ptr)
 Get a pointer to the logical scalar value. More...
 
integer(kind=c_int) function set_value (c_var_address, c_arr_ptr)
 Set new values for a given variable. More...
 
integer(kind=c_int) function set_value_double (c_var_address, c_arr_ptr)
 Set new values for a variable of type double. More...
 
integer(kind=c_int) function set_value_int (c_var_address, c_arr_ptr)
 Set new values for a variable of type integer. More...
 
integer(kind=c_int) function set_value_bool (c_var_address, c_arr_ptr)
 Set new value for a logical scalar variable. More...
 
integer(kind=c_int) function get_value_at_indices (c_var_address, c_arr_ptr, c_inds, count)
 Copy the values of a variable at the given indices into the array. More...
 
integer(kind=c_int) function set_value_at_indices (c_var_address, c_inds, count, c_arr_ptr)
 Set the values of a variable at the given indices. More...
 
logical(lgp) function valid_indices (mem_path, var_name, c_inds, count, nvalues)
 Check that every index is within the variable, and count its values. More...
 
integer(kind=c_int) function get_var_type (c_var_address, c_var_type)
 Get the variable type as a string. More...
 
integer(kind=c_int) function get_var_units (c_var_address, c_var_units)
 Get the units of a variable. More...
 
integer(kind=c_int) function get_var_location (c_var_address, c_var_location)
 Get the grid location of a variable. More...
 
integer(kind=c_int) function get_var_rank (c_var_address, c_var_rank)
 Get the variable rank (non-BMI) More...
 
integer(kind=c_int) function get_var_shape (c_var_address, c_var_shape)
 Get the shape of the array for the variable (non-BMI) More...
 

Variables

integer(c_int), bind(C, name="ISTDOUTTOFILE") istdout_to_file = 1
 output control: =0 to screen, >0 to file More...
 

Detailed Description

This BMI interface matches the CSDMS standard, with a few modifications:

  • This interface will build into a shared library that can be called from other executables and scripts, not necessarily written in Fortran. Therefore we have omitted the type-boundness of the routines, since they cannot have the bind(C,"...") attribute.
  • MODFLOW has internal data arrays with rank > 1 that we would like to expose. An example would be access to data in the BOUND array of GWF boundary packages (BndType). The get_value_ptr calls below support this, returning a C-style pointer to the arrays and methods have been added to query the variable's rank and shape.

Note on style: BMI apparently uses underscores, we use underscores in some places but camelcase in other. Since this is a dedicated BMI interface module, we'll use underscores here as well.

Function/Subroutine Documentation

◆ bmi_finalize()

integer(kind=c_int) function mf6bmi::bmi_finalize

Performs teardown tasks for the initialized simulation, this call should match the call to bmi_initialize()

Returns
BMI status code

Definition at line 156 of file mf6bmi.f90.

157  !DIR$ ATTRIBUTES DLLEXPORT :: bmi_finalize
158  ! -- modules
159  use simvariablesmodule, only: iforcestop
160  ! -- dummy variables
161  integer(kind=c_int) :: bmi_status !< BMI status code
162 
163  ! we don't want a full stop() here, this disables it:
164  iforcestop = 0
165  call mf6finalize()
166 
167  bmi_status = bmi_success
168 
This module contains simulation variables.
Definition: SimVariables.f90:9
integer(i4b) iforcestop
forced stop flag (1) forces a call to ustop(..) when the simulation has ended, (0) doesn't
Here is the call graph for this function:

◆ bmi_get_component_name()

integer(kind=c_int) function mf6bmi::bmi_get_component_name ( character(kind=c_char), dimension(bmi_lencomponentname), intent(inout)  name)
Returns
BMI status code

Definition at line 43 of file mf6bmi.f90.

45  !DIR$ ATTRIBUTES DLLEXPORT :: bmi_get_component_name
46  ! -- dummy variables
47  character(kind=c_char), intent(inout) :: name(BMI_LENCOMPONENTNAME)
48  integer(kind=c_int) :: bmi_status !< BMI status code
49  ! -- local variables
50  character(len=*), parameter :: component_name = 'MODFLOW 6'
51 
52  name(1:len(component_name) + 1) = &
53  string_to_char_array(component_name, len(component_name))
54  bmi_status = bmi_success
55 
Here is the call graph for this function:

◆ bmi_initialize()

integer(kind=c_int) function mf6bmi::bmi_initialize

It is required to have the MODFLOW 6 configuration file 'mfsim.nam' available in the current working directory when calling this routine.

NOTE: initialization should always be matched with a call to bmi_finalize(). However, we currently do not support the reinitialization of a model in the same memory space... You would have to create a new process for that.

Returns
BMI status code

Definition at line 68 of file mf6bmi.f90.

69  !DIR$ ATTRIBUTES DLLEXPORT :: bmi_initialize
70  ! -- dummy variables
71  integer(kind=c_int) :: bmi_status !< BMI status code
72  ! -- local variables
73 
74  if (istdout_to_file > 0) then
75  ! -- open stdout file mfsim.stdout
76  istdout = getunit()
77  !
78  ! -- set STDOUT to a physical file unit
79  open (unit=istdout, file=simstdout)
80  end if
81  !
82  ! -- initialize MODFLOW 6
83  call mf6initialize()
84 
85  bmi_status = bmi_success
86 
Here is the call graph for this function:

◆ bmi_update()

integer(kind=c_int) function mf6bmi::bmi_update

It will prepare the timestep, call the calculation routine on all the solution groups in the simulation, and finalize the timestep by printing out diagnostics and writing output. It can be called in succession to perform multiple steps up to the simulation's end time is reached.

Returns
BMI status code

Definition at line 97 of file mf6bmi.f90.

98  !DIR$ ATTRIBUTES DLLEXPORT :: bmi_update
99  ! -- dummy variables
100  integer(kind=c_int) :: bmi_status !< BMI status code
101  ! -- local variables
102  logical :: hasConverged
103 
104  hasconverged = mf6update()
105 
106  bmi_status = bmi_success
Here is the call graph for this function:

◆ bmi_update_until()

integer(kind=c_int) function mf6bmi::bmi_update_until ( real(kind=c_double), intent(in), value  time)

Time steps are not split, so the current time can pass time. A time before the current time or after the end time is an error.

Parameters
[in]timetime to advance the simulation to
Returns
BMI status code

Definition at line 114 of file mf6bmi.f90.

116  !DIR$ ATTRIBUTES DLLEXPORT :: bmi_update_until
117  ! -- modules
118  use constantsmodule, only: done, dprec
120  ! -- dummy variables
121  real(kind=c_double), value, intent(in) :: time !< time to advance the simulation to
122  integer(kind=c_int) :: bmi_status !< BMI status code
123  ! -- local variables
124  real(DP) :: tol
125  logical :: hasConverged
126 
127  bmi_status = bmi_failure
128 
129  ! -- times that differ by roundoff are the same time
130  tol = dprec * max(done, abs(time))
131  if (time < totim - tol) then
132  write (bmi_last_error, fmt_invalid_time) time, &
133  'which is before the current time'
134  call report_bmi_error(bmi_last_error)
135  return
136  end if
137  if (time > totalsimtime + tol) then
138  write (bmi_last_error, fmt_invalid_time) time, &
139  'which is after the end time'
140  call report_bmi_error(bmi_last_error)
141  return
142  end if
143 
144  do while (totim < time - tol .and. .not. endofsimulation)
145  hasconverged = mf6update()
146  end do
147 
148  bmi_status = bmi_success
This module contains simulation constants.
Definition: Constants.f90:9
real(dp), parameter dprec
real constant machine precision
Definition: Constants.f90:120
real(dp), parameter done
real constant 1
Definition: Constants.f90:76
logical(lgp), pointer, public endofsimulation
flag indicating end of simulation
Definition: tdis.f90:31
real(dp), pointer, public totim
time relative to start of simulation
Definition: tdis.f90:35
real(dp), pointer, public totalsimtime
time at end of simulation
Definition: tdis.f90:40
Here is the call graph for this function:

◆ get_current_time()

integer(kind=c_int) function mf6bmi::get_current_time ( real(kind=c_double), intent(out)  current_time)

As MODFLOW currently does not have internal time, this will be equal to the time passed w.r.t. the start time of the simulation.

Parameters
[out]current_timecurrent time
Returns
BMI status code

Definition at line 211 of file mf6bmi.f90.

213  !DIR$ ATTRIBUTES DLLEXPORT :: get_current_time
214  ! -- modules
215  use tdismodule, only: totim
216  ! -- dummy variables
217  real(kind=c_double), intent(out) :: current_time !< current time
218  integer(kind=c_int) :: bmi_status !< BMI status code
219 
220  current_time = totim
221  bmi_status = bmi_success
222 

◆ get_end_time()

integer(kind=c_int) function mf6bmi::get_end_time ( real(kind=c_double), intent(out)  end_time)

As MODFLOW does currently does not have internal time, this will be equal to the total runtime.

Parameters
[out]end_timeend time
Returns
BMI status code

Definition at line 193 of file mf6bmi.f90.

194  !DIR$ ATTRIBUTES DLLEXPORT :: get_end_time
195  ! -- modules
196  use tdismodule, only: totalsimtime
197  ! -- dummy variables
198  real(kind=c_double), intent(out) :: end_time !< end time
199  integer(kind=c_int) :: bmi_status !< BMI status code
200 
201  end_time = totalsimtime
202  bmi_status = bmi_success
203 

◆ get_input_item_count()

integer(kind=c_int) function mf6bmi::get_input_item_count ( integer(kind=c_int), intent(out)  count)

This concerns all variables stored in the memory manager

Parameters
[out]countthe number of input variables
Returns
BMI status code

Definition at line 284 of file mf6bmi.f90.

286  !DIR$ ATTRIBUTES DLLEXPORT :: get_input_item_count
287  ! -- dummy variables
288  integer(kind=c_int), intent(out) :: count !< the number of input variables
289  integer(kind=c_int) :: bmi_status !< BMI status code
290 
291  count = memorystore%count()
292 
293  bmi_status = bmi_success
294 

◆ get_input_var_names()

integer(kind=c_int) function mf6bmi::get_input_var_names ( character(kind=c_char, len=1), dimension(*), intent(inout)  c_names)

This functions returns the full address for all variables in the memory manager

The array c_names should be pre-allocated of proper size:

size = BMI_LENVARADDRESS * get_input_item_count()

The strings will be written contiguously with stride equal to BMI_LENVARADDRESS and nul-terminated where the trailing spaces start:

c_names = 'variable_address_1\x00 ... variable_address_2\x00 ... ' etc.

Parameters
[in,out]c_namesarray with memory paths for input variables
Returns
BMI status code

Definition at line 328 of file mf6bmi.f90.

330  !DIR$ ATTRIBUTES DLLEXPORT :: get_input_var_names
331  ! -- dummy variables
332  character(kind=c_char, len=1), intent(inout) :: c_names(*) !< array with memory paths for input variables
333  integer(kind=c_int) :: bmi_status !< BMI status code
334  ! -- local variables
335  integer(I4B) :: start, i
336  type(MemoryContainerIteratorType), allocatable :: itr
337  type(MemoryType), pointer :: mt => null()
338  character(len=LENMEMADDRESS) :: var_address
339 
340  start = 1
341  itr = memorystore%iterator()
342  do while (itr%has_next())
343  call itr%next()
344  mt => itr%value()
345  var_address = create_mem_address(mt%path, mt%name)
346  do i = 1, len(trim(var_address))
347  c_names(start + i - 1) = var_address(i:i)
348  end do
349  c_names(start + i) = c_null_char
350  start = start + bmi_lenvaraddress
351  end do
352 
353  bmi_status = bmi_success
354 
Here is the call graph for this function:

◆ get_output_item_count()

integer(kind=c_int) function mf6bmi::get_output_item_count ( integer(kind=c_int), intent(out)  count)

This concerns all variables stored in the memory manager

Parameters
[out]countthe number of output variables
Returns
BMI status code

Definition at line 301 of file mf6bmi.f90.

303  !DIR$ ATTRIBUTES DLLEXPORT :: get_output_item_count
304  ! -- dummy variables
305  integer(kind=c_int), intent(out) :: count !< the number of output variables
306  integer(kind=c_int) :: bmi_status !< BMI status code
307 
308  count = memorystore%count()
309 
310  bmi_status = bmi_success
311 

◆ get_output_var_names()

integer(kind=c_int) function mf6bmi::get_output_var_names ( character(kind=c_char, len=1), dimension(*), intent(inout)  c_names)

This function works analogously to get_input_var_names(), and currently returns the same set of memory variables, which is all of them!

Parameters
[in,out]c_namesarray with memory paths for output variables
Returns
BMI status code

Definition at line 363 of file mf6bmi.f90.

365  !DIR$ ATTRIBUTES DLLEXPORT :: get_output_var_names
366  ! -- dummy variables
367  character(kind=c_char, len=1), intent(inout) :: c_names(*) !< array with memory paths for output variables
368  integer(kind=c_int) :: bmi_status !< BMI status code
369  ! -- local variables
370  integer(I4B) :: start, i
371  type(MemoryContainerIteratorType), allocatable :: itr
372  type(MemoryType), pointer :: mt => null()
373  character(len=LENMEMADDRESS) :: var_address
374 
375  start = 1
376  itr = memorystore%iterator()
377  do while (itr%has_next())
378  call itr%next()
379  mt => itr%value()
380  var_address = create_mem_address(mt%path, mt%name)
381  do i = 1, len(trim(var_address))
382  c_names(start + i - 1) = var_address(i:i)
383  end do
384  c_names(start + i) = c_null_char
385  start = start + bmi_lenvaraddress
386  end do
387 
388  bmi_status = bmi_success
389 
Here is the call graph for this function:

◆ get_start_time()

integer(kind=c_int) function mf6bmi::get_start_time ( real(kind=c_double), intent(out)  start_time)

As MODFLOW currently does not have internal time, this will be returning 0.0 for now. New version...

Parameters
[out]start_timestart time
Returns
BMI status code

Definition at line 176 of file mf6bmi.f90.

178  !DIR$ ATTRIBUTES DLLEXPORT :: get_start_time
179  ! -- dummy variables
180  real(kind=c_double), intent(out) :: start_time !< start time
181  integer(kind=c_int) :: bmi_status !< BMI status code
182 
183  start_time = 0.0_dp
184  bmi_status = bmi_success
185 

◆ get_time_step()

integer(kind=c_int) function mf6bmi::get_time_step ( real(kind=c_double), intent(out)  time_step)

Note that the returned value may vary between and within stress periods, depending on your time discretization settings in the TDIS package.

Parameters
[out]time_stepcurrent time step
Returns
BMI status code

Definition at line 230 of file mf6bmi.f90.

232  !DIR$ ATTRIBUTES DLLEXPORT :: get_time_step
233  ! -- modules
234  use tdismodule, only: delt
235  ! -- dummy variables
236  real(kind=c_double), intent(out) :: time_step !< current time step
237  integer(kind=c_int) :: bmi_status !< BMI status code
238 
239  time_step = delt
240  bmi_status = bmi_success
241 
real(dp), pointer, public delt
length of the current time step
Definition: tdis.f90:32

◆ get_time_units()

integer(kind=c_int) function mf6bmi::get_time_units ( character(kind=c_char), dimension(bmi_lenunits), intent(out)  c_time_units)

The units are those of TIME_UNITS in the TDIS Package, as UDUNITS symbols, or 'unknown' when TIME_UNITS is not given.

Parameters
[out]c_time_unitstime units as a string
Returns
BMI status code

Definition at line 249 of file mf6bmi.f90.

251  !DIR$ ATTRIBUTES DLLEXPORT :: get_time_units
252  ! -- modules
253  use tdismodule, only: itmuni
254  ! -- dummy variables
255  character(kind=c_char), intent(out) :: c_time_units(BMI_LENUNITS) !< time units as a string
256  integer(kind=c_int) :: bmi_status !< BMI status code
257  ! -- local variables
258  character(len=LENUNITS) :: time_units
259 
260  select case (itmuni)
261  case (1)
262  time_units = 's'
263  case (2)
264  time_units = 'min'
265  case (3)
266  time_units = 'h'
267  case (4)
268  time_units = 'd'
269  case (5)
270  time_units = 'year'
271  case default
272  time_units = 'unknown'
273  end select
274  c_time_units(1:len_trim(time_units) + 1) = &
275  string_to_char_array(trim(time_units), len_trim(time_units))
276  bmi_status = bmi_success
277 
integer(i4b), pointer, public itmuni
flag indicating time units
Definition: tdis.f90:25
Here is the call graph for this function:

◆ get_value()

integer(kind=c_int) function mf6bmi::get_value ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
type(c_ptr), intent(inout)  c_arr_ptr 
)

The copied variable is located at c_var_address. The caller should provide c_arr_ptr pointing to an array of the proper shape (the BMI function get_var_shape() can be used to create it). Multi-dimensional arrays are supported.

Parameters
[in]c_var_addressmemory address string of the variable
[in,out]c_arr_ptrpointer to the array
Returns
BMI status code

Definition at line 737 of file mf6bmi.f90.

739  !DIR$ ATTRIBUTES DLLEXPORT :: get_value
740  ! -- modules
741  use constantsmodule, only: lenmemtype
742  ! -- dummy variables
743  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
744  type(c_ptr), intent(inout) :: c_arr_ptr !< pointer to the array
745  integer(kind=c_int) :: bmi_status !< BMI status code
746  ! -- local variables
747  character(len=LENMEMPATH) :: mem_path
748  character(len=LENMEMTYPE) :: mem_type
749  character(len=LENVARNAME) :: var_name
750  logical(LGP) :: valid
751 
752  bmi_status = bmi_success
753 
754  call split_address(c_var_address, mem_path, var_name, valid)
755  if (.not. valid) then
756  bmi_status = bmi_failure
757  return
758  end if
759 
760  call get_mem_type(var_name, mem_path, mem_type)
761 
762  if (index(mem_type, "DOUBLE") /= 0) then
763  bmi_status = get_value_double(c_var_address, c_arr_ptr)
764  else if (index(mem_type, "INTEGER") /= 0) then
765  bmi_status = get_value_int(c_var_address, c_arr_ptr)
766  else if (index(mem_type, "LOGICAL") /= 0) then
767  bmi_status = get_value_bool(c_var_address, c_arr_ptr)
768  else if (index(mem_type, "STRING") /= 0) then
769  bmi_status = get_value_string(c_var_address, c_arr_ptr)
770  else
771  write (bmi_last_error, fmt_unsupported_type) trim(var_name)
772  call report_bmi_error(bmi_last_error)
773  bmi_status = bmi_failure
774  return
775  end if
776 
integer(i4b), parameter, public lenmemtype
maximum length of a memory manager type
Definition: Constants.f90:62
Here is the call graph for this function:

◆ get_value_at_indices()

integer(kind=c_int) function mf6bmi::get_value_at_indices ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
type(c_ptr), intent(in)  c_arr_ptr,
integer(kind=c_int), dimension(*), intent(in)  c_inds,
integer(kind=c_int), intent(in)  count 
)

The indices are zero-based positions in the variable's values in C-style (row-major) order, so a variable of rank > 1 is indexed as if flattened. The caller should provide c_arr_ptr pointing to an array of size count. Double precision and integer variables are supported.

Parameters
[in]c_var_addressmemory address string of the variable
[in]c_arr_ptrpointer to the array to copy into
[in]c_indszero-based indices of the values
[in]countnumber of indices
Returns
BMI status code

Definition at line 1233 of file mf6bmi.f90.

1235  !DIR$ ATTRIBUTES DLLEXPORT :: get_value_at_indices
1236  ! -- modules
1237  use constantsmodule, only: lenmemtype
1238  ! -- dummy variables
1239  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
1240  type(c_ptr), intent(in) :: c_arr_ptr !< pointer to the array to copy into
1241  integer(kind=c_int), intent(in) :: c_inds(*) !< zero-based indices of the values
1242  integer(kind=c_int), intent(in) :: count !< number of indices
1243  integer(kind=c_int) :: bmi_status !< BMI status code
1244  ! -- local variables
1245  character(len=LENMEMPATH) :: mem_path
1246  character(len=LENMEMTYPE) :: mem_type
1247  character(len=LENVARNAME) :: var_name
1248  logical(LGP) :: valid
1249  integer(I4B) :: i, nvalues
1250  type(c_ptr) :: var_ptr
1251  real(DP), dimension(:), pointer, contiguous :: src_dbl, tgt_dbl
1252  integer(I4B), dimension(:), pointer, contiguous :: src_int, tgt_int
1253 
1254  bmi_status = bmi_failure
1255 
1256  call split_address(c_var_address, mem_path, var_name, valid)
1257  if (.not. valid) return
1258  if (.not. valid_indices(mem_path, var_name, c_inds, count, nvalues)) return
1259 
1260  ! -- the variable's storage, viewed as a flat array in memory order
1261  call get_mem_type(var_name, mem_path, mem_type)
1262  if (index(mem_type, "DOUBLE") /= 0) then
1263  if (get_value_ptr_double(c_var_address, var_ptr) /= bmi_success) return
1264  call c_f_pointer(var_ptr, src_dbl, [nvalues])
1265  call c_f_pointer(c_arr_ptr, tgt_dbl, [count])
1266  do i = 1, count
1267  tgt_dbl(i) = src_dbl(c_inds(i) + 1)
1268  end do
1269  else if (index(mem_type, "INTEGER") /= 0) then
1270  if (get_value_ptr_int(c_var_address, var_ptr) /= bmi_success) return
1271  call c_f_pointer(var_ptr, src_int, [nvalues])
1272  call c_f_pointer(c_arr_ptr, tgt_int, [count])
1273  do i = 1, count
1274  tgt_int(i) = src_int(c_inds(i) + 1)
1275  end do
1276  else
1277  write (bmi_last_error, fmt_unsupported_type) trim(var_name)
1278  call report_bmi_error(bmi_last_error)
1279  return
1280  end if
1281 
1282  bmi_status = bmi_success
1283 
Here is the call graph for this function:

◆ get_value_bool()

integer(kind=c_int) function mf6bmi::get_value_bool ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
type(c_ptr), intent(in)  c_arr_ptr 
)

The copied variable us located at c_var_address. The caller should provide c_arr_ptr pointing to a scalar array with rank=0.

Parameters
[in]c_var_addressmemory address string of the variable
[in]c_arr_ptrpointer to the logical array
Returns
BMI status code

Definition at line 610 of file mf6bmi.f90.

612  !DIR$ ATTRIBUTES DLLEXPORT :: get_value_bool
613  ! -- modules
615  ! -- dummy variables
616  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
617  type(c_ptr), intent(in) :: c_arr_ptr !< pointer to the logical array
618  integer(kind=c_int) :: bmi_status !< BMI status code
619  ! -- local variables
620  character(len=LENMEMPATH) :: mem_path
621  character(len=LENVARNAME) :: var_name
622  logical(LGP) :: valid
623  integer(I4B) :: rank
624  logical(LGP), pointer :: src_ptr, tgt_ptr
625 
626  bmi_status = bmi_success
627 
628  call split_address(c_var_address, mem_path, var_name, valid)
629  if (.not. valid) then
630  bmi_status = bmi_failure
631  return
632  end if
633 
634  rank = -1
635  call get_mem_rank(var_name, mem_path, rank)
636 
637  ! convert pointer
638  if (rank == 0) then
639  call mem_setptr(src_ptr, var_name, mem_path)
640  call c_f_pointer(c_arr_ptr, tgt_ptr)
641  tgt_ptr = src_ptr
642  else
643  write (bmi_last_error, fmt_unsupported_rank) trim(var_name)
644  call report_bmi_error(bmi_last_error)
645  bmi_status = bmi_failure
646  return
647  end if
648 
subroutine, public on_memory_set(var_name, mem_path, status)
Triggers the calling of the side effect handler for this variable.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_value_double()

integer(kind=c_int) function mf6bmi::get_value_double ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
type(c_ptr), intent(in)  c_arr_ptr 
)

The copied variable us located at c_var_address. The caller should provide c_arr_ptr pointing to an array of the proper shape (the BMI function get_var_shape() can be used to create it). Multi-dimensional arrays are supported.

Parameters
[in]c_var_addressmemory address string of the variable
[in]c_arr_ptrpointer to the double precision array
Returns
BMI status code

Definition at line 458 of file mf6bmi.f90.

460  !DIR$ ATTRIBUTES DLLEXPORT :: get_value_double
461  ! -- modules
463  ! -- dummy variables
464  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
465  type(c_ptr), intent(in) :: c_arr_ptr !< pointer to the double precision array
466  integer(kind=c_int) :: bmi_status !< BMI status code
467  ! -- local variables
468  character(len=LENMEMPATH) :: mem_path
469  character(len=LENVARNAME) :: var_name
470  logical(LGP) :: valid
471  integer(I4B) :: rank
472  real(DP), pointer :: src_ptr, tgt_ptr
473  real(DP), dimension(:), pointer, contiguous :: src1D_ptr, tgt1D_ptr
474  real(DP), dimension(:, :), pointer, contiguous :: src2D_ptr, tgt2D_ptr
475  real(DP), dimension(:, :, :), pointer, contiguous :: src3D_ptr, tgt3D_ptr
476  integer(I4B) :: i, j, k
477 
478  bmi_status = bmi_success
479 
480  call split_address(c_var_address, mem_path, var_name, valid)
481  if (.not. valid) then
482  bmi_status = bmi_failure
483  return
484  end if
485 
486  ! convert pointer and copy data from memory manager into
487  ! the passed array, using loops to avoid stack overflow
488  rank = -1
489  call get_mem_rank(var_name, mem_path, rank)
490 
491  if (rank == 0) then
492  call mem_setptr(src_ptr, var_name, mem_path)
493  call c_f_pointer(c_arr_ptr, tgt_ptr)
494  tgt_ptr = src_ptr
495  else if (rank == 1) then
496  call mem_setptr(src1d_ptr, var_name, mem_path)
497  call c_f_pointer(c_arr_ptr, tgt1d_ptr, shape(src1d_ptr))
498  do i = 1, size(tgt1d_ptr)
499  tgt1d_ptr(i) = src1d_ptr(i)
500  end do
501  else if (rank == 2) then
502  call mem_setptr(src2d_ptr, var_name, mem_path)
503  call c_f_pointer(c_arr_ptr, tgt2d_ptr, shape(src2d_ptr))
504  do j = 1, size(tgt2d_ptr, 2)
505  do i = 1, size(tgt2d_ptr, 1)
506  tgt2d_ptr(i, j) = src2d_ptr(i, j)
507  end do
508  end do
509  else if (rank == 3) then
510  call mem_setptr(src3d_ptr, var_name, mem_path)
511  call c_f_pointer(c_arr_ptr, tgt3d_ptr, shape(src3d_ptr))
512  do k = 1, size(tgt3d_ptr, 3)
513  do j = 1, size(tgt3d_ptr, 2)
514  do i = 1, size(tgt3d_ptr, 1)
515  tgt3d_ptr(i, j, k) = src3d_ptr(i, j, k)
516  end do
517  end do
518  end do
519  else
520  write (bmi_last_error, fmt_unsupported_rank) trim(var_name)
521  call report_bmi_error(bmi_last_error)
522  bmi_status = bmi_failure
523  return
524  end if
525 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_value_int()

integer(kind=c_int) function mf6bmi::get_value_int ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
type(c_ptr), intent(in)  c_arr_ptr 
)

The copied variable is located at c_var_address. The caller should provide c_arr_ptr pointing to an array of the proper shape (the BMI function get_var_shape() can be used to create it). Multi-dimensional arrays are supported.

Parameters
[in]c_var_addressmemory address string of the variable
[in]c_arr_ptrpointer to the integer array
Returns
BMI status code

Definition at line 535 of file mf6bmi.f90.

537  !DIR$ ATTRIBUTES DLLEXPORT :: get_value_int
538  ! -- modules
540  ! -- dummy variables
541  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
542  type(c_ptr), intent(in) :: c_arr_ptr !< pointer to the integer array
543  integer(kind=c_int) :: bmi_status !< BMI status code
544  ! -- local variables
545  character(len=LENMEMPATH) :: mem_path
546  character(len=LENVARNAME) :: var_name
547  logical(LGP) :: valid
548  integer(I4B) :: rank
549  integer(I4B), pointer :: src_ptr, tgt_ptr
550  integer(I4B), dimension(:), pointer, contiguous :: src1D_ptr, tgt1D_ptr
551  integer(I4B), dimension(:, :), pointer, contiguous :: src2D_ptr, tgt2D_ptr
552  integer(I4B), dimension(:, :, :), pointer, contiguous :: src3D_ptr, tgt3D_ptr
553  integer(I4B) :: i, j, k
554 
555  bmi_status = bmi_success
556 
557  call split_address(c_var_address, mem_path, var_name, valid)
558  if (.not. valid) then
559  bmi_status = bmi_failure
560  return
561  end if
562 
563  ! convert pointer and copy data from memory manager into
564  ! the passed array, using loops to avoid stack overflow
565  rank = -1
566  call get_mem_rank(var_name, mem_path, rank)
567 
568  if (rank == 0) then
569  call mem_setptr(src_ptr, var_name, mem_path)
570  call c_f_pointer(c_arr_ptr, tgt_ptr)
571  tgt_ptr = src_ptr
572  else if (rank == 1) then
573  call mem_setptr(src1d_ptr, var_name, mem_path)
574  call c_f_pointer(c_arr_ptr, tgt1d_ptr, shape(src1d_ptr))
575  do i = 1, size(tgt1d_ptr)
576  tgt1d_ptr(i) = src1d_ptr(i)
577  end do
578  else if (rank == 2) then
579  call mem_setptr(src2d_ptr, var_name, mem_path)
580  call c_f_pointer(c_arr_ptr, tgt2d_ptr, shape(src2d_ptr))
581  do j = 1, size(tgt2d_ptr, 2)
582  do i = 1, size(tgt2d_ptr, 1)
583  tgt2d_ptr(i, j) = src2d_ptr(i, j)
584  end do
585  end do
586  else if (rank == 3) then
587  call mem_setptr(src3d_ptr, var_name, mem_path)
588  call c_f_pointer(c_arr_ptr, tgt3d_ptr, shape(src3d_ptr))
589  do k = 1, size(tgt3d_ptr, 3)
590  do j = 1, size(tgt3d_ptr, 2)
591  do i = 1, size(tgt3d_ptr, 1)
592  tgt3d_ptr(i, j, k) = src3d_ptr(i, j, k)
593  end do
594  end do
595  end do
596  else
597  write (bmi_last_error, fmt_unsupported_rank) trim(var_name)
598  call report_bmi_error(bmi_last_error)
599  bmi_status = bmi_failure
600  return
601  end if
602 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_value_ptr()

integer(kind=c_int) function mf6bmi::get_value_ptr ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
type(c_ptr), intent(inout)  c_arr_ptr 
)

The array is located at c_var_address. There is no copying of data involved. Multi-dimensional arrays are supported and the get_var_rank() function can be used to get the variable's dimensionality, and get_var_shape() for its shape.

Parameters
[in]c_var_addressmemory address string of the variable
[in,out]c_arr_ptrpointer to the array
Returns
BMI status code

Definition at line 786 of file mf6bmi.f90.

788  !DIR$ ATTRIBUTES DLLEXPORT :: get_value_ptr
789  ! -- modules
790  use constantsmodule, only: lenmemtype
791  ! -- dummy variables
792  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
793  type(c_ptr), intent(inout) :: c_arr_ptr !< pointer to the array
794  integer(kind=c_int) :: bmi_status !< BMI status code
795  ! -- local variables
796  character(len=LENMEMPATH) :: mem_path
797  character(len=LENMEMTYPE) :: mem_type
798  character(len=LENVARNAME) :: var_name
799  logical(LGP) :: valid
800 
801  bmi_status = bmi_success
802 
803  call split_address(c_var_address, mem_path, var_name, valid)
804  if (.not. valid) then
805  bmi_status = bmi_failure
806  return
807  end if
808 
809  call get_mem_type(var_name, mem_path, mem_type)
810 
811  if (index(mem_type, "DOUBLE") /= 0) then
812  bmi_status = get_value_ptr_double(c_var_address, c_arr_ptr)
813  else if (index(mem_type, "INTEGER") /= 0) then
814  bmi_status = get_value_ptr_int(c_var_address, c_arr_ptr)
815  else if (index(mem_type, "LOGICAL") /= 0) then
816  bmi_status = get_value_ptr_bool(c_var_address, c_arr_ptr)
817  else
818  write (bmi_last_error, fmt_unsupported_type) trim(var_name)
819  call report_bmi_error(bmi_last_error)
820  bmi_status = bmi_failure
821  return
822  end if
823 
Here is the call graph for this function:

◆ get_value_ptr_bool()

integer(kind=c_int) function mf6bmi::get_value_ptr_bool ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
type(c_ptr), intent(inout)  c_arr_ptr 
)

Only scalar values (with rank=0) are supported.

Parameters
[in]c_var_addressmemory address string of the variable
[in,out]c_arr_ptrpointer to the array
Returns
BMI status code

Definition at line 940 of file mf6bmi.f90.

942  !DIR$ ATTRIBUTES DLLEXPORT :: get_value_ptr_bool
943  ! -- dummy variables
944  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
945  type(c_ptr), intent(inout) :: c_arr_ptr !< pointer to the array
946  integer(kind=c_int) :: bmi_status !< BMI status code
947  ! -- local variables
948  character(len=LENMEMPATH) :: mem_path
949  character(len=LENVARNAME) :: var_name
950  logical(LGP) :: valid
951  logical(LGP), pointer :: scalar_ptr
952  integer(I4B) :: rank
953 
954  bmi_status = bmi_success
955 
956  call split_address(c_var_address, mem_path, var_name, valid)
957  if (.not. valid) then
958  bmi_status = bmi_failure
959  return
960  end if
961 
962  rank = -1
963  call get_mem_rank(var_name, mem_path, rank)
964  if (rank == 0) then
965  call mem_setptr(scalar_ptr, var_name, mem_path)
966  c_arr_ptr = c_loc(scalar_ptr)
967  else
968  write (bmi_last_error, fmt_unsupported_rank) trim(var_name)
969  call report_bmi_error(bmi_last_error)
970  bmi_status = bmi_failure
971  return
972  end if
973 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_value_ptr_double()

integer(kind=c_int) function mf6bmi::get_value_ptr_double ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
type(c_ptr), intent(inout)  c_arr_ptr 
)

The array is located at c_var_address. There is no copying of data involved. Multi-dimensional arrays are supported and the get_var_rank() function can be used to get the variable's dimensionality, and get_var_shape() for its shape.

Parameters
[in]c_var_addressmemory address string of the variable
[in,out]c_arr_ptrpointer to the array
Returns
BMI status code

Definition at line 833 of file mf6bmi.f90.

835  !DIR$ ATTRIBUTES DLLEXPORT :: get_value_ptr_double
836  ! -- dummy variables
837  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
838  type(c_ptr), intent(inout) :: c_arr_ptr !< pointer to the array
839  integer(kind=c_int) :: bmi_status !< BMI status code
840  ! -- local variables
841  character(len=LENMEMPATH) :: mem_path
842  character(len=LENVARNAME) :: var_name
843  logical(LGP) :: valid
844  real(DP), pointer :: scalar_ptr
845  real(DP), dimension(:), pointer, contiguous :: array_ptr
846  real(DP), dimension(:, :), pointer, contiguous :: array2D_ptr
847  real(DP), dimension(:, :, :), pointer, contiguous :: array3D_ptr
848  integer(I4B) :: rank
849 
850  bmi_status = bmi_success
851 
852  call split_address(c_var_address, mem_path, var_name, valid)
853  if (.not. valid) then
854  bmi_status = bmi_failure
855  return
856  end if
857 
858  rank = -1
859  call get_mem_rank(var_name, mem_path, rank)
860  if (rank == 0) then
861  call mem_setptr(scalar_ptr, var_name, mem_path)
862  c_arr_ptr = c_loc(scalar_ptr)
863  else if (rank == 1) then
864  call mem_setptr(array_ptr, var_name, mem_path)
865  c_arr_ptr = c_loc(array_ptr)
866  else if (rank == 2) then
867  call mem_setptr(array2d_ptr, var_name, mem_path)
868  c_arr_ptr = c_loc(array2d_ptr)
869  else if (rank == 3) then
870  call mem_setptr(array3d_ptr, var_name, mem_path)
871  c_arr_ptr = c_loc(array3d_ptr)
872  else
873  write (bmi_last_error, fmt_unsupported_rank) trim(var_name)
874  call report_bmi_error(bmi_last_error)
875  bmi_status = bmi_failure
876  return
877  end if
878 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_value_ptr_int()

integer(kind=c_int) function mf6bmi::get_value_ptr_int ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
type(c_ptr), intent(inout)  c_arr_ptr 
)

The array is located at c_var_address. There is no copying of data involved. Multi-dimensional arrays are supported and the get_var_rank() function can be used to get the variable's dimensionality.

Parameters
[in]c_var_addressmemory address string of the variable
[in,out]c_arr_ptrpointer to the array
Returns
BMI status code

Definition at line 887 of file mf6bmi.f90.

889  !DIR$ ATTRIBUTES DLLEXPORT :: get_value_ptr_int
890  ! -- dummy variables
891  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
892  type(c_ptr), intent(inout) :: c_arr_ptr !< pointer to the array
893  integer(kind=c_int) :: bmi_status !< BMI status code
894  ! -- local variables
895  character(len=LENMEMPATH) :: mem_path
896  character(len=LENVARNAME) :: var_name
897  logical(LGP) :: valid
898  integer(I4B) :: rank
899  integer(I4B), pointer :: scalar_ptr
900  integer(I4B), dimension(:), pointer, contiguous :: array_ptr
901  integer(I4B), dimension(:, :), pointer, contiguous :: array2D_ptr
902  integer(I4B), dimension(:, :, :), pointer, contiguous :: array3D_ptr
903 
904  bmi_status = bmi_success
905 
906  call split_address(c_var_address, mem_path, var_name, valid)
907  if (.not. valid) then
908  bmi_status = bmi_failure
909  return
910  end if
911 
912  rank = -1
913  call get_mem_rank(var_name, mem_path, rank)
914 
915  if (rank == 0) then
916  call mem_setptr(scalar_ptr, var_name, mem_path)
917  c_arr_ptr = c_loc(scalar_ptr)
918  else if (rank == 1) then
919  call mem_setptr(array_ptr, var_name, mem_path)
920  c_arr_ptr = c_loc(array_ptr)
921  else if (rank == 2) then
922  call mem_setptr(array2d_ptr, var_name, mem_path)
923  c_arr_ptr = c_loc(array2d_ptr)
924  else if (rank == 3) then
925  call mem_setptr(array3d_ptr, var_name, mem_path)
926  c_arr_ptr = c_loc(array3d_ptr)
927  else
928  write (bmi_last_error, fmt_unsupported_rank) trim(var_name)
929  call report_bmi_error(bmi_last_error)
930  bmi_status = bmi_failure
931  return
932  end if
933 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_value_string()

integer(kind=c_int) function mf6bmi::get_value_string ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
type(c_ptr), intent(in)  c_arr_ptr 
)

The copied variable is located at c_var_address. The caller should provide c_arr_ptr pointing to an array of the proper shape (the BMI function get_var_shape() can be used to create it). For strings currently scalars and 1d arrays (of CharacterStringType) are

Parameters
[in]c_var_addressmemory address string of the variable
[in]c_arr_ptrpointer to the string array
Returns
BMI status code

Definition at line 658 of file mf6bmi.f90.

660  !DIR$ ATTRIBUTES DLLEXPORT :: get_value_string
661  ! -- modules
662  ! -- dummy variables
663  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
664  type(c_ptr), intent(in) :: c_arr_ptr !< pointer to the string array
665  integer(kind=c_int) :: bmi_status !< BMI status code
666  ! -- local variables
667  character(len=LENMEMPATH) :: mem_path
668  character(len=LENVARNAME) :: var_name
669  logical(LGP) :: valid
670  integer(I4B) :: rank
671  character(len=:), pointer :: srcstr
672  character(kind=c_char), pointer :: tgtstr(:)
673  type(CharacterStringType), dimension(:), pointer, contiguous :: srccharstr1d
674  character(kind=c_char), pointer :: tgtstr1d(:, :)
675  character(:), allocatable :: tempstr
676  integer(I4B) :: i, ilen, isize
677 
678  bmi_status = bmi_success
679 
680  call split_address(c_var_address, mem_path, var_name, valid)
681  if (.not. valid) then
682  bmi_status = bmi_failure
683  return
684  end if
685 
686  ! single string, or array of strings (CharacterStringType)
687  rank = -1
688  call get_mem_rank(var_name, mem_path, rank)
689 
690  if (rank == 0) then
691  ! a string scalar
692  call mem_setptr(srcstr, var_name, mem_path)
693  call get_mem_elem_size(var_name, mem_path, ilen)
694  call c_f_pointer(c_arr_ptr, tgtstr, shape=[ilen + 1])
695 
696  tgtstr(1:len(srcstr) + 1) = string_to_char_array(srcstr, len(srcstr))
697 
698  else if (rank == 1) then
699  ! an array of strings
700  call mem_setptr(srccharstr1d, var_name, mem_path)
701  if (.not. associated(srccharstr1d)) then
702  write (bmi_last_error, fmt_general_err) 'string type not supported in API'
703  call report_bmi_error(bmi_last_error)
704  bmi_status = bmi_failure
705  return
706  end if
707 
708  ! create fortran pointer to C data array
709  call get_isize(var_name, mem_path, isize)
710  call get_mem_elem_size(var_name, mem_path, ilen)
711  call c_f_pointer(c_arr_ptr, tgtstr1d, shape=[ilen + 1, isize])
712 
713  ! allocate work array to handle CharacterStringType,
714  ! and copy the strings
715  allocate (character(ilen) :: tempstr)
716  do i = 1, isize
717  tempstr = srccharstr1d(i)
718  tgtstr1d(1:ilen + 1, i) = string_to_char_array(tempstr, ilen)
719  end do
720  deallocate (tempstr)
721  else
722  write (bmi_last_error, fmt_unsupported_rank) trim(var_name)
723  call report_bmi_error(bmi_last_error)
724  bmi_status = bmi_failure
725  return
726  end if
727 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_var_itemsize()

integer(kind=c_int) function mf6bmi::get_var_itemsize ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
integer(kind=c_int), intent(out)  var_size 
)
Parameters
[in]c_var_addressmemory address string of the variable
[out]var_sizesize of the element in bytes
Returns
BMI status code

Definition at line 394 of file mf6bmi.f90.

396  !DIR$ ATTRIBUTES DLLEXPORT :: get_var_itemsize
397  ! -- dummy variables
398  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
399  integer(kind=c_int), intent(out) :: var_size !< size of the element in bytes
400  integer(kind=c_int) :: bmi_status !< BMI status code
401  ! -- local variables
402  character(len=LENMEMPATH) :: mem_path
403  character(len=LENVARNAME) :: var_name
404  logical(LGP) :: valid
405 
406  bmi_status = bmi_success
407 
408  call split_address(c_var_address, mem_path, var_name, valid)
409  if (.not. valid) then
410  bmi_status = bmi_failure
411  return
412  end if
413 
414  call get_mem_elem_size(var_name, mem_path, var_size)
415  if (var_size == -1) bmi_status = bmi_failure
416 
Here is the call graph for this function:

◆ get_var_location()

integer(kind=c_int) function mf6bmi::get_var_location ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
character(kind=c_char), dimension(bmi_lenvarlocation), intent(out)  c_var_location 
)

Every variable is reported at the grid nodes.

Parameters
[in]c_var_addressmemory address string of the variable
[out]c_var_locationvariable location as a string
Returns
BMI status code

Definition at line 1464 of file mf6bmi.f90.

1466  !DIR$ ATTRIBUTES DLLEXPORT :: get_var_location
1467  ! -- dummy variables
1468  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
1469  character(kind=c_char), intent(out) :: c_var_location(BMI_LENVARLOCATION) !< variable location as a string
1470  integer(kind=c_int) :: bmi_status !< BMI status code
1471  ! -- local variables
1472  character(len=LENMEMPATH) :: mem_path
1473  character(len=LENVARNAME) :: var_name
1474  character(len=*), parameter :: var_location = 'node'
1475  logical(LGP) :: valid
1476 
1477  bmi_status = bmi_failure
1478 
1479  call split_address(c_var_address, mem_path, var_name, valid)
1480  if (.not. valid) return
1481 
1482  c_var_location(1:len(var_location) + 1) = &
1483  string_to_char_array(var_location, len(var_location))
1484  bmi_status = bmi_success
1485 
Here is the call graph for this function:

◆ get_var_nbytes()

integer(kind=c_int) function mf6bmi::get_var_nbytes ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
integer(kind=c_int), intent(out)  var_nbytes 
)
Parameters
[in]c_var_addressmemory address string of the variable
[out]var_nbytessize in bytes
Returns
BMI status code

Definition at line 421 of file mf6bmi.f90.

423  !DIR$ ATTRIBUTES DLLEXPORT :: get_var_nbytes
424  ! -- dummy variables
425  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
426  integer(kind=c_int), intent(out) :: var_nbytes !< size in bytes
427  integer(kind=c_int) :: bmi_status !< BMI status code
428  ! -- local variables
429  integer(I4B) :: var_size, isize
430  character(len=LENMEMPATH) :: mem_path
431  character(len=LENVARNAME) :: var_name
432  logical(LGP) :: valid
433 
434  bmi_status = bmi_success
435 
436  call split_address(c_var_address, mem_path, var_name, valid)
437  if (.not. valid) then
438  bmi_status = bmi_failure
439  return
440  end if
441 
442  call get_mem_elem_size(var_name, mem_path, var_size)
443  if (var_size == -1) bmi_status = bmi_failure
444  call get_isize(var_name, mem_path, isize)
445  if (isize == -1) bmi_status = bmi_failure
446 
447  var_nbytes = var_size * isize
448 
Here is the call graph for this function:

◆ get_var_rank()

integer(kind=c_int) function mf6bmi::get_var_rank ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
integer(kind=c_int), intent(out)  c_var_rank 
)

In order to support multi-dimensional arrays, this function gives access to the rank of the array.

Parameters
[in]c_var_addressmemory address string of the variable
[out]c_var_rankvariable rank
Returns
BMI status code

Definition at line 1493 of file mf6bmi.f90.

1495  !DIR$ ATTRIBUTES DLLEXPORT :: get_var_rank
1496  ! -- dummy variables
1497  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
1498  integer(kind=c_int), intent(out) :: c_var_rank !< variable rank
1499  integer(kind=c_int) :: bmi_status !< BMI status code
1500  ! -- local variables
1501  character(len=LENMEMPATH) :: mem_path
1502  character(len=LENVARNAME) :: var_name
1503  logical(LGP) :: valid
1504 
1505  bmi_status = bmi_success
1506 
1507  call split_address(c_var_address, mem_path, var_name, valid)
1508  if (.not. valid) then
1509  bmi_status = bmi_failure
1510  return
1511  end if
1512 
1513  call get_mem_rank(var_name, mem_path, c_var_rank)
1514  if (c_var_rank == -1) then
1515  bmi_status = bmi_failure
1516  return
1517  end if
1518 
Here is the call graph for this function:

◆ get_var_shape()

integer(kind=c_int) function mf6bmi::get_var_shape ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
integer(c_int), dimension(*), intent(inout)  c_var_shape 
)

The shape is an integer array with size equal to the rank of the variable (see get_var_rank()) and values that give the length of the array in each dimension. The target shape array c_var_shape should be allocated before calling this routine.

Note that the returned shape representation will has been converted to C-style.

Parameters
[in]c_var_addressmemory address string of the variable
[in,out]c_var_shape1D array with the variable's shape
Returns
BMI status code

Definition at line 1531 of file mf6bmi.f90.

1533  !DIR$ ATTRIBUTES DLLEXPORT :: get_var_shape
1534  ! -- modules
1535  use constantsmodule, only: maxmemrank
1536  ! -- dummy variables
1537  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
1538  integer(c_int), intent(inout) :: c_var_shape(*) !< 1D array with the variable's shape
1539  integer(kind=c_int) :: bmi_status !< BMI status code
1540  ! -- local variables
1541  integer(I4B), dimension(MAXMEMRANK) :: var_shape
1542  integer(I4B) :: var_rank
1543  character(len=LENMEMPATH) :: mem_path
1544  character(len=LENVARNAME) :: var_name
1545  logical(LGP) :: valid
1546 
1547  bmi_status = bmi_success
1548 
1549  call split_address(c_var_address, mem_path, var_name, valid)
1550  if (.not. valid) then
1551  bmi_status = bmi_failure
1552  return
1553  end if
1554 
1555  var_shape = 0
1556  var_rank = 0
1557  call get_mem_rank(var_name, mem_path, var_rank)
1558  call get_mem_shape(var_name, mem_path, var_shape)
1559  if (var_shape(1) == -1 .or. var_rank == -1) then
1560  bmi_status = bmi_failure
1561  return
1562  end if
1563 
1564  ! External calls to this BMI are assumed C style, so if the internal shape
1565  ! is (100,1) we get (100,1,undef) from the call get_mem_shape
1566  ! This we need to convert to C-style which should be (1,100).
1567  ! Hence, we reverse the array and drop undef:
1568  c_var_shape(1:var_rank) = var_shape(var_rank:1:-1)
1569 
integer(i4b), parameter, public maxmemrank
maximum memory manager length (up to 3-dimensional arrays)
Definition: Constants.f90:61
Here is the call graph for this function:

◆ get_var_type()

integer(kind=c_int) function mf6bmi::get_var_type ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
character(kind=c_char), dimension(bmi_lenvartype), intent(out)  c_var_type 
)

The type returned is that of a single element. When the variable cannot be found, the string

Parameters
[in]c_var_addressmemory address string of the variable
[out]c_var_typevariable type as a string
Returns
BMI status code

Definition at line 1396 of file mf6bmi.f90.

1398  !DIR$ ATTRIBUTES DLLEXPORT :: get_var_type
1399  ! -- modules
1400  use constantsmodule, only: lenmemtype
1401  ! -- dummy variables
1402  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
1403  character(kind=c_char), intent(out) :: c_var_type(BMI_LENVARTYPE) !< variable type as a string
1404  integer(kind=c_int) :: bmi_status !< BMI status code
1405  ! -- local variables
1406  character(len=LENMEMPATH) :: mem_path
1407  character(len=LENVARNAME) :: var_name
1408  character(len=LENMEMTYPE) :: mem_type
1409  logical(LGP) :: valid
1410 
1411  bmi_status = bmi_success
1412 
1413  call split_address(c_var_address, mem_path, var_name, valid)
1414  if (.not. valid) then
1415  bmi_status = bmi_failure
1416  return
1417  end if
1418 
1419  call get_mem_type(var_name, mem_path, mem_type)
1420  c_var_type(1:len(trim(mem_type)) + 1) = &
1421  string_to_char_array(trim(mem_type), len(trim(mem_type)))
1422 
1423  if (mem_type == 'UNKNOWN') then
1424  write (bmi_last_error, fmt_general_err) 'unknown memory type'
1425  call report_bmi_error(bmi_last_error)
1426  bmi_status = bmi_failure
1427  end if
1428 
Here is the call graph for this function:

◆ get_var_units()

integer(kind=c_int) function mf6bmi::get_var_units ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
character(kind=c_char), dimension(bmi_lenunits), intent(out)  c_var_units 
)

The memory manager does not store units, so 'unknown' is returned for every variable.

Parameters
[in]c_var_addressmemory address string of the variable
[out]c_var_unitsvariable units as a string
Returns
BMI status code

Definition at line 1436 of file mf6bmi.f90.

1438  !DIR$ ATTRIBUTES DLLEXPORT :: get_var_units
1439  ! -- dummy variables
1440  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
1441  character(kind=c_char), intent(out) :: c_var_units(BMI_LENUNITS) !< variable units as a string
1442  integer(kind=c_int) :: bmi_status !< BMI status code
1443  ! -- local variables
1444  character(len=LENMEMPATH) :: mem_path
1445  character(len=LENVARNAME) :: var_name
1446  character(len=*), parameter :: var_units = 'unknown'
1447  logical(LGP) :: valid
1448 
1449  bmi_status = bmi_failure
1450 
1451  call split_address(c_var_address, mem_path, var_name, valid)
1452  if (.not. valid) return
1453 
1454  c_var_units(1:len(var_units) + 1) = &
1455  string_to_char_array(var_units, len(var_units))
1456  bmi_status = bmi_success
1457 
Here is the call graph for this function:

◆ set_value()

integer(kind=c_int) function mf6bmi::set_value ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
type(c_ptr), intent(inout)  c_arr_ptr 
)

The array pointed to by c_arr_ptr can have rank equal to 0, 1, or 2 and should have a C-style layout, which is particularly important for rank > 1.

Parameters
[in]c_var_addressmemory address string of the variable
[in,out]c_arr_ptrpointer to the array
Returns
BMI status code

Definition at line 982 of file mf6bmi.f90.

984  !DIR$ ATTRIBUTES DLLEXPORT :: set_value
985  ! -- modules
986  use constantsmodule, only: lenmemtype
987  ! -- dummy variables
988  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
989  type(c_ptr), intent(inout) :: c_arr_ptr !< pointer to the array
990  integer(kind=c_int) :: bmi_status !< BMI status code
991  ! -- local variables
992  character(len=LENMEMPATH) :: mem_path
993  character(len=LENMEMTYPE) :: mem_type
994  character(len=LENVARNAME) :: var_name
995  logical(LGP) :: valid
996 
997  bmi_status = bmi_success
998 
999  call split_address(c_var_address, mem_path, var_name, valid)
1000  if (.not. valid) then
1001  bmi_status = bmi_failure
1002  return
1003  end if
1004 
1005  call get_mem_type(var_name, mem_path, mem_type)
1006 
1007  if (index(mem_type, "DOUBLE") /= 0) then
1008  bmi_status = set_value_double(c_var_address, c_arr_ptr)
1009  else if (index(mem_type, "INTEGER") /= 0) then
1010  bmi_status = set_value_int(c_var_address, c_arr_ptr)
1011  else if (index(mem_type, "LOGICAL") /= 0) then
1012  bmi_status = set_value_bool(c_var_address, c_arr_ptr)
1013  else
1014  write (bmi_last_error, fmt_unsupported_type) trim(var_name)
1015  call report_bmi_error(bmi_last_error)
1016  bmi_status = bmi_failure
1017  return
1018  end if
1019 
Here is the call graph for this function:

◆ set_value_at_indices()

integer(kind=c_int) function mf6bmi::set_value_at_indices ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
integer(kind=c_int), dimension(*), intent(in)  c_inds,
integer(kind=c_int), intent(in)  count,
type(c_ptr), intent(in)  c_arr_ptr 
)

The indices are zero-based positions in the variable's values in C-style (row-major) order, as in get_value_at_indices(). The array pointed to by c_arr_ptr holds count values. Double precision and integer variables are supported. A new hydraulic conductivity does not change the saturated conductance until NPF recalculates it, as it does for TVK.

Parameters
[in]c_var_addressmemory address string of the variable
[in]c_indszero-based indices of the values
[in]countnumber of indices
[in]c_arr_ptrpointer to the array with the new values
Returns
BMI status code

Definition at line 1294 of file mf6bmi.f90.

1296  !DIR$ ATTRIBUTES DLLEXPORT :: set_value_at_indices
1297  ! -- modules
1298  use constantsmodule, only: lenmemtype
1300  ! -- dummy variables
1301  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
1302  integer(kind=c_int), intent(in) :: c_inds(*) !< zero-based indices of the values
1303  integer(kind=c_int), intent(in) :: count !< number of indices
1304  type(c_ptr), intent(in) :: c_arr_ptr !< pointer to the array with the new values
1305  integer(kind=c_int) :: bmi_status !< BMI status code
1306  ! -- local variables
1307  character(len=LENMEMPATH) :: mem_path
1308  character(len=LENMEMTYPE) :: mem_type
1309  character(len=LENVARNAME) :: var_name
1310  logical(LGP) :: valid
1311  integer(I4B) :: i, nvalues, status
1312  type(c_ptr) :: var_ptr
1313  real(DP), dimension(:), pointer, contiguous :: src_dbl, tgt_dbl
1314  integer(I4B), dimension(:), pointer, contiguous :: src_int, tgt_int
1315 
1316  bmi_status = bmi_failure
1317 
1318  call split_address(c_var_address, mem_path, var_name, valid)
1319  if (.not. valid) return
1320  if (.not. valid_indices(mem_path, var_name, c_inds, count, nvalues)) return
1321 
1322  ! -- the variable's storage, viewed as a flat array in memory order
1323  call get_mem_type(var_name, mem_path, mem_type)
1324  if (index(mem_type, "DOUBLE") /= 0) then
1325  if (get_value_ptr_double(c_var_address, var_ptr) /= bmi_success) return
1326  call c_f_pointer(var_ptr, tgt_dbl, [nvalues])
1327  call c_f_pointer(c_arr_ptr, src_dbl, [count])
1328  do i = 1, count
1329  tgt_dbl(c_inds(i) + 1) = src_dbl(i)
1330  end do
1331  else if (index(mem_type, "INTEGER") /= 0) then
1332  if (get_value_ptr_int(c_var_address, var_ptr) /= bmi_success) return
1333  call c_f_pointer(var_ptr, tgt_int, [nvalues])
1334  call c_f_pointer(c_arr_ptr, src_int, [count])
1335  do i = 1, count
1336  tgt_int(c_inds(i) + 1) = src_int(i)
1337  end do
1338  else
1339  write (bmi_last_error, fmt_unsupported_type) trim(var_name)
1340  call report_bmi_error(bmi_last_error)
1341  return
1342  end if
1343 
1344  ! trigger event:
1345  call on_memory_set(var_name, mem_path, status)
1346  if (status /= 0) then
1347  write (bmi_last_error, fmt_invalid_mem_access) trim(var_name)
1348  call report_bmi_error(bmi_last_error)
1349  return
1350  end if
1351 
1352  bmi_status = bmi_success
1353 
Here is the call graph for this function:

◆ set_value_bool()

integer(kind=c_int) function mf6bmi::set_value_bool ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
type(c_ptr), intent(in)  c_arr_ptr 
)

The array pointed to by c_arr_ptr must have a rank equal to 0.

Parameters
[in]c_var_addressmemory address string of the variable
[in]c_arr_ptrpointer to the logical array
Returns
BMI status code

Definition at line 1174 of file mf6bmi.f90.

1176  !DIR$ ATTRIBUTES DLLEXPORT :: set_value_bool
1177  ! -- modules
1179  ! -- dummy variables
1180  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
1181  type(c_ptr), intent(in) :: c_arr_ptr !< pointer to the logical array
1182  integer(kind=c_int) :: bmi_status !< BMI status code
1183  ! -- local variables
1184  character(len=LENMEMPATH) :: mem_path
1185  character(len=LENVARNAME) :: var_name
1186  logical(LGP) :: valid
1187  integer(I4B) :: rank
1188  logical(LGP), pointer :: src_ptr, tgt_ptr
1189  integer(I4B) :: status
1190 
1191  bmi_status = bmi_success
1192 
1193  call split_address(c_var_address, mem_path, var_name, valid)
1194  if (.not. valid) then
1195  bmi_status = bmi_failure
1196  return
1197  end if
1198 
1199  rank = -1
1200  call get_mem_rank(var_name, mem_path, rank)
1201 
1202  ! convert pointer
1203  if (rank == 0) then
1204  call mem_setptr(tgt_ptr, var_name, mem_path)
1205  call c_f_pointer(c_arr_ptr, src_ptr)
1206  tgt_ptr = src_ptr
1207  else
1208  write (bmi_last_error, fmt_unsupported_rank) trim(var_name)
1209  call report_bmi_error(bmi_last_error)
1210  bmi_status = bmi_failure
1211  return
1212  end if
1213 
1214  ! trigger event:
1215  call on_memory_set(var_name, mem_path, status)
1216  if (status /= 0) then
1217  ! something went terribly wrong here, aborting
1218  write (bmi_last_error, fmt_invalid_mem_access) trim(var_name)
1219  call report_bmi_error(bmi_last_error)
1220  bmi_status = bmi_failure
1221  return
1222  end if
1223 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_value_double()

integer(kind=c_int) function mf6bmi::set_value_double ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
type(c_ptr), intent(in)  c_arr_ptr 
)

The array pointed to by c_arr_ptr can have rank equal to 0, 1, or 2 and should have a C-style layout, which is particularly important for rank > 1.

Parameters
[in]c_var_addressmemory address string of the variable
[in]c_arr_ptrpointer to the double precision array
Returns
BMI status code

Definition at line 1028 of file mf6bmi.f90.

1030  !DIR$ ATTRIBUTES DLLEXPORT :: set_value_double
1031  ! -- modules
1033  ! -- dummy variables
1034  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
1035  type(c_ptr), intent(in) :: c_arr_ptr !< pointer to the double precision array
1036  integer(kind=c_int) :: bmi_status !< BMI status code
1037  ! -- local variables
1038  character(len=LENMEMPATH) :: mem_path
1039  character(len=LENVARNAME) :: var_name
1040  logical(LGP) :: valid
1041  integer(I4B) :: rank
1042  real(DP), pointer :: src_ptr, tgt_ptr
1043  real(DP), dimension(:), pointer, contiguous :: src1D_ptr, tgt1D_ptr
1044  real(DP), dimension(:, :), pointer, contiguous :: src2D_ptr, tgt2D_ptr
1045  integer(I4B) :: i, j
1046  integer(I4B) :: status
1047 
1048  bmi_status = bmi_success
1049 
1050  call split_address(c_var_address, mem_path, var_name, valid)
1051  if (.not. valid) then
1052  bmi_status = bmi_failure
1053  return
1054  end if
1055 
1056  ! convert pointer and copy, using loops to avoid stack overflow
1057  rank = -1
1058  call get_mem_rank(var_name, mem_path, rank)
1059 
1060  if (rank == 0) then
1061  call mem_setptr(tgt_ptr, var_name, mem_path)
1062  call c_f_pointer(c_arr_ptr, src_ptr)
1063  tgt_ptr = src_ptr
1064  else if (rank == 1) then
1065  call mem_setptr(tgt1d_ptr, var_name, mem_path)
1066  call c_f_pointer(c_arr_ptr, src1d_ptr, shape(tgt1d_ptr))
1067  do i = 1, size(tgt1d_ptr)
1068  tgt1d_ptr(i) = src1d_ptr(i)
1069  end do
1070  else if (rank == 2) then
1071  call mem_setptr(tgt2d_ptr, var_name, mem_path)
1072  call c_f_pointer(c_arr_ptr, src2d_ptr, shape(tgt2d_ptr))
1073  do j = 1, size(tgt2d_ptr, 2)
1074  do i = 1, size(tgt2d_ptr, 1)
1075  tgt2d_ptr(i, j) = src2d_ptr(i, j)
1076  end do
1077  end do
1078  else
1079  write (bmi_last_error, fmt_unsupported_rank) trim(var_name)
1080  call report_bmi_error(bmi_last_error)
1081  bmi_status = bmi_failure
1082  return
1083  end if
1084 
1085  ! trigger event:
1086  call on_memory_set(var_name, mem_path, status)
1087  if (status /= 0) then
1088  ! something went terribly wrong here, aborting
1089  write (bmi_last_error, fmt_invalid_mem_access) trim(var_name)
1090  call report_bmi_error(bmi_last_error)
1091  bmi_status = bmi_failure
1092  return
1093  end if
1094 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_value_int()

integer(kind=c_int) function mf6bmi::set_value_int ( character(kind=c_char), dimension(*), intent(in)  c_var_address,
type(c_ptr), intent(in)  c_arr_ptr 
)

The array pointed to by c_arr_ptr can have rank equal to 0, 1, or 2.

Parameters
[in]c_var_addressmemory address string of the variable
[in]c_arr_ptrpointer to the integer array
Returns
BMI status code

Definition at line 1101 of file mf6bmi.f90.

1103  !DIR$ ATTRIBUTES DLLEXPORT :: set_value_int
1104  ! -- modules
1106  ! -- dummy variables
1107  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
1108  type(c_ptr), intent(in) :: c_arr_ptr !< pointer to the integer array
1109  integer(kind=c_int) :: bmi_status !< BMI status code
1110  ! -- local variables
1111  character(len=LENMEMPATH) :: mem_path
1112  character(len=LENVARNAME) :: var_name
1113  logical(LGP) :: valid
1114  integer(I4B) :: rank
1115  integer(I4B), pointer :: src_ptr, tgt_ptr
1116  integer(I4B), dimension(:), pointer, contiguous :: src1D_ptr, tgt1D_ptr
1117  integer(I4B), dimension(:, :), pointer, contiguous :: src2D_ptr, tgt2D_ptr
1118  integer(I4B) :: i, j
1119  integer(I4B) :: status
1120 
1121  bmi_status = bmi_success
1122 
1123  call split_address(c_var_address, mem_path, var_name, valid)
1124  if (.not. valid) then
1125  bmi_status = bmi_failure
1126  return
1127  end if
1128 
1129  ! convert pointer and copy, using loops to avoid stack overflow
1130  rank = -1
1131  call get_mem_rank(var_name, mem_path, rank)
1132 
1133  if (rank == 0) then
1134  call mem_setptr(tgt_ptr, var_name, mem_path)
1135  call c_f_pointer(c_arr_ptr, src_ptr)
1136  tgt_ptr = src_ptr
1137  else if (rank == 1) then
1138  call mem_setptr(tgt1d_ptr, var_name, mem_path)
1139  call c_f_pointer(c_arr_ptr, src1d_ptr, shape(tgt1d_ptr))
1140  do i = 1, size(tgt1d_ptr)
1141  tgt1d_ptr(i) = src1d_ptr(i)
1142  end do
1143  else if (rank == 2) then
1144  call mem_setptr(tgt2d_ptr, var_name, mem_path)
1145  call c_f_pointer(c_arr_ptr, src2d_ptr, shape(tgt2d_ptr))
1146  do j = 1, size(tgt2d_ptr, 2)
1147  do i = 1, size(tgt2d_ptr, 1)
1148  tgt2d_ptr(i, j) = src2d_ptr(i, j)
1149  end do
1150  end do
1151  else
1152  write (bmi_last_error, fmt_unsupported_rank) trim(var_name)
1153  call report_bmi_error(bmi_last_error)
1154  bmi_status = bmi_failure
1155  return
1156  end if
1157 
1158  ! trigger event:
1159  call on_memory_set(var_name, mem_path, status)
1160  if (status /= 0) then
1161  ! something went terribly wrong here, aborting
1162  write (bmi_last_error, fmt_invalid_mem_access) trim(var_name)
1163  call report_bmi_error(bmi_last_error)
1164  bmi_status = bmi_failure
1165  return
1166  end if
1167 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ valid_indices()

logical(lgp) function mf6bmi::valid_indices ( character(len=*), intent(in)  mem_path,
character(len=*), intent(in)  var_name,
integer(kind=c_int), dimension(*), intent(in)  c_inds,
integer(kind=c_int), intent(in)  count,
integer(i4b), intent(out)  nvalues 
)
Parameters
[in]mem_pathmemory path of the variable
[in]var_namename of the variable
[in]c_indszero-based indices
[in]countnumber of indices
[out]nvaluesnumber of values in the variable
Returns
true when all indices are valid

Definition at line 1358 of file mf6bmi.f90.

1360  ! -- dummy variables
1361  character(len=*), intent(in) :: mem_path !< memory path of the variable
1362  character(len=*), intent(in) :: var_name !< name of the variable
1363  integer(kind=c_int), intent(in) :: c_inds(*) !< zero-based indices
1364  integer(kind=c_int), intent(in) :: count !< number of indices
1365  integer(I4B), intent(out) :: nvalues !< number of values in the variable
1366  logical(LGP) :: valid !< true when all indices are valid
1367  ! -- local variables
1368  integer(I4B) :: i, rank
1369 
1370  valid = .false.
1371  rank = -1
1372  call get_mem_rank(var_name, mem_path, rank)
1373  if (rank < 0 .or. rank > 3) then
1374  write (bmi_last_error, fmt_unsupported_rank) trim(var_name)
1375  call report_bmi_error(bmi_last_error)
1376  return
1377  end if
1378 
1379  call get_isize(var_name, mem_path, nvalues)
1380  do i = 1, count
1381  if (c_inds(i) < 0 .or. c_inds(i) >= nvalues) then
1382  write (bmi_last_error, fmt_invalid_index) c_inds(i), trim(var_name)
1383  call report_bmi_error(bmi_last_error)
1384  return
1385  end if
1386  end do
1387  valid = .true.
1388 
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ istdout_to_file

integer(c_int), bind(C, name="ISTDOUTTOFILE") mf6bmi::istdout_to_file = 1

Definition at line 38 of file mf6bmi.f90.

38  integer(c_int), bind(C, name="ISTDOUTTOFILE") :: istdout_to_file = 1 !< output control: =0 to screen, >0 to file