MODFLOW 6  version 6.6.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_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_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_var_type (c_var_address, c_var_type)
 Get the variable type as a string. 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 112 of file mf6bmi.f90.

113  !DIR$ ATTRIBUTES DLLEXPORT :: bmi_finalize
114  ! -- modules
115  use simvariablesmodule, only: iforcestop
116  ! -- dummy variables
117  integer(kind=c_int) :: bmi_status !< BMI status code
118 
119  ! we don't want a full stop() here, this disables it:
120  iforcestop = 0
121  call mf6finalize()
122 
123  bmi_status = bmi_success
124 
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 
51  name = string_to_char_array('MODFLOW 6', 9)
52  bmi_status = bmi_success
53 
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 66 of file mf6bmi.f90.

67  !DIR$ ATTRIBUTES DLLEXPORT :: bmi_initialize
68  ! -- dummy variables
69  integer(kind=c_int) :: bmi_status !< BMI status code
70  ! -- local variables
71 
72  if (istdout_to_file > 0) then
73  ! -- open stdout file mfsim.stdout
74  istdout = getunit()
75  !
76  ! -- set STDOUT to a physical file unit
77  open (unit=istdout, file=simstdout)
78  end if
79  !
80  ! -- initialize MODFLOW 6
81  call mf6initialize()
82 
83  bmi_status = bmi_success
84 
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 95 of file mf6bmi.f90.

96  !DIR$ ATTRIBUTES DLLEXPORT :: bmi_update
97  ! -- dummy variables
98  integer(kind=c_int) :: bmi_status !< BMI status code
99  ! -- local variables
100  logical :: hasConverged
101 
102  hasconverged = mf6update()
103 
104  bmi_status = bmi_success
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 167 of file mf6bmi.f90.

169  !DIR$ ATTRIBUTES DLLEXPORT :: get_current_time
170  ! -- modules
171  use tdismodule, only: totim
172  ! -- dummy variables
173  real(kind=c_double), intent(out) :: current_time !< current time
174  integer(kind=c_int) :: bmi_status !< BMI status code
175 
176  current_time = totim
177  bmi_status = bmi_success
178 
real(dp), pointer, public totim
time relative to start of simulation
Definition: tdis.f90:32

◆ 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 149 of file mf6bmi.f90.

150  !DIR$ ATTRIBUTES DLLEXPORT :: get_end_time
151  ! -- modules
152  use tdismodule, only: totalsimtime
153  ! -- dummy variables
154  real(kind=c_double), intent(out) :: end_time !< end time
155  integer(kind=c_int) :: bmi_status !< BMI status code
156 
157  end_time = totalsimtime
158  bmi_status = bmi_success
159 
real(dp), pointer, public totalsimtime
time at end of simulation
Definition: tdis.f90:37

◆ 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 204 of file mf6bmi.f90.

206  !DIR$ ATTRIBUTES DLLEXPORT :: get_input_item_count
207  ! -- dummy variables
208  integer(kind=c_int), intent(out) :: count !< the number of input variables
209  integer(kind=c_int) :: bmi_status !< BMI status code
210 
211  count = memorystore%count()
212 
213  bmi_status = bmi_success
214 

◆ 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 248 of file mf6bmi.f90.

250  !DIR$ ATTRIBUTES DLLEXPORT :: get_input_var_names
251  ! -- dummy variables
252  character(kind=c_char, len=1), intent(inout) :: c_names(*) !< array with memory paths for input variables
253  integer(kind=c_int) :: bmi_status !< BMI status code
254  ! -- local variables
255  integer(I4B) :: start, i
256  type(MemoryContainerIteratorType), allocatable :: itr
257  type(MemoryType), pointer :: mt => null()
258  character(len=LENMEMADDRESS) :: var_address
259 
260  start = 1
261  itr = memorystore%iterator()
262  do while (itr%has_next())
263  call itr%next()
264  mt => itr%value()
265  var_address = create_mem_address(mt%path, mt%name)
266  do i = 1, len(trim(var_address))
267  c_names(start + i - 1) = var_address(i:i)
268  end do
269  c_names(start + i) = c_null_char
270  start = start + bmi_lenvaraddress
271  end do
272 
273  bmi_status = bmi_success
274 
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 221 of file mf6bmi.f90.

