diff --git a/Makefile.am b/Makefile.am index 2c0fae94bdefff84c4c0869bf043b7d74e554558..684a8ea4499f2c563ae4a8b5b303f0dec3a37105 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,11 +4,14 @@ LDADD = $(IPOPT_LDFLAGS) $(IPOPT_LIBS) AM_CPPFLAGS += $(IPOPT_CPPFLAGS) -noinst_PROGRAMS = staticrod staticrod2 rod3d harmonicmaps dirneucoupling +noinst_PROGRAMS = staticrod staticrod2 rod3d harmonicmaps dirneucoupling rod-eoc staticrod_SOURCES = staticrod.cc staticrod2_SOURCES = staticrod2.cc rod3d_SOURCES = rod3d.cc + +rod_eoc_SOURCES = rod-eoc.cc + harmonicmaps_SOURCES = harmonicmaps.cc harmonicmaps_CXXFLAGS = $(UG_CPPFLAGS) $(AMIRAMESH_CPPFLAGS) $(IPOPT_CPPFLAGS) $(PSURFACE_CPPFLAGS) harmonicmaps_LDADD = $(UG_LDFLAGS) $(AMIRAMESH_LDFLAGS) $(UG_LIBS) $(AMIRAMESH_LIBS) \ diff --git a/rod-eoc.cc b/rod-eoc.cc new file mode 100644 index 0000000000000000000000000000000000000000..e7f0f0f808a20da6220e1495e6f4f1ef0b27e708 --- /dev/null +++ b/rod-eoc.cc @@ -0,0 +1,207 @@ +#include <config.h> + +#include <dune/common/bitsetvector.hh> +#include <dune/common/configparser.hh> + +#include <dune/grid/onedgrid.hh> + +#include <dune/istl/io.hh> + + +#include <dune-solvers/solvers/iterativesolver.hh> +#include <dune-solvers/norms/energynorm.hh> + +#include "src/rigidbodymotion.hh" +#include "src/geodesicdifference.hh" +#include "src/rotation.hh" +#include "src/rodassembler.hh" +#include "src/riemanniantrsolver.hh" +#include "src/rodrefine.hh" + +typedef Dune::OneDGrid GridType; + +typedef RigidBodyMotion<3> TargetSpace; +typedef std::vector<RigidBodyMotion<3> > SolutionType; + +const int blocksize = TargetSpace::TangentVector::size; + +using namespace Dune; +using std::string; + +void solve (const GridType& grid, + SolutionType& x, int numLevels, + const TargetSpace& dirichletValue, + ConfigParser& parameters) +{ + // read solver setting + const double innerTolerance = parameters.get<double>("innerTolerance"); + const double tolerance = parameters.get<double>("tolerance"); + const int maxTrustRegionSteps = parameters.get<int>("maxTrustRegionSteps"); + const double initialTrustRegionRadius = parameters.get<double>("initialTrustRegionRadius"); + const int multigridIterations = parameters.get<int>("numIt"); + + // read rod parameter settings + const double A = parameters.get<double>("A"); + const double J1 = parameters.get<double>("J1"); + const double J2 = parameters.get<double>("J2"); + const double E = parameters.get<double>("E"); + const double nu = parameters.get<double>("nu"); + + // Create a local assembler + RodLocalStiffness<OneDGrid::LeafGridView,double> localStiffness(grid.leafView(), + A, J1, J2, E, nu); + + + + + x.resize(grid.size(1)); + + // ////////////////////////// + // Initial solution + // ////////////////////////// + + for (int i=0; i<x.size(); i++) { + x[i].r[0] = 0; + x[i].r[1] = 0; + x[i].r[2] = double(i)/(x.size()-1); + x[i].q = Rotation<3,double>::identity(); + } + + // set Dirichlet value + x.back() = dirichletValue; + + // Both ends are Dirichlet + BitSetVector<blocksize> dirichletNodes(grid.size(1)); + dirichletNodes.unsetAll(); + + dirichletNodes[0] = dirichletNodes.back() = true; + + // /////////////////////////////////////////// + // Create a solver for the rod problem + // /////////////////////////////////////////// + + RodAssembler<GridType> rodAssembler(grid, &localStiffness); + + RiemannianTrustRegionSolver<GridType,RigidBodyMotion<3> > rodSolver; +#if 0 + rodSolver.setup(grid, + &rodAssembler, + x, + dirichletNodes, + tolerance, + maxTrustRegionSteps, + initialTrustRegionRadius, + multigridIterations, + innerTolerance, + mu, nu1, nu2, + baseIterations, + baseTolerance, + false); // instrumentation +#else + rodSolver.setupTCG(grid, + &rodAssembler, + x, + dirichletNodes, + tolerance, + maxTrustRegionSteps, + initialTrustRegionRadius, + multigridIterations, + innerTolerance, + false); // instrumentation +#endif + + // ///////////////////////////////////////////////////// + // Solve! + // ///////////////////////////////////////////////////// + + rodSolver.setInitialSolution(x); + rodSolver.solve(); + + x = rodSolver.getSol(); +} + +int main (int argc, char *argv[]) try +{ + // parse data file + ConfigParser parameterSet; + if (argc==2) + parameterSet.parseFile(argv[1]); + else + parameterSet.parseFile("rod-eoc.parset"); + + // read solver settings + const int numLevels = parameterSet.get<int>("numLevels"); + const int nu1 = parameterSet.get<int>("nu1"); + const int nu2 = parameterSet.get<int>("nu2"); + const int mu = parameterSet.get<int>("mu"); + const int baseIterations = parameterSet.get<int>("baseIt"); + const double baseTolerance = parameterSet.get<double>("baseTolerance"); + + const int numRodBaseElements = parameterSet.get<int>("numRodBaseElements"); + + // ///////////////////////////////////////// + // Read Dirichlet values + // ///////////////////////////////////////// + + RigidBodyMotion<3> dirichletValue; + dirichletValue.r[0] = parameterSet.get<double>("dirichletValueX"); + dirichletValue.r[1] = parameterSet.get<double>("dirichletValueY"); + dirichletValue.r[2] = parameterSet.get<double>("dirichletValueZ"); + + FieldVector<double,3> axis; + axis[0] = parameterSet.get<double>("dirichletAxisX"); + axis[1] = parameterSet.get<double>("dirichletAxisY"); + axis[2] = parameterSet.get<double>("dirichletAxisZ"); + double angle = parameterSet.get<double>("dirichletAngle"); + + dirichletValue.q = Rotation<3,double>(axis, M_PI*angle/180); + + // /////////////////////////////////////////////////////////// + // First compute the 'exact' solution on a very fine grid + // /////////////////////////////////////////////////////////// + + // Create the reference grid + + GridType referenceGrid(numRodBaseElements, 0, 1); + + referenceGrid.globalRefine(numLevels-1); + + // Solve the rod Dirichlet problem + SolutionType referenceSolution; + solve(referenceGrid, referenceSolution, numLevels, dirichletValue, parameterSet); + + + + // /////////////////////////////////////////////////////////// + // Compute on all coarser levels, and compare + // /////////////////////////////////////////////////////////// + + + + for (int i=1; i<=numLevels; i++) { + + GridType grid(numRodBaseElements, 0, 1); + grid.globalRefine(i-1); + + // compute again + SolutionType solution; + solve(grid, solution, i, dirichletValue, parameterSet); + + // Prolong solution to the very finest grid + for (int j=i; j<numLevels; j++) + globalRodRefine(grid, solution); + + assert(referenceSolution.size() == solution.size()); + + // Compute max-norm difference + std::cout << "Level: " << i-1 + << ", max-norm error: " << computeGeodesicDifference(solution,referenceSolution).infinity_norm() + << std::endl; + + } + + } catch (Exception e) { + + std::cout << e << std::endl; + + }