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