.. _triangle-with-results-tutorial:

#########################################
UnstructGrid: A Simple Model with Results
#########################################

.. image:: ../images/tut_triangle_with_results.png
    :height: 300 
    :align: center

This tutorial shows how to build your own :class:`UnstructGridModel <cee::ug::UnstructGridModel>` geometry, part and 
results. The geometry is a very simple structure containing a single triangle and the following results:

-   a scalar result mapped as fringes
-   a vector result
-   a displacement result

.. note::
    This example expect the application to have a correctly configured :class:`cee::vis::View`
    in place. See demo applications on how to set up a :class:`cee::vis::View` in your application.


**Create model and data source**

Create a model and set a data source. 

Since you will be building our own geometry and not read from a file, we use a 
:class:`DataSourceMemory <cee::ug::DataSourceMemory>` object.

Upon creation of the :class:`DataSourceMemory <cee::ug::DataSourceMemory>`, you must specify a unique id for this data
source and how many geometries it will contain. Number of geometries cannot be changed once the data source has been 
created. In this example you only have one geometry.

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 46-48


**Create state**

Each data source can have many data states. This simple model will only have one state.
In the construction of a state, you need to give the state an unique id and set how many
geometries it contains. The number of geometries for a state must always be the same as 
for the data source it belongs to!

Create the state with an id and number of geometries and add it to the data source.

The :class:`ModelSpec <cee::ug::ModelSpec>` object is the model specification. Among many other settings, the model
specification tells which state(s) are current. Tell the model specification to use this
state.

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 51-54

**Create geometry**

Create a geometry object and add the geometry to the state at index 0 (since you only have one state).

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 57-59

**Create nodes collection**

Create a :class:`DataNodes <cee::ug::DataNodes>` object. :class:`DataNodes <cee::ug::DataNodes>` is a collection of 
nodes used for building the triangle. In this example you will use 3 nodes to create a triangle. 
Important! The nodes object must be set to the correct size before setting the actual 
node coordinates!

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 65-69

**Create elements**

Create the connectivities array for the nodes in the elements. These are specified as
one std::vector<unsigned int> for each element. In this example that means two arrays,
one for each triangle.

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 73-74


Create the :class:`DataElements <cee::ug::DataElements>` object. DataElements is a collection of elements used to define
a part. Each element has a element type (here TRIANGLE) and a connectivities array 
towards the matching :class:`DataNodes <cee::ug::DataNodes>` object.

Add the two triangle elements. 

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 77-78

**Create the part**

Create the :class:`DataPart <cee::ug::DataPart>` object.

A part consists of:

-   Node coordinates (:class:`DataNodes <cee::ug::DataNodes>`
-   Element connectivities (:class:`DataElements <cee::ug::DataElements>`)

Set the nodes and elements created above into the part.

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 81-84

Add the part to the geometry

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 87


**Create the scalar result**

Create a scalar result using node mapping. The scalar result takes a unique id and the
result mapping type upon construction.

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 94-95

Number of parts in the :class:`DataResultScalar <cee::ug::DataResultScalar>` must match number of parts in the geometry.
Scalar values and mapping type must also fit the corresponding part in the geometry.
Here the part is a single triangle with three nodes, hence a results array with three 
values using node mappings will fit.

Create a scalar result part and add it to the scalar result.

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 98-102,107


Each state has a result group for storing available results for each of its geometries. 
Add the scalar result to the result group for the corresponding geometry.

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 110

**Create the vector result**

Create a vector result using node mapping. The vector result takes a unique id and the
result mapping type upon construction.

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 117-118

As for scalars, the number of parts in the :class:`DataResultVector <cee::ug::DataResultVector>` must match the number 
of parts in the geometry. And result values and mapping type must match the corresponding
part. This means that the vector result array must have three vectors.

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 121-125, 131


Add the vector result to the result group for the corresponding geometry.

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 134


**Create the displacement result**

The displacement result takes a unique id upon construction.

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 141-142

As for scalars and vectors, the number of parts in the :class:`DataResultDisplacement <cee::ug::DataResultDisplacement>` 
must match the number of parts in the geometry. And result values must match the corresponding
part. This means that the displacement result array must have three displacement vectors.

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 145-149, 154


Add the displacement result to the result group for the corresponding geometry.

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 157


**Create the transformation result**

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 164

As for scalars and vectors, the number of parts in the 
:class:`DataResultTransformation <cee::ug::DataResultTransformation>` must match the number of parts in the geometry. 
The part in this case is a transformation matrix which applies to the part as whole.

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 167-169, 172


Add the transformation result to the result group for the corresponding geometry.

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 175


**Set up the created model**

When you're done creating the new data source (or have modified it), you need to 
populate the directory with the latest changes.

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 183-204

Then update the model spec to show all results

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 206-215


The model is ready to use and can be added to the view. Exactly where the view exists
depends on the platform and solution. These examples uses Qt and the view is set up 
in a :class:`cee::qt::ViewerWidget`.

.. literalinclude:: ../../../../EnvisionDesktop/Tutorials/UnstructGridModelResults.cpp
    :language: cpp
    :lines: 218,220,222

**See the complete source code here:**

:ref:`triangle-with-results-example`

