Skip to content
Snippets Groups Projects
Select Git revision
  • releases/2.8
  • feature/autodiff
  • feature/hyperdual-vector-mode
  • master default protected
  • finite-strain-plasticity
  • patrizio-convexity-test
  • releases/2.6-1
  • releases/2.5-1
  • releases/2.4-1
  • releases/2.3-1
  • releases/2.2-1
  • releases/2.1-1
  • releases/2.0-1
  • subversion->git
14 results

linelast.cc

Blame
  • Forked from agnumpde / dune-elasticity
    414 commits behind the upstream repository.
    Jonathan Youett's avatar
    akbib authored and akbib@FU-BERLIN.DE committed
    [[Imported from SVN: r10709]]
    1c72dc25
    History
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    linelast.cc 10.83 KiB
    #include <config.h>
    
    #include <dune/common/bitsetvector.hh>
    #include <dune/common/parametertree.hh>
    #include <dune/common/parametertreeparser.hh>
    
    #include <dune/grid/uggrid.hh>
    #include <dune/grid/io/file/amirameshwriter.hh>
    #include <dune/grid/io/file/amirameshreader.hh>
    
    #include <dune/istl/io.hh>
    
    #include <dune/fufem/functiontools/gridfunctionadaptor.hh>
    #include <dune/fufem/functionspacebases/p1nodalbasis.hh>
    #include <dune/fufem/functionspacebases/p2nodalbasis.hh>
    #include <dune/fufem/assemblers/operatorassembler.hh>
    #include <dune/fufem/assemblers/localassemblers/stvenantkirchhoffassembler.hh>
    #include <dune/fufem/sampleonbitfield.hh>
    #include <dune/fufem/boundarypatchprolongator.hh>
    #include <dune/fufem/readbitfield.hh>
    #include <dune/fufem/estimators/fractionalmarking.hh>
    #include <dune/fufem/estimators/hierarchicalestimator.hh>
    
    #ifdef HAVE_IPOPT
    #include <dune/solvers/solvers/quadraticipopt.hh>
    #endif
    #include <dune/solvers/iterationsteps/blockgsstep.hh>
    #include <dune/solvers/iterationsteps/multigridstep.hh>
    #include <dune/solvers/transferoperators/compressedmultigridtransfer.hh>
    #include <dune/solvers/solvers/loopsolver.hh>
    
    #include <dune/solvers/norms/energynorm.hh>
    
    
    
    #define IPOPT_BASE
    
    // The grid dimension
    const int dim = 3;
    
    using namespace Dune;
    
    int main (int argc, char *argv[]) try
    {
        // Some types that I need
        typedef BCRSMatrix<FieldMatrix<double, dim, dim> > OperatorType;
        typedef BlockVector<FieldVector<double, dim> >     VectorType;
    
        // parse data file
        ParameterTree parameterSet;
        if (argc==2)
            ParameterTreeParser::readINITree(argv[1], parameterSet);
        else
            ParameterTreeParser::readINITree("linelast.parset", parameterSet);
    
        // read solver settings
        const int minLevel         = parameterSet.get<int>("minLevel");
        const int maxLevel         = parameterSet.get<int>("maxLevel");
        const int numIt            = parameterSet.get<int>("numIt");
        const int nu1              = parameterSet.get<int>("nu1");
        const int nu2              = parameterSet.get<int>("nu2");
        const int mu               = parameterSet.get<int>("mu");
        const int baseIt           = parameterSet.get<int>("baseIt");
        const double tolerance     = parameterSet.get<double>("tolerance");
        const double baseTolerance = parameterSet.get<double>("baseTolerance");
        const bool nestedIteration = parameterSet.get<int>("nestedIteration");
        const bool paramBoundaries = parameterSet.get<int>("paramBoundaries");
        
        const double threshold     = parameterSet.get<double>("threshold");
    
        // read problem settings
        std::string path                = parameterSet.get<std::string>("path");
        std::string gridFile            = parameterSet.get<std::string>("gridFile");
        std::string parFile             = parameterSet.get("parFile", "");
        std::string dirichletFile       = parameterSet.get<std::string>("dirichletFile");
        std::string dirichletValuesFile = parameterSet.get<std::string>("dirichletValuesFile");
    
        // /////////////////////////////
        //   Generate the grid
        // /////////////////////////////
        typedef UGGrid<dim> GridType;
        typedef BoundaryPatch<GridType::LevelGridView> LevelBoundaryPatch;    
        typedef BoundaryPatch<GridType::LeafGridView> LeafBoundaryPatch;    
    
        GridType grid;    
        grid.setRefinementType(GridType::COPY);
    
        if (paramBoundaries) 
            Dune::AmiraMeshReader<GridType>::read(grid, path + gridFile, path + parFile);
        else
            Dune::AmiraMeshReader<GridType>::read(grid, path + gridFile);
        
        // Read Dirichlet boundary values
        std::vector<BitSetVector<dim> >  dirichletNodes(maxLevel+1);
    
        std::vector<LevelBoundaryPatch> dirichletBoundary(maxLevel+1);
        dirichletBoundary[0].setup(grid.levelView(0));
        readBoundaryPatch<GridType>(dirichletBoundary[0], path + dirichletFile);
    
        std::vector<VectorType> dirichletValues(maxLevel+1);
        dirichletValues[0].resize(grid.size(0, dim));
        AmiraMeshReader<GridType>::readFunction(dirichletValues[0], path + dirichletValuesFile);
    
        for (int i=0; i<minLevel; i++)
            grid.globalRefine(1);
    
        //int maxlevel = grid.maxLevel();
    
        // initial solution
        VectorType x(grid.size(grid.maxLevel(), dim));
        x = 0;
    
        // //////////////////////////////////////////////////
        //   Refinement loop
        // //////////////////////////////////////////////////
    
        while (true) {
    
            // Determine Dirichlet dofs
            BoundaryPatchProlongator<GridType>::prolong(dirichletBoundary);
            LeafBoundaryPatch leafDirichletBoundary(grid.leafView());
            BoundaryPatchProlongator<GridType>::prolong(dirichletBoundary[0], leafDirichletBoundary);
            
            for (int i=0; i<=grid.maxLevel(); i++) {
                
                dirichletNodes[i].resize(grid.size(i,dim));
                for (int j=0; j<grid.size(i,dim); j++)
                    dirichletNodes[i][j] = dirichletBoundary[i].containsVertex(j);
                
            }
            
            sampleOnBitField(grid, dirichletValues, dirichletNodes);
    
            VectorType rhs(grid.size(grid.maxLevel(), dim));
            rhs = 0;
            
            for (int i=0; i<rhs.size(); i++)
                for (int j=0; j<dim; j++) {
                    if (dirichletNodes[grid.maxLevel()][i][j])
                        x[i][j] = dirichletValues[grid.maxLevel()][i][j];
                    
                }
            // Assemble elasticity problem#
            typedef P1NodalBasis<GridType::LeafGridView,double> P1Basis;
            P1Basis p1NodalBasis(grid.leafView());
            OperatorAssembler<P1Basis,P1Basis> p1Assembler(p1NodalBasis, p1NodalBasis);
                    
            StVenantKirchhoffAssembler<GridType, P1Basis::LocalFiniteElement, P1Basis::LocalFiniteElement> p1LocalAssembler(2.5e5, 0.3);
            OperatorType stiffnessMatrix;
                    
            p1Assembler.assemble(p1LocalAssembler, stiffnessMatrix);
            
            
            
            // ///////////////////////////
            //   Create a solver
            // ///////////////////////////
            
            // First create a base solver
    #ifdef IPOPT_BASE
    #if !defined HAVE_IPOPT
    #error You need to have IPOpt installed if you want to use it as the base solver!
    #endif
            QuadraticIPOptSolver<OperatorType,VectorType> baseSolver;
            baseSolver.tolerance_ = baseTolerance;
            baseSolver.verbosity_ = Solver::QUIET;
            
    #else // Gauss-Seidel is the base solver
            
            BlockGSStep<OperatorType, VectorType> baseSolverStep;
    
            EnergyNorm<OperatorType,VectorType> baseEnergyNorm(baseSolverStep);
    
            IterativeSolver<VectorType> baseSolver(&baseSolverStep,
                                                   baseIt,
                                                   baseTolerance,
                                                   &baseEnergyNorm,
                                                   Solver::QUIET);
    #endif
            
            // Make pre and postsmoothers
            BlockGSStep<OperatorType, VectorType> presmoother;
            BlockGSStep<OperatorType, VectorType> postsmoother;
            
            
            MultigridStep<OperatorType, VectorType> multigridStep(stiffnessMatrix, x, rhs, grid.maxLevel()+1);
            
            multigridStep.setMGType(1, nu1, nu2);
            multigridStep.ignoreNodes_    = &dirichletNodes.back();
            multigridStep.basesolver_     = &baseSolver;
            multigridStep.setSmoother(&presmoother,&postsmoother);    
            
            multigridStep.mgTransfer_.resize(grid.maxLevel());
            for (int i=0; i<multigridStep.mgTransfer_.size(); i++) {
                CompressedMultigridTransfer<VectorType>* newTransferOp = new CompressedMultigridTransfer<VectorType>;
                newTransferOp->setup(grid, i, i+1);
                multigridStep.mgTransfer_[i] = newTransferOp;
            }
            
            EnergyNorm<OperatorType, VectorType> energyNorm(multigridStep);
            
            LoopSolver<VectorType> solver(&multigridStep,
                                          numIt,
                                          tolerance,
                                          &energyNorm,
                                          Solver::FULL);
            
            
            
            solver.preprocess();
            multigridStep.preprocess();
            
            // Compute solution
            solver.solve();
            
            x = multigridStep.getSol();
            
            // ////////////////////////////////////////////////////////////////////////
            //    Leave adaptation loop if maximum number of levels has been reached
            // ////////////////////////////////////////////////////////////////////////
        
            if (grid.maxLevel() == maxLevel)
                break;
    
            // /////////////////////////////////////////////////////////////
            //   Estimate error and refine grid
            // /////////////////////////////////////////////////////////////
                   
            HierarchicalEstimator<P2NodalBasis<GridType::LeafGridView>,dim> estimator(grid);
            VectorType hierarchicError;
            
            VirtualFunction<FieldVector<double,dim>,FieldVector<double,dim> >* volumeTermDummy=NULL;
            VirtualFunction<FieldVector<double,dim>,FieldVector<double,dim> >* neumannTermDummy=NULL;
            
            RefinementIndicator<GridType> indicator(grid);
            
            typedef P2NodalBasis<GridType::LeafGridView>::LocalFiniteElement P2FiniteElement;
            StVenantKirchhoffAssembler<GridType,P2FiniteElement,P2FiniteElement>* localStiffness = new StVenantKirchhoffAssembler<GridType,P2FiniteElement,P2FiniteElement>(2.5e5,0.3);
            
            
            estimator.estimate(x, 
            				   volumeTermDummy,
            				   neumannTermDummy,        		
            				   leafDirichletBoundary,
            				   indicator,
            				   localStiffness);
            
            //estimator.markForRefinement(grid, hierarchicError, threshold);
            FractionalMarkingStrategy<GridType>::mark(indicator, grid, 0.2);
            // ////////////////////////////////////////////////////
            //   Refine grid
            // ////////////////////////////////////////////////////
            
            GridFunctionAdaptor<P1Basis> adaptorP1(p1NodalBasis,true,true);
    
            grid.preAdapt();
            grid.adapt();
            grid.postAdapt();
            
            p1NodalBasis.update();
            adaptorP1.adapt(x);
    //   if (paramBoundaries)
    //       improveGrid(grid,10);
    
            std::cout << "########################################################" << std::endl;
            std::cout << "  Grid refined" << std::endl;
            std::cout << "  Level: " << grid.maxLevel()
                      << "   vertices: " << grid.size(grid.maxLevel(), dim) 
                      << "   elements: " << grid.size(grid.maxLevel(), 0) << std::endl;
            std::cout << "########################################################" << std::endl;
    
        }
    
      //std::cout << "Hierarchic Error: " << std::endl << hierarchicError << std::endl;
      // Output result
      LeafAmiraMeshWriter<GridType> amiramesh;
      amiramesh.addLeafGrid(grid,true);
      amiramesh.addVertexData(x, grid.leafView());
      amiramesh.write("resultGrid");
    
     } catch (Exception e) {
    
        std::cout << e << std::endl;
    
     }