/*
 * Copyright (c) 2009-2012:  G-CSC, Goethe University Frankfurt
 * Author: Sebastian Reiter
 * 
 * This file is part of UG4.
 * 
 * UG4 is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License version 3 (as published by the
 * Free Software Foundation) with the following additional attribution
 * requirements (according to LGPL/GPL v3 §7):
 * 
 * (1) The following notice must be displayed in the Appropriate Legal Notices
 * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
 * 
 * (2) The following notice must be displayed at a prominent place in the
 * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
 * 
 * (3) The following bibliography is recommended for citation and must be
 * preserved in all covered files:
 * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
 *   parallel geometric multigrid solver on hierarchically distributed grids.
 *   Computing and visualization in science 16, 4 (2013), 151-164"
 * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
 *   flexible software system for simulating pde based models on high performance
 *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 */

/** \page pageLGOverview libGrid - Overview

- \ref secGrid "Grid"
- \ref secGeomObjs "Geometric Objects"
- \ref secObjectCreation "Object Creation"
- \ref secObjectIteration "Object Iteration"
- \ref secAttachments "Attachments"
- \ref secNeighborhood "Neighborhood"
- \ref secTools "Tools"
<br>
<hr>
\section secGrid Grid
<hr>
The central class of libGrid is the Grid class.
It handles element creation, neighbourhood management, data-attachments and observers.
The class MultiGrid is derived from Grid, and adds a hierarchical structure to the grids elements.
	- ug::Grid
	- ug::MultiGrid

<br>
<hr>
\section secGeomObjs Geometric Objects
<hr>
Geometric Objects are the building blocks of a grid.
There are four different basic geometric objects:
	- ug::Vertex
	- ug::Edge
	- ug::Face
	- ug::Volume
	
Those basic objects are then further specialized:
	- ug::Vertex
	- ug::Edge
	- ug::Triangle, ug::Quadrilateral
	- ug::Tetrahedron, ug::Hexahedron, ug::Prism, ug::Pyramid
	
For hanging-node support the following objects are introduced:
	- ug::ConstrainedVertex
	- ug::ConstrainingEdge. ug::ConstrainingEdge
	- ug::ConstrainingTriangle, ug::ConstrainingQuadrilateral, ug::ConstrainedTriangle, ug::ConstrainedQuadrilateral
	
All geometric objects deriving from Edge, Face or Volume feature methods to
access the vertices of an element:
	- ug::Face::num_vertices (the number of vertices / corners of the geometric object)
	- ug::Face::vertex (returns the i-th vertex of the geometric object)
	- ug::Face::vertices (returns a list of all vertices of the geometric object)

Furthermore they define methods like
	- ug::Face::num_sides (tells how many sides the given face has)

Please check the documentation of the different base types.


<br>
<hr>
\section secObjectCreation Object Creation
<hr>
Geometric Objects are created through the ug::Grid::create method (or ug::MultiGrid::create).
Since the Grid class only knows about the basic geometric objects,
ug::Grid::create<TGeomObj> is a template method, that takes the type
of the geometric object that is to be created as template argument:
\code
using namespace ug;(
...
Grid g;
// create vertices 
Vertex* v1 = *g.create<Vertex>();
Vertex* v2 = *g.create<Vertex>();

// create an edge 
g.create<Edge>(EdgeDescriptor(v1, v2));
\endcode

The create method takes an optional parameter:
\code ug::Grid::create(GeometricObject* pParent = NULL);\endcode
The parent is used in different ways:
	- ug::GridSubsetHandler can automatically assign a subset based on the parents subset.
	- ug::Selector can automatically assign the selection-status based on the parents selection status.
	- A ug::MultiGrid inserts elements one level above the parents level.
	- You can use the parent in your own grid-observer specializations (derive from ug::GridObserver)
	
All those beahviours can be enabled / disabled in the respective classes.

<br>
<hr>
\section secObjectIteration Object Iteration
<hr>
libGrid uses the technique of iterators for geometric-object access.
A separate iterator-type exists for each object-type:
	- ug::VertexIterator, ug::RegularVertexIterator, ...
	- ug::EdgeIterator, ug::RegularEdgeIterator, ...
	- ug::FaceIterator, ug::TriangleIterator, ug::QuadrilateralIterator, ...
	- ug::TetrahedronIterator, ug::HexahedronIterator, ug::PrismIterator, ug::PyramidIterator
	
You can query a grid for a begin and an end-iterator for each geometric-object type using
ug::Grid::begin and ug::Grid::end. Both methods are template methods. The template argument
specifies the type of geometric-object over which you want to iterate.

\code
// Let g be a grid that already contains some geometric objects 
// iterate over all vertices 
for(VertexIterator iter = g.begin<Vertex>();
	iter != g.end<Vertex>(); ++iter)
{
	Vertex* v = *iter;
	...
}

// iterate over all faces 
for(FaceIterator iter = g.begin<Face>();
	iter != g.end<Face>(); ++iter)
{
	Face* f = *iter;
	...
}

// iterate over all triangles 
for(TriangleIterator iter = g.begin<Triangle>();
	iter != g.end<Triangle>(); ++iter)
{
	Triangle* t = *iter;
	...
}
\endcode

The same technique can be used to iterate over all Triangles of a subset:
\code
using namespace ug;
...
Grid g;
SubsetHandler sh(g);	// short for GridSubsetHandler
...
// iterate over all triangles in subset 0 
for(TriangleIterator iter = sh.begin<Triangle>(0);
	iter != sh.end<Triangle>(0); ++iter)
{
	Triangle* t = *iter;
	...
}
\endcode

or a ug::Selector
\code
...
Selector sel(g);
...
for(TriangleIterator iter = sel.begin<Triangle>();
	iter != sel.end<Triangle>(); ++iter)
...
\endcode

or a level of a ug::MultiGrid
\code
...
MultiGrid mg;
...
for(TriangleIterator iter = mg.begin<Triangle>(0);
	iter != mg.end<Triangle>(0); ++iter)
\endcode

or triangles on level l in subset i of a ug::MultiGridSubsetHandler
\code
...
MGSubsetHandler mgsh(mg);	// short for MultiGridSubsetHandler
...
for(TriangleIterator iter = mgsh.begin<Triangle>(i, l);
	iter != mgsh.end<Triangle>(i, l); ++iter)
...
\endcode

There are even more classes that support this way of geometric-object iteration.
\sa ug::GridObjectCollection

<br>
<hr>
\section secAttachments Attachments
<hr>
Through attachments custom data can be associated with the geometric objects in a ug::Grid
or a subset of a ug::GridSubsetHandler or ug::MultiGridSubsetHandler.
Data is attached to all objects of the same basic type at once (ug::Vertex, ug::Edge,
ug::Face, ug::Volume).

Lets say we wanted to associate an integer with each vertex in a grid g. This could be done as follows:
\code
// we define the attachment type  
typedef Attachment<int> AInt;

// The instance of the attachment-type serves as identifier for the attachment. 
AInt aInt;

// Let g be an instance of ug::Grid or ug::MultiGrid
g.attach_to_vertices(aInt);
\endcode

When aInt is being attached to the vertices of the grid, memory is automatically allocated and
associated with the vertices. If you add or remove vertices, the memory is adjusted in the background.

To access the integer-value that is associated with each vertex, an attachment-accessor is required:

\code
// a vertex-attachment-accessor for attachments of type AInt 
// We want it to operate on the Grid g and on the attachment aInt  
Grid::VertexAttachmentAccessor<AInt> aaInt(g, aInt);

// iterate over all vertices of the grid and assign 12 to the attached integer-value 
for(VertexIterator iter = grid.vertices_begin(); iter != grid.vertices_end(); ++iter)
	aaInt[*iter] = 12;
\endcode

The vertex-attachment-accessor features the operator [] that takes a pointer to a vertex
and returns a reference to the associated value.

<br>
Data can be attached to elements of a subset of an ug::GridSubsetHandler or ug::MultiGridSubsetHandler like this:
\code
...
SubsetHandler sh(g);
...
// attach the integers to all faces in subset 2 
sh.attach_to_faces(aInt, 2);

// access the attachment 
SubsetHandler::AttachmentAccessor<Face, AInt> aaIntSH2(sh, aInt, 2);

// Assign values: 
// Please note that you may only pass faces to the accessor that are contained in subset 2. 
for(FaceIterator iter = sh.faces_begin(2); iter != sh.faces_end(2); ++iter)
	aaIntSH2[*iter] = 17;
\endcode

<br>
<hr>
\section secNeighborhood Neighborhood
<hr>
Given a geometric object, there are several methods to access neighbor elements
in a grid. The most powerful methods in this context is the method
ug::Grid::associated_elements. It can be used with any combination of
geometric base objects. E.g., it can be used to retrieve all faces which are
connected to an edge or all faces, which are connected to a volume element.
Here is an example, where we retrieve a container with all edges, which are
connected to a volume element:

\code
//	Let vol be of type Volume* (or of any derived type) and grid of type Grid&
//	declare a container in which we'll collect all associated edges of vol
Grid::edge_traits::secure_container edges;

grid.associated_elements(edges, vol);

//	one could now iterate over the received edges
for(size_t i = 0; i < edges.size(); ++i){
	Edge* e = edges[i];
	//...
}
\endcode

The code works for all combinations of Vertex, Edge, Face and Volume.
Note however, that the method does not guarantee, that the order of the elements
in the returned container is the same as the order of the reference element, e.g.,
when collecting sides of a volume. Since some methods rely on the order, a second
method exist, which guarantees that the order matches reference elements order:
ug::Grid::associated_elements_sorted. The method can basically be used as 
associated_elements, but has the restriction, that the dimension of the elements
in the returned container has to be lower than the dimension of the element in
the second argument. Otherwise no order could be defined. Furthermore
ug::Grid::associated_elements_sorted may be a little slower than 
ug::Grid::associated_elements. The latter should thus be preferred, if the order
is not important. 

While those two methods allow to completely access all neighbors in a grid
(possibly with a little work),
some conveniance methods exist to, e.g., to retrieve a single side of an element or
to retrieve all neighbors of the same geometric object type
(e.g. all faces which are adjacent to a given face). All related methods are listed below.

The main methods to access associated elements, as explained above.
Note that while those methods can be used to retrieve the vertices of, e.g., a Face,
the direct way through Face::vertex or Face::vertices should be preferred if possible.
- ug::Grid::associated_elements
- ug::Grid::associated_elements_sorted
 
Returns the geometric object given a couple of vertices
- ug::Grid::get_edge
- ug::Grid::get_face
- ug::Grid::get_volume
- ug::Grid::get_element

Returns the i-th side of a geometric object (use e.g. Face::num_sides to retrieve
the number of sides of that object).
- ug::Grid::get_side

Furthermore methods exist to collect, e.g., all faces which are adjacent to a given face
(same for vertices, edges and volumes):
- ug::CollectNeighbors


<br>
<hr>
\section secTools Tools
<hr>
There are some classes that help tremendously when implementing algorithms:
the Selector and the SubsetHandler.
	- ug::Selector
	- ug::GridSubsetHandler, ug::MultiGridSubsetHandler


*/