class ProfileFitting(ExplicitComponent):

    def setup(self):
        self.bzFoil = BPAirfoil()
        self.air = Airfoil(None)
        #####################
        ### openMDAO init ###
        ### INPUTS
        self.add_input('offsetFront', val=0.1, desc='...')
        #self.add_input('length', val=1.0, desc='...')
        self.add_input('angle', val=1.0, desc='...')
        self.add_input('bz_y_t', val=.2, desc='...')
        ### OUTPUTS
        self.add_output('height', val=0.0)
        self.add_output('heightLoss', val=0.0)

        self.declare_partials('*', '*', method='fd')
        self.executionCounter = 0

    def fit_cabin(self, xFront, angle):
        top, buttom = self.bzFoil.get_cooridnates_top_buttom(500)
        if self.bzFoil.valid == False:
            return False, False
        xBack = xFront + cabinLength  # inputs['length']
        self.air.set_coordinates(top, buttom)
        self.air.rotate(angle)
        yMinButtom = max(self.air.get_buttom_y(xFront), self.air.get_buttom_y(xBack))
        yMaxTop = min(self.air.get_top_y(xFront), self.air.get_top_y(xBack))
        maxHeight = max(self.air.get_top_y(xFront) - self.air.get_buttom_y(xFront), self.air.get_top_y(xBack) - self.air.get_buttom_y(xBack))
        height = yMaxTop - yMinButtom
        return height, maxHeight

    def compute(self, inputs, outputs):
        self.bzFoil = globBzFoil
        self.bzFoil.y_t = inputs['bz_y_t']
        # check how high the cabin can be
        height, maxHeight = self.fit_cabin(inputs['offsetFront'], inputs['angle'])
        if not self.bzFoil.valid:
            print('ANALYSIS ERROR !')
            outputs['height'] = 1.
            outputs['heightLoss'] = 1.
        else:
            outputs['height'] = height #yMaxTop- yMinButtom
            outputs['heightLoss'] = maxHeight - height
        self.executionCounter += 1
        print(str(self.executionCounter) + '\t' + str(outputs['heightLoss']) + '\t' + str(inputs['bz_y_t']) + '\t' + str(outputs['height']))
from openmdao.core.indepvarcomp import IndepVarComp

#import libaries.readInput as readInputs
#from libaries.readInput import ParamValue
#value = readInputs.readInputFile()


bzFoil = BPAirfoil()
if os.path.isfile('../dataIn/airfoil.txt'):
    bzFoil.read_parameters_from_file('../dataIn/airfoil.txt')

air = Airfoil(None)
top, buttom = bzFoil.get_cooridnates_top_buttom(500)
if bzFoil.valid == False:
    print('ERROR: invalid bzArifoil')
air.set_coordinates(top, buttom)

cabinLength = 0.55
cabinHeigth = 0.14


class ProfileFitting(ExplicitComponent):

    def setup(self):
        #####################
        ### openMDAO init ###
        ### INPUTS
        self.add_input('offsetFront', val=0.1, desc='...')
        self.add_input('length', val=1.0, desc='...')
        self.add_input('angle', val=1.0, desc='...')
        self.add_input('bz_y_t', val=.2, desc='...')
