Real ImageSampler::sample(const Point & p) { #ifdef LIBMESH_HAVE_VTK // Do nothing if the point is outside of the image domain if (!_bounding_box.contains_point(p)) return 0.0; // Determine pixel coordinates std::vector<int> x(3,0); for (int i = 0; i < LIBMESH_DIM; ++i) { // Compute position, only if voxel size is greater than zero if (_voxel[i] == 0) x[i] = 0; else { x[i] = std::floor((p(i) - _origin(i))/_voxel[i]); // If the point falls on the mesh extents the index needs to be decreased by one if (x[i] == _dims[i]) x[i]--; } } // Return the image data at the given point return _data->GetScalarComponentAsDouble(x[0], x[1], x[2], _component); #else libmesh_ignore(p); // avoid un-used parameter warnings return 0.0; #endif }
UniquePtr<OptimizationSolver<T> > OptimizationSolver<T>::build(sys_type & s, const SolverPackage solver_package) { // Prevent unused variables warnings when Tao is not available libmesh_ignore(s); // Build the appropriate solver switch (solver_package) { #if defined(LIBMESH_HAVE_PETSC_TAO) && !defined(LIBMESH_USE_COMPLEX_NUMBERS) case PETSC_SOLVERS: return UniquePtr<OptimizationSolver<T> >(new TaoOptimizationSolver<T>(s)); #endif // #if defined(LIBMESH_HAVE_PETSC_TAO) && !defined(LIBMESH_USE_COMPLEX_NUMBERS) #if defined(LIBMESH_HAVE_NLOPT) && !defined(LIBMESH_USE_COMPLEX_NUMBERS) case NLOPT_SOLVERS: return UniquePtr<OptimizationSolver<T> >(new NloptOptimizationSolver<T>(s)); #endif // #if defined(LIBMESH_HAVE_NLOPT) && !defined(LIBMESH_USE_COMPLEX_NUMBERS) default: libmesh_error_msg("ERROR: Unrecognized solver package: " << solver_package); } libmesh_error_msg("We'll never get here!"); return UniquePtr<OptimizationSolver<T> >(); }
// Constructor for writing VTKIO::VTKIO (const MeshBase & mesh, MeshData * mesh_data) : MeshOutput<MeshBase>(mesh, /*is_parallel_format=*/true) #ifdef LIBMESH_HAVE_VTK ,_vtk_grid(libmesh_nullptr) ,_mesh_data(mesh_data) ,_compress(false) #endif { // Ignore unused parameters when !LIBMESH_HAVE_VTK libmesh_ignore(mesh_data); libmesh_experimental(); }
void Partitioner::set_parent_processor_ids(MeshBase & mesh) { // Ignore the parameter when !LIBMESH_ENABLE_AMR libmesh_ignore(mesh); LOG_SCOPE("set_parent_processor_ids()", "Partitioner"); #ifdef LIBMESH_ENABLE_AMR // If the mesh is serial we have access to all the elements, // in particular all the active ones. We can therefore set // the parent processor ids indirecly through their children, and // set the subactive processor ids while examining their active // ancestors. // By convention a parent is assigned to the minimum processor // of all its children, and a subactive is assigned to the processor // of its active ancestor. if (mesh.is_serial()) { // Loop over all the active elements in the mesh MeshBase::element_iterator it = mesh.active_elements_begin(); const MeshBase::element_iterator end = mesh.active_elements_end(); for ( ; it!=end; ++it) { Elem * child = *it; // First set descendents std::vector<const Elem *> subactive_family; child->total_family_tree(subactive_family); for (unsigned int i = 0; i != subactive_family.size(); ++i) const_cast<Elem *>(subactive_family[i])->processor_id() = child->processor_id(); // Then set ancestors Elem * parent = child->parent(); while (parent) { // invalidate the parent id, otherwise the min below // will not work if the current parent id is less // than all the children! parent->invalidate_processor_id(); for (unsigned int c=0; c<parent->n_children(); c++) { child = parent->child_ptr(c); libmesh_assert(child); libmesh_assert(!child->is_remote()); libmesh_assert_not_equal_to (child->processor_id(), DofObject::invalid_processor_id); parent->processor_id() = std::min(parent->processor_id(), child->processor_id()); } parent = parent->parent(); } } } // When the mesh is parallel we cannot guarantee that parents have access to // all their children. else { // Setting subactive processor ids is easy: we can guarantee // that children have access to all their parents. // Loop over all the active elements in the mesh MeshBase::element_iterator it = mesh.active_elements_begin(); const MeshBase::element_iterator end = mesh.active_elements_end(); for ( ; it!=end; ++it) { Elem * child = *it; std::vector<const Elem *> subactive_family; child->total_family_tree(subactive_family); for (unsigned int i = 0; i != subactive_family.size(); ++i) const_cast<Elem *>(subactive_family[i])->processor_id() = child->processor_id(); } // When the mesh is parallel we cannot guarantee that parents have access to // all their children. // We will use a brute-force approach here. Each processor finds its parent // elements and sets the parent pid to the minimum of its // semilocal descendants. // A global reduction is then performed to make sure the true minimum is found. // As noted, this is required because we cannot guarantee that a parent has // access to all its children on any single processor. libmesh_parallel_only(mesh.comm()); libmesh_assert(MeshTools::n_elem(mesh.unpartitioned_elements_begin(), mesh.unpartitioned_elements_end()) == 0); const dof_id_type max_elem_id = mesh.max_elem_id(); std::vector<processor_id_type> parent_processor_ids (std::min(communication_blocksize, max_elem_id)); for (dof_id_type blk=0, last_elem_id=0; last_elem_id<max_elem_id; blk++) { last_elem_id = std::min(static_cast<dof_id_type>((blk+1)*communication_blocksize), max_elem_id); const dof_id_type first_elem_id = blk*communication_blocksize; std::fill (parent_processor_ids.begin(), parent_processor_ids.end(), DofObject::invalid_processor_id); // first build up local contributions to parent_processor_ids MeshBase::element_iterator not_it = mesh.ancestor_elements_begin(); const MeshBase::element_iterator not_end = mesh.ancestor_elements_end(); bool have_parent_in_block = false; for ( ; not_it != not_end; ++not_it) { Elem * parent = *not_it; const dof_id_type parent_idx = parent->id(); libmesh_assert_less (parent_idx, max_elem_id); if ((parent_idx >= first_elem_id) && (parent_idx < last_elem_id)) { have_parent_in_block = true; processor_id_type parent_pid = DofObject::invalid_processor_id; std::vector<const Elem *> active_family; parent->active_family_tree(active_family); for (unsigned int i = 0; i != active_family.size(); ++i) parent_pid = std::min (parent_pid, active_family[i]->processor_id()); const dof_id_type packed_idx = parent_idx - first_elem_id; libmesh_assert_less (packed_idx, parent_processor_ids.size()); parent_processor_ids[packed_idx] = parent_pid; } } // then find the global minimum mesh.comm().min (parent_processor_ids); // and assign the ids, if we have a parent in this block. if (have_parent_in_block) for (not_it = mesh.ancestor_elements_begin(); not_it != not_end; ++not_it) { Elem * parent = *not_it; const dof_id_type parent_idx = parent->id(); if ((parent_idx >= first_elem_id) && (parent_idx < last_elem_id)) { const dof_id_type packed_idx = parent_idx - first_elem_id; libmesh_assert_less (packed_idx, parent_processor_ids.size()); const processor_id_type parent_pid = parent_processor_ids[packed_idx]; libmesh_assert_not_equal_to (parent_pid, DofObject::invalid_processor_id); parent->processor_id() = parent_pid; } } } } #endif // LIBMESH_ENABLE_AMR }
void ExactErrorEstimator::estimate_error (const System & system, ErrorVector & error_per_cell, const NumericVector<Number> * solution_vector, bool estimate_parent_error) { // Ignore the fact that this variable is unused when !LIBMESH_ENABLE_AMR libmesh_ignore(estimate_parent_error); // The current mesh const MeshBase & mesh = system.get_mesh(); // The dimensionality of the mesh const unsigned int dim = mesh.mesh_dimension(); // The number of variables in the system const unsigned int n_vars = system.n_vars(); // The DofMap for this system const DofMap & dof_map = system.get_dof_map(); // Resize the error_per_cell vector to be // the number of elements, initialize it to 0. error_per_cell.resize (mesh.max_elem_id()); std::fill (error_per_cell.begin(), error_per_cell.end(), 0.); // Prepare current_local_solution to localize a non-standard // solution vector if necessary if (solution_vector && solution_vector != system.solution.get()) { NumericVector<Number> * newsol = const_cast<NumericVector<Number> *>(solution_vector); System & sys = const_cast<System &>(system); newsol->swap(*sys.solution); sys.update(); } // Loop over all the variables in the system for (unsigned int var=0; var<n_vars; var++) { // Possibly skip this variable if (error_norm.weight(var) == 0.0) continue; // The (string) name of this variable const std::string & var_name = system.variable_name(var); // The type of finite element to use for this variable const FEType & fe_type = dof_map.variable_type (var); UniquePtr<FEBase> fe (FEBase::build (dim, fe_type)); // Build an appropriate Gaussian quadrature rule UniquePtr<QBase> qrule = fe_type.default_quadrature_rule (dim, _extra_order); fe->attach_quadrature_rule (qrule.get()); // Prepare a global solution and a MeshFunction of the fine system if we need one UniquePtr<MeshFunction> fine_values; UniquePtr<NumericVector<Number> > fine_soln = NumericVector<Number>::build(system.comm()); if (_equation_systems_fine) { const System & fine_system = _equation_systems_fine->get_system(system.name()); std::vector<Number> global_soln; // FIXME - we're assuming that the fine system solution gets // used even when a different vector is used for the coarse // system fine_system.update_global_solution(global_soln); fine_soln->init (cast_int<numeric_index_type>(global_soln.size()), true, SERIAL); (*fine_soln) = global_soln; fine_values = UniquePtr<MeshFunction> (new MeshFunction(*_equation_systems_fine, *fine_soln, fine_system.get_dof_map(), fine_system.variable_number(var_name))); fine_values->init(); } else { // Initialize functors if we're using them for (unsigned int i=0; i != _exact_values.size(); ++i) if (_exact_values[i]) _exact_values[i]->init(); for (unsigned int i=0; i != _exact_derivs.size(); ++i) if (_exact_derivs[i]) _exact_derivs[i]->init(); for (unsigned int i=0; i != _exact_hessians.size(); ++i) if (_exact_hessians[i]) _exact_hessians[i]->init(); } // Request the data we'll need to compute with fe->get_JxW(); fe->get_phi(); fe->get_dphi(); #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES fe->get_d2phi(); #endif fe->get_xyz(); #ifdef LIBMESH_ENABLE_AMR // If we compute on parent elements, we'll want to do so only // once on each, so we need to keep track of which we've done. std::vector<bool> computed_var_on_parent; if (estimate_parent_error) computed_var_on_parent.resize(error_per_cell.size(), false); #endif // TODO: this ought to be threaded (and using subordinate // MeshFunction objects in each thread rather than a single // master) // Iterate over all the active elements in the mesh // that live on this processor. MeshBase::const_element_iterator elem_it = mesh.active_local_elements_begin(); const MeshBase::const_element_iterator elem_end = mesh.active_local_elements_end(); for (;elem_it != elem_end; ++elem_it) { // e is necessarily an active element on the local processor const Elem * elem = *elem_it; const dof_id_type e_id = elem->id(); #ifdef LIBMESH_ENABLE_AMR // See if the parent of element e has been examined yet; // if not, we may want to compute the estimator on it const Elem * parent = elem->parent(); // We only can compute and only need to compute on // parents with all active children bool compute_on_parent = true; if (!parent || !estimate_parent_error) compute_on_parent = false; else for (unsigned int c=0; c != parent->n_children(); ++c) if (!parent->child_ptr(c)->active()) compute_on_parent = false; if (compute_on_parent && !computed_var_on_parent[parent->id()]) { computed_var_on_parent[parent->id()] = true; // Compute a projection onto the parent DenseVector<Number> Uparent; FEBase::coarsened_dof_values(*(system.current_local_solution), dof_map, parent, Uparent, var, false); error_per_cell[parent->id()] += static_cast<ErrorVectorReal> (find_squared_element_error(system, var_name, parent, Uparent, fe.get(), fine_values.get())); } #endif // Get the local to global degree of freedom maps std::vector<dof_id_type> dof_indices; dof_map.dof_indices (elem, dof_indices, var); const unsigned int n_dofs = cast_int<unsigned int>(dof_indices.size()); DenseVector<Number> Uelem(n_dofs); for (unsigned int i=0; i != n_dofs; ++i) Uelem(i) = system.current_solution(dof_indices[i]); error_per_cell[e_id] += static_cast<ErrorVectorReal> (find_squared_element_error(system, var_name, elem, Uelem, fe.get(), fine_values.get())); } // End loop over active local elements } // End loop over variables // Each processor has now computed the error contribuions // for its local elements. We need to sum the vector // and then take the square-root of each component. Note // that we only need to sum if we are running on multiple // processors, and we only need to take the square-root // if the value is nonzero. There will in general be many // zeros for the inactive elements. // First sum the vector of estimated error values this->reduce_error(error_per_cell, system.comm()); // Compute the square-root of each component. { LOG_SCOPE("std::sqrt()", "ExactErrorEstimator"); for (dof_id_type i=0; i<error_per_cell.size(); i++) if (error_per_cell[i] != 0.) { libmesh_assert_greater (error_per_cell[i], 0.); error_per_cell[i] = std::sqrt(error_per_cell[i]); } } // If we used a non-standard solution before, now is the time to fix // the current_local_solution if (solution_vector && solution_vector != system.solution.get()) { NumericVector<Number> * newsol = const_cast<NumericVector<Number> *>(solution_vector); System & sys = const_cast<System &>(system); newsol->swap(*sys.solution); sys.update(); } }
void MeshBaseImageSampler::setupImageSampler(MeshBase & mesh) { // Don't warn that mesh or _is_pars are unused when VTK is not enabled. libmesh_ignore(mesh); libmesh_ignore(_is_pars); #ifdef LIBMESH_HAVE_VTK // Get access to the Mesh object BoundingBox bbox = MeshTools::create_bounding_box(mesh); // Set the dimensions from the Mesh if not set by the User if (_is_pars.isParamValid("dimensions")) _physical_dims = _is_pars.get<Point>("dimensions"); else { _physical_dims(0) = bbox.max()(0) - bbox.min()(0); #if LIBMESH_DIM > 1 _physical_dims(1) = bbox.max()(1) - bbox.min()(1); #endif #if LIBMESH_DIM > 2 _physical_dims(2) = bbox.max()(2) - bbox.min()(2); #endif } // Set the origin from the Mesh if not set in the input file if (_is_pars.isParamValid("origin")) _origin = _is_pars.get<Point>("origin"); else { _origin(0) = bbox.min()(0); #if LIBMESH_DIM > 1 _origin(1) = bbox.min()(1); #endif #if LIBMESH_DIM > 2 _origin(2) = bbox.min()(2); #endif } // An array of filenames, to be filled in std::vector<std::string> filenames; // The file suffix, to be determined std::string file_suffix; // Try to parse our own file range parameters. If that fails, then // see if the associated Mesh is an ImageMesh and use its. If that // also fails, then we have to throw an error... // // The parseFileRange method sets parameters, thus a writable reference to the InputParameters // object must be obtained from the warehouse. Generally, this should be avoided, but // this is a special case. if (_status != 0) { // TO DO : enable this. It was taken from ImageSampler.C, but cn't be implemented // the same way. // We don't have parameters, so see if we can get them from ImageMesh /*ImageMeshgenerator * image_mesh_gen = dynamic_cast<ImageMesh *>(&mesh); if (!image_mesh) mooseError("No file range parameters were provided and the Mesh is not an ImageMesh."); // Get the ImageMesh's parameters. This should work, otherwise // errors would already have been thrown... filenames = image_mesh->filenames(); file_suffix = image_mesh->fileSuffix();*/ } else { // Use our own parameters (using 'this' b/c of conflicts with filenames the local variable) filenames = this->filenames(); file_suffix = fileSuffix(); } // Storage for the file names _files = vtkSmartPointer<vtkStringArray>::New(); for (const auto & filename : filenames) _files->InsertNextValue(filename); // Error if no files where located if (_files->GetNumberOfValues() == 0) mooseError("No image file(s) located"); // Read the image stack. Hurray for VTK not using polymorphism in a // smart way... we actually have to explicitly create the type of // reader based on the file extension, using an if-statement... if (file_suffix == "png") _image = vtkSmartPointer<vtkPNGReader>::New(); else if (file_suffix == "tiff" || file_suffix == "tif") _image = vtkSmartPointer<vtkTIFFReader>::New(); else mooseError("Un-supported file type '", file_suffix, "'"); // Now that _image is set up, actually read the images // Indicate that data read has started _is_console << "Reading image(s)..." << std::endl; // Extract the data _image->SetFileNames(_files); _image->Update(); _data = _image->GetOutput(); _algorithm = _image->GetOutputPort(); // Set the image dimensions and voxel size member variable int * dims = _data->GetDimensions(); for (unsigned int i = 0; i < 3; ++i) { _dims.push_back(dims[i]); _voxel.push_back(_physical_dims(i) / _dims[i]); } // Set the dimensions of the image and bounding box _data->SetSpacing(_voxel[0], _voxel[1], _voxel[2]); _data->SetOrigin(_origin(0), _origin(1), _origin(2)); _bounding_box.min() = _origin; _bounding_box.max() = _origin + _physical_dims; // Indicate data read is completed _is_console << " ...image read finished" << std::endl; // Set the component parameter // If the parameter is not set then vtkMagnitude() will applied if (_is_pars.isParamValid("component")) { unsigned int n = _data->GetNumberOfScalarComponents(); _component = _is_pars.get<unsigned int>("component"); if (_component >= n) mooseError("'component' parameter must be empty or have a value of 0 to ", n - 1); } else _component = 0; // Apply filters, the toggling on and off of each filter is handled internally vtkMagnitude(); vtkShiftAndScale(); vtkThreshold(); vtkFlip(); #endif }
void PetscMatrix<T>::init (const numeric_index_type m_in, const numeric_index_type n_in, const numeric_index_type m_l, const numeric_index_type n_l, const std::vector<numeric_index_type>& n_nz, const std::vector<numeric_index_type>& n_oz, const numeric_index_type blocksize_in) { // So compilers don't warn when !LIBMESH_ENABLE_BLOCKED_STORAGE libmesh_ignore(blocksize_in); // Clear initialized matrices if (this->initialized()) this->clear(); this->_is_initialized = true; // Make sure the sparsity pattern isn't empty unless the matrix is 0x0 libmesh_assert_equal_to (n_nz.size(), m_l); libmesh_assert_equal_to (n_oz.size(), m_l); PetscErrorCode ierr = 0; PetscInt m_global = static_cast<PetscInt>(m_in); PetscInt n_global = static_cast<PetscInt>(n_in); PetscInt m_local = static_cast<PetscInt>(m_l); PetscInt n_local = static_cast<PetscInt>(n_l); ierr = MatCreate(this->comm().get(), &_mat); LIBMESH_CHKERRABORT(ierr); ierr = MatSetSizes(_mat, m_local, n_local, m_global, n_global); LIBMESH_CHKERRABORT(ierr); #ifdef LIBMESH_ENABLE_BLOCKED_STORAGE PetscInt blocksize = static_cast<PetscInt>(blocksize_in); if (blocksize > 1) { // specified blocksize, bs>1. // double check sizes. libmesh_assert_equal_to (m_local % blocksize, 0); libmesh_assert_equal_to (n_local % blocksize, 0); libmesh_assert_equal_to (m_global % blocksize, 0); libmesh_assert_equal_to (n_global % blocksize, 0); ierr = MatSetType(_mat, MATBAIJ); // Automatically chooses seqbaij or mpibaij LIBMESH_CHKERRABORT(ierr); ierr = MatSetBlockSize(_mat, blocksize); LIBMESH_CHKERRABORT(ierr); // transform the per-entry n_nz and n_oz arrays into their block counterparts. std::vector<numeric_index_type> b_n_nz, b_n_oz; transform_preallocation_arrays (blocksize, n_nz, n_oz, b_n_nz, b_n_oz); ierr = MatSeqBAIJSetPreallocation(_mat, blocksize, 0, (PetscInt*)(b_n_nz.empty()?NULL:&b_n_nz[0])); LIBMESH_CHKERRABORT(ierr); ierr = MatMPIBAIJSetPreallocation(_mat, blocksize, 0, (PetscInt*)(b_n_nz.empty()?NULL:&b_n_nz[0]), 0, (PetscInt*)(b_n_oz.empty()?NULL:&b_n_oz[0])); LIBMESH_CHKERRABORT(ierr); } else #endif { ierr = MatSetType(_mat, MATAIJ); // Automatically chooses seqaij or mpiaij LIBMESH_CHKERRABORT(ierr); ierr = MatSeqAIJSetPreallocation(_mat, 0, (PetscInt*)(n_nz.empty()?NULL:&n_nz[0])); LIBMESH_CHKERRABORT(ierr); ierr = MatMPIAIJSetPreallocation(_mat, 0, (PetscInt*)(n_nz.empty()?NULL:&n_nz[0]), 0, (PetscInt*)(n_oz.empty()?NULL:&n_oz[0])); LIBMESH_CHKERRABORT(ierr); } // Is prefix information available somewhere? Perhaps pass in the system name? ierr = MatSetOptionsPrefix(_mat, ""); LIBMESH_CHKERRABORT(ierr); ierr = MatSetFromOptions(_mat); LIBMESH_CHKERRABORT(ierr); this->zero(); }
void PetscMatrix<T>::init (const numeric_index_type m_in, const numeric_index_type n_in, const numeric_index_type m_l, const numeric_index_type n_l, const numeric_index_type nnz, const numeric_index_type noz, const numeric_index_type blocksize_in) { // So compilers don't warn when !LIBMESH_ENABLE_BLOCKED_STORAGE libmesh_ignore(blocksize_in); // Clear initialized matrices if (this->initialized()) this->clear(); this->_is_initialized = true; PetscErrorCode ierr = 0; PetscInt m_global = static_cast<PetscInt>(m_in); PetscInt n_global = static_cast<PetscInt>(n_in); PetscInt m_local = static_cast<PetscInt>(m_l); PetscInt n_local = static_cast<PetscInt>(n_l); PetscInt n_nz = static_cast<PetscInt>(nnz); PetscInt n_oz = static_cast<PetscInt>(noz); ierr = MatCreate(this->comm().get(), &_mat); LIBMESH_CHKERRABORT(ierr); ierr = MatSetSizes(_mat, m_local, n_local, m_global, n_global); LIBMESH_CHKERRABORT(ierr); #ifdef LIBMESH_ENABLE_BLOCKED_STORAGE PetscInt blocksize = static_cast<PetscInt>(blocksize_in); if (blocksize > 1) { // specified blocksize, bs>1. // double check sizes. libmesh_assert_equal_to (m_local % blocksize, 0); libmesh_assert_equal_to (n_local % blocksize, 0); libmesh_assert_equal_to (m_global % blocksize, 0); libmesh_assert_equal_to (n_global % blocksize, 0); libmesh_assert_equal_to (n_nz % blocksize, 0); libmesh_assert_equal_to (n_oz % blocksize, 0); ierr = MatSetType(_mat, MATBAIJ); // Automatically chooses seqbaij or mpibaij LIBMESH_CHKERRABORT(ierr); ierr = MatSetBlockSize(_mat, blocksize); LIBMESH_CHKERRABORT(ierr); ierr = MatSeqBAIJSetPreallocation(_mat, blocksize, n_nz/blocksize, PETSC_NULL); LIBMESH_CHKERRABORT(ierr); ierr = MatMPIBAIJSetPreallocation(_mat, blocksize, n_nz/blocksize, PETSC_NULL, n_oz/blocksize, PETSC_NULL); LIBMESH_CHKERRABORT(ierr); } else #endif { ierr = MatSetType(_mat, MATAIJ); // Automatically chooses seqaij or mpiaij LIBMESH_CHKERRABORT(ierr); ierr = MatSeqAIJSetPreallocation(_mat, n_nz, PETSC_NULL); LIBMESH_CHKERRABORT(ierr); ierr = MatMPIAIJSetPreallocation(_mat, n_nz, PETSC_NULL, n_oz, PETSC_NULL); LIBMESH_CHKERRABORT(ierr); } // Make it an error for PETSc to allocate new nonzero entries during assembly #if PETSC_VERSION_LESS_THAN(3,0,0) ierr = MatSetOption(_mat, MAT_NEW_NONZERO_ALLOCATION_ERR); #else ierr = MatSetOption(_mat, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE); #endif LIBMESH_CHKERRABORT(ierr); // Is prefix information available somewhere? Perhaps pass in the system name? ierr = MatSetOptionsPrefix(_mat, ""); LIBMESH_CHKERRABORT(ierr); ierr = MatSetFromOptions(_mat); LIBMESH_CHKERRABORT(ierr); this->zero (); }