From 5c1ceacebae2f95cc51eb9df47b82e7f9098952b Mon Sep 17 00:00:00 2001 From: Oliver Sander <sander@igpm.rwth-aachen.de> Date: Tue, 23 Aug 2005 16:43:17 +0000 Subject: [PATCH] use the monotone multigrid solver now [[Imported from SVN: r481]] --- staticrod.cc | 168 +++++++++++++++++++++++++++++---------------------- 1 file changed, 96 insertions(+), 72 deletions(-) diff --git a/staticrod.cc b/staticrod.cc index 4ac8dba2..8a50ae61 100644 --- a/staticrod.cc +++ b/staticrod.cc @@ -15,18 +15,19 @@ //#include "../common/linearipopt.hh" #include "../common/projectedblockgsstep.hh" +#include "../contact/src/contactmmgstep.hh" + #include <dune/solver/iterativesolver.hh> #include "../common/geomestimator.hh" #include "../common/energynorm.hh" #include <dune/common/configparser.hh> +#include "src/rodwriter.hh" // Choose a solver //#define IPOPT -#define GAUSS_SEIDEL -//#define MULTIGRID - -//#define IPOPT_BASE +//#define GAUSS_SEIDEL +#define MULTIGRID // Number of degrees of freedom: // 3 (x, y, theta) for a planar rod @@ -46,7 +47,6 @@ int main (int argc, char *argv[]) try parameterSet.parseFile("staticrod.parset"); // read solver settings - const int minLevel = parameterSet.get("minLevel", int(0)); const int maxLevel = parameterSet.get("maxLevel", int(0)); double loadIncrement = parameterSet.get("loadIncrement", double(0)); const int maxNewtonSteps = parameterSet.get("maxNewtonSteps", int(0)); @@ -59,42 +59,35 @@ int main (int argc, char *argv[]) try const double baseTolerance = parameterSet.get("baseTolerance", double(0)); // Problem settings - const int numRodElements = parameterSet.get("numRodElements", int(0)); + const int numRodBaseElements = parameterSet.get("numRodBaseElements", int(0)); // /////////////////////////////////////// // Create the two grids // /////////////////////////////////////// typedef OneDGrid<1,1> RodGridType; - RodGridType rod(numRodElements, 0, 1); - - - - Array<BitField> dirichletNodes; - dirichletNodes.resize(maxLevel+1); - dirichletNodes[0].resize( blocksize * (numRodElements+1) ); - - dirichletNodes[0].unsetAll(); - dirichletNodes[0][0] = dirichletNodes[0][1] = dirichletNodes[0][2] = true; - dirichletNodes[0][blocksize*numRodElements+0] = true; - dirichletNodes[0][blocksize*numRodElements+1] = true; - dirichletNodes[0][blocksize*numRodElements+2] = true; + RodGridType rod(numRodBaseElements, 0, 1); - // refine uniformly until minlevel - for (int i=0; i<minLevel; i++) + // refine uniformly until maxLevel + for (int i=0; i<maxLevel; i++) rod.globalRefine(1); int maxlevel = rod.maxlevel(); + int numRodElements = rod.size(maxlevel, 0); - // ////////////////////////////////////////////////////////// - // Create obstacles - // ////////////////////////////////////////////////////////// + + Array<BitField> dirichletNodes; + dirichletNodes.resize(maxLevel+1); + for (int i=0; i<=maxlevel; i++) { - Array<BitField> hasObstacle; - hasObstacle.resize(maxLevel+1); - hasObstacle[0].resize(numRodElements+1); - hasObstacle[0].unsetAll(); + dirichletNodes[i].resize( blocksize * rod.size(i,1) ); + dirichletNodes[i].unsetAll(); + for (int j=0; j<blocksize; j++) { + dirichletNodes[i][j] = true; + dirichletNodes[i][dirichletNodes[i].size()-1-j] = true; + } + } // ////////////////////////////////////////////////////////// // Create discrete function spaces @@ -122,6 +115,13 @@ int main (int argc, char *argv[]) try VectorType corr; MatrixType hessianMatrix; + RodAssembler<RodFuncSpaceType, 2> rodAssembler(*rodFuncSpace[maxlevel]); + rodAssembler.setParameters(1, 10, 10); + + MatrixIndexSet indices(numRodElements+1, numRodElements+1); + rodAssembler.getNeighborsPerVertex(indices); + indices.exportIdx(hessianMatrix); + rhs.resize(rodFuncSpace[maxlevel]->size()); x.resize(rodFuncSpace[maxlevel]->size()); @@ -136,21 +136,32 @@ int main (int argc, char *argv[]) try x[i][2] = M_PI/2; } - x[0][1] = x[numRodElements][1] = 1; + x[0][0] = x[numRodElements][0] = 0; + x[0][1] = x[numRodElements][1] = 0; - RodAssembler<RodFuncSpaceType,2> test(*rodFuncSpace[0]); - test.assembleGradient(x, rhs); - //std::cout << "Solution: " << std::endl << x << std::endl; - //std::cout << "Gradient: " << std::endl << rhs << std::endl; - std::cout << "Energy: " << test.computeEnergy(x) << std::endl; + x[0][2] = 0; + x[numRodElements][2] = 2*M_PI; - MatrixIndexSet indices(numRodElements+1, numRodElements+1); - test.getNeighborsPerVertex(indices); - indices.exportIdx(hessianMatrix); - test.assembleMatrix(x,hessianMatrix); + // ////////////////////////////////////////////////////////// + // Create obstacles + // ////////////////////////////////////////////////////////// + + Array<BitField> hasObstacle; + hasObstacle.resize(maxLevel+1); + for (int i=0; i<hasObstacle.size(); i++) { + hasObstacle[i].resize(rod.size(i, 1)); + hasObstacle[i].setAll(); + } + + Array<SimpleVector<BoxConstraint<3> > > obstacles(maxlevel+1); + + for (int i=0; i<obstacles.size(); i++) + obstacles[i].resize(rod.size(i,1)); - //printmatrix(std::cout, hessianMatrix, "hessianMatrix", "--"); - //exit(0); + for (int i=0; i<obstacles[maxlevel].size(); i++) { + obstacles[maxlevel][i].clear(); + obstacles[maxlevel][i].val[1] = 0.1 - x[i][0]; + } // Create a solver #if defined IPOPT @@ -169,62 +180,56 @@ int main (int argc, char *argv[]) try SmootherType projectedBlockGSStep(hessianMatrix, corr, rhs); projectedBlockGSStep.dirichletNodes_ = &dirichletNodes[maxlevel]; projectedBlockGSStep.hasObstacle_ = &hasObstacle[maxlevel]; - projectedBlockGSStep.obstacles_ = NULL;//&contactAssembler.obstacles_[maxlevel]; + projectedBlockGSStep.obstacles_ = &obstacles; EnergyNorm<MatrixType, VectorType> energyNorm(projectedBlockGSStep); IterativeSolver<MatrixType, VectorType> solver; solver.iterationStep = &projectedBlockGSStep; solver.numIt = numIt; - solver.verbosity_ = Solver::QUIET; + solver.verbosity_ = Solver::FULL; solver.errorNorm_ = &energyNorm; solver.tolerance_ = tolerance; #elif defined MULTIGRID - // First create a base solver -#ifdef IPOPT_BASE - - LinearIPOptSolver<BlockVector<FieldVector<double,dim> > > baseSolver; - baseSolver.verbosity_ = Solver::FULL; + // First create a gauss-seidel base solver + ProjectedBlockGSStep<MatrixType, VectorType> baseSolverStep; -#else // Gauss-Seidel is the base solver + EnergyNorm<MatrixType, VectorType> baseEnergyNorm(baseSolverStep); - ProjectedBlockGSStep<MatrixType, BlockVector<FieldVector<double,dim> > > baseSolverStep; - - EnergyNorm<MatrixType, BlockVector<FieldVector<double,dim> > > baseEnergyNorm(baseSolverStep); - - IterativeSolver<MatrixType, BlockVector<FieldVector<double,dim> > > baseSolver; + IterativeSolver<MatrixType, VectorType> baseSolver; baseSolver.iterationStep = &baseSolverStep; baseSolver.numIt = baseIt; baseSolver.verbosity_ = Solver::QUIET; baseSolver.errorNorm_ = &baseEnergyNorm; baseSolver.tolerance_ = baseTolerance; -#endif // Make pre and postsmoothers - ProjectedBlockGSStep<MatrixType, BlockVector<FieldVector<double,dim> > > presmoother; - ProjectedBlockGSStep<MatrixType, BlockVector<FieldVector<double,dim> > > postsmoother; - + ProjectedBlockGSStep<MatrixType, VectorType> presmoother; + ProjectedBlockGSStep<MatrixType, VectorType> postsmoother; - ContactMMGStep<MatrixType, BlockVector<FieldVector<double,dim> > , FuncSpaceType > contactMMGStep(maxlevel+1); + ContactMMGStep<MatrixType, VectorType, RodFuncSpaceType > contactMMGStep(maxlevel+1); - contactMMGStep.setMGType(1, nu1, nu2); - contactMMGStep.dirichletNodes_ = &totalDirichletNodes; + contactMMGStep.setMGType(mu, nu1, nu2); + contactMMGStep.dirichletNodes_ = &dirichletNodes; contactMMGStep.basesolver_ = &baseSolver; contactMMGStep.presmoother_ = &presmoother; contactMMGStep.postsmoother_ = &postsmoother; contactMMGStep.hasObstacle_ = &hasObstacle; - contactMMGStep.obstacles_ = &contactAssembler.obstacles_; + contactMMGStep.obstacles_ = &obstacles; // Create the transfer operators contactMMGStep.mgTransfer_.resize(maxlevel); - for (int i=0; i<contactMMGStep.mgTransfer_.size(); i++) - contactMMGStep.mgTransfer_[i] = NULL; + for (int i=0; i<contactMMGStep.mgTransfer_.size(); i++){ + TruncatedMGTransfer<VectorType>* newTransferOp = new TruncatedMGTransfer<VectorType>; + newTransferOp->setup(*rodFuncSpace[i], *rodFuncSpace[i+1]); + contactMMGStep.mgTransfer_[i] = newTransferOp; + } EnergyNorm<MatrixType, VectorType> energyNorm(contactMMGStep); - IterativeSolver<MatrixType, BlockVector<FieldVector<double,dim> > > solver; + IterativeSolver<MatrixType, VectorType> solver; solver.iterationStep = &contactMMGStep; solver.numIt = numIt; solver.verbosity_ = Solver::FULL; @@ -242,8 +247,6 @@ int main (int argc, char *argv[]) try do { - RodAssembler<RodFuncSpaceType, 1> rodAssembler(*rodFuncSpace[maxlevel]); - loadFactor += loadIncrement; std::cout << "####################################################" << std::endl; @@ -257,15 +260,20 @@ int main (int argc, char *argv[]) try for (int j=0; j<maxNewtonSteps; j++) { + std::cout << "----------------------------------------------------" << std::endl; + std::cout << " Newton Step Number: " << j << std::endl; + std::cout << "----------------------------------------------------" << std::endl; + rhs = 0; corr = 0; + //std::cout <<"Solution: " << x << std::endl; rodAssembler.assembleGradient(x, rhs); rodAssembler.assembleMatrix(x, hessianMatrix); rhs *= -1; - std::cout << "rhs: " << std::endl << rhs << std::endl; + //std::cout << "rhs: " << std::endl << rhs << std::endl; #ifndef IPOPT solver.iterationStep->setProblem(hessianMatrix, corr, rhs); @@ -285,10 +293,10 @@ int main (int argc, char *argv[]) try solver.solve(); #ifdef MULTIGRID - totalCorr = contactMMGStep.getSol(); + corr = contactMMGStep.getSol(); #endif - std::cout << "Correction: \n" << corr << std::endl; + //std::cout << "Correction: \n" << corr << std::endl; // line search printf("------ Line Search ---------\n"); @@ -317,17 +325,33 @@ int main (int argc, char *argv[]) try x.axpy(smallestFactor, corr); // Output result - std::cout << "Solution:" << std::endl << x << std::endl; + //std::cout << "Solution:" << std::endl << x << std::endl; - printf("infinity norm of the correction: %g\n", corr[0].infinity_norm()); - if (corr.infinity_norm() < 1e-8) + printf("infinity norm of the correction: %g\n", smallestFactor*corr.infinity_norm()); + if (smallestFactor*corr.infinity_norm() < 1e-8) break; + // Subtract correction from the current obstacle + for (int k=0; k<corr.size(); k++) { + FieldVector<double, blocksize> tmp = corr[k]; + tmp *= smallestFactor; + obstacles[maxlevel][k] -= tmp; + } + } } while (loadFactor < 1); + // Write result grid + writeRod(x, "rod.result"); + + // Write Lagrange multiplyers + std::ofstream lagrangeFile("lagrange"); + + VectorType lagrangeMultipliers; + rodAssembler.assembleGradient(x, lagrangeMultipliers); + lagrangeFile << lagrangeMultipliers << std::endl; } catch (Exception e) { -- GitLab