223  !DIR$ ATTRIBUTES DLLEXPORT :: get_output_item_count
224  ! -- dummy variables
225  integer(kind=c_int), intent(out) :: count !< the number of output variables
226  integer(kind=c_int) :: bmi_status !< BMI status code
227 
228  count = memorystore%count()
229 
230  bmi_status = bmi_success
231 

◆ 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 283 of file mf6bmi.f90.

285  !DIR$ ATTRIBUTES DLLEXPORT :: get_output_var_names
286  ! -- dummy variables
287  character(kind=c_char, len=1), intent(inout) :: c_names(*) !< array with memory paths for output variables
288  integer(kind=c_int) :: bmi_status !< BMI status code
289  ! -- local variables
290  integer(I4B) :: start, i
291  type(MemoryContainerIteratorType), allocatable :: itr
292  type(MemoryType), pointer :: mt => null()
293  character(len=LENMEMADDRESS) :: var_address
294 
295  start = 1
296  itr = memorystore%iterator()
297  do while (itr%has_next())
298  call itr%next()
299  mt => itr%value()
300  var_address = create_mem_address(mt%path, mt%name)
301  do i = 1, len(trim(var_address))
302  c_names(start + i - 1) = var_address(i:i)
303  end do
304  c_names(start + i) = c_null_char
305  start = start + bmi_lenvaraddress
306  end do
307 
308  bmi_status = bmi_success
309 
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 132 of file mf6bmi.f90.

134  !DIR$ ATTRIBUTES DLLEXPORT :: get_start_time
135  ! -- dummy variables
136  real(kind=c_double), intent(out) :: start_time !< start time
137  integer(kind=c_int) :: bmi_status !< BMI status code
138 
139  start_time = 0.0_dp
140  bmi_status = bmi_success
141 

◆ 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 186 of file mf6bmi.f90.

188  !DIR$ ATTRIBUTES DLLEXPORT :: get_time_step
189  ! -- modules
190  use tdismodule, only: delt
191  ! -- dummy variables
192  real(kind=c_double), intent(out) :: time_step !< current time step
193  integer(kind=c_int) :: bmi_status !< BMI status code
194 
195  time_step = delt
196  bmi_status = bmi_success
197 
real(dp), pointer, public delt
length of the current time step
Definition: tdis.f90:29

◆ 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 657 of file mf6bmi.f90.

659  !DIR$ ATTRIBUTES DLLEXPORT :: get_value
660  ! -- modules
661  use constantsmodule, only: lenmemtype
662  ! -- dummy variables
663  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
664  type(c_ptr), intent(inout) :: c_arr_ptr !< pointer to the array
665  integer(kind=c_int) :: bmi_status !< BMI status code
666  ! -- local variables
667  character(len=LENMEMPATH) :: mem_path
668  character(len=LENMEMTYPE) :: mem_type
669  character(len=LENVARNAME) :: var_name
670  logical(LGP) :: valid
671 
672  bmi_status = bmi_success
673 
674  call split_address(c_var_address, mem_path, var_name, valid)
675  if (.not. valid) then
676  bmi_status = bmi_failure
677  return
678  end if
679 
680  call get_mem_type(var_name, mem_path, mem_type)
681 
682  if (index(mem_type, "DOUBLE") /= 0) then
683  bmi_status = get_value_double(c_var_address, c_arr_ptr)
684  else if (index(mem_type, "INTEGER") /= 0) then
685  bmi_status = get_value_int(c_var_address, c_arr_ptr)
686  else if (index(mem_type, "LOGICAL") /= 0) then
687  bmi_status = get_value_bool(c_var_address, c_arr_ptr)
688  else if (index(mem_type, "STRING") /= 0) then
689  bmi_status = get_value_string(c_var_address, c_arr_ptr)
690  else
691  write (bmi_last_error, fmt_unsupported_type) trim(var_name)
692  call report_bmi_error(bmi_last_error)
693  bmi_status = bmi_failure
694  return
695  end if
696 
This module contains simulation constants.
Definition: Constants.f90:9
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_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 530 of file mf6bmi.f90.

532  !DIR$ ATTRIBUTES DLLEXPORT :: get_value_bool
533  ! -- modules
535  ! -- dummy variables
536  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
537  type(c_ptr), intent(in) :: c_arr_ptr !< pointer to the logical array
538  integer(kind=c_int) :: bmi_status !< BMI status code
539  ! -- local variables
540  character(len=LENMEMPATH) :: mem_path
541  character(len=LENVARNAME) :: var_name
542  logical(LGP) :: valid
543  integer(I4B) :: rank
544  logical(LGP), pointer :: src_ptr, tgt_ptr
545 
546  bmi_status = bmi_success
547 
548  call split_address(c_var_address, mem_path, var_name, valid)
549  if (.not. valid) then
550  bmi_status = bmi_failure
551  return
552  end if
553 
554  rank = -1
555  call get_mem_rank(var_name, mem_path, rank)
556 
557  ! convert pointer
558  if (rank == 0) then
559  call mem_setptr(src_ptr, var_name, mem_path)
560  call c_f_pointer(c_arr_ptr, tgt_ptr)
561  tgt_ptr = src_ptr
562  else
563  write (bmi_last_error, fmt_unsupported_rank) trim(var_name)
564  call report_bmi_error(bmi_last_error)
565  bmi_status = bmi_failure
566  return
567  end if
568 
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 378 of file mf6bmi.f90.

380  !DIR$ ATTRIBUTES DLLEXPORT :: get_value_double
381  ! -- modules
383  ! -- dummy variables
384  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
385  type(c_ptr), intent(in) :: c_arr_ptr !< pointer to the double precision array
386  integer(kind=c_int) :: bmi_status !< BMI status code
387  ! -- local variables
388  character(len=LENMEMPATH) :: mem_path
389  character(len=LENVARNAME) :: var_name
390  logical(LGP) :: valid
391  integer(I4B) :: rank
392  real(DP), pointer :: src_ptr, tgt_ptr
393  real(DP), dimension(:), pointer, contiguous :: src1D_ptr, tgt1D_ptr
394  real(DP), dimension(:, :), pointer, contiguous :: src2D_ptr, tgt2D_ptr
395  real(DP), dimension(:, :, :), pointer, contiguous :: src3D_ptr, tgt3D_ptr
396  integer(I4B) :: i, j, k
397 
398  bmi_status = bmi_success
399 
400  call split_address(c_var_address, mem_path, var_name, valid)
401  if (.not. valid) then
402  bmi_status = bmi_failure
403  return
404  end if
405 
406  ! convert pointer and copy data from memory manager into
407  ! the passed array, using loops to avoid stack overflow
408  rank = -1
409  call get_mem_rank(var_name, mem_path, rank)
410 
411  if (rank == 0) then
412  call mem_setptr(src_ptr, var_name, mem_path)
413  call c_f_pointer(c_arr_ptr, tgt_ptr)
414  tgt_ptr = src_ptr
415  else if (rank == 1) then
416  call mem_setptr(src1d_ptr, var_name, mem_path)
417  call c_f_pointer(c_arr_ptr, tgt1d_ptr, shape(src1d_ptr))
418  do i = 1, size(tgt1d_ptr)
419  tgt1d_ptr(i) = src1d_ptr(i)
420  end do
421  else if (rank == 2) then
422  call mem_setptr(src2d_ptr, var_name, mem_path)
423  call c_f_pointer(c_arr_ptr, tgt2d_ptr, shape(src2d_ptr))
424  do j = 1, size(tgt2d_ptr, 2)
425  do i = 1, size(tgt2d_ptr, 1)
426  tgt2d_ptr(i, j) = src2d_ptr(i, j)
427  end do
428  end do
429  else if (rank == 3) then
430  call mem_setptr(src3d_ptr, var_name, mem_path)
431  call c_f_pointer(c_arr_ptr, tgt3d_ptr, shape(src3d_ptr))
432  do k = 1, size(tgt3d_ptr, 3)
433  do j = 1, size(tgt3d_ptr, 2)
434  do i = 1, size(tgt3d_ptr, 1)
435  tgt3d_ptr(i, j, k) = src3d_ptr(i, j, k)
436  end do
437  end do
438  end do
439  else
440  write (bmi_last_error, fmt_unsupported_rank) trim(var_name)
441  call report_bmi_error(bmi_last_error)
442  bmi_status = bmi_failure
443  return
444  end if
445 
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 455 of file mf6bmi.f90.

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

