From 0b134b48c82845a18c51eb4dc892448edf30fa82 Mon Sep 17 00:00:00 2001 From: bangerth Date: Mon, 22 Jul 2013 21:34:41 +0000 Subject: [PATCH] Remove unfinished tutorial programs. git-svn-id: https://svn.dealii.org/branches/releases/Branch-8-0@30114 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/examples/step-26/CMakeLists.txt | 31 - deal.II/examples/step-26/doc/builds-on | 1 - deal.II/examples/step-26/doc/intro.dox | 115 - deal.II/examples/step-26/doc/kind | 1 - deal.II/examples/step-26/doc/results.dox | 1 - deal.II/examples/step-26/doc/tooltip | 1 - deal.II/examples/step-26/step-26.cc | 525 - deal.II/examples/step-42/CMakeLists.txt | 53 - deal.II/examples/step-42/doc/builds-on | 1 - .../examples/step-42/doc/intro-step-42.tex | 405 - deal.II/examples/step-42/doc/intro.dox | 427 - deal.II/examples/step-42/doc/kind | 1 - deal.II/examples/step-42/doc/results.dox | 418 - .../step-42/doc/step-42-CellConstitution.png | Bin 52558 -> 0 bytes .../doc/step-42-CellConstitutionBall.png | Bin 52558 -> 0 bytes .../doc/step-42-CellConstitutionBall2.png | Bin 25917 -> 0 bytes .../doc/step-42-CellConstitutionColorbar.png | Bin 6614 -> 0 bytes .../doc/step-42-CellConstitutionLi2.png | Bin 48974 -> 0 bytes deal.II/examples/step-42/doc/tooltip | 1 - deal.II/examples/step-42/obstacle_file.pbm | 13602 ---------------- deal.II/examples/step-42/step-42.cc | 1642 -- deal.II/examples/step-47/CMakeLists.txt | 31 - deal.II/examples/step-47/doc/builds-on | 1 - deal.II/examples/step-47/doc/intro.dox | 3 - deal.II/examples/step-47/doc/kind | 1 - deal.II/examples/step-47/doc/points.dat | 21 - deal.II/examples/step-47/doc/results.dox | 1 - deal.II/examples/step-47/doc/tooltip | 1 - deal.II/examples/step-47/doc/vertices.dat | 20 - deal.II/examples/step-47/step-47.cc | 1137 -- deal.II/examples/step-50/CMakeLists.txt | 52 - deal.II/examples/step-50/doc/builds-on | 1 - deal.II/examples/step-50/doc/intro.dox | 90 - deal.II/examples/step-50/doc/kind | 1 - deal.II/examples/step-50/doc/results.dox | 98 - deal.II/examples/step-50/doc/tooltip | 1 - deal.II/examples/step-50/step-50.cc | 1075 -- 37 files changed, 19759 deletions(-) delete mode 100644 deal.II/examples/step-26/CMakeLists.txt delete mode 100644 deal.II/examples/step-26/doc/builds-on delete mode 100644 deal.II/examples/step-26/doc/intro.dox delete mode 100644 deal.II/examples/step-26/doc/kind delete mode 100644 deal.II/examples/step-26/doc/results.dox delete mode 100644 deal.II/examples/step-26/doc/tooltip delete mode 100644 deal.II/examples/step-26/step-26.cc delete mode 100644 deal.II/examples/step-42/CMakeLists.txt delete mode 100644 deal.II/examples/step-42/doc/builds-on delete mode 100644 deal.II/examples/step-42/doc/intro-step-42.tex delete mode 100644 deal.II/examples/step-42/doc/intro.dox delete mode 100644 deal.II/examples/step-42/doc/kind delete mode 100644 deal.II/examples/step-42/doc/results.dox delete mode 100644 deal.II/examples/step-42/doc/step-42-CellConstitution.png delete mode 100644 deal.II/examples/step-42/doc/step-42-CellConstitutionBall.png delete mode 100644 deal.II/examples/step-42/doc/step-42-CellConstitutionBall2.png delete mode 100644 deal.II/examples/step-42/doc/step-42-CellConstitutionColorbar.png delete mode 100644 deal.II/examples/step-42/doc/step-42-CellConstitutionLi2.png delete mode 100644 deal.II/examples/step-42/doc/tooltip delete mode 100644 deal.II/examples/step-42/obstacle_file.pbm delete mode 100644 deal.II/examples/step-42/step-42.cc delete mode 100644 deal.II/examples/step-47/CMakeLists.txt delete mode 100644 deal.II/examples/step-47/doc/builds-on delete mode 100644 deal.II/examples/step-47/doc/intro.dox delete mode 100644 deal.II/examples/step-47/doc/kind delete mode 100644 deal.II/examples/step-47/doc/points.dat delete mode 100644 deal.II/examples/step-47/doc/results.dox delete mode 100644 deal.II/examples/step-47/doc/tooltip delete mode 100644 deal.II/examples/step-47/doc/vertices.dat delete mode 100644 deal.II/examples/step-47/step-47.cc delete mode 100644 deal.II/examples/step-50/CMakeLists.txt delete mode 100644 deal.II/examples/step-50/doc/builds-on delete mode 100644 deal.II/examples/step-50/doc/intro.dox delete mode 100644 deal.II/examples/step-50/doc/kind delete mode 100644 deal.II/examples/step-50/doc/results.dox delete mode 100644 deal.II/examples/step-50/doc/tooltip delete mode 100644 deal.II/examples/step-50/step-50.cc diff --git a/deal.II/examples/step-26/CMakeLists.txt b/deal.II/examples/step-26/CMakeLists.txt deleted file mode 100644 index 9b68681f1e..0000000000 --- a/deal.II/examples/step-26/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -## -# CMake script for the step-26 tutorial program: -## - -# Set the name of the project and target: -SET(TARGET "step-26") - -# Declare all source files the target consists of: -SET(TARGET_SRC - ${TARGET}.cc - # You can specify additional files here! - ) - -# Usually, you will not need to modify anything beyond this point... - -CMAKE_MINIMUM_REQUIRED(VERSION 2.8.8) - -FIND_PACKAGE(deal.II 8.0 QUIET - HINTS ${deal.II_DIR} ${DEAL_II_DIR} ../ ../../ $ENV{DEAL_II_DIR} - ) -IF(NOT ${deal.II_FOUND}) - MESSAGE(FATAL_ERROR "\n" - "*** Could not locate deal.II. ***\n\n" - "You may want to either pass a flag -DDEAL_II_DIR=/path/to/deal.II to cmake\n" - "or set an environment variable \"DEAL_II_DIR\" that contains this path." - ) -ENDIF() - -DEAL_II_INITIALIZE_CACHED_VARIABLES() -PROJECT(${TARGET}) -DEAL_II_INVOKE_AUTOPILOT() diff --git a/deal.II/examples/step-26/doc/builds-on b/deal.II/examples/step-26/doc/builds-on deleted file mode 100644 index 48a0f73876..0000000000 --- a/deal.II/examples/step-26/doc/builds-on +++ /dev/null @@ -1 +0,0 @@ -step-4 diff --git a/deal.II/examples/step-26/doc/intro.dox b/deal.II/examples/step-26/doc/intro.dox deleted file mode 100644 index 51dcc23237..0000000000 --- a/deal.II/examples/step-26/doc/intro.dox +++ /dev/null @@ -1,115 +0,0 @@ - -

Introduction

- - -

Verifying whether the code is correct

- -There are a number of things one can typically get wrong when implementing a -finite element code. In particular, for time dependent problems, the following -are common sources of bugs: -- The time integration, for example by getting the coefficients in front of - the terms involving the current and previous time steps wrong (e.g., mixing - up a factor $\theta$ for $1-\theta$). -- Handling the right hand side, for example forgetting a factor of $k_n$ or - $\theta$. -- Mishandling the boundary values, again for example forgetting a factor of - $k_n$ or $\theta$, or forgetting to apply nonzero boundary values not only - to the right hand side but also to the system matrix. - -A less common problem is getting the initial conditions wrong because one can -typically see that it is wrong by just outputting the first time step. In any -case, in order to verify the correctness of the code, it is helpful to have a -testing protocol that allows us to verify each of these components -separately. This means: -- Testing the code with nonzero initial conditions but zero right hand side - and boundary values and verifying that the time evolution is correct. -- Then testing with zero initial conditions and boundary values but nonzero - right hand side and again ensuring correctness. -- Finally, testing with zero initial conditions and right hand side but - nonzero boundary values. - -This sounds complicated, but fortunately, for linear partial differential -equations without coefficients (or constant coefficients) like the one here, -there is a fairly standard protocol that rests on the following observation: -if you choose as your domain a square $[0,1]^2$ (or, with slight -modifications, a rectangle), then the exact solution can be written as -@f{align*} - u(x,y,t) = a(t) \sin(n_x \pi x) \sin(n_y \pi y) -@f} -(with integer constants $n_x,n_y$) -if only the initial condition, right hand side and boundary values are all -of the form $\sin(n_x \pi x) \sin(n_y \pi y)$ as well. This is due to the fact -that the function $\sin(n_x \pi x) \sin(n_y \pi y)$ is an eigenfunction of the -Laplace operator and allows us to compute things like the time factor $a(t)$ -analytically and, consequently, compare with what we get numerically. - -As an example, let us consider the situation where we have -$u_0(x,y)=\sin(n_x \pi x) \sin(n_x \pi y)$ and -$f(x,y,t)=0$. With the claim (ansatz) of the form for -$u(x,y,t)$ above, we get that -@f{align*} - \left(\frac{\partial}{\partial t} -\Delta\right) - u(x,y,t) - &= - \left(\frac{\partial}{\partial t} -\Delta\right) - a(t) \sin(n_x \pi x) \sin(n_y \pi y) - \\ - &= - \left(a'(t) + (n_x^2+n_y^2)\pi^2 a(t) \right) \sin(n_x \pi x) \sin(n_y \pi y). -@f} -For this to be equal to $f(x,y,t)=0$, we need that -@f{align*} - a'(t) + (n_x^2+n_y^2)\pi^2 a(t) = 0 -@f} -and due to the initial conditions, $a(0)=1$. This differential equation can be -integrated to yield -@f{align*} - a(t) = - e^{-(n_x^2+n_y^2)\pi^2 t}. -@f} -In other words, if the initial condition is a product of sines, then the -solution has exactly the same shape of a product of sines that decays to zero -with a known time dependence. This is something that is easy to test if you -have a sufficiently fine mesh and sufficiently small time step. - -What is typically going to happen if you get the time integration scheme wrong -(e.g., by having the wrong factors of $\theta$ or $k$ in front of the various -terms) is that you don't get the right temporal behavior of the -solution. Double check the various factors until you get the right -behavior. You may also want to verify that the temporal decay rate (as -determined, for example, by plotting the value of the solution at a fixed -point) does not double or halve each time you double or halve the time step or -mesh size. You know that it's not the handling of the -boundary conditions or right hand side because these were both zero. - -If you have so verified that the time integrator is correct, take the -situation where the right hand side is nonzero but the initial conditions are -zero: $u_0(x,y)=0$ and -$f(x,y,t)=\sin(n_x \pi x) \sin(n_x \pi y)$. Again, -@f{align*} - \left(\frac{\partial}{\partial t} -\Delta\right) - u(x,y,t) - &= - \left(\frac{\partial}{\partial t} -\Delta\right) - a(t) \sin(n_x \pi x) \sin(n_y \pi y) - \\ - &= - \left(a'(t) + (n_x^2+n_y^2)\pi^2 a(t) \right) \sin(n_x \pi x) \sin(n_y \pi y), -@f} -and for this to be equal to $f(x,y,t)$, we need that -@f{align*} - a'(t) + (n_x^2+n_y^2)\pi^2 a(t) = 1 -@f} -and due to the initial conditions, $a(0)=0$. Integrating this equation in time -yields -@f{align*} - a(t) = \frac{1}{(n_x^2+n_y^2)\pi^2} \left[ 1 - e^{-(n_x^2+n_y^2)\pi^2 t} \right]. -@f} - -Again, if you have the wrong factors of $\theta$ or $k$ in front of the right -hand side terms you will either not get the right temporal behavior of the -solution, or it will converge to a maximum value other than -$\frac{1}{(n_x^2+n_y^2)\pi^2}$. - -Once we have verified that the time integration and right hand side handling -are correct using this scheme, we can go on to verifying that we have the -boundary values correct, using a very similar approach. diff --git a/deal.II/examples/step-26/doc/kind b/deal.II/examples/step-26/doc/kind deleted file mode 100644 index c1d9154931..0000000000 --- a/deal.II/examples/step-26/doc/kind +++ /dev/null @@ -1 +0,0 @@ -techniques diff --git a/deal.II/examples/step-26/doc/results.dox b/deal.II/examples/step-26/doc/results.dox deleted file mode 100644 index f4c6feefb5..0000000000 --- a/deal.II/examples/step-26/doc/results.dox +++ /dev/null @@ -1 +0,0 @@ -

Results

