Ejemplo n.º 1
0
def adaptation ( config , kind='' ):
    
    # local copy
    konfig = copy.deepcopy(config)
    
    # check kind
    if kind: konfig['KIND_ADAPT'] = kind
    kind = konfig.get('KIND_ADAPT','NONE')
    if kind == 'NONE': 
        return {}
    
    # check adapted?
    
    # decompose
    su2decomp(konfig)
    
    # get adaptation function
    adapt_function = su2mesh.adapt.name_map[kind]
    
    # setup problem
    suffix = 'adapt'
    meshname_orig = konfig['MESH_FILENAME']
    meshname_new  = su2io.add_suffix( konfig['MESH_FILENAME'], suffix )
    konfig['MESH_OUT_FILENAME'] = meshname_new
    
    # Run Adaptation
    info = adapt_function(konfig)
    
    # update super config
    config['MESH_FILENAME'] = meshname_new
    config['KIND_ADAPT']    = kind
    
    # files out
    files = { 'MESH' : meshname_new }
    
    # info out
    append_nestdict( info, { 'FILES' : files } )
    
    return info
Ejemplo n.º 2
0
def adaptation(config, kind=''):

    # local copy
    konfig = copy.deepcopy(config)

    # check kind
    if kind: konfig['KIND_ADAPT'] = kind
    kind = konfig.get('KIND_ADAPT', 'NONE')
    if kind == 'NONE':
        return {}

    # check adapted?

    # decompose
    su2decomp(konfig)

    # get adaptation function
    adapt_function = su2mesh.adapt.name_map[kind]

    # setup problem
    suffix = 'adapt'
    meshname_orig = konfig['MESH_FILENAME']
    meshname_new = su2io.add_suffix(konfig['MESH_FILENAME'], suffix)
    konfig['MESH_OUT_FILENAME'] = meshname_new

    # Run Adaptation
    info = adapt_function(konfig)

    # update super config
    config['MESH_FILENAME'] = meshname_new
    config['KIND_ADAPT'] = kind

    # files out
    files = {'MESH': meshname_new}

    # info out
    append_nestdict(info, {'FILES': files})

    return info
Ejemplo n.º 3
0
def projection( config, step = 1e-3 ):
    """ info = SU2.run.projection(config,step=1e-3)
        
        Runs an gradient projection with:
            SU2.run.decomp()
            SU2.run.GPC()
            
        Assumptions:
            Redundant decomposition if config.DECOMPOSED == True
            Writes tecplot file of gradients
            Adds objective suffix to gradient plot filename
            
        Inputs:
            config - an SU2 config
            step   - a float or list of floats for geometry sensitivity
                     finite difference step
            
        Outputs:
            info - SU2 State with keys:
                GRADIENTS.<config.OBJECTIVE_FUNCTION>
                
        Updates:
            config.DECOMPOSED
            config.MATH_PROBLEM
            
        Executes in:
            ./
    """
    # local copy
    konfig = copy.deepcopy(config)
    
    # decompose
    su2decomp(konfig)
        
    # choose dv values 
    Definition_DV = konfig['DEFINITION_DV']
    n_DV          = len(Definition_DV['KIND'])
    if isinstance(step,list):
        assert len(step) == n_DV , 'unexpected step vector length'
    else:
        step = [step]*n_DV
    dv_old = [0.0]*n_DV # SU2_GPC input requirement, assumes linear superposition of design variables
    dv_new = step
    konfig.unpack_dvs(dv_new,dv_old)

    # filenames
    objective      = konfig['OBJECTIVE_FUNCTION']
    grad_filename  = konfig['GRAD_OBJFUNC_FILENAME']
    output_format  = konfig['OUTPUT_FORMAT']
    plot_extension = su2io.get_extension(output_format)
    adj_suffix     = su2io.get_adjointSuffix(objective)
    grad_plotname  = os.path.splitext(grad_filename)[0] + '_' + adj_suffix + plot_extension    

    # Run Projection
    SU2_GPC(konfig)
    
    # read raw gradients
    raw_gradients = su2io.read_gradients(grad_filename)
    os.remove(grad_filename)
    
    # Write Gradients
    data_plot = su2util.ordered_bunch()
    data_plot['VARIABLE']     = range(len(raw_gradients)) 
    data_plot['GRADIENT']     = raw_gradients             
    data_plot['FINDIFF_STEP'] = step                       
    su2util.write_plot(grad_plotname,output_format,data_plot)

    # gradient output dictionary
    gradients = { objective : raw_gradients }
    
    # info out
    info = su2io.State()
    info.GRADIENTS.update( gradients )
    
    return info