Ejemplo n.º 3
0
class CabinFitting(ExplicitComponent):

    def setup(self):
        ######################
        ### needed Objects ###
        self.bzFoil = BPAirfoil()
        self.air = Airfoil(None)

        #####################
        ### openMDAO init ###
        ### INPUTS
        self.add_input('r_le', val=-0.05, desc='nose radius')
        self.add_input('beta_te', val=0.1, desc='thickness angle trailing edge')
        #self.add_input('dz_te', val=0., desc='thickness trailing edge')
        self.add_input('x_t', val=0.3, desc='dickenruecklage')
        self.add_input('y_t', val=0.1, desc='max thickness')

        self.add_input('gamma_le', val=0.5, desc='camber angle leading edge')
        self.add_input('x_c', val=0.5, desc='woelbungsruecklage')
        self.add_input('y_c', val=0.1, desc='max camber')
        self.add_input('alpha_te', val=-0.1, desc='camber angle trailing edge')
        self.add_input('z_te', val=0., desc='camber trailing edge')

        # bezier parameters
        self.add_input('b_8', val=0.05, desc='')
        self.add_input('b_15', val=0.75, desc='')
        self.add_input('b_0', val=0.1, desc='')
        self.add_input('b_2', val=0.25, desc='')
        self.add_input('b_17', val=0.9, desc='')

        self.add_input('offsetFront', val=0.1, desc='...')
        #self.add_input('length', val=.5, desc='...')
        self.add_input('angle', val=.0, desc='...')

        ### OUTPUTS
        #self.add_output('height', val=0.0)
        self.add_output('cabin_height', val=cabinHeigth)

        self.declare_partials('*', '*', method='fd')
        self.executionCounter = 0

    def compute(self, inputs, outputs):
        self.bzFoil.r_le = inputs['r_le']
        self.bzFoil.beta_te = inputs['beta_te']
        #self.bzFoil.dz_te = inputs['dz_te']
        self.bzFoil.x_t = inputs['x_t']
        self.bzFoil.y_t = inputs['y_t']

        self.bzFoil.gamma_le = inputs['gamma_le']
        self.bzFoil.x_c = inputs['x_c']
        self.bzFoil.y_c = inputs['y_c']
        self.bzFoil.alpha_te = inputs['alpha_te']
        self.bzFoil.z_te = inputs['z_te']

        self.bzFoil.b_8 = inputs['b_8']
        self.bzFoil.b_15 = inputs['b_15']
        self.bzFoil.b_0 = inputs['b_0']
        self.bzFoil.b_2 = inputs['b_2']
        self.bzFoil.b_17 = inputs['b_17']
        xFront = inputs['offsetFront']
        xBack = xFront + cabinLength #inputs['length']
        angle = inputs['angle']

        top, buttom = self.bzFoil.get_cooridnates_top_buttom(500, show_plot=False)
        self.air.set_coordinates(top, buttom)
        self.air.rotate(angle)
        yMinButtom = max(self.air.get_buttom_y(xFront), self.air.get_buttom_y(xBack))
        yMaxTop = min(self.air.get_top_y(xFront), self.air.get_top_y(xBack))
        height = yMaxTop - yMinButtom
        """
        iterCounter = 0
        while(abs(height - cabinHeigth) > 1e-6):
            self.bzFoil.y_t += cabinHeigth - height
            top, buttom = self.bzFoil.get_cooridnates_top_buttom(500)
            self.air.set_coordinates(top, buttom)
            self.air.rotate(angle)
            yMinButtom = max(self.air.get_buttom_y(xFront), self.air.get_buttom_y(xBack))
            yMaxTop = min(self.air.get_top_y(xFront), self.air.get_top_y(xBack))
            height = yMaxTop - yMinButtom
            iterCounter += 1
        """
        if not self.bzFoil.valid:
            print('ERROR: CabinFitting, invalid BPAirfoil')
            print('But we let AirfoilCFD handle this')
            self.bzFoil.save_parameters_to_file(WORKING_DIR + '/bz_error_' + datetime.now().strftime('%Y-%m-%d_%H_%M_%S') + '.txt')
            #raise AnalysisError('CabinFitting: invalid BPAirfoil')
            #workaround to tell openMDAO that this is bad
            outputs['cabin_height'] = 0.
        else:
            #yMinButtom = max(self.air.get_buttom_y(xFront), self.air.get_buttom_y(xBack))
            #yMaxTop = min(self.air.get_top_y(xFront), self.air.get_top_y(xBack))
            #outputs['height'] = yMaxTop - yMinButtom
            #print('cabin fitting needed ' + str(iterCounter) + ' iterations')
            print('cabinHeight= ' + str(height))
            outputs['cabin_height'] = height
            print('new cabin_height= ' + str(outputs['cabin_height']))
        self.executionCounter += 1