diff --git a/deal.II/examples/step-26/doc/tooltip b/deal.II/examples/step-26/doc/tooltip deleted file mode 100644 index 7b3e8b447a..0000000000 --- a/deal.II/examples/step-26/doc/tooltip +++ /dev/null @@ -1 +0,0 @@ -Complicated boundary descriptions. diff --git a/deal.II/examples/step-26/step-26.cc b/deal.II/examples/step-26/step-26.cc deleted file mode 100644 index 23c2250e1e..0000000000 --- a/deal.II/examples/step-26/step-26.cc +++ /dev/null @@ -1,525 +0,0 @@ -// --------------------------------------------------------------------- -// $Id$ -// -// Copyright (C) 2013 by the deal.II authors -// -// This file is part of the deal.II library. -// -// The deal.II library is free software; you can use it, redistribute -// it, and/or modify it under the terms of the GNU Lesser General -// Public License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// The full text of the license can be found in the file LICENSE at -// the top level of the deal.II distribution. -// -// --------------------------------------------------------------------- - -/* - * Author: Wolfgang Bangerth, Texas A&M University, 2013 - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - - -namespace Step26 -{ - using namespace dealii; - - - - template - class HeatEquation - { - public: - HeatEquation(); - void run(); - - private: - void setup_system(); - void solve_time_step(); - void output_results() const; - void refine_mesh (const unsigned int min_grid_level, - const unsigned int max_grid_level); - - Triangulation triangulation; - FE_Q fe; - DoFHandler dof_handler; - - ConstraintMatrix constraints; - - SparsityPattern sparsity_pattern; - SparseMatrix mass_matrix; - SparseMatrix laplace_matrix; - SparseMatrix system_matrix; - - Vector solution; - Vector old_solution; - Vector system_rhs; - - double time; - double time_step; - unsigned int timestep_number; - - const double theta; - }; - - - - template - class RightHandSide: public Function - { - public: - RightHandSide() - : - Function(), - period (0.2) - {} - - virtual double value(const Point &p, - const unsigned int component = 0) const; - - private: - const double period; - }; - - - - template - double RightHandSide::value(const Point &p, - const unsigned int component) const - { - Assert (component == 0, ExcInternalError()); - Assert (dim == 2, ExcNotImplemented()); - - const double time = this->get_time(); - const double point_within_period = (time/period - std::floor(time/period)); - - if ((point_within_period >= 0.0) && (point_within_period <= 0.2)) - { - if ((p[0] > 0.5) && (p[1] > -0.5)) - return 1; - else - return 0; - } - else if ((point_within_period >= 0.5) && (point_within_period <= 0.7)) - { - if ((p[0] > -0.5) && (p[1] > 0.5)) - return 1; - else - return 0; - } - else - return 0; - } - - - - template - class BoundaryValues: public Function - { - public: - BoundaryValues() - : - Function() - { - } - - virtual double value(const Point &p, - const unsigned int component = 0) const; - }; - - template - double BoundaryValues::value(const Point &/*p*/, - const unsigned int component) const - { - Assert(component == 0, ExcInternalError()); - return 0; - } - - - - template - HeatEquation::HeatEquation() - : - fe(1), - dof_handler(triangulation), - time_step(1. / 500), - theta(0.5) - { - } - - - - template - void HeatEquation::setup_system() - { - dof_handler.distribute_dofs(fe); - - std::cout << std::endl - << "===========================================" - << std::endl - << "Number of active cells: " << triangulation.n_active_cells() - << std::endl - << "Number of degrees of freedom: " << dof_handler.n_dofs() - << std::endl - << std::endl; - - constraints.clear (); - DoFTools::make_hanging_node_constraints (dof_handler, - constraints); - constraints.close(); - - CompressedSparsityPattern c_sparsity(dof_handler.n_dofs()); - DoFTools::make_sparsity_pattern(dof_handler, - c_sparsity, - constraints, - /*keep_constrained_dofs = */ true); - sparsity_pattern.copy_from(c_sparsity); - - mass_matrix.reinit(sparsity_pattern); - laplace_matrix.reinit(sparsity_pattern); - system_matrix.reinit(sparsity_pattern); - - MatrixCreator::create_mass_matrix(dof_handler, - QGauss(fe.degree+1), - mass_matrix, - (const Function *)0, - constraints); - MatrixCreator::create_laplace_matrix(dof_handler, - QGauss(fe.degree+1), - laplace_matrix, - (const Function *)0, - constraints); - - solution.reinit(dof_handler.n_dofs()); - old_solution.reinit(dof_handler.n_dofs()); - system_rhs.reinit(dof_handler.n_dofs()); - } - - - - template - void HeatEquation::solve_time_step() - { - SolverControl solver_control(1000, 1e-8 * system_rhs.l2_norm()); - SolverCG<> cg(solver_control); - - PreconditionSSOR<> preconditioner; - preconditioner.initialize(system_matrix, 1.0); - - cg.solve(system_matrix, solution, system_rhs, preconditioner); - - constraints.distribute(solution); - - std::cout << " " << solver_control.last_step() - << " CG iterations." << std::endl; - } - - - - template - void HeatEquation::output_results() const - { - DataOut data_out; - - data_out.attach_dof_handler(dof_handler); - data_out.add_data_vector(solution, "U"); - - data_out.build_patches(); - - const std::string filename = "solution-" - + Utilities::int_to_string(timestep_number, 3) + - ".vtk"; - std::ofstream output(filename.c_str()); - data_out.write_vtk(output); - } - - - // @sect4{BoussinesqFlowProblem::refine_mesh} - // - // This function takes care of the adaptive mesh refinement. The three tasks - // this function performs is to first find out which cells to - // refine/coarsen, then to actually do the refinement and eventually - // transfer the solution vectors between the two different grids. The first - // task is simply achieved by using the well-established Kelly error - // estimator on the temperature (it is the temperature we're mainly - // interested in for this program, and we need to be accurate in regions of - // high temperature gradients, also to not have too much numerical - // diffusion). The second task is to actually do the remeshing. That - // involves only basic functions as well, such as the - // refine_and_coarsen_fixed_fraction that refines those cells - // with the largest estimated error that together make up 80 per cent of the - // error, and coarsens those cells with the smallest error that make up for - // a combined 10 per cent of the error. - // - // If implemented like this, we would get a program that will not make much - // progress: Remember that we expect temperature fields that are nearly - // discontinuous (the diffusivity $\kappa$ is very small after all) and - // consequently we can expect that a freely adapted mesh will refine further - // and further into the areas of large gradients. This decrease in mesh size - // will then be accompanied by a decrease in time step, requiring an - // exceedingly large number of time steps to solve to a given final time. It - // will also lead to meshes that are much better at resolving - // discontinuities after several mesh refinement cycles than in the - // beginning. - // - // In particular to prevent the decrease in time step size and the - // correspondingly large number of time steps, we limit the maximal - // refinement depth of the mesh. To this end, after the refinement indicator - // has been applied to the cells, we simply loop over all cells on the - // finest level and unselect them from refinement if they would result in - // too high a mesh level. - template - void HeatEquation::refine_mesh (const unsigned int min_grid_level, - const unsigned int max_grid_level) - { - Vector estimated_error_per_cell (triangulation.n_active_cells()); - - KellyErrorEstimator::estimate (dof_handler, - QGauss(fe.degree+1), - typename FunctionMap::type(), - solution, - estimated_error_per_cell); - - GridRefinement::refine_and_coarsen_fixed_fraction (triangulation, - estimated_error_per_cell, - 0.6, 0.4); - if (triangulation.n_levels() > max_grid_level) - for (typename Triangulation::active_cell_iterator - cell = triangulation.begin_active(max_grid_level); - cell != triangulation.end(); ++cell) - cell->clear_refine_flag (); - for (typename Triangulation::active_cell_iterator - cell = triangulation.begin_active(min_grid_level); - cell != triangulation.end_active(min_grid_level); ++cell) - cell->clear_coarsen_flag (); - - - // As part of mesh refinement we need to transfer the solution vectors - // from the old mesh to the new one. To this end we use the - // SolutionTransfer class and we have to prepare the solution vectors that - // should be transferred to the new grid (we will lose the old grid once - // we have done the refinement so the transfer has to happen concurrently - // with refinement). What we definetely need are the current and the old - // temperature (BDF-2 time stepping requires two old solutions). Since the - // SolutionTransfer objects only support to transfer one object per dof - // handler, we need to collect the two temperature solutions in one data - // structure. Moreover, we choose to transfer the Stokes solution, too, - // since we need the velocity at two previous time steps, of which only - // one is calculated on the fly. - // - // Consequently, we initialize two SolutionTransfer objects for the Stokes - // and temperature DoFHandler objects, by attaching them to the old dof - // handlers. With this at place, we can prepare the triangulation and the - // data vectors for refinement (in this order). - std::vector > x_solution (2); - x_solution[0] = solution; - x_solution[1] = old_solution; - - SolutionTransfer solution_trans(dof_handler); - - triangulation.prepare_coarsening_and_refinement(); - solution_trans.prepare_for_coarsening_and_refinement(x_solution); - - // Now everything is ready, so do the refinement and recreate the dof - // structure on the new grid, and initialize the matrix structures and the - // new vectors in the setup_dofs function. Next, we actually - // perform the interpolation of the solutions between the grids. We create - // another copy of temporary vectors for temperature (now corresponding to - // the new grid), and let the interpolate function do the job. Then, the - // resulting array of vectors is written into the respective vector member - // variables. For the Stokes vector, everything is just the same – - // except that we do not need another temporary vector since we just - // interpolate a single vector. In the end, we have to tell the program - // that the matrices and preconditioners need to be regenerated, since the - // mesh has changed. - triangulation.execute_coarsening_and_refinement (); - setup_system (); - - std::vector > tmp (2); - tmp[0].reinit (solution); - tmp[1].reinit (solution); - solution_trans.interpolate(x_solution, tmp); - - solution = tmp[0]; - old_solution = tmp[1]; - } - - - - template - void HeatEquation::run() - { - const unsigned int initial_global_refinement = (dim == 2 ? 1 : 2); - const unsigned int n_adaptive_pre_refinement_steps = 1; - - GridGenerator::hyper_L (triangulation); - triangulation.refine_global (initial_global_refinement); - - setup_system(); - - unsigned int pre_refinement_step = 0; - - Vector tmp; - Vector forcing_terms; - -start_time_iteration: - - VectorTools::interpolate(dof_handler, - ZeroFunction(), - old_solution); - solution = old_solution; - - timestep_number = 0; - time = 0; - - output_results(); - - while (time <= 0.5) - { - time += time_step; - ++timestep_number; - - std::cout << "Time step " << timestep_number << " at t=" << time - << std::endl; - - tmp.reinit (solution.size()); - forcing_terms.reinit (solution.size()); - - mass_matrix.vmult(system_rhs, old_solution); - - laplace_matrix.vmult(tmp, old_solution); - system_rhs.add(-(1 - theta) * time_step, tmp); - - RightHandSide rhs_function; - rhs_function.set_time(time); - VectorTools::create_right_hand_side(dof_handler, - QGauss(fe.degree+1), - rhs_function, - tmp); - forcing_terms = tmp; - forcing_terms *= time_step * theta; - - rhs_function.set_time(time - time_step); - VectorTools::create_right_hand_side(dof_handler, - QGauss(fe.degree+1), - rhs_function, - tmp); - - forcing_terms.add(time_step * (1 - theta), tmp); - - system_rhs += forcing_terms; - - { - BoundaryValues boundary_values_function; - boundary_values_function.set_time(time); - - std::map boundary_values; - VectorTools::interpolate_boundary_values(dof_handler, - 0, - boundary_values_function, - boundary_values); - - system_matrix.copy_from(mass_matrix); - system_matrix.add(theta * time_step, laplace_matrix); - MatrixTools::apply_boundary_values(boundary_values, - system_matrix, - solution, - system_rhs); - } - - constraints.condense (system_rhs); - - solve_time_step(); - - output_results(); - - if ((timestep_number == 1) && - (pre_refinement_step < n_adaptive_pre_refinement_steps)) - { - refine_mesh (initial_global_refinement, - initial_global_refinement + n_adaptive_pre_refinement_steps); - ++pre_refinement_step; - - std::cout << std::endl; - - goto start_time_iteration; - } - else if ((timestep_number > 0) && (timestep_number % 5 == 0)) - refine_mesh (initial_global_refinement, - initial_global_refinement + n_adaptive_pre_refinement_steps); - - old_solution = solution; - } - } -} - -int main() -{ - try - { - using namespace dealii; - using namespace Step26; - - deallog.depth_console(0); - - HeatEquation<2> heat_equation_solver; - heat_equation_solver.run(); - - } - catch (std::exception &exc) - { - std::cerr << std::endl << std::endl - << "----------------------------------------------------" - << std::endl; - std::cerr << "Exception on processing: " << std::endl << exc.what() - << std::endl << "Aborting!" << std::endl - << "----------------------------------------------------" - << std::endl; - - return 1; - } - catch (...) - { - std::cerr << std::endl << std::endl - << "----------------------------------------------------" - << std::endl; - std::cerr << "Unknown exception!" << std::endl << "Aborting!" - << std::endl - << "----------------------------------------------------" - << std::endl; - return 1; - } - - return 0; -} diff --git a/deal.II/examples/step-42/CMakeLists.txt b/deal.II/examples/step-42/CMakeLists.txt deleted file mode 100644 index dc468213e4..0000000000 --- a/deal.II/examples/step-42/CMakeLists.txt +++ /dev/null @@ -1,53 +0,0 @@ -## -# CMake script for the step-42 tutorial program: -## - -# Set the name of the project and target: -SET(TARGET "step-42") - -# Declare all source files the target consists of: -SET(TARGET_SRC - ${TARGET}.cc - # You can specify additional files here! - ) - -# A custom command line to run the program -SET(TARGET_RUN mpirun -np 2 ${TARGET}) - -# Define the output that should be cleaned: -SET(CLEAN_UP_FILES *.vtu *.pvtu *.visit) - -# Usually, you will not need to modify anything beyond this point... - -CMAKE_MINIMUM_REQUIRED(VERSION 2.8.8) - -FIND_PACKAGE(deal.II 8.0 QUIET - HINTS ${deal.II_DIR} ${DEAL_II_DIR} ../ ../../ $ENV{DEAL_II_DIR} - ) -IF(NOT ${deal.II_FOUND}) - MESSAGE(FATAL_ERROR "\n" - "*** Could not locate deal.II. ***\n\n" - "You may want to either pass a flag -DDEAL_II_DIR=/path/to/deal.II to cmake\n" - "or set an environment variable \"DEAL_II_DIR\" that contains this path." - ) -ENDIF() - -# -# Are all dependencies fullfilled? -# -IF( NOT DEAL_II_WITH_MPI OR - NOT DEAL_II_WITH_P4EST OR - NOT DEAL_II_WITH_TRILINOS ) - MESSAGE(FATAL_ERROR " -Error! The deal.II library found at ${DEAL_II_PATH} was not configured with - DEAL_II_WITH_MPI = ON - DEAL_II_WITH_P4EST = ON - DEAL_II_WITH_TRILINOS = ON -which is required for this tutorial step." - ) -ENDIF() - -DEAL_II_INITIALIZE_CACHED_VARIABLES() -PROJECT(${TARGET}) - -DEAL_II_INVOKE_AUTOPILOT() diff --git a/deal.II/examples/step-42/doc/builds-on b/deal.II/examples/step-42/doc/builds-on deleted file mode 100644 index 8defe7dd9e..0000000000 --- a/deal.II/examples/step-42/doc/builds-on +++ /dev/null @@ -1 +0,0 @@ -step-41 step-40 diff --git a/deal.II/examples/step-42/doc/intro-step-42.tex b/deal.II/examples/step-42/doc/intro-step-42.tex deleted file mode 100644 index a6c6b1f752..0000000000 --- a/deal.II/examples/step-42/doc/intro-step-42.tex +++ /dev/null @@ -1,405 +0,0 @@ -\documentclass{article} - -\usepackage{amsmath} -\usepackage{amssymb} - -\title{Documentation of step-42, An obstacle problem for elasto-plastic material behavior in three dimensions} -\author{Joerg Frohne} -\date{Juni, 2012} - -\begin{document} - -\section{Introduction} - -This example is an extension of step-41, considering a contact problem with an -elasto-plastic material behavior with isotropic hardening in three dimensions. -That means that we have to take care of an additional nonlinearity: the -material behavior. Since we consider a three dimensional problem here, a -separate difference to step-41 is that the contact area is at the boundary of -the deformable body now, rather than in the interior. Finally, compared to -step-41, we also have to deal with -hanging nodes because of the adaptive mesh in both the handling of the linear -system as well as of the inequality constraints; in the latter case, we will -have to deal with prioritizing whether the constraints from the hanging nodes -or from the inequalities are more important. - -Since you can very easily reach a few million degrees of freedom in three -dimensions, even with adaptive mesh refinement, we decided to use Trilinos and -p4est to run our code in parallel, building on the framework of step-40 for -the parallelization.\\ - -\begin{huge} -{distributed} -\end{huge} - - -\section{Classical formulation} - -The classical formulation of the problem possesses the following form: -\begin{align*} - \varepsilon(u) &= A\sigma + \lambda & &\quad\text{in } \Omega,\\ - \lambda(\tau - \sigma) &\geq 0\quad\forall\tau\text{ with - }\mathcal{F}(\tau)\leq 0 & &\quad\text{in } \Omega,\\ - -\textrm{\textrm{div}}\ \sigma &= f & &\quad\text{in } \Omega,\\ - u(\mathbf x) &= 0 & &\quad\text{on }\Gamma_D,\\ - \sigma_t(u) &= 0,\quad\sigma_n(u)\leq 0 & &\quad\text{on }\Gamma_C,\\ -\sigma_n(u)(u_n - g) &= 0,\quad u_n(\mathbf x) - g(\mathbf x) \leq 0 & &\quad\text{on } \Gamma_C -\end{align*} -with $u\in H^2(\Omega),\Omega\subset\mathbb{R}^3$. The vector valued -function $u$ denotes the displacement in the deformable body. The first two lines describe the -elasto-plastic material behavior. Therein the equation shows the -strain of the deformation $\varepsilon (u)$ as the additive decomposition of the -elastic part $A\sigma$ and the plastic part $\lambda$. $A$ is defined as the -compliance tensor of fourth order which contains some material constants and -$\sigma$ as the symmetric stress tensor of second order. So we have to consider -the inequality in the second row in a pointwise sense where $\lambda(\tau - -\sigma)$ is the inner product of two symmetric tensors of second order. -Furthermore we have to distinguish two cases.\\ -The continuous and convex function $\mathcal{F}$ denotes the von Mises flow function -$$\mathcal{F}(\tau) = \vert\tau^D\vert - \sigma_0¸\quad\text{with}\quad \tau^D -= \tau - \dfrac{1}{3}tr(\tau)I,$$ -$\sigma_0$ as yield stress and $\vert .\vert$ as the frobenius norm. If there -are no plastic deformations in a particular point - that is $\lambda=0$ - this yields $\vert\sigma^D\vert < -\sigma_0$ and otherwise if $\lambda > 0$ it follows that $\vert\sigma^D\vert = \sigma_0$. -That means if the stress is smaller than the yield stress there are only elastic -deformations in that point.\\ -To consider it the other way around if the deviator stress $\sigma^D$ is in a -norm bigger than the yield stress then $\sigma^D$ has to be projected back to the yield surface and there are plastic deformations which means $\lambda$ -would be positiv for that particular point. We refer that the stresses are -computed by Hooke's law for isotorpic materials. You can find the description at the end of section 3. Else if the norm of the deviator stress tensor is smaller or equal the yield stress then $\lambda$ is zero and there are no plastic deformations in -that point.\\ -There the index $D$ denotes the deviator part of for example the stress where -$tr(.)$ is the trace of a tensor. The definition shows an additive decomposition -of the stress $\sigma$ into a hydrostatic part (or volumetric part) $\dfrac{1}{3}tr(\tau)I$ and the deviator -part $\sigma^D$. For metal the deviator stress composes the main indicator for -plastic deformations.\\ -The third equation is called equilibrium condition with a force of volume -density $f$ which we will neglect in our example. -The boundary of $\Omega$ separates as follows $\Gamma=\Gamma_D\bigcup\Gamma_C$ and $\Gamma_D\bigcap\Gamma_C=\emptyset$. -At the boundary $\Gamma_D$ we have zero Dirichlet conditions. $\Gamma_C$ denotes the potential contact boundary.\\ -The last two lines decribe the so-called Signorini contact conditions. If there is no contact the normal stress -$$ \sigma_n = \sigma n\cdot n$$ -is zero with the outward normal $n$. If there is contact ($u_n = g$) the tangential stress $\sigma_t = \sigma\cdot n - \sigma_n n$ -vanishes, because we consider a frictionless situation and the normal stress is -negative. The gap $g$ comes with the start configuration of the obstacle and the -deformable body. We refer that you have to ensure that the obstacle does not hit -the boundary of $\Gamma_C$ - -\section{Derivation of the variational inequality} - -As a starting point to derive the equations above, let us imagine that we want -to minimise an energy functional: -$$E(\tau) := \dfrac{1}{2}\int\limits_{\Omega}\tau A \tau d\tau,\quad \tau\in \Pi W^{\textrm{div}}$$ -with -$$W^{\textrm{div}}:=\lbrace \tau\in -L^2(\Omega,\mathbb{R}^{\textrm{dim}\times\textrm{dim}}_{\textrm{sym}}):\textrm{div}(\tau)\in L^2(\Omega,\mathbb{R}^{\textrm{dim}})\rbrace$$ and -$$\Pi \Sigma:=\lbrace \tau\in \Sigma, \mathcal{F}(\tau)\leq 0\rbrace$$ -as the set of admissible stresses which is defined -by a continious, convex flow function $\mathcal{F}$. - -With the goal of deriving the dual formulation of the minimisation -problem, we define a lagrange function: -$$L(\tau,\varphi) := E(\tau) + (\varphi, \textrm{div}(\tau)),\quad \lbrace\tau,\varphi\rbrace\in\Pi W^{\textrm{div}}\times V^+$$ -with -$$V^+ := \lbrace u\in V: u_n\leq g \text{ on } \Gamma_C \rbrace$$ -$$V:=\left[ H_0^1 \right]^{\textrm{dim}}:=\lbrace u\in \left[H^1(\Omega)\right]^{\textrm{dim}}: u -= 0 \text{ on } \Gamma_D\rbrace$$ -By building the Fr\'echet derivatives of $L$ for both components we obtain the -dual formulation for the stationary case which is known as \textbf{Hencky-Type-Model}:\\ -Find a pair $\lbrace\sigma,u\rbrace\in \Pi W\times V^+$ with -$$\left(A\sigma,\tau - \sigma\right) + \left(u, \textrm{div}(\tau) - \textrm{div}(\sigma)\right) \geq 0,\quad \forall \tau\in \Pi W^{\textrm{div}}$$ -$$-\left(\textrm{div}(\sigma),\varphi - u\right) \geq 0,\quad \forall \varphi\in V^+.$$ -By integrating by parts and multiplying the first inequality by the elastic -tensor $C=A^{-1}$ we achieve the primal-mixed version of our problem:\\ -Find a pair $\lbrace\sigma,u\rbrace\in \Pi W\times V^+$ with -$$\left(\sigma,\tau - \sigma\right) - \left(C\varepsilon(u), \tau - \sigma\right) \geq 0,\quad \forall \tau\in \Pi W$$ -$$\left(\sigma,\varepsilon(\varphi) - \varepsilon(u)\right) \geq 0,\quad \forall \varphi\in V^+.$$ -Therein $\varepsilon$ denotes the linearised deformation tensor with $\varepsilon(u) := \dfrac{1}{2}\left(\nabla u + \nabla u^T\right)$ for small deformations.\\ -Most materials - especially metals - have the property that they show some hardening effects during the forming process. -There are different constitutive laws to describe those material behaviors. The -simplest one is called linear isotropic hardening described by the flow function -$\mathcal{F}(\tau,\eta) = \vert\tau^D\vert - (\sigma_0 + \gamma^{\text{iso}}\eta)$ where -$\eta$ is the norm of the plastic strain $\eta = \vert \varepsilon - -A\sigma\vert$. -It can be considered by establishing an additional term in our primal-mixed formulation:\\ -Find a pair $\lbrace(\sigma,\xi),u\rbrace\in \Pi (W\times L^2(\Omega,\mathbb{R}))\times V^+$ with -$$\left(\sigma,\tau - \sigma\right) - \left(C\varepsilon(u), \tau - \sigma\right) + \gamma^{\text{iso}}\left( \xi, \eta - \xi\right) \geq 0,\quad \forall (\tau,\eta)\in \Pi (W,L^2(\Omega,\mathbb{R}))$$ -$$\left(\sigma,\varepsilon(\varphi) - \varepsilon(u)\right) \geq 0,\quad \forall \varphi\in V^+,$$ -with the hardening parameter $\gamma^{\text{iso}} > 0$.\\ -Now we want to derive a primal problem which only depends on the displacement $u$. For that purpose we -set $\eta = \xi$ and eliminate the stress $\sigma$ by applying the projection -theorem (see Grossmann, Roos: Numerical Treatment of Partial Differential -Equations, Springer-Verlag Berlin Heidelberg, 2007 and Frohne: FEM-Simulation -der Umformtechnik metallischer Oberflächen im Mikrokosmos, Ph.D. thesis, -University of Siegen, Germany, 2011) on\\ -$$\left(\sigma - C\varepsilon(u), \tau - \sigma\right) \geq 0,\quad \forall \tau\in \Pi W,$$ -which yields with the second inequality:\\ -Find the displacement $u\in V^+$ with -$$\left(P_{\Pi}(C\varepsilon(u)),\varepsilon(\varphi) - \varepsilon(u)\right) \geq 0,\quad \forall \varphi\in V^+,$$ -with the projection: -$$P_{\Pi}(\tau):=\begin{cases} - \tau, & \text{if }\vert\tau^D\vert \leq \sigma_0 + \gamma^{\text{iso}}\xi,\\ - \hat\alpha\dfrac{\tau^D}{\vert\tau^D\vert} + \dfrac{1}{3}tr(\tau), & \text{if }\vert\tau^D\vert > \sigma_0 + \gamma^{\text{iso}}\xi, - \end{cases}$$ -with the radius -$$\hat\alpha := \sigma_0 + \gamma^{\text{iso}}\xi .$$ -With the relation $\xi = \vert\varepsilon(u) - A\sigma\vert$ it is possible to eliminate $\xi$ inside the projection $P_{\Pi}$:\\ -$$P_{\Pi}(\tau):=\begin{cases} - \tau, & \text{if }\vert\tau^D\vert \leq \sigma_0,\\ - \alpha\dfrac{\tau^D}{\vert\tau^D\vert} + \dfrac{1}{3}tr(\tau), & \text{if }\vert\tau^D\vert > \sigma_0, - \end{cases}$$ -$$\alpha := \sigma_0 + \dfrac{\gamma^{\text{iso}}}{2\mu+\gamma^{\text{iso}}}\left(\vert\tau^D\vert - \sigma_0\right) ,$$ -with a further material parameter $\mu>0$ called shear modulus. We refer that -this only possible for isotropic plasticity.\\ -To make things a bit easier from now on we denote -$$\gamma := \dfrac{\gamma^{\text{iso}}}{2\mu + -\gamma^{\text{iso}}}\in[0,1)\text{ with }\gamma^{\text{iso}}\in[0,\infty),$$ -$$\beta :=\dfrac{\sigma_0}{\vert\tau^D\vert}.$$ If $\gamma^{\text{iso}}$ tends to zero $\gamma$ tends also to zero. And if $\gamma^{\text{iso}}$ tends to -infinity $\gamma$ tends to one. This allows us to reformulate our problem as -follows $$P_{\Pi}(\tau):=\begin{cases} - \tau, & \text{if }\vert\tau^D\vert \leq \sigma_0,\\ - \gamma\tau^D + (1-\gamma)\beta\tau^D - + \dfrac{1}{3}tr(\tau), & \text{if }\vert\tau^D\vert > - \sigma_0, \end{cases}.$$ -For further details see Suttmeier: On Plasticity with Hardening: -An Adaptive Finite Element Discretisation, International Mathematical Forum, 5, -2010, no. 52, 2591-2601.\\ -So what we do is to calculate the stresses -by using Hooke's law for linear elastic, isotropic materials $$\sigma = C \varepsilon(u) = 2\mu \varepsilon^D(u) + \kappa tr(\varepsilon(u))I = \left[2\mu\left(\mathbb{I} -\dfrac{1}{3} I\otimes I\right) + \kappa I\otimes I\right]\varepsilon(u)$$ -with the material parameter $\kappa>0$ (bulk modulus). The variables $I$ and -$\mathbb{I}$ denote the identity tensors of second and forth order. In that -notation $2\mu \varepsilon^D(u)$ is the deviatoric part and $\kappa -tr(\varepsilon(u))$ the volumetric part of the stress tensor.\\ -In the next step we test in a pointwise sense where the deviator part of the -stress in a norm is bigger than the yield stress. If there are such points we -project the deviator stress in those points back to the yield surface. Methods of this kind are called projections algorithm or radial-return-algorithm.\\ -Now we have a primal formulation of our elasto-plastic contact problem which only depends on the displacement $u$. -It consists of a nonlinear variational inequality and has a unique solution as -it satisfies the theorem of Lions and Stampaccia. A proof can be found in -Rodrigues: Obstacle Problems in Mathematical Physics, North-Holland, Amsterdam, -1987.\\ -To handle the nonlinearity of the constitutive law we use a Newton method and to deal with the contact we apply an -active set method like in step-41. To be more concrete we combine both methods to an inexact semi smooth Newton -method - inexact since we use an iterative solver for the linearised problems in each Newton step. - -\section{Linearization of the constitutive law for the Newton method} - -To apply Newton method we have to linearise the following semi-linearform -$$a(\psi;\varphi) := -\left(P_{\Pi}(C\varepsilon(\psi)),\varepsilon(\varphi)\right).$$ Because we have -to find the solution $u$ in the convex set $V^+$, we have to apply an SQP-method (SQP: sequential quadratic programming). That means we have -to solve a minimisation problem for a known $u^i$ in every SQP-step of the form -\begin{eqnarray*} - & & a(u^{i};u^{i+1} - u^i) + \dfrac{1}{2}a'(u^i;u^{i+1} - u^i,u^{i+1} - u^i)\\ - &=& a(u^i;u^{i+1}) - a(u^i;u^i) +\\ - & & \dfrac{1}{2}\left( a'(u^i;u^{i+1},u^{i+1}) - 2a'(u^i;u^i,u^{i+1}) - a'(u^i;u^i,u^i)\right)\\ - &\rightarrow& \textrm{min},\quad u^{i+1}\in V^+. -\end{eqnarray*} -Neglecting the constant terms $ a(u^i;u^i)$ and $ a'(u^i;u^i,u^i)$ we obtain the -following minimisation problem $$\dfrac{1}{2} a'(u^i;u^{i+1},u^{i+1}) - -F(u^{i+1})\rightarrow \textrm{min},\quad u^{i+1}\in V^+$$ with $$F(\varphi) := -\left(a'(u^{i};u^{i},\varphi) - a(u^{i},\varphi) \right).$$ -In the case of our constitutive law the Fr\'echet derivative of the -semi-linearform $a(.;.)$ at the point $u^i$ is - -$$a'(u^i;\psi,\varphi) = -(I(x)\varepsilon(\psi),\varepsilon(\varphi)),\quad x\in\Omega,$$ $$ -I(x) := \begin{cases} -C_{\mu} + C_{\kappa}, & -\quad \vert \tau^D \vert \leq \sigma_0\\ -\gamma C_{\mu} + (1-\gamma)\beta\left(C_{\mu} - -2\mu\dfrac{\tau^D\otimes\tau^D}{\vert\tau^D\vert^2}\right) + C_{\kappa}, &\quad -\vert \tau^D \vert > \sigma_0 -\end{cases} -$$ -with -$$C_{\mu} := 2\mu\left(\mathbb{I} - \dfrac{1}{3} I\otimes -I\right)\quad\text{(shear part of the stress strain tensor)},$$ -$$C_{\kappa} := \kappa I\otimes I\quad\text{(bulk part of the stress strain -tensor)},$$ -$$\tau^D := C\varepsilon^D(u^i).$$ -Remark that $a(.;.)$ is not differentiable in the common sense but it is -slantly differentiable like the function for the contact problem and again we refer to -Hintermueller, Ito, Kunisch: The primal-dual active set strategy as a semismooth newton method, SIAM J. OPTIM., 2003, Vol. 13, No. 3, pp. 865-888. -Again the first case is for elastic and the second for plastic deformation. - -\section{Formulation as a saddle point problem} - -Just as in step-41 we compose a saddle point problem out of the minimisation -problem. Again we do so to gain a formulation that allows us to solve a linear -system of equations finally.\\ -We introduce a Lagrange multiplier $\lambda$ and the convex cone $K\subset W'$, -$W'$ dual space of the trace space $W:=\left[ H_0^{\frac{1}{2}}(\Gamma_C) -\right]^{\textrm{dim}}$ of $V$ restricted to $\Gamma_C$, $$K:=\{\mu\in W':\mu_T = 0,\quad\langle\mu n,v\rangle_{\Gamma_C}\geq 0,\quad -\forall v\in H_0^{\frac{1}{2}}(\Gamma_C), v \ge 0\text{ on }\Gamma_C \}$$ -of Lagrange multipliers, where $\langle\cdot,\cdot\rangle$ -denotes the duality pairing, i.e. a boundary integral, between $W'$ and $W$. -Intuitively, $K$ is the cone of all "non-positive functions", except that $ K\subset -\left( \left[ H_0^{\frac{1}{2}}(\Gamma_C) \right]^{\textrm{dim}} \right)' $ and -so contains other objects besides regular functions as well. This yields:\\ - -\noindent -\textit{Find $u\in V$ and $\lambda\in K$ such that} -\begin{align*} - \hat{a}(u,v) + b(v,\lambda) &= f(v),\quad &&v\in V\\ - b(u,\mu - \lambda) &\leq \langle g,(\mu - - \lambda)n\rangle_{\Gamma_C},\quad&&\mu\in K, -\end{align*} -\textit{with} -\begin{align*} - \hat{a}(u,v) &:= a'(u^i;u,v)\\ - b(u,\mu) &:= \langle un,\mu n\rangle_{\Gamma_C},\quad &&u\in V,\quad\mu\in W'. -\end{align*} -As in the section before $u^i$ denotes the linearization point for the -semi-linearform $a(.;.)$. In contrast to step-41 we directly consider $\lambda$ -as the additional, positive force $\sigma(u)n$ that the obstacle -exerts on the boundary $\Gamma_C$ of the body.\\ - -\noindent -The existence and uniqueness of the analytical solution $(u,\lambda)\in V\times -K$ of this saddle point problem has been stated in Glowinski, Lions and Tr\'{e}moli\`{e}res: Numerical -Analysis of Variational Inequalities, North-Holland, 1981.\\ - -\noindent -NOTE: In this example as well as in the further documentation we make the -assumption that the normal vector $n$ equals to $(0,0,1)$. This comes up with -the starting condition of our deformable body. - -\section{Active Set methods to solve the saddle point problem} - -The linearized problem is essentially like a pure elastic problem with contact like -in step-41. The only difference consists in the fact that the contact area -is at the boundary instead of in the domain. But this has no further consequence -so that we refer to the documentation of step-41 with the only hint that -$\mathcal{S}$ containts all the vertices at the contact boundary $\Gamma_C$ this -time. - -\section{The primal-dual active set algorithm combined with the inexact semi smooth -Newton method} - -Now we describe an algorithm that combines the damped semismooth Newton-method, -which we use for the nonlinear constitutive law, with the semismooth Newton -method for the contact. It sums up the results of the sections before and works as follows: -\begin{itemize} - \item[(0)] Initialize $\mathcal{A}_k$ and $\mathcal{F}_k$, such that - $\mathcal{S} = \mathcal{A}_k \cup \mathcal{F}_k$ and $\mathcal{A}_k \cap - \mathcal{F}_k = \emptyset$ and set $k = 1$. The start value $\hat U^0 := - P_{\mathcal{A}_k}(0)$ fullfills our obstacle condition. - \item[(1)] Assemble the Newton matrix $A := a'(\hat - U^{k-1};\varphi_p,\varphi_q)$ and the right-hand-side $F(\hat U^{k-1})$. - \item[(2)] Find the primal-dual pair $(\bar U^k,\Lambda^k)$ that satisfies - \begin{align*} - A\bar U^k + B\Lambda^k & = F, &\\ - \left[B^T\bar U^k\right]_p & = G_p & \forall p\in\mathcal{A}_k,\\ - \Lambda^k_p & = 0 & \forall p\in\mathcal{F}_k. - \end{align*} - \item[(3)] Damping for $k>2$ by applying a line search and calculating a linear - combination of $U^{k-1}$ and $\bar U^k$. Find an - $\alpha_i:=2^{-i},(i=0,\ldots,10)$ so that $$U^k := \alpha_i\bar U^k + - (1-\alpha_i)U^{k-1}$$ yields $$\vert - F\left(U^{k}\right) \vert < \vert F\left(U^{k-1}\right) \vert.$$ - \item[(4)] Define the new active and inactive sets by - $$\mathcal{A}_{k+1}:=\lbrace p\in\mathcal{S}:\Lambda^k_p + - c\left(\left[B^TU^k\right]_p - G_p\right) > 0\rbrace,$$ - $$\mathcal{F}_{k+1}:=\lbrace p\in\mathcal{S}:\Lambda^k_p + - c\left(\left[B^TU^k\right]_p - G_p\right) \leq 0\rbrace.$$ - Projection $U^k$ so that it holds the second equation in (2) - $$\hat U^K := P_{\mathcal{A}_{k+1}}(U^k).$$ - \item[(5)] If $\mathcal{A}_{k+1} = \mathcal{A}_k$ and $\vert - F\left(U^{k}\right) \vert < \delta$ then stop, else set $k=k+1$ and go to - step (1). -\end{itemize} -\noindent -The subscript $p$ denotes a vertex and the meaning of the -decorated and none decorated $U$ is as follows: $\bar U$ denotes the solution of the linear system of equations in (2), $U$ is the -damped solution and equals to $\bar U$ if the damping parameter $\alpha_0 = -1$ and $\hat U := P_{\mathcal{A}}(U)$ is the projection of the active -components in $\mathcal{A}$ to the gap -$$P_{\mathcal{A}}(U):=\begin{cases} -U_p, & \textrm{if}\quad p\notin\mathcal{A}\\ -g_{h,p}, & \textrm{if}\quad -p\in\mathcal{A}. -\end{cases}$$\\ -The matrix $B\in\mathbb{R}^{n\times m}$, $n>m$ describes the coupling of the -bases for the displacements and lagrange multiplier (contact forces) -and it is not quadratic in our situation since $\Lambda^k$ is only defined on -$\Gamma_C$. Due to the ansatz functions $\psi_i$ (scalar valued) of the -lagrange multiplier are fullfilling the following biorthogonal condition (see Hüeber, Wohlmuth: A primal–dual active -set strategy for non-linear multibody contact problems, Comput. Methods Appl. Mech. Engrg. -194, 2005, pp. 3147-3166) -$$ \int\limits_{\Gamma_C}\psi_i(x)\varphi_j(x)dx = -\delta_{ij}\int\limits_{\Gamma_C}\varphi_j(x)dx$$ -this yields -$$B_{pq} = \begin{cases} -\int\limits_{\Gamma_C}\varphi_p(x)dxI_3, & \text{if}\quad p=q,\quad -p,q\in\mathcal{S}\\ -0I_3, & \text{if}\quad p\neq q,\quad p\textrm{ or }q\notin\mathcal{S}. -\end{cases}$$ -Here $I_3$ denotes the threedimensional identity matrix. -In our programm we use the structure of a quadratic sparse for -$B\in\mathbb{R}^{n\times n}$ and for $\Lambda^k$ a vector with length $n$ where -$\Lambda^k_p = 0$ for $p\notin \mathcal{S}$. -The vector $G$ is defined by a suitable approximation $g_h$ of the gap $g$ -$$G_p = \begin{cases} -g_{h,p}\int\limits_{\Gamma_C}\varphi_p(x)dx, & \text{if}\quad p\in\mathcal{S}\\ -0, & \text{if}\quad p\notin\mathcal{S}. -\end{cases}$$\\ -Note that $G_p$ is a threedimensional vector and that again we applied the -biorthogonal property of the lagrange multiplier ansatz functions to the -integral $\int\limits_{\Gamma_C}g_h(x)\varphi_p(x)dx$ with $g_h(x)=\sum\limits_i -g_{h,p}\varphi_p(x)$ (see the reference mentioned above).\\ -Compared to step-41, step (1) is added but it should be clear from the sections -above that we only linearize the problem. In step (2) we have to solve a linear system of equations again. And now the solution has to fulfill two stopping -criteria. $\mathcal{A}_{k+1} = \mathcal{A}_k$ makes sure that the contact zones -are iterated out and the second ensures an accurate enough residual which means that the plastic zones are also iterated out.\\ -A similar method can also be found in Brunssen, Schmid, Schaefer, Wohlmuth: A -fast and robust iterative solver for nonlinear contact problems using a -primal-dual active set strategy and algebraic multigrid, Int. J. Numer. -Meth. Engng, 2007, 69, pp. 524-543. But in advance we apply a line search to -obtain a more robust method regarding the start value. Solving an elastic -problem in the very first step ($k=1$) we get a reasonable start value but as -you can see in the results damping is important if we choose for example a ball as -obstacle.\\ -Damping our Newton method is more important for the nonlinearity cause by the -constitutive law as for the contact. For this reason we start to damp our method -for $k>2$ when we have two plastic iterations. Note that $U^1$ is a solution of -an elastic problem and $U^2$ is the first plastic solution. A linear combination -between these both results in stresses which are not in the convex set -of the feasible stresses. - -\section{Adaptive mesh refinement} - -Since we run our program in 3d, there is a good reason to use adaptive -mesh refined. To make life a bit easier we are choosing the -KellyErrorEstimator that is already implemented in deal.II. We hand the -solution vector to it which contains the displacement $u$. As we will see in the -results it yields a quite reasonable adaptive mesh for the contact zone. - -\section{Implementation} - -This tutorial is essentailly a mixture of step-40 and step-41 but instead of -PETSc we let the Trilinos library deal with parallelizing the linear algebra -(like in step-32). Since we are trying to solve a similar problem like in -step-41 we will use the same methods but now in parallel. - -Another difficulty is the handling of the different constraints from -(the dirichlet conditons), the hanging nodes and the inequality condition that -arises from the contact. For this purpose we create three objects of type -ConstraintMatrix. - -Beside the ConstitutiveLaw class there is another new class called Input. This -class allows us to read in an obstacle from a file. In our example the file -'obstacle\_file.dat' containts data which describe an Chinese, Japanese or -Korean symbol for force or power. (See www.orientaloutpost.com/: ``This word can be used for motivation - it -can also mean power / motion / propulsion / force. It can be anything -internal or external that keeps you going. This is the safest way to express -motivation in Chinese. If your audience is Japanese, please see the other entry -for motivation. This is a word in Japanese and Korean, but it means "motive -power" or "kinetic energy" (without the motivation meaning that you are -probably looking for)''). - -\section{Results} - - - -\end{document} diff --git a/deal.II/examples/step-42/doc/intro.dox b/deal.II/examples/step-42/doc/intro.dox deleted file mode 100644 index e968148ad2..0000000000 --- a/deal.II/examples/step-42/doc/intro.dox +++ /dev/null @@ -1,427 +0,0 @@ -
- -This program was contributed by Jörg Frohne (University of Siegen, -Germany) while on a long-term visit to Texas A&M University. -
-
- - - - -

