From 10d72af37157c511b16e5d68a9e85d0ac9d7a42b Mon Sep 17 00:00:00 2001
From: "felix.albrecht" <felix.albrecht@4028485c-44d9-4cde-a312-5a4635ee2db9>
Date: Wed, 6 Apr 2011 18:00:46 +0000
Subject: [PATCH] added example, fixed Makefiles and CmakeLists.txt

git-svn-id: https://dune.mathematik.uni-freiburg.de/svn/dune-fem-functionals/trunk@114 4028485c-44d9-4cde-a312-5a4635ee2db9
---
 .gitignore                                    |   9 +
 CMakeLists.txt                                |   4 +
 configure.ac                                  |   1 +
 dune/fem/functional/Makefile.am               |   4 +-
 examples/Makefile.am                          |   2 +-
 examples/finite_element/main.cc               |   6 -
 .../Makefile.am                               |  35 ++
 .../finite_element_local_operation.cc         | 315 ++++++++++++++++++
 .../macrogrids/unitcube1.dgf                  |  18 +
 .../macrogrids/unitcube2.dgf                  |  18 +
 .../macrogrids/unitcube3.dgf                  |  18 +
 11 files changed, 421 insertions(+), 9 deletions(-)
 create mode 100644 examples/finite_element_local_operation/Makefile.am
 create mode 100644 examples/finite_element_local_operation/finite_element_local_operation.cc
 create mode 100644 examples/finite_element_local_operation/macrogrids/unitcube1.dgf
 create mode 100644 examples/finite_element_local_operation/macrogrids/unitcube2.dgf
 create mode 100644 examples/finite_element_local_operation/macrogrids/unitcube3.dgf

diff --git a/.gitignore b/.gitignore
index ccf1d3dab..5b3ff7c36 100644
--- a/.gitignore
+++ b/.gitignore
@@ -62,3 +62,12 @@ examples/finite_element/test
 examples/finite_element/test-main.o
 tests/common/.deps/
 tests/operator/.deps/
+CMakeLists.txt.user.2.1pre1
+CMakeLists.txt.user.2.3pre1
+examples/finite_element_local_operation/.deps
+examples/finite_element_local_operation/finite_element_local_operation
+examples/finite_element_local_operation/finite_element_local_operation-finite_element_local_operation.o
+tests/common/localbasefunction_test
+tests/common/localbasefunction_test-localbasefunction_test.o
+tests/operator/ellipticfiniteelementoperator_test
+tests/operator/ellipticfiniteelementoperator_test-ellipticfiniteelementoperator_test.o
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c311d8a3f..53f5a3e1e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -129,4 +129,8 @@ TARGET_LINK_LIBRARIES( localbasefunction_test ${COMMON_LIBS}  )
 ADD_EXECUTABLE( ellipticfiniteelement_example "examples/finite_element/main.cc" ${common} ${grid} ${istl} ${fem} ${femhowto} ${femtools} ${femfunctionals} )
 TARGET_LINK_LIBRARIES( ellipticfiniteelement_example ${COMMON_LIBS}  )
 
+ADD_EXECUTABLE( ellipticfiniteelement_local_operation_example "examples/finite_element_local_operation/finite_element_local_operation.cc" ${common} ${grid} ${istl} ${fem} ${femhowto} ${femtools} ${femfunctionals} )
+TARGET_LINK_LIBRARIES( ellipticfiniteelement_local_operation_example ${COMMON_LIBS}  )
+
+
 #HEADERCHECK( ${header} )
diff --git a/configure.ac b/configure.ac
index 5b502b761..2910eed3b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -35,6 +35,7 @@ AC_CONFIG_FILES([
   examples/Makefile
   examples/poisson_new/Makefile
   examples/finite_element/Makefile
+  examples/finite_element_local_operation/Makefile
   tests/Makefile
   tests/common/Makefile
   tests/operator/Makefile
diff --git a/dune/fem/functional/Makefile.am b/dune/fem/functional/Makefile.am
index 5634c18af..4288688d4 100644
--- a/dune/fem/functional/Makefile.am
+++ b/dune/fem/functional/Makefile.am
@@ -1,4 +1,4 @@
-ltwofunctionalincludedir = $(includedir)/dune/fem/functional
-ltwofunctionalinclude_HEADERS = ltwo.hh
+finiteelementincludedir = $(includedir)/dune/fem/functional
+finiteelementinclude_HEADERS = finiteelement.hh
 
 include $(top_srcdir)/am/global-rules
diff --git a/examples/Makefile.am b/examples/Makefile.am
index f93362081..72566d903 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -1,6 +1,6 @@
 # $Id$
 
-SUBDIRS = poisson_new finite_element
+SUBDIRS = poisson_new finite_element finite_element_local_operation
 
 if BUILD_DOCS
 # TODO: set up documentation tree automatically
diff --git a/examples/finite_element/main.cc b/examples/finite_element/main.cc
index c217161b2..9092f8a9c 100644
--- a/examples/finite_element/main.cc
+++ b/examples/finite_element/main.cc
@@ -144,24 +144,18 @@ public:
   {
     ret = 1.0;
 
-    std::cout << "evaluate at ";
-
     if (!(arg[0] > 0.0)) {
       // bottom
-      std::cout << "bottom" << std::endl;
       ret = 1.0;
     } else if (!(arg[0] < 1.0)) {
       // top
-      std::cout << "top" << std::endl;
       ret = 1.0;
     }
     if (!(arg[1] > 0.0)) {
       // left
-      std::cout << "left" << std::endl;
       ret = 1.0;
     } else if (!(arg[1] < 1.0)) {
       // right
-      std::cout << "right" << std::endl;
       ret = 1.0;
     }
   }
diff --git a/examples/finite_element_local_operation/Makefile.am b/examples/finite_element_local_operation/Makefile.am
new file mode 100644
index 000000000..9b727f1f2
--- /dev/null
+++ b/examples/finite_element_local_operation/Makefile.am
@@ -0,0 +1,35 @@
+GRIDDIM=2
+GRIDTYPE=YASPGRID
+POLORDER=1
+
+noinst_PROGRAMS = finite_element_local_operation
+
+finite_element_local_operation_SOURCES = finite_element_local_operation.cc
+
+finite_element_local_operation_CPPFLAGS = $(AM_CPPFLAGS) \
+	$(DUNEMPICPPFLAGS) \
+	$(UG_CPPFLAGS) \
+	$(AMIRAMESH_CPPFLAGS) \
+	$(ALBERTA_CPPFLAGS) \
+	$(ALUGRID_CPPFLAGS) -DGRIDDIM=$(GRIDDIM) -D$(GRIDTYPE) -DPOLORDER=$(POLORDER) -Wall -O0 -DDEBUG -funroll-loops -g -ggdb -fno-strict-aliasing -std=c++0x
+# The libraries have to be given in reverse order (most basic libraries
+# last).  Also, due to some misunderstanding, a lot of libraries include the
+# -L option in LDFLAGS instead of LIBS -- so we have to include the LDFLAGS
+# here as well.
+finite_element_local_operation_LDADD = \
+	$(DUNE_LDFLAGS) $(DUNE_LIBS) \
+	$(ALUGRID_LDFLAGS) $(ALUGRID_LIBS) \
+	$(ALBERTA_LDFLAGS) $(ALBERTA_LIBS) \
+	$(AMIRAMESH_LDFLAGS) $(AMIRAMESH_LIBS) \
+	$(UG_LDFLAGS) $(UG_LIBS) \
+	$(DUNEMPILIBS)	\
+	$(LDADD)
+finite_element_local_operation_LDFLAGS = $(AM_LDFLAGS) \
+	$(DUNEMPILDFLAGS) \
+	$(UG_LDFLAGS) \
+	$(AMIRAMESH_LDFLAGS) \
+	$(ALBERTA_LDFLAGS) \
+	$(ALUGRID_LDFLAGS) \
+	$(DUNE_LDFLAGS)
+
+include $(top_srcdir)/am/global-rules
diff --git a/examples/finite_element_local_operation/finite_element_local_operation.cc b/examples/finite_element_local_operation/finite_element_local_operation.cc
new file mode 100644
index 000000000..9092f8a9c
--- /dev/null
+++ b/examples/finite_element_local_operation/finite_element_local_operation.cc
@@ -0,0 +1,315 @@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <iostream>
+#include <vector>
+
+// disable warnings about problems in dune headers
+#include <dune/fem-tools/header/disablewarnings.hh>
+
+// dune-common includes
+#include <dune/common/exceptions.hh>
+#include <dune/common/fmatrix.hh>
+
+// dune-grid includes
+#include <dune/grid/utility/gridtype.hh>
+
+// dune-istl includes
+#include <dune/istl/bcrsmatrix.hh>
+#include <dune/istl/solvers.hh>
+#include <dune/istl/bvector.hh>
+
+// dune-fem includes
+#include <dune/fem/misc/mpimanager.hh>
+#include <dune/fem/gridpart/gridpart.hh>
+#include <dune/fem/space/lagrangespace.hh>
+#include <dune/fem/storage/vector.hh>
+#include <dune/fem/function/adaptivefunction/adaptivefunction.hh>
+#include <dune/fem/gridpart/adaptiveleafgridpart.hh>
+
+// reenable warnings about problems in dune headers
+#include <dune/fem-tools/header/enablewarnings.hh>
+
+// dune-fem-functionals includes
+#include <dune/fem/constraints/dirichlet.hh>
+#include <dune/fem/subspace/subspaces.hh>
+#include <dune/fem/operator/finiteelement.hh>
+#include <dune/fem/functional/finiteelement.hh>
+#include <dune/fem/container/factory.hh>
+#include <dune/fem/solver/femassembler.hh>
+
+// dune-fem-tools includes
+#include <dune/fem-tools/function/functiontools.hh>
+#include <dune/fem-tools/space/projection.hh>
+
+using namespace Dune::Functionals;
+
+#ifndef POLORDER
+const int polOrder = 1;
+#else
+const int polOrder = POLORDER;
+#endif
+
+/**
+  * \brief  Represents the elliptic operation a(x) \gradient u(x) \gradient v(x) for given u, v, x.
+  *         In this case, a = 1.
+  **/
+class EllipticOperation
+{
+public:
+  template <class FirstLocalFunctionType, class SecondLocalFunctionType, class LocalPointType>
+  double operate(const FirstLocalFunctionType& firstLocalFunction, const SecondLocalFunctionType& secondLocalFunction,
+                 const LocalPointType& localPoint) const
+  {
+    // init return value
+    double ret = 0.0;
+
+    // some types we will need
+    typedef typename SecondLocalFunctionType::EntityType EntityType;
+
+    typedef typename FirstLocalFunctionType::JacobianRangeType JacobianRangeType;
+
+    // first gradient
+    JacobianRangeType firstGradient(0.0);
+    firstLocalFunction.jacobian(localPoint, firstGradient);
+
+    // second gradient
+    JacobianRangeType secondGradient(0.0);
+    secondLocalFunction.jacobian(localPoint, secondGradient);
+
+    const double product = firstGradient[0] * secondGradient[0];
+
+    // 1.0 * \gradient u(x) \gradient v(x)
+    ret = 1.0 * product;
+
+    // return
+    return ret;
+  }
+
+}; // end class EllipticOperation
+
+/**
+  * \brief  Represents the product operation f(x) v(x) for given v, x.
+  *         In this case, f = 1.
+  **/
+class ProductOperation
+{
+public:
+  template <class LocalFunctionType, class LocalPointType>
+  double operate(const LocalFunctionType& localFunction, const LocalPointType& localPoint) const
+  {
+    // init return value
+    double ret = 0.0;
+
+    // some types we will need
+    typedef typename LocalFunctionType::RangeType RangeType;
+
+    // evaluate local function
+    RangeType localFunctionEvaluated(0.0);
+    localFunction.evaluate(localPoint, localFunctionEvaluated);
+
+    // 1.0 * v(x)
+    ret = 1.0 * localFunctionEvaluated;
+
+    // return
+    return ret;
+  }
+
+}; // end class ProductOperation
+
+/**
+ * @class AnalyticalDirichletValues
+ * function representing the dirichlet data g for the poisson problem
+ * a \laplace u = f
+ */
+template <class FunctionSpaceImp>
+class AnalyticalDirichletValues
+{
+public:
+  typedef FunctionSpaceImp FunctionSpaceType;
+
+  typedef typename FunctionSpaceType::DomainType DomainType;
+
+  typedef typename FunctionSpaceType::RangeType RangeType;
+
+  typedef typename FunctionSpaceType::DomainFieldType DomainFieldType;
+
+  typedef typename FunctionSpaceType::RangeFieldType RangeFieldType;
+
+  typedef typename FunctionSpaceType::JacobianRangeType JacobianRangeType;
+
+  void evaluate(const DomainType& arg, RangeType& ret) const
+  {
+    ret = 1.0;
+
+    if (!(arg[0] > 0.0)) {
+      // bottom
+      ret = 1.0;
+    } else if (!(arg[0] < 1.0)) {
+      // top
+      ret = 1.0;
+    }
+    if (!(arg[1] > 0.0)) {
+      // left
+      ret = 1.0;
+    } else if (!(arg[1] < 1.0)) {
+      // right
+      ret = 1.0;
+    }
+  }
+
+  void jacobian(const DomainType& arg, JacobianRangeType& ret) const
+  {
+    ret = 0.0;
+  }
+};
+
+
+// disable warnings about problems in dune headers
+#include <dune/fem-tools/header/disablewarnings.hh>
+
+
+int main(int argc, char** argv)
+{
+  try {
+
+    // MPI manager
+    Dune::MPIManager::initialize(argc, argv);
+
+
+    // grid
+    static const unsigned int dimRange = 1;
+
+    typedef Dune::GridSelector::GridType HGridType;
+
+    typedef Dune::AdaptiveLeafGridPart<HGridType> GridPartType;
+
+    Dune::GridPtr<HGridType> gridPtr("macrogrids/unitcube2.dgf");
+
+    GridPartType gridPart(*gridPtr);
+
+
+    // function spaces and functions
+    typedef Dune::FunctionSpace<double, double, HGridType::dimension, dimRange> FunctionSpaceType;
+
+    typedef Dune::Function<double, double> FunctionType;
+
+    typedef Dune::LagrangeDiscreteFunctionSpace<FunctionSpaceType, GridPartType, polOrder> DiscreteH1Type;
+
+    DiscreteH1Type discreteH1(gridPart);
+
+    typedef Dune::AdaptiveDiscreteFunction<DiscreteH1Type> DiscreteFunctionType;
+
+    typedef Constraints::Dirichlet<DiscreteH1Type> DirichletConstraints;
+
+    DirichletConstraints dirichletConstraints(discreteH1);
+
+    typedef Subspace::Linear<DiscreteH1Type, DirichletConstraints> DiscreteH10Type;
+
+    DiscreteH10Type discreteH10(discreteH1, dirichletConstraints);
+
+    typedef AnalyticalDirichletValues<FunctionSpaceType> AnalyticalDirichletValuesType;
+
+    AnalyticalDirichletValuesType analyticalDirichletValues;
+
+    DiscreteFunctionType discreteDirichletValues("dirichlet_values", discreteH1);
+
+    Dune::FemTools::BetterL2Projection::project(analyticalDirichletValues, discreteDirichletValues);
+
+    // FunctionType should be obsolete
+    // It should be either a DoF-Container or an analytical function, and for
+    // transition phase a discrete function.
+    typedef Subspace::Affine<DiscreteH10Type, DiscreteFunctionType> DiscreteH1gType;
+
+    DiscreteH1gType discreteH1g(discreteH10, discreteDirichletValues);
+
+
+    // operator and functional
+    typedef Operator::FiniteElement<DiscreteH1Type, EllipticOperation> FEMellipticOperator;
+
+    EllipticOperation ellipticOperation;
+
+    FEMellipticOperator femEllipticOperator(discreteH1, ellipticOperation);
+
+    typedef Functional::FiniteElement<DiscreteH1Type, ProductOperation> FEMrhsFunctional;
+
+    ProductOperation productOperation;
+
+    FEMrhsFunctional femRhsFunctional(discreteH1, productOperation);
+
+
+    // matrix, rhs and solution storage
+    typedef Dune::FieldMatrix<double, dimRange, dimRange> FieldMatrixType;
+
+    typedef Container::MatrixFactory<Dune::BCRSMatrix<FieldMatrixType>> MatrixFactoryType;
+
+    typedef MatrixFactoryType::AutoPtrType MatrixContainerPtr;
+
+    typedef MatrixFactoryType::ContainerType MatrixContainer;
+
+    typedef Container::VectorFactory<Dune::BlockVector<Dune::FieldVector<double, 1>>> VectorFactoryType;
+
+    typedef VectorFactoryType::AutoPtrType VectorContainerPtr;
+
+    typedef VectorFactoryType::ContainerType VectorContainer;
+
+    //    SparsityPattern & pattern = h1.fullSparsityPattern();
+
+    MatrixContainerPtr A = MatrixFactoryType::create(discreteH10);
+    VectorContainerPtr F = VectorFactoryType::create(discreteH10);
+    VectorContainerPtr G = VectorFactoryType::create(discreteH1);
+
+    //    MatrixContainer& A  = Container::MatrixFactory<MatrixContainer>::createRef( discreteH10 );
+    //    VectorContainer& F  = Container::VectorFactory<VectorContainer>::createRef( discreteH10 );
+    //    VectorContainer& G  = Container::VectorFactory<VectorContainer>::createRef( discreteH1 );
+
+    VectorContainerPtr u0 = VectorFactoryType::create(discreteH10);
+
+
+    // assembler
+    typedef Solver::FEMAssembler<MatrixContainer, VectorContainer> Assembler;
+
+    Assembler::assembleMatrix(femEllipticOperator, *A);
+    Assembler::applyMatrixConstraints(discreteH10, *A);
+
+    Assembler::assembleVector(femRhsFunctional, *F);
+    Assembler::applyVectorConstraints(discreteH10, *F);
+
+    //    Assembler::assembleVector( femEllipticOperator( discreteDirichletValues ), *G );
+
+
+    // preconditioner and solver
+    typedef Dune::MatrixAdapter<MatrixContainer, VectorContainer, VectorContainer> MatrixAdapterType;
+
+    MatrixAdapterType op(*A);
+
+    typedef Dune::SeqILU0<MatrixContainer, VectorContainer, VectorContainer, 1> SeqILU0Type;
+
+    SeqILU0Type prec(*A, 1.0);
+
+    typedef Dune::CGSolver<VectorContainer> CG;
+
+    CG cg(op, prec, 1e-4, 100, 2);
+
+    Dune::InverseOperatorResult res;
+
+    // u_0 = A^(-1) ( F - G )
+    //    *G = G->operator*=( -1.0 );
+    //    *F = F->operator+=( *G );
+    cg.apply(*u0, *F, res);
+
+
+    // postprocessing
+    DiscreteFunctionType solution = Dune::FemTools::discreteFunctionFactory<DiscreteFunctionType>(discreteH1, *u0);
+    //    solution += discreteDirichletValues;
+    Dune::FemTools::writeDiscreteFunctionToVTK(solution, "solution");
+
+    return 0;
+  } catch (Dune::Exception& e) {
+    std::cerr << "Dune reported error: " << e << std::endl;
+  } catch (...) {
+    std::cerr << "Unknown exception thrown!" << std::endl;
+  }
+}
diff --git a/examples/finite_element_local_operation/macrogrids/unitcube1.dgf b/examples/finite_element_local_operation/macrogrids/unitcube1.dgf
new file mode 100644
index 000000000..e3d9007ea
--- /dev/null
+++ b/examples/finite_element_local_operation/macrogrids/unitcube1.dgf
@@ -0,0 +1,18 @@
+DGF
+
+Interval
+0     % first corner
+1     % second corner
+4     % 4 cells only
+# 
+
+BoundaryDomain
+default 1    % all boundaries have id 1
+#
+
+GridParameter
+name 1d_Unit_Cube
+overlap 1
+#
+
+# unitcube1.dgf 
diff --git a/examples/finite_element_local_operation/macrogrids/unitcube2.dgf b/examples/finite_element_local_operation/macrogrids/unitcube2.dgf
new file mode 100644
index 000000000..7a21d41e1
--- /dev/null
+++ b/examples/finite_element_local_operation/macrogrids/unitcube2.dgf
@@ -0,0 +1,18 @@
+DGF
+
+Interval
+0 0   % first corner
+1 1   % second corner
+40 40   % 4 cells in each direction (x, y)
+# 
+
+BoundaryDomain
+default 1    % all boundaries have id 1
+#
+
+GridParameter
+name 2d_Unit_Cube
+overlap 1
+#
+
+# unitcube2.dgf
diff --git a/examples/finite_element_local_operation/macrogrids/unitcube3.dgf b/examples/finite_element_local_operation/macrogrids/unitcube3.dgf
new file mode 100644
index 000000000..1753fa226
--- /dev/null
+++ b/examples/finite_element_local_operation/macrogrids/unitcube3.dgf
@@ -0,0 +1,18 @@
+DGF
+
+Interval
+0 0 0  % first corner
+1 1 1  % second corner
+4 4 4  % 4 cells in each direction (x, y, z)
+# 
+
+BoundaryDomain
+default 1    % all boundaries have id 1
+#
+
+GridParameter
+name 3d_Unit_Cube
+overlap 1
+#
+
+# unitcube3.dgf
-- 
GitLab