Commit c78f7350 authored by Olivier Lantsoght's avatar Olivier Lantsoght
Browse files

[MBsysPy][MbsResults] Various modifications in class

parent d3a2475e
...@@ -16,7 +16,6 @@ is used. ...@@ -16,7 +16,6 @@ is used.
# (c) Universite catholique de Louvain, 2021 # (c) Universite catholique de Louvain, 2021
import os import os
import ctypes
import numpy as np import numpy as np
from enum import IntEnum, unique from enum import IntEnum, unique
...@@ -24,7 +23,6 @@ from enum import IntEnum, unique ...@@ -24,7 +23,6 @@ from enum import IntEnum, unique
# importing MbsysPy functions # importing MbsysPy functions
from ..mbs_utilities import bytes_to_str from ..mbs_utilities import bytes_to_str
from ..mbs_utilities import mbs_warning from ..mbs_utilities import mbs_warning
from ..mbs_utilities import mbs_error
from ..mbs_utilities import mbs_msg from ..mbs_utilities import mbs_msg
...@@ -123,7 +121,7 @@ class MbsResult(object): ...@@ -123,7 +121,7 @@ class MbsResult(object):
""" """
def __init__(self, mbs): def __init__(self, mbs):
"""Initialize the fields to empty list or dict.""" """Initialize the fields to None."""
self.q = None self.q = None
self.qd = None self.qd = None
self.qdd = None self.qdd = None
...@@ -140,6 +138,26 @@ class MbsResult(object): ...@@ -140,6 +138,26 @@ class MbsResult(object):
self.t = None self.t = None
self.mbs = mbs self.mbs = mbs
def clear(self):
"""Reset all data fields to None.
The mbs is kept.
"""
self.q = None
self.qd = None
self.qdd = None
self.Qq = None
self.ux = None
self.uxd = None
self.Z = None
self.Zd = None
self.Fl = None
self.Qc = None
self.Qa = None
self.Lambda = None
self.outputs = None
self.t = None
def set_buffer(self, buf_id, buf_array, name=None): def set_buffer(self, buf_id, buf_array, name=None):
"""Set the buffer array in the field corresponding the the buffer id. """Set the buffer array in the field corresponding the the buffer id.
...@@ -194,7 +212,7 @@ class MbsResult(object): ...@@ -194,7 +212,7 @@ class MbsResult(object):
elif buf_id in ignored_buffers: elif buf_id in ignored_buffers:
pass pass
else: else:
mbs_warning(f"Invalid buffer index value: {buf_id}.") mbs_warning("Invalid buffer index value: {:d}.".format(buf_id))
return False return False
return True return True
...@@ -208,31 +226,32 @@ class MbsResult(object): ...@@ -208,31 +226,32 @@ class MbsResult(object):
The module must contain the fields 'buffers' (MbsBuffer**), 'bufferNb' The module must contain the fields 'buffers' (MbsBuffer**), 'bufferNb'
(int) and 'user_buffer' (MbsGrowingBuffer*). (int) and 'user_buffer' (MbsGrowingBuffer*).
t0 : float, optional t0 : float, optional
Initial time (if relevant) of the analysis. If the initil time in the Initial time (if relevant) of the analysis. If the initial time in the
buffer does not match the provided values, the buffer are not loaded. buffer does not match the provided value, the buffer are not loaded.
If the value is None, then the buffers are loaded whatever the available If the value is None, then the buffers are loaded whatever the available
timestep. timesteps.
The default is None. The default is None.
resfilename : str, optionnal resfilename : str, optionnal
The option of 'resfilename' of the module, this variable is only used The option of 'resfilename' of the module, this variable is only used
to recreate the user output vectors name from the user filename. to create the user output vectors name from the user filename.
The default is '' (empty str). The default is '' (empty str).
Returns Returns
------- -------
bool bool
True if the whole analysis was loaded from the buffers. True if the whole analysis was loaded from the buffers.
False if nothing was loaded from the buffers (incomplete of invalid buffers). False if nothing was loaded from the buffers in case of incomplete
or invalid buffers.
Notes Notes
----- -----
Usually the first buffer is dedicated to generalized coordinates. At the Usually the first buffer is dedicated to generalized coordinates. At the
exception of equilibrium analysis, where it is the fourth buffer. Even exception of equilibrium analysis, where it is the fourth buffer. Even
if equilibrium analysis is not (yet) handled by this function the loading if equilibrium analysis is not (yet) handled by this function the loading
iterate the buffers unil finding the one dedicated to generalized iterates on the buffers unil finding the one dedicated to generalized
coordinates. coordinates.
The buffer of the generalized coordinates is loaded to check if the full The buffer of the generalized coordinates is used to check if the full
simulation is available in the buffer. simulation is available in the buffer.
""" """
# get usefull contents # get usefull contents
...@@ -275,7 +294,7 @@ class MbsResult(object): ...@@ -275,7 +294,7 @@ class MbsResult(object):
buffer_id = buffer_list[i].contents.id buffer_id = buffer_list[i].contents.id
name = None name = None
#For user-vector-buffer, retrieve the buffer name # For user-vector-buffer, retrieve the buffer name
if buffer_id == _buffer_ids.BUFFER_OTHER.value: if buffer_id == _buffer_ids.BUFFER_OTHER.value:
# get filename # get filename
name = bytes_to_str(os.path.basename(buffer_list[i].contents.filename)[:-4]) name = bytes_to_str(os.path.basename(buffer_list[i].contents.filename)[:-4])
...@@ -286,7 +305,7 @@ class MbsResult(object): ...@@ -286,7 +305,7 @@ class MbsResult(object):
self.set_buffer(buffer_id, buffer_array, name) self.set_buffer(buffer_id, buffer_array, name)
# Load scalar user buffer # Load scalar user buffer
nb_steps = user_buffer.contents.index # Filled values in the buffer. nb_steps = user_buffer.contents.index # Filled values in the buffer.
if not nb_steps: if not nb_steps:
# nb_steps is the number of steps not (yet) save to disk. # nb_steps is the number of steps not (yet) save to disk.
# If the value is 0 it means that all has been saved to disk. # If the value is 0 it means that all has been saved to disk.
...@@ -300,42 +319,52 @@ class MbsResult(object): ...@@ -300,42 +319,52 @@ class MbsResult(object):
return True return True
def load_results_from_file(self, filename, result_path="resultsR", module=0, def load_results_from_file(self, filename, result_path="resultsR", module=0,
user_output=None, user_vector=None): user_output=None, user_vector=None):
""" """Load the results from the files.
Load the results from the files into a MbsResult instance.
This function is called if the buffers do not contain the full simulation. This function is called if the buffers do not contain the full simulation.
Parameters Parameters
---------- ----------
filename : str filename : str
The resfilename containing the results to load. The required suffix The filename of the results to load. It is either the base filename
(ie. "_q.res") will be added automatically (without the suffix and extension) or the name of a file containing
basic buffers (ie: q, qd, qdd...) to be loaded.
In the second case the suffix and extension will be stripped to
retrieve the basefilename.
It can contain the full path to files, but it will be ignored.
result_path : str, optional result_path : str, optional
The relative path of the result folder from the project folder. The relative path of the result folder from the project folder.
default is "resultsR" The default is "resultsR".
module : int
The module in which this function is called. In some modules, some
results files don't exist. Module ids corresponds to the
'MbsData.process' value. If set to 0 we try to load all files
default is 0
user_output : list user_output : list
List containing the user output files to be loaded if not None. List containing the user output files to be loaded if not None.
default is None. default is None.
user_vector : list user_vector : list
List containing the user vector output files to be loaded if not None. List containing the user vector output files to be loaded if not None.
default is None. default is None.
Returns
-------
bool
False if the result path was not located.
""" """
project_path = self.mbs.project_path # remove extension and suffix if required
if filename.endswith(".res"):
index_last_char = filename.rfind('_')
filename = filename[:index_last_char]
# remove dirname
baseFileName = os.path.basename(filename) baseFileName = os.path.basename(filename)
baseFileName = baseFileName[:-6]
# build result path
project_path = self.mbs.project_path
result_path = os.path.join(project_path, result_path) result_path = os.path.join(project_path, result_path)
# Error handeling # Error handeling
if not os.path.isdir(result_path): if not os.path.isdir(result_path):
if __DEBUG__: raise RuntimeWarning('The result directory does not exist, no results loaded.')
mbs_msg('DEBUG>> The result directory does not exist: "' + result_path + '"') return False
# Generalized coordinates # Generalized coordinates
CurFile = baseFileName + '_q.res' CurFile = baseFileName + '_q.res'
...@@ -346,100 +375,32 @@ class MbsResult(object): ...@@ -346,100 +375,32 @@ class MbsResult(object):
self.t = self.q[:, 0] self.t = self.q[:, 0]
else: else:
self.t = self.q[0] self.t = self.q[0]
else: elif __DEBUG__:
if __DEBUG__: mbs_msg("DEBUG>> file '" + CurFile + "' not found in folder '" + os.path.dirname(path))
mbs_msg("DEBUG>> file '" + CurFile + "' not found in folder '" + os.path.dirname(path))
# Other base buffers
# Generalized velocities ext = '.res'
CurFile = baseFileName + '_qd.res' base_buffers = {'_qd': _buffer_ids.BUFFER_QD.value,
path = os.path.abspath(os.path.join(result_path, CurFile)) '_qdd': _buffer_ids.BUFFER_QDD.value,
if(os.path.isfile(path)): '_Qq': _buffer_ids.BUFFER_QQ.value,
self.qd = np.loadtxt(path) '_ux': _buffer_ids.BUFFER_UX.value,
else: '_uxd': _buffer_ids.BUFFER_UXD.value,
if __DEBUG__: '_linkZ': _buffer_ids.BUFFER_LINK_Z.value,
mbs_msg("DEBUG>> file '" + CurFile + "' not found in folder '" + os.path.dirname(path)) '_linkZD': _buffer_ids.BUFFER_LINK_ZD.value,
'_linkF': _buffer_ids.BUFFER_LINK_F.value,
# Generalized accelerations '_Qc': _buffer_ids.BUFFER_QC.value,
CurFile = baseFileName + '_qdd.res' '_Qa': _buffer_ids.BUFFER_QA.value,
path = os.path.abspath(os.path.join(result_path, CurFile)) '_Lambda': _buffer_ids.BUFFER_LAMBDA.value,
if(os.path.isfile(path)): }
self.qdd = np.loadtxt(path)
else: for suffix, buffer_id in base_buffers.items():
if __DEBUG__: CurFile = baseFileName + suffix + ext
mbs_msg("DEBUG>> file '" + CurFile + "' not found in folder '" + os.path.dirname(path))
if module != 5:
CurFile = baseFileName + '_Qq.res'
path = os.path.abspath(os.path.join(result_path, CurFile)) path = os.path.abspath(os.path.join(result_path, CurFile))
if(os.path.isfile(path)): if(os.path.isfile(path)):
self.Qq = np.loadtxt(path) file_array = np.loadtxt(path)
else: self.set_buffer(buffer_id, file_array, None)
if __DEBUG__: elif __DEBUG__:
mbs_msg("DEBUG>> file '" + CurFile + "' not found in folder '" + os.path.dirname(path)) mbs_msg("DEBUG>> file '" + CurFile + "' not found in folder '" + os.path.dirname(path))
# Generalized user state
if self.mbs.Nux and (module != 5 and module != 6):
CurFile = baseFileName + '_ux.res'
path = os.path.abspath(os.path.join(result_path, CurFile))
if(os.path.isfile(path)):
self.ux = np.loadtxt(path)
else:
if __DEBUG__:
mbs_msg("DEBUG>> file '" + CurFile + "' not found in folder '" + os.path.dirname(path))
CurFile = baseFileName + '_uxd.res'
path = os.path.abspath(os.path.join(result_path, CurFile))
if(os.path.isfile(path)):
self.uxd = np.loadtxt(path)
else:
if __DEBUG__:
mbs_msg("DEBUG>> file '" + CurFile + "' not found in folder '" + os.path.dirname(path))
# Link
if self.mbs.Nlink and module != 5:
CurFile = baseFileName + '_linkF.res'
path = os.path.abspath(os.path.join(result_path, CurFile))
if(os.path.isfile(path)):
self.Fl = np.loadtxt(path)
else:
if __DEBUG__:
mbs_msg("DEBUG>> file '" + CurFile + "' not found in folder '" + os.path.dirname(path))
CurFile = baseFileName + '_linkZ.res'
path = os.path.abspath(os.path.join(result_path, CurFile))
if(os.path.isfile(path)):
self.Z = np.loadtxt(path)
else:
if __DEBUG__:
mbs_msg("DEBUG>> file '" + CurFile + "' not found in folder '" + os.path.dirname(path))
CurFile = baseFileName + '_linkZd.res'
path = os.path.abspath(os.path.join(result_path, CurFile))
if(os.path.isfile(path)):
self.Zd = np.loadtxt(path)
else:
if __DEBUG__:
mbs_msg("DEBUG>> file '" + CurFile + "' not found in folder '" + os.path.dirname(path))
# Qc
if self.mbs.nqc and module != 5:
CurFile = baseFileName + '_Qc.res'
path = os.path.abspath(os.path.join(result_path, CurFile))
if(os.path.isfile(path)):
self.Qc = np.loadtxt(path)
else:
if __DEBUG__:
mbs_msg("DEBUG>> file '" + CurFile + "' not found in folder '" + os.path.dirname(path))
# Qa
if self.mbs.nqa and (module != 5 and module != 3):
CurFile = baseFileName + '_Qa.res'
path = os.path.abspath(os.path.join(result_path, CurFile))
if(os.path.isfile(path)):
self.Qa = np.loadtxt(path)
else:
if __DEBUG__:
mbs_msg("DEBUG>> file '" + CurFile + "' not found in folder '" + os.path.dirname(path))
if user_output: if user_output:
for CurFile in user_output: for CurFile in user_output:
...@@ -452,11 +413,24 @@ class MbsResult(object): ...@@ -452,11 +413,24 @@ class MbsResult(object):
mbs_msg("DEBUG>> file '" + CurFile + "' not found in folder '" + os.path.dirname(path)) mbs_msg("DEBUG>> file '" + CurFile + "' not found in folder '" + os.path.dirname(path))
if user_vector: if user_vector:
buffer_id = _buffer_ids.BUFFER_OTHER.value
for CurFile in user_vector: for CurFile in user_vector:
# Remove the eventual path from filename
CurFile = os.path.basename(CurFile)
path = os.path.abspath(os.path.join(result_path, CurFile)) path = os.path.abspath(os.path.join(result_path, CurFile))
name = CurFile[len(baseFileName) + 1:-4]
# Remove the basefilename
buffer_name = CurFile
if buffer_name.startswith(baseFileName):
buffer_name = buffer_name[len(baseFileName) + 1:]
# Remove extension
if buffer_name.endswith(ext):
buffer_name = buffer_name[:-len(ext)]
if(os.path.isfile(path)): if(os.path.isfile(path)):
self.outputs[name] = np.loadtxt(path) file_array = np.loadtxt(path)
else: self.set_buffer(buffer_id, file_array, buffer_name)
if __DEBUG__: elif __DEBUG__:
mbs_msg("DEBUG>> file '" + CurFile + "' not found in folder '" + os.path.dirname(path)) mbs_msg("DEBUG>> file '" + CurFile + "' not found in folder '" + os.path.dirname(path))
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