void MeshRefinement::flag_elements_by_error_tolerance (const ErrorVector & error_per_cell_in) { parallel_object_only(); libmesh_assert_greater (_coarsen_threshold, 0); // Check for valid fractions.. // The fraction values must be in [0,1] libmesh_assert_greater_equal (_refine_fraction, 0); libmesh_assert_less_equal (_refine_fraction, 1); libmesh_assert_greater_equal (_coarsen_fraction, 0); libmesh_assert_less_equal (_coarsen_fraction, 1); // How much error per cell will we tolerate? const Real local_refinement_tolerance = _absolute_global_tolerance / std::sqrt(static_cast<Real>(_mesh.n_active_elem())); const Real local_coarsening_tolerance = local_refinement_tolerance * _coarsen_threshold; // Prepare another error vector if we need to sum parent errors ErrorVector error_per_parent; if (_coarsen_by_parents) { Real parent_error_min, parent_error_max; create_parent_error_vector(error_per_cell_in, error_per_parent, parent_error_min, parent_error_max); } for (auto & elem : _mesh.active_element_ptr_range()) { Elem * parent = elem->parent(); const dof_id_type elem_number = elem->id(); const ErrorVectorReal elem_error = error_per_cell_in[elem_number]; if (elem_error > local_refinement_tolerance && elem->level() < _max_h_level) elem->set_refinement_flag(Elem::REFINE); if (!_coarsen_by_parents && elem_error < local_coarsening_tolerance) elem->set_refinement_flag(Elem::COARSEN); if (_coarsen_by_parents && parent) { ErrorVectorReal parent_error = error_per_parent[parent->id()]; if (parent_error >= 0.) { const Real parent_coarsening_tolerance = std::sqrt(parent->n_children() * local_coarsening_tolerance * local_coarsening_tolerance); if (parent_error < parent_coarsening_tolerance) elem->set_refinement_flag(Elem::COARSEN); } } } }
void TransientSystem<Base>::re_update () { // re_update the parent system Base::re_update (); const std::vector<dof_id_type>& send_list = this->get_dof_map().get_send_list (); const dof_id_type first_local_dof = Base::get_dof_map().first_dof(); const dof_id_type end_local_dof = Base::get_dof_map().end_dof(); // Check sizes libmesh_assert_greater_equal (end_local_dof, first_local_dof); libmesh_assert_greater_equal (older_local_solution->size(), send_list.size()); libmesh_assert_greater_equal (old_local_solution->size(), send_list.size()); // Even if we don't have to do anything ourselves, localize() may // use parallel_only tools // if (first_local_dof == end_local_dof) // return; // Update the old & older solutions with the send_list, // which may have changed since their last update. older_local_solution->localize (first_local_dof, end_local_dof-1, send_list); old_local_solution->localize (first_local_dof, end_local_dof-1, send_list); }
void MeshRefinement::flag_elements_by_mean_stddev (const ErrorVector & error_per_cell, const Real refine_frac, const Real coarsen_frac, const unsigned int max_l) { // The function arguments are currently just there for // backwards_compatibility if (!_use_member_parameters) { // If the user used non-default parameters, lets warn // that they're deprecated if (refine_frac != 0.3 || coarsen_frac != 0.0 || max_l != libMesh::invalid_uint) libmesh_deprecated(); _refine_fraction = refine_frac; _coarsen_fraction = coarsen_frac; _max_h_level = max_l; } // Get the mean value from the error vector const Real mean = error_per_cell.mean(); // Get the standard deviation. This equals the // square-root of the variance const Real stddev = std::sqrt (error_per_cell.variance()); // Check for valid fractions libmesh_assert_greater_equal (_refine_fraction, 0); libmesh_assert_less_equal (_refine_fraction, 1); libmesh_assert_greater_equal (_coarsen_fraction, 0); libmesh_assert_less_equal (_coarsen_fraction, 1); // The refine and coarsen cutoff const Real refine_cutoff = mean + _refine_fraction * stddev; const Real coarsen_cutoff = std::max(mean - _coarsen_fraction * stddev, 0.); // Loop over the elements and flag them for coarsening or // refinement based on the element error for (auto & elem : _mesh.active_element_ptr_range()) { const dof_id_type id = elem->id(); libmesh_assert_less (id, error_per_cell.size()); const ErrorVectorReal elem_error = error_per_cell[id]; // Possibly flag the element for coarsening ... if (elem_error <= coarsen_cutoff) elem->set_refinement_flag(Elem::COARSEN); // ... or refinement if ((elem_error >= refine_cutoff) && (elem->level() < _max_h_level)) elem->set_refinement_flag(Elem::REFINE); } }
// Builds and scales a Gauss rule and a Jacobi rule. // Then combines them to compute points and weights // of a 3D conical product rule for the Tet. void QConical::conical_product_tet(unsigned int p) { // Be sure the underlying rule object was built with the same dimension as the // rule we are about to construct. libmesh_assert_equal_to (this->get_dim(), 3); QGauss gauss1D(1,static_cast<Order>(_order+2*p)); QJacobi jacA1D(1,static_cast<Order>(_order+2*p),1,0); QJacobi jacB1D(1,static_cast<Order>(_order+2*p),2,0); // The Gauss rule needs to be scaled to [0,1] std::pair<Real, Real> old_range(-1.0L, 1.0L); std::pair<Real, Real> new_range( 0.0L, 1.0L); gauss1D.scale(old_range, new_range); // Now construct the points and weights for the conical product rule. // All rules should have the same number of points libmesh_assert_equal_to (gauss1D.n_points(), jacA1D.n_points()); libmesh_assert_equal_to (jacA1D.n_points(), jacB1D.n_points()); // Save the number of points as a convenient variable const unsigned int np = gauss1D.n_points(); // All rules should be between x=0 and x=1 libmesh_assert_greater_equal (gauss1D.qp(0)(0), 0.0); libmesh_assert_less_equal (gauss1D.qp(np-1)(0), 1.0); libmesh_assert_greater_equal (jacA1D.qp(0)(0), 0.0); libmesh_assert_less_equal (jacA1D.qp(np-1)(0), 1.0); libmesh_assert_greater_equal (jacB1D.qp(0)(0), 0.0); libmesh_assert_less_equal (jacB1D.qp(np-1)(0), 1.0); // Resize the points and weights vectors _points.resize(np * np * np); _weights.resize(np * np * np); // Compute the conical product unsigned int gp = 0; for (unsigned int i=0; i<np; i++) for (unsigned int j=0; j<np; j++) for (unsigned int k=0; k<np; k++) { _points[gp](0) = jacB1D.qp(k)(0); //t[k]; _points[gp](1) = jacA1D.qp(j)(0) * (1.-jacB1D.qp(k)(0)); //s[j]*(1.-t[k]); _points[gp](2) = gauss1D.qp(i)(0) * (1.-jacA1D.qp(j)(0)) * (1.-jacB1D.qp(k)(0)); //r[i]*(1.-s[j])*(1.-t[k]); _weights[gp] = gauss1D.w(i) * jacA1D.w(j) * jacB1D.w(k); //A[i]*B[j]*C[k]; gp++; } }
unsigned int packed_size (const Elem*, std::vector<largest_id_type>::const_iterator in) { #ifndef NDEBUG const largest_id_type packed_header = *in++; libmesh_assert_equal_to (packed_header, elem_magic_header); #endif // int 0: level const unsigned int level = static_cast<unsigned int>(*in); // int 4: element type const int typeint = *(in+4); libmesh_assert_greater_equal (typeint, 0); libmesh_assert_less (typeint, INVALID_ELEM); const ElemType type = static_cast<ElemType>(typeint); const unsigned int n_nodes = Elem::type_to_n_nodes_map[type]; const unsigned int n_sides = Elem::type_to_n_sides_map[type]; const unsigned int pre_indexing_size = header_size + n_nodes + n_sides; const unsigned int indexing_size = DofObject::unpackable_indexing_size(in+pre_indexing_size); unsigned int total_packed_bc_data = 0; if (level == 0) { for (unsigned int s = 0; s != n_sides; ++s) { const int n_bcs = *(in + pre_indexing_size + indexing_size + total_packed_bc_data++); libmesh_assert_greater_equal (n_bcs, 0); total_packed_bc_data += n_bcs; } } return #ifndef NDEBUG 1 + // Account for magic header #endif pre_indexing_size + indexing_size + total_packed_bc_data; }
// ------------------------------------------------------------ // MeshBase class member functions MeshBase::MeshBase (const Parallel::Communicator & comm_in, unsigned char d) : ParallelObject (comm_in), boundary_info (new BoundaryInfo(*this)), _n_parts (1), _is_prepared (false), _point_locator (), _count_lower_dim_elems_in_point_locator(true), _partitioner (), #ifdef LIBMESH_ENABLE_UNIQUE_ID _next_unique_id(DofObject::invalid_unique_id), #endif _skip_noncritical_partitioning(false), _skip_all_partitioning(libMesh::on_command_line("--skip-partitioning")), _skip_renumber_nodes_and_elements(false), _allow_remote_element_removal(true), _spatial_dimension(d), _default_ghosting(new GhostPointNeighbors(*this)), _point_locator_close_to_point_tol(0.) { _elem_dims.insert(d); _ghosting_functors.insert(_default_ghosting.get()); libmesh_assert_less_equal (LIBMESH_DIM, 3); libmesh_assert_greater_equal (LIBMESH_DIM, d); libmesh_assert (libMesh::initialized()); }
unsigned short int InfHex18::second_order_adjacent_vertex (const unsigned int n, const unsigned int v) const { libmesh_assert_greater_equal (n, this->n_vertices()); libmesh_assert_less (n, this->n_nodes()); libmesh_assert_less (v, this->n_second_order_adjacent_vertices(n)); if (n == 16) /* * for the bubble node in the base the return value is * simply v. Why? -- the user asks for the v-th * adjacent vertex, from \p n_second_order_adjacent_vertices() * there are 4 adjacent vertices, and these happen to be * 0..3 */ return static_cast<unsigned short int>(v); else if (n == 17) /* * for the bubble node further out similar reasoning works, * but v must be shifted to the further-out nodes: * simply add 4 */ return static_cast<unsigned short int>(v+4); else /* * all others are stored in the vertices matrix -- note * that this matrix is kept in \p InfHex to foster * code-reuse */ return _second_order_adjacent_vertices[n-this->n_vertices()][v]; }
T EpetraMatrix<T>::operator () (const numeric_index_type i, const numeric_index_type j) const { libmesh_assert (this->initialized()); libmesh_assert(this->_mat); libmesh_assert (this->_mat->MyGlobalRow(static_cast<int>(i))); libmesh_assert_greater_equal (i, this->row_start()); libmesh_assert_less (i, this->row_stop()); int row_length, *row_indices; double *values; _mat->ExtractMyRowView (i-this->row_start(), row_length, values, row_indices); //libMesh::out << "row_length=" << row_length << std::endl; int *index = std::lower_bound (row_indices, row_indices+row_length, j); libmesh_assert_less (*index, row_length); libmesh_assert_equal_to (static_cast<numeric_index_type>(row_indices[*index]), j); //libMesh::out << "val=" << values[*index] << std::endl; return values[*index]; }
unsigned short int InfQuad6::second_order_adjacent_vertex (const unsigned int n, const unsigned int v) const { libmesh_assert_greater_equal (n, this->n_vertices()); libmesh_assert_less (n, this->n_nodes()); libmesh_assert_less (v, 2); return _second_order_adjacent_vertices[n-this->n_vertices()][v]; }
unsigned short int Quad8::second_order_adjacent_vertex (const unsigned int n, const unsigned int v) const { libmesh_assert_greater_equal (n, this->n_vertices()); libmesh_assert_less (n, this->n_nodes()); libmesh_assert_less (v, 2); // use the matrix from \p face_quad.C return _second_order_adjacent_vertices[n-this->n_vertices()][v]; }
std::pair<unsigned short int, unsigned short int> Tet10::second_order_child_vertex (const unsigned int n) const { libmesh_assert_greater_equal (n, this->n_vertices()); libmesh_assert_less (n, this->n_nodes()); return std::pair<unsigned short int, unsigned short int> (_second_order_vertex_child_number[n], _second_order_vertex_child_index[n]); }
std::pair<unsigned short int, unsigned short int> InfQuad6::second_order_child_vertex (const unsigned int n) const { libmesh_assert_greater_equal (n, this->n_vertices()); libmesh_assert_less (n, this->n_nodes()); return std::pair<unsigned short int, unsigned short int> (0, 2*n-7); }
unsigned short int Pyramid14::second_order_adjacent_vertex (const unsigned int n, const unsigned int v) const { libmesh_assert_greater_equal (n, this->n_vertices()); libmesh_assert_less (n, this->n_nodes()); switch (n) { case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: { libmesh_assert_less (v, 2); // This is the analog of the static, const arrays // {Hex,Prism,Tet10}::_second_order_adjacent_vertices // defined in the respective source files... possibly treat // this similarly once the Pyramid13 has been added? unsigned short node_list[8][2] = { {0,1}, {1,2}, {2,3}, {0,3}, {0,4}, {1,4}, {2,4}, {3,4} }; return node_list[n-5][v]; } // mid-face node on bottom case 13: { libmesh_assert_less (v, 4); // The vertex nodes surrounding node 13 are 0, 1, 2, and 3. // Thus, the v'th node is simply = v. return cast_int<unsigned short>(v); } default: libmesh_error_msg("Invalid n = " << n); } libmesh_error_msg("We'll never get here!"); return static_cast<unsigned short int>(-1); }
unsigned short int InfHex16::second_order_adjacent_vertex (const unsigned int n, const unsigned int v) const { libmesh_assert_greater_equal (n, this->n_vertices()); libmesh_assert_less (n, this->n_nodes()); libmesh_assert_less (v, 2); // note that the _second_order_adjacent_vertices matrix is // stored in \p InfHex return _second_order_adjacent_vertices[n-this->n_vertices()][v]; }
void Runner::check_for_unused_vars( const GetPot& input, bool warning_only ) { /* Everything should be set up now, so check if there's any unused variables in the input file. If so, then tell the user what they were and error out. */ std::vector<std::string> unused_vars = input.unidentified_variables(); bool unused_vars_detected = false; // String we use to check if there is a variable in the Materials section std::string mat_string = "Materials/"; // If we do have unused variables, make sure they are in the Materials // section since we're allowing those to be present and not used. if( !unused_vars.empty() ) { int n_total = unused_vars.size(); int n_mats = 0; for( int v = 0; v < n_total; v++ ) if( (unused_vars[v]).find(mat_string) != std::string::npos ) n_mats += 1; libmesh_assert_greater_equal( n_total, n_mats ); if( n_mats < n_total ) unused_vars_detected = true; } if( unused_vars_detected ) { libMesh::err << "==========================================================" << std::endl; if( warning_only ) libMesh::err << "Warning: "; else libMesh::err << "Error: "; libMesh::err << "Found unused variables!" << std::endl; for( std::vector<std::string>::const_iterator it = unused_vars.begin(); it != unused_vars.end(); ++it ) { // Don't print out any unused Material variables, since we allow these if( (*it).find(mat_string) != std::string::npos ) continue; libMesh::err << *it << std::endl; } libMesh::err << "==========================================================" << std::endl; if( !warning_only ) libmesh_error(); } }
// ------------------------------------------------------------ // ErrorVector class member functions ErrorVectorReal ErrorVector::minimum() const { LOG_SCOPE ("minimum()", "ErrorVector"); const dof_id_type n = cast_int<dof_id_type>(this->size()); ErrorVectorReal min = std::numeric_limits<ErrorVectorReal>::max(); for (dof_id_type i=0; i<n; i++) { // Only positive (or zero) values in the error vector libmesh_assert_greater_equal ((*this)[i], 0.); if (this->is_active_elem(i)) min = std::min (min, (*this)[i]); } // ErrorVectors are for positive values libmesh_assert_greater_equal (min, 0.); return min; }
// ------------------------------------------------------------ // ErrorVector class member functions ErrorVectorReal ErrorVector::minimum() const { START_LOG ("minimum()", "ErrorVector"); const unsigned int n = this->size(); ErrorVectorReal min = std::numeric_limits<ErrorVectorReal>::max(); for (unsigned int i=0; i<n; i++) { // Only positive (or zero) values in the error vector libmesh_assert_greater_equal ((*this)[i], 0.); if (this->is_active_elem(i)) min = std::min (min, (*this)[i]); } STOP_LOG ("minimum()", "ErrorVector"); // ErrorVectors are for positive values libmesh_assert_greater_equal (min, 0.); return min; }
void MAST::Examples::ExampleBase::update_load_parameters(Real scale) { libmesh_assert_greater_equal(scale, 0.); libmesh_assert_less_equal (scale, 1.); std::map<MAST::Parameter*, const Real>::iterator it = _load_parameters.begin(), end = _load_parameters.end(); for ( ; it != end; it++) (*it->first) = scale*it->second; }
// ------------------------------------------------------------ // MeshBase class member functions MeshBase::MeshBase (unsigned int d) : boundary_info (new BoundaryInfo(*this)), _n_parts (1), _dim (d), _is_prepared (false), _point_locator (NULL), _partitioner (NULL), _skip_partitioning(false), _skip_renumber_nodes_and_elements(false) { libmesh_assert_less_equal (LIBMESH_DIM, 3); libmesh_assert_greater_equal (LIBMESH_DIM, _dim); libmesh_assert (libMesh::initialized()); }
std::pair<unsigned short int, unsigned short int> Quad8::second_order_child_vertex (const unsigned int n) const { libmesh_assert_greater_equal (n, this->n_vertices()); libmesh_assert_less (n, this->n_nodes()); /* * the _second_order_vertex_child_* vectors are * stored in face_quad.C, since they are identical * for Quad8 and Quad9 (for the first 4 higher-order nodes) */ return std::pair<unsigned short int, unsigned short int> (_second_order_vertex_child_number[n], _second_order_vertex_child_index[n]); }
std::pair<unsigned short int, unsigned short int> InfHex18::second_order_child_vertex (const unsigned int n) const { libmesh_assert_greater_equal (n, this->n_vertices()); libmesh_assert_less (n, this->n_nodes()); /* * the _second_order_vertex_child_* vectors are * stored in cell_inf_hex.C, since they are identical * for InfHex16 and InfHex18 */ return std::pair<unsigned short int, unsigned short int> (_second_order_vertex_child_number[n], _second_order_vertex_child_index[n]); }
Real SystemNorm::calculate_norm(const std::vector<Real> & v1, const std::vector<Real> & v2) { // The vectors are assumed to both be vectors of the (same number // of) components std::size_t vsize = v1.size(); libmesh_assert_equal_to (vsize, v2.size()); // We'll support implicitly defining weights, but if the user sets // more weights than he uses then something's probably wrong std::size_t diagsize = this->_weights.size(); libmesh_assert_greater_equal (vsize, diagsize); // Initialize the variable val Real val = 0.; // Loop over all the components of the system with explicit // weights for (std::size_t i = 0; i != diagsize; i++) { val += this->_weights[i] * v1[i] * v2[i]; } // Loop over all the components of the system with implicit // weights for (std::size_t i = diagsize; i < vsize; i++) { val += v1[i] * v2[i]; } // Loop over the components of the system std::size_t nrows = this->_off_diagonal_weights.size(); libmesh_assert_less_equal (vsize, nrows); for (std::size_t i = 0; i != nrows; i++) { std::size_t ncols = this->_off_diagonal_weights[i].size(); for (std::size_t j=0; j != ncols; j++) { // The diagonal weights here were set to zero in the // constructor. val += this->_off_diagonal_weights[i][j] * v1[i] * v2[j]; } } return(val); }
unsigned short int Pyramid13::second_order_adjacent_vertex (const unsigned int n, const unsigned int v) const { libmesh_assert_greater_equal (n, this->n_vertices()); libmesh_assert_less (n, this->n_nodes()); switch (n) { case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: { libmesh_assert_less (v, 2); // This is the analog of the static, const arrays // {Hex,Prism,Tet10}::_second_order_adjacent_vertices // defined in the respective source files... unsigned short node_list[8][2] = { {0,1}, {1,2}, {2,3}, {0,3}, {0,4}, {1,4}, {2,4}, {3,4} }; return node_list[n-5][v]; } default: libmesh_error_msg("Invalid n = " << n); } libmesh_error_msg("We'll never get here!"); return static_cast<unsigned short int>(-1); }
unsigned int packed_size (const Node*, const std::vector<largest_id_type>::const_iterator in) { const unsigned int pre_indexing_size = #ifndef NDEBUG 1 + // add an int for the magic header when testing #endif header_size + LIBMESH_DIM*idtypes_per_Real; const unsigned int indexing_size = DofObject::unpackable_indexing_size(in+pre_indexing_size); const int n_bcs = *(in + pre_indexing_size + indexing_size); libmesh_assert_greater_equal (n_bcs, 0); return pre_indexing_size + indexing_size + 1 + n_bcs; }
MeshBase::MeshBase (unsigned char d) : ParallelObject (CommWorld), boundary_info (new BoundaryInfo(*this)), _n_parts (1), _is_prepared (false), _point_locator (), _partitioner (), #ifdef LIBMESH_ENABLE_UNIQUE_ID _next_unique_id(DofObject::invalid_unique_id), #endif _skip_partitioning(libMesh::on_command_line("--skip-partitioning")), _skip_renumber_nodes_and_elements(false) { _elem_dims.insert(d); libmesh_assert_less_equal (LIBMESH_DIM, 3); libmesh_assert_greater_equal (LIBMESH_DIM, d); libmesh_assert (libMesh::initialized()); }
// ------------------------------------------------------------ // MeshBase class member functions MeshBase::MeshBase (const Parallel::Communicator &comm_in, unsigned int d) : ParallelObject (comm_in), boundary_info (new BoundaryInfo(*this)), _n_parts (1), _dim (d), _is_prepared (false), _point_locator (NULL), _partitioner (NULL), #ifdef LIBMESH_ENABLE_UNIQUE_ID _next_unique_id(DofObject::invalid_unique_id), #endif _skip_partitioning(false), _skip_renumber_nodes_and_elements(false) { libmesh_assert_less_equal (LIBMESH_DIM, 3); libmesh_assert_greater_equal (LIBMESH_DIM, _dim); libmesh_assert (libMesh::initialized()); }
unsigned short int Quad9::second_order_adjacent_vertex (const unsigned int n, const unsigned int v) const { libmesh_assert_greater_equal (n, this->n_vertices()); libmesh_assert_less (n, this->n_nodes()); switch (n) { case 8: { libmesh_assert_less (v, 4); return static_cast<unsigned short int>(v); } default: { libmesh_assert_less (v, 2); // use the matrix that we inherited from \p Quad return _second_order_adjacent_vertices[n-this->n_vertices()][v]; } } }
unsigned short int Prism18::second_order_adjacent_vertex (const unsigned int n, const unsigned int v) const { libmesh_assert_greater_equal (n, this->n_vertices()); libmesh_assert_less (n, this->n_nodes()); switch (n) { /* * These nodes are unique to \p Prism18, * let our _remaining_... matrix handle * this. */ case 15: case 16: case 17: { libmesh_assert_less (v, 4); return _remaining_second_order_adjacent_vertices[n-15][v]; } /* * All other second-order nodes (6,...,14) are * identical with Prism15 and are therefore * delegated to the _second_order matrix of * \p Prism */ default: { libmesh_assert_less (v, 2); return _second_order_adjacent_vertices[n-this->n_vertices()][v]; } } libmesh_error_msg("We'll never ge here!"); return static_cast<unsigned short int>(-1); }
// FIXME: it'll be tricky getting this to work with 64-bit dof_id_type void DofObject::unpack_indexing(std::vector<int>::const_iterator begin) { _idx_buf.clear(); #ifdef LIBMESH_ENABLE_AMR this->clear_old_dof_object(); const int has_old_dof_object = *begin++; libmesh_assert(has_old_dof_object == 1 || has_old_dof_object == 0); #endif const int size = *begin++; _idx_buf.reserve(size); std::copy(begin, begin+size, back_inserter(_idx_buf)); // Check as best we can for internal consistency now libmesh_assert(_idx_buf.empty() || (_idx_buf[0] <= _idx_buf.size())); #ifdef DEBUG if (!_idx_buf.empty()) for (unsigned int i=1; i < _idx_buf[0]; ++i) { libmesh_assert_greater_equal (_idx_buf[i], _idx_buf[i-1]); libmesh_assert_equal_to ((_idx_buf[i] - _idx_buf[i-1])%2, 0); libmesh_assert_less_equal (_idx_buf[i], _idx_buf.size()); } #endif #ifdef LIBMESH_ENABLE_AMR if (has_old_dof_object) { this->old_dof_object = new DofObject(); this->old_dof_object->unpack_indexing(begin+size); } #endif }
Real ExactErrorEstimator::find_squared_element_error(const System & system, const std::string & var_name, const Elem * elem, const DenseVector<Number> & Uelem, FEBase * fe, MeshFunction * fine_values) const { // The (string) name of this system const std::string & sys_name = system.name(); const unsigned int sys_num = system.number(); const unsigned int var = system.variable_number(var_name); const unsigned int var_component = system.variable_scalar_number(var, 0); const Parameters & parameters = system.get_equation_systems().parameters; // reinitialize the element-specific data // for the current element fe->reinit (elem); // Get the data we need to compute with const std::vector<Real> & JxW = fe->get_JxW(); const std::vector<std::vector<Real> > & phi_values = fe->get_phi(); const std::vector<std::vector<RealGradient> > & dphi_values = fe->get_dphi(); const std::vector<Point> & q_point = fe->get_xyz(); #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES const std::vector<std::vector<RealTensor> > & d2phi_values = fe->get_d2phi(); #endif // The number of shape functions const unsigned int n_sf = cast_int<unsigned int>(Uelem.size()); // The number of quadrature points const unsigned int n_qp = cast_int<unsigned int>(JxW.size()); Real error_val = 0; // Begin the loop over the Quadrature points. // for (unsigned int qp=0; qp<n_qp; qp++) { // Real u_h = 0.; // RealGradient grad_u_h; Number u_h = 0.; Gradient grad_u_h; #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES Tensor grad2_u_h; #endif // Compute solution values at the current // quadrature point. This reqiures a sum // over all the shape functions evaluated // at the quadrature point. for (unsigned int i=0; i<n_sf; i++) { // Values from current solution. u_h += phi_values[i][qp]*Uelem(i); grad_u_h += dphi_values[i][qp]*Uelem(i); #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES grad2_u_h += d2phi_values[i][qp]*Uelem(i); #endif } // Compute the value of the error at this quadrature point if (error_norm.type(var) == L2 || error_norm.type(var) == H1 || error_norm.type(var) == H2) { Number val_error = u_h; if (_exact_value) val_error -= _exact_value(q_point[qp],parameters,sys_name,var_name); else if (_exact_values.size() > sys_num && _exact_values[sys_num]) val_error -= _exact_values[sys_num]-> component(var_component, q_point[qp], system.time); else if (_equation_systems_fine) val_error -= (*fine_values)(q_point[qp]); // Add the squares of the error to each contribution error_val += JxW[qp]*TensorTools::norm_sq(val_error); } // Compute the value of the error in the gradient at this // quadrature point if (error_norm.type(var) == H1 || error_norm.type(var) == H1_SEMINORM || error_norm.type(var) == H2) { Gradient grad_error = grad_u_h; if(_exact_deriv) grad_error -= _exact_deriv(q_point[qp],parameters,sys_name,var_name); else if (_exact_derivs.size() > sys_num && _exact_derivs[sys_num]) grad_error -= _exact_derivs[sys_num]-> component(var_component, q_point[qp], system.time); else if(_equation_systems_fine) grad_error -= fine_values->gradient(q_point[qp]); error_val += JxW[qp]*grad_error.norm_sq(); } #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES // Compute the value of the error in the hessian at this // quadrature point if ((error_norm.type(var) == H2_SEMINORM || error_norm.type(var) == H2)) { Tensor grad2_error = grad2_u_h; if(_exact_hessian) grad2_error -= _exact_hessian(q_point[qp],parameters,sys_name,var_name); else if (_exact_hessians.size() > sys_num && _exact_hessians[sys_num]) grad2_error -= _exact_hessians[sys_num]-> component(var_component, q_point[qp], system.time); else if (_equation_systems_fine) grad2_error -= fine_values->hessian(q_point[qp]); error_val += JxW[qp]*grad2_error.norm_sq(); } #endif } // end qp loop libmesh_assert_greater_equal (error_val, 0.); return error_val; }