Simulation of High Aspect Ratio planes in Python [SHARPy]¶
Welcome to SHARPy (Simulation of High Aspect Ratio aeroplanes in Python)!
SHARPy is an aeroelastic analysis package currently under development at the Department of Aeronautics, Imperial College London. It can be used for the structural, aerodynamic, aeroelastic and flight dynamics analysis of flexible aircraft, flying wings and wind turbines. Amongst other capabilities, it offers the following solutions to the user:
Static aerodynamic, structural and aeroelastic solutions
Finding trim conditions for aeroelastic configurations
Nonlinear, dynamic time domain simulations under a large number of conditions such as:
- Prescribed trajectories.
- Free flight.
- Dynamic follower forces.
- Control inputs in thrust, control surface deflection…
- Arbitrary time-domain gusts, including non span-constant ones.
- Full 3D turbulent fields.
Multibody dynamics with hinges, articulations and prescribed nodal motions.
- Applicable to wind turbines.
- Hinged aircraft.
- Catapult assisted takeoffs.
Linear analysis
- Linearisation around a nonlinear equilibrium.
- Frequency response analysis.
- Asymptotic stability analysis.
Model order reduction
- Krylov-subspace reduction methods.
- Balancing reduction methods.
The modular design of SHARPy allows to simulate complex aeroelastic cases involving very flexible aircraft. The structural solver supports very complex beam arrangements, while retaining geometrical nonlinearity. The UVLM solver features different wake modelling fidelities while supporting large lifting surface deformations in a native way. Detailed information on each of the solvers is presented in their respective documentation packages.
Contents¶
SHARPy Installation Guide¶
Last revision 3 February 2020
The following step by step tutorial will guide you through the installation process of SHARPy.
Requirements¶
Operating System Requirements
SHARPy is being developed and tested on the following operating systems:
- CentOS 7 and CentOS 8
- Ubuntu 18.04 LTS
- MacOS Mojave and Catalina
It is also available to the vast majority of operating systems that are supported by Docker, including Windows!
Required Distributions
- Anaconda Python 3.7
- GCC 6.0 or higher (recommended). C++ and Fortran.
Recommended Software
You may find the applications below useful, we recommend you use them but cannot provide any direct support.
- HDFView to read and view
.h5
files. HDF5 is the SHARPy input file format. - Paraview to visualise SHARPy’s output.
GitHub Repository
SHARPy can be installed from the source code available on GitHub or you can get it packed in a Docker container. If what you want is to give it a go and run some static or simple dynamic cases (and are familiar with Docker), we recommend the Docker route. If you want to check the code, modify it and compile the libraries with custom flags, build it from source (recommended).
Building SHARPy from source (release or development builds)¶
SHARPy can be built from source so that you can get the latest release or (stable) development build.
SHARPy depends on two external libraries, xbeam and UVLM. These are included as submodules to SHARPy and therefore once you initialise SHARPy you will also automatically clone the relevant versions of each library.
Set up the folder structure¶
Clone
sharpy
in your desired location, if you agree with the license inlicense.txt
git clone --recursive http://github.com/ImperialCollegeLondon/sharpy
The
--recursive
flag will also initialise and update the submodules SHARPy depends on, xbeam and UVLM.We will now set up the SHARPy environment that will install other required distributions.
Setting up the Python Environment¶
SHARPy uses the Anaconda package manager to provide the necessary Python packages. These are specified in an Anaconda environment that shall be activated prior to compiling the xbeam and UVLM libraries or running any SHARPy cases.
If you do not have it, install the Anaconda Python 3 distribution
Make sure your Python version is at least 3.7:
python --version
Create the conda environment that SHARPy will use. Change
environment_linux.yml
to readenvironment_macos.yml
file if you are installing SHARPy on Mac OS Xcd sharpy/utils conda env create -f environment_linux.yml cd ../..
We also provide a light-weight environment with the minimum required dependencies. If you’d like to use it, create the conda environment using
environment_minimal.yml
.Activate the
sharpy_env
conda environmentconda activate sharpy_env
you need to do this before you compile the
xbeam
anduvlm
libraries, as some dependencies are included in the conda environment.If you would like to use the minimal environment you can run
conda activate sharpy_minimal
.
Quick install¶
The quick install is geared towards getting the release build of SHARPy running as quickly and simply as possible. If you would like to install a develop build or modify the compilation settings of the libraries skip to the next section.
Move into the cloned repository
cd sharpy
Ensure that the SHARPy environment is active in the session. Your terminal prompt line should begin with
(sharpy_env) [usr@host] $
If it is not the case, activate the environment. Otherwise xbeam and UVLM will not compile
conda activate sharpy_env
Create a directory
build
that will be used during CMake’s building process andcd
into it:mkdir build cd build
Prepare UVLM and xbeam for compilation using
gfortran
andg++
in their release builds running. If you’d like to change compilers see the Custom Installation.cmake ..
Compile the libraries
make install -j 4
where the number after the
-j
flag will specify how many cores to use during installation.Finally, load the SHARPy variables
source bin/sharpy_vars.sh
You are ready to run SHARPy. Continue reading the Running SHARPy section.
Custom installation¶
These steps will show you how to compile the xbeam and UVLM libraries such that you can modify the compilation settings to your taste.
Ensure that the SHARPy environment is loaded in your session
conda activate sharpy_env
If you want to use SHARPy’s latest release, skip this step. If you would like to use the latest development work, you will need to checkout the
develop
branch. For more info on how we structure our development and what branches are used for what kind of features have a look at the Contributing page.git checkout -b develop --track origin/develop
This command will check out the
develop
branch and set it to track the remote origin.Run CMake with custom flags:
Choose your compilers for Fortran
FC
and C++CXX
, for instanceFC=gfortran CXX=g++ cmake ..
If you’d like to use the Intel compilers you can set them using:
FC=ifort CXX=icpc cmake ..
To build the libraries in debug mode:
cmake -DCMAKE_BUILD_TYPE=Debug ..
Compile the libraries and parallelise as you prefer
make install -j 4
This concludes the installation! Continue reading the Running SHARPy section.
Using SHARPy from a Docker container¶
Docker containers are similar to lightweight virtual machines. The SHARPy container
distributed through Docker Hub is a CentOS 8
machine with the libraries compiled with gfortran
and g++
and an
Anaconda Python distribution.
Make sure your machine has Docker working. The instructions are here: link.
You might want to run a test in your terminal:
docker pull hello-world
docker run hello-world
If this works, you’re good to go!
First, obtain the SHARPy docker container:
docker pull fonsocarre/sharpy:stable
Now you can run it:
docker run --name sharpy -it fonsocarre/sharpy:stable
You should see a welcome dialog such as:
>>>> docker run -it fonsocarre/sharpy:stable
SHARPy added to PATH from the directory: /sharpy_dir/bin
=======================================================================
Welcome to the Docker image of SHARPy
SHARPy is located in /sharpy_dir/ and the
environment is already set up!
Copyright Imperial College London. Released under BSD 3-Clause license.
=======================================================================
SHARPy>
You are now good to go.
It is important to note that a docker container runs as an independent operating system with no access to your hard drive. If you want to copy your own files, run the container and from another terminal run:
docker cp my_file.txt sharpy:/my_file.txt # copy from host to container
docker cp sharpy:/my_file.txt my_file.txt # copy from container to host
The sharpy:
part is the --name
argument you wrote in the docker run
command.
You can run the test suite once inside the container as:
cd sharpy_dir
python -m unittest
We make available two different releases: stable
and experimental
. The former is the latest SHARPy
release. The latter is our latest development work which will include new features but with higher chances
of encountering some bugs along the way. To obtain the experimental build, follow the instructions
above replacing the stable
tag for experimental
.
Enjoy!
Running SHARPy¶
In order to run SHARPy, you need to load the conda environment and load the SHARPy variables (so your computer knows where SHARPy is). Therefore, before you run any SHARPy case:
Activate the SHARPy conda environment
conda activate sharpy_env
Load the SHARPy variables
source sharpy/bin/sharpy_vars.sh
You are now ready to run SHARPy cases from the terminal.
Automated tests¶
SHARPy uses unittests to verify the integrity of the code.
These tests can be run from the ./sharpy
directory.
python -m unittest
The tests will run and you should see a success message. If you don’t… check the following options:
- Check you are running the latest version. Running the following from the root directory should update to the
latest release version:
git pull
git submodule update --init --recursive
- If the tests don’t run, make sure you have followed correctly the instructions and that you managed to compile xbeam and UVLM.
- If some tests fail, i.e. you get a message after the tests run saying that certain tests did not pass, please open
an issue with the following information:
- Operating system
- Whether you did a Custom/quick install
- UVLM and xbeam compiler of choice
- A log of the tests that failed
The SHARPy Case Structure and input files¶
Setting up a SHARPy case
SHARPy cases are usually structured in the following way:
A
generate_case.py
file: contains the setup of the problem like geometry, flight conditions etc. This script creates the output files that will then be used by SHARPy, namely:- The structural
.fem.h5
file. - The aerodynamic
.aero.h5
file. - Simulation information and settings
.sharpy
file. - The dynamic forces file
.dyn.h5
(when required). - The linear input files
.lininput.h5
(when required). - The ROM settings file
.rom.h5
(when required).
See the chapter on the case files for a detailed description on the contents of each one.Data is exchanged in binary format by means of
.h5
files that make the transmission efficient between the different languages of the required libraries. To view these.h5
files, a viewer like HDF5 is recommended.- The structural
The
h5
files contain data of the FEM, aerodynamics, dynamic conditions. They are later read by SHARPy.The
.sharpy
file contains the settings for SHARPy and is the file that is parsed to SHARPy.
To run a SHARPy case
SHARPy cases are therefore usually ran in the following way:
Create a
generate_case.py
file following the provided templates.Run it to produce the
.h5
files and the.sharpy
files.(sharpy_env) python generate_case.py
Run SHARPy (ensure the environment is activated).
(sharpy_env) sharpy case.sharpy
Running (and modifiying) a test case¶
This command generates the required files for running a static, clamped beam case that is used as part of code verification:
cd ../sharpy python ./tests/xbeam/geradin/generate_geradin.py
Now you should see a success message, and if you check the
./tests/xbeam/geradin/
folder, you should see two new files:
- geradin_cardona.sharpy
- geradin_cardona.fem.h5
Try to open the sharpy
file with a plain text editor and have a quick look. The sharpy
file is
the main settings file. We’ll get deeper into this later.
If you try to open the fem.h5
file, you’ll get an error or something meaningless. This is because the structural data
is stored in HDF5 format, which is compressed binary.
Run it (part 1)
The
sharpy
call is:# Make sure that the sharpy_env conda environment is active sharpy <path to solver file>
Results (part 1)
Since this is a test case, there is no output directly to screen.
We will therefore change this setting first. In the
generate_geradin.py
file, look for theSHARPy
settingwrite_screen
and set it toon
. This will output the progress of the execution to the terminal.We would also like to create a Paraview file to view the beam deformation. Append the post-processor
BeamPlot
to the end of theSHARPy
settingflow
, which is a list. This will run the post-processor and plot the beam in Paraview format with the settings specified in thegenerate_geradin.py
file underconfig['BeamPlot]
.Run (part 2)
Now that we have made these modifications, run again the generation script:
python ./tests/xbeam/geradin/generate_geradin.py
Check the solver file
geradin.sharpy
and look for the settings we just changed. Make sure they read what we wanted.You are now ready to run the case again:
# Make sure that the sharpy_env conda environment is active sharpy <path to solver file>
Post-processing
After a successful execution, you should a long display of information in the terminal as the case is being executed.
The deformed beam will have been written in a
.vtu
file and will be located in theoutput/
folder (or where you specified in the settings) which you can open using Paraview.In the
output
directory you will also note a folder namedWriteVariablesTime
which outputs certain variables as a function of time to a.dat
file. In this case, the beam tip position deflection and rotation is written. Check the values of those files and look for the following result:Pos_def: 4.403530 0.000000 -2.159692 Psi_def: 0.000000 0.672006 0.000000
FYI, the correct solution for this test case by Geradin and Cardona is
Delta R_3 = -2.159 m
andPsi_2 = 0.6720 rad
.
Congratulations, you’ve run your first case. You can now check the Examples section for further cases.
Capabilities¶
This is just the tip of the iceberg, possibilities are nearly endless and once you understand how SHARPy’s modular interface works, you will be capable of running very complex simulations.
Very flexible aircraft nonlinear aeroelasticity¶
The modular design of SHARPy allows to simulate complex aeroelastic cases involving very flexible aircraft. The structural solver supports very complex beam arrangements, while retaining geometrical nonlinearity. The UVLM solver features different wake modelling fidelities while supporting large lifting surface deformations in a native way.
Among the problems studied, a few interesting ones, in no particular order are:
- Catapult take off of a very flexible aircraft analysis [Paper]. In this type of simulations, a PID controller was used in order to enforce displacements and velocities in a number of structural nodes (the clamping points). Then, several take off strategies were studied in order to analyse the influence of the structural stiffness in this kind of procedures. This case is a very good example of the type of problems where nonlinear aeroelasticity is essential.
Catapult Takeoff of Flexible Aircraft
- Flight in full 3D atmospheric boundary layer (to be published). A very flexible aircraft is flown immersed in a turbulent boundary layer obtained from HPC LES simulations. The results are compared against simpler turbulence models such as von Karman and Kaimal. Intermittency and coherence features in the LES field are absent or less remarkable in the synthetic turbulence fields.
HALE Aircraft in a Turbulent Field
- Lateral gust reponse of a realistic very flexible aircraft. For this problem (to be published), a realistic very flexible aircraft (University of Michigan X-HALE) model has been created in SHARPy and validated against their own aeroelastic solver for static and dynamic cases. A set of vertical and lateral gust responses have been simulated.
X-HALE
Wind turbine aeroelasticity¶
SHARPy is suitable to simulate wind turbine aeroelasticity.
On the structural side, it accounts for material anisotropy which is needed to characterize composite blades and for geometrically non-linear deformations observed in current blades due to the increasing length and flexibility. Both rigid and flexible simulations can be performed and the structural modes can be computed accounting for rotational effects (Campbell diagrams). The rotor-tower interaction is modelled through a multibody approach based on the theory of Lagrange multipliers. Finally, he tower base can be fixed or subjected to prescribed linear and angular velocities.
On the aerodynamic side, the use of potential flow theory allows the characterization of flow unsteadiness at a reasonable computational cost. Specifically, steady and dynamic simulations can be performed. The steady simulations are carried out in a non-inertial frame of reference linked to the rotor under uniform steady wind with the assumption of prescribed helicoidal wake. On the other hand, dynamic simulations can be enriched with a wide variety of incoming winds such as shear and yaw. Moreover, the wake shape can be freely computed under no assumptions accounting for self-induction and wake expansion or can be prescribed to an helicoidal shape for computational efficiency.
Wind Turbine
Model Order Reduction¶
Numerical models of physical phenomena require fine discretisations to show convergence and agreement with their real counterparts, and, in the case of SHARPy’s aeroelastic systems, hundreds of thousands of states are not an uncommon encounter. However, modern hardware or the use of these models for other applications such as controller synthesis may limit their size, and we must turn to model order reduction techniques to achieve lower dimensional representations that can then be used.
SHARPy offers several model order reduction methods to reduce the initially large system to a lower dimension, attending to the user’s requirements of numerical efficiency or global error bound.
Krylov Methods for Model Order Reduction - Moment Matching¶
Model reduction by moment matching can be seen as approximating a transfer function through a power series expansion about a user defined point in the complex plane. The reduction by projection retains the moments between the full and reduced systems as long as the projection matrices span certain Krylov subspaces dependant on the expansion point and the system’s matrices. This can be taken advantage of, in particular for aeroelastic applications where the interest resides in the low frequency behaviour of the system, the ROM can be expanded about these low frequency points discarding accuracy higher up the frequency spectrum.
Example 1 - Aerodynamics - Frequency response of a high AR flat plate subject to a sinusoidal gust¶
The objective is to compare SHARPy’s solution of a very high aspect ratio flat plate subject to a sinusoidal gust to the closed form solution obtained by Sears (1944 - Ref). SHARPy’s inherent 3D nature makes comparing results to the 2D solution require very high aspect ratio wings with fine discretisations, resulting in very large state space models. In this case, we would like to utilise a Krylov ROM to approximate the low frequency behaviour and perform a frequency response analysis on the reduced system, since it would represent too much computational cost if it were performed on the full system.
The full order model was reduced utilising Krylov methods, in particular the Arnoldi iteration, with an expansion about zero frequency to produce the following result.
Sears Gust Bode Plot
As it can be seen from the image above, the ROM approximates well the low frequency, quasi-steady state and loses accuracy as the frequency is increased, just as intended. Still, perfect matching is never achieved even at the expansion frequency given the 3D nature of the wing compared to the 2D analytical solution.
Example 2 - Aeroelastics - Flutter analysis of a Goland wing with modal projection¶
The Goland wing flutter example is presented next. The aerodynamic surface is finely discretised for the UVLM solution, resulting in not only a large state space but also in large input/output dimensionality. Therefore, to reduce the number of inputs and outputs, the UVLM is projected onto the structural mode shapes, the first four in this particular case. The resulting multi input multi output system (mode shapes -> UVLM -> modal forces) was subsequently reduced using Krylov methods aimed at MIMO systems which use variations of the block Arnoldi iteration. Again, the expansion frequency selected was the zero frequency. As a sample, the transfer function from two inputs to two outputs is shown to illustrate the performance of the reduced model against the full order UVLM.
Goland Reduced Order Model Transfer Functions
The reduced aerodynamic model projected onto the modal shapes was then coupled to the linearised beam model, and the stability analysed against a change in velocity. Note that the UVLM model and its ROM are actually scaled to be independent on the freestream velocity, hence only one UVLM and ROM need to be computed. The structural model needs to be updated at each test velocity but its a lot less costly in computational terms. The resulting stability of the aeroelastic system is plotted on the Argand diagram below with changing freestream velocity.
Goland Flutter
Publications¶
SHARPy has been used in many technical papers that have been both published in Journals and presented at conferences. Here we present a list of past papers which have used SHARPy for research purposes:
2020¶
- Del Carre, A., Deskos, G., & Palacios, R. (2020). Realistic turbulence effects in low altitude dynamics of very flexible aircraft. In AIAA SciTech Forum (pp. 1–18). https://doi.org/10.2514/6.2020-1187
- Artola, M., Goizueta, N., Wynn, A., & Palacios, R. (2020). Modal-Based Nonlinear Estimation and Control for Highly Flexible Aeroelastic Systems. In AIAA SciTech Forum (pp. 1–23). https://doi.org/10.2514/6.2020-1192
- Muñoz-Simón, A., Wynn, A., & Palacios, R. (2020). Unsteady and three-dimensional aerodynamic effects on wind turbine rotor loads. In AIAA SciTech Forum. https://doi.org/10.2514/6.2020-0991
2019¶
- Carre, A., Muñoz-Simón, A., Goizueta, N., & Palacios, R. (2019). SHARPy : A dynamic aeroelastic simulation toolbox for very flexible aircraft and wind turbines. Journal of Open Source Software, 4(44), 1885. https://doi.org/10.21105/joss.01885
- Del Carre, A., Teixeira, P. C., Palacios, R., & Cesnik, C. E. S. (2019). Nonlinear Response of a Very Flexible Aircraft Under Lateral Gust. In International Forum on Aeroelasticity and Structural Dynamics.
- Del Carre, A., & Palacios, R. (2019). Efficient Time-Domain Simulations in Nonlinear Aeroelasticity. In AIAA Scitech Forum (pp. 1–20). https://doi.org/10.2514/6.2019-2038
- Maraniello, S., & Palacios, R. (2019). State-Space Realizations and Internal Balancing in Potential-Flow Aerodynamics with Arbitrary Kinematics. AIAA Journal, 57(6), 1–14. https://doi.org/10.2514/1.J058153
Examples¶
A set of SHARPy examples created with Jupyter Notebooks is provided for users to interact and modify cases running on SHARPy.
Flutter Analysis of a Goland Wing using the SHARPy Linear Solver¶
This is an example using SHARPy to find the flutter speed of a Goland wing by:
- Calculating aerodynamic forces and deflections using a nonlinear solver
- Linearising about this reference condition
- Creating a reduced order model of the linearised aerodynamics
- Evaluate the stability of the linearised aeroelastic system at different velocities
References¶
Maraniello, S., & Palacios, R. (2019). State-Space Realizations and Internal Balancing in Potential-Flow Aerodynamics with Arbitrary Kinematics. AIAA Journal, 57(6), 1–14. https://doi.org/10.2514/1.J058153
Required Packages¶
[1]:
import numpy as np
import matplotlib.pyplot as plt
import os
import sys
import cases.templates.flying_wings as wings # See this package for the Goland wing structural and aerodynamic definition
import sharpy.sharpy_main # used to run SHARPy from Jupyter
Problem Set-up¶
The UVLM is assembled in normalised time at a velocity of \(1 m/s\). The only matrices that need updating then with free stream velocity are the structural matrices, which is significantly cheaper to do than to update the UVLM.
[2]:
u_inf = 1.
alpha_deg = 0.
rho = 1.02
num_modes = 4
Note: To achieve convergence of the flutter results with the ones found in the literature, a significant discretisation may be required. If you are running this notebook for the first time, set M = 4
initially to verify that your system can perform!
[3]:
M = 16
N = 32
M_star_fact = 10
A moment-matching (Krylov subspace) model order reduction technique is employed. This ROM method offers the ability to interpolate the transfer functions at a desired point in the complex plane. See the ROM documentation pages for more info.
Note: this ROM method matches the transfer function but does not guarantee stability. Therefore the resulting system may be unstable. These unstable modes may appear far in the right hand plane but will not affect the flutter speed calculations.
[4]:
c_ref = 1.8288 # Goland wing reference chord. Used for frequency normalisation
rom_settings = dict()
rom_settings['algorithm'] = 'mimo_rational_arnoldi' # reduction algorithm
rom_settings['r'] = 6 # Krylov subspace order
frequency_continuous_k = np.array([0.]) # Interpolation point in the complex plane with reduced frequency units
frequency_continuous_w = 2 * u_inf * frequency_continuous_k / c_ref
rom_settings['frequency'] = frequency_continuous_w
[5]:
case_name = 'goland_cs'
case_nlin_info = 'M%dN%dMs%d_nmodes%d' % (M, N, M_star_fact, num_modes)
case_rom_info = 'rom_MIMORA_r%d_sig%04d_%04dj' % (rom_settings['r'], frequency_continuous_k[-1].real * 100,
frequency_continuous_k[-1].imag * 100)
case_name += case_nlin_info + case_rom_info
route_test_dir = os.path.abspath('')
print('The case to run will be: %s' % case_name)
print('Case files will be saved in ./cases/%s' %case_name)
print('Output files will be saved in ./output/%s/' %case_name)
The case to run will be: goland_csM16N32Ms10_nmodes4rom_MIMORA_r6_sig0000_0000j
Case files will be saved in ./cases/goland_csM16N32Ms10_nmodes4rom_MIMORA_r6_sig0000_0000j
Output files will be saved in ./output/goland_csM16N32Ms10_nmodes4rom_MIMORA_r6_sig0000_0000j/
Simulation Set-Up¶
ws
is an instance of a Goland wing with a control surface. Reference the template file cases.templates.flying_wings.GolandControlSurface
for more info on the geometrical, structural and aerodynamic definition of the Goland wing here used.
[6]:
ws = wings.GolandControlSurface(M=M,
N=N,
Mstar_fact=M_star_fact,
u_inf=u_inf,
alpha=alpha_deg,
cs_deflection=[0, 0],
rho=rho,
sweep=0,
physical_time=2,
n_surfaces=2,
route=route_test_dir + '/cases',
case_name=case_name)
ws.clean_test_files()
ws.update_derived_params()
ws.set_default_config_dict()
ws.generate_aero_file()
ws.generate_fem_file()
Surface0
Surface1
The settings for each of the solvers are now set. For a detailed description on them please reference their respective documentation pages
SHARPy Settings¶
The most important setting is the flow
list. It tells SHARPy which solvers to run and in which order.
[7]:
ws.config['SHARPy'] = {
'flow':
['BeamLoader', 'AerogridLoader',
'StaticCoupled',
'AerogridPlot',
'BeamPlot',
'Modal',
'LinearAssembler',
'FrequencyResponse',
'AsymptoticStability',
],
'case': ws.case_name, 'route': ws.route,
'write_screen': 'on', 'write_log': 'on',
'log_folder': route_test_dir + '/output/' + ws.case_name + '/',
'log_file': ws.case_name + '.log'}
Beam Loader Settings¶
[8]:
ws.config['BeamLoader'] = {
'unsteady': 'off',
'orientation': ws.quat}
Aerogrid Loader Settings¶
[9]:
ws.config['AerogridLoader'] = {
'unsteady': 'off',
'aligned_grid': 'on',
'mstar': ws.Mstar_fact * ws.M,
'freestream_dir': ws.u_inf_direction
}
Static Coupled Solver¶
[10]:
ws.config['StaticCoupled'] = {
'print_info': 'on',
'max_iter': 200,
'n_load_steps': 1,
'tolerance': 1e-10,
'relaxation_factor': 0.,
'aero_solver': 'StaticUvlm',
'aero_solver_settings': {
'rho': ws.rho,
'print_info': 'off',
'horseshoe': 'off',
'num_cores': 4,
'n_rollup': 0,
'rollup_dt': ws.dt,
'rollup_aic_refresh': 1,
'rollup_tolerance': 1e-4,
'velocity_field_generator': 'SteadyVelocityField',
'velocity_field_input': {
'u_inf': ws.u_inf,
'u_inf_direction': ws.u_inf_direction}},
'structural_solver': 'NonLinearStatic',
'structural_solver_settings': {'print_info': 'off',
'max_iterations': 150,
'num_load_steps': 4,
'delta_curved': 1e-1,
'min_delta': 1e-10,
'gravity_on': 'on',
'gravity': 9.81}}
AerogridPlot Settings¶
[11]:
ws.config['AerogridPlot'] = {'folder': route_test_dir + '/output/',
'include_rbm': 'off',
'include_applied_forces': 'on',
'minus_m_star': 0}
BeamPlot Settings¶
[12]:
ws.config['BeamPlot'] = {'folder': route_test_dir + '/output/',
'include_rbm': 'off',
'include_applied_forces': 'on'}
Modal Solver Settings¶
[13]:
ws.config['Modal'] = {'folder': route_test_dir + '/output/',
'NumLambda': 20,
'rigid_body_modes': 'off',
'print_matrices': 'on',
'keep_linear_matrices': 'on',
'write_dat': 'off',
'rigid_modes_cg': 'off',
'continuous_eigenvalues': 'off',
'dt': 0,
'plot_eigenvalues': False,
'max_rotation_deg': 15.,
'max_displacement': 0.15,
'write_modes_vtk': True,
'use_undamped_modes': True}
Linear System Assembly Settings¶
[14]:
ws.config['LinearAssembler'] = {'linear_system': 'LinearAeroelastic',
'linear_system_settings': {
'beam_settings': {'modal_projection': 'on',
'inout_coords': 'modes',
'discrete_time': 'on',
'newmark_damp': 0.5e-4,
'discr_method': 'newmark',
'dt': ws.dt,
'proj_modes': 'undamped',
'use_euler': 'off',
'num_modes': num_modes,
'print_info': 'on',
'gravity': 'on',
'remove_sym_modes': 'on',
'remove_dofs': []},
'aero_settings': {'dt': ws.dt,
'ScalingDict': {'length': 0.5 * ws.c_ref,
'speed': u_inf,
'density': rho},
'integr_order': 2,
'density': ws.rho,
'remove_predictor': 'on',
'use_sparse': 'on',
'rigid_body_motion': 'off',
'use_euler': 'off',
'remove_inputs': ['u_gust'],
'rom_method': ['Krylov'],
'rom_method_settings': {'Krylov': rom_settings}},
'rigid_body_motion': False}}
Asymptotic Stability Analysis Settings¶
[15]:
ws.config['AsymptoticStability'] = {'print_info': True,
'folder': route_test_dir + '/output/',
'velocity_analysis': [100, 180, 81],
'modes_to_plot': []}
[16]:
ws.config.write()
Run SHARPy¶
[17]:
sharpy.sharpy_main.main(['', ws.route + ws.case_name + '.sharpy'])
--------------------------------------------------------------------------------
###### ## ## ### ######## ######## ## ##
## ## ## ## ## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ## ## ####
###### ######### ## ## ######## ######## ##
## ## ## ######### ## ## ## ##
## ## ## ## ## ## ## ## ## ##
###### ## ## ## ## ## ## ## ##
--------------------------------------------------------------------------------
Aeroelastics Lab, Aeronautics Department.
Copyright (c), Imperial College London.
All rights reserved.
License available at https://github.com/imperialcollegelondon/sharpy
Running SHARPy from /home/ng213/code/sharpy/docs/source/content/example_notebooks
SHARPy being run is in /home/ng213/code/sharpy
The branch being run is dev_examples
The version and commit hash are: v0.1-1539-gd3ef7dd-d3ef7dd
The available solvers on this session are:
PreSharpy
_BaseStructural
AerogridLoader
BeamLoader
DynamicCoupled
DynamicUVLM
LinDynamicSim
LinearAssembler
Modal
NoAero
NonLinearDynamic
NonLinearDynamicCoupledStep
NonLinearDynamicMultibody
NonLinearDynamicPrescribedStep
NonLinearStatic
NonLinearStaticMultibody
PrescribedUvlm
RigidDynamicPrescribedStep
SHWUvlm
StaticCoupled
StaticCoupledRBM
StaticTrim
StaticUvlm
StepLinearUVLM
StepUvlm
Trim
Cleanup
PickleData
SaveData
CreateSnapshot
PlotFlowField
StabilityDerivatives
AeroForcesCalculator
WriteVariablesTime
AerogridPlot
LiftDistribution
StallCheck
FrequencyResponse
AsymptoticStability
BeamPlot
BeamLoads
Generating an instance of BeamLoader
Generating an instance of AerogridLoader
Variable control_surface_deflection has no assigned value in the settings file.
will default to the value: []
Variable control_surface_deflection_generator_settings has no assigned value in the settings file.
will default to the value: []
The aerodynamic grid contains 2 surfaces
Surface 0, M=16, N=16
Wake 0, M=160, N=16
Surface 1, M=16, N=16
Wake 1, M=160, N=16
In total: 512 bound panels
In total: 5120 wake panels
Total number of panels = 5632
Generating an instance of StaticCoupled
Generating an instance of NonLinearStatic
Variable newmark_damp has no assigned value in the settings file.
will default to the value: c_double(0.0001)
Variable relaxation_factor has no assigned value in the settings file.
will default to the value: c_double(0.3)
Variable dt has no assigned value in the settings file.
will default to the value: c_double(0.01)
Variable num_steps has no assigned value in the settings file.
will default to the value: c_int(500)
Variable initial_position has no assigned value in the settings file.
will default to the value: [0. 0. 0.]
Generating an instance of StaticUvlm
Variable iterative_solver has no assigned value in the settings file.
will default to the value: c_bool(False)
Variable iterative_tol has no assigned value in the settings file.
will default to the value: c_double(0.0001)
Variable iterative_precond has no assigned value in the settings file.
will default to the value: c_bool(False)
|=====|=====|============|==========|==========|==========|==========|==========|==========|
|iter |step | log10(res) | Fx | Fy | Fz | Mx | My | Mz |
|=====|=====|============|==========|==========|==========|==========|==========|==========|
| 0 | 0 | 0.00000 | -0.0000 | 0.0000 |-4271.0417| 0.0000 | 781.0842 | -0.0000 |
| 1 | 0 | -11.88931 | 0.0000 | -0.0000 |-4271.0039| 0.0000 | 781.0906 | -0.0000 |
Generating an instance of AerogridPlot
Variable include_forward_motion has no assigned value in the settings file.
will default to the value: c_bool(False)
Variable include_unsteady_applied_forces has no assigned value in the settings file.
will default to the value: c_bool(False)
Variable name_prefix has no assigned value in the settings file.
will default to the value:
Variable u_inf has no assigned value in the settings file.
will default to the value: c_double(0.0)
Variable dt has no assigned value in the settings file.
will default to the value: c_double(0.0)
Variable include_velocities has no assigned value in the settings file.
will default to the value: c_bool(False)
Variable num_cores has no assigned value in the settings file.
will default to the value: c_int(1)
...Finished
Generating an instance of BeamPlot
Variable include_FoR has no assigned value in the settings file.
will default to the value: c_bool(False)
Variable include_applied_moments has no assigned value in the settings file.
will default to the value: c_bool(True)
Variable name_prefix has no assigned value in the settings file.
will default to the value:
Variable output_rbm has no assigned value in the settings file.
will default to the value: c_bool(True)
...Finished
Generating an instance of Modal
Variable print_info has no assigned value in the settings file.
will default to the value: c_bool(True)
Variable delta_curved has no assigned value in the settings file.
will default to the value: c_double(0.01)
Variable use_custom_timestep has no assigned value in the settings file.
will default to the value: c_int(-1)
Structural eigenvalues
|==============|==============|==============|==============|==============|==============|==============|
| mode | eval_real | eval_imag | freq_n (Hz) | freq_d (Hz) | damping | period (s) |
|==============|==============|==============|==============|==============|==============|==============|
| 0 | 0.000000 | 48.067396 | 7.650164 | 7.650164 | -0.000000 | 0.130716 |
| 1 | 0.000000 | 48.067398 | 7.650164 | 7.650164 | -0.000000 | 0.130716 |
| 2 | 0.000000 | 95.685736 | 15.228858 | 15.228858 | -0.000000 | 0.065665 |
| 3 | 0.000000 | 95.685754 | 15.228861 | 15.228861 | -0.000000 | 0.065665 |
| 4 | 0.000000 | 243.144471 | 38.697644 | 38.697644 | -0.000000 | 0.025841 |
| 5 | 0.000000 | 243.144477 | 38.697645 | 38.697645 | -0.000000 | 0.025841 |
| 6 | 0.000000 | 343.801136 | 54.717650 | 54.717650 | -0.000000 | 0.018276 |
| 7 | 0.000000 | 343.801137 | 54.717650 | 54.717650 | -0.000000 | 0.018276 |
| 8 | 0.000000 | 443.324608 | 70.557303 | 70.557303 | -0.000000 | 0.014173 |
| 9 | 0.000000 | 443.324619 | 70.557304 | 70.557304 | -0.000000 | 0.014173 |
| 10 | 0.000000 | 461.992869 | 73.528449 | 73.528449 | -0.000000 | 0.013600 |
| 11 | 0.000000 | 461.992869 | 73.528449 | 73.528449 | -0.000000 | 0.013600 |
| 12 | 0.000000 | 601.126871 | 95.672313 | 95.672313 | -0.000000 | 0.010452 |
| 13 | 0.000000 | 601.126873 | 95.672313 | 95.672313 | -0.000000 | 0.010452 |
| 14 | 0.000000 | 782.997645 | 124.617946 | 124.617946 | -0.000000 | 0.008025 |
| 15 | 0.000000 | 782.997649 | 124.617946 | 124.617946 | -0.000000 | 0.008025 |
| 16 | 0.000000 | 917.191257 | 145.975522 | 145.975522 | -0.000000 | 0.006850 |
| 17 | 0.000000 | 917.191259 | 145.975523 | 145.975523 | -0.000000 | 0.006850 |
| 18 | 0.000000 | 975.005694 | 155.176976 | 155.176976 | -0.000000 | 0.006444 |
| 19 | 0.000000 | 975.005699 | 155.176977 | 155.176977 | -0.000000 | 0.006444 |
Generating an instance of LinearAssembler
Variable linearisation_tstep has no assigned value in the settings file.
will default to the value: c_int(-1)
Generating an instance of LinearAeroelastic
Variable uvlm_filename has no assigned value in the settings file.
will default to the value:
Variable track_body has no assigned value in the settings file.
will default to the value: c_bool(True)
Variable use_euler has no assigned value in the settings file.
will default to the value: c_bool(False)
Generating an instance of LinearUVLM
Variable gust_assembler has no assigned value in the settings file.
will default to the value:
Initialising Static linear UVLM solver class...
/home/ng213/code/sharpy/sharpy/solvers/linearassembler.py:79: UserWarning: LinearAssembler solver under development
warnings.warn('LinearAssembler solver under development')
...done in 1.41 sec
Generating an instance of Krylov
Variable print_info has no assigned value in the settings file.
will default to the value: c_bool(True)
Variable tangent_input_file has no assigned value in the settings file.
will default to the value:
Variable restart_arnoldi has no assigned value in the settings file.
will default to the value: c_bool(False)
Initialising Krylov Model Order Reduction
State-space realisation of UVLM equations started...
/home/ng213/code/sharpy/sharpy/linear/src/assembly.py:1256: SparseEfficiencyWarning: Changing the sparsity structure of a csc_matrix is expensive. lil_matrix is more efficient.
C[iivec, N * (M - 1) + iivec] = 1.0
/home/ng213/code/sharpy/sharpy/linear/src/assembly.py:1259: SparseEfficiencyWarning: Changing the sparsity structure of a csc_matrix is expensive. lil_matrix is more efficient.
C_star[mm * N + iivec, (mm - 1) * N + iivec] = 1.0
state-space model produced in form:
h_{n+1} = A h_{n} + B u_{n}
with:
x_n = h_n + Bp u_n
...done in 19.06 sec
Scaling UVLM system with reference time 0.914400s
Non-dimensional time step set (0.125000)
System scaled in 31.559722s
Generating an instance of LinearBeam
Warning, projecting system with damping onto undamped modes
Linearising gravity terms...
M = 7.26 kg
X_CG A -> 0.00 -0.00 -0.00
Node 1 -> B -0.000 -0.116 0.000
-> A 0.116 0.381 -0.000
-> G 0.116 0.381 -0.000
Node mass:
Matrix: 14.5125
Node 2 -> B -0.000 -0.116 0.000
-> A 0.116 0.762 -0.000
-> G 0.116 0.762 -0.000
Node mass:
Matrix: 7.2563
Node 3 -> B -0.000 -0.116 0.000
-> A 0.116 1.143 -0.000
-> G 0.116 1.143 -0.000
Node mass:
Matrix: 14.5125
Node 4 -> B -0.000 -0.116 0.000
-> A 0.116 1.524 -0.001
-> G 0.116 1.524 -0.001
Node mass:
Matrix: 7.2563
Node 5 -> B -0.000 -0.116 0.000
-> A 0.116 1.905 -0.001
-> G 0.116 1.905 -0.001
Node mass:
Matrix: 14.5125
Node 6 -> B -0.000 -0.116 0.000
-> A 0.116 2.286 -0.001
-> G 0.116 2.286 -0.001
Node mass:
Matrix: 7.2563
Node 7 -> B -0.000 -0.116 0.000
-> A 0.116 2.667 -0.002
-> G 0.116 2.667 -0.002
Node mass:
Matrix: 14.5125
Node 8 -> B -0.000 -0.116 0.000
-> A 0.116 3.048 -0.002
-> G 0.116 3.048 -0.002
Node mass:
Matrix: 7.2563
Node 9 -> B -0.000 -0.116 0.000
-> A 0.116 3.429 -0.003
-> G 0.116 3.429 -0.003
Node mass:
Matrix: 14.5125
Node 10 -> B -0.000 -0.116 0.000
-> A 0.116 3.810 -0.003
-> G 0.116 3.810 -0.003
Node mass:
Matrix: 7.2563
Node 11 -> B -0.000 -0.116 0.000
-> A 0.116 4.191 -0.004
-> G 0.116 4.191 -0.004
Node mass:
Matrix: 14.5125
Node 12 -> B -0.000 -0.116 0.000
-> A 0.116 4.572 -0.004
-> G 0.116 4.572 -0.004
Node mass:
Matrix: 7.2563
Node 13 -> B -0.000 -0.116 0.000
-> A 0.116 4.953 -0.005
-> G 0.116 4.953 -0.005
Node mass:
Matrix: 14.5125
Node 14 -> B -0.000 -0.116 0.000
-> A 0.116 5.334 -0.005
-> G 0.116 5.334 -0.005
Node mass:
Matrix: 7.2563
Node 15 -> B -0.000 -0.116 0.000
-> A 0.116 5.715 -0.006
-> G 0.116 5.715 -0.006
Node mass:
Matrix: 14.5125
Node 16 -> B -0.000 -0.116 0.000
-> A 0.116 6.096 -0.006
-> G 0.116 6.096 -0.006
Node mass:
Matrix: 3.6281
Node 17 -> B -0.000 -0.116 -0.000
-> A 0.116 -6.096 -0.006
-> G 0.116 -6.096 -0.006
Node mass:
Matrix: 3.6281
Node 18 -> B -0.000 -0.116 -0.000
-> A 0.116 -5.715 -0.006
-> G 0.116 -5.715 -0.006
Node mass:
Matrix: 14.5125
Node 19 -> B -0.000 -0.116 -0.000
-> A 0.116 -5.334 -0.005
-> G 0.116 -5.334 -0.005
Node mass:
Matrix: 7.2563
Node 20 -> B -0.000 -0.116 -0.000
-> A 0.116 -4.953 -0.005
-> G 0.116 -4.953 -0.005
Node mass:
Matrix: 14.5125
Node 21 -> B -0.000 -0.116 -0.000
-> A 0.116 -4.572 -0.004
-> G 0.116 -4.572 -0.004
Node mass:
Matrix: 7.2563
Node 22 -> B -0.000 -0.116 -0.000
-> A 0.116 -4.191 -0.004
-> G 0.116 -4.191 -0.004
Node mass:
Matrix: 14.5125
Node 23 -> B -0.000 -0.116 -0.000
-> A 0.116 -3.810 -0.003
-> G 0.116 -3.810 -0.003
Node mass:
Matrix: 7.2563
Node 24 -> B -0.000 -0.116 -0.000
-> A 0.116 -3.429 -0.003
-> G 0.116 -3.429 -0.003
Node mass:
Matrix: 14.5125
Node 25 -> B -0.000 -0.116 -0.000
-> A 0.116 -3.048 -0.002
-> G 0.116 -3.048 -0.002
Node mass:
Matrix: 7.2563
Node 26 -> B -0.000 -0.116 -0.000
-> A 0.116 -2.667 -0.002
-> G 0.116 -2.667 -0.002
Node mass:
Matrix: 14.5125
Node 27 -> B -0.000 -0.116 -0.000
-> A 0.116 -2.286 -0.002
-> G 0.116 -2.286 -0.002
Node mass:
Matrix: 7.2563
Node 28 -> B -0.000 -0.116 -0.000
-> A 0.116 -1.905 -0.001
-> G 0.116 -1.905 -0.001
Node mass:
Matrix: 14.5125
Node 29 -> B -0.000 -0.116 -0.000
-> A 0.116 -1.524 -0.001
-> G 0.116 -1.524 -0.001
Node mass:
Matrix: 7.2563
Node 30 -> B -0.000 -0.116 -0.000
-> A 0.116 -1.143 -0.000
-> G 0.116 -1.143 -0.000
Node mass:
Matrix: 14.5125
Node 31 -> B -0.000 -0.116 -0.000
-> A 0.116 -0.762 -0.000
-> G 0.116 -0.762 -0.000
Node mass:
Matrix: 7.2563
Node 32 -> B -0.000 -0.116 -0.000
-> A 0.116 -0.381 -0.000
-> G 0.116 -0.381 -0.000
Node mass:
Matrix: 14.5125
Updated the beam C, modal C and K matrices with the terms from the
gravity linearisation
Scaling beam according to reduced time...
Setting the beam time step to (0.1250)
Updating C and K matrices and natural frequencies with new normalised time...
Model Order Reduction in progress...
Moment Matching Krylov Model Reduction
Construction Algorithm:
mimo_rational_arnoldi
Interpolation points:
Krylov order:
r = 6
Unstable ROM - 2 Eigenvalues with |r| > 1
mu = -3.202177 + 0.000000j
mu = 1.062204 + 0.000000j
System reduced from order 6656 to
n = 36 states
...Completed Model Order Reduction in 2.51 s
Aeroelastic system assembled:
Aerodynamic states: 36
Structural states: 4
Total states: 40
Inputs: 8
Outputs: 6
Generating an instance of FrequencyResponse
Variable load_fom has no assigned value in the settings file.
will default to the value:
Variable num_freqs has no assigned value in the settings file.
will default to the value: c_int(50)
Computing frequency response...
Full order system:
/home/ng213/anaconda3/envs/sharpy_env/lib/python3.7/site-packages/scipy/sparse/compressed.py:708: SparseEfficiencyWarning: Changing the sparsity structure of a csc_matrix is expensive. lil_matrix is more efficient.
self[i, j] = values
Computed the frequency response of the full order system in 26.673870 s
Reduced order system:
Computed the frequency response of the reduced order system in 0.002653 s
Computing error in frequency response
m = 0, p = 0
Error Magnitude -real-: log10(error) = -4.85 (-0.00 pct) at 1.09 rad/s
Error Magnitude -imag-: log10(error) = -4.80 (-0.00 pct) at 1.07 rad/s
m = 0, p = 1
Error Magnitude -real-: log10(error) = -4.93 (-0.00 pct) at 1.09 rad/s
Error Magnitude -imag-: log10(error) = -5.17 (0.00 pct) at 1.09 rad/s
m = 1, p = 0
Error Magnitude -real-: log10(error) = -3.98 (0.00 pct) at 1.09 rad/s
Error Magnitude -imag-: log10(error) = -3.94 (0.00 pct) at 1.07 rad/s
m = 1, p = 1
Error Magnitude -real-: log10(error) = -4.06 (0.00 pct) at 1.09 rad/s
Error Magnitude -imag-: log10(error) = -4.30 (-0.00 pct) at 1.09 rad/s
m = 2, p = 0
Error Magnitude -real-: log10(error) = -4.28 (-0.00 pct) at 1.09 rad/s
Error Magnitude -imag-: log10(error) = -4.23 (-0.00 pct) at 1.07 rad/s
m = 2, p = 1
Error Magnitude -real-: log10(error) = -4.35 (-0.00 pct) at 1.09 rad/s
Error Magnitude -imag-: log10(error) = -4.61 (0.00 pct) at 1.09 rad/s
m = 3, p = 0
Error Magnitude -real-: log10(error) = -4.16 (0.00 pct) at 1.09 rad/s
Error Magnitude -imag-: log10(error) = -4.12 (0.01 pct) at 1.07 rad/s
m = 3, p = 1
Error Magnitude -real-: log10(error) = -4.24 (-0.00 pct) at 1.09 rad/s
Error Magnitude -imag-: log10(error) = -4.48 (-0.00 pct) at 1.09 rad/s
m = 4, p = 0
Error Magnitude -real-: log10(error) = -3.67 (0.00 pct) at 1.09 rad/s
Error Magnitude -imag-: log10(error) = -3.59 (0.00 pct) at 1.07 rad/s
m = 4, p = 1
Error Magnitude -real-: log10(error) = -3.71 (0.00 pct) at 1.09 rad/s
Error Magnitude -imag-: log10(error) = -4.00 (-0.00 pct) at 0.98 rad/s
m = 5, p = 0
Error Magnitude -real-: log10(error) = -3.83 (0.00 pct) at 1.09 rad/s
Error Magnitude -imag-: log10(error) = -3.75 (0.00 pct) at 1.07 rad/s
m = 5, p = 1
Error Magnitude -real-: log10(error) = -3.87 (-0.00 pct) at 1.09 rad/s
Error Magnitude -imag-: log10(error) = -4.16 (-0.00 pct) at 0.98 rad/s
Creating Quick plots of the frequency response
Plots saved to ./output//goland_csM16N32Ms10_nmodes4rom_MIMORA_r6_sig0000_0000j/frequencyresponse/
Generating an instance of AsymptoticStability
Variable reference_velocity has no assigned value in the settings file.
will default to the value: c_double(1.0)
Variable frequency_cutoff has no assigned value in the settings file.
will default to the value: c_double(0.0)
Variable export_eigenvalues has no assigned value in the settings file.
will default to the value: c_bool(False)
Variable display_root_locus has no assigned value in the settings file.
will default to the value: c_bool(False)
Variable num_evals has no assigned value in the settings file.
will default to the value: c_int(200)
Variable postprocessors has no assigned value in the settings file.
will default to the value: []
Variable postprocessors_settings has no assigned value in the settings file.
will default to the value: {}
Dynamical System Eigenvalues
|==============|==============|==============|==============|==============|==============|==============|
| mode | eval_real | eval_imag | freq_n (Hz) | freq_d (Hz) | damping | period (s) |
|==============|==============|==============|==============|==============|==============|==============|
| 0 | 10.182550 | -27.485500 | 4.664997 | 4.374453 | -0.347396 | 0.228600 |
| 1 | 0.527963 | -0.000000 | 0.084028 | 0.000000 | 1.000000 | inf |
| 2 | -0.021585 | -24.315459 | 3.869927 | 3.869926 | 0.000888 | 0.258403 |
| 3 | -0.021585 | 24.315459 | 3.869927 | 3.869926 | 0.000888 | 0.258403 |
| 4 | -0.105973 | -21.319801 | 3.393194 | 3.393152 | 0.004971 | 0.294711 |
| 5 | -0.105973 | 21.319801 | 3.393194 | 3.393152 | 0.004971 | 0.294711 |
| 6 | -0.253786 | 0.000000 | 0.040391 | 0.000000 | 1.000000 | inf |
| 7 | -0.372465 | -0.355725 | 0.081972 | 0.056615 | 0.723172 | 17.663059 |
| 8 | -0.372465 | 0.355725 | 0.081972 | 0.056615 | 0.723172 | 17.663059 |
| 9 | -0.405420 | 0.870139 | 0.152781 | 0.138487 | 0.422334 | 7.220896 |
| 10 | -0.405420 | -0.870139 | 0.152781 | 0.138487 | 0.422334 | 7.220896 |
| 11 | -0.414445 | 0.000000 | 0.065961 | 0.000000 | 1.000000 | inf |
| 12 | -0.433769 | -0.705316 | 0.131784 | 0.112255 | 0.523860 | 8.908329 |
| 13 | -0.433769 | 0.705316 | 0.131784 | 0.112255 | 0.523860 | 8.908329 |
| 14 | -0.584818 | 0.000000 | 0.093077 | 0.000000 | 1.000000 | inf |
| 15 | -0.652779 | -0.945278 | 0.182832 | 0.150446 | 0.568242 | 6.646916 |
| 16 | -0.652779 | 0.945278 | 0.182832 | 0.150446 | 0.568242 | 6.646916 |
| 17 | -0.662253 | -0.344794 | 0.118830 | 0.054876 | 0.886985 | 18.223008 |
| 18 | -0.662253 | 0.344794 | 0.118830 | 0.054876 | 0.886985 | 18.223008 |
| 19 | -0.689479 | -0.611472 | 0.146671 | 0.097319 | 0.748162 | 10.275501 |
| 20 | -0.689479 | 0.611472 | 0.146671 | 0.097319 | 0.748162 | 10.275501 |
| 21 | -0.733120 | -0.423757 | 0.134769 | 0.067443 | 0.865775 | 14.827328 |
| 22 | -0.733120 | 0.423757 | 0.134769 | 0.067443 | 0.865775 | 14.827328 |
| 23 | -0.755676 | 0.287185 | 0.128662 | 0.045707 | 0.934772 | 21.878536 |
| 24 | -0.755676 | -0.287185 | 0.128662 | 0.045707 | 0.934772 | 21.878536 |
| 25 | -0.765019 | 0.043949 | 0.121957 | 0.006995 | 0.998354 | 142.964071 |
| 26 | -0.765019 | -0.043949 | 0.121957 | 0.006995 | 0.998354 | 142.964071 |
| 27 | -0.768680 | 0.696822 | 0.165125 | 0.110903 | 0.740889 | 9.016920 |
| 28 | -0.768680 | -0.696822 | 0.165125 | 0.110903 | 0.740889 | 9.016920 |
| 29 | -0.847888 | -0.177523 | 0.137872 | 0.028254 | 0.978777 | 35.393580 |
| 30 | -0.847888 | 0.177523 | 0.137872 | 0.028254 | 0.978777 | 35.393580 |
| 31 | -2.191875 | -0.000000 | 0.348848 | 0.000000 | 1.000000 | inf |
| 32 | -3.035678 | 1.135842 | 0.515855 | 0.180775 | 0.936586 | 5.531743 |
| 33 | -3.035678 | -1.135842 | 0.515855 | 0.180775 | 0.936586 | 5.531743 |
| 34 | -4.223460 | 0.000000 | 0.672185 | 0.000000 | 1.000000 | inf |
| 35 | -9.070692 | -0.000000 | 1.443645 | 0.000000 | 1.000000 | inf |
| 36 | -26.578730 | 27.485500 | 6.085219 | 4.374453 | 0.695149 | 0.228600 |
| 37 | -28.711479 | -0.000000 | 4.569574 | 0.000000 | 1.000000 | inf |
| 38 | -35.859976 | 27.485500 | 7.190899 | 4.374453 | 0.793683 | 0.228600 |
| 39 | -36.744614 | 0.000000 | 5.848087 | 0.000000 | 1.000000 | inf |
Velocity Asymptotic Stability Analysis
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 100.00 m/2 max. CT eig. real: 1018.304110
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 52.80 49.09
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 101.00 m/2 max. CT eig. real: 1028.487151
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 53.32 49.15
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 102.00 m/2 max. CT eig. real: 1038.670193
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 53.85 49.21
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 103.00 m/2 max. CT eig. real: 1048.853234
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 54.38 49.27
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 104.00 m/2 max. CT eig. real: 1059.036275
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 54.91 49.34
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 105.00 m/2 max. CT eig. real: 1069.219316
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 55.44 49.40
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 106.00 m/2 max. CT eig. real: 1079.402357
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 55.96 49.47
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 107.00 m/2 max. CT eig. real: 1089.585399
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 56.49 49.54
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 108.00 m/2 max. CT eig. real: 1099.768440
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 57.02 49.60
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 109.00 m/2 max. CT eig. real: 1109.951481
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 57.55 49.68
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 110.00 m/2 max. CT eig. real: 1120.134522
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 58.08 49.75
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 111.00 m/2 max. CT eig. real: 1130.317564
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 58.60 49.82
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 112.00 m/2 max. CT eig. real: 1140.500605
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 59.13 49.90
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 113.00 m/2 max. CT eig. real: 1150.683646
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 59.66 49.97
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 114.00 m/2 max. CT eig. real: 1160.866687
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 60.19 50.05
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 115.00 m/2 max. CT eig. real: 1171.049728
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 60.72 50.13
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 116.00 m/2 max. CT eig. real: 1181.232770
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 61.24 50.22
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 117.00 m/2 max. CT eig. real: 1191.415811
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 61.77 50.30
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 118.00 m/2 max. CT eig. real: 1201.598852
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 62.30 50.39
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 119.00 m/2 max. CT eig. real: 1211.781893
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 62.83 83.07
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 120.00 m/2 max. CT eig. real: 1221.964934
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 63.36 82.86
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 121.00 m/2 max. CT eig. real: 1232.147976
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 63.88 82.64
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 122.00 m/2 max. CT eig. real: 1242.331017
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 64.41 82.42
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 123.00 m/2 max. CT eig. real: 1252.514058
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 64.94 82.19
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 124.00 m/2 max. CT eig. real: 1262.697099
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 65.47 81.96
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 125.00 m/2 max. CT eig. real: 1272.880140
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 66.00 81.73
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 126.00 m/2 max. CT eig. real: 1283.063182
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 66.52 81.50
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 127.00 m/2 max. CT eig. real: 1293.246223
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 67.05 81.26
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 128.00 m/2 max. CT eig. real: 1303.429264
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 67.58 81.01
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 129.00 m/2 max. CT eig. real: 1313.612305
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 68.11 80.77
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 130.00 m/2 max. CT eig. real: 1323.795346
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 68.64 80.51
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 131.00 m/2 max. CT eig. real: 1333.978388
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 69.16 80.26
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 132.00 m/2 max. CT eig. real: 1344.161429
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 69.69 80.00
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 133.00 m/2 max. CT eig. real: 1354.344470
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 70.22 79.74
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 134.00 m/2 max. CT eig. real: 1364.527511
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 70.75 79.47
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 135.00 m/2 max. CT eig. real: 1374.710552
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 71.28 79.20
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 136.00 m/2 max. CT eig. real: 1384.893594
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 71.80 78.92
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 137.00 m/2 max. CT eig. real: 1395.076635
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 72.33 78.64
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 138.00 m/2 max. CT eig. real: 1405.259676
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 72.86 78.36
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 139.00 m/2 max. CT eig. real: 1415.442717
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 73.39 78.07
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 140.00 m/2 max. CT eig. real: 1425.625758
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 73.91 77.77
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 141.00 m/2 max. CT eig. real: 1435.808799
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 74.44 77.48
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 142.00 m/2 max. CT eig. real: 1445.991841
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 74.97 77.18
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 143.00 m/2 max. CT eig. real: 1456.174882
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 75.50 76.87
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 144.00 m/2 max. CT eig. real: 1466.357923
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 76.03 76.57
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 145.00 m/2 max. CT eig. real: 1476.540964
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 76.55 76.25
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 146.00 m/2 max. CT eig. real: 1486.724005
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 77.08 75.94
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 147.00 m/2 max. CT eig. real: 1496.907047
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 77.61 75.62
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 148.00 m/2 max. CT eig. real: 1507.090088
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 78.14 75.31
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 149.00 m/2 max. CT eig. real: 1517.273129
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 78.67 74.99
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 150.00 m/2 max. CT eig. real: 1527.456170
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 79.19 74.67
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 151.00 m/2 max. CT eig. real: 1537.639211
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 79.72 74.35
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 152.00 m/2 max. CT eig. real: 1547.822253
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 80.25 74.03
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 153.00 m/2 max. CT eig. real: 1558.005294
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 80.78 73.71
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 154.00 m/2 max. CT eig. real: 1568.188335
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 81.31 73.40
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 155.00 m/2 max. CT eig. real: 1578.371376
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 81.83 73.09
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 156.00 m/2 max. CT eig. real: 1588.554417
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 82.36 72.78
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 157.00 m/2 max. CT eig. real: 1598.737458
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 82.89 72.49
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 158.00 m/2 max. CT eig. real: 1608.920500
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 83.42 72.19
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 159.00 m/2 max. CT eig. real: 1619.103541
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 83.95 71.91
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 160.00 m/2 max. CT eig. real: 1629.286582
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 84.47 71.64
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 161.00 m/2 max. CT eig. real: 1639.469623
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 85.00 71.37
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 162.00 m/2 max. CT eig. real: 1649.652664
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 85.53 71.12
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 163.00 m/2 max. CT eig. real: 1659.835706
N unstab.: 002
Unstable aeroelastic natural frequency CT(rad/s): 86.06 70.87
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 164.00 m/2 max. CT eig. real: 1670.018747
N unstab.: 004
Unstable aeroelastic natural frequency CT(rad/s): 86.59 70.64 70.64 56.53
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 165.00 m/2 max. CT eig. real: 1680.201788
N unstab.: 004
Unstable aeroelastic natural frequency CT(rad/s): 87.11 70.41 70.41 56.63
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 166.00 m/2 max. CT eig. real: 1690.384829
N unstab.: 004
Unstable aeroelastic natural frequency CT(rad/s): 87.64 70.20 70.20 56.73
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 167.00 m/2 max. CT eig. real: 1700.567870
N unstab.: 004
Unstable aeroelastic natural frequency CT(rad/s): 88.17 69.99 69.99 56.82
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 168.00 m/2 max. CT eig. real: 1710.750911
N unstab.: 004
Unstable aeroelastic natural frequency CT(rad/s): 88.70 69.79 69.79 56.90
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 169.00 m/2 max. CT eig. real: 1720.933953
N unstab.: 004
Unstable aeroelastic natural frequency CT(rad/s): 89.23 69.61 69.61 56.97
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 170.00 m/2 max. CT eig. real: 1731.116994
N unstab.: 004
Unstable aeroelastic natural frequency CT(rad/s): 89.75 69.43 69.43 57.04
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 171.00 m/2 max. CT eig. real: 1741.300035
N unstab.: 004
Unstable aeroelastic natural frequency CT(rad/s): 90.28 69.26 69.26 57.10
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 172.00 m/2 max. CT eig. real: 1751.483076
N unstab.: 004
Unstable aeroelastic natural frequency CT(rad/s): 90.81 69.10 69.10 57.16
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 173.00 m/2 max. CT eig. real: 1761.666117
N unstab.: 004
Unstable aeroelastic natural frequency CT(rad/s): 91.34 68.94 68.94 57.21
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 174.00 m/2 max. CT eig. real: 1771.849159
N unstab.: 004
Unstable aeroelastic natural frequency CT(rad/s): 91.87 68.79 68.79 57.25
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 175.00 m/2 max. CT eig. real: 1782.032200
N unstab.: 004
Unstable aeroelastic natural frequency CT(rad/s): 92.39 68.65 68.65 57.29
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 176.00 m/2 max. CT eig. real: 1792.215241
N unstab.: 004
Unstable aeroelastic natural frequency CT(rad/s): 92.92 68.51 68.51 57.33
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 177.00 m/2 max. CT eig. real: 1802.398282
N unstab.: 004
Unstable aeroelastic natural frequency CT(rad/s): 93.45 68.38 68.38 57.36
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 178.00 m/2 max. CT eig. real: 1812.581323
N unstab.: 004
Unstable aeroelastic natural frequency CT(rad/s): 93.98 68.25 68.25 57.39
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 179.00 m/2 max. CT eig. real: 1822.764364
N unstab.: 004
Unstable aeroelastic natural frequency CT(rad/s): 94.51 68.13 68.13 57.41
Updating C and K matrices and natural frequencies with new normalised time...
LTI u: 180.00 m/2 max. CT eig. real: 1832.947406
N unstab.: 004
Unstable aeroelastic natural frequency CT(rad/s): 95.03 68.01 68.01 57.43
Saving velocity analysis results...
Successful
FINISHED - Elapsed time = 87.4548716 seconds
FINISHED - CPU process time = 158.0786466 seconds
/home/ng213/code/sharpy/sharpy/postproc/asymptoticstability.py:171: UserWarning: Plotting modes is under development
warn.warn('Plotting modes is under development')
[17]:
<sharpy.presharpy.presharpy.PreSharpy at 0x7f94ae37cf28>
Analysis¶
The nonlinear equilibrium condition can be visualised and analysed by opening, with Paraview, the files in the /output/<case_name>/aero
and /output/<case_name>/beam
folders to see the deflection and aerodynamic forces acting
The stability of the Goland wing is now analysed under changing free stream velocity. The aeroelastic system is projected onto 2 structural modes (1st bending and 1st torsion). The two modes are seen quite separated at 100 m/s. As speed is increased, the damping of the torsion mode decreases until it crosses the imaginary axis onto the right hand plane and flutter begins. This flutter mode is a bending-torsion mode, as seen from the natural frequency plot where the frequencies of each coalesce into this mode.
[18]:
file_name = './output/%s/stability/velocity_analysis_min1000_max1800_nvel0081.dat' % case_name
velocity_analysis = np.loadtxt(file_name)
u_inf = velocity_analysis[:, 0]
eigs_r = velocity_analysis[:, 1]
eigs_i = velocity_analysis[:, 2]
[19]:
fig = plt.figure()
plt.scatter(eigs_r, eigs_i, c=u_inf, cmap='Blues')
cbar = plt.colorbar()
cbar.set_label('Free Stream Velocity, $u_\infty$ [m/s]')
plt.grid()
plt.xlim(-10, 10)
plt.ylim(-150, 150)
plt.xlabel('Real Part, $\lambda$ [rad/s]')
plt.ylabel('Imag Part, $\lambda$ [rad/s]');

[20]:
fig = plt.figure()
natural_frequency = np.sqrt(eigs_r ** 2 + eigs_i ** 2)
damping_ratio = eigs_r / natural_frequency
cond = (eigs_r>-25) * (eigs_r<10) * (natural_frequency<100) # filter unwanted eigenvalues for this plot (mostly aero modes)
plt.scatter(u_inf[cond], damping_ratio[cond], color='k', marker='s', s=9)
plt.grid()
plt.ylim(-0.25, 0.25)
plt.xlabel('Free Stream Velocity, $u_\infty$ [m/s]')
plt.ylabel('Damping Ratio, $\zeta$ [-]');

[21]:
fig = plt.figure()
cond = (eigs_r>-25) * (eigs_r<10) # filter unwanted eigenvalues for this plot (mostly aero modes)
plt.scatter(u_inf[cond], natural_frequency[cond], color='k', marker='s', s=9)
plt.grid()
plt.ylim(40, 100)
plt.xlabel('Free Stream Velocity, $u_\infty$ [m/s]')
plt.ylabel('Natural Frequency, $\omega_n$ [rad/s]');

[1]:
%load_ext autoreload
%autoreload 2
%matplotlib inline
%config InlineBackend.figure_format = 'svg'
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import Image
T-Tail HALE Model tutorial¶
The HALE T-Tail model intends to be a representative example of a typical HALE configuration, with high flexibility and aspect-ratio.
A geometry outline and a summary of the beam properties are given next
[2]:
url = 'https://raw.githubusercontent.com/ImperialCollegeLondon/sharpy/dev_doc/docs/source/content/example_notebooks/images/t-tail_geometry.png'
Image(url=url, width=800)
[2]:

[3]:
url = 'https://raw.githubusercontent.com/ImperialCollegeLondon/sharpy/dev_doc/docs/source/content/example_notebooks/images/t-tail_properties.png'
Image(url=url, width=500)
[3]:

This case is included in tests/coupled/simple_HALE/
. The generate_hale.py
file in that folder is the one that, if executed, generates all the required SHARPy files. This document is a step by step guide to how to process that case.
The T-Tail HALE model is subject to a 20% 1-cos spanwise constant gust.
First, let’s start with importing SHARPy in our Python environment.
[4]:
import sharpy
import sharpy.sharpy_main as sharpy_main
And now the generate_HALE.py
file needs to be executed.
[5]:
route_to_case = '../../../../cases/coupled/simple_HALE/'
%run '../../../../cases/coupled/simple_HALE/generate_hale.py'
There should be 3 new files, apart from the original generate_hale.py
:
[6]:
!ls ../../../../cases/coupled/simple_HALE/
generate_hale.py simple_HALE.aero.h5 simple_HALE.fem.h5 simple_HALE.sharpy
SHARPy can be run now. In the terminal, doing cd
to the simple_HALE
folder, the command would look like:
sharpy simple_HALE.sharpy
From a python console with import sharpy
already run, the command is:
[7]:
case_data = sharpy_main.main(['', route_to_case + 'simple_HALE.sharpy'])
/home/ad214/run/code_doc/sharpy/sharpy/aero/utils/uvlmlib.py:230: RuntimeWarning: invalid value encountered in true_divide
flightconditions.uinf_direction = np.ctypeslib.as_ctypes(ts_info.u_ext[0][:, 0, 0]/flightconditions.uinf)
/home/ad214/run/code_doc/sharpy/sharpy/aero/utils/uvlmlib.py:347: RuntimeWarning: invalid value encountered in true_divide
flightconditions.uinf_direction = np.ctypeslib.as_ctypes(ts_info.u_ext[0][:, 0, 0]/flightconditions.uinf)
The resulting data structure that is returned from the call to main
contains all the time-dependant variables for both the structural and aerodynamic solvers.
timestep_info
can be found in case_data.structure
and case_data.aero
. It is an array with custom-made structure to contain the data of each solver.
In the .sharpy
file, we can see which solvers are run:
flow = ['BeamLoader',
'AerogridLoader',
'StaticTrim',
'BeamLoads',
'AerogridPlot',
'BeamPlot',
'DynamicCoupled',
]
In order:
- BeamLoader: reads the
fem.h5
file and generates the structure for the beam solver. - AerogridLoader: reads the
aero.h5
file and generates the aerodynamic grid for the aerodynamic solver. - StaticTrim: this solver performs a longitudinal trim (Thrust, Angle of attack and Elevator deflection) using the StaticCoupled solver.
- BeamLoads: calculates the internal beam loads for the static solution
- AerogridPlot: outputs the aerodynamic grid for the static solution.
- BeamPlot: outputs the structural discretisation for the static solution.
- DynamicCoupled: is the main driver of the dynamic simulation: executes the structural and aerodynamic solvers and couples both. Every converged time step is followed by a BeamLoads, AerogridPlot and BeamPlot execution.
Structural data organisation¶
The timestep_info
structure contains several relevant variables:
for_pos
: position of the body-attached frame of reference in inertial FoR.for_vel
: velocity (in body FoR) of the body FoR wrt inertial FoR.pos
: nodal position in A FoR.psi
: nodal rotations (from the material B FoR to A FoR) in a Cartesian Rotation Vector parametrisation.applied_steady_forces
: nodal forces from the aero solver and the applied forces.postproc_cell
: is a dictionary that contains the variables generated by a postprocessor, such as the internal beam loads.
The structural timestep_info
also contains some useful variables:
cag
andcga
return \(C^{AG}\) and \(C^{GA}\), the rotation matrices from the body-attached (A) FoR to the inertial (G).glob_pos
rotates thepos
variable to give you the inertial nodal position. Ifinclude_rbm = True
is passed,for_pos
is added to it.
Aerodynamic data organisation¶
The aerodynamic datastructure can be found in case_data.aero.timestep_info
. It contains useful variables, such as:
dimensions
anddimensions_star
: gives the dimensions of every surface and wake surface. Organised as:dimensions[i_surf, 0] = chordwise panels
,dimensions[i_surf, 1] = spanwise panels
.zeta
andzeta_star
: they are the \(G\) FoR coordinates of the surface vertices.gamma
andgamma_star
: vortex ring circulations.
Structural dynamics¶
We can now plot the rigid body dynamics:
RBM trajectory
[16]:
fig, ax = plt.subplots(1, 1, figsize=(7, 4))
# extract information
n_tsteps = len(case_data.structure.timestep_info)
xz = np.zeros((n_tsteps, 2))
for it in range(n_tsteps):
xz[it, 0] = -case_data.structure.timestep_info[it].for_pos[0] # the - is so that increasing time -> increasing x
xz[it, 1] = case_data.structure.timestep_info[it].for_pos[2]
ax.plot(xz[:, 0], xz[:, 1])
fig.suptitle('Longitudinal trajectory of the T-Tail model in a 20% 1-cos gust encounter')
ax.set_xlabel('X [m]')
ax.set_ylabel('Z [m]');
plt.show()
RBM velocities
[17]:
fig, ax = plt.subplots(3, 1, figsize=(7, 6), sharex=True)
ylabels = ['Vx [m/s]', 'Vy [m/s]', 'Vz [m/s]']
# extract information
n_tsteps = len(case_data.structure.timestep_info)
dt = case_data.settings['DynamicCoupled']['dt'].value
time_vec = np.linspace(0, n_tsteps*dt, n_tsteps)
for_vel = np.zeros((n_tsteps, 3))
for it in range(n_tsteps):
for_vel[it, 0:3] = case_data.structure.timestep_info[it].for_vel[0:3]
for idim in range(3):
ax[idim].plot(time_vec, for_vel[:, idim])
ax[idim].set_ylabel(ylabels[idim])
ax[2].set_xlabel('time [s]')
plt.subplots_adjust(hspace=0)
fig.suptitle('Linear RBM velocities. T-Tail model in a 20% 1-cos gust encounter');
# ax.set_xlabel('X [m]')
# ax.set_ylabel('Z [m]');
plt.show()
[18]:
fig, ax = plt.subplots(3, 1, figsize=(7, 6), sharex=True)
ylabels = ['Roll rate [deg/s]', 'Pitch rate [deg/s]', 'Yaw rate [deg/s]']
# extract information
n_tsteps = len(case_data.structure.timestep_info)
dt = case_data.settings['DynamicCoupled']['dt'].value
time_vec = np.linspace(0, n_tsteps*dt, n_tsteps)
for_vel = np.zeros((n_tsteps, 3))
for it in range(n_tsteps):
for_vel[it, 0:3] = case_data.structure.timestep_info[it].for_vel[3:6]*180/np.pi
for idim in range(3):
ax[idim].plot(time_vec, for_vel[:, idim])
ax[idim].set_ylabel(ylabels[idim])
ax[2].set_xlabel('time [s]')
plt.subplots_adjust(hspace=0)
fig.suptitle('Angular RBM velocities. T-Tail model in a 20% 1-cos gust encounter');
# ax.set_xlabel('X [m]')
# ax.set_ylabel('Z [m]');
plt.show()
Wing tip deformation
It is stored in timestep_info
as pos
. We need to find the correct node.
[19]:
fig, ax = plt.subplots(1, 1, figsize=(6, 6))
ax.scatter(case_data.structure.ini_info.pos[:, 0], case_data.structure.ini_info.pos[:, 1])
ax.axis('equal')
tip_node = np.argmax(case_data.structure.ini_info.pos[:, 1])
print('Wing tip node is the maximum Y one: ', tip_node)
ax.scatter(case_data.structure.ini_info.pos[tip_node, 0], case_data.structure.ini_info.pos[tip_node, 1], color='red')
plt.show()
Wing tip node is the maximum Y one: 16
We can plot now the pos[tip_node,:]
variable:
[20]:
fig, ax = plt.subplots(1, 1, figsize=(7, 3))
# extract information
n_tsteps = len(case_data.structure.timestep_info)
xz = np.zeros((n_tsteps, 2))
for it in range(n_tsteps):
xz[it, 0] = case_data.structure.timestep_info[it].pos[tip_node, 0]
xz[it, 1] = case_data.structure.timestep_info[it].pos[tip_node, 2]
ax.plot(time_vec, xz[:, 1])
# fig.suptitle('Longitudinal trajectory of the T-Tail model in a 20% 1-cos gust encounter')
ax.set_xlabel('time [s]')
ax.set_ylabel('Vertical disp. [m]');
plt.show()
[21]:
fig, ax = plt.subplots(1, 1, figsize=(7, 3))
# extract information
n_tsteps = len(case_data.structure.timestep_info)
xz = np.zeros((n_tsteps, 2))
for it in range(n_tsteps):
xz[it, 0] = case_data.structure.timestep_info[it].pos[tip_node, 0]
xz[it, 1] = case_data.structure.timestep_info[it].pos[tip_node, 2]
ax.plot(time_vec, xz[:, 0])
# fig.suptitle('Longitudinal trajectory of the T-Tail model in a 20% 1-cos gust encounter')
ax.set_xlabel('time [s]')
ax.set_ylabel('Horizontal disp. [m]\nPositive is aft');
plt.show()
Wing root loads
The wing root loads can be extracted from the postproc_cell
structure in timestep_info
.
[22]:
fig, ax = plt.subplots(3, 1, figsize=(7, 6), sharex=True)
ylabels = ['Torsion [Nm2]', 'OOP [Nm2]', 'IP [Nm2]']
# extract information
n_tsteps = len(case_data.structure.timestep_info)
dt = case_data.settings['DynamicCoupled']['dt'].value
time_vec = np.linspace(0, n_tsteps*dt, n_tsteps)
loads = np.zeros((n_tsteps, 3))
for it in range(n_tsteps):
loads[it, 0:3] = case_data.structure.timestep_info[it].postproc_cell['loads'][0, 3:6]
for idim in range(3):
ax[idim].plot(time_vec, loads[:, idim])
ax[idim].set_ylabel(ylabels[idim])
ax[2].set_xlabel('time [s]')
plt.subplots_adjust(hspace=0)
fig.suptitle('Wing root loads. T-Tail model in a 20% 1-cos gust encounter');
# ax.set_xlabel('X [m]')
# ax.set_ylabel('Z [m]');
plt.show()
Aerodynamic analysis¶
The aerodynamic analysis can be obviously conducted using python. However, the easiest way is to run the case by yourself and open the files in output/simple_HALE/beam
and output/simple_HALE/aero
with Paraview.
[23]:
url = 'https://raw.githubusercontent.com/ImperialCollegeLondon/sharpy/dev_doc/docs/source/content/example_notebooks/images/t-tail_solution.png'
Image(url=url, width=600)
[23]:

Asymptotic Stability of a Flying Wing in Cruise Trimmed Conditions¶
A Horten flying wing is analysed. The nonlinear trim condition is found and the system is linearised. The eigenvalues of the linearised system are then used to evaluate the stability at the cruise trimmed flight conditions.
[1]:
# required packages
import sharpy.utils.algebra as algebra
import sharpy.sharpy_main
from cases.hangar.richards_wing import Baseline
import numpy as np
import configobj
import matplotlib.pyplot as plt
Flight Conditions¶
Initial flight conditions. The values for angle of attack alpha
, control surface deflection cs_deflection
and thrust
are only initial values. The values required for trim will be calculated by the StaticTrim
routine
[2]:
u_inf = 28
alpha_deg = 4.5135
cs_deflection = 0.1814
thrust = 5.5129
Discretisation¶
[3]:
M = 4 # chordwise panels
N = 11 # spanwise panels
Msf = 5 # wake length in chord numbers
Create Horten Wing¶
[4]:
ws = Baseline(M=M,
N=N,
Mstarfactor=Msf,
u_inf=u_inf,
rho=1.02,
alpha_deg=alpha_deg,
roll_deg=0,
cs_deflection_deg=cs_deflection,
thrust=thrust,
physical_time=20,
case_name='horten',
case_name_format=4,
case_remarks='M%gN%gMsf%g' % (M, N, Msf))
ws.set_properties()
ws.initialise()
ws.clean_test_files()
ws.update_mass_stiffness(sigma=1., sigma_mass=2.5)
ws.update_fem_prop()
ws.generate_fem_file()
ws.update_aero_properties()
ws.generate_aero_file()
0
Section Mass: 11.88
Linear Mass: 11.88
Section Ixx: 1.8777
Section Iyy: 1.0137
Section Izz: 2.5496
Linear Ixx: 1.88
1
Section Mass: 10.99
Linear Mass: 10.99
Section Ixx: 1.4694
Section Iyy: 0.9345
Section Izz: 2.1501
Linear Ixx: 1.74
2
Section Mass: 10.10
Linear Mass: 10.10
Section Ixx: 1.1257
Section Iyy: 0.8561
Section Izz: 1.7993
Linear Ixx: 1.60
3
Section Mass: 9.21
Linear Mass: 9.21
Section Ixx: 0.8410
Section Iyy: 0.7783
Section Izz: 1.4933
Linear Ixx: 1.46
4
Section Mass: 8.32
Linear Mass: 8.32
Section Ixx: 0.6096
Section Iyy: 0.7011
Section Izz: 1.2280
Linear Ixx: 1.31
5
Section Mass: 7.43
Linear Mass: 7.43
Section Ixx: 0.4260
Section Iyy: 0.6246
Section Izz: 0.9996
Linear Ixx: 1.17
6
Section Mass: 6.54
Linear Mass: 6.54
Section Ixx: 0.2845
Section Iyy: 0.5485
Section Izz: 0.8040
Linear Ixx: 1.03
7
Section Mass: 5.64
Linear Mass: 5.64
Section Ixx: 0.1796
Section Iyy: 0.4728
Section Izz: 0.6374
Linear Ixx: 0.89
8
Section Mass: 4.75
Linear Mass: 4.75
Section Ixx: 0.1055
Section Iyy: 0.3975
Section Izz: 0.4959
Linear Ixx: 0.75
9
Section Mass: 3.86
Linear Mass: 3.86
Section Ixx: 0.0567
Section Iyy: 0.3226
Section Izz: 0.3753
Linear Ixx: 0.61
10
Section Mass: 2.97
Linear Mass: 2.97
Section Ixx: 0.0275
Section Iyy: 0.2479
Section Izz: 0.2719
Linear Ixx: 0.47
Simulation Information¶
The flow
setting tells SHARPy which solvers to run and in which order. You may be stranged by the presence of the DynamicCoupled
solver but it is necessary to give an initial speed to the structure. This will allow proper linearisation of the structural and rigid body equations.
[5]:
flow = ['BeamLoader',
'AerogridLoader',
'StaticTrim',
'BeamPlot',
'AerogridPlot',
'AeroForcesCalculator',
'DynamicCoupled',
'Modal',
'LinearAssembler',
'AsymptoticStability',
'StabilityDerivatives',
]
SHARPy Settings¶
[6]:
settings = dict()
settings['SHARPy'] = {'case': ws.case_name,
'route': ws.case_route,
'flow': flow,
'write_screen': 'on',
'write_log': 'on',
'log_folder': './output/' + ws.case_name + '/',
'log_file': ws.case_name + '.log'}
Loaders¶
[7]:
settings['BeamLoader'] = {'unsteady': 'off',
'orientation': algebra.euler2quat(np.array([ws.roll,
ws.alpha,
ws.beta]))}
settings['AerogridLoader'] = {'unsteady': 'off',
'aligned_grid': 'on',
'mstar': int(ws.M * ws.Mstarfactor),
'freestream_dir': ['1', '0', '0'],
'control_surface_deflection': ['']}
StaticCoupled Solver¶
[8]:
settings['StaticCoupled'] = {'print_info': 'on',
'structural_solver': 'NonLinearStatic',
'structural_solver_settings': {'print_info': 'off',
'max_iterations': 200,
'num_load_steps': 1,
'delta_curved': 1e-5,
'min_delta': ws.tolerance,
'gravity_on': 'on',
'gravity': 9.81},
'aero_solver': 'StaticUvlm',
'aero_solver_settings': {'print_info': 'on',
'horseshoe': ws.horseshoe,
'num_cores': 4,
'n_rollup': int(0),
'rollup_dt': ws.dt,
'rollup_aic_refresh': 1,
'rollup_tolerance': 1e-4,
'velocity_field_generator': 'SteadyVelocityField',
'velocity_field_input': {'u_inf': ws.u_inf,
'u_inf_direction': [1., 0, 0]},
'rho': ws.rho},
'max_iter': 200,
'n_load_steps': 1,
'tolerance': ws.tolerance,
'relaxation_factor': 0.2}
Trim solver¶
[9]:
settings['StaticTrim'] = {'solver': 'StaticCoupled',
'solver_settings': settings['StaticCoupled'],
'thrust_nodes': ws.thrust_nodes,
'initial_alpha': ws.alpha,
'initial_deflection': ws.cs_deflection,
'initial_thrust': ws.thrust,
'max_iter': 200,
'fz_tolerance': 1e-2,
'fx_tolerance': 1e-2,
'm_tolerance': 1e-2}
Nonlinear Equilibrium Post-process¶
[10]:
settings['AerogridPlot'] = {'folder': './output/',
'include_rbm': 'off',
'include_applied_forces': 'on',
'minus_m_star': 0,
'u_inf': ws.u_inf
}
settings['AeroForcesCalculator'] = {'folder': './output/',
'write_text_file': 'off',
'text_file_name': ws.case_name + '_aeroforces.csv',
'screen_output': 'on',
'unsteady': 'off',
'coefficients': True,
'q_ref': 0.5 * ws.rho * ws.u_inf ** 2,
'S_ref': 12.809,
}
settings['BeamPlot'] = {'folder': './output/',
'include_rbm': 'on',
'include_applied_forces': 'on',
'include_FoR': 'on'}
DynamicCoupled Solver¶
As mentioned before, a single time step of DynamicCoupled
is required to give the structure the velocity required for the linearisation of the rigid body equations to be correct. Hence n_time_steps = 1
[11]:
struct_solver_settings = {'print_info': 'off',
'initial_velocity_direction': [-1., 0., 0.],
'max_iterations': 950,
'delta_curved': 1e-6,
'min_delta': ws.tolerance,
'newmark_damp': 5e-3,
'gravity_on': True,
'gravity': 9.81,
'num_steps': ws.n_tstep,
'dt': ws.dt,
'initial_velocity': ws.u_inf * 1}
step_uvlm_settings = {'print_info': 'on',
'horseshoe': ws.horseshoe,
'num_cores': 4,
'n_rollup': 1,
'convection_scheme': ws.wake_type,
'rollup_dt': ws.dt,
'rollup_aic_refresh': 1,
'rollup_tolerance': 1e-4,
'velocity_field_generator': 'SteadyVelocityField',
'velocity_field_input': {'u_inf': ws.u_inf * 0,
'u_inf_direction': [1., 0., 0.]},
'rho': ws.rho,
'n_time_steps': ws.n_tstep,
'dt': ws.dt,
'gamma_dot_filtering': 3}
settings['DynamicCoupled'] = {'print_info': 'on',
'structural_solver': 'NonLinearDynamicCoupledStep',
'structural_solver_settings': struct_solver_settings,
'aero_solver': 'StepUvlm',
'aero_solver_settings': step_uvlm_settings,
'fsi_substeps': 200,
'fsi_tolerance': ws.fsi_tolerance,
'relaxation_factor': ws.relaxation_factor,
'minimum_steps': 1,
'relaxation_steps': 150,
'final_relaxation_factor': 0.5,
'n_time_steps': 1,
'dt': ws.dt,
'include_unsteady_force_contribution': 'off',
}
Modal Solver Settings¶
[12]:
settings['Modal'] = {'print_info': True,
'use_undamped_modes': True,
'NumLambda': 30,
'rigid_body_modes': True,
'write_modes_vtk': 'on',
'print_matrices': 'on',
'write_data': 'on',
'continuous_eigenvalues': 'off',
'dt': ws.dt,
'plot_eigenvalues': False,
'rigid_modes_cg': False}
Linear Assembler Settings¶
Note that for the assembly of the linear system, we replace the parametrisation of the orientation with Euler angles instead of quaternions.
[13]:
settings['LinearAssembler'] = {'linear_system': 'LinearAeroelastic',
'linear_system_settings': {
'beam_settings': {'modal_projection': 'off',
'inout_coords': 'modes',
'discrete_time': True,
'newmark_damp': 0.5e-2,
'discr_method': 'newmark',
'dt': ws.dt,
'proj_modes': 'undamped',
'num_modes': 9,
'print_info': 'on',
'gravity': 'on',
'remove_dofs': []},
'aero_settings': {'dt': ws.dt,
'integr_order': 2,
'density': ws.rho,
'remove_predictor': 'off',
'use_sparse': 'off',
'rigid_body_motion': 'on',
'remove_inputs': ['u_gust']},
'rigid_body_motion': True,
'track_body': 'on',
'use_euler': 'on',
'linearisation_tstep': -1
}}
Asymptotic Stability Post-processor¶
[14]:
settings['AsymptoticStability'] = {
'print_info': 'on',
'frequency_cutoff': 0,
'export_eigenvalues': 'on',
'num_evals': 1000,
'folder': './output/'}
Stability Derivatives Post-processor¶
[15]:
settings['StabilityDerivatives'] = {'u_inf': ws.u_inf,
'S_ref': 12.809,
'b_ref': ws.span,
'c_ref': 0.719}
Write solver file¶
[16]:
config = configobj.ConfigObj()
np.set_printoptions(precision=16)
file_name = ws.case_route + '/' + ws.case_name + '.sharpy'
config.filename = file_name
for k, v in settings.items():
config[k] = v
config.write()
Run Simulation¶
[17]:
data = sharpy.sharpy_main.main(['', ws.case_route + '/' + ws.case_name + '.sharpy'])
--------------------------------------------------------------------------------
###### ## ## ### ######## ######## ## ##
## ## ## ## ## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ## ## ####
###### ######### ## ## ######## ######## ##
## ## ## ######### ## ## ## ##
## ## ## ## ## ## ## ## ## ##
###### ## ## ## ## ## ## ## ##
--------------------------------------------------------------------------------
Aeroelastics Lab, Aeronautics Department.
Copyright (c), Imperial College London.
All rights reserved.
License available at https://github.com/imperialcollegelondon/sharpy
Running SHARPy from /home/ng213/code/sharpy/docs/source/content/example_notebooks
SHARPy being run is in /home/ng213/code/sharpy
The branch being run is dev_examples
The version and commit hash are: v0.1-1590-g7385fe4-7385fe4
The available solvers on this session are:
PreSharpy
_BaseStructural
AerogridLoader
BeamLoader
DynamicCoupled
DynamicUVLM
LinDynamicSim
LinearAssembler
Modal
NoAero
NonLinearDynamic
NonLinearDynamicCoupledStep
NonLinearDynamicMultibody
NonLinearDynamicPrescribedStep
NonLinearStatic
NonLinearStaticMultibody
PrescribedUvlm
RigidDynamicPrescribedStep
SHWUvlm
StaticCoupled
StaticCoupledRBM
StaticTrim
StaticUvlm
StepLinearUVLM
StepUvlm
Trim
Cleanup
PickleData
SaveData
CreateSnapshot
PlotFlowField
StabilityDerivatives
AeroForcesCalculator
WriteVariablesTime
AerogridPlot
LiftDistribution
StallCheck
FrequencyResponse
AsymptoticStability
BeamPlot
BeamLoads
Generating an instance of BeamLoader
Generating an instance of AerogridLoader
Variable control_surface_deflection_generator_settings has no assigned value in the settings file.
will default to the value: []
The aerodynamic grid contains 4 surfaces
Surface 0, M=4, N=2
Wake 0, M=20, N=2
Surface 1, M=4, N=22
Wake 1, M=20, N=22
Surface 2, M=4, N=2
Wake 2, M=20, N=2
Surface 3, M=4, N=22
Wake 3, M=20, N=22
In total: 192 bound panels
In total: 960 wake panels
Total number of panels = 1152
Generating an instance of StaticTrim
Variable print_info has no assigned value in the settings file.
will default to the value: c_bool(True)
Variable tail_cs_index has no assigned value in the settings file.
will default to the value: c_int(0)
Variable initial_angle_eps has no assigned value in the settings file.
will default to the value: c_double(0.05)
Variable initial_thrust_eps has no assigned value in the settings file.
will default to the value: c_double(2.0)
Variable relaxation_factor has no assigned value in the settings file.
will default to the value: c_double(0.2)
Generating an instance of StaticCoupled
Generating an instance of NonLinearStatic
Variable newmark_damp has no assigned value in the settings file.
will default to the value: c_double(0.0001)
Variable relaxation_factor has no assigned value in the settings file.
will default to the value: c_double(0.3)
Variable dt has no assigned value in the settings file.
will default to the value: c_double(0.01)
Variable num_steps has no assigned value in the settings file.
will default to the value: c_int(500)
Variable initial_position has no assigned value in the settings file.
will default to the value: [0. 0. 0.]
Generating an instance of StaticUvlm
Variable iterative_solver has no assigned value in the settings file.
will default to the value: c_bool(False)
Variable iterative_tol has no assigned value in the settings file.
will default to the value: c_double(0.0001)
Variable iterative_precond has no assigned value in the settings file.
will default to the value: c_bool(False)
|=====|=====|============|==========|==========|==========|==========|==========|==========|
|iter |step | log10(res) | Fx | Fy | Fz | Mx | My | Mz |
|=====|=====|============|==========|==========|==========|==========|==========|==========|
|==========|==========|==========|==========|==========|==========|==========|==========|==========|==========|
| iter | alpha | elev | thrust | Fx | Fy | Fz | Mx | My | Mz |
|==========|==========|==========|==========|==========|==========|==========|==========|==========|==========|
| 0 | 0 | 0.00000 | -0.1051 | -0.0000 | 0.0604 | -0.0000 | 1.0816 | -0.0000 |
| 1 | 0 | -7.62661 | -0.1119 | 0.0000 | 0.1274 | -0.0000 | 0.0026 | 0.0000 |
| 2 | 0 | -8.34118 | -0.0941 | -0.0000 | 0.0393 | 0.0000 | -0.0793 | 0.0000 |
| 3 | 0 | -9.29266 | -0.0870 | 0.0000 | 0.0007 | -0.0000 | -0.0089 | 0.0000 |
| 4 | 0 | -10.67443 | -0.0876 | 0.0000 | 0.0028 | 0.0000 | -0.0119 | 0.0000 |
| 5 | 0 | -10.87008 | -0.0878 | 0.0000 | 0.0039 | -0.0000 | -0.0138 | 0.0000 |
| 6 | 0 | -11.64423 | -0.0877 | -0.0000 | 0.0037 | 0.0000 | -0.0135 | -0.0000 |
| 7 | 0 | -12.87835 | -0.0877 | 0.0000 | 0.0037 | -0.0000 | -0.0135 | 0.0000 |
| 0 | 4.5135 | 0.1814 | 5.5129 | -0.0877 | 0.0000 | 0.0037 | -0.0000 | -0.0135 | 0.0000 |
| 0 | 0 | 0.00000 |-116.9870 | -0.0000 | 994.8061 | -0.0000 |-882.4096 | 0.0000 |
| 1 | 0 | -5.81338 | -81.0252 | -0.0000 | 944.6090 | -0.0000 |-802.5942 | -0.0000 |
| 2 | 0 | -6.69380 | -74.1802 | -0.0000 | 937.6597 | -0.0000 |-792.1302 | 0.0000 |
| 3 | 0 | -7.20553 | -75.0015 | 0.0000 | 939.7800 | -0.0000 |-795.7138 | -0.0000 |
| 4 | 0 | -8.63165 | -74.9725 | 0.0000 | 939.7033 | -0.0000 |-795.5808 | 0.0000 |
| 5 | 0 | -8.79020 | -74.9511 | 0.0000 | 939.6488 | 0.0000 |-795.4881 | 0.0000 |
| 6 | 0 | -9.56992 | -74.9546 | -0.0000 | 939.6578 | 0.0000 |-795.5035 | -0.0000 |
| 7 | 0 | -10.77969 | -74.9549 | 0.0000 | 939.6584 | -0.0000 |-795.5044 | 0.0000 |
| 8 | 0 | -10.98913 | -74.9547 | -0.0000 | 939.6580 | 0.0000 |-795.5039 | -0.0000 |
| 9 | 0 | -12.12706 | -74.9547 | -0.0000 | 939.6581 | 0.0000 |-795.5039 | -0.0000 |
| 0 | 7.3783 | -2.6834 | 5.5129 | -74.9547 | -0.0000 | 939.6581 | 0.0000 |-795.5039 | -0.0000 |
| 0 | 0 | 0.00000 | -32.9132 | -0.0000 | 371.4719 | -0.0000 |-902.7965 | -0.0000 |
| 1 | 0 | -5.48782 | -11.8207 | 0.0000 | 298.8468 | -0.0000 |-777.2958 | 0.0000 |
| 2 | 0 | -6.40702 | -8.5206 | 0.0000 | 289.8069 | -0.0000 |-761.4879 | -0.0000 |
| 3 | 0 | -6.85006 | -9.2671 | -0.0000 | 293.2383 | 0.0000 |-767.3401 | -0.0000 |
| 4 | 0 | -8.25284 | -9.2365 | 0.0000 | 293.1025 | -0.0000 |-767.1091 | 0.0000 |
| 5 | 0 | -8.43408 | -9.2166 | 0.0000 | 293.0132 | 0.0000 |-766.9570 | 0.0000 |
| 6 | 0 | -9.20313 | -9.2199 | -0.0000 | 293.0284 | -0.0000 |-766.9829 | -0.0000 |
| 7 | 0 | -10.44114 | -9.2201 | 0.0000 | 293.0293 | -0.0000 |-766.9844 | 0.0000 |
| 8 | 0 | -10.62337 | -9.2200 | -0.0000 | 293.0287 | 0.0000 |-766.9834 | -0.0000 |
| 9 | 0 | -11.73764 | -9.2200 | -0.0000 | 293.0287 | 0.0000 |-766.9835 | -0.0000 |
| 10 | 0 | -12.29756 | -9.2200 | 0.0000 | 293.0287 | -0.0000 |-766.9835 | 0.0000 |
| 0 | 4.5135 | 3.0462 | 5.5129 | -9.2200 | 0.0000 | 293.0287 | -0.0000 |-766.9835 | 0.0000 |
| 0 | 0 | 0.00000 | -4.1051 | -0.0000 | 0.0604 | -0.0000 | 1.0812 | -0.0000 |
| 1 | 0 | -7.62660 | -4.1120 | -0.0000 | 0.1274 | -0.0000 | 0.0023 | -0.0000 |
| 2 | 0 | -8.34116 | -4.0942 | -0.0000 | 0.0393 | 0.0000 | -0.0796 | -0.0000 |
| 3 | 0 | -9.29268 | -4.0871 | 0.0000 | 0.0007 | -0.0000 | -0.0093 | 0.0000 |
| 4 | 0 | -10.67446 | -4.0876 | 0.0000 | 0.0028 | 0.0000 | -0.0123 | 0.0000 |
| 5 | 0 | -10.86979 | -4.0878 | 0.0000 | 0.0039 | -0.0000 | -0.0142 | 0.0000 |
| 6 | 0 | -11.64229 | -4.0878 | 0.0000 | 0.0037 | -0.0000 | -0.0138 | 0.0000 |
| 7 | 0 | -12.86703 | -4.0878 | 0.0000 | 0.0037 | -0.0000 | -0.0138 | 0.0000 |
| 0 | 4.5135 | 0.1814 | 7.5129 | -4.0878 | 0.0000 | 0.0037 | -0.0000 | -0.0138 | 0.0000 |
| 0 | 0 | 0.00000 | -0.0165 | 0.0000 | 0.0499 | 0.0000 | 1.1009 | 0.0000 |
| 1 | 0 | -7.62629 | -0.0236 | 0.0000 | 0.1184 | 0.0000 | 0.0195 | 0.0000 |
| 2 | 0 | -8.34096 | -0.0058 | -0.0000 | 0.0305 | -0.0000 | -0.0628 | -0.0000 |
| 3 | 0 | -9.29199 | 0.0012 | 0.0000 | -0.0082 | 0.0000 | 0.0077 | 0.0000 |
| 4 | 0 | -10.67407 | 0.0007 | 0.0000 | -0.0061 | -0.0000 | 0.0047 | 0.0000 |
| 5 | 0 | -10.86912 | 0.0005 | -0.0000 | -0.0050 | 0.0000 | 0.0028 | -0.0000 |
| 6 | 0 | -11.64225 | 0.0005 | 0.0000 | -0.0052 | -0.0000 | 0.0031 | 0.0000 |
| 7 | 0 | -12.83721 | 0.0005 | -0.0000 | -0.0052 | 0.0000 | 0.0032 | -0.0000 |
| 1 | 4.5135 | 0.1814 | 5.4690 | 0.0005 | -0.0000 | -0.0052 | 0.0000 | 0.0032 | -0.0000 |
Generating an instance of BeamPlot
Variable include_applied_moments has no assigned value in the settings file.
will default to the value: c_bool(True)
Variable name_prefix has no assigned value in the settings file.
will default to the value:
Variable output_rbm has no assigned value in the settings file.
will default to the value: c_bool(True)
...Finished
Generating an instance of AerogridPlot
Variable include_forward_motion has no assigned value in the settings file.
will default to the value: c_bool(False)
Variable include_unsteady_applied_forces has no assigned value in the settings file.
will default to the value: c_bool(False)
Variable name_prefix has no assigned value in the settings file.
will default to the value:
Variable dt has no assigned value in the settings file.
will default to the value: c_double(0.0)
Variable include_velocities has no assigned value in the settings file.
will default to the value: c_bool(False)
Variable num_cores has no assigned value in the settings file.
will default to the value: c_int(1)
...Finished
Generating an instance of AeroForcesCalculator
--------------------------------------------------------------------------------
tstep | fx_g | fy_g | fz_g | Cfx_g | Cfy_g | Cfz_g
0 | 1.090e+01 | -1.250e-07 | 1.835e+03 | 2.129e-03 | -2.441e-11 | 3.583e-01
...Finished
Generating an instance of DynamicCoupled
Variable structural_substeps has no assigned value in the settings file.
will default to the value: c_int(0)
Variable dynamic_relaxation has no assigned value in the settings file.
will default to the value: c_bool(False)
Variable postprocessors has no assigned value in the settings file.
will default to the value: []
Variable postprocessors_settings has no assigned value in the settings file.
will default to the value: {}
Variable controller_id has no assigned value in the settings file.
will default to the value: {}
Variable controller_settings has no assigned value in the settings file.
will default to the value: {}
Variable cleanup_previous_solution has no assigned value in the settings file.
will default to the value: c_bool(False)
Variable steps_without_unsteady_force has no assigned value in the settings file.
will default to the value: c_int(0)
Variable pseudosteps_ramp_unsteady_force has no assigned value in the settings file.
will default to the value: c_int(0)
Generating an instance of NonLinearDynamicCoupledStep
Variable num_load_steps has no assigned value in the settings file.
will default to the value: c_int(1)
Variable relaxation_factor has no assigned value in the settings file.
will default to the value: c_double(0.3)
Variable balancing has no assigned value in the settings file.
will default to the value: c_bool(False)
Generating an instance of StepUvlm
Variable iterative_solver has no assigned value in the settings file.
will default to the value: c_bool(False)
Variable iterative_tol has no assigned value in the settings file.
will default to the value: c_double(0.0001)
Variable iterative_precond has no assigned value in the settings file.
will default to the value: c_bool(False)
|=======|========|======|==============|==============|==============|==============|==============|
| ts | t | iter | struc ratio | iter time | residual vel | FoR_vel(x) | FoR_vel(z) |
|=======|========|======|==============|==============|==============|==============|==============|
/home/ng213/code/sharpy/sharpy/aero/utils/uvlmlib.py:230: RuntimeWarning: invalid value encountered in true_divide
flightconditions.uinf_direction = np.ctypeslib.as_ctypes(ts_info.u_ext[0][:, 0, 0]/flightconditions.uinf)
| 1 | 0.0089 | 3 | 0.652648 | 0.921936 | -10.549271 |-2.791317e+01 |-2.203427e+00 |
...Finished
Generating an instance of Modal
Variable folder has no assigned value in the settings file.
will default to the value: ./output
Variable keep_linear_matrices has no assigned value in the settings file.
will default to the value: c_bool(True)
Variable write_dat has no assigned value in the settings file.
will default to the value: c_bool(True)
Variable delta_curved has no assigned value in the settings file.
will default to the value: c_double(0.01)
Variable max_rotation_deg has no assigned value in the settings file.
will default to the value: c_double(15.0)
Variable max_displacement has no assigned value in the settings file.
will default to the value: c_double(0.15)
Variable use_custom_timestep has no assigned value in the settings file.
will default to the value: c_int(-1)
Structural eigenvalues
|==============|==============|==============|==============|==============|==============|==============|
| mode | eval_real | eval_imag | freq_n (Hz) | freq_d (Hz) | damping | period (s) |
|==============|==============|==============|==============|==============|==============|==============|
/home/ng213/code/sharpy/sharpy/solvers/modal.py:284: UserWarning: Projecting a system with damping on undamped modal shapes
'Projecting a system with damping on undamped modal shapes')
| 0 | -0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | inf |
| 1 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | inf |
| 2 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | inf |
| 3 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | inf |
| 4 | -0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | inf |
| 5 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | inf |
| 6 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | inf |
| 7 | -0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | inf |
| 8 | -0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | inf |
| 9 | -0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | inf |
| 10 | 0.000000 | 28.293939 | 4.503120 | 4.503120 | -0.000000 | 0.222068 |
| 11 | 0.000000 | 29.271318 | 4.658675 | 4.658675 | -0.000000 | 0.214653 |
| 12 | 0.000000 | 54.780234 | 8.718545 | 8.718545 | -0.000000 | 0.114698 |
| 13 | 0.000000 | 58.999779 | 9.390106 | 9.390106 | -0.000000 | 0.106495 |
| 14 | 0.000000 | 70.520741 | 11.223724 | 11.223724 | -0.000000 | 0.089097 |
| 15 | 0.000000 | 76.917111 | 12.241738 | 12.241738 | -0.000000 | 0.081688 |
| 16 | 0.000000 | 87.324076 | 13.898058 | 13.898058 | -0.000000 | 0.071952 |
| 17 | 0.000000 | 108.035577 | 17.194396 | 17.194396 | -0.000000 | 0.058158 |
| 18 | 0.000000 | 119.692139 | 19.049596 | 19.049596 | -0.000000 | 0.052495 |
| 19 | 0.000000 | 133.495187 | 21.246419 | 21.246419 | -0.000000 | 0.047067 |
| 20 | 0.000000 | 134.444788 | 21.397553 | 21.397553 | -0.000000 | 0.046734 |
| 21 | 0.000000 | 151.060442 | 24.042016 | 24.042016 | -0.000000 | 0.041594 |
| 22 | 0.000000 | 159.369020 | 25.364367 | 25.364367 | -0.000000 | 0.039425 |
| 23 | 0.000000 | 171.256102 | 27.256255 | 27.256255 | -0.000000 | 0.036689 |
| 24 | 0.000000 | 173.895881 | 27.676389 | 27.676389 | -0.000000 | 0.036132 |
| 25 | 0.000000 | 199.016557 | 31.674469 | 31.674469 | -0.000000 | 0.031571 |
| 26 | 0.000000 | 205.412581 | 32.692428 | 32.692428 | -0.000000 | 0.030588 |
| 27 | 0.000000 | 205.419531 | 32.693534 | 32.693534 | -0.000000 | 0.030587 |
| 28 | 0.000000 | 223.563796 | 35.581283 | 35.581283 | -0.000000 | 0.028105 |
| 29 | 0.000000 | 227.924750 | 36.275351 | 36.275351 | -0.000000 | 0.027567 |
Generating an instance of LinearAssembler
Variable linearisation_tstep has no assigned value in the settings file.
will default to the value: c_int(-1)
Generating an instance of LinearAeroelastic
Variable uvlm_filename has no assigned value in the settings file.
will default to the value:
Generating an instance of LinearUVLM
Variable ScalingDict has no assigned value in the settings file.
will default to the value: {}
Variable gust_assembler has no assigned value in the settings file.
will default to the value:
Variable rom_method has no assigned value in the settings file.
will default to the value: []
Variable rom_method_settings has no assigned value in the settings file.
will default to the value: {}
Variable length has no assigned value in the settings file.
will default to the value: 1.0
Variable speed has no assigned value in the settings file.
will default to the value: 1.0
Variable density has no assigned value in the settings file.
will default to the value: 1.0
Initialising Static linear UVLM solver class...
...done in 0.27 sec
State-space realisation of UVLM equations started...
state-space model produced in form:
x_{n+1} = A x_{n} + Bp u_{n+1}
...done in 2.44 sec
Generating an instance of LinearBeam
Variable remove_sym_modes has no assigned value in the settings file.
will default to the value: False
Warning, projecting system with damping onto undamped modes
Linearising gravity terms...
M = 187.12 kg
X_CG A -> 1.19 -0.00 0.01
Node 1 -> B 0.000 -0.089 -0.000
-> A 0.089 0.206 0.000
-> G 0.089 0.206 -0.007
Node mass:
Matrix: 2.6141
Node 2 -> B -0.010 -0.019 -0.000
-> A 0.019 0.403 0.000
-> G 0.019 0.403 -0.001
Node mass:
Matrix: 7.3672
Node 3 -> B -0.019 -0.087 -0.000
-> A 0.234 0.800 0.000
-> G 0.234 0.800 -0.018
Node mass:
Matrix: 5.8780
Node 4 -> B -0.019 -0.084 -0.000
-> A 0.390 1.238 0.001
-> G 0.389 1.238 -0.030
Node mass:
Matrix: 2.8288
Node 5 -> B -0.018 -0.081 -0.000
-> A 0.546 1.676 0.001
-> G 0.544 1.676 -0.041
Node mass:
Matrix: 5.4372
Node 6 -> B -0.017 -0.078 -0.000
-> A 0.702 2.113 0.002
-> G 0.700 2.113 -0.053
Node mass:
Matrix: 2.6084
Node 7 -> B -0.016 -0.074 -0.000
-> A 0.857 2.551 0.003
-> G 0.855 2.551 -0.064
Node mass:
Matrix: 4.9963
Node 8 -> B -0.016 -0.071 -0.000
-> A 1.013 2.988 0.004
-> G 1.010 2.988 -0.076
Node mass:
Matrix: 2.3879
Node 9 -> B -0.015 -0.068 -0.000
-> A 1.169 3.426 0.005
-> G 1.166 3.426 -0.087
Node mass:
Matrix: 4.5555
Node 10 -> B -0.014 -0.065 -0.000
-> A 1.325 3.863 0.006
-> G 1.321 3.863 -0.098
Node mass:
Matrix: 2.1675
Node 11 -> B -0.013 -0.061 -0.000
-> A 1.480 4.301 0.007
-> G 1.476 4.301 -0.109
Node mass:
Matrix: 4.1146
Node 12 -> B -0.013 -0.058 -0.000
-> A 1.636 4.739 0.009
-> G 1.632 4.739 -0.120
Node mass:
Matrix: 1.9471
Node 13 -> B -0.012 -0.055 -0.000
-> A 1.792 5.176 0.010
-> G 1.787 5.176 -0.131
Node mass:
Matrix: 3.6738
Node 14 -> B -0.011 -0.052 -0.000
-> A 1.948 5.614 0.011
-> G 1.943 5.614 -0.142
Node mass:
Matrix: 1.7267
Node 15 -> B -0.011 -0.048 -0.000
-> A 2.104 6.052 0.012
-> G 2.098 6.052 -0.153
Node mass:
Matrix: 3.2329
Node 16 -> B -0.010 -0.045 -0.000
-> A 2.260 6.489 0.014
-> G 2.254 6.489 -0.164
Node mass:
Matrix: 1.5062
Node 17 -> B -0.009 -0.042 -0.000
-> A 2.415 6.927 0.015
-> G 2.409 6.927 -0.175
Node mass:
Matrix: 2.7921
Node 18 -> B -0.008 -0.039 -0.000
-> A 2.571 7.364 0.016
-> G 2.564 7.364 -0.186
Node mass:
Matrix: 1.2858
Node 19 -> B -0.008 -0.035 -0.000
-> A 2.727 7.802 0.017
-> G 2.720 7.802 -0.197
Node mass:
Matrix: 2.3512
Node 20 -> B -0.007 -0.032 -0.000
-> A 2.883 8.239 0.019
-> G 2.875 8.239 -0.208
Node mass:
Matrix: 1.0654
Node 21 -> B -0.006 -0.028 -0.000
-> A 3.038 8.677 0.020
-> G 3.030 8.677 -0.219
Node mass:
Matrix: 1.9104
Node 22 -> B -0.006 -0.026 -0.000
-> A 3.194 9.114 0.021
-> G 3.186 9.114 -0.230
Node mass:
Matrix: 0.8450
Node 23 -> B -0.005 -0.022 -0.000
-> A 3.350 9.552 0.023
-> G 3.341 9.552 -0.241
Node mass:
Matrix: 1.4695
Node 24 -> B -0.005 -0.022 -0.000
-> A 3.508 9.988 0.024
-> G 3.499 9.988 -0.252
Node mass:
Matrix: 0.3674
Node 25 -> B 0.000 0.089 -0.000
-> A 0.089 -0.206 0.000
-> G 0.089 -0.206 -0.007
Node mass:
Matrix: 2.6141
Node 26 -> B -0.010 0.019 -0.000
-> A 0.019 -0.403 0.000
-> G 0.019 -0.403 -0.001
Node mass:
Matrix: 7.3672
Node 27 -> B -0.019 0.087 -0.000
-> A 0.234 -0.800 0.000
-> G 0.234 -0.800 -0.018
Node mass:
Matrix: 5.8780
Node 28 -> B -0.019 0.084 -0.000
-> A 0.390 -1.238 0.001
-> G 0.389 -1.238 -0.030
Node mass:
Matrix: 2.8288
Node 29 -> B -0.018 0.081 -0.000
-> A 0.546 -1.676 0.001
-> G 0.544 -1.676 -0.041
Node mass:
Matrix: 5.4372
Node 30 -> B -0.017 0.078 -0.000
-> A 0.702 -2.113 0.002
-> G 0.700 -2.113 -0.053
Node mass:
Matrix: 2.6084
Node 31 -> B -0.016 0.074 -0.000
-> A 0.857 -2.551 0.003
-> G 0.855 -2.551 -0.064
Node mass:
Matrix: 4.9963
Node 32 -> B -0.016 0.071 -0.000
-> A 1.013 -2.988 0.004
-> G 1.010 -2.988 -0.076
Node mass:
Matrix: 2.3879
Node 33 -> B -0.015 0.068 -0.000
-> A 1.169 -3.426 0.005
-> G 1.166 -3.426 -0.087
Node mass:
Matrix: 4.5555
Node 34 -> B -0.014 0.065 -0.000
-> A 1.325 -3.863 0.006
-> G 1.321 -3.863 -0.098
Node mass:
Matrix: 2.1675
Node 35 -> B -0.013 0.061 -0.000
-> A 1.480 -4.301 0.007
-> G 1.476 -4.301 -0.109
Node mass:
Matrix: 4.1146
Node 36 -> B -0.013 0.058 -0.000
-> A 1.636 -4.739 0.009
-> G 1.632 -4.739 -0.120
Node mass:
Matrix: 1.9471
Node 37 -> B -0.012 0.055 -0.000
-> A 1.792 -5.176 0.010
-> G 1.787 -5.176 -0.131
Node mass:
Matrix: 3.6738
Node 38 -> B -0.011 0.052 -0.000
-> A 1.948 -5.614 0.011
-> G 1.943 -5.614 -0.142
Node mass:
Matrix: 1.7267
Node 39 -> B -0.011 0.048 -0.000
-> A 2.104 -6.052 0.012
-> G 2.098 -6.052 -0.153
Node mass:
Matrix: 3.2329
Node 40 -> B -0.010 0.045 -0.000
-> A 2.260 -6.489 0.014
-> G 2.254 -6.489 -0.164
Node mass:
Matrix: 1.5062
Node 41 -> B -0.009 0.042 -0.000
-> A 2.415 -6.927 0.015
-> G 2.409 -6.927 -0.175
Node mass:
Matrix: 2.7921
Node 42 -> B -0.008 0.039 -0.000
-> A 2.571 -7.364 0.016
-> G 2.564 -7.364 -0.186
Node mass:
Matrix: 1.2858
Node 43 -> B -0.008 0.035 -0.000
-> A 2.727 -7.802 0.017
-> G 2.720 -7.802 -0.197
Node mass:
Matrix: 2.3512
Node 44 -> B -0.007 0.032 -0.000
-> A 2.883 -8.239 0.019
-> G 2.875 -8.239 -0.208
Node mass:
Matrix: 1.0654
Node 45 -> B -0.006 0.028 -0.000
-> A 3.038 -8.677 0.020
-> G 3.030 -8.677 -0.219
Node mass:
Matrix: 1.9104
Node 46 -> B -0.006 0.026 -0.000
-> A 3.194 -9.114 0.021
-> G 3.186 -9.114 -0.230
Node mass:
Matrix: 0.8450
Node 47 -> B -0.005 0.022 -0.000
-> A 3.350 -9.552 0.023
-> G 3.341 -9.552 -0.241
Node mass:
Matrix: 1.4695
Node 48 -> B -0.005 0.022 -0.000
-> A 3.508 -9.988 0.024
-> G 3.499 -9.988 -0.252
Node mass:
Matrix: 0.3674
Updated the beam C, modal C and K matrices with the terms from the
gravity linearisation
Aeroelastic system assembled:
Aerodynamic states: 1536
Structural states: 594
Total states: 2130
Inputs: 893
Outputs: 891
Generating an instance of AsymptoticStability
Variable reference_velocity has no assigned value in the settings file.
will default to the value: c_double(1.0)
Variable display_root_locus has no assigned value in the settings file.
will default to the value: c_bool(False)
Variable velocity_analysis has no assigned value in the settings file.
will default to the value: []
Variable modes_to_plot has no assigned value in the settings file.
will default to the value: []
Variable postprocessors has no assigned value in the settings file.
will default to the value: []
Variable postprocessors_settings has no assigned value in the settings file.
will default to the value: {}
Dynamical System Eigenvalues
|==============|==============|==============|==============|==============|==============|==============|
| mode | eval_real | eval_imag | freq_n (Hz) | freq_d (Hz) | damping | period (s) |
|==============|==============|==============|==============|==============|==============|==============|
| 0 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | inf |
| 1 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | inf |
| 2 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | inf |
| 3 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | inf |
| 4 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | inf |
| 5 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | inf |
| 6 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | inf |
| 7 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | inf |
| 8 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | inf |
| 9 | -0.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | inf |
| 10 | -0.000884 | 0.321695 | 0.051200 | 0.051199 | 0.002749 | 19.531499 |
| 11 | -0.000884 | -0.321695 | 0.051200 | 0.051199 | 0.002749 | 19.531499 |
| 12 | -0.008471 | -0.391290 | 0.062290 | 0.062276 | 0.021644 | 16.057627 |
| 13 | -0.008471 | 0.391290 | 0.062290 | 0.062276 | 0.021644 | 16.057627 |
| 14 | -0.022506 | 0.000000 | 0.003582 | 0.000000 | 1.000000 | inf |
| 15 | -0.064807 | -53.732340 | 8.551774 | 8.551767 | 0.001206 | 0.116935 |
| 16 | -0.064807 | 53.732340 | 8.551774 | 8.551767 | 0.001206 | 0.116935 |
| 17 | -0.101946 | 68.319126 | 10.873339 | 10.873327 | 0.001492 | 0.091968 |
| 18 | -0.101946 | -68.319126 | 10.873339 | 10.873327 | 0.001492 | 0.091968 |
| 19 | -0.147587 | 83.265087 | 13.252071 | 13.252050 | 0.001772 | 0.075460 |
| 20 | -0.147587 | -83.265087 | 13.252071 | 13.252050 | 0.001772 | 0.075460 |
| 21 | -0.248703 | 109.925761 | 17.495273 | 17.495228 | 0.002262 | 0.057158 |
| 22 | -0.248703 | -109.925761 | 17.495273 | 17.495228 | 0.002262 | 0.057158 |
| 23 | -0.293471 | -120.387486 | 19.160320 | 19.160263 | 0.002438 | 0.052191 |
| 24 | -0.293471 | 120.387486 | 19.160320 | 19.160263 | 0.002438 | 0.052191 |
| 25 | -0.350319 | -132.903267 | 21.152285 | 21.152212 | 0.002636 | 0.047276 |
| 26 | -0.350319 | 132.903267 | 21.152285 | 21.152212 | 0.002636 | 0.047276 |
| 27 | -0.376400 | -138.516845 | 22.045722 | 22.045641 | 0.002717 | 0.045360 |
| 28 | -0.376400 | 138.516845 | 22.045722 | 22.045641 | 0.002717 | 0.045360 |
| 29 | -0.494445 | -162.714219 | 25.896892 | 25.896772 | 0.003039 | 0.038615 |
| 30 | -0.494445 | 162.714219 | 25.896892 | 25.896772 | 0.003039 | 0.038615 |
| 31 | -0.511650 | 166.238203 | 26.457757 | 26.457632 | 0.003078 | 0.037796 |
| 32 | -0.511650 | -166.238203 | 26.457757 | 26.457632 | 0.003078 | 0.037796 |
| 33 | -0.559180 | 175.709808 | 27.965226 | 27.965084 | 0.003182 | 0.035759 |
| 34 | -0.559180 | -175.709808 | 27.965226 | 27.965084 | 0.003182 | 0.035759 |
| 35 | -0.569755 | -177.873185 | 28.309542 | 28.309397 | 0.003203 | 0.035324 |
| 36 | -0.569755 | 177.873185 | 28.309542 | 28.309397 | 0.003203 | 0.035324 |
| 37 | -0.669914 | -197.999013 | 31.512702 | 31.512522 | 0.003383 | 0.031733 |
| 38 | -0.669914 | 197.999013 | 31.512702 | 31.512522 | 0.003383 | 0.031733 |
| 39 | -0.678424 | -199.782668 | 31.796582 | 31.796399 | 0.003396 | 0.031450 |
| 40 | -0.678424 | 199.782668 | 31.796582 | 31.796399 | 0.003396 | 0.031450 |
| 41 | -0.715684 | -207.440558 | 33.015387 | 33.015190 | 0.003450 | 0.030289 |
| 42 | -0.715684 | 207.440558 | 33.015387 | 33.015190 | 0.003450 | 0.030289 |
| 43 | -0.721193 | -208.622990 | 33.203578 | 33.203380 | 0.003457 | 0.030117 |
| 44 | -0.721193 | 208.622990 | 33.203578 | 33.203380 | 0.003457 | 0.030117 |
| 45 | -0.796838 | -224.809925 | 35.779836 | 35.779611 | 0.003544 | 0.027949 |
| 46 | -0.796838 | 224.809925 | 35.779836 | 35.779611 | 0.003544 | 0.027949 |
| 47 | -0.801462 | -225.851206 | 35.945562 | 35.945336 | 0.003549 | 0.027820 |
| 48 | -0.801462 | 225.851206 | 35.945562 | 35.945336 | 0.003549 | 0.027820 |
| 49 | -0.823221 | -257.880049 | 41.043094 | 41.042885 | 0.003192 | 0.024365 |
| 50 | -0.823221 | 257.880049 | 41.043094 | 41.042885 | 0.003192 | 0.024365 |
| 51 | -0.829849 | 232.223375 | 36.959734 | 36.959498 | 0.003573 | 0.027057 |
| 52 | -0.829849 | -232.223375 | 36.959734 | 36.959498 | 0.003573 | 0.027057 |
| 53 | -0.833132 | 232.986709 | 37.081224 | 37.080986 | 0.003576 | 0.026968 |
| 54 | -0.833132 | -232.986709 | 37.081224 | 37.080986 | 0.003576 | 0.026968 |
| 55 | -0.837695 | 252.830753 | 40.239485 | 40.239264 | 0.003313 | 0.024851 |
| 56 | -0.837695 | -252.830753 | 40.239485 | 40.239264 | 0.003313 | 0.024851 |
| 57 | -0.843057 | 274.636583 | 43.709976 | 43.709770 | 0.003070 | 0.022878 |
| 58 | -0.843057 | -274.636583 | 43.709976 | 43.709770 | 0.003070 | 0.022878 |
| 59 | -0.855992 | 264.468482 | 42.091687 | 42.091466 | 0.003237 | 0.023758 |
| 60 | -0.855992 | -264.468482 | 42.091687 | 42.091466 | 0.003237 | 0.023758 |
| 61 | -0.864725 | 271.184097 | 43.160509 | 43.160289 | 0.003189 | 0.023169 |
| 62 | -0.864725 | -271.184097 | 43.160509 | 43.160289 | 0.003189 | 0.023169 |
| 63 | -0.871326 | -283.421753 | 45.108186 | 45.107973 | 0.003074 | 0.022169 |
| 64 | -0.871326 | 283.421753 | 45.108186 | 45.107973 | 0.003074 | 0.022169 |
| 65 | -0.878446 | -267.336880 | 42.548216 | 42.547986 | 0.003286 | 0.023503 |
| 66 | -0.878446 | 267.336880 | 42.548216 | 42.547986 | 0.003286 | 0.023503 |
| 67 | -0.882869 | -280.833492 | 44.696259 | 44.696038 | 0.003144 | 0.022373 |
| 68 | -0.882869 | 280.833492 | 44.696259 | 44.696038 | 0.003144 | 0.022373 |
| 69 | -0.884024 | 245.027541 | 38.997598 | 38.997344 | 0.003608 | 0.025643 |
| 70 | -0.884024 | -245.027541 | 38.997598 | 38.997344 | 0.003608 | 0.025643 |
| 71 | -0.886589 | -245.661872 | 39.098556 | 39.098301 | 0.003609 | 0.025577 |
| 72 | -0.886589 | 245.661872 | 39.098556 | 39.098301 | 0.003609 | 0.025577 |
| 73 | -0.891211 | 288.915187 | 45.982499 | 45.982280 | 0.003085 | 0.021748 |
| 74 | -0.891211 | -288.915187 | 45.982499 | 45.982280 | 0.003085 | 0.021748 |
| 75 | -0.908699 | 251.206722 | 39.981053 | 39.980792 | 0.003617 | 0.025012 |
| 76 | -0.908699 | -251.206722 | 39.981053 | 39.980792 | 0.003617 | 0.025012 |
| 77 | -0.910251 | 251.606123 | 40.044620 | 40.044358 | 0.003618 | 0.024972 |
| 78 | -0.910251 | -251.606123 | 40.044620 | 40.044358 | 0.003618 | 0.024972 |
| 79 | -0.914189 | -241.156654 | 38.381549 | 38.381274 | 0.003791 | 0.026054 |
| 80 | -0.914189 | 241.156654 | 38.381549 | 38.381274 | 0.003791 | 0.026054 |
| 81 | -0.915396 | 290.517028 | 46.237451 | 46.237221 | 0.003151 | 0.021628 |
| 82 | -0.915396 | -290.517028 | 46.237451 | 46.237221 | 0.003151 | 0.021628 |
| 83 | -0.933975 | 278.955366 | 44.397374 | 44.397125 | 0.003348 | 0.022524 |
| 84 | -0.933975 | -278.955366 | 44.397374 | 44.397125 | 0.003348 | 0.022524 |
| 85 | -0.943144 | 260.320871 | 41.431625 | 41.431353 | 0.003623 | 0.024136 |
| 86 | -0.943144 | -260.320871 | 41.431625 | 41.431353 | 0.003623 | 0.024136 |
| 87 | -0.944542 | 260.700477 | 41.492042 | 41.491770 | 0.003623 | 0.024101 |
| 88 | -0.944542 | -260.700477 | 41.492042 | 41.491770 | 0.003623 | 0.024101 |
| 89 | -0.953005 | 294.814043 | 46.921357 | 46.921112 | 0.003233 | 0.021312 |
| 90 | -0.953005 | -294.814043 | 46.921357 | 46.921112 | 0.003233 | 0.021312 |
| 91 | -0.960628 | 295.652741 | 47.054843 | 47.054595 | 0.003249 | 0.021252 |
| 92 | -0.960628 | -295.652741 | 47.054843 | 47.054595 | 0.003249 | 0.021252 |
| 93 | -0.960976 | 265.315973 | 42.226626 | 42.226349 | 0.003622 | 0.023682 |
| 94 | -0.960976 | -265.315973 | 42.226626 | 42.226349 | 0.003622 | 0.023682 |
| 95 | -0.961740 | -300.017780 | 47.749558 | 47.749313 | 0.003206 | 0.020943 |
| 96 | -0.961740 | 300.017780 | 47.749558 | 47.749313 | 0.003206 | 0.020943 |
| 97 | -0.961940 | -265.596058 | 42.271203 | 42.270926 | 0.003622 | 0.023657 |
| 98 | -0.961940 | 265.596058 | 42.271203 | 42.270926 | 0.003622 | 0.023657 |
| 99 | -0.965384 | 266.582845 | 42.428256 | 42.427978 | 0.003621 | 0.023569 |
| 100 | -0.965384 | -266.582845 | 42.428256 | 42.427978 | 0.003621 | 0.023569 |
| 101 | -0.968899 | -235.916658 | 37.547619 | 37.547302 | 0.004107 | 0.026633 |
| 102 | -0.968899 | 235.916658 | 37.547619 | 37.547302 | 0.004107 | 0.026633 |
| 103 | -0.969126 | 301.069959 | 47.917020 | 47.916772 | 0.003219 | 0.020870 |
| 104 | -0.969126 | -301.069959 | 47.917020 | 47.916772 | 0.003219 | 0.020870 |
| 105 | -0.977774 | -281.665806 | 44.828775 | 44.828505 | 0.003471 | 0.022307 |
| 106 | -0.977774 | 281.665806 | 44.828775 | 44.828505 | 0.003471 | 0.022307 |
| 107 | -0.984431 | -272.268138 | 43.333103 | 43.332820 | 0.003616 | 0.023077 |
| 108 | -0.984431 | 272.268138 | 43.333103 | 43.332820 | 0.003616 | 0.023077 |
| 109 | -0.985003 | 251.399896 | 40.011843 | 40.011536 | 0.003918 | 0.024993 |
| 110 | -0.985003 | -251.399896 | 40.011843 | 40.011536 | 0.003918 | 0.024993 |
| 111 | -0.985198 | -272.494340 | 43.369105 | 43.368821 | 0.003615 | 0.023058 |
| 112 | -0.985198 | 272.494340 | 43.369105 | 43.368821 | 0.003615 | 0.023058 |
| 113 | -0.998111 | 276.558228 | 44.015896 | 44.015609 | 0.003609 | 0.022719 |
| 114 | -0.998111 | -276.558228 | 44.015896 | 44.015609 | 0.003609 | 0.022719 |
| 115 | -0.998802 | 276.771420 | 44.049826 | 44.049540 | 0.003609 | 0.022702 |
| 116 | -0.998802 | -276.771420 | 44.049826 | 44.049540 | 0.003609 | 0.022702 |
| 117 | -1.002609 | -296.732610 | 47.226731 | 47.226462 | 0.003379 | 0.021175 |
| 118 | -1.002609 | 296.732610 | 47.226731 | 47.226462 | 0.003379 | 0.021175 |
| 119 | -1.006593 | -246.344800 | 39.207320 | 39.206993 | 0.004086 | 0.025506 |
| 120 | -1.006593 | 246.344800 | 39.207320 | 39.206993 | 0.004086 | 0.025506 |
| 121 | -1.012564 | -297.793229 | 47.395538 | 47.395264 | 0.003400 | 0.021099 |
| 122 | -1.012564 | 297.793229 | 47.395538 | 47.395264 | 0.003400 | 0.021099 |
| 123 | -1.014283 | 306.354455 | 48.758093 | 48.757826 | 0.003311 | 0.020510 |
| 124 | -1.014283 | -306.354455 | 48.758093 | 48.757826 | 0.003311 | 0.020510 |
| 125 | -1.014361 | 281.941928 | 44.872742 | 44.872451 | 0.003598 | 0.022285 |
| 126 | -1.014361 | -281.941928 | 44.872742 | 44.872451 | 0.003598 | 0.022285 |
| 127 | -1.014860 | 282.102785 | 44.898343 | 44.898053 | 0.003597 | 0.022273 |
| 128 | -1.014860 | -282.102785 | 44.898343 | 44.898053 | 0.003597 | 0.022273 |
| 129 | -1.017175 | -306.227153 | 48.737834 | 48.737565 | 0.003322 | 0.020518 |
| 130 | -1.017175 | 306.227153 | 48.737834 | 48.737565 | 0.003322 | 0.020518 |
| 131 | -1.017450 | 57.533524 | 9.158176 | 9.156745 | 0.017682 | 0.109209 |
| 132 | -1.017450 | -57.533524 | 9.158176 | 9.156745 | 0.017682 | 0.109209 |
| 133 | -1.021012 | 310.599833 | 49.433766 | 49.433499 | 0.003287 | 0.020229 |
| 134 | -1.021012 | -310.599833 | 49.433766 | 49.433499 | 0.003287 | 0.020229 |
| 135 | -1.021452 | 310.492397 | 49.416667 | 49.416400 | 0.003290 | 0.020236 |
| 136 | -1.021452 | -310.492397 | 49.416667 | 49.416400 | 0.003290 | 0.020236 |
| 137 | -1.022875 | -284.908060 | 45.344818 | 45.344526 | 0.003590 | 0.022053 |
| 138 | -1.022875 | 284.908060 | 45.344818 | 45.344526 | 0.003590 | 0.022053 |
| 139 | -1.023294 | 285.048653 | 45.367195 | 45.366902 | 0.003590 | 0.022043 |
| 140 | -1.023294 | -285.048653 | 45.367195 | 45.366902 | 0.003590 | 0.022043 |
| 141 | -1.036388 | -289.874565 | 46.135265 | 46.134970 | 0.003575 | 0.021676 |
| 142 | -1.036388 | 289.874565 | 46.135265 | 46.134970 | 0.003575 | 0.021676 |
| 143 | -1.036747 | -290.000394 | 46.155291 | 46.154996 | 0.003575 | 0.021666 |
| 144 | -1.036747 | 290.000394 | 46.155291 | 46.154996 | 0.003575 | 0.021666 |
| 145 | -1.040407 | 291.418922 | 46.381058 | 46.380762 | 0.003570 | 0.021561 |
| 146 | -1.040407 | -291.418922 | 46.381058 | 46.380762 | 0.003570 | 0.021561 |
| 147 | -1.040753 | 291.545493 | 46.401202 | 46.400906 | 0.003570 | 0.021551 |
| 148 | -1.040753 | -291.545493 | 46.401202 | 46.400906 | 0.003570 | 0.021551 |
| 149 | -1.041948 | 304.815949 | 48.513248 | 48.512965 | 0.003418 | 0.020613 |
| 150 | -1.041948 | -304.815949 | 48.513248 | 48.512965 | 0.003418 | 0.020613 |
| 151 | -1.042964 | -314.673618 | 50.082137 | 50.081862 | 0.003314 | 0.019967 |
| 152 | -1.042964 | 314.673618 | 50.082137 | 50.081862 | 0.003314 | 0.019967 |
| 153 | -1.043286 | -307.905151 | 49.004908 | 49.004627 | 0.003388 | 0.020406 |
| 154 | -1.043286 | 307.905151 | 49.004908 | 49.004627 | 0.003388 | 0.020406 |
| 155 | -1.044327 | 308.342971 | 49.074590 | 49.074308 | 0.003387 | 0.020377 |
| 156 | -1.044327 | -308.342971 | 49.074590 | 49.074308 | 0.003387 | 0.020377 |
| 157 | -1.046009 | -304.875396 | 48.522712 | 48.522426 | 0.003431 | 0.020609 |
| 158 | -1.046009 | 304.875396 | 48.522712 | 48.522426 | 0.003431 | 0.020609 |
| 159 | -1.047589 | 314.548401 | 50.062210 | 50.061933 | 0.003330 | 0.019975 |
| 160 | -1.047589 | -314.548401 | 50.062210 | 50.061933 | 0.003330 | 0.019975 |
| 161 | -1.049126 | -306.882777 | 48.842196 | 48.841911 | 0.003419 | 0.020474 |
| 162 | -1.049126 | 306.882777 | 48.842196 | 48.841911 | 0.003419 | 0.020474 |
| 163 | -1.050232 | 295.362748 | 47.008739 | 47.008441 | 0.003556 | 0.021273 |
| 164 | -1.050232 | -295.362748 | 47.008739 | 47.008441 | 0.003556 | 0.021273 |
| 165 | -1.050553 | -295.497323 | 47.030157 | 47.029860 | 0.003555 | 0.021263 |
| 166 | -1.050553 | 295.497323 | 47.030157 | 47.029860 | 0.003555 | 0.021263 |
| 167 | -1.051548 | -295.907799 | 47.095486 | 47.095189 | 0.003554 | 0.021234 |
| 168 | -1.051548 | 295.907799 | 47.095486 | 47.095189 | 0.003554 | 0.021234 |
| 169 | -1.051948 | 296.064745 | 47.120465 | 47.120168 | 0.003553 | 0.021222 |
| 170 | -1.051948 | -296.064745 | 47.120465 | 47.120168 | 0.003553 | 0.021222 |
| 171 | -1.054264 | -306.923573 | 48.848692 | 48.848404 | 0.003435 | 0.020471 |
| 172 | -1.054264 | 306.923573 | 48.848692 | 48.848404 | 0.003435 | 0.020471 |
| 173 | -1.054520 | -318.465849 | 50.685692 | 50.685414 | 0.003311 | 0.019730 |
| 174 | -1.054520 | 318.465849 | 50.685692 | 50.685414 | 0.003311 | 0.019730 |
| 175 | -1.055288 | -318.515081 | 50.693528 | 50.693250 | 0.003313 | 0.019726 |
| 176 | -1.055288 | 318.515081 | 50.693528 | 50.693250 | 0.003313 | 0.019726 |
| 177 | -1.057440 | 314.897307 | 50.117746 | 50.117463 | 0.003358 | 0.019953 |
| 178 | -1.057440 | -314.897307 | 50.117746 | 50.117463 | 0.003358 | 0.019953 |
| 179 | -1.058199 | -309.920136 | 49.325609 | 49.325322 | 0.003414 | 0.020274 |
| 180 | -1.058199 | 309.920136 | 49.325609 | 49.325322 | 0.003414 | 0.020274 |
| 181 | -1.059262 | 299.214097 | 47.621701 | 47.621403 | 0.003540 | 0.020999 |
| 182 | -1.059262 | -299.214097 | 47.621701 | 47.621403 | 0.003540 | 0.020999 |
| 183 | -1.059504 | -299.314232 | 47.637638 | 47.637340 | 0.003540 | 0.020992 |
| 184 | -1.059504 | 299.314232 | 47.637638 | 47.637340 | 0.003540 | 0.020992 |
| 185 | -1.060555 | -299.787498 | 47.712961 | 47.712662 | 0.003538 | 0.020959 |
| 186 | -1.060555 | 299.787498 | 47.712961 | 47.712662 | 0.003538 | 0.020959 |
| 187 | -1.060658 | -309.965877 | 49.332890 | 49.332602 | 0.003422 | 0.020271 |
| 188 | -1.060658 | 309.965877 | 49.332890 | 49.332602 | 0.003422 | 0.020271 |
| 189 | -1.060760 | 299.897460 | 47.730462 | 47.730163 | 0.003537 | 0.020951 |
| 190 | -1.060760 | -299.897460 | 47.730462 | 47.730163 | 0.003537 | 0.020951 |
| 191 | -1.064660 | 315.237918 | 50.171959 | 50.171673 | 0.003377 | 0.019932 |
| 192 | -1.064660 | -315.237918 | 50.171959 | 50.171673 | 0.003377 | 0.019932 |
| 193 | -1.065948 | -313.067380 | 49.826510 | 49.826221 | 0.003405 | 0.020070 |
| 194 | -1.065948 | 313.067380 | 49.826510 | 49.826221 | 0.003405 | 0.020070 |
| 195 | -1.066182 | 312.991749 | 49.814473 | 49.814184 | 0.003406 | 0.020075 |
| 196 | -1.066182 | -312.991749 | 49.814473 | 49.814184 | 0.003406 | 0.020075 |
| 197 | -1.070206 | 304.267646 | 48.425999 | 48.425700 | 0.003517 | 0.020650 |
| 198 | -1.070206 | -304.267646 | 48.425999 | 48.425700 | 0.003517 | 0.020650 |
| 199 | -1.070296 | 304.308945 | 48.432572 | 48.432273 | 0.003517 | 0.020647 |
| 200 | -1.070296 | -304.308945 | 48.432572 | 48.432273 | 0.003517 | 0.020647 |
| 201 | -1.071416 | -304.858400 | 48.520021 | 48.519721 | 0.003514 | 0.020610 |
| 202 | -1.071416 | 304.858400 | 48.520021 | 48.519721 | 0.003514 | 0.020610 |
| 203 | -1.071537 | -304.918001 | 48.529507 | 48.529207 | 0.003514 | 0.020606 |
| 204 | -1.071537 | 304.918001 | 48.529507 | 48.529207 | 0.003514 | 0.020606 |
| 205 | -1.071722 | -321.513275 | 51.170711 | 51.170427 | 0.003333 | 0.019543 |
| 206 | -1.071722 | 321.513275 | 51.170711 | 51.170427 | 0.003333 | 0.019543 |
| 207 | -1.072773 | -321.531559 | 51.173622 | 51.173337 | 0.003336 | 0.019541 |
| 208 | -1.072773 | 321.531559 | 51.173622 | 51.173337 | 0.003336 | 0.019541 |
| 209 | -1.073011 | 316.543066 | 50.379683 | 50.379394 | 0.003390 | 0.019849 |
| 210 | -1.073011 | -316.543066 | 50.379683 | 50.379394 | 0.003390 | 0.019849 |
| 211 | -1.073122 | -316.594455 | 50.387862 | 50.387573 | 0.003390 | 0.019846 |
| 212 | -1.073122 | 316.594455 | 50.387862 | 50.387573 | 0.003390 | 0.019846 |
| 213 | -1.075633 | 324.572398 | 51.657585 | 51.657302 | 0.003314 | 0.019358 |
| 214 | -1.075633 | -324.572398 | 51.657585 | 51.657302 | 0.003314 | 0.019358 |
| 215 | -1.076300 | -324.607705 | 51.663205 | 51.662921 | 0.003316 | 0.019356 |
| 216 | -1.076300 | 324.607705 | 51.663205 | 51.662921 | 0.003316 | 0.019356 |
| 217 | -1.078724 | 320.140186 | 50.952182 | 50.951893 | 0.003370 | 0.019626 |
| 218 | -1.078724 | -320.140186 | 50.952182 | 50.951893 | 0.003370 | 0.019626 |
| 219 | -1.078925 | 319.933158 | 50.919233 | 50.918944 | 0.003372 | 0.019639 |
| 220 | -1.078925 | -319.933158 | 50.919233 | 50.918944 | 0.003372 | 0.019639 |
| 221 | -1.080029 | 309.288686 | 49.225123 | 49.224823 | 0.003492 | 0.020315 |
| 222 | -1.080029 | -309.288686 | 49.225123 | 49.224823 | 0.003492 | 0.020315 |
| 223 | -1.080630 | 309.618139 | 49.277557 | 49.277257 | 0.003490 | 0.020293 |
| 224 | -1.080630 | -309.618139 | 49.277557 | 49.277257 | 0.003490 | 0.020293 |
| 225 | -1.080975 | 309.794320 | 49.305598 | 49.305297 | 0.003489 | 0.020282 |
| 226 | -1.080975 | -309.794320 | 49.305598 | 49.305297 | 0.003489 | 0.020282 |
| 227 | -1.081038 | 309.828767 | 49.311080 | 49.310780 | 0.003489 | 0.020280 |
| 228 | -1.081038 | -309.828767 | 49.311080 | 49.310780 | 0.003489 | 0.020280 |
| 229 | -1.082433 | 310.602445 | 49.434215 | 49.433914 | 0.003485 | 0.020229 |
| 230 | -1.082433 | -310.602445 | 49.434215 | 49.433914 | 0.003485 | 0.020229 |
| 231 | -1.084088 | 322.662762 | 51.353663 | 51.353373 | 0.003360 | 0.019473 |
| 232 | -1.084088 | -322.662762 | 51.353663 | 51.353373 | 0.003360 | 0.019473 |
| 233 | -1.084503 | -322.669036 | 51.354662 | 51.354372 | 0.003361 | 0.019473 |
| 234 | -1.084503 | 322.669036 | 51.354662 | 51.354372 | 0.003361 | 0.019473 |
| 235 | -1.085005 | -319.745514 | 50.889372 | 50.889079 | 0.003393 | 0.019651 |
| 236 | -1.085005 | 319.745514 | 50.889372 | 50.889079 | 0.003393 | 0.019651 |
| 237 | -1.085145 | 319.750916 | 50.890232 | 50.889939 | 0.003394 | 0.019650 |
| 238 | -1.085145 | -319.750916 | 50.890232 | 50.889939 | 0.003394 | 0.019650 |
| 239 | -1.086265 | -329.094966 | 52.377376 | 52.377091 | 0.003301 | 0.019092 |
| 240 | -1.086265 | 329.094966 | 52.377376 | 52.377091 | 0.003301 | 0.019092 |
| 241 | -1.086372 | -326.932381 | 52.033192 | 52.032904 | 0.003323 | 0.019219 |
| 242 | -1.086372 | 326.932381 | 52.033192 | 52.032904 | 0.003323 | 0.019219 |
| 243 | -1.086417 | 329.063936 | 52.372437 | 52.372152 | 0.003302 | 0.019094 |
| 244 | -1.086417 | -329.063936 | 52.372437 | 52.372152 | 0.003302 | 0.019094 |
| 245 | -1.087051 | 313.245575 | 49.854882 | 49.854582 | 0.003470 | 0.020058 |
| 246 | -1.087051 | -313.245575 | 49.854882 | 49.854582 | 0.003470 | 0.020058 |
| 247 | -1.087414 | 313.457338 | 49.888585 | 49.888285 | 0.003469 | 0.020045 |
| 248 | -1.087414 | -313.457338 | 49.888585 | 49.888285 | 0.003469 | 0.020045 |
| 249 | -1.087499 | 313.508013 | 49.896650 | 49.896350 | 0.003469 | 0.020042 |
| 250 | -1.087499 | -313.508013 | 49.896650 | 49.896350 | 0.003469 | 0.020042 |
| 251 | -1.087543 | 313.538425 | 49.901490 | 49.901190 | 0.003469 | 0.020040 |
| 252 | -1.087543 | -313.538425 | 49.901490 | 49.901190 | 0.003469 | 0.020040 |
| 253 | -1.087735 | 326.918220 | 52.030939 | 52.030651 | 0.003327 | 0.019219 |
| 254 | -1.087735 | -326.918220 | 52.030939 | 52.030651 | 0.003327 | 0.019219 |
| 255 | -1.089451 | 314.692046 | 50.085095 | 50.084795 | 0.003462 | 0.019966 |
| 256 | -1.089451 | -314.692046 | 50.085095 | 50.084795 | 0.003462 | 0.019966 |
| 257 | -1.089795 | -330.845038 | 52.655909 | 52.655623 | 0.003294 | 0.018991 |
| 258 | -1.089795 | 330.845038 | 52.655909 | 52.655623 | 0.003294 | 0.018991 |
| 259 | -1.091434 | -330.806905 | 52.649841 | 52.649554 | 0.003299 | 0.018994 |
| 260 | -1.091434 | 330.806905 | 52.649841 | 52.649554 | 0.003299 | 0.018994 |
| 261 | -1.091577 | 323.712470 | 51.520733 | 51.520440 | 0.003372 | 0.019410 |
| 262 | -1.091577 | -323.712470 | 51.520733 | 51.520440 | 0.003372 | 0.019410 |
| 263 | -1.091720 | -327.088590 | 52.058056 | 52.057766 | 0.003338 | 0.019209 |
| 264 | -1.091720 | 327.088590 | 52.058056 | 52.057766 | 0.003338 | 0.019209 |
| 265 | -1.091742 | -323.846011 | 51.541986 | 51.541693 | 0.003371 | 0.019402 |
| 266 | -1.091742 | 323.846011 | 51.541986 | 51.541693 | 0.003371 | 0.019402 |
| 267 | -1.092874 | 327.210801 | 52.077507 | 52.077216 | 0.003340 | 0.019202 |
| 268 | -1.092874 | -327.210801 | 52.077507 | 52.077216 | 0.003340 | 0.019202 |
| 269 | -1.092906 | -316.871195 | 50.431917 | 50.431617 | 0.003449 | 0.019829 |
| 270 | -1.092906 | 316.871195 | 50.431917 | 50.431617 | 0.003449 | 0.019829 |
| 271 | -1.092933 | 316.892539 | 50.435314 | 50.435014 | 0.003449 | 0.019827 |
| 272 | -1.092933 | -316.892539 | 50.435314 | 50.435014 | 0.003449 | 0.019827 |
| 273 | -1.092962 | 316.907185 | 50.437645 | 50.437345 | 0.003449 | 0.019827 |
| 274 | -1.092962 | -316.907185 | 50.437645 | 50.437345 | 0.003449 | 0.019827 |
| 275 | -1.092985 | -316.926030 | 50.440644 | 50.440344 | 0.003449 | 0.019825 |
| 276 | -1.092985 | 316.926030 | 50.440644 | 50.440344 | 0.003449 | 0.019825 |
| 277 | -1.093283 | -332.332221 | 52.892602 | 52.892316 | 0.003290 | 0.018906 |
| 278 | -1.093283 | 332.332221 | 52.892602 | 52.892316 | 0.003290 | 0.018906 |
| 279 | -1.093458 | 332.343157 | 52.894343 | 52.894056 | 0.003290 | 0.018906 |
| 280 | -1.093458 | -332.343157 | 52.894343 | 52.894056 | 0.003290 | 0.018906 |
| 281 | -1.094656 | 325.174138 | 51.753365 | 51.753071 | 0.003366 | 0.019323 |
| 282 | -1.094656 | -325.174138 | 51.753365 | 51.753071 | 0.003366 | 0.019323 |
| 283 | -1.095311 | 325.124568 | 51.745476 | 51.745182 | 0.003369 | 0.019325 |
| 284 | -1.095311 | -325.124568 | 51.745476 | 51.745182 | 0.003369 | 0.019325 |
| 285 | -1.096829 | -332.066508 | 52.850314 | 52.850026 | 0.003303 | 0.018921 |
| 286 | -1.096829 | 332.066508 | 52.850314 | 52.850026 | 0.003303 | 0.018921 |
| 287 | -1.097490 | -319.989534 | 50.928216 | 50.927916 | 0.003430 | 0.019636 |
| 288 | -1.097490 | 319.989534 | 50.928216 | 50.927916 | 0.003430 | 0.019636 |
| 289 | -1.097493 | 319.994348 | 50.928982 | 50.928682 | 0.003430 | 0.019635 |
| 290 | -1.097493 | -319.994348 | 50.928982 | 50.928682 | 0.003430 | 0.019635 |
| 291 | -1.097519 | -320.011922 | 50.931779 | 50.931479 | 0.003430 | 0.019634 |
| 292 | -1.097519 | 320.011922 | 50.931779 | 50.931479 | 0.003430 | 0.019634 |
| 293 | -1.097543 | -320.026563 | 50.934109 | 50.933809 | 0.003430 | 0.019633 |
| 294 | -1.097543 | 320.026563 | 50.934109 | 50.933809 | 0.003430 | 0.019633 |
| 295 | -1.098669 | -331.385423 | 52.741918 | 52.741628 | 0.003315 | 0.018960 |
| 296 | -1.098669 | 331.385423 | 52.741918 | 52.741628 | 0.003315 | 0.018960 |
| 297 | -1.100859 | -326.436651 | 51.954302 | 51.954007 | 0.003372 | 0.019248 |
| 298 | -1.100859 | 326.436651 | 51.954302 | 51.954007 | 0.003372 | 0.019248 |
| 299 | -1.101053 | -326.436812 | 51.954328 | 51.954032 | 0.003373 | 0.019248 |
| 300 | -1.101053 | 326.436812 | 51.954328 | 51.954032 | 0.003373 | 0.019248 |
| 301 | -1.101292 | 322.822286 | 51.379062 | 51.378763 | 0.003411 | 0.019463 |
| 302 | -1.101292 | -322.822286 | 51.379062 | 51.378763 | 0.003411 | 0.019463 |
| 303 | -1.101293 | 322.823898 | 51.379318 | 51.379019 | 0.003411 | 0.019463 |
| 304 | -1.101293 | -322.823898 | 51.379318 | 51.379019 | 0.003411 | 0.019463 |
| 305 | -1.101309 | 322.834412 | 51.380991 | 51.380692 | 0.003411 | 0.019463 |
| 306 | -1.101309 | -322.834412 | 51.380991 | 51.380692 | 0.003411 | 0.019463 |
| 307 | -1.101331 | 322.849724 | 51.383428 | 51.383129 | 0.003411 | 0.019462 |
| 308 | -1.101331 | -322.849724 | 51.383428 | 51.383129 | 0.003411 | 0.019462 |
| 309 | -1.102161 | -330.407444 | 52.586271 | 52.585978 | 0.003336 | 0.019016 |
| 310 | -1.102161 | 330.407444 | 52.586271 | 52.585978 | 0.003336 | 0.019016 |
| 311 | -1.102206 | -328.348838 | 52.258635 | 52.258341 | 0.003357 | 0.019136 |
| 312 | -1.102206 | 328.348838 | 52.258635 | 52.258341 | 0.003357 | 0.019136 |
| 313 | -1.102281 | -328.322944 | 52.254514 | 52.254220 | 0.003357 | 0.019137 |
| 314 | -1.102281 | 328.322944 | 52.254514 | 52.254220 | 0.003357 | 0.019137 |
| 315 | -1.103460 | 330.498141 | 52.600706 | 52.600413 | 0.003339 | 0.019011 |
| 316 | -1.103460 | -330.498141 | 52.600706 | 52.600413 | 0.003339 | 0.019011 |
| 317 | -1.104404 | -325.357719 | 51.782588 | 51.782289 | 0.003394 | 0.019312 |
| 318 | -1.104404 | 325.357719 | 51.782588 | 51.782289 | 0.003394 | 0.019312 |
| 319 | -1.104408 | -325.362658 | 51.783374 | 51.783075 | 0.003394 | 0.019311 |
| 320 | -1.104408 | 325.362658 | 51.783374 | 51.783075 | 0.003394 | 0.019311 |
| 321 | -1.104432 | 325.380976 | 51.786289 | 51.785991 | 0.003394 | 0.019310 |
| 322 | -1.104432 | -325.380976 | 51.786289 | 51.785991 | 0.003394 | 0.019310 |
| 323 | -1.104447 | -325.392512 | 51.788125 | 51.787827 | 0.003394 | 0.019310 |
| 324 | -1.104447 | 325.392512 | 51.788125 | 51.787827 | 0.003394 | 0.019310 |
| 325 | -1.104643 | 329.605095 | 52.458575 | 52.458280 | 0.003351 | 0.019063 |
| 326 | -1.104643 | -329.605095 | 52.458575 | 52.458280 | 0.003351 | 0.019063 |
| 327 | -1.104721 | 329.588858 | 52.455991 | 52.455696 | 0.003352 | 0.019064 |
| 328 | -1.104721 | -329.588858 | 52.455991 | 52.455696 | 0.003352 | 0.019064 |
| 329 | -1.106744 | -327.432658 | 52.112824 | 52.112526 | 0.003380 | 0.019189 |
| 330 | -1.106744 | 327.432658 | 52.112824 | 52.112526 | 0.003380 | 0.019189 |
| 331 | -1.106932 | 327.609429 | 52.140958 | 52.140660 | 0.003379 | 0.019179 |
| 332 | -1.106932 | -327.609429 | 52.140958 | 52.140660 | 0.003379 | 0.019179 |
| 333 | -1.106956 | -327.628565 | 52.144003 | 52.143706 | 0.003379 | 0.019178 |
| 334 | -1.106956 | 327.628565 | 52.144003 | 52.143706 | 0.003379 | 0.019178 |
| 335 | -1.106973 | 327.644199 | 52.146491 | 52.146194 | 0.003379 | 0.019177 |
| 336 | -1.106973 | -327.644199 | 52.146491 | 52.146194 | 0.003379 | 0.019177 |
| 337 | -1.107211 | -327.869981 | 52.182426 | 52.182128 | 0.003377 | 0.019164 |
| 338 | -1.107211 | 327.869981 | 52.182426 | 52.182128 | 0.003377 | 0.019164 |
| 339 | -1.107565 | 331.532240 | 52.765289 | 52.764995 | 0.003341 | 0.018952 |
| 340 | -1.107565 | -331.532240 | 52.765289 | 52.764995 | 0.003341 | 0.018952 |
| 341 | -1.107916 | -333.461804 | 53.072387 | 53.072094 | 0.003322 | 0.018842 |
| 342 | -1.107916 | 333.461804 | 53.072387 | 53.072094 | 0.003322 | 0.018842 |
| 343 | -1.108211 | 331.513313 | 52.762277 | 52.761983 | 0.003343 | 0.018953 |
| 344 | -1.108211 | -331.513313 | 52.762277 | 52.761983 | 0.003343 | 0.018953 |
| 345 | -1.108216 | -333.455247 | 53.071344 | 53.071051 | 0.003323 | 0.018843 |
| 346 | -1.108216 | 333.455247 | 53.071344 | 53.071051 | 0.003323 | 0.018843 |
| 347 | -1.108440 | 329.055252 | 52.371067 | 52.370770 | 0.003369 | 0.019095 |
| 348 | -1.108440 | -329.055252 | 52.371067 | 52.370770 | 0.003369 | 0.019095 |
| 349 | -1.108951 | 329.564068 | 52.452047 | 52.451750 | 0.003365 | 0.019065 |
| 350 | -1.108951 | -329.564068 | 52.452047 | 52.451750 | 0.003365 | 0.019065 |
| 351 | -1.108969 | 329.582680 | 52.455010 | 52.454713 | 0.003365 | 0.019064 |
| 352 | -1.108969 | -329.582680 | 52.455010 | 52.454713 | 0.003365 | 0.019064 |
| 353 | -1.108985 | 329.604673 | 52.458510 | 52.458213 | 0.003365 | 0.019063 |
| 354 | -1.108985 | -329.604673 | 52.458510 | 52.458213 | 0.003365 | 0.019063 |
| 355 | -1.109008 | 329.624636 | 52.461687 | 52.461390 | 0.003364 | 0.019062 |
| 356 | -1.109008 | -329.624636 | 52.461687 | 52.461390 | 0.003364 | 0.019062 |
| 357 | -1.109656 | -334.561471 | 53.247405 | 53.247112 | 0.003317 | 0.018780 |
| 358 | -1.109656 | 334.561471 | 53.247405 | 53.247112 | 0.003317 | 0.018780 |
| 359 | -1.109672 | -334.545407 | 53.244848 | 53.244555 | 0.003317 | 0.018781 |
| 360 | -1.109672 | 334.545407 | 53.244848 | 53.244555 | 0.003317 | 0.018781 |
| 361 | -1.110193 | -333.282365 | 53.043830 | 53.043536 | 0.003331 | 0.018852 |
| 362 | -1.110193 | 333.282365 | 53.043830 | 53.043536 | 0.003331 | 0.018852 |
| 363 | -1.110333 | -331.008434 | 52.681925 | 52.681628 | 0.003354 | 0.018982 |
| 364 | -1.110333 | 331.008434 | 52.681925 | 52.681628 | 0.003354 | 0.018982 |
| 365 | -1.110341 | 331.018034 | 52.683453 | 52.683156 | 0.003354 | 0.018981 |
| 366 | -1.110341 | -331.018034 | 52.683453 | 52.683156 | 0.003354 | 0.018981 |
| 367 | -1.110385 | -333.294673 | 53.045789 | 53.045495 | 0.003332 | 0.018852 |
| 368 | -1.110385 | 333.294673 | 53.045789 | 53.045495 | 0.003332 | 0.018852 |
| 369 | -1.110518 | 331.208602 | 52.713783 | 52.713486 | 0.003353 | 0.018970 |
| 370 | -1.110518 | -331.208602 | 52.713783 | 52.713486 | 0.003353 | 0.018970 |
| 371 | -1.110520 | 331.214085 | 52.714655 | 52.714359 | 0.003353 | 0.018970 |
| 372 | -1.110520 | -331.214085 | 52.714655 | 52.714359 | 0.003353 | 0.018970 |
| 373 | -1.110649 | 331.351732 | 52.736562 | 52.736266 | 0.003352 | 0.018962 |
| 374 | -1.110649 | -331.351732 | 52.736562 | 52.736266 | 0.003352 | 0.018962 |
| 375 | -1.110652 | -331.363928 | 52.738503 | 52.738207 | 0.003352 | 0.018962 |
| 376 | -1.110652 | 331.363928 | 52.738503 | 52.738207 | 0.003352 | 0.018962 |
| 377 | -1.111317 | -332.101213 | 52.855846 | 52.855550 | 0.003346 | 0.018919 |
| 378 | -1.111317 | 332.101213 | 52.855846 | 52.855550 | 0.003346 | 0.018919 |
| 379 | -1.111358 | -332.145988 | 52.862972 | 52.862676 | 0.003346 | 0.018917 |
| 380 | -1.111358 | 332.145988 | 52.862972 | 52.862676 | 0.003346 | 0.018917 |
| 381 | -1.111730 | -332.575059 | 52.931260 | 52.930965 | 0.003343 | 0.018893 |
| 382 | -1.111730 | 332.575059 | 52.931260 | 52.930965 | 0.003343 | 0.018893 |
| 383 | -1.111730 | 332.577756 | 52.931690 | 52.931394 | 0.003343 | 0.018892 |
| 384 | -1.111730 | -332.577756 | 52.931690 | 52.931394 | 0.003343 | 0.018892 |
| 385 | -1.111733 | -332.582902 | 52.932509 | 52.932213 | 0.003343 | 0.018892 |
| 386 | -1.111733 | 332.582902 | 52.932509 | 52.932213 | 0.003343 | 0.018892 |
| 387 | -1.111733 | 332.581750 | 52.932325 | 52.932029 | 0.003343 | 0.018892 |
| 388 | -1.111733 | -332.581750 | 52.932325 | 52.932029 | 0.003343 | 0.018892 |
| 389 | -1.111895 | -335.183640 | 53.346427 | 53.346133 | 0.003317 | 0.018746 |
| 390 | -1.111895 | 335.183640 | 53.346427 | 53.346133 | 0.003317 | 0.018746 |
| 391 | -1.111918 | -335.185684 | 53.346752 | 53.346459 | 0.003317 | 0.018745 |
| 392 | -1.111918 | 335.185684 | 53.346752 | 53.346459 | 0.003317 | 0.018745 |
| 393 | -1.111977 | -337.042524 | 53.642276 | 53.641984 | 0.003299 | 0.018642 |
| 394 | -1.111977 | 337.042524 | 53.642276 | 53.641984 | 0.003299 | 0.018642 |
| 395 | -1.111984 | 337.038066 | 53.641566 | 53.641274 | 0.003299 | 0.018642 |
| 396 | -1.111984 | -337.038066 | 53.641566 | 53.641274 | 0.003299 | 0.018642 |
| 397 | -1.113433 | 336.128317 | 53.496777 | 53.496483 | 0.003313 | 0.018693 |
| 398 | -1.113433 | -336.128317 | 53.496777 | 53.496483 | 0.003313 | 0.018693 |
| 399 | -1.113437 | 336.131297 | 53.497251 | 53.496957 | 0.003312 | 0.018693 |
| 400 | -1.113437 | -336.131297 | 53.497251 | 53.496957 | 0.003312 | 0.018693 |
| 401 | -1.113648 | -338.105396 | 53.811437 | 53.811145 | 0.003294 | 0.018584 |
| 402 | -1.113648 | 338.105396 | 53.811437 | 53.811145 | 0.003294 | 0.018584 |
| 403 | -1.113653 | -338.102774 | 53.811020 | 53.810728 | 0.003294 | 0.018584 |
| 404 | -1.113653 | 338.102774 | 53.811020 | 53.810728 | 0.003294 | 0.018584 |
| 405 | -1.113881 | 335.273046 | 53.360657 | 53.360363 | 0.003322 | 0.018741 |
| 406 | -1.113881 | -335.273046 | 53.360657 | 53.360363 | 0.003322 | 0.018741 |
| 407 | -1.114271 | 335.810669 | 53.446222 | 53.445928 | 0.003318 | 0.018710 |
| 408 | -1.114271 | -335.810669 | 53.446222 | 53.445928 | 0.003318 | 0.018710 |
| 409 | -1.114682 | -337.420697 | 53.702465 | 53.702172 | 0.003304 | 0.018621 |
| 410 | -1.114682 | 337.420697 | 53.702465 | 53.702172 | 0.003304 | 0.018621 |
| 411 | -1.114685 | -337.421129 | 53.702534 | 53.702241 | 0.003304 | 0.018621 |
| 412 | -1.114685 | 337.421129 | 53.702534 | 53.702241 | 0.003304 | 0.018621 |
| 413 | -1.114745 | -339.534726 | 54.038921 | 54.038630 | 0.003283 | 0.018505 |
| 414 | -1.114745 | 339.534726 | 54.038921 | 54.038630 | 0.003283 | 0.018505 |
| 415 | -1.114754 | 339.527234 | 54.037729 | 54.037438 | 0.003283 | 0.018506 |
| 416 | -1.114754 | -339.527234 | 54.037729 | 54.037438 | 0.003283 | 0.018506 |
| 417 | -1.115312 | 74.207184 | 11.811774 | 11.810440 | 0.015028 | 0.084671 |
| 418 | -1.115312 | -74.207184 | 11.811774 | 11.810440 | 0.015028 | 0.084671 |
| 419 | -1.115588 | 338.574851 | 53.886154 | 53.885861 | 0.003295 | 0.018558 |
| 420 | -1.115588 | -338.574851 | 53.886154 | 53.885861 | 0.003295 | 0.018558 |
| 421 | -1.115590 | 338.573805 | 53.885987 | 53.885695 | 0.003295 | 0.018558 |
| 422 | -1.115590 | -338.573805 | 53.885987 | 53.885695 | 0.003295 | 0.018558 |
| 423 | -1.115783 | -340.920059 | 54.259403 | 54.259113 | 0.003273 | 0.018430 |
| 424 | -1.115783 | 340.920059 | 54.259403 | 54.259113 | 0.003273 | 0.018430 |
| 425 | -1.115870 | 341.161924 | 54.297897 | 54.297607 | 0.003271 | 0.018417 |
| 426 | -1.115870 | -341.161924 | 54.297897 | 54.297607 | 0.003271 | 0.018417 |
| 427 | -1.115916 | 340.879701 | 54.252980 | 54.252689 | 0.003274 | 0.018432 |
| 428 | -1.115916 | -340.879701 | 54.252980 | 54.252689 | 0.003274 | 0.018432 |
| 429 | -1.116022 | -341.105628 | 54.288937 | 54.288647 | 0.003272 | 0.018420 |
| 430 | -1.116022 | 341.105628 | 54.288937 | 54.288647 | 0.003272 | 0.018420 |
| 431 | -1.116122 | 339.695422 | 54.064497 | 54.064206 | 0.003286 | 0.018497 |
| 432 | -1.116122 | -339.695422 | 54.064497 | 54.064206 | 0.003286 | 0.018497 |
| 433 | -1.116123 | 339.694299 | 54.064319 | 54.064027 | 0.003286 | 0.018497 |
| 434 | -1.116123 | -339.694299 | 54.064319 | 54.064027 | 0.003286 | 0.018497 |
| 435 | -1.116483 | -339.281941 | 53.998690 | 53.998398 | 0.003291 | 0.018519 |
| 436 | -1.116483 | 339.281941 | 53.998690 | 53.998398 | 0.003291 | 0.018519 |
| 437 | -1.116592 | -340.579316 | 54.205173 | 54.204882 | 0.003278 | 0.018449 |
| 438 | -1.116592 | 340.579316 | 54.205173 | 54.204882 | 0.003278 | 0.018449 |
| 439 | -1.116631 | -339.550217 | 54.041388 | 54.041095 | 0.003289 | 0.018504 |
| 440 | -1.116631 | 339.550217 | 54.041388 | 54.041095 | 0.003289 | 0.018504 |
| 441 | -1.116657 | -340.591235 | 54.207070 | 54.206779 | 0.003279 | 0.018448 |
| 442 | -1.116657 | 340.591235 | 54.207070 | 54.206779 | 0.003279 | 0.018448 |
| 443 | -1.117075 | 342.131792 | 54.452256 | 54.451966 | 0.003265 | 0.018365 |
| 444 | -1.117075 | -342.131792 | 54.452256 | 54.451966 | 0.003265 | 0.018365 |
| 445 | -1.117094 | 342.130820 | 54.452101 | 54.451811 | 0.003265 | 0.018365 |
| 446 | -1.117094 | -342.130820 | 54.452101 | 54.451811 | 0.003265 | 0.018365 |
| 447 | -1.117293 | -341.489178 | 54.349982 | 54.349691 | 0.003272 | 0.018399 |
| 448 | -1.117293 | 341.489178 | 54.349982 | 54.349691 | 0.003272 | 0.018399 |
| 449 | -1.117322 | 341.487729 | 54.349751 | 54.349460 | 0.003272 | 0.018399 |
| 450 | -1.117322 | -341.487729 | 54.349751 | 54.349460 | 0.003272 | 0.018399 |
| 451 | -1.117513 | -342.198690 | 54.462903 | 54.462613 | 0.003266 | 0.018361 |
| 452 | -1.117513 | 342.198690 | 54.462903 | 54.462613 | 0.003266 | 0.018361 |
| 453 | -1.117532 | -342.200560 | 54.463201 | 54.462911 | 0.003266 | 0.018361 |
| 454 | -1.117532 | 342.200560 | 54.463201 | 54.462911 | 0.003266 | 0.018361 |
| 455 | -1.117646 | 343.037593 | 54.596418 | 54.596129 | 0.003258 | 0.018316 |
| 456 | -1.117646 | -343.037593 | 54.596418 | 54.596129 | 0.003258 | 0.018316 |
| 457 | -1.117646 | -343.037592 | 54.596418 | 54.596128 | 0.003258 | 0.018316 |
| 458 | -1.117646 | 343.037592 | 54.596418 | 54.596128 | 0.003258 | 0.018316 |
| 459 | -1.117777 | -341.853412 | 54.407951 | 54.407660 | 0.003270 | 0.018380 |
| 460 | -1.117777 | 341.853412 | 54.407951 | 54.407660 | 0.003270 | 0.018380 |
| 461 | -1.117846 | -342.009266 | 54.432756 | 54.432465 | 0.003268 | 0.018371 |
| 462 | -1.117846 | 342.009266 | 54.432756 | 54.432465 | 0.003268 | 0.018371 |
| 463 | -1.118011 | -342.479554 | 54.507604 | 54.507314 | 0.003264 | 0.018346 |
| 464 | -1.118011 | 342.479554 | 54.507604 | 54.507314 | 0.003264 | 0.018346 |
| 465 | -1.118029 | -342.507545 | 54.512059 | 54.511769 | 0.003264 | 0.018345 |
| 466 | -1.118029 | 342.507545 | 54.512059 | 54.511769 | 0.003264 | 0.018345 |
| 467 | -1.118087 | -343.710417 | 54.703501 | 54.703212 | 0.003253 | 0.018280 |
| 468 | -1.118087 | 343.710417 | 54.703501 | 54.703212 | 0.003253 | 0.018280 |
| 469 | -1.118087 | 343.710417 | 54.703501 | 54.703212 | 0.003253 | 0.018280 |
| 470 | -1.118087 | -343.710417 | 54.703501 | 54.703212 | 0.003253 | 0.018280 |
| 471 | -1.118088 | -342.821813 | 54.562076 | 54.561786 | 0.003261 | 0.018328 |
| 472 | -1.118088 | 342.821813 | 54.562076 | 54.561786 | 0.003261 | 0.018328 |
| 473 | -1.118088 | 342.822024 | 54.562110 | 54.561820 | 0.003261 | 0.018328 |
| 474 | -1.118088 | -342.822024 | 54.562110 | 54.561820 | 0.003261 | 0.018328 |
| 475 | -1.118409 | -344.494693 | 54.828322 | 54.828033 | 0.003247 | 0.018239 |
| 476 | -1.118409 | 344.494693 | 54.828322 | 54.828033 | 0.003247 | 0.018239 |
| 477 | -1.118409 | -344.494693 | 54.828322 | 54.828033 | 0.003247 | 0.018239 |
| 478 | -1.118409 | 344.494693 | 54.828322 | 54.828033 | 0.003247 | 0.018239 |
| 479 | -1.118504 | -343.644764 | 54.693053 | 54.692763 | 0.003255 | 0.018284 |
| 480 | -1.118504 | 343.644764 | 54.693053 | 54.692763 | 0.003255 | 0.018284 |
| 481 | -1.118539 | -343.740135 | 54.708231 | 54.707942 | 0.003254 | 0.018279 |
| 482 | -1.118539 | 343.740135 | 54.708231 | 54.707942 | 0.003254 | 0.018279 |
| 483 | -1.118797 | 345.352018 | 54.964769 | 54.964481 | 0.003240 | 0.018194 |
| 484 | -1.118797 | -345.352018 | 54.964769 | 54.964481 | 0.003240 | 0.018194 |
| 485 | -1.118797 | 345.352018 | 54.964769 | 54.964481 | 0.003240 | 0.018194 |
| 486 | -1.118797 | -345.352018 | 54.964769 | 54.964481 | 0.003240 | 0.018194 |
| 487 | -1.118942 | -344.942716 | 54.899627 | 54.899338 | 0.003244 | 0.018215 |
| 488 | -1.118942 | 344.942716 | 54.899627 | 54.899338 | 0.003244 | 0.018215 |
| 489 | -1.118960 | -345.001926 | 54.909051 | 54.908762 | 0.003243 | 0.018212 |
| 490 | -1.118960 | 345.001926 | 54.909051 | 54.908762 | 0.003243 | 0.018212 |
| 491 | -1.119142 | 346.233999 | 55.105140 | 55.104852 | 0.003232 | 0.018147 |
| 492 | -1.119142 | -346.233999 | 55.105140 | 55.104852 | 0.003232 | 0.018147 |
| 493 | -1.119142 | 346.233999 | 55.105140 | 55.104852 | 0.003232 | 0.018147 |
| 494 | -1.119142 | -346.233999 | 55.105140 | 55.104852 | 0.003232 | 0.018147 |
| 495 | -1.119223 | 345.921418 | 55.055392 | 55.055104 | 0.003235 | 0.018164 |
| 496 | -1.119223 | -345.921418 | 55.055392 | 55.055104 | 0.003235 | 0.018164 |
| 497 | -1.119232 | 345.957711 | 55.061168 | 55.060880 | 0.003235 | 0.018162 |
| 498 | -1.119232 | -345.957711 | 55.061168 | 55.060880 | 0.003235 | 0.018162 |
| 499 | -1.119414 | -346.692126 | 55.178053 | 55.177766 | 0.003229 | 0.018123 |
| 500 | -1.119414 | 346.692126 | 55.178053 | 55.177766 | 0.003229 | 0.018123 |
| 501 | -1.119419 | -346.714128 | 55.181555 | 55.181267 | 0.003229 | 0.018122 |
| 502 | -1.119419 | 346.714128 | 55.181555 | 55.181267 | 0.003229 | 0.018122 |
| 503 | -1.119436 | -347.160911 | 55.252662 | 55.252375 | 0.003225 | 0.018099 |
| 504 | -1.119436 | 347.160911 | 55.252662 | 55.252375 | 0.003225 | 0.018099 |
| 505 | -1.119436 | -347.160911 | 55.252662 | 55.252375 | 0.003225 | 0.018099 |
| 506 | -1.119436 | 347.160911 | 55.252662 | 55.252375 | 0.003225 | 0.018099 |
| 507 | -1.119550 | -347.324058 | 55.278628 | 55.278341 | 0.003223 | 0.018090 |
| 508 | -1.119550 | 347.324058 | 55.278628 | 55.278341 | 0.003223 | 0.018090 |
| 509 | -1.119554 | -347.339241 | 55.281044 | 55.280757 | 0.003223 | 0.018089 |
| 510 | -1.119554 | 347.339241 | 55.281044 | 55.280757 | 0.003223 | 0.018089 |
| 511 | -1.119645 | 347.818682 | 55.357349 | 55.357063 | 0.003219 | 0.018065 |
| 512 | -1.119645 | -347.818682 | 55.357349 | 55.357063 | 0.003219 | 0.018065 |
| 513 | -1.119648 | 347.835778 | 55.360070 | 55.359783 | 0.003219 | 0.018064 |
| 514 | -1.119648 | -347.835778 | 55.360070 | 55.359783 | 0.003219 | 0.018064 |
| 515 | -1.119700 | 348.136761 | 55.407973 | 55.407686 | 0.003216 | 0.018048 |
| 516 | -1.119700 | -348.136761 | 55.407973 | 55.407686 | 0.003216 | 0.018048 |
| 517 | -1.119702 | 348.145161 | 55.409310 | 55.409023 | 0.003216 | 0.018048 |
| 518 | -1.119702 | -348.145161 | 55.409310 | 55.409023 | 0.003216 | 0.018048 |
| 519 | -1.119747 | 348.428886 | 55.454466 | 55.454180 | 0.003214 | 0.018033 |
| 520 | -1.119747 | -348.428886 | 55.454466 | 55.454180 | 0.003214 | 0.018033 |
| 521 | -1.119747 | 348.429776 | 55.454608 | 55.454321 | 0.003214 | 0.018033 |
| 522 | -1.119747 | -348.429776 | 55.454608 | 55.454321 | 0.003214 | 0.018033 |
| 523 | -1.119798 | -348.784816 | 55.511114 | 55.510828 | 0.003211 | 0.018015 |
| 524 | -1.119798 | 348.784816 | 55.511114 | 55.510828 | 0.003211 | 0.018015 |
| 525 | -1.119799 | 348.788549 | 55.511708 | 55.511422 | 0.003211 | 0.018014 |
| 526 | -1.119799 | -348.788549 | 55.511708 | 55.511422 | 0.003211 | 0.018014 |
| 527 | -1.119838 | 349.087485 | 55.559285 | 55.558999 | 0.003208 | 0.017999 |
| 528 | -1.119838 | -349.087485 | 55.559285 | 55.558999 | 0.003208 | 0.017999 |
| 529 | -1.119838 | 349.088940 | 55.559516 | 55.559230 | 0.003208 | 0.017999 |
| 530 | -1.119838 | -349.088940 | 55.559516 | 55.559230 | 0.003208 | 0.017999 |
| 531 | -1.119864 | 349.305750 | 55.594023 | 55.593737 | 0.003206 | 0.017988 |
| 532 | -1.119864 | -349.305750 | 55.594023 | 55.593737 | 0.003206 | 0.017988 |
| 533 | -1.119864 | 349.306973 | 55.594217 | 55.593931 | 0.003206 | 0.017988 |
| 534 | -1.119864 | -349.306973 | 55.594217 | 55.593931 | 0.003206 | 0.017988 |
| 535 | -1.119888 | -349.526188 | 55.629106 | 55.628821 | 0.003204 | 0.017976 |
| 536 | -1.119888 | 349.526188 | 55.629106 | 55.628821 | 0.003204 | 0.017976 |
| 537 | -1.119888 | -349.527157 | 55.629260 | 55.628975 | 0.003204 | 0.017976 |
| 538 | -1.119888 | 349.527157 | 55.629260 | 55.628975 | 0.003204 | 0.017976 |
| 539 | -1.119908 | -349.726171 | 55.660934 | 55.660649 | 0.003202 | 0.017966 |
| 540 | -1.119908 | 349.726171 | 55.660934 | 55.660649 | 0.003202 | 0.017966 |
| 541 | -1.119908 | -349.726960 | 55.661060 | 55.660774 | 0.003202 | 0.017966 |
| 542 | -1.119908 | 349.726960 | 55.661060 | 55.660774 | 0.003202 | 0.017966 |
| 543 | -1.119924 | 349.905629 | 55.689496 | 55.689211 | 0.003201 | 0.017957 |
| 544 | -1.119924 | -349.905629 | 55.689496 | 55.689211 | 0.003201 | 0.017957 |
| 545 | -1.119924 | -349.906343 | 55.689609 | 55.689324 | 0.003201 | 0.017957 |
| 546 | -1.119924 | 349.906343 | 55.689609 | 55.689324 | 0.003201 | 0.017957 |
| 547 | -1.119938 | 350.066095 | 55.715034 | 55.714749 | 0.003199 | 0.017949 |
| 548 | -1.119938 | -350.066095 | 55.715034 | 55.714749 | 0.003199 | 0.017949 |
| 549 | -1.119938 | 350.067052 | 55.715187 | 55.714902 | 0.003199 | 0.017949 |
| 550 | -1.119938 | -350.067052 | 55.715187 | 55.714902 | 0.003199 | 0.017949 |
| 551 | -1.119946 | -350.175587 | 55.732461 | 55.732176 | 0.003198 | 0.017943 |
| 552 | -1.119946 | 350.175587 | 55.732461 | 55.732176 | 0.003198 | 0.017943 |
| 553 | -1.119947 | 350.185229 | 55.733995 | 55.733710 | 0.003198 | 0.017942 |
| 554 | -1.119947 | -350.185229 | 55.733995 | 55.733710 | 0.003198 | 0.017942 |
| 555 | -1.119950 | -350.224672 | 55.740273 | 55.739988 | 0.003198 | 0.017940 |
| 556 | -1.119950 | 350.224672 | 55.740273 | 55.739988 | 0.003198 | 0.017940 |
| 557 | -1.119950 | -350.225655 | 55.740429 | 55.740144 | 0.003198 | 0.017940 |
| 558 | -1.119950 | 350.225655 | 55.740429 | 55.740144 | 0.003198 | 0.017940 |
| 559 | -1.119959 | -350.360870 | 55.761949 | 55.761664 | 0.003197 | 0.017933 |
| 560 | -1.119959 | 350.360870 | 55.761949 | 55.761664 | 0.003197 | 0.017933 |
| 561 | -1.119959 | -350.360874 | 55.761950 | 55.761665 | 0.003197 | 0.017933 |
| 562 | -1.119959 | 350.360874 | 55.761950 | 55.761665 | 0.003197 | 0.017933 |
| 563 | -1.119968 | -350.498253 | 55.783814 | 55.783530 | 0.003195 | 0.017926 |
| 564 | -1.119968 | 350.498253 | 55.783814 | 55.783530 | 0.003195 | 0.017926 |
| 565 | -1.119968 | -350.498253 | 55.783814 | 55.783530 | 0.003195 | 0.017926 |
| 566 | -1.119968 | 350.498253 | 55.783814 | 55.783530 | 0.003195 | 0.017926 |
| 567 | -1.202238 | 215.725167 | 34.334260 | 34.333727 | 0.005573 | 0.029126 |
| 568 | -1.202238 | -215.725167 | 34.334260 | 34.333727 | 0.005573 | 0.029126 |
| 569 | -1.211213 | 218.125851 | 34.716343 | 34.715807 | 0.005553 | 0.028805 |
| 570 | -1.211213 | -218.125851 | 34.716343 | 34.715807 | 0.005553 | 0.028805 |
| 571 | -1.314901 | 27.808792 | 4.430852 | 4.425907 | 0.047231 | 0.225942 |
| 572 | -1.314901 | -27.808792 | 4.430852 | 4.425907 | 0.047231 | 0.225942 |
| 573 | -1.331926 | -193.853508 | 30.853472 | 30.852744 | 0.006871 | 0.032412 |
| 574 | -1.331926 | 193.853508 | 30.853472 | 30.852744 | 0.006871 | 0.032412 |
| 575 | -1.387904 | -100.607607 | 16.013722 | 16.012198 | 0.013794 | 0.062452 |
| 576 | -1.387904 | 100.607607 | 16.013722 | 16.012198 | 0.013794 | 0.062452 |
| 577 | -1.429024 | 181.697099 | 28.918886 | 28.917992 | 0.007865 | 0.034581 |
| 578 | -1.429024 | -181.697099 | 28.918886 | 28.917992 | 0.007865 | 0.034581 |
| 579 | -1.467702 | -29.975101 | 4.776401 | 4.770685 | 0.048905 | 0.209613 |
| 580 | -1.467702 | 29.975101 | 4.776401 | 4.770685 | 0.048905 | 0.209613 |
| 581 | -1.475946 | -189.568142 | 30.171621 | 30.170707 | 0.007786 | 0.033145 |
| 582 | -1.475946 | 189.568142 | 30.171621 | 30.170707 | 0.007786 | 0.033145 |
| 583 | -1.552107 | 121.192652 | 19.289991 | 19.288410 | 0.012806 | 0.051845 |
| 584 | -1.552107 | -121.192652 | 19.289991 | 19.288410 | 0.012806 | 0.051845 |
| 585 | -1.569138 | 147.912741 | 23.542368 | 23.541044 | 0.010608 | 0.042479 |
| 586 | -1.569138 | -147.912741 | 23.542368 | 23.541044 | 0.010608 | 0.042479 |
| 587 | -1.679571 | -166.822478 | 26.551968 | 26.550622 | 0.010068 | 0.037664 |
| 588 | -1.679571 | 166.822478 | 26.551968 | 26.550622 | 0.010068 | 0.037664 |
| 589 | -1.900781 | 146.675612 | 23.346109 | 23.344149 | 0.012958 | 0.042837 |
| 590 | -1.900781 | -146.675612 | 23.346109 | 23.344149 | 0.012958 | 0.042837 |
| 591 | -3.829164 | 6.037090 | 1.137807 | 0.960833 | 0.535618 | 1.040764 |
| 592 | -3.829164 | -6.037090 | 1.137807 | 0.960833 | 0.535618 | 1.040764 |
| 593 | -10.569038 | -2.319301 | 1.722140 | 0.369128 | 0.976758 | 2.709085 |
| 594 | -10.569038 | 2.319301 | 1.722140 | 0.369128 | 0.976758 | 2.709085 |
| 595 | -15.876819 | 0.420548 | 2.527760 | 0.066932 | 0.999649 | 14.940485 |
| 596 | -15.876819 | -0.420548 | 2.527760 | 0.066932 | 0.999649 | 14.940485 |
| 597 | -22.629853 | 0.000000 | 3.601653 | 0.000000 | 1.000000 | inf |
| 598 | -26.267735 | 0.000000 | 4.180640 | 0.000000 | 1.000000 | inf |
| 599 | -29.470709 | 0.000000 | 4.690409 | 0.000000 | 1.000000 | inf |
| 600 | -30.882640 | -35.322709 | 7.467456 | 5.621784 | 0.658206 | 0.177879 |
| 601 | -30.882640 | 35.322709 | 7.467456 | 5.621784 | 0.658206 | 0.177879 |
| 602 | -32.639619 | 0.000000 | 5.194757 | 0.000000 | 1.000000 | inf |
| 603 | -34.172137 | 34.458728 | 7.723753 | 5.484277 | 0.704148 | 0.182339 |
| 604 | -34.172137 | -34.458728 | 7.723753 | 5.484277 | 0.704148 | 0.182339 |
| 605 | -35.603269 | 0.000000 | 5.666436 | 0.000000 | 1.000000 | inf |
| 606 | -36.439642 | -71.349091 | 12.750825 | 11.355561 | 0.454837 | 0.088063 |
| 607 | -36.439642 | 71.349091 | 12.750825 | 11.355561 | 0.454837 | 0.088063 |
| 608 | -37.441913 | 34.065477 | 8.056375 | 5.421689 | 0.739671 | 0.184444 |
| 609 | -37.441913 | -34.065477 | 8.056375 | 5.421689 | 0.739671 | 0.184444 |
| 610 | -38.677028 | 0.000000 | 6.155640 | 0.000000 | 1.000000 | inf |
| 611 | -39.517763 | 106.863529 | 18.133516 | 17.007859 | 0.346841 | 0.058796 |
| 612 | -39.517763 | -106.863529 | 18.133516 | 17.007859 | 0.346841 | 0.058796 |
| 613 | -40.027452 | 70.647916 | 12.923269 | 11.243965 | 0.492953 | 0.088937 |
| 614 | -40.027452 | -70.647916 | 12.923269 | 11.243965 | 0.492953 | 0.088937 |
| 615 | -40.915687 | -33.727014 | 8.439122 | 5.367821 | 0.771636 | 0.186295 |
| 616 | -40.915687 | 33.727014 | 8.439122 | 5.367821 | 0.771636 | 0.186295 |
| 617 | -41.445961 | -142.148833 | 23.565714 | 22.623689 | 0.279912 | 0.044201 |
| 618 | -41.445961 | 142.148833 | 23.565714 | 22.623689 | 0.279912 | 0.044201 |
| 619 | -41.867200 | 0.000000 | 6.663372 | 0.000000 | 1.000000 | inf |
| 620 | -42.728119 | -177.201966 | 29.010864 | 28.202569 | 0.234408 | 0.035458 |
| 621 | -42.728119 | 177.201966 | 29.010864 | 28.202569 | 0.234408 | 0.035458 |
| 622 | -43.280388 | -106.316208 | 18.269108 | 16.920750 | 0.377046 | 0.059099 |
| 623 | -43.280388 | 106.316208 | 18.269108 | 16.920750 | 0.377046 | 0.059099 |
| 624 | -43.336124 | 70.371812 | 13.153375 | 11.200022 | 0.524364 | 0.089286 |
| 625 | -43.336124 | -70.371812 | 13.153375 | 11.200022 | 0.524364 | 0.089286 |
| 626 | -43.703283 | -212.025014 | 34.454227 | 33.744829 | 0.201879 | 0.029634 |
| 627 | -43.703283 | 212.025014 | 34.454227 | 33.744829 | 0.201879 | 0.029634 |
| 628 | -44.464423 | -33.642593 | 8.874096 | 5.354385 | 0.797460 | 0.186763 |
| 629 | -44.464423 | 33.642593 | 8.874096 | 5.354385 | 0.797460 | 0.186763 |
| 630 | -44.565889 | 246.761554 | 39.908680 | 39.273321 | 0.177728 | 0.025463 |
| 631 | -44.565889 | -246.761554 | 39.908680 | 39.273321 | 0.177728 | 0.025463 |
| 632 | -45.337149 | -281.615994 | 45.397682 | 44.820577 | 0.158943 | 0.022311 |
| 633 | -45.337149 | 281.615994 | 45.397682 | 44.820577 | 0.158943 | 0.022311 |
| 634 | -45.383435 | -141.762571 | 23.690192 | 22.562214 | 0.304894 | 0.044322 |
| 635 | -45.383435 | 141.762571 | 23.690192 | 22.562214 | 0.304894 | 0.044322 |
| 636 | -45.635849 | 0.000000 | 7.263171 | 0.000000 | 1.000000 | inf |
| 637 | -45.889180 | 316.668954 | 50.925862 | 50.399429 | 0.143414 | 0.019841 |
| 638 | -45.889180 | -316.668954 | 50.925862 | 50.399429 | 0.143414 | 0.019841 |
| 639 | -46.088938 | 351.858377 | 56.478371 | 56.000000 | 0.129878 | 0.017857 |
| 640 | -46.676008 | 106.038788 | 18.439235 | 16.876597 | 0.402876 | 0.059254 |
| 641 | -46.676008 | -106.038788 | 18.439235 | 16.876597 | 0.402876 | 0.059254 |
| 642 | -46.767036 | 70.167150 | 13.420626 | 11.167449 | 0.554609 | 0.089546 |
| 643 | -46.767036 | -70.167150 | 13.420626 | 11.167449 | 0.554609 | 0.089546 |
| 644 | -46.853578 | -176.902076 | 29.125616 | 28.154840 | 0.256028 | 0.035518 |
| 645 | -46.853578 | 176.902076 | 29.125616 | 28.154840 | 0.256028 | 0.035518 |
| 646 | -47.914776 | 211.777248 | 34.557310 | 33.705396 | 0.220673 | 0.029669 |
| 647 | -47.914776 | -211.777248 | 34.557310 | 33.705396 | 0.220673 | 0.029669 |
| 648 | -48.163221 | 33.591764 | 9.345665 | 5.346295 | 0.820211 | 0.187045 |
| 649 | -48.163221 | -33.591764 | 9.345665 | 5.346295 | 0.820211 | 0.187045 |
| 650 | -48.252213 | 0.000000 | 7.679578 | 0.000000 | 1.000000 | inf |
| 651 | -48.812816 | 246.582271 | 40.006344 | 39.244787 | 0.194189 | 0.025481 |
| 652 | -48.812816 | -246.582271 | 40.006344 | 39.244787 | 0.194189 | 0.025481 |
| 653 | -48.813029 | -141.441198 | 23.813922 | 22.511066 | 0.326231 | 0.044423 |
| 654 | -48.813029 | 141.441198 | 23.813922 | 22.511066 | 0.326231 | 0.044423 |
| 655 | -49.598916 | 281.503089 | 45.492720 | 44.802608 | 0.173520 | 0.022320 |
| 656 | -49.598916 | -281.503089 | 45.492720 | 44.802608 | 0.173520 | 0.022320 |
| 657 | -50.130642 | -105.892724 | 18.646515 | 16.853351 | 0.427884 | 0.059335 |
| 658 | -50.130642 | 105.892724 | 18.646515 | 16.853351 | 0.427884 | 0.059335 |
| 659 | -50.155612 | 316.615486 | 51.019264 | 50.390920 | 0.156461 | 0.019845 |
| 660 | -50.155612 | -316.615486 | 51.019264 | 50.390920 | 0.156461 | 0.019845 |
| 661 | -50.199758 | 70.036291 | 13.714223 | 11.146622 | 0.582573 | 0.089713 |
| 662 | -50.199758 | -70.036291 | 13.714223 | 11.146622 | 0.582573 | 0.089713 |
| 663 | -50.274891 | -176.631667 | 29.228367 | 28.111803 | 0.273758 | 0.035572 |
| 664 | -50.274891 | 176.631667 | 29.228367 | 28.111803 | 0.273758 | 0.035572 |
| 665 | -50.356641 | 351.858377 | 56.570596 | 56.000000 | 0.141673 | 0.017857 |
| 666 | -50.561744 | 0.000000 | 8.047151 | 0.000000 | 1.000000 | inf |
| 667 | -51.384725 | -211.606085 | 34.656889 | 33.678154 | 0.235974 | 0.029693 |
| 668 | -51.384725 | 211.606085 | 34.656889 | 33.678154 | 0.235974 | 0.029693 |
| 669 | -52.064864 | 33.485400 | 9.852221 | 5.329367 | 0.841067 | 0.187640 |
| 670 | -52.064864 | -33.485400 | 9.852221 | 5.329367 | 0.841067 | 0.187640 |
| 671 | -52.270240 | -141.316069 | 23.980382 | 22.491151 | 0.346911 | 0.044462 |
| 672 | -52.270240 | 141.316069 | 23.980382 | 22.491151 | 0.346911 | 0.044462 |
| 673 | -52.308018 | -246.494054 | 40.104345 | 39.230747 | 0.207585 | 0.025490 |
| 674 | -52.308018 | 246.494054 | 40.104345 | 39.230747 | 0.207585 | 0.025490 |
| 675 | -53.091325 | -281.471463 | 45.587508 | 44.797575 | 0.185352 | 0.022323 |
| 676 | -53.091325 | 281.471463 | 45.587508 | 44.797575 | 0.185352 | 0.022323 |
| 677 | -53.523354 | 105.809988 | 18.872114 | 16.840183 | 0.451381 | 0.059382 |
| 678 | -53.523354 | -105.809988 | 18.872114 | 16.840183 | 0.451381 | 0.059382 |
| 679 | -53.632759 | -316.607749 | 51.107559 | 50.389688 | 0.167019 | 0.019845 |
| 680 | -53.632759 | 316.607749 | 51.107559 | 50.389688 | 0.167019 | 0.019845 |
| 681 | -53.713623 | 176.509633 | 29.364326 | 28.092381 | 0.291128 | 0.035597 |
| 682 | -53.713623 | -176.509633 | 29.364326 | 28.092381 | 0.291128 | 0.035597 |
| 683 | -53.826264 | 351.858377 | 56.651466 | 56.000000 | 0.151218 | 0.017857 |
| 684 | -53.844578 | 69.950619 | 14.049269 | 11.132987 | 0.609970 | 0.089823 |
| 685 | -53.844578 | -69.950619 | 14.049269 | 11.132987 | 0.609970 | 0.089823 |
| 686 | -53.932606 | 0.000000 | 8.583641 | 0.000000 | 1.000000 | inf |
| 687 | -54.796128 | 211.491959 | 34.771427 | 33.659991 | 0.250812 | 0.029709 |
| 688 | -54.796128 | -211.491959 | 34.771427 | 33.659991 | 0.250812 | 0.029709 |
| 689 | -55.610859 | 33.325370 | 10.318284 | 5.303897 | 0.857773 | 0.188541 |
| 690 | -55.610859 | -33.325370 | 10.318284 | 5.303897 | 0.857773 | 0.188541 |
| 691 | -55.689855 | 141.250770 | 24.164910 | 22.480758 | 0.366785 | 0.044482 |
| 692 | -55.689855 | -141.250770 | 24.164910 | 22.480758 | 0.366785 | 0.044482 |
| 693 | -55.734550 | -246.399761 | 40.206452 | 39.215740 | 0.220622 | 0.025500 |
| 694 | -55.734550 | 246.399761 | 40.206452 | 39.215740 | 0.220622 | 0.025500 |
| 695 | -56.557649 | 281.398311 | 45.681566 | 44.785932 | 0.197047 | 0.022328 |
| 696 | -56.557649 | -281.398311 | 45.681566 | 44.785932 | 0.197047 | 0.022328 |
| 697 | -57.110723 | -105.753973 | 19.128767 | 16.831268 | 0.475172 | 0.059413 |
| 698 | -57.110723 | 105.753973 | 19.128767 | 16.831268 | 0.475172 | 0.059413 |
| 699 | -57.130384 | 316.567088 | 51.197105 | 50.383217 | 0.177600 | 0.019848 |
| 700 | -57.130384 | -316.567088 | 51.197105 | 50.383217 | 0.177600 | 0.019848 |
| 701 | -57.151223 | -176.440063 | 29.517711 | 28.081308 | 0.308151 | 0.035611 |
| 702 | -57.151223 | 176.440063 | 29.517711 | 28.081308 | 0.308151 | 0.035611 |
| 703 | -57.334973 | 351.858377 | 56.738596 | 56.000000 | 0.160828 | 0.017857 |
| 704 | -57.797155 | 69.873743 | 14.432160 | 11.120752 | 0.637375 | 0.089922 |
| 705 | -57.797155 | -69.873743 | 14.432160 | 11.120752 | 0.637375 | 0.089922 |
| 706 | -58.238487 | -211.435876 | 34.904261 | 33.651065 | 0.265553 | 0.029717 |
| 707 | -58.238487 | 211.435876 | 34.904261 | 33.651065 | 0.265553 | 0.029717 |
| 708 | -58.985465 | -33.192087 | 10.772097 | 5.282685 | 0.871495 | 0.189298 |
| 709 | -58.985465 | 33.192087 | 10.772097 | 5.282685 | 0.871495 | 0.189298 |
| 710 | -59.167429 | -246.361687 | 40.324620 | 39.209680 | 0.233525 | 0.025504 |
| 711 | -59.167429 | 246.361687 | 40.324620 | 39.209680 | 0.233525 | 0.025504 |
| 712 | -59.256196 | -141.231341 | 24.375965 | 22.477666 | 0.386894 | 0.044489 |
| 713 | -59.256196 | 141.231341 | 24.375965 | 22.477666 | 0.386894 | 0.044489 |
| 714 | -59.966273 | 281.381357 | 45.788914 | 44.783234 | 0.208433 | 0.022330 |
| 715 | -59.966273 | -281.381357 | 45.788914 | 44.783234 | 0.208433 | 0.022330 |
| 716 | -60.004171 | 1.461338 | 9.552792 | 0.232579 | 0.999704 | 4.299611 |
| 717 | -60.004171 | -1.461338 | 9.552792 | 0.232579 | 0.999704 | 4.299611 |
| 718 | -60.524592 | 316.563727 | 51.295275 | 50.382682 | 0.187791 | 0.019848 |
| 719 | -60.524592 | -316.563727 | 51.295275 | 50.382682 | 0.187791 | 0.019848 |
| 720 | -60.724664 | 351.858377 | 56.827855 | 56.000000 | 0.170069 | 0.017857 |
| 721 | -60.725048 | -176.425011 | 29.695649 | 28.078913 | 0.325458 | 0.035614 |
| 722 | -60.725048 | 176.425011 | 29.695649 | 28.078913 | 0.325458 | 0.035614 |
| 723 | -61.050615 | 105.665542 | 19.422371 | 16.817193 | 0.500274 | 0.059463 |
| 724 | -61.050615 | -105.665542 | 19.422371 | 16.817193 | 0.500274 | 0.059463 |
| 725 | -61.075659 | 0.000000 | 9.720493 | 0.000000 | 1.000000 | inf |
| 726 | -61.346469 | 69.792184 | 14.788859 | 11.107771 | 0.660199 | 0.090027 |
| 727 | -61.346469 | -69.792184 | 14.788859 | 11.107771 | 0.660199 | 0.090027 |
| 728 | -61.829886 | -211.392322 | 35.053727 | 33.644133 | 0.280727 | 0.029723 |
| 729 | -61.829886 | 211.392322 | 35.053727 | 33.644133 | 0.280727 | 0.029723 |
| 730 | -62.781634 | 246.294823 | 40.452501 | 39.199039 | 0.247006 | 0.025511 |
| 731 | -62.781634 | -246.294823 | 40.452501 | 39.199039 | 0.247006 | 0.025511 |
| 732 | -62.929241 | 32.946966 | 11.305147 | 5.243673 | 0.885924 | 0.190706 |
| 733 | -62.929241 | -32.946966 | 11.305147 | 5.243673 | 0.885924 | 0.190706 |
| 734 | -63.197906 | 141.166186 | 24.616011 | 22.467296 | 0.408606 | 0.044509 |
| 735 | -63.197906 | -141.166186 | 24.616011 | 22.467296 | 0.408606 | 0.044509 |
| 736 | -63.604162 | 281.320050 | 45.903569 | 44.773477 | 0.220526 | 0.022335 |
| 737 | -63.604162 | -281.320050 | 45.903569 | 44.773477 | 0.220526 | 0.022335 |
| 738 | -64.180338 | -316.529779 | 51.402419 | 50.377279 | 0.198719 | 0.019850 |
| 739 | -64.180338 | 316.529779 | 51.402419 | 50.377279 | 0.198719 | 0.019850 |
| 740 | -64.386941 | 351.858377 | 56.929880 | 56.000000 | 0.180002 | 0.017857 |
| 741 | -64.589799 | 105.551154 | 19.694669 | 16.798988 | 0.521958 | 0.059527 |
| 742 | -64.589799 | -105.551154 | 19.694669 | 16.798988 | 0.521958 | 0.059527 |
| 743 | -64.637285 | 69.696959 | 15.128634 | 11.092615 | 0.679992 | 0.090150 |
| 744 | -64.637285 | -69.696959 | 15.128634 | 11.092615 | 0.679992 | 0.090150 |
| 745 | -64.694697 | -176.381060 | 29.900670 | 28.071918 | 0.344356 | 0.035623 |
| 746 | -64.694697 | 176.381060 | 29.900670 | 28.071918 | 0.344356 | 0.035623 |
| 747 | -64.771747 | 0.000000 | 10.308744 | 0.000000 | 1.000000 | inf |
| 748 | -65.832104 | -211.365674 | 35.233797 | 33.639892 | 0.297371 | 0.029727 |
| 749 | -65.832104 | 211.365674 | 35.233797 | 33.639892 | 0.297371 | 0.029727 |
| 750 | -66.701546 | 141.026543 | 24.828978 | 22.445071 | 0.427560 | 0.044553 |
| 751 | -66.701546 | -141.026543 | 24.828978 | 22.445071 | 0.427560 | 0.044553 |
| 752 | -66.800140 | -246.281319 | 40.613132 | 39.196889 | 0.261777 | 0.025512 |
| 753 | -66.800140 | 246.281319 | 40.613132 | 39.196889 | 0.261777 | 0.025512 |
| 754 | -67.619843 | -281.313309 | 46.047687 | 44.772404 | 0.233715 | 0.022335 |
| 755 | -67.619843 | 281.313309 | 46.047687 | 44.772404 | 0.233715 | 0.022335 |
| 756 | -67.868949 | -105.428356 | 19.955601 | 16.779444 | 0.541286 | 0.059597 |
| 757 | -67.868949 | 105.428356 | 19.955601 | 16.779444 | 0.541286 | 0.059597 |
| 758 | -68.186016 | 316.527115 | 51.532480 | 50.376855 | 0.210588 | 0.019850 |
| 759 | -68.186016 | -316.527115 | 51.532480 | 50.376855 | 0.210588 | 0.019850 |
| 760 | -68.198245 | 176.244217 | 30.076926 | 28.050138 | 0.360878 | 0.035650 |
| 761 | -68.198245 | -176.244217 | 30.076926 | 28.050138 | 0.360878 | 0.035650 |
| 762 | -68.388553 | 351.858377 | 57.047959 | 56.000000 | 0.190793 | 0.017857 |
| 763 | -68.578841 | -32.592349 | 12.084586 | 5.187233 | 0.903189 | 0.192781 |
| 764 | -68.578841 | 32.592349 | 12.084586 | 5.187233 | 0.903189 | 0.192781 |
| 765 | -68.595368 | -69.515583 | 15.543288 | 11.063749 | 0.702380 | 0.090385 |
| 766 | -68.595368 | 69.515583 | 15.543288 | 11.063749 | 0.702380 | 0.090385 |
| 767 | -69.371175 | 211.255741 | 35.388755 | 33.622396 | 0.311985 | 0.029742 |
| 768 | -69.371175 | -211.255741 | 35.388755 | 33.622396 | 0.311985 | 0.029742 |
| 769 | -69.970974 | -140.859652 | 25.032082 | 22.418510 | 0.444878 | 0.044606 |
| 770 | -69.970974 | 140.859652 | 25.032082 | 22.418510 | 0.444878 | 0.044606 |
| 771 | -70.388014 | 246.207763 | 40.755083 | 39.185182 | 0.274876 | 0.025520 |
| 772 | -70.388014 | -246.207763 | 40.755083 | 39.185182 | 0.274876 | 0.025520 |
| 773 | -71.236074 | 281.270855 | 46.179040 | 44.765647 | 0.245513 | 0.022339 |
| 774 | -71.236074 | -281.270855 | 46.179040 | 44.765647 | 0.245513 | 0.022339 |
| 775 | -71.291210 | 3.919085 | 11.363480 | 0.623742 | 0.998492 | 1.603228 |
| 776 | -71.291210 | -3.919085 | 11.363480 | 0.623742 | 0.998492 | 1.603228 |
| 777 | -71.480906 | 176.099249 | 30.248010 | 28.027066 | 0.376109 | 0.035680 |
| 778 | -71.480906 | -176.099249 | 30.248010 | 28.027066 | 0.376109 | 0.035680 |
| 779 | -71.511939 | -32.497012 | 12.501530 | 5.172060 | 0.910407 | 0.193347 |
| 780 | -71.511939 | 32.497012 | 12.501530 | 5.172060 | 0.910407 | 0.193347 |
| 781 | -71.808080 | 316.508402 | 51.654047 | 50.373877 | 0.221253 | 0.019852 |
| 782 | -71.808080 | -316.508402 | 51.654047 | 50.373877 | 0.221253 | 0.019852 |
| 783 | -71.851202 | 105.271767 | 20.285070 | 16.754522 | 0.563738 | 0.059685 |
| 784 | -71.851202 | -105.271767 | 20.285070 | 16.754522 | 0.563738 | 0.059685 |
| 785 | -72.010158 | 351.858377 | 57.160732 | 56.000000 | 0.200501 | 0.017857 |
| 786 | -72.173154 | -32.720681 | 12.612070 | 5.207658 | 0.910772 | 0.192025 |
| 787 | -72.173154 | 32.720681 | 12.612070 | 5.207658 | 0.910772 | 0.192025 |
| 788 | -72.681232 | 211.168850 | 35.543559 | 33.608566 | 0.325448 | 0.029754 |
| 789 | -72.681232 | -211.168850 | 35.543559 | 33.608566 | 0.325448 | 0.029754 |
| 790 | -73.692957 | 246.188140 | 40.899802 | 39.182059 | 0.286764 | 0.025522 |
| 791 | -73.692957 | -246.188140 | 40.899802 | 39.182059 | 0.286764 | 0.025522 |
| 792 | -73.972481 | -2.000937 | 11.777392 | 0.318459 | 0.999634 | 3.140121 |
| 793 | -73.972481 | 2.000937 | 11.777392 | 0.318459 | 0.999634 | 3.140121 |
| 794 | -73.984999 | -140.684708 | 25.298111 | 22.390667 | 0.465453 | 0.044661 |
| 795 | -73.984999 | 140.684708 | 25.298111 | 22.390667 | 0.465453 | 0.044661 |
| 796 | -74.508606 | -281.292379 | 46.312977 | 44.769073 | 0.256049 | 0.022337 |
| 797 | -74.508606 | 281.292379 | 46.312977 | 44.769073 | 0.256049 | 0.022337 |
| 798 | -74.757158 | 69.289437 | 16.222612 | 11.027756 | 0.733419 | 0.090680 |
| 799 | -74.757158 | -69.289437 | 16.222612 | 11.027756 | 0.733419 | 0.090680 |
| 800 | -75.045687 | -316.530852 | 51.773970 | 50.377450 | 0.230693 | 0.019850 |
| 801 | -75.045687 | 316.530852 | 51.773970 | 50.377450 | 0.230693 | 0.019850 |
| 802 | -75.233144 | 351.858377 | 57.265785 | 56.000000 | 0.209090 | 0.017857 |
| 803 | -75.487405 | 175.907873 | 30.465569 | 27.996608 | 0.394353 | 0.035719 |
| 804 | -75.487405 | -175.907873 | 30.465569 | 27.996608 | 0.394353 | 0.035719 |
| 805 | -76.676467 | -211.007198 | 35.731372 | 33.582839 | 0.341533 | 0.029777 |
| 806 | -76.676467 | 211.007198 | 35.731372 | 33.582839 | 0.341533 | 0.029777 |
| 807 | -77.232425 | 69.389625 | 16.524367 | 11.043702 | 0.743866 | 0.090549 |
| 808 | -77.232425 | -69.389625 | 16.524367 | 11.043702 | 0.743866 | 0.090549 |
| 809 | -77.356873 | -69.260283 | 16.525367 | 11.023116 | 0.745020 | 0.090718 |
| 810 | -77.356873 | 69.260283 | 16.525367 | 11.023116 | 0.745020 | 0.090718 |
| 811 | -77.358540 | -32.280256 | 13.340905 | 5.137562 | 0.922875 | 0.194645 |
| 812 | -77.358540 | 32.280256 | 13.340905 | 5.137562 | 0.922875 | 0.194645 |
| 813 | -77.690399 | 246.077645 | 41.069996 | 39.164474 | 0.301067 | 0.025533 |
| 814 | -77.690399 | -246.077645 | 41.069996 | 39.164474 | 0.301067 | 0.025533 |
| 815 | -78.253904 | 105.127152 | 20.858038 | 16.731506 | 0.597108 | 0.059767 |
| 816 | -78.253904 | -105.127152 | 20.858038 | 16.731506 | 0.597108 | 0.059767 |
| 817 | -78.514848 | -281.228183 | 46.470483 | 44.758856 | 0.268902 | 0.022342 |
| 818 | -78.514848 | 281.228183 | 46.470483 | 44.758856 | 0.268902 | 0.022342 |
| 819 | -79.058786 | 316.501686 | 51.920531 | 50.372808 | 0.242343 | 0.019852 |
| 820 | -79.058786 | -316.501686 | 51.920531 | 50.372808 | 0.242343 | 0.019852 |
| 821 | -79.248414 | 351.858377 | 57.402806 | 56.000000 | 0.219724 | 0.017857 |
| 822 | -80.292059 | -105.140847 | 21.055070 | 16.733686 | 0.606926 | 0.059760 |
| 823 | -80.292059 | 105.140847 | 21.055070 | 16.733686 | 0.606926 | 0.059760 |
| 824 | -80.376065 | -140.569414 | 25.771344 | 22.372317 | 0.496375 | 0.044698 |
| 825 | -80.376065 | 140.569414 | 25.771344 | 22.372317 | 0.496375 | 0.044698 |
| 826 | -80.738344 | -105.068490 | 21.089122 | 16.722169 | 0.609314 | 0.059801 |
| 827 | -80.738344 | 105.068490 | 21.089122 | 16.722169 | 0.609314 | 0.059801 |
| 828 | -81.728740 | 175.741308 | 30.846755 | 27.970098 | 0.421682 | 0.035752 |
| 829 | -81.728740 | -175.741308 | 30.846755 | 27.970098 | 0.421682 | 0.035752 |
| 830 | -82.328091 | -4.824289 | 13.125400 | 0.767809 | 0.998288 | 1.302406 |
| 831 | -82.328091 | 4.824289 | 13.125400 | 0.767809 | 0.998288 | 1.302406 |
| 832 | -82.600442 | 140.579658 | 25.950297 | 22.373948 | 0.506594 | 0.044695 |
| 833 | -82.600442 | -140.579658 | 25.950297 | 22.373948 | 0.506594 | 0.044695 |
| 834 | -82.777733 | -69.111821 | 17.162628 | 10.999488 | 0.767626 | 0.090913 |
| 835 | -82.777733 | 69.111821 | 17.162628 | 10.999488 | 0.767626 | 0.090913 |
| 836 | -82.862711 | 210.764530 | 36.043558 | 33.544217 | 0.365891 | 0.029811 |
| 837 | -82.862711 | -210.764530 | 36.043558 | 33.544217 | 0.365891 | 0.029811 |
| 838 | -82.995671 | 140.490869 | 25.970052 | 22.359816 | 0.508631 | 0.044723 |
| 839 | -82.995671 | -140.490869 | 25.970052 | 22.359816 | 0.508631 | 0.044723 |
| 840 | -84.019349 | 245.657331 | 41.321103 | 39.097579 | 0.323614 | 0.025577 |
| 841 | -84.019349 | -245.657331 | 41.321103 | 39.097579 | 0.323614 | 0.025577 |
| 842 | -84.263147 | 25.881773 | 14.029257 | 4.119212 | 0.955923 | 0.242765 |
| 843 | -84.263147 | -25.881773 | 14.029257 | 4.119212 | 0.955923 | 0.242765 |
| 844 | -84.334363 | 3.013423 | 13.430797 | 0.479601 | 0.999362 | 2.085066 |
| 845 | -84.334363 | -3.013423 | 13.430797 | 0.479601 | 0.999362 | 2.085066 |
| 846 | -84.417542 | -175.895762 | 31.051794 | 27.994680 | 0.432679 | 0.035721 |
| 847 | -84.417542 | 175.895762 | 31.051794 | 27.994680 | 0.432679 | 0.035721 |
| 848 | -84.577439 | -175.688159 | 31.033040 | 27.961639 | 0.433761 | 0.035763 |
| 849 | -84.577439 | 175.688159 | 31.033040 | 27.961639 | 0.433761 | 0.035763 |
| 850 | -85.105900 | 280.538672 | 46.658453 | 44.649116 | 0.290302 | 0.022397 |
| 851 | -85.105900 | -280.538672 | 46.658453 | 44.649116 | 0.290302 | 0.022397 |
| 852 | -85.168644 | 38.197052 | 14.855827 | 6.079250 | 0.912437 | 0.164494 |
| 853 | -85.168644 | -38.197052 | 14.855827 | 6.079250 | 0.912437 | 0.164494 |
| 854 | -85.665558 | 211.188899 | 36.271736 | 33.611757 | 0.375888 | 0.029751 |
| 855 | -85.665558 | -211.188899 | 36.271736 | 33.611757 | 0.375888 | 0.029751 |
| 856 | -85.756665 | -210.815246 | 36.222096 | 33.552289 | 0.376803 | 0.029804 |
| 857 | -85.756665 | 210.815246 | 36.222096 | 33.552289 | 0.376803 | 0.029804 |
| 858 | -85.966733 | -315.560139 | 52.053273 | 50.222956 | 0.262847 | 0.019911 |
| 859 | -85.966733 | 315.560139 | 52.053273 | 50.222956 | 0.262847 | 0.019911 |
| 860 | -85.974527 | 105.007973 | 21.599556 | 16.712538 | 0.633498 | 0.059835 |
| 861 | -85.974527 | -105.007973 | 21.599556 | 16.712538 | 0.633498 | 0.059835 |
| 862 | -86.375776 | 246.597853 | 41.585233 | 39.247267 | 0.330577 | 0.025479 |
| 863 | -86.375776 | -246.597853 | 41.585233 | 39.247267 | 0.330577 | 0.025479 |
| 864 | -86.519761 | 350.775137 | 57.500737 | 55.827597 | 0.239476 | 0.017912 |
| 865 | -86.519761 | -350.775137 | 57.500737 | 55.827597 | 0.239476 | 0.017912 |
| 866 | -86.708900 | 282.092865 | 46.969538 | 44.896474 | 0.293811 | 0.022273 |
| 867 | -86.708900 | -282.092865 | 46.969538 | 44.896474 | 0.293811 | 0.022273 |
| 868 | -86.734242 | -245.973742 | 41.510438 | 39.147937 | 0.332547 | 0.025544 |
| 869 | -86.734242 | 245.973742 | 41.510438 | 39.147937 | 0.332547 | 0.025544 |
| 870 | -86.757772 | -317.567748 | 52.394664 | 50.542477 | 0.263537 | 0.019785 |
| 871 | -86.757772 | 317.567748 | 52.394664 | 50.542477 | 0.263537 | 0.019785 |
| 872 | -87.524583 | 281.194311 | 46.871277 | 44.753465 | 0.297196 | 0.022345 |
| 873 | -87.524583 | -281.194311 | 46.871277 | 44.753465 | 0.297196 | 0.022345 |
| 874 | -88.040412 | -316.496355 | 52.284532 | 50.371959 | 0.267996 | 0.019852 |
| 875 | -88.040412 | 316.496355 | 52.284532 | 50.371959 | 0.267996 | 0.019852 |
| 876 | -88.170415 | 140.558523 | 26.407599 | 22.370584 | 0.531391 | 0.044702 |
| 877 | -88.170415 | -140.558523 | 26.407599 | 22.370584 | 0.531391 | 0.044702 |
| 878 | -88.219075 | 351.858377 | 57.733315 | 56.000000 | 0.243196 | 0.017857 |
| 879 | -88.657831 | 27.265548 | 14.762529 | 4.339447 | 0.955821 | 0.230444 |
| 880 | -88.657831 | -27.265548 | 14.762529 | 4.339447 | 0.955821 | 0.230444 |
| 881 | -89.526558 | 36.237090 | 15.371543 | 5.767312 | 0.926946 | 0.173391 |
| 882 | -89.526558 | -36.237090 | 15.371543 | 5.767312 | 0.926946 | 0.173391 |
| 883 | -89.792477 | 175.890513 | 31.430648 | 27.993845 | 0.454681 | 0.035722 |
| 884 | -89.792477 | -175.890513 | 31.430648 | 27.993845 | 0.454681 | 0.035722 |
| 885 | -90.026130 | -62.325176 | 17.426653 | 9.919360 | 0.822195 | 0.100813 |
| 886 | -90.026130 | 62.325176 | 17.426653 | 9.919360 | 0.822195 | 0.100813 |
| 887 | -90.376140 | 75.533052 | 18.745918 | 12.021459 | 0.767304 | 0.083185 |
| 888 | -90.376140 | -75.533052 | 18.745918 | 12.021459 | 0.767304 | 0.083185 |
| 889 | -90.531744 | 0.000000 | 14.408575 | 0.000000 | 1.000000 | inf |
| 890 | -91.010852 | -211.042064 | 36.578546 | 33.588388 | 0.395992 | 0.029772 |
| 891 | -91.010852 | 211.042064 | 36.578546 | 33.588388 | 0.395992 | 0.029772 |
| 892 | -91.898481 | -246.139516 | 41.815668 | 39.174321 | 0.349776 | 0.025527 |
| 893 | -91.898481 | 246.139516 | 41.815668 | 39.174321 | 0.349776 | 0.025527 |
| 894 | -92.541781 | -281.308683 | 47.132053 | 44.771668 | 0.312494 | 0.022336 |
| 895 | -92.541781 | 281.308683 | 47.132053 | 44.771668 | 0.312494 | 0.022336 |
| 896 | -92.956744 | -316.560408 | 52.509422 | 50.382154 | 0.281750 | 0.019848 |
| 897 | -92.956744 | 316.560408 | 52.509422 | 50.382154 | 0.281750 | 0.019848 |
| 898 | -93.101793 | 351.858377 | 57.927209 | 56.000000 | 0.255797 | 0.017857 |
| 899 | -93.387365 | -98.033026 | 21.548706 | 15.602441 | 0.689743 | 0.064093 |
| 900 | -93.387365 | 98.033026 | 21.548706 | 15.602441 | 0.689743 | 0.064093 |
| 901 | -93.532091 | -111.580776 | 23.172502 | 17.758632 | 0.642403 | 0.056311 |
| 902 | -93.532091 | 111.580776 | 23.172502 | 17.758632 | 0.642403 | 0.056311 |
| 903 | -93.692886 | -4.289078 | 14.927302 | 0.682628 | 0.998954 | 1.464927 |
| 904 | -93.692886 | 4.289078 | 14.927302 | 0.682628 | 0.998954 | 1.464927 |
| 905 | -94.349268 | 63.861696 | 18.132562 | 10.163905 | 0.828132 | 0.098387 |
| 906 | -94.349268 | -63.861696 | 18.132562 | 10.163905 | 0.828132 | 0.098387 |
| 907 | -94.745043 | 73.683778 | 19.102520 | 11.727138 | 0.789380 | 0.085272 |
| 908 | -94.745043 | -73.683778 | 19.102520 | 11.727138 | 0.789380 | 0.085272 |
| 909 | -95.202577 | 6.142057 | 15.183461 | 0.977539 | 0.997925 | 1.022977 |
| 910 | -95.202577 | -6.142057 | 15.183461 | 0.977539 | 0.997925 | 1.022977 |
| 911 | -95.692689 | 133.532122 | 26.145974 | 21.252297 | 0.582497 | 0.047054 |
| 912 | -95.692689 | -133.532122 | 26.145974 | 21.252297 | 0.582497 | 0.047054 |
| 913 | -95.747216 | -147.119968 | 27.936936 | 23.414870 | 0.545466 | 0.042708 |
| 914 | -95.747216 | 147.119968 | 27.936936 | 23.414870 | 0.545466 | 0.042708 |
| 915 | -97.319856 | 168.949269 | 31.031137 | 26.889111 | 0.499142 | 0.037190 |
| 916 | -97.319856 | -168.949269 | 31.031137 | 26.889111 | 0.499142 | 0.037190 |
| 917 | -97.471196 | 182.439238 | 32.920349 | 29.036107 | 0.471229 | 0.034440 |
| 918 | -97.471196 | -182.439238 | 32.920349 | 29.036107 | 0.471229 | 0.034440 |
| 919 | -97.628457 | -99.626238 | 22.200091 | 15.856008 | 0.699909 | 0.063068 |
| 920 | -97.628457 | 99.626238 | 22.200091 | 15.856008 | 0.699909 | 0.063068 |
| 921 | -97.948677 | -19.505992 | 15.895131 | 3.104475 | 0.980742 | 0.322116 |
| 922 | -97.948677 | 19.505992 | 15.895131 | 3.104475 | 0.980742 | 0.322116 |
| 923 | -97.952152 | -109.843672 | 23.423508 | 17.482163 | 0.665552 | 0.057201 |
| 924 | -97.952152 | 109.843672 | 23.423508 | 17.482163 | 0.665552 | 0.057201 |
| 925 | -98.399975 | 204.263076 | 36.085013 | 32.509478 | 0.433999 | 0.030760 |
| 926 | -98.399975 | -204.263076 | 36.085013 | 32.509478 | 0.433999 | 0.030760 |
| 927 | -98.873793 | -217.775410 | 38.065044 | 34.660033 | 0.413404 | 0.028852 |
| 928 | -98.873793 | 217.775410 | 38.065044 | 34.660033 | 0.413404 | 0.028852 |
| 929 | -99.104578 | -239.370236 | 41.233058 | 38.096956 | 0.382532 | 0.026249 |
| 930 | -99.104578 | 239.370236 | 41.233058 | 38.096956 | 0.382532 | 0.026249 |
| 931 | -99.299795 | -43.283124 | 17.240145 | 6.888723 | 0.916701 | 0.145165 |
| 932 | -99.299795 | 43.283124 | 17.240145 | 6.888723 | 0.916701 | 0.145165 |
| 933 | -99.680943 | -274.334108 | 46.454570 | 43.661629 | 0.341510 | 0.022903 |
| 934 | -99.680943 | 274.334108 | 46.454570 | 43.661629 | 0.341510 | 0.022903 |
| 935 | -99.833988 | -135.101920 | 26.735830 | 21.502138 | 0.594299 | 0.046507 |
| 936 | -99.833988 | 135.101920 | 26.735830 | 21.502138 | 0.594299 | 0.046507 |
| 937 | -99.860702 | 253.218384 | 43.321645 | 40.300958 | 0.366868 | 0.024813 |
| 938 | -99.860702 | -253.218384 | 43.321645 | 40.300958 | 0.366868 | 0.024813 |
| 939 | -100.175662 | -309.342071 | 51.750492 | 49.233320 | 0.308083 | 0.020311 |
| 940 | -100.175662 | 309.342071 | 51.750492 | 49.233320 | 0.308083 | 0.020311 |
| 941 | -100.185518 | -145.532934 | 28.120014 | 23.162286 | 0.567035 | 0.043174 |
| 942 | -100.185518 | 145.532934 | 28.120014 | 23.162286 | 0.567035 | 0.043174 |
| 943 | -100.392397 | 288.649950 | 48.639330 | 45.940066 | 0.328498 | 0.021767 |
| 944 | -100.392397 | -288.649950 | 48.639330 | 45.940066 | 0.328498 | 0.021767 |
| 945 | -100.497591 | -344.475254 | 57.110455 | 54.824939 | 0.280066 | 0.018240 |
| 946 | -100.497591 | 344.475254 | 57.110455 | 54.824939 | 0.280066 | 0.018240 |
| 947 | -100.581039 | 323.994069 | 53.992878 | 51.565258 | 0.296483 | 0.019393 |
| 948 | -100.581039 | -323.994069 | 53.992878 | 51.565258 | 0.296483 | 0.019393 |
| 949 | -101.426917 | 170.408514 | 31.561866 | 27.121357 | 0.511459 | 0.036871 |
| 950 | -101.426917 | -170.408514 | 31.561866 | 27.121357 | 0.511459 | 0.036871 |
| 951 | -101.798814 | 180.982879 | 33.048247 | 28.804320 | 0.490246 | 0.034717 |
| 952 | -101.798814 | -180.982879 | 33.048247 | 28.804320 | 0.490246 | 0.034717 |
| 953 | -101.883732 | 6.664475 | 16.249954 | 1.060684 | 0.997867 | 0.942788 |
| 954 | -101.883732 | -6.664475 | 16.249954 | 1.060684 | 0.997867 | 0.942788 |
| 955 | -102.388876 | 20.965247 | 16.633804 | 3.336723 | 0.979673 | 0.299695 |
| 956 | -102.388876 | -20.965247 | 16.633804 | 3.336723 | 0.979673 | 0.299695 |
| 957 | -102.649996 | -205.587598 | 36.572158 | 32.720283 | 0.446713 | 0.030562 |
| 958 | -102.649996 | 205.587598 | 36.572158 | 32.720283 | 0.446713 | 0.030562 |
| 959 | -102.964960 | -216.303713 | 38.127187 | 34.425805 | 0.429808 | 0.029048 |
| 960 | -102.964960 | 216.303713 | 38.127187 | 34.425805 | 0.429808 | 0.029048 |
| 961 | -103.611476 | 240.711782 | 41.708769 | 38.310470 | 0.395367 | 0.026103 |
| 962 | -103.611476 | -240.711782 | 41.708769 | 38.310470 | 0.395367 | 0.026103 |
| 963 | -103.754665 | -56.004045 | 18.765092 | 8.913321 | 0.879989 | 0.112192 |
| 964 | -103.754665 | 56.004045 | 18.765092 | 8.913321 | 0.879989 | 0.112192 |
| 965 | -103.791363 | 4.588853 | 16.535046 | 0.730339 | 0.999024 | 1.369228 |
| 966 | -103.791363 | -4.588853 | 16.535046 | 0.730339 | 0.999024 | 1.369228 |
| 967 | -103.792027 | 41.452110 | 17.787701 | 6.597308 | 0.928676 | 0.151577 |
| 968 | -103.792027 | -41.452110 | 17.787701 | 6.597308 | 0.928676 | 0.151577 |
| 969 | -103.817204 | -251.551913 | 43.311314 | 40.035730 | 0.381494 | 0.024978 |
| 970 | -103.817204 | 251.551913 | 43.311314 | 40.035730 | 0.381494 | 0.024978 |
| 971 | -103.986268 | -34.363132 | 17.430169 | 5.469062 | 0.949499 | 0.182847 |
| 972 | -103.986268 | 34.363132 | 17.430169 | 5.469062 | 0.949499 | 0.182847 |
| 973 | -104.260819 | -80.880610 | 21.001212 | 12.872549 | 0.790127 | 0.077685 |
| 974 | -104.260819 | 80.880610 | 21.001212 | 12.872549 | 0.790127 | 0.077685 |
| 975 | -104.322107 | 275.875236 | 46.941333 | 43.906907 | 0.353705 | 0.022775 |
| 976 | -104.322107 | -275.875236 | 46.941333 | 43.906907 | 0.353705 | 0.022775 |
| 977 | -104.432405 | -286.781615 | 48.574814 | 45.642712 | 0.342172 | 0.021909 |
| 978 | -104.432405 | 286.781615 | 48.574814 | 45.642712 | 0.342172 | 0.021909 |
| 979 | -104.765916 | -311.109362 | 52.246700 | 49.514593 | 0.319140 | 0.020196 |
| 980 | -104.765916 | 311.109362 | 52.246700 | 49.514593 | 0.319140 | 0.020196 |
| 981 | -104.812659 | -322.040367 | 53.900610 | 51.254316 | 0.309485 | 0.019511 |
| 982 | -104.812659 | 322.040367 | 53.900610 | 51.254316 | 0.309485 | 0.019511 |
| 983 | -104.929967 | 346.389833 | 57.603584 | 55.129654 | 0.289915 | 0.018139 |
| 984 | -104.929967 | -346.389833 | 57.603584 | 55.129654 | 0.289915 | 0.018139 |
| 985 | -105.208237 | 0.000000 | 16.744411 | 0.000000 | 1.000000 | inf |
| 986 | -106.069332 | 34.680255 | 17.760881 | 5.519534 | 0.950485 | 0.181175 |
| 987 | -106.069332 | -34.680255 | 17.760881 | 5.519534 | 0.950485 | 0.181175 |
| 988 | -106.442343 | -69.300672 | 20.214906 | 11.029544 | 0.838036 | 0.090666 |
| 989 | -106.442343 | 69.300672 | 20.214906 | 11.029544 | 0.838036 | 0.090666 |
| 990 | -107.170073 | 91.634457 | 22.441580 | 14.584077 | 0.760047 | 0.068568 |
| 991 | -107.170073 | -91.634457 | 22.441580 | 14.584077 | 0.760047 | 0.068568 |
| 992 | -107.393409 | 117.085123 | 25.286245 | 18.634676 | 0.675948 | 0.053663 |
| 993 | -107.393409 | -117.085123 | 25.286245 | 18.634676 | 0.675948 | 0.053663 |
| 994 | -108.092648 | 57.766084 | 19.506022 | 9.193758 | 0.881957 | 0.108769 |
| 995 | -108.092648 | -57.766084 | 19.506022 | 9.193758 | 0.881957 | 0.108769 |
| 996 | -108.203753 | 32.422115 | 17.977638 | 5.160140 | 0.957921 | 0.193793 |
| 997 | -108.203753 | -32.422115 | 17.977638 | 5.160140 | 0.957921 | 0.193793 |
| 998 | -108.324174 | 69.398551 | 20.474951 | 11.045122 | 0.842020 | 0.090538 |
| 999 | -108.324174 | -69.398551 | 20.474951 | 11.045122 | 0.842020 | 0.090538 |
Generating an instance of StabilityDerivatives
Variable print_info has no assigned value in the settings file.
will default to the value: c_bool(True)
Variable folder has no assigned value in the settings file.
will default to the value: ./output/
/home/ng213/code/sharpy/sharpy/postproc/asymptoticstability.py:171: UserWarning: Plotting modes is under development
warn.warn('Plotting modes is under development')
|==============|==============|==============|==============|==============|==============|==============|
| der | X | Y | Z | L | M | N |
|==============|==============|==============|==============|==============|==============|==============|
| u | -0.000000 | -0.032063 | 0.000000 | 103.702544 | -0.000000 | 0.215455 |
| v | 131.843986 | 0.000000 | -982.084813 | -0.000000 | 1279.474176 | -0.000000 |
| w | 0.000000 | -187.481605 | -0.000000 |-22078.785295 | 0.000000 | -3334.924961 |
| p | -187.422614 | 0.000000 | 1572.771760 | 0.000000 | -2857.778575 | 0.000000 |
| q | 0.000000 | -2.610892 | 0.000000 | 1127.543337 | -0.000000 | -38.871906 |
| r | 0.000000 | 0.000000 | -0.000000 | 0.000000 | 0.000000 | 0.000000 |
| flap1 | -0.000000 | 1.108474 | 0.000000 | 271.384778 | -0.000000 | 23.331888 |
|==============|==============|==============|==============|==============|==============|==============|
| der | C_D | C_Y | C_L | C_l | C_m | C_n |
|==============|==============|==============|==============|==============|==============|==============|
| u | -0.000000 | -0.000006 | 0.000000 | 0.001009 | -0.000000 | -0.000078 |
| v | 0.010573 | 0.000000 | -0.193187 | -0.000000 | 0.347457 | -0.000000 |
| w | 0.000000 | -0.036606 | -0.000000 | -0.217442 | 0.000000 | -0.015495 |
| p | -0.479599 | 0.000000 | 12.034020 | 0.000000 | -30.222290 | 0.000000 |
| q | 0.000000 | -0.019853 | 0.000000 | 0.010944 | -0.000000 | -0.001245 |
| r | 0.000000 | 0.000000 | -0.000000 | 0.000000 | 0.000000 | 0.000000 |
| alpha | 0.000000 | -1.024980 | -0.000000 | -6.088362 | 0.000000 | -0.433847 |
| beta | 0.296049 | 0.000000 | -5.409222 | -0.000000 | 9.728798 | -0.000000 |
FINISHED - Elapsed time = 29.3233356 seconds
FINISHED - CPU process time = 69.2634336 seconds
Post-processing¶
Nonlinear Equilibrium¶
The files can be opened with Paraview to see the deformation and aerodynamic loading on the flying wing in trim conditions.
Asymptotic Stability¶
[18]:
eigenvalues_trim = np.loadtxt('./output/horten_u_inf2800_M4N11Msf5/stability/eigenvalues.dat')
The flight dynamics modes can be found close to the origin of the Argand diagram. In particular, the phugoid is the mode that is closest to the imaginary axis. An exercise is left to the user to compare this phugoid predicition with the nonlinear response!
[19]:
fig = plt.figure()
plt.scatter(eigenvalues_trim[:, 0], eigenvalues_trim[:, 1],
marker='x',
color='k')
plt.xlim(-0.5, 0.5)
plt.ylim(-0.5, 0.5)
plt.grid()
plt.xlabel('Real Part, $Re(\lambda)$ [rad/s]')
plt.ylabel('Imaginary Part, $Im(\lambda)$ [rad/s]');

Looking further out on the plot, the structural modes appear. There is a curve given the Newmark-\(\beta\) integration scheme and on top of it several modes are damped by the presence of the aerodynamics.
Try changing newmark_damp
in the LinearAssembler
settings to see how this plot changes!
[20]:
fig = plt.figure()
plt.scatter(eigenvalues_trim[:, 0], eigenvalues_trim[:, 1],
marker='x',
color='k')
plt.xlim(-5, 0.5)
plt.ylim(-200, 200)
plt.grid()
plt.xlabel('Real Part, $Re(\lambda)$ [rad/s]')
plt.ylabel('Imaginary Part, $Im(\lambda)$ [rad/s]');

Stability Derivatives¶
Stability derivatives are calculated using the steady-state frequency response of the UVLM system. The output is saved in ./output/<case_name>/stability/
. Note that stability derivatives are expressed in the SHARPy Frame of Reference, which is South East Up (not the conventional in flight dynamics literature).
This body attached frame of reference has:
- \(x\) positive downstream
- \(y\) positive towards the right wing
- \(z\) positive up
Simulation NREL 5MW wind turbine¶
[1]:
%config InlineBackend.figure_format = 'svg'
from IPython.display import Image
url = 'https://raw.githubusercontent.com/ImperialCollegeLondon/sharpy/dev_doc/docs/source/content/example_notebooks/images/turbulence_no_legend.png'
Image(url=url, width=800)
[1]:

In this notebook the blade loads on the NREL-5MW reference wind turbine computed with SHARPy and OpenFAST will be compared. However, zero-drag airfoils have been used.
OpenFAST: https://openfast.readthedocs.io
NREL-5MW: Jonkman, J.; Butterfield, S.; Musial, W. and Scott, G.. Definition of a 5-MW Reference Wind Turbine for Offshore System Development, Technical Report, NREL 2009
Load the required packages:
[2]:
# Required packages
import numpy as np
import os
import matplotlib.pyplot as plt
# Required SHARPy modules
import sharpy.sharpy_main
import sharpy.utils.algebra as algebra
import sharpy.utils.generate_cases as gc
import cases.templates.template_wt as template_wt
These are the results from the OpenFAST simulation for comparison: out-of-plane of_cNdrR
and in-plane of_cTdrR
coefficients along the blade and thrust of_ct
and power of_cp
rotor coefficients
[3]:
of_rR = np.array([0.20158356, 0.3127131, 0.40794048, 0.5984148, 0.6936519, 0.85238045, 0.899999, 0.95555407, 0.98729974, 1.0])
of_cNdrR = np.array([0.08621394, 0.14687876, 0.19345148, 0.2942731, 0.36003628, 0.43748564, 0.44762507, 0.38839236, 0.29782477, 0.0])
of_cTdrR = np.array([0.048268348, 0.051957503, 0.05304592, 0.052862607, 0.056001827, 0.0536646, 0.050112925, 0.038993906, 0.023664437, 0.0])
of_ct = 0.69787693
of_cp = 0.48813498
Create SHARPy case¶
Definition of parameters
[4]:
# Mathematical constants
deg2rad = np.pi/180.
# Case
case = 'rotor'
# route = os.path.dirname(os.path.realpath(__file__)) + '/'
route = './'
# Geometry discretization
chord_panels = np.array([8], dtype=int)
revs_in_wake = 5
# Operation
rotation_velocity = 12.1*2*np.pi/60
pitch_deg = 0. #degrees
# Wind
WSP = 12.
air_density = 1.225
# Simulation
dphi = 4.*deg2rad
revs_to_simulate = 5
Computation of associated parameters
[5]:
dt = dphi/rotation_velocity
time_steps = int(revs_to_simulate*2.*np.pi/dphi)
mstar = int(revs_in_wake*2.*np.pi/dphi)
Generation of the rotor geometry based on the information in the excel file
[6]:
rotor = template_wt.rotor_from_excel_type02(
chord_panels,
rotation_velocity,
pitch_deg,
excel_file_name= 'source/type02_db_NREL5MW_v01.xlsx',
excel_sheet_parameters = 'parameters',
excel_sheet_structural_blade = 'structural_blade',
excel_sheet_discretization_blade = 'discretization_blade',
excel_sheet_aero_blade = 'aero_blade',
excel_sheet_airfoil_info = 'airfoil_info',
excel_sheet_airfoil_coord = 'airfoil_coord',
m_distribution = 'uniform',
n_points_camber = 100,
tol_remove_points = 1e-8,
wsp = WSP,
dt = dt)
WARNING: The poisson cofficient is assumed equal to 0.3
WARNING: Cross-section area is used as shear area
WARNING: Using perpendicular axis theorem to compute the inertia around xB
WARNING: Replacing node 49 by node 0
WARNING: Replacing node 98 by node 0
Define simulation details. The steady simulation is faster than the dynamic simulation. However, the dynamic simulation includes wake self-induction and provides more accurate results.
[7]:
steady_simulation = False
[8]:
SimInfo = gc.SimulationInformation()
SimInfo.set_default_values()
if steady_simulation:
SimInfo.solvers['SHARPy']['flow'] = ['BeamLoader',
'AerogridLoader',
'StaticCoupledRBM',
'BeamPlot',
'AerogridPlot',
'SaveData']
else:
SimInfo.solvers['SHARPy']['flow'] = ['BeamLoader',
'AerogridLoader',
'StaticCoupledRBM',
'DynamicCoupled']
SimInfo.solvers['SHARPy']['case'] = case
SimInfo.solvers['SHARPy']['route'] = route
SimInfo.solvers['SHARPy']['write_log'] = True
SimInfo.set_variable_all_dicts('dt', dt)
SimInfo.set_variable_all_dicts('rho', air_density)
SimInfo.solvers['SteadyVelocityField']['u_inf'] = WSP
SimInfo.solvers['SteadyVelocityField']['u_inf_direction'] = np.array([0., 0., 1.])
SimInfo.solvers['BeamLoader']['unsteady'] = 'on'
SimInfo.solvers['AerogridLoader']['unsteady'] = 'on'
SimInfo.solvers['AerogridLoader']['mstar'] = mstar
SimInfo.solvers['AerogridLoader']['freestream_dir'] = np.array([0.,0.,0.])
SimInfo.solvers['StaticCoupledRBM']['structural_solver'] = 'RigidDynamicPrescribedStep'
SimInfo.solvers['StaticCoupledRBM']['structural_solver_settings'] = SimInfo.solvers['RigidDynamicPrescribedStep']
SimInfo.solvers['StaticCoupledRBM']['aero_solver'] = 'SHWUvlm'
SimInfo.solvers['StaticCoupledRBM']['aero_solver_settings'] = SimInfo.solvers['SHWUvlm']
SimInfo.solvers['StaticCoupledRBM']['tolerance'] = 1e-8
SimInfo.solvers['StaticCoupledRBM']['n_load_steps'] = 0
SimInfo.solvers['StaticCoupledRBM']['relaxation_factor'] = 0.
SimInfo.solvers['SHWUvlm']['convection_scheme'] = 2
SimInfo.solvers['SHWUvlm']['num_cores'] = 8
SimInfo.solvers['SHWUvlm']['rot_vel'] = rotation_velocity
SimInfo.solvers['SHWUvlm']['rot_axis'] = np.array([0.,0.,1.])
SimInfo.solvers['SHWUvlm']['rot_center'] = np.zeros((3),)
SimInfo.solvers['SHWUvlm']['velocity_field_generator'] = 'SteadyVelocityField'
SimInfo.solvers['SHWUvlm']['velocity_field_input'] = SimInfo.solvers['SteadyVelocityField']
SimInfo.solvers['SaveData']['compress_float'] = True
# Only used for steady_simulation = False
SimInfo.solvers['StepUvlm']['convection_scheme'] = 3
SimInfo.solvers['StepUvlm']['num_cores'] = 8
SimInfo.solvers['StepUvlm']['velocity_field_generator'] = 'SteadyVelocityField'
SimInfo.solvers['StepUvlm']['velocity_field_input'] = SimInfo.solvers['SteadyVelocityField']
SimInfo.solvers['DynamicCoupled']['structural_solver'] = 'RigidDynamicPrescribedStep'
SimInfo.solvers['DynamicCoupled']['structural_solver_settings'] = SimInfo.solvers['RigidDynamicPrescribedStep']
SimInfo.solvers['DynamicCoupled']['aero_solver'] = 'StepUvlm'
SimInfo.solvers['DynamicCoupled']['aero_solver_settings'] = SimInfo.solvers['StepUvlm']
SimInfo.solvers['DynamicCoupled']['postprocessors'] = ['BeamPlot', 'AerogridPlot', 'Cleanup', 'SaveData']
SimInfo.solvers['DynamicCoupled']['postprocessors_settings'] = {'BeamPlot': SimInfo.solvers['BeamPlot'],
'AerogridPlot': SimInfo.solvers['AerogridPlot'],
'Cleanup': SimInfo.solvers['Cleanup'],
'SaveData': SimInfo.solvers['SaveData']}
SimInfo.solvers['DynamicCoupled']['minimum_steps'] = 0
SimInfo.solvers['DynamicCoupled']['include_unsteady_force_contribution'] = True
SimInfo.solvers['DynamicCoupled']['relaxation_factor'] = 0.
SimInfo.solvers['DynamicCoupled']['final_relaxation_factor'] = 0.
SimInfo.solvers['DynamicCoupled']['dynamic_relaxation'] = False
SimInfo.solvers['DynamicCoupled']['relaxation_steps'] = 0
# Define dynamic simulation (used regardless the value of "steady_simulation" variable)
SimInfo.define_num_steps(time_steps)
SimInfo.with_forced_vel = True
SimInfo.for_vel = np.zeros((time_steps,6), dtype=float)
SimInfo.for_vel[:,5] = rotation_velocity
SimInfo.for_acc = np.zeros((time_steps,6), dtype=float)
SimInfo.with_dynamic_forces = True
SimInfo.dynamic_forces = np.zeros((time_steps,rotor.StructuralInformation.num_node,6), dtype=float)
Generate simulation files
[9]:
gc.clean_test_files(SimInfo.solvers['SHARPy']['route'], SimInfo.solvers['SHARPy']['case'])
rotor.generate_h5_files(SimInfo.solvers['SHARPy']['route'], SimInfo.solvers['SHARPy']['case'])
SimInfo.generate_solver_file()
SimInfo.generate_dyn_file(time_steps)
Run SHARPy case¶
[10]:
sharpy_output = sharpy.sharpy_main.main(['', SimInfo.solvers['SHARPy']['route'] + SimInfo.solvers['SHARPy']['case'] + '.sharpy'])
--------------------------------------------------------------------------------
###### ## ## ### ######## ######## ## ##
## ## ## ## ## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ## ## ####
###### ######### ## ## ######## ######## ##
## ## ## ######### ## ## ## ##
## ## ## ## ## ## ## ## ## ##
###### ## ## ## ## ## ## ## ##
--------------------------------------------------------------------------------
Aeroelastics Lab, Aeronautics Department.
Copyright (c), Imperial College London.
All rights reserved.
License available at https://github.com/imperialcollegelondon/sharpy
Running SHARPy from /home/arturo/code/sharpy/docs/source/content/example_notebooks
SHARPy being run is in /home/arturo/code/sharpy
The branch being run is dev_doc
The version and commit hash are: v0.1-1816-g6185d82-6185d82
The available solvers on this session are:
_BaseStructural
AerogridLoader
BeamLoader
DynamicCoupled
DynamicUVLM
LinDynamicSim
LinearAssembler
Modal
NoAero
NonLinearDynamic
NonLinearDynamicCoupledStep
NonLinearDynamicMultibody
NonLinearDynamicPrescribedStep
NonLinearStatic
NonLinearStaticMultibody
PrescribedUvlm
RigidDynamicPrescribedStep
SHWUvlm
StaticCoupled
StaticCoupledRBM
StaticTrim
StaticUvlm
StepLinearUVLM
StepUvlm
Trim
FrequencyResponse
WriteVariablesTime
BeamPlot
LiftDistribution
AeroForcesCalculator
CreateSnapshot
StabilityDerivatives
Cleanup
AsymptoticStability
PickleData
SaveData
StallCheck
BeamLoads
PlotFlowField
AerogridPlot
PreSharpy
Generating an instance of BeamLoader
Generating an instance of AerogridLoader
The aerodynamic grid contains 3 surfaces
Surface 0, M=8, N=48
Wake 0, M=450, N=48
Surface 1, M=8, N=48
Wake 1, M=450, N=48
Surface 2, M=8, N=48
Wake 2, M=450, N=48
In total: 1152 bound panels
In total: 64800 wake panels
Total number of panels = 65952
Generating an instance of StaticCoupledRBM
Generating an instance of RigidDynamicPrescribedStep
Generating an instance of SHWUvlm
i_step: 0, i_iter: 0
i_step: 0, i_iter: 1
Pos res = 0.000000e+00. Psi res = 0.000000e+00.
Pos_dot res = 0.000000e+00. Psi_dot res = 0.000000e+00.
Resultant forces and moments: (array([1.19344329e-02, 4.42818203e-03, 8.51720587e+05]), array([-2.23034084e-02, 8.00768152e-03, 6.02114389e+06]))
Generating an instance of DynamicCoupled
Generating an instance of RigidDynamicPrescribedStep
Generating an instance of StepUvlm
Generating an instance of BeamPlot
Generating an instance of AerogridPlot
Generating an instance of Cleanup
Generating an instance of SaveData
Variable save_linear has no assigned value in the settings file.
will default to the value: c_bool(False)
Variable save_linear_uvlm has no assigned value in the settings file.
will default to the value: c_bool(False)
Variable skip_attr has no assigned value in the settings file.
will default to the value: ['fortran', 'airfoils', 'airfoil_db', 'settings_types', 'ct_dynamic_forces_list', 'ct_gamma_dot_list', 'ct_gamma_list', 'ct_gamma_star_list', 'ct_normals_list', 'ct_u_ext_list', 'ct_u_ext_star_list', 'ct_zeta_dot_list', 'ct_zeta_list', 'ct_zeta_star_list', 'dynamic_input', ['fortran', 'airfoils', 'airfoil_db', 'settings_types', 'ct_dynamic_forces_list', 'ct_forces_list', 'ct_gamma_dot_list', 'ct_gamma_list', 'ct_gamma_star_list', 'ct_normals_list', 'ct_u_ext_list', 'ct_u_ext_star_list', 'ct_zeta_dot_list', 'ct_zeta_list', 'ct_zeta_star_list', 'dynamic_input']]
Variable format has no assigned value in the settings file.
will default to the value: h5
|=======|========|======|==============|==============|==============|==============|==============|
| ts | t | iter | struc ratio | iter time | residual vel | FoR_vel(x) | FoR_vel(z) |
|=======|========|======|==============|==============|==============|==============|==============|
/home/arturo/code/sharpy/sharpy/solvers/dynamiccoupled.py:449: RuntimeWarning: divide by zero encountered in log10
np.log10(self.res_dqdt),
| 1 | 0.0551 | 1 | 0.000689 | 46.721959 | -inf | 0.000000e+00 | 0.000000e+00 |
| 2 | 0.1102 | 1 | 0.000686 | 46.839166 | -inf | 0.000000e+00 | 0.000000e+00 |
| 3 | 0.1653 | 1 | 0.000687 | 46.816562 | -inf | 0.000000e+00 | 0.000000e+00 |
| 4 | 0.2204 | 1 | 0.000666 | 48.386563 | -inf | 0.000000e+00 | 0.000000e+00 |
| 5 | 0.2755 | 1 | 0.000683 | 47.135425 | -inf | 0.000000e+00 | 0.000000e+00 |
| 6 | 0.3306 | 1 | 0.000707 | 46.560263 | -inf | 0.000000e+00 | 0.000000e+00 |
| 7 | 0.3857 | 1 | 0.000697 | 46.562699 | -inf | 0.000000e+00 | 0.000000e+00 |
| 8 | 0.4408 | 1 | 0.000692 | 46.757933 | -inf | 0.000000e+00 | 0.000000e+00 |
| 9 | 0.4959 | 1 | 0.000691 | 46.622405 | -inf | 0.000000e+00 | 0.000000e+00 |
| 10 | 0.5510 | 1 | 0.000700 | 46.480478 | -inf | 0.000000e+00 | 0.000000e+00 |
| 11 | 0.6061 | 1 | 0.000703 | 46.450803 | -inf | 0.000000e+00 | 0.000000e+00 |
| 12 | 0.6612 | 1 | 0.000708 | 46.466538 | -inf | 0.000000e+00 | 0.000000e+00 |
| 13 | 0.7163 | 1 | 0.000576 | 55.899692 | -inf | 0.000000e+00 | 0.000000e+00 |
| 14 | 0.7713 | 1 | 0.000642 | 50.701285 | -inf | 0.000000e+00 | 0.000000e+00 |
| 15 | 0.8264 | 1 | 0.000671 | 47.593583 | -inf | 0.000000e+00 | 0.000000e+00 |
| 16 | 0.8815 | 1 | 0.000699 | 47.287386 | -inf | 0.000000e+00 | 0.000000e+00 |
| 17 | 0.9366 | 1 | 0.000691 | 46.559619 | -inf | 0.000000e+00 | 0.000000e+00 |
| 18 | 0.9917 | 1 | 0.000681 | 46.953868 | -inf | 0.000000e+00 | 0.000000e+00 |
| 19 | 1.0468 | 1 | 0.000693 | 46.526422 | -inf | 0.000000e+00 | 0.000000e+00 |
| 20 | 1.1019 | 1 | 0.000692 | 46.634115 | -inf | 0.000000e+00 | 0.000000e+00 |
| 21 | 1.1570 | 1 | 0.000691 | 46.424641 | -inf | 0.000000e+00 | 0.000000e+00 |
| 22 | 1.2121 | 1 | 0.000684 | 46.882152 | -inf | 0.000000e+00 | 0.000000e+00 |
| 23 | 1.2672 | 1 | 0.000694 | 46.586424 | -inf | 0.000000e+00 | 0.000000e+00 |
| 24 | 1.3223 | 1 | 0.000687 | 46.776280 | -inf | 0.000000e+00 | 0.000000e+00 |
| 25 | 1.3774 | 1 | 0.000692 | 46.704067 | -inf | 0.000000e+00 | 0.000000e+00 |
| 26 | 1.4325 | 1 | 0.000679 | 46.886657 | -inf | 0.000000e+00 | 0.000000e+00 |
| 27 | 1.4876 | 1 | 0.000684 | 46.516365 | -inf | 0.000000e+00 | 0.000000e+00 |
| 28 | 1.5427 | 1 | 0.000682 | 46.684166 | -inf | 0.000000e+00 | 0.000000e+00 |
| 29 | 1.5978 | 1 | 0.000683 | 47.033028 | -inf | 0.000000e+00 | 0.000000e+00 |
| 30 | 1.6529 | 1 | 0.000694 | 46.291923 | -inf | 0.000000e+00 | 0.000000e+00 |
| 31 | 1.7080 | 1 | 0.000687 | 46.680159 | -inf | 0.000000e+00 | 0.000000e+00 |
| 32 | 1.7631 | 1 | 0.000683 | 46.629501 | -inf | 0.000000e+00 | 0.000000e+00 |
| 33 | 1.8182 | 1 | 0.000682 | 46.806173 | -inf | 0.000000e+00 | 0.000000e+00 |
| 34 | 1.8733 | 1 | 0.000687 | 46.757005 | -inf | 0.000000e+00 | 0.000000e+00 |
| 35 | 1.9284 | 1 | 0.000683 | 47.033428 | -inf | 0.000000e+00 | 0.000000e+00 |
| 36 | 1.9835 | 1 | 0.000659 | 48.662729 | -inf | 0.000000e+00 | 0.000000e+00 |
| 37 | 2.0386 | 1 | 0.000659 | 48.571643 | -inf | 0.000000e+00 | 0.000000e+00 |
| 38 | 2.0937 | 1 | 0.000673 | 47.434747 | -inf | 0.000000e+00 | 0.000000e+00 |
| 39 | 2.1488 | 1 | 0.000661 | 48.286789 | -inf | 0.000000e+00 | 0.000000e+00 |
| 40 | 2.2039 | 1 | 0.000679 | 47.779096 | -inf | 0.000000e+00 | 0.000000e+00 |
| 41 | 2.2590 | 1 | 0.000677 | 48.413777 | -inf | 0.000000e+00 | 0.000000e+00 |
| 42 | 2.3140 | 1 | 0.000671 | 47.798777 | -inf | 0.000000e+00 | 0.000000e+00 |
| 43 | 2.3691 | 1 | 0.000710 | 46.501405 | -inf | 0.000000e+00 | 0.000000e+00 |
| 44 | 2.4242 | 1 | 0.000690 | 46.611010 | -inf | 0.000000e+00 | 0.000000e+00 |
| 45 | 2.4793 | 1 | 0.000688 | 46.704990 | -inf | 0.000000e+00 | 0.000000e+00 |
| 46 | 2.5344 | 1 | 0.000728 | 46.796206 | -inf | 0.000000e+00 | 0.000000e+00 |
| 47 | 2.5895 | 1 | 0.000693 | 46.510013 | -inf | 0.000000e+00 | 0.000000e+00 |
| 48 | 2.6446 | 1 | 0.000692 | 46.604489 | -inf | 0.000000e+00 | 0.000000e+00 |
| 49 | 2.6997 | 1 | 0.000693 | 46.648462 | -inf | 0.000000e+00 | 0.000000e+00 |
| 50 | 2.7548 | 1 | 0.000703 | 46.233052 | -inf | 0.000000e+00 | 0.000000e+00 |
| 51 | 2.8099 | 1 | 0.000696 | 46.494563 | -inf | 0.000000e+00 | 0.000000e+00 |
| 52 | 2.8650 | 1 | 0.000689 | 46.427002 | -inf | 0.000000e+00 | 0.000000e+00 |
| 53 | 2.9201 | 1 | 0.000685 | 46.556616 | -inf | 0.000000e+00 | 0.000000e+00 |
| 54 | 2.9752 | 1 | 0.000688 | 46.986618 | -inf | 0.000000e+00 | 0.000000e+00 |
| 55 | 3.0303 | 1 | 0.000685 | 47.021588 | -inf | 0.000000e+00 | 0.000000e+00 |
| 56 | 3.0854 | 1 | 0.000695 | 46.501523 | -inf | 0.000000e+00 | 0.000000e+00 |
| 57 | 3.1405 | 1 | 0.000690 | 46.545832 | -inf | 0.000000e+00 | 0.000000e+00 |
| 58 | 3.1956 | 1 | 0.000688 | 46.394942 | -inf | 0.000000e+00 | 0.000000e+00 |
| 59 | 3.2507 | 1 | 0.000690 | 46.572368 | -inf | 0.000000e+00 | 0.000000e+00 |
| 60 | 3.3058 | 1 | 0.000689 | 46.388416 | -inf | 0.000000e+00 | 0.000000e+00 |
| 61 | 3.3609 | 1 | 0.000674 | 47.326130 | -inf | 0.000000e+00 | 0.000000e+00 |
| 62 | 3.4160 | 1 | 0.000691 | 46.475252 | -inf | 0.000000e+00 | 0.000000e+00 |
| 63 | 3.4711 | 1 | 0.000692 | 46.700463 | -inf | 0.000000e+00 | 0.000000e+00 |
| 64 | 3.5262 | 1 | 0.000684 | 46.761324 | -inf | 0.000000e+00 | 0.000000e+00 |
| 65 | 3.5813 | 1 | 0.000690 | 46.305145 | -inf | 0.000000e+00 | 0.000000e+00 |
| 66 | 3.6364 | 1 | 0.000681 | 47.033500 | -inf | 0.000000e+00 | 0.000000e+00 |
| 67 | 3.6915 | 1 | 0.000690 | 46.707418 | -inf | 0.000000e+00 | 0.000000e+00 |
| 68 | 3.7466 | 1 | 0.000687 | 46.829002 | -inf | 0.000000e+00 | 0.000000e+00 |
| 69 | 3.8017 | 1 | 0.000686 | 46.771566 | -inf | 0.000000e+00 | 0.000000e+00 |
| 70 | 3.8567 | 1 | 0.000687 | 46.798868 | -inf | 0.000000e+00 | 0.000000e+00 |
| 71 | 3.9118 | 1 | 0.000687 | 46.656061 | -inf | 0.000000e+00 | 0.000000e+00 |
| 72 | 3.9669 | 1 | 0.000689 | 46.650955 | -inf | 0.000000e+00 | 0.000000e+00 |
| 73 | 4.0220 | 1 | 0.000689 | 46.676483 | -inf | 0.000000e+00 | 0.000000e+00 |
| 74 | 4.0771 | 1 | 0.000701 | 46.733123 | -inf | 0.000000e+00 | 0.000000e+00 |
| 75 | 4.1322 | 1 | 0.000693 | 46.613006 | -inf | 0.000000e+00 | 0.000000e+00 |
| 76 | 4.1873 | 1 | 0.000691 | 46.569005 | -inf | 0.000000e+00 | 0.000000e+00 |
| 77 | 4.2424 | 1 | 0.000691 | 46.714434 | -inf | 0.000000e+00 | 0.000000e+00 |
| 78 | 4.2975 | 1 | 0.000691 | 46.564491 | -inf | 0.000000e+00 | 0.000000e+00 |
| 79 | 4.3526 | 1 | 0.000691 | 46.293432 | -inf | 0.000000e+00 | 0.000000e+00 |
| 80 | 4.4077 | 1 | 0.000691 | 46.444557 | -inf | 0.000000e+00 | 0.000000e+00 |
| 81 | 4.4628 | 1 | 0.000685 | 46.583821 | -inf | 0.000000e+00 | 0.000000e+00 |
| 82 | 4.5179 | 1 | 0.000692 | 46.464751 | -inf | 0.000000e+00 | 0.000000e+00 |
| 83 | 4.5730 | 1 | 0.000691 | 46.614111 | -inf | 0.000000e+00 | 0.000000e+00 |
| 84 | 4.6281 | 1 | 0.000682 | 47.093682 | -inf | 0.000000e+00 | 0.000000e+00 |
| 85 | 4.6832 | 1 | 0.000668 | 47.848219 | -inf | 0.000000e+00 | 0.000000e+00 |
| 86 | 4.7383 | 1 | 0.000690 | 46.453935 | -inf | 0.000000e+00 | 0.000000e+00 |
| 87 | 4.7934 | 1 | 0.000671 | 47.508853 | -inf | 0.000000e+00 | 0.000000e+00 |
| 88 | 4.8485 | 1 | 0.000704 | 46.453028 | -inf | 0.000000e+00 | 0.000000e+00 |
| 89 | 4.9036 | 1 | 0.000686 | 46.783497 | -inf | 0.000000e+00 | 0.000000e+00 |
| 90 | 4.9587 | 1 | 0.000695 | 46.473095 | -inf | 0.000000e+00 | 0.000000e+00 |
| 91 | 5.0138 | 1 | 0.000699 | 46.384601 | -inf | 0.000000e+00 | 0.000000e+00 |
| 92 | 5.0689 | 1 | 0.000671 | 48.773508 | -inf | 0.000000e+00 | 0.000000e+00 |
| 93 | 5.1240 | 1 | 0.000682 | 46.843241 | -inf | 0.000000e+00 | 0.000000e+00 |
| 94 | 5.1791 | 1 | 0.000691 | 46.690389 | -inf | 0.000000e+00 | 0.000000e+00 |
| 95 | 5.2342 | 1 | 0.000685 | 46.811431 | -inf | 0.000000e+00 | 0.000000e+00 |
| 96 | 5.2893 | 1 | 0.000683 | 46.832472 | -inf | 0.000000e+00 | 0.000000e+00 |
| 97 | 5.3444 | 1 | 0.000690 | 46.410221 | -inf | 0.000000e+00 | 0.000000e+00 |
| 98 | 5.3994 | 1 | 0.000693 | 46.644631 | -inf | 0.000000e+00 | 0.000000e+00 |
| 99 | 5.4545 | 1 | 0.000695 | 46.328560 | -inf | 0.000000e+00 | 0.000000e+00 |
| 100 | 5.5096 | 1 | 0.000693 | 46.709863 | -inf | 0.000000e+00 | 0.000000e+00 |
| 101 | 5.5647 | 1 | 0.000696 | 46.303366 | -inf | 0.000000e+00 | 0.000000e+00 |
| 102 | 5.6198 | 1 | 0.000688 | 46.450453 | -inf | 0.000000e+00 | 0.000000e+00 |
| 103 | 5.6749 | 1 | 0.000704 | 46.611641 | -inf | 0.000000e+00 | 0.000000e+00 |
| 104 | 5.7300 | 1 | 0.000686 | 46.622834 | -inf | 0.000000e+00 | 0.000000e+00 |
| 105 | 5.7851 | 1 | 0.000693 | 46.442312 | -inf | 0.000000e+00 | 0.000000e+00 |
| 106 | 5.8402 | 1 | 0.000697 | 46.894939 | -inf | 0.000000e+00 | 0.000000e+00 |
| 107 | 5.8953 | 1 | 0.000695 | 46.583571 | -inf | 0.000000e+00 | 0.000000e+00 |
| 108 | 5.9504 | 1 | 0.000692 | 46.596199 | -inf | 0.000000e+00 | 0.000000e+00 |
| 109 | 6.0055 | 1 | 0.000689 | 46.675746 | -inf | 0.000000e+00 | 0.000000e+00 |
| 110 | 6.0606 | 1 | 0.000688 | 46.948383 | -inf | 0.000000e+00 | 0.000000e+00 |
| 111 | 6.1157 | 1 | 0.000708 | 46.583486 | -inf | 0.000000e+00 | 0.000000e+00 |
| 112 | 6.1708 | 1 | 0.000687 | 46.777358 | -inf | 0.000000e+00 | 0.000000e+00 |
| 113 | 6.2259 | 1 | 0.000696 | 46.655726 | -inf | 0.000000e+00 | 0.000000e+00 |
| 114 | 6.2810 | 1 | 0.000692 | 46.488556 | -inf | 0.000000e+00 | 0.000000e+00 |
| 115 | 6.3361 | 1 | 0.000687 | 46.641207 | -inf | 0.000000e+00 | 0.000000e+00 |
| 116 | 6.3912 | 1 | 0.000699 | 46.693835 | -inf | 0.000000e+00 | 0.000000e+00 |
| 117 | 6.4463 | 1 | 0.000717 | 47.359647 | -inf | 0.000000e+00 | 0.000000e+00 |
| 118 | 6.5014 | 1 | 0.000689 | 46.684606 | -inf | 0.000000e+00 | 0.000000e+00 |
| 119 | 6.5565 | 1 | 0.000686 | 46.892280 | -inf | 0.000000e+00 | 0.000000e+00 |
| 120 | 6.6116 | 1 | 0.000690 | 46.391236 | -inf | 0.000000e+00 | 0.000000e+00 |
| 121 | 6.6667 | 1 | 0.000687 | 46.619935 | -inf | 0.000000e+00 | 0.000000e+00 |
| 122 | 6.7218 | 1 | 0.000685 | 46.847298 | -inf | 0.000000e+00 | 0.000000e+00 |
| 123 | 6.7769 | 1 | 0.000698 | 46.383369 | -inf | 0.000000e+00 | 0.000000e+00 |
| 124 | 6.8320 | 1 | 0.000690 | 46.623488 | -inf | 0.000000e+00 | 0.000000e+00 |
| 125 | 6.8871 | 1 | 0.000689 | 46.456695 | -inf | 0.000000e+00 | 0.000000e+00 |
| 126 | 6.9421 | 1 | 0.000748 | 46.666541 | -inf | 0.000000e+00 | 0.000000e+00 |
| 127 | 6.9972 | 1 | 0.000695 | 46.393158 | -inf | 0.000000e+00 | 0.000000e+00 |
| 128 | 7.0523 | 1 | 0.000632 | 50.929908 | -inf | 0.000000e+00 | 0.000000e+00 |
| 129 | 7.1074 | 1 | 0.000685 | 47.093784 | -inf | 0.000000e+00 | 0.000000e+00 |
| 130 | 7.1625 | 1 | 0.000688 | 46.682273 | -inf | 0.000000e+00 | 0.000000e+00 |
| 131 | 7.2176 | 1 | 0.000690 | 46.667180 | -inf | 0.000000e+00 | 0.000000e+00 |
| 132 | 7.2727 | 1 | 0.000689 | 46.673738 | -inf | 0.000000e+00 | 0.000000e+00 |
| 133 | 7.3278 | 1 | 0.000690 | 46.813912 | -inf | 0.000000e+00 | 0.000000e+00 |
| 134 | 7.3829 | 1 | 0.000698 | 46.399704 | -inf | 0.000000e+00 | 0.000000e+00 |
| 135 | 7.4380 | 1 | 0.000687 | 46.776766 | -inf | 0.000000e+00 | 0.000000e+00 |
| 136 | 7.4931 | 1 | 0.000687 | 46.979810 | -inf | 0.000000e+00 | 0.000000e+00 |
| 137 | 7.5482 | 1 | 0.000693 | 46.578824 | -inf | 0.000000e+00 | 0.000000e+00 |
| 138 | 7.6033 | 1 | 0.000689 | 46.882381 | -inf | 0.000000e+00 | 0.000000e+00 |
| 139 | 7.6584 | 1 | 0.000676 | 48.142078 | -inf | 0.000000e+00 | 0.000000e+00 |
| 140 | 7.7135 | 1 | 0.000693 | 46.784018 | -inf | 0.000000e+00 | 0.000000e+00 |
| 141 | 7.7686 | 1 | 0.000688 | 46.642419 | -inf | 0.000000e+00 | 0.000000e+00 |
| 142 | 7.8237 | 1 | 0.000689 | 46.662693 | -inf | 0.000000e+00 | 0.000000e+00 |
| 143 | 7.8788 | 1 | 0.000689 | 46.802617 | -inf | 0.000000e+00 | 0.000000e+00 |
| 144 | 7.9339 | 1 | 0.000690 | 46.776085 | -inf | 0.000000e+00 | 0.000000e+00 |
| 145 | 7.9890 | 1 | 0.000701 | 46.875717 | -inf | 0.000000e+00 | 0.000000e+00 |
| 146 | 8.0441 | 1 | 0.000685 | 46.822466 | -inf | 0.000000e+00 | 0.000000e+00 |
| 147 | 8.0992 | 1 | 0.000677 | 47.384767 | -inf | 0.000000e+00 | 0.000000e+00 |
| 148 | 8.1543 | 1 | 0.000675 | 47.679214 | -inf | 0.000000e+00 | 0.000000e+00 |
| 149 | 8.2094 | 1 | 0.000689 | 46.763218 | -inf | 0.000000e+00 | 0.000000e+00 |
| 150 | 8.2645 | 1 | 0.000679 | 46.940251 | -inf | 0.000000e+00 | 0.000000e+00 |
| 151 | 8.3196 | 1 | 0.000686 | 46.627359 | -inf | 0.000000e+00 | 0.000000e+00 |
| 152 | 8.3747 | 1 | 0.000687 | 46.664798 | -inf | 0.000000e+00 | 0.000000e+00 |
| 153 | 8.4298 | 1 | 0.000687 | 46.633910 | -inf | 0.000000e+00 | 0.000000e+00 |
| 154 | 8.4848 | 1 | 0.000679 | 46.877187 | -inf | 0.000000e+00 | 0.000000e+00 |
| 155 | 8.5399 | 1 | 0.000696 | 46.384902 | -inf | 0.000000e+00 | 0.000000e+00 |
| 156 | 8.5950 | 1 | 0.000690 | 46.680191 | -inf | 0.000000e+00 | 0.000000e+00 |
| 157 | 8.6501 | 1 | 0.000690 | 46.595866 | -inf | 0.000000e+00 | 0.000000e+00 |
| 158 | 8.7052 | 1 | 0.000711 | 46.561896 | -inf | 0.000000e+00 | 0.000000e+00 |
| 159 | 8.7603 | 1 | 0.000682 | 46.789459 | -inf | 0.000000e+00 | 0.000000e+00 |
| 160 | 8.8154 | 1 | 0.000712 | 46.585605 | -inf | 0.000000e+00 | 0.000000e+00 |
| 161 | 8.8705 | 1 | 0.000674 | 47.731465 | -inf | 0.000000e+00 | 0.000000e+00 |
| 162 | 8.9256 | 1 | 0.000679 | 47.806239 | -inf | 0.000000e+00 | 0.000000e+00 |
| 163 | 8.9807 | 1 | 0.000687 | 46.597511 | -inf | 0.000000e+00 | 0.000000e+00 |
| 164 | 9.0358 | 1 | 0.000695 | 46.662126 | -inf | 0.000000e+00 | 0.000000e+00 |
| 165 | 9.0909 | 1 | 0.000678 | 47.138759 | -inf | 0.000000e+00 | 0.000000e+00 |
| 166 | 9.1460 | 1 | 0.000687 | 46.654425 | -inf | 0.000000e+00 | 0.000000e+00 |
| 167 | 9.2011 | 1 | 0.000683 | 47.072656 | -inf | 0.000000e+00 | 0.000000e+00 |
| 168 | 9.2562 | 1 | 0.000688 | 46.655192 | -inf | 0.000000e+00 | 0.000000e+00 |
| 169 | 9.3113 | 1 | 0.000683 | 46.990134 | -inf | 0.000000e+00 | 0.000000e+00 |
| 170 | 9.3664 | 1 | 0.000704 | 46.960453 | -inf | 0.000000e+00 | 0.000000e+00 |
| 171 | 9.4215 | 1 | 0.000688 | 46.615369 | -inf | 0.000000e+00 | 0.000000e+00 |
| 172 | 9.4766 | 1 | 0.000686 | 46.761498 | -inf | 0.000000e+00 | 0.000000e+00 |
| 173 | 9.5317 | 1 | 0.000686 | 46.698208 | -inf | 0.000000e+00 | 0.000000e+00 |
| 174 | 9.5868 | 1 | 0.000686 | 46.964062 | -inf | 0.000000e+00 | 0.000000e+00 |
| 175 | 9.6419 | 1 | 0.000693 | 46.608047 | -inf | 0.000000e+00 | 0.000000e+00 |
| 176 | 9.6970 | 1 | 0.000684 | 46.848123 | -inf | 0.000000e+00 | 0.000000e+00 |
| 177 | 9.7521 | 1 | 0.000687 | 46.693659 | -inf | 0.000000e+00 | 0.000000e+00 |
| 178 | 9.8072 | 1 | 0.000682 | 46.766093 | -inf | 0.000000e+00 | 0.000000e+00 |
| 179 | 9.8623 | 1 | 0.000689 | 46.497713 | -inf | 0.000000e+00 | 0.000000e+00 |
| 180 | 9.9174 | 1 | 0.000694 | 46.824867 | -inf | 0.000000e+00 | 0.000000e+00 |
| 181 | 9.9725 | 1 | 0.000686 | 46.686000 | -inf | 0.000000e+00 | 0.000000e+00 |
| 182 |10.0275 | 1 | 0.000687 | 46.847956 | -inf | 0.000000e+00 | 0.000000e+00 |
| 183 |10.0826 | 1 | 0.000696 | 46.639555 | -inf | 0.000000e+00 | 0.000000e+00 |
| 184 |10.1377 | 1 | 0.000694 | 46.582859 | -inf | 0.000000e+00 | 0.000000e+00 |
| 185 |10.1928 | 1 | 0.000692 | 46.696143 | -inf | 0.000000e+00 | 0.000000e+00 |
| 186 |10.2479 | 1 | 0.000688 | 47.038347 | -inf | 0.000000e+00 | 0.000000e+00 |
| 187 |10.3030 | 1 | 0.000662 | 48.575645 | -inf | 0.000000e+00 | 0.000000e+00 |
| 188 |10.3581 | 1 | 0.000662 | 48.531096 | -inf | 0.000000e+00 | 0.000000e+00 |
| 189 |10.4132 | 1 | 0.000674 | 47.867980 | -inf | 0.000000e+00 | 0.000000e+00 |
| 190 |10.4683 | 1 | 0.000683 | 47.185120 | -inf | 0.000000e+00 | 0.000000e+00 |
| 191 |10.5234 | 1 | 0.000680 | 47.472356 | -inf | 0.000000e+00 | 0.000000e+00 |
| 192 |10.5785 | 1 | 0.000671 | 48.044142 | -inf | 0.000000e+00 | 0.000000e+00 |
| 193 |10.6336 | 1 | 0.000679 | 47.648927 | -inf | 0.000000e+00 | 0.000000e+00 |
| 194 |10.6887 | 1 | 0.000669 | 48.052096 | -inf | 0.000000e+00 | 0.000000e+00 |
| 195 |10.7438 | 1 | 0.000672 | 47.870581 | -inf | 0.000000e+00 | 0.000000e+00 |
| 196 |10.7989 | 1 | 0.000688 | 47.670530 | -inf | 0.000000e+00 | 0.000000e+00 |
| 197 |10.8540 | 1 | 0.000669 | 47.552862 | -inf | 0.000000e+00 | 0.000000e+00 |
| 198 |10.9091 | 1 | 0.000668 | 47.895285 | -inf | 0.000000e+00 | 0.000000e+00 |
| 199 |10.9642 | 1 | 0.000677 | 47.475987 | -inf | 0.000000e+00 | 0.000000e+00 |
| 200 |11.0193 | 1 | 0.000689 | 47.705888 | -inf | 0.000000e+00 | 0.000000e+00 |
| 201 |11.0744 | 1 | 0.000677 | 47.488158 | -inf | 0.000000e+00 | 0.000000e+00 |
| 202 |11.1295 | 1 | 0.000712 | 48.576639 | -inf | 0.000000e+00 | 0.000000e+00 |
| 203 |11.1846 | 1 | 0.000673 | 47.734807 | -inf | 0.000000e+00 | 0.000000e+00 |
| 204 |11.2397 | 1 | 0.000670 | 47.568058 | -inf | 0.000000e+00 | 0.000000e+00 |
| 205 |11.2948 | 1 | 0.000663 | 48.250896 | -inf | 0.000000e+00 | 0.000000e+00 |
| 206 |11.3499 | 1 | 0.000670 | 47.559952 | -inf | 0.000000e+00 | 0.000000e+00 |
| 207 |11.4050 | 1 | 0.000670 | 47.573367 | -inf | 0.000000e+00 | 0.000000e+00 |
| 208 |11.4601 | 1 | 0.000687 | 46.850101 | -inf | 0.000000e+00 | 0.000000e+00 |
| 209 |11.5152 | 1 | 0.000685 | 46.660332 | -inf | 0.000000e+00 | 0.000000e+00 |
| 210 |11.5702 | 1 | 0.000685 | 46.485644 | -inf | 0.000000e+00 | 0.000000e+00 |
| 211 |11.6253 | 1 | 0.000687 | 46.798719 | -inf | 0.000000e+00 | 0.000000e+00 |
| 212 |11.6804 | 1 | 0.000688 | 46.841973 | -inf | 0.000000e+00 | 0.000000e+00 |
| 213 |11.7355 | 1 | 0.000685 | 46.615664 | -inf | 0.000000e+00 | 0.000000e+00 |
| 214 |11.7906 | 1 | 0.000685 | 46.819705 | -inf | 0.000000e+00 | 0.000000e+00 |
| 215 |11.8457 | 1 | 0.000695 | 46.534639 | -inf | 0.000000e+00 | 0.000000e+00 |
| 216 |11.9008 | 1 | 0.000687 | 47.054001 | -inf | 0.000000e+00 | 0.000000e+00 |
| 217 |11.9559 | 1 | 0.000685 | 46.458661 | -inf | 0.000000e+00 | 0.000000e+00 |
| 218 |12.0110 | 1 | 0.000685 | 46.475964 | -inf | 0.000000e+00 | 0.000000e+00 |
| 219 |12.0661 | 1 | 0.000681 | 46.980705 | -inf | 0.000000e+00 | 0.000000e+00 |
| 220 |12.1212 | 1 | 0.000683 | 46.885118 | -inf | 0.000000e+00 | 0.000000e+00 |
| 221 |12.1763 | 1 | 0.000690 | 46.385044 | -inf | 0.000000e+00 | 0.000000e+00 |
| 222 |12.2314 | 1 | 0.000687 | 46.472218 | -inf | 0.000000e+00 | 0.000000e+00 |
| 223 |12.2865 | 1 | 0.000711 | 46.681981 | -inf | 0.000000e+00 | 0.000000e+00 |
| 224 |12.3416 | 1 | 0.000686 | 46.755873 | -inf | 0.000000e+00 | 0.000000e+00 |
| 225 |12.3967 | 1 | 0.000684 | 47.479635 | -inf | 0.000000e+00 | 0.000000e+00 |
| 226 |12.4518 | 1 | 0.000697 | 46.237011 | -inf | 0.000000e+00 | 0.000000e+00 |
| 227 |12.5069 | 1 | 0.000681 | 46.954574 | -inf | 0.000000e+00 | 0.000000e+00 |
| 228 |12.5620 | 1 | 0.000665 | 47.804645 | -inf | 0.000000e+00 | 0.000000e+00 |
| 229 |12.6171 | 1 | 0.000683 | 46.649178 | -inf | 0.000000e+00 | 0.000000e+00 |
| 230 |12.6722 | 1 | 0.000619 | 51.822896 | -inf | 0.000000e+00 | 0.000000e+00 |
| 231 |12.7273 | 1 | 0.000691 | 46.453337 | -inf | 0.000000e+00 | 0.000000e+00 |
| 232 |12.7824 | 1 | 0.000688 | 46.512926 | -inf | 0.000000e+00 | 0.000000e+00 |
| 233 |12.8375 | 1 | 0.000693 | 46.372334 | -inf | 0.000000e+00 | 0.000000e+00 |
| 234 |12.8926 | 1 | 0.000691 | 46.443784 | -inf | 0.000000e+00 | 0.000000e+00 |
| 235 |12.9477 | 1 | 0.000685 | 46.595713 | -inf | 0.000000e+00 | 0.000000e+00 |
| 236 |13.0028 | 1 | 0.000685 | 46.675990 | -inf | 0.000000e+00 | 0.000000e+00 |
| 237 |13.0579 | 1 | 0.000673 | 47.477098 | -inf | 0.000000e+00 | 0.000000e+00 |
| 238 |13.1129 | 1 | 0.000685 | 46.907466 | -inf | 0.000000e+00 | 0.000000e+00 |
| 239 |13.1680 | 1 | 0.000679 | 46.745359 | -inf | 0.000000e+00 | 0.000000e+00 |
| 240 |13.2231 | 1 | 0.000667 | 47.812544 | -inf | 0.000000e+00 | 0.000000e+00 |
| 241 |13.2782 | 1 | 0.000676 | 46.828156 | -inf | 0.000000e+00 | 0.000000e+00 |
| 242 |13.3333 | 1 | 0.000674 | 47.228874 | -inf | 0.000000e+00 | 0.000000e+00 |
| 243 |13.3884 | 1 | 0.000675 | 47.213317 | -inf | 0.000000e+00 | 0.000000e+00 |
| 244 |13.4435 | 1 | 0.000685 | 46.946864 | -inf | 0.000000e+00 | 0.000000e+00 |
| 245 |13.4986 | 1 | 0.000686 | 46.518108 | -inf | 0.000000e+00 | 0.000000e+00 |
| 246 |13.5537 | 1 | 0.000683 | 46.918194 | -inf | 0.000000e+00 | 0.000000e+00 |
| 247 |13.6088 | 1 | 0.000681 | 46.772611 | -inf | 0.000000e+00 | 0.000000e+00 |
| 248 |13.6639 | 1 | 0.000681 | 46.738571 | -inf | 0.000000e+00 | 0.000000e+00 |
| 249 |13.7190 | 1 | 0.000701 | 46.844015 | -inf | 0.000000e+00 | 0.000000e+00 |
| 250 |13.7741 | 1 | 0.000692 | 46.682392 | -inf | 0.000000e+00 | 0.000000e+00 |
| 251 |13.8292 | 1 | 0.000684 | 46.749444 | -inf | 0.000000e+00 | 0.000000e+00 |
| 252 |13.8843 | 1 | 0.000690 | 46.676376 | -inf | 0.000000e+00 | 0.000000e+00 |
| 253 |13.9394 | 1 | 0.000688 | 46.902780 | -inf | 0.000000e+00 | 0.000000e+00 |
| 254 |13.9945 | 1 | 0.000700 | 46.342343 | -inf | 0.000000e+00 | 0.000000e+00 |
| 255 |14.0496 | 1 | 0.000676 | 47.290718 | -inf | 0.000000e+00 | 0.000000e+00 |
| 256 |14.1047 | 1 | 0.000690 | 46.483884 | -inf | 0.000000e+00 | 0.000000e+00 |
| 257 |14.1598 | 1 | 0.000687 | 46.475610 | -inf | 0.000000e+00 | 0.000000e+00 |
| 258 |14.2149 | 1 | 0.000697 | 46.243039 | -inf | 0.000000e+00 | 0.000000e+00 |
| 259 |14.2700 | 1 | 0.000691 | 46.327818 | -inf | 0.000000e+00 | 0.000000e+00 |
| 260 |14.3251 | 1 | 0.000684 | 47.023605 | -inf | 0.000000e+00 | 0.000000e+00 |
| 261 |14.3802 | 1 | 0.000684 | 46.992628 | -inf | 0.000000e+00 | 0.000000e+00 |
| 262 |14.4353 | 1 | 0.000689 | 46.655423 | -inf | 0.000000e+00 | 0.000000e+00 |
| 263 |14.4904 | 1 | 0.000687 | 46.780777 | -inf | 0.000000e+00 | 0.000000e+00 |
| 264 |14.5455 | 1 | 0.000687 | 46.914670 | -inf | 0.000000e+00 | 0.000000e+00 |
| 265 |14.6006 | 1 | 0.000688 | 46.680806 | -inf | 0.000000e+00 | 0.000000e+00 |
| 266 |14.6556 | 1 | 0.000678 | 47.492095 | -inf | 0.000000e+00 | 0.000000e+00 |
| 267 |14.7107 | 1 | 0.000688 | 46.786733 | -inf | 0.000000e+00 | 0.000000e+00 |
| 268 |14.7658 | 1 | 0.000680 | 47.164431 | -inf | 0.000000e+00 | 0.000000e+00 |
| 269 |14.8209 | 1 | 0.000708 | 45.651456 | -inf | 0.000000e+00 | 0.000000e+00 |
| 270 |14.8760 | 1 | 0.000684 | 47.118467 | -inf | 0.000000e+00 | 0.000000e+00 |
| 271 |14.9311 | 1 | 0.000686 | 46.986024 | -inf | 0.000000e+00 | 0.000000e+00 |
| 272 |14.9862 | 1 | 0.000705 | 45.811613 | -inf | 0.000000e+00 | 0.000000e+00 |
| 273 |15.0413 | 1 | 0.000701 | 45.809912 | -inf | 0.000000e+00 | 0.000000e+00 |
| 274 |15.0964 | 1 | 0.000698 | 46.075125 | -inf | 0.000000e+00 | 0.000000e+00 |
| 275 |15.1515 | 1 | 0.000697 | 46.349127 | -inf | 0.000000e+00 | 0.000000e+00 |
| 276 |15.2066 | 1 | 0.000707 | 45.612900 | -inf | 0.000000e+00 | 0.000000e+00 |
| 277 |15.2617 | 1 | 0.000699 | 45.962354 | -inf | 0.000000e+00 | 0.000000e+00 |
| 278 |15.3168 | 1 | 0.000703 | 45.854950 | -inf | 0.000000e+00 | 0.000000e+00 |
| 279 |15.3719 | 1 | 0.000688 | 46.591173 | -inf | 0.000000e+00 | 0.000000e+00 |
| 280 |15.4270 | 1 | 0.000691 | 46.439605 | -inf | 0.000000e+00 | 0.000000e+00 |
| 281 |15.4821 | 1 | 0.000700 | 45.609099 | -inf | 0.000000e+00 | 0.000000e+00 |
| 282 |15.5372 | 1 | 0.000705 | 45.473630 | -inf | 0.000000e+00 | 0.000000e+00 |
| 283 |15.5923 | 1 | 0.000704 | 45.499228 | -inf | 0.000000e+00 | 0.000000e+00 |
| 284 |15.6474 | 1 | 0.000707 | 45.474494 | -inf | 0.000000e+00 | 0.000000e+00 |
| 285 |15.7025 | 1 | 0.000690 | 46.229681 | -inf | 0.000000e+00 | 0.000000e+00 |
| 286 |15.7576 | 1 | 0.000699 | 45.890873 | -inf | 0.000000e+00 | 0.000000e+00 |
| 287 |15.8127 | 1 | 0.000693 | 46.117946 | -inf | 0.000000e+00 | 0.000000e+00 |
| 288 |15.8678 | 1 | 0.000698 | 45.995581 | -inf | 0.000000e+00 | 0.000000e+00 |
| 289 |15.9229 | 1 | 0.000707 | 45.766717 | -inf | 0.000000e+00 | 0.000000e+00 |
| 290 |15.9780 | 1 | 0.000726 | 45.936229 | -inf | 0.000000e+00 | 0.000000e+00 |
| 291 |16.0331 | 1 | 0.000709 | 46.439345 | -inf | 0.000000e+00 | 0.000000e+00 |
| 292 |16.0882 | 1 | 0.000690 | 46.546813 | -inf | 0.000000e+00 | 0.000000e+00 |
| 293 |16.1433 | 1 | 0.000693 | 46.523355 | -inf | 0.000000e+00 | 0.000000e+00 |
| 294 |16.1983 | 1 | 0.000709 | 45.438468 | -inf | 0.000000e+00 | 0.000000e+00 |
| 295 |16.2534 | 1 | 0.000698 | 46.057489 | -inf | 0.000000e+00 | 0.000000e+00 |
| 296 |16.3085 | 1 | 0.000692 | 46.396248 | -inf | 0.000000e+00 | 0.000000e+00 |
| 297 |16.3636 | 1 | 0.000671 | 47.804347 | -inf | 0.000000e+00 | 0.000000e+00 |
| 298 |16.4187 | 1 | 0.000700 | 45.745559 | -inf | 0.000000e+00 | 0.000000e+00 |
| 299 |16.4738 | 1 | 0.000695 | 46.054604 | -inf | 0.000000e+00 | 0.000000e+00 |
| 300 |16.5289 | 1 | 0.000705 | 45.744685 | -inf | 0.000000e+00 | 0.000000e+00 |
| 301 |16.5840 | 1 | 0.000698 | 45.782885 | -inf | 0.000000e+00 | 0.000000e+00 |
| 302 |16.6391 | 1 | 0.000694 | 46.331677 | -inf | 0.000000e+00 | 0.000000e+00 |
| 303 |16.6942 | 1 | 0.000693 | 46.501020 | -inf | 0.000000e+00 | 0.000000e+00 |
| 304 |16.7493 | 1 | 0.000697 | 45.868491 | -inf | 0.000000e+00 | 0.000000e+00 |
| 305 |16.8044 | 1 | 0.000699 | 46.378612 | -inf | 0.000000e+00 | 0.000000e+00 |
| 306 |16.8595 | 1 | 0.000695 | 46.308039 | -inf | 0.000000e+00 | 0.000000e+00 |
| 307 |16.9146 | 1 | 0.000691 | 46.526447 | -inf | 0.000000e+00 | 0.000000e+00 |
| 308 |16.9697 | 1 | 0.000696 | 46.122122 | -inf | 0.000000e+00 | 0.000000e+00 |
| 309 |17.0248 | 1 | 0.000684 | 46.856025 | -inf | 0.000000e+00 | 0.000000e+00 |
| 310 |17.0799 | 1 | 0.000701 | 46.113206 | -inf | 0.000000e+00 | 0.000000e+00 |
| 311 |17.1350 | 1 | 0.000692 | 46.398112 | -inf | 0.000000e+00 | 0.000000e+00 |
| 312 |17.1901 | 1 | 0.000767 | 45.619590 | -inf | 0.000000e+00 | 0.000000e+00 |
| 313 |17.2452 | 1 | 0.000675 | 47.797250 | -inf | 0.000000e+00 | 0.000000e+00 |
| 314 |17.3003 | 1 | 0.000685 | 46.677846 | -inf | 0.000000e+00 | 0.000000e+00 |
| 315 |17.3554 | 1 | 0.000689 | 46.488186 | -inf | 0.000000e+00 | 0.000000e+00 |
| 316 |17.4105 | 1 | 0.000711 | 46.798838 | -inf | 0.000000e+00 | 0.000000e+00 |
| 317 |17.4656 | 1 | 0.000690 | 46.569277 | -inf | 0.000000e+00 | 0.000000e+00 |
| 318 |17.5207 | 1 | 0.000695 | 46.209487 | -inf | 0.000000e+00 | 0.000000e+00 |
| 319 |17.5758 | 1 | 0.000698 | 45.909949 | -inf | 0.000000e+00 | 0.000000e+00 |
| 320 |17.6309 | 1 | 0.000679 | 47.280223 | -inf | 0.000000e+00 | 0.000000e+00 |
| 321 |17.6860 | 1 | 0.000696 | 45.957118 | -inf | 0.000000e+00 | 0.000000e+00 |
| 322 |17.7410 | 1 | 0.000689 | 46.661208 | -inf | 0.000000e+00 | 0.000000e+00 |
| 323 |17.7961 | 1 | 0.000689 | 46.485928 | -inf | 0.000000e+00 | 0.000000e+00 |
| 324 |17.8512 | 1 | 0.000702 | 45.910141 | -inf | 0.000000e+00 | 0.000000e+00 |
| 325 |17.9063 | 1 | 0.000698 | 46.091762 | -inf | 0.000000e+00 | 0.000000e+00 |
| 326 |17.9614 | 1 | 0.000697 | 46.191874 | -inf | 0.000000e+00 | 0.000000e+00 |
| 327 |18.0165 | 1 | 0.000697 | 46.020327 | -inf | 0.000000e+00 | 0.000000e+00 |
| 328 |18.0716 | 1 | 0.000683 | 47.056295 | -inf | 0.000000e+00 | 0.000000e+00 |
| 329 |18.1267 | 1 | 0.000679 | 47.225815 | -inf | 0.000000e+00 | 0.000000e+00 |
| 330 |18.1818 | 1 | 0.000687 | 46.711211 | -inf | 0.000000e+00 | 0.000000e+00 |
| 331 |18.2369 | 1 | 0.000683 | 46.838738 | -inf | 0.000000e+00 | 0.000000e+00 |
| 332 |18.2920 | 1 | 0.000690 | 46.530371 | -inf | 0.000000e+00 | 0.000000e+00 |
| 333 |18.3471 | 1 | 0.000682 | 47.151909 | -inf | 0.000000e+00 | 0.000000e+00 |
| 334 |18.4022 | 1 | 0.000705 | 46.465808 | -inf | 0.000000e+00 | 0.000000e+00 |
| 335 |18.4573 | 1 | 0.000698 | 46.918384 | -inf | 0.000000e+00 | 0.000000e+00 |
| 336 |18.5124 | 1 | 0.000680 | 46.982040 | -inf | 0.000000e+00 | 0.000000e+00 |
| 337 |18.5675 | 1 | 0.000688 | 46.834463 | -inf | 0.000000e+00 | 0.000000e+00 |
| 338 |18.6226 | 1 | 0.000685 | 47.082787 | -inf | 0.000000e+00 | 0.000000e+00 |
| 339 |18.6777 | 1 | 0.000667 | 47.776211 | -inf | 0.000000e+00 | 0.000000e+00 |
| 340 |18.7328 | 1 | 0.000694 | 46.342369 | -inf | 0.000000e+00 | 0.000000e+00 |
| 341 |18.7879 | 1 | 0.000679 | 47.334009 | -inf | 0.000000e+00 | 0.000000e+00 |
| 342 |18.8430 | 1 | 0.000676 | 47.224326 | -inf | 0.000000e+00 | 0.000000e+00 |
| 343 |18.8981 | 1 | 0.000681 | 47.006368 | -inf | 0.000000e+00 | 0.000000e+00 |
| 344 |18.9532 | 1 | 0.000682 | 46.777730 | -inf | 0.000000e+00 | 0.000000e+00 |
| 345 |19.0083 | 1 | 0.000694 | 46.232870 | -inf | 0.000000e+00 | 0.000000e+00 |
| 346 |19.0634 | 1 | 0.000692 | 46.253289 | -inf | 0.000000e+00 | 0.000000e+00 |
| 347 |19.1185 | 1 | 0.000693 | 46.055296 | -inf | 0.000000e+00 | 0.000000e+00 |
| 348 |19.1736 | 1 | 0.000687 | 46.546440 | -inf | 0.000000e+00 | 0.000000e+00 |
| 349 |19.2287 | 1 | 0.000685 | 46.769534 | -inf | 0.000000e+00 | 0.000000e+00 |
| 350 |19.2837 | 1 | 0.000698 | 45.705568 | -inf | 0.000000e+00 | 0.000000e+00 |
| 351 |19.3388 | 1 | 0.000699 | 45.612452 | -inf | 0.000000e+00 | 0.000000e+00 |
| 352 |19.3939 | 1 | 0.000689 | 46.311269 | -inf | 0.000000e+00 | 0.000000e+00 |
| 353 |19.4490 | 1 | 0.000704 | 45.581321 | -inf | 0.000000e+00 | 0.000000e+00 |
| 354 |19.5041 | 1 | 0.000692 | 46.268870 | -inf | 0.000000e+00 | 0.000000e+00 |
| 355 |19.5592 | 1 | 0.000695 | 45.857139 | -inf | 0.000000e+00 | 0.000000e+00 |
| 356 |19.6143 | 1 | 0.000672 | 47.383261 | -inf | 0.000000e+00 | 0.000000e+00 |
| 357 |19.6694 | 1 | 0.000697 | 46.039425 | -inf | 0.000000e+00 | 0.000000e+00 |
| 358 |19.7245 | 1 | 0.000673 | 47.209931 | -inf | 0.000000e+00 | 0.000000e+00 |
| 359 |19.7796 | 1 | 0.000693 | 46.166173 | -inf | 0.000000e+00 | 0.000000e+00 |
| 360 |19.8347 | 1 | 0.000689 | 46.307711 | -inf | 0.000000e+00 | 0.000000e+00 |
| 361 |19.8898 | 1 | 0.000690 | 46.204995 | -inf | 0.000000e+00 | 0.000000e+00 |
| 362 |19.9449 | 1 | 0.000707 | 45.873240 | -inf | 0.000000e+00 | 0.000000e+00 |
| 363 |20.0000 | 1 | 0.000702 | 45.896570 | -inf | 0.000000e+00 | 0.000000e+00 |
| 364 |20.0551 | 1 | 0.000703 | 45.762990 | -inf | 0.000000e+00 | 0.000000e+00 |
| 365 |20.1102 | 1 | 0.000689 | 46.398000 | -inf | 0.000000e+00 | 0.000000e+00 |
| 366 |20.1653 | 1 | 0.000698 | 45.893426 | -inf | 0.000000e+00 | 0.000000e+00 |
| 367 |20.2204 | 1 | 0.000690 | 46.226002 | -inf | 0.000000e+00 | 0.000000e+00 |
| 368 |20.2755 | 1 | 0.000694 | 46.151370 | -inf | 0.000000e+00 | 0.000000e+00 |
| 369 |20.3306 | 1 | 0.000688 | 46.556177 | -inf | 0.000000e+00 | 0.000000e+00 |
| 370 |20.3857 | 1 | 0.000707 | 45.573970 | -inf | 0.000000e+00 | 0.000000e+00 |
| 371 |20.4408 | 1 | 0.000693 | 46.446767 | -inf | 0.000000e+00 | 0.000000e+00 |
| 372 |20.4959 | 1 | 0.000694 | 46.152634 | -inf | 0.000000e+00 | 0.000000e+00 |
| 373 |20.5510 | 1 | 0.000696 | 46.155208 | -inf | 0.000000e+00 | 0.000000e+00 |
| 374 |20.6061 | 1 | 0.000705 | 45.472315 | -inf | 0.000000e+00 | 0.000000e+00 |
| 375 |20.6612 | 1 | 0.000676 | 47.016364 | -inf | 0.000000e+00 | 0.000000e+00 |
| 376 |20.7163 | 1 | 0.000700 | 45.441678 | -inf | 0.000000e+00 | 0.000000e+00 |
| 377 |20.7713 | 1 | 0.000705 | 45.608852 | -inf | 0.000000e+00 | 0.000000e+00 |
| 378 |20.8264 | 1 | 0.000693 | 46.611538 | -inf | 0.000000e+00 | 0.000000e+00 |
| 379 |20.8815 | 1 | 0.000701 | 46.255489 | -inf | 0.000000e+00 | 0.000000e+00 |
| 380 |20.9366 | 1 | 0.000688 | 46.646919 | -inf | 0.000000e+00 | 0.000000e+00 |
| 381 |20.9917 | 1 | 0.000585 | 54.423797 | -inf | 0.000000e+00 | 0.000000e+00 |
| 382 |21.0468 | 1 | 0.000667 | 47.716783 | -inf | 0.000000e+00 | 0.000000e+00 |
| 383 |21.1019 | 1 | 0.000700 | 46.025102 | -inf | 0.000000e+00 | 0.000000e+00 |
| 384 |21.1570 | 1 | 0.000699 | 45.861447 | -inf | 0.000000e+00 | 0.000000e+00 |
| 385 |21.2121 | 1 | 0.000698 | 46.278300 | -inf | 0.000000e+00 | 0.000000e+00 |
| 386 |21.2672 | 1 | 0.000699 | 45.952605 | -inf | 0.000000e+00 | 0.000000e+00 |
| 387 |21.3223 | 1 | 0.000704 | 45.592786 | -inf | 0.000000e+00 | 0.000000e+00 |
| 388 |21.3774 | 1 | 0.000689 | 46.150288 | -inf | 0.000000e+00 | 0.000000e+00 |
| 389 |21.4325 | 1 | 0.000697 | 45.931689 | -inf | 0.000000e+00 | 0.000000e+00 |
| 390 |21.4876 | 1 | 0.000697 | 45.977116 | -inf | 0.000000e+00 | 0.000000e+00 |
| 391 |21.5427 | 1 | 0.000690 | 45.976451 | -inf | 0.000000e+00 | 0.000000e+00 |
| 392 |21.5978 | 1 | 0.000690 | 46.597288 | -inf | 0.000000e+00 | 0.000000e+00 |
| 393 |21.6529 | 1 | 0.000681 | 46.697688 | -inf | 0.000000e+00 | 0.000000e+00 |
| 394 |21.7080 | 1 | 0.000696 | 47.318465 | -inf | 0.000000e+00 | 0.000000e+00 |
| 395 |21.7631 | 1 | 0.000699 | 46.267378 | -inf | 0.000000e+00 | 0.000000e+00 |
| 396 |21.8182 | 1 | 0.000689 | 46.555969 | -inf | 0.000000e+00 | 0.000000e+00 |
| 397 |21.8733 | 1 | 0.000679 | 47.319640 | -inf | 0.000000e+00 | 0.000000e+00 |
| 398 |21.9284 | 1 | 0.000671 | 47.558353 | -inf | 0.000000e+00 | 0.000000e+00 |
| 399 |21.9835 | 1 | 0.000689 | 46.302612 | -inf | 0.000000e+00 | 0.000000e+00 |
| 400 |22.0386 | 1 | 0.000667 | 47.758410 | -inf | 0.000000e+00 | 0.000000e+00 |
| 401 |22.0937 | 1 | 0.000687 | 46.813205 | -inf | 0.000000e+00 | 0.000000e+00 |
| 402 |22.1488 | 1 | 0.000689 | 46.336472 | -inf | 0.000000e+00 | 0.000000e+00 |
| 403 |22.2039 | 1 | 0.000707 | 46.668331 | -inf | 0.000000e+00 | 0.000000e+00 |
| 404 |22.2590 | 1 | 0.000688 | 46.649211 | -inf | 0.000000e+00 | 0.000000e+00 |
| 405 |22.3140 | 1 | 0.000691 | 46.482820 | -inf | 0.000000e+00 | 0.000000e+00 |
| 406 |22.3691 | 1 | 0.000681 | 46.947114 | -inf | 0.000000e+00 | 0.000000e+00 |
| 407 |22.4242 | 1 | 0.000689 | 46.618766 | -inf | 0.000000e+00 | 0.000000e+00 |
| 408 |22.4793 | 1 | 0.000680 | 46.817495 | -inf | 0.000000e+00 | 0.000000e+00 |
| 409 |22.5344 | 1 | 0.000686 | 46.703945 | -inf | 0.000000e+00 | 0.000000e+00 |
| 410 |22.5895 | 1 | 0.000675 | 47.620927 | -inf | 0.000000e+00 | 0.000000e+00 |
| 411 |22.6446 | 1 | 0.000689 | 46.717914 | -inf | 0.000000e+00 | 0.000000e+00 |
| 412 |22.6997 | 1 | 0.000674 | 47.499379 | -inf | 0.000000e+00 | 0.000000e+00 |
| 413 |22.7548 | 1 | 0.000683 | 46.991697 | -inf | 0.000000e+00 | 0.000000e+00 |
| 414 |22.8099 | 1 | 0.000844 | 47.362969 | -inf | 0.000000e+00 | 0.000000e+00 |
| 415 |22.8650 | 1 | 0.000681 | 47.379998 | -inf | 0.000000e+00 | 0.000000e+00 |
| 416 |22.9201 | 1 | 0.000688 | 46.840415 | -inf | 0.000000e+00 | 0.000000e+00 |
| 417 |22.9752 | 1 | 0.000696 | 46.394910 | -inf | 0.000000e+00 | 0.000000e+00 |
| 418 |23.0303 | 1 | 0.000680 | 47.481963 | -inf | 0.000000e+00 | 0.000000e+00 |
| 419 |23.0854 | 1 | 0.000677 | 47.425381 | -inf | 0.000000e+00 | 0.000000e+00 |
| 420 |23.1405 | 1 | 0.000675 | 47.313570 | -inf | 0.000000e+00 | 0.000000e+00 |
| 421 |23.1956 | 1 | 0.000680 | 47.051804 | -inf | 0.000000e+00 | 0.000000e+00 |
| 422 |23.2507 | 1 | 0.000692 | 46.392776 | -inf | 0.000000e+00 | 0.000000e+00 |
| 423 |23.3058 | 1 | 0.000700 | 46.097488 | -inf | 0.000000e+00 | 0.000000e+00 |
| 424 |23.3609 | 1 | 0.000704 | 45.675144 | -inf | 0.000000e+00 | 0.000000e+00 |
| 425 |23.4160 | 1 | 0.000678 | 47.188528 | -inf | 0.000000e+00 | 0.000000e+00 |
| 426 |23.4711 | 1 | 0.000674 | 47.721276 | -inf | 0.000000e+00 | 0.000000e+00 |
| 427 |23.5262 | 1 | 0.000679 | 47.517682 | -inf | 0.000000e+00 | 0.000000e+00 |
| 428 |23.5813 | 1 | 0.000699 | 47.314847 | -inf | 0.000000e+00 | 0.000000e+00 |
| 429 |23.6364 | 1 | 0.000677 | 46.942705 | -inf | 0.000000e+00 | 0.000000e+00 |
| 430 |23.6915 | 1 | 0.000685 | 46.500190 | -inf | 0.000000e+00 | 0.000000e+00 |
| 431 |23.7466 | 1 | 0.000690 | 46.497821 | -inf | 0.000000e+00 | 0.000000e+00 |
| 432 |23.8017 | 1 | 0.000681 | 46.785045 | -inf | 0.000000e+00 | 0.000000e+00 |
| 433 |23.8567 | 1 | 0.000695 | 45.813771 | -inf | 0.000000e+00 | 0.000000e+00 |
| 434 |23.9118 | 1 | 0.000710 | 45.188591 | -inf | 0.000000e+00 | 0.000000e+00 |
| 435 |23.9669 | 1 | 0.000692 | 46.043509 | -inf | 0.000000e+00 | 0.000000e+00 |
| 436 |24.0220 | 1 | 0.000703 | 45.755100 | -inf | 0.000000e+00 | 0.000000e+00 |
| 437 |24.0771 | 1 | 0.000696 | 45.757484 | -inf | 0.000000e+00 | 0.000000e+00 |
| 438 |24.1322 | 1 | 0.000683 | 46.637429 | -inf | 0.000000e+00 | 0.000000e+00 |
| 439 |24.1873 | 1 | 0.000688 | 46.360789 | -inf | 0.000000e+00 | 0.000000e+00 |
| 440 |24.2424 | 1 | 0.000691 | 46.138279 | -inf | 0.000000e+00 | 0.000000e+00 |
| 441 |24.2975 | 1 | 0.000697 | 46.142083 | -inf | 0.000000e+00 | 0.000000e+00 |
| 442 |24.3526 | 1 | 0.000699 | 46.033069 | -inf | 0.000000e+00 | 0.000000e+00 |
| 443 |24.4077 | 1 | 0.000685 | 46.517459 | -inf | 0.000000e+00 | 0.000000e+00 |
| 444 |24.4628 | 1 | 0.000699 | 45.831956 | -inf | 0.000000e+00 | 0.000000e+00 |
| 445 |24.5179 | 1 | 0.000683 | 47.009859 | -inf | 0.000000e+00 | 0.000000e+00 |
| 446 |24.5730 | 1 | 0.000703 | 46.299859 | -inf | 0.000000e+00 | 0.000000e+00 |
| 447 |24.6281 | 1 | 0.000684 | 46.631679 | -inf | 0.000000e+00 | 0.000000e+00 |
| 448 |24.6832 | 1 | 0.000696 | 46.171868 | -inf | 0.000000e+00 | 0.000000e+00 |
| 449 |24.7383 | 1 | 0.000704 | 45.749519 | -inf | 0.000000e+00 | 0.000000e+00 |
| 450 |24.7934 | 1 | 0.000673 | 47.822073 | -inf | 0.000000e+00 | 0.000000e+00 |
...Finished
FINISHED - Elapsed time = 21435.5371006 seconds
FINISHED - CPU process time = 165060.5815336 seconds
Postprocessing¶
Read the structural and aerodynamic information of the last time step
[11]:
tstep = sharpy_output.structure.timestep_info[-1]
astep = sharpy_output.aero.timestep_info[-1]
Separate the structure into blades
[12]:
# Define beams
ielem = 0
nblades = np.max(sharpy_output.structure.beam_number) + 1
nodes_blade = []
first_node = 0
for iblade in range(nblades):
nodes_blade.append(np.zeros((sharpy_output.structure.num_node,), dtype=bool))
while sharpy_output.structure.beam_number[ielem] <= iblade:
ielem += 1
if ielem == sharpy_output.structure.num_elem:
break
nodes_blade[iblade][first_node:sharpy_output.structure.connectivities[ielem-1,1]+1] = True
first_node = sharpy_output.structure.connectivities[ielem-1,1]+1
Compute the radial position of the nodes and initialise the rest of the variables
[13]:
r = []
c = []
dr = []
forces = []
CN_drR = []
CTan_drR = []
CP_drR = []
nodes_num = []
for iblade in range(nblades):
forces.append(tstep.steady_applied_forces[nodes_blade[iblade]].copy())
nodes_num.append(np.arange(0, sharpy_output.structure.num_node, 1)[nodes_blade[iblade]])
r.append(np.linalg.norm(tstep.pos[nodes_blade[iblade], :], axis=1))
dr.append(np.zeros(np.sum(nodes_blade[iblade])))
dr[iblade][0] = 0.5*(r[iblade][1]-r[iblade][0])
dr[iblade][-1] = 0.5 * (r[iblade][-1] - r[iblade][-2])
for inode in range(1,len(r[iblade]) - 1):
dr[iblade][inode] = 0.5*(r[iblade][inode+1] - r[iblade][inode-1])
CN_drR.append(np.zeros(len(r[iblade])))
c.append(np.zeros(len(r[iblade])))
CTan_drR.append(np.zeros(len(r[iblade])))
CP_drR.append(np.zeros(len(r[iblade])))
Transform the loads computed by SHARPy into out-of-plane and in-plane components
[14]:
rho = sharpy_output.settings['StaticCoupledRBM']['aero_solver_settings']['rho'].value
uinf = sharpy_output.settings['StaticCoupledRBM']['aero_solver_settings']['velocity_field_input']['u_inf'].value
R = np.max(r[0])
Cp = 0
Ct = 0
global_force_factor = 0.5 * rho * uinf** 2 * np.pi * R**2
global_power_factor = global_force_factor*uinf
for iblade in range(nblades):
for inode in range(len(r[iblade])):
forces[iblade][inode, 0] *= 0. # Discard the spanwise component
node_global_index = nodes_num[iblade][inode]
ielem = sharpy_output.structure.node_master_elem[node_global_index, 0]
inode_in_elem = sharpy_output.structure.node_master_elem[node_global_index, 1]
CAB = algebra.crv2rotation(tstep.psi[ielem, inode_in_elem, :])
c[iblade][inode] = sharpy_output.aero.aero_dict['chord'][ielem,inode_in_elem]
forces_AFoR = np.dot(CAB, forces[iblade][inode, 0:3])
CN_drR[iblade][inode] = forces_AFoR[2]/dr[iblade][inode]*R / global_force_factor
CTan_drR[iblade][inode] = np.linalg.norm(forces_AFoR[0:2])/dr[iblade][inode]*R / global_force_factor
CP_drR[iblade][inode] = np.linalg.norm(forces_AFoR[0:2])/dr[iblade][inode]*R * r[iblade][inode]*rotation_velocity / global_power_factor
Cp += np.sum(CP_drR[iblade]*dr[iblade]/R)
Ct += np.sum(CN_drR[iblade]*dr[iblade]/R)
Results¶
Plot of the loads along the blade
[15]:
fig, list_plots = plt.subplots(1, 2, figsize=(12, 3))
list_plots[0].grid()
list_plots[0].set_xlabel("r/R [-]")
list_plots[0].set_ylabel("CN/d(r/R) [-]")
list_plots[0].plot(r[0]/R, CN_drR[0], '-', label='SHARPy')
list_plots[0].plot(of_rR, of_cNdrR, '-', label='OpenFAST')
list_plots[0].legend()
list_plots[1].grid()
list_plots[1].set_xlabel("r/R [-]")
list_plots[1].set_ylabel("CT/d(r/R) [-]")
list_plots[1].plot(r[0]/R, CTan_drR[0], '-', label='SHARPy')
list_plots[1].plot(of_rR, of_cTdrR, '-', label='OpenFAST')
list_plots[1].legend()
plt.show()
Print the rotor thrust and power coefficients
[16]:
print(" OpenFAST SHARPy")
print("Cp[-] %.2f %.2f" % (of_cp, Cp))
print("Ct[-] %.2f %.2f" % (of_ct, Ct))
OpenFAST SHARPy
Cp[-] 0.49 0.55
Ct[-] 0.70 0.76
Contributing to SHARPy¶
Bug fixes and features¶
SHARPy is a collaborative effort, and this means that some coding practices need to be encouraged so that the code is kept tidy and consistent. Any user is welcome to raise issues for bug fixes and feature proposals through Github.
If you are submitting a bug report:
- Make sure your SHARPy, xbeam and uvlm local copies are up to date and in the same branch.
- Double check that your python distribution is updated by comparing with
the
utils/environment_*.yml
file. - Try to assemble a minimal working example that can be run quickly and easily.
- Describe as accurately as possible your setup (OS, path, compilers…) and the problem.
- Raise an issue with all this information in the Github repo and label it
potential bug
.
Please bear in mind that we do not have the resources to provide support for user modifications of the code through Github. If you have doubts about how to modify certain parts of the code, contact us through email and we will help you as much as we can.
If you are fixing a bug:
- THANKS!
- Please create a pull request from your modified fork, and describe in a few lines which bug you are fixing, a minimal example that triggers the bug and how you are fixing it. We will review it ASAP and hopefully it will be incorporated in the code!
If you have an idea for new functionality but do not know how to implement it:
- We welcome tips and suggestions from users, as it allow us to broaden the scope of the code. The more people using it, the better!
- Feel free to fill an issue in Github, and tag it as
feature proposal
. Please understand that the more complete the description of the potential feature, the more likely it is that some of the developers will give it a go.
If you have developed new functionality and you want to share it with the world:
- AWESOME! Please follow the same instructions than for the bug fix submission. If you have some peer-reviewed references related to the new code, even better, as it will save us some precious time.
Code formatting¶
We try to follow the PEP8 standards
(with spaces, no tabs please!) and Google Python Style Guide.
We do not ask you to freak out over formatting, but please, try to keep it tidy and
descriptive. A good tip is to run pylint
https://www.pylint.org/
to make sure there are no obvious formatting problems.
Documentation¶
Contributing to SHARPy’s documentation benefits everyone. As a developer, writing documentation helps you better understand what you have done and whether your functions etc make logical sense. As a user, any documentation is better than digging through the code. The more we have documented, the easier the code is to use and the more users we can have.
If you want to contribute by documenting code, you have come to the right place.
SHARPy is documented using Sphinx and it extracts the documentation directly from the source code. It is then sorted into directories automatically and a human readable website generated. The amount of work you need to do is minimal. That said, the recipe for a successfully documented class, function, module is the following:
Your documentation has to be written in ReStructuredText (rst). I know, another language… hence I will leave a few tips:
Inline code is written using two backticks
``
Inline math is written as
:math:`1+\exp^{i\pi} = 0`
. Don’t forget the backticks!Math in a single or multiple lines is simple:
.. math:: 1 + \exp{i\pi} = 0
Lists in ReStructuredText are tricky, I must admit. Therefore, I will link to some examples. The key resides in not forgetting the spaces, in particular when you go onto a second line!
The definite example list can be found here.
Titles and docstrings, the bare minimum:
Start docstrings with
r
such that they are interpreted raw:r""" My docstring """
All functions, modules and classes should be given a title that goes in the first line of the docstring
If you are writing a whole package with an
__init__.py
file, even if it’s empty, give it a human readable docstring. This will then be imported into the documentationFor modules with several functions, the module docstring has to be at the very top of the file, prior to the
import
statements.
We use the Google documentation style. See description.
Function arguments and returns:
Function arguments are simple to describe:
def func(arg1, arg2): """Summary line. Extended description of function. Args: arg1 (int): Description of arg1 arg2 (str): Description of arg2 Returns: bool: Description of return value """ return True
Solver settings:
If your code has a settings dictionary, with defaults and types then make sure that:
They are defined as class variables and not instance attributes.
Define a
settings_types
,settings_default
andsettings_description
dictionaries.After all your settings, update the docstring with the automatically generated settings table. You will need to import the
sharpy.utils.settings
modulesettings_types = dict() settings_default = dict() settings_description = dict() # keep adding settings settings_table = sharpy.utils.settings.SettingsTable() __doc__ += settings_table.generate(settings_types, settings_default ,settings_description)
See how your docs looks like!
- Once you are done, run the following
SHARPy
command:
sharpy any_string -d
- If you are making minor updates to docstrings (i.e. you are not documenting a previously undocumented
function/class/module) you can simply change directory to
sharpy/docs
and run
make html
- Your documentation will compile and warnings will appear etc. You can check the result by opening
docs/build/index.html
and navigating to your recently created page.
- Make sure that before committing any changes in the documentation you update the entire
docs
directory by running
sharpy any_string -d
- Once you are done, run the following
Thank you for reading through this and contributing to make SHARPy a better documented, more user friendly code!
Git branching model¶
For the development of SHARPy, we try to follow this branching model summarised by the schematic
BranchingModel
Credit: Vincent Driessen https://nvie.com/posts/a-successful-git-branching-model/
Therefore, attending to this model our branches have the following versions of the code:
master
: latest stable release - paired with the appropriate tag.develop
: latest stable development build. Features get merged to develop.rc-**
: release candidate branch. Prior to releasing tests are performed on this branch.dev_doc
: documentation development branch. All work relating to documentation gets done here.fix_**
: hotfix branch.dev_**
: feature development branch.
If you contribute, please make sure you know what branch to work from. If in doubt please ask!
The SHARPy Case files¶
SHARPy takes as input a series of .h5
files that contain the numerical data and a .sharpy
file that contains
the settings for each of the solvers. How these files are generated is at the user’s discretion, though templates are
provided, and all methods are valid as long as the required variables are provided with the appropriate format.
Modular Framework¶
SHARPy is built with a modular framework in mind. The following diagram shows the strutuctre of a nonlinear, time marching aeroelastic simulation

Each of the blocks correspond to individual solvers with specific settings. How we choose which solvers to run, in which order and with what settings is done through the solver configuration file, explained in the next section.
Solver configuration file¶
The solver configuration file is the main input to SHARPy. It is a ConfigObj
formatted file with the .sharpy
extension. It contains the settings for each of the solvers and the order in which
to run them.
A typical way to assemble the solver configuration file is to place all your desired settings
in a dictionary and then convert to and write your ConfigObj
. If a setting is not provided the default value will be used. The settings that each solver takes, its type and default value are explained in their relevant documentation pages.
import configobj
filename = '<case_route>/<case_name>.sharpy'
config = configobj.ConfigObj()
config.filename = filename
config['SHARPy'] = {'case': '<your SHARPy case name>', # an example setting
# Rest of your settings for the PreSHARPy class
}
config['BeamLoader'] = {'orientation': [1., 0., 0.], # an example setting
# Rest of settings for the BeamLoader solver
}
# Continue as above for the remainder of solvers that you would like to include
# finally, write the config file
config.write()
The resulting .sharpy
file is a plain text file with your specified settings for each of
the solvers.
Note that, therefore, if one of your settings is a np.array
, it will get transformed into
a string of plain text before being read by SHARPy. However, any setting with list(float)
specified as its setting type will get converted into a np.array
once it is read by SHARPy.
FEM file¶
The case.fem.h5
file has several components. We go one by one:
num_node_elem [int]
: number of nodes per element.Always 3 in our case (3 nodes per structural elements - quadratic beam elements).
num_elem [int]
: number of structural elements.num_node [int]
: number of nodes.For simple structures, it is
num_elem*(num_node_elem - 1) - 1
. For more complicated ones, you need to calculate it properly.coordinates [num_node, 3]
: coordinates of the nodes in body-attached FoR (A).connectivites [num_elem, num_node_elem]
: Beam element’s connectivities.Every row refers to an element, and the three integers in that row are the indices of the three nodes belonging to that elem. Now, the catch: the ordering is not as you’d think. Order them as
[0, 2, 1]
. That means, first one, last one, central one. The following image shows the node indices inside the circles representing the nodes, the element indices in blue and the resulting connectivities matrix next to it. Connectivities are tricky when considering complex configurations. Pay attention at the beginning and you’ll save yourself a lot of trouble.stiffness_db [:, 6, 6]
: database of stiffness matrices.The first dimension has as many elements as different stiffness matrices are in the model.
elem_stiffness [num_elem]
: array of indices (starting at 0).It links every element (index) to the stiffness matrix index in
stiffness_db
. For exampleelem_stiffness[0] = 0
;elem_stiffness[2] = 1
means that the element0
has a stiffness matrix equal tostiffness_db[0, :, :]
, and the second element has a stiffness matrix equal tostiffness_db[1, :, :]
.The shape of a stiffness matrix, \(\mathrm{S}\) is:
\[\begin{split}\mathrm{S} = \begin{bmatrix} EA & & & & & \\ & GA_y & & & & \\ & & GA_z & & & \\ & & & GJ & & \\ & & & & EI_y & \\ & & & & & EI_z \\ \end{bmatrix}\end{split}\]with the cross terms added if needed.
mass_db
andelem_mass
follow the same scheme than the stiffness, but the mass matrix is given by:\[\begin{split}\mathrm{M} = \begin{bmatrix} m\mathbf{I} & -\tilde{\boldsymbol{\xi}}_{cg}m \\ \tilde{\boldsymbol{\xi}}_{cg}m & \mathbf{J}\\ \end{bmatrix}\end{split}\]where \(m\) is the distributed mass per unit length \(kg/m\) , \((\tilde{\bullet})\) is the skew-symmetric matrix of a vector and \(\boldsymbol{\xi}_{cg}\) is the location of the centre of gravity with respect to the elastic axis in MATERIAL (local) FoR. And what is the Material FoR? This is an important point, because all the inputs that move WITH the beam are in material FoR. For example: follower forces, stiffness, mass, lumped masses…
The material frame of reference is noted as \(B\). Essentially, the \(x\) component is tangent to the beam in the increasing node ordering, \(z\) looks up generally and \(y\) is oriented such that the FoR is right handed.
In the practice (vertical surfaces, structural twist effects…) it is more complicated than this. The only sure thing about \(B\) is that its \(x\) direction is tangent to the beam in the increasing node number direction. However, with just this, we have an infinite number of potential reference frames, with \(y\) and \(z\) being normal to \(x\) but rotating around it. The solution is to indicate a
for_delta
, or frame of reference delta vector (\(\Delta\)).Now we can define unequivocally the material frame of reference. With \(x_B\) and \(\Delta\) defining a plane, \(y_b\) is chosen such that the \(z\) component is oriented upwards with respect to the lifting surface.
From this definition comes the only constraint to \(\Delta\): it cannot be parallel to \(x_B\).
frame_of_reference_delta [num_elem, num_node_elem, 3]
: rotation vector to FoR \(B\).contains the \(\Delta\) vector in body-attached (\(A\)) frame of reference.
As a rule of thumb:
\[\begin{split}\Delta = \begin{cases} [-1, 0, 0], \quad \text{if right wing} \\ [1, 0, 0], \quad \text{if left wing} \\ [0, 1, 0], \quad \text{if fuselage} \\ [-1, 0, 0], \quad \text{if vertical fin} \\ \end{cases}\end{split}\]These rules of thumb only work if the nodes increase towards the tip of the surfaces (and the tail in the case of the fuselage).
structural_twist [num_elem, num_node_elem]
: Element twist.Technically not necessary, as the same effect can be achieved with
FoR_delta
.boundary_conditions [num_node]
: boundary conditions.An array of integers
(np.zeros((num_node, ), dtype=int))
and contains all0
except for- One node NEEDS to have a
1
, this is the reference node. Usually, the first node has 1 and is located in[0, 0, 0]
. This makes things much easier. - If the node is a tip of a beam (is not attached to 2 elements, but just 1), it needs to have a
-1
.
- One node NEEDS to have a
beam_number [num_elem]
: beam index.Is another array of integers. Usually you don’t need to modify its value. Leave it at 0.
app_forces [num_elem, 6]
: applied forces and moments.Contains the applied forces
app_forces[:, 0:3]
and momentsapp_forces[:, 3:6]
in a given node.Important points: the forces are given in Material FoR (check above). That means that in a symmetrical model, a thrust force oriented upstream would have the shape
[0, T, 0, 0, 0, 0]
in the right wing, while the left would be[0, -T, 0, 0, 0, 0]
. Likewise, a torsional moment for twisting the wing leading edge up would be[0, 0, 0, M, 0, 0]
for the right, and[0, 0, 0, -M, 0, 0]
for the left. But careful, because an out-of-plane bending moment (wing tip up) has the same sign (think about it).lumped_mass [:]
: lumped masses.Is an array with as many masses as needed (in kg this time). Their order is important, as more information is required to implement them in a model.
lumped_mass_nodes [:]
: Lumped mass nodes.Is an array of integers. It contains the index of the nodes related to the masses given in lumped_mass in order.
lumped_mass_inertia [:, 3, 3]
: Lumped mass inertia.Is an array of
3x3
inertial tensors. The relationship is set by the ordering as well.lumped_mass_position [:, 3]
: Lumped mass position.Is the relative position of the lumped mass with respect to the node (given in
lumped_masss_nodes
) coordinates. ATTENTION: the lumped mass is solidly attached to the node, and thus, its position is given in Material FoR.
Aerodynamics file¶
All the aerodynamic data is contained in case.aero.h5
.
It is important to know that the input for aero is usually based on elements (and inside the elements, their nodes). This causes sometimes an overlap in information, as some nodes are shared by two adjacent elements (like in the connectivities graph in the previous section). The easier way of dealing with this is to make sure the data is consistent, so that the properties of the last node of the first element are the same than the first node of the second element.
Item by item:
airfoils
: Airfoil group.In the
aero.h5
file, there is a Group calledairfoils
. The airfoils are stored in this group (which acts as a folder) as a two-column matrix with \(x/c\) and \(y/c\) in each column. They are named'0', '1'
, and so on.chords [num_elem, num_node_elem]
: ChordIs an array with the chords of every airfoil given in an element/node basis.
twist [num_elem, num_node_elem]
: Twist.Has the twist angle in radians. It is implemented as a rotation around the local \(x\) axis.
sweep [num_elem, num_node_elem]
: Sweep.Same here, just a rotation around \(z\).
airfoil_distribution_input [num_elem, num_node_elem]
: Airfoil distribution.Contains the indices of the airfoils that you put previously in
airfoils
.surface_distribution_input [num_elem]
: Surface integer array.It contains the index of the surface the element belongs to. Surfaces need to be continuous, so please note that if your beam numbering is not continuous, you need to make a surface per continuous section.
surface_m [num_surfaces]
: Chordwise panelling.Is an integer array with the number of chordwise panels for every surface.
m_distribution [string]
: Discretisation method.Is a string with the chordwise panel distribution. In almost all cases, leave it at
uniform
.aero_node_input [num_node]
: Aerodynamic node definition.Is a boolean (
True
orFalse
) array that indicates if that node has a lifting surface attached to it.elastic_axis [num_elem, num_node_elem]
: elastic axis.Indicates the elastic axis location with respect to the leading edge as a fraction of the chord of that rib. Note that the elastic axis is already determined, as the beam is fixed now, so this settings controls the location of the lifting surface wrt the beam.
control_surface [num_elem, num_node_elem]
: Control surface.Is an integer array containing
-1
if that section has no control surface associated to it, and0, 1, 2 ...
if the section belongs to the control surface0, 1, 2 ...
respectively.control_surface_type [num_control_surface]
: Control Surface type.Contains
0
if the control surface deflection is static, and1
is it is dynamic.control_surface_chord [num_control_surface]
: Control surface chord.Is an INTEGER array with the number of panels belonging to the control surface. For example, if
M = 4
and you want your control surface to be \(0.25c\), you need to put1
.control_surface_hinge_coord [num_control_surface]
: Control surface hinge coordinate.Only necessary for lifting surfaces that are deflected as a whole, like some horizontal tails in some aircraft. Leave it at
0
if you are not modelling this.airfoil_efficiency [num_elem, num_node_elem, 2, 3]
: Airfoil efficiency.This is an optional setting that introduces a user-defined efficiency and constant terms to the mapping between the aerodynamic forces calculated at the lattice grid and the structural nodes. The formatting of the 4-dimensional array is simple. The first two dimensions correspond to the element index and the local node index. The third index is whether the term is the multiplier to the force
0
or a constant term1
. The final term refers to, in the local, body-attachedB
frame, the factors and constant terms for:fy, fz, mx
. For more information on how these factors are included in the mapping terms seesharpy.aero.utils.mapping.aero2struct_force_mapping()
.
SHARPy Solvers¶
The available SHARPy solvers are listed below. Attending to SHARPy’s modular structure, they can be run independently so the order in which you desire to run them is important.
The starting point is the PreSharpy loader. It contains the simulation configuration and which solvers are to be run and in the order that should happen.
Aero Solvers¶
DynamicUVLM¶
Dynamic Aerodynamic Time Domain Simulation
Provides an aerodynamic only simulation in time by time stepping the solution. The type of aerodynamic solver is parsed as a setting.
- To Do:
- Clean timestep information for memory efficiency
Warning
Under development. Issues encountered when using the linear UVLM as the aerodynamic solver with integration order = 1.
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default print_info
bool
Write status to screen True
structural_solver
str
Structural solver to use in the coupled simulation None
structural_solver_settings
dict
Dictionary of settings for the structural solver None
aero_solver
str
Aerodynamic solver to use in the coupled simulation None
aero_solver_settings
dict
Dictionary of settings for the aerodynamic solver None
n_time_steps
int
Number of time steps for the simulation None
dt
float
Time step None
include_unsteady_force_contribution
bool
If on, added mass contribution is added to the forces. This depends on the time derivative of the bound circulation. Check filter_gamma_dot
in the aero solverFalse
postprocessors
list(str)
List of the postprocessors to run at the end of every time step []
postprocessors_settings
dict
Dictionary with the applicable settings for every psotprocessor
. Everypostprocessor
needs its entry, even if empty{}
NoAero¶
Solver to be used with DynamicCoupled when aerodynamics are not of interest
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default To be called just once per simulation.
PrescribedUvlm¶
This class runs a prescribed rigid body motion simulation of a rigid aerodynamic body.
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default print_info
bool
Write status to screen True
structural_solver
str
Structural solver to use in the coupled simulation None
structural_solver_settings
dict
Dictionary of settings for the structural solver None
aero_solver
str
Aerodynamic solver to use in the coupled simulation None
aero_solver_settings
dict
Dictionary of settings for the aerodynamic solver None
n_time_steps
int
Number of time steps for the simulation None
dt
float
Time step None
postprocessors
list(str)
List of the postprocessors to run at the end of every time step []
postprocessors_settings
dict
Dictionary with the applicable settings for every psotprocessor
. Everypostprocessor
needs its entry, even if empty{}
SHWUvlm¶
Steady vortex method assuming helicoidal wake shape
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default print_info
bool
Output run-time information True
num_cores
int
Number of cores to used in parallelisation 0
convection_scheme
int
Convection scheme for the wake (only 2 tested for this solver) 2
dt
float
time step used to discretise the wake 0.1
iterative_solver
bool
False
iterative_tol
float
0.0001
iterative_precond
bool
False
velocity_field_generator
str
Name of the velocity field generator SteadyVelocityField
velocity_field_input
dict
Dictionary of inputs needed by the velocity field generator {}
gamma_dot_filtering
int
Parameter used to filter gamma dot (only odd numbers bigger than one allowed) 0
rho
float
Density 1.225
rot_vel
float
Rotation velocity in rad/s 0.0
rot_axis
list(float)
Axis of rotation of the wake [1.0, 0.0, 0.0]
rot_center
list(float)
Center of rotation of the wake [0.0, 0.0, 0.0]
StaticUvlm¶
StaticUvlm
solver class, inherited fromBaseSolver
Aerodynamic solver that runs a UVLM routine to solve the steady or unsteady aerodynamic problem. The aerodynamic problem is posed in the form of an
Aerogrid
object.Parameters: - data (PreSharpy) – object with problem data
- custom_settings (dict) – custom settings that override the settings in the solver
.txt
file. None by default
Name-value pair of settings employed by solver. See Notes for valid combinations
Type: dict
Acceptable data types for entries in
settings
Type: dict
Default values for the available
settings
Type: dict
object containing the information of the problem
Type: PreSharpy
object containing the flow conditions information
Type: object
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default print_info
bool
Print info to screen True
horseshoe
bool
Horseshoe wake modelling for steady simulations. False
num_cores
int
Number of cores to use in the VLM lib 0
n_rollup
int
Number of rollup iterations for free wake. Use at least n_rollup > 1.1*m_star
1
rollup_dt
float
Controls when the AIC matrix is refreshed during the wake rollup 0.1
rollup_aic_refresh
int
1
rollup_tolerance
float
Convergence criterium for rollup wake 0.0001
iterative_solver
bool
Not in use False
iterative_tol
float
Not in use 0.0001
iterative_precond
bool
Not in use False
velocity_field_generator
str
Name of the velocity field generator to be used in the simulation SteadyVelocityField
velocity_field_input
dict
Dictionary of settings for the velocity field generator {}
rho
float
Air density 1.225
Updates de aerogrid based on the info of the step, and increases the self.ts counter
StepLinearUVLM¶
Time domain aerodynamic solver that uses a linear UVLM formulation to be used with the
solvers.DynamicCoupled
solver.To use this solver, the
solver_id = StepLinearUVLM
must be given as the name for theaero_solver
is the case of an aeroelastic solver, where the setting below would be parsed throughaero_solver_settings
.Notes
The
integr_order
variable refers to the finite differencing scheme used to calculate the bound circulation derivative with respect to time \(\dot{\mathbf{\Gamma}}\). A first order scheme is used whenintegr_order == 1
\[\dot{\mathbf{\Gamma}}^{n+1} = \frac{\mathbf{\Gamma}^{n+1}-\mathbf{\Gamma}^n}{\Delta t}\]If
integr_order == 2
a higher order scheme is used (but it isn’t exactly second order accurate [1]).\[\dot{\mathbf{\Gamma}}^{n+1} = \frac{3\mathbf{\Gamma}^{n+1}-4\mathbf{\Gamma}^n + \mathbf{\Gamma}^{n-1}} {2\Delta t}\]If
track_body
isTrue
, the UVLM is projected onto a frameU
that is:- Coincident with
G
at the linearisation timestep. - Thence, rotates by the same quantity as the FoR
A
.
It is similar to a stability axes and is recommended any time rigid body dynamics are included.
See also
sharpy.sharpy.linear.assembler.linearuvlm.LinearUVLM
References
[1] Maraniello, S., & Palacios, R.. State-Space Realizations and Internal Balancing in Potential-Flow Aerodynamics with Arbitrary Kinematics. AIAA Journal, 57(6), 1–14. 2019. https://doi.org/10.2514/1.J058153
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default dt
float
Time step 0.1
integr_order
int
Integration order of the circulation derivative. Either 1
or2
.2
ScalingDict
dict
Dictionary of scaling factors to achieve normalised UVLM realisation. {}
remove_predictor
bool
Remove the predictor term from the UVLM equations True
use_sparse
bool
Assemble UVLM plant matrix in sparse format True
density
float
Air density 1.225
track_body
bool
UVLM inputs and outputs projected to coincide with lattice at linearisation True
track_body_number
int
Frame of reference number to follow. If -1
trackA
frame.-1
The settings that
ScalingDict
accepts are the following:Name Type Description Default length
float
Reference length to be used for UVLM scaling 1.0
speed
float
Reference speed to be used for UVLM scaling 1.0
density
float
Reference density to be used for UVLM scaling 1.0
Initialises the Linear UVLM aerodynamic solver and the chosen velocity generator.
Settings are parsed into the standard SHARPy settings format for solvers. It then checks whether there is any previous information about the linearised system (in order for a solution to be restarted without overwriting the linearisation).
If a linearised system does not exist, a linear UVLM system is created linearising about the current time step.
The reference values for the input and output are transformed into column vectors \(\mathbf{u}\) and \(\mathbf{y}\), respectively.
The information pertaining to the linear system is stored in a dictionary
self.data.aero.linear
within the maindata
variable.Parameters: - data (PreSharpy) – class containing the problem information
- custom_settings (dict) – custom settings dictionary
Transform a SHARPy AeroTimestep instance into a column vector containing the input to the linear UVLM system.
\[[\zeta,\, \dot{\zeta}, u_{ext}] \longrightarrow \mathbf{u}\]If the
track_body
option is on, the function projects all the input into a frame that:- is equal to the FoR G at time 0 (linearisation point)
- rotates as the body frame specified in the
track_body_number
Returns: Input vector Return type: np.ndarray
Transform SHARPy Aerotimestep format into column vector containing the state information.
The state vector is of a different form depending on the order of integration chosen. If a second order scheme is chosen, the state includes the bound circulation at the previous timestep, hence the timestep information for the previous timestep shall be parsed.
The transformation is of the form:
If
integr_order==1
:\[\mathbf{x}_n = [\mathbf{\Gamma}^T_n,\, \mathbf{\Gamma_w}_n^T,\, \Delta t \,\mathbf{\dot{\Gamma}}_n^T]^T\]Else, if
integr_order==2
:\[\mathbf{x}_n = [\mathbf{\Gamma}_n^T,\, \mathbf{\Gamma_w}_n^T,\, \Delta t \,\mathbf{\dot{\Gamma}}_n^T,\, \mathbf{\Gamma}_{n-1}^T]^T\]
For the second order integration scheme, if the previous timestep information is not parsed, a first order stencil is employed to estimate the bound circulation at the previous timestep:
\[\mathbf{\Gamma}^{n-1} = \mathbf{\Gamma}^n - \Delta t \mathbf{\dot{\Gamma}}^n\]Parameters: - aero_tstep (AeroTimeStepInfo) – Aerodynamic timestep information at the current timestep
n
. - aero_tstep_m1 (AeroTimeStepInfo) –
Returns: State vector
Return type: np.ndarray
Solve the linear aerodynamic UVLM model at the current time step
n
. The step increment is solved as:\[\begin{split}\mathbf{x}^n &= \mathbf{A\,x}^{n-1} + \mathbf{B\,u}^n \\ \mathbf{y}^n &= \mathbf{C\,x}^n + \mathbf{D\,u}^n\end{split}\]A change of state is possible in order to solve the system without the predictor term. In which case the system is solved by:
\[\begin{split}\mathbf{h}^n &= \mathbf{A\,h}^{n-1} + \mathbf{B\,u}^{n-1} \\ \mathbf{y}^n &= \mathbf{C\,h}^n + \mathbf{D\,u}^n\end{split}\]Variations are taken with respect to initial reference state. The state and input vectors for the linear UVLM system are of the form:
- If
integr_order==1
: - \[\mathbf{x}_n = [\delta\mathbf{\Gamma}^T_n,\, \delta\mathbf{\Gamma_w}_n^T,\, \Delta t \,\delta\mathbf{\dot{\Gamma}}_n^T]^T\]
- Else, if
integr_order==2
: - \[\mathbf{x}_n = [\delta\mathbf{\Gamma}_n^T,\, \delta\mathbf{\Gamma_w}_n^T,\, \Delta t \,\delta\mathbf{\dot{\Gamma}}_n^T,\, \delta\mathbf{\Gamma}_{n-1}^T]^T\]
- And the input vector:
- \[\mathbf{u}_n = [\delta\mathbf{\zeta}_n^T,\, \delta\dot{\mathbf{\zeta}}_n^T,\,\delta\mathbf{u_{ext}}^T_n]^T\]
where the subscript
n
refers to the time step.The linear UVLM system is then solved as detailed in
sharpy.linear.src.linuvlm.Dynamic.solve_step()
. The output is a column vector containing the aerodynamic forces at the panel vertices.To Do: option for impulsive start?
Parameters: - aero_tstep (AeroTimeStepInfo) – object containing the aerodynamic data at the current time step
- structure_tstep (StructTimeStepInfo) – object containing the structural data at the current time step
- convect_wake (bool) – for backward compatibility only. The linear UVLM assumes a frozen wake geometry
- dt (float) – time increment
- t (float) – current time
- unsteady_contribution (bool) – (backward compatibily). Unsteady aerodynamic effects are always included
Returns: updated
self.data
class with the new forces and circulation terms of the systemReturn type: - If
Transform column vectors used in the state space formulation into SHARPy format
The column vectors are transformed into lists with one entry per aerodynamic surface. Each entry contains a matrix with the quantities at each grid vertex.
\[\mathbf{y}_n \longrightarrow \mathbf{f}_{aero}\]\[\mathbf{x}_n \longrightarrow \mathbf{\Gamma}_n,\, \mathbf{\Gamma_w}_n,\, \mathbf{\dot{\Gamma}}_n\]If the
track_body
option is on, the output forces are projected from the linearization frame, to the G frame. Note that the linearisation frame is:- equal to the FoR G at time 0 (linearisation point)
- rotates as the body frame specified in the
track_body_number
Parameters: - y_n (np.ndarray) – Column output vector of linear UVLM system
- x_n (np.ndarray) – Column state vector of linear UVLM system
- u_n (np.ndarray) – Column input vector of linear UVLM system
- aero_tstep (AeroTimeStepInfo) – aerodynamic timestep information class instance
Returns: Tuple containing:
- forces (list):
Aerodynamic forces in a list with
n_surf
entries. Each entry is a(6, M+1, N+1)
matrix, where the first 3 indices correspond to the components inx
,y
andz
. The latter 3 are zero.- gamma (list):
Bound circulation list with
n_surf
entries. Circulation is stored in an(M+1, N+1)
matrix, corresponding to the panel vertices.- gamma_dot (list):
Bound circulation derivative list with
n_surf
entries. Circulation derivative is stored in an(M+1, N+1)
matrix, corresponding to the panel vertices.- gamma_star (list):
Wake (free) circulation list with
n_surf
entries. Wake circulation is stored in an(M_star+1, N+1)
matrix, corresponding to the panel vertices of the wake.
Return type: tuple
- Coincident with
StepUvlm¶
StepUVLM is the main solver to use for unsteady aerodynamics.
The desired flow field is injected into the simulation by means of a
generator
. For a list of available velocity field generators see the documentation page on generators which can be found under SHARPy Source Code.Typical generators could be:
amongst others.
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default Options print_info
bool
Print info to screen True
num_cores
int
Number of cores to use in the VLM lib 0
n_time_steps
int
Number of time steps to be run 100
convection_scheme
int
0
: fixed wake,2
: convected with background flow;``3``: full force-free wake3
0
,2
,3
dt
float
Time step 0.1
iterative_solver
bool
Not in use False
iterative_tol
float
Not in use 0.0001
iterative_precond
bool
Not in use False
velocity_field_generator
str
Name of the velocity field generator to be used in the simulation SteadyVelocityField
velocity_field_input
dict
Dictionary of settings for the velocity field generator {}
gamma_dot_filtering
int
Filtering parameter for the Welch filter for the Gamma_dot estimation. Used when unsteady_force_contribution
ison
.0
rho
float
Air density 1.225
To be called just once per simulation.
Runs a step of the aerodynamics as implemented in UVLM.
Coupled Solvers¶
DynamicCoupled¶
The
DynamicCoupled
solver couples the aerodynamic and structural solvers of choice to march forward in time the aeroelastic system’s solution.Using the
DynamicCoupled
solver requires that an instance of theStaticCoupled
solver is called in the SHARPy solutionflow
when defining the problem case.The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default print_info
bool
Write status to screen True
structural_solver
str
Structural solver to use in the coupled simulation None
structural_solver_settings
dict
Dictionary of settings for the structural solver None
aero_solver
str
Aerodynamic solver to use in the coupled simulation None
aero_solver_settings
dict
Dictionary of settings for the aerodynamic solver None
n_time_steps
int
Number of time steps for the simulation None
dt
float
Time step None
fsi_substeps
int
Max iterations in the FSI loop 70
fsi_tolerance
float
Convergence threshold for the FSI loop 1e-05
structural_substeps
int
Number of extra structural time steps per aero time step. 0 is a fully coupled simulation. 0
relaxation_factor
float
Relaxation parameter in the FSI iteration. 0 is no relaxation and -> 1 is very relaxed 0.2
final_relaxation_factor
float
Relaxation factor reached in relaxation_steps
withdynamic_relaxation
on0.0
minimum_steps
int
Number of minimum FSI iterations before convergence 3
relaxation_steps
int
Length of the relaxation factor ramp between relaxation_factor
andfinal_relaxation_factor
withdynamic_relaxation
on100
dynamic_relaxation
bool
Controls if relaxation factor is modified during the FSI iteration process False
postprocessors
list(str)
List of the postprocessors to run at the end of every time step []
postprocessors_settings
dict
Dictionary with the applicable settings for every psotprocessor
. Everypostprocessor
needs its entry, even if empty{}
controller_id
dict
Dictionary of id of every controller (key) and its type (value) {}
controller_settings
dict
Dictionary with settings (value) of every controller id (key) {}
cleanup_previous_solution
bool
Controls if previous timestep_info
arrays are reset before running the solverFalse
include_unsteady_force_contribution
bool
If on, added mass contribution is added to the forces. This depends on the time derivative of the bound circulation. Check filter_gamma_dot
in the aero solverFalse
steps_without_unsteady_force
int
Number of initial timesteps that don’t include unsteady forces contributions. This avoids oscillations due to no perfectly trimmed initial conditions 0
pseudosteps_ramp_unsteady_force
int
Length of the ramp with which unsteady force contribution is introduced every time step during the FSI iteration process 0
Check convergence in the FSI loop.
Convergence is determined as:
\[\epsilon_q^k = \frac{|| q^k - q^{k - 1} ||}{q^0}\]\[\epsilon_\dot{q}^k = \frac{|| \dot{q}^k - \dot{q}^{k - 1} ||}{\dot{q}^0}\]FSI converged if \(\epsilon_q^k < \mathrm{FSI\ tolerance}\) and \(\epsilon_\dot{q}^k < \mathrm{FSI\ tolerance}\)
Getter for
g
, the gravity value
Getter for
rho
, the density value
Controls the initialisation process of the solver, including processing the settings and initialising the aero and structural solvers, postprocessors and controllers.
Performs a linear interpolation between step0 and step1 based on coeff in [0, 1]. 0 means info in out_step == step0 and 1 out_step == step1.
Quantities interpolated: * steady_applied_forces * unsteady_applied_forces * velocity input in Lagrange constraints
This function modified the solver properties and parameters as requested from the controller.
This keeps the main loop much cleaner, while allowing for flexibility
Please, if you add options in here, always code the possibility of that specific option not being there without the code complaining to the user.
If it possible, use the same Key for the new setting as for the setting in the solver. For example, if you want to modify the structural_substeps variable in settings, use that Key in the info dictionary.
As a convention: a value of None returns the value to the initial one specified in settings, while the key not being in the dict is ignored, so if any change was made before, it will stay there.
Run the time stepping procedure with controllers and postprocessors included.
Setter for
g
, the gravity value
Setter for
rho
, the density value
LinDynamicSim¶
Time-domain solution of Linear Time Invariant Systems
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default folder
str
Output directory ./output/
write_dat
list(str)
List of vectors to write: x
,y
,u
and/ort
[]
reference_velocity
float
Velocity to scale the structural equations when using a non-dimensional system 1.0
n_tsteps
int
Number of time steps to run 10
physical_time
float
Time to run 2.0
dt
float
Time increment for the solution of systems without a specified dt 0.001
postprocessors
list(str)
[]
postprocessors_settings
dict
{}
RigidDynamicPrescribedStep¶
@modified Alfonso del Carre
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default dt
float
Time step of simulation 0.01
num_steps
int
Number of timesteps to be run 500
StaticCoupled¶
This class is the main FSI driver for static simulations. It requires a
structural_solver
and aaero_solver
to be defined.The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default print_info
bool
Write status to screen True
structural_solver
str
Structural solver to use in the coupled simulation None
structural_solver_settings
dict
Dictionary of settings for the structural solver None
aero_solver
str
Aerodynamic solver to use in the coupled simulation None
aero_solver_settings
dict
Dictionary of settings for the aerodynamic solver None
max_iter
int
Max iterations in the FSI loop 100
n_load_steps
int
Length of ramp for forces and gravity during FSI iteration 0
tolerance
float
Convergence threshold for the FSI loop 1e-05
relaxation_factor
float
Relaxation parameter in the FSI iteration. 0 is no relaxation and -> 1 is very relaxed 0.0
StaticCoupledRBM¶
Steady coupled solver including rigid body motions
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default print_info
bool
Output run-time information True
structural_solver
str
Name of the structural solver used in the computation None
structural_solver_settings
dict
Dictionary os settings needed by the structural solver None
aero_solver
str
Name of the aerodynamic solver used in the computation None
aero_solver_settings
dict
Dictionary os settings needed by the aerodynamic solver None
max_iter
int
Maximum numeber of FSI iterations 100
n_load_steps
int
Number of steps to ramp up the application of loads 1
tolerance
float
FSI tolerance 1e-05
relaxation_factor
float
Relaxation factor 0.0
Flight dynamics Solvers¶
StaticTrim¶
The
StaticTrim
solver determines the longitudinal state of trim (equilibrium) for an aeroelastic system in static conditions. It wraps around the desired solver to yield the state of trim of the system, in most cases theStaticCoupled
solver.It calculates the required angle of attack, elevator deflection and thrust required to achieve longitudinal equilibrium. The output angles are shown in degrees.
The results from the trimming iteration can be saved to a text file by using the save_info option.
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default print_info
bool
Print info to screen True
solver
str
Solver to run in trim routine solver_settings
dict
Solver settings dictionary {}
max_iter
int
Maximum number of iterations of trim routine 100
fz_tolerance
float
Tolerance in vertical force 0.01
fx_tolerance
float
Tolerance in horizontal force 0.01
m_tolerance
float
Tolerance in pitching moment 0.01
tail_cs_index
int
Index of control surfaces that move to achieve trim 0
thrust_nodes
list(int)
Nodes at which thrust is applied [0]
initial_alpha
float
Initial angle of attack 0.0
initial_deflection
float
Initial control surface deflection 0.0
initial_thrust
float
Initial thrust setting 0.0
initial_angle_eps
float
Initial change of control surface deflection 0.05
initial_thrust_eps
float
Initial thrust setting change 2.0
relaxation_factor
float
Relaxation factor 0.2
save_info
bool
Save trim results to text file False
folder
str
Output location for trim results ./output/
Trim algorithm method
The trim condition is found iteratively.
Returns: array of trim values for angle of attack, control surface deflection and thrust. Return type: np.array
Trim¶
Trim routine with support for lateral dynamics. It usually struggles much more than the
StaticTrim
(only longitudinal) solver.We advise to start with
StaticTrim
even if you configuration is not totally symmetric.The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default print_info
bool
Print info to screen True
solver
str
Solver to run in trim routine solver_settings
dict
Solver settings dictionary {}
max_iter
int
Maximum number of iterations of trim routine 100
tolerance
float
Threshold for convergence of trim 0.0001
initial_alpha
float
Initial angle of attack 0.0
initial_beta
float
Initial sideslip angle 0.0
initial_roll
float
Initial roll angle 0
cs_indices
list(int)
Indices of control surfaces to be trimmed []
initial_cs_deflection
list(float)
Initial deflection of the control surfaces in order. []
thrust_nodes
list(int)
Nodes at which thrust is applied [0]
initial_thrust
list(float)
Initial thrust setting [1.0]
thrust_direction
list(float)
Thrust direction setting [0.0, 1.0, 0.0]
special_case
dict
Extra settings for specific cases such as differential thrust control {}
refine_solution
bool
If True
and the optimiser routine allows for it, the optimiser will try to improve the solution with hybrid methodsFalse
Linear Solvers¶
LinearAssembler¶
Warning
Under development - please advise of new features and bugs!
Creates a workspace containing the different linear elements of the state-space.
The user specifies which elements to build sequentially via the
linear_system
setting.The most common uses will be:
- Aerodynamic:
sharpy.linear.assembler.LinearUVLM
solver - Structural:
sharpy.linear.assembler.LinearBeam
solver - Aeroelastic:
sharpy.linear.assembler.LinearAeroelastic
solver
The solver enables to load a user specific assembly of a state-space by means of the
LinearCustom
block.See
sharpy.sharpy.linear.assembler.LinearAssembler
for a detailed description of each of the state-space assemblies.Upon assembly of the linear system, the data structure
data.linear
will be created. TheLinear
contains the state-space as an attribute. This state space will be the one employed by postprocessors.Important: running the linear routines requires information on the tangent mass, stiffness and gyroscopic structural matrices therefore the solver
solvers.modal.Modal
must have been run prior to linearisation. In addition, if the problem includes rigid body velocities, at least one timestep ofsolvers.DynamicCoupled
must have run such that the rigid body velocity is included.Example:
The typical
flow
setting used prior to using this solver for an aeroelastic simulation with rigid body dynamics will be similar to:>>> flow = ['BeamLoader', >>> 'AerogridLoader', >>> 'StaticTrim', >>> 'DynamicCoupled', # a single time step will suffice >>> 'Modal', >>> 'LinearAssembler']
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default linear_system
str
Name of chosen state space assembly type None
linear_system_settings
dict
Settings for the desired state space assembler {}
linearisation_tstep
int
Chosen linearisation time step number from available time steps -1
- Aerodynamic:
Modal¶
Modal
solver class, inherited fromBaseSolver
Extracts the
M
,K
andC
matrices from theFortran
library for the beam. Depending on the choice of modal projection, these may or may not be transformed to a state-space form to compute the eigenvalues and mode shapes of the structure.The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default print_info
bool
Write status to screen True
folder
str
Output folder ./output
rigid_body_modes
bool
Write modes with rigid body mode shapes False
use_undamped_modes
bool
Project the modes onto undamped mode shapes True
NumLambda
int
Number of modes to retain 20
keep_linear_matrices
bool
Save M, C and K matrices to output dictionary True
write_modes_vtk
bool
Write Paraview files with mode shapes True
print_matrices
bool
Write M, C and K matrices to file False
write_dat
bool
Write mode shapes, frequencies and damping to file True
continuous_eigenvalues
bool
Use continuous time eigenvalues False
dt
float
Time step to compute discrete time eigenvalues 0
delta_curved
float
Threshold for linear expressions in rotation formulas 0.01
plot_eigenvalues
bool
Plot to screen root locus diagram False
max_rotation_deg
float
Scale mode shape to have specified maximum rotation 15.0
max_displacement
float
Scale mode shape to have specified maximum displacement 0.15
use_custom_timestep
int
If > -1, it will use that time step geometry for calculating the modes -1
rigid_modes_cg
bool
Modify the ridid body modes such that they are defined wrt to the CG False
Returns the rigid body modes defined with respect to the centre of gravity
The transformation from the modes defined at the FoR A origin, \(\boldsymbol{\Phi}\), to the modes defined using the centre of gravity as a reference is
\[\boldsymbol{\Phi}_{rr,CG}|_{TRA} = \boldsymbol{\Phi}_{RR}|_{TRA} + \tilde{\mathbf{r}}_{CG} \boldsymbol{\Phi}_{RR}|_{ROT}\]\[\boldsymbol{\Phi}_{rr,CG}|_{ROT} = \boldsymbol{\Phi}_{RR}|_{ROT}\]Returns: Transformed eigenvectors Return type: (np.array)
Extracts the eigenvalues and eigenvectors of the clamped structure.
If
use_undamped_modes == True
then the free vibration modes of the clamped structure are found solving:\[\mathbf{M\,\ddot{\eta}} + \mathbf{K\,\eta} = 0\]that flows down to solving the non-trivial solutions to:
\[(-\omega_n^2\,\mathbf{M} + \mathbf{K})\mathbf{\Phi} = 0\]On the other hand, if the damped modes are chosen because the system has damping, the free vibration modes are found solving the equation of motion of the form:
\[\mathbf{M\,\ddot{\eta}} + \mathbf{C\,\dot{\eta}} + \mathbf{K\,\eta} = 0\]which can be written in state space form, with the state vector \(\mathbf{x} = [\eta^T,\,\dot{\eta}^T]^T\) as
\[\begin{split}\mathbf{\dot{x}} = \begin{bmatrix} 0 & \mathbf{I} \\ -\mathbf{M^{-1}K} & -\mathbf{M^{-1}C} \end{bmatrix} \mathbf{x}\end{split}\]and therefore the mode shapes and frequencies correspond to the solution of the eigenvalue problem
\[\mathbf{A\,\Phi} = \mathbf{\Lambda\,\Phi}.\]From the eigenvalues, the following system characteristics are provided:
- Natural Frequency: \(\omega_n = |\lambda|\)
- Damped natural frequency: \(\omega_d = \text{Im}(\lambda) = \omega_n \sqrt{1-\zeta^2}\)
- Damping ratio: \(\zeta = -\frac{\text{Re}(\lambda)}{\omega_n}\)
In addition to the above, the modal output dictionary includes the following:
M
: Tangent mass matrixC
: Tangent damping matrixK
: Tangent stiffness matrixCcut
: Modal damping matrix \(\mathbf{C}_m = \mathbf{\Phi}^T\mathbf{C}\mathbf{\Phi}\)Kin_damp
: Forces gain matrix (when damped): \(K_{in} = \mathbf{\Phi}_L^T \mathbf{M}^{-1}\)eigenvectors
: Right eigenvectorseigenvectors_left
: Left eigenvectors given when the system is damped
Returns: updated data object with modal analysis as part of the last structural time step. Return type: PreSharpy
Loader Solvers¶
PreSharpy¶
The PreSharpy solver is the main loader solver of SHARPy. It takes the admin-like settings for the simulation, including the case name, case route and the list of solvers to run and in which order to run them. This order of solvers is referred to, throughout SHARPy, as the
flow
setting.This is a mandatory solver for all simulations at the start so it is never included in the
flow
setting.The settings for this solver are parsed through in the configuration file under the header
SHARPy
. I.e, when you are defining the config file for a simulation, the settings for PreSharpy are included as:import configobj filename = '<case_route>/<case_name>.sharpy' config = configobj.ConfigObj() config.filename = filename config['SHARPy'] = {'case': '<your SHARPy case name>', # an example setting # Rest of your settings for the PreSHARPy class }
The following are the settings that the PreSharpy class takes:
Name Type Description Default flow
list(str)
List of the desired solvers’ solver_id
to run in sequential order.None
case
str
Case name default_case_name
route
str
Route to case files None
write_screen
bool
Display output on terminal screen. True
write_log
bool
Write log file False
log_folder
str
Log folder destination directory
AerogridLoader¶
AerogridLoader
class, inherited fromBaseSolver
Generates aerodynamic grid based on the input data
Parameters: data (PreSharpy) – ProblemData
class structureName-value pair of the settings employed by the aerodynamic solver
Type: dict
Acceptable types for the values in
settings
Type: dict
Name-value pair of default values for the aerodynamic settings
Type: dict
class structure
Type: ProblemData
name of the
.aero.h5
HDF5 fileType: str
empty attribute
key-value pairs of aerodynamic data
Type: dict
Notes
The
control_surface_deflection
setting allows the user to use a time specific control surface deflection, should the problem include them. This setting takes a list of strings, each for the required control surface generator.The
control_surface_deflection_generator_settings
setting is a list of dictionaries, one for each control surface. The dictionaries specify the settings for the generatorDynamicControlSurface
. If the relevant control surface is simply static, an empty string should be parsed. See the documentation forDynamicControlSurface
generators for accepted key-value pairs as settings.The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default unsteady
bool
Unsteady effects False
aligned_grid
bool
Align grid True
freestream_dir
list(float)
Free stream flow direction [1.0, 0.0, 0.0]
mstar
int
Number of chordwise wake panels 10
control_surface_deflection
list(str)
List of control surface generators for each control surface []
control_surface_deflection_generator_settings
list(dict)
List of dictionaries with the settings for each generator []
BeamLoader¶
BeamLoader
class solver inherited fromBaseSolver
Loads the structural beam solver with the specified user settings.
Parameters: data (ProblemData) – class containing the problem information contains the specific settings for the solver
Type: dict
Key value pairs of the accepted types for the settings values
Type: dict
Dictionary containing the default solver settings, should none be provided.
Type: dict
class containing the data for the problem
Type: ProblemData
name of the
.fem.h5
HDF5 fileType: str
name of the
.dyn.h5
HDF5 fileType: str
key-value pairs of FEM data
Type: dict
key-value pairs of data for dynamic problems
Type: dict
Empty attribute
Type: None
Notes
For further reference on Quaternions see: https://en.wikipedia.org/wiki/Quaternion
See also
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default unsteady
bool
If True
it will be a dynamic problem. The default is usually good for all simulationsTrue
orientation
list(float)
Initial attitude of the structure given as the quaternion that parametrises the rotation from G to A frames of reference. [1.0, 0, 0, 0]
Structural Solvers¶
NonLinearDynamic¶
Structural solver used for the dynamic simulation of free-flying structures.
This solver provides an interface to the structural library (
xbeam
) and updates the structural parameters for every time step of the simulation.This solver is called as part of a standalone structural simulation.
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default print_info
bool
Print output to screen True
max_iterations
int
Sets maximum number of iterations 100
num_load_steps
int
1
delta_curved
float
0.01
min_delta
float
Structural solver tolerance 1e-05
newmark_damp
float
Sets the Newmark damping coefficient 0.0001
gravity_on
bool
Flag to include gravitational forces False
gravity
float
Gravitational acceleration 9.81
relaxation_factor
float
0.3
dt
float
Time step increment 0.01
num_steps
int
500
prescribed_motion
bool
None
gravity_dir
list(float)
[0, 0, 1]
NonLinearDynamicCoupledStep¶
Structural solver used for the dynamic simulation of free-flying structures.
This solver provides an interface to the structural library (
xbeam
) and updates the structural parameters for every k-th step in the FSI iteration.This solver can be called as part of a standalone structural simulation or as the structural solver of a coupled aeroelastic simulation.
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default print_info
bool
Print output to screen True
max_iterations
int
Sets maximum number of iterations 100
num_load_steps
int
1
delta_curved
float
0.01
min_delta
float
Structural solver tolerance 1e-05
newmark_damp
float
Sets the Newmark damping coefficient 0.0001
gravity_on
bool
Flag to include gravitational forces False
gravity
float
Gravitational acceleration 9.81
relaxation_factor
float
0.3
dt
float
Time step increment 0.01
num_steps
int
500
balancing
bool
False
initial_velocity_direction
list(float)
Initial velocity of the reference node given in the inertial FOR [-1.0, 0.0, 0.0]
initial_velocity
float
Initial velocity magnitude of the reference node 0
NonLinearDynamicMultibody¶
Nonlinear dynamic multibody
Nonlinear dynamic step solver for multibody structures.
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default print_info
bool
Print output to screen True
max_iterations
int
Sets maximum number of iterations 100
num_load_steps
int
1
delta_curved
float
0.01
min_delta
float
Structural solver tolerance 1e-05
newmark_damp
float
Sets the Newmark damping coefficient 0.0001
gravity_on
bool
Flag to include gravitational forces False
gravity
float
Gravitational acceleration 9.81
relaxation_factor
float
0.3
dt
float
Time step increment 0.01
num_steps
int
500
NonLinearDynamicPrescribedStep¶
Structural solver used for the dynamic simulation of clamped structures or those subject to a prescribed motion.
This solver provides an interface to the structural library (
xbeam
) and updates the structural parameters for every k-th step in the FSI iteration.This solver can be called as part of a standalone structural simulation or as the structural solver of a coupled aeroelastic simulation.
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default print_info
bool
Print output to screen True
max_iterations
int
Sets maximum number of iterations 100
num_load_steps
int
1
delta_curved
float
0.01
min_delta
float
Structural solver tolerance 1e-05
newmark_damp
float
Sets the Newmark damping coefficient 0.0001
gravity_on
bool
Flag to include gravitational forces False
gravity
float
Gravitational acceleration 9.81
relaxation_factor
float
0.3
dt
float
Time step increment 0.01
num_steps
int
500
NonLinearStatic¶
Structural solver used for the static simulation of free-flying structures.
This solver provides an interface to the structural library (
xbeam
) and updates the structural parameters for every k-th step of the FSI iteration.This solver can be called as part of a standalone structural simulation or as the structural solver of a coupled static aeroelastic simulation.
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default print_info
bool
Print output to screen True
max_iterations
int
Sets maximum number of iterations 100
num_load_steps
int
1
delta_curved
float
0.01
min_delta
float
Structural solver tolerance 1e-05
newmark_damp
float
Sets the Newmark damping coefficient 0.0001
gravity_on
bool
Flag to include gravitational forces False
gravity
float
Gravitational acceleration 9.81
relaxation_factor
float
0.3
dt
float
Time step increment 0.01
num_steps
int
500
initial_position
list(float)
<sphinx.ext.autodoc.importer._MockObject object at 0x7fa06fdf3860>
NonLinearStaticMultibody¶
Nonlinear static multibody
Nonlinear static solver for multibody structures.
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default print_info
bool
Print output to screen True
max_iterations
int
Sets maximum number of iterations 100
num_load_steps
int
1
delta_curved
float
0.01
min_delta
float
Structural solver tolerance 1e-05
newmark_damp
float
Sets the Newmark damping coefficient 0.0001
gravity_on
bool
Flag to include gravitational forces False
gravity
float
Gravitational acceleration 9.81
relaxation_factor
float
0.3
dt
float
Time step increment 0.01
num_steps
int
500
Post-Processing¶
AeroForcesCalculator¶
Calculates the total aerodynamic forces on the frame of reference
A
.The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default folder
str
Output folder location ./output
write_text_file
bool
Write txt
file with resultsFalse
text_file_name
str
Text file name screen_output
bool
Show results on screen True
unsteady
bool
Include unsteady contributions False
coefficients
bool
Calculate aerodynamic coefficients False
q_ref
float
Reference dynamic pressure 1
S_ref
float
Reference area 1
AerogridPlot¶
Aerodynamic Grid Plotter
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default folder
str
Output folder ./output
include_rbm
bool
True
include_forward_motion
bool
False
include_applied_forces
bool
True
include_unsteady_applied_forces
bool
False
minus_m_star
int
0
name_prefix
str
Prefix to add to file name u_inf
float
0.0
dt
float
0.0
include_velocities
bool
False
num_cores
int
1
AsymptoticStability¶
Calculates the asymptotic stability properties of the linearised aeroelastic system by computing the corresponding eigenvalues.
To use an iterative eigenvalue solver, the setting
iterative_eigvals
should be set toon
. This will be beneficial when deailing with very large systems. However, the direct method is preferred and more efficient when the system is of a relatively small size (typically around 5000 states).Warning
The setting
modes_to_plot
to plot the eigenvectors in Paraview is currently under development.The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default folder
str
Output folder ./output
print_info
bool
Print information and table of eigenvalues False
reference_velocity
float
Reference velocity at which to compute eigenvalues for scaled systems 1.0
frequency_cutoff
float
Truncate higher frequency modes. If zero none are truncated 0
export_eigenvalues
bool
Save eigenvalues and eigenvectors to file. False
display_root_locus
bool
Show plot with eigenvalues on Argand diagram False
velocity_analysis
list(float)
List containing min, max and number of velocities to analyse the system []
iterative_eigvals
bool
Calculate the first num_evals
using an iterative solver.False
num_evals
int
Number of eigenvalues to retain. 200
modes_to_plot
list(int)
List of mode numbers to simulate and plot []
postprocessors
list(str)
To be used with modes_to_plot
. Under development.[]
postprocessors_settings
dict
To be used with modes_to_plot
. Under development.{}
Displays root locus diagrams.
Returns the
fig
andax
handles for further editing.Returns: ax: Return type: fig
Saves a
num_evals
number of eigenvalues and eigenvectors to file. The files are saved in the output directoy and include:eigenvectors.dat
:(num_dof, num_evals)
array of eigenvectorseigenvalues_r.dat
:(num_evals, 1)
array of the real part of the eigenvalueseigenvalues_i.dat
:(num_evals, 1)
array of the imaginary part of the eigenvalues.
The units of the eigenvalues are
rad/s
References
Loading and saving complex arrays: https://stackoverflow.com/questions/6494102/how-to-save-and-load-an-array-of-complex-numbers-using-numpy-savetxt/6522396
Parameters: num_evals – Number of eigenvalues to save
Returns a single, scaled mode shape in time domain.
Parameters: - fact – Structural deformation scaling
- fact_rbm – Rigid body motion scaling
- mode_num – Number of mode to plot
- cycles – Number of periods/cycles to plot
Returns: Time domain array and scaled eigenvector in time.
Return type: tuple
Warning
Under development
Plot the aeroelastic mode shapes for the first
n_modes_to_plot
Prints the eigenvalues to a table with the corresponding natural frequency, period and damping ratios
Computes the eigenvalues and eigenvectors
Returns: Eigenvalues sorted and frequency truncated eigenvectors (np.ndarray): Corresponding mode shapes Return type: eigenvalues (np.ndarray)
Sort continuous-time eigenvalues by order of magnitude.
The conjugate of complex eigenvalues is removed, then if specified, high frequency modes are truncated. Finally, the eigenvalues are sorted by largest to smallest real part.
Parameters: - eigenvalues (np.ndarray) – Continuous-time eigenvalues
- eigenvectors (np.ndarray) – Corresponding right eigenvectors
- frequency_cutoff (float) – Cutoff frequency for truncation
[rad/s]
Returns:
BeamLoads¶
Writes to file the total loads acting on the beam elements
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default csv_output
bool
Write csv
file with resultsFalse
output_file_name
str
Output file name beam_loads
folder
str
Output folder path ./output
BeamPlot¶
Plots beam to Paraview format
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default folder
str
Output folder path ./output
include_rbm
bool
Include frame of reference rigid body motion True
include_FoR
bool
Include frame of reference variables False
include_applied_forces
bool
Write beam applied forces True
include_applied_moments
bool
Write beam applied moments True
name_prefix
str
Name prefix for files output_rbm
bool
Write csv
file with rigid body motion dataTrue
FrequencyResponse¶
Frequency Response Calculator
Computes the frequency response of a linear system. If a reduced order model has been created, a comparison is made between the two responses.
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default Options folder
str
Output folder ./output
print_info
bool
Write output to screen False
compute_fom
bool
Compute frequency response of full order model (use caution if large) False
load_fom
str
Folder to locate full order model frequency response data frequency_unit
str
Units of frequency, “w” for rad/s, “k” reduced k
w
,k
frequency_bounds
list(float)
Lower and upper frequency bounds in the corresponding unit [0.001, 1]
num_freqs
int
Number of frequencies to evaluate 50
quick_plot
bool
Produce array of .png
plots showing response. Requires matplotlibFalse
Get the frequency response of the linear state-space Returns:
PickleData¶
This postprocessor writes the SHARPy
data
structure in a pickle file, such that classes and methods from SHARPy are retained for restarted solutions or further post-processing.The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default folder
str
Folder to output pickle file ./output
SaveData¶
The
SaveData
postprocessor writes the SHARPy variables intohdf5
files. The linear state space files may be saved to.mat
if desired instead.It has options to save the following classes:
Aerogrid
includingsharpy.sharpy.utils.datastructures.AeroTimeStepInfo
Beam
includingsharpy.sharpy.utils.datastructures.StructTimeStepInfo
sharpy.solvers.linearassembler.Linear
including classes insharpy.linear.assembler
Notes
This method saves simply the data. If you would like to preserve the SHARPy methods of the relevant classes see also
sharpy.solvers.pickledata.PickleData
.The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default Options folder
str
Folder to save data ./output
save_aero
bool
Save aerodynamic classes. True
save_struct
bool
Save structural classes. True
save_linear
bool
Save linear state space system. False
save_linear_uvlm
bool
Save linear UVLM state space system. Use with caution when dealing with large systems. False
skip_attr
list(str)
List of attributes to skip when writing file ['fortran', 'airfoils', 'airfoil_db', 'settings_types', 'ct_dynamic_forces_list', 'ct_gamma_dot_list', 'ct_gamma_list', 'ct_gamma_star_list', 'ct_normals_list', 'ct_u_ext_list', 'ct_u_ext_star_list', 'ct_zeta_dot_list', 'ct_zeta_list', 'ct_zeta_star_list', 'dynamic_input']
compress_float
bool
Compress float False
format
str
Save linear state space to hdf5 .h5
or Matlab.mat
format.h5
h5
,mat
StabilityDerivatives¶
Outputs the stability derivatives of a free-flying aircraft
Warning
Under Development
- To Do:
- Coefficient of stability derivatives
- Option to output in NED frame
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default print_info
bool
Display info to screen True
folder
str
Output directory ./output/
u_inf
float
Free stream reference velocity 1.0
S_ref
float
Reference planform area 1.0
b_ref
float
Reference span 1.0
c_ref
float
Reference chord 1.0
Stability derivatives calculated using the transfer function of the UVLM projected onto the structural degrees of freedom at zero frequency (steady state).
Returns: - matrix containing the steady state values of the transfer function between the force output
- (columns) and the velocity / control surface inputs (rows).
Return type: np.array
StallCheck¶
Outputs the incidence angle of every panel of the surface.
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default print_info
bool
Print info to screen True
airfoil_stall_angles
dict
Dictionary of stall angles for each airfoil {}
output_degrees
bool
Output incidence angles in degrees vs radians False
WriteVariablesTime¶
Write variables with time
WriteVariablesTime
is a class inherited fromBaseSolver
It is a postprocessor that outputs the value of variables with time onto a text file.
Acceptable data types of the input data
Type: dict
Default values for input data should the user not provide them
Type: dict
-
See the list of arguments
directory to output the information
Type: str
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default folder
str
Output folder directory ./output/
delimiter
str
Delimiter to be used in the output file `` `` FoR_variables
list(str)
Variables of StructTimeStepInfo
associated to the frame of reference to be writen['']
FoR_number
list(int)
Number of the A frame of reference to output (for multibody configurations) <sphinx.ext.autodoc.importer._MockObject object at 0x7fa06fa285f8>
structure_variables
list(str)
Variables of StructTimeStepInfo
associated to the frame of reference to be writen['']
structure_nodes
list(int)
Number of the nodes to be writen <sphinx.ext.autodoc.importer._MockObject object at 0x7fa06fa28668>
aero_panels_variables
list(str)
Variables of AeroTimeStepInfo
associated to panels to be writen['']
aero_panels_isurf
list(int)
Number of the panels’ surface to be output <sphinx.ext.autodoc.importer._MockObject object at 0x7fa06fa286a0>
aero_panels_im
list(int)
Chordwise index of the panels to be output <sphinx.ext.autodoc.importer._MockObject object at 0x7fa06fa286d8>
aero_panels_in
list(int)
Spanwise index of the panels to be output <sphinx.ext.autodoc.importer._MockObject object at 0x7fa06fa28710>
aero_nodes_variables
list(str)
Variables of AeroTimeStepInfo
associated to nodes to be writen['']
aero_nodes_isurf
list(int)
Number of the nodes’ surface to be output <sphinx.ext.autodoc.importer._MockObject object at 0x7fa06fa28748>
aero_nodes_im
list(int)
Chordwise index of the nodes to be output <sphinx.ext.autodoc.importer._MockObject object at 0x7fa06fa28780>
aero_nodes_in
list(int)
Spanwise index of the nodes to be output <sphinx.ext.autodoc.importer._MockObject object at 0x7fa06fa287b8>
cleanup_old_solution
bool
Remove the existing files false
SHARPy Source Code¶
The core SHARPy documentation is found herein.
Note
The docs are still a work in progress and therefore, most functions/classes with which there is not much user interaction are not fully documented. We would appreciate any help by means of you contributing to our growing documentation!
If you feel that a function/class is not well documented and, hence, you cannot use it, feel free to raise an issue so that we can improve it.
Aerodynamic Packages¶
Models¶
Aerogrid¶
Aerogrid contains all the necessary routines to generate an aerodynamic grid based on the input dictionaries.
Aerogrid
is the main object containing information of the grid of panelsIt is created by the solver
sharpy.solvers.aerogridloader.AerogridLoader
Computes the temporal derivative of circulation (gamma) using finite differences.
It will use a first order approximation for the first evaluation (when
len(previous_tsteps) == 1
), and then second order ones.\[\left.\frac{d\Gamma}{dt}\right|^n \approx \lim_{\Delta t \rightarrow 0}\frac{\Gamma^n-\Gamma^{n-1}}{\Delta t}\]For the second time step and onwards, the following second order approximation is used:
\[\left.\frac{d\Gamma}{dt}\right|^n \approx \lim_{\Delta t \rightarrow 0}\frac{3\Gamma^n -4\Gamma^{n-1}+\Gamma^{n-2}}{2\Delta t}\]Parameters: - dt (float) – delta time for the finite differences
- tstep (AeroTimeStepInfo) – tstep at time n (current)
- previous_tsteps (list(AeroTimeStepInfo)) – previous tstep structure in order:
[n-N,..., n-2, n-1]
Returns: first derivative of circulation with respect to time
Return type: float
See also
Returns a strip of panels in A
frame of reference, it has to be then rotated to
simulate angles of attack, etc
Utilities¶
Force Mapping Utilities¶
Maps the aerodynamic forces at the lattice to the structural nodes
The aerodynamic forces from the UVLM are always in the inertial G
frame of reference and have to be transformed
to the body or local B
frame of reference in which the structural forces are defined.
Since the structural nodes and aerodynamic panels are coincident in a spanwise direction, the aerodynamic forces
that correspond to a structural node are the summation of the M+1
forces defined at the lattice at that
spanwise location.
where \(\tilde{\boldsymbol{\zeta}}^G\) is the skew-symmetric matrix of the vector between the lattice grid vertex and the structural node.
It is possible to introduce efficiency and constant terms in the mapping of forces that are user-defined. For more
info see efficiency_local_aero2struct_forces()
.
The efficiency and constant terms are introduced by means of the array airfoil_efficiency
in the aero.h5
input file. If this variable has been defined, the function used to map the forces will be
efficiency_local_aero2struct_forces()
. Else, the standard formulation
local_aero2struct_forces()
will be used.
param aero_forces: | |
---|---|
Aerodynamic forces from the UVLM in inertial frame of reference | |
type aero_forces: | |
list | |
param struct2aero_mapping: | |
Structural to aerodynamic node mapping | |
type struct2aero_mapping: | |
dict | |
param zeta: | Aerodynamic grid coordinates |
type zeta: | list |
param pos_def: | Vector of structural node displacements |
type pos_def: | np.ndarray |
param psi_def: | Vector of structural node rotations (CRVs) |
type psi_def: | np.ndarray |
param master: | Unused |
param conn: | Connectivities matrix |
type conn: | np.ndarray |
param cag: | Transformation matrix between inertial and body-attached reference A |
type cag: | np.ndarray |
param aero_dict: | |
Dictionary containing the grid’s information. | |
type aero_dict: | dict |
returns: | structural forces in an n_node x 6 vector |
rtype: | np.ndarray |
Maps the local aerodynamic forces at a given vertex to its corresponding structural node, introducing user-defined efficiency and constant value factors.
param local_aero_forces: | |
---|---|
aerodynamic forces and moments at a grid vertex | |
type local_aero_forces: | |
np.ndarray | |
param chi_g: | vector between grid vertex and structural node in inertial frame |
type chi_g: | np.ndarray |
param cbg: | transformation matrix between inertial and body frames of reference |
type cbg: | np.ndarray |
param force_efficiency: | |
force efficiency matrix for all structural elements. Its size is n_elem x n_node_elem x 2 x 3 |
|
type force_efficiency: | |
np.ndarray | |
param moment_efficiency: | |
moment efficiency matrix for all structural elements. Its size is n_elem x n_node_elem x 2 x 3 |
|
type moment_efficiency: | |
np.ndarray | |
param i_elem: | element index |
type i_elem: | int |
param i_local_node: | |
local node index within element | |
type i_local_node: | |
int | |
returns: | corresponding aerodynamic force at the structural node from the force and moment at a grid vertex |
rtype: | np.ndarray |
Maps the local aerodynamic forces at a given vertex to its corresponding structural node.
param local_aero_forces: | |
---|---|
aerodynamic forces and moments at a grid vertex | |
type local_aero_forces: | |
np.ndarray | |
param chi_g: | vector between grid vertex and structural node in inertial frame |
type chi_g: | np.ndarray |
param cbg: | transformation matrix between inertial and body frames of reference |
type cbg: | np.ndarray |
param force_efficiency: | |
Unused. See efficiency_local_aero2struct_forces() . |
|
type force_efficiency: | |
np.ndarray | |
param moment_efficiency: | |
Unused. See efficiency_local_aero2struct_forces() . |
|
type moment_efficiency: | |
np.ndarray | |
param i_elem: | |
type i_elem: | int |
returns: | corresponding aerodynamic force at the structural node from the force and moment at a grid vertex |
rtype: | np.ndarray |
Controllers¶
ControlSurfacePidController¶
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default time_history_input_file
str
Route and file name of the time history of desired state None
P
float
Proportional gain of the controller None
I
float
Integral gain of the controller 0.0
D
float
Differential gain of the controller 0.0
input_type
str
Quantity used to define the reference state. Supported: pitch None
dt
float
Time step of the simulation None
controlled_surfaces
list(int)
Control surface indices to be actuated by this controller None
controlled_surfaces_coeff
list(float)
Control surface deflection coefficients. For example, for antisymmetric deflections => [1, -1]. [1.0]
write_controller_log
bool
Write a time history of input, required input, and control True
controller_log_route
str
Directory where the log will be stored ./output/
Main routine of the controller. Input is data (the self.data in the solver), and currrent_state which is a dictionary with [‘structural’, ‘aero’] time steps for the current iteration.
Parameters: - data – problem data containing all the information.
- controlled_state – dict with two vars: structural and aero containing the timestep_info that will be returned with the control variables.
Returns: A dict with structural and aero time steps and control input included.
TakeOffTrajectoryController¶
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default trajectory_input_file
str
Route and file name of the trajectory file given as a csv with columns: time, x, y, z None
dt
float
Time step of the simulation None
trajectory_method
str
Trajectory controller method. For now, “lagrange” is the supported option lagrange
controlled_constraint
str
Name of the controlled constraint in the multibody context Usually, it is something like constraint_00. None
controller_log_route
str
Directory where the log will be stored ./output/
write_controller_log
bool
Controls if the log from the controller is written or not. True
free_trajectory_structural_solver
str
If different than and empty string, the structural solver will be changed after the end of the trajectory has been reached free_trajectory_structural_substeps
int
Controls the structural solver structural substeps once the end of the trajectory has been reached 0
initial_ramp_length_structural_substeps
int
Controls the number of timesteps that are used to increase the structural substeps from 0 10
Main routine of the controller. Input is data (the self.data in the solver), and currrent_state which is a dictionary with [‘structural’, ‘aero’] time steps for the current iteration.
Parameters: - data – problem data containing all the information.
- controlled_state – dict with two vars: structural and aero containing the timestep_info that will be returned with the control variables.
Returns: A dict with structural and aero time steps and control input included.
Generators¶
Velocity field generators prescribe the flow conditions for your problem. For instance, you can have an aircraft at a prescribed fixed location in a velocity field towards the aircraft. Alternatively, you can have a free moving aircraft in a static velocity field.
Dynamic Control Surface generators enable the user to prescribe a certain control surface deflection in time.
BumpVelocityField¶
Bump Velocity Field Generator
BumpVelocityField
is a class inherited fromBaseGenerator
The
BumpVelocityField
class generates a bump-shaped gust profile velocity field, and the profile has the characteristics specified by the user.To call this generator, the
generator_id = BumpVelocityField
shall be used. This is parsed as the value for thevelocity_field_generator
key in the desired aerodynamic solver’s settings.The resultant velocity, $w_g$, is calculated as follows:
\[w_g = \frac{w_0}{4}\left( 1 + \cos(\frac{(x - x_0)}{H_x} \right)\left( 1 + \cos(\frac{(y - y_0)}{H_y} \right)\]Notes
For now, only simulations where the inertial FoR is fixed are supported.
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default gust_intensity
float
Intensity of the gust None
x0
float
x location of the centre of the bump 0.0
y0
float
y location of the centre of the bump 0.0
hx
float
Gust gradient in the x direction 1.0
hy
float
Gust gradient in the y direction 1.0
relative_motion
bool
When true the gust will move at the prescribed velocity False
u_inf
float
Free stream velocity None
u_inf_direction
list(float)
Free stream velocity direction <sphinx.ext.autodoc.importer._MockObject object at 0x7fa070a653c8>
DynamicControlSurface¶
Dynamic Control Surface deflection Generator
DynamicControlSurface
class inherited fromBaseGenerator
The object generates a deflection in radians based on the time series given as a vector in the input data
To call this generator, the
generator_id = DynamicControlSurface
shall be used. This is parsed as the value for thecontrol_surface_deflection_generator
key in the aerogridloader solver’s settings.Parameters: in_dict (dict) – Input data in the form of dictionary. See acceptable entries below.
Name Type Description Default dt
float
Timestep for the simulation None
deflection_file
str
Relative path to the file with the deflection information. None
Acceptable data types of the input data
Type: dict
Default values for input data should the user not provide them
Type: dict
Array of deflection of the control surface
Type: np.array
Array of the time derivative of the cs deflection. Calculated using 1st order finite differences.
Type: np.array
See also
GridBox¶
Generatex a grid within a box to be used to generate the flow field during the postprocessing
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default coords_0
list(float)
First bounding box corner [0.0, 0.0, 0.0]
coords_1
list(float)
Second bounding box corner [10.0, 0.0, 10.0]
spacing
list(float)
Spacing parameters of the bbox [1.0, 1.0, 1.0]
moving
bool
If True
, the box moves with the body frame of reference. It does not rotate with it, thoughFalse
Gust Velocity Field Generators¶
These generators are used to create a gust velocity field. GustVelocityField
is the main class that should be
parsed as the velocity_field_input
to the desired aerodynamic solver.
The remaining classes are the specific gust profiles and parsed as gust_shape
.
- Examples:
The typical input to the aerodynamic solver settings would therefore read similar to:
>>> aero_settings = {'<some_aero_settings>': '<some_aero_settings>', >>> 'velocity_field_generator': 'GustVelocityField', >>> 'velocity_field_input': {'u_inf': 1, >>> 'gust_shape': '<desired_gust>', >>> 'gust_parameters': '<gust_settings>'}}
DARPA¶
Discrete, non-uniform span model
\[U_z = \frac{u_{de}}{2}\left[1-\cos\left(\frac{2\pi x}{S}\right)\right]\cos\left(\frac{\pi y}{b}\right)\]This gust can be used by using the setting
gust_shape = 'DARPA'
inGustVelocityField
.The
GustVelocityField
generator takes the following settings as a dictionary assignedtogust_parameters
.Name Type Description Default gust_length
float
Length of gust 0.0
gust_intensity
float
Intensity of the gust 0.0
span
float
Wing span 0.0
GustVelocityField¶
Gust Velocity Field Generator
GustVelocityField
is a class inherited fromBaseGenerator
The
GustVelocityField
class generates a gust profile velocity field, and the profile has the characteristics specified by the user.To call this generator, the
generator_id = GustVelocityField
shall be used. This is parsed as the value for thevelocity_field_generator
key in the desired aerodynamic solver’s settings.Notation: \(u_{de}\) is the gust intensity, \(S\) is the gust length and \(b\) is the wing span. \(x\) and \(y\) refer to the chordwise and spanwise distance penetrated into the gust, respectively.
Several gust profiles are available. Your chosen gust profile should be parsed to
gust_shape
and the corresponding settings as a dictionary togust_parameters
.This generator takes the following settings
Name Type Description Default u_inf
float
Free stream velocity None
u_inf_direction
list(float)
Free stream velocity relative component [1.0, 0.0, 0.0]
offset
float
Spatial offset of the gust with respect to origin 0.0
relative_motion
bool
If true, the gust is convected with u_inf False
gust_shape
str
Gust profile shape None
gust_parameters
dict
Dictionary of parameters specific of the gust_shape selected {}
continuous_sin¶
Continuous sinusoidal gust model
\[U_z = \frac{u_{de}}{2}\sin\left(\frac{2\pi x}{S}\right)\]This gust can be used by using the setting
gust_shape = 'continuous_sin'
inGustVelocityField
.The
GustVelocityField
generator takes the following settings as a dictionary assignedtogust_parameters
.Name Type Description Default gust_length
float
Length of gust 0.0
gust_intensity
float
Intensity of the gust 0.0
lateral_one_minus_cos¶
This gust can be used by using the setting
gust_shape = 'lateral 1-cos'
inGustVelocityField
.The
GustVelocityField
generator takes the following settings as a dictionary assignedtogust_parameters
.Name Type Description Default gust_length
float
Length of gust 0.0
gust_intensity
float
Intensity of the gust 0.0
one_minus_cos¶
One minus cos gust (single bump)
\[U_z = \frac{u_{de}}{2}\left[1-\cos\left(\frac{2\pi x}{S}\right)\right]\]This gust can be used by using the setting
gust_shape = '1-cos'
inGustVelocityField
.The
GustVelocityField
generator takes the following settings as a dictionary assignedtogust_parameters
.Name Type Description Default gust_length
float
Length of gust, \(S\). 0.0
gust_intensity
float
Intensity of the gust \(u_{de}\). 0.0
span_sine¶
This gust can be used by using the setting
gust_shape = 'span sine'
inGustVelocityField
.The
GustVelocityField
generator takes the following settings as a dictionary assignedtogust_parameters
.Name Type Description Default gust_intensity
float
Intensity of the gust 0.0
span
float
Wing span 0.0
periods_per_span
int
Number of times that the sine is repeated in the span of the wing 1
perturbation_dir
list(float)
Direction in which the perturbation will be applied in A FoR <sphinx.ext.autodoc.importer._MockObject object at 0x7fa070aa7ac8>
span_dir
list(float)
Direction of the span of the wing <sphinx.ext.autodoc.importer._MockObject object at 0x7fa070aa7400>
span_with_gust
float
Extension of the span to which the gust will be applied 0.0
time_varying¶
The inflow velocity changes with time but it is uniform in space. It is read from a 4 column file:
\[time[s] \Delta U_x \Delta U_y \Delta U_z\]This gust can be used by using the setting
gust_shape = 'time varying'
in :class:.`GustVelocityField`.The
GustVelocityField
generator takes the following settings as a dictionary assignedtogust_parameters
.Name Type Description Default file
str
File with the information
time_varying_global¶
Similar to the previous one but the velocity changes instanteneously in the whole flow field. It is not fed into the solid.
This gust can be used by using the setting
gust_shape = 'time varying global'
inGustVelocityField
.The
GustVelocityField
generator takes the following settings as a dictionary assignedtogust_parameters
.Name Type Description Default file
str
File with the information (only for time varying)
ShearVelocityField¶
Shear Velocity Field Generator
ShearVelocityField
class inherited fromBaseGenerator
The object creates a steady velocity field with shear
\[\hat{u} = \hat{u}\_\infty \left( \frac{h - h\_\mathrm{corr}}{h\_\mathrm{ref}} \right)^{\mathrm{shear}\_\mathrm{exp}}\]\[h = \zeta \cdot \mathrm{shear}\_\mathrm{direction}\]The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default u_inf
float
Free stream velocity magnitude None
u_inf_direction
list(float)
x
,y
andz
relative components of the free stream velocity<sphinx.ext.autodoc.importer._MockObject object at 0x7fa070a65908>
shear_direction
list(float)
x
,y
andz
relative components of the direction along which shear applies<sphinx.ext.autodoc.importer._MockObject object at 0x7fa070a65198>
shear_exp
float
Exponent of the shear law 0.0
h_ref
float
Reference height at which u_inf
is defined1.0
h_corr
float
Height to correct shear law 0.0
SteadyVelocityField¶
Steady Velocity Field Generator
SteadyVelocityField
class inherited fromBaseGenerator
The object creates a steady velocity field with the velocity and flow direction specified by the user.
To call this generator, the
generator_id = SteadyVelocityField
shall be used. This is parsed as the value for thevelocity_field_generator
key in the desired aerodynamic solver’s settings.Parameters: in_dict (dict) – Input data in the form of dictionary. See acceptable entries below:
Name Type Description Default u_inf
float
Free stream velocity magnitude 0
u_inf_direction
list(float)
x
,y
andz
relative components of the free stream velocity[1.0, 0.0, 0.0]
Acceptable data types of the input data
Type: dict
Default values for input data should the user not provide them
Type: dict
Free stream velocity selection
Type: float
x
,y
andz
relative contributions to the free stream velocityType: list(float)
See also
TrajectoryGenerator¶
TrajectoryGenerator
is used to generate nodal positions or velocities for trajectory constraints such as the ones included in the multibody solver.It is usually called from a
Controller
module.The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default angle_end
float
Trajectory angle wrt horizontal at release 0.0
veloc_end
float
Release velocity at release None
shape
str
Shape of the z
vsx
function.quadratic
orlinear
are supportedquadratic
acceleration
str
Acceleration law, possible values are linear
orconstant
linear
dt
float
Time step of the simulation None
coords_end
list(float)
Coordinates of the final ramp point None
plot
bool
Plot the ramp shape. Requires matplotlib installed False
print_info
bool
Print information on runtime False
time_offset
float
Time interval before the start of the ramp acceleration 0.0
offset
list(float)
Coordinates of the starting point of the simulation <sphinx.ext.autodoc.importer._MockObject object at 0x7fa070aa70f0>
return_velocity
bool
If True
, nodal velocities are given, ifFalse
, coordinates are the outputFalse
TurbVelocityField¶
Turbulent Velocity Field Generator
TurbVelocitityField
is a class inherited fromBaseGenerator
The
TurbVelocitityField
class generates a velocity field based on the input from an [XDMF](http://www.xdmf.org) file. It supports time-dependant fields as well as frozen turbulence.To call this generator, the
generator_id = TurbVelocityField
shall be used. This is parsed as the value for thevelocity_field_generator
key in the desired aerodynamic solver’s settings.- Supported files:
- field_id.xdmf: Steady or Unsteady XDMF file
This generator also performs time interpolation between two different time steps. For now, only linear interpolation is possible.
Space interpolation is done through scipy.interpolate trilinear interpolation. However, turbulent fields are read directly from the binary file and not copied into memory. This is performed using np.memmap. The overhead of this procedure is ~18% for the interpolation stage, however, initially reading the binary velocity field (which will be much more common with time-domain simulations) is faster by a factor of 1e4. Also, memory savings are quite substantial: from 6Gb for a typical field to a handful of megabytes for the whole program.
Parameters: in_dict (dict) – Input data in the form of dictionary. See acceptable entries below: Attributes:
See also
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default print_info
bool
Output solver-specific information in runtime. True
turbulent_field
str
XDMF file path of the velocity field None
offset
list(float)
Spatial offset in the 3 dimensions <sphinx.ext.autodoc.importer._MockObject object at 0x7fa070b1e748>
centre_y
bool
Flat for changing the domain to [ -y_max/2
,y_max/2
]True
periodicity
str
Axes in which periodicity is enforced xy
frozen
bool
If True
, the turbulent field will not be updated in timeTrue
store_field
bool
If True
, the xdmf snapshots are stored in memory. Only two at a time for the linear interpolationFalse
Legacy function, not using the custom format based on HDF5 anymore.
This function returns an interpolator list of size 3 made of scipy.interpolate.RegularGridInterpolator objects.
Reads the xml file <case_name>.xdmf. Writes the self.grid_data data structure with all the information necessary.
Note: this function does not load any turbulence data (such as ux000, …), it only reads the header information contained in the xdmf file.
TurbVelocityFieldBts¶
Turbulent Velocity Field Generator from TurbSim bts files
TurbVelocitityFieldBts
is a class inherited fromBaseGenerator
The
TurbVelocitityFieldBts
class generates a velocity field based on the input from a bts file generated by TurbSim. https://nwtc.nrel.gov/TurbSimTo call this generator, the
generator_id = TurbVelocityField
shall be used. This is parsed as the value for thevelocity_field_generator
key in the desired aerodynamic solver’s settings.The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default print_info
bool
Output solver-specific information in runtime True
turbulent_field
str
BTS file path of the velocity file None
new_orientation
str
New order of the axes xyz
u_fed
list(float)
Velocity at which the turbulence field is fed into the solid <sphinx.ext.autodoc.importer._MockObject object at 0x7fa070a65278>
u_out
list(float)
Velocity to set for points outside the interpolating box <sphinx.ext.autodoc.importer._MockObject object at 0x7fa070a656a0>
case_with_tower
bool
Does the SHARPy case will include the tower in the simulation? False
Linear SHARPy¶
The code included herein enables the assembly of linearised state-space systems based on the previous solution of a nonlinear problem that will be used as linearisation reference.
The code is structured in the following way:
- Assembler: different state-spaces to assemble, from only structural/aerodynamic to fully coupled aeroelastic
- Src: source code required for the linearisation and utilities for the manipulation of state-space elements
References:
Maraniello, S. , Palacios, R.. State-Space Realizations and Internal Balancing in Potential-Flow Aerodynamics with Arbitrary Kinematics. AIAA Journal, Vol. 57, No.6, June 2019
Assembler¶
Control surface deflector for linear systems¶
Control surface deflector for linear systems
Subsystem that deflects control surfaces for use with linear state space systems
The current version supports only deflections. Future work will include standalone state-space systems to model physical actuators.
Warning
Under-development
Will assemble the state-space for an actuator model Returns:
Generates a matrix mapping a linear control surface deflection onto the aerodynamic grid.
The parsing of arguments is temporary since this state space element will include a full actuator model.
The parsing of arguments is optional if the class has been previously initialised.
Parameters: - linuvlm –
- tsaero0 –
- tsstruct0 –
- aero –
- structure –
Returns:
Linearised rotation vector of the vector v
by angle theta
about an arbitrary axis u
.
The rotation of a vector \(\mathbf{v}\) about the axis \(\mathbf{u}\) by an angle \(\boldsymbol{\theta}\) can be expressed as
where \(\mathbf{R}\) is a \(\mathbb{R}^{3\times 3}\) matrix.
This expression can be linearised for it to be included in the linear solver as
The matrix \(\mathbf{R}\) is
and its linearised expression becomes
and is of dimension \(\mathbb{R}^{3\times 1}\).
param u: | Arbitrary rotation axis |
---|---|
type u: | numpy.ndarray |
param theta: | Rotation angle (radians) |
type theta: | float |
param v: | Vector to rotate |
type v: | numpy.ndarray |
returns: | Linearised rotation vector of dimensions \(\mathbb{R}^{3\times 1}\). |
rtype: | numpy.ndarray |
LinearAeroelastic¶
Assemble a linearised aeroelastic system
The aeroelastic system can be seen as the coupling between a linearised aerodynamic system (System 1) and a linearised beam system (System 2).
The coupled system retains inputs and outputs from both systems such that
\[\mathbf{u} = [\mathbf{u}_1;\, \mathbf{u}_2]\]and the outputs are also ordered in a similar fashion
\[\mathbf{y} = [\mathbf{y}_1;\, \mathbf{y}_2]\]Reference the individual systems for the particular ordering of the respective input and output variables.
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default aero_settings
dict
Linear UVLM settings None
beam_settings
dict
Linear Beam settings None
uvlm_filename
str
Path to .data.h5 file containing UVLM/ROM state space to load track_body
bool
UVLM inputs and outputs projected to coincide with lattice at linearisation True
use_euler
bool
Parametrise orientations in terms of Euler angles False
Assembly of the linearised aeroelastic system.
The UVLM state-space system has already been assembled. Prior to assembling the beam’s first order state-space, the damping and stiffness matrices have to be modified to include the damping and stiffenning terms that arise from the linearisation of the aeordynamic forces with respect to the A frame of reference. See
sharpy.linear.src.lin_aeroela.get_gebm2uvlm_gains()
for details on the linearisation.Then the beam is assembled as per the given settings in normalised time if the aerodynamic system has been scaled. The discrete time systems of the UVLM and the beam must have the same time step.
The UVLM inputs and outputs are then projected onto the structural degrees of freedom (obviously with the exception of external gusts and control surfaces). Hence, the gains \(\mathbf{K}_{sa}\) and \(\mathbf{K}_{as}\) are added to the output and input of the UVLM system, respectively. These gains perform the following relation:
\[\begin{split}\begin{bmatrix}\zeta \\ \zeta' \\ u_g \\ \delta \end{bmatrix} = \mathbf{K}_{as} \begin{bmatrix} \eta \\ \eta' \\ u_g \\ \delta \end{bmatrix} =\end{split}\]\[\mathbf{N}_{nodes} = \mathbf{K}_{sa} \mathbf{f}_{vertices}\]If the beam is expressed in modal form, the UVLM is further projected onto the beam’s modes to have the following input/output structure:
Returns:
Provides:
- the gain matrices required to connect the linearised GEBM and UVLM
inputs/outputs- the stiffening and damping factors to be added to the linearised GEBM equations in order to account for non-zero aerodynamic loads at the linearisation point.
The function produces the gain matrices:
Kdisp
: gains from GEBM to UVLM grid displacementsKvel_disp
: influence of GEBM dofs displacements to UVLM grid velocities.Kvel_vel
: influence of GEBM dofs displacements to UVLM grid displacements.Kforces
(UVLM->GEBM) dimensions are the transpose than theKdisp and Kvel* matrices. Hence, when allocation this term,
ii
andjj
indices will unintuitively refer to columns and rows,
respectively.
And the stiffening/damping terms accounting for non-zero aerodynamic forces at the linearisation point:
Kss
: stiffness factor (flexible dof -> flexible dof) accounting for non-zero forces at the linearisation point.Csr
: damping factor (rigid dof -> flexible dof)Crs
: damping factor (flexible dof -> rigid dof)Crr
: damping factor (rigid dof -> rigid dof)
Stiffening and damping related terms due to the non-zero aerodynamic forces at the linearisation point:
\[\mathbf{F}_{A,n} = C^{AG}(\mathbf{\chi})\sum_j \mathbf{f}_{G,j} \rightarrow \delta\mathbf{F}_{A,n} = C^{AG}_0 \sum_j \delta\mathbf{f}_{G,j} + \frac{\partial}{\partial\chi}(C^{AG}\sum_j \mathbf{f}_{G,j}^0)\delta\chi\]The term multiplied by the variation in the quaternion, \(\delta\chi\), couples the forces with the rigid body equations and becomes part of \(\mathbf{C}_{sr}\).
Similarly, the linearisation of the moments results in expression that contribute to the stiffness and damping matrices.
\[\mathbf{M}_{B,n} = \sum_j \tilde{X}_B C^{BA}(\Psi)C^{AG}(\chi)\mathbf{f}_{G,j}\]\[\delta\mathbf{M}_{B,n} = \sum_j \tilde{X}_B\left(C_0^{BG}\delta\mathbf{f}_{G,j} + \frac{\partial}{\partial\Psi}(C^{BA}\delta\mathbf{f}^0_{A,j})\delta\Psi + \frac{\partial}{\partial\chi}(C^{BA}_0 C^{AG} \mathbf{f}_{G,j})\delta\chi\right)\]The linearised equations of motion for the geometrically exact beam model take the input term \(\delta \mathbf{Q}_n = \{\delta\mathbf{F}_{A,n},\, T_0^T\delta\mathbf{M}_{B,n}\}\), which means that the moments should be provided as \(T^T(\Psi)\mathbf{M}_B\) instead of \(\mathbf{M}_A = C^{AB}\mathbf{M}_B\), where \(T(\Psi)\) is the tangential operator.
\[\delta(T^T\mathbf{M}_B) = T^T_0\delta\mathbf{M}_B + \frac{\partial}{\partial\Psi}(T^T\delta\mathbf{M}_B^0)\delta\Psi\]is the linearised expression for the moments, where the first term would correspond to the input terms to the beam equations and the second arises due to the non-zero aerodynamic moment at the linearisation point and must be subtracted (since it comes from the forces) to form part of \(\mathbf{K}_{ss}\). In addition, the \(\delta\mathbf{M}_B\) term depends on both \(\delta\Psi\) and \(\delta\chi\), therefore those terms would also contribute to \(\mathbf{K}_{ss}\) and \(\mathbf{C}_{sr}\), respectively.
The contribution from the total forces and moments will be accounted for in \(\mathbf{C}_{rr}\) and \(\mathbf{C}_{rs}\).
\[\delta\mathbf{F}_{tot,A} = \sum_n\left(C^{GA}_0 \sum_j \delta\mathbf{f}_{G,j} + \frac{\partial}{\partial\chi}(C^{AG}\sum_j \mathbf{f}_{G,j}^0)\delta\chi\right)\]Therefore, after running this method, the beam matrices will be updated as:
>>> K_beam[:flex_dof, :flex_dof] += Kss >>> C_beam[:flex_dof, -rigid_dof:] += Csr >>> C_beam[-rigid_dof:, :flex_dof] += Crs >>> C_beam[-rigid_dof:, -rigid_dof:] += Crr
Track body option
The
track_body
setting restricts the UVLM grid to linear translation motions and therefore should be used to ensure that the forces are computed using the reference linearisation frame.The UVLM and beam are linearised about a reference equilibrium condition. The UVLM is defined in the inertial reference frame while the beam employs the body attached frame and therefore a projection from one frame onto another is required during the coupling process.
However, the inputs to the UVLM (i.e. the lattice grid coordinates) are obtained from the beam deformation which is expressed in A frame and therefore the grid coordinates need to be projected onto the inertial frame
G
. As the beam rotates, the projection onto theG
frame of the lattice grid coordinates will result in a grid that is not coincident with that at the linearisation reference and therefore the grid coordinates must be projected onto the original frame, which will be referred to asU
. The transformation between the inertial frameG
and theU
frame is a function of the rotation of theA
frame and the original position:\[C^{UG}(\chi) = C^{GA}(\chi_0)C^{AG}(\chi)\]Therefore, the grid coordinates obtained in
A
frame and projected onto theG
frame can be transformed to theU
frame using\[\zeta_U = C^{UG}(\chi) \zeta_G\]which allows the grid lattice coordinates to be projected onto the original linearisation frame.
In a similar fashion, the output lattice vertex forces of the UVLM are defined in the original linearisation frame
U
and need to be transformed onto the inertial frameG
prior to projecting them onto theA
frame to use them as the input forces to the beam system.\[\boldsymbol{f}_G = C^{GU}(\chi)\boldsymbol{f}_U\]The linearisation of the above relations lead to the following expressions that have to be added to the coupling matrices:
Kdisp_vel
terms:\[\delta\boldsymbol{\zeta}_U= C^{GA}_0 \frac{\partial}{\partial \boldsymbol{\chi}} \left(C^{AG}\boldsymbol{\zeta}_{G,0}\right)\delta\boldsymbol{\chi} + \delta\boldsymbol{\zeta}_G\]Kvel_vel
terms:\[\delta\dot{\boldsymbol{\zeta}}_U= C^{GA}_0 \frac{\partial}{\partial \boldsymbol{\chi}} \left(C^{AG}\dot{\boldsymbol{\zeta}}_{G,0}\right)\delta\boldsymbol{\chi} + \delta\dot{\boldsymbol{\zeta}}_G\]
The transformation of the forces and moments introduces terms that are functions of the orientation and are included as stiffening and damping terms in the beam’s matrices:
Csr
damping terms relating to translation forces:\[C_{sr}^{tra} -= \frac{\partial}{\partial\boldsymbol{\chi}} \left(C^{GA} C^{AG}_0 \boldsymbol{f}_{G,0}\right)\delta\boldsymbol{\chi}\]Csr
damping terms related to moments:\[C_{sr}^{rot} -= T^\top\widetilde{\mathbf{X}}_B C^{BG} \frac{\partial}{\partial\boldsymbol{\chi}} \left(C^{GA} C^{AG}_0 \boldsymbol{f}_{G,0}\right)\delta\boldsymbol{\chi}\]
The
track_body
setting.When
track_body
is enabled, the UVLM grid is no longer coincident with the inertial reference frame throughout the simulation but rather it is able to rotate as theA
frame rotates. This is to simulate a free flying vehicle, where, for instance, the orientation does not affect the aerodynamics. The UVLM defined in this frame of reference, namedU
, satisfies the following convention:- The
U
frame is coincident with theG
frame at the time of linearisation. - The
U
frame rotates as theA
frame rotates.
Transformations related to the
U
frame of reference:The angle between the
U
frame and theA
frame is always constant and equal to \(\boldsymbol{\Theta}_0\).The angle between the
A
frame and theG
frame is \(\boldsymbol{\Theta}=\boldsymbol{\Theta}_0 + \delta\boldsymbol{\Theta}\)The projection of a vector expressed in the
G
frame onto theU
frame is expressed by:\[\boldsymbol{v}^U = C^{GA}_0 C^{AG} \boldsymbol{v}^G\]The reverse, a projection of a vector expressed in the
U
frame onto theG
frame, is expressed by\[\boldsymbol{v}^U = C^{GA} C^{AG}_0 \boldsymbol{v}^U\]
The effect this has on the aeroelastic coupling between the UVLM and the structural dynamics is that the orientation and change of orientation of the vehicle has no effect on the aerodynamics. The aerodynamics are solely affected by the contribution of the 6-rigid body velocities (as well as the flexible DOFs velocities).
Updates the aeroelastic scaled system with the new reference velocity.
Only the beam equations need updating since the only dependency in the forward flight velocity resides there.
Parameters: u_infty (float) – New reference velocity Returns: Updated aeroelastic state-space system Return type: sharpy.linear.src.libss.ss
Linear State Beam Element Class¶
Linear State Beam Element Class
State space member
Define class for linear state-space realisation of GEBM flexible-body equations from SHARPy
timestep_info
class and with the nonlinear structural information.State-space models can be defined in continuous or discrete time (dt required). Modal projection, either on the damped or undamped modal shapes, is also avaiable.
Notes on the settings:
modal_projection={True,False}
: determines whether to project the statesonto modal coordinates. Projection over damped or undamped modal shapes can be obtained selecting:
proj_modes = {'damped','undamped'}
while
inout_coords={'modes','nodal'}
determines whether the modal state-space inputs/outputs are modal coords or nodal degrees-of-freedom. If
modes
is selected, theKin
andKout
gain matrices are generated to transform nodal to modal dofs
dlti={True,False}
: if true, generates discrete-time system.The continuous to discrete transformation method is determined by:
discr_method={ 'newmark', # Newmark-beta 'zoh', # Zero-order hold 'bilinear'} # Bilinear (Tustin) transformation
DLTIs can be obtained directly using the Newmark-\(\beta\) method
discr_method='newmark'
newmark_damp=xx
withxx<<1.0
for full-states descriptions (
modal_projection=False
) and modal projection over the undamped structural modes (modal_projection=True
andproj_modes
). The Zero-order holder and bilinear methods, instead, work in all descriptions, but require the continuous state-space equations.
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default Options modal_projection
bool
Use modal projection True
inout_coords
str
Beam state space input/output coordinates nodes
nodes
,modes
num_modes
int
Number of modes to retain 10
discrete_time
bool
Assemble beam in discrete time True
dt
float
Discrete time system integration time step 0.001
proj_modes
str
Use undamped
ordamped
modesundamped
damped
,undamped
discr_method
str
Discrete time assembly system method: newmark
newmark
,zoh
,bilinear
newmark_damp
float
Newmark damping value. For systems assembled using newmark
0.0001
use_euler
bool
Use euler angles for rigid body parametrisation False
print_info
bool
Display information on screen True
gravity
bool
Linearise gravitational forces False
remove_dofs
list(str)
Remove desired degrees of freedom []
eta
,V
,W
,orient
remove_sym_modes
bool
Remove symmetric modes if wing is clamped False
Assemble the beam state-space system.
Parameters: t_ref (float) – Scaling factor to non-dimensionalise the beam’s time step. Returns:
Removes symmetric modes when the wing is clamped at the midpoint.
It will force the wing tip displacements in
z
to be postive for all modes.Updates the mode shapes matrix, the natural frequencies and the number of modes.
Warning
- Under development. Missing:
- Accelerations
- Double check the cartesian rotation vector
- Tangential operator for the moments
Takes the state \(x = [\eta, \dot{\eta}]\) and input vectors \(u = N\) of a linearised beam and returns a SHARPy timestep instance, including the reference values.
Parameters: - x_n (np.ndarray) – Structural beam state vector in nodal space
- y_n (np.ndarray) – Beam input vector (nodal forces)
- struct_tstep (utils.datastructures.StructTimeStepInfo) – Reference timestep used for linearisation
Returns: new timestep with linearised values added to the reference value
Return type: utils.datastructures.StructTimeStepInfo
LinearGustGenerator¶
Reduces the entire gust field input to a user-defined set of more comprehensive inputs
Linear UVLM State Space System¶
Linear UVLM State Space System
Linear UVLM System Assembler
Produces state-space model of the form
\[\begin{split}\mathbf{x}_{n+1} &= \mathbf{A}\,\mathbf{x}_n + \mathbf{B} \mathbf{u}_{n+1} \\ \mathbf{y}_n &= \mathbf{C}\,\mathbf{x}_n + \mathbf{D} \mathbf{u}_n\end{split}\]where the state, inputs and outputs are:
\[\mathbf{x}_n = \{ \delta \mathbf{\Gamma}_n,\, \delta \mathbf{\Gamma_{w_n}},\, \Delta t\,\delta\mathbf{\Gamma}'_n,\, \delta\mathbf{\Gamma}_{n-1} \}\]\[\mathbf{u}_n = \{ \delta\mathbf{\zeta}_n,\, \delta\mathbf{\zeta}'_n,\, \delta\mathbf{u}_{ext,n} \}\]\[\mathbf{y} = \{\delta\mathbf{f}\}\]with \(\mathbf{\Gamma}\in\mathbb{R}^{MN}\) being the vector of vortex circulations, \(\mathbf{\zeta}\in\mathbb{R}^{3(M+1)(N+1)}\) the vector of vortex lattice coordinates and \(\mathbf{f}\in\mathbb{R}^{3(M+1)(N+1)}\) the vector of aerodynamic forces and moments. Note that \((\bullet)'\) denotes a derivative with respect to time.
Note that the input is atypically defined at time
n+1
. If the settingremove_predictor = True
the predictor termu_{n+1}
is eliminated through the change of state[1]:\[\begin{split}\mathbf{h}_n &= \mathbf{x}_n - \mathbf{B}\,\mathbf{u}_n \\\end{split}\]such that:
\[\begin{split}\mathbf{h}_{n+1} &= \mathbf{A}\,\mathbf{h}_n + \mathbf{A\,B}\,\mathbf{u}_n \\ \mathbf{y}_n &= \mathbf{C\,h}_n + (\mathbf{C\,B}+\mathbf{D})\,\mathbf{u}_n\end{split}\]which only modifies the equivalent \(\mathbf{B}\) and \(\mathbf{D}\) matrices.
The
integr_order
setting refers to the finite differencing scheme used to calculate the bound circulation derivative with respect to time \(\dot{\mathbf{\Gamma}}\). A first order scheme is used whenintegr_order == 1
\[\dot{\mathbf{\Gamma}}^{n+1} = \frac{\mathbf{\Gamma}^{n+1}-\mathbf{\Gamma}^n}{\Delta t}\]If
integr_order == 2
a higher order scheme is used (but it isn’t exactly second order accurate [1]).\[\dot{\mathbf{\Gamma}}^{n+1} = \frac{3\mathbf{\Gamma}^{n+1}-4\mathbf{\Gamma}^n + \mathbf{\Gamma}^{n-1}} {2\Delta t}\]References
[1] Franklin, GF and Powell, JD. Digital Control of Dynamic Systems, Addison-Wesley Publishing Company, 1980
[2] Maraniello, S., & Palacios, R.. State-Space Realizations and Internal Balancing in Potential-Flow Aerodynamics with Arbitrary Kinematics. AIAA Journal, 57(6), 1–14. 2019. https://doi.org/10.2514/1.J058153
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default Options dt
float
Time step 0.1
integr_order
int
Integration order of the circulation derivative. 2
1
,2
ScalingDict
dict
Dictionary of scaling factors to achieve normalised UVLM realisation. {}
remove_predictor
bool
Remove the predictor term from the UVLM equations True
use_sparse
bool
Assemble UVLM plant matrix in sparse format True
density
float
Air density 1.225
remove_inputs
list(str)
List of inputs to remove. u_gust
to remove external velocity input.[]
u_gust
gust_assembler
str
Selected linear gust assembler. leading_edge
rom_method
list(str)
List of model reduction methods to reduce UVLM. []
rom_method_settings
dict
Dictionary with settings for the desired ROM methods, where the name of the ROM method is the key to the dictionary {}
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default Options length
float
Reference length to be used for UVLM scaling 1.0
speed
float
Reference speed to be used for UVLM scaling 1.0
density
float
Reference density to be used for UVLM scaling 1.0
Assembles the linearised UVLM system, removes the desired inputs and adds linearised control surfaces (if present).
With all possible inputs present, these are ordered as
\[\mathbf{u} = [\boldsymbol{\zeta},\,\dot{\boldsymbol{\zeta}},\,\mathbf{w},\,\delta]\]Control surface inputs are ordered last as:
\[[\delta_1, \delta_2, \dots, \dot{\delta}_1, \dot{\delta_2}]\]
Remove certain inputs from the input vector
- To do:
- Support for block UVLM
Parameters: remove_list (list) – Inputs to remove
Unpacks the input vector into the corresponding grid coordinates, velocities and external velocities.
Parameters: u_n (np.ndarray) – UVLM input vector. May contain control surface deflections and external velocities. Returns: Tuple containing zeta
,zeta_dot
andu_ext
, accounting for the effect of control surfaces.Return type: tuple
Transform column vectors used in the state space formulation into SHARPy format
The column vectors are transformed into lists with one entry per aerodynamic surface. Each entry contains a matrix with the quantities at each grid vertex.
\[\mathbf{y}_n \longrightarrow \mathbf{f}_{aero}\]\[\mathbf{x}_n \longrightarrow \mathbf{\Gamma}_n,\, \mathbf{\Gamma_w}_n,\, \mathbf{\dot{\Gamma}}_n\]If the
track_body
option is on, the output forces are projected from the linearization frame, to the G frame. Note that the linearisation frame is:- equal to the FoR G at time 0 (linearisation point)
- rotates as the body frame specified in the
track_body_number
Parameters: - y_n (np.ndarray) – Column output vector of linear UVLM system
- x_n (np.ndarray) – Column state vector of linear UVLM system
- u_n (np.ndarray) – Column input vector of linear UVLM system
- aero_tstep (AeroTimeStepInfo) – aerodynamic timestep information class instance
Returns: Tuple containing:
- forces (list):
Aerodynamic forces in a list with
n_surf
entries. Each entry is a(6, M+1, N+1)
matrix, where the first 3 indices correspond to the components inx
,y
andz
. The latter 3 are zero.- gamma (list):
Bound circulation list with
n_surf
entries. Circulation is stored in an(M+1, N+1)
matrix, corresponding to the panel vertices.- gamma_dot (list):
Bound circulation derivative list with
n_surf
entries. Circulation derivative is stored in an(M+1, N+1)
matrix, corresponding to the panel vertices.- gamma_star (list):
Wake (free) circulation list with
n_surf
entries. Wake circulation is stored in an(M_star+1, N+1)
matrix, corresponding to the panel vertices of the wake.
Return type: tuple
Linearised System Source Code¶
Assembly of linearised UVLM system¶
- Maraniello, 25 May 2018
- Includes:
- Boundary conditions methods:
- AICs: allocate aero influence coefficient matrices of multi-surfaces configurations
nc_dqcdzeta_Sin_to_Sout
: derivative matrix ofnc*dQ/dzeta
where Q is the induced velocity at the bound collocation points of one surface to another.nc_dqcdzeta_coll
: assemblesnc_dqcdzeta_coll_Sin_to_Sout
matrices in multi-surfaces configurationsuc_dncdzeta
: assemble derivative matrix dnc/dzeta*Uc at bound collocation points
Given a list of bound (Surfs) and wake (Surfs_star) instances of surface.AeroGridSurface, returns the list of AIC matrices in the format:
- AIC_list[ii][jj] contains the AIC from the bound surface Surfs[jj] to
Surfs[ii]. - AIC_star_list[ii][jj] contains the AIC from the wake surface Surfs[jj] to Surfs[ii].
Assemble derivative of quasi-steady force w.r.t. gamma with fixed relative velocity - the changes in induced velocities due to gamma are not accounted for. The routine exploits the get_joukovski_qs method insude the AeroGridSurface class
Assemble derivative of quasi-steady force w.r.t. external input velocity.
Assemble derivative of quasi-steady force w.r.t. induced velocities changes due to gamma. Note: the routine is memory consuming but avoids unnecessary computations.
Assemble derivative of quasi-steady force w.r.t. induced velocities changes due to zeta.
Assemble derivative of quasi-steady force w.r.t. to zeta The contribution implemented is related with the omega x zeta term call: Der_list = dfqsdzeta_omega(Surfs,Surfs_star)
Assemble derivative of quasi-steady force w.r.t. zeta with fixed relative velocity - the changes in induced velocities due to zeta over the surface inducing the velocity are not accounted for. The routine exploits the available relative velocities at the mid-segment points
Computes derivative of unsteady aerodynamic force with respect to changes in circulation.
Note: the function also checks that the first derivative of the circulation at the linearisation point is null. If not, a further contribution to the added mass, depending on the changes in panel area and normal, arises and needs to be implemented.
Produces derivatives of induced velocity by Surf_in w.r.t. the zetac point. Derivatives are divided into those associated to the movement of zetac, and to the movement of the Surf_in vertices (DerVert).
If Surf_in is bound (IsBound==True), the circulation over the TE due to the wake is not included in the input.
If Surf_in is a wake (IsBound==False), derivatives w.r.t. collocation points are computed ad the TE contribution on DerVert. In this case, the chordwise paneling Min_bound of the associated input is required so as to calculate Kzeta and correctly allocate the derivative matrix.
The output derivatives are: - Dercoll: 3 x 3 matrix - Dervert: 3 x 3*Kzeta (if Surf_in is a wake, Kzeta is that of the bound)
Warning: zetac must be contiguously stored!
Used by autodoc_mock_imports.
Used by autodoc_mock_imports.
Produces a list of derivative matrix d(omaga x zeta)/dzeta, where omega is the rotation speed of the A FoR, ASSUMING constant panel norm.
Each list is such that: - the ii-th element is associated to the ii-th bound surface collocation point, and will contain a sub-list such that:
- the j-th element of the sub-list is the dAIC_dzeta matrices w.r.t. the
zeta d.o.f. of the j-th bound surface.
Hence, DAIC*[ii][jj] will have size K_ii x Kzeta_jj
call: ncDOmegaZetavert = nc_domegazetadzeta(Surfs,Surfs_star)
Produces a list of derivative matrix
where \(\mathcal{A}\) is the aerodynamic influence coefficient matrix at the bound surfaces collocation point, assuming constant panel norm.
Each list is such that:
the
ii
-th element is associated to theii
-th bound surface collocation point, and will contain a sub-list such that:
- the
j
-th element of the sub-list is thedAIC_dzeta
matrices w.r.t. thezeta
d.o.f. of thej
-th bound surface.
Hence, DAIC*[ii][jj]
will have size K_ii x Kzeta_jj
If Merge
is True
, the derivatives due to collocation points movement are added
to Dvert
to minimise storage space.
To do:
- Dcoll is highly sparse, exploit?
- Computes derivative matrix of
- nc*dQ/dzeta
where Q is the induced velocity induced by bound surface Surf_in onto bound surface Surf_out. The panel normals of Surf_out are constant.
The input/output are: - Der_coll of size (Kout,3*Kzeta_out): derivative due to the movement of collocation point on Surf_out. - Der_vert of size:
- (Kout,3*Kzeta_in) if Surf_in_bound is True
- (Kout,3*Kzeta_bound_in) if Surf_in_bound is False; Kzeta_bound_in is
the number of vertices in the bound surface of whom Surf_out is the wake.
Note that: - if Surf_in_bound is False, only the TE movement contributes to Der_vert. - if Surf_in_bound is False, the allocation of Der_coll could be speed-up by scanning only the wake segments along the chordwise direction, as on the others the net circulation is null.
Test allocation of single term of wake propagation matrix
Build derivative of
where \(\boldsymbol{u}_c\) is the total velocity at the collocation points.
param Surf: | the input can also be a list of surface.AerogridSurface |
---|---|
type Surf: | surface.AerogridSurface |
References
Assembly of wake propagation matrices, in sparse or dense matrices format
Note: wake propagation matrices are very sparse. Nonetheless, allocation in dense format (from numpy.zeros) or sparse does not have important differences in terms of cpu time and memory used as numpy.zeros does not allocate memory until this is accessed.
Mapping methods for bound surface panels¶
- Maraniello, 19 May 2018
Produces mapping between panels, segment and vertices of a surface. Grid elements are identified through the indices (m,n), where:
- m: chordwise index
- n: spanwise index
The same indexing is applied to panel, vertices and segments.
Elements: - panels=(M,N) - vertices=(M+1,N+1) - segments: these are divided in segments developing along the chordwise and spanwise directions.
- chordwise: (M,N+1)
- spanwise: (M+1,N)
Mapping structures: - Mpv: for each panel (mp,np) returns the chord/span-wise indices of its vertices, (mv,nv). This has size (M,N,4,2) - Mps: maps each panel (mp,np) to the ii-th segment. This has size (M,N,4,2)
# - Mps_extr: for each panel (m,n) returns the indices of the extrema of each side # of the panel.
Note: - mapping matrices are stored as np.int16 or np.int32 arrays
For each panel (m,n) it provides the ms,ns indices of each segment.
From panel of indices (m,n) to indices of vertices
Returns the panel for which the vertex is locally numbered as 0,1,2,3. Returns a (4,2) array such that its elements are:
[vv_local,(m,n) of panel]where vv_local is the local verteix number.
Important: indices -1 are possible is the vertex does not have local index 0,1,2 or 3 with respect to any panel.
Mapping from panel of segments. self.Mpv is a (M,N,4,2) array such that:
- [m, n, local_segment_number,
- chordwise/spanwise index of segment,]
Mapping from panel of vertices. self.Mpv is a (M,N,4,2) array such that its element are:
[m, n, local_vertex_number, spanwise/chordwise indices of vertex]
Mapping: - FROM: the index of a scalar quantity defined at panel collocation point and stored in 1D array. - TO: index of a scalar quantity defined at vertices and stored in 1D
- The Mpv1d_scalar has size (K,4) where:
- [1d index of panel, index of vertex 0,1,2 or 3]
Maps from vertices to panels. Produces a (M+1,N+1,4,2) array, associating vertices to panels. Its elements are:
- [m vertex,
- n vertex,
- vertex local index,
- chordwise/spanwise panel indices]
Mapping: - FROM: the index of a scalar quantity defined at vertices and stored in 1D array. - TO: index of a scalar quantity defined at panels and stored in 1D
- The Mpv1d_scalar has size (Kzeta,4) where:
- [1d index of vertex, index of vertex 0,1,2 or 3 w.r.t. panel]
Defines interpolation methods (geometrically-exact) and matrices (linearisation)¶
Defines interpolation methods (geometrically-exact) and matrices (linearisation) S. Maraniello, 20 May 2018
Provide projection matrix from nodal velocities to normal velocity at collocation points
Produce scalar interpolation matrix Wvc for state-space realisation.
Important: this will not work for coordinates extrapolation, as it would require information about the panel size. It works for other forces/scalar quantities extrapolation. It assumes the quantity at the collocation point is determined proportionally to the weight associated to each vertex and obtained through get_panel_wcv.
Produces a compact array with weights for bilinear interpolation, where aN,aM in [0,1] are distances in the chordwise and spanwise directions such that:
- (aM,aN)=(0,0) –> quantity at vertex 0
- (aM,aN)=(1,0) –> quantity at vertex 1
- (aM,aN)=(1,1) –> quantity at vertex 2
- (aM,aN)=(0,1) –> quantity at vertex 3
Induced Velocity Derivatives¶
Calculate derivatives of induced velocity.
Methods:
- eval_seg_exp and eval_seg_exp_loop: profide ders in format
[Q_{x,y,z},ZetaPoint_{x,y,z}]
and use fully-expanded analytical formula.
eval_panel_exp: iterates through whole panel
- eval_seg_comp and eval_seg_comp_loop: profide ders in format
[Q_{x,y,z},ZetaPoint_{x,y,z}]
and use compact analytical formula.
Used by autodoc_mock_imports.
Used by autodoc_mock_imports.
Used by autodoc_mock_imports.
Used by autodoc_mock_imports.
Used by autodoc_mock_imports.
Used by autodoc_mock_imports.
Used by autodoc_mock_imports.
Used by autodoc_mock_imports.
Used by autodoc_mock_imports.
Induced Velocity Derivatives with respect to Panel Normal¶
Calculate derivative of
\[\boldsymbol{u}_c\frac{\partial\boldsymbol{n}_c}{\partial\boldsymbol{zeta}}\]
with respect to local panel coordinates.
Returns a 4 x 3 array, containing the derivative of Wnc*Uc w.r.t the panel vertices coordinates.
Fitting Tools Library¶
@author: Salvatore Maraniello
@date: 15 Jan 2018
Wrapper for fitfrd (mag=0) and fitfrdmag (mag=1) functions in continuous and discrete time (if ds in input). Input:
kv,yv: frequency array and frequency response N: order for rational function approximation mag=1,0: Flag for determining method to use dt (optional): sampling time for DLTI systems
Returns magnitude of the residual Yfit-Yv of a RFA approximation at each point kv. The coefficients of the approximations are: - cnum=xv[:Nnum] - cdem=xv[Nnum:] where cnum and cden are as per the ‘rfa’ function.
Define residual scalar norm of Pade approximation of coefficients cnum=xv[:Nnum] and cden[Nnum:] (see get_rfa_res and rfa function) and time-step ds (if discrete time).
Find best II order fitting polynomial from frequency response Yv over the frequency range kv for both continuous (ds=None) and discrete (ds>0) LTI systems.
Input: - kv: frequency points - Yv: frequency response - dyv,ddyv: frequency responses of I and II order derivatives - method=’leastsq’,’dev’: algorithm for minimisation - Bup (only ‘dev’ method): bounds for bv coefficients as per scipy.optimize.differential_evolution. This is a length 3 array.
Important: - this function attributes equal weight to each data-point!
Evaluates over the frequency range kv.the rational function approximation: [cnum[-1] + cnum[-2] z + … + cnum[0] z**Nnum ]/…
[cden[-1] + cden[-2] z + … + cden[0] z**Nden]
where the numerator and denominator polynomial orders, Nnum and Nden, are the length of the cnum and cden arrays and:
- z=exp(1.j*kv*ds), with ds sampling time if ds is given (discrete-time
system) - z=1.*kv, if ds is None (continuous time system)
Find best fitting RFA approximation from frequency response Yv over the frequency range kv for both continuous (ds=None) and discrete (ds>0) LTI systems.
- The RFA approximation is found through a 2-stage strategy:
- a. an evolutionary algoryhtm is run to determine the optimal fitting coefficients b. the search is refined through a least squares algorithm.
- and is stopped as soon as:
- 1. the maximum absolute error in frequency response of the RFA falls
below
TolAbs
2. the maximum number of iterations is reached.
Input: - kv: frequency range for approximation - Yv: frequency response vector over kv - TolAbs: maximum admissible absolute difference in frequency response between RFA and original system. - Nnum,Ndem: number of coefficients for Pade approximation. - ds: sampling time for DLTI systems - NtrialMax: maximum number of repetition of global and least square optimisations - Cfbouds: maximum absolute values of coeffieicnts (only for evolutionary algorithm) - OutFull: if False, only outputs optimal coefficients of RFA. Otherwise,
outputs cost and RFA coefficients of each trial.
Output: - cnopt: optimal coefficients (numerator) - cdopt: optimal coefficients (denominator)
Important: - this function has the same objective as fitfrd in matwrapper module. While generally slower, the global optimisation approach allows to verify the results from fitfrd.
Given the frequency response of a MIMO DLTI system, this function returns the A,B,C,D matrices associated to the rational function approximation of the original system.
Input: - Yfull: frequency response (as per libss.freqresp) of full size system over the frequencies kv. - kv: array of frequencies over which the RFA approximation is evaluated. - tolAbs: absolute tolerance for the rfa fitting - Nnum: number of numerator coefficients for RFA - Nden: number of denominator coefficients for RFA - NtrialMax: maximum number of attempts - method=[‘intependent’]. Method used to produce the system:
- intependent: each input-output combination is treated separately. The
resulting system is a collection of independent SISO DLTIs
Evaluates over the frequency range kv.the derivative of order m of the rational function approximation: [cnum[-1] + cnum[-2] z + … + cnum[0] z**Nnum ]/…
[cden[-1] + cden[-2] z + … + cden[0] z**Nden]
where the numerator and denominator polynomial orders, Nnum and Nden, are the length of the cnum and cden arrays and:
- z=exp(1.j*kv*ds), with ds sampling time if ds is given (discrete-time
system) - z=1.*kv, if ds is None (continuous time system)
Collect tools to manipulate sparse and/or mixed dense/sparse matrices.¶
Collect tools to manipulate sparse and/or mixed dense/sparse matrices.
author: S. Maraniello date: Dec 2018
Comment: manipulating large linear system may require using both dense and sparse matrices. While numpy/scipy automatically handle most operations between mixed dense/sparse arrays, some (e.g. dot product) require more attention. This library collects methods to handle these situations.
Classes: scipy.sparse matrices are wrapped so as to ensure compatibility with numpy arrays upon conversion to dense. - csc_matrix: this is a wrapper of scipy.csc_matrix. - SupportedTypes: types supported for operations - WarningTypes: due to some bugs in scipy (v.1.1.0), sum (+) operations between np.ndarray and scipy.sparse matrices can result in numpy.matrixlib.defmatrix.matrix types. This list contains such undesired types that can result from dense/sparse operations and raises a warning if required. (b) convert these types into numpy.ndarrays.
Methods: - dot: handles matrix dot products across different types. - solve: solves linear systems Ax=b with A and b dense, sparse or mixed. - dense: convert matrix to numpy array
Warning: - only sparse types into SupportedTypes are supported!
To Do: - move these methods into an algebra module?
dot product between block matrices.
Inputs: A, B: are nested lists of dense/sparse matrices of compatible shape for block matrices product. Empty blocks can be defined with None. (see numpy.block)
dot product between block matrices.
Inputs: A, B: are nested lists of dense/sparse matrices of compatible shape for block matrices product. Empty blocks can be defined with None. (see numpy.block)
Wrapper of scipy.csc_matrix that ensures best compatibility with numpy.ndarray. The following methods have been overwritten to ensure that numpy.ndarray are returned instead of numpy.matrixlib.defmatrix.matrix.
- todense
- _add_dense
Warning: this format is memory inefficient to allocate new sparse matrices. Consider using: - scipy.sparse.lil_matrix, which supports slicing, or - scipy.sparse.coo_matrix, though slicing is not supported :(
As per scipy.spmatrix.todense but returns a numpy.ndarray.
If required, converts sparse array to dense.
- Method to compute
- C = A*B ,
where * is the matrix product, with dense/sparse/mixed matrices.
The format (sparse or dense) of C is specified through ‘type_out’. If type_out==None, the output format is sparse if both A and B are sparse, dense otherwise.
The following formats are supported: - numpy.ndarray - scipy.csc_matrix
Produces an identity matrix as per M, in shape and type
- Wrapper of
- numpy.linalg.solve and scipy.sparse.linalg.spsolve
for solution of the linear system A x = b. - if A is a dense numpy array np.linalg.solve is called for solution. Note that if B is sparse, this requires convertion to dense. In this case, solution through LU factorisation of A should be considered to exploit the sparsity of B. - if A is sparse, scipy.sparse.linalg.spsolve is used.
Produces an identity matrix as per M, in shape and type
Linear Time Invariant systems¶
Linear Time Invariant systems author: S. Maraniello date: 15 Sep 2017 (still basement…)
Library of methods to build/manipulate state-space models. The module supports the sparse arrays types defined in libsparse.
The module includes:
Classes: - ss: provides a class to build DLTI/LTI systems with full and/or sparse
matrices and wraps many of the methods in these library. Methods include: - freqresp: wraps the freqresp function - addGain: adds gains in input/output. This is not a wrapper of addGain, as the system matrices are overwritten
Methods for state-space manipulation: - couple: feedback coupling. Does not support sparsity - freqresp: calculate frequency response. Supports sparsity. - series: series connection between systems - parallel: parallel connection between systems - SSconv: convert state-space model with predictions and delays - addGain: add gains to state-space model. - join2: merge two state-space models into one. - join: merge a list of state-space models into one. - sum state-space models and/or gains - scale_SS: scale state-space model - simulate: simulates discrete time solution - Hnorm_from_freq_resp: compute H norm of a frequency response - adjust_phase: remove discontinuities from a frequency response
Special Models: - SSderivative: produces DLTI of a numerical derivative scheme - SSintegr: produces DLTI of an integration scheme - build_SS_poly: build state-space model with polynomial terms.
Filtering: - butter
Utilities: - get_freq_from_eigs: clculate frequency corresponding to eigenvalues
Comments: - the module supports sparse matrices hence relies on libsparse.
- to do:
- remove unnecessary coupling routines
- couple function can handle sparse matrices but only outputs dense matrices
- verify if typical coupled systems are sparse
- update routine
- add method to automatically determine whether to use sparse or dense?
Given a frequency response over a domain kv, this funcion computes the H norms through numerical integration.
Note that if kv[-1]<np.pi/dt, the method assumed gv=0 for each frequency kv[-1]<k<np.pi/dt.
Warning: only use for SISO systems! For MIMO definitions are different
Convert a DLTI system with prediction and delay of the form:
\[\begin{split}\mathbf{x}_{n+1} &= \mathbf{A\,x}_n + \mathbf{B_0\,u}_n + \mathbf{B_1\,u}_{n+1} + \mathbf{B_{m1}\,u}_{n-1} \\ \mathbf{y}_n &= \mathbf{C\,x}_n + \mathbf{D\,u}_n\end{split}\]
into the state-space form:
\[\begin{split}\mathbf{h}_{n+1} &= \mathbf{A_h\,h}_n + \mathbf{B_h\,u}_n \\ \mathbf{y}_n &= \mathbf{C_h\,h}_n + \mathbf{D_h\,u}_n\end{split}\]
If \(\mathbf{B_{m1}}\) is None
, the original state is retrieved through
\[\mathbf{x}_n = \mathbf{h}_n + \mathbf{B_1\,u}_n\]
and only the \(\mathbf{B}\) and \(\mathbf{D}\) matrices are modified.
If \(\mathbf{B_{m1}}\) is not None
, the SS is augmented with the new state
\[\mathbf{g}_{n} = \mathbf{u}_{n-1}\]
or, equivalently, with the equation
\[\mathbf{g}_{n+1} = \mathbf{u}_n\]
leading to the new form
\[\begin{split}\mathbf{H}_{n+1} &= \mathbf{A_A\,H}_{n} + \mathbf{B_B\,u}_n \\ \mathbf{y}_n &= \mathbf{C_C\,H}_{n} + \mathbf{D_D\,u}_n\end{split}\]
where \(\mathbf{H} = (\mathbf{x},\,\mathbf{g})\).
param A: | dynamics matrix |
---|---|
type A: | np.ndarray |
param B0: | input matrix for input at current time step n . Set to None if this is zero. |
type B0: | np.ndarray |
param B1: | input matrix for input at time step n+1 (predictor term) |
type B1: | np.ndarray |
param C: | output matrix |
type C: | np.ndarray |
param D: | direct matrix |
type D: | np.ndarray |
param Bm1: | input matrix for input at time step n-1 (delay term) |
type Bm1: | np.ndarray |
returns: | tuple packed with the state-space matrices \(\mathbf{A},\,\mathbf{B},\,\mathbf{C}\) and \(\mathbf{D}\). |
rtype: | tuple |
References
Franklin, GF and Powell, JD. Digital Control of Dynamic Systems, Addison-Wesley Publishing Company, 1980
Warning
functions untested for delays (Bm1 != 0)
Given a time-step ds, and an single input time history u, this SS model returns the output y=[u,du/ds], where du/dt is computed with second order accuracy.
Builds a state-space model of an integrator.
- method: Numerical scheme. Available options are:
- 1tay: 1st order Taylor (fwd)
- I[ii+1,:]=I[ii,:] + ds*F[ii,:]
- trap: I[ii+1,:]=I[ii,:] + 0.5*dx*(F[ii,:]+F[ii+1,:])
Note: other option can be constructured if information on derivative of F is available (for e.g.)
Convert input u or output y of a SS DLTI system through gain matrix K. We have the following transformations: - where=’in’: the input dof of the state-space are changed
u_new -> Kmat*u -> SS -> y => u_new -> SSnew -> y
- where=’out’: the output dof of the state-space are changed
u -> SS -> y -> Kmat*u -> ynew => u -> SSnew -> ynew
- where=’parallel’: the input dofs are changed, but not the output
{u_1 -> SS -> y_1
- { u_2 -> y_2= Kmat*u_2 => u_new=(u_1,u_2) -> SSnew -> y=y_1+y_2
- {y = y_1+y_2
Warning: function not tested for Kmat stored in sparse format
Modify the phase y of a frequency response to remove discontinuities.
Builds a discrete-time state-space representation of a polynomial system whose frequency response has from:
Ypoly[oo,ii](k) = -A2[oo,ii] D2(k) - A1[oo,ii] D1(k) - A0[oo,ii]
where C1,D2 are discrete-time models of first and second derivatives, ds is the time-step and the coefficient matrices are such that:
A{nn}=Acf[oo,ii,nn]
build MIMO butterworth filter of order ord and cut-off freq over Nyquist freq ratio Wn. The filter will have N input and N output and N*ord states.
Note: the state-space form of the digital filter does not depend on the sampling time, but only on the Wn ratio. As a result, this function only returns the A,B,C,D matrices of the filter state-space form.
Assert matrices of state-space models are identical
Couples 2 dlti systems ss01 and ss02 through the gains K12 and K21, where K12 transforms the output of ss02 into an input of ss01.
Other inputs: - out_sparse: if True, the output system is stored as sparse (not recommended)
In-house frequency response function supporting dense/sparse types
Inputs: - SS: instance of ss class, or scipy.signal.StateSpace* - wv: frequency range - dlti: True if discrete-time system is considered.
Outputs: - Yfreq[outputs,inputs,len(wv)]: frequency response over wv
Warnings: - This function may not be very efficient for dense matrices (as A is not reduced to upper Hessenberg form), but can exploit sparsity in the state-space matrices.
Compute natural freq corresponding to eigenvalues, eigs, of a continuous or discrete-time (dlti=True) systems.
Note: if dlti=True, the frequency is normalised by (1./dt), where dt is the DLTI time-step - i.e. the frequency in Hertz is obtained by multiplying fn by (1./dt).
Given a list of state-space models belonging to the ss class, creates a joined system whose output is the sum of the state-space outputs. If wv is not None, this is a list of weights, such that the output is:
y = sum( wv[ii] y_ii )
Ref: equation (4.22) of Benner, P., Gugercin, S. & Willcox, K., 2015. A Survey of Projection-Based Model Reduction Methods for Parametric Dynamical Systems. SIAM Review, 57(4), pp.483–531.
Warning: - system matrices must be numpy arrays - the function does not perform any check!
Join two state-spaces or gain matrices such that, given:
\[\begin{split}\mathbf{u}_1 \longrightarrow &\mathbf{SS}_1 \longrightarrow \mathbf{y}_1 \\ \mathbf{u}_2 \longrightarrow &\mathbf{SS}_2 \longrightarrow \mathbf{y}_2\end{split}\]
we obtain:
\[\mathbf{u} \longrightarrow \mathbf{SS}_{TOT} \longrightarrow \mathbf{y}\]
with \(\mathbf{u}=(\mathbf{u}_1,\mathbf{u}_2)^T\) and \(\mathbf{y}=(\mathbf{y}_1,\mathbf{y}_2)^T\).
The output \(\mathbf{SS}_{TOT}\) is either a gain matrix or a state-space system according to the input \(\mathbf{SS}_1\) and \(\mathbf{SS}_2\)
param SS1: | State space 1 or gain 1 |
---|---|
type SS1: | scsig.StateSpace or np.ndarray |
param SS2: | State space 2 or gain 2 |
type SS2: | scsig.StateSpace or np.ndarray |
returns: | combined state space or gain matrix |
rtype: | scsig.StateSpace or np.ndarray |
Returns the sum (or parallel connection of two systems). Given two state-space models with the same output, but different input:
u1 –> SS01 –> y u2 –> SS02 –> y
Given 2 transformation matrices, (WT,V) of shapes (Nk,self.states) and (self.states,Nk) respectively, this routine returns a projection of the state space ss_here according to:
Anew = WT A V Bnew = WT B Cnew = C V Dnew = D
The projected model has the same number of inputs/outputs as the original one, but Nk states.
Define random system from number of states (Nx), inputs (Nu) and output (Ny).
Given a state-space system, scales the equations such that the original input and output, \(u\) and \(y\), are substituted by \(u_{AD}=\frac{u}{u_{ref}}\) and \(y_{AD}=\frac{y}{y_{ref}}\).
If the original system has form:
\[\begin{split}\mathbf{x}^{n+1} &= \mathbf{A\,x}^n + \mathbf{B\,u}^n \\ \mathbf{y}^{n} &= \mathbf{C\,x}^{n} + \mathbf{D\,u}^n\end{split}\]
the transformation is such that:
\[\begin{split}\mathbf{x}^{n+1} &= \mathbf{A\,x}^n + \mathbf{B}\,\frac{u_{ref}}{x_{ref}}\mathbf{u_{AD}}^n \\ \mathbf{y_{AD}}^{n+1} &= \frac{1}{y_{ref}}(\mathbf{C}\,x_{ref}\,\mathbf{x}^{n+1} + \mathbf{D}\,u_{ref}\,\mathbf{u_{AD}}^n)\end{split}\]
By default, the state-space model is manipulated by reference (byref=True
)
param SSin: | original state-space formulation |
---|---|
type SSin: | scsig.dlti |
param input_scal: | |
input scaling factor \(u_{ref}\). It can be a float or an array, in which case the each element of the input vector will be scaled by a different factor. | |
type input_scal: | |
float or np.ndarray | |
param output_scal: | |
output scaling factor \(y_{ref}\). It can be a float or an array, in which case the each element of the output vector will be scaled by a different factor. | |
type output_scal: | |
float or np.ndarray | |
param state_scal: | |
state scaling factor \(x_{ref}\). It can be a float or an array, in which case the each element of the state vector will be scaled by a different factor. | |
type state_scal: | |
float or np.ndarray | |
param byref: | state space manipulation order |
type byref: | bool |
returns: | scaled state space formulation |
rtype: | scsig.dlti |
Connects two state-space blocks in series. If these are instances of DLTI state-space systems, they need to have the same type and time-step. If the input systems are sparse, they are converted to dense.
The connection is such that:
param SS01: | State Space 1 instance. Can be DLTI/CLTI, dense or sparse. |
---|---|
type SS01: | libss.ss |
param SS02: | State Space 2 instance. Can be DLTI/CLTI, dense or sparse. |
type SS02: | libss.ss |
- Returns
- libss.ss: Combined state space system in series in dense format.
Routine to simulate response to generic input. @warning: this routine is for testing and may lack of robustness. Use
scipy.signal instead.
Wrap state-space models allocation into a single class and support both full and sparse matrices. The class emulates
scipy.signal.ltisys.StateSpaceContinuous scipy.signal.ltisys.StateSpaceDiscretebut supports sparse matrices and other functionalities.
Methods: - get_mats: return matrices as tuple - check_types: check matrices types are supported - freqresp: calculate frequency response over range. - addGain: project inputs/outputs - scale: allows scaling a system
Projects input u or output y the state-space system through the gain matrix K. The input ‘where’ determines whether inputs or outputs are projected as:
- where=’in’: inputs are projected such that:
- u_new -> u=K*u_new -> SS -> y => u_new -> SSnew -> y
- where=’out’: outputs are projected such that:
- u -> SS -> y -> y_new=K*y => u -> SSnew -> ynew
Warning: this is not a wrapper of the addGain method in this module, as the state-space matrices are directly overwritten.
Calculate frequency response over frequencies wv
Note: this wraps frequency response function.
Number of inputs \(m\) to the system.
Returns most unstable eigenvalue
Number of outputs \(p\) of the system.
Given 2 transformation matrices, (WT,V) of shapes (Nk,self.states) and (self.states,Nk) respectively, this routine projects the state space model states according to:
Anew = WT A V Bnew = WT B Cnew = C V Dnew = DThe projected model has the same number of inputs/outputs as the original one, but Nk states.
Given a state-space system, scales the equations such that the original state, input and output, (x, u and y), are substituted by
xad=x/state_scal uad=u/input_scal yad=y/output_scal- The entries input_scal/output_scal/state_scal can be:
- floats: in this case all input/output are scaled by the same value
- lists/arrays of length Nin/Nout: in this case each dof will be scaled
by a different factor
- If the original system has form:
- xnew=A*x+B*u y=C*x+D*u
- the transformation is such that:
- xnew=A*x+(B*uref/xref)*uad yad=1/yref( C*xref*x+D*uref*uad )
Number of states \(n\) of the system.
Retains only the first N states.
State-space model in block form. This class has the same purpose as “ss”, but the A, B, C, D are allocated in the form of nested lists. The format is similar to the one used in numpy.block but:
- Block matrices can contain both dense and sparse matrices
- Empty blocks are defined through None type
Methods: - remove_block: drop one of the blocks from the s-s model - addGain: project inputs/outputs - project: project state
Projects input u or output y the state-space system through the gain block matrix K. The input ‘where’ determines whether inputs or outputs are projected as:
- where=’in’: inputs are projected such that:
- u_new -> u=K*u_new -> SS -> y => u_new -> SSnew -> y
- where=’out’: outputs are projected such that:
- u -> SS -> y -> y_new=K*y => u -> SSnew -> ynew
Input: K must be a list of list of matrices. The size of K must be compatible with either B or C for block matrix product.
Get the size of each block in M.
Given 2 transformation matrices, (W,V) of shape (Nk,self.states), this routine projects the state space model states according to:
Anew = W^T A V Bnew = W^T B Cnew = C V Dnew = DThe projected model has the same number of inputs/outputs as the original one, but Nk states.
Inputs: - WT = W^T - V = V - by_arrays: if True, W, V are either numpy.array or sparse matrices. If
False, they are block matrices.- overwrite: if True, overwrites the A, B, C matrices
Remove a block from either inputs or outputs.
Inputs: - where = {‘in’, ‘out’}: determined whether to remove inputs or outputs - index: index of block to remove
Converts to a scipy.signal linear time invariant system
param ss: | SHARPy state space object |
---|---|
type ss: | libss.ss |
returns: | scipy.signal.dlti |
Given 2 systems or gain matrices (or a combination of the two) having the same amount of input/output, the function returns a gain or state space model summing the two. Namely, given:
u -> SS1 -> y1 u -> SS2 -> y2
- we obtain:
- u -> SStot -> y1+y2 if negative=False
Linear aeroelastic model based on coupled GEBM + UVLM¶
Linear aeroelastic model based on coupled GEBM + UVLM S. Maraniello, Jul 2018
- Future work:
- settings are converted from string to type in __init__ method.
- implement all settings of LinUVLM (e.g. support for sparse matrices)
- When integrating in SHARPy:
- define:
- self.setting_types
- self.setting_default
- use settings.to_custom_types(self.in_dict, self.settings_types, self.settings_default) for conversion to type.
Parameters: - data (sharpy.presharpy.PreSharpy) – main SHARPy data class
- settings_linear (dict) – optional settings file if they are not included in the
data
structure
solver settings for the linearised aeroelastic solution
Type: dict
linearised geometrically exact beam model
Type: lingebm.FlexDynamic
number of structural degrees of freedom
Type: int
number of rigid degrees of freedom
Type: int
number of flexible degrees of freedom (
num_dof_flex+num_dof_rigid=num_dof_str
)Type: int
linearised UVLM class
Type: linuvlm.Dynamic
aerodynamic state timestep info
Type: sharpy.utils.datastructures.AeroTimeStepInfo
structural state timestep info
Type: sharpy.utils.datastructures.StructTimeStepInfo
time increment
Type: float
corresponding vector of displacements of dimensions
[1, num_dof_str]
Type: np.array
time derivative (\(\dot{\mathbf{q}}\)) of the corresponding vector of displacements with dimensions
[1, num_dof_str]
Type: np.array
state space formulation (discrete or continuous time), as selected by the user
Type: scipy.signal
Assemble State Space formulation
- Provides:
- the gain matrices required to connect the linearised GEBM and UVLM
inputs/outputs- the stiffening and damping factors to be added to the linearised
GEBM equations in order to account for non-zero aerodynamic loads at the linearisation point.
The function produces the gain matrices:
Kdisp
: gains from GEBM to UVLM grid displacementsKvel_disp
: influence of GEBM dofs displacements to UVLM grid velocities.Kvel_vel
: influence of GEBM dofs displacements to UVLM grid displacements.Kforces
(UVLM->GEBM) dimensions are the transpose than the
Kdisp and Kvel* matrices. Hence, when allocation this term,
ii
andjj
indices will unintuitively refer to columns and rows, respectively.And the stiffening/damping terms accounting for non-zero aerodynamic forces at the linearisation point:
Kss
: stiffness factor (flexible dof -> flexible dof) accounting
for non-zero forces at the linearisation point. -
Csr
: damping factor (rigid dof -> flexible dof) -Crs
: damping factor (flexible dof -> rigid dof) -Crr
: damping factor (rigid dof -> rigid dof)Stiffening and damping related terms due to the non-zero aerodynamic forces at the linearisation point:
\[\mathbf{F}_{A,n} = C^{AG}(\mathbf{\chi})\sum_j \mathbf{f}_{G,j} \rightarrow \delta\mathbf{F}_{A,n} = C^{AG}_0 \sum_j \delta\mathbf{f}_{G,j} + \frac{\partial}{\partial\chi}(C^{AG}\sum_j \mathbf{f}_{G,j}^0)\delta\chi\]The term multiplied by the variation in the quaternion, \(\delta\chi\), couples the forces with the rigid body equations and becomes part of \(\mathbf{C}_{sr}\).
Similarly, the linearisation of the moments results in expression that contribute to the stiffness and damping matrices.
\[\mathbf{M}_{B,n} = \sum_j \tilde{X}_B C^{BA}(\Psi)C^{AG}(\chi)\mathbf{f}_{G,j}\]\[\delta\mathbf{M}_{B,n} = \sum_j \tilde{X}_B\left(C_0^{BG}\delta\mathbf{f}_{G,j} + \frac{\partial}{\partial\Psi}(C^{BA}\delta\mathbf{f}^0_{A,j})\delta\Psi + \frac{\partial}{\partial\chi}(C^{BA}_0 C^{AG} \mathbf{f}_{G,j})\delta\chi\right)\]The linearised equations of motion for the geometrically exact beam model take the input term \(\delta \mathbf{Q}_n = \{\delta\mathbf{F}_{A,n},\, T_0^T\delta\mathbf{M}_{B,n}\}\), which means that the moments should be provided as \(T^T(\Psi)\mathbf{M}_B\) instead of \(\mathbf{M}_A = C^{AB}\mathbf{M}_B\), where \(T(\Psi)\) is the tangential operator.
\[\delta(T^T\mathbf{M}_B) = T^T_0\delta\mathbf{M}_B + \frac{\partial}{\partial\Psi}(T^T\delta\mathbf{M}_B^0)\delta\Psi\]is the linearised expression for the moments, where the first term would correspond to the input terms to the beam equations and the second arises due to the non-zero aerodynamic moment at the linearisation point and must be subtracted (since it comes from the forces) to form part of \(\mathbf{K}_{ss}\). In addition, the \(\delta\mathbf{M}_B\) term depends on both \(\delta\Psi\) and \(\delta\chi\), therefore those terms would also contribute to \(\mathbf{K}_{ss}\) and \(\mathbf{C}_{sr}\), respectively.
The contribution from the total forces and moments will be accounted for in \(\mathbf{C}_{rr}\) and \(\mathbf{C}_{rs}\).
\[\delta\mathbf{F}_{tot,A} = \sum_n\left(C^{GA}_0 \sum_j \delta\mathbf{f}_{G,j} + \frac{\partial}{\partial\chi}(C^{AG}\sum_j \mathbf{f}_{G,j}^0)\delta\chi\right)\]Therefore, after running this method, the beam matrices should be updated as:
>>> K_beam[:flex_dof, :flex_dof] += Kss >>> C_beam[:flex_dof, -rigid_dof:] += Csr >>> C_beam[-rigid_dof:, :flex_dof] += Crs >>> C_beam[-rigid_dof:, -rigid_dof:] += Crr
Track body option
The
track_body
setting restricts the UVLM grid to linear translation motions and therefore should be used to ensure that the forces are computed using the reference linearisation frame.The UVLM and beam are linearised about a reference equilibrium condition. The UVLM is defined in the inertial reference frame while the beam employs the body attached frame and therefore a projection from one frame onto another is required during the coupling process.
However, the inputs to the UVLM (i.e. the lattice grid coordinates) are obtained from the beam deformation which is expressed in A frame and therefore the grid coordinates need to be projected onto the inertial frame
G
. As the beam rotates, the projection onto theG
frame of the lattice grid coordinates will result in a grid that is not coincident with that at the linearisation reference and therefore the grid coordinates must be projected onto the original frame, which will be referred to asU
. The transformation between the inertial frameG
and theU
frame is a function of the rotation of theA
frame and the original position:\[C^{UG}(\chi) = C^{GA}(\chi_0)C^{AG}(\chi)\]Therefore, the grid coordinates obtained in
A
frame and projected onto theG
frame can be transformed to theU
frame using\[\zeta_U = C^{UG}(\chi) \zeta_G\]which allows the grid lattice coordinates to be projected onto the original linearisation frame.
In a similar fashion, the output lattice vertex forces of the UVLM are defined in the original linearisation frame
U
and need to be transformed onto the inertial frameG
prior to projecting them onto theA
frame to use them as the input forces to the beam system.\[\boldsymbol{f}_G = C^{GU}(\chi)\boldsymbol{f}_U\]The linearisation of the above relations lead to the following expressions that have to be added to the coupling matrices:
Kdisp_vel
terms:\[\delta\boldsymbol{\zeta}_U= C^{GA}_0 \frac{\partial}{\partial \boldsymbol{\chi}} \left(C^{AG}\boldsymbol{\zeta}_{G,0}\right)\delta\boldsymbol{\chi} + \delta\boldsymbol{\zeta}_G\]Kvel_vel
terms:\[\delta\dot{\boldsymbol{\zeta}}_U= C^{GA}_0 \frac{\partial}{\partial \boldsymbol{\chi}} \left(C^{AG}\dot{\boldsymbol{\zeta}}_{G,0}\right)\delta\boldsymbol{\chi} + \delta\dot{\boldsymbol{\zeta}}_G\]
The transformation of the forces and moments introduces terms that are functions of the orientation and are included as stiffening and damping terms in the beam’s matrices:
Csr
damping terms relating to translation forces:\[C_{sr}^{tra} -= \frac{\partial}{\partial\boldsymbol{\chi}} \left(C^{GA} C^{AG}_0 \boldsymbol{f}_{G,0}\right)\delta\boldsymbol{\chi}\]Csr
damping terms related to moments:\[C_{sr}^{rot} -= T^\top\widetilde{\mathbf{X}}_B C^{BG} \frac{\partial}{\partial\boldsymbol{\chi}} \left(C^{GA} C^{AG}_0 \boldsymbol{f}_{G,0}\right)\delta\boldsymbol{\chi}\]
The
track_body
setting.When
track_body
is enabled, the UVLM grid is no longer coincident with the inertial reference frame throughout the simulation but rather it is able to rotate as theA
frame rotates. This is to simulate a free flying vehicle, where, for instance, the orientation does not affect the aerodynamics. The UVLM defined in this frame of reference, namedU
, satisfies the following convention:- The
U
frame is coincident with theG
frame at the time of linearisation. - The
U
frame rotates as theA
frame rotates.
Transformations related to the
U
frame of reference:The angle between the
U
frame and theA
frame is always constant and equal to \(\boldsymbol{\Theta}_0\).The angle between the
A
frame and theG
frame is \(\boldsymbol{\Theta}=\boldsymbol{\Theta}_0 + \delta\boldsymbol{\Theta}\)The projection of a vector expressed in the
G
frame onto theU
frame is expressed by:\[\boldsymbol{v}^U = C^{GA}_0 C^{AG} \boldsymbol{v}^G\]The reverse, a projection of a vector expressed in the
U
frame onto theG
frame, is expressed by\[\boldsymbol{v}^U = C^{GA} C^{AG}_0 \boldsymbol{v}^U\]
The effect this has on the aeroelastic coupling between the UVLM and the structural dynamics is that the orientation and change of orientation of the vehicle has no effect on the aerodynamics. The aerodynamics are solely affected by the contribution of the 6-rigid body velocities (as well as the flexible DOFs velocities).
Reshape structural input in a column vector
Utilities functions for linear analysis¶
Utilities functions for linear analysis
Summarise info about a data point
Compute total force with exact displacements
Extract relevant info from data structure. If assemble is True, it will also generate a linear UVLM and the displacements/velocities gain matrices
Given 2 Info() classes associated to a reference linearisation point Ref and a perturbed state Pert, the method produces in output the prediction at the Pert state of a linearised model.
The solution is carried on using both the aero and beam input
Linear beam model class¶
Linear beam model class
S. Maraniello, Aug 2018 N. Goizueta
Define class for linear state-space realisation of GEBM flexible-body equations from SHARPy``timestep_info`` class and with the nonlinear structural information.
The linearised beam takes the following arguments:
Parameters: - tsinfo (sharpy.utils.datastructures.StructImeStepInfo) – Structural timestep containing the modal information
- structure (sharpy.solvers.beamloader.Beam) – Beam class with the structural information
- custom_settings (dict) – settings for the linearised beam
State-space models can be defined in continuous or discrete time (dt required). Modal projection, either on the damped or undamped modal shapes, is also avaiable. The rad/s array wv can be optionally passed for freq. response analysis
To produce the state-space equations:
- Set the settings:
modal_projection={True,False}
: determines whether to project the statesonto modal coordinates. Projection over damped or undamped modal shapes can be obtained selecting:
proj_modes={'damped','undamped'}
while
inout_coords={'modes','nodal'}
determines whether the modal state-space inputs/outputs are modal coords or nodal degrees-of-freedom. If
modes
is selected, theKin
andKout
gain matrices are generated to transform nodal to modal dofs
dlti={True,False}
: if true, generates discrete-time system.The continuous to discrete transformation method is determined by:
discr_method={ 'newmark', # Newmark-beta 'zoh', # Zero-order hold 'bilinear'} # Bilinear (Tustin) transformation
DLTIs can be obtained directly using the Newmark-\(\beta\) method
discr_method='newmark'
newmark_damp=xx
withxx<<1.0
for full-states descriptions (
modal_projection=False
) and modal projection over the undamped structural modes (modal_projection=True
andproj_modes
). The Zero-order holder and bilinear methods, instead, work in all descriptions, but require the continuous state-space equations.
Generate an instance of the beam
2. Run
self.assemble()
. The method accepts an additional parameter,Nmodes
, which allows using a lower number of modes than specified inself.Nmodes
Examples
>>> beam_settings = {'modal_projection': True, >>> 'inout_coords': 'modes', >>> 'discrete_time': False, >>> 'proj_modes': 'undamped', >>> 'use_euler': True} >>> >>> beam = lingebm.FlexDynamic(tsstruct0, structure=data.structure, custom_settings=beam_settings) >>> >>> beam.assemble()
Notes
- Modal projection will automatically select between damped/undamped modes shapes, based on the data available from tsinfo.
- If the full system matrices are available, use the modal_sol methods to override mode-shapes and eigenvectors
Assemble state-space model
Several assembly options are available:
- Discrete-time, Newmark-\(\beta\):
Modal projection onto undamped modes. It uses the modal projection such that the generalised coordinates \(\eta\) are transformed into modal space by
\[\mathbf{\eta} = \mathbf{\Phi\,q}\]where \(\mathbf{\Phi}\) are the first
Nmodes
right eigenvectors. Therefore, the equation of motion can be re-written such that the modes normalise the mass matrix to become the identity matrix.\[\mathbf{I_{Nmodes}}\mathbf{\ddot{q}} + \mathbf{\Lambda_{Nmodes}\,q} = 0\]The system is then assembled in Newmark-\(\beta\) form as detailed in
newmark_ss()
Full size system assembly. No modifications are made to the mass, damping or stiffness matrices and the system is directly assembled by
newmark_ss()
.
Continuous time state-space
Parameters: Nmodes (int) – number of modes to retain
Convert continuous-time SS model into
Determine number of modes required to achieve a certain convergence of the modal solution in a prescribed frequency range
wv
. The H-infinity norm of the error w.r.t.Yref
is used for assessing convergence.Warning
if a reference freq. response, Yref, is not provided, the full- state continuous-time frequency response is used as reference. This requires the full-states matrices
Mstr
,Cstr
,Kstr
to be available.
Introduce the linearised Euler propagation equations that relate the body fixed angular velocities to the Earth fixed Euler angles.
This method will remove the quaternion propagation equations created by SHARPy; the resulting system will have 9 rigid degrees of freedom.
Parameters: tsstr – Returns:
Computes the frequency response of the current state-space model. If
self.modal=True
, the in/out are determined according toself.inout_coords
Linearises gravity forces and includes the resulting terms in the C and K matrices. The method takes the linearisation condition (optional argument), linearises and updates:
- Stiffness matrix
- Damping matrix
- Modal damping matrix
The method works for both the quaternion and euler angle orientation parametrisation.
Parameters: tsstr (sharpy.utils.datastructures.StructTimeStepInfo) – Structural timestep at the linearisation point Notes
The gravity forces are linearised to express them in terms of the beam formulation input variables:
- Nodal forces: \(\delta \mathbf{f}_A\)
- Nodal moments: \(\delta(T^T \mathbf{m}_B)\)
- Total forces (rigid body equations): \(\delta \mathbf{F}_A\)
- Total moments (rigid body equations): \(\delta \mathbf{M}_A\)
Gravity forces are naturally expressed in
G
(inertial) frame\[\mathbf{f}_{G,0} = \mathbf{M\,g}\]where the \(\mathbf{M}\) is the tangent mass matrix obtained at the linearisation reference.
To obtain the gravity forces expressed in A frame we make use of the projection matrices
\[\mathbf{f}_A = C^{AG}(\boldsymbol{\chi}) \mathbf{f}_{G,0}\]that projects a vector in the inertial frame
G
onto the body attached frameA
.The projection of a vector can then be linearised as
\[\delta \mathbf{f}_A = C^{AG} \delta \mathbf{f}_{G,0} + \frac{\partial}{\partial \boldsymbol{\chi}}(C^{AG} \mathbf{f}_{G,0}) \delta\boldsymbol{\chi}.\]Nodal forces:
The linearisation of the gravity forces acting at each node is simply
\[\delta \mathbf{f}_A = + \frac{\partial}{\partial \boldsymbol{\chi}}(C^{AG} \mathbf{f}_{G,0}) \delta\boldsymbol{\chi}\]where it is assumed that \(\delta\mathbf{f}_G = 0\).
Nodal moments:
The gravity moments can be expressed in the local node frame of reference
B
by\[\mathbf{m}_B = \tilde{X}_{B,CG}C^{BA}(\Psi)C^{AG}(\boldsymbol{\chi})\mathbf{f}_{G,0}\]The linearisation is given by:
\[\delta \mathbf{m}_B = \tilde{X}_{B,CG} \left(\frac{\partial}{\partial\Psi}(C^{BA}\mathbf{f}_{A,0})\delta\Psi + C^{BA}\frac{\partial}{\partial\boldsymbol{\chi}}(C^{AG}\mathbf{f}_{G,0})\delta\boldsymbol{\chi}\right)\]However, recall that the input moments are defined in tangential space \(\delta(T^\top\mathbf{m}_B)\) whose linearised expression is
\[\delta(T^T(\Psi) \mathbf{m}_B) = T_0^T \delta \mathbf{m}_B + \frac{\partial}{\partial \Psi}(T^T \mathbf{m}_{B,0})\delta\Psi\]where the \(\delta \mathbf{m}_B\) term has been defined above.
Total forces:
The total forces include the contribution from all flexible degrees of freedom as well as the gravity forces arising from the mass at the clamped node
\[\mathbf{F}_A = \sum_n \mathbf{f}_A + \mathbf{f}_{A,clamped}\]which becomes
\[\delta \mathbf{F}_A = \sum_n \delta \mathbf{f}_A + \frac{\partial}{\partial\boldsymbol{\chi}}\left(C^{AG}\mathbf{f}_{G,clamped}\right) \delta\boldsymbol{\chi}.\]Total moments:
The total moments, as opposed to the nodal moments, are expressed in A frame and again require the addition of the moments from the flexible structural nodes as well as the ones from the clamped node itself.
\[\mathbf{M}_A = \sum_n \tilde{X}_{A,n}^{CG} C^{AG} \mathbf{f}_{n,G} + \tilde{X}_{A,clamped}C^{AG}\mathbf{f}_{G, clamped}\]where \(X_{A,n}^{CG} = R_{A,n} + C^{AB}(\Psi)X_{B,n}^{CG}\). Its linearised form is
\[\delta X_{A,n}^{CG} = \delta R_{A,n} + \frac{\partial}{\partial \Psi}(C^{AB} X_{B,CG})\delta\Psi\]Therefore, the overall linearisation of the total moment is defined as
\[\delta \mathbf{M}_A = \tilde{X}_{A,total}^{CG} \frac{\partial}{\partial \boldsymbol{\chi}}(C^{AG}\mathbf{F}_{G, total}) \delta \boldsymbol{\chi} -\sum_n \tilde{C}^{AG}\mathbf{f}_{G,0} \delta X_{A,n}^{CG}\]where \(X_{A, total}\) is the centre of gravity of the entire system expressed in
A
frame and \(\mathbf{F}_{G, total}\) are the gravity forces of the overall system inG
frame, including the contributions from the clamped node.
The linearisation introduces damping and stiffening terms since the \(\delta\boldsymbol{\chi}\) and \(\delta\boldsymbol{\Psi}\) terms are found in the damping and stiffness matrices respectively.
Therefore, the beam matrices need updating to account for these terms:
Terms from the linearisation of the nodal moments will be assembled in the rows corresponding to moment equations and columns corresponding to the cartesian rotation vector
\[K_{ss}^{m,\Psi} \leftarrow -T_0^T \tilde{X}_{B,CG} \frac{\partial}{\partial\Psi}(C^{BA}\mathbf{f}_{A,0}) -\frac{\partial}{\partial \Psi}(T^T \mathbf{m}_{B,0})\]Terms from the linearisation of the translation forces with respect to the orientation are assembled in the damping matrix, the rows corresponding to translational forces and columns to orientation degrees of freedom
\[C_{sr}^{f,\boldsymbol{\chi}} \leftarrow - \frac{\partial}{\partial \boldsymbol{\chi}}(C^{AG} \mathbf{f}_{G,0})\]Terms from the linearisation of the moments with respect to the orientation are assembled in the damping matrix, with the rows correspondant to the moments and the columns to the orientation degrees of freedom
\[C_{sr}^{m,\boldsymbol{\chi}} \leftarrow - T_0^T\tilde{X}_{B,CG}C^{BA}\frac{\partial}{\partial\boldsymbol{\chi}}(C^{AG}\mathbf{f}_{G,0})\]Terms from the linearisation of the total forces with respect to the orientation correspond to the rigid body equations in the damping matrix, the rows to the translational forces and columns to the orientation
\[C_{rr}^{F,\boldsymbol{\chi}} \leftarrow - \sum_n \frac{\partial}{\partial \boldsymbol{\chi}}(C^{AG} \mathbf{f}_{G,0})\]Terms from the linearisation of the total moments with respect to the orientation correspond to the rigid body equations in the damping matrix, the rows to the moments and the columns to the orientation
\[C_{rr}^{M,\boldsymbol{\chi}} \leftarrow - \sum_n\tilde{X}_{A,n}^{CG} \frac{\partial}{\partial \boldsymbol{\chi}}(C^{AG}\mathbf{f}_{G,0})\]Terms from the linearisation of the total moments with respect to the nodal position \(R_A\) are included in the stiffness matrix, the rows corresponding to the moments in the rigid body equations and the columns to the nodal position
\[K_{rs}^{M,R} \leftarrow + \sum_n \tilde{\mathbf{f}_{A,0}}\]Terms from the linearisation of the total moments with respect to the cartesian rotation vector are included in the stiffness matrix, the rows corresponding to the moments in the rigid body equations and the columns to the cartesian rotation vector
\[K_{rs}^{M, \Psi} \leftarrow + \sum_n \tilde{\mathbf{f}_{A,0}}\frac{\partial}{\partial \Psi}(C^{AB} X_{B,CG})\]
Reshape structural input in a column vector
Scale the system with a normalised time step. The resulting time step is \(\Delta t = \Delta \bar{t}/t_{ref}\), where the over bar denotes dimensional time. The structural equations of motion are rescaled as:
\[\mathbf{M}\ddot{\boldsymbol{\eta}} + \mathbf{C} t_{ref} \dot{\boldsymbol{\eta}} + \mathbf{K} t_{ref}^2 \boldsymbol{\eta} = t_{ref}^2 \mathbf{N}\]For aeroelastic applications, the reference time is usually defined using the semi-chord, \(b\), and the free stream velocity, \(U_\infty\).
\[t_{ref,ae} = \frac{b}{U_\infty}\]Parameters: time_ref (float) – Normalisation factor such that \(t/\bar{t}\) is non-dimensional.
Tune artifical damping to achieve a percent reduction of the lower frequency (lower damped) mode
Re-projects the full-states continuous-time structural dynamics equations
\[\mathbf{M}\,\mathbf{\ddot{x}} +\mathbf{C}\,\mathbf{\dot{x}} + \mathbf{K\,x} = \mathbf{F}\]onto modal space. The modes used to project are controlled through the
self.proj_modes={damped or undamped}
attribute.Warning
This method overrides SHARPy
timestep_info
results and requiresMstr
,Cstr
,Kstr
to be available.
Updates the system to the specified number of modes
Parameters: nmodes – Returns:
Produces a discrete-time state-space model of the structural equations
based on the Newmark-\(\beta\) integration scheme. The output state-space model has form:
with \(\mathbf{X} = [\mathbf{x}, \mathbf{\dot{x}}]^T\)
Note that as the state-space representation only requires the input force \(\mathbf{F}\) to be evaluated at time-step \(n\),the \(\mathbf{C}\) and \(\mathbf{D}\) matrices are, in general, fully populated.
The Newmark-\(\beta\) integration scheme is carried out following the modifications presented by Geradin [1] that render it unconditionally stable. The displacement and velocities are estimated as:
The stencil is unconditionally stable if the tuning parameters \(\theta_1\) and \(\theta_2\) are chosen as:
where \(\alpha>0\) accounts for small positive algorithmic damping.
The following steps describe how to apply the Newmark-beta scheme to a state-space formulation. The original idea is based on [1].
The equation of a second order system dynamics reads:
Applying that equation to the time steps \(n\) and \(n+1\), rearranging terms and multiplying by \(M^{-1}\):
The relations of the Newmark-beta scheme are:
Substituting the former relation onto the later ones, rearranging terms, and writing it in state-space form:
To understand SHARPy code, it is convenient to apply the following change of notation:
Finally:
To finally isolate the vector at \(n+1\), instead of inverting the \(A_{ss1}\) matrix, several systems are solved. Moreover, the output equation is simply \(y=x\).
param Minv: | Inverse mass matrix \(\mathbf{M^{-1}}\) |
---|---|
type Minv: | np.array |
param C: | Damping matrix \(\mathbf{C}\) |
type C: | np.array |
param K: | Stiffness matrix \(\mathbf{K}\) |
type K: | np.array |
param dt: | Timestep increment |
type dt: | float |
param num_damp: | Numerical damping. Default 1e-4 |
type num_damp: | float |
returns: | the A, B, C, D matrices of the state space packed in a tuple with the predictor and delay term removed. |
rtype: | tuple |
References
[1] - Geradin M., Rixen D. - Mechanical Vibrations: Theory and application to structural dynamics
sort by magnitude (frequency) and imaginary part if complex conj
Linearise UVLM solver¶
Linearise UVLM solver S. Maraniello, 7 Jun 2018
Class for dynamic linearised UVLM solution. Linearisation around steady-state are only supported. The class is built upon Static, and inherits all the methods contained there.
- Input:
tsdata: aero timestep data from SHARPy solution
dt: time-step
integr_order=2: integration order for UVLM unsteady aerodynamic force
RemovePredictor=True: if true, the state-space model is modified so as to accept in input perturbations, u, evaluated at time-step n rather than n+1.
ScalingDict=None: disctionary containing fundamental reference units:
{'length': reference_length, 'speed': reference_speed, 'density': reference density}
used to derive scaling quantities for the state-space model variables. The scaling factors are stored in
self.ScalingFact
.Note that while time, circulation, angular speeds) are scaled accordingly, FORCES ARE NOT. These scale by \(q_\infty b^2\), where \(b\) is the reference length and \(q_\infty\) is the dynamic pressure.
UseSparse=False: builds the A and B matrices in sparse form. C and D are dense anyway so the sparse format cannot be applied to them.
-
- nondimss
normalises a dimensional state-space model based on the scaling factors in self.ScalingFact.
-
- dimss
inverse of nondimss.
-
- assemble_ss
builds state-space model. See function for more details.
-
- assemble_ss_profiling
generate profiling report of the assembly and saves it into self.prof_out. To read the report:
import pstats p = pstats.Stats(self.prof_out)
-
- solve_steady
solves for the steady state. Several methods available.
-
- solve_step
solves one time-step
-
- freqresp
ad-hoc method for fast frequency response (only implemented) for
remove_predictor=False
Number of states
Type: int
Number of inputs
Type: int
Number of outputs
Type: int
Number of paneles \(K = MN\)
Type: int
Number of wake panels \(K^*=M^*N\)
Type: int
Number of panel vertices \(K_\zeta=(M+1)(N+1)\)
Type: int
Number of wake panel vertices \(K_{\zeta,w} = (M^*+1)(N+1)\)
Type: int
To do: Upgrade to linearise around unsteady snapshot (adjoint)
-
Nu
Number of inputs \(m\) to the system.
-
Nx
Number of states \(n\) of the system.
-
Ny
Number of outputs \(p\) of the system.
Produces state-space model of the form
\[\begin{split}\mathbf{x}_{n+1} &= \mathbf{A}\,\mathbf{x}_n + \mathbf{B} \mathbf{u}_{n+1} \\ \mathbf{y}_n &= \mathbf{C}\,\mathbf{x}_n + \mathbf{D} \mathbf{u}_n\end{split}\]where the state, inputs and outputs are:
\[\mathbf{x}_n = \{ \delta \mathbf{\Gamma}_n,\, \delta \mathbf{\Gamma_{w_n}},\, \Delta t\,\delta\mathbf{\Gamma}'_n,\, \delta\mathbf{\Gamma}_{n-1} \}\]\[\mathbf{u}_n = \{ \delta\mathbf{\zeta}_n,\, \delta\mathbf{\zeta}'_n,\, \delta\mathbf{u}_{ext,n} \}\]\[\mathbf{y} = \{\delta\mathbf{f}\}\]with \(\mathbf{\Gamma}\in\mathbb{R}^{MN}\) being the vector of vortex circulations, \(\mathbf{\zeta}\in\mathbb{R}^{3(M+1)(N+1)}\) the vector of vortex lattice coordinates and \(\mathbf{f}\in\mathbb{R}^{3(M+1)(N+1)}\) the vector of aerodynamic forces and moments. Note that \((\bullet)'\) denotes a derivative with respect to time.
Note that the input is atypically defined at time
n+1
, therefore by defaultself.remove_predictor = True
and the predictor termu_{n+1}
is eliminated through the change of state[1]:\[\begin{split}\mathbf{h}_n &= \mathbf{x}_n - \mathbf{B}\,\mathbf{u}_n \\\end{split}\]such that:
\[\begin{split}\mathbf{h}_{n+1} &= \mathbf{A}\,\mathbf{h}_n + \mathbf{A\,B}\,\mathbf{u}_n \\ \mathbf{y}_n &= \mathbf{C\,h}_n + (\mathbf{C\,B}+\mathbf{D})\,\mathbf{u}_n\end{split}\]which only modifies the equivalent \(\mathbf{B}\) and \(\mathbf{D}\) matrices.
References
[1] Franklin, GF and Powell, JD. Digital Control of Dynamic Systems, Addison-Wesley Publishing Company, 1980
To do: - remove all calls to scipy.linalg.block_diag
Generate profiling report for assembly and save it in self.prof_out.
- To read the report:
- import pstats p=pstats.Stats(self.prof_out)
Low-rank method for frequency limited balancing. The Observability ad controllability Gramians over the frequencies kv are solved in factorised form. Balancd modes are then obtained with a square-root method.
Details:
Observability and controllability Gramians are solved in factorised form through explicit integration. The number of integration points determines both the accuracy and the maximum size of the balanced model.
Stability over all (Nb) balanced states is achieved if:
- one of the Gramian is integrated through the full Nyquist range
- the integration points are enough.
Note, however, that even when stability is not achieved over the full balanced states, stability of the balanced truncated model with Ns<=Nb states is normally observed even when a low number of integration points is used. Two integration methods (trapezoidal rule on uniform grid and Gauss-Legendre quadrature) are provided.
Input:
DictBalFreq: dictionary specifying integration method with keys:
frequency
: defines limit frequencies for balancing. The balanced model will be accurate in the range [0,F], where F is the value of this key. Note that F units must be consistent with the units specified in the self.ScalingFacts dictionary.method_low
: [‘gauss’,’trapz’] specifies whether to use gauss quadrature or trapezoidal rule in the low-frequency range [0,F]options_low
: options to use for integration in the low-frequencies. These depend on the integration scheme (See below).method_high
: method to use for integration in the range [F,F_N], where F_N is the Nyquist frequency. See ‘method_low’.options_high
: options to use for integration in the high-frequencies.check_stability
: if True, the balanced model is truncated to eliminate unstable modes - if any is found. Note that very accurate balanced model can still be obtained, even if high order modes are unstable. Note that this option is overridden if “”get_frequency_response
: if True, the function also returns the frequency response evaluated at the low-frequency range integration points. If True, this option also allows to automatically tune the balanced model.
Future options:
truncation_tolerance
: ifget_frequency_response
is True, allows to truncate the balanced model so as to achieved a prescribed tolerance in the low-frequwncy range.Ncpu
: for parallel run
The following integration schemes are available:
trapz
: performs integration over equally spaced points using trapezoidal rule. It accepts options dictionaries with keys:points
: number of integration points to use (including domain boundary)
gauss
performs gauss-lobotto quadrature. The domain can be partitioned in Npart sub-domain in which the gauss-lobotto quadrature of order Ord can be applied. A total number of Npart*Ord points is required. It accepts options dictionaries of the form:partitions
: number of partitionsorder
: quadrature order.
Example:
The following dictionary
DictBalFreq={ 'frequency': 1.2, 'method_low': 'trapz', 'options_low': {'points': 12}, 'method_high': 'gauss', 'options_high': {'partitions': 2, 'order': 8}, 'check_stability': True }
balances the state-space model self.SS in the frequency range [0, 1.2] using
- 12 equally-spaced points integration of the Gramians in the low-frequency range [0,1.2] and
- a 2 Gauss-Lobotto 8-th order quadratures of the controllability Gramian in the high-frequency range.
A total number of 28 integration points will be required, which will result into a balanced model with number of states
min{2*28* number_inputs, 2*28* number_outputs}
The model is finally truncated so as to retain only the first Ns stable modes.
Generate profiling report for balfreq function and saves it into
self.prof_out.
The function also returns apstats.Stats
object.- To read the report:
import pstats p=pstats.Stats(self.prof_out).sort_stats('cumtime') p.print_stats(20)
Ad-hoc method for fast UVLM frequency response over the frequencies kv. The method, only requires inversion of a K x K matrix at each frequency as the equation for propagation of wake circulation are solved exactly. The algorithm implemented here can be used also upon projection of the state-space model.
Note: This method is very similar to the “minsize” solution option is the steady_solve.
Produces a sparse matrix
\[\bar{\mathbf{C}}(z)\]where
\[z = e^{k \Delta t}\]such that the wake circulation frequency response at \(z\) is
\[\bar{\boldsymbol{\Gamma}}_w = \bar{\mathbf{C}}(z) \bar{\mathbf{\Gamma}}\]
Scale state-space model based of self.ScalingFacts
Steady state solution from state-space model.
Warning: these methods are less efficient than the solver in Static class, Static.solve, and should be used only for verification purposes. The “minsize” method, however, guarantees the inversion of a K x K matrix only, similarly to what is done in Static.solve.
Solve step.
If the predictor term has not been removed (
remove_predictor = False
) then the system is solved as:\[\begin{split}\mathbf{x}^{n+1} &= \mathbf{A\,x}^n + \mathbf{B\,u}^n \\ \mathbf{y}^{n+1} &= \mathbf{C\,x}^{n+1} + \mathbf{D\,u}^n\end{split}\]Else, if
remove_predictor = True
, the state is modified as\[\mathbf{h}^n = \mathbf{x}^n - \mathbf{B\,u}^n\]And the system solved by:
\[\begin{split}\mathbf{h}^{n+1} &= \mathbf{A\,h}^n + \mathbf{B_{mod}\,u}^{n} \\ \mathbf{y}^{n+1} &= \mathbf{C\,h}^{n+1} + \mathbf{D_{mod}\,u}^{n+1}\end{split}\]Finally, the original state is recovered using the reverse transformation:
\[\mathbf{x}^{n+1} = \mathbf{h}^{n+1} + \mathbf{B\,u}^{n+1}\]where the modifications to the \(\mathbf{B}_{mod}\) and \(\mathbf{D}_{mod}\) are detailed in
Dynamic.assemble_ss()
.Notes
Although the original equations include the term \(\mathbf{u}_{n+1}\), it is a reasonable approximation to take \(\mathbf{u}_{n+1}\approx\mathbf{u}_n\) given a sufficiently small time step, hence if the input at time
n+1
is not parsed, it is estimated from \(u^n\).Parameters: - x_n (np.array) – State vector at the current time step \(\mathbf{x}^n\)
- u_n (np.array) – Input vector at time step \(\mathbf{u}^n\)
- u_n1 (np.array) – Input vector at time step \(\mathbf{u}^{n+1}\)
- transform_state (bool) – When the predictor term is removed, if true it will transform the state vector. If false it will be assumed that the state vector that is parsed is already transformed i.e. it is \(\mathbf{h}\).
Returns: Updated state and output vector packed in a tuple \((\mathbf{x}^{n+1},\,\mathbf{y}^{n+1})\)
Return type: Tuple
Notes
- To speed-up the solution and use minimal memory:
- solve for bound vorticity (and)
- propagate the wake
- compute the output separately.
Unpacks the state vector into physical constituents for full order models.
The state vector \(\mathbf{x}\) of the form
\[\mathbf{x}_n = \{ \delta \mathbf{\Gamma}_n,\, \delta \mathbf{\Gamma_{w_n}},\, \Delta t\,\delta\mathbf{\Gamma}'_n,\, \delta\mathbf{\Gamma}_{n-1} \}\]Is unpacked into:
\[{\delta \mathbf{\Gamma}_n,\, \delta \mathbf{\Gamma_{w_n}},\, \,\delta\mathbf{\Gamma}'_n}\]Parameters: xvec (np.ndarray) – State vector Returns: Column vectors for bound circulation, wake circulation and circulation derivative packed in a tuple. Return type: tuple
Class for dynamic linearised UVLM solution. Linearisation around steady-state are only supported.
The class is a low-memory implementation of Dynamic, and inherits most of the methods contained there. State-space models are allocated in list-block form (as per numpy.block) to minimise memory usage. This class provides lower memory / computational time assembly, frequency response and frequency limited balancing.
Input:
tsdata: aero timestep data from SHARPy solution
dt: time-step
integr_order=2: integration order for UVLM unsteady aerodynamic force
RemovePredictor=True: if true, the state-space model is modified so as to accept in input perturbations, u, evaluated at time-step n rather than n+1.
ScalingDict=None: disctionary containing fundamental reference units
>>> {'length': reference_length, 'speed': reference_speed, 'density': reference density}
used to derive scaling quantities for the state-space model variables. The scaling factors are stores in
self.ScalingFact
.Note that while time, circulation, angular speeds) are scaled accordingly, FORCES ARE NOT. These scale by qinf*b**2, where b is the reference length and qinf is the dinamic pressure.
UseSparse=False: builds the A and B matrices in sparse form. C and D are dense, hence the sparce format is not used.
-
- nondimss
normalises a dimensional state-space model based on the scaling factors in self.ScalingFact.
-
- dimss
inverse of nondimss.
-
- assemble_ss
builds state-space model. See function for more details.
-
- assemble_ss_profiling
generate profiling report of the assembly and saves it into self.prof_out. To read the report:
>>> import pstats p=pstats.Stats(self.prof_out)
-
- freqresp
ad-hoc method for fast frequency response (only implemented) for remove_predictor=False
To do: upgrade to linearise around unsteady snapshot (adjoint)
Produces block-form of state-space model
\[\begin{split}\mathbf{x}_{n+1} &= \mathbf{A}\,\mathbf{x}_n + \mathbf{B} \mathbf{u}_{n+1} \\ \mathbf{y}_n &= \mathbf{C}\,\mathbf{x}_n + \mathbf{D} \mathbf{u}_n\end{split}\]where the state, inputs and outputs are:
\[\mathbf{x}_n = \{ \delta \mathbf{\Gamma}_n,\, \delta \mathbf{\Gamma_{w_n}},\, \Delta t\,\delta\mathbf{\Gamma}'_n,\, \delta\mathbf{\Gamma}_{n-1} \}\]\[\mathbf{u}_n = \{ \delta\mathbf{\zeta}_n,\, \delta\mathbf{\zeta}'_n,\, \delta\mathbf{u}_{ext,n} \}\]\[\mathbf{y} = \{\delta\mathbf{f}\}\]with \(\mathbf{\Gamma}\) being the vector of vortex circulations, \(\mathbf{\zeta}\) the vector of vortex lattice coordinates and \(\mathbf{f}\) the vector of aerodynamic forces and moments. Note that \((\bullet)'\) denotes a derivative with respect to time.
Note that the input is atypically defined at time
n+1
, therefore by defaultself.remove_predictor = True
and the predictor termu_{n+1}
is eliminated through the change of state[1]:\[\begin{split}\mathbf{h}_n &= \mathbf{x}_n - \mathbf{B}\,\mathbf{u}_n \\\end{split}\]such that:
\[\begin{split}\mathbf{h}_{n+1} &= \mathbf{A}\,\mathbf{h}_n + \mathbf{A\,B}\,\mathbf{u}_n \\ \mathbf{y}_n &= \mathbf{C\,h}_n + (\mathbf{C\,B}+\mathbf{D})\,\mathbf{u}_n\end{split}\]which only modifies the equivalent \(\mathbf{B}\) and \(\mathbf{D}\) matrices.
References
[1] Franklin, GF and Powell, JD. Digital Control of Dynamic Systems, Addison-Wesley Publishing Company, 1980
To do: - remove all calls to scipy.linalg.block_diag
Low-rank method for frequency limited balancing. The Observability ad controllability Gramians over the frequencies kv are solved in factorised form. Balancd modes are then obtained with a square-root method.
Details: Observability and controllability Gramians are solved in factorised form through explicit integration. The number of integration points determines both the accuracy and the maximum size of the balanced model.
- Stability over all (Nb) balanced states is achieved if:
- one of the Gramian is integrated through the full Nyquist range
- the integration points are enough.
Note, however, that even when stability is not achieved over the full balanced states, stability of the balanced truncated model with Ns<=Nb states is normally observed even when a low number of integration points is used. Two integration methods (trapezoidal rule on uniform grid and Gauss-Legendre quadrature) are provided.
Input:
DictBalFreq: dictionary specifying integration method with keys:
- ‘frequency’: defines limit frequencies for balancing. The balanced
model will be accurate in the range [0,F], where F is the value of this key. Note that F units must be consistent with the units specified in the self.ScalingFacts dictionary.
- ‘method_low’: [‘gauss’,’trapz’] specifies whether to use gauss
quadrature or trapezoidal rule in the low-frequency range [0,F]
- ‘options_low’: options to use for integration in the low-frequencies.
These depend on the integration scheme (See below).
- ‘method_high’: method to use for integration in the range [F,F_N],
where F_N is the Nyquist frequency. See ‘method_low’.
- ‘options_high’: options to use for integration in the high-frequencies.
- ‘check_stability’: if True, the balanced model is truncated to
eliminate unstable modes - if any is found. Note that very accurate balanced model can still be obtained, even if high order modes are unstable. Note that this option is overridden if “”
- ‘get_frequency_response’: if True, the function also returns the
frequency response evaluated at the low-frequency range integration points. If True, this option also allows to automatically tune the balanced model.
Future options:
- ‘truncation_tolerance’: if ‘get_frequency_response’ is True, allows
to truncatethe balanced model so as to achieved a prescribed tolerance in the low-frequwncy range.
- Ncpu: for parallel run
- The following integration schemes are available:
- ‘trapz’: performs integration over equally spaced points using
- trapezoidal rule. It accepts options dictionaries with keys:
- ‘points’: number of integration points to use (including
domain boundary)
- ‘gauss’ performs gauss-lobotto quadrature. The domain can be
partitioned in Npart sub-domain in which the gauss-lobotto quadrature of order Ord can be applied. A total number of Npart*Ord points is required. It accepts options dictionaries of the form:
- ‘partitions’: number of partitions
- ‘order’: quadrature order.
Example: The following dictionary
- DictBalFreq={ ‘frequency’: 1.2,
- ‘method_low’: ‘trapz’, ‘options_low’: {‘points’: 12}, ‘method_high’: ‘gauss’, ‘options_high’: {‘partitions’: 2, ‘order’: 8}, ‘check_stability’: True }
balances the state-space model self.SS in the frequency range [0, 1.2] using
- 12 equally-spaced points integration of the Gramians in
- the low-frequency range [0,1.2] and
- (b) a 2 Gauss-Lobotto 8-th order quadratures of the controllability Gramian in the high-frequency range.
A total number of 28 integration points will be required, which will result into a balanced model with number of states
min{ 2*28* number_inputs, 2*28* number_outputs }The model is finally truncated so as to retain only the first Ns stable modes.
Ad-hoc method for fast UVLM frequency response over the frequencies kv. The method, only requires inversion of a K x K matrix at each frequency as the equation for propagation of wake circulation are solved exactly. The algorithm implemented here can be used also upon projection of the state-space model.
Note: This method is very similar to the “minsize” solution option is the steady_solve.
Scale state-space model based of self.ScalingFacts.
Solve step.
If the predictor term has not been removed (
remove_predictor = False
) then the system is solved as:\[\begin{split}\mathbf{x}^{n+1} &= \mathbf{A\,x}^n + \mathbf{B\,u}^n \\ \mathbf{y}^{n+1} &= \mathbf{C\,x}^{n+1} + \mathbf{D\,u}^n\end{split}\]Else, if
remove_predictor = True
, the state is modified as\[\mathbf{h}^n = \mathbf{x}^n - \mathbf{B\,u}^n\]And the system solved by:
\[\begin{split}\mathbf{h}^{n+1} &= \mathbf{A\,h}^n + \mathbf{B_{mod}\,u}^{n} \\ \mathbf{y}^{n+1} &= \mathbf{C\,h}^{n+1} + \mathbf{D_{mod}\,u}^{n+1}\end{split}\]Finally, the original state is recovered using the reverse transformation:
\[\mathbf{x}^{n+1} = \mathbf{h}^{n+1} + \mathbf{B\,u}^{n+1}\]where the modifications to the \(\mathbf{B}_{mod}\) and \(\mathbf{D}_{mod}\) are detailed in
Dynamic.assemble_ss()
.Notes
Although the original equations include the term \(\mathbf{u}_{n+1}\), it is a reasonable approximation to take \(\mathbf{u}_{n+1}\approx\mathbf{u}_n\) given a sufficiently small time step, hence if the input at time
n+1
is not parsed, it is estimated from \(u^n\).Parameters: - x_n (np.array) – State vector at the current time step \(\mathbf{x}^n\)
- u_n (np.array) – Input vector at time step \(\mathbf{u}^n\)
- u_n1 (np.array) – Input vector at time step \(\mathbf{u}^{n+1}\)
- transform_state (bool) – When the predictor term is removed, if true it will transform the state vector. If false it will be assumed that the state vector that is parsed is already transformed i.e. it is \(\mathbf{h}\).
Returns: Updated state and output vector packed in a tuple \((\mathbf{x}^{n+1},\,\mathbf{y}^{n+1})\)
Return type: Tuple
Notes
Because in BlockDynamics the predictor is never removed when building ‘self.SS’, the implementation change with respect to Dynamic. However, formulas are consistent.
Class for frequency description of linearised UVLM solution. Linearisation around steady-state are only supported. The class is built upon Static, and inherits all the methods contained there.
The class supports most of the features of Dynamics but has lower memory requirements of Dynamic, and should be preferred for:
- producing memory and computationally cheap frequency responses
- building reduced order models using RFA/polynomial fitting
Usage: Upon initialisation, the assemble method produces all the matrices required for the frequency description of the UVLM (see assemble for details). A state-space model is not allocated but:
- Time stepping is also possible (but not implemented yet) as all the fundamental terms describing the UVLM equations are still produced (except the propagation of wake circulation)
- ad-hoc methods for scaling, unscaling and frequency response are provided.
Input:
tsdata: aero timestep data from SHARPy solution
dt: time-step
integr_order=0,1,2: integration order for UVLM unsteady aerodynamic force. If 0, the derivative is computed exactly.
RemovePredictor=True: This flag is only used for the frequency response calculation. The frequency description, in fact, naturally arises without the predictor, but lags can be included during the frequency response calculation. See Dynamic documentation for more details.
ScalingDict=None: disctionary containing fundamental reference units
{'length': reference_length, 'speed': reference_speed, 'density': reference density}
used to derive scaling quantities for the state-space model variables. The scaling factors are stores in
self.ScalingFact.
Note that while time, circulation, angular speeds) are scaled accordingly, FORCES ARE NOT. These scale by qinf*b**2, where b is the reference length and qinf is the dinamic pressure.
UseSparse=False: builds the A and B matrices in sparse form. C and D are dense, hence the sparce format is not used.
-
- nondimss
normalises matrices produced by the assemble method based on the scaling factors in self.ScalingFact.
-
- dimss
inverse of nondimss.
-
- assemble
builds matrices for UVLM minimal size description.
-
- assemble_profiling
generate profiling report of the assembly and saves it into self.prof_out. To read the report:
import pstats p=pstats.Stats(self.prof_out)
-
- freqresp
fast algorithm for frequency response.
Methods to implement:
- solve_steady: runs freqresp at 0 frequency.
- solve_step: solves one time-step
Assembles matrices for minumal size frequency description of UVLM. The state equation is represented in the form:
\[\mathbf{A_0} \mathbf{\Gamma} + \mathbf{A_{w_0}} \mathbf{\Gamma_w} = \mathbf{B_0} \mathbf{u}\]While the output equation is as per the Dynamic class, namely:
\[\mathbf{y} = \mathbf{C} \mathbf{x} + \mathbf{D} \mathbf{u}\]where
\[\mathbf{x} = [\mathbf{\Gamma}; \mathbf{\Gamma_w}; \Delta\mathbf(\Gamma)]\]The propagation of wake circulation matrices are not produced as these are not required for frequency response analysis.
Generate profiling report for assembly and save it in self.prof_out.
- To read the report:
- import pstats p=pstats.Stats(self.prof_out)
Ad-hoc method for fast UVLM frequency response over the frequencies kv. The method, only requires inversion of a K x K matrix at each frequency as the equation for propagation of wake circulation are solved exactly.
Produces a sparse matrix
\[\bar{\mathbf{C}}(z)\]where
\[z = e^{k \Delta t}\]such that the wake circulation frequency response at \(z\) is
\[\bar{\goldsymbol{\Gamma}}_w = \bar{\mathbf{C}}(z) \bar{\boldsymbol{\Gamma}}\]
Scale state-space model based of self.ScalingFacts
Static linear solver
Assemble global matrices
Generate profiling report for assembly and save it in self.prof_out.
- To read the report:
- import pstats p=pstats.Stats(self.prof_out)
Gains to reproduce rigid-body motion such that grid displacements and velocities are given by:
dzeta = Ktra*u_tra + Krot*u_rot
dzeta_dot = Ktra_vel*u_tra_dot + Krot*u_rot_dot
Rotations are assumed to happen independently with respect to the zeta_rotation point and about the x,y and z axes of the inertial frame.
Gains to computes sectional forces. Moments are computed w.r.t. mid-vertex (chord-wise index M/2) of each section.
Calculates gain matrices to calculate the total force (Kftot) and moment (Kmtot, Kmtot_disp) about the pole zeta_pole.
Being \(f\) and \(\zeta\) the force and position at the vertex (m,n) of the lattice these are produced as:
ftot=sum(f) -> dftot += df
mtot-sum((zeta-zeta_pole) x f) -> dmtot += cross(zeta0-zeta_pole) df - cross(f0) dzeta
Reshapes state/output according to SHARPy format
Solve for bound \(\\Gamma\) using the equation;
\[\begin{split}\\mathcal{A}(\\Gamma^n) = u^n\end{split}\]# … at constant rotation speed
self.Dfqsdzeta+=scalg.block_diag(*ass.dfqsdzeta_omega(MS.Surfs,MS.Surfs_star))
Calculates total force (Ftot) and moment (Mtot) (about pole zeta_pole).
Generation of multiple aerodynamic surfaces¶
- Maraniello, 25 May 2018
Creates and assembles multiple aerodynamic surfaces from data
Computes normal induced velocities at collocation points.
Computes induced velocities at mid-segment points.
Returns quasi-steady forces over
- Warning: forces are stored in a NON-redundant format:
- (3,4,M,N)
- where the element
- (:,ss,mm,nn)
is the contribution to the force over the ss-th segment due to the circulation of panel (mm,nn).
Computes normal induced velocities at collocation points.
Note: for state-equation both projected and not projected induced velocities are required at the collocation points. Hence, this method tries to first the u_ind_coll attribute in each surface.
Verify aic at collocaiton points using non-penetration condition
Verify quasi-steady contribution for forces matches against SHARPy.
Verify state variables fulfill non-penetration condition at bound surfaces
Geometrical methods for bound surfaces¶
Geometrical methods for bound surfaces
- Maraniello, 20 May 2018
Allows retrieving geometrical information of a surface. Requires a gridmapping.AeroGridMap mapping structure in input and the surface vertices coordinates.
Indices convention: each panel is characterised through the following indices: - m,n: chord/span-wise indices
Methods: - get_*: retrieve information of a panel (e.g. normal, surface area) - generate_*: apply get_* method to each panel and store info into array.
Interpolation matrices, W: - these are labelled as ‘Wba’, where ‘a’ defines the initial format, b the final. Hence, given the array vb, it holds va=Wab*vb
Using bilinear interpolation, retrieves panel collocation point, where aN,aM in [0,1] are distances in the chordwise and spanwise directions such that:
- (aM,aN)=(0,0) –> quantity at vertex 0
- (aM,aN)=(1,0) –> quantity at vertex 1
- (aM,aN)=(1,1) –> quantity at vertex 2
- (aM,aN)=(0,1) –> quantity at vertex 3
Retrieves coordinates of panel (m,n) vertices.
Produces a compact array with weights for bilinear interpolation, where aN,aM in [0,1] are distances in the chordwise and spanwise directions such that:
- (aM,aN)=(0,0) –> quantity at vertex 0
- (aM,aN)=(1,0) –> quantity at vertex 1
- (aM,aN)=(1,1) –> quantity at vertex 2
- (aM,aN)=(0,1) –> quantity at vertex 3
Project a quantity q_vert (scalar or vector) defined at vertices to collocation points.
Project a vector quantity q_coll defined at collocation points to normal.
Contains geometric and aerodynamic information about bound/wake surface.
- Compulsory input are those that apply to both bound and wake surfaces:
zeta
: defines geometrygamma
: circulation
- With respect to
AeroGridGeo
, the class contains methods to: - project prescribed input velocity at nodes (
u_ext
,zeta_dot
) over collocation points. - compute induced velocity over ANOTHER surface.
- compute AIC induced over ANOTHER surface
- project prescribed input velocity at nodes (
Parameters: - Map (gridmapping.AeroGridMap) – Map of grid.
- zeta (list(np.ndarray)) – Grid vertices coordinates in inertial (G) frame.
- zeta_dot (list(np.ndarray)) – Grid vertices velocities in inertial (G) frame. Default is
None
. - u_ext (list(np.ndarray)) – Grid external velocities in inertial (G) frame. Default is
None
. - gamma_dot (list(np.ndarray)) – Panel circulation derivative. Default is
None
. - rho (float) – Air density. Default is
1.
- aM (float) – Chordwise position in panel of collocation point. Default is
0.5
- aN (float) – Spanwise position in panel of collocation point. Default is
0.5
- for_vel (np.ndarray) – Frame of reference velocity (including rotational velocity) in the inertial frame.
- To add:
- project prescribed input velocity at nodes (u_ext, zeta_dot) over
mid-point segments
Produces influence coefficinet matrix to calculate the induced velocity at a target point. The aic3 matrix has shape (3,K)
Produces influence coefficient matrices such that the velocity induced over the Surface_target is given by the product:
- if target==’collocation’:
- if Project:
- u_ind_coll_norm.rehape(-1)=AIC*self.gamma.reshape(-1,order=’C’)
- else:
- u_ind_coll_norm[ii,:,:].rehape(-1)=
- AIC[ii,:,:]*self.gamma.reshape(-1,order=’C’)
where ii=0,1,2
- if targer==’segments’:
- AIC has shape (3,self.maps.K,4,Mout,Nout), such that
- AIC[:,:,ss,mm,nn]
is the influence coefficient matrix associated to the induced velocity at segment ss of panel (mm,nn)
Computes induced velocity at a point zeta_target.
Computes induced velocity over an instance of AeroGridSurface, where target specifies the target grid (collocation or segments). If Project is True, velocities are projected onver panel normal (only available at collocation points).
Note: for state-equation, both projected and non-projected velocities at the collocation points are required. Hence, it is suggested to use this method with Projection=False, and project afterwards.
Warning: induced velocities at grid segments are stored in a redundant format:
(3,4,M,N)- where the element
- (:,ss,mm,nn)
is the induced velocity over the ss-th segment of panel (mm,nn). A fast looping is implemented to re-use previously computed velocities
Returns velocities at collocation points from nodal values
u_ext
andzeta_dot
of shape(3, M+1, N+1)
at the collocation points.Notes:
\[oldsymbol{u}_{c} = \mathcal{W}_{cv}(oldsymbol(\]u)_0 - oldsymbol{zeta}_0)
is the input velocity at the collocation point, where \(\mathcal{W}_{cv} projects the velocity from the grid points onto the collocation point. This variable is referred to as \) and depends on the coordinateszeta
when the body is rotating.
Returns velocities at mid-segment points from nodal values u_ext and zeta_dot of shape (3,M+1,N+1).
Warning: input velocities at grid segments are stored in a redundant format:
(3,4,M,N)- where the element
- (:,ss,mm,nn)
is the induced velocity over the ss-th segment of panel (mm,nn). A fast looping is implemented to re-use previously computed velocities
2018/08/24: Include effects due to rotation (omega x zeta). Now it depends on the coordinates zeta
Returns quasi-steady forces evaluated at mid-segment points over the surface.
Important: the circulation at the first row of wake panel is required! Hence all
- Warning: forces are stored in a NON-redundant format:
- (3,4,M,N)
- where the element
- (:,ss,mm,nn)
is the contribution to the force over the ss-th segment due to the circulation of panel (mm,nn).
Returns added mass effects over lattive grid
From nodal input velocity to normal velocities at collocation points.
Used by autodoc_mock_imports.
Model Order Reduction¶
Balancing Methods¶
The following classes are available to reduce a linear system employing balancing methods.
The main class is Balanced
and the other available classes:
correspond to the reduction algorithm.
Balanced¶
Balancing ROM methods
Main class to load a balancing ROM. See below for the appropriate settings to be parsed in the
algorithm_settings
based on your selection.- Supported algorithms:
- Direct balancing
Direct
- Iterative balancing
Iterative
- Frequency limited balancing
FrequencyLimited
- Direct balancing
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default Options print_info
bool
Write output to screen True
algorithm
str
Balanced realisation method Direct
,Iterative
,FrequencyLimited
algorithm_settings
dict
Settings for the desired algorithm {}
Direct¶
Find balanced realisation of continuous (
DLTI = False
) and discrete (DLTI = True
) time of LTI systems using scipy libraries.The function proceeds to achieve balanced realisation of the state-space system by first solving the Lyapunov equations. They are solved using Barlets-Stewart algorithm for Sylvester equation, which is based on A matrix Schur decomposition.
\[\begin{split}\mathbf{A\,W_c + W_c\,A^T + B\,B^T} &= 0 \\ \mathbf{A^T\,W_o + W_o\,A + C^T\,C} &= 0\end{split}\]to obtain the reachability and observability gramians, which are positive definite matrices.
Then, the gramians are decomposed into their Cholesky factors such that:
\[\begin{split}\mathbf{W_c} &= \mathbf{Q_c\,Q_c^T} \\ \mathbf{W_o} &= \mathbf{Q_o\,Q_o^T}\end{split}\]A singular value decomposition (SVD) of the product of the Cholesky factors is performed
\[(\mathbf{Q_o^T\,Q_c}) = \mathbf{U\,\Sigma\,V^*}\]The singular values are then used to build the transformation matrix \(\mathbf{T}\)
\[\begin{split}\mathbf{T} &= \mathbf{Q_c\,V\,\Sigma}^{-1/2} \\ \mathbf{T}^{-1} &= \mathbf{\Sigma}^{-1/2}\,\mathbf{U^T\,Q_o^T}\end{split}\]The balanced system is therefore of the form:
\[\begin{split}\mathbf{A_b} &= \mathbf{T\,A\,T^{-1}} \\ \mathbf{B_b} &= \mathbf{T\,B} \\ \mathbf{C_b} &= \mathbf{C\,T^{-1}} \\ \mathbf{D_b} &= \mathbf{D}\end{split}\]Warning
This function may be less computationally efficient than the
balreal
Matlab implementation and does not offer the option to bound the realisation in frequency and time.Notes
Lyapunov equations are solved using Barlets-Stewart algorithm for Sylvester equation, which is based on A matrix Schur decomposition.
Parameters: - A (np.ndarray) – Plant Matrix
- B (np.ndarray) – Input Matrix
- C (np.ndarray) – Output Matrix
- DLTI (bool) – Discrete time state-space flag
- Schur (bool) – Use Schur decomposition to solve the Lyapunov equations
Returns: - Tuple of the form
(S, T, Tinv)
containing: - Singular values in diagonal matrix (
S
) - Transformation matrix (
T
). - Inverse transformation matrix(
Tinv
).
- Singular values in diagonal matrix (
Return type: tuple of np.ndarrays
References
Anthoulas, A.C.. Approximation of Large Scale Dynamical Systems. Chapter 7. Advances in Design and Control. SIAM. 2005.
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default Options tune
bool
Tune ROM to specified tolerance True
use_schur
bool
Use Schur decomposition during build False
rom_tolerance
float
Absolute accuracy with respect to full order frequency response 0.01
rom_tune_freq_range
list(float)
Beginning and end of frequency range where to tune ROM [0, 1]
convergence
str
ROM tuning convergence. If min
attempts to find minimal number of states.Ifall
it starts from larger size ROM until convergence to specified tolerance is found.min
reduction_method
str
Desired reduction method realisation
realisation
,truncation
FrequencyLimited¶
Method for frequency limited balancing.
The Observability and controllability Gramians over the frequencies kv are solved in factorised form. Balanced modes are then obtained with a square-root method.
Details:
Observability and controllability Gramians are solved in factorised form through explicit integration. The number of integration points determines both the accuracy and the maximum size of the balanced model.
Stability over all (Nb) balanced states is achieved if:
- one of the Gramian is integrated through the full Nyquist range
- the integration points are enough.
Input:
DictBalFreq: dictionary specifying integration method with keys:
frequency
: defines limit frequencies for balancing. The balanced- model will be accurate in the range
[0,F]
, whereF
is the value of this key. Note thatF
units must be consistent with the units specified in theself.ScalingFacts
dictionary.
method_low
:['gauss','trapz']
specifies whether to use gauss quadrature or trapezoidal rule in the low-frequency range[0,F]
.options_low
: options to use for integration in the low-frequencies. These depend on the integration scheme (See below).method_high
: method to use for integration in the range [F,F_N], where F_N is the Nyquist frequency. See ‘method_low’.options_high
: options to use for integration in the high-frequencies.check_stability
: if True, the balanced model is truncated to eliminate unstable modes - if any is found. Note that very accurate balanced model can still be obtained, even if high order modes are unstable. Note that this option is overridden if “”get_frequency_response
: if True, the function also returns the frequency response evaluated at the low-frequency range integration points. If True, this option also allows to automatically tune the balanced model.
- Future options:
- Ncpu: for parallel run
- The following integration schemes are available:
trapz
: performs integration over equally spaced points using trapezoidal rule. It accepts options dictionaries with keys:points
: number of integration points to use (including domain boundary)
gauss
performs gauss-lobotto quadrature. The domain can be partitioned in Npart sub-domain in which the gauss-lobotto quadrature of order Ord can be applied. A total number of Npart*Ord points is required. It accepts options dictionaries of the form:partitions
: number of partitionsorder
: quadrature order.
Examples
The following dictionary
>>> DictBalFreq={'frequency': 1.2, >>> 'method_low': 'trapz', >>> 'options_low': {'points': 12}, >>> 'method_high': 'gauss', >>> 'options_high': {'partitions': 2, 'order': 8}, >>> 'check_stability': True }
balances the state-space model in the frequency range [0, 1.2] using:
- 12 equally-spaced points integration of the Gramians in the low-frequency range [0,1.2] and
- A 2 Gauss-Lobotto 8-th order quadratures of the controllability Gramian in the high-frequency range.
A total number of 28 integration points will be required, which will result into a balanced model with number of states
>>> min{ 2*28* number_inputs, 2*28* number_outputs }
The model is finally truncated so as to retain only the first Ns stable modes.
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default Options frequency
float
defines limit frequencies for balancing. The balanced model will be accurate in the range [0,F]
, whereF
is the value of this key. Note thatF
units must be consistent with the units specified in the in theself.ScalingFacts
dictionary.1.0
method_low
str
Specifies whether to use gauss quadrature or trapezoidal rule in the low-frequency range [0,F]
trapz
gauss
,trapz
options_low
dict
Settings for the low frequency integration. See Notes. {}
method_high
str
Specifies whether to use gauss quadrature or trapezoidal rule in the high-frequency range [F,FN]
trapz
gauss
,trapz
options_high
dict
Settings for the high frequency integration. See Notes. {}
check_stability
bool
if True, the balanced model is truncated to eliminate unstable modes - if any is found. Note that very accurate balanced model can still be obtained, even if high order modes are unstable. True
get_frequency_response
bool
if True, the function also returns the frequency response evaluated at the low-frequency range integration points. If True, this option also allows to automatically tune the balanced model. False
The parameters of integration take the following options:
Name Type Description Default points
int
Trapezoidal points of integration 12
partitions
int
Number of Gauss-Lobotto quadratures 2
order
int
Order of Gauss-Lobotto quadratures 2
Iterative¶
Find balanced realisation of DLTI system.
Notes
Lyapunov equations are solved using iterative squared Smith algorithm, in its low or full rank version. These implementations are as per the low_rank_smith and smith_iter functions respectively but, for computational efficiency, the iterations are rewritten here so as to solve for the observability and controllability Gramians contemporary.
Exploiting sparsity:
This algorithm is not ideal to exploit sparsity. However, the following strategies are implemented:
- if the A matrix is provided in sparse format, the powers of A will be calculated exploiting sparsity UNTIL the number of non-zero elements is below 15% the size of A. Upon this threshold, the cost of the matrix multiplication rises dramatically, and A is hence converted to a dense numpy array.
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default lowrank
bool
Use low rank methods True
smith_tol
float
Smith tolerance 1e-10
tolSVD
float
SVD threshold 1e-06
Krylov-subspaces model order reduction techniques¶
Krylov¶
Model Order Reduction Methods for Single Input Single Output (SISO) and MIMO Linear Time-Invariant (LTI) Systems using moment matching (Krylov Methods).
Examples
General calling sequences for different systems
- SISO single point interpolation:
>>> algorithm = 'one_sided_arnoldi' >>> interpolation_point = np.array([0.0]) >>> krylov_r = 4 >>> >>> rom = Krylov() >>> rom.initialise(sharpy_data, FullOrderModelSS) >>> rom.run(algorithm, krylov_r, interpolation_point)
- 2 by 2 MIMO with tangential, multipoint interpolation:
>>> algorithm = 'dual_rational_arnoldi' >>> interpolation_point = np.array([0.0, 1.0j]) >>> krylov_r = 4 >>> right_vector = np.block([[1, 0], [0, 1]]) >>> left_vector = right_vector >>> >>> rom = Krylov() >>> rom.initialise(sharpy_data, FullOrderModelSS) >>> rom.run(algorithm, krylov_r, interpolation_point, right_vector, left_vector)
- 2 by 2 MIMO multipoint interpolation:
>>> algorithm = 'mimo_rational_arnoldi' >>> interpolation_point = np.array([0.0]) >>> krylov_r = 4 >>> >>> rom = Krylov() >>> rom.initialise(sharpy_data, FullOrderModelSS) >>> rom.run(algorithm, krylov_r, interpolation_point)
The settings that this solver accepts are given by a dictionary, with the following key-value pairs:
Name Type Description Default Options print_info
bool
Write ROM information to screen and log True
frequency
list(complex)
Interpolation points in the continuous time complex plane [rad/s] [0]
algorithm
str
Krylov reduction method algorithm r
int
Moments to match at the interpolation points 1
single_side
str
Construct the rom using a single side. Leave blank (or empty string) for both. controllability
,observability
tangent_input_file
str
Filepath to .h5 file containing tangent interpolation vectors restart_arnoldi
bool
Restart Arnoldi iteration with r-=1 if ROM is unstable False
Checks the stability of the ROM by computing its eigenvalues.
If the resulting system is unstable, the Arnoldi procedure can be restarted to eliminate the eigenvalues outside the stability boundary.
However, if this is the case, the ROM no longer matches the moments of the original system at the specific frequencies since now the approximation is done with respect to a system of the form:
\[\begin{split}\Sigma = \left(\begin{array}{c|c} \mathbf{A} & \mathbf{\bar{B}} \\ \hline \mathbf{C} & \ \end{array}\right)\end{split}\]where \(\mathbf{\bar{B}} = (\mu \mathbf{I}_n - \mathbf{A})\mathbf{B}\)
Parameters: restart_arnoldi (bool) – Restart the relevant Arnoldi algorithm with the unstable eigenvalues removed.
Dual Rational Arnoli Interpolation for SISO sytems [1] and MIMO systems through tangential interpolation [2].
Effectively the same as the two_sided_arnoldi and the resulting V matrices for each interpolation point are concatenated
\[\begin{split}\bigcup\limits_{k = 1}^K\mathcal{K}_{b_k}((\sigma_i\mathbf{I}_n - \mathbf{A})^{-1}, (\sigma_i\mathbf{I}_n - \mathbf{A})^{-1}\mathbf{b})\subseteq\mathcal{V}&=\text{range}(\mathbf{V}) \\ \bigcup\limits_{k = 1}^K\mathcal{K}_{c_k}((\sigma_i\mathbf{I}_n - \mathbf{A})^{-T}, (\sigma_i\mathbf{I}_n - \mathbf{A})^{-T}\mathbf{c}^T)\subseteq\mathcal{Z}&=\text{range}(\mathbf{Z})\end{split}\]For MIMO systems, tangential interpolation is used through the right and left tangential direction vectors \(\mathbf{r}_i\) and \(\mathbf{l}_i\).
\[\begin{split}\bigcup\limits_{k = 1}^K\mathcal{K}_{b_k}((\sigma_i\mathbf{I}_n - \mathbf{A})^{-1}, (\sigma_i\mathbf{I}_n - \mathbf{A})^{-1}\mathbf{Br}_i)\subseteq\mathcal{V}&=\text{range}(\mathbf{V}) \\ \bigcup\limits_{k = 1}^K\mathcal{K}_{c_k}((\sigma_i\mathbf{I}_n - \mathbf{A})^{-T}, (\sigma_i\mathbf{I}_n - \mathbf{A})^{-T}\mathbf{C}^T\mathbf{l}_i)\subseteq\mathcal{Z}&=\text{range}(\mathbf{Z})\end{split}\]Parameters: - frequency (np.ndarray) – Array containing the interpolation points \(\sigma = \{\sigma_1, \dots, \sigma_K\}\in\mathbb{C}\)
- r (int) – Krylov space order \(b_k\) and \(c_k\). At the moment, different orders for the controllability and observability constructions are not supported.
- right_tangent (np.ndarray) – Matrix containing the right tangential direction interpolation vector for each interpolation point in column form, i.e. \(\mathbf{r}\in\mathbb{R}^{m \times K}\).
- left_tangent (np.ndarray) – Matrix containing the left tangential direction interpolation vector for each interpolation point in column form, i.e. \(\mathbf{l}\in\mathbb{R}^{p \times K}\).
Returns: The reduced order model matrices: \(\mathbf{A}_r\), \(\mathbf{B}_r\) and \(\mathbf{C}_r\).
Return type: tuple
References
[1] Grimme [2] Gallivan
Construct full rank orthonormal projection basis \(\mathbf{V}\) and \(\mathbf{W}\).
The main issue that one normally encounters with MIMO systems is that the minimality assumption of the system does not guarantee the resulting Krylov space to be full rank, unlike in the SISO case. Therefore, the construction is performed vector by vector, where linearly dependent vectors are eliminated or deflated from the Krylov subspace.
If the number of inputs differs the number of outputs, both Krylov spaces will be built such that both are the same size, therefore one Krylov space may be of higher order than the other one.
Following the method for vector-wise construction in Gugercin [1].
Parameters: - frequency (np.ndarray) – Array containing interpolation frequencies
- r (int) – Krylov space order
Returns: Tuple of reduced system matrices
A
,B
andC
.Return type: tuple
References
- [1] Gugercin, S. Projection Methods for Model Reduction of Large-Scale Dynamical
- Systems PhD Thesis. Rice University 2003.
One-sided Arnoldi method expansion about a single interpolation point, \(\sigma\). The projection matrix \(\mathbf{V}\) is constructed using an order \(r\) Krylov space. The space for a single finite interpolation point known as a Pade approximation is described by:
\[\text{range}(\textbf{V}) = \mathcal{K}_r((\sigma\mathbf{I}_n - \mathbf{A})^{-1}, (\sigma\mathbf{I}_n - \mathbf{A})^{-1}\mathbf{b})\]In the case of an interpolation about infinity, the problem is known as partial realisation and the Krylov space is
\[\text{range}(\textbf{V}) = \mathcal{K}_r(\mathbf{A}, \mathbf{b})\]The resulting orthogonal projection leads to the following reduced order system:
\[\begin{split}\hat{\Sigma} : \left(\begin{array}{c|c} \hat{A} & \hat{B} \\ \hline \hat{C} & {D}\end{array}\right) \text{with } \begin{cases}\hat{A}=V^TAV\in\mathbb{R}^{k\times k},\,\\ \hat{B}=V^TB\in\mathbb{R}^{k\times m},\,\\ \hat{C}=CV\in\mathbb{R}^{p\times k},\,\\ \hat{D}=D\in\mathbb{R}^{p\times m}\end{cases}\end{split}\]Parameters: - frequency (complex) – Interpolation point \(\sigma \in \mathbb{C}\)
- r (int) – Number of moments to match. Equivalent to Krylov space order and order of the ROM.
Returns: The reduced order model matrices: \(\mathbf{A}_r\), \(\mathbf{B}_r\) and \(\mathbf{C}_r\)
Return type: tuple
When employing complex frequencies, the projection matrix can be normalised to be real Following Algorithm 1b in Lee(2006) :param frequency: :param r:
Returns:
Implicitly Restarted Krylov Algorithm
Performs Model Order Reduction employing Krylov space projection methods.
Supported methods include:
Algorithm Interpolation Points Systems one_sided_arnoldi
1 SISO Systems two_sided_arnoldi
1 SISO Systems dual_rational_arnoldi
K SISO systems and Tangential interpolation for MIMO systems mimo_rational_arnoldi
K MIMO systems. Uses vector-wise construction (more robust) mimo_block_arnoldi
K MIMO systems. Uses block Arnoldi methods (more efficient) Parameters: ss (sharpy.linear.src.libss.ss) – State space to reduce Returns: Reduced state space system Return type: (libss.ss)
Remove unstable poles left after reduction
Using a Schur decomposition of the reduced plant matrix \(\mathbf{A}_m\in\mathbb{C}^{m\times m}\), the method removes the unstable eigenvalues that could have appeared after the moment-matching reduction.
The oblique projection matrices \(\mathbf{T}_L\in\mathbb{C}^{m \times p}\) and \(\mathbf{T}_R\in\mathbb{C}^{m \times p}\) result in a stable realisation
\[\mathbf{A}_s = \mathbf{T}_L^\top\mathbf{AT}_R \in \mathbb{C}^{p\times p}.\]Parameters: A (np.ndarray) – plant matrix (if not provided self.ssrom.A
will be used).Returns: - Left and right projection matrices \(\mathbf{T}_L\in\mathbb{C}^{m \times p}\) and
- \(\mathbf{T}_R\in\mathbb{C}^{m \times p}\)
Return type: tuple References
Jaimoukha, I. M., Kasenally, E. D.. Implicitly Restarted Krylov Subspace Methods for Stable Partial Realizations. SIAM Journal of Matrix Analysis and Applications, 1997.
See also
The method employs
sharpy.rom.utils.krylovutils.schur_ordered()
andsharpy.rom.utils.krylovutils.remove_a12()
.
Two-sided projection with a single interpolation point following the Arnoldi procedure. Very similar to the one-sided method available, but it adds the projection \(\mathbf{W}\) built using the Krylov space for the \(\mathbf{c}\) vector:
\[\mathcal{K}_r((\sigma\mathbf{I}_n - \mathbf{A})^{-T}, (\sigma\mathbf{I}_n - \mathbf{A})^{-T}\mathbf{c}^T)\subseteq\mathcal{W}=\text{range}(\mathbf{W})\]The oblique projection \(\mathbf{VW}^T\) matches twice as many moments as the single sided projection.
The resulting system takes the form:
\[\begin{split}\hat{\Sigma} : \left(\begin{array}{c|c} \hat{A} & \hat{B} \\ \hline \hat{C} & {D}\end{array}\right) \text{with } \begin{cases}\hat{A}=W^TAV\in\mathbb{R}^{k\times k},\,\\ \hat{B}=W^TB\in\mathbb{R}^{k\times m},\,\\ \hat{C}=CV\in\mathbb{R}^{p\times k},\,\\ \hat{D}=D\in\mathbb{R}^{p\times m}\end{cases}\end{split}\]Parameters: - frequency (complex) – Interpolation point \(\sigma \in \mathbb{C}\)
- r (int) – Number of moments to match on each side. The resulting ROM will be of order \(2r\).
Returns: The reduced order model matrices: \(\mathbf{A}_r\), \(\mathbf{B}_r\) and \(\mathbf{C}_r\).
Return type: tuple
Utils¶
Krylov Model Reduction Methods Utilities¶
Simple utility to verify matrix inverses
Asserts that
param T: | Matrix to test |
---|---|
type T: | np.ndarray |
param Tinv: | Supposed matrix inverse |
type Tinv: | np.ndarray |
param msg: | Output error message if inverse check not satisfied |
type msg: | str |
param eps: | Error threshold (\(10^\varepsilon\)) |
type eps: | float |
raises: | AssertionError – if matrix inverse check is not satisfied |
Contructs a Krylov subspace in an iterative manner following the methods of Gugercin [1].
The construction of the Krylov space is focused on Pade and partial realisation cases for the purposes of model
reduction. I.e. the partial realisation form of the Krylov space is used if
approx_type = 'partial_realisation'
\[\text{range}(\textbf{V}) = \mathcal{K}_r(\mathbf{A}, \mathbf{b})\]
Else, it is replaced by the Pade approximation form:
\[\text{range}(\textbf{V}) = \mathcal{K}_r((\sigma\mathbf{I}_n - \mathbf{A})^{-1}, (\sigma\mathbf{I}_n - \mathbf{A})^{-1}\mathbf{b})\]
Note that no inverses are actually computed but rather a single LU decomposition is performed at the beginning of the algorithm. Forward and backward substitution is used thereinafter to calculate the required vectors.
The algorithm also builds the Krylov space for the \(\mathbf{C}^T\) matrix. It should simply replace B
and side
should be side = 'c'
.
Examples
Partial Realisation:
>>> V = construct_krylov(r, A, B, 'partial_realisation', 'b')
>>> W = construct_krylov(r, A, C.T, 'partial_realisation', 'c')
Pade Approximation:
>>> V = construct_krylov(r, (sigma * np.eye(nx) - A), B, 'Pade', 'b')
>>> W = construct_krylov(r, (sigma * np.eye(nx) - A), C.T, 'Pade', 'c')
References
[1]. Gugercin, S. - Projection Methods for Model Reduction of Large-Scale Dynamical Systems. PhD Thesis. Rice University. 2003.
param r: | Krylov space order |
---|---|
type r: | int |
param lu_A: | For Pade approximations it should be the LU decomposition of \((\sigma I - \mathbf{A})\)
in tuple form, as output from the scipy.linalg.lu_factor() . For partial realisations it is
simply \(\mathbf{A}\). |
type lu_A: | np.ndarray |
param B: | If doing the B side it should be \(\mathbf{B}\), else \(\mathbf{C}^T\). |
type B: | np.ndarray |
param approx_type: | |
Type of approximation: partial_realisation or Pade . |
|
type approx_type: | |
str | |
param side: | Side of the projection b or c . |
returns: | Projection matrix |
rtype: | np.ndarray |
j-th unit vector (in row format)
param j: | Unit vector dimension |
---|---|
returns: | j-th unit vector |
rtype: | np.ndarray |
Examples
>>> evec(2)
np.array([0, 1])
>>> evec(3)
np.array([0, 0, 1])
LU Factorisation wrapper of:
In the case of A
being a sparse matrix, the sparse methods in scipy are employed
param sigma: | Expansion frequency |
---|---|
type sigma: | float |
param A: | Dynamics matrix |
type A: | csc_matrix or np.ndarray |
returns: | tuple (dense) or SuperLU (sparse) objects containing the LU factorisation |
rtype: | tuple or SuperLU |
LU solve wrapper.
Computes the solution to
or
if trans=1
.
It uses the SuperLU.solve()
method if the input is a SuperLU
or else will revert to the dense methods
in scipy.
param lu_A: | object or tuple containing the information of the LU factorisation |
---|---|
type lu_A: | SuperLU or tuple |
param b: | Right hand side vector to solve |
type b: | np.ndarray |
param trans: | 0 or 1 for either solution option. |
type trans: | int |
returns: | Solution to the system. |
rtype: | np.ndarray |
Modified Gram-Schmidt Orthogonalisation
Orthogonalises input matrix \(\mathbf{X}\) column by column.
param X: | Input matrix of dimensions \(n\) by \(m\). |
---|---|
type X: | np.ndarray |
returns: | Orthogonalised matrix of dimensions \(n\) by \(m\). |
rtype: | np.ndarray |
Notes
This method is faster than scipy’s scipy.linalg.qr()
method that returns an orthogonal matrix as part of
the QR decomposition, albeit at a higher number of function calls.
Basis change to remove the (1, 2) block of the block-ordered real Schur matrix \(\mathbf{A}\)
Being \(\mathbf{A}_s\in\mathbb{R}^{m\times m}\) a matrix of the form
the (1,2) block is removed by solving the Sylvester equation
used to build the change of basis
where \(s\) and \(u\) are the respective number of stable and unstable eigenvalues, such that
param As: | Block-ordered real Schur matrix (can be built using
sharpy.rom.utils.krylovutils.schur_ordered() ). |
---|---|
type As: | np.ndarray |
param n_stable: | Number of stable eigenvalues in As . |
type n_stable: | int |
returns: | Basis transformation \(\mathbf{T}\in\mathbb{R}^{m\times m}\). |
rtype: | np.ndarray |
References
Jaimoukha, I. M., Kasenally, E. D.. Implicitly Restarted Krylov Subspace Methods for Stable Partial Realizations SIAM Journal of Matrix Analysis and Applications, 1997.
Returns block ordered complex Schur form of matrix \(\mathbf{A}\)
where \(A_{11}\in\mathbb{C}^{s\times s}\) contains the \(s\) stable eigenvalues of \(\mathbf{A}\in\mathbb{R}^{m\times m}\).
param A: | Matrix to decompose. |
---|---|
type A: | np.ndarray |
param ct: | Continuous time system. |
type ct: | bool |
returns: | Tuple containing the Schur decomposition of \(\mathbf{A}\), \(\mathbf{A}_s\); the transformation \(\mathbf{T}\in\mathbb{C}^{m\times m}\); and the number of stable eigenvalues of \(\mathbf{A}\). |
rtype: | tuple |
Notes
This function is a wrapper of scipy.linalg.schur
imposing the settings required for this application.
General ROM utilities¶
- Maraniello, 14 Feb 2018
Method for frequency limited balancing.
The Observability and controllability Gramians over the frequencies kv are solved in factorised form. Balanced modes are then obtained with a square-root method.
Details:
Observability and controllability Gramians are solved in factorised form through explicit integration. The number of integration points determines both the accuracy and the maximum size of the balanced model.
Stability over all (Nb) balanced states is achieved if:
- one of the Gramian is integrated through the full Nyquist range
- the integration points are enough.
Input:
DictBalFreq: dictionary specifying integration method with keys:
frequency
: defines limit frequencies for balancing. The balanced- model will be accurate in the range
[0,F]
, whereF
is the value of this key. Note thatF
units must be consistent with the units specified in theself.ScalingFacts
dictionary.
method_low
:['gauss','trapz']
specifies whether to use gauss quadrature or trapezoidal rule in the low-frequency range[0,F]
.options_low
: options to use for integration in the low-frequencies. These depend on the integration scheme (See below).method_high
: method to use for integration in the range [F,F_N], where F_N is the Nyquist frequency. See ‘method_low’.options_high
: options to use for integration in the high-frequencies.check_stability
: if True, the balanced model is truncated to eliminate unstable modes - if any is found. Note that very accurate balanced model can still be obtained, even if high order modes are unstable. Note that this option is overridden if “”get_frequency_response
: if True, the function also returns the frequency response evaluated at the low-frequency range integration points. If True, this option also allows to automatically tune the balanced model.
- Future options:
- Ncpu: for parallel run
- The following integration schemes are available:
trapz
: performs integration over equally spaced points using trapezoidal rule. It accepts options dictionaries with keys:points
: number of integration points to use (including domain boundary)
gauss
performs gauss-lobotto quadrature. The domain can be partitioned in Npart sub-domain in which the gauss-lobotto quadrature of order Ord can be applied. A total number of Npart*Ord points is required. It accepts options dictionaries of the form:partitions
: number of partitionsorder
: quadrature order.
Examples
The following dictionary
>>> DictBalFreq={'frequency': 1.2,
>>> 'method_low': 'trapz',
>>> 'options_low': {'points': 12},
>>> 'method_high': 'gauss',
>>> 'options_high': {'partitions': 2, 'order': 8},
>>> 'check_stability': True }
balances the state-space model in the frequency range [0, 1.2] using:
- 12 equally-spaced points integration of the Gramians in the low-frequency range [0,1.2] and
- A 2 Gauss-Lobotto 8-th order quadratures of the controllability Gramian in the high-frequency range.
A total number of 28 integration points will be required, which will result into a balanced model with number of states
>>> min{ 2*28* number_inputs, 2*28* number_outputs }
The model is finally truncated so as to retain only the first Ns stable modes.
Find balanced realisation of continuous (DLTI = False
) and discrete (DLTI = True
)
time of LTI systems using scipy libraries.
The function proceeds to achieve balanced realisation of the state-space system by first solving the Lyapunov equations. They are solved using Barlets-Stewart algorithm for Sylvester equation, which is based on A matrix Schur decomposition.
to obtain the reachability and observability gramians, which are positive definite matrices.
Then, the gramians are decomposed into their Cholesky factors such that:
A singular value decomposition (SVD) of the product of the Cholesky factors is performed
The singular values are then used to build the transformation matrix \(\mathbf{T}\)
The balanced system is therefore of the form:
Warning
This function may be less computationally efficient than the balreal
Matlab implementation and does not offer the option to bound the realisation
in frequency and time.
Notes
Lyapunov equations are solved using Barlets-Stewart algorithm for Sylvester equation, which is based on A matrix Schur decomposition.
param A: | Plant Matrix |
---|---|
type A: | np.ndarray |
param B: | Input Matrix |
type B: | np.ndarray |
param C: | Output Matrix |
type C: | np.ndarray |
param DLTI: | Discrete time state-space flag |
type DLTI: | bool |
param Schur: | Use Schur decomposition to solve the Lyapunov equations |
type Schur: | bool |
returns: |
|
rtype: | tuple of np.ndarrays |
References
Anthoulas, A.C.. Approximation of Large Scale Dynamical Systems. Chapter 7. Advances in Design and Control. SIAM. 2005.
Find balanced realisation of DLTI system.
Notes
Lyapunov equations are solved using iterative squared Smith algorithm, in its low or full rank version. These implementations are as per the low_rank_smith and smith_iter functions respectively but, for computational efficiency, the iterations are rewritten here so as to solve for the observability and controllability Gramians contemporary.
Exploiting sparsity:
This algorithm is not ideal to exploit sparsity. However, the following strategies are implemented:
- if the A matrix is provided in sparse format, the powers of A will be calculated exploiting sparsity UNTIL the number of non-zero elements is below 15% the size of A. Upon this threshold, the cost of the matrix multiplication rises dramatically, and A is hence converted to a dense numpy array.
Find balanced realisation of DLTI system.
Notes: Lyapunov equations are solved using iterative squared Smith algorithm, in its low or full rank version. These implementations are as per the low_rank_smith and smith_iter functions respectively but, for computational efficiency,, the iterations are rewritten here so as to solve for the observability and controllability Gramians contemporary.
Checks the stability of the system.
param A: | System plant matrix |
---|---|
type A: | np.ndarray |
param dt: | Discrete time system |
type dt: | bool |
returns: | True if the system is stable |
rtype: | bool |
Eigen decomposition of state-space model (either discrete or continuous time) defined by the A,B,C matrices. Eigen-states are organised in decreasing damping order or increased frequency order such that the truncation
A[:N,:N], B[:N,:], C[:,:N]
will retain the least N damped (or lower frequency) modes.
If the eigenvalues of A, eigs, are complex, the state-space is automatically convert into real by separating its real and imaginary part. This procedure retains the minimal number of states as only 2 equations are added for each pair of complex conj eigenvalues. Extra care is however required when truncating the system, so as to ensure that the chosen value of N does not retain the real part, but not the imaginary part, of a complex pair.
For this reason, the function also returns an optional output, Nlist
, such
that, for each N in Nlist, the truncation
A[:N,:N], B[:N,:], C[:,:N]
does guarantee that both the real and imaginary part of a complex conj pair
is included in the truncated model. Note that if `order_by == None
, the eigs
and UR must be given in input and must be such that complex pairs are stored
consecutively.
param A: | state-space matrix |
---|---|
param B: | state-space matrix |
param C: | matrices of state-space model |
param dlti: | specifies whether discrete (True) or continuous-time. This information is only required to order the eigenvalues in decreasing dmaping order |
param N: | number of states to retain. If None, all states are retained |
param eigs,Ur: | eigenvalues and right eigenvector of A matrix as given by: eigs,Ur=scipy.linalg.eig(A,b=None,left=False,right=True) |
param Urinv: | inverse of Ur |
param order_by={‘damp’,’freq’,’stab’}: | |
order according to increasing damping (damp) | |
param or decreasing frequency: | |
If None, the same order as eigs/UR is followed. | |
type or decreasing frequency: | |
freq) or decreasing damping (stab | |
param tol: | absolute tolerance used to identify complex conj pair of eigenvalues |
param complex: | if true, the system is left in complex form |
Returns: (Aproj,Bproj,Cproj): state-space matrices projected over the first N (or N+1
if N removes the imaginary part equations of a complex conj pair of eigenvalues) related to the least damped modes
Nlist: list of acceptable truncation values
Returns gauss-legendre frequency grid (kv of length Npart*order) and weights (wv) for Gramians integration.
The integration grid is divided into Npart partitions, and in each of them integration is performed using a Gauss-Legendre quadrature of order order.
Note: integration points are never located at k0 or kend, hence there is no need for special treatment as in (for e.g.) a uniform grid case (see get_unif_weights)
Returns uniform frequency grid (kv of length Nk) and weights (wv) for Gramians integration using trapezoidal rule. If knyq is True, it is assumed that kend is also the Nyquist frequency.
- Low-rank smith algorithm for Stein equation
- A.T X A - X = -Q Q.T
The algorithm can only be used if T is symmetric positive-definite, but this is not checked in this routine for computational performance. The solution X is provided in its factorised form:
X=Z Z.T
As in the most general case, a solution X exists only if the eigenvalues of S are stricktly smaller than one, and the algorithm will not converge otherwise. The algorithm can not exploits parsity, hence, while convergence can be improved for very large matrices, it can not be employed if matrices are too large to be stored in memory.
Parameters: - tol: tolerance for stopping convergence of Smith algorithm - Square: if true the squared-Smith algorithm is used - tolSVD: tolerance for reduce Z matrix based on singular values - kmax: if given, the Z matrix is forced to have size kmax - tolAbs: if True, the tolerance - fullOut: not implemented - Convergence: ‘Zk’,’res’.
- If ‘Zk’ the iteration is stopped when the inf norm of the incremental
matrix goes below tol. - If ‘res’ the residual of the Lyapunov equation is computed. This strategy may fail to converge if kmax is too low or tolSVD too large!
Ref. P. Benner, G.E. Khoury and M. Sadkane, “On the squared Smith method for large-scale Stein equations”, 2014.
Produces a reduced order model with N states from balanced or modal system SSb. Both “truncation” and “residualisation” methods are employed.
Note: - this method is designed for small size systems, i.e. a deep copy of SSb is produced by default.
- Provides residual of discrete Lyapunov equation:
- A.T X A - X = -Q Q.T
- If Factorised option is true,
- X=Z*Z.T
otherwise X=Z is chosen.
Reminder: contr: A W A.T - W = - B B.T obser: A.T W A - W = - C.T C
- Solves the Stein equation
- S.T X S - X = -T
by mean of Smith or squared-Smith algorithm. Note that a solution X exists only if the eigenvalues of S are stricktly smaller than one, and the algorithm will not converge otherwise. The algorithm can not exploit sparsity, hence, while convergence can be improved for very large matrices, it can not be employed if matrices are too large to be stored in memory.
Ref. Penzt, “A cyclic low-rank Smith method for large sparse Lyapunov equations”, 2000.
Starting from a balanced DLTI, this function determines the number of states N required in a ROM (obtained either through ‘residualisation’ or ‘truncation’ as specified in method - see also librom.modred) to match the frequency response of SSb over the frequency array, kv, with absolute accuracy tol. gv contains the balanced system Hankel singular value, and is used to determine the upper bound for the ROM order N.
Unless kv does not conver the full Nyquist frequency range, the ROM accuracy is not guaranteed to increase monothonically with the number of states. To account for this, two criteria can be used to determine the ROM convergence:
- convergence=’all’: in this case, the number of ROM states N is chosen
such that any ROM of order greater than N produces an error smaller than tol. To guarantee this the ROM frequency response is computed for all N<=Nb, where Nb is the number of balanced states. This method is numerically inefficient.
- convergence=’min’: atempts to find the minimal number of states to
achieve the accuracy tol.
Note: - the input state-space model, SSb, must be balanced. - the routine in not implemented for numerical efficiency and assumes that SSb is small.
Methods for the interpolation of DLTI ROMs¶
This is library for state-space models interpolation. These routines are intended for small size state-space models (ROMs), hence some methods may not be optimised to exploit sparsity structures. For generality purposes, all methods require in input interpolatory weights.
The module includes the methods:
transfer_function()
: returns an interpolatory state-space model based on the transfer function method [1]. This method is general and is, effectively, a wrapper of thesharpy.linear.src.libss.join()
method.BT_transfer_function()
: evolution of transfer function methods. The growth of the interpolated system size is avoided through balancing.
References:
[1] Benner, P., Gugercin, S. & Willcox, K., 2015. A Survey of Projection-Based Model Reduction Methods for Parametric Dynamical Systems. SIAM Review, 57(4), pp.483–531.
Author: S. Maraniello
Date: Mar-Apr 2019
Returns an interpolatory state-space model based on the transfer function method [1]. This method is applicable to frequency limited balanced state-space models only.
Features:
- stability preserved
- the interpolated state-space model has the same size than the tabulated ones
- all state-space models, need to have the same size and the same numbers of hankel singular values.
- suitable for any ROM
param SS_list: | List of state-space models instances of |
---|---|
type SS_list: | list |
param wv: | list of interpolatory weights. |
type wv: | list |
param U_list: | small size, thin SVD factors of Gramians square roots of each state space model (\(\mathbf{U}\)). |
type U_list: | list |
param VT_list: | small size, thin SVD factors of Gramians square roots of each state space model (\(\mathbf{V}^\top\)). |
type VT_list: | list |
param hsv_list: | small size, thin SVD factors of Gramians square roots of each state space model. If
where |
type hsv_list: | list |
param M_list: | for fast on-line evaluation. Small size product of Gramians
factors of each state-space model. Each element of this list is equal to:
|
type M_list: | list |
Notes
Message for future generations:
- the implementation is divided into an offline and online part.
References:
Maraniello S. and Palacios R., Frequency-limited balanced truncation for parametric reduced-order modelling of the UVLM. Only in the best theaters.
See also
Frequency-Limited Balanced ROMs may be obtained from SHARPy using sharpy.rom.balanced.FrequencyLimited
.
State-space 1D interpolation class.
This class allows interpolating from a list of state-space models, SS.
State-space models are required to have the same number of inputs and outputs and need to have the same number of states.
For state-space interpolation, state-space models also need to be defined over the same set of generalised coordinates. If this is not the case, the projection matrices W and V used to produce the ROMs, ie
\[\mathbf{A}_{proj} = \mathbf{W}^\top \mathbf{A V}\]where A is the full-states matrix, also need to be provided. This will allow projecting the state-space models onto a common set of generalised coordinates before interpoling.
For development purposes, the method currently creates a hard copy of the projected matrices into the self.AA, self.BB, self.CC lists
Inputs:
SS: list of state-space models (instances of libss.ss class)
VV: list of V matrices used to produce SS. If None, it is assumed that ROMs are defined over the same basis
WWT: list of W^T matrices used to derive the ROMs.
Vref, WTref: reference subspaces for projection. Some methods neglect this input (e.g. panzer)
method_proj: method for projection of state-space models over common coordinates. Available options are:
leastsq: find left/right projectors using least squares approx. Suitable for all basis.
strongMAC: strong Modal Assurance Criterion [4] enforcement for general basis. See Ref. [3], Eq. (7)
strongMAC_BT: strong Modal Assurance Criterion [4] enforcement for basis obtained by Balanced Truncation. Equivalent to strongMAC
maraniello_BT: this is equivalent to strongMAC and strongMAC_BT but avoids inversions. However, performance are the same as other strongMAC approaches - it works only when basis map the same subspaces
weakMAC_right_orth: weak MAC enforcement [1,3] for state-space models with right orthonoraml basis, i.e. V.T V = I. This is like Ref. [1], but implemented only on one side.
weakMAC: implementation of weak MAC enforcement for a general system. The method orthonormalises the right basis (V) and then solves the orthogonal Procrustes problem.
for orthonormal basis (V.T V = I): !!! These methods are not tested !!!
- panzer: produces a new reference point based on svd [2]
- amsallem: project over Vref,WTref [1]
References:
[1] D. Amsallem and C. Farhat, An online method for interpolating linear parametric reduced-order models, SIAM J. Sci. Comput., 33 (2011), pp. 2169–2198.
[2] Panzer, J. Mohring, R. Eid, and B. Lohmann, Parametric model order reduction by matrix interpolation, at–Automatisierungstechnik, 58 (2010), pp. 475–484.
[3] Mahony, R., Sepulchre, R. & Absil, P. -a., 2004. Riemannian Geometry of Grassmann Manifolds with a View on Algorithmic Computation. Acta Applicandae Mathematicae, 80(2), pp.199–220.
[4] Geuss, M., Panzer, H. & Lohmann, B., 2013. On parametric model order reduction by matrix interpolation. 2013 European Control Conference (ECC), pp.3433–3438.
Project the state-space models onto the generalised coordinates of state-space model IImap
Returns an interpolatory state-space model based on the transfer function
method [1]. This method is general and is, effectively, a wrapper of the
sharpy.linear.src.libss.join()
method.
Features:
- stability preserved
- system size increases with interpolatory order, but can be optimised for fast on-line evaluation
param SS_list: | List of state-space models instances of sharpy.linear.src.libss.ss class. |
---|---|
type SS_list: | list |
param wv: | list of interpolatory weights. |
type wv: | list |
Notes
For fast online evaluation, this routine can be optimised to return a class that handles each state-space model independently. See ref. [1] for more details.
References
[1] Benner, P., Gugercin, S. & Willcox, K., 2015. A Survey of Projection-Based Model Reduction Methods for Parametric Dynamical Systems. SIAM Review, 57(4), pp.483–531.
Structural Packages¶
Models¶
Element¶
This class stores all the required data for the definition of a linear or quadratic beam element.
Generates two unit vectors in body FoR that define the local FoR for a beam element. These vectors are calculated using frame_of_reference_delta :return:
Utils¶
LagrangeConstraints library¶
LagrangeConstraints library
Library used to create the matrices associate to boundary conditions through the method of Lagrange Multipliers
Args:
Returns:
- Examples:
- To use this library: import sharpy.structure.utils.lagrangeconstraints as lagrangeconstraints
Notes:
define_FoR_dof
Define the position of the first degree of freedom associated to a certain frame of reference
param MB_beam: | list of ‘Beam’ |
---|---|
type MB_beam: | list |
param node_body: | |
body to which the node belongs | |
type node_body: | int |
param num_node: | number os the node within the body |
type num_node: | int |
returns: | first degree of freedom associated to the node |
rtype: | node_dof(int) |
Examples:
Notes:
define_node_dof
Define the position of the first degree of freedom associated to a certain node
param MB_beam: | list of ‘Beam’ |
---|---|
type MB_beam: | list |
param node_body: | |
body to which the node belongs | |
type node_body: | int |
param num_node: | number os the node within the body |
type num_node: | int |
returns: | first degree of freedom associated to the node |
rtype: | node_dof(int) |
Examples:
Notes:
define_num_LM_eq
Define the number of equations needed to define the boundary boundary conditions
param lc_list(): | |
---|---|
list of all the defined contraints | |
returns: | number of new equations needed to define the boundary boundary conditions |
rtype: | num_LM_eq(int) |
Examples
num_LM_eq = lagrangeconstraints.define_num_LM_eq(lc_list)
Notes:
generate_lagrange_matrix
Generates the matrices associated to the Lagrange multipliers boundary conditions
param lc_list(): | |
---|---|
list of all the defined contraints | |
param MBdict: | dictionary with the MultiBody and LagrangeMultipliers information |
type MBdict: | MBdict |
param MB_beam: | list of ‘beams’ of each of the bodies that form the system |
type MB_beam: | list |
param MB_tstep: | list of ‘StructTimeStepInfo’ of each of the bodies that form the system |
type MB_tstep: | list |
param num_LM_eq: | |
number of new equations needed to define the boundary boundary conditions | |
type num_LM_eq: | int |
param sys_size: | total number of degrees of freedom of the multibody system |
type sys_size: | int |
param dt: | time step |
type dt: | float |
param Lambda: | list of Lagrange multipliers values |
type Lambda: | numpy array |
param Lambda_dot: | |
list of the first derivative of the Lagrange multipliers values | |
type Lambda_dot: | |
numpy array | |
param dynamic_or_static: | |
string defining if the computation is dynamic or static | |
type dynamic_or_static: | |
str | |
returns: | Damping matrix associated to the Lagrange Multipliers equations LM_K (numpy array): Stiffness matrix associated to the Lagrange Multipliers equations LM_Q (numpy array): Vector of independent terms associated to the Lagrange Multipliers equations |
rtype: | LM_C (numpy array) |
Examples:
Notes:
get_mode_zeta¶
Retrieves the UVLM grid nodal displacements associated to the eigenvector eigvect
scale_mode¶
- Scales the eigenvector such that:
- the maximum change in component of the beam cartesian rotation vector
- is equal to rot_max_deg degrees.
- the maximum translational displacement does not exceed perc_max the
maximum nodal position.
Warning
If the eigenvector is in state-space form, only the first half of the eigenvector is scanned for determining the scaling.
write_modes_vtk¶
Writes a vtk file for each of the first NumLambda
eigenvectors. When these
are associated to the state-space form of the structural equations, only
the displacement field is saved.
write_zeta_vtk¶
Given a list of arrays representing the coordinates of a set of n_surf UVLM lattices and organised as:
zeta[n_surf][3,M+1,N=1]
this function writes a vtk for each of the n_surf surfaces.
- Input:
- zeta: lattice coordinates to plot
- zeta_ref: reference lattice used to compute the magnitude of displacements
- filename_root: initial part of filename (full path) without file
extension (.vtk)
Xbopts¶
cbeam3_asbly_dynamic¶
Used by autodoc_mock_imports.
cbeam3_asbly_static¶
Used by autodoc_mock_imports.
cbeam3_correct_gravity_forces¶
Used by autodoc_mock_imports.
cbeam3_loads¶
Used by autodoc_mock_imports.
cbeam3_solv_modal¶
Used by autodoc_mock_imports.
cbeam3_solv_nlnstatic¶
Used by autodoc_mock_imports.
xbeam3_asbly_dynamic¶
Used by autodoc_mock_imports.
Utilities¶
Algebra package¶
Algebra package
Extensive library with geometrical and algebraic operations
- Note:
- Tests can be found in
tests/utils/algebra_test
cross3¶
Computes the cross product of two vectors (v and w) with size 3
crv2quat¶
Converts a Cartesian rotation vector,
\[\vec{\psi} = \psi\,\mathbf{\hat{n}}\]
into a “minimal rotation” quaternion, i.e. being the quaternion, \(\vec{\chi}\), defined as:
\[\vec{\chi}= \left[\cos\left(\frac{\psi}{2}\right),\, \sin\left(\frac{\psi}{2}\right)\mathbf{\hat{n}}\right]\]
the rotation axis, \(\mathbf{\hat{n}}\) is such that the rotation angle, \(\psi\), is in \([-\pi,\,\pi]\) or, equivalently, \(\chi_0\ge0\).
param psi: | Cartesian Rotation Vector, CRV: \(\vec{\psi} = \psi\,\mathbf{\hat{n}}\). |
---|---|
type psi: | np.array |
returns: | equivalent quaternion \(\vec{\chi}\) |
rtype: | np.array |
crv2rotation¶
Given a Cartesian rotation vector, \(\boldsymbol{\Psi}\), the function produces the rotation matrix required to rotate a vector according to \(\boldsymbol{\Psi}\).
The rotation matrix is given by
To avoid the singularity when \(||\boldsymbol{\Psi}||=0\), the series expansion is used
param psi: | Cartesian rotation vector \(\boldsymbol{\Psi}\). |
---|---|
type psi: | np.array |
returns: | equivalent rotation matrix |
rtype: | np.array |
References
Geradin and Cardona, Flexible Multibody Dynamics: A finite element approach. Chapter 4
crv2tan¶
Returns the tangential operator, \(\mathbf{T}(\boldsymbol{\Psi})\), that is a function of the Cartesian Rotation Vector, \(\boldsymbol{\Psi}\).
When the norm of the CRV approaches 0, the series expansion expression is used in-lieu of the above expression
param psi: | Cartesian Rotation Vector, \(\boldsymbol{\Psi}\). |
---|---|
type psi: | np.array |
returns: | Tangential operator |
rtype: | np.array |
References
Geradin and Cardona. Flexible Multibody Dynamics: A Finite Element Approach. Chapter 4.
crv_bounds¶
Forces the Cartesian rotation vector norm, \(\|\vec{\psi}\|\), to be in the range \([-\pi,\pi]\), i.e. determines the rotation axis orientation, \(\mathbf{\hat{n}}\), so as to ensure “minimal rotation”.
param crv_ini: | Cartesian rotation vector, \(\vec{\psi}\) |
---|---|
type crv_ini: | np.array |
returns: | modified and bounded, equivalent Cartesian rotation vector |
rtype: | np.array |
der_CcrvT_by_v¶
Being C=C(fv0) the rotation matrix depending on the Cartesian rotation vector fv0 and defined as C=crv2rotation(fv0), the function returns the derivative, w.r.t. the CRV components, of the vector dot(C.T,v), where v is a constant vector.
The elements of the resulting derivative matrix D are ordered such that:
where \(d(.)\) is a delta operator.
der_Ccrv_by_v¶
Being C=C(fv0) the rotational matrix depending on the Cartesian rotation vector fv0 and defined as C=crv2rotation(fv0), the function returns the derivative, w.r.t. the CRV components, of the vector dot(C,v), where v is a constant vector.
The elements of the resulting derivative matrix D are ordered such that:
where \(d(.)\) is a delta operator.
der_Ceuler_by_v¶
Provides the derivative of the product between the rotation matrix \(C^{AG}(\mathbf{\Theta})\) and a constant vector, \(\mathbf{v}\), with respect to the Euler angles, \(\mathbf{\Theta}=[\phi,\theta,\psi]^T\):
where \(\frac{\partial \mathbf{f}}{\partial\mathbf{\Theta}}\) is the resulting 3 by 3 matrix.
Being \(C^{AG}(\Theta)\) the rotation matrix from the G frame to the A frame in terms of the Euler angles \(\Theta\) as:
the components of the derivative at hand are the following, where \(f_{1\theta} = \frac{\partial \mathbf{f}_1}{\partial\theta}\).
param euler: | Vector of Euler angles, \(\mathbf{\Theta} = [\phi, \theta, \psi]\), in radians. |
---|---|
type euler: | np.ndarray |
param v: | 3 dimensional vector in G frame. |
type v: | np.ndarray |
returns: | Resulting 3 by 3 matrix \(\frac{\partial \mathbf{f}}{\partial\mathbf{\Theta}}\). |
rtype: | np.ndarray |
der_Ceuler_by_v_NED¶
Provides the derivative of the product between the rotation matrix \(C^{AG}(\mathbf{\Theta})\) and a constant vector, \(\mathbf{v}\), with respect to the Euler angles, \(\mathbf{\Theta}=[\phi,\theta,\psi]^T\):
where \(\frac{\partial \mathbf{f}}{\partial\mathbf{\Theta}}\) is the resulting 3 by 3 matrix.
Being \(C^{AG}(\Theta)\) the rotation matrix from the G frame to the A frame in terms of the Euler angles \(\Theta\) as:
the components of the derivative at hand are the following, where \(f_{1\theta} = \frac{\partial \mathbf{f}_1}{\partial\theta}\).
Note
This function is defined in a North East Down frame which is not the typically used one in SHARPy.
param euler: | Vector of Euler angles, \(\mathbf{\Theta} = [\phi, \theta, \psi]\), in radians. |
---|---|
type euler: | np.ndarray |
param v: | 3 dimensional vector in G frame. |
type v: | np.ndarray |
returns: | Resulting 3 by 3 matrix \(\frac{\partial \mathbf{f}}{\partial\mathbf{\Theta}}\). |
rtype: | np.ndarray |
der_CquatT_by_v¶
Returns the derivative with respect to quaternion components of a projection matrix times a constant vector.
Being \(\mathbf{C}=\mathbf{R}(\boldsymbol{\chi})^\top\) the projection matrix depending on the quaternion
\(\boldsymbol{\chi}\) and obtained through the function
defined as C=quat2rotation(q).T
, this function returns the derivative with respect to the
quaternion components, of the vector \((\mathbf{C\cdot v})\), where \(\mathbf{v}\) is a constant
vector.
The derivative operation is defined as:
where, for simplicity, we define
and \(\delta(\bullet)\) is a delta operator.
The members of \(\mathbf{D}\) are the following:
returns: | \(\mathbf{D}\) matrix. |
---|---|
rtype: | np.array |
der_Cquat_by_v¶
Being C=C(quat) the rotational matrix depending on the quaternion q and defined as C=quat2rotation(q), the function returns the derivative, w.r.t. the quanternion components, of the vector dot(C,v), where v is a constant vector.
The elements of the resulting derivative matrix D are ordered such that:
where \(d(.)\) is a delta operator.
der_Peuler_by_v¶
Provides the derivative of the product between the projection matrix \(P^{AG}(\mathbf{\Theta})\) (that projects a vector in G frame onto A frame) and a constant vector expressed in G frame of reference, \(\mathbf{v}_G\), with respect to the Euler angles, \(\mathbf{\Theta}=[\phi,\theta,\psi]^T\):
where \(\frac{\partial \mathbf{f}}{\partial\mathbf{\Theta}}\) is the resulting 3 by 3 matrix.
Being \(P^{AG}(\Theta)\) the projection matrix from the G frame to the A frame in terms of the Euler angles \(\Theta\) as \(P^{AG}(\Theta) = \tau_x(-\Phi)\tau_y(-\Theta)\tau_z(-\Psi)\), where the rotation matrix is expressed as:
and the projection matrix as:
the components of the derivative at hand are the following, where \(f_{1\theta} = \frac{\partial \mathbf{f}_1}{\partial\theta}\).
param euler: | Vector of Euler angles, \(\mathbf{\Theta} = [\phi, \theta, \psi]\), in radians. |
---|---|
type euler: | np.ndarray |
param v: | 3 dimensional vector in G frame. |
type v: | np.ndarray |
returns: | Resulting 3 by 3 matrix \(\frac{\partial \mathbf{f}}{\partial\mathbf{\Theta}}\). |
rtype: | np.ndarray |
der_TanT_by_xv¶
Being fv0 a cartesian rotation vector and Tan the corresponding tangential operator (computed through crv2tan(fv)), the function returns the derivative of dot(Tan^T,xv), where xv is a constant vector.
The elements of the resulting derivative matrix D are ordered such that:
where \(d(.)\) is a delta operator.
Note
The derivative expression has been derived symbolically and verified by FDs. A more compact expression may be possible.
der_Tan_by_xv¶
Being fv0 a cartesian rotation vector and Tan the corresponding tangential operator (computed through crv2tan(fv)), the function returns the derivative of dot(Tan,xv), where xv is a constant vector.
The elements of the resulting derivative matrix D are ordered such that:
where \(d(.)\) is a delta operator.
Note
The derivative expression has been derived symbolically and verified by FDs. A more compact expression may be possible.
der_Teuler_by_w¶
Calculates the matrix
from the linearised euler propagation equations
where \(T^{GA}\) is the nonlinear relation between the euler angle rates and the rotational velocities and is
provided by deuler_dt()
.
The concerned matrix is calculated as follows:
Note
This function is defined in a North East Down frame which is not the typically used one in SHARPy.
param euler: | Euler angles at the linearisation point \(\mathbf{\Theta}_0 = [\phi,\theta,\psi]\) or roll, pitch and yaw angles, respectively. |
---|---|
type euler: | np.ndarray |
param w: | Rotational velocities at the linearisation point in A frame \(\omega^A_0\). |
type w: | np.ndarray |
returns: | Computed \(\frac{\partial}{\partial\Theta}\left.\left(T^{GA}(\mathbf{\Theta})\mathbf{\omega}^A\right)\right|_{\Theta_0,\omega^A_0}\) |
rtype: | np.ndarray |
der_Teuler_by_w_NED¶
Warning
Based on a NED G frame
Calculates the matrix
from the linearised euler propagation equations
where \(T^{GA}\) is the nonlinear relation between the euler angle rates and the rotational velocities and is
provided by deuler_dt()
.
The concerned matrix is calculated as follows:
param euler: | Euler angles at the linearisation point \(\mathbf{\Theta}_0 = [\phi,\theta,\psi]\) or roll, pitch and yaw angles, respectively. |
---|---|
type euler: | np.ndarray |
param w: | Rotational velocities at the linearisation point in A frame \(\omega^A_0\). |
type w: | np.ndarray |
returns: | Computed \(\frac{\partial}{\partial\Theta}\left.\left(T^{GA}(\mathbf{\Theta})\mathbf{\omega}^A\right)\right|_{\Theta_0,\omega^A_0}\) |
rtype: | np.ndarray |
der_quat_wrt_crv¶
Provides change of quaternion, dquat, due to elementary rotation, dcrv, expressed as a 3 components Cartesian rotation vector such that
where C are rotation matrices.
Examples
- Assume 3 FoRs, G, A and B where:
G is the initial FoR
quat0 defines te rotation required to obtain A from G, namely: Cga=quat2rotation(quat0)
dcrv is an inifinitesimal Cartesian rotation vector, defined in A components, which describes an infinitesimal rotation A -> B, namely:
..math :: Cab=crv2rotation(dcrv)
- The total rotation G -> B is:
Cga = Cga * Cab
As dcrv -> 0, Cga is equal to:
\[algebra.quat2rotation(quat0 + dquat),\]where dquat is the output of this function.
deuler_dt¶
Rate of change of the Euler angles in time for a given angular velocity in A frame \(\omega^A=[p, q, r]\).
param euler: | Euler angles \([\phi, \theta, \psi]\) for roll, pitch and yaw, respectively. |
---|---|
type euler: | np.ndarray |
returns: | Propagation matrix relating the rotational velocities to the euler angles. |
rtype: | np.ndarray |
deuler_dt_NED¶
Warning
Based on a NED frame
Rate of change of the Euler angles in time for a given angular velocity in A frame \(\omega^A=[p, q, r]\).
Note
This function is defined in a North East Down frame which is not the typically used one in SHARPy.
param euler: | Euler angles \([\phi, \theta, \psi]\) for roll, pitch and yaw, respectively. |
---|---|
type euler: | np.ndarray |
returns: | Propagation matrix relating the rotational velocities to the euler angles. |
rtype: | np.ndarray |
euler2quat¶
param euler: | Euler angles |
---|---|
returns: | Equivalent quaternion. |
rtype: | np.ndarray |
euler2rot¶
Transforms Euler angles (roll, pitch and yaw \(\Phi, \Theta, \Psi\)) into a 3x3 rotation matrix describing that rotates a vector in yaw pitch, and roll.
The rotations are performed successively, first in yaw, then in pitch and finally in roll.
where \(\mathbf{\tau}\) represents the rotation about the subscripted axis.
param euler: | 1x3 array with the Euler angles in the form [roll, pitch, yaw] in radians |
---|---|
type euler: | np.array |
returns: | 3x3 transformation matrix describing the rotation by the input Euler angles. |
rtype: | np.array |
get_triad¶
Generates two unit vectors in body FoR that define the local FoR for a beam element. These vectors are calculated using frame_of_reference_delta :return:
mat2quat¶
Rotation matrix to quaternion function.
Warning
This function is deprecated and now longer supported. Please use algebra.rotation2quat(rot.T)
instead.
param rot: | Rotation matrix |
---|---|
returns: | equivalent quaternion |
rtype: | np.array |
multiply_matrices¶
multiply_matrices
Multiply a series of matrices from left to right
param *argv: | series of numpy arrays |
---|---|
returns: | product of all the given matrices |
rtype: | sol(numpy array) |
Examples
solution = multiply_matrices(A, B, C)
norm3d¶
Norm of a 3D vector
Notes
Faster than np.linalg.norm
param v: | 3D vector |
---|---|
type v: | np.ndarray |
returns: | Norm of the vector |
rtype: | np.ndarray |
normsq3d¶
Square of the norm of a 3D vector
param v: | 3D vector |
---|---|
type v: | np.ndarray |
returns: | Square of the norm of the vector |
rtype: | np.ndarray |
quadskew¶
Generates the matrix needed to obtain the quaternion in the following time step through integration of the FoR angular velocity.
param vector: | FoR angular velocity |
---|---|
type vector: | np.array |
Notes
The angular velocity is assumed to be constant in the time interval Equivalent to lib_xbeam function Quaternion ODE to compute orientation of body-fixed frame a See Shearer and Cesnik (2007) for definition
returns: | matrix |
---|---|
rtype: | np.array |
quat2euler¶
Quaternion to Euler angles transformation.
Transforms a normalised quaternion \(\chi\longrightarrow[\phi, \theta, \psi]\) to roll, pitch and yaw angles respectively.
The transformation is valid away from the singularity present at:
where \(\Delta = q_0 q_2 - q_1 q_3\).
The transformation is carried out as follows:
param quat: | Normalised quaternion. |
---|---|
type quat: | np.ndarray |
returns: | Array containing the Euler angles \([\phi, \theta, \psi]\) for roll, pitch and yaw, respectively. |
rtype: | np.ndarray |
References
Blanco, J.L. - A tutorial on SE(3) transformation parameterizations and on-manifold optimization. Technical Report 012010. ETS Ingenieria Informatica. Universidad de Malaga. 2013.
quat2rotation¶
Calculate rotation matrix based on quaternions.
If B is a FoR obtained rotating a FoR A by an angle \(\phi\) about an axis \(\mathbf{n}\) (recall \(\mathbf{n}\) will be invariant during the rotation), and \(\mathbf{q}\) is the related quaternion, \(\mathbf{q}(\phi,\mathbf{n})\), the function will return the matrix \(C^{AB}\) such that:
- \(C^{AB}\) rotates FoR A onto FoR B.
- \(C^{AB}\) transforms the coordinates of a vector defined in B component to A components i.e. \(\mathbf{v}^A = C^{AB}(\mathbf{q})\mathbf{v}^B\).
Notes
The inverse rotation is defined as the transpose of the matrix \(C^{BA} = C^{{AB}^T}\).
In typical SHARPy applications, the quaternion relation between the A and G frames is expressed as \(C^{GA}(\mathbf{q})\), and in the context of this function it corresponds to:
>>> C_ga = quat2rotation(q1)
>>> C_ag = quat2rotation.T(q1)
param q: | Quaternion \(\mathbf{q}(\phi, \mathbf{n})\). |
---|---|
type q: | np.ndarray |
returns: | \(C^{AB}\) rotation matrix from FoR B to FoR A. |
rtype: | np.ndarray |
References
Stevens, L. Aircraft Control and Simulation. 1985. pg 41
quat_bound¶
Given a quaternion, \(\vec{\chi}\), associated to a rotation of angle \(\psi\) about an axis \(\mathbf{\hat{n}}\), the function “bounds” the quaternion, i.e. sets the rotation axis \(\mathbf{\hat{n}}\) such that \(\psi\) in \([-\pi,\pi]\).
Notes
As quaternions are defined as:
\[\vec{\chi}= \left[\cos\left(\frac{\psi}{2}\right),\, \sin\left(\frac{\psi}{2}\right)\mathbf{\hat{n}}\right]\]
this is equivalent to enforcing \(\chi_0\ge0\).
param quat: | quaternion to bound |
---|---|
type quat: | np.array |
returns: | bounded quaternion |
rtype: | np.array |
rotation2crv¶
Given a rotation matrix \(C^{AB}\) rotating the frame A onto B, the function returns the minimal size Cartesian rotation vector, \(\vec{\psi}\) representing this rotation.
param Cab: | rotation matrix \(C^{AB}\) |
---|---|
type Cab: | np.array |
returns: | equivalent Cartesian rotation vector, \(\vec{\psi}\). |
rtype: | np.array |
Notes
this is the inverse of algebra.crv2rotation
for Cartesian rotation vectors
associated to rotations in the range \([-\pi,\,\pi]\), i.e.:
fv == algebra.rotation2crv(algebra.crv2rotation(fv))
for each Cartesian rotation vector of the form \(\vec{\psi} = \psi\,\mathbf{\hat{n}}\)
represented as fv=a*nv
such that nv
is a unit vector and the scalar a
is in the
range \([-\pi,\,\pi]\).
rotation2quat¶
Given a rotation matrix \(C^{AB}\) rotating the frame A onto B, the function returns the minimal “positive angle” quaternion representing this rotation, where the quaternion, \(\vec{\chi}\) is defined as:
\[\vec{\chi}= \left[\cos\left(\frac{\psi}{2}\right),\, \sin\left(\frac{\psi}{2}\right)\mathbf{\hat{n}}\right]\]
param Cab: | rotation matrix \(C^{AB}\) from frame A to B |
---|---|
type Cab: | np.array |
returns: | equivalent quaternion \(\vec{\chi}\) |
rtype: | np.array |
Notes
This is the inverse of algebra.quat2rotation
for Cartesian rotation vectors
associated to rotations in the range \([-\pi,\pi]\), i.e.:
fv == algebra.rotation2crv(algebra.crv2rotation(fv))
where fv
represents the Cartesian Rotation Vector, \(\vec{\psi}\) defined as:
\[\vec{\psi} = \psi\,\mathbf{\hat{n}}\]
such that \(\mathbf{\hat{n}}\) is a unit vector and the scalar \(\psi\) is in the range \([-\pi,\,\pi]\).
rotation3d_x¶
Rotation matrix about the x axis by the input angle \(\Phi\)
param angle: | angle of rotation in radians about the x axis |
---|---|
type angle: | float |
returns: | 3x3 rotation matrix about the x axis |
rtype: | np.array |
rotation3d_y¶
Rotation matrix about the y axis by the input angle \(\Theta\)
param angle: | angle of rotation in radians about the y axis |
---|---|
type angle: | float |
returns: | 3x3 rotation matrix about the y axis |
rtype: | np.array |
rotation3d_z¶
Rotation matrix about the z axis by the input angle \(\Psi\)
param angle: | angle of rotation in radians about the z axis |
---|---|
type angle: | float |
returns: | 3x3 rotation matrix about the z axis |
rtype: | np.array |
skew¶
Returns a skew symmetric matrix such that
where
param vector: | 3-dimensional vector |
---|---|
type vector: | np.ndarray |
returns: | Skew-symmetric matrix. |
rtype: | np.array |
tangent_vector¶
Tangent vector calculation for 2+ noded elements.
Calculates the tangent vector interpolating every dimension separately. It uses a (n_nodes - 1) degree polynomial, and the differentiation is analytical.
Calculation method:
- A n_nodes-1 polynomial is fitted through the nodes per dimension.
- Those polynomials are analytically differentiated with respect to the node index
- The tangent vector is given by:
\[\vec{t} = \frac{s_x'\vec{i} + s_y'\vec{j} + s_z'\vec{k}}{\left| s_x'\vec{i} + s_y'\vec{j} + s_z'\vec{k}\right|}\]where \('\) notes the differentiation with respect to the index number
param in_coord: | array of coordinates of the nodes. Dimensions = [n_nodes, ndim] |
---|---|
type in_coord: | np.ndarray |
Notes
Dimensions are treated independent from each other, interpolating polynomials are computed individually.
triad2rotation¶
If the input triad is the “b” coord system given in “a” frame, (the vectors of the triad are xb, yb, zb), this function returns Rab, ie the rotation matrix required to rotate the FoR A onto B. :param xb: :param yb: :param zb: :return: rotation matrix Rab
unit_vector¶
Transforms the input vector into a unit vector
param vector: | vector to normalise |
---|---|
type vector: | np.array |
returns: | unit vector |
rtype: | np.array |
Analytical Functions¶
Analytical solutions for 2D aerofoil based on thin plates theory
Author: Salvatore Maraniello
Date: 23 May 2017
References:
- Simpson, R.J.S., Palacios, R. & Murua, J., 2013. Induced-Drag Calculations in the Unsteady Vortex Lattice Method. AIAA Journal, 51(7), pp.1775–1779.
- Gulcat, U., 2009. Propulsive Force of a Flexible Flapping Thin Airfoil. Journal of Aircraft, 46(2), pp.465–473.
flat_plate_analytical¶
Computes the analytical frequency response of a plat plate for the input
output sequences in input_seq
and output_seq
over the frequency points kv
,
if available.
The output complex values array Yan
has shape (Nout, Nin, Nk)
; if an analytical
solution is not available, the response is assumed to be zero.
If plunge_deriv
is True
, the plunge response is expressed in terms of first
derivative dh.
param kv: | Frequency range of length |
---|---|
type kv: | np.array |
param x_ea_perc: | |
Elastic axis location along the chord as chord length percentage. |
|
type x_ea_perc: | float |
param x_fh_perc: | |
Flap hinge location along the chord as chord length percentage. |
|
type x_fh_perc: | float |
param input_seq: | |
List of
|
|
type input_seq: | list(str) |
param output_seq: | |
List of
|
|
type output_seq: | |
list(str) |
|
param output_scal: | |
Array of factors by which to divide the desired outputs. Dimensions of |
|
type output_scal: | |
np.array |
|
param plunge_deriv: | |
If |
|
type plunge_deriv: | |
bool |
:param rate of change of plunge \(d\dot{h}\).:
returns: | A (Nout, Nin, Nk) array containing the scaled frequency response for the inputs and outputs
specified. |
---|---|
rtype: | np.array |
See also
The lift coefficient due to pitch and plunging motions is calculated
using sharpy.utils.analytical.theo_CL_freq_resp()
. In turn, the pitching moment is found using
sharpy.utils.analytical.theo_CM_freq_resp()
.
The response to the continuous sinusoidal gust is calculated using
sharpy.utils.analytical.sears_CL_freq_resp()
.
garrick_drag_pitch¶
Returns Garrick solution for drag coefficient at a specific time. Ref.[1], eq.(9), (10) and (11)
The aerofoil pitching motion is assumed to be:
\[a(t)=A\sin(\omegat)=A\sin(ks)\]
The \(C_d\) is such that:
- \(C_d>0\): drag
- \(C_d<0\): suction
garrick_drag_plunge¶
Returns Garrick solution for drag coefficient at a specific time. Ref.[1], eq.(8) (see also eq.(1) and (2)) or Ref[2], eq.(2)
The aerofoil vertical motion is assumed to be:
The \(C_d\) is such that:
- \(C_d>0\): drag
- \(C_d<0\): suction
nc_derivs¶
Provides non-circulatory aerodynamic lift and moment coefficients derivatives Ref. Palacios and Cesnik, Chap 3.
param x_ea_perc: | |
---|---|
position of axis of rotation in percentage of chord (measured from LE) | |
param x_fc_perc: | |
position of flap axis of rotation in percentage of chord (measured from LE) |
qs_derivs¶
Provides quasi-steady aerodynamic lift and moment coefficients derivatives Ref. Palacios and Cesnik, Chap 3.
param x_ea_perc: | |
---|---|
position of axis of rotation in percentage of chord (measured from LE) | |
param x_fc_perc: | |
position of flap axis of rotation in percentage of chord (measured from LE) |
sears_CL_freq_resp¶
Frequency response of lift coefficient according Sear’s solution. Ref. Palacios and Cesnik, Chap.3
sears_fun¶
Produces Sears function
sears_lift_sin_gust¶
Returns the lift coefficient for a sinusoidal gust (see set_gust.sin) as the imaginary part of the CL complex function defined below. The input gust must be the imaginary part of
with:
and xcoord=0
at the aerofoil half-chord.
theo_CL_freq_resp¶
Frequency response of lift coefficient according Theodorsen’s theory.
The output is a 3 elements array containing the CL frequency response w.r.t. to pitch, plunge and flap motion, respectively. Sign conventions are as follows:
- plunge: positive when moving upward
- x_ea_perc: position of axis of rotation in percentage of chord (measured from LE)
- x_fc_perc: position of flap axis of rotation in percentage of chord (measured from LE)
Warning
this function uses different input/output w.r.t. theo_lift
theo_CM_freq_resp¶
Frequency response of moment coefficient according Theodorsen’s theory.
The output is a 3 elements array containing the CL frequency response w.r.t. to pitch, plunge and flap motion, respectively.
theo_fun¶
Returns the value of Theodorsen’s function at a reduced frequency \(k\).
where \(H_0^{(2)}(k)\) and \(H_1^{(2)}(k)\) are Hankel functions of the second kind.
param k: | Reduced frequency/frequencies at which to evaluate the function. |
---|---|
type k: | np.array |
returns: | Value of Theodorsen’s function evaluated at the desired reduced frequencies. |
rtype: | np.array |
theo_lift¶
Theodorsen’s solution for lift of aerofoil undergoing sinusoidal motion.
Time histories are built assuming:
a(t)=+/- A cos(w t) ??? not verified
- \(h(t)=-H\cos(w t)\)
param w: | frequency (rad/sec) of oscillation |
---|---|
param A: | amplitude of angle of attack change |
param H: | amplitude of plunge motion |
param c: | aerofoil chord |
param rhoinf: | flow density |
param uinf: | flow speed |
param x12: | distance of elastic axis from mid-point of aerofoil (positive if the elastic axis is ahead) |
wagner_imp_start¶
Lift coefficient resulting from impulsive start solution.
Controller Utilities¶
PID¶
Class implementing a classic PID controller
Instance attributes: :param gain_p: Proportional gain. :param gain_i: Integral gain. :param gain_d: Derivative gain. :param dt: Simulation time step.
The class should be used as:
pid = PID(100, 10, 0.1, 0.1) pid.set_point(target_point) control = pid(current_point)
Data Management Structures¶
Classes for the Aerotimestep and Structuraltimestep, amongst others
LinearTimeStepInfo¶
Linear timestep info containing the state, input and output variables for a given timestep
Documentation Generator¶
Functions to automatically document the code.
Comments and complaints: N. Goizueta
check_folder_in_ignore¶
Checks whether a folder is in the ignore_list
.
param folder: | Absolute path to folder |
---|---|
type folder: | str |
param ignore_list: | |
Ignore list | |
type ignore_list: | |
list | |
returns: | Bool whether file/folder is in ignore list. |
rtype: | bool |
generate_documentation¶
Main routine that generates the documentation in ./docs/source/includes
output_documentation_module_page¶
Generates the documentation for a package with a single page per module in the desired folder Returns:
write_file¶
Writes the contents of a python file with one module per page.
Warning
If the function to be written does not have a docstring no output will be produced and a warning will be given.
param file: | Absolute path to file |
---|---|
type file: | str |
write_folder¶
Creates the documentation for the contents in a folder.
It checks that the file folder is not in the ignore_list
. If there is a subfolder in the folder, this gets
opened, written and an index file is created.
param folder: | Absolute path to folder |
---|---|
type folder: | str |
param ignore_list: | |
List with filenames and folders to ignore and skip |
|
type ignore_list: | |
list |
|
returns: |
|
rtype: | tuple |
SHARPy Exception Classes¶
Generate cases¶
Generate cases
This library provides functions and classes to help in the definition of SHARPy cases
Examples:
tests in: tests/utils/generate_cases examples: test/coupled/multibody/fix_node_velocity_wrtG/test_fix_node_velocity_wrtG
test/coupled/multibody/fix_node_velocity_wrtA/test_fix_node_velocity_wrtA test/coupled/multibody/double_pendulum/test_double_pendulum_geradin test/coupled/prescribed/WindTurbine/test_rotor
Notes:
To use this library: import sharpy.utils.generate_cases as generate_cases
AerodynamicInformation¶
Aerodynamic information needed to build a case
Note
It should be defined after the StructuralInformation of the case
This function concatenates aerodynamic properties to be writen in the same h5 File
Parameters: *args – list of AerodynamicInformation() to be meged into ‘self’
Changes the discretization of the matrix of airfoil coordinates
Parameters: - airfoils (np.array) – Matrix with the x-y coordinates of all the airfoils to be modified
- new_num_nodes (int) – Number of points that the output coordinates will have
Returns: Matrix with the x-y coordinates of all the airfoils with the new discretization
Return type: new_airfoils (np.array)
Check some properties of the AerodynamicInformation()
Notes
These conditions have to be to correctly define a case but they are not the only ones
Returns a copy of the object
Returns: new object with the same properties Return type: copied(AerodynamicInformation)
Defines the whole case from the appropiated variables in vector form (associated to nodes)
Parameters: - StructuralInformation (StructuralInformation) – Structural infromation of the case
- vec_aero_node (np.array) – defines if a node has aerodynamic properties or not
- vec_chord (np.array) – chord of the nodes
- vec_twist (np.array) – twist of the nodes
- vec_sweep (np.array) – sweep of the nodes
- vec_surface_m (np.array) – Number of panels in the chord direction
- vec_surface_distribution (np.array) – Surface at which each element belongs
- vec_m_distribution (np.array) – distribution of the panels along the chord
- vec_elastic_axis (np.array) – position of the elastic axis in the chord
- vec_airfoil_distribution (np.array) – airfoil at each element node
- airfoils (np.array) – coordinates of the camber lines of the airfoils
Defines the whole case from the appropiated variables constant at every point
Parameters: - StructuralInformation (StructuralInformation) – Structural infromation of the case
- chord (float) – chord
- twist (float) – twist
- sweep (float) – sweep
- num_chord_panels (int) – Number of panels in the chord direction
- m_distribution (str) – distribution of the panels along the chord
- elastic_axis (float) – position of the elastic axis in the chord
- num_points_camber (int) – Number of points to define the camber line
- airfoils (np.array) – coordinates of the camber lines of the airfoils
Writes the h5 file with the aerodynamic information
Parameters: - route (string) – path of the case
- case_name (string) – name of the case
Defines the whole case from the appropiated variables
Parameters: - aero_node (np.array) – defines if a node has aerodynamic properties or not
- chord (np.array) – chord of the elements
- twist (np.array) – twist of the elements
- sweep (np.array) – sweep of the elements
- surface_m (np.array) – Number of panels in the chord direction
- surface_distribution (np.array) – Surface at which each element belongs
- m_distribution (str) – distribution of the panels along the chord
- elastic_axis (np.array) – position of the elastic axis in the chord
- airfoil_distribution (np.array) – airfoil at each element node
- airfoils (np.array) – coordinates of the camber lines of the airfoils
Create the camber of the airfoil at each node position from the camber of the pure airfoils present in the blade
Parameters: - pure_airfoils_camber (np.array) – xy coordinates of the camber lines of the pure airfoils
- r_pure_airfoils (np.array) – radial position of the pure airfoils
- r (np.array) – radial positions to compute the camber lines through linear interpolation
Returns: camber lines at the new radial positions
Return type: airfoils_camber (np.array)
Create the camber of the airfoil at each node position from the camber of the pure airfoils present in the blade based on the thickness
Parameters: - pure_airfoils_camber (np.array) – xy coordinates of the camber lines of the pure airfoils
- thicknesss_pure_airfoils (np.array) – thickness of the pure airfoils
- blade_thickness (np.array) – thickness of the blade positions
Returns: camber lines at the new radial positions
Return type: airfoils_camber (np.array)
Sets to zero all the variables
Parameters: - num_node_elem (int) – number of nodes per element
- num_node (int) – number of nodes
- num_elem (int) – number of elements
- num_airfoils (int) – number of different airfoils
- num_surfaces (int) – number of aerodynamic surfaces
- num_points_camber (int) – number of points to define the camber line of the airfoil
AeroelasticInformation¶
Structural and aerodynamic information needed to build a case
This function concatenates structures and aerodynamic properties to be writen in the same h5 File
Parameters: *args – list of AeroelasticInformation() to be meged into ‘self’ Notes:
Returns a copy of the object
Returns: new object with the same properties Return type: copied(AeroelasticInformation)
Generates an object from the structural and the aerodynamic information
Parameters: - StructuralInformation (StructuralInformation) – structural information
- AerodynamicInformation (AerodynamicInformation) – aerodynamic information
write_h5_files
Writes the structural and aerodynamic h5 files
Removes the points that are closer than ‘tol’ and modifies the aeroelastic information accordingly
Parameters: tol (float) – tolerance. Maximum distance between nodes to be merged Notes
This function will not work if an element or an aerdoynamic surface is completely eliminated This function only checks geometrical proximity, not aeroelastic properties as a merging criteria
SimulationInformation¶
Simulation information needed to build a case
Set the number of steps in the simulation for all the solvers
Parameters: num_steps (int) – number of steps
Set the inflow velocity in the simulation for all the solvers
Parameters: - unit_vector (np.array) – direction of the inflow velocity
- norm (float) – Norm of the inflow velocity
Generates the dynamic file
Parameters: - route (string) – path of the case
- case_name (string) – name of the case
- num_steps (int) – number of steps
Generates the solver file
Parameters: - route (string) – path of the case
- case_name (string) – name of the case
Set the default values for all the solvers
Defines the value of a variable in all the available solvers
Parameters: - variable (str) – variable name
- ( ) (value) – value
StructuralInformation¶
Structural information needed to build a case
This function concatenates structures to be writen in the same h5 File
Parameters: *args – list of StructuralInformation() to be meged into ‘self’ Notes
The structures does NOT merge any node (even if nodes are defined at the same coordinates)
Check some properties of the StructuralInformation()
Notes
These conditions have to be to correctly define a case but they are not the only ones
It computes the number of elements when no nodes are shared between beams
It computes the number of nodes when no nodes are shared between beams
Returns a copy of the object
Returns: new object with the same properties Return type: copied(StructuralInformation)
Define the coordinates of the yB axis in the AFoR
Parameters: y_BFoR (string) – Direction of the yB axis
Create the mass matrices from the vectors of properties
Parameters: - vec_mass_per_unit_length (np.array) – masses per unit length
- vec_mass_iner_x (np.array) – inertias around the x axis
- vec_mass_iner_y (np.array) – inertias around the y axis
- vec_mass_iner_z (np.array) – inertias around the z axis
- vec_pos_cg_B (np.array) – position of the masses
- vec_mass_iner_yz (np.array) – inertias around the yz axis
Create the matrix of connectivities for one single beam with the nodes ordered in increasing xB direction
Create the stiffness matrices from the vectors of properties
Parameters: - vec_EA (np.array) – Axial stiffness
- vec_GAy (np.array) – Shear stiffness in the y direction
- vec_GAz (np.array) – Shear stiffness in the z direction
- vec_GJ (np.array) – Torsional stiffness
- vec_EIy (np.array) – Bending stiffness in the y direction
- vec_EIz (np.array) – Bending stiffness in the z direction
- vec_EIyz (np.array) – Bending stiffness in the yz direction
Writes the h5 file with the structural information
Parameters: - route (string) – path of the case
- case_name (string) – name of the case
Defines the whole case from the appropiated variables
Parameters: - num_node_elem (int) – number of nodes per element
- num_node (int) – number of nodes
- num_elem (int) – number of elements
- coordinates (np.array) – nodes coordinates
- connectivities (np.array) – element connectivities
- elem_stiffness (np.array) – element stiffness index
- stiffness_db (np.array) – Stiffness matrices
- elem_mass (np.array) – element mass index
- mass_db (np.array) – Mass matrices
- frame_of_reference_delta (np.array) – element direction of the y axis in the BFoR wrt the AFoR
- structural_twist (np.array) – element based twist
- boundary_conditions (np.array) – node boundary condition
- beam_number (np.array) – node beam number
- app_forces (np.array) – steady applied follower forces at the nodes
- lumped_mass_nodes (np.array) – nodes with lumped masses
- lumped_mass (np.array) – value of the lumped masses
- lumped_mass_inertia (np.array) – inertia of the lumped masses
- lumped_mass_position (np.array) – position of the lumped masses
Generates the input data for SHARPy of a uniform beam
Parameters: - node_pos (np.array) – coordinates of the nodes
- mass_per_unit_length (float) – mass per unit length
- mass_iner_x (float) – Inertia of the mass in the x direction
- mass_iner_y (float) – Inertia of the mass in the y direction
- mass_iner_z (float) – Inertia of the mass in the z direction
- pos_cg_B (np.array) – position of the masses
- EA (np.array) – Axial stiffness
- GAy (np.array) – Shear stiffness in the y direction
- GAz (np.array) – Shear stiffness in the z direction
- GJ (np.array) – Torsional stiffness
- EIy (np.array) – Bending stiffness in the y direction
- EIz (np.array) – Bending stiffness in the z direction
- num_node_elem (int) – number of nodes per element
- y_BFoR (str) – orientation of the yB axis
- num_lumped_mass (int) – number of lumped masses
Generates the input data for SHARPy of a uniform symmetric beam
Parameters: - node_pos (np.array) – coordinates of the nodes
- mass_per_unit_length (float) – mass per unit length
- mass_iner (float) – Inertia of the mass
- EA (float) – Axial stiffness
- GA (float) – Shear stiffness
- GJ (float) – Torsional stiffness
- EI (float) – Bending stiffness
- num_node_elem (int) – number of nodes per element
- y_BFoR (str) – orientation of the yB axis
- num_lumped_mass (int) – number of lumped masses
Rotates a structure
Parameters: - axis (np.array) – axis of rotation
- angle (float) – angle of rotation in radians
Sets to zero all the variables
Parameters: - num_node_elem (int) – number of nodes per element
- num_node (int) – number of nodes
- num_elem (int) – number of elements
- num_mass_db (int) – number of different mass matrices in the case
- num_stiffness_db (int) – number of different stiffness matrices in the case
- num_lumped_mass (int) – number of lumped masses in the case
clean_test_files¶
clean_test_files
Removes the previous h5 files
param route: | path of the case |
---|---|
type route: | string |
param case_name: | |
name of the case | |
type case_name: | string |
from_node_array_to_elem_matrix¶
from_node_array_to_elem_matrix
Same as the previous function but with an array as input
from_node_list_to_elem_matrix¶
from_node_list_to_elem_matrix
Convert list of properties associated to nodes to matrix of properties associated to elements based on the connectivities
The ‘ith’ value of the ‘node_list’ array stores the property of the ‘ith’ node. The ‘jth’ ‘kth’ value of the ‘elem_matrix’ array stores the property of the ‘kth’ node within the ‘jth’ element
param node_list: | |
---|---|
Properties of the nodes | |
type node_list: | np.array |
param connectivities: | |
Connectivities between the nodes to form elements | |
type connectivities: | |
np.array | |
returns: | Properties of the elements |
rtype: | elem_matrix (np.array) |
get_airfoil_camber¶
get_airfoil_camber
Define the camber of an airfoil based on its coordinates
param x: | x coordinates of the airfoil surface |
---|---|
type x: | np.array |
param y: | y coordinates of the airfoil surface |
type y: | np.array |
param n_points_camber: | |
number of points to define the camber line | |
type n_points_camber: | |
int | |
returns: | x coordinates of the camber line camber_y (np.array): y coordinates of the camber line |
rtype: | camber_x (np.array) |
Notes
The x and y vectors are expected in XFOIL format: TE - suction side - LE - pressure side - TE
get_aoacl0_from_camber¶
This section provies the angle of attach of zero lift for a thin airfoil which camber line is defined by ‘x’ and ‘y’ coordinates
Check Theory of wing sections. Abbott. pg 69
get_factor_geometric_progression¶
This function provides the factor in a geometric series which first element is ‘a0’, has ‘n’ points and the sum of the spacings is ‘Sn_target’ approximately.
get_mu0_from_camber¶
This funrcion provides the constant \(\mu_0\) for a thin airfoil which camber line is defined by ‘x’ and ‘y’ coordinates
Check Theory of wing sections. Abbott. pg 69
read_column_sheet_type01¶
read_column_sheet_type01
This function reads a column from an excel file with the following format:
- First row: column_name
- Second row: units (not read, not checked)
- Third row: type of data (see below)
param excel_file_name: | |
---|---|
File name | |
type excel_file_name: | |
string | |
param excel_sheet: | |
Name of the sheet inside the excel file | |
type excel_sheet: | |
string | |
param column_name: | |
Name of the column | |
type column_name: | |
string | |
returns: | Data in the excel file according to the type of data defined in the third row |
rtype: | var |
Generator Interface¶
output_documentation¶
Creates the .rst
files for the generators that have a docstring such that they can be parsed to Sphinx
param route: | Path to folder where generator files are to be created. |
---|---|
type route: | str |
Airfoil Geometry Utils¶
generate_naca_camber¶
Defines the x and y coordinates of a 4-digit NACA profile’s camber line (i.e no thickness).
- The NACA 4-series airfoils follow the nomenclature: NACA MPTT where:
- M indicates the maximum camber \(M = 100m\)
- P indicates the position of the maximum camber \(P=10p\)
- TT indicates the thickness to chord ratio \(TT=(t/c)*100\)
param M: | maximum camber times 100 (i.e. the first of the 4 digits) |
---|---|
type M: | float |
param P: | position of the maximum camber times 10 (i.e. the second of the 4 digits) |
type P: | float |
returns: | x and y coordinates of the chosen airfoil |
rtype: | (x_vec,y_vec) |
Example
The NACA2400 airfoil would have 2% camber with the maximum at 40% of the chord and 0 thickness. To plot the camber line one would use this function as:
x_vec, y_vec = generate_naca_camber(M = 2, P = 4)
interpolate_naca_camber¶
Interpolate aerofoil camber at non-dimensional coordinate eta in (0,1), where (M00,P00) and (M01,P01) define the camber properties at eta=0 and eta=1 respectively.
Notes
For two surfaces, eta can be in (-1,1). In this case, the root is eta=0 and the tips are at eta=+-1.
H5 File Management Utilities¶
Set of utilities for opening/reading files
add_array_to_grp¶
Add numpy array (data) as dataset ‘name’ to the group grp. If compress is True, 64-bit float arrays are converted to 32-bit
add_as_grp¶
Given a class, dictionary, list or tuples instance ‘obj’, the routine adds it as a sub-group of name grpname to the parent group grpParent. An attribute _read_as, specifying the type of obj, is added to the group so as to allow reading correctly the h5 file.
- Usage and Remarks:
- if obj contains dictionaries, listes or tuples, these are automatically saved
- if list only contains scalars or arrays of the same dimension, this will be saved as a numpy array
- if obj contains classes, only those that are instances of the classes specified in ClassesToSave will be saved
- If grpParent already contains a sub-group with name grpname, this will not be overwritten. However, pre-existing attributes of the sub-group will be overwritten if obj contains attrributes with the same names.
- attributes belonging to SkipAttr will not be saved - This functionality needs improving
- if compress_float is True, numpy arrays will be saved in single precisions.
check_file_exists¶
Checks if the file exists and throws a FileNotFoundError exception that includes the route to the non-existing file.
param file_name: | |
---|---|
path to the HDF5 file | |
type file_name: | str |
returns: | if the file does not exist, an error is raised with path to the non-existent file |
rtype: | FileNotFoundError |
read_group¶
Read an hdf5 group
readh5¶
Read the HDF5 file ‘filename’ into a class. Groups within the hdf5 file are by default loaded as sub classes, unless they include a _read_as attribute (see sharpy.postproc.savedata). In this case, group can be loaded as classes, dictionaries, lists or tuples.
filename: string to file location
GroupName = string or list of strings. Default is None: if given, allows reading a specific group h5 file.
Warning
Groups that need to be read as lists and tuples are assumed to conform to the format used in sharpy.postproc.savedata
save_list_as_array¶
Works for both lists and tuples. Returns True if the saving was successful.
saveh5¶
Creates h5filename and saves all the classes specified in class_inst
- Args
- savedir: target directory h5filename: file name class_inst: a number of classes to save permission=[‘a’,’w’]: append or overwrite, according to h5py.File ClassesToSave: if the classes in class_inst contain sub-classes, these will be saved only if instances of the classes in this list
Modelling Utilities¶
Modelling Utilities
mass_matrix_generator¶
This function takes the mass, position of the center of gravity wrt the elastic axis and the inertia matrix J (3x3) and returns the complete 6x6 mass matrix.
Multibody library¶
Multibody library
Library used to manipulate multibody systems
Args:
Returns:
- Examples:
- To use this library: import sharpy.utils.multibody as mb
Notes:
disp2state¶
disp2state
Fills the vector of states according to the displacements information
Longer description
param MB_beam: | each entry represents a body |
---|---|
type MB_beam: | list of beam |
param MB_tstep: | each entry represents a body |
type MB_tstep: | list of StructTimeStepInfo |
param q: | Vector of states |
type q: | numpy array |
param dqdt: | Time derivatives of states |
type dqdt: | numpy array |
param dqddt: | Second time derivatives of states |
type dqddt: | numpy array |
Returns:
Examples:
Notes:
merge_multibody¶
merge_multibody
This functions merges a series of bodies into a multibody system at a certain time step
Longer description
param MB_beam: | each entry represents a body |
---|---|
type MB_beam: | list of beam |
param MB_tstep: | each entry represents a body |
type MB_tstep: | list of StructTimeStepInfo |
param beam: | structural information of the multibody system |
type beam: | beam |
param tstep: | timestep information of the multibody system |
type tstep: | StructTimeStepInfo |
param mb_data_dict (): | |
Dictionary including the multibody information | |
param dt: | time step |
type dt: | int |
returns: | structural information of the multibody system tstep (StructTimeStepInfo): timestep information of the multibody system |
rtype: | beam (beam) |
Examples:
Notes:
split_multibody¶
split_multibody
This functions splits a structure at a certain time step in its different bodies
Longer description
param beam: | structural information of the multibody system |
---|---|
type beam: | beam |
param tstep: | timestep information of the multibody system |
type tstep: | StructTimeStepInfo |
param mb_data_dict (): | |
Dictionary including the multibody information | |
returns: | each entry represents a body MB_tstep (list of StructTimeStepInfo): each entry represents a body |
rtype: | MB_beam (list of beam) |
Examples:
Notes:
state2disp¶
state2disp
Recovers the displacements from the states
Longer description
param MB_beam: | each entry represents a body |
---|---|
type MB_beam: | list of beam |
param MB_tstep: | each entry represents a body |
type MB_tstep: | list of StructTimeStepInfo |
param q: | Vector of states |
type q: | numpy array |
param dqdt: | Time derivatives of states |
type dqdt: | numpy array |
param dqddt: | Second time derivatives of states |
type dqddt: | numpy array |
Returns:
Examples:
Notes:
update_mb_dB_before_merge¶
update_mb_db_before_merge
Updates the FoR information database before merge the bodies
Longer description
param tstep: | timestep information of the multibody system |
---|---|
type tstep: | StructTimeStepInfo |
param MB_tstep: | each entry represents a body |
type MB_tstep: | list of StructTimeStepInfo |
Returns:
Examples:
Notes:
update_mb_db_before_split¶
update_mb_db_before_split
Updates the FoR information database before split the system
Longer description
param tstep: | timestep information of the multibody system |
---|---|
type tstep: | StructTimeStepInfo |
Returns:
Examples:
Notes
At this point, this function does nothing, but we might need it at some point
Plotting utilities¶
set_axes_equal¶
Make axes of 3D plot have equal scale so that spheres appear as spheres, cubes as cubes, etc.. This is one possible solution to Matplotlib’s ax.set_aspect(‘equal’) and ax.axis(‘equal’) not working for 3D.
- Input
- ax: a matplotlib axis, e.g., as output from plt.gca().
Settings Generator Utilities¶
Settings Generator Utilities
SettingsTable¶
Generates the documentation’s setting table at runtime.
Sphinx is our chosen documentation manager and takes docstrings in reStructuredText format. Given that the SHARPy solvers contain several settings, this class produces a table in reStructuredText format with the solver’s settings and adds it to the solver’s docstring.
This table will then be printed alongside the remaining docstrings.
To generate the table, parse the setting’s description to a solver dictionary named
settings_description
, in a similar fashion to what is done withsettings_types
andsettings_default
. If no description is given it will be left blank.Then, add at the end of the solver’s class declaration method an instance of the
SettingsTable
class and a call to theSettingsTable.generate()
method.Examples
The end of the solver’s class declaration should contain
# Generate documentation table settings_table = settings.SettingsTable() __doc__ += settings_table.generate(settings_types, settings_default, settings_description)
to generate the settings table.
Returns a rst-format table with the settings’ names, types, description and default values
Parameters: - settings_types (dict) – Setting types.
- settings_default (dict) – Settings default value.
- settings_description (dict) – Setting description.
- header_line (str) – Header line description (optional)
Returns: .rst formatted string with a table containing the settings’ information.
Return type: str
check_settings_in_options¶
Checks that settings given a type str
or int
and allowable options are indeed valid.
param settings: | Dictionary of processed settings |
---|---|
type settings: | dict |
param settings_types: | |
Dictionary of settings types | |
type settings_types: | |
dict | |
param settings_options: | |
Dictionary of options (may be empty) | |
type settings_options: | |
dict | |
raises: | exception.NotValidSetting – if the setting is not allowed. |
load_config_file¶
This function reads the flight condition and solver input files.
param file_name: | |
---|---|
contains the path and file name of the file to be read by the configparser
reader. |
|
type file_name: | str |
returns: | a ConfigParser object that behaves like a dictionary |
rtype: | config (dict) |
SHARPy
Test Cases¶
The following test cases are provided as a tutorial and introduction to SHARPy
as well as for code validation purposes.
- Geradin and Cardona Beam - See Installation and see test case in
./sharpy/tests/xbeam/
A Short Debugging Guide¶
We have put together a list of common traps you may fall into, hopefully you will find the tools here to get yourself out of them!
Did you forget conda activate sharpy_env and source bin/sharpy_vars.sh?
- If you do in the terminal: which sharpy, do you get the one you want?
- If you do which python, does the result point to anaconda3/envs/sharpy_env/bin (or similar)?
Wrong input (inconsistent connectivities, mass = 0…)
- Sometimes not easy to detect. For the structural model, run BeamLoader and BeamPlot with no structural solver in between. Go over the structure in Paraview. Check the fem.h5 file with HDFView.
- Remember that connectivities are ordered as $[0, 2, 1]$ (the central node goes last).
- Make sure the num_elem and num_node variables are actually your correct number of elements and nodes.
Not running the actual case you want to.
- Cleanup the folder and regenerate the case
Not running the SHARPy version you want.
- Check at the beginning of the execution the path to the SHARPy folder.
Not running the correct branch of the code.
- You probably want to use develop. Again, check the first few lines of SHARPy output.
Very different (I’m talking orders of magnitude) stiffnesses between nodes or directions?
Maybe the UVLM requires a smaller a smaller vortex core cutoff (only for linear UVLM simulations, as the nonlinear uses another vortex core model).
Newmark damping is not enough for this case?
Do you have an element with almost 0 mass or inertia?
Are you mass matrices consistent? Check that \(I_{xx} = I_{yy} + I_{zz}\).
Have a look at the $dot{Gamma}$ filtering and numerical parameters in the settings of StepUvlm and DynamicCoupled.
Add more relaxation to the StaticCoupled or DynamicCoupled solvers.
The code has a bug (depending on where, it may be likely).
- Go over the rest of the list. Plot the case in paraview. Go over the rest of the list again. Prepare the simplest example that reproduces the problem and raise an issue.
- The code diverges because it has to (physical unstable behaviour)
- Then don’t complain
- Your model still doesn’t work and you don’t know why.
- import pdb; pdb.set_trace() and patience
If nothing else works… get a rubber duck (or a very very patient good friend) and go over every step

If your model doesn’t do what it is supposed to do:
Check for symmetric response where the model is symmetric.
- If it is not, run the beam solver first and make sure your properties are correct. Make sure the matrices for mass and stiffness are rotated if they need to be (remember the Material FoR definition and the for_delta?)
- Now run the aerodynamic solver only and double check that the forces are symmetric.
- Make sure your tolerances are low enough so that at least 4 FSI iterations are performed in StaticCoupled or DynamicCoupled.
Make sure your inputs are correct. For example: a dynamic case can be run with \(u_\infty = 0\) and the plane moving forwards, or \(u_\infty = x\) whatever and the plane velocity = 0. It is very easy to mix both, and end up with double the effective incoming speed (or none).
Run simple stuff before coupling it. For example, if your wing tip deflections don’t match what you’d expect, calculate the deflection under a small tip force (not too small, make sure the deflection is > 1% of the length!) by hand, and compare.
It is more difficult to do the same with the UVLM, as you need a VERY VERY high aspect ratio to get close to the 2D potential solutions. You are going to have to take my word for it: the UVLM works.
But check the aero grid geometry in Paraview, including chords lengths and angles.
Citing SHARPy¶
SHARPy has been published in the Journal of Open Source Software (JOSS) and the relevant paper can be found here.
If you are using SHARPy for your work, please remember to cite it using the paper in JOSS as:
del Carre et al., (2019). SHARPy: A dynamic aeroelastic simulation toolbox for very flexible aircraft and wind turbines. Journal of Open Source Software, 4(44), 1885, https://doi.org/10.21105/joss.01885
The bibtex entry for this citation is:
@Article{delCarre2019,
doi = {10.21105/joss.01885},
url = {https://doi.org/10.21105/joss.01885},
year = {2019},
month = dec,
publisher = {The Open Journal},
volume = {4},
number = {44},
pages = {1885},
author = {Alfonso del Carre and Arturo Mu{\~{n}}oz-Sim\'on and Norberto Goizueta and Rafael Palacios},
title = {{SHARPy}: A dynamic aeroelastic simulation toolbox for very flexible aircraft and wind turbines},
journal = {Journal of Open Source Software}
}
Indices and tables¶
Contact¶
SHARPy is developed at the Department of Aeronautics, Imperial College London. To get in touch, visit the Loads Control and Aeroelastics Lab website.