diff --git a/test/adolctest.cc b/test/adolctest.cc index e8ea73ac63f010974ad6006fe2a400ec4fd6cdab..671e97eac661c4249f23bdd58ad057f7df041be5 100644 --- a/test/adolctest.cc +++ b/test/adolctest.cc @@ -5,39 +5,18 @@ // 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> -namespace std -{ - adouble max(adouble a, adouble b) { - return fmax(a,b); - } - - adouble sqrt(adouble a) { - return sqrt(a); - } - - adouble abs(adouble a) { - return fabs(a); - } +#include <dune/gfe/adolcnamespaceinjections.hh> - adouble pow(const adouble& a, const adouble& b) { - return pow(a,b); - } - - bool isnan(adouble a) { - return std::isnan(a.value()); - } - - bool isinf(adouble a) { - return std::isinf(a.value()); - } - -} +#include <dune/common/parametertree.hh> +#include <dune/common/parametertreeparser.hh> #include <dune/grid/yaspgrid.hh> #include <dune/geometry/quadraturerules.hh> @@ -47,6 +26,7 @@ namespace std #include <dune/gfe/realtuple.hh> #include <dune/gfe/localgeodesicfefunction.hh> #include <dune/gfe/harmonicenergystiffness.hh> +#include <dune/gfe/cosseratenergystiffness.hh> using namespace Dune; @@ -59,104 +39,51 @@ energy(const typename GridView::template Codim<0>::Entity& element, const std::vector<TargetSpace>& localPureSolution) { double pureEnergy; - typedef RealTuple<adouble,1> ADTargetSpace; - std::vector<ADTargetSpace> localSolution(localPureSolution.size()); typedef typename TargetSpace::template rebind<adouble>::other ATargetSpace; + std::vector<ATargetSpace> localSolution(localPureSolution.size()); +#if 0 HarmonicEnergyLocalStiffness<GridView,LocalFiniteElement,ATargetSpace> assembler; +#else + ParameterTree parameterSet; + ParameterTreeParser::readINITree("../cosserat-continuum.parset", parameterSet); - 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); + const ParameterTree& materialParameters = parameterSet.sub("materialParameters"); + std::cout << "Material parameters:" << std::endl; + materialParameters.report(); - return pureEnergy; -} + CosseratEnergyLocalStiffness<GridView,LocalFiniteElement,3, adouble> assembler(materialParameters, NULL, NULL); #endif -#if 0 -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) -{ - typedef RealTuple<adouble,1> ADTargetSpace; - std::vector<ADTargetSpace> localSolution(localPureSolution.size()); - trace_on(1); - for (size_t i=0; i<localSolution.size(); i++) - localSolution[i] <<= localPureSolution[i]; - - assert(element.type() == localFiniteElement.type()); - - static const int gridDim = GridView::dimension; - typedef typename GridView::template Codim<0>::Entity::Geometry Geometry; - - double pureEnergy; adouble energy = 0; - LocalGeodesicFEFunction<gridDim, adouble, LocalFiniteElement, ADTargetSpace> localGeodesicFEFunction(localFiniteElement, - localSolution); - - int quadOrder = (element.type().isSimplex()) ? (localFiniteElement.localBasis().order()-1) * 2 - : localFiniteElement.localBasis().order() * 2 * gridDim; - - - - const Dune::QuadratureRule<double, gridDim>& quad - = Dune::QuadratureRules<double, gridDim>::rule(element.type(), quadOrder); - - for (size_t pt=0; pt<quad.size(); pt++) { - // Local position of the quadrature point - const Dune::FieldVector<double,gridDim>& quadPos = quad[pt].position(); - - const double integrationElement = element.geometry().integrationElement(quadPos); - - const typename Geometry::JacobianInverseTransposed& jacobianInverseTransposed = element.geometry().jacobianInverseTransposed(quadPos); - - double weight = quad[pt].weight() * integrationElement; - - // The derivative of the local function defined on the reference element - Dune::FieldMatrix<adouble, TargetSpace::EmbeddedTangentVector::dimension, gridDim> referenceDerivative = localGeodesicFEFunction.evaluateDerivative(quadPos); - - // The derivative of the function defined on the actual element - Dune::FieldMatrix<adouble, TargetSpace::EmbeddedTangentVector::dimension, gridDim> derivative(0); - - for (size_t comp=0; comp<referenceDerivative.N(); comp++) - jacobianInverseTransposed.umv(referenceDerivative[comp], derivative[comp]); - - // Add the local energy density - // The Frobenius norm is the correct norm here if the metric of TargetSpace is the identity. - // (And if the metric of the domain space is the identity, which it always is here.) - energy += weight * derivative.frobenius_norm2(); + for (size_t i=0; i<localSolution.size(); i++) + localSolution[i] <<=localPureSolution[i]; - } + energy = assembler.energy(element,localFiniteElement,localSolution); - energy *= 0.5; 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() { - size_t n = 4; + size_t nDofs = 4; //std::cout << className< decltype(adouble() / double()) >() << std::endl; @@ -169,33 +96,62 @@ int main() { typedef Q1LocalFiniteElement<double,double,dim> LocalFE; LocalFE localFiniteElement; - typedef RealTuple<double,1> TargetSpace; - std::vector<TargetSpace> localSolution(n); - localSolution[0] = TargetSpace(0); - localSolution[1] = TargetSpace(0); - localSolution[2] = TargetSpace(1); - localSolution[3] = TargetSpace(1); + //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; - std::vector<double> xp(n); - for (size_t i=0; i<n; i++) - xp[i] = 1; + 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); - double** H = (double**) malloc(n*sizeof(double*)); - for(size_t i=0; i<n; i++) + // 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,n,xp.data(),H); // H equals (n-1)g since g is + 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<n; i++) { - for (size_t j=0; j<n; j++) { + 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; + exit(0); } // Get gradient