708  !DIR$ ATTRIBUTES DLLEXPORT :: get_value_ptr
709  ! -- modules
710  use constantsmodule, only: lenmemtype
711  ! -- dummy variables
712  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
713  type(c_ptr), intent(inout) :: c_arr_ptr !< pointer to the array
714  integer(kind=c_int) :: bmi_status !< BMI status code
715  ! -- local variables
716  character(len=LENMEMPATH) :: mem_path
717  character(len=LENMEMTYPE) :: mem_type
718  character(len=LENVARNAME) :: var_name
719  logical(LGP) :: valid
720 
721  bmi_status = bmi_success
722 
723  call split_address(c_var_address, mem_path, var_name, valid)
724  if (.not. valid) then
725  bmi_status = bmi_failure
726  return
727  end if
728 
729  call get_mem_type(var_name, mem_path, mem_type)
730 
731  if (index(mem_type, "DOUBLE") /= 0) then
732  bmi_status = get_value_ptr_double(c_var_address, c_arr_ptr)
733  else if (index(mem_type, "INTEGER") /= 0) then
734  bmi_status = get_value_ptr_int(c_var_address, c_arr_ptr)
735  else if (index(mem_type, "LOGICAL") /= 0) then
736  bmi_status = get_value_ptr_bool(c_var_address, c_arr_ptr)
737  else
738  write (bmi_last_error, fmt_unsupported_type) trim(var_name)
739  call report_bmi_error(bmi_last_error)
740  bmi_status = bmi_failure
741  return
742  end if
743 
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 860 of file mf6bmi.f90.

862  !DIR$ ATTRIBUTES DLLEXPORT :: get_value_ptr_bool
863  ! -- dummy variables
864  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
865  type(c_ptr), intent(inout) :: c_arr_ptr !< pointer to the array
866  integer(kind=c_int) :: bmi_status !< BMI status code
867  ! -- local variables
868  character(len=LENMEMPATH) :: mem_path
869  character(len=LENVARNAME) :: var_name
870  logical(LGP) :: valid
871  logical(LGP), pointer :: scalar_ptr
872  integer(I4B) :: rank
873 
874  bmi_status = bmi_success
875 
876  call split_address(c_var_address, mem_path, var_name, valid)
877  if (.not. valid) then
878  bmi_status = bmi_failure
879  return
880  end if
881 
882  rank = -1
883  call get_mem_rank(var_name, mem_path, rank)
884  if (rank == 0) then
885  call mem_setptr(scalar_ptr, var_name, mem_path)
886  c_arr_ptr = c_loc(scalar_ptr)
887  else
888  write (bmi_last_error, fmt_unsupported_rank) trim(var_name)
889  call report_bmi_error(bmi_last_error)
890  bmi_status = bmi_failure
891  return
892  end if
893 
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 753 of file mf6bmi.f90.

755  !DIR$ ATTRIBUTES DLLEXPORT :: get_value_ptr_double
756  ! -- dummy variables
757  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
758  type(c_ptr), intent(inout) :: c_arr_ptr !< pointer to the array
759  integer(kind=c_int) :: bmi_status !< BMI status code
760  ! -- local variables
761  character(len=LENMEMPATH) :: mem_path
762  character(len=LENVARNAME) :: var_name
763  logical(LGP) :: valid
764  real(DP), pointer :: scalar_ptr
765  real(DP), dimension(:), pointer, contiguous :: array_ptr
766  real(DP), dimension(:, :), pointer, contiguous :: array2D_ptr
767  real(DP), dimension(:, :, :), pointer, contiguous :: array3D_ptr
768  integer(I4B) :: rank
769 
770  bmi_status = bmi_success
771 
772  call split_address(c_var_address, mem_path, var_name, valid)
773  if (.not. valid) then
774  bmi_status = bmi_failure
775  return
776  end if
777 
778  rank = -1
779  call get_mem_rank(var_name, mem_path, rank)
780  if (rank == 0) then
781  call mem_setptr(scalar_ptr, var_name, mem_path)
782  c_arr_ptr = c_loc(scalar_ptr)
783  else if (rank == 1) then
784  call mem_setptr(array_ptr, var_name, mem_path)
785  c_arr_ptr = c_loc(array_ptr)
786  else if (rank == 2) then
787  call mem_setptr(array2d_ptr, var_name, mem_path)
788  c_arr_ptr = c_loc(array2d_ptr)
789  else if (rank == 3) then
790  call mem_setptr(array3d_ptr, var_name, mem_path)
791  c_arr_ptr = c_loc(array3d_ptr)
792  else
793  write (bmi_last_error, fmt_unsupported_rank) trim(var_name)
794  call report_bmi_error(bmi_last_error)
795  bmi_status = bmi_failure
796  return
797  end if
798 
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 807 of file mf6bmi.f90.

