Source code for bladex.params

"""
Module to read and write a parameter file
which can be used for parameters deformations.
"""
try:
    import configparser as configparser
except ImportError:
    import ConfigParser as configparser
import os
import numpy as np


[docs]class ParamFile(object): """ Read and Write a parameter file :cvar array_like radii: contains radii values of the blade sectional profiles, starting from the hub. Default value is None :cvar dict parameters: dictionary that contains the radial distribution of parameters `chord`, `pitch`, `rake`, `skew`, `camber` at specific blade sections. Each element of the dictionary is an array_like of length equals to that of the array radii. Both parameters `chord` and `camber` descibes the chord length and the camber of the 2D foil representing the blade section. Possible dictionary keys are `chord`, `pitch`, `rake`, `skew`, `camber`. Default values are None :cvar dict nbasis: dictionary that contains number of control points for each parameter. Possible dictionary keys are: `chord`, `pitch`, `rake`, `skew`, `camber` :cvar dict degree: dictionary that contains degree of the BSpline to be constructed according to the parameter radial distribution. Possible dictionary keys are: `chord`, `pitch`, `rake`, `skew`, `camber` :cvar dict npoints: dictionary that contains number of points to be evaluated using the BSpline interpolation, for each of the parameter curves. Possible dictionary keys for the parameters are: `chord`, `pitch`, `rake`, `skew`, `camber` :cvar dict deformations: dictionary that contains the control points Y-deformations of the parameter BSpline curve. Possible dictionary keys are: `chord`, `pitch`, `rake`, `skew`, `camber` """ def __init__(self): self.radii = None self.parameters = { 'chord': None, 'pitch': None, 'rake': None, 'skew': None, 'camber': None } self.nbasis = { 'chord': 10, 'pitch': 10, 'rake': 10, 'skew': 10, 'camber': 10 } self.degree = { 'chord': 3, 'pitch': 3, 'rake': 3, 'skew': 3, 'camber': 3 } self.npoints = { 'chord': 500, 'pitch': 500, 'rake': 500, 'skew': 500, 'camber': 500 } self.deformations = { 'chord': np.zeros(self.nbasis['chord']), 'pitch': np.zeros(self.nbasis['chord']), 'rake': np.zeros(self.nbasis['chord']), 'skew': np.zeros(self.nbasis['chord']), 'camber': np.zeros(self.nbasis['chord']) }
[docs] def _check_params(self): """ Private method that is called while writing a parameter file. 1. The method checks if the user specifies a radii array, otherwise it raises exception. 2. In case no values assigned to any of the remaining parameter arrays then an array of zeros is assigned, in which its length is equal to the radii array. 3. Any array that is not numpy is converted to be one. Finally, in case the user specifies the parameter array values but not with same length, then an exception is raised. """ if self.radii is None: raise ValueError('Array radii can not have a None value.') if not isinstance(self.radii, np.ndarray): self.radii = np.asarray(self.radii) for param in ['chord', 'pitch', 'rake', 'skew', 'camber']: # If any parameter is not inserted then assign that parameter # with array of zeros. This is useful in case the user is # interested in only one or few parameters, while not interested # in (or does have information about) the remaining ones. if self.parameters[param] is None: self.parameters[param] = np.zeros(self.radii.shape[0]) # In case inserted parameters are not numpy arrays if not isinstance(self.parameters[param], np.ndarray): self.parameters[param] = np.asarray(self.parameters[param]) # check the case if user inserts inhomogeneous radial distributions if not self.parameters[param].shape == self.radii.shape: raise ValueError( 'Array ' + param + ' must have same shape of array radii.') # If inserted deformations array not correspond to nbasis if not self.nbasis[param] == len(self.deformations[param]): raise ValueError( param + ' deformations must correspond to nbasis.')
[docs] def read_parameters(self, filename='parameters.prm'): """ Reads in the parameters file and fill the self structure. :param str filename: parameters file to be read in. Default value is parameters.prm """ if not isinstance(filename, str): raise TypeError('filename must be a string') # Checks if the parameters file exists. If not it writes a default # parameters file with zero deformations for all parameters at uniform # radial sections. if not os.path.isfile(filename): self.radii = np.arange(0.3, 1.1, 0.1) self.write_parameters(filename=filename) config = configparser.RawConfigParser() config.read(filename) radii = config.get('Original parameters', 'Radial sections') lines = radii.split('\n') self.radii = np.zeros(len(lines)) for j, line in enumerate(lines): if len(line.split()) > 1: raise ValueError( 'Radial sections must have single value at each section.') self.radii[j] = float(line) params = ['chord', 'pitch', 'rake', 'skew', 'camber'] for param in params: parameters = config.get('Original parameters', 'Radial distribution of ' + param) lines = parameters.split('\n') self.parameters[param] = np.zeros(len(lines)) for j, line in enumerate(lines): if len(line.split()) > 1: raise ValueError( param + ' radial distribution must have single value at each'\ ' radial section.' ) self.parameters[param][j] = float(line) if not (len(self.radii) == len(self.parameters['chord']) == len(self.parameters['pitch']) == len(self.parameters['rake']) == len(self.parameters['skew']) == len(self.parameters['camber'])): raise ValueError( 'Arrays "radii", "chord", "pitch", "rake", "skew", "camber"'\ ' must have same length.' ) section_all = [ 'Chord B-Spline', 'Pitch B-Spline', 'Rake B-Spline', 'Skew B-Spline', 'Camber B-Spline' ] for section, param in zip(section_all, params): self.degree[param] = config.getint(section, 'spline degree') self.npoints[param] = config.getint(section, 'spline npoints') self.nbasis[param] = config.getint(section, 'number of control points') deformations = config.get(section, 'control points Y-deformations') if bool(deformations) is False: raise ValueError('control points Y-deformations in section [' + section + '] must be non-empty.') lines = deformations.split('\n') self.deformations[param] = np.zeros(len(lines)) for j, line in enumerate(lines): if len(line.split()) > 1: raise ValueError( 'You can pass only one value for each control point', ' Y-deformation of the ' + param) self.deformations[param][j] = float(line) if not len(self.deformations[param]) == self.nbasis[param]: raise ValueError(param + ' has nbasis not equal deformations.')
[docs] def write_parameters(self, filename='parameters.prm'): """ This method writes a parameters file (.prm) called `filename` and fills it with all the parameters class members. Default value is parameters.prm. :param str filename: parameters file to be written out. :param bool param_pptc: if True, then the parameter arrays are replaced with that of the benchmark PPTC propeller. """ if not isinstance(filename, str): raise TypeError("filename must be a string") self._check_params() output_string = "" output_string += '\n[Original parameters]\n' output_string += '# This section describes the radial distributions'\ ' of the parameters:\n' output_string += '# "chord lengths", "pitch", "rake", "skew angles",'\ ' and "camber"\n' output_string += '# at given radial sections.\n' output_string += '\nRadial sections = ' offset = 1 for radius in self.radii: output_string += offset * ' ' + str(radius) + '\n' offset = 19 params = ['chord', 'pitch', 'rake', 'skew', 'camber'] gaps = [0, 0, 1, 1, -1] for param, gap in zip(params, gaps): offset = 1 + gap output_string += '\nRadial distribution of ' + param + ' = ' for parameter in self.parameters[param]: output_string += offset * ' ' + str(parameter) + '\n' offset = 32 sections = [ '[Chord B-Spline]', '[Pitch B-Spline]', '[Rake B-Spline]', '[Skew B-Spline]', '[Camber B-Spline]' ] for section, param in zip(sections, params): output_string += '\n\n' + section + '\n' output_string += '# This section describes the B-Spline'\ ' construction of the RADII -- ' + param.upper() + ' curve.\n' output_string += '\n# degree of the B-Spline curve\n' output_string += 'spline degree: {}\n'.format( str(self.degree[param])) output_string += '\n# number of points to be evaluated with the'\ ' B-Spline interpolation\n' output_string += 'spline npoints: {}\n'.format( str(self.npoints[param])) output_string += '\n# number of the control points\n' output_string += 'number of control points: {}\n'.format( str(self.nbasis[param])) output_string += '\n# Y-deformations of the control points.\n' output_string += 'control points Y-deformations = ' offset = 1 for i in range(self.nbasis[param]): output_string += offset * ' ' + str( self.deformations[param][i]) + '\n' offset = 33 with open(filename, 'w') as f: f.write(output_string)
[docs] def __str__(self): """ This method prints all the parameters on the screen. Its purpose is for debugging. """ string = '' string += 'radii = {}'.format(self.radii) params = ['chord', 'pitch', 'rake', 'skew', 'camber'] for param in params: string += '\n\n' + param + ' = {}'.format(self.parameters[param]) string += '\n' + param + ' degree = {}'.format( self.degree[param]) string += '\n' + param + ' npoints = {}'.format( self.npoints[param]) string += '\n' + param + ' nbasis = {}'.format(self.nbasis[param]) string += '\n' + param + ' control points deformations = ' string += '{}'.format(self.deformations[param]) return string