Commit dc1b6990 authored by Jorn Bruggeman's avatar Jorn Bruggeman
Browse files

python driver: enable access to background value of state variables

parent 9e805207
......@@ -31,7 +31,11 @@ fabm = ctypes.CDLL(dllpath)
fabm.initialize.argtypes = [ctypes.c_char_p]
fabm.get_variable_counts.argtypes = [ctypes.POINTER(ctypes.c_int),ctypes.POINTER(ctypes.c_int),ctypes.POINTER(ctypes.c_int),ctypes.POINTER(ctypes.c_int),ctypes.POINTER(ctypes.c_int),ctypes.POINTER(ctypes.c_int),ctypes.POINTER(ctypes.c_int),ctypes.POINTER(ctypes.c_int),ctypes.POINTER(ctypes.c_int)]
fabm.get_variable_metadata.argtypes = [ctypes.c_int,ctypes.c_int,ctypes.c_int,ctypes.c_char_p,ctypes.c_char_p,ctypes.c_char_p,ctypes.c_char_p]
fabm.get_variable_ptr.argtypes = [ctypes.c_int,ctypes.c_int]
fabm.get_variable_ptr.restype = ctypes.c_void_p
fabm.get_variable_metadata_ptr.argtypes = [ctypes.c_void_p,ctypes.c_int,ctypes.c_char_p,ctypes.c_char_p,ctypes.c_char_p]
fabm.get_variable_background_value.argtypes = [ctypes.c_void_p]
fabm.get_variable_background_value.restype = ctypes.c_double
fabm.get_variable_long_path.argtypes = [ctypes.c_void_p,ctypes.c_int,ctypes.c_char_p]
fabm.get_parameter_metadata.argtypes = [ctypes.c_int,ctypes.c_int,ctypes.c_char_p,ctypes.c_char_p,ctypes.c_char_p,ctypes.POINTER(ctypes.c_int),ctypes.POINTER(ctypes.c_int)]
fabm.get_dependency_metadata.argtypes = [ctypes.c_int,ctypes.c_int,ctypes.c_char_p,ctypes.c_char_p]
......@@ -150,8 +154,9 @@ class Dependency(Variable):
value = property(getValue, setValue)
class StateVariable(Variable):
def __init__(self,statearray,name,index,units=None,long_name=None,path=None):
def __init__(self,variable_pointer,statearray,name,index,units=None,long_name=None,path=None):
Variable.__init__(self,name,units,long_name,path)
self.variable_pointer = variable_pointer
self.index = index
self.statearray = statearray
......@@ -163,6 +168,10 @@ class StateVariable(Variable):
value = property(getValue, setValue)
@property
def background_value(self):
return fabm.get_variable_background_value(self.variable_pointer)
class DiagnosticVariable(Variable):
def __init__(self,name,index,horizontal,units=None,long_name=None,path=None):
Variable.__init__(self,name,units,long_name,path)
......@@ -336,14 +345,17 @@ class Model(object):
self.parameters = []
self.dependencies = []
for i in range(nstate_bulk.value):
ptr = fabm.get_variable_ptr(BULK_STATE_VARIABLE,i+1)
fabm.get_variable_metadata(BULK_STATE_VARIABLE,i+1,ATTRIBUTE_LENGTH,strname,strunits,strlong_name,strpath)
self.bulk_state_variables.append(StateVariable(self.state,strname.value,i,strunits.value,strlong_name.value,strpath.value))
self.bulk_state_variables.append(StateVariable(ptr,self.state,strname.value,i,strunits.value,strlong_name.value,strpath.value))
for i in range(nstate_surface.value):
ptr = fabm.get_variable_ptr(SURFACE_STATE_VARIABLE,i+1)
fabm.get_variable_metadata(SURFACE_STATE_VARIABLE,i+1,ATTRIBUTE_LENGTH,strname,strunits,strlong_name,strpath)
self.surface_state_variables.append(StateVariable(self.state,strname.value,nstate_bulk.value+i,strunits.value,strlong_name.value,strpath.value))
self.surface_state_variables.append(StateVariable(ptr,self.state,strname.value,nstate_bulk.value+i,strunits.value,strlong_name.value,strpath.value))
for i in range(nstate_bottom.value):
ptr = fabm.get_variable_ptr(BOTTOM_STATE_VARIABLE,i+1)
fabm.get_variable_metadata(BOTTOM_STATE_VARIABLE,i+1,ATTRIBUTE_LENGTH,strname,strunits,strlong_name,strpath)
self.bottom_state_variables.append(StateVariable(self.state,strname.value,nstate_bulk.value+nstate_surface.value+i,strunits.value,strlong_name.value,strpath.value))
self.bottom_state_variables.append(StateVariable(ptr,self.state,strname.value,nstate_bulk.value+nstate_surface.value+i,strunits.value,strlong_name.value,strpath.value))
for i in range(ndiag_bulk.value):
fabm.get_variable_metadata(BULK_DIAGNOSTIC_VARIABLE,i+1,ATTRIBUTE_LENGTH,strname,strunits,strlong_name,strpath)
self.bulk_diagnostic_variables.append(DiagnosticVariable(strname.value,i,False,strunits.value,strlong_name,strpath.value))
......
......@@ -223,6 +223,31 @@
call copy_to_c_string(variable%path, path)
end subroutine
function get_variable_ptr(category,index) bind(c) result(pvariable)
!DIR$ ATTRIBUTES DLLEXPORT :: get_variable_ptr
integer(c_int), intent(in), value :: category,index
type (c_ptr) :: pvariable
type (type_internal_variable),pointer :: variable
! Get a pointer to the target variable
select case (category)
case (BULK_STATE_VARIABLE)
variable => model%state_variables(index)%target
case (SURFACE_STATE_VARIABLE)
variable => model%surface_state_variables(index)%target
case (BOTTOM_STATE_VARIABLE)
variable => model%bottom_state_variables(index)%target
case (BULK_DIAGNOSTIC_VARIABLE)
variable => model%diagnostic_variables(index)%target
case (HORIZONTAL_DIAGNOSTIC_VARIABLE)
variable => model%horizontal_diagnostic_variables(index)%target
case (CONSERVED_QUANTITY)
variable => model%conserved_quantities(index)%target
end select
pvariable = c_loc(variable)
end function get_variable_ptr
subroutine get_parameter_metadata(index,length,name,units,long_name,typecode,has_default) bind(c)
!DIR$ ATTRIBUTES DLLEXPORT :: get_parameter_metadata
integer(c_int), intent(in), value :: index,length
......@@ -345,6 +370,18 @@
call copy_to_c_string(long_name_,long_name)
end subroutine get_variable_long_path
function get_variable_background_value(pvariable) bind(c) result(value)
!DIR$ ATTRIBUTES DLLEXPORT :: get_variable_background_value
type (c_ptr), value, intent(in) :: pvariable
real(kind=c_double) :: value
type (type_internal_variable),pointer :: variable
call c_f_pointer(pvariable, variable)
value = 0.0_rk
if (size(variable%background_values%pointers)>0) value = variable%background_values%pointers(1)%p
end function get_variable_background_value
subroutine get_variable_metadata_ptr(pvariable,length,name,units,long_name) bind(c)
!DIR$ ATTRIBUTES DLLEXPORT :: get_variable_metadata_ptr
type (c_ptr), intent(in), value :: pvariable
......
......@@ -24,7 +24,7 @@ except ImportError:
pass
# ------------------------------------------
def processFile(infile,outfile):
def processFile(infile,outfile,subtract_background=False):
# Create model object from YAML file.
model = pyfabm.Model(infile)
......@@ -83,14 +83,16 @@ def processFile(infile,outfile):
if len(path)==3:
if path[-1]=='parameters':
metadata = model.findParameter(path[1]+'/'+key,case_insensitive=True)
value = metadata.value
elif path[-1]=='initialization':
metadata = model.findStateVariable(path[1]+'_'+key)
value = metadata.value
if subtract_background: value -= metadata.background_value
elif path[-1]=='coupling':
try:
metadata = model.findCoupling(path[1]+'/'+key)
except KeyError:
pass
if path[-1]!='coupling': value = metadata.value
value = python2yaml(value)
if metadata is not None:
f.write('%s: %s' % (metadata.name[len(path[1])+1:],value))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment