Code Monkey home page Code Monkey logo

fado's Introduction

FADO

Framework for Aerostructural Design Optimization

Motivation

Q: "What is my purpose?"

A: "You run other codes."

More seriously, the typical use case is: you have a simulation code (CFD, FEA, etc.) that reads/writes its inputs/outputs from/to text file(s), you want to wrap the execution of that code, for example to use it in an optimization, but that code does not have a Python interface quite like what you would like...

FADO provides abstractions to make this job easier than writing specialized scripts for each application, scripting is still required, but the resulting scripts should be easier to maintain/adapt/modify.

The design of the framework is centered around large scale applications (10k+ variables) and functions that are expensive to evaluate (compared to the cost of preparing input files).

Abstractions

From the top down (and not a replacement for the docs):

  • Driver: The class of objects used to wrap the execution steps required to evaluate functions and their gradients in a way that conforms to the interface of particular optimizers. Drivers can evaluate all their functions simultaneously (i.e. in parallel).
  • Function: An entity with one scalar output and any number of input "variables". Functions are further defined by the steps ("evaluations") required to obtain their value and possibly their gradient.
  • Variable: The scalar or vector inputs of functions that are exposed to the optimizers.
  • Evaluation: These wrap the calls to the external codes, they are configured with the input and data files, and the instructions, required to execute the code. "Parameters" can be associated with evaluations to introduce small changes to the input files (e.g. change a boundary condition in a multipoint optimization).
  • Parameter: A numeric or text variable that is not exposed to the optimizer, they are useful to introduce small modifications to the input files to make a small number of template input files applicable to as many evaluations as possible.

Note: The calls to external codes from FADO.ExternalRun evaluations are made with subprocess.call(..., shell=True), don't run optimizations as root, or in system directories, etc.

Interfacing with files

Function, Variable, and Parameter need ways to be written and read to or from files. Any object implementing write(file,values) and/or read(file) -> values can be used, five classes are provided that should cover most scenarios:

  • LabelReplacer: Replaces any occurrence of a label (a string) with the value of a scalar variable or parameter.
  • ArrayLabelReplacer: Does the same for array-like values.
  • PreStringHandler: Reads(writes) a list of values separated by a configurable delimiter from(in) front of a label defining the start of a line (i.e. the line must start with the label).
  • TableReader/Writer: Reads or writes to a section of a delimited table, rows outside of the table range do not need to be in table format, but those inside are expected to have the same number of columns, the examples should make it clear how to use these classes.
  • LabeledTableReader: Reads values from CSV-type files based on column name and range of rows.

Installation

Make the parent directory ("../") and FADO's ("./") reachable to Python, usually via PYTHONPATH, from FADO import * should then work (provided the name of the directory was not changed).

Dependencies

Hard dependency on NumPy, ndarrays are used throughout the code. The ExteriorPenaltyDriver was designed around the SciPy.optimize.minimize interface, but a simple implementation of the Fletcher-Reeves method is available (see example2_SU2). The ScipyDriver was designed with the constrained optimization methods in mind (especially SLSQP) but does not strictly require SciPy to be used. To use the IpoptDriver you need IPyOpt and Ipopt, the latter can be installed with apt-get.

Usage

Have a look at the examples, "examples/rosenbrock" is a contrived example using the Rosenbrock function, the others are realistic uses of SU2 (version > 7.1.0). All the important classes and methods have Python documentation strings, these can be printed using the utility function printDocumentation, e.g. FADO.printDocumentation(FADO.TableReader), for classes this will print the documentation for all their methods. In general, undocumented methods are meant for FADO's internal use, and should not be called by users.

License

LGPL-3.0

fado's People

Contributors

pcarruscag avatar tobikattmann avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

fado's Issues

Why does SLSQP "revert" a better design?

Hi @pcarruscag,

In an optimization with FADO using the SLSQP optimizer I noticed that, despite finding a notable better design in the first step, the optimizer does not "accept" that design and "reverts" the deformation subsequently by trying the same gradient with smaller scales (and ends up at pretty much the initial design).

