OpenFOAM Motorbike Tutorial

From $1

    In Work - some information may be wrong! Also updating to OpenFOAM 2.1.1

    The basis of the Vespa CFD modelling (to start with at least) is the OpenFOAM Motorbike tutorial. Here are some notes on that tutorial, the first thing that people will need to do is get the tutorial to run before adapting it for a Vespa. Nerd Warning: This is a techy process to set-up and to get working, involving Linux commands and compiling and stuff. Also maths is involved and these notes are from a non-CFD expert and therefore are an overly simplified perspective (which may help or hinder). Any CFD experts out there, please feel free to jump in and correct and contribute!


    Getting Set Up

    OpenFOAM is free but for Linux type OS's only. You can get OpenFOAM at If you have a Windows you can get CAE Linux with OpenFOAM precanned and install it as a partition or run it as a virtual machine. The info below is based on OpenFOAM 2.1.1 (which may require an OpenFOAM update to CAE Linux or you can try with the version it comes with).

    Running the Tutorial

    There is general instruction on using OpenFOAM in their User Guide. OpenFOAM doesn't give you any information on how to run the motorbike tutorial as it is part of a course, however all the bits you need are there to enable you to run it and then tweak it. You can find the motorbike tutorial in the following location:


    Below is the annotated (in brackets) contents of that directory derived from the OpenFOAM case file structure and SST k-omega module info:

    |-- ("time" directory starting with T=0, giving conditions from the initial step in time)
    |   |-- U (flow velocity)
    |   |-- include
    |   |   |-- fixedInlet
    |   |   |-- frontBackUpperPatches
    |   |   `-- initialConditions
    |   |-- k (turbulence kenetic energy)
    |   |-- nut (turbulence viscosity)
    |   |-- omega (turbulence specific dissipation rate)
    |   `-- p (pressure)
    |-- Allclean (precanned clean file)
    |-- Allrun (precanned run file)
    |-- constant (hard static stuff i.e. physical properties)
    |   |-- RASProperties (Reynolds-Averaged Simulation Model to use e.g. kOmegaSST)
    |   |-- polyMesh
    |   |   |-- blockMeshDict
    |   |   `-- boundary
    |   |-- transportProperties (Transport Model  e.g. Newtonian)
    |   `-- triSurface
    |       `-- motorBike.obj (this is the actual motorbike model that you can view with ParaView)
    `-- system (soft stuff i.e. the info on the computational system used to analyse the problem)
        |-- controlDict (the main dictionary for controlling the simulation)
        |-- decomposeParDict (dictionary for partitioning up the space into smaller chunks)
        |-- fvSchemes
        `-- snappyHexMeshDict (the dictionary for adding a mesh for simulating surface interactions)

    The simpliest way to run the tutorial is to trust in blind faith and use "Allrun", this will give you are starting point knowing that everything actually works :) It also gives you a good idea of what is happening to get CFD happening with a motorbike (see output below)

    cd $HOME/OpenFOAM/OpenFOAM-2.1.1
    source etc/bashrc
    cd tutorials/incompressible/simpleFoam/motorBike/
    Running blockMesh on /home/pmcintos/OpenFOAM/OpenFOAM-2.1.1/tutorials/incompressible/simpleFoam/motorBike
    Running snappyHexMesh on /home/pmcintos/OpenFOAM/OpenFOAM-2.1.1/tutorials/incompressible/simpleFoam/motorBike
    Running potentialFoam on /home/pmcintos/OpenFOAM/OpenFOAM-2.1.1/tutorials/incompressible/simpleFoam/motorBike
    Running simpleFoam on /home/pmcintos/OpenFOAM/OpenFOAM-2.1.1/tutorials/incompressible/simpleFoam/motorBike

    Also note the system/forceCoeffs dictionary for calculating Drag and Lift e.g. Aref the frontal area of the vehicle

    Looking at the Result

    The above goes through and creates 5 time steps 0,100,200,400 and 500. Without going into detail of what all the data means, we can look at it and create pretty pictures with ParaView.


    You will also find some handy coefficient output in the log.simpleFOAM file (as of OpenFOAM 2.0.1). A coefficient is a number that allows you to compare a motorbike with a Vespa (both wasp and scooter) or a Boeing 747 by removing the size factor and giving a relative number that expresses the "nessness" of something. By "nessness" think of some descriptive property you want measure and have more or less of, e.g. smoothness. In the output below the "draginess" of this motorbike is the Cd (proper name Drag Coefficient) and it is a number that you'd like to be as close to zero as possible (a Boeing 747 will have a much lower number though but won't fly at all with a Vespa engine bolted on). 

    Drag Coefficient (Cd)
    Lift Coefficient (Cl)
    Pitching moment (Cm)

    forceCoeffs output:
        Cd = 0.416234
        Cl = 0.0663582
        Cm = 0.151496

    Look at the numbers at the bottom of the file. The simulation takes a while to "converge", which means that all the simulated bits take a little time to balance out the math, so they start by having wildly varying values and the end results "should" (you need to check) have more consistent values.

    More CPU (GPU?) Power

    Depending on your system you are likely to be waiting around a while for the result. On an Intel Core i7 CPU @ 3.07GHz the result will take about 16 minutes. If you use the Linux "top" you will see it is only running on one process(core) rather than the full 8 cores. So we have a V8 but we are only running on one cylinder. Let's give it some more power...


    First do an ./Allclean of the motorbike directory and then make a copy (we want to keep the original as-is for reference). e.g. cp -r motorbike motorbikeParallel6

    It appears that OpenFOAM started to play with adding a parallel bit in the tutorial because there is already a system/decomposeParDict there. This describes how we break up the problem into smaller bits so we can give a bit to each core. This is set to use 6 CPU. To make use if this, alter the Allrun as follows:

    # Source tutorial run functions
    . $WM_PROJECT_DIR/bin/tools/RunFunctions
    cp -r 0 > /dev/null 2>&1
    runApplication blockMesh
    runApplication snappyHexMesh -overwrite
    runApplication potentialFoam -noFunctionObjects -writep
    # runApplication `getApplication`
    runApplication decomposePar
    runParallel `getApplication` 6
    runApplication reconstructPar

    With the above we reduce the 16 minute execution time down to 10 minutes. We are using 6 cores out of 8 but won't bother using the other 2 cores at the moment because, until we configure the partitioning to suit, we won't get much more speed-up. We'll revisit this when we start asking it to solve bigger problems more accurately. To run the case on a 4 core processor e.g. Intel® Core™ 2 Quad update the system/decomposeParDict and Allrun  file according to the files attached.

    Once we have run the job in parallel we can do a check to see if the numbers are roughly the same:

    forceCoeffs output:
        Cd = 0.415571
        Cl = 0.0671005
        Cm = 0.15037


    Below is some info that was added but I have not yet confirmed working with the motorBike tut

    TODO: See if we can make this even faster with GPU's e.g. with details below

    Symscape ofgpu


    CNC (Concurrent Number Cruncher)

    These libraries transfer the calculation to your NVIDIA graphics card or a TESLA card. NVIDIA TESLA cards are expensive parallel processing cards offering significant double precision performance that can be leveraged using SpeedIT extreme. The other libraries offer "only" single precision support. Double precision support on NVIDIA graphics cards is very limited for NVIDIA TESLA marketing reasons. NVIDIA graphics cards offer very high single precision performance e.g. GTX 480 1344 GFlop/s (but only 168 GFlop/s double precision). Modern CPUs offer less than 100 GFlop/s double precision. I compared the double precision performance of an Intel 9550 with a GTX 480 using SpeedIT extreme. Running the case in parallel on the Intel 9550 was always faster. I assume this was caused by the PCI bottleneck (data transfer between memory and GPU via PCI is much slower than data transfer between CPU and memory via mainboard bus).  Nevertheless running large cases in single precision (this is where GPUs perform best due to technical/PCI bottleneck reasons) using Symscape ofgpu and a NVIDIA graphics card should result in a performance boost in the range of 5x to 15x compared to an Intel® Core™ 2 Quad.

    Benchmark based on Symscape ofgpu and OpenFoam sample case pitzDaily:

    System CPU: AMD Opteron 6134
    System GPU: NVIDIA Tesla C2050 (1000 GFlop/s single precision)

    commands: blockMesh and simpleFoam

    For 12225 Cells:
    CPU Time: 16 s
    GPU Time: 45 s

    For 122250 Cells:
    CPU Time: 303 s
    GPU Time: 105 s

    For 299100 Cells:
    CPU Time: 808 s
    GPU Time: 186 s

    Note: GPU processing is only effective with high numbers of cells!

    More Speed

    The precanned tutorial is like a virtual wind tunnel and we can see the speed that the motorbike is being tested at within the file. This is the "flowVelocity (20 0 0)" parameter which is 20m/s or 72km/hr. Lets create some different cases for some more exciting speeds of 100km/hr (28m/s), 130km/hr (36m/s) and 160km/hr (45m/s). This should give us some good comparison runs for a Vespa running at highway speeds in different countries and an extreme example in racing.

    Lets create the 100km/hr case first

    ../Allclean (remove results from motorBike run)
    cd ..
    cp -rf motorbikeParallelx motorBike motorBike_100

    And adjust the bits in motorBike_100/

    /*--------------------------------*- C++ -*----------------------------------*\
    | =========                 |                                                 |
    | \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
    |  \\    /   O peration     | Version:  2.0.1                                 |
    |   \\  /    A nd           | Web:                      |
    |    \\/     M anipulation  |                                                 |
    flowVelocity         (28 0 0);
    pressure             0;
    turbulentKE          0.24;
    turbulentOmega       1.78;
    #inputMode           merge
    // ************************************************************************* //

    So the forces are calculated correctly you also need to change the magUInf value in the system/forceCoeffs configuration to 28 (or whatever you have set the flowVelocity above to).

    Then we can run is as before with the ./Allrun command from within the motorBike_100 directory.

    We can do the same for 130km/hr (36m/s) and 160km/hr (45m/s).

    We should see similar results for the force coefficients

    forceCoeffs output:
        Cd = 0.41525
        Cl = 0.0671618
        Cm = 0.150203

    More Accuracy

    Increasing mesh resolution

    Here we will talk about blockMeshdict

    Increasing snappyHexMesh accuracy

    Here we will talk about improving the accuracy around the model

    Results of using various parameters for mesh size, resolution, etc

      forceCoeffs blockMeshDict snappyHexMeshDict snappyHexMeshDict snappyHexMeshDict Cd CdA Time
      Aref blocks.hex refinementSurfaces maxBoundarySkewness maxInternalSkewness      
    motorBike 0.75 20 8 8 2 2 1 1 0.4264 0.31986375 5m53
    motorBike 0.64438 20 8 8 2 2 1 1 0.4963 0.31986400 5m54
    motorBike 0.64438 40 16 16 2 2 1 1 0.5140 0.33125672 50m0
    motorBike 0.64438 40 16 16 2 4 1 1 0.5140 0.33125672 50m6
    motorBike 0.64438 40 16 16 4 6 1 1 0.4722 0.30428923 93m17
    motorBike 0.64438 40 16 16 5 7 1 1 0.5021 0.32358597 154m21
    motorBike 0.64438 40 16 16 6 7 1 1 0.4989 0.32154584 160m46
    motorBike 0.64438 40 16 16 7 8 1 1 0.5008 0.32273022 197m10

    Validating the Model

    A lot of blind faith was used in the above. Before we jump into the Vespa version, we'll test a few things to make sure that the data we are getting makes sense.

    Checking for Errors

    The first step in making sure everything is ok is checking the output logs from the OpenFOAM run, this will show if the run actually worked or not. For each stage there is a log.<stage> output. Below is some errors and fixes (please add as they are found)

    log.simpleFoam error

    When running with the original single CPU job I get:

    simpleFoam: symbol lookup error: /home/pmcintos/OpenFOAM/OpenFOAM-2.0.1/platforms/linux64GccDPOpt/lib/ undefined symbol: _ZN4Foam8LESdelta34destroydictionaryConstructorTablesEv

    This was fixed by upgrading to Centos 6.0. This is probably not an issue though as it is only at the end of the log file (not at each iteration) and the name "destroy" indicates it is just part of the memory clean up process (the process ends anyway).

    OpenFOAM Checking Utilties

    As we will be adding our own Vespa mesh and tinkering with it to test various things out, we'll need to check the model and make sure that OpenFOAM thinks it is ok. Let's check the motorcycle using surfaceCheck, we see below that there are some problems.

    surfaceCheck motorBike.stl | grep illegal
    Surface has 60941 illegal triangles.
    Dumping conflicting face labels to "illegalFaces"

    To fix the problems use "clean" while converting from stl to stl.

    surfaceConvert -clean motorBike.stl motorBike_clean.stl | grep illegal
        Removing 67326 illegal faces.
    surfaceCheck motorBike_clean.stl | grep illegal
    Surface has no illegal triangles.

    Now we can replace the dirty motorbike with the clean one and run the simulation again.

    forceCoeffs output:
        Cd = 0.416234
        Cl = 0.0663582
        Cm = 0.151496

    Checking the Result with Reality

    Note: there is a question mark on if Cd means Cd or CdA...

    From the above we see drag coefficent of Cd = 0.416. Unfortunately the motorcycle make and model is not known and it would be hard anyway to find what the actual Cd was in reality with owning one yourself. 0.416 is pretty low but the motorbike does look pretty sporty so it is possible that the values are correct. So it looks OK(?) but the only real way to check is to validate the results with some real world test. Since this is Vespa Labs, well leave the motorbike stuff here and start working on the OpenFOAM Vespa Tutorial.

    Tags: (Edit tags)
    • No tags
    Comments (8)
    Viewing 8 of 8 comments: view all
    thanks hightech - I have just got back from SC11 and will try these out. I met a few other people there into CFD so I gave gained some good knowledge and it looks like others will be updating this information too :) edited 15:31, 21 Nov 2011
    Posted 14:52, 21 Nov 2011
    I'd like to add that CAE Linux, unless used via a Live CD/USB requries a 64bit system to work on.

    There is a distribution called GeekoCFD based on OpenSUSE which has both x32 and x64 versions and is also based on the latest version of SUSE, unlike CAE Linux. This distribution also has OpenFOAM, GMsh and a few other applications pre installed. SUSE also allows you to create a custom OS with their online SUSE studio tools. (URL : )

    Some useful links I've collected for getting started with Linux : edited 20:50, 17 Aug 2012
    Posted 20:50, 17 Aug 2012
    Can SnappyHexMesh/BlockMesh use multiple cores for the meshing process itself ? I've noticed even commercial meshers like ICEM seem to use only a single core.

    Would this actually be useful ?
    Posted 21:28, 17 Aug 2012
    yes it can but I have not tried it myself. I think you can make it split up the problem and then run each bit separately. I was at a course recently as was told that you could also run the bits in serial, which is handy as it can be a memory hog (i.e. a workaround when memory limits the performance)
    Posted 21:56, 17 Aug 2012
    Hi I am curious as to what tools you used and how you created the MESH for the bike and rider. We have tried creating meshes using CAD diagrams from sketchup, blender and freecad and exporting the mesh using snappyHexMesh dict and engrid respectively. For all but the simplest models we run into problems creating the mesh or end up with a mesh that is too complex to load into openfoam. How does one create a mesh for a complex structure like the Vespa ?
    Posted 05:16, 1 Aug 2013
    This Vespa mesh was generated by a 3D scanner and I have spent many many hours repairing the mesh with Rhino 3D. I am mostly filling holes but there are things that I am simplifying e.g. springs that are going to be streamlined later anyway.

    I also have a computer with a lot of RAM (192G) and I have found RAM the thing that limits the size of a mesh that can ne "snapped" - I think you can run snappyHexMesh on a section of a model so in theory you could break it into chunks and get around the RAM requirement.

    My model is quite complex, too complex I have been told, and should be much more complex than a hand crafted mesh (i.e. mine has every bump, even stickers can be seen). Maybe you a generating a mesh with too many triangles and just need to lower the resolution.
    Posted 07:34, 1 Aug 2013
    Thanks for the info. I assume you are using windows 7 ? but what kind of hw config are you using ? 3 x 64 GB ram ? what kind of motherboard ? Manufacturer ?
    Posted 00:19, 2 Aug 2013
    I am using this

    Yes I am using the Windows 7 but the above is Centos 5.8. OpenFOAM only works on Linux. If you have a very large mesh trying bringing it into ParaView and decimating the mesh to make it smaller. You'll find making it work on a smaller mesh first will save you a lot of hassles.
    Posted 07:20, 2 Aug 2013
    Viewing 8 of 8 comments: view all
    You must login to post a comment.

    Powered by MindTouch Core

    Disclaimer: Vespa Labs contains information that is VERY likely to wreck your scooter and possibly yourself both intentionally (i.e. gaining more peformance while sacrificing reliability + safety) and unintentionally (i.e. misleading or incorrect information). Vespa Labs is only a wiki and intended as a dumping ground for information and not as a properly reviewed source. The same disclaimers that use apply to Vespa Labs. The short version is use information at your own risk, both information on the main wiki and in the user areas are intended to be used only as "thought provoking" for someone that knows what they are doing. If you try to implement a "thought" Vespa Labs is not reponsible and if something goes wrong we hope that you live and update the offending information with corrections to warn others.

    Vespa Labs is an international site and therefore may contain information that is not road legal in some countries/states and may also invalidate insurance policies. Treat all information as experimental and for "race use only" (i.e. not for road use - even if it is implied or explicitly stated). Refer to and adhere to your local road and legal rules, as well as the manufacturers recommendations.