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