On the left axis the avg-Temp makes a very promising 1 degree drop. Additionally i plotted the pressure drop on the right axis (const massflow prescribed) for good measure.
image

A gradient is only computed for the initial design afterwards it has to be scaling of that initial gradient. I would fully understand that kind of behavior iff the first step were to worsen the OF. Then the optimizer might think the step/scale was to aggressive and tries smaller deformations ... because in the assumption of a correct gradient is has to work/optimize, if small enough of a deformation is applied.

This is btw the first step, the initial is fully round. and from the 2nd step on, this "large" deformation is reverted by applying scaled down deformations until it is round again.
image

Now, of course the first instinct would be to say: "There is a wrong sign then somewhere :)" But I do in FADO

ffd = InputVariable(np.zeros((nDV,)),ArrayLabelReplacer("__FFD_PTS__"), 0, np.ones(nDV), -0.0008,0.0008)

and

driver.addObjective("min", avgT, 1.0e-9)

and in the cfg:

OBJECTIVE_FUNCTION= AVG_TEMPERATURE
OBJECTIVE_WEIGHT= 1.0  
and DV_PARAMS (collapsible section)

where I compute the gradient only on the middle half pin but I apply the very same deformation to the front and back-quarter pin. Therefor the ugly setup below for DEF and the distinction between the gradient computation and deformation

%__ADJOINT__DV_PARAM= \
%__ADJOINT__( BOX, 0, 2, 0.0, 1.0);( BOX, 1, 2, 0.0, 1.0);( BOX, 2, 2, 0.0, 1.0);( BOX, 3, 2, 0.0, 1.0);( BOX, 4, 2, 0.0, 1.0);( BOX, 5, 2, 0.0, 1.0);( BOX, 6, 2, 0.0, 1.0);( BOX, 7, 2, 0.0, 1.0);( BOX, 8, 2, 0.0, 1.0);\
%__ADJOINT__( BOX, 0, 3, 0.0, 1.0);( BOX, 1, 3, 0.0, 1.0);( BOX, 2, 3, 0.0, 1.0);( BOX, 3, 3, 0.0, 1.0);( BOX, 4, 3, 0.0, 1.0);( BOX, 5, 3, 0.0, 1.0);( BOX, 6, 3, 0.0, 1.0);( BOX, 7, 3, 0.0, 1.0);( BOX, 8, 3, 0.0, 1.0);\
%__ADJOINT__( BOX, 0, 4, 0.0, 1.0);( BOX, 1, 4, 0.0, 1.0);( BOX, 2, 4, 0.0, 1.0);( BOX, 3, 4, 0.0, 1.0);( BOX, 4, 4, 0.0, 1.0);( BOX, 5, 4, 0.0, 1.0);( BOX, 6, 4, 0.0, 1.0);( BOX, 7, 4, 0.0, 1.0);( BOX, 8, 4, 0.0, 1.0);\
%__ADJOINT__( BOX, 0, 5, 0.0, 1.0);( BOX, 1, 5, 0.0, 1.0);( BOX, 2, 5, 0.0, 1.0);( BOX, 3, 5, 0.0, 1.0);( BOX, 4, 5, 0.0, 1.0);( BOX, 5, 5, 0.0, 1.0);( BOX, 6, 5, 0.0, 1.0);( BOX, 7, 5, 0.0, 1.0);( BOX, 8, 5, 0.0, 1.0);\
%__ADJOINT__( BOX, 0, 6, 0.0, 1.0);( BOX, 1, 6, 0.0, 1.0);( BOX, 2, 6, 0.0, 1.0);( BOX, 3, 6, 0.0, 1.0);( BOX, 4, 5, 0.0, 1.0);( BOX, 5, 6, 0.0, 1.0);( BOX, 6, 5, 0.0, 1.0);( BOX, 7, 6, 0.0, 1.0);( BOX, 8, 6, 0.0, 1.0)

and the deformation. Scale for Front and Backbox is -1.0 because I can therefore apply the very same DV_VALUE to all three FFD-Boxes which allows me to use %__DEF__DV_VALUE= __FFD_PTS__, __FFD_PTS__, __FFD_PTS__ which I believe is a very elegant solution to my periodic problem.

