COOLFluiD  Release kernel
COOLFluiD is a Collaborative Simulation Environment (CSE) focused on complex MultiPhysics simulations.
Flexible mesh data structure

Features

Description

The mesh is assembled from specialized components. The two most important components are the topology and the geometry_fields.

An example mesh tree of a plane:

tree                                                  |  type
-------------------------------------------------------------------------------
mesh                                                  |  cf3::mesh::Mesh
                                                      |
    topology                                          |  cf3::mesh::Region
        surrounding                                   |  cf3::mesh::Region
        body                                          |  cf3::mesh::Region
        wings                                         |  cf3::mesh::Region
            wing_1                                    |  cf3::mesh::Region
            wing_2                                    |  cf3::mesh::Region
                patch_1                               |  cf3::mesh::Region
                patch_2                               |  cf3::mesh::Region
        tail                                          |  cf3::mesh::Region
                                                      |
    geometry                                          |  cf3::mesh::Dictionary
        coordinates                                   |  cf3::mesh::Field

Elements

Inside the regions there exist more nested components of the type Entities, defining elements. Every element type is grouped separately. Looking at the region "body" more deeply:

tree                                                  |  type
-------------------------------------------------------------------------------
...                                                   |
    body                                              |  cf3::mesh::Mesh
                                                      |
        quads                                         |  cf3::mesh::Entities
            element_type                              |  cf3::mesh::ElementType
            spaces                                    |  cf3::common::Group
                geometry                              |  cf3::mesh::Space
                    shape_function                    |  cf3::mesh::ShapeFunction
                    connectivity                      |  cf3::mesh::Connectivity
                                                      |
        triags                                        |  cf3::mesh::Entities
            element_type                              |  cf3::mesh::ElementType
            spaces                                    |  cf3::common::Group
                geometry                              |  cf3::mesh::Space
                    shape_function                    |  cf3::mesh::ShapeFunction
                    connectivity                      |  cf3::mesh::Connectivity
...                                                   |

In this tree you can see that the body of the plane is constructed out of quadrilaterals and triangles. The element type of each is defined in the component "element_type". The element_type provides all information needed to describe the element and transformations of a physical space to a mapped space.

The connectivity-table of the elements, which for each element describes which nodes it connects, is stored in the component "connectivity". It is essentially a table where each row describes one element, and the values of each row point to indexes in the geometry field-group at "mesh/geometry".

Spaces and Dictionaries

The concept of "space" is here introduced as an invisible mesh completely overlapping the original mesh. It has exactly the same elements as the original mesh, but every element is defined by a different set of nodes.

One "space" that is always there is called "geometry". This name is not by coincidence the same as the Dictionary "geometry", as this space and dictionary together describe the actual mesh geometry.

When a mesh is defined with Lagrange-P1 elements (nodes in vertices), but a field of a higher order P2 is desired, another "space" can be created a posteriori. Let's create the space "P2" in the same tree:

tree                                                  |  type
-------------------------------------------------------------------------------
...                                                   | 
    body                                              |  cf3::mesh::Mesh
        quads                                         |  cf3::mesh::Entities
            element_type                              |  cf3::mesh::ElementType
            spaces                                    |  cf3::common::Group
                geometry                              |  cf3::mesh::Space
                    ...                               |
                P2                                    |  cf3::mesh::Space
                    shape_function                    |  cf3::mesh::ShapeFunction
                    connectivity                      |  cf3::mesh::Connectivity
        triags                                        |  cf3::mesh::Entities
            ...                                       |
...                                                   |

The shape_function here describes Lagrange-P2 quadrilateral elements with 9 nodes. This space has therefore a connectivity-table with 9 columns instead of 4 for the (Lagrange-P1) geometry space. What is evident now is that the entries of this connectivity table are indexes to something that does not exist yet: another SpaceFields.

A SpaceFields is characterized by 2 things:

Fields that share the same space and region are grouped together inside the SpaceFields. Hence its name.

The mesh tree now has to contain the SpaceFields as well.

tree                                                  |  type
-------------------------------------------------------------------------------
mesh                                                  |  cf3::mesh::Mesh
                                                      |
    topology                                          |  cf3::mesh::Region
        surrounding                                   |  cf3::mesh::Region
        body                                          |  cf3::mesh::Region
        wings                                         |  cf3::mesh::Region
            ...                                       |
        tail                                          |  cf3::mesh::Region
                                                      |
    geometry                                          |  cf3::mesh::Dictionary
        coordinates                                   |  cf3::mesh::Field
                                                      |
    P2                                                |  cf3::mesh::Dictionary
        coordinates                                   |  cf3::mesh::Field
        pressure                                      |  cf3::mesh::Field
        velocity                                      |  cf3::mesh::Field

Remarks

It can be noticed that the coordinates Field is not strictly necessary in the P2 SpaceFields, as it can be computed on the fly through the information from the P2 and geometry shape functions, and the geometry coordinates.

The creation of the P2 space and SpaceFields is completely optional and for demonstration purposes only. It is perfectly possible to create all desired fields in the geometry space and fieldgroup. Note however that the geometry fieldgroup only supports continuous fields.

Discontinuous fields require a separate space.

Note
Following should go to different page for developers

Elements

The component grouping elements of the same type and region are of the abstract type cf3::mesh::Entities.

The distinction is made between cf3::mesh::Cells and cf3::mesh::Faces for the purpose of identification only. It is easier in algorithms to identify what is a cell or a face:

boost_foreach( const cf3::mesh::Cells& cells, find_components_recursively<cf3::mesh::Cells>(mesh) )
{
// only volume elements are looped over.
}
boost_foreach( const cf3::mesh::Faces& faces, find_components_recursively<cf3::mesh::Faces>(mesh) )
{
// only face elements are looped over.
}
boost_foreach( const cf3::mesh::Entities& elements, find_components_recursively<cf3::mesh::Elements>(mesh) )
{
// both face and volume elements are looped over.
}

Working with fields

Often one wants to loop over fields through the use of the elements.

// Assume we have a cf3::mesh::Field "mesh/P2/velocity" called velocity
// Get the dictionary this field is located in.
const cf3::mesh::Dictionary& dict = velocity.dict();
// Loop over all Entities that this dictionary is defined for
boost_foreach( const Handle<cf3::mesh::Entities const>& entities, dict.entities_range() )
{
// The dictionary specifies which space to use
const cf3::mesh::Space& space = entities.space(dict);
// Loop over every element of this type
for (Uint elem=0; elem<entities.size(); ++elem)
{
// loop over every point of this element
for (Uint point=0; point<shape_function().nb_nodes(); ++point)
{
velocity[ space.connectivity()[elem][point] ][ XX ] = 1.5;
velocity[ space.connectivity()[elem][point] ][ YY ] = 0.1;
}
}
}

Notice that in this case the vertices that are shared between elements are visited multiple times. This is only the case for continuous spaces. For discontinuous spaces the vertices are never shared.

You can also loop over the field directly:

// Assume we have a cf3::mesh::Field "mesh/P2/velocity" called velocity,
// and we want it to assign a rotational velocity around (0,0)
// Get the dictionary this field is located in.
const cf3::mesh::Dictionary& dict = velocity.dict();
// A dictionary also has a coordinates field that can be used
// Loop over all field indices
for (Uint point=0; point<dict.size(); ++point)
{
velocity[point][XX] = coordinates[point][YY];
velocity[point][YY] = -coordinates[point][XX];
}
Send comments to:
COOLFluiD Web Admin