Ejemplo n.º 4
0
def direct ( config ): 
    """ info = SU2.run.direct(config)
        
        Runs an adjoint analysis with:
            SU2.run.decomp()
            SU2.run.CFD()
            SU2.run.merge()
            
        Assumptions:
            Redundant decomposition if config.DECOMPOSED == True
            Does not rename restart filename to solution filename
            Adds 'direct' suffix to convergence filename
                        
        Outputs:
            info - SU2 State with keys:
                FUNCTIONS
                HISTORY.DIRECT
                FILES.DIRECT
                
        Updates:
            config.DECOMPOSED
            config.MATH_PROBLEM
            
        Executes in:
            ./
    """
    
    # local copy
    konfig = copy.deepcopy(config)

    # decompose
    su2decomp(konfig)
    
    # setup direct problem
    konfig['MATH_PROBLEM']  = 'DIRECT'
    konfig['CONV_FILENAME'] = konfig['CONV_FILENAME'] + '_direct'    
    
    # Run Solution
    SU2_CFD(konfig)
    
    # merge
    konfig['SOLUTION_FLOW_FILENAME'] = konfig['RESTART_FLOW_FILENAME'] 
    su2merge(konfig)
    
    # filenames
    plot_format      = konfig['OUTPUT_FORMAT']
    plot_extension   = su2io.get_extension(plot_format)
    history_filename = konfig['CONV_FILENAME'] + plot_extension
    special_cases    = su2io.get_specialCases(konfig)

    # get history and objectives
    history      = su2io.read_history( history_filename )
    aerodynamics = su2io.read_aerodynamics( history_filename , special_cases )
    
    # update super config
    config.update({ 'DECOMPOSED'   : konfig['DECOMPOSED']   ,
                    'MATH_PROBLEM' : konfig['MATH_PROBLEM']  })
                    
    # info out
    info = su2io.State()
    info.FUNCTIONS.update( aerodynamics )
    info.FILES.DIRECT = konfig['RESTART_FLOW_FILENAME']
    if 'EQUIV_AREA' in special_cases:
        info.FILES.WEIGHT_NF = 'WeightNF.dat'
    info.HISTORY.DIRECT = history
    
    return info
