diff --git a/problems/cosserat-continuum-cantilever.parset b/problems/cosserat-continuum-cantilever.parset index bfa21a8436ebefa2092dc2b059faac5f2d8323fd..ac1a07651c4e668550e5797e222e597df6073367 100644 --- a/problems/cosserat-continuum-cantilever.parset +++ b/problems/cosserat-continuum-cantilever.parset @@ -20,6 +20,9 @@ numLevels = 1 # Number of homotopy steps for the Dirichlet boundary conditions numHomotopySteps = 1 +# Solver type: trustRegion or proximalNewton +solvertype = trustRegion + # Tolerance of the trust region solver tolerance = 1e-3 diff --git a/problems/film-on-substrate.parset b/problems/film-on-substrate.parset index 1ce5db4b6676909c3c747f427fddc174dccbc3c7..8bfd20122b0ba089f52c008e4f21f3da2e779291 100644 --- a/problems/film-on-substrate.parset +++ b/problems/film-on-substrate.parset @@ -61,7 +61,7 @@ initialDeformation = "x" # Solver parameters ############################################# -# Inner solver, cholmod or multigrid +# Solver type: trustRegion or proximalNewton solvertype = trustRegion # Number of homotopy steps for the Dirichlet boundary conditions diff --git a/src/cosserat-continuum.cc b/src/cosserat-continuum.cc index ee4f3bd2335f24f577613a8605ecc0cc6762cca1..be9c92887f27d075a9bb6b765eab451d8a1733db 100644 --- a/src/cosserat-continuum.cc +++ b/src/cosserat-continuum.cc @@ -43,6 +43,8 @@ #include <dune/foamgrid/foamgrid.hh> #endif +#include <dune/istl/multitypeblockvector.hh> + #include <dune/functions/functionspacebases/lagrangebasis.hh> #include <dune/functions/functionspacebases/compositebasis.hh> #include <dune/functions/functionspacebases/powerbasis.hh> @@ -66,6 +68,7 @@ #include <dune/gfe/assemblers/mixedgfeassembler.hh> #if MIXED_SPACE +#include <dune/gfe/mixedriemannianpnsolver.hh> #include <dune/gfe/mixedriemanniantrsolver.hh> #else #include <dune/gfe/assemblers/geodesicfeassemblerwrapper.hh> @@ -504,31 +507,65 @@ int main (int argc, char *argv[]) try RealTuple<double,3>, Rotation<double,3> > mixedAssembler(compositeBasis, &localGFEADOLCStiffness); #if MIXED_SPACE - MixedRiemannianTrustRegionSolver<GridType, - CompositeBasis, - DeformationFEBasis, RealTuple<double,3>, - OrientationFEBasis, Rotation<double,3> > solver; - solver.setup(*grid, - &mixedAssembler, - deformationFEBasis, - orientationFEBasis, - x, - deformationDirichletDofs, - orientationDirichletDofs, tolerance, - maxSolverSteps, - initialTrustRegionRadius, - multigridIterations, - mgTolerance, - mu, nu1, nu2, - baseIterations, - baseTolerance, - instrumented); + if (parameterSet.get<std::string>("solvertype", "trustRegion") == "trustRegion") + { - solver.setScaling(parameterSet.get<FieldVector<double,6> >("solverScaling")); + MixedRiemannianTrustRegionSolver<GridType, + CompositeBasis, + DeformationFEBasis, RealTuple<double,3>, + OrientationFEBasis, Rotation<double,3> > solver; + solver.setup(*grid, + &mixedAssembler, + deformationFEBasis, + orientationFEBasis, + x, + deformationDirichletDofs, + orientationDirichletDofs, tolerance, + maxSolverSteps, + initialTrustRegionRadius, + multigridIterations, + mgTolerance, + mu, nu1, nu2, + baseIterations, + baseTolerance, + instrumented); - solver.setInitialIterate(x); - solver.solve(); - x = solver.getSol(); + solver.setScaling(parameterSet.get<FieldVector<double,6> >("solverScaling")); + + solver.setInitialIterate(x); + solver.solve(); + x = solver.getSol(); + } + else + { + //Create BitVector matching the tangential space + const int dimRotationTangent = Rotation<double,3>::TangentVector::dimension; + using VectorForBit = MultiTypeBlockVector<std::vector<FieldVector<double,3> >, std::vector<FieldVector<double,dimRotationTangent> > >; + using BitVector = Solvers::DefaultBitVector_t<VectorForBit>; + BitVector dirichletDofs; + dirichletDofs[_0].resize(compositeBasis.size({0})); + dirichletDofs[_1].resize(compositeBasis.size({1})); + for (size_t i = 0; i < compositeBasis.size({0}); i++) { + for (size_t j = 0; j < 3; j++) + dirichletDofs[_0][i][j] = deformationDirichletDofs[i][j]; + } + for (size_t i = 0; i < compositeBasis.size({1}); i++) { + for (int j = 0; j < dimRotationTangent; j++) + dirichletDofs[_1][i][j] = orientationDirichletDofs[i][j]; + } + GFE::MixedRiemannianProximalNewtonSolver<CompositeBasis, DeformationFEBasis, RealTuple<double,3>, OrientationFEBasis, Rotation<double,3>, BitVector> solver; + solver.setup(*grid, + &mixedAssembler, + x, + dirichletDofs, + tolerance, + maxSolverSteps, + initialRegularization, + instrumented); + solver.setInitialIterate(x); + solver.solve(); + x = solver.getSol(); + } #else //The MixedRiemannianTrustRegionSolver can treat the Displacement and Orientation Space as separate ones //The RiemannianTrustRegionSolver can only treat the Displacement and Rotation together in a ProductManifold. diff --git a/src/film-on-substrate.cc b/src/film-on-substrate.cc index 0630bf58bb61cff74976e897171a95bc4248ed0f..97fc8ef8d204ed73bf7a83099e9be19e6980a47b 100644 --- a/src/film-on-substrate.cc +++ b/src/film-on-substrate.cc @@ -64,6 +64,7 @@ #include <dune/gfe/assemblers/sumenergy.hh> #if MIXED_SPACE +#include <dune/gfe/mixedriemannianpnsolver.hh> #include <dune/gfe/mixedriemanniantrsolver.hh> #else #include <dune/gfe/assemblers/geodesicfeassemblerwrapper.hh> @@ -650,7 +651,18 @@ int main (int argc, char *argv[]) try } else { //parameterSet.get<std::string>("solvertype") == "proximalNewton" #if MIXED_SPACE - DUNE_THROW(Exception, "Error: There is no MixedRiemannianProximalNewtonSolver!"); + GFE::MixedRiemannianProximalNewtonSolver<CompositeBasis, DeformationFEBasis, RealTuple<double,dim>, OrientationFEBasis, Rotation<double,dim>, BitVector> solver; + solver.setup(*grid, + &mixedAssembler, + x, + dirichletDofs, + tolerance, + maxSolverSteps, + initialRegularization, + instrumented); + solver.setInitialIterate(x); + solver.solve(); + x = solver.getSol(); #else RiemannianProximalNewtonSolver<DeformationFEBasis, RBM, GFEAssemblerWrapper> solver; solver.setup(*grid, diff --git a/test/filmonsubstratetest.cc b/test/filmonsubstratetest.cc index 876871dfe33adb8ae69c98dd06ffce1f65f6cbff..c9b40dda93a72713d1e2cc7b0034606e64856fed 100644 --- a/test/filmonsubstratetest.cc +++ b/test/filmonsubstratetest.cc @@ -47,6 +47,7 @@ #include <dune/gfe/assemblers/sumenergy.hh> #if MIXED_SPACE +#include <dune/gfe/mixedriemannianpnsolver.hh> #include <dune/gfe/mixedriemanniantrsolver.hh> #else #include <dune/gfe/assemblers/geodesicfeassemblerwrapper.hh> @@ -458,7 +459,18 @@ int main (int argc, char *argv[]) } else { // solverType == "proximalNewton" #if MIXED_SPACE - DUNE_THROW(Exception, "Error: There is no MixedRiemannianProximalNewtonSolver!"); + GFE::MixedRiemannianProximalNewtonSolver<CompositeBasis, DeformationFEBasis, RealTuple<double,dim>, OrientationFEBasis, Rotation<double,dim>, BitVector> solver; + solver.setup(*grid, + &mixedAssembler, + x, + dirichletDofs, + tolerance, + maxSolverSteps, + 1.0 /* initialRegularization */, + false /* instrumented */); + solver.setInitialIterate(x); + solver.solve(); + x = solver.getSol(); #else RiemannianProximalNewtonSolver<DeformationFEBasis, RBM, GFEAssemblerWrapper> solver; solver.setup(*grid,