809  !DIR$ ATTRIBUTES DLLEXPORT :: get_value_ptr_int
810  ! -- dummy variables
811  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
812  type(c_ptr), intent(inout) :: c_arr_ptr !< pointer to the array
813  integer(kind=c_int) :: bmi_status !< BMI status code
814  ! -- local variables
815  character(len=LENMEMPATH) :: mem_path
816  character(len=LENVARNAME) :: var_name
817  logical(LGP) :: valid
818  integer(I4B) :: rank
819  integer(I4B), pointer :: scalar_ptr
820  integer(I4B), dimension(:), pointer, contiguous :: array_ptr
821  integer(I4B), dimension(:, :), pointer, contiguous :: array2D_ptr
822  integer(I4B), dimension(:, :, :), pointer, contiguous :: array3D_ptr
823 
824  bmi_status = bmi_success
825 
826  call split_address(c_var_address, mem_path, var_name, valid)
827  if (.not. valid) then
828  bmi_status = bmi_failure
829  return
830  end if
831 
832  rank = -1
833  call get_mem_rank(var_name, mem_path, rank)
834 
835  if (rank == 0) then
836  call mem_setptr(scalar_ptr, var_name, mem_path)
837  c_arr_ptr = c_loc(scalar_ptr)
838  else if (rank == 1) then
839  call mem_setptr(array_ptr, var_name, mem_path)
840  c_arr_ptr = c_loc(array_ptr)
841  else if (rank == 2) then
842  call mem_setptr(array2d_ptr, var_name, mem_path)
843  c_arr_ptr = c_loc(array2d_ptr)
844  else if (rank == 3) then
845  call mem_setptr(array3d_ptr, var_name, mem_path)
846  c_arr_ptr = c_loc(array3d_ptr)
847  else
848  write (bmi_last_error, fmt_unsupported_rank) trim(var_name)
849  call report_bmi_error(bmi_last_error)
850  bmi_status = bmi_failure
851  return
852  end if
853 
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 578 of file mf6bmi.f90.

580  !DIR$ ATTRIBUTES DLLEXPORT :: get_value_string
581  ! -- modules
582  ! -- dummy variables
583  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
584  type(c_ptr), intent(in) :: c_arr_ptr !< pointer to the string array
585  integer(kind=c_int) :: bmi_status !< BMI status code
586  ! -- local variables
587  character(len=LENMEMPATH) :: mem_path
588  character(len=LENVARNAME) :: var_name
589  logical(LGP) :: valid
590  integer(I4B) :: rank
591  character(len=:), pointer :: srcstr
592  character(kind=c_char), pointer :: tgtstr(:)
593  type(CharacterStringType), dimension(:), pointer, contiguous :: srccharstr1d
594  character(kind=c_char), pointer :: tgtstr1d(:, :)
595  character(:), allocatable :: tempstr
596  integer(I4B) :: i, ilen, isize
597 
598  bmi_status = bmi_success
599 
600  call split_address(c_var_address, mem_path, var_name, valid)
601  if (.not. valid) then
602  bmi_status = bmi_failure
603  return
604  end if
605 
606  ! single string, or array of strings (CharacterStringType)
607  rank = -1
608  call get_mem_rank(var_name, mem_path, rank)
609 
610  if (rank == 0) then
611  ! a string scalar
612  call mem_setptr(srcstr, var_name, mem_path)
613  call get_mem_elem_size(var_name, mem_path, ilen)
614  call c_f_pointer(c_arr_ptr, tgtstr, shape=[ilen + 1])
615 
616  tgtstr(1:len(srcstr) + 1) = string_to_char_array(srcstr, len(srcstr))
617 
618  else if (rank == 1) then
619  ! an array of strings
620  call mem_setptr(srccharstr1d, var_name, mem_path)
621  if (.not. associated(srccharstr1d)) then
622  write (bmi_last_error, fmt_general_err) 'string type not supported in API'
623  call report_bmi_error(bmi_last_error)
624  bmi_status = bmi_failure
625  return
626  end if
627 
628  ! create fortran pointer to C data array
629  call get_isize(var_name, mem_path, isize)
630  call get_mem_elem_size(var_name, mem_path, ilen)
631  call c_f_pointer(c_arr_ptr, tgtstr1d, shape=[ilen + 1, isize])
632 
633  ! allocate work array to handle CharacterStringType,
634  ! and copy the strings
635  allocate (character(ilen) :: tempstr)
636  do i = 1, isize
637  tempstr = srccharstr1d(i)
638  tgtstr1d(1:ilen + 1, i) = string_to_char_array(tempstr, ilen)
639  end do
640  deallocate (tempstr)
641  else
642  write (bmi_last_error, fmt_unsupported_rank) trim(var_name)
643  call report_bmi_error(bmi_last_error)
644  bmi_status = bmi_failure
645  return
646  end if
647 
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 314 of file mf6bmi.f90.

316  !DIR$ ATTRIBUTES DLLEXPORT :: get_var_itemsize
317  ! -- dummy variables
318  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
319  integer(kind=c_int), intent(out) :: var_size !< size of the element in bytes
320  integer(kind=c_int) :: bmi_status !< BMI status code
321  ! -- local variables
322  character(len=LENMEMPATH) :: mem_path
323  character(len=LENVARNAME) :: var_name
324  logical(LGP) :: valid
325 
326  bmi_status = bmi_success
327 
328  call split_address(c_var_address, mem_path, var_name, valid)
329  if (.not. valid) then
330  bmi_status = bmi_failure
331  return
332  end if
333 
334  call get_mem_elem_size(var_name, mem_path, var_size)
335  if (var_size == -1) bmi_status = bmi_failure
336 
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 341 of file mf6bmi.f90.

343  !DIR$ ATTRIBUTES DLLEXPORT :: get_var_nbytes
344  ! -- dummy variables
345  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
346  integer(kind=c_int), intent(out) :: var_nbytes !< size in bytes
347  integer(kind=c_int) :: bmi_status !< BMI status code
348  ! -- local variables
349  integer(I4B) :: var_size, isize
350  character(len=LENMEMPATH) :: mem_path
351  character(len=LENVARNAME) :: var_name
352  logical(LGP) :: valid
353 
354  bmi_status = bmi_success
355 
356  call split_address(c_var_address, mem_path, var_name, valid)
357  if (.not. valid) then
358  bmi_status = bmi_failure
359  return
360  end if
361 
362  call get_mem_elem_size(var_name, mem_path, var_size)
363  if (var_size == -1) bmi_status = bmi_failure
364  call get_isize(var_name, mem_path, isize)
365  if (isize == -1) bmi_status = bmi_failure
366 
367  var_nbytes = var_size * isize
368 
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 1191 of file mf6bmi.f90.

1193  !DIR$ ATTRIBUTES DLLEXPORT :: get_var_rank
1194  ! -- dummy variables
1195  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
1196  integer(kind=c_int), intent(out) :: c_var_rank !< variable rank
1197  integer(kind=c_int) :: bmi_status !< BMI status code
1198  ! -- local variables
1199  character(len=LENMEMPATH) :: mem_path
1200  character(len=LENVARNAME) :: var_name
1201  logical(LGP) :: valid
1202 
1203  bmi_status = bmi_success
1204 
1205  call split_address(c_var_address, mem_path, var_name, valid)
1206  if (.not. valid) then
1207  bmi_status = bmi_failure
1208  return
1209  end if
1210 
1211  call get_mem_rank(var_name, mem_path, c_var_rank)
1212  if (c_var_rank == -1) then
1213  bmi_status = bmi_failure
1214  return
1215  end if
1216 
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 1229 of file mf6bmi.f90.

