Skip to content
Snippets Groups Projects
adolctest.cc 4.73 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/gfe/realtuple.hh>
    #include <dune/gfe/localgeodesicfefunction.hh>
    #include <dune/gfe/harmonicenergystiffness.hh>
    
    #include <dune/gfe/cosseratenergystiffness.hh>
    
    
    using namespace Dune;
    
    
    #if 1
    template <class GridView, class LocalFiniteElement, class TargetSpace>
    double
    energy(const typename GridView::template Codim<0>::Entity& element,
           const LocalFiniteElement& localFiniteElement,
           const std::vector<TargetSpace>& localPureSolution)
    {
        double pureEnergy;
    
        typedef typename TargetSpace::template rebind<adouble>::other ATargetSpace;
    
        std::vector<ATargetSpace> localSolution(localPureSolution.size());
    
        HarmonicEnergyLocalStiffness<GridView,LocalFiniteElement,ATargetSpace> assembler;
    
    #else
        ParameterTree parameterSet;
        ParameterTreeParser::readINITree("../cosserat-continuum.parset", parameterSet);
    
        const ParameterTree& materialParameters = parameterSet.sub("materialParameters");
        std::cout << "Material parameters:" << std::endl;
        materialParameters.report();
    
        CosseratEnergyLocalStiffness<GridView,LocalFiniteElement,3, adouble> assembler(materialParameters, NULL, NULL);
    
    #endif
    
        trace_on(1);
    
        adouble energy = 0;
    
    
        for (size_t i=0; i<localSolution.size(); i++)
          localSolution[i] <<=localPureSolution[i];
    
        energy = assembler.energy(element,localFiniteElement,localSolution);
    
    
        energy >>= pureEnergy;
    
        trace_off(1);
    
    
        size_t tape_stats[STAT_SIZE];
        tapestats(1,tape_stats);             // reading of tape statistics
        cout<<"maxlive "<<tape_stats[NUM_MAX_LIVES]<<"\n";
        // ..... print other tape stats
    
    
        return pureEnergy;
    }
    #endif
    
    
    /****************************************************************************/
    /*                                                             MAIN PROGRAM */
    int main() {
    
    
    
      //std::cout << className< decltype(adouble() / double()) >() << std::endl;
    
      const int dim = 2;
      typedef YaspGrid<dim> GridType;
      FieldVector<double,dim> l(1);
      std::array<int,dim> elements = {{1, 1}};
      GridType grid(l,elements);
    
      typedef Q1LocalFiniteElement<double,double,dim> LocalFE;
      LocalFE localFiniteElement;
    
    
      //typedef RealTuple<double,1> TargetSpace;
      typedef RigidBodyMotion<double,3> TargetSpace;
      std::vector<TargetSpace> localSolution(nDofs);
      FieldVector<double,7> identity(0);
      identity[6] = 1;
    
      for (auto vIt = grid.leafbegin<dim>(); vIt != grid.leafend<dim>(); ++vIt) {
        localSolution[grid.leafView().indexSet().index(*vIt)].r = 0;
        for (int i=0; i<dim; i++)
          localSolution[grid.leafView().indexSet().index(*vIt)].r[i] = 2*vIt->geometry().corner(0)[i];
        localSolution[grid.leafView().indexSet().index(*vIt)].q = Rotation<double,3>::identity();
      }
    
      for (size_t i=0; i<localSolution.size(); i++)
        std::cout << localSolution[i] << std::endl;
    
    
      double laplaceEnergy = energy<GridType::LeafGridView,LocalFE, TargetSpace>(*grid.leafbegin<0>(), localFiniteElement, localSolution);
    
      std::cout << "Laplace energy: " << laplaceEnergy << std::endl;
    
    
      size_t nDoubles = nDofs*sizeof(TargetSpace) / sizeof(double);
      std::vector<double> xp(nDoubles);
      int idx=0;
      for (size_t i=0; i<nDofs; i++)
        for (size_t j=0; j<sizeof(TargetSpace) / sizeof(double); j++)
            xp[idx++] = localSolution[i].globalCoordinates()[j];
    
      // Compute gradient
        double* g = new double[nDoubles];
        gradient(1,nDoubles,xp.data(),g);                  // gradient evaluation
    
      int idx2 = 0;
      for(size_t i=0; i<nDofs; i++) {
        for (size_t j=0; j<sizeof(TargetSpace) / sizeof(double); j++) {
          std::cout << g[idx2++] << "  ";
        }
        std::cout << std::endl;
      }
    
    
      //exit(0);
    
      // Compute Hessian
      double** H   = (double**) malloc(nDoubles*sizeof(double*));
      for(size_t i=0; i<nDoubles; i++)
    
          H[i] = (double*)malloc((i+1)*sizeof(double));
    
      hessian(1,nDoubles,xp.data(),H);                   // H equals (n-1)g since g is
    
    
      std::cout << "Hessian:" << std::endl;
    
      for(size_t i=0; i<nDoubles; i++) {
        for (size_t j=0; j<nDoubles; j++) {
    
          double value = (j<=i) ? H[i][j] : H[j][i];
          std::cout << value << "  ";
        }
        std::cout << std::endl;
      }
    
        return 0;
    } // end main