Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion include/numerics/numeric_vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ class NumericVector : public ReferenceCountedObject<NumericVector<T>>,
*/
static std::unique_ptr<NumericVector<T>>
build(const Parallel::Communicator & comm,
const SolverPackage solver_package = libMesh::default_solver_package());
SolverPackage solver_package = libMesh::default_solver_package(),
ParallelType parallel_type = AUTOMATIC);

/**
* \returns \p true if the vector has been initialized,
Expand All @@ -154,8 +155,25 @@ class NumericVector : public ReferenceCountedObject<NumericVector<T>>,

/**
* \returns The type (SERIAL, PARALLEL, GHOSTED) of the vector.
*
* \deprecated because it is dangerous to change the ParallelType
* of an already-initialized NumericVector. See NumericVector::set_type()
* for a safer, non-deprecated setter.
*/
#ifdef LIBMESH_ENABLE_DEPRECATED
ParallelType & type() { return _type; }
#endif

/**
* Allow the user to change the ParallelType of the NumericVector
* under some circumstances. If the NumericVector has not been
* initialized yet, then it is generally safe to change the
* ParallelType. otherwise, if the NumericVector has already been
* initialized with a specific type, we cannot change it without
* doing some extra copying/reinitialization work, and we currently
* throw an error if this is requested.
*/
void set_type(ParallelType t);

/**
* \returns \p true if the vector is closed and ready for
Expand Down
45 changes: 39 additions & 6 deletions src/numerics/numeric_vector.C
Original file line number Diff line number Diff line change
Expand Up @@ -47,39 +47,72 @@ namespace libMesh
// Full specialization for Real datatypes
template <typename T>
std::unique_ptr<NumericVector<T>>
NumericVector<T>::build(const Parallel::Communicator & comm, const SolverPackage solver_package)
NumericVector<T>::build(const Parallel::Communicator & comm,
SolverPackage solver_package,
ParallelType parallel_type)
{
// Build the appropriate vector
switch (solver_package)
{

#ifdef LIBMESH_HAVE_LASPACK
case LASPACK_SOLVERS:
return std::make_unique<LaspackVector<T>>(comm, AUTOMATIC);
return std::make_unique<LaspackVector<T>>(comm, parallel_type);
#endif

#ifdef LIBMESH_HAVE_PETSC
case PETSC_SOLVERS:
return std::make_unique<PetscVector<T>>(comm, AUTOMATIC);
return std::make_unique<PetscVector<T>>(comm, parallel_type);
#endif

#ifdef LIBMESH_TRILINOS_HAVE_EPETRA
case TRILINOS_SOLVERS:
return std::make_unique<EpetraVector<T>>(comm, AUTOMATIC);
return std::make_unique<EpetraVector<T>>(comm, parallel_type);
#endif

#ifdef LIBMESH_HAVE_EIGEN
case EIGEN_SOLVERS:
return std::make_unique<EigenSparseVector<T>>(comm, AUTOMATIC);
return std::make_unique<EigenSparseVector<T>>(comm, parallel_type);
#endif

default:
return std::make_unique<DistributedVector<T>>(comm, AUTOMATIC);
return std::make_unique<DistributedVector<T>>(comm, parallel_type);
}
}



template <typename T>
void NumericVector<T>::set_type(ParallelType t)
{
// Check for no-op
if (_type == t)
return;

// If the NumericVector is not yet initialized, then it is generally
// safe to change the ParallelType, with minor restrictions.
if (!this->initialized())
{
// If ghosted vectors are not enabled and the user requested a
// GHOSTED vector, fall back on SERIAL.
#ifndef LIBMESH_ENABLE_GHOSTED
if (t == GHOSTED)
{
_type = SERIAL;
return;
}
#endif

_type = t;
return;
}

// If we made it here, then the NumericVector was already
// initialized and we don't currently allow the ParallelType to be
// changed, although this could potentially be added later.
libmesh_not_implemented();
}

template <typename T>
void NumericVector<T>::insert (const T * v,
const std::vector<numeric_index_type> & dof_indices)
Expand Down
18 changes: 14 additions & 4 deletions src/systems/system.C
Original file line number Diff line number Diff line change
Expand Up @@ -792,19 +792,29 @@ NumericVector<Number> & System::add_vector (std::string_view vec_name,
vec.swap(*new_vec);
}
else
vec.type() = type;
// The PARALLEL vec is not yet initialized, so we can
// just "upgrade" it to GHOSTED.
vec.set_type(type);
}
}

// Any upgrades are done; we're happy here.
return vec;
}

// Otherwise build the vector
auto pr = _vectors.emplace(vec_name, NumericVector<Number>::build(this->comm()));
// Otherwise, build the vector. The following emplace() is
// guaranteed to succeed because, if we made it here, we don't
// already have a vector named "vec_name". We pass the user's
// requested ParallelType directly to NumericVector::build() so
// that, even if the vector is not initialized now, it will get the
// right type when it is initialized later.
auto pr =
_vectors.emplace(vec_name,
NumericVector<Number>::build(this->comm(),
libMesh::default_solver_package(),
type));
auto buf = pr.first->second.get();
_vector_projections.emplace(vec_name, projections);
buf->type() = type;

// Vectors are primal by default
_vector_is_adjoint.emplace(vec_name, -1);
Expand Down