1231  !DIR$ ATTRIBUTES DLLEXPORT :: get_var_shape
1232  ! -- modules
1233  use constantsmodule, only: maxmemrank
1234  ! -- dummy variables
1235  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
1236  integer(c_int), intent(inout) :: c_var_shape(*) !< 1D array with the variable's shape
1237  integer(kind=c_int) :: bmi_status !< BMI status code
1238  ! -- local variables
1239  integer(I4B), dimension(MAXMEMRANK) :: var_shape
1240  integer(I4B) :: var_rank
1241  character(len=LENMEMPATH) :: mem_path
1242  character(len=LENVARNAME) :: var_name
1243  logical(LGP) :: valid
1244 
1245  bmi_status = bmi_success
1246 
1247  call split_address(c_var_address, mem_path, var_name, valid)
1248  if (.not. valid) then
1249  bmi_status = bmi_failure
1250  return
1251  end if
1252 
1253  var_shape = 0
1254  var_rank = 0
1255  call get_mem_rank(var_name, mem_path, var_rank)
1256  call get_mem_shape(var_name, mem_path, var_shape)
1257  if (var_shape(1) == -1 .or. var_rank == -1) then
1258  bmi_status = bmi_failure
1259  return
1260  end if
1261 
1262  ! External calls to this BMI are assumed C style, so if the internal shape
1263  ! is (100,1) we get (100,1,undef) from the call get_mem_shape
1264  ! This we need to convert to C-style which should be (1,100).
1265  ! Hence, we reverse the array and drop undef:
1266  c_var_shape(1:var_rank) = var_shape(var_rank:1:-1)
1267 
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 1151 of file mf6bmi.f90.

1153  !DIR$ ATTRIBUTES DLLEXPORT :: get_var_type
1154  ! -- modules
1155  use constantsmodule, only: lenmemtype
1156  ! -- dummy variables
1157  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
1158  character(kind=c_char), intent(out) :: c_var_type(BMI_LENVARTYPE) !< variable type as a string
1159  integer(kind=c_int) :: bmi_status !< BMI status code
1160  ! -- local variables
1161  character(len=LENMEMPATH) :: mem_path
1162  character(len=LENVARNAME) :: var_name
1163  character(len=LENMEMTYPE) :: mem_type
1164  logical(LGP) :: valid
1165 
1166  bmi_status = bmi_success
1167 
1168  call split_address(c_var_address, mem_path, var_name, valid)
1169  if (.not. valid) then
1170  bmi_status = bmi_failure
1171  return
1172  end if
1173 
1174  call get_mem_type(var_name, mem_path, mem_type)
1175  c_var_type(1:len(trim(mem_type)) + 1) = &
1176  string_to_char_array(trim(mem_type), len(trim(mem_type)))
1177 
1178  if (mem_type == 'UNKNOWN') then
1179  write (bmi_last_error, fmt_general_err) 'unknown memory type'
1180  call report_bmi_error(bmi_last_error)
1181  bmi_status = bmi_failure
1182  end if
1183 
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 902 of file mf6bmi.f90.

904  !DIR$ ATTRIBUTES DLLEXPORT :: set_value
905  ! -- modules
906  use constantsmodule, only: lenmemtype
907  ! -- dummy variables
908  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
909  type(c_ptr), intent(inout) :: c_arr_ptr !< pointer to the array
910  integer(kind=c_int) :: bmi_status !< BMI status code
911  ! -- local variables
912  character(len=LENMEMPATH) :: mem_path
913  character(len=LENMEMTYPE) :: mem_type
914  character(len=LENVARNAME) :: var_name
915  logical(LGP) :: valid
916 
917  bmi_status = bmi_success
918 
919  call split_address(c_var_address, mem_path, var_name, valid)
920  if (.not. valid) then
921  bmi_status = bmi_failure
922  return
923  end if
924 
925  call get_mem_type(var_name, mem_path, mem_type)
926 
927  if (index(mem_type, "DOUBLE") /= 0) then
928  bmi_status = set_value_double(c_var_address, c_arr_ptr)
929  else if (index(mem_type, "INTEGER") /= 0) then
930  bmi_status = set_value_int(c_var_address, c_arr_ptr)
931  else if (index(mem_type, "LOGICAL") /= 0) then
932  bmi_status = set_value_bool(c_var_address, c_arr_ptr)
933  else
934  write (bmi_last_error, fmt_unsupported_type) trim(var_name)
935  call report_bmi_error(bmi_last_error)
936  bmi_status = bmi_failure
937  return
938  end if
939 
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 1094 of file mf6bmi.f90.

