void MeshFunction::hessian (const Point& p, const Real, std::vector<Tensor>& output, const std::set<subdomain_id_type>* subdomain_ids) { libmesh_assert (this->initialized()); const Elem* element = this->find_element(p,subdomain_ids); if (!element) { output.resize(0); } else { // resize the output vector to the number of output values // that the user told us output.resize (this->_system_vars.size()); { const unsigned int dim = element->dim(); /* * Get local coordinates to feed these into compute_data(). * Note that the fe_type can safely be used from the 0-variable, * since the inverse mapping is the same for all FEFamilies */ const Point mapped_point (FEInterface::inverse_map (dim, this->_dof_map.variable_type(0), element, p)); std::vector<Point> point_list (1, mapped_point); // loop over all vars for (unsigned int index=0; index < this->_system_vars.size(); index++) { /* * the data for this variable */ const unsigned int var = _system_vars[index]; const FEType& fe_type = this->_dof_map.variable_type(var); UniquePtr<FEBase> point_fe (FEBase::build(dim, fe_type)); const std::vector<std::vector<RealTensor> >& d2phi = point_fe->get_d2phi(); point_fe->reinit(element, &point_list); // where the solution values for the var-th variable are stored std::vector<dof_id_type> dof_indices; this->_dof_map.dof_indices (element, dof_indices, var); // interpolate the solution Tensor hess; for (unsigned int i=0; i<dof_indices.size(); i++) hess.add_scaled(d2phi[i][0], this->_vector(dof_indices[i])); output[index] = hess; } } } // all done return; }
void MeshFunction::hessian (const Point& p, const Real, std::vector<Tensor>& output) { libmesh_assert (this->initialized()); /* Ensure that in the case of a master mesh function, the out-of-mesh mode is enabled either for both or for none. This is important because the out-of-mesh mode is also communicated to the point locator. Since this is time consuming, enable it only in debug mode. */ #ifdef DEBUG if (this->_master != NULL) { const MeshFunction* master = libmesh_cast_ptr<const MeshFunction*>(this->_master); if(_out_of_mesh_mode!=master->_out_of_mesh_mode) libmesh_error_msg("ERROR: If you use out-of-mesh-mode in connection with master mesh " \ << "functions, you must enable out-of-mesh mode for both the master and the slave mesh function."); } #endif // locate the point in the other mesh const Elem* element = this->_point_locator->operator()(p); // If we have an element, but it's not a local element, then we // either need to have a serialized vector or we need to find a // local element sharing the same point. if (element && (element->processor_id() != this->processor_id()) && _vector.type() != SERIAL) { // look for a local element containing the point std::set<const Elem*> point_neighbors; element->find_point_neighbors(p, point_neighbors); element = NULL; std::set<const Elem*>::const_iterator it = point_neighbors.begin(); const std::set<const Elem*>::const_iterator end = point_neighbors.end(); for (; it != end; ++it) { const Elem* elem = *it; if (elem->processor_id() == this->processor_id()) { element = elem; break; } } } if (!element) { output.resize(0); } else { // resize the output vector to the number of output values // that the user told us output.resize (this->_system_vars.size()); { const unsigned int dim = this->_eqn_systems.get_mesh().mesh_dimension(); /* * Get local coordinates to feed these into compute_data(). * Note that the fe_type can safely be used from the 0-variable, * since the inverse mapping is the same for all FEFamilies */ const Point mapped_point (FEInterface::inverse_map (dim, this->_dof_map.variable_type(0), element, p)); std::vector<Point> point_list (1, mapped_point); // loop over all vars for (unsigned int index=0; index < this->_system_vars.size(); index++) { /* * the data for this variable */ const unsigned int var = _system_vars[index]; const FEType& fe_type = this->_dof_map.variable_type(var); AutoPtr<FEBase> point_fe (FEBase::build(dim, fe_type)); const std::vector<std::vector<RealTensor> >& d2phi = point_fe->get_d2phi(); point_fe->reinit(element, &point_list); // where the solution values for the var-th variable are stored std::vector<dof_id_type> dof_indices; this->_dof_map.dof_indices (element, dof_indices, var); // interpolate the solution Tensor hess; for (unsigned int i=0; i<dof_indices.size(); i++) hess.add_scaled(d2phi[i][0], this->_vector(dof_indices[i])); output[index] = hess; } } } // all done return; }