class AirfoilCFD(ExplicitComponent):
    def setup(self):
        ######################
        ### needed Objects ###
        self.bzFoil = BPAirfoil()
        self.air = Airfoil(None)

        #####################
        ### openMDAO init ###
        ### INPUTS

        self.add_input('r_le', val=-0.05, desc='nose radius')
        self.add_input('beta_te',
                       val=0.1,
                       desc='thickness angle trailing edge')
        #self.add_input('dz_te', val=0., desc='thickness trailing edge')
        self.add_input('x_t', val=0.3, desc='dickenruecklage')
        #self.add_input('y_t', val=0.1, desc='max thickness')

        self.add_input('gamma_le', val=0.5, desc='camber angle leading edge')
        self.add_input('x_c', val=0.5, desc='woelbungsruecklage')
        self.add_input('y_c', val=0.1, desc='max camber')
        self.add_input('alpha_te', val=-0.1, desc='camber angle trailing edge')
        #self.add_input('z_te', val=0., desc='camber trailing edge')

        # bezier parameters
        self.add_input('b_8', val=0.05, desc='')
        self.add_input('b_15', val=0.75, desc='')
        self.add_input('b_0', val=0.1, desc='')
        self.add_input('b_2', val=0.25, desc='')
        self.add_input('b_17', val=0.9, desc='')

        # just for plotin
        self.add_input('offsetFront', val=0.1, desc='...')
        self.add_input('angle', val=.0, desc='...')
        #self.add_input('cabin_height', val=.0, desc='...')

        ### OUTPUTS
        self.add_output('c_d', val=.2)
        self.add_output('c_l', val=.2)
        self.add_output('c_m', val=.2)
        self.add_output('y_t', val=0.1, desc='max thickness')

        self.add_output('cabin_height', val=cabinHeigth)

        self.declare_partials('*', '*', method='fd')
        self.executionCounter = 0

    def fit_cabin(self, xFront, angle):
        top, buttom = self.bzFoil.get_cooridnates_top_buttom(500)
        if self.bzFoil.valid == False:
            return False
        xBack = xFront + cabinLength  # inputs['length']
        self.air.set_coordinates(top, buttom)
        self.air.rotate(angle)
        yMinButtom = max(self.air.get_buttom_y(xFront),
                         self.air.get_buttom_y(xBack))
        yMaxTop = min(self.air.get_top_y(xFront), self.air.get_top_y(xBack))
        height = yMaxTop - yMinButtom
        return height
        #outputs['cabin_height'] = height

    def compute(self, inputs, outputs):
        error = False
        self.bzFoil.r_le = inputs['r_le']
        self.bzFoil.beta_te = inputs['beta_te']
        #self.bzFoil.dz_te = inputs['dz_te']
        self.bzFoil.x_t = inputs['x_t']
        #self.bzFoil.y_t = inputs['y_t']

        self.bzFoil.gamma_le = inputs['gamma_le']
        self.bzFoil.x_c = inputs['x_c']
        self.bzFoil.y_c = inputs['y_c']
        self.bzFoil.alpha_te = inputs['alpha_te']
        self.bzFoil.z_te = 0  #inputs['z_te']

        self.bzFoil.b_8 = inputs['b_8']
        self.bzFoil.b_15 = inputs['b_15']
        self.bzFoil.b_0 = inputs['b_0']
        self.bzFoil.b_2 = inputs['b_2']
        self.bzFoil.b_17 = inputs['b_17']

        projectName = PROJECT_NAME_PREFIX + '_%09d' % self.executionCounter
        cfd = CFDrun(projectName)

        airFoilCoords = self.bzFoil.generate_airfoil(
            500,
            show_plot=False,
            save_plot_path=WORKING_DIR + '/' + projectName + '/airfoil.png',
            param_dump_file=WORKING_DIR + '/' + projectName + '/airfoil.txt')

        # check how high the cabin can be
        height = self.fit_cabin(inputs['offsetFront'], inputs['angle'])
        if self.bzFoil.valid:
            iterCounter = 0
            while (abs(height - cabinHeigth) > 1e-6):
                self.bzFoil.y_t += cabinHeigth - height
                height = self.fit_cabin(inputs['offsetFront'], inputs['angle'])
                if height == False:
                    break
                iterCounter += 1

            outputs['cabin_height'] = height
            outputs['y_t'] = self.bzFoil.y_t
            print('new cabin_height= ' + str(outputs['cabin_height']))
            print('needed iterations= ' + str(iterCounter))

        if not self.bzFoil.valid:
            #raise AnalysisError('AirfoilCFD: invalid BPAirfoil')
            print('ERROR: AirfoilCFD, invalid BPAirfoil')
            self.bzFoil.save_parameters_to_file(
                WORKING_DIR + '/bz_error_' +
                datetime.now().strftime('%Y-%m-%d_%H_%M_%S') + '.txt')
            error = True
        else:

            self.bzFoil.plot_airfoil_with_cabin(inputs['offsetFront'],
                                                cabinLength,
                                                outputs['cabin_height'],
                                                inputs['angle'],
                                                show_plot=False,
                                                save_plot_path=WORKING_DIR +
                                                '/' + projectName +
                                                '/airfoil_cabin.png')

            ### now we do cfd
            top, buttom = self.bzFoil.get_cooridnates_top_buttom(500)
            cfd.set_airfoul_coords(top, buttom)

            cfd.c2d.pointsInNormalDir = 80
            cfd.c2d.pointNrAirfoilSurface = 200
            cfd.c2d.reynoldsNum = REYNOLD
            cfd.construct2d_generate_mesh(scale=SCALE, plot=False)
            cfd.su2_fix_mesh()
            cfd.su2_solve(config)
            #totalCL, totalCD, totalCM, totalE = cfd.su2_parse_results()
            results = cfd.su2_parse_iteration_result()
            cfd.clean_up()

            if float(results['CD']) <= 0. or float(results['CD']) > 100.:
                #raise AnalysisError('AirfoilCFD: c_d is out of range (cfd failed)')
                print('ERROR: AirfoilCFD, c_d is out of range (cfd failed)')
                error = True

            outputs['c_d'] = results['CD']
            outputs['c_l'] = results['CL']
            outputs['c_m'] = results['CMz']
            print('c_l= ' + str(outputs['c_l']))
            print('c_d= ' + str(outputs['c_d']))
            print('c_m= ' + str(outputs['c_m']))
            print('c_l/c_d= ' + str(results['CL/CD']))
            print('cfdIterations= ' + str(results['Iteration']))
            write_to_log(
                str(self.executionCounter) + ',' +
                datetime.now().strftime('%H:%M:%S') + ',' +
                str(outputs['c_l']) + ',' + str(outputs['c_d']) + ',' +
                str(outputs['c_m']) + ',' + str(results['CL/CD']) + ',' +
                str(results['Iteration']) + ',' +
                str(outputs['cabin_height']) + ',' +
                str(inputs['offsetFront']) + ',' + str(inputs['angle']) + ',' +
                str(inputs['r_le']) + ',' + str(inputs['beta_te']) + ',' +
                str(inputs['x_t']) + ',' + str(outputs['y_t']) + ',' +
                str(inputs['gamma_le']) + ',' + str(inputs['x_c']) + ',' +
                str(inputs['y_c']) + ',' + str(inputs['alpha_te']) + ',' +
                str(self.bzFoil.z_te) + ',' + str(inputs['b_8']) + ',' +
                str(inputs['b_15']) + ',' + str(inputs['b_0']) + ',' +
                str(inputs['b_17']) + ',' + str(inputs['b_2']))

        #workaround since raising an error seems to crash the optimization
        if error:
            outputs['c_d'] = 999.
            outputs['c_l'] = 0.
            outputs['c_m'] = 0.
        self.executionCounter += 1
Ejemplo n.º 5
0
    def plot_airfoil_with_cabin(self,
                                offsetFront,
                                length,
                                height,
                                angle,
                                show_plot=True,
                                save_plot_path='',
                                clear_plot=True,
                                ax=None):
        top, buttom = self.get_cooridnates_top_buttom(500)
        #if bzFoil.valid == False:
        #    return False, False
        air = Airfoil(None)
        air.set_coordinates(top, buttom)

        air.rotate(angle)
        # air.rotate(angle)
        px_ul = offsetFront
        px_ur = offsetFront + length
        py_ul = max(air.get_buttom_y(px_ul), air.get_buttom_y(px_ur))
        py_ur = py_ul
        px_ol = px_ul
        px_or = px_ur
        py_ol = min(air.get_top_y(px_ol), air.get_top_y(px_or))
        py_or = py_ol
        print('geometrical calculated height = ' + str(py_ol - py_ul))
        (px_ol, py_ol) = air.rotatePoint((0, 0), (px_ol, py_ol), -angle)
        (px_ul, py_ul) = air.rotatePoint((0, 0), (px_ul, py_ul), -angle)

        # py_ur = air.get_buttom_y(px_ur)
        # px_or = px_ur
        # py_or = py_ur + height
        (px_or, py_or) = air.rotatePoint((0, 0), (px_or, py_or), -angle)
        (px_ur, py_ur) = air.rotatePoint((0, 0), (px_ur, py_ur), -angle)
        air.rotate(0.)

        #fig, ax = air.plotAirfoil(showPlot=False, showPoints=False, ax=ax)

        ax.plot([px_ol, px_ul, px_ur, px_or, px_ol],
                [py_ol, py_ul, py_ur, py_or, py_ol],
                'rx-',
                label='cabin',
                color='#AD031B')
        #plt.show()

        plt.axis('equal')
        if save_plot_path != '':
            fig.set_size_inches(18.5, 10.5)
            #plt.savefig(save_plot_path, dpi=900)
            plt.savefig(save_plot_path + '.svg', dpi=900)
        if show_plot:
            plt.show()
        if clear_plot:
            plt.clf()
        '''
        #angle = 0.
        #offsetFront = 0.11
        #length = 0.55
        air = Airfoil(None)
        air.set_coordinates(self.topCoords, self.buttomCoords)
        air.rotate(angle)

        px_ul = offsetFront
        px_ur = offsetFront + length
        py_ul = max(air.get_buttom_y(px_ul), air.get_buttom_y(px_ur))
        py_ur = py_ul
        px_ol = px_ul
        px_or = px_ur
        py_ol = min(air.get_top_y(px_ol), air.get_top_y(px_or))
        py_or = py_ol
        print('geometrical calculated height = ' + str(py_ol - py_ul))
        (px_ol, py_ol) = air.rotatePoint((0, 0), (px_ol, py_ol), -angle)
        (px_ul, py_ul) = air.rotatePoint((0, 0), (px_ul, py_ul), -angle)

        # py_ur = air.get_buttom_y(px_ur)
        # px_or = px_ur
        # py_or = py_ur + height
        (px_or, py_or) = air.rotatePoint((0, 0), (px_or, py_or), -angle)
        (px_ur, py_ur) = air.rotatePoint((0, 0), (px_ur, py_ur), -angle)
        air.rotate(0.)
        fig, ax = air.plotAirfoil(showPlot=False, showPoints=False)
        ax.plot([px_ol, px_ul, px_ur, px_or, px_ol], [py_ol, py_ul, py_ur, py_or, py_ol], 'rx-')
        '''
        """
Ejemplo n.º 6
0
class CFDrun:
    def __init__(self, project_name, used_cores=SU2_USED_CORES):
        # create project dir if necessary
        self.projectDir = WORKING_DIR + '/' + project_name
        # create project dir if necessary
        if not os.path.isdir(self.projectDir):
            os.mkdir(self.projectDir)
        self.su2 = SU2(SU2_BIN_PATH,
                       used_cores=used_cores,
                       mpi_exec=OS_MPI_COMMAND)
        self.foilCoord = None
        self.gmsh = Gmsh(GMSH_EXE_PATH)
        self.c2d = Construct2d(CONSTRUCT2D_EXE_PATH)

    def load_airfoil_from_file(self, file_name):
        self.airfoil = Airfoil(file_name)
        self.foilCoord = self.airfoil.get_sorted_point_list()

    #def load_airfoil_bp(self):
    #    bp = BPAirfoil()
    #    self.foilCoord = bp.generate_airfoil(500, show_plot=False)

    def set_airfoul_coords(self, buttom, top):
        #self.foilCoord = coords
        self.airfoil = Airfoil(None)
        self.airfoil.set_coordinates(top, buttom)
        self.foilCoord = self.airfoil.get_sorted_point_list()

    def gmsh_generate_mesh(self, scale=1.):
        print('start meshing with gmsh...')
        self.gmsh.generate_geo_file(self.foilCoord,
                                    'airfoilMesh.geo',
                                    1000,
                                    working_dir=self.projectDir,
                                    scale=scale)
        self.gmsh.run_2d_geo_file('airfoilMesh.geo',
                                  'airfoilMesh.su2',
                                  working_dir=self.projectDir)

    def construct2d_generate_mesh(self,
                                  scale=1.,
                                  plot=False,
                                  wake_extension=0):
        print('start meshing with construct2d...')
        self.airfoil.write_to_dat('airfoil.dat', working_dir=self.projectDir)

        self.c2d.run_mesh_generatoin('airfoil.dat',
                                     working_dir=self.projectDir)
        #p2_to_su2_ogrid(self.projectDir + '/' + 'airfoil.p3d')
        c2dParser = Construct2dParser(self.projectDir + '/' + 'airfoil.p3d')
        if wake_extension > 0:
            c2dParser.extend_wake(wake_extension)
        c2dParser.p3d_to_su2_cgrid(self.projectDir + '/' + 'airfoilMesh.su2',
                                   scale=scale)
        if plot:
            print('saving mesh plot...')
            c2dParser.plot_mesh(scale=scale)

        #if os.path.isfile(self.projectDir + '/' + 'airfoilMesh.su2'):
        #    os.remove(self.projectDir + '/' + 'airfoilMesh.su2')
        #os.rename(self.projectDir + '/' + 'airfoil.su2', self.projectDir + '/' + 'airfoilMesh.su2')

    def su2_fix_mesh(self):
        print('start mesh-fixing...')
        self.su2.fix_mesh('airfoilMesh.su2',
                          'airfoilMeshFixed.su2',
                          working_dir=self.projectDir)

    def su2_solve(self, config):
        print('start solving...')
        self.su2.write_single_core_batch_file(working_dir=self.projectDir)
        return self.su2.run_cfd('airfoilMeshFixed.su2',
                                config,
                                working_dir=self.projectDir)

    def su2_parse_results(self):
        print('parse results...')
        totalCL, totalCD, totalCM, totalE = self.su2.parse_force_breakdown(
            'forces_breakdown.dat', working_dir=self.projectDir)
        return totalCL, totalCD, totalCM, totalE

    def su2_parse_iteration_result(self):
        print('parsing cfd iteration results')
        return self.su2.parse_result_from_history('history.vtk',
                                                  working_dir=self.projectDir)

    def clean_up(self):
        print('clean up...')
        if os.path.isfile(self.projectDir + '/airfoilMesh.su2'):
            os.remove(self.projectDir + '/airfoilMesh.su2')
        if os.path.isfile(self.projectDir + '/airfoil_stats.p3d'):
            os.remove(self.projectDir + '/airfoil_stats.p3d')
        if os.path.isfile(self.projectDir + '/airfoil.p3d'):
            os.remove(self.projectDir + '/airfoil.p3d')
        if os.path.isfile(self.projectDir + '/airfoil.nmf'):
            os.remove(self.projectDir + '/airfoil.nmf')
        #if os.path.isfile(self.projectDir + '/restart_flow.dat'):
        #    os.remove(self.projectDir + '/restart_flow.dat')
        if os.path.isfile(self.projectDir + '/original_grid.dat'):
            os.remove(self.projectDir + '/original_grid.dat')
        if os.path.isfile(self.projectDir + '/meshFix.cfg'):
            os.remove(self.projectDir + '/meshFix.cfg')
        if os.path.isfile(self.projectDir + '/surface_analysis.vtk'):
            os.remove(self.projectDir + '/surface_analysis.vtk')