<a name="Intro"></a>
<h1>Introduction</h1>


deal.II has a unique feature which we call
``dimension independent programming''. You may have noticed in the
previous examples that many classes had a number in angle brackets
suffixed to them. This is to indicate that for example the
triangulation in two and three space dimensions are different, but
related data %types. We could as well have called them
<code>Triangulation2d</code> and <code>Triangulation3d</code> instead
of <code>Triangulation@<2@></code> and
<code>Triangulation@<3@></code> to name the two classes, but this
has an important drawback: assume you have a function which does
exactly the same functionality, but on 2d or 3d triangulations,
depending on which dimension we would like to solve the equation in
presently (if you don't believe that it is the common case that a
function does something that is the same in all dimensions, just take
a look at the code below - there are almost no distinctions between 2d
and 3d!). We would have to write the same function twice, once
working on <code>Triangulation2d</code> and once working with a
<code>Triangulation3d</code>. This is an unnecessary obstacle in
programming and leads to a nuisance to keep the two function in sync
(at best) or difficult to find errors if the two versions get out of
sync (at worst; this would probably the more common case).




Such obstacles can be circumvented by using some template magic as
provided by the C++ language: templatized classes and functions are
not really classes or functions but only a pattern depending on an
as-yet undefined data type parameter or on a numerical value which is
also unknown at the point of definition. However, the compiler can
build proper classes or functions from these templates if you provide
it with the information that is needed for that. Of course, parts of
the template can depend on the template parameters, and they will be
resolved at the time of compilation for a specific template
parameter. For example, consider the following piece of code:
@code
  template <int dim>
  void make_grid (Triangulation<dim> &triangulation)
  {
    GridGenerator::hyper_cube (triangulation, -1, 1);
  };
@endcode



At the point where the compiler sees this function, it does not know
anything about the actual value of <code>dim</code>. The only thing the compiler has is
a template, i.e. a blueprint, to generate
functions <code>make_grid</code> if given a particular value of
<code>dim</code>. Since <code>dim</code> has an unknown value, there is no
code the compiler can generate for the moment.



However, if later down the compiler would encounter code that looks, for
example, like this,
@code
  Triangulation<2> triangulation;
  make_grid (triangulation);
@endcode
then the compiler will deduce that the function <code>make_grid</code> for
<code>dim==2</code> was
requested and will compile the template above into a function with dim replaced
by 2 everywhere, i.e. it will compile the function as if it were defined
as
@code
  void make_grid (Triangulation<2> &triangulation)
  {
    GridGenerator::hyper_cube (triangulation, -1, 1);
  };
@endcode



However, it is worth to note that the function
<code>GridGenerator::hyper_cube</code> depends on the dimension as
well, so in this case, the compiler will call the function
<code>GridGenerator::hyper_cube@<2@></code> while if dim were 3,
it would call <code>GridGenerator::hyper_cube@<3@></code> which
might be (and actually is) a totally unrelated  function.



The same can be done with member variables. Consider the following
function, which might in turn call the above one:
@code
  template <int dim>
  void make_grid_and_dofs (Triangulation<dim> &triangulation)
  {
    make_grid (triangulation);

    DoFHandler<dim> dof_handler(triangulation);
    ...
  };
@endcode
This function has a member variable of type
<code>DoFHandler@<dim@></code>. Again, the compiler can't
compile this function until it knows for which dimension. If you call
this function for a specific dimension as above, the compiler will
take the template, replace all occurrences of dim by the dimension for
which it was called, and compile it. If you call the function several
times for different dimensions, it will compile it several times, each
time calling the right <code>make_grid</code> function and reserving the right
amount of memory for the member variable; note that the size of a
<code>DoFHandler</code> might, and indeed does, depend on the space dimension.



The deal.II library is build around this concept
of dimension-independent programming, and therefore allows you to program in
a way that will not need to
distinguish between the space dimensions. It should be noted that in
only a very few places is it necessary to actually compare the
dimension using <code>if</code>s or <code>switch</code>es. However, since the compiler
has to compile each function for each dimension separately, even there
it knows the value of <code>dim</code> at the time of compilation and will
therefore be able to optimize away the <code>if</code> statement along with the
unused branch.



In this example program, we will show how to program dimension
independently (which in fact is even simpler than if you had to take
care about the dimension) and we will extend the Laplace problem of
the last example to a program that runs in two and three space
dimensions at the same time. Other extensions are the use of a
non-constant right hand side function and of non-zero boundary values.


@note When using templates, C++ imposes all sorts of syntax constraints that
make it sometimes a bit difficult to understand why exactly something has to
be written this way. A typical example is the need to use the keyword
<code>typename</code> in so many places. If you are not entirely familiar with
this already, then several of these difficulties are explained in the deal.II
Frequently Asked Questions (FAQ) linked to from the <a
href="http://www.dealii.org/">deal.II homepage</a>.