1096  !DIR$ ATTRIBUTES DLLEXPORT :: set_value_bool
1097  ! -- modules
1099  ! -- dummy variables
1100  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
1101  type(c_ptr), intent(in) :: c_arr_ptr !< pointer to the logical array
1102  integer(kind=c_int) :: bmi_status !< BMI status code
1103  ! -- local variables
1104  character(len=LENMEMPATH) :: mem_path
1105  character(len=LENVARNAME) :: var_name
1106  logical(LGP) :: valid
1107  integer(I4B) :: rank
1108  logical(LGP), pointer :: src_ptr, tgt_ptr
1109  integer(I4B) :: status
1110 
1111  bmi_status = bmi_success
1112 
1113  call split_address(c_var_address, mem_path, var_name, valid)
1114  if (.not. valid) then
1115  bmi_status = bmi_failure
1116  return
1117  end if
1118 
1119  rank = -1
1120  call get_mem_rank(var_name, mem_path, rank)
1121 
1122  ! convert pointer
1123  if (rank == 0) then
1124  call mem_setptr(tgt_ptr, var_name, mem_path)
1125  call c_f_pointer(c_arr_ptr, src_ptr)
1126  tgt_ptr = src_ptr
1127  else
1128  write (bmi_last_error, fmt_unsupported_rank) trim(var_name)
1129  call report_bmi_error(bmi_last_error)
1130  bmi_status = bmi_failure
1131  return
1132  end if
1133 
1134  ! trigger event:
1135  call on_memory_set(var_name, mem_path, status)
1136  if (status /= 0) then
1137  ! something went terribly wrong here, aborting
1138  write (bmi_last_error, fmt_invalid_mem_access) trim(var_name)
1139  call report_bmi_error(bmi_last_error)
1140  bmi_status = bmi_failure
1141  return
1142  end if
1143 
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 948 of file mf6bmi.f90.

950  !DIR$ ATTRIBUTES DLLEXPORT :: set_value_double
951  ! -- modules
953  ! -- dummy variables
954  character(kind=c_char), intent(in) :: c_var_address(*) !< memory address string of the variable
955  type(c_ptr), intent(in) :: c_arr_ptr !< pointer to the double precision array
956  integer(kind=c_int) :: bmi_status !< BMI status code
957  ! -- local variables
958  character(len=LENMEMPATH) :: mem_path
959  character(len=LENVARNAME) :: var_name
960  logical(LGP) :: valid
961  integer(I4B) :: rank
962  real(DP), pointer :: src_ptr, tgt_ptr
963  real(DP), dimension(:), pointer, contiguous :: src1D_ptr, tgt1D_ptr
964  real(DP), dimension(:, :), pointer, contiguous :: src2D_ptr, tgt2D_ptr
965  integer(I4B) :: i, j
966  integer(I4B) :: status
967 
968  bmi_status = bmi_success
969 
970  call split_address(c_var_address, mem_path, var_name, valid)
971  if (.not. valid) then
972  bmi_status = bmi_failure
973  return
974  end if
975 
976  ! convert pointer and copy, using loops to avoid stack overflow
977  rank = -1
978  call get_mem_rank(var_name, mem_path, rank)
979 
980  if (rank == 0) then
981  call mem_setptr(tgt_ptr, var_name, mem_path)
982  call c_f_pointer(c_arr_ptr, src_ptr)
983  tgt_ptr = src_ptr
984  else if (rank == 1) then
985  call mem_setptr(tgt1d_ptr, var_name, mem_path)
986  call c_f_pointer(c_arr_ptr, src1d_ptr, shape(tgt1d_ptr))
987  do i = 1, size(tgt1d_ptr)
988  tgt1d_ptr(i) = src1d_ptr(i)
989  end do
990  else if (rank == 2) then
991  call mem_setptr(tgt2d_ptr, var_name, mem_path)
992  call c_f_pointer(c_arr_ptr, src2d_ptr, shape(tgt2d_ptr))
993  do j = 1, size(tgt2d_ptr, 2)
994  do i = 1, size(tgt2d_ptr, 1)
995  tgt2d_ptr(i, j) = src2d_ptr(i, j)
996  end do
997  end do
998  else
999  write (bmi_last_error, fmt_unsupported_rank) trim(var_name)
1000  call report_bmi_error(bmi_last_error)
1001  bmi_status = bmi_failure
1002  return
1003  end if
1004 
1005  ! trigger event:
1006  call on_memory_set(var_name, mem_path, status)
1007  if (status /= 0) then
1008  ! something went terribly wrong here, aborting
1009  write (bmi_last_error, fmt_invalid_mem_access) trim(var_name)
1010  call report_bmi_error(bmi_last_error)
1011  bmi_status = bmi_failure
1012  return
1013  end if
1014 
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 1021 of file mf6bmi.f90.

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