__DEF__DV_PARAM= \
%__DEF__    ( BOX, 0, 2, 0.0, 1.0);( BOX, 1, 2, 0.0, 1.0);( BOX, 2, 2, 0.0, 1.0);( BOX, 3, 2, 0.0, 1.0);( BOX, 4, 2, 0.0, 1.0);( BOX, 5, 2, 0.0, 1.0);( BOX, 6, 2, 0.0, 1.0);( BOX, 7, 2, 0.0, 1.0);( BOX, 8, 2, 0.0, 1.0);\
%__DEF__    ( BOX, 0, 3, 0.0, 1.0);( BOX, 1, 3, 0.0, 1.0);( BOX, 2, 3, 0.0, 1.0);( BOX, 3, 3, 0.0, 1.0);( BOX, 4, 3, 0.0, 1.0);( BOX, 5, 3, 0.0, 1.0);( BOX, 6, 3, 0.0, 1.0);( BOX, 7, 3, 0.0, 1.0);( BOX, 8, 3, 0.0, 1.0);\
%__DEF__    ( BOX, 0, 4, 0.0, 1.0);( BOX, 1, 4, 0.0, 1.0);( BOX, 2, 4, 0.0, 1.0);( BOX, 3, 4, 0.0, 1.0);( BOX, 4, 4, 0.0, 1.0);( BOX, 5, 4, 0.0, 1.0);( BOX, 6, 4, 0.0, 1.0);( BOX, 7, 4, 0.0, 1.0);( BOX, 8, 4, 0.0, 1.0);\
%__DEF__    ( BOX, 0, 5, 0.0, 1.0);( BOX, 1, 5, 0.0, 1.0);( BOX, 2, 5, 0.0, 1.0);( BOX, 3, 5, 0.0, 1.0);( BOX, 4, 5, 0.0, 1.0);( BOX, 5, 5, 0.0, 1.0);( BOX, 6, 5, 0.0, 1.0);( BOX, 7, 5, 0.0, 1.0);( BOX, 8, 5, 0.0, 1.0);\
%__DEF__    ( BOX, 0, 6, 0.0, 1.0);( BOX, 1, 6, 0.0, 1.0);( BOX, 2, 6, 0.0, 1.0);( BOX, 3, 6, 0.0, 1.0);( BOX, 4, 5, 0.0, 1.0);( BOX, 5, 6, 0.0, 1.0);( BOX, 6, 5, 0.0, 1.0);( BOX, 7, 6, 0.0, 1.0);( BOX, 8, 6, 0.0, 1.0);\
%__DEF__( FRONTBOX, 0, 2, 0.0, -1.0);( FRONTBOX, 1, 2, 0.0, -1.0);( FRONTBOX, 2, 2, 0.0, -1.0);( FRONTBOX, 3, 2, 0.0, -1.0);( FRONTBOX, 4, 2, 0.0, -1.0);( FRONTBOX, 5, 2, 0.0, -1.0);( FRONTBOX, 6, 2, 0.0, -1.0);( FRONTBOX, 7, 2, 0.0, -1.0
%__DEF__( FRONTBOX, 0, 3, 0.0, -1.0);( FRONTBOX, 1, 3, 0.0, -1.0);( FRONTBOX, 2, 3, 0.0, -1.0);( FRONTBOX, 3, 3, 0.0, -1.0);( FRONTBOX, 4, 3, 0.0, -1.0);( FRONTBOX, 5, 3, 0.0, -1.0);( FRONTBOX, 6, 3, 0.0, -1.0);( FRONTBOX, 7, 3, 0.0, -1.0
%__DEF__( FRONTBOX, 0, 4, 0.0, -1.0);( FRONTBOX, 1, 4, 0.0, -1.0);( FRONTBOX, 2, 4, 0.0, -1.0);( FRONTBOX, 3, 4, 0.0, -1.0);( FRONTBOX, 4, 4, 0.0, -1.0);( FRONTBOX, 5, 4, 0.0, -1.0);( FRONTBOX, 6, 4, 0.0, -1.0);( FRONTBOX, 7, 4, 0.0, -1.0
%__DEF__( FRONTBOX, 0, 5, 0.0, -1.0);( FRONTBOX, 1, 5, 0.0, -1.0);( FRONTBOX, 2, 5, 0.0, -1.0);( FRONTBOX, 3, 5, 0.0, -1.0);( FRONTBOX, 4, 5, 0.0, -1.0);( FRONTBOX, 5, 5, 0.0, -1.0);( FRONTBOX, 6, 5, 0.0, -1.0);( FRONTBOX, 7, 5, 0.0, -1.0
%__DEF__( FRONTBOX, 0, 6, 0.0, -1.0);( FRONTBOX, 1, 6, 0.0, -1.0);( FRONTBOX, 2, 6, 0.0, -1.0);( FRONTBOX, 3, 6, 0.0, -1.0);( FRONTBOX, 4, 5, 0.0, -1.0);( FRONTBOX, 5, 6, 0.0, -1.0);( FRONTBOX, 6, 5, 0.0, -1.0);( FRONTBOX, 7, 6, 0.0, -1.0
%__DEF__( BACKBOX, 0, 2, 0.0, -1.0);( BACKBOX, 1, 2, 0.0, -1.0);( BACKBOX, 2, 2, 0.0, -1.0);( BACKBOX, 3, 2, 0.0, -1.0);( BACKBOX, 4, 2, 0.0, -1.0);( BACKBOX, 5, 2, 0.0, -1.0);( BACKBOX, 6, 2, 0.0, -1.0);( BACKBOX, 7, 2, 0.0, -1.0);( BACK
%__DEF__( BACKBOX, 0, 3, 0.0, -1.0);( BACKBOX, 1, 3, 0.0, -1.0);( BACKBOX, 2, 3, 0.0, -1.0);( BACKBOX, 3, 3, 0.0, -1.0);( BACKBOX, 4, 3, 0.0, -1.0);( BACKBOX, 5, 3, 0.0, -1.0);( BACKBOX, 6, 3, 0.0, -1.0);( BACKBOX, 7, 3, 0.0, -1.0);( BACK
%__DEF__( BACKBOX, 0, 4, 0.0, -1.0);( BACKBOX, 1, 4, 0.0, -1.0);( BACKBOX, 2, 4, 0.0, -1.0);( BACKBOX, 3, 4, 0.0, -1.0);( BACKBOX, 4, 4, 0.0, -1.0);( BACKBOX, 5, 4, 0.0, -1.0);( BACKBOX, 6, 4, 0.0, -1.0);( BACKBOX, 7, 4, 0.0, -1.0);( BACK
%__DEF__( BACKBOX, 0, 5, 0.0, -1.0);( BACKBOX, 1, 5, 0.0, -1.0);( BACKBOX, 2, 5, 0.0, -1.0);( BACKBOX, 3, 5, 0.0, -1.0);( BACKBOX, 4, 5, 0.0, -1.0);( BACKBOX, 5, 5, 0.0, -1.0);( BACKBOX, 6, 5, 0.0, -1.0);( BACKBOX, 7, 5, 0.0, -1.0);( BACK
%__DEF__( BACKBOX, 0, 6, 0.0, -1.0);( BACKBOX, 1, 6, 0.0, -1.0);( BACKBOX, 2, 6, 0.0, -1.0);( BACKBOX, 3, 6, 0.0, -1.0);( BACKBOX, 4, 5, 0.0, -1.0);( BACKBOX, 5, 6, 0.0, -1.0);( BACKBOX, 6, 5, 0.0, -1.0);( BACKBOX, 7, 6, 0.0, -1.0);( BACK
%

What do I overlook? Why is SLSQP doing this to me? I know my whole setup is a butchered mess, but any idea would be highly appreciated ๐Ÿ‘
I already used the very same OF in a CHT case with SLSQP succesfully (cylinder in crossflow with a solid inner pin).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.