From e8fdc33b1327cbf1a2b4ecad6fee231af452c485 Mon Sep 17 00:00:00 2001 From: Malo Rosemeier <malo.rosemeier@iwes.fraunhofer.de> Date: Fri, 21 Jul 2017 11:49:31 +0200 Subject: [PATCH] added docu, clean up --- .gitignore | 3 +- README.md | 35 ++++++++++++---- finstrip_wrapper/core/blade.py | 74 +++++++++++++++++++++++----------- finstrip_wrapper/core/main.py | 59 +++++++++------------------ 4 files changed, 99 insertions(+), 72 deletions(-) diff --git a/.gitignore b/.gitignore index efc7233..5ecf294 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,4 @@ *.settings *~ becas_* -*.buc -*.ldc \ No newline at end of file +finstrip_* \ No newline at end of file diff --git a/README.md b/README.md index 914af6d..74db942 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,13 @@ FINSTRIPWrapper FINSTRIPWrapper wraps WMC's [FINSTRIP](https://wmc.eu/bladknik.php) (FINite STRIP) buckling tool into Python and OpenMDAO enabling batch runs for optimization purposes. # Dependencies and supported versions +* Python 2.7.x +* Numpy * FINSTRIP as of FOCUS 6.3 * OpenMDAO 1.7.3 * FUSED-Wind dev +* PGL - Parametric Geometry Library +* BECAS (optional) # OS @@ -53,10 +57,10 @@ sudo apt-get install wine1.8-amd64 winetricks ``` -* install Sentinel HASP at least version 7.55, download from https://sentinelcustomer.gemalto.com/sentineldownloads/ +* install Sentinel HASP (at least version 7.55), download from https://sentinelcustomer.gemalto.com/sentineldownloads/ * Sentinel HASP,LDK Script for Linux 32-bit Compatibility Packages * Sentinel HASP LDK Ubuntu, DEB Run-time Installer -* add license server to `/etc/hasplm/hasplm.ini` +* add license server to `/etc/hasplm/hasplm.ini`, e. g.: ```bash serveraddr = 10.16.51.84 ``` @@ -68,7 +72,7 @@ sudo service aksusbd start sudo service aksusbd status ``` -* check if license server is reachable via +* check if license dongle is reachable via http://localhost:1947/_int_/devices.html * add FINSTRIP executable to wine's PATH @@ -85,7 +89,7 @@ PATH = z:\\\home\\\mrosemeier\\\finstrip\\\ wine finstrip ``` -* to ommit popup windows in batch install xvfb: +* to ommit popup windows in batch run install xvfb: ```bash sudo apt-get install xvfb ``` @@ -95,12 +99,29 @@ sudo apt-get install xvfb xvfb-run -a wine finstrip test.buc ``` -* clone FISNTRIPWrapper: +* clone PGL - Parametric Geometry Library: ```bash $ cd git -$ git clone ssh://git@github.com:OpenMDAO/OpenMDAO.git -$ git checkout 1.7.3 +$ git clone git@gitlab.windenergy.dtu.dk:frza/PGL.git +$ git checkout master +``` + + +* clone FINSTRIPWrapper: + +```bash +$ cd git +$ git clone git@gitlab.iwes.fraunhofer.de:bdt/FINSTRIPWrapper.git +$ git checkout master +``` + +* in case you want to calculate cross section properties for FINSTRIP with [BECAS](http://www.becas.dtu.dk/) install BECAS and clone BECASWrapper: + +```bash +$ cd git +$ git clone git@gitlab.windenergy.dtu.dk:HAWTOpt2/BECASWrapper.git +$ git checkout master ``` ## Framework diff --git a/finstrip_wrapper/core/blade.py b/finstrip_wrapper/core/blade.py index 6a15e97..4f4b6a1 100644 --- a/finstrip_wrapper/core/blade.py +++ b/finstrip_wrapper/core/blade.py @@ -1,10 +1,29 @@ import numpy as np -from finstrip_wrapper.core.main import FINSTRIPWrapper, status +from finstrip_wrapper.core.main import FINSTRIPWrapper from PGL.components.airfoil import AirfoilShape class FINSTRIPWrapperBlade(FINSTRIPWrapper): - ''' Base class for all blade models, i.e. BladeShell and BladeBeam + ''' + A basic wrapper for FINSTRIP that provides three primary functionalities: + file input generation, execution and file output reading. + This class extends FINSTRIPWrapper doing blade specific setup + + The following keys should be passed as dictionary, otherwise the standard + values are used. + + keys + ---- + name: str + job name + elsize_factor: float + element length as fraction of arc length of airfoil surface + core_mats: list + list of material name strings to be identified as core + spanpos: float + span wise position of cross section + use_becas_stiffness: bool + use BECAS cross section properties if True ''' def __init__(self, **kwargs): @@ -13,9 +32,14 @@ class FINSTRIPWrapperBlade(FINSTRIPWrapper): # data base output name self.name = 'blade' - self.core_mats = [] # list of materials to be identified as core + # element length as fraction of arc length of airfoil surface + self.elsize_factor = 0.015 + + # list of material name strings to be identified as core + self.core_mats = [] self.spanpos = 0 # position along span of analysed cross-section + # use BECAS cross section properties or not self.use_becas_stiffness = False for k, w in kwargs.iteritems(): @@ -28,7 +52,7 @@ class FINSTRIPWrapperBlade(FINSTRIPWrapper): self._init_finstrip_input_files_names() def init_dicts(self, cs2d): - # dictionaries written by FINSTRIPBladeStructure according to FUSED-Wind format + # dictionaries written by FINSTRIPBladeStability according to FUSED-Wind format # NOTE: absolut dimensions are required! self.cs2d = cs2d @@ -79,7 +103,9 @@ class FINSTRIPWrapperBlade(FINSTRIPWrapper): self._write_finstrip_analysis_files() def _det_maxlength_element(self): - # calculate arc length of airfoil surface + ''' calculate element length based on fraction of arc length of airfoil + surface + ''' af = AirfoilShape() af.initialize(points=self.cs2d['coords']) @@ -138,7 +164,7 @@ class FINSTRIPWrapperBlade(FINSTRIPWrapper): G13 = matprops[i, 7] * 1E-6 # to N/mm*2 G23 = matprops[i, 8] * 1E-6 # to N/mm*2 rho = matprops[i, 9] * 1E-9 # to kg/mm*3 - # deterimne material type + # determine material type if label in self.core_mats: # mat_type = 'core' _write_core( @@ -199,30 +225,32 @@ class FINSTRIPWrapperBlade(FINSTRIPWrapper): I_xx = self.csprops_ref[7] I_yy = self.csprops_ref[8] I_xy = self.csprops_ref[9] - nu = self.csprops_ref[17] + np.pi / 2 - # TODO: check if sign is correct in I_xy! + nu = self.csprops_ref[17] + # TODO: check if sign is correctly taken for I_xy! # A = self.csprops_ref[15] # Gere 12-30 - theta = 0.5 * np.arctan(-2 * I_xy / (I_xx - I_yy)) + theta = 0.5 * np.arctan(-2 * I_xy / (I_xx - I_yy)) + np.pi / 2 # Gere 12-32 - R = np.sqrt((0.5 * (I_xx - I_yy))**2 + I_xy**2) + #R = np.sqrt((0.5 * (I_xx - I_yy))**2 + I_xy**2) # Gere 12-31a - theta1 = 0.5 * np.arccos((I_xx - I_yy) / (2 * R)) + #theta1 = 0.5 * np.arccos((I_xx - I_yy) / (2 * R)) # Gere 12-31b - theta2 = 0.5 * np.arcsin(-I_xy / R) + #theta2 = 0.5 * np.arcsin(-I_xy / R) # if not np.sign(theta) == np.sign(nu): # raise RuntimeError('BECAS input not consistent') + # check the output format of BECASWrapper config = {} config['BECASWrapper'] = {} config['BECASWrapper']['hawc2_FPM'] = True from becas_wrapper.becas_bladestructure import set_cs_size cs_size, _ = set_cs_size(config) + if cs_size == len(self.csprops): #hawc2_FPM = True AE = self.csprops[20] * 1E-3 # to N/mm @@ -241,7 +269,7 @@ class FINSTRIPWrapperBlade(FINSTRIPWrapper): (x_e, y_e, AE, EI_xx, EI_yy, EI_xy) + n) fid = open(self.file_input, 'w') - for i, line in enumerate(out_str): + for line in out_str: fid.write(line) fid.close() @@ -258,12 +286,11 @@ class FINSTRIPWrapperBlade(FINSTRIPWrapper): my = self.csloads[case, 4] mz = self.csloads[case, 5] n = '\n' - # write header out_str.append( 'loads, %s, %i, %g, %g, %g, %g, %g' % (self.spanpos, fx, fy, fz, mx, my, mz) + n) fid = open(self.file_load, 'w') - for i, line in enumerate(out_str): + for line in out_str: fid.write(line) fid.close() @@ -301,14 +328,15 @@ class FINSTRIPWrapperBlade(FINSTRIPWrapper): # x-u p1, y-u p1, x-u p2, y-u p2 for case in range(self.ncase): for mode in range(self.nmode): - self.mode_shape[case, mode, :, :] = np.loadtxt('R' + - '%05i' % (self.spanpos) + - '_LC' + - '%03d' % (case) + - '_mode' - '%03d' % (mode) + - self.txt_sfx, - skiprows=2) + # convert to m + self.mode_shape[case, mode, :, :] = 1E-3 * np.loadtxt('R' + + '%05i' % (self.spanpos) + + '_LC' + + '%03d' % (case) + + '_mode' + '%03d' % (mode) + + self.txt_sfx, + skiprows=2) idxs = [] # identify surface and web nodes diff --git a/finstrip_wrapper/core/main.py b/finstrip_wrapper/core/main.py index 7275aec..e2d2483 100644 --- a/finstrip_wrapper/core/main.py +++ b/finstrip_wrapper/core/main.py @@ -7,44 +7,33 @@ import sys class FINSTRIPWrapper(object): - """ - A basic wrapper of FINSTRIP that provides two primary functionalities: - model generation, meshing and solving - - parameters - ---------- - finstrip_work_dir: Str - ANSYS working directory - job_name: str - standard: 'blade' - ANSYS job name - file_input: str - standard: 'runFINSTRIP.inp' - FINSTRIP input file name - number_cores: int - number of cores for ANSYS execution - workspace_memory: int - ANSYS workspace memory, units in MByte - database_memory: int - standards: 100 - ANSYS database memory, units in MByte - - """ + ''' + A basic wrapper for FINSTRIP that provides three primary functionalities: + file input generation, execution and file output reading. + + The following keys should be passed as dictionary, otherwise the standard + values are used. + + keys + ---- + nmode: int + number of buckling modes to be processed + lambda_min: float + minimum half wavelength in m + lambda_max: float + maximum half wavelength in m + ''' def __init__(self, **kwargs): super(FINSTRIPWrapper, self).__init__() - # element length as fraction of arc length of airfoil surface - self.elsize_factor = 0.015 + # number of buckling modes to be processed + self.nmode = 21 # finstrip program parameters self.lambda_min = 0.01 # minimum half wavelength in m self.lambda_max = 15.126 # maximum half wavelength in m - self.nmode = 21 - #self.ncoord = 79 - #self.ncase = 1 - # flags self.debug_mode = True self.dry_run = False @@ -61,21 +50,11 @@ class FINSTRIPWrapper(object): # input file names self.buc_sfx = '.buc' self.lcd_sfx = '.ldc' - # self.fdb_prfx = 'db' # why no "." ?? self.txt_sfx = '.txt' self.file_input = self.name + self.buc_sfx self.file_load = self.name + self.lcd_sfx - #self.file_output = self.name + self.fcdb_prfx - #self.file_mat = 'MAT' + self.fd_sfx - #self.file_failmat = 'FAILMAT' + self.fd_sfx - #self.file_et = 'ET' + self.fd_sfx - #self.file_mesh = 'MESH' + self.fi_prfx - #self.file_variables = 'VARS' + self.fi_prfx - #self.file_vars_analysis = 'VARS_ANALYSIS' + self.fi_prfx - - # output file names + self.file_rst_eigen = self.name + '_result_status' + self.txt_sfx - self.file_rst_loadcase = self.name + '_result_status' + self.txt_sfx def compute(self): ''' Runs FINSTRIP - setup/execution and post processing -- GitLab