Example codes
and tutorials
The (Not-so) Quick Guide
List of tutorials/demo codes
Single-Physics Problems
Poisson
Adaptivity illustrated for Poisson
Advection-Diffusion
Unsteady heat equation
Linear wave equation
The Young-Laplace equation
Navier-Stokes
Free-surface Navier-Stokes
Axisymmetric Navier-Stokes
Solid mechanics
Beam structures
Shell structures
Multi-physics Problems
Fluid-structure interaction
Boussinesq convection
Steady thermoelasticity
Methods-based example codes and tutorials
Mesh generation
Linear solvers and preconditioners
Visualisation of the results
Parallel processing
How to write a new element
How to write a new refineable element
Default nonlinear solvers -- the sequence of action functions
...
Documentation
FE theory and top-down discussion of the data structure
The (Not-so) Quick Guide
Comprehensive bottom-up discussion of the data structure
List of available structured and unstructured meshes
Linear solvers and preconditioners
Visualisation of the results
Parallel processing
Coding conventions and C++ style
Creating documentation
Optimisation - robustness vs. "raw speed"
Linear vs. nonlinear problems
Storing shape functions
Changing the default "full" integration scheme
Disabling the ALE formulation of unsteady equations
C vs. C++ output
Different sparse assembly techniques and the STL memory pool
Publications
Publications
Talks
Journal publications
Theses
Picture show
Download
Copyright
Download/installation instructions
Download page
FAQ & Contact
FAQ
Change log
Bugs and other known problems
Completeness of the library & our "To-Do List"
Contact the developers
Get involved

 


Beta release!

Please note that the library has not been "officially" released. While we continue to work on the documentation, these web pages are likely to contain broken links and documents in draft form. Please send an email to

oomph-lib AT maths DOT man DOT ac DOT uk

if you wish to be informed of the library's "official" release.

Frequently Asked Questions

Here are some frequently asked questions (with assorted frequently given answers...). Please check these before contacting us with any problems.





Installation

How do I specify different levels of optimisation and/or non-standard compiler options?

  1. Compiler flags/options for the compilation of the library

    By default, oomph-lib's installation is performed with the gcc compiler suite, using full optimisation and warning (-O6 -Wall ).

    If you install the library with the autogen.sh script you are given the option to overwrite the default compilation flags, either by specifying alternative flags on the command line, or by recycling any of the previously used combinations of flags, stored in the directory config/configure_options. The files in this directory also contain more details on available flags and options.

    If you prefer the standard linux configure/make/make install installation procedure, you should already know how to specify flags at the configure stage...

  2. Compiler flags/options for the compilation of individual (driver) codes

    Within the autotools framework, additional flags for the compilation of individual (driver) codes may be specified by setting the appropriate automake variables in the Makefile.am. For instance, to use the compiler flag -DUSE_TAYLOR_HOOD during the compilation of the executable test_code, add
       test_code_CXXFLAGS = -DUSE_TAYLOR_HOOD
    
    to the appropriate Makefile.am. The C++ section of the automake manual provides more detail on other automake variables.

    If you link against oomph-lib from outside the autotools framework, you can, of course, use whatever technique you prefer to customise the compilation of your driver code.

The compilation fails when I use my xxx [non gcc] compiler

oomph-lib is developed in a GNU Linux enviroment, using the gcc compiler suite. We believe (!) the source code complies with the C++ standard and it compiles cleanly under the gcc compilers that we have access to (version 3.2.3 and later). Some warning messages tend to be issued during the compilation of the third-party libraries distributed with oomph-lib, but these are not our responsibility!

We occasionally compile (or get other people to compile) the library under other compilers and we generally try to rectify any problems that are flagged up in the process. If you encounter any problems (errors or warning messages) while compiling the library with your own (non-gcc) compiler we would like to hear from you, especially if you suggest concrete bug fixes.

There are problems with version 7 of the intel compiler suite but the library compiles cleanly under version 9. We suggest you upgrade to that if you wish to use the intel compilers.


