Skip to content
Snippets Groups Projects
Commit 5c1ceace authored by Oliver Sander's avatar Oliver Sander Committed by sander
Browse files

use the monotone multigrid solver now

[[Imported from SVN: r481]]
parent 6da41f3c
No related branches found
No related tags found
No related merge requests found
...@@ -15,18 +15,19 @@ ...@@ -15,18 +15,19 @@
//#include "../common/linearipopt.hh" //#include "../common/linearipopt.hh"
#include "../common/projectedblockgsstep.hh" #include "../common/projectedblockgsstep.hh"
#include "../contact/src/contactmmgstep.hh"
#include <dune/solver/iterativesolver.hh> #include <dune/solver/iterativesolver.hh>
#include "../common/geomestimator.hh" #include "../common/geomestimator.hh"
#include "../common/energynorm.hh" #include "../common/energynorm.hh"
#include <dune/common/configparser.hh> #include <dune/common/configparser.hh>
#include "src/rodwriter.hh"
// Choose a solver // Choose a solver
//#define IPOPT //#define IPOPT
#define GAUSS_SEIDEL //#define GAUSS_SEIDEL
//#define MULTIGRID #define MULTIGRID
//#define IPOPT_BASE
// Number of degrees of freedom: // Number of degrees of freedom:
// 3 (x, y, theta) for a planar rod // 3 (x, y, theta) for a planar rod
...@@ -46,7 +47,6 @@ int main (int argc, char *argv[]) try ...@@ -46,7 +47,6 @@ int main (int argc, char *argv[]) try
parameterSet.parseFile("staticrod.parset"); parameterSet.parseFile("staticrod.parset");
// read solver settings // read solver settings
const int minLevel = parameterSet.get("minLevel", int(0));
const int maxLevel = parameterSet.get("maxLevel", int(0)); const int maxLevel = parameterSet.get("maxLevel", int(0));
double loadIncrement = parameterSet.get("loadIncrement", double(0)); double loadIncrement = parameterSet.get("loadIncrement", double(0));
const int maxNewtonSteps = parameterSet.get("maxNewtonSteps", int(0)); const int maxNewtonSteps = parameterSet.get("maxNewtonSteps", int(0));
...@@ -59,42 +59,35 @@ int main (int argc, char *argv[]) try ...@@ -59,42 +59,35 @@ int main (int argc, char *argv[]) try
const double baseTolerance = parameterSet.get("baseTolerance", double(0)); const double baseTolerance = parameterSet.get("baseTolerance", double(0));
// Problem settings // Problem settings
const int numRodElements = parameterSet.get("numRodElements", int(0)); const int numRodBaseElements = parameterSet.get("numRodBaseElements", int(0));
// /////////////////////////////////////// // ///////////////////////////////////////
// Create the two grids // Create the two grids
// /////////////////////////////////////// // ///////////////////////////////////////
typedef OneDGrid<1,1> RodGridType; typedef OneDGrid<1,1> RodGridType;
RodGridType rod(numRodElements, 0, 1); RodGridType rod(numRodBaseElements, 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;
// refine uniformly until minlevel // refine uniformly until maxLevel
for (int i=0; i<minLevel; i++) for (int i=0; i<maxLevel; i++)
rod.globalRefine(1); rod.globalRefine(1);
int maxlevel = rod.maxlevel(); 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; dirichletNodes[i].resize( blocksize * rod.size(i,1) );
hasObstacle.resize(maxLevel+1);
hasObstacle[0].resize(numRodElements+1);
hasObstacle[0].unsetAll();
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 // Create discrete function spaces
...@@ -122,6 +115,13 @@ int main (int argc, char *argv[]) try ...@@ -122,6 +115,13 @@ int main (int argc, char *argv[]) try
VectorType corr; VectorType corr;
MatrixType hessianMatrix; 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()); rhs.resize(rodFuncSpace[maxlevel]->size());
x.resize(rodFuncSpace[maxlevel]->size()); x.resize(rodFuncSpace[maxlevel]->size());
...@@ -136,21 +136,32 @@ int main (int argc, char *argv[]) try ...@@ -136,21 +136,32 @@ int main (int argc, char *argv[]) try
x[i][2] = M_PI/2; 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]); x[0][2] = 0;
test.assembleGradient(x, rhs); x[numRodElements][2] = 2*M_PI;
//std::cout << "Solution: " << std::endl << x << std::endl;
//std::cout << "Gradient: " << std::endl << rhs << std::endl;
std::cout << "Energy: " << test.computeEnergy(x) << std::endl;
MatrixIndexSet indices(numRodElements+1, numRodElements+1); // //////////////////////////////////////////////////////////
test.getNeighborsPerVertex(indices); // Create obstacles
indices.exportIdx(hessianMatrix); // //////////////////////////////////////////////////////////
test.assembleMatrix(x,hessianMatrix);
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", "--"); for (int i=0; i<obstacles[maxlevel].size(); i++) {
//exit(0); obstacles[maxlevel][i].clear();
obstacles[maxlevel][i].val[1] = 0.1 - x[i][0];
}
// Create a solver // Create a solver
#if defined IPOPT #if defined IPOPT
...@@ -169,62 +180,56 @@ int main (int argc, char *argv[]) try ...@@ -169,62 +180,56 @@ int main (int argc, char *argv[]) try
SmootherType projectedBlockGSStep(hessianMatrix, corr, rhs); SmootherType projectedBlockGSStep(hessianMatrix, corr, rhs);
projectedBlockGSStep.dirichletNodes_ = &dirichletNodes[maxlevel]; projectedBlockGSStep.dirichletNodes_ = &dirichletNodes[maxlevel];
projectedBlockGSStep.hasObstacle_ = &hasObstacle[maxlevel]; projectedBlockGSStep.hasObstacle_ = &hasObstacle[maxlevel];
projectedBlockGSStep.obstacles_ = NULL;//&contactAssembler.obstacles_[maxlevel]; projectedBlockGSStep.obstacles_ = &obstacles;
EnergyNorm<MatrixType, VectorType> energyNorm(projectedBlockGSStep); EnergyNorm<MatrixType, VectorType> energyNorm(projectedBlockGSStep);
IterativeSolver<MatrixType, VectorType> solver; IterativeSolver<MatrixType, VectorType> solver;
solver.iterationStep = &projectedBlockGSStep; solver.iterationStep = &projectedBlockGSStep;
solver.numIt = numIt; solver.numIt = numIt;
solver.verbosity_ = Solver::QUIET; solver.verbosity_ = Solver::FULL;
solver.errorNorm_ = &energyNorm; solver.errorNorm_ = &energyNorm;
solver.tolerance_ = tolerance; solver.tolerance_ = tolerance;
#elif defined MULTIGRID #elif defined MULTIGRID
// First create a base solver // First create a gauss-seidel base solver
#ifdef IPOPT_BASE ProjectedBlockGSStep<MatrixType, VectorType> baseSolverStep;
LinearIPOptSolver<BlockVector<FieldVector<double,dim> > > baseSolver;
baseSolver.verbosity_ = Solver::FULL;
#else // Gauss-Seidel is the base solver EnergyNorm<MatrixType, VectorType> baseEnergyNorm(baseSolverStep);
ProjectedBlockGSStep<MatrixType, BlockVector<FieldVector<double,dim> > > baseSolverStep; IterativeSolver<MatrixType, VectorType> baseSolver;
EnergyNorm<MatrixType, BlockVector<FieldVector<double,dim> > > baseEnergyNorm(baseSolverStep);
IterativeSolver<MatrixType, BlockVector<FieldVector<double,dim> > > baseSolver;
baseSolver.iterationStep = &baseSolverStep; baseSolver.iterationStep = &baseSolverStep;
baseSolver.numIt = baseIt; baseSolver.numIt = baseIt;
baseSolver.verbosity_ = Solver::QUIET; baseSolver.verbosity_ = Solver::QUIET;
baseSolver.errorNorm_ = &baseEnergyNorm; baseSolver.errorNorm_ = &baseEnergyNorm;
baseSolver.tolerance_ = baseTolerance; baseSolver.tolerance_ = baseTolerance;
#endif
// Make pre and postsmoothers // Make pre and postsmoothers
ProjectedBlockGSStep<MatrixType, BlockVector<FieldVector<double,dim> > > presmoother; ProjectedBlockGSStep<MatrixType, VectorType> presmoother;
ProjectedBlockGSStep<MatrixType, BlockVector<FieldVector<double,dim> > > postsmoother; 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.setMGType(mu, nu1, nu2);
contactMMGStep.dirichletNodes_ = &totalDirichletNodes; contactMMGStep.dirichletNodes_ = &dirichletNodes;
contactMMGStep.basesolver_ = &baseSolver; contactMMGStep.basesolver_ = &baseSolver;
contactMMGStep.presmoother_ = &presmoother; contactMMGStep.presmoother_ = &presmoother;
contactMMGStep.postsmoother_ = &postsmoother; contactMMGStep.postsmoother_ = &postsmoother;
contactMMGStep.hasObstacle_ = &hasObstacle; contactMMGStep.hasObstacle_ = &hasObstacle;
contactMMGStep.obstacles_ = &contactAssembler.obstacles_; contactMMGStep.obstacles_ = &obstacles;
// Create the transfer operators // Create the transfer operators
contactMMGStep.mgTransfer_.resize(maxlevel); contactMMGStep.mgTransfer_.resize(maxlevel);
for (int i=0; i<contactMMGStep.mgTransfer_.size(); i++) for (int i=0; i<contactMMGStep.mgTransfer_.size(); i++){
contactMMGStep.mgTransfer_[i] = NULL; TruncatedMGTransfer<VectorType>* newTransferOp = new TruncatedMGTransfer<VectorType>;
newTransferOp->setup(*rodFuncSpace[i], *rodFuncSpace[i+1]);
contactMMGStep.mgTransfer_[i] = newTransferOp;
}
EnergyNorm<MatrixType, VectorType> energyNorm(contactMMGStep); EnergyNorm<MatrixType, VectorType> energyNorm(contactMMGStep);
IterativeSolver<MatrixType, BlockVector<FieldVector<double,dim> > > solver; IterativeSolver<MatrixType, VectorType> solver;
solver.iterationStep = &contactMMGStep; solver.iterationStep = &contactMMGStep;
solver.numIt = numIt; solver.numIt = numIt;
solver.verbosity_ = Solver::FULL; solver.verbosity_ = Solver::FULL;
...@@ -242,8 +247,6 @@ int main (int argc, char *argv[]) try ...@@ -242,8 +247,6 @@ int main (int argc, char *argv[]) try
do { do {
RodAssembler<RodFuncSpaceType, 1> rodAssembler(*rodFuncSpace[maxlevel]);
loadFactor += loadIncrement; loadFactor += loadIncrement;
std::cout << "####################################################" << std::endl; std::cout << "####################################################" << std::endl;
...@@ -257,15 +260,20 @@ int main (int argc, char *argv[]) try ...@@ -257,15 +260,20 @@ int main (int argc, char *argv[]) try
for (int j=0; j<maxNewtonSteps; j++) { 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; rhs = 0;
corr = 0; corr = 0;
//std::cout <<"Solution: " << x << std::endl;
rodAssembler.assembleGradient(x, rhs); rodAssembler.assembleGradient(x, rhs);
rodAssembler.assembleMatrix(x, hessianMatrix); rodAssembler.assembleMatrix(x, hessianMatrix);
rhs *= -1; rhs *= -1;
std::cout << "rhs: " << std::endl << rhs << std::endl; //std::cout << "rhs: " << std::endl << rhs << std::endl;
#ifndef IPOPT #ifndef IPOPT
solver.iterationStep->setProblem(hessianMatrix, corr, rhs); solver.iterationStep->setProblem(hessianMatrix, corr, rhs);
...@@ -285,10 +293,10 @@ int main (int argc, char *argv[]) try ...@@ -285,10 +293,10 @@ int main (int argc, char *argv[]) try
solver.solve(); solver.solve();
#ifdef MULTIGRID #ifdef MULTIGRID
totalCorr = contactMMGStep.getSol(); corr = contactMMGStep.getSol();
#endif #endif
std::cout << "Correction: \n" << corr << std::endl; //std::cout << "Correction: \n" << corr << std::endl;
// line search // line search
printf("------ Line Search ---------\n"); printf("------ Line Search ---------\n");
...@@ -317,17 +325,33 @@ int main (int argc, char *argv[]) try ...@@ -317,17 +325,33 @@ int main (int argc, char *argv[]) try
x.axpy(smallestFactor, corr); x.axpy(smallestFactor, corr);
// Output result // 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()); printf("infinity norm of the correction: %g\n", smallestFactor*corr.infinity_norm());
if (corr.infinity_norm() < 1e-8) if (smallestFactor*corr.infinity_norm() < 1e-8)
break; 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); } 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) { } catch (Exception e) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment