Skip to content
Snippets Groups Projects
adolctest.cc 7.84 KiB
Newer Older
  • Learn to ignore specific revisions
  • #include "config.h"
    
    #include <adolc/adouble.h>            // use of active doubles
    #include <adolc/drivers/drivers.h>    // use of "Easy to Use" drivers
    // gradient(.) and hessian(.)
    #include <adolc/taping.h>             // use of taping
    
    
    #undef overwrite  // stupid: ADOL-C sets this to 1, so the name cannot be used
    
    
    #include <iostream>
    #include <vector>
    
    #include <cstdlib>
    #include <math.h>
    
    
    #include <dune/gfe/adolcnamespaceinjections.hh>
    
    #include <dune/common/parametertree.hh>
    #include <dune/common/parametertreeparser.hh>
    
    #include <dune/grid/yaspgrid.hh>
    #include <dune/geometry/quadraturerules.hh>
    
    #include <dune/localfunctions/lagrange/q1.hh>
    
    
    #include <dune/fufem/functionspacebases/q1nodalbasis.hh>
    
    
    #include <dune/gfe/realtuple.hh>
    #include <dune/gfe/localgeodesicfefunction.hh>
    #include <dune/gfe/harmonicenergystiffness.hh>
    
    #include <dune/gfe/cosseratenergystiffness.hh>
    
    #include <dune/gfe/localgeodesicfeadolcstiffness.hh>
    
    #include "valuefactory.hh"
    #include "multiindex.hh"
    
    
    using namespace Dune;
    
    
    /** \brief Computes the diameter of a set */
    template <class TargetSpace>
    double diameter(const std::vector<TargetSpace>& v)
    {
        double d = 0;
        for (size_t i=0; i<v.size(); i++)
            for (size_t j=0; j<v.size(); j++)
                d = std::max(d, TargetSpace::distance(v[i],v[j]));
        return d;
    }
    
    
    
    
    template <int blocksize, class TargetSpace>
    
    void compareMatrices(const Matrix<FieldMatrix<double,blocksize,blocksize> >& fdMatrix,
    
                         const Matrix<FieldMatrix<double,blocksize,blocksize> >& adolcMatrix,
                         const std::vector<TargetSpace>& configuration)
    
    {
      assert(fdMatrix.N() == adolcMatrix.N());
      assert(fdMatrix.M() == adolcMatrix.M());
    
      Matrix<FieldMatrix<double,blocksize,blocksize> > diff = fdMatrix;
      diff -= adolcMatrix;
    
      if ( (diff.frobenius_norm() / fdMatrix.frobenius_norm()) > 1e-4) {
    
    
        std::cout << "Matrices differ for" << std::endl;
        for (size_t j=0; j<configuration.size(); j++)
          std::cout << configuration[j] << std::endl;
    
    
        std::cout << "finite differences:" << std::endl;
        printmatrix(std::cout, fdMatrix, "finite differences", "--");
        std::cout << "ADOL-C:" << std::endl;
        printmatrix(std::cout, adolcMatrix, "ADOL-C", "--");
        assert(false);
      }
    }
    
    
    template <class TargetSpace, int gridDim>
    
    int testHarmonicEnergy() {
    
      std::cout << " --- Testing " << className<TargetSpace>() << ", domain dimension: " << gridDim << " ---" << std::endl;
    
    
      // set up a test grid
    
      typedef YaspGrid<gridDim> GridType;
      FieldVector<double,gridDim> l(1);
      std::array<int,gridDim> elements;
    
      std::fill(elements.begin(), elements.end(), 1);
    
      GridType grid(l,elements);
    
    
      typedef Q1NodalBasis<typename GridType::LeafGridView,double> Q1Basis;
    
    Oliver Sander's avatar
    Oliver Sander committed
      Q1Basis q1Basis(grid.leafGridView());
    
      typedef Q1LocalFiniteElement<double,double,gridDim> LocalFE;
    
      LocalFE localFiniteElement;
    
      // Assembler using finite differences
    
      HarmonicEnergyLocalStiffness<typename GridType::LeafGridView,
                                   typename Q1Basis::LocalFiniteElement,
    
                                   TargetSpace> harmonicEnergyLocalStiffness;
    
    
      // Assembler using ADOL-C
    
      typedef typename TargetSpace::template rebind<adouble>::other ATargetSpace;
      HarmonicEnergyLocalStiffness<typename GridType::LeafGridView,
                                   typename Q1Basis::LocalFiniteElement,
    
                                   ATargetSpace> harmonicEnergyADOLCLocalStiffness;
    
      LocalGeodesicFEADOLCStiffness<typename GridType::LeafGridView,
                                    typename Q1Basis::LocalFiniteElement,
    
                                    TargetSpace> localGFEADOLCStiffness(&harmonicEnergyADOLCLocalStiffness);
    
    
      size_t nDofs = localFiniteElement.localBasis().size();
    
      std::vector<TargetSpace> localSolution(nDofs);
    
      std::vector<TargetSpace> testPoints;
      ValueFactory<TargetSpace>::get(testPoints);
    
      int nTestPoints = testPoints.size();
    
      MultiIndex index(nDofs, nTestPoints);
      int numIndices = index.cycle();
    
      for (int i=0; i<numIndices; i++, ++index) {
    
        for (size_t j=0; j<nDofs; j++)
          localSolution[j] = testPoints[index[j]];
    
        if (diameter(localSolution) > 0.5*M_PI)
            continue;
    
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    
        std::vector<typename TargetSpace::TangentVector> localGradient;
        harmonicEnergyLocalStiffness.assembleGradientAndHessian(*grid.template leafbegin<0>(),localFiniteElement, localSolution,
                                                                localGradient);
    
        localGFEADOLCStiffness.assembleGradientAndHessian(*grid.template leafbegin<0>(),localFiniteElement, localSolution,
                                                          localGradient);
    
        compareMatrices(harmonicEnergyLocalStiffness.A_, localGFEADOLCStiffness.A_, localSolution);
    
    }
    
    int testCosseratEnergy() {
    
      typedef RigidBodyMotion<double,3> TargetSpace;
      const int gridDim = 2;
    
      std::cout << " --- Testing " << className<TargetSpace>() << ", domain dimension: " << gridDim << " ---" << std::endl;
    
      ParameterTree parameterSet;
      ParameterTreeParser::readINITree("../cosserat-continuum.parset", parameterSet);
    
      const ParameterTree& materialParameters = parameterSet.sub("materialParameters");
      std::cout << "Material parameters:" << std::endl;
      materialParameters.report();
    
      // set up a test grid
      typedef YaspGrid<gridDim> GridType;
      FieldVector<double,gridDim> l(1);
      std::array<int,gridDim> elements;
      std::fill(elements.begin(), elements.end(), 1);
    
      GridType grid(l,elements);
    
    
      typedef Q1NodalBasis<typename GridType::LeafGridView,double> Q1Basis;
    
    Oliver Sander's avatar
    Oliver Sander committed
      Q1Basis q1Basis(grid.leafGridView());
    
      typedef Q1LocalFiniteElement<double,double,gridDim> LocalFE;
      LocalFE localFiniteElement;
    
      // Assembler using finite differences
      CosseratEnergyLocalStiffness<GridType::LeafGridView,
                                   Q1Basis::LocalFiniteElement,
                                   3> cosseratEnergyLocalStiffness(materialParameters,NULL,NULL);
    
      // Assembler using ADOL-C
      CosseratEnergyLocalStiffness<GridType::LeafGridView,
                                   Q1Basis::LocalFiniteElement,
                                   3,adouble> cosseratEnergyADOLCLocalStiffness(materialParameters, NULL, NULL);
      LocalGeodesicFEADOLCStiffness<GridType::LeafGridView,
                                    Q1Basis::LocalFiniteElement,
                                    TargetSpace> localGFEADOLCStiffness(&cosseratEnergyADOLCLocalStiffness);
    
      size_t nDofs = localFiniteElement.localBasis().size();
    
      std::vector<TargetSpace> localSolution(nDofs);
      std::vector<TargetSpace> testPoints;
      ValueFactory<TargetSpace>::get(testPoints);
    
      int nTestPoints = testPoints.size();
    
      MultiIndex index(nDofs, nTestPoints);
      int numIndices = index.cycle();
    
      for (int i=0; i<numIndices; i++, ++index) {
    
        for (size_t j=0; j<nDofs; j++)
          localSolution[j] = testPoints[index[j]];
    
        if (diameter(localSolution) > TargetSpace::convexityRadius)
    
        std::vector<typename TargetSpace::TangentVector> localGradient;
        cosseratEnergyLocalStiffness.assembleGradientAndHessian(*grid.leafbegin<0>(),localFiniteElement, localSolution,
                                                                localGradient);
    
        localGFEADOLCStiffness.assembleGradientAndHessian(*grid.leafbegin<0>(),localFiniteElement, localSolution,
                                                          localGradient);
    
        compareMatrices(cosseratEnergyLocalStiffness.A_, localGFEADOLCStiffness.A_, localSolution);
    
       testHarmonicEnergy<UnitVector<double,2>, 1>();
       testHarmonicEnergy<UnitVector<double,3>, 1>();
       testHarmonicEnergy<UnitVector<double,2>, 2>();
       testHarmonicEnergy<UnitVector<double,3>, 2>();
    
    
       testCosseratEnergy();
    }