DiscontinuityMeasure Class Reference
#include <discontinuity_measure.h>

Public Types | |
| typedef std::map< std::pair < const System *, unsigned int > , ErrorVector * > | ErrorMap |
Public Member Functions | |
| DiscontinuityMeasure () | |
| ~DiscontinuityMeasure () | |
| void | attach_essential_bc_function (std::pair< bool, Real > fptr(const System &system, const Point &p, const std::string &var_name)) |
| virtual 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 | scale_by_n_flux_faces |
| SystemNorm | error_norm |
Protected Member Functions | |
| virtual void | initialize (const System &system, ErrorVector &error_per_cell, bool estimate_parent_error) |
| virtual void | internal_side_integration () |
| virtual bool | boundary_side_integration () |
| void | reinit_sides () |
| float | coarse_n_flux_faces_increment () |
| void | reduce_error (std::vector< float > &error_per_cell) const |
Protected Attributes | |
| const System * | my_system |
| std::pair< bool, Real >(* | _bc_function )(const System &system, const Point &p, const std::string &var_name) |
| bool | integrate_boundary_sides |
| const Elem * | fine_elem |
| const Elem * | coarse_elem |
| Real | fine_error |
| Real | coarse_error |
| unsigned int | fine_side |
| unsigned int | var |
| DenseVector< Number > | Ufine |
| DenseVector< Number > | Ucoarse |
| AutoPtr< FEBase > | fe_fine |
| AutoPtr< FEBase > | fe_coarse |
Detailed Description
This class measures discontinuities between elements for debugging purposes. It derives from ErrorEstimator just in case someone finds it useful in a DG framework.
Definition at line 46 of file discontinuity_measure.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
| DiscontinuityMeasure::DiscontinuityMeasure | ( | ) | [inline] |
Constructor. Responsible for initializing the _bc_function function pointer to NULL. Defaults to L2 norm; changes to system norm are ignored.
Definition at line 55 of file discontinuity_measure.h.
References ErrorEstimator::error_norm, and libMeshEnums::L2.
00055 : _bc_function(NULL) { error_norm = L2; }
| DiscontinuityMeasure::~DiscontinuityMeasure | ( | ) | [inline] |
Member Function Documentation
| void DiscontinuityMeasure::attach_essential_bc_function | ( | std::pair< bool, Real > | fptrconst System &system,const Point &p,const std::string &var_name | ) |
Register a user function to use in computing the essential BCs. The return value is std::pair<bool, Real>
Definition at line 163 of file discontinuity_measure.C.
00166 { 00167 _bc_function = fptr; 00168 00169 // We may be turning boundary side integration on or off 00170 if (fptr) 00171 integrate_boundary_sides = true; 00172 else 00173 integrate_boundary_sides = false; 00174 }
| bool DiscontinuityMeasure::boundary_side_integration | ( | ) | [protected, virtual] |
The function which calculates a normal derivative jump based error term on a boundary side. Returns true if the flux bc function is in fact defined on the current side.
Reimplemented from JumpErrorEstimator.
Definition at line 95 of file discontinuity_measure.C.
References _bc_function, ErrorEstimator::error_norm, JumpErrorEstimator::fe_fine, JumpErrorEstimator::fine_elem, JumpErrorEstimator::fine_error, Elem::hmax(), libmesh_norm(), my_system, JumpErrorEstimator::Ufine, JumpErrorEstimator::var, System::variable_name(), and SystemNorm::weight().
00096 { 00097 const std::string &var_name = my_system->variable_name(var); 00098 00099 std::vector<std::vector<Real> > phi_fine = fe_fine->get_phi(); 00100 std::vector<Real> JxW_face = fe_fine->get_JxW(); 00101 std::vector<Point> qface_point = fe_fine->get_xyz(); 00102 00103 // The reinitialization also recomputes the locations of 00104 // the quadrature points on the side. By checking if the 00105 // first quadrature point on the side is on an essential boundary 00106 // for a particular variable, we will determine if the whole 00107 // element is on an essential boundary (assuming quadrature points 00108 // are strictly contained in the side). 00109 if (this->_bc_function(*my_system, qface_point[0], var_name).first) 00110 { 00111 const Real h = fine_elem->hmax(); 00112 00113 // The number of quadrature points 00114 const unsigned int n_qp = fe_fine->n_quadrature_points(); 00115 00116 // The error contribution from this face 00117 Real error = 1.e-30; 00118 00119 // loop over the integration points on the face. 00120 for (unsigned int qp=0; qp<n_qp; qp++) 00121 { 00122 // Value of the imposed essential BC at this quadrature point. 00123 const std::pair<bool,Real> essential_bc = 00124 this->_bc_function(*my_system, qface_point[qp], var_name); 00125 00126 // Be sure the BC function still thinks we're on the 00127 // essential boundary. 00128 libmesh_assert (essential_bc.first == true); 00129 00130 // The solution gradient from each element 00131 Number u_fine = 0.; 00132 00133 // Compute the solution gradient on element e 00134 for (unsigned int i=0; i != Ufine.size(); i++) 00135 u_fine += phi_fine[i][qp] * Ufine(i); 00136 00137 // The difference between the desired BC and the approximate solution. 00138 const Number jump = essential_bc.second - u_fine; 00139 00140 // The flux jump squared. If using complex numbers, 00141 // libmesh_norm(z) returns |z|^2, where |z| is the modulus of z. 00142 const Real jump2 = libmesh_norm(jump); 00143 00144 // Integrate the error on the face. The error is 00145 // scaled by an additional power of h, where h is 00146 // the maximum side length for the element. This 00147 // arises in the definition of the indicator. 00148 error += JxW_face[qp]*jump2; 00149 00150 } // End quadrature point loop 00151 00152 fine_error = error*h*error_norm.weight(var); 00153 00154 return true; 00155 } // end if side on flux boundary 00156 return false; 00157 }
| float JumpErrorEstimator::coarse_n_flux_faces_increment | ( | ) | [protected, inherited] |
A utility function to correctly increase n_flux_faces for the coarse element
Definition at line 433 of file jump_error_estimator.C.
References JumpErrorEstimator::coarse_elem, Elem::dim(), dim, JumpErrorEstimator::fine_elem, and Elem::level().
Referenced by JumpErrorEstimator::estimate_error().
00434 { 00435 // Keep track of the number of internal flux sides found on each 00436 // element 00437 unsigned int dim = coarse_elem->dim(); 00438 00439 const unsigned int divisor = 00440 1 << (dim-1)*(fine_elem->level() - coarse_elem->level()); 00441 00442 // With a difference of n levels between fine and coarse elements, 00443 // we compute a fractional flux face for the coarse element by adding: 00444 // 1/2^n in 2D 00445 // 1/4^n in 3D 00446 // each time. This code will get hit 2^n times in 2D and 4^n 00447 // times in 3D so that the final flux face count for the coarse 00448 // element will be an integer value. 00449 00450 return 1.0 / static_cast<Real>(divisor); 00451 }
| void JumpErrorEstimator::estimate_error | ( | const System & | system, | |
| ErrorVector & | error_per_cell, | |||
| const NumericVector< Number > * | solution_vector = NULL, |
|||
| bool | estimate_parent_error = false | |||
| ) | [virtual, inherited] |
This function uses the derived class's jump error estimate formula to estimate the error on each cell. The estimated error is output in the vector error_per_cell
Implements ErrorEstimator.
Definition at line 52 of file jump_error_estimator.C.
References Elem::active(), MeshBase::active_local_elements_begin(), MeshBase::active_local_elements_end(), JumpErrorEstimator::boundary_side_integration(), FEBase::build(), Elem::child(), JumpErrorEstimator::coarse_elem, JumpErrorEstimator::coarse_error, JumpErrorEstimator::coarse_n_flux_faces_increment(), FEBase::coarsened_dof_values(), System::current_solution(), FEType::default_quadrature_order(), dim, DofMap::dof_indices(), ErrorEstimator::error_norm, JumpErrorEstimator::fe_coarse, JumpErrorEstimator::fe_fine, FEBase::fe_type, JumpErrorEstimator::fine_elem, JumpErrorEstimator::fine_error, JumpErrorEstimator::fine_side, System::get_dof_map(), System::get_mesh(), DofObject::id(), JumpErrorEstimator::initialize(), JumpErrorEstimator::integrate_boundary_sides, JumpErrorEstimator::internal_side_integration(), Elem::level(), MeshBase::max_elem_id(), mesh, MeshBase::mesh_dimension(), Elem::n_children(), Elem::n_neighbors(), System::n_vars(), n_vars, Elem::neighbor(), Elem::parent(), FEBase::qrule, ErrorEstimator::reduce_error(), JumpErrorEstimator::reinit_sides(), JumpErrorEstimator::scale_by_n_flux_faces, System::solution, NumericVector< T >::swap(), JumpErrorEstimator::Ucoarse, JumpErrorEstimator::Ufine, JumpErrorEstimator::var, DofMap::variable_type(), and SystemNorm::weight().
Referenced by Adaptive< T >::solve().
00056 { 00057 START_LOG("estimate_error()", "JumpErrorEstimator"); 00058 /* 00059 00060 Conventions for assigning the direction of the normal: 00061 00062 - e & f are global element ids 00063 00064 Case (1.) Elements are at the same level, e<f 00065 Compute the flux jump on the face and 00066 add it as a contribution to error_per_cell[e] 00067 and error_per_cell[f] 00068 00069 ---------------------- 00070 | | | 00071 | | f | 00072 | | | 00073 | e |---> n | 00074 | | | 00075 | | | 00076 ---------------------- 00077 00078 00079 Case (2.) The neighbor is at a higher level. 00080 Compute the flux jump on e's face and 00081 add it as a contribution to error_per_cell[e] 00082 and error_per_cell[f] 00083 00084 ---------------------- 00085 | | | | 00086 | | e |---> n | 00087 | | | | 00088 |-----------| f | 00089 | | | | 00090 | | | | 00091 | | | | 00092 ---------------------- 00093 */ 00094 00095 // The current mesh 00096 const MeshBase& mesh = system.get_mesh(); 00097 00098 // The dimensionality of the mesh 00099 const unsigned int dim = mesh.mesh_dimension(); 00100 00101 // The number of variables in the system 00102 const unsigned int n_vars = system.n_vars(); 00103 00104 // The DofMap for this system 00105 const DofMap& dof_map = system.get_dof_map(); 00106 00107 // Resize the error_per_cell vector to be 00108 // the number of elements, initialize it to 0. 00109 error_per_cell.resize (mesh.max_elem_id()); 00110 std::fill (error_per_cell.begin(), error_per_cell.end(), 0.); 00111 00112 // Declare a vector of floats which is as long as 00113 // error_per_cell above, and fill with zeros. This vector will be 00114 // used to keep track of the number of edges (faces) on each active 00115 // element which are either: 00116 // 1) an internal edge 00117 // 2) an edge on a Neumann boundary for which a boundary condition 00118 // function has been specified. 00119 // The error estimator can be scaled by the number of flux edges (faces) 00120 // which the element actually has to obtain a more uniform measure 00121 // of the error. Use floats instead of ints since in case 2 (above) 00122 // f gets 1/2 of a flux face contribution from each of his 00123 // neighbors 00124 std::vector<float> n_flux_faces (error_per_cell.size()); 00125 00126 // Prepare current_local_solution to localize a non-standard 00127 // solution vector if necessary 00128 if (solution_vector && solution_vector != system.solution.get()) 00129 { 00130 NumericVector<Number>* newsol = 00131 const_cast<NumericVector<Number>*>(solution_vector); 00132 System &sys = const_cast<System&>(system); 00133 newsol->swap(*sys.solution); 00134 sys.update(); 00135 } 00136 00137 // Loop over all the variables in the system 00138 for (var=0; var<n_vars; var++) 00139 { 00140 // Possibly skip this variable 00141 if (error_norm.weight(var) == 0.0) continue; 00142 00143 // The type of finite element to use for this variable 00144 const FEType& fe_type = dof_map.variable_type (var); 00145 00146 // Finite element objects for the same face from 00147 // different sides 00148 fe_fine = FEBase::build (dim, fe_type); 00149 fe_coarse = FEBase::build (dim, fe_type); 00150 00151 // Build an appropriate Gaussian quadrature rule 00152 QGauss qrule (dim-1, fe_type.default_quadrature_order()); 00153 00154 // Tell the finite element for the fine element about the quadrature 00155 // rule. The finite element for the coarse element need not know about it 00156 fe_fine->attach_quadrature_rule (&qrule); 00157 00158 // By convention we will always do the integration 00159 // on the face of element e. We'll need its Jacobian values and 00160 // physical point locations, at least 00161 fe_fine->get_JxW(); 00162 fe_fine->get_xyz(); 00163 00164 // Our derived classes may want to do some initialization here 00165 this->initialize(system, error_per_cell, estimate_parent_error); 00166 00167 // The global DOF indices for elements e & f 00168 std::vector<unsigned int> dof_indices_fine; 00169 std::vector<unsigned int> dof_indices_coarse; 00170 00171 00172 00173 // Iterate over all the active elements in the mesh 00174 // that live on this processor. 00175 MeshBase::const_element_iterator elem_it = mesh.active_local_elements_begin(); 00176 const MeshBase::const_element_iterator elem_end = mesh.active_local_elements_end(); 00177 00178 for (; elem_it != elem_end; ++elem_it) 00179 { 00180 // e is necessarily an active element on the local processor 00181 const Elem* e = *elem_it; 00182 const unsigned int e_id = e->id(); 00183 00184 #ifdef LIBMESH_ENABLE_AMR 00185 // See if the parent of element e has been examined yet; 00186 // if not, we may want to compute the estimator on it 00187 const Elem* parent = e->parent(); 00188 00189 // We only can compute and only need to compute on 00190 // parents with all active children 00191 bool compute_on_parent = true; 00192 if (!parent || !estimate_parent_error) 00193 compute_on_parent = false; 00194 else 00195 for (unsigned int c=0; c != parent->n_children(); ++c) 00196 if (!parent->child(c)->active()) 00197 compute_on_parent = false; 00198 00199 if (compute_on_parent && 00200 !error_per_cell[parent->id()]) 00201 { 00202 // Compute a projection onto the parent 00203 DenseVector<Number> Uparent; 00204 FEBase::coarsened_dof_values(*(system.solution), 00205 dof_map, parent, Uparent, 00206 var, false); 00207 00208 // Loop over the neighbors of the parent 00209 for (unsigned int n_p=0; n_p<parent->n_neighbors(); n_p++) 00210 { 00211 if (parent->neighbor(n_p) != NULL) // parent has a neighbor here 00212 { 00213 // Find the active neighbors in this direction 00214 std::vector<const Elem*> active_neighbors; 00215 parent->neighbor(n_p)-> 00216 active_family_tree_by_neighbor(active_neighbors, 00217 parent); 00218 // Compute the flux to each active neighbor 00219 for (unsigned int a=0; 00220 a != active_neighbors.size(); ++a) 00221 { 00222 const Elem *f = active_neighbors[a]; 00223 // FIXME - what about when f->level < 00224 // parent->level()?? 00225 if (f->level() >= parent->level()) 00226 { 00227 fine_elem = f; 00228 coarse_elem = parent; 00229 Ucoarse = Uparent; 00230 00231 dof_map.dof_indices (fine_elem, dof_indices_fine, var); 00232 const unsigned int n_dofs_fine = dof_indices_fine.size(); 00233 Ufine.resize(n_dofs_fine); 00234 00235 for (unsigned int i=0; i<n_dofs_fine; i++) 00236 Ufine(i) = system.current_solution(dof_indices_fine[i]); 00237 this->reinit_sides(); 00238 this->internal_side_integration(); 00239 00240 error_per_cell[fine_elem->id()] += fine_error; 00241 error_per_cell[coarse_elem->id()] += coarse_error; 00242 00243 // Keep track of the number of internal flux 00244 // sides found on each element 00245 n_flux_faces[fine_elem->id()]++; 00246 n_flux_faces[coarse_elem->id()] += this->coarse_n_flux_faces_increment(); 00247 } 00248 } 00249 } 00250 else if (integrate_boundary_sides) 00251 { 00252 fine_elem = parent; 00253 Ufine = Uparent; 00254 00255 // Reinitialize shape functions on the fine element side 00256 fe_fine->reinit (fine_elem, fine_side); 00257 00258 if (this->boundary_side_integration()) 00259 { 00260 error_per_cell[fine_elem->id()] += fine_error; 00261 n_flux_faces[fine_elem->id()]++; 00262 } 00263 } 00264 } 00265 } 00266 #endif // #ifdef LIBMESH_ENABLE_AMR 00267 00268 // If we do any more flux integration, e will be the fine element 00269 fine_elem = e; 00270 00271 // Loop over the neighbors of element e 00272 for (unsigned int n_e=0; n_e<e->n_neighbors(); n_e++) 00273 { 00274 fine_side = n_e; 00275 00276 if (e->neighbor(n_e) != NULL) // e is not on the boundary 00277 { 00278 const Elem* f = e->neighbor(n_e); 00279 const unsigned int f_id = f->id(); 00280 00281 // Compute flux jumps if we are in case 1 or case 2. 00282 if ((f->active() && (f->level() == e->level()) && (e_id < f_id)) 00283 || (f->level() < e->level())) 00284 { 00285 // f is now the coarse element 00286 coarse_elem = f; 00287 00288 // Get the DOF indices for the two elements 00289 dof_map.dof_indices (fine_elem, dof_indices_fine, var); 00290 dof_map.dof_indices (coarse_elem, dof_indices_coarse, var); 00291 00292 // The number of DOFS on each element 00293 const unsigned int n_dofs_fine = dof_indices_fine.size(); 00294 const unsigned int n_dofs_coarse = dof_indices_coarse.size(); 00295 Ufine.resize(n_dofs_fine); 00296 Ucoarse.resize(n_dofs_coarse); 00297 00298 // The local solutions on each element 00299 for (unsigned int i=0; i<n_dofs_fine; i++) 00300 Ufine(i) = system.current_solution(dof_indices_fine[i]); 00301 for (unsigned int i=0; i<n_dofs_coarse; i++) 00302 Ucoarse(i) = system.current_solution(dof_indices_coarse[i]); 00303 00304 this->reinit_sides(); 00305 this->internal_side_integration(); 00306 00307 error_per_cell[fine_elem->id()] += fine_error; 00308 error_per_cell[coarse_elem->id()] += coarse_error; 00309 00310 // Keep track of the number of internal flux 00311 // sides found on each element 00312 n_flux_faces[fine_elem->id()]++; 00313 n_flux_faces[coarse_elem->id()] += this->coarse_n_flux_faces_increment(); 00314 } // end if (case1 || case2) 00315 } // if (e->neigbor(n_e) != NULL) 00316 00317 // Otherwise, e is on the boundary. If it happens to 00318 // be on a Dirichlet boundary, we need not do anything. 00319 // On the other hand, if e is on a Neumann (flux) boundary 00320 // with grad(u).n = g, we need to compute the additional residual 00321 // (h * \int |g - grad(u_h).n|^2 dS)^(1/2). 00322 // We can only do this with some knowledge of the boundary 00323 // conditions, i.e. the user must have attached an appropriate 00324 // BC function. 00325 else 00326 { 00327 if (integrate_boundary_sides) 00328 { 00329 // Reinitialize shape functions on the fine element side 00330 fe_fine->reinit (fine_elem, fine_side); 00331 00332 // Get the DOF indices 00333 dof_map.dof_indices (fine_elem, dof_indices_fine, var); 00334 00335 // The number of DOFS on each element 00336 const unsigned int n_dofs_fine = dof_indices_fine.size(); 00337 Ufine.resize(n_dofs_fine); 00338 00339 for (unsigned int i=0; i<n_dofs_fine; i++) 00340 Ufine(i) = system.current_solution(dof_indices_fine[i]); 00341 00342 if (this->boundary_side_integration()) 00343 { 00344 error_per_cell[fine_elem->id()] += fine_error; 00345 n_flux_faces[fine_elem->id()]++; 00346 } 00347 } // end if _bc_function != NULL 00348 } // end if (e->neighbor(n_e) == NULL) 00349 } // end loop over neighbors 00350 } // End loop over active local elements 00351 } // End loop over variables 00352 00353 00354 00355 // Each processor has now computed the error contribuions 00356 // for its local elements. We need to sum the vector 00357 // and then take the square-root of each component. Note 00358 // that we only need to sum if we are running on multiple 00359 // processors, and we only need to take the square-root 00360 // if the value is nonzero. There will in general be many 00361 // zeros for the inactive elements. 00362 00363 // First sum the vector of estimated error values 00364 this->reduce_error(error_per_cell); 00365 00366 // Compute the square-root of each component. 00367 for (unsigned int i=0; i<error_per_cell.size(); i++) 00368 if (error_per_cell[i] != 0.) 00369 error_per_cell[i] = std::sqrt(error_per_cell[i]); 00370 00371 00372 if (this->scale_by_n_flux_faces) 00373 { 00374 // Sum the vector of flux face counts 00375 this->reduce_error(n_flux_faces); 00376 00377 // Sanity check: Make sure the number of flux faces is 00378 // always an integer value 00379 #ifdef DEBUG 00380 for (unsigned int i=0; i<n_flux_faces.size(); ++i) 00381 libmesh_assert (n_flux_faces[i] == static_cast<float>(static_cast<unsigned int>(n_flux_faces[i])) ); 00382 #endif 00383 00384 // Scale the error by the number of flux faces for each element 00385 for (unsigned int i=0; i<n_flux_faces.size(); ++i) 00386 { 00387 if (n_flux_faces[i] == 0.0) // inactive or non-local element 00388 continue; 00389 00390 //std::cout << "Element " << i << " has " << n_flux_faces[i] << " flux faces." << std::endl; 00391 error_per_cell[i] /= static_cast<Real>(n_flux_faces[i]); 00392 } 00393 } 00394 00395 // If we used a non-standard solution before, now is the time to fix 00396 // the current_local_solution 00397 if (solution_vector && solution_vector != system.solution.get()) 00398 { 00399 NumericVector<Number>* newsol = 00400 const_cast<NumericVector<Number>*>(solution_vector); 00401 System &sys = const_cast<System&>(system); 00402 newsol->swap(*sys.solution); 00403 sys.update(); 00404 } 00405 00406 STOP_LOG("estimate_error()", "JumpErrorEstimator"); 00407 }
| 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 }
| void DiscontinuityMeasure::initialize | ( | const System & | system, | |
| ErrorVector & | error_per_cell, | |||
| bool | estimate_parent_error | |||
| ) | [protected, virtual] |
An initialization function, for requesting specific data from the FE objects
Reimplemented from JumpErrorEstimator.
Definition at line 41 of file discontinuity_measure.C.
References JumpErrorEstimator::fe_coarse, JumpErrorEstimator::fe_fine, and my_system.
00044 { 00045 // Hang onto the system - we may need it for variable names later. 00046 my_system = &system; 00047 00048 // We'll need values for jump computation 00049 fe_fine->get_phi(); 00050 fe_coarse->get_phi(); 00051 }
| void DiscontinuityMeasure::internal_side_integration | ( | ) | [protected, virtual] |
The function which calculates a normal derivative jump based error term on an internal side
Implements JumpErrorEstimator.
Definition at line 56 of file discontinuity_measure.C.
References JumpErrorEstimator::coarse_elem, JumpErrorEstimator::coarse_error, ErrorEstimator::error_norm, JumpErrorEstimator::fe_coarse, JumpErrorEstimator::fe_fine, JumpErrorEstimator::fine_elem, JumpErrorEstimator::fine_error, Elem::hmax(), libmesh_norm(), JumpErrorEstimator::Ucoarse, JumpErrorEstimator::Ufine, JumpErrorEstimator::var, and SystemNorm::weight().
00057 { 00058 Real error = 1.e-30; 00059 unsigned int n_qp = fe_fine->n_quadrature_points(); 00060 unsigned int n_fine_dofs = Ufine.size(); 00061 unsigned int n_coarse_dofs = Ucoarse.size(); 00062 00063 std::vector<std::vector<Real> > phi_coarse = fe_coarse->get_phi(); 00064 std::vector<std::vector<Real> > phi_fine = fe_fine->get_phi(); 00065 std::vector<Real> JxW_face = fe_fine->get_JxW(); 00066 00067 for (unsigned int qp=0; qp != n_qp; ++qp) 00068 { 00069 // Calculate solution values on fine and coarse elements 00070 // at this quadrature point 00071 Number u_fine = 0., u_coarse = 0.; 00072 for (unsigned int i=0; i != n_coarse_dofs; ++i) 00073 u_coarse += phi_coarse[i][qp] * Ucoarse(i); 00074 00075 for (unsigned int i=0; i != n_fine_dofs; ++i) 00076 u_fine += phi_fine[i][qp] * Ufine(i); 00077 00078 // Find the jump in the value 00079 // at this quadrature point 00080 const Number jump = u_fine - u_coarse; 00081 const Real jump2 = libmesh_norm(jump); 00082 // Accumulate the jump integral 00083 error += JxW_face[qp] * jump2; 00084 } 00085 00086 // Add the h-weighted jump integral to each error term 00087 fine_error = 00088 error * fine_elem->hmax() * error_norm.weight(var); 00089 coarse_error = 00090 error * coarse_elem->hmax() * error_norm.weight(var); 00091 }
| 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().
| void JumpErrorEstimator::reinit_sides | ( | ) | [protected, inherited] |
A utility function to reinit the finite element data on elements sharing a side
Definition at line 412 of file jump_error_estimator.C.
References JumpErrorEstimator::coarse_elem, Elem::dim(), JumpErrorEstimator::fe_coarse, JumpErrorEstimator::fe_fine, JumpErrorEstimator::fine_elem, JumpErrorEstimator::fine_side, and InfFE< Dim, T_radial, T_map >::inverse_map().
Referenced by JumpErrorEstimator::estimate_error().
00413 { 00414 // The master quadrature point locations on the coarse element 00415 std::vector<Point> qp_coarse; 00416 00417 // Reinitialize shape functions on the fine element side 00418 fe_fine->reinit (fine_elem, fine_side); 00419 00420 // Get the physical locations of the fine element quadrature points 00421 std::vector<Point> qface_point = fe_fine->get_xyz(); 00422 00423 // Find their locations on the coarse element 00424 FEInterface::inverse_map (coarse_elem->dim(), fe_coarse->get_fe_type(), 00425 coarse_elem, qface_point, qp_coarse); 00426 00427 // Calculate the coarse element shape functions at those locations 00428 fe_coarse->reinit (coarse_elem, &qp_coarse); 00429 }
Member Data Documentation
std::pair<bool,Real>(* DiscontinuityMeasure::_bc_function)(const System &system, const Point &p, const std::string &var_name) [protected] |
Pointer to function that returns BC information.
Referenced by boundary_side_integration().
const Elem * JumpErrorEstimator::coarse_elem [protected, inherited] |
Definition at line 130 of file jump_error_estimator.h.
Referenced by JumpErrorEstimator::coarse_n_flux_faces_increment(), JumpErrorEstimator::estimate_error(), KellyErrorEstimator::internal_side_integration(), LaplacianErrorEstimator::internal_side_integration(), internal_side_integration(), and JumpErrorEstimator::reinit_sides().
Real JumpErrorEstimator::coarse_error [protected, inherited] |
Definition at line 135 of file jump_error_estimator.h.
Referenced by JumpErrorEstimator::estimate_error(), KellyErrorEstimator::internal_side_integration(), LaplacianErrorEstimator::internal_side_integration(), and internal_side_integration().
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(), boundary_side_integration(), DiscontinuityMeasure(), JumpErrorEstimator::estimate_error(), ErrorEstimator::estimate_errors(), ExactErrorEstimator::ExactErrorEstimator(), ExactErrorEstimator::find_squared_element_error(), KellyErrorEstimator::internal_side_integration(), LaplacianErrorEstimator::internal_side_integration(), internal_side_integration(), KellyErrorEstimator::KellyErrorEstimator(), LaplacianErrorEstimator::LaplacianErrorEstimator(), PatchRecoveryErrorEstimator::EstimateError::operator()(), PatchRecoveryErrorEstimator::PatchRecoveryErrorEstimator(), and UniformRefinementEstimator::UniformRefinementEstimator().
AutoPtr<FEBase> JumpErrorEstimator::fe_coarse [protected, inherited] |
Definition at line 155 of file jump_error_estimator.h.
Referenced by JumpErrorEstimator::estimate_error(), KellyErrorEstimator::initialize(), LaplacianErrorEstimator::initialize(), initialize(), KellyErrorEstimator::internal_side_integration(), LaplacianErrorEstimator::internal_side_integration(), internal_side_integration(), and JumpErrorEstimator::reinit_sides().
AutoPtr<FEBase> JumpErrorEstimator::fe_fine [protected, inherited] |
The finite element objects for fine and coarse elements
Definition at line 155 of file jump_error_estimator.h.
Referenced by KellyErrorEstimator::boundary_side_integration(), boundary_side_integration(), JumpErrorEstimator::estimate_error(), KellyErrorEstimator::initialize(), LaplacianErrorEstimator::initialize(), initialize(), KellyErrorEstimator::internal_side_integration(), LaplacianErrorEstimator::internal_side_integration(), internal_side_integration(), and JumpErrorEstimator::reinit_sides().
const Elem* JumpErrorEstimator::fine_elem [protected, inherited] |
The fine and coarse elements sharing a face
Definition at line 130 of file jump_error_estimator.h.
Referenced by KellyErrorEstimator::boundary_side_integration(), boundary_side_integration(), JumpErrorEstimator::coarse_n_flux_faces_increment(), JumpErrorEstimator::estimate_error(), KellyErrorEstimator::internal_side_integration(), LaplacianErrorEstimator::internal_side_integration(), internal_side_integration(), and JumpErrorEstimator::reinit_sides().
Real JumpErrorEstimator::fine_error [protected, inherited] |
The fine and coarse error values to be set by each side_integration();
Definition at line 135 of file jump_error_estimator.h.
Referenced by KellyErrorEstimator::boundary_side_integration(), boundary_side_integration(), JumpErrorEstimator::estimate_error(), KellyErrorEstimator::internal_side_integration(), LaplacianErrorEstimator::internal_side_integration(), and internal_side_integration().
unsigned int JumpErrorEstimator::fine_side [protected, inherited] |
Which side of the fine element is this?
Definition at line 140 of file jump_error_estimator.h.
Referenced by JumpErrorEstimator::estimate_error(), and JumpErrorEstimator::reinit_sides().
bool JumpErrorEstimator::integrate_boundary_sides [protected, inherited] |
A boolean flag, by default false, to be set to true if integrations with boundary_side_integration() should be performed
Definition at line 125 of file jump_error_estimator.h.
Referenced by KellyErrorEstimator::attach_flux_bc_function(), and JumpErrorEstimator::estimate_error().
const System* DiscontinuityMeasure::my_system [protected] |
A pointer to the current System
Definition at line 96 of file discontinuity_measure.h.
Referenced by boundary_side_integration(), and initialize().
bool JumpErrorEstimator::scale_by_n_flux_faces [inherited] |
This boolean flag allows you to scale the error indicator result for each element by the number of "flux faces" the element actually has. This tends to weight more evenly cells which are on the boundaries and thus have fewer contributions to their flux. The value is initialized to false, simply set it to true if you want to use the feature.
Definition at line 86 of file jump_error_estimator.h.
Referenced by JumpErrorEstimator::estimate_error().
DenseVector<Number> JumpErrorEstimator::Ucoarse [protected, inherited] |
Definition at line 150 of file jump_error_estimator.h.
Referenced by JumpErrorEstimator::estimate_error(), KellyErrorEstimator::internal_side_integration(), LaplacianErrorEstimator::internal_side_integration(), and internal_side_integration().
DenseVector<Number> JumpErrorEstimator::Ufine [protected, inherited] |
The local degree of freedom values on fine and coarse elements
Definition at line 150 of file jump_error_estimator.h.
Referenced by KellyErrorEstimator::boundary_side_integration(), boundary_side_integration(), JumpErrorEstimator::estimate_error(), KellyErrorEstimator::internal_side_integration(), LaplacianErrorEstimator::internal_side_integration(), and internal_side_integration().
unsigned int JumpErrorEstimator::var [protected, inherited] |
The variable number currently being evaluated
Definition at line 145 of file jump_error_estimator.h.
Referenced by KellyErrorEstimator::boundary_side_integration(), boundary_side_integration(), JumpErrorEstimator::estimate_error(), KellyErrorEstimator::internal_side_integration(), LaplacianErrorEstimator::internal_side_integration(), and internal_side_integration().
The documentation for this class was generated from the following files: