AdjointResidualErrorEstimator Class Reference
#include <adjoint_residual_error_estimator.h>

Public Types | |
| typedef std::map< std::pair < const System *, unsigned int > , ErrorVector * > | ErrorMap |
Public Member Functions | |
| AdjointResidualErrorEstimator () | |
| ~AdjointResidualErrorEstimator () | |
| AutoPtr< ErrorEstimator > & | primal_error_estimator () |
| AutoPtr< ErrorEstimator > & | dual_error_estimator () |
| QoISet & | qoi_set () |
| void | estimate_error (const System &system, ErrorVector &error_per_cell, const NumericVector< Number > *solution_vector=NULL, bool estimate_parent_error=false) |
| 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=NULL, bool estimate_parent_error=false) |
| virtual void | estimate_errors (const EquationSystems &equation_systems, ErrorMap &errors_per_cell, const std::map< const System *, const NumericVector< Number > * > *solution_vectors=NULL, bool estimate_parent_error=false) |
Public Attributes | |
| bool | adjoint_already_solved |
| std::string | error_plot_suffix |
| SystemNorm | error_norm |
Protected Member Functions | |
| void | reduce_error (std::vector< float > &error_per_cell) const |
Protected Attributes | |
| AutoPtr< ErrorEstimator > | _primal_error_estimator |
| AutoPtr< ErrorEstimator > | _dual_error_estimator |
| QoISet | _qoi_set |
Detailed Description
This class implements a goal oriented error indicator, by weighting residual-based estimates from the primal problem against estimates from the adjoint problem.This is based on a trick suggested by Brian Carnes, but if it doesn't actually work then the misunderstanding or misimplementation will be the fault of Roy Stogner. It's also Roy's fault there's no literature reference here yet.
Definition at line 52 of file adjoint_residual_error_estimator.h.
Member Typedef Documentation
typedef std::map<std::pair<const System*, unsigned int>, ErrorVector*> ErrorEstimator::ErrorMap [inherited] |
When calculating many error vectors at once, we need a data structure to hold them all
Definition at line 105 of file error_estimator.h.
Constructor & Destructor Documentation
| AdjointResidualErrorEstimator::AdjointResidualErrorEstimator | ( | ) |
Constructor. Responsible for picking default subestimators.
Definition at line 36 of file adjoint_residual_error_estimator.C.
00036 : 00037 adjoint_already_solved(false), 00038 error_plot_suffix(), 00039 _primal_error_estimator(new PatchRecoveryErrorEstimator()), 00040 _dual_error_estimator(new PatchRecoveryErrorEstimator()), 00041 _qoi_set(QoISet()) 00042 { 00043 }
| AdjointResidualErrorEstimator::~AdjointResidualErrorEstimator | ( | ) | [inline] |
Member Function Documentation
| AutoPtr<ErrorEstimator>& AdjointResidualErrorEstimator::dual_error_estimator | ( | ) | [inline] |
Access to the "subestimator" (default: PatchRecovery) to use on the dual/adjoint solution
Definition at line 76 of file adjoint_residual_error_estimator.h.
References _dual_error_estimator.
00076 { return _dual_error_estimator; }
| void AdjointResidualErrorEstimator::estimate_error | ( | const System & | system, | |
| ErrorVector & | error_per_cell, | |||
| const NumericVector< Number > * | solution_vector = NULL, |
|||
| bool | estimate_parent_error = false | |||
| ) | [virtual] |
Compute the adjoint-weighted error on each element and place it in the error_per_cell vector. Note that this->error_norm is ignored; the error estimate is in the seminorm given by the absolute value of the error in the quantity of interest functional. The primal and dual subestimator error_norm values are used, and should be chosen appropriately for your model.
Implements ErrorEstimator.
Definition at line 47 of file adjoint_residual_error_estimator.C.
References _dual_error_estimator, _primal_error_estimator, _qoi_set, adjoint_already_solved, System::adjoint_solve(), error_plot_suffix, System::get_adjoint_solution(), System::get_mesh(), QoISet::has_index(), ErrorVector::plot_error(), System::qoi, and QoISet::weight().
00051 { 00052 START_LOG("estimate_error()", "AdjointResidualErrorEstimator"); 00053 00054 // Start by estimating the primal problem error 00055 _primal_error_estimator->estimate_error 00056 (_system, error_per_cell, solution_vector, estimate_parent_error); 00057 00058 // Solve the dual problem if we have to 00059 if (!adjoint_already_solved) 00060 { 00061 // FIXME - we'll need to change a lot of APIs to make this trick 00062 // work with a const System... 00063 System& system = const_cast<System&>(_system); 00064 system.adjoint_solve(_qoi_set); 00065 } 00066 00067 // This bookkeeping should now be taken care of in subestimators 00068 // when they see a non-default solution_vector 00069 // 00070 // // Swap the system solution and dual solution, so our next error 00071 // // estimate will use the latter 00072 // // system.solution->swap(system.get_adjoint_solution()); 00073 00074 // // Don't forget to keep the current_local_solution consistent, as 00075 // // error estimators are likely to use that! 00076 // // system.update(); 00077 00078 // Get a separate estimate of the dual problem error 00079 ErrorVector total_dual_error_per_cell; 00080 00081 // Sum and weight this estimate based on our QoISet 00082 for (unsigned int i = 0; i != _system.qoi.size(); ++i) 00083 if (_qoi_set.has_index(i)) 00084 { 00085 Real error_weight = _qoi_set.weight(i); 00086 00087 ErrorVector dual_error_per_cell; 00088 _dual_error_estimator->estimate_error 00089 (_system, dual_error_per_cell, &(_system.get_adjoint_solution(i)), 00090 estimate_parent_error); 00091 00092 unsigned int error_size = dual_error_per_cell.size(); 00093 libmesh_assert(!total_dual_error_per_cell.size() || 00094 total_dual_error_per_cell.size() == error_size); 00095 total_dual_error_per_cell.resize(error_size); 00096 for (unsigned int e = 0; e != error_size; ++e) 00097 total_dual_error_per_cell[e] += 00098 error_weight * dual_error_per_cell[e]; 00099 } 00100 00101 // Do some debugging plots if requested 00102 if (!error_plot_suffix.empty()) 00103 { 00104 std::string primal_out = "primal_"; 00105 std::string dual_out = "dual_"; 00106 primal_out += error_plot_suffix; 00107 dual_out += error_plot_suffix; 00108 error_per_cell.plot_error(primal_out, _system.get_mesh()); 00109 total_dual_error_per_cell.plot_error(dual_out, _system.get_mesh()); 00110 } 00111 00112 // More bookkeeping for subestimators to do 00113 // 00114 // // Swap the system solution and dual solution back to their proper 00115 // // places 00116 // system.solution->swap(system.get_adjoint_solution()); 00117 00118 // // Don't forget to fix the current_local_solution 00119 // system.update(); 00120 00121 // Weight the primal error by the dual error 00122 // FIXME: we ought to thread this 00123 for (unsigned int i=0; i != error_per_cell.size(); ++i) 00124 error_per_cell[i] *= total_dual_error_per_cell[i]; 00125 00126 STOP_LOG("estimate_error()", "AdjointResidualErrorEstimator"); 00127 }
| void ErrorEstimator::estimate_errors | ( | const EquationSystems & | equation_systems, | |
| ErrorMap & | errors_per_cell, | |||
| const std::map< const System *, const NumericVector< Number > * > * | solution_vectors = NULL, |
|||
| bool | estimate_parent_error = false | |||
| ) | [virtual, inherited] |
This virtual function can be redefined in derived classes, but by default it calls estimate_error repeatedly to calculate the requested error vectors.
Currently this function ignores the error_norm.weight() values because it calculates each variable's error individually, unscaled.
The user selects which errors get computed by filling a map with error vectors: If errors_per_cell[&system][v] exists, it will be filled with the error values in variable v of system
FIXME: This is a default implementation - derived classes should reimplement it for efficiency.
Definition at line 92 of file error_estimator.C.
References ErrorEstimator::error_norm, ErrorEstimator::estimate_error(), EquationSystems::get_system(), EquationSystems::n_systems(), System::n_vars(), n_vars, and SystemNorm::type().
00096 { 00097 SystemNorm old_error_norm = this->error_norm; 00098 00099 // Find the requested error values from each system 00100 for (unsigned int s = 0; s != equation_systems.n_systems(); ++s) 00101 { 00102 const System &sys = equation_systems.get_system(s); 00103 00104 unsigned int n_vars = sys.n_vars(); 00105 00106 for (unsigned int v = 0; v != n_vars; ++v) 00107 { 00108 // Only fill in ErrorVectors the user asks for 00109 if (errors_per_cell.find(std::make_pair(&sys, v)) == 00110 errors_per_cell.end()) 00111 continue; 00112 00113 // Calculate error in only one variable 00114 std::vector<Real> weights(n_vars, 0.0); 00115 weights[v] = 1.0; 00116 this->error_norm = 00117 SystemNorm(std::vector<FEMNormType>(n_vars, old_error_norm.type(0)), 00118 weights); 00119 00120 const NumericVector<Number>* solution_vector = NULL; 00121 if (solution_vectors && 00122 solution_vectors->find(&sys) != solution_vectors->end()) 00123 solution_vector = solution_vectors->find(&sys)->second; 00124 00125 this->estimate_error 00126 (sys, *errors_per_cell[std::make_pair(&sys, v)], 00127 solution_vector, estimate_parent_error); 00128 } 00129 } 00130 00131 // Restore our old state before returning 00132 this->error_norm = old_error_norm; 00133 }
| void ErrorEstimator::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 = NULL, |
|||
| bool | estimate_parent_error = false | |||
| ) | [virtual, inherited] |
This virtual function can be redefined in derived classes, but by default computes the sum of the error_per_cell for each system in the equation_systems.
Currently this function ignores the error_norm member variable, and uses the function argument error_norms instead.
This function is named estimate_errors instead of estimate_error because otherwise C++ can get confused.
Reimplemented in UniformRefinementEstimator.
Definition at line 46 of file error_estimator.C.
References ErrorEstimator::error_norm, ErrorEstimator::estimate_error(), EquationSystems::get_system(), and EquationSystems::n_systems().
00051 { 00052 SystemNorm old_error_norm = this->error_norm; 00053 00054 // Sum the error values from each system 00055 for (unsigned int s = 0; s != equation_systems.n_systems(); ++s) 00056 { 00057 ErrorVector system_error_per_cell; 00058 const System &sys = equation_systems.get_system(s); 00059 if (error_norms.find(&sys) == error_norms.end()) 00060 this->error_norm = old_error_norm; 00061 else 00062 this->error_norm = error_norms.find(&sys)->second; 00063 00064 const NumericVector<Number>* solution_vector = NULL; 00065 if (solution_vectors && 00066 solution_vectors->find(&sys) != solution_vectors->end()) 00067 solution_vector = solution_vectors->find(&sys)->second; 00068 00069 this->estimate_error(sys, system_error_per_cell, 00070 solution_vector, estimate_parent_error); 00071 00072 if (s) 00073 { 00074 libmesh_assert(error_per_cell.size() == system_error_per_cell.size()); 00075 for (unsigned int i=0; i != error_per_cell.size(); ++i) 00076 error_per_cell[i] += system_error_per_cell[i]; 00077 } 00078 else 00079 error_per_cell = system_error_per_cell; 00080 } 00081 00082 // Restore our old state before returning 00083 this->error_norm = old_error_norm; 00084 }
| AutoPtr<ErrorEstimator>& AdjointResidualErrorEstimator::primal_error_estimator | ( | ) | [inline] |
Access to the "subestimator" (default: PatchRecovery) to use on the primal/forward solution
Definition at line 70 of file adjoint_residual_error_estimator.h.
References _primal_error_estimator.
00070 { return _primal_error_estimator; }
| QoISet& AdjointResidualErrorEstimator::qoi_set | ( | ) | [inline] |
Access to the QoISet (default: weight all QoIs equally) to use when computing errors
Definition at line 82 of file adjoint_residual_error_estimator.h.
References _qoi_set.
00082 { return _qoi_set; }
| void ErrorEstimator::reduce_error | ( | std::vector< float > & | error_per_cell | ) | const [protected, inherited] |
This method takes the local error contributions in error_per_cell from each processor and combines them to get the global error vector.
Referenced by PatchRecoveryErrorEstimator::estimate_error(), and JumpErrorEstimator::estimate_error().
Member Data Documentation
An error estimator for the adjoint problem
Definition at line 123 of file adjoint_residual_error_estimator.h.
Referenced by dual_error_estimator(), and estimate_error().
An error estimator for the forward problem
Definition at line 118 of file adjoint_residual_error_estimator.h.
Referenced by estimate_error(), and primal_error_estimator().
QoISet AdjointResidualErrorEstimator::_qoi_set [protected] |
A QoISet to handle cases with multiple QoIs available
Definition at line 128 of file adjoint_residual_error_estimator.h.
Referenced by estimate_error(), and qoi_set().
Has the adjoint problem already been solved? If the user sets adjoint_already_solved to true, we won't waste time solving it again.
Definition at line 89 of file adjoint_residual_error_estimator.h.
Referenced by estimate_error().
SystemNorm ErrorEstimator::error_norm [inherited] |
When estimating the error in a single system, the error_norm is used to control the scaling and norm choice for each variable. Not all estimators will support all norm choices. The default scaling is for all variables to be weighted equally. The default norm choice depends on the error estimator.
Part of this functionality was supported via component_scale and sobolev_order in older libMesh versions, and a small part was supported via component_mask in even older versions. Hopefully the encapsulation here will allow us to avoid changing this API again.
Definition at line 137 of file error_estimator.h.
Referenced by KellyErrorEstimator::boundary_side_integration(), DiscontinuityMeasure::boundary_side_integration(), DiscontinuityMeasure::DiscontinuityMeasure(), JumpErrorEstimator::estimate_error(), ErrorEstimator::estimate_errors(), ExactErrorEstimator::ExactErrorEstimator(), ExactErrorEstimator::find_squared_element_error(), KellyErrorEstimator::internal_side_integration(), LaplacianErrorEstimator::internal_side_integration(), DiscontinuityMeasure::internal_side_integration(), KellyErrorEstimator::KellyErrorEstimator(), LaplacianErrorEstimator::LaplacianErrorEstimator(), PatchRecoveryErrorEstimator::EstimateError::operator()(), PatchRecoveryErrorEstimator::PatchRecoveryErrorEstimator(), and UniformRefinementEstimator::UniformRefinementEstimator().
| std::string AdjointResidualErrorEstimator::error_plot_suffix |
To aid in investigating error estimator behavior, set this string to a suffix with which to plot (prefixed by "primal_" or "dual_") the subestimator results. The suffix should end with a file extension (e.g. ".gmv") that the ErrorVector::plot_error recognizes.
Definition at line 98 of file adjoint_residual_error_estimator.h.
Referenced by estimate_error().
The documentation for this class was generated from the following files: