From b1d7e14d627b7e74f96b898312f7bc9296bf8d5e Mon Sep 17 00:00:00 2001 From: Oliver Sander <sander@igpm.rwth-aachen.de> Date: Mon, 28 Nov 2005 12:49:46 +0000 Subject: [PATCH] solver now uses a trust-region [[Imported from SVN: r594]] --- staticrod.cc | 74 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 16 deletions(-) diff --git a/staticrod.cc b/staticrod.cc index 11e55b4c..c2d122dc 100644 --- a/staticrod.cc +++ b/staticrod.cc @@ -37,6 +37,37 @@ const int blocksize = 3; using namespace Dune; using std::string; +void setTrustRegionObstacles(double trustRegionRadius, + SimpleVector<BoxConstraint<blocksize> >& trustRegionObstacles, + const SimpleVector<BoxConstraint<blocksize> >& trueObstacles, + const BitField& dirichletNodes) +{ + //std::cout << "True obstacles\n" << trueObstacles << std::endl; + + for (int j=0; j<trustRegionObstacles.size(); j++) { + + for (int k=0; k<blocksize; k++) { + + if (dirichletNodes[j*blocksize+k]) + continue; + + trustRegionObstacles[j].val[2*k] = + (trueObstacles[j].val[2*k] < -1e10) + ? std::min(-trustRegionRadius, trueObstacles[j].val[2*k+1] - trustRegionRadius) + : trueObstacles[j].val[2*k]; + + trustRegionObstacles[j].val[2*k+1] = + (trueObstacles[j].val[2*k+1] > 1e10) + ? std::max(trustRegionRadius,trueObstacles[j].val[2*k] + trustRegionRadius) + : trueObstacles[j].val[2*k+1]; + + } + + } + + //std::cout << "TrustRegion obstacles\n" << trustRegionObstacles << std::endl; +} + int main (int argc, char *argv[]) try { // Some types that I need @@ -80,9 +111,7 @@ int main (int argc, char *argv[]) try dirichletNodes.resize(maxLevel+1); for (int i=0; i<=maxlevel; i++) { - dirichletNodes[i].resize( blocksize * rod.size(i,1) ); - - dirichletNodes[i].unsetAll(); + dirichletNodes[i].resize( blocksize * rod.size(i,1), false ); for (int j=0; j<blocksize; j++) { dirichletNodes[i][j] = true; @@ -154,15 +183,18 @@ int main (int argc, char *argv[]) try hasObstacle[i].setAll(); } - Array<SimpleVector<BoxConstraint<3> > > obstacles(maxlevel+1); + Array<SimpleVector<BoxConstraint<3> > > trueObstacles(maxlevel+1); + Array<SimpleVector<BoxConstraint<3> > > trustRegionObstacles(maxlevel+1); - for (int i=0; i<obstacles.size(); i++) - obstacles[i].resize(rod.size(i,1)); + for (int i=0; i<maxlevel+1; i++) { + trueObstacles[i].resize(rod.size(i,1)); + trustRegionObstacles[i].resize(rod.size(i,1)); + } - for (int i=0; i<obstacles[maxlevel].size(); i++) { - obstacles[maxlevel][i].clear(); - obstacles[maxlevel][i].val[0] = - x[i][0]; - obstacles[maxlevel][i].val[1] = 0.1 - x[i][0]; + for (int i=0; i<trueObstacles[maxlevel].size(); i++) { + trueObstacles[maxlevel][i].clear(); + //trueObstacles[maxlevel][i].val[0] = - x[i][0]; + trueObstacles[maxlevel][i].val[1] = 0.1 - x[i][0]; } // Create a solver @@ -182,7 +214,7 @@ int main (int argc, char *argv[]) try SmootherType projectedBlockGSStep(hessianMatrix, corr, rhs); projectedBlockGSStep.dirichletNodes_ = &dirichletNodes[maxlevel]; projectedBlockGSStep.hasObstacle_ = &hasObstacle[maxlevel]; - projectedBlockGSStep.obstacles_ = &obstacles; + projectedBlockGSStep.obstacles_ = &trueObstacles; EnergyNorm<MatrixType, VectorType> energyNorm(projectedBlockGSStep); @@ -219,7 +251,7 @@ int main (int argc, char *argv[]) try contactMMGStep.presmoother_ = &presmoother; contactMMGStep.postsmoother_ = &postsmoother; contactMMGStep.hasObstacle_ = &hasObstacle; - contactMMGStep.obstacles_ = &obstacles; + contactMMGStep.obstacles_ = &trustRegionObstacles; // Create the transfer operators contactMMGStep.mgTransfer_.resize(maxlevel); @@ -243,9 +275,10 @@ int main (int argc, char *argv[]) try #endif // /////////////////////////////////////////////////// - // Do a homotopy of the Dirichlet boundary data + // Do a homotopy of the material parameters // /////////////////////////////////////////////////// double loadFactor = 0; + double trustRegionRadius = 0.1; do { @@ -257,8 +290,8 @@ int main (int argc, char *argv[]) try std::cout << "####################################################" << std::endl; // The continuation variable determines the material parameters - double A1 = loadFactor * 1000; - double A3 = loadFactor * 1000; + double A1 = loadFactor * 10000; + double A3 = loadFactor * 10000; rodAssembler.setParameters(1, A1, A3); // ///////////////////////////////////////////////////// @@ -280,7 +313,15 @@ int main (int argc, char *argv[]) try rhs *= -1; + // Apply trust-region obstacles + setTrustRegionObstacles(trustRegionRadius, + trustRegionObstacles[maxlevel], + trueObstacles[maxlevel], + dirichletNodes[maxlevel]); + //std::cout << "rhs: " << std::endl << rhs << std::endl; + //std::cout << "Trust Region obstacles:" << std::endl; + //std::cout << (*contactMMGStep.obstacles_)[maxlevel] << std::endl; #ifndef IPOPT solver.iterationStep->setProblem(hessianMatrix, corr, rhs); @@ -342,7 +383,7 @@ int main (int argc, char *argv[]) try for (int k=0; k<corr.size(); k++) { FieldVector<double, blocksize> tmp = corr[k]; tmp *= smallestFactor; - obstacles[maxlevel][k] -= tmp; + trueObstacles[maxlevel][k] -= tmp; } } @@ -363,6 +404,7 @@ int main (int argc, char *argv[]) try + "_" + a3AsAscii.str() + ".result"; writeRod(x, solutionFilename); + //break; } while (loadFactor < 1); -- GitLab