From cebeb864b79a7b9f060ce2dbcd59780d29f55399 Mon Sep 17 00:00:00 2001 From: Su Tian Date: Thu, 22 Jul 2021 17:57:09 -0400 Subject: [PATCH] 0722 --- msgpi/cross_section.py | 14 ++- msgpi/interface.py | 74 +++++++++++++++ msgpi/ms/blade.py | 201 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 274 insertions(+), 15 deletions(-) create mode 100644 msgpi/interface.py diff --git a/msgpi/cross_section.py b/msgpi/cross_section.py index ffdb080..e3eb24e 100644 --- a/msgpi/cross_section.py +++ b/msgpi/cross_section.py @@ -67,12 +67,19 @@ def __init__(self, name): self.name = name self.name_template = '' #: Base name of the main input file template - self.name_baseline = '' #: Base name of the base lines file - self.name_layup = '' #: Base name of the layups file self.fn_vabs_in = self.name + '.sg' #: File name of the VABS input self.fn_sc_in = self.name + '.sg' #: File name of the SwiftComp input # self.fn_gmsh_msh = self.name + '.msh' #: File name of the Gmsh mesh file + self.sg = None # Structure gene + self.bp = None # Beam property + + # Design + self.params = {} + + self.name_baseline = '' #: Base name of the base lines file + self.name_layup = '' #: Base name of the layups file + self.num_layertypes = 0 #: Number of layer types self.layertypes = {} #: Layer types {lid: [mid, ply angle], ...} self.element_layertype = {} @@ -125,7 +132,8 @@ def __init__(self, name): self.fendiv = 10 - + def summary(self): + print(f'Name: {self.name}') diff --git a/msgpi/interface.py b/msgpi/interface.py new file mode 100644 index 0000000..96d4b21 --- /dev/null +++ b/msgpi/interface.py @@ -0,0 +1,74 @@ +import platform +import msgpi.analysis as sga +import msgpi.logger as mlog +import dakota.interfacing as di + + +class CrossSectionJob(): + + def __init__(self, name="", design={}, job_args={}, logger=None): + self.name = name + self.design = design + self.job_args = job_args + + if logger is None: + self.logger = mlog.initLogger(__name__) + else: + self.logger = logger + + self.bp = None + self.result = {} + + + + + def run(self): + self.logger.info(f'running analysis job for {self.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'] + + + + # preVABS/VABS + fn_main = self.design['fn_cs_main'] + + # print('\ncs_params') + # pprt.pprint(cs_params) + # print('\n') + + # Substitute parameters + di.dprepro( + template=self.design['fn_cs_temp'], output=fn_main, + include=self.design + ) + + # Solve + self.bp = sga.solve( + fn_main, 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.result[n] = self.bp.get(n) + + + # self.cs_data['props'] = self.results + diff --git a/msgpi/ms/blade.py b/msgpi/ms/blade.py index 842c9cd..bd93cef 100644 --- a/msgpi/ms/blade.py +++ b/msgpi/ms/blade.py @@ -1,6 +1,7 @@ -import numpy as np import pprint -import msgpi.sg as sg +import xml.etree.ElementTree as et +import msgpi.cross_section as mcs +import msgpi.utils as utils class BladeSegment(object): @@ -18,6 +19,8 @@ def __init__(self): #: `[beginning, ending]` self.css = [] + self.cs_template = [] + # {local coord: section name, ...} self.sections = {} @@ -48,16 +51,6 @@ def summary(self): print(' cs templates:', self.cs_template) print(' cs parameters:', self.cs_parameters) - def calcLengthSq(self): - """Calculate the square of the segment length. - - Returns - ------- - float - Squred length of the segment. - """ - return ((np.array(self.coords[0]) - np.array(self.coords[1]))**2).sum() - @@ -89,6 +82,10 @@ def __init__(self): #: `{sid: BeamProperty object, ...}` self.sections = {} + #: dictionary: Cross-section repository + #: `{name: msgpi.cross_section.CrossSection}` + self.cross_sections_repo = {} + # {section name: msgpi.sg.CrossSection, ...} self.section_database = {} @@ -100,6 +97,9 @@ def __init__(self): self.functions = {} #: Functions self.distributions = {} #: Distributions + # {section name: template name, ...} + self.section_templates = {} + @@ -193,3 +193,180 @@ def findSectionByName(self, name): return 0 + + + def genCrossSectionDesign(self, segi, csj): + bs = self.segments[segi] + cs_name = bs.css[csj] + + # ls_cs_name.append(cs_name) + + # 1. Copy all parameter in the interim_params + # cs_params = copy.deepcopy(params) + cs_params = {} + cs_params['r'] = bs.coords[csj][0] + cs_params['fn_cs_temp'] = bs.cs_template[csj] + cs_params['fn_cs_main'] = cs_name + '.xml' + + # 2. Add parameters calculated from distribution functions + for param, func in self.distributions.items(): + fn = func[0] + cs_params[param] = self.functions[fn](cs_params['r']) + # print(k, dakota_params_cs[k]) + + for param, values in bs.cs_parameters.items(): + cs_params[param] = values[csj] + + # print(cs_params) + # cs_data[cs_name] = {'params': cs_params} + return cs_name, cs_params + + + + + + + + + +def readBladeInput(fn_blade): + + blade = Blade() + + with open(fn_blade, 'r') as fo: + tree = et.parse(fo) + xr_beam = tree.getroot() + + # Read design + xe_design = xr_beam.find('design') + + + + + # Read points + # pn2l = {} # point name to label dictionary + # plabel = 0 + xe_points = xe_design.find('points') + for xe_point in xe_points.findall('point'): + # plabel += 1 + pname = xe_point.get('name') + pcoord = list(map(float, xe_point.text.strip().split())) + # pn2l[pname] = plabel + # beam.points[plabel] = pcoord + blade.points[pname] = pcoord + + + + + # Read functions + xe_functions = xr_beam.find('functions') + for xe_function in xe_functions.findall('function'): + fname = xe_function.get('name') + ftype = xe_function.get('type', default='polynomial') + fpointsx = [] + fpointsy = [] + + xe_coeffs = xe_function.find('coefficients') + if xe_coeffs is not None: + # print(xe_coeffs.text) + fcoeffs = list(map(float, xe_coeffs.text.strip().split())) + xe_points = xe_function.find('points') + if xe_points is not None: + for xe_point in xe_points.findall('point'): + x, y = list(map(float, xe_point.text.strip().split())) + fpointsx.append(x) + fpointsy.append(y) + + blade.functions[fname] = utils.PolynomialFunction( + coefficients=fcoeffs, x=fpointsx, y=fpointsy + ) + + + + + # Read distributions + xe_distributions = xe_design.find('distributions') + for xe_distribution in xe_distributions.findall('distribution'): + # distr_type = xe_distribution.get('type', default='function') + param_name = xe_distribution.find('parameter').text + + func_name = xe_distribution.find('function').text + value_type = 'float' + xe_type = xe_distribution.find('type') + if xe_type is not None: + value_type = xe_distribution.find('type').text + m = 1.0 + if xe_distribution.find('multiplier'): + m = float(xe_distribution.find('multiplier').text) + blade.distributions[param_name] = [func_name, m, value_type] + + + + + # Read segments + xe_segments = xe_design.find('segments') + bslabel = 0 + for xe_sgm in xe_segments.findall('segment'): + bslabel += 1 + bs = BladeSegment() + + # Beginning station + xe_start = xe_sgm.find('begin') + pn = xe_start.find('location').text.strip() + # bs.points.append(pn2l[pn]) + bs.points.append(pn) + # pc = beam.findPtCoordByName(pn2l[pn]) + pc = blade.findPtCoordByName(pn) + bs.coords.append(pc) + xe_cs = xe_start.find('cross_section') + fn_cs_template = xe_cs.get('template') + cs_name = xe_cs.text.strip() + # fn_cs = cs_name + '.xml' + bs.cs_template.append(fn_cs_template) + bs.css.append(cs_name) + + if not cs_name in blade.section_templates.keys(): + blade.section_templates[cs_name] = fn_cs_template + + # Ending station + xe_stop = xe_sgm.find('end') + pn = xe_stop.find('location').text.strip() + # bs.points.append(pn2l[pn]) + bs.points.append(pn) + # pc = beam.findPtCoordByName(pn2l[pn]) + pc = blade.findPtCoordByName(pn) + bs.coords.append(pc) + xe_cs = xe_stop.find('cross_section') + fn_cs_template = xe_cs.get('template') + cs_name = xe_cs.text.strip() + # fn_cs = cs_name + '.xml' + bs.cs_template.append(fn_cs_template) + bs.css.append(cs_name) + + if not cs_name in blade.section_templates.keys(): + blade.section_templates[cs_name] = fn_cs_template + + + # Cross-section parameters + for xe_param in xe_sgm.findall('parameter'): + name = xe_param.find('name').text.strip() + values = [0, 0] + for xe_value in xe_param.findall('value'): + apply = xe_value.get('apply', default='all') + value = float(xe_value.text.strip()) + if apply == 'all': + values = [value, value] + elif apply == 'begin': + values[0] = value + elif apply == 'end': + values[1] = value + bs.cs_parameters[name] = values + + + blade.segments[bslabel] = bs + + + return blade + + +