Amandus: Simulations based on multilevel Schwarz methods
apps.h
Go to the documentation of this file.
1 /**********************************************************************
2  * Copyright (C) 2011 - 2014 by the authors
3  * Distributed under the MIT License
4  *
5  * See the files AUTHORS and LICENSE in the project root directory
6  *
7  **********************************************************************/
8 
9 #ifndef __apps_h
10 #define __apps_h
11 
12 #include <deal.II/algorithms/any_data.h>
13 #include <deal.II/base/convergence_table.h>
14 #include <deal.II/base/logstream.h>
15 #include <deal.II/base/quadrature_lib.h>
16 #include <deal.II/base/utilities.h>
17 #include <deal.II/lac/vector.h>
18 
19 #include <algorithm>
20 #include <amandus/adaptivity.h>
21 #include <amandus/amandus.h>
22 #include <iomanip>
23 #include <sstream>
24 
31 template <int dim>
32 void
34  dealii::Algorithms::OperatorBase& solver,
35  dealii::Algorithms::OperatorBase& residual,
36  const AmandusIntegrator<dim>* error = 0,
37  AmandusIntegrator<dim>* estimator = 0,
38  const dealii::Function<dim>* initial_vector = 0,
39  const bool boundary_projection = false)
40 {
41  dealii::Vector<double> res;
42  dealii::Vector<double> sol;
43  dealii::BlockVector<double> errors;
44  if (error != 0)
45  errors.reinit(error->n_errors());
46  dealii::ConvergenceTable convergence_table;
47 
48  for (unsigned int s = 0; s < n_steps; ++s)
49  {
50  dealii::deallog << "Step " << s << std::endl;
51  if (s != 0)
52  app.refine_mesh(true);
53  solver.notify(dealii::Algorithms::Events::remesh);
54  app.setup_system();
55  app.setup_vector(res);
56  app.setup_vector(sol);
57 
58  if (initial_vector != 0)
59  {
60  if (boundary_projection)
61  {
62  app.update_vector_inhom_boundary(sol, *initial_vector, boundary_projection);
63  }
64  else
65  {
66  dealii::QGauss<dim> quadrature(app.dofs().get_fe().tensor_degree() + 2);
67  dealii::VectorTools::project(
68  app.dofs(), app.hanging_nodes(), quadrature, *initial_vector, sol);
69  /* dealii::VectorTools::interpolate(app.dofs(), *initial_vector, sol); */
70  }
71  }
72 
73  dealii::AnyData solution_data;
74  dealii::Vector<double>* p = &sol;
75  solution_data.add(p, "solution");
76 
77  dealii::AnyData data;
78 
79  dealii::Vector<double>* rhs = &res;
80  data.add(rhs, "RHS");
81  dealii::AnyData residual_data;
82  residual(data, residual_data);
83  dealii::deallog << "Residual " << res.l2_norm() << std::endl;
84  solver(solution_data, data);
85  if (error != 0)
86  {
87  app.error(errors, solution_data, *error);
88  std::vector<double> global_errors(errors.n_blocks(), 0.);
89  for (unsigned int i = 0; i < errors.n_blocks(); ++i)
90  {
91  if (error->error_type(i) == 0)
92  global_errors[i] = errors.block(i).linfty_norm();
93  else if (error->error_type(i) == 1)
94  for (unsigned int k = 0; k < errors.block(i).size(); ++k)
95  global_errors[i] += errors.block(i)[k];
96  else
97  global_errors[i] = errors.block(i).lp_norm(error->error_type(i));
98  if (error->error_name(i) != std::string())
99  dealii::deallog << "Error(" << error->error_name(i) << "): " << global_errors[i]
100  << std::endl;
101  else
102  dealii::deallog << "Error(" << i << "): " << global_errors[i] << std::endl;
103  }
104 
105  for (unsigned int i = 0; i < errors.n_blocks(); ++i)
106  {
107  std::string err_name{ "Error(" };
108  err_name += std::to_string(i);
109  err_name += ")";
110  if (error->error_name(i) != std::string())
111  err_name = error->error_name(i);
112  convergence_table.add_value(err_name, global_errors[i]);
113  convergence_table.evaluate_convergence_rates(err_name,
114  dealii::ConvergenceTable::reduction_rate_log2);
115  convergence_table.set_scientific(err_name, 1);
116  }
117  }
118 
119  if (estimator != 0)
120  {
121  dealii::deallog << "Error::Estimate: " << app.estimate(solution_data, *estimator)
122  << std::endl;
123  }
124  dealii::AnyData out_data;
125  out_data.merge(solution_data);
126  if (error != 0)
127  for (unsigned int i = 0; i < errors.n_blocks(); ++i)
128  {
129  std::string err_name{ "Error(" };
130  err_name += std::to_string(i);
131  err_name += ")";
132  if (error->error_name(i) != std::string())
133  err_name = error->error_name(i);
134  out_data.add(&errors.block(i), err_name);
135  }
136  app.output_results(s, &out_data);
137  std::cout << std::endl;
138  convergence_table.write_text(std::cout);
139  }
140 }
141 
147 template <int dim>
148 void
150  dealii::Algorithms::OperatorBase& solve,
151  const AmandusIntegrator<dim>* error = 0,
152  AmandusIntegrator<dim>* estimator = 0,
153  const dealii::Function<dim>* initial_vector = 0,
154  const dealii::Function<dim>* inhom_boundary = 0,
155  const bool boundary_projection = false)
156 {
157  dealii::Vector<double> sol;
158  dealii::BlockVector<double> errors;
159  if (error != 0)
160  errors.reinit(error->n_errors());
161  dealii::ConvergenceTable convergence_table;
162 
163  for (unsigned int s = 0; s < n_steps; ++s)
164  {
165  dealii::deallog << "Step " << s << std::endl;
166  app.refine_mesh(true);
167  solve.notify(dealii::Algorithms::Events::remesh);
168  app.setup_system();
169  app.setup_vector(sol);
170 
171  if (initial_vector != 0)
172  {
173  dealii::QGauss<dim> quadrature(app.dofs().get_fe().tensor_degree() + 2);
174  dealii::VectorTools::project(
175  app.dofs(), app.hanging_nodes(), quadrature, *initial_vector, sol);
176  }
177 
178  if (inhom_boundary != 0)
179  app.update_vector_inhom_boundary(sol, *inhom_boundary, boundary_projection);
180 
181  dealii::AnyData solution_data;
182  solution_data.add(&sol, "solution");
183 
184  dealii::AnyData data;
185  solve(solution_data, data);
186  if (error != 0)
187  {
188  app.error(errors, solution_data, *error);
189  for (unsigned int i = 0; i < errors.n_blocks(); ++i)
190  {
191  dealii::deallog << "Error(" << i << "): " << errors.block(i).l2_norm() << std::endl;
192  }
193  for (unsigned int i = 0; i < errors.n_blocks(); ++i)
194  {
195  std::string err_name{ "Error(" };
196  err_name += std::to_string(i);
197  err_name += ")";
198  convergence_table.add_value(err_name, errors.block(i).l2_norm());
199  convergence_table.evaluate_convergence_rates(err_name,
200  dealii::ConvergenceTable::reduction_rate_log2);
201  convergence_table.set_scientific(err_name, 1);
202  }
203  }
204 
205  if (estimator != 0)
206  {
207  dealii::deallog << "Error::Estimate: " << app.estimate(solution_data, *estimator)
208  << std::endl;
209  }
210 
211  dealii::AnyData out_data;
212  out_data.merge(solution_data);
213  if (error != 0)
214  for (unsigned int i = 0; i < errors.n_blocks(); ++i)
215  {
216  std::string err_name{ "Error(" };
217  err_name += std::to_string(i);
218  err_name += ")";
219  out_data.add(&errors.block(i), err_name);
220  }
221  app.output_results(s, &out_data);
222  std::cout << std::endl;
223  convergence_table.write_text(std::cout);
224  }
225 }
226 
232 template <int dim>
233 void
234 global_refinement_eigenvalue_loop(unsigned int n_steps, unsigned int n_values,
236  dealii::Algorithms::OperatorBase& solve)
237 {
238  std::vector<std::complex<double>> eigenvalues(n_values);
239  bool symmetric = false;
240  if (app.param != 0)
241  {
242  app.param->enter_subsection("Arpack");
243  symmetric = app.param->get_bool("Symmetric");
244  app.param->leave_subsection();
245  }
246 
247  unsigned int n_vectors = n_values;
248  if (!symmetric)
249  n_vectors = 2 * n_values;
250  std::vector<dealii::Vector<double>> eigenvectors(n_vectors);
251 
252  for (unsigned int s = 0; s < n_steps; ++s)
253  {
254  dealii::deallog << "Step " << s << std::endl;
255  app.refine_mesh(true);
256  solve.notify(dealii::Algorithms::Events::remesh);
257  app.setup_system();
258  for (unsigned int i = 0; i < eigenvectors.size(); ++i)
259  app.setup_vector(eigenvectors[i]);
260 
261  dealii::AnyData solution_data;
262  solution_data.add(&eigenvalues, "eigenvalues");
263  solution_data.add(&eigenvectors, "eigenvectors");
264 
265  dealii::AnyData data;
266  solve(solution_data, data);
267 
268  dealii::AnyData out_data;
269  for (unsigned int i = 0; i < n_values; ++i)
270  {
271  std::ostringstream nstream;
272  nstream << "ev" << std::setw(3) << std::setfill('0') << i;
273  if (symmetric)
274  {
275  out_data.add(&eigenvectors[i], nstream.str());
276  dealii::deallog << "Eigenvalue " << i << '\t' << std::setprecision(15)
277  << eigenvalues[i].real() << std::endl;
278  }
279  else
280  {
281  out_data.add(&eigenvectors[i], nstream.str() + std::string("re"));
282  out_data.add(&eigenvectors[n_values + i], nstream.str() + std::string("im"));
283  dealii::deallog << "Eigenvalue " << i << '\t' << std::setprecision(15) << eigenvalues[i]
284  << std::endl;
285  }
286  }
287 
288  app.output_results(s, &out_data);
289  }
290 }
291 
298 template <int dim>
299 void
301  unsigned int n_steps, AmandusApplicationSparse<dim>& app, dealii::Triangulation<dim>& tria,
302  dealii::Algorithms::OperatorBase& solver, dealii::Algorithms::OperatorBase& residual,
303  const AmandusIntegrator<dim>* error = 0, AmandusIntegrator<dim>* estimator = 0,
304  const dealii::Function<dim>* initial_vector = 0, const bool boundary_projection = false)
305 {
306  dealii::Vector<double> rhs;
307  dealii::Vector<double> sol;
308  dealii::BlockVector<double> errors;
309  if (error != 0)
310  errors.reinit(error->n_errors());
311  dealii::ConvergenceTable convergence_table;
312 
313  // initial setup
314  solver.notify(dealii::Algorithms::Events::initial);
315  app.setup_system();
316  app.setup_vector(sol);
317  dealii::AnyData solution_data;
318  solution_data.add(&sol, "solution");
319  dealii::AnyData residual_data;
320  residual_data.add(&rhs, "RHS");
321  dealii::AnyData data;
322  UniformRemesher<dealii::Vector<double>, dim> remesh(app, tria);
323 
324  for (unsigned int s = 0; s < n_steps; ++s)
325  {
326  dealii::deallog << "Step " << s << std::endl;
327  app.setup_vector(rhs);
328  if (initial_vector != 0)
329  {
330  if (boundary_projection)
331  {
332  app.update_vector_inhom_boundary(sol, *initial_vector, boundary_projection);
333  }
334  else
335  {
336  dealii::QGauss<dim> quadrature(app.dofs().get_fe().tensor_degree() + 2);
337  dealii::VectorTools::project(
338  app.dofs(), app.hanging_nodes(), quadrature, *initial_vector, sol);
339  /* dealii::VectorTools::interpolate(app.dofs(), *initial_vector, sol); */
340  }
341  }
342 
343  residual(residual_data, data);
344  solver(solution_data, residual_data);
345 
346  if (error != 0)
347  {
348  app.error(errors, solution_data, *error);
349  for (unsigned int i = 0; i < errors.n_blocks(); ++i)
350  {
351  dealii::deallog << "Error(" << i << "): " << errors.block(i).l2_norm() << std::endl;
352  }
353  for (unsigned int i = 0; i < errors.n_blocks(); ++i)
354  {
355  std::string err_name{ "Error(" };
356  err_name += std::to_string(i);
357  err_name += ")";
358  convergence_table.add_value(err_name, errors.block(i).l2_norm());
359  convergence_table.evaluate_convergence_rates(err_name,
360  dealii::ConvergenceTable::reduction_rate_log2);
361  convergence_table.set_scientific(err_name, 1);
362  }
363  }
364 
365  if (estimator != 0)
366  {
367  dealii::deallog << "Error::Estimate: " << app.estimate(solution_data, *estimator)
368  << std::endl;
369  }
370  dealii::AnyData out_data;
371  out_data.merge(solution_data);
372  if (error != 0)
373  for (unsigned int i = 0; i < errors.n_blocks(); ++i)
374  {
375  std::string err_name{ "Error(" };
376  err_name += std::to_string(i);
377  err_name += ")";
378  out_data.add(&errors.block(i), err_name);
379  }
380  app.output_results(s, &out_data);
381  std::cout << std::endl;
382  convergence_table.write_text(std::cout);
383 
384  if (s < n_steps - 1)
385  {
386  remesh(solution_data, data);
387  solver.notify(dealii::Algorithms::Events::remesh);
388  }
389  }
390 }
391 
397 template <int dim>
398 void
400  unsigned int n_steps, AmandusApplicationSparse<dim>& app, dealii::Triangulation<dim>& tria,
401  dealii::Algorithms::OperatorBase& solve, const AmandusIntegrator<dim>* error = 0,
402  AmandusIntegrator<dim>* estimator = 0, const dealii::Function<dim>* initial_vector = 0,
403  const dealii::Function<dim>* inhom_boundary = 0, const bool boundary_projection = false)
404 {
405  dealii::Vector<double> sol;
406  dealii::BlockVector<double> errors;
407  if (error != 0)
408  errors.reinit(error->n_errors());
409  dealii::ConvergenceTable convergence_table;
410 
411  // initial setup
412  solve.notify(dealii::Algorithms::Events::initial);
413  app.setup_system();
414  app.setup_vector(sol);
415  dealii::AnyData solution_data;
416  solution_data.add(&sol, "solution");
417  dealii::AnyData data;
418  UniformRemesher<dealii::Vector<double>, dim> remesh(app, tria);
419 
420  for (unsigned int s = 0; s < n_steps; ++s)
421  {
422  dealii::deallog << "Step " << s << std::endl;
423 
424  if (initial_vector != 0)
425  {
426  dealii::QGauss<dim> quadrature(app.dofs().get_fe().tensor_degree() + 2);
427  dealii::VectorTools::project(
428  app.dofs(), app.hanging_nodes(), quadrature, *initial_vector, sol);
429  }
430 
431  if (inhom_boundary != 0)
432  app.update_vector_inhom_boundary(sol, *inhom_boundary, boundary_projection);
433 
434  solve(solution_data, data);
435 
436  if (error != 0)
437  {
438  app.error(errors, solution_data, *error);
439  for (unsigned int i = 0; i < errors.n_blocks(); ++i)
440  {
441  dealii::deallog << "Error(" << i << "): " << errors.block(i).l2_norm() << std::endl;
442  }
443  for (unsigned int i = 0; i < errors.n_blocks(); ++i)
444  {
445  std::string err_name{ "Error(" };
446  err_name += std::to_string(i);
447  err_name += ")";
448  convergence_table.add_value(err_name, errors.block(i).l2_norm());
449  convergence_table.evaluate_convergence_rates(err_name,
450  dealii::ConvergenceTable::reduction_rate_log2);
451  convergence_table.set_scientific(err_name, 1);
452  }
453  }
454 
455  if (estimator != 0)
456  {
457  dealii::deallog << "Error::Estimate: " << app.estimate(solution_data, *estimator)
458  << std::endl;
459  }
460 
461  dealii::AnyData out_data;
462  out_data.merge(solution_data);
463  if (error != 0)
464  for (unsigned int i = 0; i < errors.n_blocks(); ++i)
465  {
466  std::string err_name{ "Error(" };
467  err_name += std::to_string(i);
468  err_name += ")";
469  out_data.add(&errors.block(i), err_name);
470  }
471  app.output_results(s, &out_data);
472  std::cout << std::endl;
473  convergence_table.write_text(std::cout);
474 
475  if (s < n_steps - 1)
476  {
477  remesh(solution_data, data);
478  solve.notify(dealii::Algorithms::Events::remesh);
479  }
480  }
481 }
482 
489 template <int dim>
490 void
492  dealii::Triangulation<dim>& tria,
493  dealii::Algorithms::OperatorBase& solver,
494  dealii::Algorithms::OperatorBase& right_hand_side,
496  const AmandusIntegrator<dim>* error = 0)
497 {
498  dealii::Vector<double> rhs;
499  dealii::Vector<double> sol;
500  dealii::BlockVector<double> errors;
501  if (error != 0)
502  errors.reinit(error->n_errors());
503  dealii::ConvergenceTable convergence_table;
504  unsigned int step = 0;
505 
506  // initial setup
507  solver.notify(dealii::Algorithms::Events::initial);
508  app.setup_system();
509  app.setup_vector(sol);
510  dealii::AnyData solution_data;
511  solution_data.add(&sol, "solution");
512  dealii::AnyData data;
513  EstimateRemesher<dealii::Vector<double>, dim> remesh(app, tria, mark, estimator);
514 
515  while (true)
516  {
517  dealii::deallog << "Step " << step++ << std::endl;
518 
519  // solve
520  app.setup_vector(rhs);
521  dealii::AnyData rhs_data;
522  rhs_data.add(&rhs, "RHS");
523  right_hand_side(rhs_data, data);
524  app.constraints().set_zero(sol);
525  solver(solution_data, rhs_data);
526 
527  // error
528  dealii::deallog << "Dofs: " << app.dofs().n_dofs() << std::endl;
529  convergence_table.add_value("cells", app.dofs().get_triangulation().n_active_cells());
530  convergence_table.add_value("dofs", app.dofs().n_dofs());
531  if (error != 0)
532  {
533  app.error(errors, solution_data, *error);
534  for (unsigned int i = 0; i < errors.n_blocks(); ++i)
535  {
536  dealii::deallog << "Error(" << i << "): " << errors.block(i).l2_norm() << std::endl;
537  }
538  for (unsigned int i = 0; i < errors.n_blocks(); ++i)
539  {
540  std::string err_name{ "Error(" };
541  err_name += std::to_string(i);
542  err_name += ")";
543  convergence_table.add_value(err_name, errors.block(i).l2_norm());
544  convergence_table.evaluate_convergence_rates(
545  err_name, "cells", dealii::ConvergenceTable::reduction_rate_log2, dim);
546  convergence_table.set_scientific(err_name, 1);
547  }
548  }
549 
550  // estimator
551  const double est = app.estimate(solution_data, estimator);
552  dealii::deallog << "Estimate: " << est << std::endl;
553  convergence_table.add_value("estimate", est);
554  convergence_table.evaluate_convergence_rates(
555  "estimate", "cells", dealii::ConvergenceTable::reduction_rate_log2, dim);
556  convergence_table.set_scientific("estimate", 1);
557 
558  // output
559  dealii::AnyData out_data;
560  out_data.merge(solution_data);
561  if (error != 0)
562  for (unsigned int i = 0; i < errors.n_blocks(); ++i)
563  {
564  std::string err_name{ "Error(" };
565  err_name += std::to_string(i);
566  err_name += ")";
567  out_data.add(&errors.block(i), err_name);
568  }
569  dealii::Vector<double> indicators;
570  indicators = app.indicators();
571  out_data.add(&indicators, "estimator");
572  app.output_results(step, &out_data);
573  std::cout << std::endl;
574  convergence_table.write_text(std::cout);
575 
576  // stop
577  if (app.dofs().n_dofs() >= max_dofs)
578  break;
579 
580  // mark & refine using remesher
581  remesh(solution_data, data);
582  solver.notify(dealii::Algorithms::Events::remesh);
583  }
584 }
585 
592 template <int dim>
593 void
595  unsigned int max_dofs, AmandusApplicationSparse<dim>& app, dealii::Triangulation<dim>& tria,
596  dealii::Algorithms::OperatorBase& solver, AmandusIntegrator<dim>& estimator,
597  AmandusRefineStrategy<dim>& mark, const AmandusIntegrator<dim>* error = 0,
598  const dealii::Function<dim>* inhom_boundary = 0, const bool boundary_projection = false)
599 {
600  dealii::Vector<double> sol;
601  dealii::BlockVector<double> errors;
602  if (error != 0)
603  errors.reinit(error->n_errors());
604  dealii::ConvergenceTable convergence_table;
605  unsigned int step = 0;
606 
607  // initial setup
608  solver.notify(dealii::Algorithms::Events::initial);
609  app.setup_system();
610  app.setup_vector(sol);
611  dealii::AnyData solution_data;
612  solution_data.add(&sol, "solution");
613  dealii::AnyData data;
614  EstimateRemesher<dealii::Vector<double>, dim> remesh(app, tria, mark, estimator);
615 
616  while (true)
617  {
618  dealii::deallog << "Step " << step++ << std::endl;
619 
620  // solve
621  if (inhom_boundary != 0)
622  app.update_vector_inhom_boundary(sol, *inhom_boundary, boundary_projection);
623  solver(solution_data, data);
624 
625  // error
626  dealii::deallog << "Dofs: " << app.dofs().n_dofs() << std::endl;
627  convergence_table.add_value("cells", app.dofs().get_triangulation().n_active_cells());
628  convergence_table.add_value("dofs", app.dofs().n_dofs());
629  if (error != 0)
630  {
631  app.error(errors, solution_data, *error);
632  for (unsigned int i = 0; i < errors.n_blocks(); ++i)
633  {
634  dealii::deallog << "Error(" << i << "): " << errors.block(i).l2_norm() << std::endl;
635  }
636  for (unsigned int i = 0; i < errors.n_blocks(); ++i)
637  {
638  std::string err_name{ "Error(" };
639  err_name += std::to_string(i);
640  err_name += ")";
641  convergence_table.add_value(err_name, errors.block(i).l2_norm());
642  convergence_table.evaluate_convergence_rates(
643  err_name, "cells", dealii::ConvergenceTable::reduction_rate_log2, dim);
644  convergence_table.set_scientific(err_name, 1);
645  }
646  }
647 
648  // estimator
649  const double est = app.estimate(solution_data, estimator);
650  dealii::deallog << "Estimate: " << est << std::endl;
651  convergence_table.add_value("estimate", est);
652  convergence_table.evaluate_convergence_rates(
653  "estimate", "cells", dealii::ConvergenceTable::reduction_rate_log2, dim);
654  convergence_table.set_scientific("estimate", 1);
655 
656  // output
657  dealii::AnyData out_data;
658  out_data.merge(solution_data);
659  if (error != 0)
660  for (unsigned int i = 0; i < errors.n_blocks(); ++i)
661  {
662  std::string err_name{ "Error(" };
663  err_name += std::to_string(i);
664  err_name += ")";
665  out_data.add(&errors.block(i), err_name);
666  }
667  dealii::Vector<double> indicators;
668  indicators = app.indicators();
669  out_data.add(&indicators, "estimator");
670  app.output_results(step, &out_data);
671  std::cout << std::endl;
672  convergence_table.write_text(std::cout);
673 
674  // stop
675  if (app.dofs().n_dofs() >= max_dofs)
676  break;
677 
678  // mark & refine using remesher
679  remesh(solution_data, data);
680  solver.notify(dealii::Algorithms::Events::remesh);
681  }
682 }
683 
692 template <int dim>
693 void
694 adaptive_refinement_eigenvalue_loop(unsigned int max_dofs, unsigned int n_eigenvalue,
696  dealii::Algorithms::OperatorBase& solver,
697  AmandusIntegrator<dim>& estimator,
699  const double exact_eigenvalue = std::nan(NULL),
700  const unsigned int multiplicity = 1, const unsigned int k = 0)
701 {
702  const unsigned int n_vectors = n_eigenvalue + multiplicity - 1 + k;
703  std::vector<std::complex<double>> eigenvalues(n_vectors);
704  std::vector<dealii::Vector<double>> eigenvectors(n_vectors);
705  dealii::ConvergenceTable convergence_table;
706  std::vector<std::pair<unsigned int, double>> sort_eigenvalues(n_vectors);
707  solver.notify(dealii::Algorithms::Events::initial);
708  dealii::AnyData solution_data;
709  solution_data.add(&eigenvalues, "eigenvalues");
710  solution_data.add(&eigenvectors, "eigenvectors");
711  unsigned int step = 0;
712 
713  for (unsigned int i = 0; i < multiplicity; ++i)
714  estimator.input_vector_names.push_back(std::string("eigenvector") + std::to_string(i));
715 
716  while (true)
717  {
718  dealii::deallog << "Step " << step++ << std::endl;
719 
720  // setup
721  app.setup_system();
722  for (unsigned int i = 0; i < eigenvectors.size(); ++i)
723  app.setup_vector(eigenvectors[i]);
724 
725  // solve
726  dealii::AnyData data;
727  solver(solution_data, data);
728 
729  // sort eigenvalues
730  for (unsigned int i = 0; i < n_vectors; ++i)
731  {
732  sort_eigenvalues[i].first = i;
733  sort_eigenvalues[i].second = eigenvalues[i].real();
734  }
735  sort(sort_eigenvalues.begin(),
736  sort_eigenvalues.end(),
737  [](const std::pair<unsigned int, double>& left,
738  const std::pair<unsigned int, double>& right) { return left.second < right.second; });
739 
740  // eigenvalue errors
741  dealii::deallog << "Dofs: " << app.dofs().n_dofs() << std::endl;
742  convergence_table.add_value("cells", app.dofs().get_triangulation().n_active_cells());
743  convergence_table.add_value("dofs", app.dofs().n_dofs());
744  if (std::isfinite(exact_eigenvalue))
745  {
746  for (unsigned int i = 0; i < multiplicity; ++i)
747  {
748  const double error =
749  std::abs(exact_eigenvalue - sort_eigenvalues[n_eigenvalue + i - 1].second);
750  dealii::deallog << "ev-error-" << i << ": " << error << std::endl;
751  convergence_table.add_value(std::string("ev-error-") + std::to_string(i), error);
752  convergence_table.evaluate_convergence_rates(std::string("ev-error-") + std::to_string(i),
753  "cells",
754  dealii::ConvergenceTable::reduction_rate_log2,
755  1);
756  convergence_table.set_scientific(std::string("ev-error-") + std::to_string(i), 1);
757  }
758  }
759 
760  // estimator for n,n+1,...,n+m (real) eigenvalues
761  dealii::AnyData estimator_data;
762  for (unsigned int i = 0; i < multiplicity; ++i)
763  {
764  const unsigned int eigenvalue_idx = sort_eigenvalues[n_eigenvalue + i - 1].first;
765  estimator_data.add(&eigenvectors[eigenvalue_idx],
766  std::string("eigenvector") + std::to_string(i));
767  estimator_data.add(&sort_eigenvalues[n_eigenvalue + i - 1].second,
768  std::string("ev") + std::to_string(i));
769  }
770  const double est = std::pow(app.estimate(estimator_data, estimator), 2);
771  dealii::deallog << "Estimate: " << est << std::endl;
772  convergence_table.add_value("estimate", est);
773  convergence_table.evaluate_convergence_rates(
774  "estimate", "cells", dealii::ConvergenceTable::reduction_rate_log2, 1);
775  convergence_table.set_scientific("estimate", 1);
776 
777  // output
778  dealii::AnyData out_data;
779  for (unsigned int i = 0; i < multiplicity; ++i)
780  {
781  const unsigned int eigenvalue_idx = sort_eigenvalues[n_eigenvalue + i - 1].first;
782  out_data.add(&eigenvectors[eigenvalue_idx], std::string("ev") + std::to_string(i + 1));
783  }
784  dealii::Vector<double> indicators;
785  indicators = app.indicators();
786  out_data.add(&indicators, "estimator");
787  for (unsigned int i = 0; i < n_vectors; ++i)
788  dealii::deallog << "Eigenvalue " << '\t' << std::setprecision(15)
789  << sort_eigenvalues[i].second << std::endl;
790  app.output_results(step, &out_data);
791  std::cout << std::endl;
792  convergence_table.write_text(std::cout);
793 
794  // stop
795  if (app.dofs().n_dofs() >= max_dofs)
796  break;
797  // mark
798  mark(app.indicators());
799  // refine
800  app.refine_mesh(false);
801  solver.notify(dealii::Algorithms::Events::remesh);
802  }
803 }
804 
805 #endif
const dealii::ConstraintMatrix & hanging_nodes() const
The object describing the constraints for hanging nodes, not for the boundary.
Definition: amandus.h:592
dealii::SmartPointer< dealii::ParameterHandler > param
Definition: amandus.h:316
double estimate(const dealii::AnyData &in, AmandusIntegrator< dim > &integrator)
Definition: amandus_sparse.cc:521
const dealii::DoFHandler< dim > & dofs() const
The object describing the finite element space.
Definition: amandus.h:578
void global_refinement_linear_loop(unsigned int n_steps, AmandusApplicationSparse< dim > &app, dealii::Algorithms::OperatorBase &solver, dealii::Algorithms::OperatorBase &residual, const AmandusIntegrator< dim > *error=0, AmandusIntegrator< dim > *estimator=0, const dealii::Function< dim > *initial_vector=0, const bool boundary_projection=false)
Definition: apps.h:33
Remesher interpolating all vectors for uniform refinement. Refines the mesh and interpolates all the ...
Definition: adaptivity.h:172
void global_refinement_nested_linear_loop(unsigned int n_steps, AmandusApplicationSparse< dim > &app, dealii::Triangulation< dim > &tria, dealii::Algorithms::OperatorBase &solver, dealii::Algorithms::OperatorBase &residual, const AmandusIntegrator< dim > *error=0, AmandusIntegrator< dim > *estimator=0, const dealii::Function< dim > *initial_vector=0, const bool boundary_projection=false)
Definition: apps.h:300
void adaptive_refinement_linear_loop(unsigned int max_dofs, AmandusApplicationSparse< dim > &app, dealii::Triangulation< dim > &tria, dealii::Algorithms::OperatorBase &solver, dealii::Algorithms::OperatorBase &right_hand_side, AmandusIntegrator< dim > &estimator, AmandusRefineStrategy< dim > &mark, const AmandusIntegrator< dim > *error=0)
Definition: apps.h:491
virtual void setup_vector(dealii::Vector< double > &v) const
Definition: amandus_sparse.cc:148
void refine_mesh(const bool global=false)
Definition: amandus_sparse.cc:598
void global_refinement_nested_nonlinear_loop(unsigned int n_steps, AmandusApplicationSparse< dim > &app, dealii::Triangulation< dim > &tria, dealii::Algorithms::OperatorBase &solve, const AmandusIntegrator< dim > *error=0, AmandusIntegrator< dim > *estimator=0, const dealii::Function< dim > *initial_vector=0, const dealii::Function< dim > *inhom_boundary=0, const bool boundary_projection=false)
Definition: apps.h:399
void output_results(unsigned int refinement_cycle, const dealii::AnyData *data=0) const
Definition: amandus_sparse.cc:697
const dealii::ConstraintMatrix & constraints() const
The object describing the constraints.
Definition: amandus.h:585
void adaptive_refinement_nonlinear_loop(unsigned int max_dofs, AmandusApplicationSparse< dim > &app, dealii::Triangulation< dim > &tria, dealii::Algorithms::OperatorBase &solver, AmandusIntegrator< dim > &estimator, AmandusRefineStrategy< dim > &mark, const AmandusIntegrator< dim > *error=0, const dealii::Function< dim > *inhom_boundary=0, const bool boundary_projection=false)
Definition: apps.h:594
Definition: amandus.h:115
virtual void setup_system()
Definition: amandus_sparse.cc:182
void global_refinement_eigenvalue_loop(unsigned int n_steps, unsigned int n_values, AmandusApplicationSparse< dim > &app, dealii::Algorithms::OperatorBase &solve)
Definition: apps.h:234
abstract base class AmandusRefineStrategy
Definition: refine_strategy.h:25
void adaptive_refinement_eigenvalue_loop(unsigned int max_dofs, unsigned int n_eigenvalue, AmandusApplicationSparse< dim > &app, dealii::Algorithms::OperatorBase &solver, AmandusIntegrator< dim > &estimator, AmandusRefineStrategy< dim > &mark, const double exact_eigenvalue=std::nan(NULL), const unsigned int multiplicity=1, const unsigned int k=0)
Definition: apps.h:694
void global_refinement_nonlinear_loop(unsigned int n_steps, AmandusApplicationSparse< dim > &app, dealii::Algorithms::OperatorBase &solve, const AmandusIntegrator< dim > *error=0, AmandusIntegrator< dim > *estimator=0, const dealii::Function< dim > *initial_vector=0, const dealii::Function< dim > *inhom_boundary=0, const bool boundary_projection=false)
Definition: apps.h:149
void error(dealii::BlockVector< double > &out, const dealii::AnyData &in, const AmandusIntegrator< dim > &integrator)
const dealii::Vector< double > & indicators() const
The error indicators.
Definition: amandus.h:599
Definition: integrator.h:29
virtual void update_vector_inhom_boundary(dealii::Vector< double > &v, const dealii::Function< dim > &inhom_boundary, bool projection=false) const
Definition: amandus_sparse.cc:155
Remesher interpolating all vectors and using an estimator integrator to calculate criterion...
Definition: adaptivity.h:244