Commit 8ce38da0 authored by Jakub Klinkovský's avatar Jakub Klinkovský
Browse files

Documentation: writing mesh tutorial

parent 9fd8dd80
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -5,3 +5,4 @@ add_subdirectory( ReductionAndScan )
add_subdirectory( ForLoops )
add_subdirectory( Pointers )
add_subdirectory( Matrices )
add_subdirectory( Meshes )
+51 −0
Original line number Diff line number Diff line
set( COMMON_EXAMPLES
)
set( CPP_EXAMPLES
   ReadMeshExample
   ${COMMON_EXAMPLES}
)
set( CUDA_EXAMPLES
   ${COMMON_EXAMPLES}
)

foreach( target IN ITEMS ${CPP_EXAMPLES} )
   add_executable( ${target} ${target}.cpp )
   add_custom_command( COMMAND ${target} > ${TNL_DOCUMENTATION_OUTPUT_SNIPPETS_PATH}/${target}.out OUTPUT ${target}.out )
   set( CPP_OUTPUTS ${CPP_OUTPUTS} ${target}.out )
endforeach()
add_custom_target( RunTutorialsMeshesExamples ALL DEPENDS ${CPP_OUTPUTS} )

if( BUILD_CUDA )
   foreach( target IN ITEMS ${CUDA_EXAMPLES} )
      cuda_add_executable( ${target}-cuda ${target}.cu OPTIONS )
      add_custom_command( COMMAND ${target}-cuda > ${TNL_DOCUMENTATION_OUTPUT_SNIPPETS_PATH}/${target}.out OUTPUT ${target}.out )
      set( CUDA_OUTPUTS ${CUDA_OUTPUTS} ${target}.out )
   endforeach()
   add_custom_target( RunTutorialsMeshesCudaExamples ALL DEPENDS ${CUDA_OUTPUTS} )
endif()

find_package( ZLIB )
if( ZLIB_FOUND )
   foreach( target IN ITEMS ${CPP_EXAMPLES} ${CUDA_EXAMPLES} )
      target_compile_definitions(${target} PUBLIC "-DHAVE_ZLIB")
      target_include_directories(${target} PUBLIC ${ZLIB_INCLUDE_DIRS})
      target_link_libraries(${target} ${ZLIB_LIBRARIES})
   endforeach()
endif()

find_package( tinyxml2 QUIET )
if( tinyxml2_FOUND )
   foreach( target IN ITEMS ${CPP_EXAMPLES} ${CUDA_EXAMPLES} )
      target_compile_definitions(${target} PUBLIC "-DHAVE_TINYXML2")
      target_link_libraries(${target} tinyxml2::tinyxml2)
   endforeach()
endif()


set( DATA_FILES
   example-triangles.vtu
)

foreach( file IN ITEMS ${DATA_FILES} )
   configure_file(${file} ${CMAKE_CURRENT_BINARY_DIR}/${file} COPYONLY)
endforeach()
+35 −0
Original line number Diff line number Diff line
#include <TNL/Meshes/TypeResolver/TypeResolver.h>

// Define the tag for the MeshTypeResolver configuration
struct MeshConfigTag {};

namespace TNL {
namespace Meshes {
namespace BuildConfigTags {

template<> struct MeshCellTopologyTag< MeshConfigTag, Topologies::Triangle > { enum { enabled = true }; };
template<> struct MeshCellTopologyTag< MeshConfigTag, Topologies::Quadrangle > { enum { enabled = true }; };

} // namespace BuildConfigTags
} // namespace Meshes
} // namespace TNL

// Define the main task/function of the program
template< typename Mesh >
bool task( const Mesh& mesh, const std::string& inputFileName )
{
   std::cout << "The file '" << inputFileName << "' contains the following mesh: "
             << TNL::getType<Mesh>() << std::endl;
   return true;
}

int main( int argc, char* argv[] )
{
   const std::string inputFileName = "example-triangles.vtu";

   auto wrapper = [&] ( auto& reader, auto&& mesh ) -> bool
   {
      return task( mesh, inputFileName );
   };
   return ! TNL::Meshes::resolveAndLoadMesh< MeshConfigTag, TNL::Devices::Host >( wrapper, inputFileName, "auto" );
}
+23 −0
Original line number Diff line number Diff line
<?xml version="1.0"?>
<VTKFile type="UnstructuredGrid" version="1.0" byte_order="LittleEndian" header_type="UInt64" compressor="vtkZLibDataCompressor">
<UnstructuredGrid>
<Piece NumberOfPoints="142" NumberOfCells="242">
<Points>
<DataArray type="Float64" Name="Points" NumberOfComponents="3" format="binary">
AQAAAAAAAABQDQAAAAAAAFANAAAAAAAA+QYAAAAAAAA=eJxtVns4lGkUp5J00VPRblTSTY2WwtiimRNdLLkr2qRohMKmp6QttpJLuWR1sxNLuZX2ERWV6W4o0yZjaIpGbtPMmJqli9t6NPtN3/re+WY6f/DM77185/x+57znaGh823bvYGJWAar4J/OHe9PvXQdnP/y/6vp13fOkc/l1nmx9OzZMd5ryMLi4nMD3nbdkONDKYeO0AMExczaBB/gqvstRu3fEKr7ej9YHCvW4orw60Ljn09IQX652bkKyJWYNBJ62uzjhrOlNsHRU/OIS+KES+8iWyidwLNM0uLzvMYGfkVuQzn/bnyZiPT6+6LjuzjIw9/uyt9qXT+DSceFfuml8GMg+kN3ZX0bgeuvuL4tP4cHr/k+WDtIqte/s/knxt43A/Z+G/xVWcAtqmI4pEw+2EPj3+ex6HcsamGhvVbqOxyPwKA8myT9VkzMU/HQS6736rPDcslJYzlecayfwouVJ8RksLkya6MkXWD1H+yNmuHFfV0Hm0pUXHDe9IvA76QsKfJ4KIOj1Cu+70eq6PPstCDMRge83ia03eXAT3Py3ML0bhQQucPANjN3XBOy1HV6rOlGeQI7W7X0/82HfbEaZtVMtgS9OLBCEtFeCcw0jmyJG/le3bDGKuMGBpNHJV0I93xC43IJhEzOeC3Uvzuo/aEb+l2hafdW971bhx8bLSH+jfDlmrWrxLNAl8zhihhE4jzfH4nk3gmc6keMfMderzzATgr8deT/ZetTwhfcV594T+NYovD71PyTWu1yWETi5PtXv+UPhLrOLwBO+pPkveVkKlczJgzpiMYEbf6h5cdr8FuRd4g4MiqUEPjWRfH7E2sLDenRbxUD7vD16kT/K/9Qlq8NZGWxY4zduqvU25GfOdZxnrzkK/pHuoyIqZ6XPZUNk25z17Y+RP/5ao2kBZhxIYGmeiHuD8ic9uhbjRQBcs37jVttnBD42zoWSl9UEpZtiLadfQfoOnlw+5ujROjjuPS3qyNQOAtcexN+RNeOHy3Puo/xppj1/yYjiQ8TTzhadlajOkthkPUbs6STt+dxR78DeYIDJH3ubWHcZj+ePiEqOl/d/nlDDyDhu6voJPuN62/1Ifp/J7yY6947x1qurTgJ7fMy0tCjq96v2gXmz/ZxsEziQ65iwtDMF6e7xWH904CQu2NyZJdxFRzr2C/H8d1lL5t/jfV8gfbgOBuVG+ZnFSMdB5/6cmQsaQBJqZsjqQDp2SJzm+GLvoLecYdKlVI+808wH454L4EjeW7ePFoh/q5hhrnsEH2JrD2jEzEI6Ck3NgrtymqAkY6N3NQvpaJFjzfl1kwz23z51Lm8d4qFpyKZ6Q70UalX6kqN27dc6DbYjx7VmWRDjc68YpDsOjjLdgnByH1LVrQdU+16offOFFmoDxCVuzm6NRDzHseDuxRA+jO32pFnYIp4nNBziRlt1wpDmxowTSvlsO6TIHz68tT4su1SCeNYJqzqxEMt/nf3yMe4ixDM95EbJm/Pt4HpRI6bXCvGZ+uT8h2SM/55mgyHOPcRbd013fihPABbGDzlZcxHPLutpbzxWyKDfPiGFqYv67MJHDT5pn7pAeK3IWe8o8vNTOp7nibXk95bcX9V5U+3PMcmneQPY/h9SfA2tlXj72w1/B/q2U9xSbRBvvXMN14l4Qti6eYhXqFS/CaIq91Zs/5nHz9cWK/FG97PXGoXxsH2DS7C1FPE2JgivX00j8vtwpszk5RSMT4Ngu1nB8xE/2cG4H/GLcH1G8LMmEzXlMyWQI8qjXI1D/pDnAMSDJrXZvU8khT8X92U9SVXt8z2g2v9Xee3q1sbuoTmYWhop8cNJH1yeidUpNWiIflKJn6Q9tnR5kgjoob3FlM8orslVlKgsbP+rDK2zRUr8HA8PNb6C8TAsSdnTrMRPwprJL9uwelly7Y7rDSUe+gILD2q5ymDXtBqNJVUCxE+Uu9B6nhSo669ENvqifkueV9TzQbU/U5q1NajY/l9cAy8bKsU7IMH7bG4YOR9EBs8i6ZMkYGUm9oimIz/jQzz1NnOEYHDO+YjbVRTvjLRp9dkhInBb/JtX9D8oXpaUo3vYUQZSSgr11mE0h5DnHuT/bpPfs+OqpVDTVHpxW0GHWlyq80XFd238xgARMFfr5yzci+Kq8C8ShsrFYFPsstqMhuLyuIT35eHKopVUJV0u7uQXZUrEMKZUM6AwF8WVdcF9uk7Ne1gmP7o4WShU80fVf/L8gXBKD96PMlXmEPKcgfb/a2uaxjJ/B6dah7W9nGRq3/12X+0B1Xlq9sp2/Xo9KbTpu884bo744Tfe7p3gLQOXOzNSfWzeofl2Qwr7Qr4U9iyqSPbxEyvpZaH3yFgGw9ZzSyc4SNS+qzrv/Aefg+qo
</DataArray>
</Points>
<Cells>
<DataArray type="Int32" Name="connectivity" format="binary">
AQAAAAAAAABYCwAAAAAAAFgLAAAAAAAAbAMAAAAAAAA=eJxN0ItXlVUQxuFTaRoUEZZGiGKSWUkaR4jQlASMi5qACkKKmBFeTkIiVMbFJPUI/M/uWT3fWvusNWtm9sy87+87pVKp9EaKN0v//yK/5W1H1kfe6f1tsx3eYrbL3k7z3ebvmNXoa+3skmvsv5vd7Lb3nvs6uUZd47bW3ftuIuq9f+C+Qa5Tx+2eTKdWHzof0vrI/V59fcYU9T7zBjsN9D4WdTRr7e6h3UjvEx5N8l51zPbzaHZbT/9A5hUeB+XQbklxSL2P16f8Ih9O0Sp/luJIis9THE3xhTrylxgacXyF9Zjd6Nu8NXlvwnUAc73bQ1iaMR+0U3AXzC24g+vrFMcxt+I4jLfVznH9USwFd+QTbr7J+I/ZC872jDlYyilOYoz9DkzNGWtnim/VwdqVsQfvdym61d34WjE0qoP3lNlp/fcpzrhvwx7fcNb3nMC2n1Yb9nb8ZXUZayf+ZnddGDvwd/qGLn0L7zMZd+QezKf4HsFc8Pfog/8H98F2DvNZuRdHaPTZabfXn7GXsZ3HGjc/phjAWvAP2hvSx2wYc/ENF/D18Q3mi3IwX5J7sA+77cUcbD/5hl4cJ+mdw9wvypg7sZ3H3OFuCOOAehD3MM5uPD36voz3knwa52V3vThGcEY/yi/ux8yK/7gf15UUV9WDmOLmWopxfPE2YT7E7zq2SUwF50VeUxnvZfsF5wi2n7EWnGN8R/AVbFfwXcUwgW3A/gSucTwX+E3xn1SPYQqeG3ZG+d3EE/10ilu0x8xGcMxkXLflgif2f8n6Oyl+5R9eszgm6Rf/0w1713mP8vwN0zTda+5uZiwzGctt3nfEuLvQnuM7K8/RmvIWDHftTvO4hyH6+7Ti5oH5jJ0Z3hU5vH+X4+Yh3Xm+s/ICrVve7topGO7x/QNHwfCAZuFdybwL34fqeT5z7mb14fXIPHQWM6/Ij2nEzZKdir0K7WU7f+r/oj3vbsHtI7N5uvfp/M2v8FqiVaG9qF/O9J9kugv60P/H/LG7FfrRr9pfo7dIc0W/ro/7pzSX5DXaT83/TfEsxQbtFfr/8Vs1j/65/dh9wWuN37rbZW9PeITXS/UzGht0Y79Ke9XshfkrOpuZftXNGr1N2lv65+421Ktutum+sr/tZp1GVb+Z6VTtb8tbompvy3v0rwHybcuS
</DataArray>
<DataArray type="Int32" Name="offsets" format="binary">
AQAAAAAAAADIAwAAAAAAAMgDAAAAAAAAgwEAAAAAAAA=eJwNwwOMUAEAANB/l3nZtm3btm3bdZdt27Zt21itVqvVarVarVarVe9tL1IQBFGNYWzDTGBik5nSNKY3k1nNYW7zWdAiFreUZa1gZatZ0zrWt5FNbWFr29nRLna3l30d4GCHOdIxjnWCk53mTOc430UudYWrXedGt7jdXe71gIc95knPeN5LXvWGt73nQ5/4zBe+8o3v/OAnv/jNH/7yj/8MDQmCKEY3lnGNbyKTmsLUpjOjWcxuLvNawMIWs6RlLG8lq1rD2tazoU1sbivb2sHOdrOnfezvIIc6wtFGON5JTnWGs53nQpe43FWudYOb3eZO97jfQx71hKc950WveN1b3vWBj33qc1/62re+96Of/ep3f/rbv4aEBkFkoxnTOMYzoUlMbirTmsHMZjOnecxvIYtawtKWs6JVrG4t69rAxjazpW1sbye72sPe9nOgQxzuKMMd50SnON1ZznWBi13mSte43k1udYe73edBj3jcU571gpe95k3veN9H/gcAo3R3
</DataArray>
<DataArray type="UInt8" Name="types" format="binary">
AQAAAAAAAADyAAAAAAAAAPIAAAAAAAAADAAAAAAAAAA=eJxjZR1pAAA/VwS7
</DataArray>
</Cells>
</Piece>
</UnstructuredGrid>
</VTKFile>
+67 −0
Original line number Diff line number Diff line
\page tutorial_Meshes  Unstructured meshes tutorial

[TOC]

## Introduction

The [Mesh](@ref TNL::Meshes::Mesh) class template is a data structure for _conforming unstructured homogeneous_ meshes, which can be used as the fundamental data structure for numerical schemes based on finite volume or finite element methods.
The abstract representation supports almost any cell shape which can be described by an [entity topology](@ref TNL::Meshes::Topologies).
Currently there are common 2D quadrilateral, 3D hexahedron and arbitrarily dimensional simplex topologies built in the library.
The implementation is highly configurable via templates of the C++ language, which allows to avoid the storage of unnecessary dynamic data.
The internal memory layout is based on state--of--the--art [sparse matrix formats](@ref TNL::Matrices), which are optimized for different hardware architectures in order to provide high performance computations.
The [DistributedMesh](@ref TNL::Meshes::DistributedMeshes::DistributedMesh) class template is an extended data structure based on `Mesh`, which allows to represent meshes decomposed into several subdomains for distributed computing using the Message Passing Interface (MPI).

## Reading a mesh from a file

The most common way of mesh initialization is by reading a prepared input file created by an external program.
TNL provides classes and functions for reading the common VTK, VTU and Netgen file formats.

\dontinclude ReadMeshExample.cpp

The main difficulty is mapping the mesh included in the file to the correct C++ type, which can represent the mesh stored in the file.
This can be done with the [MeshTypeResolver](@ref TNL::Meshes::MeshTypeResolver) class, which needs to be configured to enable the processing of the specific cell topologies, which we want our program to handle.
For example, in the following code we enable loading of 2D triangular and quadrangular meshes:

