diff --git a/msgpi/analysis.py b/msgpi/analysis.py deleted file mode 100644 index 8b14101..0000000 --- a/msgpi/analysis.py +++ /dev/null @@ -1,321 +0,0 @@ -import os -import traceback -import subprocess as sbp - -import msgpi.logger as mlog -# import msgpi.timer as mtime -import msgpi.presg as psg -import msgpi.io.iosc as miosc -import msgpi.io.iovabs as miovabs -# import msgpi.utils as utils - -def solve( - sg_xml, analysis, ppcmd, solver, integrated=False, - aperiodic=False, output_gmsh_format=True, reduced_integration=False, - timeout=30, scrnout=True, logger=None, timer=None - ): - """Solve - - Parameters - ---------- - sg_xml : str - File name of SG design parameters (XML format). - analysis : str - Analysis to be carried out. - - * h - homogenization - * d - dehomogenization/localization/recover - * f - initial failure strength - * fe - initial failure envelope - * fi - initial failure indices and strength ratios - ppcmd : str - Preprocessor command. - solver : str - Command of the solver. - integrated : bool, optional - Use integrated solver or not (standalone), by default False. - aperiodic : bool, optional - (SwiftComp) If the structure gene is periodic, by default False. - output_gmsh_format : bool, optional - (SwiftComp) If output dehomogenization results in Gmsh format, by default True - reduced_integration : bool, optional - (SwiftComp) If reduced integration is used for certain elements, by default False. - timeout : int, optional - Time to wait before stop, by default 30. - scrnout : bool, optional - Switch of printing solver messages, by default True. - logger : logging.Logger, optional - Logger object, by default None. - - Returns - ------- - various - Different analyses return different types of results. - """ - - if logger is None: - logger = mlog.initLogger(__name__) - - # t = mtime.Timer(logger=logger.info) - - # Preprocess - logger.info('preprocessing...') - - if timer: - timer.start() - sg_in, smdim = psg.preSG( - sg_xml, analysis, ppcmd, solver, integrated, - timeout=timeout, scrnout=scrnout, logger=logger - ) - if timer: - timer.stop() - - - # Solve - if not integrated: - logger.info('running analysis...') - logger.debug('solver: ' + solver) - if timer: - timer.start() - run( - solver, sg_in, analysis, smdim, - aperiodic, output_gmsh_format, reduced_integration, - scrnout, logger=logger - ) - if timer: - timer.stop() - - - # Parse results - logger.info('reading results...') - - results = None - - if timer: - timer.start() - - if 'vabs' in solver.lower(): - results = miovabs.readVABSOut(sg_in, analysis, scrnout) - - elif 'swiftcomp' in solver.lower(): - results = miosc.readSCOut(sg_in, smdim, analysis, scrnout) - - - if timer: - timer.stop() - - return results - - - - - - - - - -def runVABS(command, input_name, analysis, scrnout=True, logger=None): - """Run VABS. - - Parameters - ---------- - command : str - Command name of VABS - input_name : str - Name of the input file. - analysis : {0, 1, 2, 3, '', 'h', 'dn', 'dl', 'd', 'l', 'fi'} - Analysis to be carried out. - - * 0 or 'h' or '' - homogenization - * 1 or 'dn' - dehomogenization (nonlinear) - * 2 or 'dl' or 'd' or 'l' - dehomogenization (linear) - * 3 or 'fi' - initial failure indices and strength ratios - scrnout : bool, default True - Switch of printing solver messages. - logger : logging.Logger - Logger object - """ - - if logger is None: - logger = mlog.initLogger(__name__) - - try: - cmd = [command, input_name] - - if analysis == 0 or analysis == 'h' or analysis == '': - pass - elif analysis == 1 or analysis == 'dn': - cmd.append('1') - elif analysis == 2 or analysis == 'dl' or analysis == 'd' or analysis == 'l': - cmd.append('2') - elif analysis == 3 or analysis == 'fi': - cmd.append('3') - - logger.info(' '.join(cmd)) - - if scrnout: - sbp.call(cmd) - else: - FNULL = open(os.devnull, 'w') - sbp.call(cmd, stdout=FNULL, stderr=sbp.STDOUT) - - except: - e = traceback.format_exc() - logger.critical(e, exc_info=1) - - return - - - - - - - - - -def runSwiftComp( - command, input_name, analysis, smdim, - aperiodic=False, output_gmsh_format=True, reduced_integration=False, - scrnout=True, logger=None): - """Run SwiftComp. - - Parameters - ---------- - command : str - Command name of SwiftComp - input_name : str - Name of the input file. - analysis : {0, 2, 3, 4, 5, '', 'h', 'dl', 'd', 'l', 'fi', 'f', 'fe'} - Analysis to be carried out. - - * 0 or 'h' or '' - homogenization - * 2 or 'dl' or 'd' or 'l' - dehomogenization (linear) - * 3 or 'fi' - initial failure indices and strength ratios - * 4 or 'f' - initial failure strength - * 5 or 'fe' - initial failure envelope - smdim : int - Dimension of the macroscopic structural model. - aperiodic : bool - If the structure gene is periodic. - output_gmsh_format : bool - If output dehomogenization results in Gmsh format - reduced_integration : bool - If reduced integration is used for certain elements. - scrnout : bool, default True - Switch of printing solver messages.. - logger : logging.Logger - Logger object - """ - - if logger is None: - logger = mlog.initLogger(__name__) - - try: - cmd = [command, input_name] - - cmd.append(str(smdim) + 'D') - - arg = '' - - if analysis == 0 or analysis == 'h' or analysis == '': - arg = 'H' - if aperiodic: - arg += 'A' - elif analysis == 2 or analysis == 'dl' or analysis == 'd' or analysis == 'l': - arg = 'L' - if aperiodic: - arg += 'A' - if output_gmsh_format: - arg += 'G' - elif analysis == 3 or analysis == 'fi': - arg = 'FI' - elif analysis == 4 or analysis == 'f': - arg = 'F' - elif analysis == 5 or analysis == 'fe': - arg = 'FE' - - - - cmd.append(arg) - - if reduced_integration: - cmd.append('R') - - logger.info(' '.join(cmd)) - - if scrnout: - sbp.call(cmd) - else: - FNULL = open(os.devnull, 'w') - sbp.call(cmd, stdout=FNULL, stderr=sbp.STDOUT) - - except: - e = traceback.format_exc() - logger.critical(e, exc_info=1) - - return - - - - - - - - - -def run( - command, input_name, analysis, smdim=2, - aperiodic=False, output_gmsh_format=True, reduced_integration=False, - scrnout=True, logger=None): - """Run codes. - - Parameters - ---------- - command : str - Command name of VABS or SwiftComp - input_name : str - Name of the input file. - analysis : {0, 1, 2, 3, 4, 5, '', 'h', 'dn', 'dl', 'd', 'l', 'fi', 'f', 'fe'} - Analysis to be carried out. - - * 0 or 'h' or '' - homogenization - * 1 or 'dn' - (VABS) dehomogenization (nonlinear) - * 2 or 'dl' or 'd' or 'l' - dehomogenization (linear) - * 3 or 'fi' - initial failure indices and strength ratios - * 4 or 'f' - (SwiftComp) initial failure strength - * 5 or 'fe' - (SwiftComp) initial failure envelope - smdim : int - (SwiftComp) Dimension of the macroscopic structural model. - aperiodic : bool - (SwiftComp) If the structure gene is periodic. - output_gmsh_format : bool - (SwiftComp) If output dehomogenization results in Gmsh format - reduced_integration : bool - (SwiftComp) If reduced integration is used for certain elements. - scrnout : bool, default True - Switch of printing solver messages. - logger : logging.Logger - Logger object - """ - if logger is None: - logger = mlog.initLogger(__name__) - - try: - if 'vabs' in command.lower(): - runVABS(command, input_name, analysis, scrnout, logger) - - elif 'swiftcomp' in command.lower(): - runSwiftComp( - command, input_name, analysis, smdim, - aperiodic, output_gmsh_format, reduced_integration, - scrnout, logger - ) - - except: - e = traceback.format_exc() - logger.critical(e, exc_info=1) - - -def runBatch(): - - return diff --git a/msgpi/csda.py b/msgpi/csda.py index 629d815..fcce600 100644 --- a/msgpi/csda.py +++ b/msgpi/csda.py @@ -7,6 +7,8 @@ class CrossSectionDesignAnalysis(DesignAnalysis): + class_name = 'cs' + def __init__(self, name='', inputs={}, outputs={}, settings={}, prepros=[], postpros=[], analyses=[], logger=None): DesignAnalysis.__init__(self, inputs, outputs, settings, prepros, postpros, analyses, logger) # self.cs = cs diff --git a/msgpi/dakota/interface.py b/msgpi/dakota/interface.py new file mode 100644 index 0000000..19eaf4c --- /dev/null +++ b/msgpi/dakota/interface.py @@ -0,0 +1,477 @@ +import json +import traceback as tb + +import msgpi.design_analysis as mda +import msgpi.utils.logger as mlog +import dakota.interfacing as di + + +class DakotaDesignAnalysis(mda.DesignAnalysis): + def __init__(self): + mda.DesignAnalysis.__init__(self) + self.evid = 0 + self.inputs = {} + self.outputs = { + "interim": {}, + "final": [] + } + self.settings = {} + self.interface_args = {} + self.analyses = [] + self.classes = [] + self.objects = [] + self.log_prompt = '' + self.logger = None + self.das = {} + + + def initialize(self, fn_json_args): + + # Load JSON arguments + # ------------------- + with open(fn_json_args, 'r') as fo: + self.interface_args = json.load(fo) + + self.updateDataAll(self.interface_args) + + # ------------------------------------------------------------ + # FROM DAKOTA + # ------------------------------------------------------------ + + try: + dakota_params, dakota_results = di.read_parameters_file( + 'input.in', 'output.out' + ) + + self.evid = int(dakota_params.eval_id) + self.log_prompt = f'eval {self.evid}' + self.inputs['eval_id'] = self.evid + for param_name in dakota_params.descriptors: + self.inputs[param_name] = dakota_params[param_name] + except FileNotFoundError: + pass + + # ------------------------------------------------------------ + # FROM DAKOTA END + # ------------------------------------------------------------ + + + # Load data processing module + # --------------------------- + # try: + # fn_dpf = self.interface_args['data_process_functions_file'] + # if fn_dpf != '': + # import_str = 'import {0} as dpf'.format(fn_dpf) + # exec(import_str) + # except KeyError: + # pass + + + + # Initialize inputs/outputs data structure + # ---------------------------------------- + for analysis in self.analyses: + cls = analysis['class'] + + if not cls in self.inputs.keys(): + self.inputs[cls] = {} + if not cls in self.outputs.keys(): + self.outputs[cls] = {} + if not cls in self.classes: + self.classes.append(cls) + + for obj in analysis.keys(): + if obj in ['class', 'all']: + continue + + if not obj in self.inputs[cls].keys(): + self.inputs[cls][obj] = {} + if not obj in self.outputs[cls].keys(): + self.outputs[cls][obj] = {} + if not obj in self.objects: + self.objects.append(obj) + + + # Logger initialization + # --------------------- + try: + log_level_cmd = self.settings['log_level_cmd'].upper() + except KeyError: + log_level_cmd = 'INFO' + self.settings['log_level_cmd'] = log_level_cmd + + try: + log_level_file = self.settings['log_level_file'].upper() + except KeyError: + log_level_file = 'INFO' + self.settings['log_level_file'] = log_level_file + + try: + log_file_name = self.settings['log_file_name'] + except KeyError: + log_file_name = 'log.txt' + self.settings['log_file_name'] = log_file_name + + self.logger = mlog.initLogger( + __name__, + cout_level=log_level_cmd, fout_level=log_level_file, filename=log_file_name + ) + + self.logger.info(f'{self.log_prompt} start') + + return + + + def writeOutput(self, status): + if status == 0: + # Success + with open('interim.out', 'w') as fo: + json.dump(self.outputs['interim'], fo, indent=4) + + with open('output.out', 'w') as fo: + for r in self.outputs['final']: + fo.write(f'{r[1]:24.16E} {r[0]}\n') + + + self.logger.critical(f'{self.log_prompt} finished') + elif status == 1: + # Fail + self.logger.info(f'{self.log_prompt} failed') + with open('output.out', 'w') as fo: + fo.write('FAIL') + + e = tb.format_exc() + print(e) + + return + + + + + + + + + +# ============== +# LEGACY SCRIPTS +# ============== + + +# def process(fn_json_args): +# # if logger is None: +# # logger = mlog.initLogger(__name__) +# # if timer is None: +# # timer = mtime.Timer(logger=logger.info) + +# # print() + +# # timer.start() +# # Load JSON arguments +# with open(fn_json_args, 'r') as fo: +# interface_args = json.load(fo) + +# # Set logger +# log_level_cmd = 'INFO' +# log_level_file = 'INFO' +# log_file_name = 'log.txt' +# if 'log_level_cmd' in interface_args.keys(): +# log_level_cmd = interface_args['log_level_cmd'].upper() +# if 'log_level_file' in interface_args.keys(): +# log_level_file = interface_args['log_level_file'].upper() +# if 'log_file_name' in interface_args.keys(): +# log_file_name = interface_args['log_file_name'] +# logger = mlog.initLogger( +# __name__, +# cout_level=log_level_cmd, fout_level=log_level_file, filename=log_file_name +# ) + +# # Load data processing module +# if 'data_process_functions_file' in interface_args.keys(): +# fn_dpf = interface_args['data_process_functions_file'] +# if fn_dpf != '': +# import_str = 'import {0} as dpf'.format(fn_dpf) +# exec(import_str) + + +# # Read parameters +# params, results = di.read_parameters_file(sys.argv[-2], sys.argv[-1]) + + +# # Pre-processing of parameters +# if 'pre_process' in interface_args.keys(): +# funcs = interface_args['pre_process'] +# if len(funcs) > 0: +# for func in funcs: +# eval('dpf.{0}'.format(func))(params) + + +# # Substitute templates +# for fn_t, fn_i in interface_args['template_output'].items(): +# di.dprepro(template=fn_t, parameters=params, output=fn_i) + +# evid = int(params.eval_id) +# # print(msgfmt_w_ts.format( +# # ts=dt.datetime.now(), +# # msg=' '.join(('eval', str(evid), 'start')) +# # )) +# evtag = ' '.join(('eval', str(evid))) +# logger.info(' '.join((evtag, 'start'))) + + +# try: +# # preVABS/VABS +# # print(' - running cross-sectional analysis...') +# logger.info(evtag + ' running cross-sectional analysis...') +# fn_main = interface_args['fn_main'] +# analysis = interface_args['analysis'] + +# if platform.system() == 'Windows': +# ppcmd = interface_args['prevabs_cmd_win'] +# elif platform.system() == 'Linux': +# ppcmd = interface_args['prevabs_cmd_linux'] + +# solver = interface_args['solver'] +# integrated = False +# if 'integrated' in interface_args.keys(): +# integrated = interface_args['integrated'] +# timeout = 30 +# if 'timeout' in interface_args.keys(): +# timeout = interface_args['timeout'] +# scrnout = False +# if 'scrnout' in interface_args.keys(): +# scrnout = interface_args['scrnout'] + +# # timer.stop() + + +# # timer.start() +# bp = sga.solve( +# fn_main, analysis, ppcmd, solver, integrated, +# timeout=timeout, scrnout=scrnout, logger=logger +# ) +# # timer.stop() + + +# # timer.start() +# # Location of the origin relative to a ref point +# # e.g., leading edge of the airfoil +# # origin_ref_2 = interface_args['origin_ref_2'] +# # sc_ref_2 = ms.shear_center[1] + origin_ref_2 +# # xo2 = 0 +# # xo3 = 0 + + +# # Extract beam properties +# # bps = {'xo2': xo2, 'xo3': xo3} +# bps = {} +# for n in interface_args['beam_properties']: +# bps[n] = bp.get(n) + +# # Calculate actual responses +# # rc = None +# inter = {} # Intermediate values + + +# for pp in interface_args['post_process']: +# fn = pp[0] # function name +# rn = pp[1] # response name +# # print(rn) +# args = pp[1:] +# if fn == 'self': +# # r = bps[args[1]] +# inter[rn] = bps[args[1]] +# else: +# r = eval(f'dpf.{fn}')(interface_args, params, bps, inter, *args) +# # results[rn].function = r +# # print(results.descriptors) +# # print(inter) +# for rn in results.descriptors: +# if rn in inter.keys(): +# results[rn].function = inter[rn] + + +# # Write output +# results.write() + +# # print(' - done.') +# logger.critical(' '.join((evtag, 'finished'))) +# # timer.stop() + +# return + +# except: +# # print(fse.format(dt.datetime.now(), evid, 'FAIL')) +# logger.critical(' '.join((evtag, 'failed'))) +# if 'fail_replace' in interface_args.keys(): +# for k, v in interface_args['fail_replace'].items(): +# # if v == 'inf' or v == '-inf': +# results[k].function = float(v) +# results.write() +# else: +# results.fail() +# with open('results.out', 'w') as fout: +# results.write(stream=fout) +# e = tb.format_exc() +# print(e) + +# # timer.stop() + +# return + + + + + + + + + + +# def substitute( +# fn_temp, fn_true, fn_dvc_labels, fn_dvd_labels, +# fn_finals='finaldata1.dat', final_line=1, params={}, proc_func=None +# ): +# print('- reading variable labels...') +# dvc_labels = [] +# with open(fn_dvc_labels, 'r') as fo: +# for line in fo.readlines(): +# line = line.replace("'", "") +# line = line.strip().split() +# dvc_labels = dvc_labels + line +# # print(line) +# ndvc = len(dvc_labels) +# # print(ndvc, dvc_labels) + +# dvd_labels = [] +# with open(fn_dvd_labels, 'r') as fo: +# for line in fo.readlines(): +# line = line.replace("'", "") +# line = line.strip().split() +# dvd_labels = dvd_labels + line +# # print(line) +# ndvd = len(dvd_labels) +# # print(ndvd, dvd_labels) + + +# print('- reading final data...') +# dvcs = [] +# dvds = [] +# with open(fn_finals, 'r') as fo: +# ro = csv.reader(fo, delimiter='\t') +# for row in ro: +# dvc = list(map(float, row[:ndvc])) +# dvd = list(map(int, row[ndvc:(ndvc+ndvd)])) +# dvcs.append(dvc) +# dvds.append(dvd) +# # print(nums_d) +# # print(dvcs) + + +# print('- creating params...') +# for label, dv in zip(dvc_labels, dvcs[final_line-1]): +# params[label] = dv +# for label, dv in zip(dvd_labels, dvds[final_line-1]): +# params[label] = dv + +# if not proc_func is None: +# if type(proc_func).__name__ == 'list': +# for pf in proc_func: +# pf(params) +# else: +# proc_func(params) +# # print(params) + + +# print('- substituting...') +# di.dprepro(template=fn_temp, include=params, output=fn_true) + + +# print('- done.') + + + + + + + + + +# # Format string +# fse = 'x [{0:%H}:{0:%M}] eval {1:6d} {2:s}' +# fsi = '> [{0:%H}:{0:%M}] eval {1:6d} {2:s}' + + +# def printInfo(evid, *argv): +# print('> [{0:%H}:{0:%M}] eval {1:6d} {2:s}'.format( +# dt.datetime.now(), evid, ' '.join(argv) +# )) + + +# def interface(params, results, tmp_map, res_map, sg_xml, analysis, solver, scrnout=True): +# """ Create a workflow for a design problem using Dakota + +# Parameters +# ---------- +# params : Parameters +# Dakota Parameters object +# results : Results +# Dakota Results object +# tmp_map : dict +# Dictionary of file names that will be used in dprepro +# {'template name': 'true name', ...} +# res_map : dict +# Disctionary of keywords for results of Dakota +# {'dakota_response_keyword': 'sg_result_keyword', ...} +# sg_xml : str +# Main file name for preprocessor +# analysis : str +# The analysis that will be carried out after the generation of +# the input file. +# h - homogenization +# d - dehomogenization/localization/recover +# f - initial failure strength +# fe - initial failure envelope +# fi - initial failure indices and strength ratios +# solver : str +# The name of the executable ('vabs' or 'swiftcomp') +# """ +# evid = int(params.eval_id) + +# # try: +# print(' - eval {evid:d}: writing input files...'.format(evid=evid)) +# for fn_t, fn_i in tmp_map.items(): +# di.dprepro(template=fn_t, parameters=params, output=fn_i) + +# # Solve homogenization +# print(' - eval {evid:d}: running solver...'.format(evid=evid)) +# sm = sga.solve(sg_xml, analysis, solver, scrnout) + +# # Extract results needed +# print(' - eval {evid:d}: extracting results...'.format(evid=evid)) +# for k, v in res_map.items(): +# tmp = sm.eff_props +# v = v.strip().split('.') +# for i, tag in enumerate(v): +# if '#' in tag: +# tag = int(tag.replace('#', '')) +# if i > 0: +# tag = tag - 1 +# tmp = tmp[tag] +# results[k].function = tmp + +# # except: +# # e = sys.exc_info()[0] +# # print('Error:', e) +# # results.fail() +# # with open('results.out', 'w') as fout: +# # results.write(stream=fout) +# # # printInfo(evid, '>>> FAIL <<<') +# # return + +# # else: +# # results.write() +# # # printInfo(evid, '>>> FINISH <<<') + + + diff --git a/msgpi/design_analysis.py b/msgpi/design_analysis.py index 5c5aff6..d245ce4 100644 --- a/msgpi/design_analysis.py +++ b/msgpi/design_analysis.py @@ -1,15 +1,18 @@ import abc import pprint -import platform -import msgpi.sg.cross_section as mcs +# import platform +# import msgpi.sg.cross_section as mcs import msgpi.utils.logger as mlog -import dakota.interfacing as di +# import dakota.interfacing as di class DesignAnalysis(metaclass=abc.ABCMeta): + class_name = '' + def __init__(self, inputs={}, outputs={}, settings={}, prepros=[], postpros=[], analyses=[], logger=None): # self.object = object + self.name = '' self.design = None self.model = None @@ -41,7 +44,7 @@ def __init__(self, inputs={}, outputs={}, settings={}, prepros=[], postpros=[], def summary(self, title=''): - pp = pprint.PrettyPrinter() + pp = pprint.PrettyPrinter(indent=1, width=-1) print('\n', title) print('----------') print('settings') @@ -73,6 +76,51 @@ def updateData(self, inputs={}, outputs={}, settings={}, prepros=[], postpros=[] return + def pullInputs(self, other_da, ignore_keywords=[]): + assert isinstance(other_da, DesignAnalysis) + + for k, v in other_da.inputs.items(): + if (k in ignore_keywords): + continue + self.inputs[k] = v + + try: + for k, v in other_da.inputs[self.class_name].items(): + if (k in ignore_keywords): + continue + self.inputs[k] = v + + # if self.name in other_da.inputs[self.class_name].items(): + for k, v in other_da.inputs[self.class_name][self.name].items(): + if (k in ignore_keywords): + continue + self.inputs[k] = v + except KeyError: + pass + + + def pushInputs(self, other_da, structured=True): + assert isinstance(other_da, DesignAnalysis) + + if structured: + for k, v in self.inputs.items(): + other_da.inputs[self.class_name][self.name][k] = v + else: + for k, v in self.inputs.items(): + other_da.inputs[k] = v + + + def pushOutputs(self, other_da, structured=True): + assert isinstance(other_da, DesignAnalysis) + + if structured: + for k, v in self.outputs.items(): + other_da.outputs[self.class_name][self.name][k] = v + else: + for k, v in self.outputs.items(): + other_da.outputs[k] = v + + def updateDataAll(self, data): """ data = { @@ -205,44 +253,44 @@ def run(self): -class DakotaDesignAnalysis(DesignAnalysis): - def __init__(self, data={}, fn_dakota_params='', fn_dakota_results='', logger=None): +# class DakotaDesignAnalysis(DesignAnalysis): +# def __init__(self, data={}, fn_dakota_params='', fn_dakota_results='', logger=None): - DesignAnalysis.__init__(self, logger=logger) - self.updateData(data) +# DesignAnalysis.__init__(self, logger=logger) +# self.updateData(data) - # self.dakota_params = None - # self.dakota_results = None +# # self.dakota_params = None +# # self.dakota_results = None - self.dakota_params, self.dakota_results = di.read_parameters_file( - fn_dakota_params, fn_dakota_results - ) - self.settings['eval_num'] = self.dakota_params.eval_num - for param_name in self.dakota_params.descriptors: - self.inputs[param_name] = self.dakota_params[param_name] +# self.dakota_params, self.dakota_results = di.read_parameters_file( +# fn_dakota_params, fn_dakota_results +# ) +# self.settings['eval_num'] = self.dakota_params.eval_num +# for param_name in self.dakota_params.descriptors: +# self.inputs[param_name] = self.dakota_params[param_name] - def analyze(self): +# def analyze(self): - for a in self.analyses: - try: - da = a['object'] - except KeyError: - class_name = a['class'] - da = eval(f'{class_name}DesignAnalysis')(logger=self.logger) +# for a in self.analyses: +# try: +# da = a['object'] +# except KeyError: +# class_name = a['class'] +# da = eval(f'{class_name}DesignAnalysis')(logger=self.logger) - try: - da.updateData(self.settings[a['group']]) - except KeyError: - pass +# try: +# da.updateData(self.settings[a['group']]) +# except KeyError: +# pass - da.updateData(a) +# da.updateData(a) - da.run() +# da.run() - a['object'] = da +# a['object'] = da - return +# return @@ -252,16 +300,16 @@ def analyze(self): -class BladeDesignAnalysis(DesignAnalysis): - def __init__(self, blade=None, data={}, logger=None): - DesignAnalysis.__init__(self, object=blade, logger=logger) - self.updateData(data) +# class BladeDesignAnalysis(DesignAnalysis): +# def __init__(self, blade=None, data={}, logger=None): +# DesignAnalysis.__init__(self, object=blade, logger=logger) +# self.updateData(data) - def generateDesign(self): - return +# def generateDesign(self): +# return - def analyze(self): - return +# def analyze(self): +# return @@ -271,75 +319,75 @@ def analyze(self): -class CrossSectionDesignAnalysis(DesignAnalysis): +# class CrossSectionDesignAnalysis(DesignAnalysis): - def __init__(self, cs: mcs.CrossSection, inputs={}, outputs={}, prepros=[], postpros=[], config={}, logger=None): - DesignAnalysis.__init__(self, cs, inputs, outputs, config, prepros, postpros, logger) - # self.cs = cs - # self.job_args = job_args +# def __init__(self, cs: mcs.CrossSection, inputs={}, outputs={}, prepros=[], postpros=[], config={}, logger=None): +# DesignAnalysis.__init__(self, cs, inputs, outputs, config, prepros, postpros, logger) +# # self.cs = cs +# # self.job_args = job_args - # if logger is None: - # self.logger = mlog.initLogger(__name__) - # else: - # self.logger = logger +# # if logger is None: +# # self.logger = mlog.initLogger(__name__) +# # else: +# # self.logger = logger - # self.inputs = inputs - # self.outputs = {} +# # self.inputs = inputs +# # self.outputs = {} - def analyze(self): - self.logger.info(f'running design analysis for {self.cs.name}...') +# def analyze(self): +# self.logger.info(f'running design analysis for {self.cs.name}...') - analysis = self.config['analysis'] +# analysis = self.config['analysis'] - if platform.system() == 'Windows': - ppcmd = self.config['prevabs_cmd_win'] - elif platform.system() == 'Linux': - ppcmd = self.config['prevabs_cmd_linux'] +# if platform.system() == 'Windows': +# ppcmd = self.config['prevabs_cmd_win'] +# elif platform.system() == 'Linux': +# ppcmd = self.config['prevabs_cmd_linux'] - solver = self.config['solver'] - integrated = False - if 'integrated' in self.config.keys(): - integrated = self.config['integrated'] - timeout = 30 - if 'timeout' in self.config.keys(): - timeout = self.config['timeout'] - scrnout = False - if 'scrnout' in self.config.keys(): - scrnout = self.config['scrnout'] +# solver = self.config['solver'] +# integrated = False +# if 'integrated' in self.config.keys(): +# integrated = self.config['integrated'] +# timeout = 30 +# if 'timeout' in self.config.keys(): +# timeout = self.config['timeout'] +# scrnout = False +# if 'scrnout' in self.config.keys(): +# scrnout = self.config['scrnout'] - # Pre-process data - # ---------------- - self.preprocess() +# # Pre-process data +# # ---------------- +# self.preprocess() - # Substitute parameters - # --------------------- - if self.sg.fn_design_xml == '': - self.sg.fn_design_xml = self.sg.name + '.xml' - di.dprepro( - template=self.sg.fn_design_tmp, output=self.sg.fn_design_xml, - include=self.inputs - ) - - # Solve - # ----- - self.sg.props = sga.solve( - self.sg.fn_design_xml, analysis, ppcmd, solver, integrated, - timeout=timeout, scrnout=scrnout, logger=self.logger - ) +# # Substitute parameters +# # --------------------- +# if self.sg.fn_design_xml == '': +# self.sg.fn_design_xml = self.sg.name + '.xml' +# di.dprepro( +# template=self.sg.fn_design_tmp, output=self.sg.fn_design_xml, +# include=self.inputs +# ) - # Extract beam properties - # ----------------------- - self.logger.debug('extracting beam properties...') - for n in self.job_args['beam_properties']: - self.outputs[n] = self.sg.props.get(n) +# # Solve +# # ----- +# self.sg.props = sga.solve( +# self.sg.fn_design_xml, analysis, ppcmd, solver, integrated, +# timeout=timeout, scrnout=scrnout, logger=self.logger +# ) +# # Extract beam properties +# # ----------------------- +# self.logger.debug('extracting beam properties...') +# for n in self.job_args['beam_properties']: +# self.outputs[n] = self.sg.props.get(n) - # Post-process data - # ----------------- - self.postprocess() + +# # Post-process data +# # ----------------- +# self.postprocess() diff --git a/msgpi/legacy/analysis.py b/msgpi/legacy/analysis.py index 02ff934..8b14101 100644 --- a/msgpi/legacy/analysis.py +++ b/msgpi/legacy/analysis.py @@ -1,139 +1,321 @@ import os -import sys -import datetime as dt +import traceback import subprocess as sbp -import traceback as tb -import numpy as np -import msgpi.ms.prebeam as prb -import msgpi.ms.iogebt as miogebt -import msgpi.io.iovabs as miovabs - -def solveGEBT(beam_xml, scrnout=True): - """Carry out a global beam analysis using GEBT. +import msgpi.logger as mlog +# import msgpi.timer as mtime +import msgpi.presg as psg +import msgpi.io.iosc as miosc +import msgpi.io.iovabs as miovabs +# import msgpi.utils as utils - This function includes the preprocessing of the input data, - running GEBT and parsing the results. +def solve( + sg_xml, analysis, ppcmd, solver, integrated=False, + aperiodic=False, output_gmsh_format=True, reduced_integration=False, + timeout=30, scrnout=True, logger=None, timer=None + ): + """Solve Parameters ---------- - beam_xml : str - Beam xml input file. - scrnout : bool - Switch for printing GEBT cmd outputs. + sg_xml : str + File name of SG design parameters (XML format). + analysis : str + Analysis to be carried out. + + * h - homogenization + * d - dehomogenization/localization/recover + * f - initial failure strength + * fe - initial failure envelope + * fi - initial failure indices and strength ratios + ppcmd : str + Preprocessor command. + solver : str + Command of the solver. + integrated : bool, optional + Use integrated solver or not (standalone), by default False. + aperiodic : bool, optional + (SwiftComp) If the structure gene is periodic, by default False. + output_gmsh_format : bool, optional + (SwiftComp) If output dehomogenization results in Gmsh format, by default True + reduced_integration : bool, optional + (SwiftComp) If reduced integration is used for certain elements, by default False. + timeout : int, optional + Time to wait before stop, by default 30. + scrnout : bool, optional + Switch of printing solver messages, by default True. + logger : logging.Logger, optional + Logger object, by default None. Returns ------- + various + Different analyses return different types of results. """ + if logger is None: + logger = mlog.initLogger(__name__) + + # t = mtime.Timer(logger=logger.info) + # Preprocess - beam = prb.preBeam(beam_xml) + logger.info('preprocessing...') - for sid, mso in beam.sections.items(): - section = miovabs.readVABSOutHomo(mso.name+'.sg.k') - beam.sections[sid] = section + if timer: + timer.start() + sg_in, smdim = psg.preSG( + sg_xml, analysis, ppcmd, solver, integrated, + timeout=timeout, scrnout=scrnout, logger=logger + ) + if timer: + timer.stop() - fn_gebt_in = miogebt.writeGEBTIn(beam, beam.name+'.dat') # Solve - fn_gebt_out = runGEBT(fn_gebt_in, scrnout) + if not integrated: + logger.info('running analysis...') + logger.debug('solver: ' + solver) + if timer: + timer.start() + run( + solver, sg_in, analysis, smdim, + aperiodic, output_gmsh_format, reduced_integration, + scrnout, logger=logger + ) + if timer: + timer.stop() + # Parse results - results = miogebt.readGEBTOut(fn_gebt_out, beam) + logger.info('reading results...') + + results = None + if timer: + timer.start() + + if 'vabs' in solver.lower(): + results = miovabs.readVABSOut(sg_in, analysis, scrnout) + + elif 'swiftcomp' in solver.lower(): + results = miosc.readSCOut(sg_in, smdim, analysis, scrnout) + + + if timer: + timer.stop() + return results -def runGEBT(fn_input, scrnout=True): - """Run GEBT analysis. + + + + + + + +def runVABS(command, input_name, analysis, scrnout=True, logger=None): + """Run VABS. Parameters ---------- - fn_input : str - File name of the GEBT input. - scrnout : bool - Switch for printing GEBT cmd outputs. + command : str + Command name of VABS + input_name : str + Name of the input file. + analysis : {0, 1, 2, 3, '', 'h', 'dn', 'dl', 'd', 'l', 'fi'} + Analysis to be carried out. - Returns - ------- - str - File name of the GEBT output. + * 0 or 'h' or '' - homogenization + * 1 or 'dn' - dehomogenization (nonlinear) + * 2 or 'dl' or 'd' or 'l' - dehomogenization (linear) + * 3 or 'fi' - initial failure indices and strength ratios + scrnout : bool, default True + Switch of printing solver messages. + logger : logging.Logger + Logger object """ - cmd = ['gebt', fn_input] - # cmd = ' '.join(cmd) + + if logger is None: + logger = mlog.initLogger(__name__) try: - sys.stdout.write(' - running gebt...\n') - sys.stdout.flush() + cmd = [command, input_name] + + if analysis == 0 or analysis == 'h' or analysis == '': + pass + elif analysis == 1 or analysis == 'dn': + cmd.append('1') + elif analysis == 2 or analysis == 'dl' or analysis == 'd' or analysis == 'l': + cmd.append('2') + elif analysis == 3 or analysis == 'fi': + cmd.append('3') + + logger.info(' '.join(cmd)) + if scrnout: sbp.call(cmd) else: FNULL = open(os.devnull, 'w') sbp.call(cmd, stdout=FNULL, stderr=sbp.STDOUT) + except: - # sys.stdout.write('failed\n') - # sys.stdout.flush() - print(tb.format_exc()) - return + e = traceback.format_exc() + logger.critical(e, exc_info=1) + + return - return fn_input + '.out' -def solvePLECS(length, compliance, x1, f1=0, f2=0, f3=0, m1=0, m2=0, m3=0): - """ Solve the static problem of a prismatic, linearly elastic, - cantilever beam. Find the three displacements and three rotations - of a point x1 given loads f1, f2, f3, m1, m2, m3 applied at the - tip. - Equations (5.59) and (5.61) from the book - Nonlinear Composite Beam Theory by D. H. Hodges - are used. + + + + + +def runSwiftComp( + command, input_name, analysis, smdim, + aperiodic=False, output_gmsh_format=True, reduced_integration=False, + scrnout=True, logger=None): + """Run SwiftComp. Parameters ---------- - length : float - Total length of the beam. - compliance : list of lists of floats - The 6x6 compliance matrix of the beam cross-section. - x1 : float - The location where the result is wanted. + command : str + Command name of SwiftComp + input_name : str + Name of the input file. + analysis : {0, 2, 3, 4, 5, '', 'h', 'dl', 'd', 'l', 'fi', 'f', 'fe'} + Analysis to be carried out. - Returns - ------- - list of lists of floats - Results (displacement, rotations, forces, moments). + * 0 or 'h' or '' - homogenization + * 2 or 'dl' or 'd' or 'l' - dehomogenization (linear) + * 3 or 'fi' - initial failure indices and strength ratios + * 4 or 'f' - initial failure strength + * 5 or 'fe' - initial failure envelope + smdim : int + Dimension of the macroscopic structural model. + aperiodic : bool + If the structure gene is periodic. + output_gmsh_format : bool + If output dehomogenization results in Gmsh format + reduced_integration : bool + If reduced integration is used for certain elements. + scrnout : bool, default True + Switch of printing solver messages.. + logger : logging.Logger + Logger object """ - F = np.array([[f1, f2, f3, m1, m2, m3]]).T - e1tilde = np.array([ - [0.0, 0.0, 0.0], - [0.0, 0.0, -1.0], - [0.0, 1.0, 0.0] - ]) + if logger is None: + logger = mlog.initLogger(__name__) + + try: + cmd = [command, input_name] - Fx = np.array([[f1, f2, f3]]).T - Mx = np.array([[m1, m2, m3]]).T + (length - x1) * np.dot(e1tilde, F[:3, :]) + cmd.append(str(smdim) + 'D') - R = compliance[:3, :3] - Z = compliance[:3, 3:] - T = compliance[3:, 3:] + arg = '' - K = np.zeros((6, 6)) + if analysis == 0 or analysis == 'h' or analysis == '': + arg = 'H' + if aperiodic: + arg += 'A' + elif analysis == 2 or analysis == 'dl' or analysis == 'd' or analysis == 'l': + arg = 'L' + if aperiodic: + arg += 'A' + if output_gmsh_format: + arg += 'G' + elif analysis == 3 or analysis == 'fi': + arg = 'FI' + elif analysis == 4 or analysis == 'f': + arg = 'F' + elif analysis == 5 or analysis == 'fe': + arg = 'FE' - # Equation (5.61) - K[:3, :3] = ( - x1 * R + - (x1 * length - x1**2 / 2.0) * np.dot(Z, e1tilde) - - x1**2 / 2.0 * np.dot(e1tilde, Z.T) - - (x1**2 * length / 2.0 - x1**3 / 6.0) * np.dot(e1tilde, np.dot(T, e1tilde)) - ) - K[:3, 3:] = x1 * Z - x1**2 / 2.0 * np.dot(e1tilde, T) - # Equation (5.59) - K[3:, :3] = x1 * Z.T + (x1 * length - x1**2 / 2.0) * np.dot(T, e1tilde) - K[3:, 3:] = x1 * T - ur = np.dot(K, F) - result = np.vstack((ur, Fx, Mx)) + cmd.append(arg) + + if reduced_integration: + cmd.append('R') + + logger.info(' '.join(cmd)) + + if scrnout: + sbp.call(cmd) + else: + FNULL = open(os.devnull, 'w') + sbp.call(cmd, stdout=FNULL, stderr=sbp.STDOUT) + + except: + e = traceback.format_exc() + logger.critical(e, exc_info=1) + + return + + + + + + + + + +def run( + command, input_name, analysis, smdim=2, + aperiodic=False, output_gmsh_format=True, reduced_integration=False, + scrnout=True, logger=None): + """Run codes. + + Parameters + ---------- + command : str + Command name of VABS or SwiftComp + input_name : str + Name of the input file. + analysis : {0, 1, 2, 3, 4, 5, '', 'h', 'dn', 'dl', 'd', 'l', 'fi', 'f', 'fe'} + Analysis to be carried out. + + * 0 or 'h' or '' - homogenization + * 1 or 'dn' - (VABS) dehomogenization (nonlinear) + * 2 or 'dl' or 'd' or 'l' - dehomogenization (linear) + * 3 or 'fi' - initial failure indices and strength ratios + * 4 or 'f' - (SwiftComp) initial failure strength + * 5 or 'fe' - (SwiftComp) initial failure envelope + smdim : int + (SwiftComp) Dimension of the macroscopic structural model. + aperiodic : bool + (SwiftComp) If the structure gene is periodic. + output_gmsh_format : bool + (SwiftComp) If output dehomogenization results in Gmsh format + reduced_integration : bool + (SwiftComp) If reduced integration is used for certain elements. + scrnout : bool, default True + Switch of printing solver messages. + logger : logging.Logger + Logger object + """ + if logger is None: + logger = mlog.initLogger(__name__) + + try: + if 'vabs' in command.lower(): + runVABS(command, input_name, analysis, scrnout, logger) + + elif 'swiftcomp' in command.lower(): + runSwiftComp( + command, input_name, analysis, smdim, + aperiodic, output_gmsh_format, reduced_integration, + scrnout, logger + ) + + except: + e = traceback.format_exc() + logger.critical(e, exc_info=1) + + +def runBatch(): - return result + return diff --git a/msgpi/legacy/beam_analysis.py b/msgpi/legacy/beam_analysis.py new file mode 100644 index 0000000..02ff934 --- /dev/null +++ b/msgpi/legacy/beam_analysis.py @@ -0,0 +1,139 @@ +import os +import sys +import datetime as dt +import subprocess as sbp +import traceback as tb +import numpy as np +import msgpi.ms.prebeam as prb +import msgpi.ms.iogebt as miogebt +import msgpi.io.iovabs as miovabs + + +def solveGEBT(beam_xml, scrnout=True): + """Carry out a global beam analysis using GEBT. + + This function includes the preprocessing of the input data, + running GEBT and parsing the results. + + Parameters + ---------- + beam_xml : str + Beam xml input file. + scrnout : bool + Switch for printing GEBT cmd outputs. + + Returns + ------- + """ + + # Preprocess + beam = prb.preBeam(beam_xml) + + for sid, mso in beam.sections.items(): + section = miovabs.readVABSOutHomo(mso.name+'.sg.k') + beam.sections[sid] = section + + fn_gebt_in = miogebt.writeGEBTIn(beam, beam.name+'.dat') + + # Solve + fn_gebt_out = runGEBT(fn_gebt_in, scrnout) + + # Parse results + results = miogebt.readGEBTOut(fn_gebt_out, beam) + + return results + + +def runGEBT(fn_input, scrnout=True): + """Run GEBT analysis. + + Parameters + ---------- + fn_input : str + File name of the GEBT input. + scrnout : bool + Switch for printing GEBT cmd outputs. + + Returns + ------- + str + File name of the GEBT output. + """ + cmd = ['gebt', fn_input] + # cmd = ' '.join(cmd) + + try: + sys.stdout.write(' - running gebt...\n') + sys.stdout.flush() + if scrnout: + sbp.call(cmd) + else: + FNULL = open(os.devnull, 'w') + sbp.call(cmd, stdout=FNULL, stderr=sbp.STDOUT) + except: + # sys.stdout.write('failed\n') + # sys.stdout.flush() + print(tb.format_exc()) + return + + return fn_input + '.out' + + +def solvePLECS(length, compliance, x1, f1=0, f2=0, f3=0, m1=0, m2=0, m3=0): + """ Solve the static problem of a prismatic, linearly elastic, + cantilever beam. Find the three displacements and three rotations + of a point x1 given loads f1, f2, f3, m1, m2, m3 applied at the + tip. + + Equations (5.59) and (5.61) from the book + Nonlinear Composite Beam Theory by D. H. Hodges + are used. + + Parameters + ---------- + length : float + Total length of the beam. + compliance : list of lists of floats + The 6x6 compliance matrix of the beam cross-section. + x1 : float + The location where the result is wanted. + + Returns + ------- + list of lists of floats + Results (displacement, rotations, forces, moments). + """ + + F = np.array([[f1, f2, f3, m1, m2, m3]]).T + e1tilde = np.array([ + [0.0, 0.0, 0.0], + [0.0, 0.0, -1.0], + [0.0, 1.0, 0.0] + ]) + + Fx = np.array([[f1, f2, f3]]).T + Mx = np.array([[m1, m2, m3]]).T + (length - x1) * np.dot(e1tilde, F[:3, :]) + + R = compliance[:3, :3] + Z = compliance[:3, 3:] + T = compliance[3:, 3:] + + K = np.zeros((6, 6)) + + # Equation (5.61) + K[:3, :3] = ( + x1 * R + + (x1 * length - x1**2 / 2.0) * np.dot(Z, e1tilde) - + x1**2 / 2.0 * np.dot(e1tilde, Z.T) - + (x1**2 * length / 2.0 - x1**3 / 6.0) * np.dot(e1tilde, np.dot(T, e1tilde)) + ) + K[:3, 3:] = x1 * Z - x1**2 / 2.0 * np.dot(e1tilde, T) + + # Equation (5.59) + K[3:, :3] = x1 * Z.T + (x1 * length - x1**2 / 2.0) * np.dot(T, e1tilde) + K[3:, 3:] = x1 * T + + ur = np.dot(K, F) + result = np.vstack((ur, Fx, Mx)) + + return result diff --git a/msgpi/dakota_interface.py b/msgpi/legacy/dakota_interface.py similarity index 100% rename from msgpi/dakota_interface.py rename to msgpi/legacy/dakota_interface.py diff --git a/msgpi/interface.py b/msgpi/legacy/interface.py similarity index 96% rename from msgpi/interface.py rename to msgpi/legacy/interface.py index a4ef390..bfdf2f0 100644 --- a/msgpi/interface.py +++ b/msgpi/legacy/interface.py @@ -1,75 +1,75 @@ -import platform -import msgpi.cross_section as mcs -import msgpi.analysis as sga -import msgpi.logger as mlog -import dakota.interfacing as di - - -class CrossSectionJob(): - - def __init__(self, cs: mcs.CrossSection, inputs={}, job_args={}, logger=None): - self.cs = cs - self.job_args = job_args - - if logger is None: - self.logger = mlog.initLogger(__name__) - else: - self.logger = logger - - self.inputs = inputs - self.outputs = {} - - - - - def run(self): - self.logger.info(f'running analysis job for {self.cs.name}...') - - analysis = self.job_args['analysis'] - - if platform.system() == 'Windows': - ppcmd = self.job_args['prevabs_cmd_win'] - elif platform.system() == 'Linux': - ppcmd = self.job_args['prevabs_cmd_linux'] - - solver = self.job_args['solver'] - integrated = False - if 'integrated' in self.job_args.keys(): - integrated = self.job_args['integrated'] - timeout = 30 - if 'timeout' in self.job_args.keys(): - timeout = self.job_args['timeout'] - scrnout = False - if 'scrnout' in self.job_args.keys(): - scrnout = self.job_args['scrnout'] - - - # fn_main = self.design['fn_cs_main'] - # fn_design_xml = self.cs.name + '.xml' - - # print('\ncs_params') - # pprt.pprint(cs_params) - # print('\n') - - # Substitute parameters - if self.cs.fn_design_xml == '': - self.cs.fn_design_xml = self.cs.name + '.xml' - di.dprepro( - template=self.cs.fn_design_tmp, output=self.cs.fn_design_xml, - include=self.inputs - ) - - # Solve - self.cs.props = sga.solve( - self.cs.fn_design_xml, analysis, ppcmd, solver, integrated, - timeout=timeout, scrnout=scrnout, logger=self.logger - ) - - # Extract beam properties - self.logger.debug('extracting beam properties...') - for n in self.job_args['beam_properties']: - self.outputs[n] = self.cs.props.get(n) - - - # self.cs_data['props'] = self.results - +import platform +import msgpi.cross_section as mcs +import msgpi.analysis as sga +import msgpi.logger as mlog +import dakota.interfacing as di + + +class CrossSectionJob(): + + def __init__(self, cs: mcs.CrossSection, inputs={}, job_args={}, logger=None): + self.cs = cs + self.job_args = job_args + + if logger is None: + self.logger = mlog.initLogger(__name__) + else: + self.logger = logger + + self.inputs = inputs + self.outputs = {} + + + + + def run(self): + self.logger.info(f'running analysis job for {self.cs.name}...') + + analysis = self.job_args['analysis'] + + if platform.system() == 'Windows': + ppcmd = self.job_args['prevabs_cmd_win'] + elif platform.system() == 'Linux': + ppcmd = self.job_args['prevabs_cmd_linux'] + + solver = self.job_args['solver'] + integrated = False + if 'integrated' in self.job_args.keys(): + integrated = self.job_args['integrated'] + timeout = 30 + if 'timeout' in self.job_args.keys(): + timeout = self.job_args['timeout'] + scrnout = False + if 'scrnout' in self.job_args.keys(): + scrnout = self.job_args['scrnout'] + + + # fn_main = self.design['fn_cs_main'] + # fn_design_xml = self.cs.name + '.xml' + + # print('\ncs_params') + # pprt.pprint(cs_params) + # print('\n') + + # Substitute parameters + if self.cs.fn_design_xml == '': + self.cs.fn_design_xml = self.cs.name + '.xml' + di.dprepro( + template=self.cs.fn_design_tmp, output=self.cs.fn_design_xml, + include=self.inputs + ) + + # Solve + self.cs.props = sga.solve( + self.cs.fn_design_xml, analysis, ppcmd, solver, integrated, + timeout=timeout, scrnout=scrnout, logger=self.logger + ) + + # Extract beam properties + self.logger.debug('extracting beam properties...') + for n in self.job_args['beam_properties']: + self.outputs[n] = self.cs.props.get(n) + + + # self.cs_data['props'] = self.results + diff --git a/msgpi/process.py b/msgpi/legacy/process.py similarity index 100% rename from msgpi/process.py rename to msgpi/legacy/process.py