Commit 1877f875 authored by Olivier Lantsoght's avatar Olivier Lantsoght

[MBsysPy][Load][UserModel] User state and vectors always use index 1.

Remark: some code refactoring and better documented.
parent a521e8c9
......@@ -941,65 +941,89 @@ class MbsData(object):
The second one contains the names of the parameters as keys and
numpy arrays that point toward C memory as values
"""
self.user_model._locked = False
infos_c_ptr = self.mbs_infos_ptr.contents
# Unlock modification in dictionnary.
self.user_model._locked = False
# Counter for generation of user state id, used if user function are in Python.
next_user_state = 1
# Shortcut to know if we are using Python user function
UmPy = self.opt_load_c < 2
# Loop on each user model
for i in range(infos_c_ptr.user_models.contents.n_user_model):
# Retrieve the user model c structure (MbsInfoUserModel)
user_model_list = infos_c_ptr.user_models.contents.user_model_list[i].contents
# Retrieve its name and create subdictionnary for the parameters
name = bytes_to_str(user_model_list.name)
self.user_model[name] = _UserModelDict()
self.user_model[name]._parent_key = name
self.user_model[name]._locked = False
self.user_model[name]._type = dict()
# Loop on each parameter of the current user model
for j in range(user_model_list.n_parameter):
# Retrieve the parameter c structure (MbsInfoParameter)
parameter_list = user_model_list.parameter_list[j].contents
# And parameter name
name2 = bytes_to_str(parameter_list.name)
val_ptr = parameter_list.val_ptr
value_list = parameter_list.value_list
# Retrive pointer to values, as ctypes.POINTER(ctypes.c_double)
val_ptr = parameter_list.val_ptr # Currently set in memory
# Retrive number of value in the parameter
size = parameter_list.n_value
# Type of the parameter
self.user_model[name]._type[name2] = parameter_list.type
um_type = parameter_list.type # shortcut for comparison
UmPy = (ctypes.cast(val_ptr, ctypes.c_void_p).value == ctypes.cast(value_list, ctypes.c_void_p).value)
if UmPy: # Using pure Python memory
size = parameter_list.n_value # index start at 0
if um_type == 5: # user state
state = np.array([np.arange(next_user_state, size + next_user_state)])
if um_type == 1: # scalar
self.user_model[name][name2] = np.ctypeslib.as_array(val_ptr, (1, 1))
elif um_type == 2: # vector, using index starting at 1.
self.user_model[name][name2] = np.ctypeslib.as_array(val_ptr, (1, size + 1))
elif um_type == 5: # user state
if UmPy:
# The pointer is set to the initial value of the user states.
# The indices of the user state must be created.
state = np.array([np.arange(next_user_state - 1, size + next_user_state)])
state[0][0] = size
next_user_state += size
state.flags["WRITEABLE"] = False
self.user_model[name][name2] = state
elif um_type in [1, 2, 7]: # scalar, vector, integer
self.user_model[name][name2] = np.ctypeslib.as_array(val_ptr, (1, size))
# In full python project, the C memory is always a double (even if set as integer in PAD).
else:
type_convertor = ['Invalid Value', 'a scalar', 'a vector',
'a 1D Look-Up-Table', 'a 2D Look-Up-Table',
'an user state', 'a structure', 'an integer']
type_str = 'not an known type' if len(type_convertor) <= um_type else type_convertor[um_type]
mbs_warning("The user model '{:}->{:}', which is {:}, is not "
"supported in MBsysPy.\n This user model "
"will not be accessible.".format(name, name2, type_str))
self.user_model[name][name2] = [type_str]
else: # Using C binding
size = parameter_list.n_value + 1 # index start at 1
if um_type == 5: # user state
state = np.ctypeslib.as_array(ctypes.cast(val_ptr, ctypes.POINTER(ctypes.c_int)), (1, size))
state.flags["WRITEABLE"] = False
self.user_model[name][name2] = state
elif um_type == 7: # interger
self.user_model[name][name2] = np.ctypeslib.as_array(ctypes.cast(val_ptr, ctypes.POINTER(ctypes.c_int)), (1, 1))
elif um_type == 1: # scalar
# The indices of the user state have been create by the c UserModel.
state = np.ctypeslib.as_array(ctypes.cast(val_ptr, ctypes.POINTER(ctypes.c_int)), (1, size + 1))
# Preventing the user to modify the user state ids.
state.flags["WRITEABLE"] = False
self.user_model[name][name2] = state
elif um_type == 7:
if UmPy:
# The values loaded from files are stored as double. The convertion
# to integer will be done for the user when asking for the parameter.
self.user_model[name][name2] = np.ctypeslib.as_array(val_ptr, (1, 1))
elif um_type == 2: # vector
self.user_model[name][name2] = np.ctypeslib.as_array(val_ptr, (1, size))
else:
type_convertor = ['Invalid Value', 'a scalar', 'a vector',
'a 1D Look-Up-Table', 'a 2D Look-Up-Table',
'an user state', 'a structure', 'an integer']
type_str = 'not an known type' if len(type_convertor) <= um_type else type_convertor[um_type]
mbs_warning("The user model '{:}->{:}', which is {:}, is not "
"supported in MBsysPy.\n This user model "
"will not be accessible from Python side.".format(name, name2, type_str))
self.user_model[name][name2] = [type_str]
# At UserModel creation the val_ptr is redirected toward an int.
# Casting the pointer to a pointer to int is required
self.user_model[name][name2] = np.ctypeslib.as_array(ctypes.cast(val_ptr, ctypes.POINTER(ctypes.c_int)), (1, 1))
else:
# Other parameter type are either nunaccessible or unknown.
type_convertor = ['Invalid Value', 'a scalar', 'a vector',
'a 1D Look-Up-Table', 'a 2D Look-Up-Table',
'an user state', 'a structure', 'an integer']
type_str = 'not an known type' if len(type_convertor) <= um_type else type_convertor[um_type]
message = "The user model '{:}->{:}', which is {:}, is not supported in MBsysPy.\n"\
.format(name, name2, type_str)
message += " " # Spacing for alignment
if UmPy:
message += "This user model will not be used at all."
else:
message += "This user model will not be accessible from Python side."
mbs_warning(message)
# Lock the current user model (additionnal parameters not possible)
self.user_model[name]._locked = True
# Lock the user models (additionnal user model not possible)
self.user_model._locked = True
def set_nb_userc(self, nb):
......
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