From 8a1b7f872602a1aced9fcc46f5fec55de880800e Mon Sep 17 00:00:00 2001 From: Oliver Sander <sander@igpm.rwth-aachen.de> Date: Wed, 15 Nov 2006 10:11:13 +0000 Subject: [PATCH] further steps towards a working implementation [[Imported from SVN: r1041]] --- dirneucoupling.cc | 186 ++++++++++++++++++++++++++++------------------ 1 file changed, 113 insertions(+), 73 deletions(-) diff --git a/dirneucoupling.cc b/dirneucoupling.cc index 8cb84786..399f627f 100644 --- a/dirneucoupling.cc +++ b/dirneucoupling.cc @@ -1,7 +1,5 @@ #include <config.h> -//#define HAVE_IPOPT - #include <dune/grid/onedgrid.hh> #include <dune/grid/uggrid.hh> @@ -15,26 +13,22 @@ #include <dune/common/bitfield.hh> #include <dune/common/configparser.hh> -#include "../contact/src/contactmmgstep.hh" +#include "../common/multigridstep.hh" #include "../solver/iterativesolver.hh" #include "../common/projectedblockgsstep.hh" -#include "../common/geomestimator.hh" #include "../common/readbitfield.hh" #include "../common/energynorm.hh" #include "../common/boundarypatch.hh" #include "../common/prolongboundarypatch.hh" +#include "../common/neumannassembler.hh" #include "src/quaternion.hh" -//#include "src/rodassembler.hh" +#include "src/rodassembler.hh" #include "src/configuration.hh" #include "src/averageinterface.hh" #include "src/rodsolver.hh" #include "src/rodwriter.hh" -// Number of degrees of freedom of a correction for a rod configuration -// 6 (x, y, z, v_1, v_2, v_3) for a spatial rod -const int blocksize = 6; - // Space dimension const int dim = 3; @@ -44,12 +38,9 @@ using std::string; int main (int argc, char *argv[]) try { // Some types that I need - typedef BCRSMatrix<FieldMatrix<double, dim, dim> > MatrixType; - typedef BlockVector<FieldVector<double, dim> > VectorType; - - //typedef BCRSMatrix<FieldMatrix<double, blocksize, blocksize> > RodMatrixType; - //typedef BlockVector<FieldVector<double, blocksize> > RodCorrectionType; - typedef std::vector<Configuration> RodSolutionType; + typedef BCRSMatrix<FieldMatrix<double, dim, dim> > MatrixType; + typedef BlockVector<FieldVector<double, dim> > VectorType; + typedef std::vector<Configuration> RodSolutionType; // parse data file ConfigParser parameterSet; @@ -60,13 +51,15 @@ int main (int argc, char *argv[]) try const int maxLevel = parameterSet.get("maxLevel", int(0)); const int maxDirichletNeumannSteps = parameterSet.get("maxDirichletNeumannSteps", int(0)); const int maxTrustRegionSteps = parameterSet.get("maxTrustRegionSteps", int(0)); - const int numIt = parameterSet.get("numIt", int(0)); + const int multigridIterations = parameterSet.get("numIt", int(0)); const int nu1 = parameterSet.get("nu1", int(0)); const int nu2 = parameterSet.get("nu2", int(0)); const int mu = parameterSet.get("mu", int(0)); - const int baseIt = parameterSet.get("baseIt", int(0)); - const double tolerance = parameterSet.get("tolerance", double(0)); + const int baseIterations = parameterSet.get("baseIt", int(0)); + const double mgTolerance = parameterSet.get("tolerance", double(0)); const double baseTolerance = parameterSet.get("baseTolerance", double(0)); + const int initialTrustRegionRadius = parameterSet.get("initialTrustRegionRadius", int(0)); + const double damping = parameterSet.get("damping", double(1)); // Problem settings std::string path = parameterSet.get("path", "xyz"); @@ -92,12 +85,7 @@ int main (int argc, char *argv[]) try AmiraMeshReader<GridType>::read(grid, path + objectName); - - //Array<SimpleVector<BoxConstraint<dim> > > trustRegionObstacles(1); - //Array<BitField> hasObstacle(1); - Array<BitField> dirichletNodes(1); - - double trustRegionRadius = 0.1; + std::vector<BitField> dirichletNodes(1); RodSolutionType rodX(rodGrid.size(0,1)); @@ -140,7 +128,7 @@ int main (int argc, char *argv[]) try dirichletValues[0].resize(grid.size(0, dim)); AmiraMeshReader<int>::readFunction(dirichletValues[0], path + dirichletValuesFile); - Array<BoundaryPatch<GridType> > dirichletBoundary; + std::vector<BoundaryPatch<GridType> > dirichletBoundary; dirichletBoundary.resize(maxLevel+1); dirichletBoundary[0].setup(grid, 0); readBoundaryPatch(dirichletBoundary[0], path + dirichletNodesFile); @@ -149,26 +137,23 @@ int main (int argc, char *argv[]) try dirichletNodes.resize(toplevel+1); for (int i=0; i<=toplevel; i++) { - dirichletNodes[i].resize( dim*grid.size(i,dim) + blocksize * rodGrid.size(i,1)); - dirichletNodes[i].unsetAll(); + dirichletNodes[i].resize( dim*grid.size(i,dim)); for (int j=0; j<grid.size(i,dim); j++) for (int k=0; k<dim; k++) dirichletNodes[i][j*dim+k] = dirichletBoundary[i].containsVertex(j); - for (int j=0; j<blocksize; j++) - dirichletNodes[i][dirichletNodes[i].size()-1-j] = true; - } - // //////////////////////////////////////////////////////////// - // Create solution and rhs vectors - // //////////////////////////////////////////////////////////// - - VectorType totalRhs, totalCorr; - totalRhs.resize(grid.size(toplevel,dim) + 2*rodGrid.size(toplevel,1)); - totalCorr.resize(grid.size(toplevel,dim) + 2*rodGrid.size(toplevel,1)); - + // ///////////////////////////////////////////////////// + // Determine the interface boundary + // ///////////////////////////////////////////////////// + std::vector<BoundaryPatch<GridType> > interfaceBoundary; + interfaceBoundary.resize(maxLevel+1); + interfaceBoundary[0].setup(grid, 0); + readBoundaryPatch(interfaceBoundary[0], path + interfaceNodesFile); + PatchProlongator<GridType>::prolong(interfaceBoundary); + // ////////////////////////////////////////// // Assemble 3d linear elasticity problem // ////////////////////////////////////////// @@ -177,8 +162,11 @@ int main (int argc, char *argv[]) try LeafP1OperatorAssembler<GridType,double,dim> hessian3d(grid); hessian3d.assemble(lstiff,u,f); + // //////////////////////////////////////////////////////////// + // Create solution and rhs vectors + // //////////////////////////////////////////////////////////// + VectorType x3d(grid.size(toplevel,dim)); - //VectorType corr3d(grid.size(toplevel,dim)); VectorType rhs3d(grid.size(toplevel,dim)); // No external forces @@ -191,59 +179,73 @@ int main (int argc, char *argv[]) try if (dirichletNodes[toplevel][i*dim+j]) x3d[i][j] = dirichletValues[toplevel][i][j]; + // /////////////////////////////////////////// + // Create a solver for the rod problem + // /////////////////////////////////////////// + RodAssembler<RodGridType> rodAssembler(rodGrid); + rodAssembler.setShapeAndMaterial(1, 1, 1, 2.5e5, 0.3); + + RodSolver<RodGridType> rodSolver; + rodSolver.setup(rodGrid, + &rodAssembler, + rodX, + maxTrustRegionSteps, + initialTrustRegionRadius, + multigridIterations, + mgTolerance, + mu, nu1, nu2, + baseIterations, + baseTolerance); + // //////////////////////////////// // Create a multigrid solver // //////////////////////////////// // First create a gauss-seidel base solver - ProjectedBlockGSStep<MatrixType, VectorType> baseSolverStep; + BlockGSStep<MatrixType, VectorType> baseSolverStep; EnergyNorm<MatrixType, VectorType> baseEnergyNorm(baseSolverStep); - IterativeSolver<MatrixType, VectorType> baseSolver; - baseSolver.iterationStep = &baseSolverStep; - baseSolver.numIt = baseIt; - baseSolver.verbosity_ = Solver::QUIET; - baseSolver.errorNorm_ = &baseEnergyNorm; - baseSolver.tolerance_ = baseTolerance; + IterativeSolver<MatrixType, VectorType> baseSolver(&baseSolverStep, + baseIterations, + baseTolerance, + &baseEnergyNorm, + Solver::QUIET); // Make pre and postsmoothers - ProjectedBlockGSStep<MatrixType, VectorType> presmoother, postsmoother; + BlockGSStep<MatrixType, VectorType> presmoother, postsmoother; - ContactMMGStep<MatrixType, VectorType> contactMMGStep(totalHessian, totalCorr, totalRhs, 1); + MultigridStep<MatrixType, VectorType> multigridStep(*hessian3d, x3d, rhs3d, 1); - contactMMGStep.setMGType(mu, nu1, nu2); - contactMMGStep.dirichletNodes_ = &dirichletNodes; - contactMMGStep.basesolver_ = &baseSolver; - contactMMGStep.presmoother_ = &presmoother; - contactMMGStep.postsmoother_ = &postsmoother; - contactMMGStep.hasObstacle_ = &hasObstacle; - contactMMGStep.obstacles_ = &trustRegionObstacles; - contactMMGStep.verbosity_ = Solver::QUIET; + multigridStep.setMGType(mu, nu1, nu2); + multigridStep.dirichletNodes_ = &dirichletNodes; + multigridStep.basesolver_ = &baseSolver; + multigridStep.presmoother_ = &presmoother; + multigridStep.postsmoother_ = &postsmoother; + multigridStep.verbosity_ = Solver::REDUCED; - EnergyNorm<MatrixType, VectorType> energyNorm(contactMMGStep); + EnergyNorm<MatrixType, VectorType> energyNorm(multigridStep); - IterativeSolver<MatrixType, VectorType> solver; - solver.iterationStep = &contactMMGStep; - solver.numIt = numIt; - solver.verbosity_ = Solver::FULL; - solver.errorNorm_ = &energyNorm; - solver.tolerance_ = tolerance; + IterativeSolver<MatrixType, VectorType> solver(&multigridStep, + multigridIterations, + mgTolerance, + &energyNorm, + Solver::FULL); // //////////////////////////////////// // Create the transfer operators // //////////////////////////////////// - for (int k=0; k<contactMMGStep.mgTransfer_.size(); k++) - delete(contactMMGStep.mgTransfer_[k]); + for (int k=0; k<multigridStep.mgTransfer_.size(); k++) + delete(multigridStep.mgTransfer_[k]); - contactMMGStep.mgTransfer_.resize(toplevel); + multigridStep.mgTransfer_.resize(toplevel); - for (int i=0; i<contactMMGStep.mgTransfer_.size(); i++){ + for (int i=0; i<multigridStep.mgTransfer_.size(); i++){ TruncatedMGTransfer<VectorType>* newTransferOp = new TruncatedMGTransfer<VectorType>; newTransferOp->setup(grid,i,i+1); - contactMMGStep.mgTransfer_[i] = newTransferOp; + multigridStep.mgTransfer_[i] = newTransferOp; } // ///////////////////////////////////////////////////// @@ -251,9 +253,8 @@ int main (int argc, char *argv[]) try // ///////////////////////////////////////////////////// // Init interface value - Configuration lambda; - lambda.r = 0; - lambda.q = Quaternion<double>::identity(); + Configuration referenceInterface = rodX[0]; + Configuration lambda = referenceInterface; for (int i=0; i<maxDirichletNeumannSteps; i++) { @@ -266,27 +267,63 @@ int main (int argc, char *argv[]) try // ////////////////////////////////////////////////// rodX[0] = lambda; - + rodSolver.setInitialSolution(rodX); rodSolver.solve(); + rodX = rodSolver.getSol(); + // /////////////////////////////////////////////////////////// // Extract Neumann values and transfer it to the 3d object // /////////////////////////////////////////////////////////// + FieldVector<double,dim> resultantForce = rodAssembler.getResultantForce(rodX); + std::cout << "resultant force: " << resultantForce << std::endl; +#if 0 + FieldVector<double,dim> resultantTorque = rodAssembler.getResultantTorque(grid, rodX); +#endif + VectorType neumannValues(grid.size(dim)); + neumannValues = 0; + for (int j=0; j<neumannValues.size(); j++) + if (interfaceBoundary[grid.maxLevel()].containsVertex(j)) + neumannValues[j] = resultantForce; + + rhs3d = 0; + assembleAndAddNeumannTerm<GridType, VectorType>(interfaceBoundary[grid.maxLevel()], + neumannValues, + rhs3d); // /////////////////////////////////////////////////////////// // Solve the Neumann problem for the 3d body // /////////////////////////////////////////////////////////// + multigridStep.setProblem(*hessian3d, x3d, rhs3d, grid.maxLevel()+1); + + solver.preprocess(); + multigridStep.preprocess(); + + solver.solve(); + + x3d = multigridStep.getSol(); // /////////////////////////////////////////////////////////// // Extract new interface position and orientation // /////////////////////////////////////////////////////////// + Configuration averageInterface; - computeAverageInterface(interface, x, averageInterface); +// x3d = 0; +// for (int i=0; i<x3d.size(); i++) +// x3d[i][2] = 1; + + computeAverageInterface(interfaceBoundary[toplevel], x3d, averageInterface); + + std::cout << "average interface: " << averageInterface << std::endl; // /////////////////////////////////////////////////////////// // Compute new damped interface value // /////////////////////////////////////////////////////////// + for (int j=0; j<dim; j++) + lambda.r[j] = (1-damping) * lambda.r[j] + damping * (referenceInterface.r[j] + averageInterface.r[j]); + lambda.q = averageInterface.q.mult(referenceInterface.q); + } // ////////////////////////////// @@ -296,6 +333,9 @@ int main (int argc, char *argv[]) try AmiraMeshWriter<GridType>::writeBlockVector(grid, x3d, "grid.sol"); writeRod(rodX, "rod3d.result"); + for (int i=0; i<rodX.size(); i++) + std::cout << rodX[i] << std::endl; + } catch (Exception e) { std::cout << e << std::endl; -- GitLab