Skip to content

Commit 6ef7d43

Browse files
authored
Merge pull request #4024 from jwpeterson/test_numeric_vector_type_api_removal
Deprecate NumericVector::type() that returns a writable reference
2 parents 7d03474 + d13c580 commit 6ef7d43

File tree

3 files changed

+72
-11
lines changed

3 files changed

+72
-11
lines changed

include/numerics/numeric_vector.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ class NumericVector : public ReferenceCountedObject<NumericVector<T>>,
139139
*/
140140
static std::unique_ptr<NumericVector<T>>
141141
build(const Parallel::Communicator & comm,
142-
const SolverPackage solver_package = libMesh::default_solver_package());
142+
SolverPackage solver_package = libMesh::default_solver_package(),
143+
ParallelType parallel_type = AUTOMATIC);
143144

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

155156
/**
156157
* \returns The type (SERIAL, PARALLEL, GHOSTED) of the vector.
158+
*
159+
* \deprecated because it is dangerous to change the ParallelType
160+
* of an already-initialized NumericVector. See NumericVector::set_type()
161+
* for a safer, non-deprecated setter.
157162
*/
163+
#ifdef LIBMESH_ENABLE_DEPRECATED
158164
ParallelType & type() { return _type; }
165+
#endif
166+
167+
/**
168+
* Allow the user to change the ParallelType of the NumericVector
169+
* under some circumstances. If the NumericVector has not been
170+
* initialized yet, then it is generally safe to change the
171+
* ParallelType. otherwise, if the NumericVector has already been
172+
* initialized with a specific type, we cannot change it without
173+
* doing some extra copying/reinitialization work, and we currently
174+
* throw an error if this is requested.
175+
*/
176+
void set_type(ParallelType t);
159177

160178
/**
161179
* \returns \p true if the vector is closed and ready for

src/numerics/numeric_vector.C

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,39 +47,72 @@ namespace libMesh
4747
// Full specialization for Real datatypes
4848
template <typename T>
4949
std::unique_ptr<NumericVector<T>>
50-
NumericVector<T>::build(const Parallel::Communicator & comm, const SolverPackage solver_package)
50+
NumericVector<T>::build(const Parallel::Communicator & comm,
51+
SolverPackage solver_package,
52+
ParallelType parallel_type)
5153
{
5254
// Build the appropriate vector
5355
switch (solver_package)
5456
{
5557

5658
#ifdef LIBMESH_HAVE_LASPACK
5759
case LASPACK_SOLVERS:
58-
return std::make_unique<LaspackVector<T>>(comm, AUTOMATIC);
60+
return std::make_unique<LaspackVector<T>>(comm, parallel_type);
5961
#endif
6062

6163
#ifdef LIBMESH_HAVE_PETSC
6264
case PETSC_SOLVERS:
63-
return std::make_unique<PetscVector<T>>(comm, AUTOMATIC);
65+
return std::make_unique<PetscVector<T>>(comm, parallel_type);
6466
#endif
6567

6668
#ifdef LIBMESH_TRILINOS_HAVE_EPETRA
6769
case TRILINOS_SOLVERS:
68-
return std::make_unique<EpetraVector<T>>(comm, AUTOMATIC);
70+
return std::make_unique<EpetraVector<T>>(comm, parallel_type);
6971
#endif
7072

7173
#ifdef LIBMESH_HAVE_EIGEN
7274
case EIGEN_SOLVERS:
73-
return std::make_unique<EigenSparseVector<T>>(comm, AUTOMATIC);
75+
return std::make_unique<EigenSparseVector<T>>(comm, parallel_type);
7476
#endif
7577

7678
default:
77-
return std::make_unique<DistributedVector<T>>(comm, AUTOMATIC);
79+
return std::make_unique<DistributedVector<T>>(comm, parallel_type);
7880
}
7981
}
8082

8183

8284

85+
template <typename T>
86+
void NumericVector<T>::set_type(ParallelType t)
87+
{
88+
// Check for no-op
89+
if (_type == t)
90+
return;
91+
92+
// If the NumericVector is not yet initialized, then it is generally
93+
// safe to change the ParallelType, with minor restrictions.
94+
if (!this->initialized())
95+
{
96+
// If ghosted vectors are not enabled and the user requested a
97+
// GHOSTED vector, fall back on SERIAL.
98+
#ifndef LIBMESH_ENABLE_GHOSTED
99+
if (t == GHOSTED)
100+
{
101+
_type = SERIAL;
102+
return;
103+
}
104+
#endif
105+
106+
_type = t;
107+
return;
108+
}
109+
110+
// If we made it here, then the NumericVector was already
111+
// initialized and we don't currently allow the ParallelType to be
112+
// changed, although this could potentially be added later.
113+
libmesh_not_implemented();
114+
}
115+
83116
template <typename T>
84117
void NumericVector<T>::insert (const T * v,
85118
const std::vector<numeric_index_type> & dof_indices)

src/systems/system.C

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -792,19 +792,29 @@ NumericVector<Number> & System::add_vector (std::string_view vec_name,
792792
vec.swap(*new_vec);
793793
}
794794
else
795-
vec.type() = type;
795+
// The PARALLEL vec is not yet initialized, so we can
796+
// just "upgrade" it to GHOSTED.
797+
vec.set_type(type);
796798
}
797799
}
798800

799801
// Any upgrades are done; we're happy here.
800802
return vec;
801803
}
802804

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

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

0 commit comments

Comments
 (0)