From d655c2cc387c87dc63ea7fed7270bf8ed21279fb Mon Sep 17 00:00:00 2001
From: Simon Praetorius <simon.praetorius@tu-dresden.de>
Date: Fri, 1 Mar 2019 16:27:32 +0100
Subject: [PATCH] added macro add_amdis_executable and adapted examples to this

---
 CMakeLists.txt                                |   7 +-
 bin/CMakeLists.txt                            |   4 +
 bin/amdisproject                              | 804 ++++++++++++++++++
 cmake/modules/AddAmdisExecutable.cmake        | 121 +++
 ...XFeatures.cmake => AmdisCXXFeatures.cmake} |   0
 cmake/modules/AmdisMacros.cmake               |   3 +-
 cmake/modules/CMakeLists.txt                  |   6 +-
 doc/Mainpage.md                               |   2 +-
 examples/CMakeLists.txt                       |  53 +-
 examples/boundary.cc                          |   2 +-
 examples/convection_diffusion.cc              |   4 +-
 examples/ellipt.cc                            |   6 +-
 examples/heat.cc                              |   4 +-
 examples/navier_stokes.cc                     |   4 +-
 examples/stokes0.cc                           |   4 +-
 examples/stokes1.cc                           |   4 +-
 examples/stokes3.cc                           |   2 +-
 examples/vecellipt.cc                         |   4 +-
 .../gridfunctions/GridFunctionConcepts.hpp    |   4 +-
 19 files changed, 981 insertions(+), 57 deletions(-)
 create mode 100644 bin/CMakeLists.txt
 create mode 100644 bin/amdisproject
 create mode 100644 cmake/modules/AddAmdisExecutable.cmake
 rename cmake/modules/{AMDiSCXXFeatures.cmake => AmdisCXXFeatures.cmake} (100%)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3d7c107c..a6705c67 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,12 +14,13 @@ dune_project()
 
 dune_enable_all_packages(MODULE_LIBRARIES amdis fmt)
 
+add_subdirectory("bin")
+add_subdirectory("cmake/modules")
+add_subdirectory("doc")
+add_subdirectory("externals")
 add_subdirectory("src")
 add_subdirectory("test")
 add_subdirectory("examples" EXCLUDE_FROM_ALL)
-add_subdirectory("doc")
-add_subdirectory("cmake/modules")
-add_subdirectory("externals")
 
 target_link_libraries(amdis fmt)
 
