MODFLOW 6  version 6.8.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 114 of file mf6bmi.f90.

115  !DIR$ ATTRIBUTES DLLEXPORT :: bmi_finalize
116  ! -- modules
117  use simvariablesmodule, only: iforcestop
118  ! -- dummy variables
119  integer(kind=c_int) :: bmi_status !< BMI status code
120 
121  ! we don't want a full stop() here, this disables it:
122  iforcestop = 0
123  call mf6finalize()
124 
125  bmi_status = bmi_success
126 
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:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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