The build process fails under cygwin

Here are a few things to check:


The build process fails under Apple's Darwin (OSX) or other BSD Linux distributions

Here are some general guidelines for installing under OSX, contributed by Rich Hewitt:

  1. Make sure you have installed the development tools from the OSX install DVDs. If your install media is fairly old, you may wish to look for an updated online version at:

    http://developer.apple.com/tools/xcode/

    You do not need to use the Xcode IDE, but we do need the associated development kit tools (in particular GCC!)

  2. Install a FORTRAN compiler. Apple does not ship a FORTRAN version, so the easiest way to do this is to install the relevant pre-packaged GNU FORTRAN from here:

    http://hpc.sourceforge.net/

    (I would recommend sticking with the version of GCC4 provided by Apple.)

  3. Make sure the FORTRAN compiler ('gfortran' in the packages pointed to above) is in the installing user's path.

  4. Follow the oomph-lib install procedure as normal.

  5. For associated Unix-goodness (doxygen, gnuplot, subversion etc), I would recommend using a ports mechanism to install any additional unix tools painlessly:

    http://trac.macosforge.org/projects/macports/wiki

    For example: "sudo port install gnuplot" etc.

The linking self-test fails under Apple's OSX

As discussed in the installation instructions, Darwin (the BSD-derived UNIX core of Apple's OSX operating system) requires a slight change to the default procedure for linking against oomph-lib from outside its autotools framework. As a result, the linking self-test tends to fail on machines with this operating system. Instructions on how to fix this problem are provided in installation instructions.


Some of the self tests fail

Tolerance of comparison between floating point numbers

The full oomph-lib distribution contains a large number of demo codes in the sub-directory demo_drivers. Primarily, these codes serve as demo codes for the oomph-lib documentation (contained in the sub-directory doc) but they are also used during the library's self-test procedure which checks that oomph-lib was installed correctly. The self-tests can either be initiated at the end of the autogen.sh - based installation or by typing

make check
in oomph-lib's top-level directory. The self-test builds and runs all demo codes and compares their results against the reference data stored in the validata sub-directories. The comparison is performed with the python script bin/fpdiff.py which tolerates small (machine- and compiler-dependent) roundoff errors and suppresses the comparison of numbers whose absolute value falls below some threshold (to avoid the comparison of numerical zeroes).

If any of the self-test fail, you should first check the output in the file validation.log to assess if the differences between the computed data and the reference data are significant. If the discrepancy appears to be due to larger-than-anticipated round-off errors (you'll have to judge this yourself!), modify the validate.sh script to specify a larger relative tolerance and/or a larger value for the threshold below which fpdiff.py regards numbers as numerical zeroes and excluses them from the comparison. [Type

bin/fpdiff.py 
in oomph-lib's top-level directory for instructions on how to use the script].

The self-test fails even though the output files produced by the code are correct

This is an odd error that is usually caused by the use of wildcards in the validations scripts, or the comparison of data that is stored in certain STL containers. Typically, the self-test is performed by the validate.sh shell script, which runs the executable and concatenates selected output files to a single file whose contents are compared against the reference file in the validata directory.

While it is tempting to write

cat RESLT* /soln0.dat > results_file.dat
it is important to realise that the order in which the files are concatenated is machine- and/or operating-system dependent. If the above command is run in a directory with the following structure
|-- RESLT
|   |-- soln0.dat
|   `-- trace.dat
|-- RESLT_elastic
|   |-- soln0.dat
|   `-- trace.dat
some operating systems will expand the command to
cat RESLT/soln0.dat RESLT_elastic/soln0.dat > results_file.dat
while others will excecute
cat RESLT_elastic/soln0.dat RESLT/soln0.dat > results_file.dat
In this case the self-test will report a failure, even though the solution files are correct. The validate.sh scripts should therefore not contain any wildcards.

Similar problems can arise if the validation data includes data that is stored in certain STL containers such as sets. The order in which items are stored in such containers may vary from machine to machine and from compiler to compiler. If such data is to be included in a self-test the data should be sorted first, based on a user-controllable sorting criterion.


The oomph-lib distribution includes some third-party libraries. How do I get the code to link against optimised local versions of these libraries that are already installed on my machine?

To facilitate the installation, the oomph-lib distribution includes the relevant parts of certain third-party libraries, such as SuperLU and BLAS. These "external libraries" are built and installed along with oomph-lib's own sub-libraries. To distinguish them from any already existing local versions of these libraries, their names are pre-fixed with the string oomph_.

All demo codes are automatically linked against these libraries. This is achieved by defining the variable EXTERNAL_LIBS in the configure script:

 # Define "external" libraries
 #----------------------------
 # These are the third-party libraries distributed with oomph-lib.
 # Note: If you want to link against another, already existing local
 # installation of one of these libraries, edit the EXTERNAL_LIBS
 # assignment below. As an example, if you want to use your own BLAS
 # library, and you'd usually link against this with
 #
 #    g++ -o my_code my_code.cc -lblas
 #
 # then replace "-loomph_blas" by "-lblas" below:
 #
 EXTERNAL_LIBS='-loomph_hsl -loomph_superlu_3.0 -loomph_metis_4.0 -loomph_arpack -loomph_lapack -loomph_flapack -loomph_blas'

If you wish to link against some other version of the library, edit the EXTERNAL_LIBS variable accordingly.

WARNING: If you work within the autotools framework, remember that the configure script is generated by autoconf, using the file configure.ac, which is itself (re-)generated whenever you run autogen.sh with the --rebuild flag. If you use the autotools, you should edit the EXTERNAL_LIBS variable in the file configure/configure.ac_scripts/start which forms one of the building blocks from which autogen.sh assembles the configure.ac file. Once you have changed the EXTERNAL_LIBS variable in configure/configure.ac_scripts/start you should (re-)run autogen.sh --rebuild in oomph-lib's top-level directory.

NEW (version 0.85)
You can now use the --with-blas and --with-lapack configure flags to specify the location of your own blas and lapack libraries; see the installation tutorial for details. Equivalent flags will soon be added for the other libraries.


Missing 'this->'

Recent versions of the gcc compilers enforce the C++ standard much more rigorously than earlier versions. Unfortunately, the standard includes some rules that are so counter-intuitive that it is hard get into the habit of using them, especially if code is developed on a compiler that does not enforce the standard as rigorously.

The most frequent problem arises in classes that are derived from a templated base class. The C++ standard insists that all references to member functions (or member data) that is defined in the templated base class must be preceded by "this->" when the reference is made in the derived class. Allegedly, this is necessary to avoid ambiguities, though it is not entirely clear what this ambiguity is supposed to be... Here is a driver code that illustrates the problem.

//LIC// ====================================================================
//LIC// This file forms part of oomph-lib, the object-oriented, 
//LIC// multi-physics finite-element library, available 
//LIC// at http://www.oomph-lib.org.
//LIC// 
//LIC//           Version 0.90. August 3, 2009.
//LIC// 
//LIC// Copyright (C) 2006-2009 Matthias Heil and Andrew Hazel
//LIC// 
//LIC// This library is free software; you can redistribute it and/or
//LIC// modify it under the terms of the GNU Lesser General Public
//LIC// License as published by the Free Software Foundation; either
//LIC// version 2.1 of the License, or (at your option) any later version.
//LIC// 
//LIC// This library is distributed in the hope that it will be useful,
//LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
//LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//LIC// Lesser General Public License for more details.
//LIC// 
//LIC// You should have received a copy of the GNU Lesser General Public
//LIC// License along with this library; if not, write to the Free Software
//LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
//LIC// 02110-1301  USA.
//LIC// 
//LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
//LIC// 
//LIC//====================================================================
//Demo code to document problem with missing "this->"
#include<iostream>



//==========Templated_base_class=======================================
/// Some Non-templated base class
//=====================================================================
template<unsigned TEMPLATE_PARAMETER>
class TemplatedBaseClass
{
public:

 /// Empty constructor
 TemplatedBaseClass(){};

 /// Empty virtual constructor
 ~TemplatedBaseClass(){};

 /// Some member function
 void say_hello_world()
  {
   std::cout << "Hello world from base class " << std::endl;
  }

};



//======templated_derived_class=======================================
/// Some templated derived class
//=====================================================================
template<unsigned TEMPLATE_PARAMETER>
class SomeDerivedClass : public virtual TemplatedBaseClass<TEMPLATE_PARAMETER>
{

public:

 // Empty constructor
 SomeDerivedClass(){};

 // Virtual empty constructor
 virtual ~SomeDerivedClass(){};

 /// Some member function
 void output_template_parameter()
  {
   std::cout << "My template parameter is: " 
             << TEMPLATE_PARAMETER << std::endl;

   // Now call the function in the base class

#ifdef USE_BROKEN_VERSION

   // This is illegal according to the C++ standard 
   say_hello_world();

#else 

   // This is stupid but in line with the C++ standard
   this->say_hello_world();
 
#endif

  }

};


//======start_of_main==================================================
/// Driver
//=====================================================================
int main()
{

 // Build the templated object:
 SomeDerivedClass<2> object;

 // Get it to output its template parameter and say hello:
 object.output_template_parameter();

} // end of main

If you compile this with sufficiently recent versions of the gcc compilers, using the flag -DUSE_BROKEN_VERSION, the compilation will fail with the following error:

broken_this_demo.cc: In member function 'void SomeDerivedClass<TEMPLATE_PARAMETER>::output_template_parameter()':
broken_this_demo.cc:55: error: there are no arguments to 'say_hello_world' that depend on a template parameter, so a declaration of 'say_hello_world' must be available
broken_this_demo.cc:55: error: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)

You may not only stumble across this problem in one of your own codes but it is also possible that some code in the library itself still violates this rule. This is because templated classes are only built when needed and it is conceivable that oomph-lib's suite of self-tests do not instantiate all templated classes that exist in the library. If you encounter any such problems, check if putting a "this->" in front of the function call fixes the problem. If it does, let us know!





Compilation problems and run-time errors

Warning about "discarded sections" during linking

When linking, some versions of the gcc compiler produce warnings about references to "discarded sections" being referenced. Here's an example:

/usr/bin/ld: `.gnu.linkonce.t._ZNK5oomph8QElementILj3ELj3EE14vertex_node_ptERKj' referenced in section `.rodata' of /home/mheil/version185/oomph/build/lib/libgeneric.a(Qelements.o): defined in discarded section `.gnu.linkonce.t._ZNK5oomph8QElementILj3ELj3EE14vertex_node_ptERKj' of /home/mheil/version185/oomph/build/lib/libgeneric.a(Qelements.o)

We admit to being slightly baffled by this. Other libraries seem to suffer from the same problem (google for .rodata discarded, say), but as far as we can tell no solution has ever been suggested, nor does one seem to be required. The executable works fine. Upgrade to a newer version of gcc?


My driver code compiles but dies with a segmentation fault

Suggestions:


My driver code runs but it produces incorrect/non-sensical results

Suggestions:

The Newton solver diverges

Suggestions:





Customisation and optimisation

I don't have tecplot. How do I change oomph-lib's output so it can be displayed by my own plotting package?

oomph-lib's high-level post-processing routines output the results of the computations in a form that is suitable for display with tecplot, a powerful commercial plotting package. Purists may find it odd that an open-source library should choose an output format that is customised for a commercial software package. We tend to agree... Our only excuse is that tecplot is very very good, and without it we would have found it extremely difficult to create many of the plots shown in the tutorials. [If you know of any open-source plotting package whose capabilities are comparable to those of tecplot, let us know!]

Angelo Simone has written a python script that converts oomph-lib's output to the vtu format that can be read by paraview, an open-source 3D plotting package. The conversion script can currently deal with output from meshes that are composed of 2D quad elements -- the extension to 3D is work in progress. Use of the conversion script is documented in another tutorial.

It is possible to display oomph-lib's default output (in more elementary form, obviously) with gnuplot. The trick is to specify the using option in gnuplot's plot commands -- in this mode gnuplot ignores tecplot's "ZONE" commands. For instance, trying to plot the x-y data created by the demo code for the solution of the 1D Poisson equation with

plot "RESLT/soln0.dat"
will fail because gnuplot gets confused by the ZONE specifications required by tecplot. However,
plot "RESLT/soln0.dat" using 1:2
works.

If the data is too complex to be displayed by gnuplot, you may wish to customise the output for your preferred plotting package. This is easily done as oomph-lib creates its output element-by-element. The elements' various output(...) functions are virtual functions that can easily be overloaded in a user-defined wrapper class.

Here is an example driver code that illustrates how to change the output from oomph-lib's QPoissonElement family of 1D-line/2D-quad/3D-brick Poisson elements so that they output the string "Hello world".

We include oomph-lib's generic and poisson library headers:

//LIC// ====================================================================
//LIC// This file forms part of oomph-lib, the object-oriented, 
//LIC// multi-physics finite-element library, available 
//LIC// at http://www.oomph-lib.org.
//LIC// 
//LIC//           Version 0.90. August 3, 2009.
//LIC// 
//LIC// Copyright (C) 2006-2009 Matthias Heil and Andrew Hazel
//LIC// 
//LIC// This library is free software; you can redistribute it and/or
//LIC// modify it under the terms of the GNU Lesser General Public
//LIC// License as published by the Free Software Foundation; either
//LIC// version 2.1 of the License, or (at your option) any later version.
//LIC// 
//LIC// This library is distributed in the hope that it will be useful,
//LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
//LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//LIC// Lesser General Public License for more details.
//LIC// 
//LIC// You should have received a copy of the GNU Lesser General Public
//LIC// License along with this library; if not, write to the Free Software
//LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
//LIC// 02110-1301  USA.
//LIC// 
//LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
//LIC// 
//LIC//====================================================================
//Demo code to document customisation of output

// oomph-lib includes
#include "generic.h"
#include "poisson.h"

and then create a customised version of the Poisson elements in which we overload the tecplot-based QPoissonElement<DIM,NNODE_1D>::output(...) function, defined in the poisson library:

// The wrapper class for the element has to be included into 
// the oomph-lib namespace
namespace oomph
{

//======customised_poisson=============================================
/// Customised Poisson element -- simply overloads the output function.
/// All other functionality is retained.
//=====================================================================
template<unsigned DIM, unsigned NNODE_1D>
class CustomisedQPoissonElement : public virtual QPoissonElement<DIM,NNODE_1D>
{

public:

 /// Empty constructor
 CustomisedQPoissonElement(){};

 /// Empty virtual constructor
 ~CustomisedQPoissonElement(){};

 /// Overload output function
 void output(std::ostream& output_file)
  {
   output_file << "Hello world" << std::endl;
  }

};

} //end extension of oomph-lib namespace

If we now call the output function, the version defined in the customised element is used. The remaining implementation of the Poisson element remains unchanged.



//======start_of_main==================================================
/// Driver
//=====================================================================
int main()
{

 using namespace oomph;

 // Build the templated object:
 CustomisedQPoissonElement<2,2> element;

 // Call the element's (customised) output function and dump to screen
 element.output(std::cout);

} // end of main






oomph-lib's implemention of the Navier-Stokes equations (say) is too general (and therefore too expensive) for my application. How do I change this?

Many of oomph-lib's equations classes (or elements) are implemented in great generality. For instance, our discretisation of the Navier-Stokes equations includes a source term in the continuity equation, and body force terms in the momentum equations; it allows switching between the stress-divergence and simplified forms of the viscous terms; it includes the mesh velocity into the ALE formulation of the time-derivatives; etc. This makes the elements very versatile and robust. However, the generality/robustness comes at a price: Even though we provide default values for most functions (e.g. the body force terms default to zero), their evaluation requires a finite amount of CPU time. If you wish to use the elements in a simple application in which the Navier-Stokes equations are solved in a fixed domain, without any body forces or other source terms, say, you may wish to disable the additional functionality.

This is easily done: After all, oomph-lib is open-source software and you can therefore change anything you want! In principle, you could edit the source code in the src/navier_stokes directory and delete (or at least comment out) all the functionality that you do not require. However, this is probably a risky step as it will break all demo codes (used during oomph-lib's self-test procedure) that use some of the features that you are not interested in. We therefore recommend copying the content of the directory src/navier_stokes into a new directory, e.g. user_src/my_navier_stokes and to edit the copied sources. Follow the instructions on the oomph-lib installation page to turn these sources into a separate library against which you can link.





Finding your way around the distribution


There is so much information -- how do I get started?

Yes, oomph-lib does contain a lot of code and a lot of documentation. How to get started obviously depends on your background: Are you familiar with the finite element method? How good is your knowledge of C++? Etc.

Here are some possible "routemaps" around the library:






Where is this class/function/... defined?

Assume you have studied one of the example codes and wish to find out more about the implementation of a particular class or function that is used there. How do you find its source code and/or its full documentation?

Generally, a class/function that is used in a demo code can only be defined in one of two places:

  1. In the demo driver code itself.
  2. In an included file and/or an associated library.
oomph-lib's tutorials tend to provide a fairly complete annotated listing of the relevant driver codes; if the function you are interested in is not mentioned explicitly in the tutorial, it is most likely to be defined in an include file. You can inspect the driver code in its entirety by following the link at the end of the tutorials. If you cannot find the class/function there, it must be defined in one of the include files listed at the beginning of the source code.

The included files themselves can either be located in the same directory as the demo driver (the directory also tends to be mentioned at the end of the tutorial) or in one of oomph-lib's sub-libraries. The source code for these is located in the sub-directories of the src directory. Often the class/function is defined in a source file with an "obvious" name; if not, use grep to find it. This can, of course, be done recursively. For instance, the command

find . \( -name '*.h' -o -name '*.cc' \) -exec grep -H FiniteElement {} \;  

issued in oomph-lib's top-level directory will search through the entire distribution to locate files that contain the string "FiniteElement".

You can also use the html-based representation of oomph-lib's data structure, created by doxygen, in the "bottom-up" discussion of the data structure. (Note that the search menu may not work on your browser.)





If all else fails...

How to report problems/bugs

If all else fails and you think you have found a bug in the library, make sure you follow these steps:
  1. Isolate the problem: Try to identify the shortest driver code that still produces the problem.

  2. Double-check the relevant documentation, the installation instructions and the other FAQs listed here.

  3. Does the problem persist when you compile the library and your test code without optimisation, and when the RANGE_CHECKING and PARANOID flags are set?

  4. Does the problem occur with a sufficiently recent version of the gcc compiler suite (version 3.2.3 and later)?

  5. If the above steps identify the problem, let us know, ideally with a bug fix!

  6. If you can't fix the problem yourself, get in touch either directly, or via our bugzilla-based bug-and-feature-tracking system, accessible online at

    http://oomph-lib.maths.man.ac.uk/bugzilla

    and provide as much information as possible (clear description of the problem; the source code; the Makefile; details of the compiler and compilation flags used; any warning/error messages that are displayed during the compilation of the library or the driver code itself; etc.)



PDF file

A pdf version of this document is available.
Generated on Mon Aug 10 11:18:34 2009 by  doxygen 1.4.7