diff --git a/bin/CMakeLists.txt b/bin/CMakeLists.txt
new file mode 100644
index 00000000..1f24fbe0
--- /dev/null
+++ b/bin/CMakeLists.txt
@@ -0,0 +1,4 @@
+
+install(PROGRAMS
+    amdisproject
+  DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/bin/amdisproject b/bin/amdisproject
new file mode 100644
index 00000000..6c0e11be
--- /dev/null
+++ b/bin/amdisproject
@@ -0,0 +1,804 @@
+#!/usr/bin/env bash
+
+#
+# TODO:
+#
+# * Check module names entered as dependencies.
+
+set -e
+
+canonicalname(){
+	if test $# -ne 1; then
+		echo Usage: canonicalname path >&2
+		return 1
+	fi
+	file="`eval echo $1`" # expand ~
+	if test ! -e "$file"; then
+		echo $file: file not found >&2
+		return 1
+	fi
+    # if this is a symlink, then follow the symlink
+	if test -L "$file"; then
+		fdir="`dirname \"$file\"`"
+		flink="`readlink \"$file\"`"
+		if test -e "$flink"; then
+			# these are absolute links, or links in the CWD
+			canonicalname "$flink"
+		else
+			canonicalname "$fdir/$flink"
+		fi
+	else
+        # if this is a file, then remember the filename and
+        # canonicalize the directory name
+		if test -f "$file"; then
+			fdir="`dirname \"$file\"`"
+			fname="`basename \"$file\"`"
+			fdir="`canonicalname \"$fdir\"`"
+			echo "$fdir/$fname"
+		fi
+        # if this is a directory, then create an absolute
+        # directory name and we are done
+		if test -d "$file"; then
+			(cd "$file"; pwd)
+		fi
+	fi
+}
+
+canonicalpath(){
+  if test $# -ne 1; then
+     echo Usage: canonicalpath path >&2
+     return 1
+  fi
+  dirname "$(canonicalname "$1")"
+}
+
+pkg_config_dependencies(){
+    if test $# -ne 1; then
+	echo Usage: pkg_config_dependencies name >&2
+	return 1
+    fi
+    name="$1"
+    depends="`pkg-config --variable=DEPENDENCIES $name| sed -e 's/,/ /g'`"
+    for pkg in $depends; do
+	depends="$depends `pkg_config_dependencies $pkg`"
+    done
+    echo $depends
+}
+
+modulesexist(){
+  local status dep found
+  status=0
+
+  for dep in $1; do
+    found=false
+    if [[ " $2 " == *" $dep "* ]]; then
+      found=true
+    fi
+    # If module not found in list, try pkg-config
+    if ! $found && pkg-config $dep &> /dev/null; then
+       found=true
+    fi
+    if ! $found; then
+      echo "ERROR:">&2
+      echo "Module with name $dep was not found" >&2
+      echo "Did you forget to specify its location" >&2
+      echo "in the DUNE_CONTROL_PATH variable?">&2
+      echo >&2
+      status=1
+    fi
+  done
+
+  return $status
+}
+
+make_unique(){
+  if [ "$#" = "1" ]; then
+      # take first word
+      for exclude_word in $1; do
+	  break;
+      done
+      make_unique $exclude_word "$1" 0
+  else
+      local exclude_word="$1"
+      local words="$2"
+      local pos="$3"
+      local length=0
+      local i=0
+      local new_words=""
+      local cur=0
+      for word in $words; do
+	  if [ $i -le $pos ]; then
+	      i=$((i+1))
+	      length=$((length+1))
+	      new_words="$new_words $word"
+	      continue
+	  fi
+	  if [ "$word" != "$exclude_word" ]; then
+	      new_words="$new_words $word"
+	      if [ "$((length-1))" = "$pos" ]; then
+		  next_word="$word"
+	      fi
+	      length=$((length+1))
+	  fi
+      done
+      if [ "$pos" -lt "$length" ]; then
+       # process next word
+	  make_unique "$next_word" "$new_words" $((pos+1))
+      else
+	  export UNIQUE_WORDS="$new_words"
+      fi
+  fi
+}
+
+echo
+echo == AMDiS project/module generator ==
+echo
+echo amdisproject will assist you in the creation of a new AMDiS application.
+echo During this process a new directory with the name of your project will be
+echo created. This directory will hold all configuration and Makefiles and a
+echo simple example application.
+echo
+
+################## FIND AVAILABLE MODULES ##################
+
+DUNE_MODULES_LIB=$(IFS=':' && find $DUNE_CONTROL_PATH -type f -path "*/lib/dunemodules.lib")
+. ${DUNE_MODULES_LIB}
+
+export PREFIX_DIR="`canonicalpath "${DUNE_MODULES_LIB}"`/.."
+
+extract_multiarch_pkg_config_path
+
+# search for modules, both installed and src modules
+find_modules_in_path
+
+# sort modules to remove duplicates
+sort_modules $FOUND_MODULES
+FOUND_MODULES=$MODULES
+
+# require module amdis
+modulesexist "amdis" "$FOUND_MODULES"
+
+# get the real module names
+MODULES=""
+for i in $FOUND_MODULES; do
+  if [ "$i" != "amdis" ]; then
+    mod=$(eval echo \$NAME_$i)
+    MODULES="$MODULES$mod "
+  fi
+done
+
+if [ "$MODULES" = "" ]; then
+  echo "ERROR:">&2
+  echo "  No dune modules were found!">&2
+  echo "  Did you forget to specify the places where ">&2
+  echo "  you installed your modules in the ">&2
+  echo "  DUNE_CONTROL_PATH environment variable">&2
+  echo "  and adjusted the PKG_CONFIG_PATH environment">&2
+  echo "  accordingly?" >&2
+  exit 1;
+fi
+
+################## READ CMDLINE OPTIONS ##########
+PROJECT="$1"
+DEPENDENCIES="$2"
+VERSION="$3"
+MAINTAINER="$4"
+
+################## READ OPTIONS ##################
+
+while [ "$DATACORRECT" != "y" -a "$DATACORRECT" != "Y" ]; do
+
+  while [ -z $PROJECT ]; do
+    read -p "1) Name of your new Project? (e.g.: amdis-ellipt): " PROJECT
+    if echo "$MODULES" | grep -q ^$PROJECT$; then
+      read -p "   A module named $PROJECT already exists. Continue anyway? [y/N] " CONT
+      if test x$DELETE = xy -o x$DELETE = xY; then
+        PROJECT=""
+      fi
+    elif echo "$PROJECT" | grep -q "\."; then
+      echo "The Name contains a dot (.) which is not allowed."
+      PROJECT=""
+    fi
+  done
+  MODULE="$PROJECT"
+
+  DEPOK=1
+
+  while [ "$DEPOK" != 0 ]; do
+    echo "2) Which additional modules should this project depend on?"
+    echo "   The following modules have been found:"
+    echo "   $MODULES"
+  #  for i in $MODULES; do echo -n " $i"; done
+  #  echo ""
+    read -p "   Enter space-separated list (or nothing): " DEPENDENCIES
+    if [ -z "$DEPENDENCIES" ]; then
+      DEPOK=0
+    fi
+    set +e
+    modulesexist "$DEPENDENCIES" "$MODULES"
+    DEPOK=$?
+    set -e
+    if [ "$DEPOK" != 0 ]; then
+      DEPENDENCIES=""
+    fi
+  done
+  if [ -z "$DEPENDENCIES" ]; then
+    DEPENDENCIES="amdis"
+  else
+    DEPENDENCIES="amdis ${DEPENDENCIES}"
+  fi
+
+  while [ -z $VERSION ]; do
+    read -p "3) Project/Module version? " VERSION
+  done
+  while [ -z "$MAINTAINER" ]; do
+    read -p "4) Maintainer's email address? " MAINTAINER
+  done
+
+  echo
+  echo "creating Project \"$PROJECT\", version $VERSION "
+  echo "which depends on \"$DEPENDENCIES\""
+  echo "with maintainer \"$MAINTAINER\""
+  read -p "Are these informations correct? [y/N] " DATACORRECT
+
+  # reset data if necessary
+  if [ "$DATACORRECT" != "y" -a "$DATACORRECT" != "Y" ]; then
+    PROJECT=""
+    DEPENDENCIES=""
+    VERSION=""
+    MAINTAINER=""
+  fi
+
+done
+
+
+
+echo
+echo "A sample code $MODULE.cc is generated in the \"$PROJECT\" directory."
+echo "Look at the README.md and dune.module files there."
+echo "Now you can run the dunecontrol script which will setup the new module."
+echo "Sometimes you may have to tweak CMakeLists.txt a bit."
+
+if test -d $PROJECT; then
+  echo WARNING:
+  echo "A directory with the name $PROJECT already exists."
+  echo "Do you want to continue anyway?"
+  read -p "Type Y to overwrite the old directory, N to abort. [y/N] " DELETE
+  if test x$DELETE != xy -a x$DELETE != xY; then
+    echo Abort...
+    exit 1
+  fi
+  rm -rf "$PROJECT"
+fi
+mkdir "$PROJECT"
+
+################## dune.module ##################
+cat > "$PROJECT/dune.module" <<C_DELIM
+################################
+# Dune module information file #
+################################
+
+Module: $MODULE
+Version: $VERSION
+Maintainer: $MAINTAINER
+
+Depends: $DEPENDENCIES
+Suggests: # add additional optional dune modules here
+C_DELIM
+
+## Create the parameters passed to DUNE_CHECK_ALL
+
+# save module list of dunemodules.inc
+save_MODULES=$MODULES
+for name in $DEPENDENCIES; do
+  mod="`fix_variable_name $name`"
+  if test "x$(eval echo \$HAVE_$mod)" != "x"; then
+    # found via dunemodules.inc
+    sort_modules "$mod"
+    for mod in $MODULES; do
+      M_DEPS="$M_DEPS $(eval echo \$NAME_$mod)"
+    done
+    MODULES=$save_MODULES
+  else
+    # found via pkg-config
+    M_DEPS="`pkg_config_dependencies $name` $name"
+  fi
+  for dep in $M_DEPS; do
+      CHECK="$CHECK [$dep]"
+  done
+done
+set +x
+make_unique "$CHECK"
+
+# insert , between modules
+j=0
+for dep in $UNIQUE_WORDS; do
+if [ "$j" = "0" ]; then
+      CHECK="$dep"
+      j=1
+    else
+      CHECK="$CHECK, $dep"
+    fi
+done
+
+echo "------------------------------------------"
+echo "writing initial files:"
+
+# complete module name with _ instead of - to not confuse automake
+fix_and_assign CMODULE $MODULE
+# module name without prefix "amdis-"
+NAME=`echo $PROJECT | sed -e 's/amdis[_-]//'`
+# $NAME with _ instead of - to not confuse automake
+NAME_=`echo $NAME | tr '-' '_'`
+# module name in uppercase with _ instead of -
+UNAME=`echo $PROJECT | tr '-' '_' | sed 's/\(.*\)/\U\1/'`
+
+################## README ##################
+echo "- $PROJECT/README.md"
+cat > "$PROJECT/README.md" <<R_DELIM
+Preparing the Sources
+=========================
+
+Additional to the software mentioned in README.md you'll need the
+following programs installed on your system:
+
+  cmake >= 3.1
+
+Getting started
+---------------
+
+If these preliminaries are met, you should run
+
+  dunecontrol all
+
+which will find all installed dune modules as well as all dune modules
+(not installed) which sources reside in a subdirectory of the current
+directory. Note that if dune is not installed properly you will either
+have to add the directory where the dunecontrol script resides (probably
+./dune-common/bin) to your path or specify the relative path of the script.
+
+Most probably you'll have to provide additional information to dunecontrol
+(e.g. compilers, configure options) and/or make options.
+
+The most convenient way is to use options files in this case. The files
+define four variables:
+
+CMAKE_FLAGS      flags passed to cmake (during configure)
+
+An example options file might look like this:
+
+#use this options to configure and make if no other options are given
+CMAKE_FLAGS=" \\
+-DCMAKE_CXX_COMPILER=g++-5 \\
+-DCMAKE_CXX_FLAGS='-Wall -pedantic' \\
+-DCMAKE_INSTALL_PREFIX=/install/path" #Force g++-5 and set compiler flags
+
+If you save this information into example.opts you can pass the opts file to
+dunecontrol via the --opts option, e.g.
+
+  dunecontrol --opts=example.opts all
+
+More info
+---------
+
+See
+
+     dunecontrol --help
+
+for further options.
+
+
+The full build system is described in the dune-common/doc/buildsystem (Git version) or under share/doc/dune-common/buildsystem if you installed DUNE!
+R_DELIM
+
+################## CMakeLists.txt ##################
+echo "- $PROJECT/CMakeLists.txt"
+cat> "$PROJECT/CMakeLists.txt" << M_DELIM
+# We require version CMake version 3.1 to prevent issues
+# with dune_enable_all_packages and older CMake versions.
+cmake_minimum_required(VERSION 3.1)
+project($PROJECT CXX)
+
+if(NOT (dune-common_DIR OR dune-common_ROOT OR
+      "\${CMAKE_PREFIX_PATH}" MATCHES ".*dune-common.*"))
+    string(REPLACE  \${CMAKE_PROJECT_NAME} dune-common dune-common_DIR
+      \${PROJECT_BINARY_DIR})
+endif()
+
+#find dune-common and set the module path
+find_package(dune-common REQUIRED)
+list(APPEND CMAKE_MODULE_PATH "\${PROJECT_SOURCE_DIR}/cmake/modules"
+  \${dune-common_MODULE_PATH})
+
+#include the dune macros
+include(DuneMacros)
+
+# start a dune project with information from dune.module
+dune_project()
+
+dune_enable_all_packages()
+
+add_subdirectory(amdis)
+add_subdirectory(cmake/modules)
+add_subdirectory(doc)
+add_subdirectory(init)
+add_subdirectory(macro)
+add_subdirectory(src)
+
+# finalize the dune project, e.g. generating config.h etc.
+finalize_dune_project(GENERATE_CONFIG_H_CMAKE)
+M_DELIM
+
+################## PROJECT.PC.IN ##################
+echo "- $PROJECT/$MODULE.pc.in"
+cat> "$PROJECT/$MODULE.pc.in" << CC_DELIM
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+CXX=@CXX@
+CC=@CC@
+DEPENDENCIES=@REQUIRES@
+
+Name: @PACKAGE_NAME@
+Version: @VERSION@
+Description: $MODULE module
+URL: http://gitlab.mn.tu-dresden.de
+Requires: ${DEPENDENCIES}
+Libs: -L\${libdir}
+Cflags: -I\${includedir}
+CC_DELIM
+echo "    Please remember to update your $PROJECT/$MODULE.pc.in,"
+echo "    Description and URL are missing right now."
+
+################# config.h.cmake #####################
+
+echo "- $PROJECT/config.h.cmake"
+cat> "$PROJECT/config.h.cmake" <<EOF
+/* begin $PROJECT
+   put the definitions for config.h specific to
+   your project here. Everything above will be
+   overwritten
+*/
+
+/* begin private */
+/* Name of package */
+#define PACKAGE "@DUNE_MOD_NAME@"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "@DUNE_MAINTAINER@"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "@DUNE_MOD_NAME@"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "@DUNE_MOD_NAME@ @DUNE_MOD_VERSION@"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "@DUNE_MOD_NAME@"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL "@DUNE_MOD_URL@"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "@DUNE_MOD_VERSION@"
+
+/* end private */
+
+/* Define to the version of $PROJECT */
+#define ${UNAME}_VERSION "@${UNAME}_VERSION@"
+
+/* Define to the major version of $PROJECT */
+#define ${UNAME}_VERSION_MAJOR @${UNAME}_VERSION_MAJOR@
+
+/* Define to the minor version of $PROJECT */
+#define ${UNAME}_VERSION_MINOR @${UNAME}_VERSION_MINOR@
+
+/* Define to the revision of $PROJECT */
+#define ${UNAME}_VERSION_REVISION @${UNAME}_VERSION_REVISION@
+
+/* end $PROJECT
+   Everything below here will be overwritten
+*/
+EOF
+## done
+
+###############################################################
+################## The source subdirectory ####################
+###############################################################
+
+mkdir "$PROJECT/src"
+
+################## src/CMakeLists.txt ##################
+
+echo "- $PROJECT/src/CMakeLists.txt"
+cat> "$PROJECT/src/CMakeLists.txt" << M_DELIM
+add_amdis_executable(
+  NAME "${MODULE}"
+  SOURCES ${MODULE}.cpp
+  DIM 2 DOW 2
+  ALBERTA_GRID)
+M_DELIM
+
+################## PROJECT.CC ##################
+echo "- $PROJECT/src/$MODULE.cpp"
+cat> "$PROJECT/src/$MODULE.cpp" << CC_DELIM
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <amdis/AMDiS.hpp>
+
+using namespace AMDiS;
+int main(int argc, char** argv)
+{
+  AMDiS::init(argc, argv);
+
+  // your code comes here
+
+  AMDiS::finalize();
+}
+CC_DELIM
+
+################################################################
+################## The headers subdirectory ####################
+################################################################
+
+echo "- $PROJECT/amdis/$NAME"
+mkdir "$PROJECT/amdis"
+mkdir "$PROJECT/amdis/$NAME"
+
+################## amdis/CMakeLists.txt #################
+echo "- $PROJECT/amdis/CMakeLists.txt"
+cat> $PROJECT/amdis/CMakeLists.txt <<EOF
+add_subdirectory($NAME)
+EOF
+
+################## amdis/$NAME/CMakeLists.txt ###########
+echo "- $PROJECT/amdis/$NAME/CMakeLists.txt"
+cat> $PROJECT/amdis/$NAME/CMakeLists.txt <<EOF
+#install headers
+install(FILES ${NAME}.hpp DESTINATION \${CMAKE_INSTALL_INCLUDEDIR}/amdis/$NAME)
+EOF
+
+################## amdis/$NAME/$NAME.hh #################
+echo "- $PROJECT/amdis/$NAME/$NAME.hpp"
+cat> $PROJECT/amdis/$NAME/$NAME.hpp <<EOF
+#pragma once
+
+// add your classes here
+
+EOF
+
+
+###############################################################
+################## The doc subdirectory #######################
+###############################################################
+
+mkdir "$PROJECT/doc"
+
+################## doc/CMakeLists.txt #################
+echo "- $PROJECT/doc/CMakeLists.txt"
+cat> "$PROJECT/doc/CMakeLists.txt" << CC_DELIM
+add_subdirectory("doxygen")
+CC_DELIM
+
+###############################################################
+############### The doc/doxygen subdirectory ##################
+###############################################################
+
+mkdir "$PROJECT/doc/doxygen"
+
+#################### basic Doxylocal ##########################
+
+echo "- $PROJECT/doc/doxygen/Doxylocal"
+if [ "x`which doxygen`" == "x" ]; then
+    echo "Doxygen is not installed! Your documentation will not work without."
+fi
+# Where to search and which files to use
+cat> $PROJECT/doc/doxygen/Doxylocal << CC_DELIM
+# This file contains local changes to the doxygen configuration
+# please us '+=' to add file/directories to the lists
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT                 += @top_srcdir@/amdis/
+# see e.g. dune-grid for the examples of mainpage and modules
+# INPUT                 += @srcdir@/mainpage \\
+#                          @srcdir@/modules
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+# EXCLUDE               += @top_srcdir@/amdis/$NAME/test
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+# EXAMPLE_PATH          += @top_srcdir@/src
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+# IMAGE_PATH            += @top_srcdir@/amdis/$NAME/pics
+CC_DELIM
+
+################# doc/doxygen/CMakeLists.txt #####################
+
+echo "- $PROJECT/doc/doxygen/CMakeLists.txt"
+cat> "$PROJECT/doc/doxygen/CMakeLists.txt" << CC_DELIM
+# shortcut for creating the Doxyfile.in and Doxyfile
+add_doxygen_target()
+CC_DELIM
+
+#########################################################
+############### The cmake subdirectory ##################
+#########################################################
+
+mkdir "$PROJECT/cmake"
+
+#########################################################
+############### The cmake/modules subdirectory ##########
+#########################################################
+
+mkdir "$PROJECT/cmake/modules"
+
+macroname=""
+for i in $(echo $PROJECT| sed 's/-/ /g'); do
+  firstchar=$(echo $i | sed 's/\(.\).*/\1/')
+  macroname=$macroname$(echo $firstchar | tr '[a-z]' '[A-Z]')$(echo $i | sed 's/.\(.*\)/\1/')
+done
+macroname="$macroname""Macros.cmake"
+
+################# cmake/modules/CMakeLists.txt #####################
+
+echo "- $PROJECT/cmake/modules/CMakeLists.txt"
+cat> "$PROJECT/cmake/modules/CMakeLists.txt" <<EOF
+set(modules "$macroname")
+
+install(FILES \${modules} DESTINATION \${DUNE_INSTALL_MODULEDIR})
+EOF
+
+################# cmake/modules/$macroname #####################
+
+echo "- $PROJECT/cmake/modules/$macroname"
+cat> "$PROJECT/cmake/modules/$macroname" <<EOF
+# File for module specific CMake tests.
+EOF
+
+#########################################################
+############### The init subdirectory ##########
+#########################################################
+
+mkdir "$PROJECT/init"
+
+echo "- $PROJECT/init/$NAME.dat"
+cat> "$PROJECT/init/$NAME.dat" <<EOF
+mesh->global refinements: 0
+
+$NAME->mesh: mesh
+$NAME->solver->name: default
+$NAME->solver->tolerance: 1.e-8
+$NAME->solver->info: 1
+
+$NAME->output[0]->filename: $NAME_
+$NAME->output[0]->name: solution
+$NAME->output[0]->ParaView mode: 1
+EOF
+
+################# init/CMakeLists.txt #####################
+
+echo "- $PROJECT/init/CMakeLists.txt"
+cat> "$PROJECT/init/CMakeLists.txt" <<EOF
+install(FILES
+  $NAME.dat
+  DESTINATION init)
+EOF
+
+#########################################################
+############### The macro subdirectory ##########
+#########################################################
+
+mkdir "$PROJECT/macro"
+
+echo "- $PROJECT/macro/$NAME.2d.amc"
+cat> "$PROJECT/macro/$NAME.2d.amc" <<EOF
+DIM:          2
+DIM_OF_WORLD: 2
+
+number of vertices: 5
+number of elements: 4
+
+vertex coordinates:
+ 0.0  0.0
+ 1.0  0.0
+ 1.0  1.0
+ 0.0  1.0
+ 0.5  0.5
+
+element vertices:
+0 1 4
+1 2 4
+2 3 4
+3 0 4
+
+element boundaries:
+0 0 1
+0 0 1
+0 0 1
+0 0 1
+
+element neighbours:
+1 3 -1
+2 0 -1
+3 1 -1
+0 2 -1
+EOF
+
+
+echo "- $PROJECT/macro/$NAME.3d.amc"
+cat> "$PROJECT/macro/$NAME.3d.amc" <<EOF
+DIM:          3
+DIM_OF_WORLD: 3
+
+number of vertices: 8
+number of elements: 6
+
+vertex coordinates:
+ 0.0  0.0  0.0
+ 1.0  0.0  0.0
+ 0.0  0.0  1.0
+ 1.0  0.0  1.0
+ 1.0  1.0  0.0
+ 1.0  1.0  1.0
+ 0.0  1.0  0.0
+ 0.0  1.0  1.0
+
+element vertices:
+  0    5    4    1
+  0    5    3    1
+  0    5    3    2
+  0    5    4    6
+  0    5    7    6
+  0    5    7    2
+
+element boundaries:
+  1    1    0    0
+  1    1    0    0
+  1    1    0    0
+  1    1    0    0
+  1    1    0    0
+  1    1    0    0
+
+element neighbours:
+ -1   -1    1    3
+ -1   -1    0    2
+ -1   -1    5    1
+ -1   -1    4    0
+ -1   -1    3    5
+ -1   -1    2    4
+EOF
+
+################# macro/CMakeLists.txt #####################
+
+echo "- $PROJECT/macro/CMakeLists.txt"
+cat> "$PROJECT/macro/CMakeLists.txt" <<EOF
+install(FILES
+  $NAME.2d.amc
+  $NAME.3d.amc
+  DESTINATION macro)
+EOF
+
+#################           done           #####################
+
+echo
+echo "done."
+echo "------------------------------------------"
+echo "For further details read the Dune build system documentation at"
+echo "https://www.dune-project.org/buildsystem/"
diff --git a/cmake/modules/AddAmdisExecutable.cmake b/cmake/modules/AddAmdisExecutable.cmake
new file mode 100644
index 00000000..bf0f1d2a
--- /dev/null
+++ b/cmake/modules/AddAmdisExecutable.cmake
@@ -0,0 +1,121 @@
+# Module that provides tools for adding executable with all required flags
+#
+# .. cmake_function:: add_amdis_executable
+#
+#    .. cmake_brief::
+#
+#       Adds an executable using the AMDiS library
+#
+#    .. cmake_param:: NAME
+#       :single:
+#
+#       The name of the test that should be added. If an executable
+#       is also added (by specifying SOURCES), the executable is also
+#       named accordingly. If omitted, the name will be deduced from
+#       the (single) sources parameter or from the given target. Note
+#       that this requires you to take care, that you only use a target
+#       or source file for but one such test.
+#
+#    .. cmake_param:: SOURCES
+#       :multi:
+#
+#       The source files that this test depends on. These are the
+#       sources that will be passed to :ref:`add_executable`.
+#
+#       You *must* specify either :code:`SOURCES` or :code:`TARGET`.
+#
+#    .. cmake_param:: DIM
+#       :single:
+#
+#       Specify the grid dimension.
+#
+#    .. cmake_param:: DOW
+#       :single:
+#
+#       Specify the world dimension. If not specified it is assumed to be equal to DIM
+#
+#    .. cmake_param:: ALU_GRID
+#       :option:
+#
+#       Enables ALUGrid with specified grid dimension and world dimension.
+#
+#    .. cmake_param:: ALBERTA_GRID
+#       :option:
+#
+#       Enables AlbertaGrid with specified grid dimension and world dimension.
+#
+#    This file defines the a function for adding executables to cmake and setting all required
+#    parameters for dependent modules.
+#
+
+function(add_amdis_executable)
+  include(CMakeParseArguments)
+  set(OPTIONS ALU_GRID ALBERTA_GRID)
+  set(SINGLEARGS NAME DIM DOW)
+  set(MULTIARGS SOURCES)
+  cmake_parse_arguments(ADDEXE "${OPTIONS}" "${SINGLEARGS}" "${MULTIARGS}" ${ARGN})
+
+  # Check whether the parser produced any errors
+  if(ADDTEST_UNPARSED_ARGUMENTS)
+    message(WARNING "Unrecognized arguments ('${ADDTEST_UNPARSED_ARGUMENTS}') for add_amdis_executable!")
+  endif()
+
+  # Check input for validity and apply defaults
+  if(NOT ADDEXE_SOURCES)
+    message(FATAL_ERROR "You need to specify the SOURCES option for add_amdis_executable!")
+  endif()
+  if(NOT ADDEXE_NAME)
+    # try deducing the executable name form the source name
+    if(ADDEXE_SOURCES)
+      # deducing a name is only possible with a single source argument
+      list(LENGTH ADDEXE_SOURCES len)
+      if(NOT len STREQUAL "1")
+        message(FATAL_ERROR "Cannot deduce executable name from multiple sources!")
+      endif()
+      # strip file extension
+      get_filename_component(ADDEXE_NAME ${ADDEXE_SOURCES} NAME_WE)
+    endif()
+  endif()
+
+  # Add the executable
+  add_executable(${ADDEXE_NAME} ${ADDEXE_SOURCES})
+  # add all flags to the target!
+  add_dune_all_flags(${ADDEXE_NAME})
+  target_link_dune_default_libraries(${ADDEXE_NAME})
+  target_link_libraries(${ADDEXE_NAME} amdis)
+
+  if(ADDEXE_DIM)
+    set(GRIDDIM ${ADDEXE_DIM})
+  endif(ADDEXE_DIM)
+
+  if(ADDEXE_DOW)
+    set(WORLDDIM ${ADDEXE_DOW})
+  else(ADDEXE_DOW)
+    set(WORLDDIM ${ADDEXE_DIM})
+  endif(ADDEXE_DOW)
+
+  # set dimension flag
+  if(GRIDDIM)
+    target_compile_definitions(${ADDEXE_NAME} PRIVATE "GRIDDIM=${GRIDDIM}")
+  endif(GRIDDIM)
+  if(WORLDDIM)
+    target_compile_definitions(${ADDEXE_NAME} PRIVATE "WORLDDIM=${WORLDDIM}")
+  endif(WORLDDIM)
+
+  # add flags for AlbertaGrid
+  if(ADDEXE_ALBERTA_GRID)
+    if(NOT ADDEXE_DIM)
+      message(FATAL_ERROR "You need to specify dimension for ALBERTA_GRID!")
+    endif()
+    if(NOT ADDEXE_DOW)
+      message(WARNING "dimensionworld not specified for ALBERTA_GRID. Setting DOW=DIM.")
+    endif()
+
+    add_dune_alberta_flags(GRIDDIM ${GRIDDIM} WORLDDIM ${WORLDDIM} ${ADDEXE_NAME})
+  endif(ADDEXE_ALBERTA_GRID)
+
+  # add flags for ALUGrid
+  if(ADDEXE_ALU_GRID)
+    # nothing special to do
+  endif(ADDEXE_ALU_GRID)
+endfunction(add_amdis_executable)
\ No newline at end of file
diff --git a/cmake/modules/AMDiSCXXFeatures.cmake b/cmake/modules/AmdisCXXFeatures.cmake
similarity index 100%
rename from cmake/modules/AMDiSCXXFeatures.cmake
rename to cmake/modules/AmdisCXXFeatures.cmake
diff --git a/cmake/modules/AmdisMacros.cmake b/cmake/modules/AmdisMacros.cmake
index 5fe75fc9..b1609f5a 100644
--- a/cmake/modules/AmdisMacros.cmake
+++ b/cmake/modules/AmdisMacros.cmake
@@ -1,4 +1,5 @@
-include(AMDiSCXXFeatures)
+include(AmdisCXXFeatures)
+include(AddAmdisExecutable)
 
 set(BACKEND "ISTL" CACHE STRING "LinearAlgebra backend. One of MTL, EIGEN, ISTL")
 set_property(CACHE BACKEND PROPERTY STRINGS "MTL" "EIGEN" "ISTL")
diff --git a/cmake/modules/CMakeLists.txt b/cmake/modules/CMakeLists.txt
index e1cf35ab..30c9a184 100644
--- a/cmake/modules/CMakeLists.txt
+++ b/cmake/modules/CMakeLists.txt
@@ -1,5 +1,5 @@
-
-install(FILES 
+install(FILES
+    AddAmdisExecutable.cmake
     AmdisMacros.cmake
-    AMDiSCXXFeatures.cmake
+    AmdisCXXFeatures.cmake
   DESTINATION ${DUNE_INSTALL_MODULEDIR})
diff --git a/doc/Mainpage.md b/doc/Mainpage.md
index fb1d0f79..46adb2a7 100644
--- a/doc/Mainpage.md
+++ b/doc/Mainpage.md
@@ -22,7 +22,7 @@ and \f$ \Gamma \f$ the lower and left edge of the boundary.
 using namespace AMDiS;
 
 // A dune grid type
-using Grid = Dune::AlbertaGrid<AMDIS_DIM, AMDIS_DOW>;
+using Grid = Dune::AlbertaGrid<GRIDDIM, WORLDDIM>;
 
 // A dune-functions globalBasis wrapped in a struct,
 // here representing local polynomial shape functions of degree 1
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 14ca4fe4..a22ffee3 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,34 +1,27 @@
 add_custom_target(examples)
 
-set(projects2d
-  "ellipt"
-  "heat"
-  "vecellipt"
-  "stokes0"
-  "stokes1"
-  "stokes3"
-  "navier_stokes"
-  "convection_diffusion"
-  "boundary"
-  "periodic"
-  "neumann")
+add_amdis_executable(NAME ellipt.2d SOURCES ellipt.cc DIM 2 DOW 2)
+add_amdis_executable(NAME ellipt.3d SOURCES ellipt.cc DIM 3 DOW 3)
+add_dependencies(examples
+  ellipt.2d
+  ellipt.3d)
 
-foreach(project ${projects2d})
-    add_executable(${project}.2d ${project}.cc)
-    add_dune_alberta_flags(GRIDDIM 2 WORLDDIM 2 ${project}.2d)
-    target_link_dune_default_libraries(${project}.2d)
-    target_link_libraries(${project}.2d amdis)
-    target_compile_definitions(${project}.2d PRIVATE AMDIS_DIM=2 AMDIS_DOW=2)
-    add_dependencies(examples ${project}.2d)
-endforeach()
+add_amdis_executable(NAME heat.2d SOURCES heat.cc DIM 2 DOW 2)
+add_amdis_executable(NAME heat.3d SOURCES heat.cc DIM 3 DOW 3)
+add_dependencies(examples
+  heat.2d
+  heat.3d)
 
-set(projects3d "ellipt" "heat")
-
-foreach(project ${projects3d})
-    add_executable(${project}.3d ${project}.cc)
-    add_dune_alberta_flags(GRIDDIM 3 WORLDDIM 3 ${project}.3d)
-    target_link_dune_default_libraries(${project}.3d)
-    target_link_libraries(${project}.3d amdis)
-    target_compile_definitions(${project}.3d PRIVATE AMDIS_DIM=3 AMDIS_DOW=3)
-    add_dependencies(examples ${project}.3d)
-endforeach()
+add_amdis_executable(NAME vecellipt.2d SOURCES vecellipt.cc DIM 2 DOW 2)
+add_amdis_executable(NAME stokes0.2d SOURCES stokes0.cc DIM 2 DOW 2)
+add_amdis_executable(NAME stokes1.2d SOURCES stokes1.cc DIM 2 DOW 2)
+add_amdis_executable(NAME stokes3.2d SOURCES stokes3.cc DIM 2 DOW 2)
+add_amdis_executable(NAME navier_stokes.2d SOURCES navier_stokes.cc DIM 2 DOW 2)
+add_amdis_executable(NAME convection_diffusion.2d SOURCES convection_diffusion.cc DIM 2 DOW 2)
+add_dependencies(examples
+  vecellipt.2d
+  stokes0.2d
+  stokes1.2d
+  stokes3.2d
+  navier_stokes.2d
+  convection_diffusion.2d)
\ No newline at end of file
diff --git a/examples/boundary.cc b/examples/boundary.cc
index c2fb95ec..2c53d45a 100644
--- a/examples/boundary.cc
+++ b/examples/boundary.cc
@@ -17,7 +17,7 @@ using namespace AMDiS;
 using namespace Dune::Indices;
 
 // 1 component with polynomial degree 2
-using Param   = YaspGridBasis<AMDIS_DIM, 2>;
+using Param   = YaspGridBasis<GRIDDIM, 2>;
 using ElliptProblem = ProblemStat<Param>;
 
 template <class SetBoundary>
diff --git a/examples/convection_diffusion.cc b/examples/convection_diffusion.cc
index 16c2d939..188b6f12 100644
--- a/examples/convection_diffusion.cc
+++ b/examples/convection_diffusion.cc
@@ -11,8 +11,8 @@
 using namespace AMDiS;
 
 // 1 component with polynomial degree 1
-//using Grid = Dune::AlbertaGrid<AMDIS_DIM, AMDIS_DOW>;
-using ElliptParam   = YaspGridBasis<AMDIS_DIM, 1>;
+//using Grid = Dune::AlbertaGrid<GRIDDIM, WORLDDIM>;
+using ElliptParam   = YaspGridBasis<GRIDDIM, 1>;
 using ElliptProblem = ProblemStat<ElliptParam>;
 
 int main(int argc, char** argv)
diff --git a/examples/ellipt.cc b/examples/ellipt.cc
index df4cde81..6e0adb2b 100644
--- a/examples/ellipt.cc
+++ b/examples/ellipt.cc
@@ -13,14 +13,14 @@ using namespace AMDiS;
 using namespace Dune::Indices;
 
 // 1 component with polynomial degree 1
-using Param   = YaspGridBasis<AMDIS_DIM, 2>;
+using Param   = YaspGridBasis<GRIDDIM, 2>;
 using ElliptProblem = ProblemStat<Param>;
 
 int main(int argc, char** argv)
 {
   AMDiS::init(argc, argv);
 
-  int numLevels = AMDIS_DIM == 2 ? 8 : 5;
+  int numLevels = GRIDDIM == 2 ? 8 : 5;
   if (argc > 2)
     numLevels = std::atoi(argv[2]);
 
@@ -30,7 +30,7 @@ int main(int argc, char** argv)
     return -(400.0 * r2 - 20.0 * x.size()) * ux;
   };
   auto g = [](auto const& x){ return std::exp(-10.0 * dot(x,x)); };
-  auto grad_g = [](auto const& x) -> FieldMatrix<double,1,AMDIS_DIM> {
+  auto grad_g = [](auto const& x) -> FieldMatrix<double,1,GRIDDIM> {
     return {-20.0 * std::exp(-10.0 * dot(x,x)) * x};
   };
 
diff --git a/examples/heat.cc b/examples/heat.cc
index 1ab60048..95d06ab6 100644
--- a/examples/heat.cc
+++ b/examples/heat.cc
@@ -14,8 +14,8 @@
 using namespace AMDiS;
 
 // 1 component with polynomial degree 1
-//using Grid = Dune::AlbertaGrid<AMDIS_DIM, AMDIS_DOW>;
-using HeatParam   = YaspGridBasis<AMDIS_DIM, 2>;
+//using Grid = Dune::AlbertaGrid<GRIDDIM, WORLDDIM>;
+using HeatParam   = YaspGridBasis<GRIDDIM, 2>;
 using HeatProblem = ProblemStat<HeatParam>;
 using HeatProblemInstat = ProblemInstat<HeatParam>;
 
diff --git a/examples/navier_stokes.cc b/examples/navier_stokes.cc
index 5e28b93f..623a411c 100644
--- a/examples/navier_stokes.cc
+++ b/examples/navier_stokes.cc
@@ -18,7 +18,7 @@ using namespace AMDiS;
 
 struct NavierStokesBasis
 {
-  using Grid = Dune::YaspGrid<AMDIS_DIM>;
+  using Grid = Dune::YaspGrid<GRIDDIM>;
   using GlobalBasis = typename TaylorHoodBasis<Grid::LeafGridView>::GlobalBasis;
 };
 
@@ -70,7 +70,7 @@ int main(int argc, char** argv)
     density * trans(gradientAtQP(prob.solution(_v))));
   prob.addMatrixOperator(opNonlin1, _v, _v);
 
-  for (std::size_t i = 0; i < AMDIS_DOW; ++i) {
+  for (std::size_t i = 0; i < WORLDDIM; ++i) {
     // <(u^old * nabla)u_i, v_i>
     auto opNonlin2 = makeOperator(tag::test_gradtrial{},
       density * prob.solution(_v));
diff --git a/examples/stokes0.cc b/examples/stokes0.cc
index 5a593998..c418b5f6 100644
--- a/examples/stokes0.cc
+++ b/examples/stokes0.cc
@@ -13,13 +13,13 @@
 #ifdef DOW
 #undef DOW
 #endif
-#define DOW AMDIS_DOW
+#define DOW WORLDDIM
 
 using namespace AMDiS;
 
 // 3 components: velocity with polynomial degree 2 and pressure with polynomial degree 1
 
-using Grid = Dune::YaspGrid<AMDIS_DIM>;
+using Grid = Dune::YaspGrid<GRIDDIM>;
 using StokesParam   = TaylorHoodBasis<Grid::LeafGridView>;
 using StokesProblem = ProblemStat<StokesParam>;
 
diff --git a/examples/stokes1.cc b/examples/stokes1.cc
index af6eac97..0ad0ba63 100644
--- a/examples/stokes1.cc
+++ b/examples/stokes1.cc
@@ -13,13 +13,13 @@
 #ifdef DOW
 #undef DOW
 #endif
-#define DOW AMDIS_DOW
+#define DOW WORLDDIM
 
 using namespace AMDiS;
 
 // 3 components: velocity with polynomial degree 2 and pressure with polynomial degree 1
 
-using Grid = Dune::YaspGrid<AMDIS_DIM>;
+using Grid = Dune::YaspGrid<GRIDDIM>;
 using StokesParam   = TaylorHoodBasis<Grid::LeafGridView>;
 using StokesProblem = ProblemStat<StokesParam>;
 
diff --git a/examples/stokes3.cc b/examples/stokes3.cc
index 0fe98d45..f6ae5779 100644
--- a/examples/stokes3.cc
+++ b/examples/stokes3.cc
@@ -13,7 +13,7 @@
 
 using namespace AMDiS;
 
-using Grid = Dune::YaspGrid<AMDIS_DIM>;
+using Grid = Dune::YaspGrid<GRIDDIM>;
 using StokesParam   = TaylorHoodBasis<Grid::LeafGridView>;
 using StokesProblem = ProblemStat<StokesParam>;
 
diff --git a/examples/vecellipt.cc b/examples/vecellipt.cc
index 6b81c7f6..09fa7997 100644
--- a/examples/vecellipt.cc
+++ b/examples/vecellipt.cc
@@ -11,8 +11,8 @@
 using namespace AMDiS;
 
 // 1 component with polynomial degree 1
-//using Grid = Dune::AlbertaGrid<AMDIS_DIM, AMDIS_DOW>;
-using ElliptParam   = YaspGridBasis<AMDIS_DIM, 2,2>;
+//using Grid = Dune::AlbertaGrid<GRIDDIM, WORLDDIM>;
+using ElliptParam   = YaspGridBasis<GRIDDIM, 2,2>;
 using ElliptProblem = ProblemStat<ElliptParam>;
 
 int main(int argc, char** argv)
diff --git a/src/amdis/gridfunctions/GridFunctionConcepts.hpp b/src/amdis/gridfunctions/GridFunctionConcepts.hpp
index ac073736..bc27c0b1 100644
--- a/src/amdis/gridfunctions/GridFunctionConcepts.hpp
+++ b/src/amdis/gridfunctions/GridFunctionConcepts.hpp
@@ -100,14 +100,14 @@ namespace AMDiS
 
 
     /// \brief Functor F is collable with GlobalCoordinates `F(Dune::FieldVector<double,DOW>)`
-#ifndef AMDIS_DOW
+#ifndef WORLDDIM
     template <class F>
     constexpr bool CallableDomain =
       Definition::CallableDow<F, 1> || Definition::CallableDow<F, 2> || Definition::CallableDow<F, 3>;
 #else
     template <class F>
     constexpr bool CallableDomain =
-      Definition::CallableDow<F, AMDIS_DOW>;
+      Definition::CallableDow<F, WORLDDIM>;
 #endif
 
     /// \brief GridFunction GF is a Type that has LocalFunction and provides some
-- 
GitLab