Ejemplo n.º 5
0
def adjoint( config ): 
    """ info = SU2.run.adjoint(config)
        
        Runs an adjoint analysis with:
            SU2.run.decomp()
            SU2.run.CFD()
            SU2.run.merge()
            
        Assumptions:
            Redundant decomposition if config.DECOMPOSED == True
            Does not run Gradient Projection
            Does not rename restart filename to solution filename
            Adds 'adjoint' suffix to convergence filename
            
        Outputs:
            info - SU2 State with keys:
                HISTORY.ADJOINT_NAME
                FILES.ADJOINT_NAME
                
        Updates:
            config.DECOMPOSED
            config.MATH_PROBLEM
            
        Executes in:
            ./
    """
    
    # local copy
    konfig = copy.deepcopy(config)

    # decompose
    su2decomp(konfig)
    
    # setup problem    
    konfig['MATH_PROBLEM']  = 'ADJOINT'
    konfig['CONV_FILENAME'] = konfig['CONV_FILENAME'] + '_adjoint'
    
    # Run Solution
    SU2_CFD(konfig)
    
    # merge
    konfig['SOLUTION_ADJ_FILENAME'] = konfig['RESTART_ADJ_FILENAME'] 
    su2merge(konfig)
    
    # filenames
    plot_format      = konfig['OUTPUT_FORMAT']
    plot_extension   = su2io.get_extension(plot_format)
    history_filename = konfig['CONV_FILENAME'] + plot_extension
    special_cases    = su2io.get_specialCases(konfig)
    
    # get history
    history = su2io.read_history( history_filename )
    
    # update super config
    config.update({ 'DECOMPOSED'   : konfig['DECOMPOSED']   ,
                    'MATH_PROBLEM' : konfig['MATH_PROBLEM'] ,
                    'OBJECTIVE_FUNCTION'  : konfig['OBJECTIVE_FUNCTION']   })
    
    # files out
    objective    = konfig['OBJECTIVE_FUNCTION']
    adj_title    = 'ADJOINT_' + objective
    suffix       = su2io.get_adjointSuffix(objective)
    restart_name = konfig['RESTART_FLOW_FILENAME']
    restart_name = su2io.add_suffix(restart_name,suffix)
    
    # info out
    info = su2io.State()
    info.FILES[adj_title] = restart_name
    info.HISTORY[adj_title] = history
    
    return info
Ejemplo n.º 6
0
def direct(config):
    """ info = SU2.run.direct(config)
        
        Runs an adjoint analysis with:
            SU2.run.decomp()
            SU2.run.CFD()
            SU2.run.merge()
            
        Assumptions:
            Redundant decomposition if config.DECOMPOSED == True
            Does not rename restart filename to solution filename
            Adds 'direct' suffix to convergence filename
                        
        Outputs:
            info - SU2 State with keys:
                FUNCTIONS
                HISTORY.DIRECT
                FILES.DIRECT
                
        Updates:
            config.DECOMPOSED
            config.MATH_PROBLEM
            
        Executes in:
            ./
    """

    # local copy
    konfig = copy.deepcopy(config)

    # decompose
    su2decomp(konfig)

    # setup direct problem
    konfig['MATH_PROBLEM'] = 'DIRECT'
    konfig['CONV_FILENAME'] = konfig['CONV_FILENAME'] + '_direct'

    # Run Solution
    SU2_CFD(konfig)

    # merge
    konfig['SOLUTION_FLOW_FILENAME'] = konfig['RESTART_FLOW_FILENAME']
    su2merge(konfig)

    # filenames
    plot_format = konfig['OUTPUT_FORMAT']
    plot_extension = su2io.get_extension(plot_format)
    history_filename = konfig['CONV_FILENAME'] + plot_extension
    special_cases = su2io.get_specialCases(konfig)

    # averaging final iterations
    final_avg = config.get('ITER_AVERAGE_OBJ', 0)

    # get history and objectives
    history = su2io.read_history(history_filename)
    aerodynamics = su2io.read_aerodynamics(history_filename, special_cases,
                                           final_avg)

    # update super config
    config.update({
        'DECOMPOSED': konfig['DECOMPOSED'],
        'MATH_PROBLEM': konfig['MATH_PROBLEM']
    })

    # info out
    info = su2io.State()
    info.FUNCTIONS.update(aerodynamics)
    info.FILES.DIRECT = konfig['RESTART_FLOW_FILENAME']
    if 'EQUIV_AREA' in special_cases:
        info.FILES.WEIGHT_NF = 'WeightNF.dat'
    if 'INV_DESIGN_CP' in special_cases:
        info.FILES.TARGET_CP = 'TargetCp.dat'
    if 'INV_DESIGN_HEATFLUX' in special_cases:
        info.FILES.TARGET_HEATFLUX = 'TargetHeatFlux.dat'
    info.HISTORY.DIRECT = history

    return info
