libMesh
uniform_refinement_estimator.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 // C++ includes
19 #include <algorithm> // for std::fill
20 #include <sstream>
21 #include <cstdlib> // *must* precede <cmath> for proper std:abs() on PGI, Sun Studio CC
22 #include <cmath> // for sqrt
23 
24 // Local Includes
25 #include "libmesh/dof_map.h"
26 #include "libmesh/elem.h"
27 #include "libmesh/equation_systems.h"
28 #include "libmesh/error_vector.h"
29 #include "libmesh/fe.h"
30 #include "libmesh/libmesh_common.h"
31 #include "libmesh/libmesh_logging.h"
32 #include "libmesh/mesh_base.h"
33 #include "libmesh/mesh_refinement.h"
34 #include "libmesh/numeric_vector.h"
35 #include "libmesh/quadrature.h"
36 #include "libmesh/system.h"
37 #include "libmesh/uniform_refinement_estimator.h"
38 #include "libmesh/partitioner.h"
39 #include "libmesh/tensor_tools.h"
40 #include "libmesh/enum_error_estimator_type.h"
41 #include "libmesh/enum_norm_type.h"
42 #include "libmesh/int_range.h"
43 #include "libmesh/auto_ptr.h" // libmesh_make_unique
44 
45 #ifdef LIBMESH_ENABLE_AMR
46 
47 namespace libMesh
48 {
49 
50 //-----------------------------------------------------------------
51 // ErrorEstimator implementations
52 
55  number_h_refinements(1),
56  number_p_refinements(0)
57 {
58  error_norm = H1;
59 }
60 
61 
62 
64 {
65  return UNIFORM_REFINEMENT;
66 }
67 
68 
70  ErrorVector & error_per_cell,
71  const NumericVector<Number> * solution_vector,
72  bool estimate_parent_error)
73 {
74  LOG_SCOPE("estimate_error()", "UniformRefinementEstimator");
75  std::map<const System *, const NumericVector<Number> *> solution_vectors;
76  solution_vectors[&_system] = solution_vector;
77  this->_estimate_error (nullptr,
78  &_system,
79  &error_per_cell,
80  nullptr,
81  nullptr,
82  &solution_vectors,
83  estimate_parent_error);
84 }
85 
87  ErrorVector & error_per_cell,
88  const std::map<const System *, SystemNorm> & error_norms,
89  const std::map<const System *, const NumericVector<Number> *> * solution_vectors,
90  bool estimate_parent_error)
91 {
92  LOG_SCOPE("estimate_errors()", "UniformRefinementEstimator");
93  this->_estimate_error (&_es,
94  nullptr,
95  &error_per_cell,
96  nullptr,
97  &error_norms,
98  solution_vectors,
99  estimate_parent_error);
100 }
101 
103  ErrorMap & errors_per_cell,
104  const std::map<const System *, const NumericVector<Number> *> * solution_vectors,
105  bool estimate_parent_error)
106 {
107  LOG_SCOPE("estimate_errors()", "UniformRefinementEstimator");
108  this->_estimate_error (&_es,
109  nullptr,
110  nullptr,
111  &errors_per_cell,
112  nullptr,
113  solution_vectors,
114  estimate_parent_error);
115 }
116 
118  const System * _system,
119  ErrorVector * error_per_cell,
120  ErrorMap * errors_per_cell,
121  const std::map<const System *, SystemNorm> * _error_norms,
122  const std::map<const System *, const NumericVector<Number> *> * solution_vectors,
123  bool)
124 {
125  // Get a vector of the Systems we're going to work on,
126  // and set up a error_norms map if necessary
127  std::vector<System *> system_list;
128  auto error_norms = libmesh_make_unique<std::map<const System *, SystemNorm>>();
129 
130  if (_es)
131  {
132  libmesh_assert(!_system);
133  libmesh_assert(_es->n_systems());
134  _system = &(_es->get_system(0));
135  libmesh_assert_equal_to (&(_system->get_equation_systems()), _es);
136 
137  libmesh_assert(_es->n_systems());
138  for (auto i : IntRange<unsigned int>(0, _es->n_systems()))
139  // We have to break the rules here, because we can't refine a const System
140  system_list.push_back(const_cast<System *>(&(_es->get_system(i))));
141 
142  // If we're computing one vector, we need to know how to scale
143  // each variable's contributions to it.
144  if (_error_norms)
145  {
146  libmesh_assert(!errors_per_cell);
147  }
148  else
149  // If we're computing many vectors, we just need to know which
150  // variables to skip
151  {
152  libmesh_assert (errors_per_cell);
153 
154  _error_norms = error_norms.get();
155 
156  for (auto i : IntRange<unsigned int>(0, _es->n_systems()))
157  {
158  const System & sys = _es->get_system(i);
159  unsigned int n_vars = sys.n_vars();
160 
161  std::vector<Real> weights(n_vars, 0.0);
162  for (unsigned int v = 0; v != n_vars; ++v)
163  {
164  if (errors_per_cell->find(std::make_pair(&sys, v)) ==
165  errors_per_cell->end())
166  continue;
167 
168  weights[v] = 1.0;
169  }
170  (*error_norms)[&sys] =
171  SystemNorm(std::vector<FEMNormType>(n_vars, error_norm.type(0)),
172  weights);
173  }
174  }
175  }
176  else
177  {
178  libmesh_assert(_system);
179  // We have to break the rules here, because we can't refine a const System
180  system_list.push_back(const_cast<System *>(_system));
181 
182  libmesh_assert(!_error_norms);
183  (*error_norms)[_system] = error_norm;
184  _error_norms = error_norms.get();
185  }
186 
187  // An EquationSystems reference will be convenient.
188  // We have to break the rules here, because we can't refine a const System
189  EquationSystems & es =
190  const_cast<EquationSystems &>(_system->get_equation_systems());
191 
192  // The current mesh
193  MeshBase & mesh = es.get_mesh();
194 
195  // The dimensionality of the mesh
196  const unsigned int dim = mesh.mesh_dimension();
197 
198  // Resize the error_per_cell vectors to be
199  // the number of elements, initialize them to 0.
200  if (error_per_cell)
201  {
202  error_per_cell->clear();
203  error_per_cell->resize (mesh.max_elem_id(), 0.);
204  }
205  else
206  {
207  libmesh_assert(errors_per_cell);
208  for (const auto & pr : *errors_per_cell)
209  {
210  ErrorVector * e = pr.second;
211  e->clear();
212  e->resize(mesh.max_elem_id(), 0.);
213  }
214  }
215 
216  // We'll want to back up all coarse grid vectors
217  std::vector<std::map<std::string, std::unique_ptr<NumericVector<Number>>>> coarse_vectors(system_list.size());
218  std::vector<std::unique_ptr<NumericVector<Number>>> coarse_solutions(system_list.size());
219  std::vector<std::unique_ptr<NumericVector<Number>>> coarse_local_solutions(system_list.size());
220  // And make copies of projected solutions
221  std::vector<std::unique_ptr<NumericVector<Number>>> projected_solutions(system_list.size());
222 
223  // And we'll need to temporarily change solution projection settings
224  std::vector<bool> old_projection_settings(system_list.size());
225 
226  // And it'll be best to avoid any repartitioning
227  std::unique_ptr<Partitioner> old_partitioner(mesh.partitioner().release());
228 
229  // And we can't allow any renumbering
230  const bool old_renumbering_setting = mesh.allow_renumbering();
231  mesh.allow_renumbering(false);
232 
233  for (auto i : index_range(system_list))
234  {
235  System & system = *system_list[i];
236 
237  // Check for valid error_norms
238  libmesh_assert (_error_norms->find(&system) !=
239  _error_norms->end());
240 
241  // Back up the solution vector
242  coarse_solutions[i] = system.solution->clone();
243  coarse_local_solutions[i] = system.current_local_solution->clone();
244 
245  // Back up all other coarse grid vectors
246  for (System::vectors_iterator vec = system.vectors_begin(); vec !=
247  system.vectors_end(); ++vec)
248  {
249  // The (string) name of this vector
250  const std::string & var_name = vec->first;
251 
252  coarse_vectors[i][var_name] = vec->second->clone();
253  }
254 
255  // Use a non-standard solution vector if necessary
256  if (solution_vectors &&
257  solution_vectors->find(&system) != solution_vectors->end() &&
258  solution_vectors->find(&system)->second &&
259  solution_vectors->find(&system)->second != system.solution.get())
260  {
261  NumericVector<Number> * newsol =
262  const_cast<NumericVector<Number> *>
263  (solution_vectors->find(&system)->second);
264  newsol->swap(*system.solution);
265  system.update();
266  }
267 
268  // Make sure the solution is projected when we refine the mesh
269  old_projection_settings[i] = system.project_solution_on_reinit();
270  system.project_solution_on_reinit() = true;
271  }
272 
273  // Find the number of coarse mesh elements, to make it possible
274  // to find correct coarse elem ids later
275  const dof_id_type max_coarse_elem_id = mesh.max_elem_id();
276 #ifndef NDEBUG
277  // n_coarse_elem is only used in an assertion later so
278  // avoid declaring it unless asserts are active.
279  const dof_id_type n_coarse_elem = mesh.n_elem();
280 #endif
281 
282  // Uniformly refine the mesh
283  MeshRefinement mesh_refinement(mesh);
284 
286 
287  // FIXME: this may break if there is more than one System
288  // on this mesh but estimate_error was still called instead of
289  // estimate_errors
290  for (unsigned int i = 0; i != number_h_refinements; ++i)
291  {
292  mesh_refinement.uniformly_refine(1);
293  es.reinit();
294  }
295 
296  for (unsigned int i = 0; i != number_p_refinements; ++i)
297  {
298  mesh_refinement.uniformly_p_refine(1);
299  es.reinit();
300  }
301 
302  for (auto i : index_range(system_list))
303  {
304  System & system = *system_list[i];
305 
306  // Copy the projected coarse grid solutions, which will be
307  // overwritten by solve()
308  projected_solutions[i] = NumericVector<Number>::build(system.comm());
309  projected_solutions[i]->init(system.solution->size(), true, SERIAL);
310  system.solution->localize(*projected_solutions[i],
311  system.get_dof_map().get_send_list());
312  }
313 
314  // Are we doing a forward or an adjoint solve?
315  bool solve_adjoint = false;
316  if (solution_vectors)
317  {
318  System * sys = system_list[0];
319  libmesh_assert (solution_vectors->find(sys) !=
320  solution_vectors->end());
321  const NumericVector<Number> * vec = solution_vectors->find(sys)->second;
322  for (auto j : IntRange<unsigned int>(0, sys->n_qois()))
323  {
324  std::ostringstream adjoint_name;
325  adjoint_name << "adjoint_solution" << j;
326 
327  if (vec == sys->request_vector(adjoint_name.str()))
328  {
329  solve_adjoint = true;
330  break;
331  }
332  }
333  }
334 
335  // Get the uniformly refined solution.
336 
337  if (_es)
338  {
339  // Even if we had a decent preconditioner, valid matrix etc. before
340  // refinement, we don't any more.
341  for (auto i : IntRange<unsigned int>(0, _es->n_systems()))
342  es.get_system(i).disable_cache();
343 
344  // No specified vectors == forward solve
345  if (!solution_vectors)
346  es.solve();
347  else
348  {
349  libmesh_assert_equal_to (solution_vectors->size(), es.n_systems());
350  libmesh_assert (solution_vectors->find(system_list[0]) !=
351  solution_vectors->end());
352  libmesh_assert(solve_adjoint ||
353  (solution_vectors->find(system_list[0])->second ==
354  system_list[0]->solution.get()) ||
355  !solution_vectors->find(system_list[0])->second);
356 
357 #ifdef DEBUG
358  for (const auto & sys : system_list)
359  {
360  libmesh_assert (solution_vectors->find(sys) !=
361  solution_vectors->end());
362  const NumericVector<Number> * vec = solution_vectors->find(sys)->second;
363  if (solve_adjoint)
364  {
365  bool found_vec = false;
366  for (auto j : IntRange<unsigned int>(0, sys->n_qois()))
367  {
368  std::ostringstream adjoint_name;
369  adjoint_name << "adjoint_solution" << j;
370 
371  if (vec == sys->request_vector(adjoint_name.str()))
372  {
373  found_vec = true;
374  break;
375  }
376  }
377  libmesh_assert(found_vec);
378  }
379  else
380  libmesh_assert(vec == sys->solution.get() || !vec);
381  }
382 #endif
383 
384  if (solve_adjoint)
385  {
386  std::vector<unsigned int> adjs(system_list.size(),
388  // Set up proper initial guesses
389  for (auto i : index_range(system_list))
390  {
391  System * sys = system_list[i];
392  libmesh_assert (solution_vectors->find(sys) !=
393  solution_vectors->end());
394  const NumericVector<Number> * vec = solution_vectors->find(sys)->second;
395  for (auto j : IntRange<unsigned int>(0, sys->n_qois()))
396  {
397  std::ostringstream adjoint_name;
398  adjoint_name << "adjoint_solution" << j;
399 
400  if (vec == sys->request_vector(adjoint_name.str()))
401  {
402  adjs[i] = j;
403  break;
404  }
405  }
406  libmesh_assert_not_equal_to (adjs[i], libMesh::invalid_uint);
407  sys->get_adjoint_solution(adjs[i]) = *sys->solution;
408  }
409 
410  es.adjoint_solve();
411 
412  // Put the adjoint_solution into solution for
413  // comparisons
414  for (auto i : index_range(system_list))
415  {
416  system_list[i]->get_adjoint_solution(adjs[i]).swap(*system_list[i]->solution);
417  system_list[i]->update();
418  }
419  }
420  else
421  es.solve();
422  }
423  }
424  else
425  {
426  System * sys = system_list[0];
427 
428  // Even if we had a decent preconditioner, valid matrix etc. before
429  // refinement, we don't any more.
430  sys->disable_cache();
431 
432  // No specified vectors == forward solve
433  if (!solution_vectors)
434  sys->solve();
435  else
436  {
437  libmesh_assert (solution_vectors->find(sys) !=
438  solution_vectors->end());
439 
440  const NumericVector<Number> * vec = solution_vectors->find(sys)->second;
441 
442  libmesh_assert(solve_adjoint ||
443  (solution_vectors->find(sys)->second ==
444  sys->solution.get()) ||
445  !solution_vectors->find(sys)->second);
446 
447  if (solve_adjoint)
448  {
449  unsigned int adj = libMesh::invalid_uint;
450  for (unsigned int j=0, n_qois = sys->n_qois();
451  j != n_qois; ++j)
452  {
453  std::ostringstream adjoint_name;
454  adjoint_name << "adjoint_solution" << j;
455 
456  if (vec == sys->request_vector(adjoint_name.str()))
457  {
458  adj = j;
459  break;
460  }
461  }
462  libmesh_assert_not_equal_to (adj, libMesh::invalid_uint);
463 
464  // Set up proper initial guess
465  sys->get_adjoint_solution(adj) = *sys->solution;
466  sys->adjoint_solve();
467  // Put the adjoint_solution into solution for
468  // comparisons
469  sys->get_adjoint_solution(adj).swap(*sys->solution);
470  sys->update();
471  }
472  else
473  sys->solve();
474  }
475  }
476 
477  // Get the error in the uniformly refined solution(s).
478  for (auto sysnum : index_range(system_list))
479  {
480  System & system = *system_list[sysnum];
481 
482  unsigned int n_vars = system.n_vars();
483 
484  DofMap & dof_map = system.get_dof_map();
485 
486  const SystemNorm & system_i_norm =
487  _error_norms->find(&system)->second;
488 
489  NumericVector<Number> * projected_solution = projected_solutions[sysnum].get();
490 
491  // Loop over all the variables in the system
492  for (unsigned int var=0; var<n_vars; var++)
493  {
494  // Get the error vector to fill for this system and variable
495  ErrorVector * err_vec = error_per_cell;
496  if (!err_vec)
497  {
498  libmesh_assert(errors_per_cell);
499  err_vec =
500  (*errors_per_cell)[std::make_pair(&system,var)];
501  }
502 
503  // The type of finite element to use for this variable
504  const FEType & fe_type = dof_map.variable_type (var);
505 
506  // Finite element object for each fine element
507  std::unique_ptr<FEBase> fe (FEBase::build (dim, fe_type));
508 
509  // Build and attach an appropriate quadrature rule
510  std::unique_ptr<QBase> qrule = fe_type.default_quadrature_rule(dim);
511  fe->attach_quadrature_rule (qrule.get());
512 
513  const std::vector<Real> & JxW = fe->get_JxW();
514  const std::vector<std::vector<Real>> & phi = fe->get_phi();
515  const std::vector<std::vector<RealGradient>> & dphi =
516  fe->get_dphi();
517 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
518  const std::vector<std::vector<RealTensor>> & d2phi =
519  fe->get_d2phi();
520 #endif
521 
522  // The global DOF indices for the fine element
523  std::vector<dof_id_type> dof_indices;
524 
525  // Iterate over all the active elements in the fine mesh
526  // that live on this processor.
527  for (const auto & elem : mesh.active_local_element_ptr_range())
528  {
529  // Find the element id for the corresponding coarse grid element
530  const Elem * coarse = elem;
531  dof_id_type e_id = coarse->id();
532  while (e_id >= max_coarse_elem_id)
533  {
534  libmesh_assert (coarse->parent());
535  coarse = coarse->parent();
536  e_id = coarse->id();
537  }
538 
539  Real L2normsq = 0., H1seminormsq = 0.;
540 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
541  Real H2seminormsq = 0.;
542 #endif
543 
544  // reinitialize the element-specific data
545  // for the current element
546  fe->reinit (elem);
547 
548  // Get the local to global degree of freedom maps
549  dof_map.dof_indices (elem, dof_indices, var);
550 
551  // The number of quadrature points
552  const unsigned int n_qp = qrule->n_points();
553 
554  // The number of shape functions
555  const unsigned int n_sf =
556  cast_int<unsigned int>(dof_indices.size());
557 
558  //
559  // Begin the loop over the Quadrature points.
560  //
561  for (unsigned int qp=0; qp<n_qp; qp++)
562  {
563  Number u_fine = 0., u_coarse = 0.;
564 
565  Gradient grad_u_fine, grad_u_coarse;
566 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
567  Tensor grad2_u_fine, grad2_u_coarse;
568 #endif
569 
570  // Compute solution values at the current
571  // quadrature point. This requires a sum
572  // over all the shape functions evaluated
573  // at the quadrature point.
574  for (unsigned int i=0; i<n_sf; i++)
575  {
576  u_fine += phi[i][qp]*system.current_solution (dof_indices[i]);
577  u_coarse += phi[i][qp]*(*projected_solution) (dof_indices[i]);
578  grad_u_fine += dphi[i][qp]*system.current_solution (dof_indices[i]);
579  grad_u_coarse += dphi[i][qp]*(*projected_solution) (dof_indices[i]);
580 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
581  grad2_u_fine += d2phi[i][qp]*system.current_solution (dof_indices[i]);
582  grad2_u_coarse += d2phi[i][qp]*(*projected_solution) (dof_indices[i]);
583 #endif
584  }
585 
586  // Compute the value of the error at this quadrature point
587  const Number val_error = u_fine - u_coarse;
588 
589  // Add the squares of the error to each contribution
590  if (system_i_norm.type(var) == L2 ||
591  system_i_norm.type(var) == H1 ||
592  system_i_norm.type(var) == H2)
593  {
594  L2normsq += JxW[qp] * system_i_norm.weight_sq(var) *
595  TensorTools::norm_sq(val_error);
596  libmesh_assert_greater_equal (L2normsq, 0.);
597  }
598 
599 
600  // Compute the value of the error in the gradient at this
601  // quadrature point
602  if (system_i_norm.type(var) == H1 ||
603  system_i_norm.type(var) == H2 ||
604  system_i_norm.type(var) == H1_SEMINORM)
605  {
606  Gradient grad_error = grad_u_fine - grad_u_coarse;
607 
608  H1seminormsq += JxW[qp] * system_i_norm.weight_sq(var) *
609  grad_error.norm_sq();
610  libmesh_assert_greater_equal (H1seminormsq, 0.);
611  }
612 
613  // Compute the value of the error in the hessian at this
614  // quadrature point
615  if (system_i_norm.type(var) == H2 ||
616  system_i_norm.type(var) == H2_SEMINORM)
617  {
618 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
619  Tensor grad2_error = grad2_u_fine - grad2_u_coarse;
620 
621  H2seminormsq += JxW[qp] * system_i_norm.weight_sq(var) *
622  grad2_error.norm_sq();
623  libmesh_assert_greater_equal (H2seminormsq, 0.);
624 #else
625  libmesh_error_msg
626  ("libMesh was not configured with --enable-second");
627 #endif
628  }
629  } // end qp loop
630 
631  if (system_i_norm.type(var) == L2 ||
632  system_i_norm.type(var) == H1 ||
633  system_i_norm.type(var) == H2)
634  (*err_vec)[e_id] +=
635  static_cast<ErrorVectorReal>(L2normsq);
636  if (system_i_norm.type(var) == H1 ||
637  system_i_norm.type(var) == H2 ||
638  system_i_norm.type(var) == H1_SEMINORM)
639  (*err_vec)[e_id] +=
640  static_cast<ErrorVectorReal>(H1seminormsq);
641 
642 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
643  if (system_i_norm.type(var) == H2 ||
644  system_i_norm.type(var) == H2_SEMINORM)
645  (*err_vec)[e_id] +=
646  static_cast<ErrorVectorReal>(H2seminormsq);
647 #endif
648  } // End loop over active local elements
649  } // End loop over variables
650 
651  // Don't bother projecting the solution; we'll restore from backup
652  // after coarsening
653  system.project_solution_on_reinit() = false;
654  }
655 
656 
657  // Uniformly coarsen the mesh, without projecting the solution
659 
660  for (unsigned int i = 0; i != number_h_refinements; ++i)
661  {
662  mesh_refinement.uniformly_coarsen(1);
663  // FIXME - should the reinits here be necessary? - RHS
664  es.reinit();
665  }
666 
667  for (unsigned int i = 0; i != number_p_refinements; ++i)
668  {
669  mesh_refinement.uniformly_p_coarsen(1);
670  es.reinit();
671  }
672 
673  // We should be back where we started
674  libmesh_assert_equal_to (n_coarse_elem, mesh.n_elem());
675 
676  // Each processor has now computed the error contributions
677  // for its local elements. We need to sum the vector
678  // and then take the square-root of each component. Note
679  // that we only need to sum if we are running on multiple
680  // processors, and we only need to take the square-root
681  // if the value is nonzero. There will in general be many
682  // zeros for the inactive elements.
683 
684  if (error_per_cell)
685  {
686  // First sum the vector of estimated error values
687  this->reduce_error(*error_per_cell, es.comm());
688 
689  // Compute the square-root of each component.
690  LOG_SCOPE("std::sqrt()", "UniformRefinementEstimator");
691  for (auto & val : *error_per_cell)
692  if (val != 0.)
693  val = std::sqrt(val);
694  }
695  else
696  {
697  for (const auto & pr : *errors_per_cell)
698  {
699  ErrorVector & e = *(pr.second);
700  // First sum the vector of estimated error values
701  this->reduce_error(e, es.comm());
702 
703  // Compute the square-root of each component.
704  LOG_SCOPE("std::sqrt()", "UniformRefinementEstimator");
705  for (auto & val : e)
706  if (val != 0.)
707  val = std::sqrt(val);
708  }
709  }
710 
711  // Restore old solutions and clean up the heap
712  for (auto i : index_range(system_list))
713  {
714  System & system = *system_list[i];
715 
716  system.project_solution_on_reinit() = old_projection_settings[i];
717 
718  // Restore the coarse solution vectors and delete their copies
719  *system.solution = *coarse_solutions[i];
720  *system.current_local_solution = *coarse_local_solutions[i];
721 
722  for (System::vectors_iterator vec = system.vectors_begin(); vec !=
723  system.vectors_end(); ++vec)
724  {
725  // The (string) name of this vector
726  const std::string & var_name = vec->first;
727 
728  system.get_vector(var_name) = *coarse_vectors[i][var_name];
729 
730  coarse_vectors[i][var_name]->clear();
731  }
732  }
733 
734  // Restore old partitioner and renumbering settings
735  mesh.partitioner().reset(old_partitioner.release());
736  mesh.allow_renumbering(old_renumbering_setting);
737 }
738 
739 } // namespace libMesh
740 
741 #endif // #ifdef LIBMESH_ENABLE_AMR
libMesh::System
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:100
libMesh::EquationSystems::solve
virtual void solve()
Call solve on all the individual equation systems.
Definition: equation_systems.C:446
libMesh::Number
Real Number
Definition: libmesh_common.h:195
libMesh::dof_id_type
uint8_t dof_id_type
Definition: id_types.h:67
libMesh::System::n_vars
unsigned int n_vars() const
Definition: system.h:2155
libMesh::System::get_equation_systems
const EquationSystems & get_equation_systems() const
Definition: system.h:720
libMesh::invalid_uint
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value.
Definition: libmesh.h:249
libMesh::EquationSystems::get_mesh
const MeshBase & get_mesh() const
Definition: equation_systems.h:637
libMesh::System::vectors_iterator
std::map< std::string, NumericVector< Number > * >::iterator vectors_iterator
Vector iterator typedefs.
Definition: system.h:756
libMesh::ErrorEstimator::error_norm
SystemNorm error_norm
When estimating the error in a single system, the error_norm is used to control the scaling and norm ...
Definition: error_estimator.h:164
libMesh::DofMap::dof_indices
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Fills the vector di with the global degree of freedom indices for the element.
Definition: dof_map.C:1967
n_vars
unsigned int n_vars
Definition: adaptivity_ex3.C:116
libMesh::UniformRefinementEstimator::number_p_refinements
unsigned char number_p_refinements
How many p refinements to perform to get the fine grid.
Definition: uniform_refinement_estimator.h:121
libMesh::MeshRefinement::uniformly_p_refine
void uniformly_p_refine(unsigned int n=1)
Uniformly p refines the mesh n times.
Definition: mesh_refinement.C:1649
libMesh::ErrorEstimatorType
ErrorEstimatorType
Defines an enum for the different types of error estimators which are available.
Definition: enum_error_estimator_type.h:33
libMesh::NumericVector::swap
virtual void swap(NumericVector< T > &v)
Swaps the contents of this with v.
Definition: numeric_vector.h:989
libMesh::System::get_adjoint_solution
NumericVector< Number > & get_adjoint_solution(unsigned int i=0)
Definition: system.C:957
libMesh::ErrorEstimator
This class holds functions that will estimate the error in a finite element solution on a given mesh.
Definition: error_estimator.h:67
libMesh::SERIAL
Definition: enum_parallel_type.h:35
libMesh::index_range
IntRange< std::size_t > index_range(const std::vector< T > &vec)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:106
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::H1_SEMINORM
Definition: enum_norm_type.h:43
libMesh::EquationSystems::get_system
const T_sys & get_system(const std::string &name) const
Definition: equation_systems.h:757
libMesh::SystemNorm::weight_sq
Real weight_sq(unsigned int var) const
Definition: system_norm.C:176
std::sqrt
MetaPhysicL::DualNumber< T, D > sqrt(const MetaPhysicL::DualNumber< T, D > &in)
libMesh::ParallelObject::comm
const Parallel::Communicator & comm() const
Definition: parallel_object.h:94
libMesh::UNIFORM_REFINEMENT
Definition: enum_error_estimator_type.h:43
libMesh::H2
Definition: enum_norm_type.h:38
mesh
MeshBase & mesh
Definition: mesh_communication.C:1257
dim
unsigned int dim
Definition: adaptivity_ex3.C:113
libMesh::NumericVector::build
static std::unique_ptr< NumericVector< T > > build(const Parallel::Communicator &comm, const SolverPackage solver_package=libMesh::default_solver_package())
Builds a NumericVector on the processors in communicator comm using the linear solver package specifi...
Definition: numeric_vector.C:49
libMesh::SystemNorm::type
FEMNormType type(unsigned int var) const
Definition: system_norm.C:111
libMesh::VectorValue< Number >
libMesh::NumericVector< Number >
libMesh::System::current_solution
Number current_solution(const dof_id_type global_dof_number) const
Definition: system.C:194
libMesh::System::n_qois
unsigned int n_qois() const
Number of currently active quantities of interest.
Definition: system.h:2328
libMesh::MeshRefinement
Implements (adaptive) mesh refinement algorithms for a MeshBase.
Definition: mesh_refinement.h:61
libMesh::System::project_solution_on_reinit
bool & project_solution_on_reinit(void)
Tells the System whether or not to project the solution vector onto new grids when the system is rein...
Definition: system.h:802
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::IntRange
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
Definition: int_range.h:53
libMesh::MeshBase
This is the MeshBase class.
Definition: mesh_base.h:78
libMesh::System::vectors_end
vectors_iterator vectors_end()
End of vectors container.
Definition: system.h:2307
libMesh::System::vectors_begin
vectors_iterator vectors_begin()
Beginning of vectors container.
Definition: system.h:2295
libMesh::TypeVector::norm_sq
auto norm_sq() const -> decltype(std::norm(T()))
Definition: type_vector.h:986
libMesh::UniformRefinementEstimator::type
virtual ErrorEstimatorType type() const override
Definition: uniform_refinement_estimator.C:63
libMesh::TypeTensor::norm_sq
auto norm_sq() const -> decltype(std::norm(T()))
Definition: type_tensor.h:1390
libMesh::UniformRefinementEstimator::number_h_refinements
unsigned char number_h_refinements
How many h refinements to perform to get the fine grid.
Definition: uniform_refinement_estimator.h:116
libMesh::FEGenericBase::build
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
libMesh::System::current_local_solution
std::unique_ptr< NumericVector< Number > > current_local_solution
All the values I need to compute my contribution to the simulation at hand.
Definition: system.h:1551
libMesh::TensorValue
This class defines a tensor in LIBMESH_DIM dimensional Real or Complex space.
Definition: exact_solution.h:53
libMesh::ErrorVector
The ErrorVector is a specialization of the StatisticsVector for error data computed on a finite eleme...
Definition: error_vector.h:50
libMesh::DofMap::variable_type
const FEType & variable_type(const unsigned int c) const
Definition: dof_map.h:1924
libMesh::FEType::default_quadrature_rule
std::unique_ptr< QBase > default_quadrature_rule(const unsigned int dim, const int extraorder=0) const
Definition: fe_type.C:31
libMesh::EquationSystems::n_systems
unsigned int n_systems() const
Definition: equation_systems.h:652
libMesh::DofMap::get_send_list
const std::vector< dof_id_type > & get_send_list() const
Definition: dof_map.h:496
libMesh::H2_SEMINORM
Definition: enum_norm_type.h:44
libMesh::NumericVector::clear
virtual void clear()
Restores the NumericVector<T> to a pristine state.
Definition: numeric_vector.h:811
libMesh::UniformRefinementEstimator::estimate_errors
virtual void estimate_errors(const EquationSystems &equation_systems, ErrorVector &error_per_cell, const std::map< const System *, SystemNorm > &error_norms, const std::map< const System *, const NumericVector< Number > * > *solution_vectors=nullptr, bool estimate_parent_error=false) override
Currently this function ignores the error_norm member variable, and uses the function argument error_...
Definition: uniform_refinement_estimator.C:86
libMesh::EquationSystems
This is the EquationSystems class.
Definition: equation_systems.h:74
libMesh::Elem::parent
const Elem * parent() const
Definition: elem.h:2434
libMesh::EquationSystems::reinit
virtual void reinit()
Handle any mesh changes and reinitialize all the systems on the updated mesh.
Definition: equation_systems.C:121
libMesh::ErrorEstimator::ErrorMap
std::map< std::pair< const System *, unsigned int >, ErrorVector * > ErrorMap
When calculating many error vectors at once, we need a data structure to hold them all.
Definition: error_estimator.h:127
libMesh::System::solution
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1539
libMesh::TensorTools::norm_sq
T norm_sq(std::complex< T > a)
Definition: tensor_tools.h:85
libMesh::FEType
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:178
libMesh::ErrorEstimator::reduce_error
void reduce_error(std::vector< ErrorVectorReal > &error_per_cell, const Parallel::Communicator &comm) const
This method takes the local error contributions in error_per_cell from each processor and combines th...
Definition: error_estimator.C:32
libMesh::DofMap
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:176
libMesh::DofObject::id
dof_id_type id() const
Definition: dof_object.h:767
libMesh::System::request_vector
const NumericVector< Number > * request_vector(const std::string &vec_name) const
Definition: system.C:716
libMesh::UniformRefinementEstimator::_estimate_error
virtual void _estimate_error(const EquationSystems *equation_systems, const System *system, ErrorVector *error_per_cell, std::map< std::pair< const System *, unsigned int >, ErrorVector * > *errors_per_cell, const std::map< const System *, SystemNorm > *error_norms, const std::map< const System *, const NumericVector< Number > * > *solution_vectors=nullptr, bool estimate_parent_error=false)
The code for estimate_error and both estimate_errors versions is very similar, so we use the same fun...
Definition: uniform_refinement_estimator.C:117
libMesh::L2
Definition: enum_norm_type.h:36
libMesh::Elem
This is the base class from which all geometric element types are derived.
Definition: elem.h:100
libMesh::EquationSystems::adjoint_solve
virtual void adjoint_solve(const QoISet &qoi_indices=QoISet())
Call adjoint_solve on all the individual equation systems.
Definition: equation_systems.C:466
libMesh::SystemNorm
This class defines a norm/seminorm to be applied to a NumericVector which contains coefficients in a ...
Definition: system_norm.h:51
libMesh::NumericVector::get
virtual void get(const std::vector< numeric_index_type > &index, T *values) const
Access multiple components at once.
Definition: numeric_vector.h:821
libMesh::System::get_dof_map
const DofMap & get_dof_map() const
Definition: system.h:2099
libMesh::H1
Definition: enum_norm_type.h:37
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::System::adjoint_solve
virtual std::pair< unsigned int, Real > adjoint_solve(const QoISet &qoi_indices=QoISet())
Solves the adjoint system, for the specified qoi indices, or for every qoi if qoi_indices is nullptr.
Definition: system.h:2350
libMesh::System::disable_cache
virtual void disable_cache()
Avoids use of any cached data that might affect any solve result.
Definition: system.h:2325
libMesh::UniformRefinementEstimator::estimate_error
virtual void estimate_error(const System &system, ErrorVector &error_per_cell, const NumericVector< Number > *solution_vector=nullptr, bool estimate_parent_error=false) override
This function does uniform refinements and a solve to get an improved solution on each cell,...
Definition: uniform_refinement_estimator.C:69
libMesh::MeshRefinement::uniformly_refine
void uniformly_refine(unsigned int n=1)
Uniformly refines the mesh n times.
Definition: mesh_refinement.C:1678
libMesh::MeshRefinement::uniformly_coarsen
void uniformly_coarsen(unsigned int n=1)
Attempts to uniformly coarsen the mesh n times.
Definition: mesh_refinement.C:1703
libMesh::System::get_vector
const NumericVector< Number > & get_vector(const std::string &vec_name) const
Definition: system.C:774
libMesh::System::solve
virtual void solve()
Solves the system.
Definition: system.h:334
libMesh::UniformRefinementEstimator::UniformRefinementEstimator
UniformRefinementEstimator()
Constructor.
Definition: uniform_refinement_estimator.C:53
libMesh::MeshRefinement::uniformly_p_coarsen
void uniformly_p_coarsen(unsigned int n=1)
Attempts to uniformly p coarsen the mesh n times.
Definition: mesh_refinement.C:1663
libMesh::System::update
virtual void update()
Update the local values to reflect the solution on neighboring processors.
Definition: system.C:408