deal.II version GIT relicensing-2173-gae8fc9d14b 2024-11-24 06:40:00+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
ElastoplasticTorsion.h
Go to the documentation of this file.
1
39 *  
40 *  
41 *   /*
42 *   This piece of software solves the elliptic p-laplacian
43 *   boundary-value problems:
44 *  
45 *   Min {∫ 1/2 W(|Du|²)+ 1/p |Du|^p -fu : u=g on ∂S } (1)
46 *   u
47 *  
48 *   for large values of p, which approximates (see Alvarez & Flores 2015)
49 *  
50 *   Min {∫ 1/2 W(|Du|²) -fu : |Du|<1 a.s. on S, u=g on ∂S }
51 *   u
52 *  
53 *   By default W(t)=t and S=unit disk.
54 *  
55 *   Large portions of this code are borrowed from the deal.ii tutorials
56 *  
57 *   @ref step_15 "step-15" @ref step_29 "step-29".
58 *  
59 *   For further details see the technical report
60 *   "Solving variational problems with uniform gradient bounds by p-Laplacian
61 *   approximation: Elastoplastic torsion implementation using the deal.II
62 *   library"
63 *   available at the documentation and at http://www.dim.uchile.cl/~sflores.
64 *  
65 *   */
66 *  
67 * @endcode
68 *
69 * Include files
70 *
71
72 *
73 *
74 * @code
75 *   #include <deal.II/base/quadrature_lib.h>
76 *   #include <deal.II/base/function.h>
77 *   #include <deal.II/base/logstream.h>
78 *   #include <deal.II/base/utilities.h>
79 *   #include <deal.II/base/convergence_table.h>
80 *   #include <deal.II/base/smartpointer.h>
81 *   #include <deal.II/base/parameter_handler.h>
82 *   #include <deal.II/base/timer.h>
83 *  
84 *   #include <deal.II/lac/vector.h>
85 *   #include <deal.II/lac/full_matrix.h>
86 *   #include <deal.II/lac/sparse_matrix.h>
87 *   #include <deal.II/lac/solver_cg.h>
88 *   #include <deal.II/lac/precondition.h>
89 *   #include <deal.II/lac/affine_constraints.h>
90 *   #include <deal.II/lac/dynamic_sparsity_pattern.h>
91 *  
92 *   #include <deal.II/grid/tria.h>
93 *   #include <deal.II/grid/grid_generator.h>
94 *   #include <deal.II/grid/tria_accessor.h>
95 *   #include <deal.II/grid/tria_iterator.h>
96 *   #include <deal.II/grid/manifold_lib.h>
97 *   #include <deal.II/grid/grid_refinement.h>
98 *   #include <deal.II/grid/grid_in.h>
99 *  
100 *   #include <deal.II/dofs/dof_handler.h>
101 *   #include <deal.II/dofs/dof_accessor.h>
102 *   #include <deal.II/dofs/dof_tools.h>
103 *   #include <deal.II/dofs/dof_renumbering.h>
104 *  
105 *   #include <deal.II/fe/fe_values.h>
106 *   #include <deal.II/fe/fe_q.h>
107 *  
108 *   #include <deal.II/numerics/vector_tools.h>
109 *   #include <deal.II/numerics/matrix_tools.h>
110 *   #include <deal.II/numerics/data_out.h>
111 *   #include <deal.II/numerics/error_estimator.h>
112 *   #include <deal.II/numerics/solution_transfer.h>
113 *  
114 *   #include <typeinfo>
115 *   #include <fstream>
116 *   #include <iostream>
117 *  
118 *   #include <deal.II/numerics/solution_transfer.h>
119 *  
120 * @endcode
121 *
122 * Open a namespace for this program and import everything from the
123 * dealii namespace into it.
124 *
125 * @code
126 *   namespace nsp
127 *   {
128 *   using namespace dealii;
129 *  
130 * @endcode
131 *
132 * ********************************************************
133 *
134 * @code
135 *   class ParameterReader : public Subscriptor
136 *   {
137 *   public:
138 *   ParameterReader(ParameterHandler &);
139 *   void read_parameters(const std::string);
140 *   private:
141 *   void declare_parameters();
142 *   ParameterHandler &prm;
143 *   };
144 * @endcode
145 *
146 * Constructor
147 *
148 * @code
149 *   ParameterReader::ParameterReader(ParameterHandler &paramhandler):
150 *   prm(paramhandler)
151 *   {}
152 *  
153 *   void ParameterReader::declare_parameters()
154 *   {
155 *  
156 *   prm.enter_subsection ("Global Parameters");
157 *   {
158 *   prm.declare_entry("p", "100",Patterns::Double(2.1),
159 *   "Penalization parameter");
160 *   prm.declare_entry("known_solution", "true",Patterns::Bool(),
161 *   "Whether the exact solution is known");
162 *   }
163 *   prm.leave_subsection ();
164 *  
165 *   prm.enter_subsection ("Mesh & Refinement Parameters");
166 *   {
167 *   prm.declare_entry("Code for the domain", "0",Patterns::Integer(0,2),
168 *   "Number identifying the domain in which we solve the problem");
169 *   prm.declare_entry("No of initial refinements", "4",Patterns::Integer(0),
170 *   "Number of global mesh refinement steps applied to initial coarse grid");
171 *   prm.declare_entry("No of adaptive refinements", "8",Patterns::Integer(0),
172 *   "Number of global adaptive mesh refinements");
173 *   prm.declare_entry("top_fraction_of_cells", "0.25",Patterns::Double(0),
174 *   "refinement threshold");
175 *   prm.declare_entry("bottom_fraction_of_cells", "0.05",Patterns::Double(0),
176 *   "coarsening threshold");
177 *   }
178 *   prm.leave_subsection ();
179 *  
180 *  
181 *   prm.enter_subsection ("Algorithm Parameters");
182 *   {
183 *   prm.declare_entry("Descent_direction", "0",Patterns::Integer(0,1),
184 *   "0: Preconditioned descent, 1: Newton Method");
185 *   prm.declare_entry("init_p", "10",Patterns::Double(2),
186 *   "Initial p");
187 *   prm.declare_entry("delta_p", "50",Patterns::Double(0),
188 *   "increase of p");
189 *   prm.declare_entry("Max_CG_it", "1500",Patterns::Integer(1),
190 *   "Maximum Number of CG iterations");
191 *   prm.declare_entry("CG_tol", "1e-10",Patterns::Double(0),
192 *   "Tolerance for CG iterations");
193 *   prm.declare_entry("max_LS_it", "45",Patterns::Integer(1),
194 *   "Maximum Number of LS iterations");
195 *   prm.declare_entry("line_search_tolerence", "1e-6",Patterns::Double(0),
196 *   "line search tolerance constant (c1 in Nocedal-Wright)");
197 *   prm.declare_entry("init_step_length", "1e-2",Patterns::Double(0),
198 *   "initial step length in line-search");
199 *   prm.declare_entry("Max_inner", "800",Patterns::Integer(1),
200 *   "Maximum Number of inner iterations");
201 *   prm.declare_entry("eps", "1.0e-8",Patterns::Double(0),
202 *   "Threshold on norm of the derivative to declare optimality achieved");
203 *   prm.declare_entry("hi_eps", "1.0e-9",Patterns::Double(0),
204 *   "Threshold on norm of the derivative to declare optimality achieved in highly refined mesh");
205 *   prm.declare_entry("hi_th", "8",Patterns::Integer(0),
206 *   "Number of adaptive refinement before change convergence threshold");
207 *   }
208 *   prm.leave_subsection ();
209 *  
210 *   }
211 *   void ParameterReader::read_parameters (const std::string parameter_file)
212 *   {
213 *   declare_parameters();
214 *   prm.parse_input (parameter_file);
215 *   }
216 *  
217 * @endcode
218 *
219 * ******************************************************************************************
220 * The solution of the elastoplastic torsion problem on the unit disk with rhs=4.
221 *
222
223 *
224 *
225 * @code
226 *   template <int dim>
227 *   class Solution : public Function<dim>
228 *   {
229 *   public:
230 *   Solution () : Function<dim>() {}
231 *   virtual double value (const Point<dim> &pto, const unsigned int component = 0) const override;
232 *   virtual Tensor<1,dim> gradient (const Point<dim> &pto, const unsigned int component = 0) const override;
233 *   };
234 *  
235 *   template <int dim>
236 *   double Solution<dim>::value (const Point<dim> &pto,const unsigned int) const
237 *   {
238 *   double r=sqrt(pto.square());
239 *   if (r<0.5)
240 *   return -1.0*std::pow(r,2.0)+0.75;
241 *   else
242 *   return 1.0-r;
243 *   }
244 *  
245 *  
246 *  
247 *   template <int dim>
248 *   Tensor<1,dim> Solution<dim>::gradient (const Point<dim> &pto,const unsigned int) const
249 *   {
250 *   double r=sqrt(pto.square());
251 *   if (r<0.5)
252 *   return -2.0*pto;
253 *   else
254 *   return -1.0*pto/r;
255 *   }
256 *  
257 *  
258 *  
259 *  
260 * @endcode
261 *
262 * ******************************************************************************************
263 *
264 * @code
265 *   /* Compute the Lagrange multiplier (as a derived quantity) */
266 *  
267 *  
268 *   template <int dim>
269 *   class ComputeMultiplier : public DataPostprocessor<dim>
270 *   {
271 *   private:
272 *   double p;
273 *   public:
274 *   ComputeMultiplier (double pe);
275 *  
276 *   virtual
277 *   void compute_derived_quantities_scalar (
278 *   const std::vector< double > &,
279 *   const std::vector< Tensor< 1, dim > > &,
280 *   const std::vector< Tensor< 2, dim > > &,
281 *   const std::vector< Point< dim > > &,
282 *   const std::vector< Point< dim > > &,
283 *   std::vector< Vector< double > > &
284 *   ) const;
285 *  
286 *   virtual std::vector<std::string> get_names () const override;
287 *  
288 *   virtual
289 *   std::vector<DataComponentInterpretation::DataComponentInterpretation>
290 *   get_data_component_interpretation () const override;
291 *  
292 *   virtual UpdateFlags get_needed_update_flags () const override;
293 *   };
294 *  
295 *  
296 *   template <int dim>
297 *   ComputeMultiplier<dim>::ComputeMultiplier (double pe): p(pe)
298 *   {}
299 *  
300 *  
301 *   template <int dim>
302 *   void ComputeMultiplier<dim>::compute_derived_quantities_scalar(
303 *   const std::vector< double > & /*uh*/,
304 *   const std::vector< Tensor< 1, dim > > &duh,
305 *   const std::vector< Tensor< 2, dim > > & /*dduh*/,
306 *   const std::vector< Point< dim > > & /* normals*/,
307 *   const std::vector< Point< dim > > & /*evaluation_points*/,
308 *   std::vector< Vector< double > > &computed_quantities ) const
309 *   {
310 *   const unsigned int n_quadrature_points = duh.size();
311 *  
312 *   for (unsigned int q=0; q<n_quadrature_points; ++q)
313 *   {
314 *   long double sqrGrad=duh[q]* duh[q]; //squared norm of the gradient
315 *   long double exponent=(p-2.0)/2*std::log(sqrGrad);
316 *   computed_quantities[q](0) = std::sqrt(sqrGrad); // norm of the gradient
317 *   computed_quantities[q](1)= std::exp(exponent); // multiplier
318 *   }
319 *   }
320 *  
321 *  
322 *  
323 *  
324 *  
325 *   template <int dim>
326 *   std::vector<std::string>
327 *   ComputeMultiplier<dim>::get_names() const
328 *   {
329 *   std::vector<std::string> solution_names;
330 *   solution_names.push_back ("Gradient_norm");
331 *   solution_names.push_back ("Lagrange_multiplier");
332 *   return solution_names;
333 *   }
334 *  
335 *  
336 *   template <int dim>
337 *   UpdateFlags
338 *   ComputeMultiplier<dim>::get_needed_update_flags () const
339 *   {
340 *   return update_gradients;
341 *   }
342 *  
343 *  
344 *  
345 *   template <int dim>
346 *   std::vector<DataComponentInterpretation::DataComponentInterpretation>
347 *   ComputeMultiplier<dim>:: get_data_component_interpretation () const
348 *   {
349 *   std::vector<DataComponentInterpretation::DataComponentInterpretation>
350 *   interpretation;
351 * @endcode
352 *
353 * norm of the gradient
354 *
355 * @code
356 *   interpretation.push_back (DataComponentInterpretation::component_is_scalar);
357 * @endcode
358 *
359 * Lagrange multiplier
360 *
361 * @code
362 *   interpretation.push_back (DataComponentInterpretation::component_is_scalar);
363 *   return interpretation;
364 *   }
365 *  
366 *  
367 *  
368 *  
369 *  
370 * @endcode
371 *
372 * ***************************************************************************************
373 *
374 * @code
375 *   template <int dim>
376 *   class ElastoplasticTorsion
377 *   {
378 *   public:
379 *   ElastoplasticTorsion (ParameterHandler &);
380 *   ~ElastoplasticTorsion ();
381 *   void run ();
382 *  
383 *   private:
384 *   void setup_system (const bool initial_step);
385 *   void assemble_system ();
386 *   bool solve (const int inner_it);
387 *   void init_mesh ();
388 *   void refine_mesh ();
389 *   void set_boundary_values ();
390 *   double phi (const double alpha) const;
391 *   bool checkWolfe(double &alpha, double &phi_alpha) const;
392 *   bool determine_step_length (const int inner_it);
393 *   void print_it_message (const int counter, bool ks);
394 *   void output_results (unsigned int refinement) const;
395 *   void format_convergence_tables();
396 *   void process_solution (const unsigned int cycle);
397 *   void process_multiplier (const unsigned int cycle,const int iter,double time);
398 *   double dual_error () const;
399 *   double dual_infty_error () const;
400 *   double W (double Du2) const;
401 *   double Wp (double Du2) const;
402 *   double G (double Du2) const;
403 *  
404 *  
405 *  
406 *   ParameterHandler &prm;
408 *   DoFHandler<dim> dof_handler;
409 *   AffineConstraints<double> hanging_node_constraints;
410 *   SparsityPattern sparsity_pattern;
411 *   SparseMatrix<double> system_matrix;
412 *   ConvergenceTable convergence_table;
413 *   ConvergenceTable dual_convergence_table;
414 *   Vector<double> present_solution;
415 *   Vector<double> newton_update;
416 *   Vector<double> system_rhs;
417 *   Vector<double> grad_norm;
419 *  
420 *  
421 *   double step_length,phi_zero,phi_alpha,phip,phip_zero;
422 *   double old_step,old_phi_zero,old_phip;
423 *   double L2_error;
424 *   double H1_error;
425 *   double Linfty_error;
426 *   double dual_L1_error;
427 *   double dual_L_infty_error;
428 *   FE_Q<dim> fe;
429 *   double p;
430 *   double line_search_tolerence; // c_1 in Nocedal & Wright
431 *   unsigned int dir_id;
432 *   std::string elements;
433 *   std::string Method;
434 *  
435 *   };
436 *  
437 *   /*******************************************************************************************/
438 * @endcode
439 *
440 * Boundary condition
441 *
442
443 *
444 *
445 * @code
446 *   template <int dim>
447 *   class BoundaryValues : public Function<dim>
448 *   {
449 *   public:
450 *   BoundaryValues () : Function<dim>() {}
451 *  
452 *   virtual double value (const Point<dim> &p,
453 *   const unsigned int component = 0) const override;
454 *   };
455 *  
456 *  
457 *   template <int dim>
458 *   double BoundaryValues<dim>::value (const Point<dim> &/*pto*/,
459 *   const unsigned int /*component*/) const
460 *   {
461 * @endcode
462 *
463 * could be anything else (theory works provided |Dg|_infty < 1/2)
464 *
465 * @code
466 *   return 0.0;
467 *  
468 *   /* A challenging BC leading to overdetermined problems
469 *   it is regulated by the parameter 0<eta<1.
470 *   eta closer to 1 leads to more difficult problems.
471 *  
472 *   double pii=numbers::PI;
473 *   double theta=std::atan2(p[1],p[0])+pii;
474 *   double eta=0.9;
475 *  
476 *   if (theta <= 0.5)
477 *   return eta*(theta*theta);
478 *   else if ((theta >0.5) & (theta<= pii-0.5))
479 *   return eta*(theta-0.25);
480 *   else if ((theta>pii-0.5)&(theta<= pii+0.5))
481 *   return eta*(pii-0.75-(theta-(pii-0.5))*(theta-(pii+0.5)));
482 *   else if ((theta>pii+0.5)&(theta<= 2*pii-0.5))
483 *   return eta*((2*pii-theta)-0.25);
484 *   else
485 *   return eta*((theta-2*pii)*(theta-2*pii) );*/
486 *   }
487 *  
488 *  
489 *  
490 *   /******************************************************************************/
491 * @endcode
492 *
493 * Right-Hand Side
494 *
495 * @code
496 *   template <int dim>
497 *   class RightHandSide : public Function<dim>
498 *   {
499 *   public:
500 *   RightHandSide () : Function<dim>() {}
501 *   virtual double value (const Point<dim> &p,
502 *   const unsigned int component = 0) const override;
503 *   };
504 *  
505 *   template <int dim>
506 *   double RightHandSide<dim>::value (const Point<dim> &/*p*/,
507 *   const unsigned int /*component*/) const
508 *   {
509 * @endcode
510 *
511 * set to constant = 4, for which explicit solution to compare exists
512 * could be anything
513 *
514 * @code
515 *   double return_value = 4.0;
516 *   return return_value;
517 *   }
518 *  
519 *  
520 *  
521 *   /*******************************************************************/
522 * @endcode
523 *
524 * The ElastoplasticTorsion class implementation
525 *
526
527 *
528 * Constructor of the class
529 *
530 * @code
531 *   template <int dim>
532 *   ElastoplasticTorsion<dim>::ElastoplasticTorsion (ParameterHandler &param):
533 *   prm(param),
534 *   dof_handler (triangulation),
535 *   L2_error(1.0),
536 *   H1_error(1.0),
537 *   Linfty_error(1.0),
538 *   dual_L1_error(1.0),
539 *   dual_L_infty_error(1.0),
540 *   fe(2)
541 *   {
542 *   prm.enter_subsection ("Global Parameters");
543 *   p=prm.get_double("p");
544 *   prm.leave_subsection ();
545 *   prm.enter_subsection ("Algorithm Parameters");
546 *   line_search_tolerence=prm.get_double("line_search_tolerence");
547 *   dir_id=prm.get_integer("Descent_direction");
548 *   prm.leave_subsection ();
549 *   if (fe.degree==1)
550 *   elements="P1";
551 *   else elements="P2";
552 *  
553 *   if (dir_id==0)
554 *   Method="Precond";
555 *   else
556 *   Method="Newton";
557 *   }
558 *  
559 *  
560 *  
561 *   template <int dim>
562 *   ElastoplasticTorsion<dim>::~ElastoplasticTorsion ()
563 *   {
564 *   dof_handler.clear ();
565 *   }
566 *  
567 *   /*****************************************************************************************/
568 * @endcode
569 *
570 * print iteration message
571 *
572
573 *
574 *
575 * @code
576 *   template <int dim>
577 *   void ElastoplasticTorsion<dim>::print_it_message (const int counter, bool ks)
578 *   {
579 *   if (ks)
580 *   {
581 *   process_solution (counter);
582 *   std::cout << "iteration="<< counter+1 << " J(u_h)= "<< phi_zero << ", H1 error: "
583 *   << H1_error <<", W0-1,infty error: "<< Linfty_error<< " J'(u_h)(w)= "<< phip
584 *   << ", |J'(u_h)|= "<< system_rhs.l2_norm()<<std::endl;
585 *   }
586 *   else
587 *   {
588 *   std::cout << "iteration= " << counter+1 << " J(u_h)= "
589 *   << phi_alpha << " J'(u_h)= "<< phip<<std::endl;
590 *   }
591 *   }
592 *  
593 *  
594 *   /*****************************************************************************************/
595 * @endcode
596 *
597 * Convergence Tables
598 *
599
600 *
601 *
602
603 *
604 *
605 * @code
606 *   /*************************************************************/
607 * @endcode
608 *
609 * formatting
610 *
611
612 *
613 *
614 * @code
615 *   template <int dim>
616 *   void ElastoplasticTorsion<dim>::format_convergence_tables()
617 *   {
618 *   convergence_table.set_precision("L2", 3);
619 *   convergence_table.set_precision("H1", 3);
620 *   convergence_table.set_precision("Linfty", 3);
621 *   convergence_table.set_precision("function value", 3);
622 *   convergence_table.set_precision("derivative", 3);
623 *   dual_convergence_table.set_precision("dual_L1", 3);
624 *   dual_convergence_table.set_precision("dual_Linfty", 3);
625 *   dual_convergence_table.set_precision("L2", 3);
626 *   dual_convergence_table.set_precision("H1", 3);
627 *   dual_convergence_table.set_precision("Linfty", 3);
628 *   convergence_table.set_scientific("L2", true);
629 *   convergence_table.set_scientific("H1", true);
630 *   convergence_table.set_scientific("Linfty", true);
631 *   convergence_table.set_scientific("function value", true);
632 *   convergence_table.set_scientific("derivative", true);
633 *   dual_convergence_table.set_scientific("dual_L1", true);
634 *   dual_convergence_table.set_scientific("dual_Linfty", true);
635 *   dual_convergence_table.set_scientific("L2", true);
636 *   dual_convergence_table.set_scientific("H1", true);
637 *   dual_convergence_table.set_scientific("Linfty", true);
638 *  
639 *   }
640 *  
641 *   /****************************************/
642 * @endcode
643 *
644 * fill-in entry for the solution
645 *
646 * @code
647 *   template <int dim>
648 *   void ElastoplasticTorsion<dim>::process_solution (const unsigned int it)
649 *   {
650 *   Vector<float> difference_per_cell (triangulation.n_active_cells());
651 *  
652 * @endcode
653 *
654 * compute L2 error (save to difference_per_cell)
655 *
656 * @code
657 *   VectorTools::integrate_difference (dof_handler,present_solution,
658 *   Solution<dim>(),difference_per_cell,QGauss<dim>(3),VectorTools::L2_norm);
659 *   L2_error = difference_per_cell.l2_norm();
660 *  
661 * @endcode
662 *
663 * compute H1 error (save to difference_per_cell)
664 *
665 * @code
666 *   VectorTools::integrate_difference (dof_handler,present_solution,Solution<dim>(),
667 *   difference_per_cell,QGauss<dim>(3),VectorTools::H1_seminorm);
668 *   H1_error = difference_per_cell.l2_norm();
669 *  
670 * @endcode
671 *
672 * compute W1infty error (save to difference_per_cell)
673 *
674 * @code
675 *   const QTrapezoid<1> q_trapez;
676 *   const QIterated<dim> q_iterated (q_trapez, 5);
677 *   VectorTools::integrate_difference (dof_handler,present_solution,Solution<dim>(),
678 *   difference_per_cell,q_iterated,VectorTools::W1infty_seminorm);
679 *   Linfty_error = difference_per_cell.linfty_norm();
680 *  
681 *  
682 *   convergence_table.add_value("cycle", it);
683 *   convergence_table.add_value("p", p);
684 *   convergence_table.add_value("L2", L2_error);
685 *   convergence_table.add_value("H1", H1_error);
686 *   convergence_table.add_value("Linfty", Linfty_error);
687 *   convergence_table.add_value("function value", phi_alpha);
688 *   convergence_table.add_value("derivative", phip);
689 *   }
690 *  
691 *  
692 *   /***************************************/
693 * @endcode
694 *
695 * fill-in entry for the multiplier
696 *
697 * @code
698 *   template <int dim>
699 *   void ElastoplasticTorsion<dim>::process_multiplier (const unsigned int cycle, const int iter,double time)
700 *   {
701 *   const unsigned int n_active_cells=triangulation.n_active_cells();
702 *   const unsigned int n_dofs=dof_handler.n_dofs();
703 *   dual_L1_error=dual_error();
704 *   dual_L_infty_error=dual_infty_error();
705 *  
706 *  
707 *   dual_convergence_table.add_value("cycle", cycle);
708 *   dual_convergence_table.add_value("p", p);
709 *   dual_convergence_table.add_value("iteration_number", iter);
710 *   dual_convergence_table.add_value("cpu_time", time);
711 *   dual_convergence_table.add_value("cells", n_active_cells);
712 *   dual_convergence_table.add_value("dofs", n_dofs);
713 *   dual_convergence_table.add_value("L2", L2_error);
714 *   dual_convergence_table.add_value("H1", H1_error);
715 *   dual_convergence_table.add_value("Linfty", Linfty_error);
716 *   dual_convergence_table.add_value("dual_L1", dual_L1_error);
717 *   dual_convergence_table.add_value("dual_Linfty", dual_L_infty_error);
718 *  
719 *   }
720 *  
721 *  
722 *  
723 *  
724 *   /****************************************************************************************/
725 * @endcode
726 *
727 * ElastoplasticTorsion::setup_system
728 * unchanged from @ref step_15 "step-15"
729 *
730
731 *
732 *
733 * @code
734 *   template <int dim>
735 *   void ElastoplasticTorsion<dim>::setup_system (const bool initial_step)
736 *   {
737 *   if (initial_step)
738 *   {
739 *   dof_handler.distribute_dofs (fe);
740 *   present_solution.reinit (dof_handler.n_dofs());
741 *   grad_norm.reinit (dof_handler.n_dofs());
742 *   lambda.reinit (dof_handler.n_dofs());
743 *  
744 *   hanging_node_constraints.clear ();
746 *   hanging_node_constraints);
747 *   hanging_node_constraints.close ();
748 *   }
749 *  
750 *  
751 * @endcode
752 *
753 * The remaining parts of the function
754 *
755
756 *
757 *
758 * @code
759 *   newton_update.reinit (dof_handler.n_dofs());
760 *   system_rhs.reinit (dof_handler.n_dofs());
761 *   DynamicSparsityPattern c_sparsity(dof_handler.n_dofs());
762 *   DoFTools::make_sparsity_pattern (dof_handler, c_sparsity);
763 *   hanging_node_constraints.condense (c_sparsity);
764 *   sparsity_pattern.copy_from(c_sparsity);
765 *   system_matrix.reinit (sparsity_pattern);
766 *   }
767 *  
768 *   /***************************************************************************************/
769 *   /* the coefficients W, W' and G defining the problem.
770 *  
771 *   Min_u \int W(|Du|^2) dx
772 *  
773 *   They must be consistent as G(s)=W'(s)+2s W''(s) for any s>0.
774 *   recall that they receive the SQUARED gradient. */
775 *  
776 *   template <int dim>
777 *   double ElastoplasticTorsion<dim>::W (double Du2) const
778 *   {
779 *   return Du2;
780 *   }
781 *  
782 *   template <int dim>
783 *   double ElastoplasticTorsion<dim>::Wp (double /*Du2*/) const
784 *   {
785 *   return 1.0;
786 *   }
787 *  
788 *   template <int dim>
789 *   double ElastoplasticTorsion<dim>::G (double /*Du2*/) const
790 *   {
791 *   return 1.0;
792 *   }
793 *   /***************************************************************************************/
794 *  
795 *   template <int dim>
796 *   void ElastoplasticTorsion<dim>::assemble_system ()
797 *   {
798 *  
799 *  
800 *   const QGauss<dim> quadrature_formula(3);
801 *   const RightHandSide<dim> right_hand_side;
802 *   system_matrix = 0;
803 *   system_rhs = 0;
804 *  
805 *   FEValues<dim> fe_values (fe, quadrature_formula,
806 *   update_gradients |
807 *   update_values |
809 *   update_JxW_values);
810 *  
811 *   const unsigned int dofs_per_cell = fe.dofs_per_cell;
812 *   const unsigned int n_q_points = quadrature_formula.size();
813 *  
814 *   FullMatrix<double> cell_matrix (dofs_per_cell, dofs_per_cell);
815 *   Vector<double> cell_rhs (dofs_per_cell);
816 *  
817 *   std::vector<Tensor<1, dim> > old_solution_gradients(n_q_points);
818 *   std::vector<types::global_dof_index> local_dof_indices (dofs_per_cell);
819 *  
820 *  
822 *   cell = dof_handler.begin_active(),
823 *   endc = dof_handler.end();
824 *   for (; cell!=endc; ++cell)
825 *   {
826 *   cell_matrix = 0;
827 *   cell_rhs = 0;
828 *  
829 *   fe_values.reinit (cell);
830 *   fe_values.get_function_gradients(present_solution,
831 *   old_solution_gradients);
832 *  
833 *   for (unsigned int q_point = 0; q_point < n_q_points; ++q_point)
834 *   {
835 *   long double coeff=0.0;
836 *   long double a=old_solution_gradients[q_point] * old_solution_gradients[q_point];
837 *   long double exponent=(p-2.0)/2*std::log(a);
838 *   coeff= std::exp( exponent);
839 *   for (unsigned int i=0; i<dofs_per_cell; ++i)
840 *   {
841 *   for (unsigned int j=0; j<dofs_per_cell; ++j)
842 *   {
843 *   if (dir_id==1)
844 *   {
845 *   cell_matrix(i, j) += fe_values.shape_grad(i, q_point) * fe_values.shape_grad(j, q_point)
846 *   * (G(a)+(p-1.0)*coeff) * fe_values.JxW(q_point);
847 *   }
848 *   else
849 *   {
850 *   cell_matrix(i, j) += fe_values.shape_grad(i, q_point) * fe_values.shape_grad(j, q_point)
851 *   * (Wp(a)+coeff)
852 *   * fe_values.JxW(q_point);
853 *   }
854 *   }
855 *  
856 *   cell_rhs(i) -= ( fe_values.shape_grad(i, q_point)
857 *   * old_solution_gradients[q_point]
858 *   * (Wp(a)+coeff)
859 *   -right_hand_side.value(fe_values.quadrature_point(q_point))
860 *   *fe_values.shape_value(i, q_point)
861 *   )
862 *   * fe_values.JxW(q_point);
863 *   }
864 *   }
865 *  
866 *   cell->get_dof_indices (local_dof_indices);
867 *   for (unsigned int i=0; i<dofs_per_cell; ++i)
868 *   {
869 *   for (unsigned int j=0; j<dofs_per_cell; ++j)
870 *   system_matrix.add (local_dof_indices[i],
871 *   local_dof_indices[j],
872 *   cell_matrix(i,j));
873 *  
874 *   system_rhs(local_dof_indices[i]) += cell_rhs(i);
875 *   }
876 *   }
877 *  
878 *   hanging_node_constraints.condense (system_matrix);
879 *   hanging_node_constraints.condense (system_rhs);
880 *  
881 *   std::map<types::global_dof_index,double> boundary_values;
883 *   0,
885 *   boundary_values);
886 *   MatrixTools::apply_boundary_values (boundary_values,
887 *   system_matrix,
888 *   newton_update,
889 *   system_rhs);
890 *   }
891 *  
892 *  
893 *  
894 *  
895 *   /********************************** Refine Mesh ****************************************/
896 * @endcode
897 *
898 * unchanged from @ref step_15 "step-15"
899 *
900
901 *
902 *
903 * @code
904 *   template <int dim>
905 *   void ElastoplasticTorsion<dim>::refine_mesh ()
906 *   {
907 *   using FunctionMap = std::map<types::boundary_id, const Function<dim> *>;
908 *  
909 *   Vector<float> estimated_error_per_cell (triangulation.n_active_cells());
910 *   KellyErrorEstimator<dim>::estimate (dof_handler,
911 *   QGauss<dim-1>(3),
912 *   FunctionMap(),
913 *   present_solution,
914 *   estimated_error_per_cell);
915 *  
916 *   prm.enter_subsection ("Mesh & Refinement Parameters");
917 *   const double top_fraction=prm.get_double("top_fraction_of_cells");
918 *   const double bottom_fraction=prm.get_double("bottom_fraction_of_cells");
919 *   prm.leave_subsection ();
921 *   estimated_error_per_cell,
922 *   top_fraction, bottom_fraction);
923 *  
924 *   triangulation.prepare_coarsening_and_refinement ();
925 *   SolutionTransfer<dim> solution_transfer(dof_handler);
926 *   solution_transfer.prepare_for_coarsening_and_refinement(present_solution);
927 *   triangulation.execute_coarsening_and_refinement();
928 *   dof_handler.distribute_dofs(fe);
929 *   # if DEAL_II_VERSION_GTE(9, 7, 0)
930 *   present_solution.reinit(dof_handler.n_dofs());
931 *   solution_transfer.interpolate(present_solution);
932 *   # else
933 *   Vector<double> tmp(dof_handler.n_dofs());
934 *   solution_transfer.interpolate(present_solution, tmp);
935 *   present_solution = tmp;
936 *   # endif
937 *   set_boundary_values ();
938 *   hanging_node_constraints.clear();
939 *  
941 *   hanging_node_constraints);
942 *   hanging_node_constraints.close();
943 *   hanging_node_constraints.distribute (present_solution);
944 *   setup_system (false);
945 *   }
946 *  
947 *  
948 *   /*******************************************************************************************/
949 * @endcode
950 *
951 * Dump the norm of the gradient and the lagrange multiplier in vtu format for visualization
952 *
953 * @code
954 *   template <int dim>
955 *   void ElastoplasticTorsion<dim>::output_results (unsigned int counter) const
956 *   {
957 * @endcode
958 *
959 * multiplier object contains both |Du| and lambda.
960 *
961 * @code
962 *   ComputeMultiplier<dim> multiplier(p);
963 *   DataOut<dim> data_out;
964 *  
965 *   data_out.attach_dof_handler (dof_handler);
966 *   data_out.add_data_vector (present_solution, "solution");
967 *   data_out.add_data_vector (present_solution, multiplier);
968 *   data_out.build_patches ();
969 *   std::ostringstream p_str;
970 *   p_str << p<<"-cycle-"<<counter;
971 *   std::string str = p_str.str();
972 *   const std::string filename = "solution-" + str+".vtu";
973 *   std::ofstream output (filename.c_str());
974 *   data_out.write_vtu (output);
975 *   }
976 *  
977 *   /********************************************************************************************/
978 * @endcode
979 *
980 * unchanged from @ref step_15 "step-15"
981 *
982 * @code
983 *   template <int dim>
984 *   void ElastoplasticTorsion<dim>::set_boundary_values ()
985 *   {
986 *   std::map<types::global_dof_index, double> boundary_values;
988 *   0,
989 *   BoundaryValues<dim>(),
990 *   boundary_values);
991 *   for (std::map<types::global_dof_index, double>::const_iterator
992 *   bp = boundary_values.begin();
993 *   bp != boundary_values.end(); ++bp)
994 *   present_solution(bp->first) = bp->second;
995 *   }
996 *  
997 *  
998 *   /****************************************************************************************/
999 * @endcode
1000 *
1001 * COMPUTE @f$\phi(\alpha)=J_p(u_h+\alpha w)@f$
1002 *
1003 * @code
1004 *   template <int dim>
1005 *   double ElastoplasticTorsion<dim>::phi (const double alpha) const
1006 *   {
1007 *   double obj = 0.0;
1008 *   const RightHandSide<dim> right_hand_side;
1009 *   Vector<double> evaluation_point (dof_handler.n_dofs());
1010 *   evaluation_point = present_solution; // copy of u_h
1011 *   evaluation_point.add (alpha, newton_update); // u_{n+1}=u_n+alpha w_n
1012 *  
1013 *   const QGauss<dim> quadrature_formula(3);
1014 *   FEValues<dim> fe_values (fe, quadrature_formula,
1015 *   update_gradients |
1016 *   update_values |
1018 *   update_JxW_values);
1019 *  
1020 *   const unsigned int dofs_per_cell = fe.dofs_per_cell;
1021 *   const unsigned int n_q_points = quadrature_formula.size();
1022 *  
1023 *   Vector<double> cell_residual (dofs_per_cell);
1024 *   std::vector<Tensor<1, dim> > gradients(n_q_points);
1025 *   std::vector<double> values(n_q_points);
1026 *  
1027 *  
1028 *   std::vector<types::global_dof_index> local_dof_indices (dofs_per_cell);
1029 *  
1031 *   cell = dof_handler.begin_active(),
1032 *   endc = dof_handler.end();
1033 *   for (; cell!=endc; ++cell)
1034 *   {
1035 *   cell_residual = 0;
1036 *   fe_values.reinit (cell);
1037 *   fe_values.get_function_gradients (evaluation_point, gradients);
1038 *   fe_values.get_function_values (evaluation_point, values);
1039 *  
1040 *  
1041 *   for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
1042 *   {
1043 *   double Du2=gradients[q_point] * gradients[q_point]; // Du2=|Du|^2
1044 *   double penalty;
1045 *   if (Du2<1.0e-10)
1046 *   penalty=0.0;
1047 *   else
1048 *   penalty=std::pow(Du2,p/2.0); // penalty=|Du|^p
1049 *  
1050 * @endcode
1051 *
1052 * obj+= 1/2 W(|Du|^2)+1/p |Du|^p -fu (see (1))
1053 *
1054 * @code
1055 *   obj+=(
1056 *   (0.5*W(Du2)+penalty/p)- right_hand_side.value(fe_values.quadrature_point(q_point))*values[q_point]
1057 *   ) * fe_values.JxW(q_point);
1058 *   }
1059 *  
1060 *   }
1061 *  
1062 *   return obj;
1063 *   }
1064 *  
1065 *  
1066 *   /***************************************************************************************************/
1067 * @endcode
1068 *
1069 * Compute L^1 error norm of Lagrange Multiplier
1070 * with respect to exact solution (cf. Alvarez & Flores, 2015)
1071 *
1072
1073 *
1074 *
1075 * @code
1076 *   template <int dim>
1077 *   double ElastoplasticTorsion<dim>::dual_error () const
1078 *   {
1079 *   double obj = 0.0;
1080 *  
1081 *   const QGauss<dim> quadrature_formula(3);
1082 *   FEValues<dim> fe_values (fe, quadrature_formula,
1083 *   update_gradients |
1085 *   update_JxW_values);
1086 *  
1087 *   const unsigned int dofs_per_cell = fe.dofs_per_cell;
1088 *   const unsigned int n_q_points = quadrature_formula.size();
1089 *  
1090 *   Vector<double> cell_residual (dofs_per_cell);
1091 *   std::vector<Tensor<1, dim> > gradients(n_q_points);
1092 *  
1093 *   std::vector<types::global_dof_index> local_dof_indices (dofs_per_cell);
1094 *  
1096 *   cell = dof_handler.begin_active(),
1097 *   endc = dof_handler.end();
1098 *   for (; cell!=endc; ++cell)
1099 *   {
1100 *   cell_residual = 0;
1101 *   fe_values.reinit (cell);
1102 *   fe_values.get_function_gradients (present_solution, gradients);
1103 *  
1104 *   for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
1105 *   {
1106 *   double coeff=gradients[q_point] * gradients[q_point] ;
1107 *   if (coeff<1.0e-15)
1108 *   coeff=0.0;
1109 *   else
1110 *   coeff=std::pow(coeff,(p-2.0)/2.0); // |Du_p|^(p-2)
1111 *  
1112 *   double r=std::sqrt(fe_values.quadrature_point(q_point).square());
1113 *   double exact=0;
1114 *   if (r>0.5)
1115 *   exact= 2*r-1;
1116 *  
1117 *   obj+=( std::abs(coeff-exact) ) * fe_values.JxW(q_point);
1118 *   }
1119 *  
1120 *   }
1121 *  
1122 *   return obj;
1123 *   }
1124 *  
1125 *   /*******************************************************************************************/
1126 * @endcode
1127 *
1128 * Compute L^infinity error norm of Lagrange Multiplier
1129 * with respect to exact solution (cf. Alvarez & Flores, 2015)
1130 *
1131
1132 *
1133 *
1134 * @code
1135 *   template <int dim>
1136 *   double ElastoplasticTorsion<dim>::dual_infty_error () const
1137 *   {
1138 *   double obj = 0.0;
1139 *   const QTrapezoid<1> q_trapez;
1140 *   const QIterated<dim> quadrature_formula (q_trapez, 10);
1141 *  
1142 *   FEValues<dim> fe_values (fe, quadrature_formula,
1143 *   update_gradients |
1145 *  
1146 *   const unsigned int dofs_per_cell = fe.dofs_per_cell;
1147 *   const unsigned int n_q_points = quadrature_formula.size();
1148 *  
1149 *   Vector<double> cell_residual (dofs_per_cell);
1150 *   std::vector<Tensor<1, dim> > gradients(n_q_points);
1151 *  
1152 *   std::vector<types::global_dof_index> local_dof_indices (dofs_per_cell);
1153 *  
1155 *   cell = dof_handler.begin_active(),
1156 *   endc = dof_handler.end();
1157 *   for (; cell!=endc; ++cell)
1158 *   {
1159 *   cell_residual = 0;
1160 *   fe_values.reinit (cell);
1161 *   fe_values.get_function_gradients (present_solution, gradients);
1162 *  
1163 *   for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
1164 *   {
1165 *   long double sqdGrad=gradients[q_point] * gradients[q_point] ;
1166 *   double r=std::sqrt(fe_values.quadrature_point(q_point).square());
1167 *   double exact=0;
1168 *   if (r>0.5)
1169 *   exact= 2*r-1.0;
1170 * @endcode
1171 *
1172 * compute |Du|^(p-2) as exp(p-2/2*log(Du^2))
1173 *
1174 * @code
1175 *   long double exponent=(p-2.0)/2*std::log(sqdGrad);
1176 *   long double coeff=std::exp(exponent);
1177 *  
1178 *   if (std::abs(coeff-exact)>obj )
1179 *   obj=std::abs(coeff-exact);
1180 *   }
1181 *  
1182 *   }
1183 *  
1184 *   return obj;
1185 *   }
1186 *  
1187 *   /*****************************************************************************************/
1188 * @endcode
1189 *
1190 * check whether putative step-length satisfies sufficient decrease conditions
1191 *
1192 * @code
1193 *   template <int dim>
1194 *   bool ElastoplasticTorsion<dim>::checkWolfe(double &alpha, double &phi_alpha) const
1195 *   {
1196 *   if (phi_alpha< phi_zero+line_search_tolerence*phip*alpha )
1197 *   return true;
1198 *   else
1199 *   return false;
1200 *   }
1201 *  
1202 *  
1203 *   /*****************************************************************************************/
1204 * @endcode
1205 *
1206 * Find a step-length satisfying sufficient decrease condition by line-search
1207 * uses quadratic interpolation
1208 *
1209
1210 *
1211 *
1212 * @code
1213 *   template <int dim>
1214 *   bool ElastoplasticTorsion<dim>::determine_step_length(const int inner_it)
1215 *   {
1216 *   unsigned int it=0;
1217 *   bool done;
1218 *   double alpha,nalpha;
1219 *   prm.enter_subsection ("Algorithm Parameters");
1220 *   const unsigned int max_LS_it=prm.get_integer("max_LS_it");
1221 *   double init_SL=prm.get_double("init_step_length");
1222 *   prm.leave_subsection ();
1223 *   if (inner_it==0)
1224 *   alpha=init_SL;
1225 *   else
1226 *   {
1227 *   alpha=std::min(1.45*old_step*old_phip/phip,1.0);
1228 *   }
1229 *   phi_alpha=phi(alpha);
1230 *   std::cerr << "Step length=" << alpha << ", Value= " << phi_alpha;
1231 * @endcode
1232 *
1233 * check if step-size satisfies sufficient decrease condition
1234 *
1235 * @code
1236 *   done=checkWolfe(alpha,phi_alpha);
1237 *   if (done)
1238 *   std::cerr << " accepted" << std::endl;
1239 *   else
1240 *   std::cerr << " rejected" ;
1241 *  
1242 *   while ((!done) & (it<max_LS_it))
1243 *   {
1244 * @endcode
1245 *
1246 * new try obtained by quadratic interpolation
1247 *
1248 * @code
1249 *   nalpha=-(phip*alpha*alpha)/(2*(phi_alpha-phi_zero-phip*alpha));
1250 *  
1251 *   if (nalpha<1e-3*alpha || std::abs(nalpha-alpha)/alpha<1e-8)
1252 *   nalpha=alpha/2;
1253 *   else if ( phi_alpha-phi_zero>1e3*std::abs(phi_zero) )
1254 *   nalpha=alpha/10;
1255 *   alpha=nalpha;
1256 *   phi_alpha=phi(alpha);
1257 *   done=checkWolfe(alpha,phi_alpha);
1258 *   if (done)
1259 *   std::cerr << ", finished with steplength= "<< alpha<< ", fcn value= "<< phi_alpha<<std::endl;
1260 *   it=it+1;
1261 *   }
1262 *   if (!done)
1263 *   {
1264 *   std::cerr << ", max. no. of iterations reached with steplength= "<< alpha
1265 *   << ", fcn value= "<< phi_alpha<<std::endl;
1266 *   return false;
1267 *   }
1268 *   else
1269 *   {
1270 *   step_length=alpha;
1271 *   return true;
1272 *   }
1273 *  
1274 *   }
1275 *  
1276 *   /**************************************************************************************************/
1277 * @endcode
1278 *
1279 * ElastoplasticTorsion::init_mesh()
1280 *
1281
1282 *
1283 *
1284 * @code
1285 *   template <int dim>
1286 *   void ElastoplasticTorsion<dim>::init_mesh ()
1287 *   {
1288 * @endcode
1289 *
1290 * get parameters
1291 *
1292 * @code
1293 *   prm.enter_subsection ("Mesh & Refinement Parameters");
1294 *   const int domain_id=prm.get_integer("Code for the domain");
1295 *   const int init_ref=prm.get_integer("No of initial refinements");
1296 *   prm.leave_subsection ();
1297 *  
1298 *  
1299 *   if (domain_id==0)
1300 *   {
1301 * @endcode
1302 *
1303 * For the unit disk around the origin
1304 *
1305 * @code
1307 *   static const SphericalManifold<dim> boundary;
1308 *   triangulation.set_manifold (0, boundary);
1309 *   }
1310 *   else if (domain_id==1)
1311 *   {
1312 * @endcode
1313 *
1314 * For the unit square
1315 *
1316 * @code
1318 *   }
1319 *   else if (domain_id==2)
1320 *   {
1321 *   /* For Glowinski's domain
1322 *   ___ ___ __ 1
1323 *   | |__| | __ .8
1324 *   | |
1325 *   | |
1326 *   |__________| __ 0
1327 *  
1328 *   | | | |
1329 *   0 .4 .6 1
1330 *  
1331 *   */
1332 *   Triangulation<dim> tria1;
1333 *   Triangulation<dim> tria2;
1334 *   Triangulation<dim> tria3;
1335 *   Triangulation<dim> tria4;
1336 *   Triangulation<dim> tria5;
1337 *   Triangulation<dim> tria6;
1338 *   GridGenerator::hyper_rectangle(tria1, Point<2>(0.0,0.0), Point<2>(0.4,0.8));
1339 *   GridGenerator::hyper_rectangle(tria2, Point<2>(0.0,0.8), Point<2>(0.4,1.0));
1340 *   GridGenerator::hyper_rectangle(tria3, Point<2>(0.4,0.0), Point<2>(0.6,0.8));
1341 *   GridGenerator::hyper_rectangle(tria4, Point<2>(0.6,0.0), Point<2>(1.0,0.8));
1342 *   GridGenerator::hyper_rectangle(tria5, Point<2>(0.6,0.8), Point<2>(1.0,1.0));
1343 *   GridGenerator::merge_triangulations (tria1, tria2, tria6);
1344 *   GridGenerator::merge_triangulations (tria6, tria3, tria6);
1345 *   GridGenerator::merge_triangulations (tria6, tria4, tria6);
1347 *   }
1348 * @endcode
1349 *
1350 * perform initial refinements
1351 *
1352 * @code
1353 *   triangulation.refine_global(init_ref);
1354 *   }
1355 *  
1356 *   /**************************************************************************************************/
1357 * @endcode
1358 *
1359 * ElastoplasticTorsion::solve(inner_it)
1360 * Performs one inner iteration
1361 *
1362
1363 *
1364 *
1365 * @code
1366 *   template <int dim>
1367 *   bool ElastoplasticTorsion<dim>::solve (const int inner_it)
1368 *   {
1369 *   prm.enter_subsection ("Algorithm Parameters");
1370 *   const unsigned int max_CG_it=prm.get_integer("Max_CG_it");
1371 *   const double CG_tol=prm.get_double("CG_tol");
1372 *   prm.leave_subsection ();
1373 *  
1374 *   SolverControl solver_control (max_CG_it,CG_tol);
1375 *   SolverCG<> solver (solver_control);
1376 *  
1377 *   PreconditionSSOR<> preconditioner;
1378 *   preconditioner.initialize(system_matrix,0.25);
1379 *  
1380 *   solver.solve (system_matrix, newton_update, system_rhs,
1381 *   preconditioner);
1382 *   hanging_node_constraints.distribute (newton_update);
1383 *   /****** save current quantities for line-search **** */
1384 * @endcode
1385 *
1386 * Recall that phi(alpha)=J(u+alpha w)
1387 *
1388 * @code
1389 *   old_step=step_length;
1390 *   old_phi_zero=phi_zero;
1391 *   phi_zero=phi(0); // phi(0)=J(u)
1392 *   old_phip=phip;
1393 *   phip=-1.0*(newton_update*system_rhs); //phi'(0)=J'(u) *w, rhs=-J'(u).
1394 *   if (inner_it==0)
1395 *   phip_zero=phip;
1396 *  
1397 *   if (phip>0) // this should not happen, step back
1398 *   {
1399 *   std::cout << "Not a descent direction!" <<std::endl;
1400 *   present_solution.add (-1.0*step_length, newton_update);
1401 *   step_length=step_length/2;
1402 *   phip=old_phip;
1403 *   return false;
1404 *   }
1405 *   else
1406 *   {
1407 *   if (determine_step_length(inner_it))
1408 *   {
1409 * @endcode
1410 *
1411 * update u_{n+1}=u_n+alpha w_n
1412 *
1413 * @code
1414 *   present_solution.add (step_length, newton_update);
1415 *   return true;
1416 *   }
1417 *   else return false;
1418 *   }
1419 *   }
1420 *  
1421 *  
1422 *  
1423 *   /*************************************************************************************************************/
1424 * @endcode
1425 *
1426 * ElastoplasticTorsion::run
1427 *
1428 * @code
1429 *   template <int dim>
1430 *   void ElastoplasticTorsion<dim>::run ()
1431 *   {
1432 *  
1433 * @endcode
1434 *
1435 * get parameters
1436 *
1437 * @code
1438 *   prm.enter_subsection ("Mesh & Refinement Parameters");
1439 *   const int adapt_ref=prm.get_integer("No of adaptive refinements");
1440 *   prm.leave_subsection ();
1441 *   prm.enter_subsection ("Algorithm Parameters");
1442 *   const int max_inner=prm.get_integer("Max_inner");
1443 *   const double eps=prm.get_double("eps");
1444 *   const double hi_eps=prm.get_double("hi_eps");
1445 *   const int hi_th=prm.get_integer("hi_th");
1446 *   const double init_p=prm.get_double("init_p");
1447 *   const double delta_p=prm.get_double("delta_p");
1448 *   prm.leave_subsection ();
1449 *   prm.enter_subsection ("Global Parameters");
1450 *   bool known_solution=prm.get_bool("known_solution");
1451 *   double actual_p=prm.get_double("p");
1452 *   prm.leave_subsection ();
1453 *   /************************/
1454 *  
1455 * @endcode
1456 *
1457 * init Timer
1458 *
1459 * @code
1460 *   Timer timer;
1461 *   double ptime=0.0;
1462 *   timer.start ();
1463 *  
1464 * @endcode
1465 *
1466 * initialize mesh for the selected domain
1467 *
1468 * @code
1469 *   init_mesh();
1470 *  
1471 * @endcode
1472 *
1473 * setup FE space
1474 *
1475 * @code
1476 *   setup_system (true);
1477 *   set_boundary_values ();
1478 *  
1479 * @endcode
1480 *
1481 * init counters
1482 *
1483 * @code
1484 *   int global_it=0; // Total inner iterations (counting both loops)
1485 *   int cycle=0; // Total outer iterations (counting both loops)
1486 *   int refinement = 0; // Refinements performed (adaptive) = outer iterations 2nd loop
1487 *  
1488 *  
1489 * @endcode
1490 *
1491 * prepare to start first loop
1492 *
1493 * @code
1494 *   p=init_p;
1495 *   bool well_solved=true;
1496 *  
1497 *   /***************************** First loop ***********************************/
1498 *   /****************** Prepare initial condition using increasing p *************************/
1499 *   while (p<actual_p) // outer iteration, increasing p.
1500 *   {
1501 *   std::cout <<"--Preparing initial condition with p="<<p<<" iter.= " << global_it<< " .-- "<< std::endl;
1502 *   timer.restart();
1503 *   for (int inner_iteration=0; inner_iteration<max_inner; ++inner_iteration,++global_it)
1504 *   {
1505 *   assemble_system ();
1506 *   well_solved=solve (inner_iteration);
1507 *   print_it_message (global_it, known_solution);
1508 *   if (
1509 *   ((system_rhs.l2_norm()/std::sqrt(system_rhs.size()) <1e-4) & (cycle<1)) |
1510 *   ((system_rhs.l2_norm()/std::sqrt(system_rhs.size()) <1e-5) & (cycle>=1)) |
1511 *   !well_solved
1512 *   )
1513 *   break;
1514 *   }
1515 *   ptime=timer.cpu_time();
1516 *   if (well_solved)
1517 *   output_results (cycle);
1518 *  
1519 *   if (known_solution)
1520 *   {
1521 *   process_multiplier(cycle,global_it,ptime);
1522 * @endcode
1523 *
1524 * dual_convergence_table.write_tex(dual_error_table_file);
1525 *
1526 * @code
1527 *   }
1528 *   refine_mesh();
1529 *   cycle++;
1530 *   p+=delta_p;
1531 *   }
1532 *   /*************************** first loop finished ********************/
1533 *  
1534 *  
1535 * @endcode
1536 *
1537 * prepare for second loop
1538 *
1539 * @code
1540 *   p=actual_p;
1541 *   well_solved=true;
1542 *  
1543 *  
1544 *   /***************************** Second loop *********************************/
1545 *   /**************************** Solve problem for target p *********************************/
1546 *  
1547 *   std::cout << "============ Solving problem with p=" <<p << " ==================" << std::endl;
1548 *   /***** Outer iteration - refining mesh ******************/
1549 *   while ((cycle<adapt_ref) & well_solved)
1550 *   {
1551 *   timer.restart();
1552 * @endcode
1553 *
1554 * inner iteration
1555 *
1556 * @code
1557 *   for (int inner_iteration=0; inner_iteration<max_inner; ++inner_iteration,++global_it)
1558 *   {
1559 *   assemble_system ();
1560 *   well_solved=solve (inner_iteration);
1561 *   print_it_message (global_it, known_solution);
1562 *  
1563 *   if (
1564 *   ((system_rhs.l2_norm()/std::sqrt(system_rhs.size()) < eps) & (refinement<hi_th)) |
1565 *   (( system_rhs.l2_norm()/ std::sqrt (system_rhs.size()) <hi_eps) | (!well_solved))
1566 *   )
1567 *   break;
1568 *   }
1569 * @endcode
1570 *
1571 * inner iterations finished
1572 *
1573 * @code
1574 *   ptime=timer.cpu_time();
1575 *   if (well_solved)
1576 *   output_results (cycle);
1577 *  
1578 * @endcode
1579 *
1580 * compute and display error, if the explicit solution is known
1581 *
1582 * @code
1583 *   if (known_solution)
1584 *   {
1585 *   process_multiplier(cycle,global_it,ptime);
1586 *   std::cout << "finished with H1 error: " << H1_error << ", dual error (L1): "
1587 *   << dual_L1_error << "dual error (L infty): "<<dual_L_infty_error <<std::endl;
1588 *   }
1589 *  
1590 * @endcode
1591 *
1592 * update counters
1593 *
1594 * @code
1595 *   ++refinement;
1596 *   ++cycle;
1597 * @endcode
1598 *
1599 * refine mesh
1600 *
1601 * @code
1602 *   std::cout << "******** Refined mesh " << cycle << " ********" << std::endl;
1603 *   refine_mesh();
1604 *   }// second loop
1605 *  
1606 * @endcode
1607 *
1608 * write convergence tables to file
1609 *
1610 * @code
1611 *   if (known_solution)
1612 *   {
1613 *   format_convergence_tables();
1614 *   std::string error_filename = "error"+Method+elements+".tex";
1615 *   std::ofstream error_table_file(error_filename.c_str());
1616 *   std::string dual_error_filename = "dual_error"+Method+elements+".tex";
1617 *   std::ofstream dual_error_table_file(dual_error_filename.c_str());
1618 *   convergence_table.write_tex(error_table_file);
1619 *   dual_convergence_table.write_tex(dual_error_table_file);
1620 *   }
1621 *   }//run()
1622 *  
1623 *   }//namespace
1624 *  
1625 *   /**********************************************************************************************/
1626 * @endcode
1627 *
1628 * The main function
1629 *
1630 * @code
1631 *   int main ()
1632 *   {
1633 *   try
1634 *   {
1635 *   using namespace dealii;
1636 *   using namespace nsp;
1637 *   deallog.depth_console (0);
1638 *  
1639 *   ParameterHandler prm;
1640 *   ParameterReader param(prm);
1641 *   param.read_parameters("EPT.prm");
1642 *   ElastoplasticTorsion<2> ElastoplasticTorsionProblem(prm);
1643 *   ElastoplasticTorsionProblem .run ();
1644 *   }
1645 *   catch (std::exception &exc)
1646 *   {
1647 *   std::cerr << std::endl << std::endl
1648 *   << "----------------------------------------------------" << std::endl;
1649 *   std::cerr << "Exception on processing: " << std::endl
1650 *   << exc.what() << std::endl
1651 *   << "Aborting!" << std::endl
1652 *   << "----------------------------------------------------"
1653 *   << std::endl;
1654 *  
1655 *   return 1;
1656 *   }
1657 *   catch (...)
1658 *   {
1659 *   std::cerr << std::endl << std::endl
1660 *   << "----------------------------------------------------"
1661 *   << std::endl;
1662 *   std::cerr << "Unknown exception!" << std::endl
1663 *   << "Aborting!" << std::endl
1664 *   << "----------------------------------------------------"
1665 *   << std::endl;
1666 *   return 1;
1667 *   }
1668 *   return 0;
1669 *   }
1670 * @endcode
1671
1672
1673*/
void attach_dof_handler(const DoFHandler< dim, spacedim > &)
virtual UpdateFlags get_needed_update_flags() const =0
virtual std::vector< std::string > get_names() const =0
virtual std::vector< DataComponentInterpretation::DataComponentInterpretation > get_data_component_interpretation() const
Definition fe_q.h:554
virtual Tensor< 1, dim, RangeNumberType > gradient(const Point< dim > &p, const unsigned int component=0) const
virtual RangeNumberType value(const Point< dim > &p, const unsigned int component=0) const
static void estimate(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof, const Quadrature< dim - 1 > &quadrature, const std::map< types::boundary_id, const Function< spacedim, Number > * > &neumann_bc, const ReadVector< Number > &solution, Vector< float > &error, const ComponentMask &component_mask={}, const Function< spacedim > *coefficients=nullptr, const unsigned int n_threads=numbers::invalid_unsigned_int, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id, const types::material_id material_id=numbers::invalid_material_id, const Strategy strategy=cell_diameter_over_24)
unsigned int depth_console(const unsigned int n)
Definition logstream.cc:349
Definition point.h:111
void initialize(const MatrixType &A, const AdditionalData &parameters=AdditionalData())
Definition timer.h:117
void start()
Definition timer.cc:176
#define DEAL_II_VERSION_GTE(major, minor, subminor)
Definition config.h:329
Point< 2 > second
Definition grid_out.cc:4624
Point< 2 > first
Definition grid_out.cc:4623
typename ActiveSelector::active_cell_iterator active_cell_iterator
void loop(IteratorType begin, std_cxx20::type_identity_t< IteratorType > end, DOFINFO &dinfo, INFOBOX &info, const std::function< void(std_cxx20::type_identity_t< DOFINFO > &, typename INFOBOX::CellInfo &)> &cell_worker, const std::function< void(std_cxx20::type_identity_t< DOFINFO > &, typename INFOBOX::CellInfo &)> &boundary_worker, const std::function< void(std_cxx20::type_identity_t< DOFINFO > &, std_cxx20::type_identity_t< DOFINFO > &, typename INFOBOX::CellInfo &, typename INFOBOX::CellInfo &)> &face_worker, AssemblerType &assembler, const LoopControl &lctrl=LoopControl())
Definition loop.h:564
void make_hanging_node_constraints(const DoFHandler< dim, spacedim > &dof_handler, AffineConstraints< number > &constraints)
void make_sparsity_pattern(const DoFHandler< dim, spacedim > &dof_handler, SparsityPatternBase &sparsity_pattern, const AffineConstraints< number > &constraints={}, const bool keep_constrained_dofs=true, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id)
UpdateFlags
@ update_values
Shape function values.
@ update_JxW_values
Transformed quadrature weights.
@ update_gradients
Shape function gradients.
@ update_quadrature_points
Transformed quadrature points.
LogStream deallog
Definition logstream.cc:36
std::size_t size
Definition mpi.cc:734
const Event initial
Definition event.cc:64
void hyper_ball(Triangulation< dim > &tria, const Point< dim > &center=Point< dim >(), const double radius=1., const bool attach_spherical_manifold_on_boundary_cells=false)
void hyper_rectangle(Triangulation< dim, spacedim > &tria, const Point< dim > &p1, const Point< dim > &p2, const bool colorize=false)
void hyper_cube(Triangulation< dim, spacedim > &tria, const double left=0., const double right=1., const bool colorize=false)
void merge_triangulations(const Triangulation< dim, spacedim > &triangulation_1, const Triangulation< dim, spacedim > &triangulation_2, Triangulation< dim, spacedim > &result, const double duplicated_vertex_tolerance=1.0e-12, const bool copy_manifold_ids=false, const bool copy_boundary_ids=false)
void refine(Triangulation< dim, spacedim > &tria, const Vector< Number > &criteria, const double threshold, const unsigned int max_to_mark=numbers::invalid_unsigned_int)
void refine_and_coarsen_fixed_number(Triangulation< dim, spacedim > &triangulation, const Vector< Number > &criteria, const double top_fraction_of_cells, const double bottom_fraction_of_cells, const unsigned int max_n_cells=std::numeric_limits< unsigned int >::max())
void cell_matrix(FullMatrix< double > &M, const FEValuesBase< dim > &fe, const FEValuesBase< dim > &fetest, const ArrayView< const std::vector< double > > &velocity, const double factor=1.)
Definition advection.h:74
void cell_residual(Vector< double > &result, const FEValuesBase< dim > &fe, const std::vector< Tensor< 1, dim > > &input, const ArrayView< const std::vector< double > > &velocity, double factor=1.)
Definition advection.h:130
double norm(const FEValuesBase< dim > &fe, const ArrayView< const std::vector< Tensor< 1, dim > > > &Du)
Definition divergence.h:471
void L2(Vector< number > &result, const FEValuesBase< dim > &fe, const std::vector< double > &input, const double factor=1.)
Definition l2.h:159
void apply_boundary_values(const std::map< types::global_dof_index, number > &boundary_values, SparseMatrix< number > &matrix, Vector< number > &solution, Vector< number > &right_hand_side, const bool eliminate_columns=true)
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
void interpolate_boundary_values(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof, const std::map< types::boundary_id, const Function< spacedim, number > * > &function_map, std::map< types::global_dof_index, number > &boundary_values, const ComponentMask &component_mask={})
void integrate_difference(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof, const ReadVector< Number > &fe_function, const Function< spacedim, Number > &exact_solution, OutVector &difference, const Quadrature< dim > &q, const NormType &norm, const Function< spacedim, double > *weight=nullptr, const double exponent=2.)
void run(const Iterator &begin, const std_cxx20::type_identity_t< Iterator > &end, Worker worker, Copier copier, const ScratchData &sample_scratch_data, const CopyData &sample_copy_data, const unsigned int queue_length, const unsigned int chunk_size)
bool check(const ConstraintKinds kind_in, const unsigned int dim)
unsigned int n_active_cells(const internal::TriangulationImplementation::NumberCache< 1 > &c)
Definition tria.cc:14878
STL namespace.
::VectorizedArray< Number, width > log(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > exp(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > pow(const ::VectorizedArray< Number, width > &, const Number p)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation