Newer
Older
#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

Oliver Sander
committed
#undef overwrite // stupid: ADOL-C sets this to 1, so the name cannot be used
#include <iostream>
#include <vector>
#include <cstdlib>
#include <math.h>

Oliver Sander
committed
#include <dune/gfe/adolcnamespaceinjections.hh>

Oliver Sander
committed
#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>

Oliver Sander
committed
#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;

Oliver Sander
committed
std::vector<ATargetSpace> localSolution(localPureSolution.size());

Oliver Sander
committed
#if 0
HarmonicEnergyLocalStiffness<GridView,LocalFiniteElement,ATargetSpace> assembler;

Oliver Sander
committed
#else
ParameterTree parameterSet;
ParameterTreeParser::readINITree("../cosserat-continuum.parset", parameterSet);

Oliver Sander
committed
const ParameterTree& materialParameters = parameterSet.sub("materialParameters");
std::cout << "Material parameters:" << std::endl;
materialParameters.report();

Oliver Sander
committed
CosseratEnergyLocalStiffness<GridView,LocalFiniteElement,3, adouble> assembler(materialParameters, NULL, NULL);
#endif
trace_on(1);
adouble energy = 0;

Oliver Sander
committed
for (size_t i=0; i<localSolution.size(); i++)
localSolution[i] <<=localPureSolution[i];

Oliver Sander
committed
energy = assembler.energy(element,localFiniteElement,localSolution);
energy >>= pureEnergy;
trace_off(1);

Oliver Sander
committed
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

Oliver Sander
committed
/****************************************************************************/
/* MAIN PROGRAM */
int main() {

Oliver Sander
committed
size_t nDofs = 4;
//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;

Oliver Sander
committed
//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;

Oliver Sander
committed
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);

Oliver Sander
committed
// 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));

Oliver Sander
committed
hessian(1,nDoubles,xp.data(),H); // H equals (n-1)g since g is
std::cout << "Hessian:" << std::endl;

Oliver Sander
committed
for(size_t i=0; i<nDoubles; i++) {
for (size_t j=0; j<nDoubles; j++) {