\skip #include
\until // namespace TNL

There are other build config tags which can be used to enable or disable specific types used in the mesh: `RealType`, `GlobalIndexType` and `LocalIndexType`.
See the [BuildConfigTags](@ref TNL::Meshes::BuildConfigTags) namespace for an overview of these tags.

Next, we can define the main task of our program as a templated function, which will be ultimately launched with the correct mesh type based on the input file.
We can also use any number of additional parameters, such as the input file name:

\skip Define the main task
\until }

Of course in practice, the function would be much more complex than this example, where we just print the file name and some textual representation of the mesh to the standard output.

Finally, we define the `main` function, which sets the input parameters (hard-coded in this example) and calls the [resolveAndLoadMesh](@ref TNL::Meshes::resolveAndLoadMesh) function to resolve the mesh type and load the mesh from the file into the created object:

\skip int main
\until }
\until }

We need to specify two template parameters when calling `resolveAndLoadMesh`:

1. our build config tag (`MeshConfigTag` in this example),
2. and the [device](@ref TNL::Devices) where the mesh should be allocated.

Then we pass the the function which should be called with the initialized mesh, the input file name, and the input file format (`"auto"` means auto-detection based on the file name).
In order to show the flexibility of passing other parameters to our main `task` function as defined above, we suggest to implement a wrapper lambda function (called `wrapper` in the example), which captures the relevant variables and forwards them to the `task`.

The return value of the `resolveAndLoadMesh` function is a boolean value representing the success (`true`) or failure (`false`) of the whole function call chain.
Hence, the return type of both `wrapper` and `task` needs to be `bool` as well.

For completeness, the full example follows:
\includelineno ReadMeshExample.cpp

## Mesh configuration

## Public interface and basic usage

## Parallel iteration over mesh entities

## Writing a mesh and data to a file

## Example: Game of Life
Loading