AdjointResidualErrorEstimator Class Reference

#include <adjoint_residual_error_estimator.h>

Inheritance diagram for AdjointResidualErrorEstimator:

List of all members.

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 ()
QoISetqoi_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.

Author:
Roy H. Stogner, 2009.

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.

AdjointResidualErrorEstimator::~AdjointResidualErrorEstimator (  )  [inline]

Destructor.

Definition at line 64 of file adjoint_residual_error_estimator.h.

00064 {}


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().

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().

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().

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:

Site Created By: libMesh Developers
Last modified: November 25 2009 03:43:54.

Hosted By:
SourceForge.net Logo