Go to the documentation of this file.
   24 #include <unordered_map> 
   25 #include <unordered_set> 
   28 #include "libmesh/dof_map.h" 
   29 #include "libmesh/elem.h" 
   30 #include "libmesh/equation_systems.h" 
   31 #include "libmesh/error_vector.h" 
   32 #include "libmesh/fe.h" 
   33 #include "libmesh/fe_interface.h" 
   34 #include "libmesh/libmesh_common.h" 
   35 #include "libmesh/libmesh_logging.h" 
   36 #include "libmesh/mesh_base.h" 
   37 #include "libmesh/mesh_refinement.h" 
   38 #include "libmesh/numeric_vector.h" 
   39 #include "libmesh/quadrature.h" 
   40 #include "libmesh/system.h" 
   41 #include "libmesh/diff_physics.h" 
   42 #include "libmesh/fem_system.h" 
   43 #include "libmesh/implicit_system.h" 
   44 #include "libmesh/partitioner.h" 
   45 #include "libmesh/adjoint_refinement_estimator.h" 
   46 #include "libmesh/enum_error_estimator_type.h" 
   47 #include "libmesh/enum_norm_type.h" 
   48 #include "libmesh/utility.h" 
   50 #ifdef LIBMESH_ENABLE_AMR 
   75   number_h_refinements(1),
 
   76   number_p_refinements(0),
 
   77   _residual_evaluation_physics(nullptr),
 
   96   System & system = const_cast<System &>(_system);
 
  120   for (
unsigned int j=0,
 
  121        n_qois = system.
n_qois(); j != n_qois; j++)
 
  139             if (swapping_physics)
 
  143             (dynamic_cast<ImplicitSystem &>(system)).assembly(
true, 
false, 
false, 
true);
 
  146             coarse_residual = &(dynamic_cast<ExplicitSystem &>(system)).get_vector(
"RHS Vector");
 
  147             coarse_residual->
close();
 
  150             std::ostringstream liftfunc_name;
 
  151             liftfunc_name << 
"adjoint_lift_function" << j;
 
  160               (system.
get_vector(liftfunc_name.str()), static_cast<unsigned int>(j));
 
  163             std::cout<<
"The flux QoI "<<static_cast<unsigned int>(j)<<
" is: "<<coarse_residual->
dot(system.
get_vector(liftfunc_name.str()))<<std::endl<<std::endl;
 
  166             if (swapping_physics)
 
  173   std::map<std::string, std::unique_ptr<NumericVector<Number>>> coarse_vectors;
 
  177       const std::string & var_name = pr.first;
 
  179       coarse_vectors[var_name] = pr.second->clone();
 
  183   std::unique_ptr<NumericVector<Number>> coarse_solution = system.
solution->clone();
 
  187   bool old_projection_setting;
 
  194   std::unique_ptr<Partitioner> old_partitioner(
mesh.partitioner().release());
 
  197   const bool old_renumbering_setting = 
mesh.allow_renumbering();
 
  198   mesh.allow_renumbering(
false);
 
  201   if (solution_vector && solution_vector != system.
solution.get())
 
  211   error_per_cell.clear();
 
  212   error_per_cell.resize (
mesh.max_elem_id(), 0.);
 
  220   const unsigned int sysnum = system.
number();
 
  221   for (
const auto * node : 
mesh.local_node_ptr_range())
 
  222     for (
unsigned int v=0, nvars = node->n_vars(sysnum);
 
  224       if (node->n_comp(sysnum, v))
 
  226           local_dof_bearing_nodes++;
 
  253   std::vector<std::unique_ptr<NumericVector<Number>>> coarse_adjoints;
 
  266           coarse_adjoints.emplace_back(std::move(coarse_adjoint));
 
  269         coarse_adjoints.emplace_back(
nullptr);
 
  279     if (swapping_physics)
 
  285     (dynamic_cast<ImplicitSystem &>(system)).assembly(
true, 
false);
 
  288     if (swapping_physics)
 
  292   NumericVector<Number> & projected_residual = (dynamic_cast<ExplicitSystem &>(system)).get_vector(
"RHS Vector");
 
  293   projected_residual.
close();
 
  321               std::ostringstream liftfunc_name;
 
  322               liftfunc_name << 
"adjoint_lift_function" << j;
 
  390   std::unordered_map<dof_id_type, unsigned int> shared_element_count;
 
  397   std::unordered_set<dof_id_type> processed_node_ids;
 
  401   for (
const auto & elem : 
mesh.active_local_element_ptr_range())
 
  402     for (
const Node & node : elem->node_ref_range())
 
  408         if (processed_node_ids.find(node_id) == processed_node_ids.end())
 
  411             std::set<const Elem *> fine_grid_neighbor_set;
 
  414             elem->find_point_neighbors(node, fine_grid_neighbor_set);
 
  417             std::vector<dof_id_type> coarse_grid_neighbors;
 
  420             for (
const auto & fine_elem : fine_grid_neighbor_set)
 
  423                 const Elem * coarse_elem = fine_elem;
 
  428                     coarse_elem = coarse_elem->
parent();
 
  437                 for (std::size_t cgns = coarse_grid_neighbors.size(); j != cgns; j++)
 
  438                   if (coarse_grid_neighbors[j] == coarse_id)
 
  443                 if (j == coarse_grid_neighbors.size())
 
  444                   coarse_grid_neighbors.push_back(coarse_id);
 
  449             shared_element_count[node_id] =
 
  450               cast_int<unsigned int>(coarse_grid_neighbors.size());
 
  453             processed_node_ids.insert(node_id);
 
  461   std::vector<dof_id_type> dof_indices;
 
  487           for (
const auto & elem : 
mesh.active_local_element_ptr_range())
 
  490               const Elem * coarse = elem;
 
  496                   coarse = coarse->
parent();
 
  505               Number local_contribution = 0.;
 
  508               for (
const auto & dof : dof_indices)
 
  509                 local_contribution += (*localized_projected_residual)(dof) * (*localized_adjoint_solution)(dof);
 
  512               local_contribution *= error_weight;
 
  516               error_per_cell[e_id] += static_cast<ErrorVectorReal>
 
  546   libmesh_assert_equal_to (n_coarse_elem, 
mesh.n_active_elem());
 
  552   for (
const auto * node : 
mesh.local_node_ptr_range())
 
  553     for (
unsigned int v=0, nvars = node->n_vars(sysnum);
 
  555       if (node->n_comp(sysnum, v))
 
  557           final_local_dof_bearing_nodes++;
 
  560   libmesh_assert_equal_to (local_dof_bearing_nodes,
 
  561                            final_local_dof_bearing_nodes);
 
  568   *system.
solution = *coarse_solution;
 
  574       const std::string & var_name = pr.first;
 
  578       auto it = coarse_vectors.find(var_name);
 
  579       if (it != coarse_vectors.end())
 
  589   mesh.partitioner().reset(old_partitioner.release());
 
  590   mesh.allow_renumbering(old_renumbering_setting);
 
  601 #endif // #ifdef LIBMESH_ENABLE_AMR 
  
Manages consistently variables, degrees of freedom, and coefficient vectors.
 
const EquationSystems & get_equation_systems() const
 
virtual ErrorEstimatorType type() const
 
const MeshBase & get_mesh() const
 
SystemNorm error_norm
When estimating the error in a single system, the error_norm is used to control the scaling and norm ...
 
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.
 
void uniformly_p_refine(unsigned int n=1)
Uniformly p refines the mesh n times.
 
std::vector< Number > computed_global_QoI_errors
 
ErrorEstimatorType
Defines an enum for the different types of error estimators which are available.
 
virtual void swap(NumericVector< T > &v)
Swaps the contents of this with v.
 
bool has_index(std::size_t) const
Return whether or not this index is in the set to be calculated.
 
bool has_adjoint_dirichlet_boundaries(unsigned int q) const
 
QoISet _qoi_set
A QoISet to handle cases with multiple QoIs available.
 
NumericVector< Number > & get_adjoint_solution(unsigned int i=0)
 
This class holds functions that will estimate the error in a finite element solution on a given mesh.
 
The libMesh namespace provides an interface to certain functionality in the library.
 
DifferentiablePhysics * _residual_evaluation_physics
Pointer to object to use for physics assembly evaluations.
 
virtual void close()=0
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
 
const Parallel::Communicator & comm() const
 
unsigned int number() const
 
bool is_adjoint_already_solved() const
Accessor for the adjoint_already_solved boolean.
 
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...
 
unsigned int n_qois() const
Number of currently active quantities of interest.
 
void enforce_adjoint_constraints_exactly(NumericVector< Number > &v, unsigned int q) const
Heterogenously constrains the numeric vector v, which represents an adjoint solution defined on the m...
 
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
 
Implements (adaptive) mesh refinement algorithms for a MeshBase.
 
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...
 
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
 
This is the MeshBase class.
 
MetaPhysicL::DualNumber< T, D > abs(const MetaPhysicL::DualNumber< T, D > &in)
 
vectors_iterator vectors_end()
End of vectors container.
 
virtual void localize(std::vector< T > &v_local) const =0
Creates a copy of the global vector in the local vector v_local.
 
vectors_iterator vectors_begin()
Beginning of vectors container.
 
dof_id_type n_local_dofs() const
 
Data structure for specifying which Quantities of Interest should be calculated in an adjoint or a pa...
 
std::unique_ptr< NumericVector< Number > > current_local_solution
All the values I need to compute my contribution to the simulation at hand.
 
A Node is like a Point, but with more information.
 
The ErrorVector is a specialization of the StatisticsVector for error data computed on a finite eleme...
 
unsigned char number_h_refinements
How many h refinements to perform to get the fine grid.
 
unsigned char number_p_refinements
How many p refinements to perform to get the fine grid.
 
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
 
Real weight(std::size_t) const
Get the weight for this index (default 1.0)
 
const std::vector< dof_id_type > & get_send_list() const
 
virtual void clear()
Restores the NumericVector<T> to a pristine state.
 
AdjointRefinementEstimator()
Constructor.
 
This is the EquationSystems class.
 
const Elem * parent() const
 
virtual void reinit()
Handle any mesh changes and reinitialize all the systems on the updated mesh.
 
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
 
virtual void estimate_error(const System &system, ErrorVector &error_per_cell, const NumericVector< Number > *solution_vector=nullptr, bool estimate_parent_error=false)
This function does uniform refinements and an adjoint solve to get an adjoint solution on each cell,...
 
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...
 
This class handles the numbering of degrees of freedom on a mesh.
 
This is the base class from which all geometric element types are derived.
 
NumericVector< Number > & add_vector(const std::string &vec_name, const bool projections=true, const ParallelType type=PARALLEL)
Adds the additional vector vec_name to this system.
 
virtual void get(const std::vector< numeric_index_type > &index, T *values) const
Access multiple components at once.
 
const DofMap & get_dof_map() const
 
dof_id_type n_dofs() const
 
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
 
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.
 
void uniformly_refine(unsigned int n=1)
Uniformly refines the mesh n times.
 
void uniformly_coarsen(unsigned int n=1)
Attempts to uniformly coarsen the mesh n times.
 
const NumericVector< Number > & get_vector(const std::string &vec_name) const
 
void uniformly_p_coarsen(unsigned int n=1)
Attempts to uniformly p coarsen the mesh n times.
 
virtual void update()
Update the local values to reflect the solution on neighboring processors.
 
virtual T dot(const NumericVector< T > &v) const =0