Introduction

- -This example is an extension of step-41, considering a contact problem with an -elasto-plastic material behavior with isotropic hardening in three dimensions. -That means that we have to take care of an additional nonlinearity: the -material behavior. Since we consider a three dimensional problem here, a -separate difference to step-41 is that the contact area is at the boundary of -the deformable body now, rather than in the interior. Finally, compared to -step-41, we also have to deal with hanging nodes because of the adaptive mesh -in both the handling of the linear -system as well as of the inequality constraints; in the latter case, we will -have to deal with prioritizing whether the constraints from the hanging nodes -or from the inequalities are more important. - -Since you can very easily reach a few million degrees of freedom in three -dimensions, even with adaptive mesh refinement, we decided to use Trilinos and -p4est to run our code in parallel, building on the framework of step-40 for -the parallelization. - -@f{huge} -{distributed} -@f} - - -

Classical formulation

- -The classical formulation of the problem possesses the following form: -@f{align*} - \varepsilon(u) &= A\sigma + \lambda & &\quad\text{in } \Omega,\\ - \lambda(\tau - \sigma) &\geq 0\quad\forall\tau\text{ with - }\mathcal{F}(\tau)\leq 0 & &\quad\text{in } \Omega,\\ - -\textrm{\textrm{div}}\ \sigma &= f & &\quad\text{in } \Omega,\\ - u(\mathbf x) &= 0 & &\quad\text{on }\Gamma_D,\\ - \sigma_t(u) &= 0,\quad\sigma_n(u)\leq 0 & &\quad\text{on }\Gamma_C,\\ -\sigma_n(u)(u_n - g) &= 0,\quad u_n(\mathbf x) - g(\mathbf x) \leq 0 & &\quad\text{on } \Gamma_C -@f} -with $u\in H^2(\Omega),\Omega\subset\mathbb{R}^3$. The vector valued -function $u$ denotes the displacement in the deformable body. The first two lines describe the -elasto-plastic material behavior. Therein the equation shows the -strain of the deformation $\varepsilon (u)$ as the additive decomposition of the -elastic part $A\sigma$ and the plastic part $\lambda$. $A$ is defined as the compliance tensor of fourth order which contains some material constants and $\sigma$ as the -symmetric stress tensor of second order. So we have to consider -the inequality in the second row in a pointwise sense where $\lambda(\tau - -\sigma)$ is the inner product of two symmetric tensors of second order. Furthermore we have to -distinguish two cases. - -The continuous and convex function $\mathcal{F}$ denotes the von Mises flow function -@f{gather*}\mathcal{F}(\tau) = \vert\tau^D\vert - \sigma_0�\quad\text{with}\quad \tau^D -= \tau - \dfrac{1}{3}tr(\tau)I,@f} -$\sigma_0$ as yield stress and $\vert .\vert$ as the Frobenius norm. If there -are no plastic deformations in a particular point - that is $\lambda=0$ - this yields $\vert\sigma^D\vert < -\sigma_0$ and otherwise if $\lambda > 0$ it follows that $\vert\sigma^D\vert = \sigma_0$. -That means if the stress is smaller than the yield stress there are only elastic -deformations in that point. - -To consider it the other way around if the deviator stress $\sigma^D$ is in a -norm bigger than the yield stress then $\sigma^D$ has to be projected back to the yield surface and there are plastic deformations which means $\lambda$ -would be positiv for that particular point. We refer that the stresses are -computed by Hooke's law for isotorpic materials. You can find the description at the end of section 3. Else if the norm of the deviator stress tensor is smaller or equal the yield stress then $\lambda$ is zero and there are no plastic deformations in -that point. - -There the index $D$ denotes the deviator part of for example the stress where -$tr(.)$ is the trace of a tensor. The definition shows an additive decomposition -of the stress $\sigma$ into a hydrostatic part (or volumetric part) $\dfrac{1}{3}tr(\tau)I$ and the deviator -part $\sigma^D$. For metal the deviator stress composes the main indicator for -plastic deformations. - -The third equation is called equilibrium condition with a force of volume -density $f$ which we will neglect in our example. -The boundary of $\Omega$ separates as follows $\Gamma=\Gamma_D\bigcup\Gamma_C$ and $\Gamma_D\bigcap\Gamma_C=\emptyset$. -At the boundary $\Gamma_D$ we have zero Dirichlet conditions. $\Gamma_C$ denotes the potential contact boundary. - -The last two lines decribe the so-called Signorini contact conditions. If there is no contact the normal stress -@f{gather*} \sigma_n = \sigma n\cdot n@f} -is zero with the outward normal $n$. If there is contact ($u_n = g$) the tangential stress $\sigma_t = \sigma\cdot n - \sigma_n n$ -vanishes, because we consider a frictionless situation and the normal stress is -negative. The gap $g$ comes with the start configuration of the obstacle and the -deformable body. - - -

Derivation of the variational inequality

- -As a starting point to derive the equations above, let us imagine that we want -to minimise an energy functional: -@f{gather*}E(\tau) := \dfrac{1}{2}\int\limits_{\Omega}\tau A \tau d\tau,\quad \tau\in \Pi W^{\textrm{div}}@f} -with -@f{gather*}W^{\textrm{div}}:=\lbrace \tau\in -L^2(\Omega,\mathbb{R}^{\textrm{dim}\times\textrm{dim}}_{\textrm{sym}}):\textrm{div}(\tau)\in L^2(\Omega,\mathbb{R}^{\textrm{dim}})\rbrace@f} and -@f{gather*}\Pi \Sigma:=\lbrace \tau\in \Sigma, \mathcal{F}(\tau)\leq 0\rbrace@f} -as the set of admissible stresses which is defined -by a continious, convex flow function $\mathcal{F}$. - -With the goal of deriving the dual formulation of the minimisation -problem, we define a lagrange function: -@f{gather*}L(\tau,\varphi) := E(\tau) + (\varphi, \textrm{div}(\tau)),\quad \lbrace\tau,\varphi\rbrace\in\Pi W^{\textrm{div}}\times V^+@f} -with -@f{gather*}V^+ := \lbrace u\in V: u_n\leq g \text{ on } \Gamma_C \rbrace@f} -@f{gather*}V:=\left[ H_0^1 \right]^{\textrm{dim}}:=\lbrace u\in \left[H^1(\Omega)\right]^{\textrm{dim}}: u -= 0 \text{ on } \Gamma_D\rbrace@f} -By building the Fréchet derivatives of $L$ for both components we obtain the -dual formulation for the stationary case which is known as Hencky-Type-Model:\\ -Find a pair $\lbrace\sigma,u\rbrace\in \Pi W\times V^+$ with -@f{gather*}\left(A\sigma,\tau - \sigma\right) + \left(u, \textrm{div}(\tau) - \textrm{div}(\sigma)\right) \geq 0,\quad \forall \tau\in \Pi W^{\textrm{div}}@f} -@f{gather*}-\left(\textrm{div}(\sigma),\varphi - u\right) \geq 0,\quad \forall \varphi\in V^+.@f} -By integrating by parts and multiplying the first inequality by the elastic -tensor $C=A^{-1}$ we achieve the primal-mixed version of our problem: -Find a pair $\lbrace\sigma,u\rbrace\in \Pi W\times V^+$ with -@f{gather*}\left(\sigma,\tau - \sigma\right) - \left(C\varepsilon(u), \tau - \sigma\right) \geq 0,\quad \forall \tau\in \Pi W@f} -@f{gather*}\left(\sigma,\varepsilon(\varphi) - \varepsilon(u)\right) \geq 0,\quad \forall \varphi\in V^+.@f} -Therein $\varepsilon$ denotes the linearised deformation tensor with $\varepsilon(u) := \dfrac{1}{2}\left(\nabla u + \nabla u^T\right)$ for small deformations. - -Most materials - especially metals - have the property that they show some hardening effects during the forming process. -There are different constitutive laws to describe those material behaviors. The -simplest one is called linear isotropic hardening described by the flow function -$\mathcal{F}(\tau,\eta) = \vert\tau^D\vert - (\sigma_0 + \gamma^{\text{iso}}\eta)$ where -$\eta$ is the norm of the plastic strain $\eta = \vert \varepsilon - -A\sigma\vert$. -It can be considered by establishing an additional term in our primal-mixed formulation: -Find a pair $\lbrace(\sigma,\xi),u\rbrace\in \Pi (W\times L^2(\Omega,\mathbb{R}))\times V^+$ with -@f{gather*}\left(\sigma,\tau - \sigma\right) - \left(C\varepsilon(u), \tau - \sigma\right) + \gamma^{\text{iso}}\left( \xi, \eta - \xi\right) \geq 0,\quad \forall (\tau,\eta)\in \Pi (W,L^2(\Omega,\mathbb{R}))@f} -@f{gather*}\left(\sigma,\varepsilon(\varphi) - \varepsilon(u)\right) \geq 0,\quad \forall \varphi\in V^+,@f} -with the hardening parameter $\gamma^{\text{iso}} > 0$. - -Now we want to derive a primal problem which only depends on the displacement $u$. For that purpose we -set $\eta = \xi$ and eliminate the stress $\sigma$ by applying the projection -theorem (see Grossmann, Roos: Numerical Treatment of Partial Differential -Equations, Springer-Verlag Berlin Heidelberg, 2007 and Frohne: FEM-Simulation -der Umformtechnik metallischer Oberflächen im Mikrokosmos, Ph.D. thesis, -University of Siegen, Germany, 2011) on -@f{gather*}\left(\sigma - C\varepsilon(u), \tau - \sigma\right) \geq 0,\quad \forall \tau\in \Pi W,@f} -which yields with the second inequality:\\ -Find the displacement $u\in V^+$ with -@f{gather*}\left(P_{\Pi}(C\varepsilon(u)),\varepsilon(\varphi) - \varepsilon(u)\right) \geq 0,\quad \forall \varphi\in V^+,@f} -with the projection: -@f{gather*}P_{\Pi}(\tau):=\begin{cases} - \tau, & \text{if }\vert\tau^D\vert \leq \sigma_0 + \gamma^{\text{iso}}\xi,\\ - \hat\alpha\dfrac{\tau^D}{\vert\tau^D\vert} + \dfrac{1}{3}tr(\tau), & \text{if }\vert\tau^D\vert > \sigma_0 + \gamma^{\text{iso}}\xi, - \end{cases}@f} -with the radius -@f{gather*}\hat\alpha := \sigma_0 + \gamma^{\text{iso}}\xi .@f} -With the relation $\xi = \vert\varepsilon(u) - A\sigma\vert$ it is possible to eliminate $\xi$ inside the projection $P_{\Pi}$:\\ -@f{gather*}P_{\Pi}(\tau):=\begin{cases} - \tau, & \text{if }\vert\tau^D\vert \leq \sigma_0,\\ - \alpha\dfrac{\tau^D}{\vert\tau^D\vert} + \dfrac{1}{3}tr(\tau), & \text{if }\vert\tau^D\vert > \sigma_0, - \end{cases}@f} -@f{gather*}\alpha := \sigma_0 + \dfrac{\gamma^{\text{iso}}}{2\mu+\gamma^{\text{iso}}}\left(\vert\tau^D\vert - \sigma_0\right) ,@f} -with a further material parameter $\mu>0$ called shear modulus. We refer that -this only possible for isotropic plasticity. - -To make things a bit easier from now on we denote -@f{gather*}\gamma := \dfrac{\gamma^{\text{iso}}}{2\mu + -\gamma^{\text{iso}}}\in[0,1)\text{ with }\gamma^{\text{iso}}\in[0,\infty),@f} -@f{gather*}\beta :=\dfrac{\sigma_0}{\vert\tau^D\vert}.@f} -If $\gamma^{\text{iso}}$ tends to zero $\gamma$ tends also to zero. And if $\gamma^{\text{iso}}$ tends to -infinity $\gamma$ tends to one. This allows us to reformulate our problem as -follows -@f{gather*}P_{\Pi}(\tau):=\begin{cases} - \tau, & \text{if }\vert\tau^D\vert \leq \sigma_0,\\ - \gamma\tau^D + (1-\gamma)\beta\tau^D - + \dfrac{1}{3}tr(\tau), & \text{if }\vert\tau^D\vert > - \sigma_0, \end{cases}.@f} -For further details e.g., see Suttmeier: On Plasticity with Hardening: -An Adaptive Finite Element Discretisation, International Mathematical Forum, 5, -2010, no. 52, 2591-2601. - -So what we do is to calculate the stresses by using Hooke's law for linear elastic, isotropic materials -@f{gather*}\sigma = C \varepsilon(u) = 2\mu \varepsilon^D(u) + \kappa tr(\varepsilon(u))I = \left[2\mu\left(\mathbb{I} -\dfrac{1}{3} I\otimes I\right) + \kappa I\otimes I\right]\varepsilon(u)@f} -with the material parameter $\kappa>0$ (bulk modulus). The variables $I$ and -$\mathbb{I}$ denote the identity tensors of second and forth order. In that -notation $2\mu \varepsilon^D(u)$ is the deviatoric part and $\kappa -tr(\varepsilon(u))$ the volumetric part of the stress tensor. - -In the next step we test in a pointwise sense where the deviator part of the -stress in a norm is bigger than the yield stress. If there are such points we -project the deviator stress in those points back to the yield surface. Methods of this kind are called projections algorithm or radial-return-algorithm. - -Now we have a primal formulation of our elasto-plastic contact problem which only depends on the displacement $u$. -It consists of a nonlinear variational inequality and has a unique solution as -it satisfies the theorem of Lions and Stampaccia. A proof can be found in -Rodrigues: Obstacle Problems in Mathematical Physics, North-Holland, Amsterdam, -1987. - -To handle the nonlinearity of the constitutive law we use a Newton method and to deal with the contact we apply an -active set method like in step-41. To be more concrete we combine both methods to an inexact semi smooth Newton -method - inexact since we use an iterative solver for the linearised problems in each Newton step. - - -

Linearisation of the constitutive law for the Newton method

- -For the Newton method we have to linearise the following semi-linearform -@f{gather*}a(\psi;\varphi) := \left(P_{\Pi}(C\varepsilon(\psi)),\varepsilon(\varphi)\right).@f} -Because we have to find the solution $u$ in the convex set $V^+$, we have to -apply an SQP-method (SQP: sequential quadratic programming). That means we have -to solve a minimisation problem for a known $u^i$ in every SQP-step of the form -@f{eqnarray*} - & & a(u^{i};u^{i+1} - u^i) + \dfrac{1}{2}a'(u^i;u^{i+1} - u^i,u^{i+1} - u^i)\\ - &=& a(u^i;u^{i+1}) - a(u^i;u^i) +\\ - & & \dfrac{1}{2}\left( a'(u^i;u^{i+1},u^{i+1}) - 2a'(u^i;u^i,u^{i+1}) - a'(u^i;u^i,u^i)\right)\\ - &\rightarrow& \textrm{min},\quad u^{i+1}\in V^+. -@f} -Neglecting the constant terms $ a(u^i;u^i)$ and $ a'(u^i;u^i,u^i)$ we obtain the -following minimisation problem @f{gather*}\dfrac{1}{2} a'(u^i;u^{i+1},u^{i+1}) - F(u^i)\rightarrow \textrm{min},\quad u^{i+1}\in V^+@f} with -@f{gather*}F(\varphi) := \left(a'(\varphi;\varphi,u^{i+1}) - a(\varphi;u^{i+1}) \right).@f} -In the case of our constitutive law the Fréchet derivative of the -semi-linearform $a(.;.)$ at the point $u^i$ is - -@f{gather*}a'(u^i;\psi,\varphi) = -(I(x)\varepsilon(\psi),\varepsilon(\varphi)),\quad x\in\Omega,@f} -@f{gather*} -I(x) := \begin{cases} -C_{\mu} + C_{\kappa}, & -\quad \vert \tau^D \vert \leq \sigma_0\\ -\gamma C_{\mu} + (1-\gamma)\beta\left(C_{\mu} - -2\mu\dfrac{\tau^D\otimes\tau^D}{\vert\tau^D\vert^2}\right) + C_{\kappa}, &\quad -\vert \tau^D \vert > \sigma_0 -\end{cases} -@f} -with -@f{gather*}C_{\mu} := 2\mu\left(\mathbb{I} - \dfrac{1}{3} I\otimes -I\right)\quad\text{(shear part of the stress strain tensor)},@f} -@f{gather*}C_{\kappa} := \kappa I\otimes I\quad\text{(bulk part of the stress strain -tensor)},@f} -@f{gather*}\tau^D := C\varepsilon^D(u^i).@f} -Remark that $a(.;.)$ is not differentiable in the common sense but it is -slantly differentiable like the function for the contact problem and again we refer to -Hintermueller, Ito, Kunisch: The primal-dual active set strategy as a semismooth newton method, SIAM J. OPTIM., 2003, Vol. 13, No. 3, pp. 865-888. -Again the first case is for elastic and the second for plastic deformation. - - -

Formulation as a saddle point problem

- -Just as in step-41 we compose a saddle point problem out of the minimisation -problem. Again we do so to gain a formulation that allows us to solve a linear -system of equations finally. - -We introduce a Lagrange multiplier $\lambda$ and the convex cone $K\subset W'$, -$W'$ dual space of the trace space $W:=\left[ H_0^{\frac{1}{2}}(\Gamma_C) -\right]^{\textrm{dim}}$ of $V$ restricted to $\Gamma_C$, -@f{gather*}K:=\{\mu\in W':\mu_T = 0,\quad\langle\mu n,v\rangle_{\Gamma_C}\geq 0,\quad -\forall v\in H_0^{\frac{1}{2}}(\Gamma_C), v \ge 0\text{ on }\Gamma_C \}@f} -of Lagrange multipliers, where $\langle\cdot,\cdot\rangle$ -denotes the duality pairing, i.e. a boundary integral, between $W'$ and $W$. -Intuitively, $K$ is the cone of all "non-positive functions", except that $ K\subset -\left( \left[ H_0^{\frac{1}{2}}(\Gamma_C) \right]^{\textrm{dim}} \right)' $ and so contains other -objects besides regular functions as well. This yields: - -Find $u\in V$ and $\lambda\in K$ such that -@f{align*} - \hat{a}(u,v) + b(v,\lambda) &= f(v),\quad &&v\in V\\ - b(u,\mu - \lambda) &\leq \langle g,(\mu - - \lambda)n\rangle_{\Gamma_C},\quad&&\mu\in K, -@f} -with -@f{align*} - \hat{a}(u,v) &:= a'(u^i;u,v)\\ - b(u,\mu) &:= \langle un,\mu n\rangle_{\Gamma_C},\quad &&u\in V,\quad\mu\in W'. -@f} -As in the section before $u^i$ denotes the linearization point for the -semi-linearform $a(.;.)$. In contrast to step-41 we directly consider $\lambda$ -as the additional, positive force $\sigma(u)n$ that the obstacle -exerts on the boundary $\Gamma_C$ of the body. - -The existence and uniqueness of the analytical solution $(u,\lambda)\in V\times -K$ of this saddle point problem has been stated in Glowinski, Lions and Tr\'{e}moli\`{e}res: Numerical -Analysis of Variational Inequalities, North-Holland, 1981. - -NOTE: In this example as well as in the further documentation we make the -assumption that the normal vector $n$ equals to $(0,0,1)$. This comes up with -the starting condition of our deformable body. - - -

Active Set methods to solve the saddle point problem

- -The linearized problem is essentially like a pure elastic problem with contact like -in step-41. The only difference consists in the fact that the contact area -is at the boundary instead of in the domain. But this has no further consequence -so that we refer to the documentation of step-41 with the only hint that -$\mathcal{S}$ containts all the vertices at the contact boundary $\Gamma_C$ this -time. - - -

The primal-dual active set algorithm combined with the inexact semi smooth -Newton method

- -Now we describe an algorithm that combines the damped semismooth Newton-method, -which we use for the nonlinear constitutive law, with the semismooth Newton -method for the contact. It sums up the results of the sections before and works as follows: -
    -
  1. Initialize $\mathcal{A}_k$ and $\mathcal{F}_k$, such that - $\mathcal{S} = \mathcal{A}_k \cup \mathcal{F}_k$ and $\mathcal{A}_k \cap - \mathcal{F}_k = \emptyset$ and set $k = 1$. The start value $\hat U^0 := - P_{\mathcal{A}_k}(0)$ fullfills our obstacle condition. -
  2. Assemble the Newton matrix $A := a'(\hat - U^{k-1};\varphi_p,\varphi_q)$ and the right-hand-side $F(\hat U^{k-1})$. -
  3. Find the primal-dual pair $(\bar U^k,\Lambda^k)$ that satisfies - @f{align*} - A\bar U^k + B\Lambda^k & = F, &\\ - \left[B^T\bar U^k\right]_p & = G_p & \forall p\in\mathcal{A}_k,\\ - \Lambda^k_p & = 0 & \forall p\in\mathcal{F}_k. - @f} -
  4. Damping for $k>2$ by applying a line search and calculating a linear - combination of $U^{k-1}$ and $\bar U^k$. Find an - $\alpha_i:=2^{-i},(i=0,\ldots,10)$ so that - @f{gather*}U^k := \alpha_i\bar U^k + - (1-\alpha_i)U^{k-1}@f} - yields - @f{gather*}\vert F\left(U^{k}\right) \vert < \vert F\left(U^{k-1}\right) \vert.\f} -
  5. Define the new active and inactive sets by - @f{gather*}\mathcal{A}_{k+1}:=\lbrace p\in\mathcal{S}:\Lambda^k_p + - c\left(\left[B^TU^k\right]_p - G_p\right) > 0\rbrace,@f} - @f{gather*}\mathcal{F}_{k+1}:=\lbrace p\in\mathcal{S}:\Lambda^k_p + - c\left(\left[B^TU^k\right]_p - G_p\right) \leq 0\rbrace.@f} - Projection $U^k$ so that it holds the second equation in (2) - @f{gather*}\hat U^K := P_{\mathcal{A}_{k+1}}(U^k).@f} -
  6. If $\mathcal{A}_{k+1} = \mathcal{A}_k$ and $\vert - F\left(U^{k}\right) \vert < \delta$ then stop, else set $k=k+1$ and go to - step (1). -
- -The subscript $p$ denotes a vertex and the meaning of the -decorated and none decorated $U$ is as follows: $\bar U$ denotes the solution of the linear system of equations in (2), $U$ is the -damped solution and equals to $\bar U$ if the damping parameter $\alpha_0 = -1$ and $\hat U := P_{\mathcal{A}}(U)$ is the projection of the active -components in $\mathcal{A}$ to the gap - -@f{gather*}P_{\mathcal{A}}(U):=\begin{cases} -U_p, & \textrm{if}\quad p\notin\mathcal{A}\\ -g_{h,p}, & \textrm{if}\quad -p\in\mathcal{A}. -\end{cases}@f}\\ -The matrix $B\in\mathbb{R}^{n\times m}$, $n>m$ describes the coupling of the -bases for the displacements and lagrange multiplier (contact forces) -and it is not quadratic in our situation since $\Lambda^k$ is only defined on -$\Gamma_C$. Due to the ansatz functions $\psi_i$ (scalar valued) of the -lagrange multiplier are fullfilling the following biorthogonal condition (see Hüeber, Wohlmuth: A primal–dual active -set strategy for non-linear multibody contact problems, Comput. Methods Appl. Mech. Engrg. -194, 2005, pp. 3147-3166) -@f{gather} \int\limits_{\Gamma_C}\psi_i(x)\varphi_j(x)dx = -\delta_{ij}\int\limits_{\Gamma_C}\varphi_j(x)dx@f} -this yields -@f{gather*}B_{pq} = \begin{cases} -\int\limits_{\Gamma_C}\varphi_p(x)dxI_3, & \text{if}\quad p=q,\quad -p,q\in\mathcal{S}\\ -0I_3, & \text{if}\quad p\neq q,\quad p\textrm{ or }q\notin\mathcal{S}. -\end{cases}@f} -Here $I_3$ denotes the threedimensional identity matrix. -In our programm we use the structure of a quadratic sparse for -$B\in\mathbb{R}^{n\times n}$ and for $\Lambda^k$ a vector with length $n$ where -$\Lambda^k_p = 0$ for $p\notin \mathcal{S}$. -The vector $G$ is defined by a suitable approximation $g_h$ of the gap $g$ -@f{gather*}G_p = \begin{cases} -g_{h,p}\int\limits_{\Gamma_C}\varphi_p(x)dx, & \text{if}\quad p\in\mathcal{S}\\ -0, & \text{if}\quad p\notin\mathcal{S}. -\end{cases}@f} - -Note that $G_p$ is a threedimensional vector and that again we applied the -biorthogonal property of the lagrange multiplier ansatz functions to the -integral $\int\limits_{\Gamma_C}g_h(x)\varphi_p(x)dx$ with $g_h(x)=\sum\limits_i -g_{h,p}\varphi_p(x)$ (see the reference mentioned above). - -Compared to step-41, step (1) is added but it should be clear -from the sections above that we only linearize the problem. In step (2) we have -to solve a linear system of equations again. And now the solution has to fulfill two stopping -criteria. $\mathcal{A}_{k+1} = \mathcal{A}_k$ makes sure that the contact zones -are iterated out and the second ensures an accurate enough residual which means -that the plastic zones are also iterated out. - -A similar method can also be found in Brunssen, Schmid, Schäfer, -Wohlmuth: A fast and robust iterative solver for nonlinear contact problems -using a primal-dual active set strategy and algebraic multigrid, Int. J. Numer. -Meth. Engng, 2007, 69, pp. 524-543. But in advance we apply a line search to -obtain a more robust method regarding the start value. Solving an elastic -problem in the very first step ($k=1$) we get a reasonable start value but as -you can see in the results damping is important if we choose for example a ball as -obstacle. - -Damping our Newton method is more important for the nonlinearity cause by the -constitutive law as for the contact. For this reason we start to damp our method -for $k>2$ when we have two plastic iterations. Note that $U^1$ is a solution of -an elastic problem and $U^2$ is the first plastic solution. A linear combination -between these both results in stresses which are not in the convex set -of the feasible stresses. - - -

Adaptive mesh refinement

- -Since we run our program in 3d, there is a good reason to use adaptive -mesh refinement. To make things a bit easier we are choosing the -KellyErrorEstimator that is already implemented in deal.II. We hand the -solution vector to it which contains the displacement $u$. As we will see in the -results it yields a quite reasonable adaptive mesh for the contact zone as well -as for plasticity! - - -

Implementation

