@@ -27,7 +27,7 @@ module mf6bmi
2727 use CharacterStringModule
2828 use MemoryManagerModule, only: mem_setptr, get_mem_elem_size, get_isize, &
2929 get_mem_rank, get_mem_shape, get_mem_type, &
30- memorystore
30+ get_from_memorystore, memorystore
3131 use MemoryContainerIteratorModule, only: MemoryContainerIteratorType
3232 use MemoryTypeModule, only: MemoryType
3333 use MemoryHelperModule, only: create_mem_address
@@ -199,42 +199,63 @@ end function get_time_step
199199
200200 ! > @brief Get the number of input variables in the simulation
201201 ! !
202- ! ! This concerns all variables stored in the memory manager
202+ ! ! Counts variables stored in the memory manager that are not marked
203+ ! ! read-only, i.e. those an API consumer may write.
203204 ! <
204205 function get_input_item_count (count ) result(bmi_status) &
205206 bind(C, name= " get_input_item_count" )
206207 ! DIR$ ATTRIBUTES DLLEXPORT :: get_input_item_count
207208 ! -- dummy variables
208209 integer (kind= c_int), intent (out ) :: count ! < the number of input variables
209210 integer (kind= c_int) :: bmi_status ! < BMI status code
211+ ! -- local variables
212+ type (MemoryContainerIteratorType), allocatable :: itr
213+ type (MemoryType), pointer :: mt = > null ()
210214
211- count = memorystore% count ()
215+ count = 0
216+ itr = memorystore% iterator()
217+ do while (itr% has_next())
218+ call itr% next()
219+ mt = > itr% value()
220+ if (.not. mt% readonly) count = count + 1
221+ end do
212222
213223 bmi_status = BMI_SUCCESS
214224
215225 end function get_input_item_count
216226
217227 ! > @brief Get the number of output variables in the simulation
218228 ! !
219- ! ! This concerns all variables stored in the memory manager
229+ ! ! Counts variables stored in the memory manager that are marked
230+ ! ! as output.
220231 ! <
221232 function get_output_item_count (count ) result(bmi_status) &
222233 bind(C, name= " get_output_item_count" )
223234 ! DIR$ ATTRIBUTES DLLEXPORT :: get_output_item_count
224235 ! -- dummy variables
225236 integer (kind= c_int), intent (out ) :: count ! < the number of output variables
226237 integer (kind= c_int) :: bmi_status ! < BMI status code
238+ ! -- local variables
239+ type (MemoryContainerIteratorType), allocatable :: itr
240+ type (MemoryType), pointer :: mt = > null ()
227241
228- count = memorystore% count ()
242+ count = 0
243+ itr = memorystore% iterator()
244+ do while (itr% has_next())
245+ call itr% next()
246+ mt = > itr% value()
247+ if (mt% output) count = count + 1
248+ end do
229249
230250 bmi_status = BMI_SUCCESS
231251
232252 end function get_output_item_count
233253
234254 ! > @brief Returns all input variables in the simulation
235255 ! !
236- ! ! This functions returns the full address for all variables in the
237- ! ! memory manager
256+ ! ! This function returns the full address for every variable in the
257+ ! ! memory manager that is not marked read-only, i.e. those an API
258+ ! ! consumer may write.
238259 ! !
239260 ! ! The array @p c_names should be pre-allocated of proper size:
240261 ! !
@@ -262,6 +283,7 @@ function get_input_var_names(c_names) result(bmi_status) &
262283 do while (itr% has_next())
263284 call itr% next()
264285 mt = > itr% value()
286+ if (mt% readonly) cycle
265287 var_address = create_mem_address(mt% path, mt% name)
266288 do i = 1 , len (trim (var_address))
267289 c_names(start + i - 1 ) = var_address(i:i)
@@ -276,9 +298,9 @@ end function get_input_var_names
276298
277299 ! > @brief Returns all output variables in the simulation
278300 ! !
279- ! ! This function works analogously to get_input_var_names(),
280- ! ! and currently returns the same set of memory variables,
281- ! ! which is all of them!
301+ ! ! This function works analogously to get_input_var_names(), but returns
302+ ! ! the full address for every variable in the memory manager that is
303+ ! ! marked as output.
282304 ! <
283305 function get_output_var_names (c_names ) result(bmi_status) &
284306 bind(C, name= " get_output_var_names" )
@@ -297,6 +319,7 @@ function get_output_var_names(c_names) result(bmi_status) &
297319 do while (itr% has_next())
298320 call itr% next()
299321 mt = > itr% value()
322+ if (.not. mt% output) cycle
300323 var_address = create_mem_address(mt% path, mt% name)
301324 do i = 1 , len (trim (var_address))
302325 c_names(start + i - 1 ) = var_address(i:i)
@@ -913,6 +936,8 @@ function set_value(c_var_address, c_arr_ptr) result(bmi_status) &
913936 character (len= LENMEMTYPE) :: mem_type
914937 character (len= LENVARNAME) :: var_name
915938 logical (LGP) :: valid
939+ logical (LGP) :: found
940+ type (MemoryType), pointer :: mt = > null ()
916941
917942 bmi_status = BMI_SUCCESS
918943
@@ -922,6 +947,16 @@ function set_value(c_var_address, c_arr_ptr) result(bmi_status) &
922947 return
923948 end if
924949
950+ call get_from_memorystore(var_name, mem_path, mt, found, check= .false. )
951+ if (found) then
952+ if (mt% readonly) then
953+ write (bmi_last_error, fmt_readonly_var) trim (var_name)
954+ call report_bmi_error(bmi_last_error)
955+ bmi_status = BMI_FAILURE
956+ return
957+ end if
958+ end if
959+
925960 call get_mem_type(var_name, mem_path, mem_type)
926961
927962 if (index (mem_type, " DOUBLE" ) /= 0 ) then
0 commit comments