Ejemplo n.º 7
0
def deform ( config, dv_new=None, dv_old=None ):
    """ info = SU2.run.deform(config,dv_new=[],dv_old=[])
        
        Deforms mesh with:
            SU2.run.decomp()
            SU2.run.DEF()
            
        Assumptions:
            Redundant decomposition if config.DECOMPOSED == True
            If optional dv_new ommitted, config is setup for deformation
            If using dv_old, must provide dv_new
            Adds 'deform' suffix to mesh output name
            
        Outputs:
            info - SU2 State with keys:
                HISTORY.ADJOINT_NAME
                FILES.ADJOINT_NAME
                
        Updates:
            config.DECOMPOSED
            config.MESH_FILENAME
            config.DV_VALUE_OLD = config.DV_VALUE_NEW
            
        Executes in:
            ./
    """    
    
    if dv_new is None: dv_new = []
    if dv_old is None: dv_old = []
    
    # error check
    if dv_old and not dv_new: raise Exception, 'must provide dv_old with dv_new'
    
    # local copy
    konfig = copy.deepcopy(config)
    
    # decompose
    su2decomp(konfig)
    
    # unpack design variables
    if dv_new: konfig.unpack_dvs(dv_new,dv_old)
    
    # redundancy check
    if konfig['DV_VALUE_NEW'] == konfig['DV_VALUE_OLD']:
        info = su2io.State()
        info.FILES.MESH = konfig.MESH_FILENAME
        info.VARIABLES.DV_VALUE_NEW = konfig.DV_VALUE_NEW        
        return info
    
    # setup mesh name
    suffix = 'deform'
    mesh_name = konfig['MESH_FILENAME']
    meshname_suffixed = su2io.add_suffix( mesh_name , suffix )
    konfig['MESH_OUT_FILENAME'] = meshname_suffixed
    
    # Run Deformation
    SU2_DEF(konfig)
    
    # update super config
    config.update({ 'DECOMPOSED'    : konfig['DECOMPOSED']        ,
                    'MESH_FILENAME' : konfig['MESH_OUT_FILENAME'] , 
                    'DV_KIND'       : konfig['DV_KIND']           ,
                    'DV_MARKER'     : konfig['DV_MARKER']         ,
                    'DV_PARAM'      : konfig['DV_PARAM']          ,
                    'DV_VALUE_OLD'  : konfig['DV_VALUE_NEW']      ,
                    'DV_VALUE_NEW'  : konfig['DV_VALUE_NEW']      })
    # not modified: config['MESH_OUT_FILENAME']
        
    # info out
    info = su2io.State()
    info.FILES.MESH = meshname_suffixed
    info.VARIABLES.DV_VALUE_NEW = konfig.DV_VALUE_NEW
    
    return info

#: def deform()
Ejemplo n.º 8
0
def deform(config, dv_new=None, dv_old=None):
    """ info = SU2.run.deform(config,dv_new=[],dv_old=[])
        
        Deforms mesh with:
            SU2.run.decomp()
            SU2.run.DEF()
            
        Assumptions:
            Redundant decomposition if config.DECOMPOSED == True
            If optional dv_new ommitted, config is setup for deformation
            If using dv_old, must provide dv_new
            Adds 'deform' suffix to mesh output name
            
        Outputs:
            info - SU2 State with keys:
                HISTORY.ADJOINT_NAME
                FILES.ADJOINT_NAME
                
        Updates:
            config.DECOMPOSED
            config.MESH_FILENAME
            config.DV_VALUE_OLD = config.DV_VALUE_NEW
            
        Executes in:
            ./
    """

    if dv_new is None: dv_new = []
    if dv_old is None: dv_old = []

    # error check
    if dv_old and not dv_new:
        raise Exception, 'must provide dv_old with dv_new'

    # local copy
    konfig = copy.deepcopy(config)

    # decompose
    su2decomp(konfig)

    # unpack design variables
    if dv_new: konfig.unpack_dvs(dv_new, dv_old)

    # redundancy check
    if konfig['DV_VALUE_NEW'] == konfig['DV_VALUE_OLD']:
        info = su2io.State()
        info.FILES.MESH = konfig.MESH_FILENAME
        info.VARIABLES.DV_VALUE_NEW = konfig.DV_VALUE_NEW
        return info

    # setup mesh name
    suffix = 'deform'
    mesh_name = konfig['MESH_FILENAME']
    meshname_suffixed = su2io.add_suffix(mesh_name, suffix)
    konfig['MESH_OUT_FILENAME'] = meshname_suffixed

    # Run Deformation
    SU2_DEF(konfig)

    # update super config
    config.update({
        'DECOMPOSED': konfig['DECOMPOSED'],
        'MESH_FILENAME': konfig['MESH_OUT_FILENAME'],
        'DV_KIND': konfig['DV_KIND'],
        'DV_MARKER': konfig['DV_MARKER'],
        'DV_PARAM': konfig['DV_PARAM'],
        'DV_VALUE_OLD': konfig['DV_VALUE_NEW'],
        'DV_VALUE_NEW': konfig['DV_VALUE_NEW']
    })
    # not modified: config['MESH_OUT_FILENAME']

    # info out
    info = su2io.State()
    info.FILES.MESH = meshname_suffixed
    info.VARIABLES.DV_VALUE_NEW = konfig.DV_VALUE_NEW

    return info


#: def deform()
Ejemplo n.º 9
0
def geometry ( config , step = 1e-3 ): 
    """ info = SU2.run.geometry(config)
        
        Runs an geometry analysis with:
            SU2.run.decomp()
            SU2.run.GEO()
            
        Assumptions:
            Redundant decomposition if config.DECOMPOSED == True
            Performs both function and gradient analysis
                        
        Inputs:
            config - an SU2 configuration
            step   - gradient finite difference step if config.GEO_MODE=GRADIENT
        
        Outputs:
            info - SU2 State with keys:
                FUNCTIONS
                GRADIENTS
                
        Updates:
            config.DECOMPOSED
            
        Executes in:
            ./
    """
    
    # local copy
    konfig = copy.deepcopy(config)
    
    # unpack
    function_name = konfig['GEO_PARAM']
    func_filename = 'of_func.dat'
    grad_filename = 'of_grad.dat'
    
    # choose dv values 
    Definition_DV = konfig['DEFINITION_DV']
    n_DV          = len(Definition_DV['KIND'])
    if isinstance(step,list):
        assert len(step) == n_DV , 'unexpected step vector length'
    else:
        step = [step]*n_DV
    dv_old = [0.0]*n_DV # SU2_DOT input requirement, assumes linear superposition of design variables
    dv_new = step
    konfig.unpack_dvs(dv_new,dv_old)    
    
    # decompose
    su2decomp(konfig)
    
    # Run Solution
    SU2_GEO(konfig)
    
    # info out
    info = su2io.State()    
    
    # get function values
    if konfig.GEO_MODE == 'FUNCTION':
        functions = su2io.tools.read_plot(func_filename)
        for key,value in functions.items():
            functions[key] = value[0]
        info.FUNCTIONS.update( functions )
    
    # get gradient_values
    if konfig.GEO_MODE == 'GRADIENT':
        gradients = su2io.tools.read_plot(grad_filename)
        info.GRADIENTS.update( gradients )
    
    # update super config
    config.update({ 'DECOMPOSED' : konfig['DECOMPOSED'] })
    
    return info
Ejemplo n.º 10
0
def adjoint(config):
    """ info = SU2.run.adjoint(config)
        
        Runs an adjoint analysis with:
            SU2.run.decomp()
            SU2.run.CFD()
            SU2.run.merge()
            
        Assumptions:
            Redundant decomposition if config.DECOMPOSED == True
            Does not run Gradient Projection
            Does not rename restart filename to solution filename
            Adds 'adjoint' suffix to convergence filename
            
        Outputs:
            info - SU2 State with keys:
                HISTORY.ADJOINT_NAME
                FILES.ADJOINT_NAME
                
        Updates:
            config.DECOMPOSED
            config.MATH_PROBLEM
            
        Executes in:
            ./
    """

    # local copy
    konfig = copy.deepcopy(config)

    # decompose
    su2decomp(konfig)

    # setup problem
    konfig['MATH_PROBLEM'] = 'ADJOINT'
    konfig['CONV_FILENAME'] = konfig['CONV_FILENAME'] + '_adjoint'

    # Run Solution
    SU2_CFD(konfig)

    # merge
    konfig['SOLUTION_ADJ_FILENAME'] = konfig['RESTART_ADJ_FILENAME']
    su2merge(konfig)

    # filenames
    plot_format = konfig['OUTPUT_FORMAT']
    plot_extension = su2io.get_extension(plot_format)
    history_filename = konfig['CONV_FILENAME'] + plot_extension
    special_cases = su2io.get_specialCases(konfig)

    # get history
    history = su2io.read_history(history_filename)

    # update super config
    config.update({
        'DECOMPOSED': konfig['DECOMPOSED'],
        'MATH_PROBLEM': konfig['MATH_PROBLEM'],
        'ADJ_OBJFUNC': konfig['ADJ_OBJFUNC']
    })

    # files out
    objective = konfig['ADJ_OBJFUNC']
    adj_title = 'ADJOINT_' + objective
    suffix = su2io.get_adjointSuffix(objective)
    restart_name = konfig['RESTART_FLOW_FILENAME']
    restart_name = su2io.add_suffix(restart_name, suffix)

    # info out
    info = su2io.State()
    info.FILES[adj_title] = restart_name
    info.HISTORY[adj_title] = history

    return info
Ejemplo n.º 11
0
def projection(config, step=1e-3):
    """ info = SU2.run.projection(config,step=1e-3)
        
        Runs an gradient projection with:
            SU2.run.decomp()
            SU2.run.DOT()
            
        Assumptions:
            Redundant decomposition if config.DECOMPOSED == True
            Writes tecplot file of gradients
            Adds objective suffix to gradient plot filename
            
        Inputs:
            config - an SU2 config
            step   - a float or list of floats for geometry sensitivity
                     finite difference step
            
        Outputs:
            info - SU2 State with keys:
                GRADIENTS.<config.OBJECTIVE_FUNCTION>
                
        Updates:
            config.DECOMPOSED
            config.MATH_PROBLEM
            
        Executes in:
            ./
    """
    # local copy
    konfig = copy.deepcopy(config)

    # decompose
    su2decomp(konfig)

    # choose dv values
    Definition_DV = konfig['DEFINITION_DV']
    n_DV = len(Definition_DV['KIND'])
    if isinstance(step, list):
        assert len(step) == n_DV, 'unexpected step vector length'
    else:
        step = [step] * n_DV
    dv_old = [
        0.0
    ] * n_DV  # SU2_DOT input requirement, assumes linear superposition of design variables
    dv_new = step
    konfig.unpack_dvs(dv_new, dv_old)

    # filenames
    objective = konfig['OBJECTIVE_FUNCTION']
    grad_filename = konfig['GRAD_OBJFUNC_FILENAME']
    output_format = konfig['OUTPUT_FORMAT']
    plot_extension = su2io.get_extension(output_format)
    adj_suffix = su2io.get_adjointSuffix(objective)
    grad_plotname = os.path.splitext(
        grad_filename)[0] + '_' + adj_suffix + plot_extension

    # Run Projection
    SU2_DOT(konfig)

    # read raw gradients
    raw_gradients = su2io.read_gradients(grad_filename)
    os.remove(grad_filename)

    # Write Gradients
    data_plot = su2util.ordered_bunch()
    data_plot['VARIABLE'] = range(len(raw_gradients))
    data_plot['GRADIENT'] = raw_gradients
    data_plot['FINDIFF_STEP'] = step
    su2util.write_plot(grad_plotname, output_format, data_plot)

    # gradient output dictionary
    gradients = {objective: raw_gradients}

    # info out
    info = su2io.State()
    info.GRADIENTS.update(gradients)

    return info
Ejemplo n.º 12
0
def geometry ( config , step = 1e-3 ): 
    """ info = SU2.run.geometry(config)
        
        Runs an geometry analysis with:
            SU2.run.decomp()
            SU2.run.GDC()
            
        Assumptions:
            Redundant decomposition if config.DECOMPOSED == True
            Performs both function and gradient analysis
                        
        Inputs:
            config - an SU2 configuration
            step   - gradient finite difference step if config.GEO_MODE=GRADIENT
        
        Outputs:
            info - SU2 State with keys:
                FUNCTIONS
                GRADIENTS
                
        Updates:
            config.DECOMPOSED
            
        Executes in:
            ./
    """
    
    # local copy
    konfig = copy.deepcopy(config)
    
    # unpack
    function_name = konfig['GEO_PARAM']
    func_filename = 'of_func.dat'
    grad_filename = 'of_grad.dat'
    
    # choose dv values 
    Definition_DV = konfig['DEFINITION_DV']
    n_DV          = len(Definition_DV['KIND'])
    if isinstance(step,list):
        assert len(step) == n_DV , 'unexpected step vector length'
    else:
        step = [step]*n_DV
    dv_old = [0.0]*n_DV # SU2_GPC input requirement, assumes linear superposition of design variables
    dv_new = step
    konfig.unpack_dvs(dv_new,dv_old)    
    
    # decompose
    su2decomp(konfig)
    
    # Run Solution
    SU2_GDC(konfig)
    
    # info out
    info = su2io.State()    
    
    # get function values
    if konfig.GEO_MODE == 'FUNCTION':
        functions = su2io.tools.read_plot(func_filename)
        for key,value in functions.items():
            functions[key] = value[0]
        info.FUNCTIONS.update( functions )
    
    # get gradient_values
    if konfig.GEO_MODE == 'GRADIENT':
        gradients = su2io.tools.read_plot(grad_filename)
        info.GRADIENTS.update( gradients )
    
    # update super config
    config.update({ 'DECOMPOSED' : konfig['DECOMPOSED'] })
    
    return info
Ejemplo n.º 13
0
def geometry(config, step=1e-3):
    """ info = SU2.run.geometry(config)
        
        Runs an geometry analysis with:
            SU2.run.decomp()
            SU2.run.GDC()
            
        Assumptions:
            Redundant decomposition if config.DECOMPOSED == True
            Performs both function and gradient analysis
                        
        Outputs:
            info - SU2 State with keys:
                FUNCTIONS
                GRADIENTS
                
        Updates:
            config.DECOMPOSED
            
        Executes in:
            ./
    """

    # local copy
    konfig = copy.deepcopy(config)

    # unpack
    function_name = konfig['GEO_PARAM']
    func_filename = 'of_eval.dat'
    grad_filename = 'of_grad.dat'

    # does both direct and gradient, very cheap
    konfig.GEO_MODE = 'GRADIENT'

    # choose dv values
    Definition_DV = konfig['DEFINITION_DV']
    n_DV = len(Definition_DV['KIND'])
    if isinstance(step, list):
        assert len(step) == n_DV, 'unexpected step vector length'
    else:
        step = [step] * n_DV
    dv_old = [
        0.0
    ] * n_DV  # SU2_GPC input requirement, assumes linear superposition of design variables
    dv_new = step
    konfig.unpack_dvs(dv_new, dv_old)

    # decompose
    su2decomp(konfig)

    # Run Solution
    SU2_GDC(konfig)

    # get function values
    func_file = open(func_filename)
    funcs = float(func_file.readline().strip())
    func_file.close()
    functions = ordered_bunch({function_name: funcs})

    # get gradient_values
    grads = su2io.read_gradients(grad_filename)
    gradients = ordered_bunch({function_name: grads})

    # update super config
    config.update({'DECOMPOSED': konfig['DECOMPOSED']})

    # info out
    info = su2io.State()
    info.FUNCTIONS.update(functions)
    info.GRADIENTS.update(gradients)

    return info