- -This tutorial is essentially a mixture of step-40 and step-41 but instead of -PETSc we let the Trilinos library deal with parallelizing the linear algebra -(like in step-32). Since we are trying to solve a similar problem like in -step-41 we will use the same methods but now in parallel. - -Another difficulty is the handling of the different constraints from -(the dirichlet conditons), the hanging nodes and the inequality condition that -arises from the contact. For this purpose we create three objects of type -ConstraintMatrix. - -Beside the ConstitutiveLaw class there is another new class called Input. This -class allows us to read in an obstacle from a file. In our example the file -'obstacle_file.dat' containts data which describe an Chinese, Japanese or -Korean symbol for force or power. (See http://www.orientaloutpost.com/ : -"This word can be used for motivation - it -can also mean power/motion/propulsion/force. It can be anything -internal or external that keeps you going. This is the safest way to express -motivation in Chinese. If your audience is Japanese, please see the other entry -for motivation. This is a word in Japanese and Korean, but it means "motive -power" or "kinetic energy" (without the motivation meaning that you are -probably looking for)".) diff --git a/deal.II/examples/step-42/doc/kind b/deal.II/examples/step-42/doc/kind deleted file mode 100644 index 56e049c91a..0000000000 --- a/deal.II/examples/step-42/doc/kind +++ /dev/null @@ -1 +0,0 @@ -solids diff --git a/deal.II/examples/step-42/doc/results.dox b/deal.II/examples/step-42/doc/results.dox deleted file mode 100644 index 11104ccc74..0000000000 --- a/deal.II/examples/step-42/doc/results.dox +++ /dev/null @@ -1,418 +0,0 @@ -

Results

- -Running the program (with a ball as obstacle) on 12 cores produces output like this: -@code -Cycle 0: - Number of active cells: 218 - Total number of cells: 249 - Number of degrees of freedom: 2187 - - Newton iteration 1 - Updating active set... - Size of active set: 1 - Assembling system... - Solving system... - Error: 173.076 -> 0.157131 in 8 FGMRES iterations. - Number of elastic quadrature points: 4096 and plastic quadrature points: 0 - Residual of the non-contact part of the system: 0.157131 - with a damping parameter alpha = 1 - - Newton iteration 2 - Updating active set... - Size of active set: 1 - Assembling system... - Solving system... - Error: 57.3852 -> 0.0426777 in 9 FGMRES iterations. - Number of elastic quadrature points: 3944 and plastic quadrature points: 152 - Residual of the non-contact part of the system: 24.9209 - with a damping parameter alpha = 1 - - Newton iteration 3 - Updating active set... - Size of active set: 1 - Assembling system... - Solving system... - Error: 24.9209 -> 0.0157852 in 8 FGMRES iterations. - Number of elastic quadrature points: 3960 and plastic quadrature points: 136 - Residual of the non-contact part of the system: 1.63601 - with a damping parameter alpha = 1 - - Newton iteration 4 - Updating active set... - Size of active set: 1 - Assembling system... - Solving system... - Error: 1.63601 -> 0.00131281 in 8 FGMRES iterations. - Number of elastic quadrature points: 3960 and plastic quadrature points: 136 - Residual of the non-contact part of the system: 0.00479668 - with a damping parameter alpha = 1 - - Newton iteration 5 - Updating active set... - Size of active set: 1 - Assembling system... - Solving system... - Error: 0.00479668 -> 2.27976e-06 in 9 FGMRES iterations. - Number of elastic quadrature points: 3960 and plastic quadrature points: 136 - Residual of the non-contact part of the system: 2.29051e-06 - with a damping parameter alpha = 1 - - Newton iteration 6 - Updating active set... - Size of active set: 1 - Assembling system... - Solving system... - Error: 2.29051e-06 -> 1.31066e-09 in 9 FGMRES iterations. - Number of elastic quadrature points: 3960 and plastic quadrature points: 136 - Residual of the non-contact part of the system: 1.31067e-09 - with a damping parameter alpha = 1 - - Number of assembled systems = 6 - Number of Solver-Iterations = 51 - Writing graphical output... - - -+---------------------------------------------+------------+------------+ -| Total wallclock time elapsed since start | 6.23s | | -| | | | -| Section | no. calls | wall time | % of total | -+---------------------------------+-----------+------------+------------+ -| Assembling | 6 | 0.859s | 14% | -| Graphical output | 1 | 0.22s | 3.5% | -| Residual and lambda | 6 | 0.189s | 3% | -| Setup | 1 | 0.265s | 4.3% | -| Setup: distribute DoFs | 1 | 0.0549s | 0.88% | -| Setup: matrix | 1 | 0.0142s | 0.23% | -| Solve | 6 | 4.51s | 72% | -| Solve: iterate | 6 | 1.79s | 29% | -| Solve: setup preconditioner | 6 | 2.7s | 43% | -| Update solution and constraints | 6 | 0.0246s | 0.4% | -+---------------------------------+-----------+------------+------------+ - - -Cycle 1: - Number of active cells: 463 - Total number of cells: 529 - Number of degrees of freedom: 6294 - - Newton iteration 1 - Updating active set... - Size of active set: 8 - Assembling system... - Solving system... - Error: 69.7055 -> 0.0512854 in 11 FGMRES iterations. - Number of elastic quadrature points: 11400 and plastic quadrature points: 984 - Residual of the non-contact part of the system: 16.4859 - with a damping parameter alpha = 1 - - Newton iteration 2 - Updating active set... - Size of active set: 9 - Assembling system... - Solving system... - Error: 142.778 -> 0.0754216 in 8 FGMRES iterations. - Number of elastic quadrature points: 11252 and plastic quadrature points: 1132 - Residual of the non-contact part of the system: 17.2965 - with a damping parameter alpha = 1 - - Newton iteration 3 - Updating active set... - Size of active set: 9 - Assembling system... - Solving system... - Error: 17.2965 -> 0.0126474 in 10 FGMRES iterations. - Number of elastic quadrature points: 11032 and plastic quadrature points: 1352 - Residual of the non-contact part of the system: 14.2312 - with a damping parameter alpha = 1 - - Newton iteration 4 - Updating active set... - Size of active set: 9 - Assembling system... - Solving system... - Error: 14.2312 -> 0.0130557 in 10 FGMRES iterations. - Number of elastic quadrature points: 11189 and plastic quadrature points: 1195 - Residual of the non-contact part of the system: 12.6684 - with a damping parameter alpha = 1 - - Newton iteration 5 - Updating active set... - Size of active set: 9 - Assembling system... - Solving system... - Error: 12.6684 -> 0.00951713 in 10 FGMRES iterations. - Number of elastic quadrature points: 10987 and plastic quadrature points: 1397 - Residual of the non-contact part of the system: 13.9042 - with a damping parameter alpha = 1 - Number of elastic quadrature points: 11161 and plastic quadrature points: 1223 - Residual of the non-contact part of the system: 8.7982 - with a damping parameter alpha = 0.5 - - Newton iteration 6 - Updating active set... - Size of active set: 9 - Assembling system... - Solving system... - Error: 8.7982 -> 0.0057014 in 10 FGMRES iterations. - Number of elastic quadrature points: 11068 and plastic quadrature points: 1316 - Residual of the non-contact part of the system: 9.05367 - with a damping parameter alpha = 1 - Number of elastic quadrature points: 11160 and plastic quadrature points: 1224 - Residual of the non-contact part of the system: 4.7814 - with a damping parameter alpha = 0.5 - - Newton iteration 7 - Updating active set... - Size of active set: 9 - Assembling system... - Solving system... - Error: 4.7814 -> 0.00316863 in 10 FGMRES iterations. - Number of elastic quadrature points: 11152 and plastic quadrature points: 1232 - Residual of the non-contact part of the system: 1.71796 - with a damping parameter alpha = 1 - - Newton iteration 8 - Updating active set... - Size of active set: 9 - Assembling system... - Solving system... - Error: 1.71796 -> 0.00104906 in 7 FGMRES iterations. - Number of elastic quadrature points: 11144 and plastic quadrature points: 1240 - Residual of the non-contact part of the system: 0.013944 - with a damping parameter alpha = 1 - - Newton iteration 9 - Updating active set... - Size of active set: 9 - Assembling system... - Solving system... - Error: 0.013944 -> 1.26708e-05 in 11 FGMRES iterations. - Number of elastic quadrature points: 11144 and plastic quadrature points: 1240 - Residual of the non-contact part of the system: 1.38354e-05 - with a damping parameter alpha = 1 - - Newton iteration 10 - Updating active set... - Size of active set: 9 - Assembling system... - Solving system... - Error: 1.38354e-05 -> 7.16927e-09 in 14 FGMRES iterations. - Number of elastic quadrature points: 11144 and plastic quadrature points: 1240 - Residual of the non-contact part of the system: 7.16925e-09 - with a damping parameter alpha = 1 - - Number of assembled systems = 10 - Number of Solver-Iterations = 101 - Writing graphical output... - - -+---------------------------------------------+------------+------------+ -| Total wallclock time elapsed since start | 12.1s | | -| | | | -| Section | no. calls | wall time | % of total | -+---------------------------------+-----------+------------+------------+ -| Assembling | 10 | 4.07s | 34% | -| Graphical output | 1 | 0.282s | 2.3% | -| Residual and lambda | 12 | 0.819s | 6.8% | -| Setup | 1 | 0.895s | 7.4% | -| Setup: distribute DoFs | 1 | 0.139s | 1.1% | -| Setup: matrix | 1 | 0.0272s | 0.22% | -| Setup: refine mesh | 1 | 0.579s | 4.8% | -| Solve | 10 | 5.68s | 47% | -| Solve: iterate | 10 | 3.44s | 28% | -| Solve: setup preconditioner | 10 | 2.18s | 18% | -| Update solution and constraints | 10 | 0.0952s | 0.79% | -+---------------------------------+-----------+------------+------------+ - - -Cycle 2: - Number of active cells: 1170 - Total number of cells: 1337 - Number of degrees of freedom: 18207 - - . - . - . - - -Cycle 3: - Number of active cells: 2955 - Total number of cells: 3377 - Number of degrees of freedom: 52497 - - . - . - . - - -Cycle 4: - Number of active cells: 7400 - Total number of cells: 8457 - Number of degrees of freedom: 154647 - - . - . - . - - -Cycle 5: - Number of active cells: 19279 - Total number of cells: 22033 - Number of degrees of freedom: 461106 - - Newton iteration 1 - Updating active set... - Size of active set: 1672 - Assembling system... - Solving system... - Error: 3.36904 -> 0.00314153 in 28 FGMRES iterations. - Number of elastic quadrature points: 57144 and plastic quadrature points: 1065608 - Residual of the non-contact part of the system: 0.174753 - with a damping parameter alpha = 1 - - Newton iteration 2 - Updating active set... - Size of active set: 2335 - Assembling system... - Solving system... - Error: 2.84616 -> 0.00266184 in 25 FGMRES iterations. - Number of elastic quadrature points: 56415 and plastic quadrature points: 1066337 - Residual of the non-contact part of the system: 0.0845109 - with a damping parameter alpha = 1 - - Newton iteration 3 - Updating active set... - Size of active set: 2313 - Assembling system... - Solving system... - Error: 0.0870898 -> 8.60248e-05 in 97 FGMRES iterations. - Number of elastic quadrature points: 56802 and plastic quadrature points: 1065950 - Residual of the non-contact part of the system: 0.0148214 - with a damping parameter alpha = 1 - - Newton iteration 4 - Updating active set... - Size of active set: 2313 - Assembling system... - Solving system... - Error: 0.0148214 -> 1.46054e-05 in 72 FGMRES iterations. - Number of elastic quadrature points: 56828 and plastic quadrature points: 1065924 - Residual of the non-contact part of the system: 0.00125281 - with a damping parameter alpha = 1 - - Newton iteration 5 - Updating active set... - Size of active set: 2313 - Assembling system... - Solving system... - Error: 0.00125281 -> 1.22184e-06 in 68 FGMRES iterations. - Number of elastic quadrature points: 56828 and plastic quadrature points: 1065924 - Residual of the non-contact part of the system: 4.38909e-06 - with a damping parameter alpha = 1 - - Newton iteration 6 - Updating active set... - Size of active set: 2313 - Assembling system... - Solving system... - Error: 4.38909e-06 -> 4.30005e-09 in 189 FGMRES iterations. - Number of elastic quadrature points: 56828 and plastic quadrature points: 1065924 - Residual of the non-contact part of the system: 4.30364e-09 - with a damping parameter alpha = 1 - - Number of assembled systems = 6 - Number of Solver-Iterations = 479 - Writing graphical output... - - -+---------------------------------------------+------------+------------+ -| Total wallclock time elapsed since start | 445s | | -| | | | -| Section | no. calls | wall time | % of total | -+---------------------------------+-----------+------------+------------+ -| Assembling | 6 | 218s | 49% | -| Graphical output | 1 | 4.47s | 1% | -| Residual and lambda | 6 | 31.9s | 7.2% | -| Setup | 1 | 33s | 7.4% | -| Setup: distribute DoFs | 1 | 4.69s | 1.1% | -| Setup: matrix | 1 | 1.29s | 0.29% | -| Setup: refine mesh | 1 | 22.4s | 5% | -| Solve | 6 | 154s | 35% | -| Solve: iterate | 6 | 145s | 33% | -| Solve: setup preconditioner | 6 | 9.12s | 2.1% | -| Update solution and constraints | 6 | 1.24s | 0.28% | -+---------------------------------+-----------+------------+------------+ - -@endcode - -For each adaptive refinement cycle the iterations end if the active set doesn't -change anymore and if the residual is accurate enough. In the tables -at the end of each cycle you find informations about computing time and the -number of calls of different parts of the program like Assembling or calculating -the residual. In the second cycle there are 12 calls for the residual function -and only 10 calls for Solving or Assembling what means that two damping steps were -necessary in this cycle. - -For this simulation we used the SolutionTranfer class to interpolate the solution -of the previous cycle to new mesh of the current cycle (for the start solution of cycle 0 -we used a pure elastic solution). That worked out well for the ball but for the -Chinese symbol as obstacle it turns out that an elastic start solution for each -cycle results in fewer Newton iterations. - -In every refinement step you can observe that the acitve set - the contact points - -are iterated out at first. After that the Newton method has only to struggle with the -plasticity. For the finer meshes there is quadratic convergence not until the -last 4 or 5 Newton iterations. - - - - - - - - -
- @image html step-42-CellConstitutionColorbar.png - - @image html step-42-CellConstitutionBall2.png - -   - - @image html step-42-CellConstitutionLi2.png -
- -The picture shows the adaptive refinement and as well how much a cell is -plastified druing the contact with the ball. Remember that we consider the -norm of the deviator part of the stress in each quadrature point to -see if there is elastic or plastic behavior. In the middle of the top - -where the mesh is finest - you can see the hollow caused by the ball. The blue -color means that this cell contains only elastic quadrature points in -contrast to the red cells in which all quadrature points are plastified. -Since we used trilinear ansatz functions each cell contains eight -of these points which may or may not be elastic or plastic. -For further details see Frohne, Heister, Bangerth: Efficient -Numerical Methods For The Large-Scale, Parallel Solution Of Elastoplastic Contact -Problems, preprint. - - - -

Possibilities for extensions

- -Extend the program from a static to a quasi-static problem, perhaps by choosing a -backward-euler-scheme for the time discretization (for theoretical results see Frohne: FEM-Simulation -der Umformtechnik metallischer Oberflächen im Mikrokosmos, Ph.D. thesis, -University of Siegen, Germany, 2011). - -Like mentioned in step-41 it would be an interesting advance to consider a contact -problem with friction. In almost every mechanical process friction has a big influence. -For the modelling we have to take into account tangential stresses at the contact -surface. Also we have to observe that friction adds another nonlinearity to -our problem. - -If we simulate a frictional contact the next step to consider heat development -over the contact zone is not too far away. The heat that is caused by friction -between two bodies rises up the temperature in the deformable body and entails an -change of some material parameters. - -It might be of interest to implement more accurate, problem-adapted error -estimators for contact as well as for the plasticity. \ No newline at end of file diff --git a/deal.II/examples/step-42/doc/step-42-CellConstitution.png b/deal.II/examples/step-42/doc/step-42-CellConstitution.png deleted file mode 100644 index be03288e5b2839880c14a247b36f82785e2d78c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52558 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%0Dt5p)V5EPwoPG$wlEmJ`K?_+AC15p3V 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 V&S?G09)gn8P}fAKSj#2+e*p}P{V4zd diff --git a/deal.II/examples/step-42/doc/step-42-CellConstitutionBall.png b/deal.II/examples/step-42/doc/step-42-CellConstitutionBall.png deleted file mode 100644 index be03288e5b2839880c14a247b36f82785e2d78c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52558 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%0Dt5p)V5EPwoPG$wlEmJ`K?_+AC15p3V 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 V&S?G09)gn8P}fAKSj#2+e*p}P{V4zd diff --git a/deal.II/examples/step-42/doc/step-42-CellConstitutionBall2.png b/deal.II/examples/step-42/doc/step-42-CellConstitutionBall2.png deleted file mode 100644 index e4509806c3f9c85c1482f8279145a1e94c79edfa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25917 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 x+gqobcr2yP7O$ diff --git a/deal.II/examples/step-42/doc/step-42-CellConstitutionColorbar.png b/deal.II/examples/step-42/doc/step-42-CellConstitutionColorbar.png deleted file mode 100644 index ec9790ff6ef1a9dbef53cb42f71b3935c9f543d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6614 zcmbtZbyQSQw;w`Ex*S5fMPL8{k&qfnLZm@rXz7sd?obIuBnA{jx)ebiQc4(7>28oN ziFfAJ_pR@}wca0ZF>`0uT+Y4coW1ui_KnllR3;&!CxSpAB&sTkI^Z)JysrrG!10A=j9{yyg!t!7qevDn_0V2!0&qjdkW}*bIKe_fpkR!k@;$#l@l<9Pmqk zKyzLH##lYW%9wxUwFG1hNF4!@8PLmdG^>~K-` zfz`JGq)jI)GaM%`SA%u}GGnX~VdRQbxQ8_49C&hwe?3$bLdlqA6#e}rU%Ysc`sPi1 zcz8JJ@42X(w+=%>t}joTt{I*f7{qLCIhlS7r0eeP{_*oC+}XKIHOQ}XCSbUJHK;Rr zN;9VIP3p^+ZTb~v{iaW!zSiZl5fBh?n)@E+^dpsZD}qeMLfmD_LQw75Gd`+>j;)Kc zgG5*-xKma|g`g{4j%L^K&U7y}4$f;NlHJqY-BPFI6$zbiq(-(_()LVq_PUqkvB~gZ zjp(@TmdLlnZ7FKPToHy(S-gOixCG5_} zFeAo38Qm5rfg{6oO4`TDOsYJV)%eZ7G3u01L$q~uBSq|fvIq-PrZ7o|%jbtawD6bC zFD>0Ht;)eu2)@`;7JD|rQ}4B|b3BK_LDG(nj8xup9II4)$yL?b+De)NC5j3+GB&Pu zo~*z3HCgc6Y538`XhP5-TAAw>3~KeMxH$IYx;GZuS${CZ)|symqit*) h~7jk_C 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - - -#include - -namespace Step42 -{ - using namespace dealii; - - // @sect3{The Input class template} - - // This class has the the only purpose - // to read in data from a picture file - // that has to be stored in pbm ascii - // format. This data will be bilinear - // interpolated and provides in this way - // a function which describes an obstacle. - // - // The data which we read in by the - // function read_obstacle () from the file - // "obstacle_file.pbm" will be stored - // in a double std::vector named - // obstacle_data. - // This vector composes the base - // to calculate a piecewise bilinear - // function as a polynomial interpolation. - // This will be done by obstacle_function (). - // - // In the function run () of the class - // PlasticityContactProblem we create - // an object of the class Input which will - // be used in the class Obstacle to - // supply the obstacle function in - // update_solution_and_constraints () of - // the class PlasticityContactProblem. - - template - class Input - { - public: - Input (const char *_name) : - name (_name), - mpi_communicator (MPI_COMM_WORLD), - pcout (std::cout, - (Utilities::MPI::this_mpi_process(mpi_communicator) == 0)), - obstacle_data (0), - hx (0), - hy (0), - nx (0), - ny (0) - { - read_obstacle (name); - } - - double hv (int i, int j); - - double obstacle_function (double x,double y); - - void read_obstacle (const char *name); - - private: - const char *name; - MPI_Comm mpi_communicator; - ConditionalOStream pcout; - std::vector obstacle_data; - double hx, hy; - int nx, ny; - }; - - // This function is used in obstacle_function () - // to provide the proper value of the obstacle. - template - double Input::hv (int i, int j) - { - assert(i>=0 && i=0 && j - double Input::obstacle_function (double x,double y) - { - int ix = (int)(x/hx); - int iy = (int)(y/hy); - - if (ix<0) - ix = 0; - - if (iy<0) - iy = 0; - - if (ix>=nx-1) - ix = nx-2; - - if (iy>=ny-1) - iy = ny-2; - - double val = 0.0; - { - FullMatrix H(4,4); - Vector X(4); - Vector b(4); - - double xx = 0.0; - double yy = 0.0; - - xx = ix*hx; - yy = iy*hy; - H(0,0) = xx; - H(0,1) = yy; - H(0,2) = xx*yy; - H(0,3) = 1.0; - b(0) = hv (ix, iy); - - xx = (ix + 1)*hx; - yy = iy*hy; - H(1,0) = xx; - H(1,1) = yy; - H(1,2) = xx*yy; - H(1,3) = 1.0; - b(1) = hv (ix + 1, iy); - - xx = (ix + 1)*hx; - yy = (iy + 1)*hy; - H(2,0) = xx; - H(2,1) = yy; - H(2,2) = xx*yy; - H(2,3) = 1.0; - b(2) = hv (ix + 1, iy + 1); - - xx = ix*hx; - yy = (iy + 1)*hy; - H(3,0) = xx; - H(3,1) = yy; - H(3,2) = xx*yy; - H(3,3) = 1.0; - b(3) = hv (ix, iy + 1); - - H.gauss_jordan (); - H.vmult (X, b); - - val = X(0)*x + X(1)*y + X(2)*x*y + X(3); - } - - return val; - } - - // As mentioned above this function reads in the - // obstacle datas and stores them in the std::vector - // obstacle_data. It will be used only in run (). - template - void Input::read_obstacle (const char *name) - { - std::ifstream f(name); - - std::string temp; - f >> temp >> nx >> ny; - assert(nx>0 && ny>0); - - for (int k=0; k> val; - obstacle_data.push_back(val); - } - - hx = 1.0/(nx - 1); - hy = 1.0/(ny - 1); - - pcout << "Resolution of the scanned obstacle picture: " << nx << " x " << ny << std::endl; - } - - // @sect3{The ConstitutiveLaw class template} - - // This class provides an interface - // for a constitutive law. In this - // example we are using an elasto - // plastic material behavior with linear, - // isotropic hardening. - // For gamma = 0 we obtain perfect elasto - // plasticity behavior. - template - class ConstitutiveLaw - { - public: - ConstitutiveLaw (double _E, - double _nu, - double _sigma_0, - double _gamma, - MPI_Comm _mpi_communicator, - ConditionalOStream _pcout); - - void plast_linear_hardening (SymmetricTensor<4,dim> &stress_strain_tensor, - const SymmetricTensor<2,dim> &strain_tensor, - unsigned int &elast_points, - unsigned int &plast_points, - double &yield); - void linearized_plast_linear_hardening (SymmetricTensor<4,dim> &stress_strain_tensor_linearized, - SymmetricTensor<4,dim> &stress_strain_tensor, - const SymmetricTensor<2,dim> &strain_tensor); - inline SymmetricTensor<2,dim> get_strain (const FEValues &fe_values, - const unsigned int shape_func, - const unsigned int q_point) const; - void set_sigma_0 (double sigma_hlp) - { - sigma_0 = sigma_hlp; - } - - private: - SymmetricTensor<4,dim> stress_strain_tensor_mu; - SymmetricTensor<4,dim> stress_strain_tensor_kappa; - double E; - double nu; - double sigma_0; - double gamma; - double mu; - double kappa; - MPI_Comm mpi_communicator; - ConditionalOStream pcout; - }; - - // The constructor of the ConstitutiveLaw class sets the - // required material parameter for our deformable body: - // E -> elastic modulus - // nu -> Passion's number - // sigma_0 -> yield stress - // gamma -> hardening parameter. - // Also it supplies the stress strain tensor of forth order - // of the volumetric and deviator part. For further details - // see the documentation above. - template - ConstitutiveLaw::ConstitutiveLaw(double _E, double _nu, double _sigma_0, double _gamma, MPI_Comm _mpi_communicator, ConditionalOStream _pcout) - :E (_E), - nu (_nu), - sigma_0 (_sigma_0), - gamma (_gamma), - mpi_communicator (_mpi_communicator), - pcout (_pcout) - { - mu = E/(2*(1+nu)); - kappa = E/(3*(1-2*nu)); - stress_strain_tensor_kappa = kappa*outer_product(unit_symmetric_tensor(), unit_symmetric_tensor()); - stress_strain_tensor_mu = 2*mu*(identity_tensor() - outer_product(unit_symmetric_tensor(), unit_symmetric_tensor())/3.0); - } - - // Calculates the strain for the shape functions. - template - inline - SymmetricTensor<2,dim> ConstitutiveLaw::get_strain (const FEValues &fe_values, - const unsigned int shape_func, - const unsigned int q_point) const - { - const FEValuesExtractors::Vector displacement (0); - SymmetricTensor<2,dim> tmp; - - tmp = fe_values[displacement].symmetric_gradient (shape_func,q_point); - - return tmp; - } - - // This is the implemented constitutive law. It projects the - // deviator part of the stresses in a quadrature point back to - // the yield stress plus the linear isotropic hardening. - // Also we sum up the elastic and the plastic quadrature - // points. - template - void ConstitutiveLaw::plast_linear_hardening (SymmetricTensor<4,dim> &stress_strain_tensor, - const SymmetricTensor<2,dim> &strain_tensor, - unsigned int &elast_points, - unsigned int &plast_points, - double &yield) - { - if (dim == 3) - { - SymmetricTensor<2,dim> stress_tensor; - stress_tensor = (stress_strain_tensor_kappa + stress_strain_tensor_mu)*strain_tensor; - - SymmetricTensor<2,dim> deviator_stress_tensor = deviator(stress_tensor); - - double deviator_stress_tensor_norm = deviator_stress_tensor.norm (); - - yield = 0; - stress_strain_tensor = stress_strain_tensor_mu; - double beta = 1.0; - if (deviator_stress_tensor_norm > sigma_0) - { - beta = sigma_0/deviator_stress_tensor_norm; - stress_strain_tensor *= (gamma + (1 - gamma)*beta); - yield = 1; - plast_points += 1; - } - else - elast_points += 1; - - stress_strain_tensor += stress_strain_tensor_kappa; - } - } - - // This function returns the linearized stress strain tensor. - // It contains the derivative of the nonlinear constitutive law. - template - void ConstitutiveLaw::linearized_plast_linear_hardening (SymmetricTensor<4,dim> &stress_strain_tensor_linearized, - SymmetricTensor<4,dim> &stress_strain_tensor, - const SymmetricTensor<2,dim> &strain_tensor) - { - if (dim == 3) - { - SymmetricTensor<2,dim> stress_tensor; - stress_tensor = (stress_strain_tensor_kappa + stress_strain_tensor_mu)*strain_tensor; - - SymmetricTensor<2,dim> deviator_stress_tensor = deviator(stress_tensor); - - double deviator_stress_tensor_norm = deviator_stress_tensor.norm (); - - stress_strain_tensor = stress_strain_tensor_mu; - stress_strain_tensor_linearized = stress_strain_tensor_mu; - double beta = 1.0; - if (deviator_stress_tensor_norm > sigma_0) - { - beta = sigma_0/deviator_stress_tensor_norm; - stress_strain_tensor *= (gamma + (1 - gamma)*beta); - stress_strain_tensor_linearized *= (gamma + (1 - gamma)*beta); - deviator_stress_tensor /= deviator_stress_tensor_norm; - stress_strain_tensor_linearized -= (1 - gamma)*beta*2*mu*outer_product(deviator_stress_tensor, deviator_stress_tensor); - } - - stress_strain_tensor += stress_strain_tensor_kappa; - stress_strain_tensor_linearized += stress_strain_tensor_kappa; - } - } - - // In this namespace we provide three functions: - // one for the body force, one for the boundary displacement - // and one for the Obstacle. - namespace EquationData - { - // It possible to apply an additional body force - // but in here it is set to zero. - template - class RightHandSide : public Function - { - public: - RightHandSide () : Function(dim) {} - - virtual double value (const Point &p, - const unsigned int component = 0) const; - - virtual void vector_value (const Point &p, - Vector &values) const; - }; - - template - double RightHandSide::value (const Point &p, - const unsigned int component) const - { - double return_value = 0.0; - - if (component == 0) - return_value = 0.0; - if (component == 1) - return_value = 0.0; - if (component == 2) - return_value = 0.0; - - return return_value; - } - - template - void RightHandSide::vector_value (const Point &p, - Vector &values) const - { - for (unsigned int c=0; cn_components; ++c) - values(c) = RightHandSide::value (p, c); - } - - // This function class is used to describe the prescribed displacements - // at the boundary. But again we set this to zero. - template - class BoundaryValues : public Function - { - public: - BoundaryValues () : Function(dim) {}; - - virtual double value (const Point &p, - const unsigned int component = 0) const; - - virtual void vector_value (const Point &p, - Vector &values) const; - }; - - template - double BoundaryValues::value (const Point &p, - const unsigned int component) const - { - double return_value = 0; - - if (component == 0) - return_value = 0.0; - if (component == 1) - return_value = 0.0; - if (component == 2) - return_value = 0.0; - - return return_value; - } - - template - void BoundaryValues::vector_value (const Point &p, - Vector &values) const - { - for (unsigned int c=0; cn_components; ++c) - values(c) = BoundaryValues::value (p, c); - } - - // This function is obviously implemented to - // define the obstacle that penetrates our deformable - // body. You can choose between two ways to define - // your obstacle: to read it from a file or to use - // a function (here a ball). - template - class Obstacle : public Function - { - public: - Obstacle (std_cxx1x::shared_ptr > const &_input, bool _use_read_obstacle) : - Function(dim), - input_obstacle_copy(_input), - use_read_obstacle(_use_read_obstacle) - {} - - virtual double value (const Point &p, - const unsigned int component = 0) const; - - virtual void vector_value (const Point &p, - Vector &values) const; - - private: - std_cxx1x::shared_ptr > const &input_obstacle_copy; - bool use_read_obstacle; - }; - - template - double Obstacle::value (const Point &p, - const unsigned int component) const - { - double R = 0.03; - double return_value = 100.0; - if (component == 0) - return_value = p(0); - if (component == 1) - return_value = p(1); - if (component == 2) - { - if (use_read_obstacle) - return_value = 1.999 - input_obstacle_copy->obstacle_function (p(0), p(1)); - else - return_value = -std::sqrt (0.36 - (p(0)-0.5)*(p(0)-0.5) - (p(1)-0.5)*(p(1)-0.5)) + 1.59; - } - return return_value; - } - - template - void Obstacle::vector_value (const Point &p, - Vector &values) const - { - for (unsigned int c=0; cn_components; ++c) - values(c) = Obstacle::value (p, c); - } - } - - // @sect3{The PlasticityContactProblem class template} - - // This class supplies all function - // and variables needed to describe - // the nonlinear contact problem. It is - // close to step-41 but with some additional - // features like: handling hanging nodes, - // a Newton method, using Trilinos and p4est - // for parallel distributed computing. - // To deal with hanging nodes makes - // life a bit more complicated since - // we need an other ConstraintMatrix now. - // We create a Newton method for the - // active set method for the contact - // situation and to handle the nonlinear - // operator for the constitutive law. - - template - class PlasticityContactProblem - { - public: - PlasticityContactProblem (int _n_refinements_global); - void run (); - - private: - void make_grid (); - void setup_system(); - void assemble_nl_system (TrilinosWrappers::MPI::Vector &u); - void residual_nl_system (TrilinosWrappers::MPI::Vector &u); - void assemble_mass_matrix_diagonal (TrilinosWrappers::SparseMatrix &mass_matrix); - void update_solution_and_constraints (); - void dirichlet_constraints (); - void solve (); - void solve_newton (); - void refine_grid (); - void move_mesh (const TrilinosWrappers::MPI::Vector &_complete_displacement) const; - void output_results (const std::string &title) const; - - unsigned int n_refinements_global; - unsigned int cycle; - bool use_read_obstacle; - - MPI_Comm mpi_communicator; - - parallel::distributed::Triangulation triangulation; - - FESystem fe; - DoFHandler dof_handler; - - std_cxx1x::shared_ptr > soltrans; - - IndexSet locally_owned_dofs; - IndexSet locally_relevant_dofs; - - unsigned int number_iterations; - - ConstraintMatrix constraints; - ConstraintMatrix constraints_hanging_nodes; - ConstraintMatrix constraints_dirichlet_hanging_nodes; - - TrilinosWrappers::SparseMatrix system_matrix_newton; - - TrilinosWrappers::MPI::Vector solution; - TrilinosWrappers::MPI::Vector system_rhs_newton; - TrilinosWrappers::MPI::Vector resid_vector; - TrilinosWrappers::MPI::Vector diag_mass_matrix_vector; - Vector cell_constitution; - IndexSet active_set; - - ConditionalOStream pcout; - - TrilinosWrappers::PreconditionAMG::AdditionalData additional_data; - TrilinosWrappers::PreconditionAMG preconditioner_u; - - std_cxx1x::shared_ptr > input_obstacle; - std_cxx1x::shared_ptr > plast_lin_hard; - - double sigma_0; // Yield stress - double gamma; // Parameter for the linear isotropic hardening - double e_modul; // E-Modul - double nu; // Poisson ratio - - TimerOutput computing_timer; - }; - - // @sect3{Implementation of the PlasticityContactProblem class} - - // Next for the implementation of the class - // template that makes use of the functions - // above. As before, we will write everything - - template - PlasticityContactProblem::PlasticityContactProblem (int _n_refinements_global) - : - n_refinements_global (_n_refinements_global), - mpi_communicator (MPI_COMM_WORLD), - triangulation (mpi_communicator), - fe (FE_Q(1), dim), - dof_handler (triangulation), - pcout (std::cout, - (Utilities::MPI::this_mpi_process(mpi_communicator) == 0)), - sigma_0 (400), - gamma (0.01), - e_modul (2.0e+5), - nu (0.3), - computing_timer (MPI_COMM_WORLD, - pcout, - TimerOutput::never, - TimerOutput::wall_times) - { - plast_lin_hard.reset (new ConstitutiveLaw (e_modul, nu, sigma_0, gamma, mpi_communicator, pcout)); - } - - template - void PlasticityContactProblem::make_grid () - { - std::vector repet(3); - repet[0] = 1; - repet[1] = 1; - repet[2] = 1; - - Point p1 (0,0,0); - Point p2 (1.0, 1.0, 1.0); - GridGenerator::subdivided_hyper_rectangle (triangulation, repet, p1, p2); - - Triangulation<3>::active_cell_iterator - cell = triangulation.begin_active(), - endc = triangulation.end(); - - /* boundary_indicators: - _______ - / 9 /| - /______ / | - 8| | 8| - | 8 | / - |_______|/ - 6 - */ - - for (; cell!=endc; ++cell) - for (unsigned int face=0; face::faces_per_cell; ++face) - { - if (cell->face (face)->center ()[2] == p2(2)) - cell->face (face)->set_boundary_indicator (9); - if (cell->face (face)->center ()[0] == p1(0) || - cell->face (face)->center ()[0] == p2(0) || - cell->face (face)->center ()[1] == p1(1) || - cell->face (face)->center ()[1] == p2(1)) - cell->face (face)->set_boundary_indicator (8); - if (cell->face (face)->center ()[2] == p1(2)) - cell->face (face)->set_boundary_indicator (6); - } - - triangulation.refine_global (n_refinements_global); - } - - // In following function we setup the degrees of freedom before each refinement - // cycle. Except that we are using Trilinos here instead of PETSc most of it - // is similar to step-40. - - // We are using TimerOutput to control the scaling for the distributing the dofs - // and setting of the sparsity pattern and the system matrix. - template - void PlasticityContactProblem::setup_system () - { - { - computing_timer.enter_section("Setup: distribute DoFs"); - dof_handler.distribute_dofs (fe); - - locally_owned_dofs = dof_handler.locally_owned_dofs (); - locally_relevant_dofs.clear(); - DoFTools::extract_locally_relevant_dofs (dof_handler, - locally_relevant_dofs); - computing_timer.exit_section("Setup: distribute DoFs"); - } - - // Setup of the hanging nodes and the Dirichlet constraints. - { - constraints_hanging_nodes.clear (); - constraints_hanging_nodes.reinit (locally_relevant_dofs); - DoFTools::make_hanging_node_constraints (dof_handler, - constraints_hanging_nodes); - constraints_hanging_nodes.close (); - - pcout << " Number of active cells: " - << triangulation.n_global_active_cells() - << std::endl - << " Number of degrees of freedom: " - << dof_handler.n_dofs () - << std::endl; - - dirichlet_constraints (); - } - - // Initialization for matrices and vectors. - { - solution.reinit (locally_relevant_dofs, mpi_communicator); - system_rhs_newton.reinit (locally_owned_dofs, mpi_communicator); - resid_vector.reinit (system_rhs_newton); - diag_mass_matrix_vector.reinit (system_rhs_newton); - cell_constitution.reinit (triangulation.n_active_cells ()); - active_set.clear (); - active_set.set_size (locally_relevant_dofs.size ()); - } - - // Here we setup sparsity pattern. - { - computing_timer.enter_section("Setup: matrix"); - TrilinosWrappers::SparsityPattern sp (locally_owned_dofs, - mpi_communicator); - - DoFTools::make_sparsity_pattern (dof_handler, sp, constraints_dirichlet_hanging_nodes, false, - Utilities::MPI::this_mpi_process(mpi_communicator)); - - sp.compress(); - - system_matrix_newton.reinit (sp); - - // we are going to reuse the system - // matrix for assembling the diagonal - // of the mass matrix so that we do not - // need to allocate two sparse matrices - // at the same time: - TrilinosWrappers::SparseMatrix &mass_matrix = system_matrix_newton; - assemble_mass_matrix_diagonal (mass_matrix); - const unsigned int - start = (system_rhs_newton.local_range().first), - end = (system_rhs_newton.local_range().second); - for (unsigned int j=start; j - void PlasticityContactProblem::assemble_nl_system (TrilinosWrappers::MPI::Vector &u) - { - computing_timer.enter_section("Assembling"); - - QGauss quadrature_formula(2); - QGauss face_quadrature_formula(2); - - FEValues fe_values (fe, quadrature_formula, - UpdateFlags(update_values | - update_gradients | - update_q_points | - update_JxW_values)); - - FEFaceValues fe_values_face (fe, face_quadrature_formula, - update_values | update_quadrature_points | - update_JxW_values); - - const unsigned int dofs_per_cell = fe.dofs_per_cell; - const unsigned int n_q_points = quadrature_formula.size (); - const unsigned int n_face_q_points = face_quadrature_formula.size(); - - const EquationData::RightHandSide right_hand_side; - std::vector > right_hand_side_values (n_q_points, - Vector(dim)); - std::vector > right_hand_side_values_face (n_face_q_points, - Vector(dim)); - - FullMatrix cell_matrix (dofs_per_cell, dofs_per_cell); - Vector cell_rhs (dofs_per_cell); - - std::vector local_dof_indices (dofs_per_cell); - - typename DoFHandler::active_cell_iterator cell = dof_handler.begin_active(), - endc = dof_handler.end(); - - const FEValuesExtractors::Vector displacement (0); - - const double kappa = 1.0; - for (; cell!=endc; ++cell) - if (cell->is_locally_owned()) - { - fe_values.reinit (cell); - cell_matrix = 0; - cell_rhs = 0; - - right_hand_side.vector_value_list (fe_values.get_quadrature_points(), - right_hand_side_values); - - std::vector > strain_tensor (n_q_points); - fe_values[displacement].get_function_symmetric_gradients (u, strain_tensor); - - for (unsigned int q_point=0; q_point stress_strain_tensor_linearized; - SymmetricTensor<4,dim> stress_strain_tensor; - SymmetricTensor<2,dim> stress_tensor; - - plast_lin_hard->linearized_plast_linear_hardening (stress_strain_tensor_linearized, - stress_strain_tensor, - strain_tensor[q_point]); - - for (unsigned int i=0; iget_strain(fe_values, i, q_point); - - for (unsigned int j=0; jget_strain(fe_values, j, q_point) * - fe_values.JxW (q_point)); - } - - // the linearized part a(v^i;v^i,v) of the rhs - cell_rhs(i) += (stress_tensor * - strain_tensor[q_point] * - fe_values.JxW (q_point)); - - // the residual part a(v^i;v) of the rhs - cell_rhs(i) -= (strain_tensor[q_point] * stress_strain_tensor * - plast_lin_hard->get_strain(fe_values, i, q_point) * - fe_values.JxW (q_point)); - - // the residual part F(v) of the rhs - Tensor<1,dim> rhs_values; - rhs_values = 0; - cell_rhs(i) += (fe_values[displacement].value (i, q_point) * - rhs_values * - fe_values.JxW (q_point)); - } - } - - for (unsigned int face=0; face::faces_per_cell; ++face) - { - if (cell->face (face)->at_boundary() - && cell->face (face)->boundary_indicator () == 9) - { - fe_values_face.reinit (cell, face); - - right_hand_side.vector_value_list (fe_values_face.get_quadrature_points(), - right_hand_side_values_face); - - for (unsigned int q_point=0; q_point rhs_values; - rhs_values = 0; - for (unsigned int i=0; iget_dof_indices (local_dof_indices); - constraints.distribute_local_to_global (cell_matrix, cell_rhs, - local_dof_indices, - system_matrix_newton, system_rhs_newton, true); - }; - - system_matrix_newton.compress (VectorOperation::add); - system_rhs_newton.compress (VectorOperation::add); - - computing_timer.exit_section("Assembling"); - } - - template - void PlasticityContactProblem::residual_nl_system (TrilinosWrappers::MPI::Vector &u) - { - QGauss quadrature_formula(2); - QGauss face_quadrature_formula(2); - - FEValues fe_values (fe, quadrature_formula, - UpdateFlags(update_values | - update_gradients | - update_q_points | - update_JxW_values)); - - FEFaceValues fe_values_face (fe, face_quadrature_formula, - update_values | update_quadrature_points | - update_JxW_values); - - const unsigned int dofs_per_cell = fe.dofs_per_cell; - const unsigned int n_q_points = quadrature_formula.size (); - const unsigned int n_face_q_points = face_quadrature_formula.size(); - - const EquationData::RightHandSide right_hand_side; - std::vector > right_hand_side_values (n_q_points, - Vector(dim)); - std::vector > right_hand_side_values_face (n_face_q_points, - Vector(dim)); - - Vector cell_rhs (dofs_per_cell); - - std::vector local_dof_indices (dofs_per_cell); - - const FEValuesExtractors::Vector displacement (0); - - typename DoFHandler::active_cell_iterator cell = dof_handler.begin_active(), - endc = dof_handler.end(); - - unsigned int elast_points = 0; - unsigned int plast_points = 0; - double yield = 0; - unsigned int cell_number = 0; - cell_constitution = 0; - - for (; cell!=endc; ++cell) - if (cell->is_locally_owned()) - { - fe_values.reinit (cell); - cell_rhs = 0; - - right_hand_side.vector_value_list (fe_values.get_quadrature_points(), - right_hand_side_values); - - std::vector > strain_tensor (n_q_points); - fe_values[displacement].get_function_symmetric_gradients (u, strain_tensor); - - for (unsigned int q_point=0; q_point stress_strain_tensor; - SymmetricTensor<2,dim> stress_tensor; - - plast_lin_hard->plast_linear_hardening (stress_strain_tensor, strain_tensor[q_point], - elast_points, plast_points, yield); - - cell_constitution (cell_number) += yield; - for (unsigned int i=0; iget_strain(fe_values, i, q_point) * - fe_values.JxW (q_point)); - - Tensor<1,dim> rhs_values; - rhs_values = 0; - cell_rhs(i) += ((fe_values[displacement].value (i, q_point) * - rhs_values) * - fe_values.JxW (q_point)); - }; - }; - - for (unsigned int face=0; face::faces_per_cell; ++face) - { - if (cell->face (face)->at_boundary() - && cell->face (face)->boundary_indicator () == 9) - { - fe_values_face.reinit (cell, face); - - right_hand_side.vector_value_list (fe_values_face.get_quadrature_points(), - right_hand_side_values_face); - - for (unsigned int q_point=0; q_point rhs_values; - rhs_values = 0; - for (unsigned int i=0; iget_dof_indices (local_dof_indices); - constraints_dirichlet_hanging_nodes.distribute_local_to_global (cell_rhs, - local_dof_indices, - system_rhs_newton); - - cell_number += 1; - } - else - { - cell_constitution (cell_number) = 0; - cell_number += 1; - }; - - cell_constitution /= n_q_points; - cell_constitution.compress (VectorOperation::add); - system_rhs_newton.compress (VectorOperation::add); - - unsigned int sum_elast_points = Utilities::MPI::sum(elast_points, mpi_communicator); - unsigned int sum_plast_points = Utilities::MPI::sum(plast_points, mpi_communicator); - pcout << " Number of elastic quadrature points: " << sum_elast_points - << " and plastic quadrature points: " << sum_plast_points << std::endl; - } - - template - void PlasticityContactProblem::assemble_mass_matrix_diagonal (TrilinosWrappers::SparseMatrix &mass_matrix) - { - QTrapez face_quadrature_formula; - - FEFaceValues fe_values_face (fe, face_quadrature_formula, - update_values | - update_quadrature_points | - update_JxW_values); - - const unsigned int dofs_per_cell = fe.dofs_per_cell; - const unsigned int n_face_q_points = face_quadrature_formula.size(); - - FullMatrix cell_matrix (dofs_per_cell, dofs_per_cell); - Tensor<1,dim,double> ones (dim); - for (unsigned i=0; i local_dof_indices (dofs_per_cell); - - const FEValuesExtractors::Vector displacement (0); - - typename DoFHandler::active_cell_iterator - cell = dof_handler.begin_active(), - endc = dof_handler.end(); - - for (; cell!=endc; ++cell) - if (cell->is_locally_owned()) - for (unsigned int face=0; face::faces_per_cell; ++face) - if (cell->face (face)->at_boundary() - && cell->face (face)->boundary_indicator () == 9) - { - fe_values_face.reinit (cell, face); - cell_matrix = 0; - - for (unsigned int q_point=0; q_pointget_dof_indices (local_dof_indices); - - constraints_dirichlet_hanging_nodes.distribute_local_to_global (cell_matrix, - local_dof_indices, - mass_matrix); - } - - mass_matrix.compress (VectorOperation::add); - } - - // @sect4{PlasticityContactProblem::update_solution_and_constraints} - - // Projection and updating of the active set - // for the dofs which penetrates the obstacle. - template - void PlasticityContactProblem::update_solution_and_constraints () - { - computing_timer.enter_section("Update solution and constraints"); - - const EquationData::Obstacle obstacle (input_obstacle, use_read_obstacle); - std::vector vertex_touched (dof_handler.n_dofs (), false); - - typename DoFHandler::active_cell_iterator - cell = dof_handler.begin_active(), - endc = dof_handler.end(); - - TrilinosWrappers::MPI::Vector distributed_solution (system_rhs_newton); - distributed_solution = solution; - TrilinosWrappers::MPI::Vector lambda (solution); - lambda = resid_vector; - TrilinosWrappers::MPI::Vector diag_mass_matrix_vector_relevant (solution); - diag_mass_matrix_vector_relevant = diag_mass_matrix_vector; - - constraints.reinit(locally_relevant_dofs); - active_set.clear (); - IndexSet active_set_locally_owned; - active_set_locally_owned.set_size (locally_owned_dofs.size ()); - const double c = 100.0*e_modul; - - for (; cell!=endc; ++cell) - if (cell->is_locally_owned()) - for (unsigned int face=0; face::faces_per_cell; ++face) - if (cell->face (face)->at_boundary() - && cell->face (face)->boundary_indicator () == 9) - for (unsigned int v=0; v::vertices_per_cell; ++v) - { - unsigned int index_z = cell->face (face)->vertex_dof_index (v,2); - - if (vertex_touched[cell->face (face)->vertex_index(v)] == false) - vertex_touched[cell->face (face)->vertex_index(v)] = true; - else - continue; - - // the local row where - Point point (cell->face (face)->vertex (v)[0], - cell->face (face)->vertex (v)[1], - cell->face (face)->vertex (v)[2]); - - double obstacle_value = obstacle.value (point, 2); - double solution_index_z = solution (index_z); - double gap = obstacle_value - point (2); - - -// std::cout << "lambda = " << lambda (index_z) -// << ", solution_index_z - gap = " << solution_index_z - gap -// << ", diag_mass_matrix_vector_relevant = " << diag_mass_matrix_vector_relevant (index_z) -// << std::endl; - - if (lambda (index_z) + - c * - diag_mass_matrix_vector_relevant (index_z) * - (solution_index_z - gap) - > 0 && - !(constraints_hanging_nodes.is_constrained(index_z))) - { - constraints.add_line (index_z); - constraints.set_inhomogeneity (index_z, gap); - - distributed_solution (index_z) = gap; - - if (locally_relevant_dofs.is_element (index_z)) - active_set.add_index (index_z); - - if (locally_owned_dofs.is_element (index_z)) - active_set_locally_owned.add_index (index_z); - } - } - distributed_solution.compress (VectorOperation::insert); - - unsigned int sum_contact_constraints = Utilities::MPI::sum(active_set_locally_owned.n_elements (), - mpi_communicator); - pcout << " Size of active set: " << sum_contact_constraints < - void PlasticityContactProblem::dirichlet_constraints () - { - /* boundary_indicators: - _______ - / 9 /| - /______ / | - 8| | 8| - | 8 | / - |_______|/ - 6 - */ - - constraints_dirichlet_hanging_nodes.reinit (locally_relevant_dofs); - constraints_dirichlet_hanging_nodes.merge (constraints_hanging_nodes); - - // interpolate all components of the solution - VectorTools::interpolate_boundary_values (dof_handler, - 6, - EquationData::BoundaryValues(), - constraints_dirichlet_hanging_nodes, - ComponentMask()); - - // interpolate x- and y-components of the - // solution (this is a bit mask, so apply - // operator| ) - FEValuesExtractors::Scalar x_displacement(0); - FEValuesExtractors::Scalar y_displacement(1); - VectorTools::interpolate_boundary_values (dof_handler, - 8, - EquationData::BoundaryValues(), - constraints_dirichlet_hanging_nodes, - (fe.component_mask(x_displacement) - | - fe.component_mask(y_displacement))); - constraints_dirichlet_hanging_nodes.close (); - } - - // @sect4{PlasticityContactProblem::solve} - - // In addition to step-41 we have - // to deal with the hanging node - // constraints. Again we also consider - // the locally_owned_dofs only by - // creating the vector distributed_solution. - // - // For the hanging nodes we have to apply - // the set_zero function to system_rhs_newton. - // This is necessary if a hanging node value x_0 - // has one neighbor which is in contact with - // value x_0 and one neighbor which is not with - // value x_1. This leads to an inhomogeneity - // constraint with value x_1/2 = gap/2 in the - // ConstraintMatrix. - // So the corresponding entries in the - // ride-hang-side are non-zero with a - // meaningless value. These values have to - // to set to zero. - - // The rest of the function is similar to - // step-41 except that we use a FGMRES-solver - // instead of CG. For a very small hardening - // value gamma the linear system becomes - // almost semi definite but still symmetric. - template - void PlasticityContactProblem::solve () - { - computing_timer.enter_section ("Solve"); - - TrilinosWrappers::MPI::Vector distributed_solution (system_rhs_newton); - distributed_solution = solution; - - constraints_hanging_nodes.set_zero (distributed_solution); - constraints_hanging_nodes.set_zero (system_rhs_newton); - distributed_solution.compress(VectorOperation::insert); - system_rhs_newton.compress(VectorOperation::insert); - - computing_timer.enter_section("Solve: setup preconditioner"); - - preconditioner_u.initialize (system_matrix_newton, additional_data); - - computing_timer.exit_section("Solve: setup preconditioner"); - - computing_timer.enter_section("Solve: iterate"); - - PrimitiveVectorMemory mem; - TrilinosWrappers::MPI::Vector tmp (system_rhs_newton); - const double solver_tolerance = 1e-3 * - system_matrix_newton.residual (tmp, distributed_solution, system_rhs_newton); - -// SolverControl solver_control (system_matrix_newton.m(), solver_tolerance); -// SolverFGMRES -// solver(solver_control, mem, -// SolverFGMRES:: -// AdditionalData(30, true)); -// -// solver.solve(system_matrix_newton, distributed_solution, system_rhs_newton, preconditioner_u); -// -// pcout << " Error: " << solver_control.initial_value() -// << " -> " << solver_control.last_value() -// << " in " << solver_control.last_step() -// << " FGMRES iterations." -// << std::endl; - - SolverControl solver_control (system_matrix_newton.m(), solver_tolerance); - SolverBicgstab - solver(solver_control, mem, - SolverBicgstab:: - AdditionalData(false, 1.e-10)); - - solver.solve(system_matrix_newton, distributed_solution, system_rhs_newton, preconditioner_u); - - pcout << " Error: " << solver_control.initial_value() - << " -> " << solver_control.last_value() - << " in " << solver_control.last_step() - << " Bicgstab iterations." - << std::endl; - - computing_timer.exit_section("Solve: iterate"); - - number_iterations += solver_control.last_step(); - - constraints.distribute (distributed_solution); - - solution = distributed_solution; - - computing_timer.exit_section("Solve"); - } - - // @sect4{PlasticityContactProblem::solve_newton} - - // In this function the damped Newton method is implemented. - // That means two nested loops: the outer loop for the newton - // iteration and the inner loop for the damping steps which - // will be used only if necessary. To obtain a good and reasonable - // starting value we solve an elastic problem in very first step (j=1). - template - void PlasticityContactProblem::solve_newton () - { - double resid=0; - double resid_old=100000; - TrilinosWrappers::MPI::Vector old_solution (system_rhs_newton); - TrilinosWrappers::MPI::Vector res (system_rhs_newton); - TrilinosWrappers::MPI::Vector tmp_vector (system_rhs_newton); - - std::vector > constant_modes; - DoFTools::extract_constant_modes (dof_handler, - ComponentMask(), - constant_modes); - - double sigma_hlp = sigma_0; - - additional_data.constant_modes = constant_modes; - additional_data.elliptic = true; - additional_data.n_cycles = 1; - additional_data.w_cycle = false; - additional_data.output_details = false; - additional_data.smoother_sweeps = 2; - additional_data.aggregation_threshold = 1e-2; - - IndexSet active_set_old (active_set); - unsigned int j = 1; - unsigned int number_assemble_system = 0; - for (; j<=100; j++) - { - if (j == 1 && cycle == 0) - plast_lin_hard->set_sigma_0 (1e+10); - else if (j == 2 || cycle > 0) - plast_lin_hard->set_sigma_0 (sigma_hlp); - - pcout << " " <(i)); - old_solution = tmp_vector; - old_solution.sadd(1-a,a, distributed_solution); - old_solution.compress (VectorOperation::add); - - computing_timer.enter_section("Residual and lambda"); - - system_rhs_newton = 0; - - solution = old_solution; - residual_nl_system (solution); - res = system_rhs_newton; - - const unsigned int - start_res = (res.local_range().first), - end_res = (res.local_range().second); - for (unsigned int n=start_res; n::type_dof_data, - data_component_interpretation); - data_out.add_data_vector (lambda, std::vector(dim, "Residual"), - DataOut::type_dof_data, - data_component_interpretation); - data_out.add_data_vector (active_set, std::vector(dim, "ActiveSet"), - DataOut::type_dof_data, - data_component_interpretation); - - Vector subdomain (triangulation.n_active_cells()); - for (unsigned int i=0; i filenames; - for (unsigned int i=0; - i - void PlasticityContactProblem::run () - { - use_read_obstacle = false; - if (use_read_obstacle) - { - pcout << "Read the obstacle from a file." << std::endl; - input_obstacle.reset (new Input("obstacle_file.pbm")); - pcout << "Obstacle is available now." << std::endl; - } - - const unsigned int n_cycles = 6; - for (cycle=0; cycle(dof_handler)); - refine_grid (); - computing_timer.exit_section("Setup: refine mesh"); - } - - setup_system (); - - if (cycle > 0) - { - TrilinosWrappers::MPI::Vector distributed_solution (system_rhs_newton); - distributed_solution = solution; - soltrans->interpolate(distributed_solution); - solution = distributed_solution; - } - - computing_timer.exit_section("Setup"); - - solve_newton (); - - pcout << " Writing graphical output..." << std::endl; - computing_timer.enter_section("Graphical output"); - - std::ostringstream filename_solution; - filename_solution << "solution-"; - filename_solution << cycle; - output_results (filename_solution.str ()); - - computing_timer.exit_section("Graphical output"); - - computing_timer.print_summary(); - computing_timer.reset(); - } - } -} - -// @sect3{The main function} - -int main (int argc, char *argv[]) -{ - using namespace dealii; - using namespace Step42; - - deallog.depth_console (0); - - Utilities::MPI::MPI_InitFinalize mpi_initialization (argc, argv); - { - int _n_refinements_global = 3; - - if (argc == 2) - _n_refinements_global = atoi(argv[1]); - - PlasticityContactProblem<3> laplace_problem_3d (_n_refinements_global); - laplace_problem_3d.run (); - } - - return 0; -} diff --git a/deal.II/examples/step-47/CMakeLists.txt b/deal.II/examples/step-47/CMakeLists.txt deleted file mode 100644 index 0321ee6c15..0000000000 --- a/deal.II/examples/step-47/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -## -# CMake script for the step-47 tutorial program: -## - -# Set the name of the project and target: -SET(TARGET "step-47") - -# Declare all source files the target consists of: -SET(TARGET_SRC - ${TARGET}.cc - # You can specify additional files here! - ) - -# Usually, you will not need to modify anything beyond this point... - -CMAKE_MINIMUM_REQUIRED(VERSION 2.8.8) - -FIND_PACKAGE(deal.II 8.0 QUIET - HINTS ${deal.II_DIR} ${DEAL_II_DIR} ../ ../../ $ENV{DEAL_II_DIR} - ) -IF(NOT ${deal.II_FOUND}) - MESSAGE(FATAL_ERROR "\n" - "*** Could not locate deal.II. ***\n\n" - "You may want to either pass a flag -DDEAL_II_DIR=/path/to/deal.II to cmake\n" - "or set an environment variable \"DEAL_II_DIR\" that contains this path." - ) -ENDIF() - -DEAL_II_INITIALIZE_CACHED_VARIABLES() -PROJECT(${TARGET}) -DEAL_II_INVOKE_AUTOPILOT() diff --git a/deal.II/examples/step-47/doc/builds-on b/deal.II/examples/step-47/doc/builds-on deleted file mode 100644 index 9fdd726254..0000000000 --- a/deal.II/examples/step-47/doc/builds-on +++ /dev/null @@ -1 +0,0 @@ -step-5 diff --git a/deal.II/examples/step-47/doc/intro.dox b/deal.II/examples/step-47/doc/intro.dox deleted file mode 100644 index 1518606e43..0000000000 --- a/deal.II/examples/step-47/doc/intro.dox +++ /dev/null @@ -1,3 +0,0 @@ - -

Introduction

- diff --git a/deal.II/examples/step-47/doc/kind b/deal.II/examples/step-47/doc/kind deleted file mode 100644 index 15a13db451..0000000000 --- a/deal.II/examples/step-47/doc/kind +++ /dev/null @@ -1 +0,0 @@ -basic diff --git a/deal.II/examples/step-47/doc/points.dat b/deal.II/examples/step-47/doc/points.dat deleted file mode 100644 index 01ce16ad3c..0000000000 --- a/deal.II/examples/step-47/doc/points.dat +++ /dev/null @@ -1,21 +0,0 @@ -#xfem quadrature Points -0.781998 0.781998 -0.941587 0.72508 -0.72508 0.941587 -0.926335 0.926335 -0.397329 0.926335 -0.583333 0.72508 -0.583333 0.941587 -0.686004 0.781998 -0.72508 0.583333 -0.926335 0.397329 -0.781998 0.686004 -0.941587 0.583333 -0.115331 0.315492 -0.430422 0.60008 -0.069578 0.816587 -0.259669 0.892842 -0.315492 0.115331 -0.816587 0.069578 -0.60008 0.430422 -0.892842 0.259669 diff --git a/deal.II/examples/step-47/doc/results.dox b/deal.II/examples/step-47/doc/results.dox deleted file mode 100644 index f4c6feefb5..0000000000 --- a/deal.II/examples/step-47/doc/results.dox +++ /dev/null @@ -1 +0,0 @@ -

Results

diff --git a/deal.II/examples/step-47/doc/tooltip b/deal.II/examples/step-47/doc/tooltip deleted file mode 100644 index 00262bfbfb..0000000000 --- a/deal.II/examples/step-47/doc/tooltip +++ /dev/null @@ -1 +0,0 @@ -Adaptive local refinement. Higher order elements. \ No newline at end of file diff --git a/deal.II/examples/step-47/doc/vertices.dat b/deal.II/examples/step-47/doc/vertices.dat deleted file mode 100644 index 8d1ef87323..0000000000 --- a/deal.II/examples/step-47/doc/vertices.dat +++ /dev/null @@ -1,20 +0,0 @@ -#vertices of xfem subcells -0 0 -1 0 -1 1 -0 1 - -0.25 1 -1 0.25 - -0.625 0.625 -0.75 0.75 - -0.75 0.75 -0.625 1 - -0.75 0.75 -1 0.625 - -0 0 -0.625 0.625 diff --git a/deal.II/examples/step-47/step-47.cc b/deal.II/examples/step-47/step-47.cc deleted file mode 100644 index fa212abae8..0000000000 --- a/deal.II/examples/step-47/step-47.cc +++ /dev/null @@ -1,1137 +0,0 @@ -// --------------------------------------------------------------------- -// $Id$ -// -// Copyright (C) 2011 - 2013 by the deal.II authors -// -// This file is part of the deal.II library. -// -// The deal.II library is free software; you can use it, redistribute -// it, and/or modify it under the terms of the GNU Lesser General -// Public License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// The full text of the license can be found in the file LICENSE at -// the top level of the deal.II distribution. -// -// --------------------------------------------------------------------- - -/* - * Author: Wolfgang Bangerth, University of Heidelberg, 2000 - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - - -#include - -#include - -#include - -namespace Step47 -{ - using namespace dealii; - - - - double sign (double d) - { - if (d > 0) - return 1; - else if (d < 0) - return -1; - else - return 0; - } - - - template - class LaplaceProblem - { - public: - LaplaceProblem (); - ~LaplaceProblem (); - - void run (); - - private: - bool interface_intersects_cell (const typename Triangulation::cell_iterator &cell) const; - std::pair > compute_quadrature(const Quadrature &plain_quadrature, const typename hp::DoFHandler::active_cell_iterator &cell, const std::vector &level_set_values); - void append_quadrature(const Quadrature &plain_quadrature, - const std::vector > &v , - std::vector > &xfem_points, - std::vector &xfem_weights); - - void setup_system (); - void assemble_system (); - void solve (); - void refine_grid (); - void output_results (const unsigned int cycle) const; - void compute_error () const; - - Triangulation triangulation; - - hp::DoFHandler dof_handler; - hp::FECollection fe_collection; - - ConstraintMatrix constraints; - - SparsityPattern sparsity_pattern; - SparseMatrix system_matrix; - - Vector solution; - Vector system_rhs; - }; - - - - - template - class Coefficient : public Function - { - public: - Coefficient () : Function() {} - - virtual double value (const Point &p, - const unsigned int component = 0) const; - - virtual void value_list (const std::vector > &points, - std::vector &values, - const unsigned int component = 0) const; - }; - - - - template - double Coefficient::value (const Point &p, - const unsigned int) const - { - if (p.square() < 0.5*0.5) - return 20; - else - return 1; - } - - - - template - void Coefficient::value_list (const std::vector > &points, - std::vector &values, - const unsigned int component) const - { - const unsigned int n_points = points.size(); - - Assert (values.size() == n_points, - ExcDimensionMismatch (values.size(), n_points)); - - Assert (component == 0, - ExcIndexRange (component, 0, 1)); - - for (unsigned int i=0; i - double exact_solution (const Point &p) - { - const double r = p.norm(); - - return (r < 0.5 - ? - 1./20 * (-1./4*r*r + 61./16) - : - 1./4 * (1-r*r)); - } - - - template - LaplaceProblem::LaplaceProblem () - : - dof_handler (triangulation) - { - fe_collection.push_back (FESystem (FE_Q(1), 1, - FE_Nothing(), 1)); - fe_collection.push_back (FESystem (FE_Q(1), 1, - FE_Q(1), 1)); - } - - - - template - LaplaceProblem::~LaplaceProblem () - { - dof_handler.clear (); - } - - - - template - double - level_set (const Point &p) - { - return p.norm() - 0.5; - } - - - - template - Tensor<1,dim> - grad_level_set (const Point &p) - { - return p / p.norm(); - } - - - - template - bool - LaplaceProblem:: - interface_intersects_cell (const typename Triangulation::cell_iterator &cell) const - { - for (unsigned int v=0; v::vertices_per_cell-1; ++v) - if (level_set(cell->vertex(v)) * level_set(cell->vertex(v+1)) < 0) - return true; - - // we get here only if all vertices have the same sign, which means that - // the cell is not intersected - return false; - } - - - - template - void LaplaceProblem::setup_system () - { - for (typename hp::DoFHandler::cell_iterator cell - = dof_handler.begin_active(); - cell != dof_handler.end(); ++cell) - if (interface_intersects_cell(cell) == false) - cell->set_active_fe_index(0); - else - cell->set_active_fe_index(1); - - dof_handler.distribute_dofs (fe_collection); - - solution.reinit (dof_handler.n_dofs()); - system_rhs.reinit (dof_handler.n_dofs()); - - - constraints.clear (); -//TODO: fix this, it currently crashes - // DoFTools::make_hanging_node_constraints (dof_handler, constraints); - -//TODO: component 1 must satisfy zero boundary conditions - constraints.close(); - - - CompressedSparsityPattern c_sparsity(dof_handler.n_dofs()); - DoFTools::make_sparsity_pattern (dof_handler, c_sparsity); - - constraints.condense (c_sparsity); - - sparsity_pattern.copy_from(c_sparsity); - - system_matrix.reinit (sparsity_pattern); - } - - - template - void LaplaceProblem::assemble_system () - { - const QGauss quadrature_formula(3); - - - FEValues plain_fe_values (fe_collection[0], quadrature_formula, - update_values | update_gradients | - update_quadrature_points | update_JxW_values); - FEValues enriched_fe_values (fe_collection[1], quadrature_formula, - update_values | update_gradients | - update_quadrature_points | update_JxW_values); - - const unsigned int n_q_points = quadrature_formula.size(); - - FullMatrix cell_matrix; - Vector cell_rhs; - - std::vector local_dof_indices; - - const Coefficient coefficient; - std::vector coefficient_values (n_q_points); - - typename hp::DoFHandler::active_cell_iterator - cell = dof_handler.begin_active(), - endc = dof_handler.end(); - - for (; cell!=endc; ++cell) - { - const unsigned int dofs_per_cell = cell->get_fe().dofs_per_cell; - cell_matrix.reinit (dofs_per_cell, dofs_per_cell); - cell_rhs.reinit (dofs_per_cell); - - cell_matrix = 0; - cell_rhs = 0; - - if (cell->active_fe_index() == 0) - { - plain_fe_values.reinit (cell); - - coefficient_values.resize (plain_fe_values.n_quadrature_points); - coefficient.value_list (plain_fe_values.get_quadrature_points(), - coefficient_values); - - for (unsigned int q_point=0; q_pointactive_fe_index() == 1, ExcInternalError()); - Assert (interface_intersects_cell(cell) == true, ExcInternalError()); - - std::vector level_set_values (GeometryInfo::vertices_per_cell); - for (unsigned int v=0; v::vertices_per_cell; ++v) - level_set_values[v] = level_set (cell->vertex(v)); - - FEValues this_fe_values (fe_collection[1], - compute_quadrature(quadrature_formula, cell, - level_set_values).second, - update_values | update_gradients | - update_quadrature_points | update_JxW_values ); - - this_fe_values.reinit (cell); - - coefficient_values.resize (this_fe_values.n_quadrature_points); - coefficient.value_list (this_fe_values.get_quadrature_points(), - coefficient_values); - - for (unsigned int q_point=0; q_pointget_fe().system_to_component_index(i).first == 0) - { - for (unsigned int j=0; jget_fe().system_to_component_index(j).first == 0) - cell_matrix(i,j) += (coefficient_values[q_point] * - this_fe_values.shape_grad(i,q_point) * - this_fe_values.shape_grad(j,q_point) * - this_fe_values.JxW(q_point)); - else - cell_matrix(i,j) += (coefficient_values[q_point] * - this_fe_values.shape_grad(i,q_point) - * - ((std::fabs(level_set(this_fe_values.quadrature_point(q_point))) - - - std::fabs(level_set(cell->vertex(cell->get_fe().system_to_component_index(j).second))))* - this_fe_values.shape_grad(j,q_point) - + - grad_level_set(this_fe_values.quadrature_point(q_point)) * - sign(level_set(this_fe_values.quadrature_point(q_point))) * - this_fe_values.shape_value(j,q_point)) * - this_fe_values.JxW(q_point)); - - cell_rhs(i) += (this_fe_values.shape_value(i,q_point) * - 1.0 * - this_fe_values.JxW(q_point)); - } - else - { - for (unsigned int j=0; jget_fe().system_to_component_index(j).first == 0) - cell_matrix(i,j) += (coefficient_values[q_point] * - ((std::fabs(level_set(this_fe_values.quadrature_point(q_point))) - - - std::fabs(level_set(cell->vertex(cell->get_fe().system_to_component_index(i).second))))* - this_fe_values.shape_grad(i,q_point) - + - grad_level_set(this_fe_values.quadrature_point(q_point)) * - sign(level_set(this_fe_values.quadrature_point(q_point))) * - this_fe_values.shape_value(i,q_point)) * - this_fe_values.shape_grad(j,q_point) * - this_fe_values.JxW(q_point)); - else - cell_matrix(i,j) += (coefficient_values[q_point] * - ((std::fabs(level_set(this_fe_values.quadrature_point(q_point))) - - - std::fabs(level_set(cell->vertex(cell->get_fe().system_to_component_index(i).second))))* - this_fe_values.shape_grad(i,q_point) - + - grad_level_set(this_fe_values.quadrature_point(q_point)) * - sign(level_set(this_fe_values.quadrature_point(q_point))) * - this_fe_values.shape_value(i,q_point)) * - ((std::fabs(level_set(this_fe_values.quadrature_point(q_point))) - - - std::fabs(level_set(cell->vertex(cell->get_fe().system_to_component_index(j).second))))* - this_fe_values.shape_grad(j,q_point) - + - grad_level_set(this_fe_values.quadrature_point(q_point)) * - sign(level_set(this_fe_values.quadrature_point(q_point))) * - this_fe_values.shape_value(j,q_point)) * - this_fe_values.JxW(q_point)); - - cell_rhs(i) += ((std::fabs(level_set(this_fe_values.quadrature_point(q_point))) - - - std::fabs(level_set(cell->vertex(cell->get_fe().system_to_component_index(i).second))))* - this_fe_values.shape_value(i,q_point) * - 1.0 * - this_fe_values.JxW(q_point)); - } - } - - local_dof_indices.resize (dofs_per_cell); - cell->get_dof_indices (local_dof_indices); - constraints.distribute_local_to_global (cell_matrix, cell_rhs, - local_dof_indices, - system_matrix, system_rhs); - } - - - std::map boundary_values; - VectorTools::interpolate_boundary_values (dof_handler, - 0, - ZeroFunction(2), - boundary_values); - MatrixTools::apply_boundary_values (boundary_values, - system_matrix, - solution, - system_rhs); - - } - -// To integrate the enriched elements we have to find the geometrical -// decomposition of the original element in subelements. The subelements are -// used to integrate the elements on both sides of the discontinuity. The -// disontinuity line is approximated by a piece-wise linear interpolation -// between the intersection of the discontinuity with the edges of the -// elements. The vector level_set_values has the values of the level set -// function at the vertices of the elements. From these values can be found by -// linear interpolation the intersections. There are three kind of -// decomposition that are considered. Type 1: there is not cut. Type 2: a -// corner of the element is cut. Type 3: two corners are cut. - - template - std::pair > - LaplaceProblem::compute_quadrature (const Quadrature &plain_quadrature, - const typename hp::DoFHandler::active_cell_iterator &cell, - const std::vector &level_set_values ) - { - - unsigned int type = 0; - - // find the type of cut - int sign_ls[GeometryInfo::vertices_per_cell]; - for (unsigned int v=0; v::vertices_per_cell; ++v) - { - if (level_set_values[v] > 0) sign_ls[v] = 1; - else if (level_set_values[v] < 0) sign_ls[v] = -1; - else sign_ls[v] = 0; - } - - // the sign of the level set function at the 4 nodes of the elements can - // be positive + or negative - depending on the sign of the level set - // function we have the folloing three classes of decomposition type 1: - // ++++, ---- type 2: -+++, +-++, ++-+, +++-, +---, -+--, --+-, ---+ type - // 3: +--+, ++--, +-+-, -++-, --++, -+-+ - - if ( sign_ls[0]==sign_ls[1] & sign_ls[0]==sign_ls[2] & sign_ls[0]==sign_ls[3] ) type =1; - else if ( sign_ls[0]*sign_ls[1]*sign_ls[2]*sign_ls[3] < 0 ) type = 2; - else type = 3; - - unsigned int Pos = 100; - - Point v0(0,0); - Point v1(1,0); - Point v2(0,1); - Point v3(1,1); - - Point A(0,0); - Point B(0,0); - Point C(0,0); - Point D(0,0); - Point E(0,0); - Point F(0,0); - - if (type == 1) - return std::pair >(1, plain_quadrature); - - if (type==2) - { - const unsigned int n_q_points = plain_quadrature.size(); - - // loop over all subelements for integration in type 2 there are 5 - // subelements - - Quadrature xfem_quadrature(5*n_q_points); - - std::vector > v(GeometryInfo::vertices_per_cell); - - if (sign_ls[0]!=sign_ls[1] && sign_ls[0]!=sign_ls[2] && sign_ls[0]!=sign_ls[3]) Pos = 0; - else if (sign_ls[1]!=sign_ls[0] && sign_ls[1]!=sign_ls[2] && sign_ls[1]!=sign_ls[3]) Pos = 1; - else if (sign_ls[2]!=sign_ls[0] && sign_ls[2]!=sign_ls[1] && sign_ls[2]!=sign_ls[3]) Pos = 2; - else if (sign_ls[3]!=sign_ls[0] && sign_ls[3]!=sign_ls[1] && sign_ls[3]!=sign_ls[2]) Pos = 3; - else assert(0); // error message - - // Find cut coordinates - - // deal.ii local coordinates - - // 2-------3 | | | | | | 0-------1 - - if (Pos == 0) - { - A[0] = 1. - level_set_values[1]/(level_set_values[1]-level_set_values[0]); - B[1] = 1. - level_set_values[2]/(level_set_values[2]-level_set_values[0]); - A(1) = 0.; - B(0) = 0.; - C(0) = 0.5*( A(0) + B(0) ); - C(1) = 0.5*( A(1) + B(1) ); - D(0) = 2./3. * C(0); - D(1) = 2./3. * C(1); - E(0) = 0.5*A(0); - E(1) = 0.; - F(0) = 0.; - F(1) = 0.5*B(1); - } - else if (Pos == 1) - { - A[0] = level_set_values[0]/(level_set_values[0]-level_set_values[1]); - B[1] = 1 - level_set_values[3]/(level_set_values[3]-level_set_values[1]); - A(1) = 0.; - B(0) = 1.; - C(0) = 0.5*( A(0) + B(0) ); - C(1) = 0.5*( A(1) + B(1) ); - D(0) = 1./3. + 2./3. * C(0); - D(1) = 2./3. * C(1); - E(0) = 0.5*(1 + A(0)); - E(1) = 0.; - F(0) = 1.; - F(1) = 0.5*B(1); - } - else if (Pos == 2) - { - A[0] = 1 - level_set_values[3]/(level_set_values[3]-level_set_values[2]); - B[1] = level_set_values[0]/(level_set_values[0]-level_set_values[2]); - A(1) = 1.; - B(0) = 0.; - C(0) = 0.5*( A(0) + B(0) ); - C(1) = 0.5*( A(1) + B(1) ); - D(0) = 2./3. * C(0); - D(1) = 1./3. + 2./3. * C(1); - E(0) = 0.5* A(0); - E(1) = 1.; - F(0) = 0.; - F(1) = 0.5*( 1. + B(1) ); - } - else if (Pos == 3) - { - A[0] = level_set_values[2]/(level_set_values[2]-level_set_values[3]); - B[1] = level_set_values[1]/(level_set_values[1]-level_set_values[3]); - A(1) = 1.; - B(0) = 1.; - C(0) = 0.5*( A(0) + B(0) ); - C(1) = 0.5*( A(1) + B(1) ); - D(0) = 1./3. + 2./3. * C(0); - D(1) = 1./3. + 2./3. * C(1); - E(0) = 0.5*( 1. + A(0) ); - E(1) = 1.; - F(0) = 1.; - F(1) = 0.5*( 1. + B(1) ); - } - - //std::cout << A << std::endl; std::cout << B << std::endl; std::cout - //<< C << std::endl; std::cout << D << std::endl; std::cout << E << - //std::endl; std::cout << F << std::endl; - - std::string filename = "vertices.dat"; - std::ofstream output (filename.c_str()); - output << "#vertices of xfem subcells" << std::endl; - output << v0(0) << " " << v0(1) << std::endl; - output << v1(0) << " " << v1(1) << std::endl; - output << v3(0) << " " << v3(1) << std::endl; - output << v2(0) << " " << v2(1) << std::endl; - output << std::endl; - output << A(0) << " " << A(1) << std::endl; - output << B(0) << " " << B(1) << std::endl; - output << std::endl; - output << C(0) << " " << C(1) << std::endl; - output << D(0) << " " << D(1) << std::endl; - output << std::endl; - output << D(0) << " " << D(1) << std::endl; - output << E(0) << " " << E(1) << std::endl; - output << std::endl; - output << D(0) << " " << D(1) << std::endl; - output << F(0) << " " << F(1) << std::endl; - output << std::endl; - - if (Pos==0) - output << v3(0) << " " << v3(1) << std::endl; - else if (Pos==1) - output << v2(0) << " " << v2(1) << std::endl; - else if (Pos==2) - output << v1(0) << " " << v1(1) << std::endl; - else if (Pos==3) - output << v0(0) << " " << v0(1) << std::endl; - output << C(0) << " " << C(1) << std::endl; - - Point subcell_vertices[10]; - subcell_vertices[0] = v0; - subcell_vertices[1] = v1; - subcell_vertices[2] = v2; - subcell_vertices[3] = v3; - subcell_vertices[4] = A; - subcell_vertices[5] = B; - subcell_vertices[6] = C; - subcell_vertices[7] = D; - subcell_vertices[8] = E; - subcell_vertices[9] = F; - - std::vector > xfem_points; - std::vector xfem_weights; - - // lookup table for the decomposition - - if (dim==2) - { - unsigned int subcell_v_indices[4][5][4] = - { - {{0,8,9,7}, {9,7,5,6}, {8,4,7,6}, {5,6,2,3}, {6,4,3,1}}, - {{8,1,7,9}, {4,8,6,7}, {6,7,5,9}, {0,4,2,6}, {2,6,3,5}}, - {{9,7,2,8}, {5,6,9,7}, {6,4,7,8}, {0,1,5,6}, {6,1,4,3}}, - {{7,9,8,3}, {4,6,8,7}, {6,5,7,9}, {0,6,2,4}, {0,1,6,5}} - }; - - for (unsigned int subcell = 0; subcell<5; subcell++) - { - //std::cout << "subcell : " << subcell << std::endl; - std::vector > vertices; - for (unsigned int i=0; i<4; i++) - { - vertices.push_back( subcell_vertices[subcell_v_indices[Pos][subcell][i]] ); - //std::cout << "i : " << i << std::endl; std::cout << - //"subcell v : " << subcell_v_indices[Pos][subcell][i] << - //std::endl; std::cout << vertices[i](0) << " " << - //vertices[i](1) << std::endl; - } - //std::cout << std::endl; create quadrature rule - append_quadrature( plain_quadrature, - vertices, - xfem_points, - xfem_weights); - //initialize xfem_quadrature with quadrature points of all - //subelements - xfem_quadrature.initialize(xfem_points, xfem_weights); - } - } - - Assert (xfem_quadrature.size() == plain_quadrature.size() * 5, ExcInternalError()); - return std::pair >(2, xfem_quadrature); - } - - // Type three decomposition (+--+, ++--, +-+-, -++-, --++, -+-+) - - if (type==3) - { - const unsigned int n_q_points = plain_quadrature.size(); - - // loop over all subelements for integration in type 2 there are 5 - // subelements - - Quadrature xfem_quadrature(5*n_q_points); - - std::vector > v(GeometryInfo::vertices_per_cell); - - if ( sign_ls[0]==sign_ls[1] && sign_ls[2]==sign_ls[3] ) - { - Pos = 0; - A(0) = 0.; - A(1) = level_set_values[0]/((level_set_values[0]-level_set_values[2])); - B(0) = 1.; - B(1) = level_set_values[1]/((level_set_values[1]-level_set_values[3])); - } - else if ( sign_ls[0]==sign_ls[2] && sign_ls[1]==sign_ls[3] ) - { - Pos = 1; - A(0) = level_set_values[0]/((level_set_values[0]-level_set_values[1])); - A(1) = 0.; - B(0) = level_set_values[2]/((level_set_values[2]-level_set_values[3])); - B(1) = 1.; - } - else if ( sign_ls[0]==sign_ls[3] && sign_ls[1]==sign_ls[2] ) - { - std::cout << "Error: the element has two cut lines and this is not allowed" << std::endl; - assert(0); - } - else - { - std::cout << "Error: the level set function has not the right values" << std::endl; - assert(0); - } - - //std::cout << "Pos " << Pos << std::endl; std::cout << A << - //std::endl; std::cout << B << std::endl; - std::string filename = "vertices.dat"; - std::ofstream output (filename.c_str()); - output << "#vertices of xfem subcells" << std::endl; - output << A(0) << " " << A(1) << std::endl; - output << B(0) << " " << B(1) << std::endl; - - //fill xfem_quadrature - Point subcell_vertices[6]; - subcell_vertices[0] = v0; - subcell_vertices[1] = v1; - subcell_vertices[2] = v2; - subcell_vertices[3] = v3; - subcell_vertices[4] = A; - subcell_vertices[5] = B; - - std::vector > xfem_points; - std::vector xfem_weights; - - if (dim==2) - { - unsigned int subcell_v_indices[2][2][4] = - { - {{0,1,4,5}, {4,5,2,3}}, - {{0,4,2,5}, {4,1,5,3}} - }; - - //std::cout << "Pos : " << Pos << std::endl; - for (unsigned int subcell = 0; subcell<2; subcell++) - { - //std::cout << "subcell : " << subcell << std::endl; - std::vector > vertices; - for (unsigned int i=0; i<4; i++) - { - vertices.push_back( subcell_vertices[subcell_v_indices[Pos][subcell][i]] ); - //std::cout << "i : " << i << std::endl; std::cout << - //"subcell v : " << subcell_v_indices[Pos][subcell][i] << - //std::endl; std::cout << vertices[i](0) << " " << - //vertices[i](1) << std::endl; - } - //std::cout << std::endl; create quadrature rule - append_quadrature( plain_quadrature, - vertices, - xfem_points, - xfem_weights); - //initialize xfem_quadrature with quadrature points of all - //subelements - xfem_quadrature.initialize(xfem_points, xfem_weights); - } - } - Assert (xfem_quadrature.size() == plain_quadrature.size() * 2, ExcInternalError()); - return std::pair >(3, xfem_quadrature); - } - - return std::pair >(0, plain_quadrature);; - - } - - template - void LaplaceProblem::append_quadrature ( const Quadrature &plain_quadrature, - const std::vector > &v, - std::vector > &xfem_points, - std::vector &xfem_weights) - - { - // Project integration points into sub-elements. This maps quadrature - // points from a reference element to a subelement of a reference element. - // To implement the action of this map the coordinates of the subelements - // have been calculated (A(0)...F(0),A(1)...F(1)) the coordinates of the - // quadrature points are given by the bi-linear map defined by the form - // functions $x^\prime_i = \sum_j v^\prime \phi_j(x^hat_i)$, where the - // $\phi_j$ are the shape functions of the FEQ. - - unsigned int n_v = GeometryInfo::vertices_per_cell; - - std::vector > q_points = plain_quadrature.get_points(); - std::vector > q_transf(q_points.size()); - std::vector W = plain_quadrature.get_weights(); - std::vector phi(n_v); - std::vector > grad_phi(n_v); - - const unsigned int n_q_points = plain_quadrature.size(); - - std::vector JxW(n_q_points); - - for ( unsigned int i = 0; i < n_q_points; i++) - { - switch (dim) - { - case 2: - { - double xi = q_points[i](0); - double eta = q_points[i](1); - - // Define shape functions on reference element we consider a - // bi-linear mapping - phi[0] = (1. - xi) * (1. - eta); - phi[1] = xi * (1. - eta); - phi[2] = (1. - xi) * eta; - phi[3] = xi * eta; - - grad_phi[0][0] = (-1. + eta); - grad_phi[1][0] = (1. - eta); - grad_phi[2][0] = -eta; - grad_phi[3][0] = eta; - - grad_phi[0][1] = (-1. + xi); - grad_phi[1][1] = -xi; - grad_phi[2][1] = 1-xi; - grad_phi[3][1] = xi; - - break; - } - - default: - Assert (false, ExcNotImplemented()); - } - - - Tensor<2,dim> jacobian; - - // Calculate Jacobian of transformation - for (unsigned int d=0; d::vertices_per_cell; j++) - { - jacobian[d][e] += grad_phi[j][e] * v[j](d); - } - } - - double detJ = determinant(jacobian); - xfem_weights.push_back (W[i] * detJ); - - // Map integration points from reference element to subcell of - // reference element - Point q_prime; - for (unsigned int d=0; d::vertices_per_cell; j++) - q_prime[d] += v[j](d) * phi[j]; - xfem_points.push_back(q_prime); - } - - } - - - template - void LaplaceProblem::solve () - { - SolverControl solver_control (1000, 1e-12); - SolverCG<> solver (solver_control); - - PreconditionSSOR<> preconditioner; - preconditioner.initialize(system_matrix, 1.2); - - solver.solve (system_matrix, solution, system_rhs, - preconditioner); - - constraints.distribute (solution); - } - - - - template - void LaplaceProblem::refine_grid () - { - Vector estimated_error_per_cell (triangulation.n_active_cells()); - - KellyErrorEstimator::estimate (dof_handler, - QGauss(3), - typename FunctionMap::type(), - solution, - estimated_error_per_cell); - - GridRefinement::refine_and_coarsen_fixed_number (triangulation, - estimated_error_per_cell, - 0.3, 0.03); - - triangulation.execute_coarsening_and_refinement (); - } - - - - template - class Postprocessor : public DataPostprocessor - { - public: - virtual - void - compute_derived_quantities_vector (const std::vector > &uh, - const std::vector > > &duh, - const std::vector > > &dduh, - const std::vector > &normals, - const std::vector > &evaluation_points, - std::vector > &computed_quantities) const; - - virtual std::vector get_names () const; - - virtual - std::vector - get_data_component_interpretation () const; - - virtual UpdateFlags get_needed_update_flags () const; - }; - - - template - std::vector - Postprocessor::get_names() const - { - std::vector solution_names (1, "total_solution"); - solution_names.push_back ("error"); - return solution_names; - } - - - template - std::vector - Postprocessor:: - get_data_component_interpretation () const - { - std::vector - interpretation (2, - DataComponentInterpretation::component_is_scalar); - return interpretation; - } - - - template - UpdateFlags - Postprocessor::get_needed_update_flags() const - { - return update_values | update_q_points; - } - - - template - void - Postprocessor:: - compute_derived_quantities_vector (const std::vector > &uh, - const std::vector > > &/*duh*/, - const std::vector > > &/*dduh*/, - const std::vector > &/*normals*/, - const std::vector > &evaluation_points, - std::vector > &computed_quantities) const - { - const unsigned int n_quadrature_points = uh.size(); - Assert (computed_quantities.size() == n_quadrature_points, ExcInternalError()); - Assert (uh[0].size() == 2, ExcInternalError()); - - for (unsigned int q=0; q - void LaplaceProblem::output_results (const unsigned int cycle) const - { - Assert (cycle < 10, ExcNotImplemented()); - - std::string filename = "solution-"; - filename += ('0' + cycle); - filename += ".vtk"; - - std::ofstream output (filename.c_str()); - - Postprocessor postprocessor; - DataOut > data_out; - - data_out.attach_dof_handler (dof_handler); - data_out.add_data_vector (solution, "solution"); - data_out.add_data_vector (solution, postprocessor); - data_out.build_patches (5); - - data_out.write_vtk (output); - } - - - - template - void LaplaceProblem::compute_error () const - { - hp::QCollection q_collection; - q_collection.push_back (QGauss(2)); - q_collection.push_back (QIterated(QGauss<1>(2), 4)); - - hp::FEValues hp_fe_values (fe_collection, q_collection, - update_values | update_q_points | update_JxW_values); - - double l2_error_square = 0; - - std::vector > solution_values; - - typename hp::DoFHandler::active_cell_iterator - cell = dof_handler.begin_active(), - endc = dof_handler.end(); - - for (; cell!=endc; ++cell) - { - hp_fe_values.reinit (cell); - - const FEValues &fe_values = hp_fe_values.get_present_fe_values (); - - solution_values.resize (fe_values.n_quadrature_points, - Vector(2)); - fe_values.get_function_values (solution, - solution_values); - - for (unsigned int q=0; q boundary; - triangulation.set_boundary (0, boundary); - - triangulation.refine_global (2); - } - else - triangulation.refine_global (1); -// refine_grid (); - - - std::cout << " Number of active cells: " - << triangulation.n_active_cells() - << std::endl; - - setup_system (); - - std::cout << " Number of degrees of freedom: " - << dof_handler.n_dofs() - << std::endl; - - assemble_system (); - solve (); - compute_error (); - output_results (cycle); - } - } -} - - - -int main () -{ - - try - { - using namespace dealii; - using namespace Step47; - - deallog.depth_console (0); - - LaplaceProblem<2> laplace_problem_2d; - laplace_problem_2d.run (); - } - catch (std::exception &exc) - { - std::cerr << std::endl << std::endl - << "----------------------------------------------------" - << std::endl; - std::cerr << "Exception on processing: " << std::endl - << exc.what() << std::endl - << "Aborting!" << std::endl - << "----------------------------------------------------" - << std::endl; - - return 1; - } - catch (...) - { - std::cerr << std::endl << std::endl - << "----------------------------------------------------" - << std::endl; - std::cerr << "Unknown exception!" << std::endl - << "Aborting!" << std::endl - << "----------------------------------------------------" - << std::endl; - return 1; - } - - return 0; -} diff --git a/deal.II/examples/step-50/CMakeLists.txt b/deal.II/examples/step-50/CMakeLists.txt deleted file mode 100644 index babcd817e0..0000000000 --- a/deal.II/examples/step-50/CMakeLists.txt +++ /dev/null @@ -1,52 +0,0 @@ -## -# CMake script for the step-32 tutorial program: -## - -# Set the name of the project and target: -SET(TARGET "step-50") - -# Declare all source files the target consists of: -SET(TARGET_SRC - ${TARGET}.cc - # You can specify additional files here! - ) - -# A custom command line to run the program -SET(TARGET_RUN mpirun -np 2 ${TARGET}) - -# Define the output that should be cleaned: -SET(CLEAN_UP_FILES *.vtu *.pvtu *.visit) - -# Usually, you will not need to modify anything beyond this point... - -CMAKE_MINIMUM_REQUIRED(VERSION 2.8.8) - -FIND_PACKAGE(deal.II 8.0 QUIET - HINTS ${deal.II_DIR} ${DEAL_II_DIR} ../ ../../ $ENV{DEAL_II_DIR} - ) -IF(NOT ${deal.II_FOUND}) - MESSAGE(FATAL_ERROR "\n" - "*** Could not locate deal.II. ***\n\n" - "You may want to either pass a flag -DDEAL_II_DIR=/path/to/deal.II to cmake\n" - "or set an environment variable \"DEAL_II_DIR\" that contains this path." - ) -ENDIF() - -# -# Are all dependencies fullfilled? -# -IF( NOT DEAL_II_WITH_MPI OR - NOT DEAL_II_WITH_P4EST OR - NOT DEAL_II_WITH_TRILINOS ) - MESSAGE(FATAL_ERROR " -Error! The deal.II library found at ${DEAL_II_PATH} was not configured with - DEAL_II_WITH_MPI = ON - DEAL_II_WITH_P4EST = ON - DEAL_II_WITH_TRILINOS = ON -which is required for this tutorial step." - ) -ENDIF() - -DEAL_II_INITIALIZE_CACHED_VARIABLES() -PROJECT(${TARGET}) -DEAL_II_INVOKE_AUTOPILOT() diff --git a/deal.II/examples/step-50/doc/builds-on b/deal.II/examples/step-50/doc/builds-on deleted file mode 100644 index 17402734c7..0000000000 --- a/deal.II/examples/step-50/doc/builds-on +++ /dev/null @@ -1 +0,0 @@ -step-6 diff --git a/deal.II/examples/step-50/doc/intro.dox b/deal.II/examples/step-50/doc/intro.dox deleted file mode 100644 index 99666726d3..0000000000 --- a/deal.II/examples/step-50/doc/intro.dox +++ /dev/null @@ -1,90 +0,0 @@ -
- -This program has evolved from a version originally written by Guido -Kanschat in 2003. It has undergone significant revisions by Bärbel -Janssen, Guido Kanschat and Wolfgang Bangerth in 2009 and 2010 to demonstrate -multigrid algorithms on adaptively refined meshes. - - - - -

Introduction

- - -This example shows the basic usage of the multilevel functions in -deal.II. It solves the same problem as used in step-6, -but demonstrating the things one has to provide when using multigrid -as a preconditioner. In particular, this requires that we define a -hierarchy of levels, provide transfer operators from one level to the -next and back, and provide representations of the Laplace operator on -each level. - -In order to allow sufficient flexibility in conjunction with systems of -differential equations and block preconditioners, quite a few different objects -have to be created before starting the multilevel method, although -most of what needs to be done is provided by deal.II itself. These are -
    -
  • An the object handling transfer between grids; we use the - MGTransferPrebuilt class for this that does almost all of the work - inside the library. -
  • The solver on the coarsest level; here, we use MGCoarseGridHouseholder. -
  • The smoother on all other levels, which in our case will be the - MGSmootherRelaxation class using SOR as the underlying method -
  • And MGMatrix, a class having a special level multiplication, i.e. we - basically store one matrix per grid level and allow multiplication - with it. -
-Most of these objects will only be needed inside the function that -actually solves the linear system. There, these objects are combined -in an object of type Multigrid, containing the implementation of the -V-cycle, which is in turn used by the preconditioner PreconditionMG, -ready for plug-in into a linear solver of the LAC library. - -The multilevel method in deal.II follows in many respects the outlines -of the various publications by James Bramble, Joseph Pasciak and -Jinchao Xu (i.e. the "BPX" framework). In order to understand many of -the options, a rough familiarity with their work is quite helpful. - -However, in comparison to this framework, the implementation in -deal.II has to take into account the fact that we want to solve linear -systems on adaptively refined meshes. This leads to the complication -that it isn't quite as clear any more what exactly a "level" in a -multilevel hierarchy of a mesh is. The following image shows what we -consider to be a "level": - -

- @image html "hanging_nodes.png" "" -

- -In other words, the fine level in this mesh consists only of the -degrees of freedom that are defined on the refined cells, but does not -extend to that part of the domain that is not refined. While this -guarantees that the overall effort grows as ${\cal O}(N)$ as necessary -for optimal multigrid complexity, it leads to problems when defining -where to smooth and what boundary conditions to pose for the operators -defined on individual levels if the level boundary is not an external -boundary. These questions are discussed in detail in the -@ref mg_paper "Multigrid paper by Janssen and Kanschat" that describes -the implementation in deal.II. - - - -

The testcase

- -The problem we solve here is exactly the same as in -step-6, the only difference being the solver we use -here. You may want to look there for a definition of what we solve, -right hand side and boundary conditions. Obviously, the program would -also work if we changed the geometry and other pieces of data that -defines this particular problem. - -The things that are new are all those parts that concern the -multigrid. In particular, this includes the following members of the -main class: -- LaplaceProblem::mg_dof_handler -- LaplaceProblem::mg_sparsity -- LaplaceProblem::mg_matrices -- LaplaceProblem::mg_interface_matrices_up -- LaplaceProblem::assemble_multigrid () -- LaplaceProblem::solve () -Take a look at these functions. diff --git a/deal.II/examples/step-50/doc/kind b/deal.II/examples/step-50/doc/kind deleted file mode 100644 index c1d9154931..0000000000 --- a/deal.II/examples/step-50/doc/kind +++ /dev/null @@ -1 +0,0 @@ -techniques diff --git a/deal.II/examples/step-50/doc/results.dox b/deal.II/examples/step-50/doc/results.dox deleted file mode 100644 index 2d5fe0deb0..0000000000 --- a/deal.II/examples/step-50/doc/results.dox +++ /dev/null @@ -1,98 +0,0 @@ -

Results

- -The output that this program generates is, of course, the same as that -of step-6, so you may see there for more results. On the -other hand, since no tutorial program is a good one unless it has at -least one colorful picture, here is, again, the solution: - - -When run, the output of this program is -
-Cycle 0:
-   Number of active cells:       20
-   Number of degrees of freedom: 25 (by level: 8, 25)
-   7 CG iterations needed to obtain convergence.
-Cycle 1:
-   Number of active cells:       44
-   Number of degrees of freedom: 57 (by level: 8, 25, 48)
-   8 CG iterations needed to obtain convergence.
-Cycle 2:
-   Number of active cells:       92
-   Number of degrees of freedom: 117 (by level: 8, 25, 80, 60)
-   9 CG iterations needed to obtain convergence.
-Cycle 3:
-   Number of active cells:       188
-   Number of degrees of freedom: 221 (by level: 8, 25, 80, 200)
-   12 CG iterations needed to obtain convergence.
-Cycle 4:
-   Number of active cells:       416
-   Number of degrees of freedom: 485 (by level: 8, 25, 89, 288, 280)
-   13 CG iterations needed to obtain convergence.
-Cycle 5:
-   Number of active cells:       800
-   Number of degrees of freedom: 925 (by level: 8, 25, 89, 288, 784, 132)
-   14 CG iterations needed to obtain convergence.
-Cycle 6:
-   Number of active cells:       1628
-   Number of degrees of freedom: 1865 (by level: 8, 25, 89, 304, 1000, 1164, 72)
-   14 CG iterations needed to obtain convergence.
-Cycle 7:
-   Number of active cells:       3194
-   Number of degrees of freedom: 3603 (by level: 8, 25, 89, 328, 1032, 2200, 1392)
-   16 CG iterations needed to obtain convergence.
-
-That's not perfect — we would have hoped for a constant number -of iterations rather than one that increases as we get more and more -degrees of freedom — but it is also not far away. The reason for -this is easy enough to understand, however: since we have a strongly -varying coefficient, the operators that we assembly by quadrature on -the lower levels become worse and worse approximations of the operator -on the finest level. Consequently, even if we had perfect solvers on -the coarser levels, they would not be good preconditioners on the -finest level. This theory is easily tested by comparing results when -we use a constant coefficient: in that case, the number of iterations -remains constant at 9 after the first three or four refinement steps. - -We can also compare what this program produces with how @ref step_5 -"step-5" performed. To solve the same problem as in step-5, the only -two changes that are necessary are (i) to replace the body of the -function LaplaceProblem::refine_grid by a call to -triangulation.refine_global(1), and (ii) to use the same -SolverControl object and tolerance as in step-5 — the rest of the -program remains unchanged. In that case, here is how the solvers used -in step-5 and the multigrid solver used in the current program -compare: - - - - - - - - -
cellsstep-5step-16
20 13 6
80 17 7
320 29 9
1280 51 10
5120 94 11
2048018013
-This isn't only fewer iterations than in step-5 (each of which -is, however, much more expensive) but more importantly, the number of -iterations also grows much more slowly under mesh refinement (again, -it would be almost constant if the coefficient was constant rather -than strongly varying as chosen here). This justifies the common -observation that, whenever possible, multigrid methods should be used -for second order problems. - - -

Possible extensions

- -A close inspection of this program's performance shows that it is mostly -dominated by matrix-vector operations. step-37 shows one way -how this can be avoided by working with matrix-free methods. - -Another avenue would be to use algebraic multigrid methods. The -geometric multigrid method used here can at times be a bit awkward to -implement because it needs all those additional data structures, and -it becomes even more difficult if the program is to run in %parallel on -machines coupled through MPI, for example. In that case, it would be -simpler if one could use a black-box preconditioner that uses some -sort of multigrid hierarchy for good performance but can figure out -level matrices and similar things out by itself. Algebraic multigrid -methods do exactly this, and we will use them in -step-31 for the solution of a Stokes problem. diff --git a/deal.II/examples/step-50/doc/tooltip b/deal.II/examples/step-50/doc/tooltip deleted file mode 100644 index 2fd65590a0..0000000000 --- a/deal.II/examples/step-50/doc/tooltip +++ /dev/null @@ -1 +0,0 @@ -Multigrid on adaptive meshes. diff --git a/deal.II/examples/step-50/step-50.cc b/deal.II/examples/step-50/step-50.cc deleted file mode 100644 index b76f929eee..0000000000 --- a/deal.II/examples/step-50/step-50.cc +++ /dev/null @@ -1,1075 +0,0 @@ -// --------------------------------------------------------------------- -// $Id$ -// -// Copyright (C) 2003 - 2013 by the deal.II authors -// -// This file is part of the deal.II library. -// -// The deal.II library is free software; you can use it, redistribute -// it, and/or modify it under the terms of the GNU Lesser General -// Public License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// The full text of the license can be found in the file LICENSE at -// the top level of the deal.II distribution. -// -// --------------------------------------------------------------------- - -/* - * Author: Guido Kanschat, University of Heidelberg, 2003 - * Baerbel Janssen, University of Heidelberg, 2010 - * Wolfgang Bangerth, Texas A&M University, 2010 - */ - - -// parallel geometric multi-grid. work in progress! - -// As discussed in the introduction, most of -// this program is copied almost verbatim -// from step-6, which itself is only a slight -// modification of step-5. Consequently, a -// significant part of this program is not -// new if you've read all the material up to -// step-6, and we won't comment on that part -// of the functionality that is -// unchanged. Rather, we will focus on those -// aspects of the program that have to do -// with the multigrid functionality which -// forms the new aspect of this tutorial -// program. - -// @sect3{Include files} - -// Again, the first few include files -// are already known, so we won't -// comment on them: -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -// These, now, are the include necessary for -// the multi-level methods. The first two -// declare classes that allow us to enumerate -// degrees of freedom not only on the finest -// mesh level, but also on intermediate -// levels (that's what the MGDoFHandler class -// does) as well as allow to access this -// information (iterators and accessors over -// these cells). -// -// The rest of the include files deals with -// the mechanics of multigrid as a linear -// operator (solver or preconditioner). -#include -#include -#include -#include -#include -#include -#include -#include - -// This is C++: -#include -#include - -// The last step is as in all -// previous programs: -namespace Step50 -{ - using namespace dealii; - - - // @sect3{The LaplaceProblem class template} - - // This main class is basically the same - // class as in step-6. As far as member - // functions is concerned, the only addition - // is the assemble_multigrid - // function that assembles the matrices that - // correspond to the discrete operators on - // intermediate levels: - template - class LaplaceProblem - { - public: - LaplaceProblem (const unsigned int deg); - void run (); - - private: - void setup_system (); - void assemble_system (); - void assemble_multigrid (); - void solve (); - void refine_grid (); - void output_results (const unsigned int cycle) const; - - parallel::distributed::Triangulation triangulation; - FE_Q fe; - DoFHandler mg_dof_handler; - - typedef TrilinosWrappers::SparseMatrix matrix_t; - typedef TrilinosWrappers::MPI::Vector vector_t; - - matrix_t system_matrix; - - IndexSet locally_relevant_set; - - // We need an additional object for the - // hanging nodes constraints. They are - // handed to the transfer object in the - // multigrid. Since we call a compress - // inside the multigrid these constraints - // are not allowed to be inhomogeneous so - // we store them in different ConstraintMatrix - // objects. - ConstraintMatrix hanging_node_constraints; - ConstraintMatrix constraints; - - vector_t solution; - vector_t system_rhs; - - const unsigned int degree; - - // The following four objects are the - // only additional member variables, - // compared to step-6. They first three - // represent the - // operators that act on individual - // levels of the multilevel hierarchy, - // rather than on the finest mesh as do - // the objects above while the last object - // stores information about the boundary - // indices on each level and information - // about indices lying on a refinement - // edge between two different refinement - // levels. - // - // To facilitate having objects on each - // level of a multilevel hierarchy, - // deal.II has the MGLevelObject class - // template that provides storage for - // objects on each level. What we need - // here are matrices on each level, which - // implies that we also need sparsity - // patterns on each level. As outlined in - // the @ref mg_paper, the operators - // (matrices) that we need are actually - // twofold: one on the interior of each - // level, and one at the interface - // between each level and that part of - // the domain where the mesh is - // coarser. In fact, we will need the - // latter in two versions: for the - // direction from coarse to fine mesh and - // from fine to coarse. Fortunately, - // however, we here have a self-adjoint - // problem for which one of these is the - // transpose of the other, and so we only - // have to build one; we choose the one - // from coarse to fine. - MGLevelObject mg_matrices; - MGLevelObject mg_interface_matrices; - MGConstrainedDoFs mg_constrained_dofs; - }; - - - - // @sect3{Nonconstant coefficients} - - // The implementation of nonconstant - // coefficients is copied verbatim - // from step-5 and step-6: - - template - class Coefficient : public Function - { - public: - Coefficient () : Function() {} - - virtual double value (const Point &p, - const unsigned int component = 0) const; - - virtual void value_list (const std::vector > &points, - std::vector &values, - const unsigned int component = 0) const; - }; - - - - template - double Coefficient::value (const Point &p, - const unsigned int) const - { - if (p.square() < 0.5*0.5) - return 20; - else - return 1; - } - - - - template - void Coefficient::value_list (const std::vector > &points, - std::vector &values, - const unsigned int component) const - { - const unsigned int n_points = points.size(); - - Assert (values.size() == n_points, - ExcDimensionMismatch (values.size(), n_points)); - - Assert (component == 0, - ExcIndexRange (component, 0, 1)); - - for (unsigned int i=0; i::value (points[i]); - } - - - // @sect3{The LaplaceProblem class implementation} - - // @sect4{LaplaceProblem::LaplaceProblem} - - // The constructor is left mostly - // unchanged. We take the polynomial degree - // of the finite elements to be used as a - // constructor argument and store it in a - // member variable. - // - // By convention, all adaptively refined - // triangulations in deal.II never change by - // more than one level across a face between - // cells. For our multigrid algorithms, - // however, we need a slightly stricter - // guarantee, namely that the mesh also does - // not change by more than refinement level - // across vertices that might connect two - // cells. In other words, we must prevent the - // following situation: - // - // @image html limit_level_difference_at_vertices.png "" - // - // This is achieved by passing the - // Triangulation::limit_level_difference_at_vertices - // flag to the constructor of the - // triangulation class. - template - LaplaceProblem::LaplaceProblem (const unsigned int degree) - : - triangulation (MPI_COMM_WORLD,Triangulation:: - limit_level_difference_at_vertices, - parallel::distributed::Triangulation::construct_multigrid_hierarchy), - fe (degree), - mg_dof_handler (triangulation), - degree(degree) - { - if (Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)!=0) - deallog.depth_console(0); - } - - - - // @sect4{LaplaceProblem::setup_system} - - // The following function extends what the - // corresponding one in step-6 did. The top - // part, apart from the additional output, - // does the same: - template - void LaplaceProblem::setup_system () - { - mg_dof_handler.distribute_dofs (fe); - mg_dof_handler.distribute_mg_dofs (fe); - - - // Here we output not only the - // degrees of freedom on the finest - // level, but also in the - // multilevel structure - deallog << "Number of degrees of freedom: " - << mg_dof_handler.n_dofs(); - - for (unsigned int l=0; l::type dirichlet_boundary; - ZeroFunction homogeneous_dirichlet_bc (1); - dirichlet_boundary[0] = &homogeneous_dirichlet_bc; - VectorTools::interpolate_boundary_values (mg_dof_handler, - dirichlet_boundary, - constraints); - constraints.close (); - hanging_node_constraints.close (); - - CompressedSimpleSparsityPattern csp(mg_dof_handler.n_dofs(), mg_dof_handler.n_dofs()); - DoFTools::make_sparsity_pattern (mg_dof_handler, csp, constraints); - system_matrix.reinit (mg_dof_handler.locally_owned_dofs(), csp, MPI_COMM_WORLD, true); - - // The multigrid constraints have to be - // initialized. They need to know about - // the boundary values as well, so we - // pass the dirichlet_boundary - // here as well. - mg_constrained_dofs.clear(); - mg_constrained_dofs.initialize(mg_dof_handler, dirichlet_boundary); - - - // Now for the things that concern the - // multigrid data structures. First, we - // resize the multi-level objects to hold - // matrices and sparsity patterns for every - // level. The coarse level is zero (this is - // mandatory right now but may change in a - // future revision). Note that these - // functions take a complete, inclusive - // range here (not a starting index and - // size), so the finest level is - // n_levels-1. We first have - // to resize the container holding the - // SparseMatrix classes, since they have to - // release their SparsityPattern before the - // can be destroyed upon resizing. - const unsigned int n_levels = triangulation.n_global_levels(); - - mg_interface_matrices.resize(0, n_levels-1); - mg_interface_matrices.clear (); - mg_matrices.resize(0, n_levels-1); - mg_matrices.clear (); - - // Now, we have to provide a matrix on each - // level. To this end, we first use the - // MGTools::make_sparsity_pattern function - // to first generate a preliminary - // compressed sparsity pattern on each - // level (see the @ref Sparsity module for - // more information on this topic) and then - // copy it over to the one we really - // want. The next step is to initialize - // both kinds of level matrices with these - // sparsity patterns. - // - // It may be worth pointing out that the - // interface matrices only have entries for - // degrees of freedom that sit at or next - // to the interface between coarser and - // finer levels of the mesh. They are - // therefore even sparser than the matrices - // on the individual levels of our - // multigrid hierarchy. If we were more - // concerned about memory usage (and - // possibly the speed with which we can - // multiply with these matrices), we should - // use separate and different sparsity - // patterns for these two kinds of - // matrices. - for (unsigned int level=0; level - void LaplaceProblem::assemble_system () - { - const QGauss quadrature_formula(degree+1); - - FEValues fe_values (fe, quadrature_formula, - update_values | update_gradients | - update_quadrature_points | update_JxW_values); - - const unsigned int dofs_per_cell = fe.dofs_per_cell; - const unsigned int n_q_points = quadrature_formula.size(); - - FullMatrix cell_matrix (dofs_per_cell, dofs_per_cell); - Vector cell_rhs (dofs_per_cell); - - std::vector local_dof_indices (dofs_per_cell); - - const Coefficient coefficient; - std::vector coefficient_values (n_q_points); - - typename DoFHandler::active_cell_iterator - cell = mg_dof_handler.begin_active(), - endc = mg_dof_handler.end(); - for (; cell!=endc; ++cell) - if (cell->is_locally_owned()) - { - cell_matrix = 0; - cell_rhs = 0; - - fe_values.reinit (cell); - - coefficient.value_list (fe_values.get_quadrature_points(), - coefficient_values); - - for (unsigned int q_point=0; q_pointget_dof_indices (local_dof_indices); - constraints.distribute_local_to_global (cell_matrix, cell_rhs, - local_dof_indices, - system_matrix, system_rhs); - } - - system_matrix.compress(VectorOperation::add); - system_rhs.compress(VectorOperation::add); - } - - - // @sect4{LaplaceProblem::assemble_multigrid} - - // The next function is the one that builds - // the linear operators (matrices) that - // define the multigrid method on each level - // of the mesh. The integration core is the - // same as above, but the loop below will go - // over all existing cells instead of just - // the active ones, and the results must be - // entered into the correct matrix. Note also - // that since we only do multi-level - // preconditioning, no right-hand side needs - // to be assembled here. - // - // Before we go there, however, we have to - // take care of a significant amount of book - // keeping: - template - void LaplaceProblem::assemble_multigrid () - { - QGauss quadrature_formula(1+degree); - - FEValues fe_values (fe, quadrature_formula, - update_values | update_gradients | - update_quadrature_points | update_JxW_values); - - const unsigned int dofs_per_cell = fe.dofs_per_cell; - const unsigned int n_q_points = quadrature_formula.size(); - - FullMatrix cell_matrix (dofs_per_cell, dofs_per_cell); - - std::vector local_dof_indices (dofs_per_cell); - - const Coefficient coefficient; - std::vector coefficient_values (n_q_points); - - // Next a few things that are specific to building the multigrid - // data structures (since we only need them in the current - // function, rather than also elsewhere, we build them here - // instead of the setup_system function). Some of the - // following may be a bit obscure if you're not familiar with the - // algorithm actually implemented in deal.II to support multilevel - // algorithms on adaptive meshes; if some of the things below seem - // strange, take a look at the @ref mg_paper. - // - // Our first job is to identify those degrees of freedom on each - // level that are located on interfaces between adaptively refined - // levels, and those that lie on the interface but also on the - // exterior boundary of the domain. As in many other parts of the - // library, we do this by using boolean masks, i.e. vectors of - // booleans each element of which indicates whether the - // corresponding degree of freedom index is an interface DoF or - // not. The MGConstraints already computed the - // information for us when we called initialize in - // setup_system(). - std::vector > interface_dofs - = mg_constrained_dofs.get_refinement_edge_indices (); - std::vector > boundary_interface_dofs - = mg_constrained_dofs.get_refinement_edge_boundary_indices (); - - // The indices just identified will later be used to decide where - // the assembled value has to be added into on each level. On the - // other hand, we also have to impose zero boundary conditions on - // the external boundary of each level. But this the - // MGConstraints knows it. So we simply ask for them - // by calling get_boundary_indices (). The third - // step is to construct constraints on all those degrees of - // freedom: their value should be zero after each application of - // the level operators. To this end, we construct ConstraintMatrix - // objects for each level, and add to each of these constraints - // for each degree of freedom. Due to the way the ConstraintMatrix - // stores its data, the function to add a constraint on a single - // degree of freedom and force it to be zero is called - // Constraintmatrix::add_line(); doing so for several degrees of - // freedom at once can be done using - // Constraintmatrix::add_lines(): - std::vector boundary_constraints (triangulation.n_global_levels()); - std::vector boundary_interface_constraints (triangulation.n_global_levels()); - for (unsigned int level=0; levelassemble_system, with two exceptions: (i) we don't - // need a right hand side, and more significantly (ii) we don't - // just loop over all active cells, but in fact all cells, active - // or not. Consequently, the correct iterator to use is - // MGDoFHandler::cell_iterator rather than - // MGDoFHandler::active_cell_iterator. Let's go about it: - typename DoFHandler::cell_iterator cell = mg_dof_handler.begin(), - endc = mg_dof_handler.end(); - - for (; cell!=endc; ++cell) - if (cell->level_subdomain_id()==triangulation.locally_owned_subdomain()) - { - cell_matrix = 0; - fe_values.reinit (cell); - - coefficient.value_list (fe_values.get_quadrature_points(), - coefficient_values); - - for (unsigned int q_point=0; q_pointget_mg_dof_indices (local_dof_indices); - - // Next, we need to copy local contributions into the level - // objects. We can do this in the same way as in the global - // assembly, using a constraint object that takes care of - // constrained degrees (which here are only boundary nodes, - // as the individual levels have no hanging node - // constraints). Note that the - // boundary_constraints object makes sure that - // the level matrices contains no contributions from degrees - // of freedom at the interface between cells of different - // refinement level. - boundary_constraints[cell->level()] - .distribute_local_to_global (cell_matrix, - local_dof_indices, - mg_matrices[cell->level()]); - - // The next step is again slightly more obscure (but - // explained in the @ref mg_paper): We need the remainder of - // the operator that we just copied into the - // mg_matrices object, namely the part on the - // interface between cells at the current level and cells - // one level coarser. This matrix exists in two directions: - // for interior DoFs (index $i$) of the current level to - // those sitting on the interface (index $j$), and the other - // way around. Of course, since we have a symmetric - // operator, one of these matrices is the transpose of the - // other. - // - // The way we assemble these matrices is as follows: since - // the are formed from parts of the local contributions, we - // first delete all those parts of the local contributions - // that we are not interested in, namely all those elements - // of the local matrix for which not $i$ is an interface DoF - // and $j$ is not. The result is one of the two matrices - // that we are interested in, and we then copy it into the - // mg_interface_matrices object. The - // boundary_interface_constraints object at the - // same time makes sure that we delete contributions from - // all degrees of freedom that are not only on the interface - // but also on the external boundary of the domain. - // - // The last part to remember is how to get the other - // matrix. Since it is only the transpose, we will later (in - // the solve() function) be able to just pass - // the transpose matrix where necessary. - for (unsigned int i=0; ilevel()][local_dof_indices[i]]==true && - interface_dofs[cell->level()][local_dof_indices[j]]==false)) - cell_matrix(i,j) = 0; - - boundary_interface_constraints[cell->level()] - .distribute_local_to_global (cell_matrix, - local_dof_indices, - mg_interface_matrices[cell->level()]); - } - - for (unsigned int i=0; i - void LaplaceProblem::solve () - { - - // Create the object that deals with the transfer between - // different refinement levels. We need to pass it the hanging - // node constraints. - MGTransferPrebuilt mg_transfer(hanging_node_constraints, mg_constrained_dofs); - // Now the prolongation matrix has to be built. This matrix needs - // to take the boundary values on each level into account and - // needs to know about the indices at the refinement egdes. The - // MGConstraints knows about that so pass it as an - // argument. - mg_transfer.build_matrices(mg_dof_handler); - - matrix_t &coarse_matrix = mg_matrices[0]; - //coarse_matrix.copy_from (mg_matrices[0]); - //MGCoarseGridHouseholder coarse_grid_solver; - //coarse_grid_solver.initialize (coarse_matrix); - - SolverControl coarse_solver_control (1000, 1e-10, false, false); - SolverGMRES coarse_solver(coarse_solver_control); - PreconditionIdentity id; - MGCoarseGridLACIteration,vector_t> coarse_grid_solver(coarse_solver, - coarse_matrix, - id); - - // The next component of a multilevel solver or preconditioner is - // that we need a smoother on each level. A common choice for this - // is to use the application of a relaxation method (such as the - // SOR, Jacobi or Richardson method). The MGSmootherPrecondition - // class provides support for this kind of smoother. Here, we opt - // for the application of a single SOR iteration. To this end, we - // define an appropriate typedef and then setup a - // smoother object. - // - // The last step is to initialize the smoother object with our - // level matrices and to set some smoothing parameters. The - // initialize() function can optionally take - // additional arguments that will be passed to the smoother object - // on each level. In the current case for the SOR smoother, this - // could, for example, include a relaxation parameter. However, we - // here leave these at their default values. The call to - // set_steps() indicates that we will use two pre- - // and two post-smoothing steps on each level; to use a variable - // number of smoother steps on different levels, more options can - // be set in the constructor call to the mg_smoother - // object. - // - // The last step results from the fact that - // we use the SOR method as a smoother - - // which is not symmetric - but we use the - // conjugate gradient iteration (which - // requires a symmetric preconditioner) - // below, we need to let the multilevel - // preconditioner make sure that we get a - // symmetric operator even for nonsymmetric - // smoothers: - typedef TrilinosWrappers::PreconditionJacobi Smoother; - MGSmootherPrecondition mg_smoother; - mg_smoother.initialize(mg_matrices); - mg_smoother.set_steps(2); - //mg_smoother.set_symmetric(false); - - // The next preparatory step is that we - // must wrap our level and interface - // matrices in an object having the - // required multiplication functions. We - // will create two objects for the - // interface objects going from coarse to - // fine and the other way around; the - // multigrid algorithm will later use the - // transpose operator for the latter - // operation, allowing us to initialize - // both up and down versions of the - // operator with the matrices we already - // built: - MGMatrix mg_matrix(&mg_matrices); - MGMatrix mg_interface_up(&mg_interface_matrices); - MGMatrix mg_interface_down(&mg_interface_matrices); - - // Now, we are ready to set up the - // V-cycle operator and the - // multilevel preconditioner. - Multigrid mg(mg_dof_handler, - mg_matrix, - coarse_grid_solver, - mg_transfer, - mg_smoother, - mg_smoother); - //mg.set_debug(6); - mg.set_edge_matrices(mg_interface_down, mg_interface_up); - - PreconditionMG > - preconditioner(mg_dof_handler, mg, mg_transfer); - - // With all this together, we can finally - // get about solving the linear system in - // the usual way: - SolverControl solver_control (500, 1e-8*system_rhs.l2_norm(), false); - SolverCG cg (solver_control); - - solution = 0; - - if (false) - { - // code to optionally compare to Trilinos ML - TrilinosWrappers::PreconditionAMG prec; - - TrilinosWrappers::PreconditionAMG::AdditionalData Amg_data; - // Amg_data.constant_modes = constant_modes; - Amg_data.elliptic = true; - Amg_data.higher_order_elements = true; - Amg_data.smoother_sweeps = 2; - Amg_data.aggregation_threshold = 0.02; - // Amg_data.symmetric = true; - - prec.initialize (system_matrix, - Amg_data); - cg.solve (system_matrix, solution, system_rhs, - prec); - } - else - { - cg.solve (system_matrix, solution, system_rhs, - preconditioner); - } - - constraints.distribute (solution); - } - - - - // @sect4{Postprocessing} - - // The following two functions postprocess a - // solution once it is computed. In - // particular, the first one refines the mesh - // at the beginning of each cycle while the - // second one outputs results at the end of - // each such cycle. The functions are almost - // unchanged from those in step-6, with the - // exception of two minor differences: The - // KellyErrorEstimator::estimate function - // wants an argument of type DoFHandler, not - // MGDoFHandler, and so we have to cast from - // derived to base class; and we generate - // output in VTK format, to use the more - // modern visualization programs available - // today compared to those that were - // available when step-6 was written. - template - void LaplaceProblem::refine_grid () - { - Vector estimated_error_per_cell (triangulation.n_active_cells()); - - TrilinosWrappers::MPI::Vector temp_solution; - temp_solution.reinit(locally_relevant_set, MPI_COMM_WORLD); - temp_solution = solution; - - KellyErrorEstimator::estimate (static_cast&>(mg_dof_handler), - QGauss(3), - typename FunctionMap::type(), - temp_solution, - estimated_error_per_cell); - parallel::distributed::GridRefinement:: - refine_and_coarsen_fixed_fraction (triangulation, - estimated_error_per_cell, - 0.3, 0.03); - triangulation.execute_coarsening_and_refinement (); - } - - - - template - void LaplaceProblem::output_results (const unsigned int cycle) const - { - DataOut data_out; - - TrilinosWrappers::MPI::Vector temp_solution; - temp_solution.reinit(locally_relevant_set, MPI_COMM_WORLD); - temp_solution = solution; - - - TrilinosWrappers::MPI::Vector temp = solution; - system_matrix.residual(temp,solution,system_rhs); - TrilinosWrappers::MPI::Vector res_ghosted = temp_solution; - res_ghosted = temp; - - data_out.attach_dof_handler (mg_dof_handler); - data_out.add_data_vector (temp_solution, "solution"); - data_out.add_data_vector (res_ghosted, "res"); - Vector subdomain (triangulation.n_active_cells()); - for (unsigned int i=0; i filenames; - for (unsigned int i=0; iassemble_multigrid that takes - // care of forming the matrices on every - // level that we need in the multigrid - // method. - template - void LaplaceProblem::run () - { - for (unsigned int cycle=0; cycle<13; ++cycle) - { - deallog << "Cycle " << cycle << ':' << std::endl; - - if (cycle == 0) - { - GridGenerator::hyper_cube (triangulation); - - triangulation.refine_global (3); - } - else - refine_grid (); - - deallog << " Number of active cells: " - << triangulation.n_global_active_cells() - << std::endl; - - setup_system (); - - deallog << " Number of degrees of freedom: " - << mg_dof_handler.n_dofs() - << " (by level: "; - for (unsigned int level=0; level laplace_problem(1); - laplace_problem.run (); - } - catch (std::exception &exc) - { - std::cerr << std::endl << std::endl - << "----------------------------------------------------" - << std::endl; - std::cerr << "Exception on processing: " << std::endl - << exc.what() << std::endl - << "Aborting!" << std::endl - << "----------------------------------------------------" - << std::endl; - - return 1; - } - catch (...) - { - std::cerr << std::endl << std::endl - << "----------------------------------------------------" - << std::endl; - std::cerr << "Unknown exception!" << std::endl - << "Aborting!" << std::endl - << "----------------------------------------------------" - << std::endl; - return 1; - } - - return 0; -} -- 2.39.5