#include <deal.II/base/config.h>
#ifdef DEAL_II_WITH_SUNDIALS
-# if DEAL_II_SUNDIALS_VERSION_GTE(5, 0, 0)
+# include <sundials/sundials_nvector.h>
-# include <sundials/sundials_nvector.h>
-
-# include <memory>
+# include <memory>
DEAL_II_NAMESPACE_OPEN
-# ifndef DOXYGEN
+# ifndef DOXYGEN
namespace SUNDIALS
{
namespace internal
class NVectorView;
}
} // namespace SUNDIALS
-# endif
+# endif
namespace SUNDIALS
{
* auto view = make_nvector_view(vector);
* @endcode
*
+ * The resulting object `view` must be kept around as long as any other
+ * object will use the internally viewed N_Vector.
+ *
* @tparam VectorType Type of the viewed vector. This parameter can be
* deduced automatically and will respect a potential const-qualifier.
* @param vector The vector to view.
/**
* Default constructor.
*
- * @note This constructor exists for compilers that are not eliding the
- * copy in a statement like:
- * @code
- * auto view = make_nvector_view(vector);
- * @endcode
+ * The object is not actually viewing anything and needs to be assigned to
+ * with operator=(NVectorView &&).
*/
NVectorView() = default;
DEAL_II_NAMESPACE_CLOSE
-# endif
#endif
#endif
#include <deal.II/sundials/n_vector.h>
#ifdef DEAL_II_WITH_SUNDIALS
-# if DEAL_II_SUNDIALS_VERSION_GTE(5, 0, 0)
-# include <deal.II/base/exceptions.h>
+# include <deal.II/base/exceptions.h>
+
+# include <deal.II/lac/block_vector.h>
+# include <deal.II/lac/la_parallel_block_vector.h>
+# include <deal.II/lac/la_parallel_vector.h>
+# include <deal.II/lac/la_vector.h>
+# include <deal.II/lac/trilinos_parallel_block_vector.h>
+# include <deal.II/lac/trilinos_vector.h>
+# include <deal.II/lac/vector_memory.h>
+
+# if DEAL_II_SUNDIALS_VERSION_LT(5, 0, 0)
+# include <deal.II/sundials/sundials_backport.h>
+# endif
-# include <deal.II/lac/block_vector.h>
-# include <deal.II/lac/la_parallel_block_vector.h>
-# include <deal.II/lac/la_parallel_vector.h>
-# include <deal.II/lac/la_vector.h>
-# include <deal.II/lac/trilinos_parallel_block_vector.h>
-# include <deal.II/lac/trilinos_vector.h>
-# include <deal.II/lac/vector_memory.h>
DEAL_II_NAMESPACE_OPEN
namespace SUNDIALS
realtype
max_norm(N_Vector x);
+ template <
+ typename VectorType,
+ typename std::enable_if_t<is_serial_vector<VectorType>::value, int> = 0>
+ realtype
+ min_element(N_Vector x);
+
+ template <
+ typename VectorType,
+ typename std::enable_if_t<!is_serial_vector<VectorType>::value &&
+ !IsBlockVector<VectorType>::value,
+ int> = 0>
+ realtype
+ min_element(N_Vector x);
+
+ template <
+ typename VectorType,
+ typename std::enable_if_t<!is_serial_vector<VectorType>::value &&
+ IsBlockVector<VectorType>::value,
+ int> = 0>
+ realtype
+ min_element(N_Vector x);
+
template <typename VectorType>
void
scale(realtype c, N_Vector x, N_Vector z);
template <
typename VectorType,
typename std::enable_if_t<is_serial_vector<VectorType>::value, int> = 0>
- void *get_communicator(N_Vector);
+ MPI_Comm get_communicator(N_Vector);
template <
typename VectorType,
typename std::enable_if_t<!is_serial_vector<VectorType>::value &&
!IsBlockVector<VectorType>::value,
int> = 0>
- void *
+ MPI_Comm
get_communicator(N_Vector v);
template <
typename std::enable_if_t<!is_serial_vector<VectorType>::value &&
IsBlockVector<VectorType>::value,
int> = 0>
- void *
+ MPI_Comm
get_communicator(N_Vector v);
+
+ /**
+ * Sundials likes a void* but we want to use the above functions
+ * internally with a safe type.
+ */
+ template <typename VectorType>
+ inline void *
+ get_communicator_as_void_ptr(N_Vector v)
+ {
+ return get_communicator<VectorType>(v);
+ }
+
} // namespace NVectorOperations
} // namespace internal
} // namespace SUNDIALS
template <typename VectorType>
SUNDIALS::internal::NVectorView<VectorType>::operator N_Vector() const
{
+ Assert(vector_ptr != nullptr, ExcNotInitialized());
return vector_ptr.get();
}
template <typename VectorType>
N_Vector SUNDIALS::internal::NVectorView<VectorType>::operator->() const
{
+ Assert(vector_ptr != nullptr, ExcNotInitialized());
return vector_ptr.get();
}
v->content = nullptr;
}
- /* free ops and vector */
- if (v->ops != nullptr)
- {
- free(v->ops);
- v->ops = nullptr;
- }
- free(v);
+ N_VFreeEmpty(v);
}
template <typename VectorType,
std::enable_if_t<is_serial_vector<VectorType>::value, int>>
-void *SUNDIALS::internal::NVectorOperations::get_communicator(N_Vector)
+MPI_Comm SUNDIALS::internal::NVectorOperations::get_communicator(N_Vector)
{
return nullptr;
}
std::enable_if_t<!is_serial_vector<VectorType>::value &&
IsBlockVector<VectorType>::value,
int>>
-void *
+MPI_Comm
SUNDIALS::internal::NVectorOperations::get_communicator(N_Vector v)
{
return unwrap_nvector_const<VectorType>(v)->block(0).get_mpi_communicator();
std::enable_if_t<!is_serial_vector<VectorType>::value &&
!IsBlockVector<VectorType>::value,
int>>
-void *
+MPI_Comm
SUNDIALS::internal::NVectorOperations::get_communicator(N_Vector v)
{
return unwrap_nvector_const<VectorType>(v)->get_mpi_communicator();
+template <typename VectorType,
+ typename std::enable_if_t<is_serial_vector<VectorType>::value, int>>
+realtype
+SUNDIALS::internal::NVectorOperations::min_element(N_Vector x)
+{
+ auto *vector = unwrap_nvector_const<VectorType>(x);
+ return *std::min_element(vector->begin(), vector->end());
+}
+
+
+
+template <typename VectorType,
+ typename std::enable_if_t<!is_serial_vector<VectorType>::value &&
+ !IsBlockVector<VectorType>::value,
+ int>>
+realtype
+SUNDIALS::internal::NVectorOperations::min_element(N_Vector x)
+{
+ auto * vector = unwrap_nvector_const<VectorType>(x);
+ const auto local_min = *std::min_element(vector->begin(), vector->end());
+ return Utilities::MPI::min(local_min, get_communicator<VectorType>(x));
+}
+
+
+
+template <typename VectorType,
+ typename std::enable_if_t<!is_serial_vector<VectorType>::value &&
+ IsBlockVector<VectorType>::value,
+ int>>
+realtype
+SUNDIALS::internal::NVectorOperations::min_element(N_Vector x)
+{
+ auto *vector = unwrap_nvector_const<VectorType>(x);
+
+ // initialize local minimum to the largest possible value
+ auto proc_local_min =
+ std::numeric_limits<typename VectorType::value_type>::max();
+
+ for (unsigned i = 0; i < vector->n_blocks(); ++i)
+ {
+ const auto block_local_min_element =
+ std::min_element(vector->block(i).begin(), vector->block(i).end());
+
+ // guard against empty blocks on this processor
+ if (block_local_min_element != vector->block(i).end())
+ proc_local_min = std::min(proc_local_min, *block_local_min_element);
+ }
+
+ return Utilities::MPI::min(proc_local_min, get_communicator<VectorType>(x));
+}
+
+
+
template <typename VectorType>
void
SUNDIALS::internal::NVectorOperations::scale(realtype c, N_Vector x, N_Vector z)
v->ops->nvcloneempty = NVectorOperations::clone_empty;
v->ops->nvdestroy = NVectorOperations::destroy<VectorType>;
// v->ops->nvspace = undef;
- v->ops->nvgetcommunicator = NVectorOperations::get_communicator<VectorType>;
- v->ops->nvgetlength = NVectorOperations::get_global_length<VectorType>;
+# if DEAL_II_SUNDIALS_VERSION_GTE(5, 0, 0)
+ v->ops->nvgetcommunicator =
+ NVectorOperations::get_communicator_as_void_ptr<VectorType>;
+ v->ops->nvgetlength = NVectorOperations::get_global_length<VectorType>;
+# endif
/* standard vector operations */
v->ops->nvlinearsum = NVectorOperations::linear_sum<VectorType>;
v->ops->nvmaxnorm = NVectorOperations::max_norm<VectorType>;
v->ops->nvwrmsnorm = NVectorOperations::weighted_rms_norm<VectorType>;
// v->ops->nvwrmsnormmask = undef;
- // v->ops->nvmin = undef;
+ v->ops->nvmin = NVectorOperations::min_element<VectorType>;
// v->ops->nvwl2norm = undef;
// v->ops->nvl1norm = undef;
// v->ops->nvcompare = undef;
DEAL_II_NAMESPACE_CLOSE
-# endif
#endif
#endif
--- /dev/null
+//-----------------------------------------------------------
+//
+// Copyright (C) 2020 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+//-----------------------------------------------------------
+
+/*
+ * The functions in this file are based on an implementation distributed within
+ * the SUNDIALS package, see the license here:
+ * https://computing.llnl.gov/projects/sundials/license.
+ * -----------------------------------------------------------------
+ * Programmer(s): Daniel Reynolds @ SMU
+ * David J. Gardner, Carol S. Woodward, and
+ * Slaven Peles @ LLNL
+ * -----------------------------------------------------------------*/
+
+#ifndef dealii_sundials_backport_h
+#define dealii_sundials_backport_h
+
+#include <deal.II/base/config.h>
+
+#ifdef DEAL_II_WITH_SUNDIALS
+
+# include <sundials/sundials_nvector.h>
+
+DEAL_II_NAMESPACE_OPEN
+namespace SUNDIALS
+{
+ namespace internal
+ {
+ N_Vector
+ N_VNewEmpty()
+ {
+ N_Vector v = new _generic_N_Vector;
+ N_Vector_Ops ops = new _generic_N_Vector_Ops;
+
+ /* initialize operations to nullptr */
+
+ /* constructors, destructors, and utility operations */
+ ops->nvgetvectorid = nullptr;
+ ops->nvclone = nullptr;
+ ops->nvcloneempty = nullptr;
+ ops->nvdestroy = nullptr;
+ ops->nvspace = nullptr;
+ ops->nvgetarraypointer = nullptr;
+ ops->nvsetarraypointer = nullptr;
+# if DEAL_II_SUNDIALS_VERSION_GTE(5, 0, 0)
+ ops->nvgetcommunicator = nullptr;
+ ops->nvgetlength = nullptr;
+# endif
+
+ /* standard vector operations */
+ ops->nvlinearsum = nullptr;
+ ops->nvconst = nullptr;
+ ops->nvprod = nullptr;
+ ops->nvdiv = nullptr;
+ ops->nvscale = nullptr;
+ ops->nvabs = nullptr;
+ ops->nvinv = nullptr;
+ ops->nvaddconst = nullptr;
+ ops->nvdotprod = nullptr;
+ ops->nvmaxnorm = nullptr;
+ ops->nvwrmsnormmask = nullptr;
+ ops->nvwrmsnorm = nullptr;
+ ops->nvmin = nullptr;
+ ops->nvwl2norm = nullptr;
+ ops->nvl1norm = nullptr;
+ ops->nvcompare = nullptr;
+ ops->nvinvtest = nullptr;
+ ops->nvconstrmask = nullptr;
+ ops->nvminquotient = nullptr;
+
+# if DEAL_II_SUNDIALS_VERSION_GTE(5, 0, 0)
+ /* fused vector operations (optional) */
+ ops->nvlinearcombination = nullptr;
+ ops->nvscaleaddmulti = nullptr;
+ ops->nvdotprodmulti = nullptr;
+
+ /* vector array operations (optional) */
+ ops->nvlinearsumvectorarray = nullptr;
+ ops->nvscalevectorarray = nullptr;
+ ops->nvconstvectorarray = nullptr;
+ ops->nvwrmsnormvectorarray = nullptr;
+ ops->nvwrmsnormmaskvectorarray = nullptr;
+ ops->nvscaleaddmultivectorarray = nullptr;
+ ops->nvlinearcombinationvectorarray = nullptr;
+
+ /* local reduction operations (optional) */
+ ops->nvdotprodlocal = nullptr;
+ ops->nvmaxnormlocal = nullptr;
+ ops->nvminlocal = nullptr;
+ ops->nvl1normlocal = nullptr;
+ ops->nvinvtestlocal = nullptr;
+ ops->nvconstrmasklocal = nullptr;
+ ops->nvminquotientlocal = nullptr;
+ ops->nvwsqrsumlocal = nullptr;
+ ops->nvwsqrsummasklocal = nullptr;
+
+ /* XBraid interface operations */
+ ops->nvbufsize = nullptr;
+ ops->nvbufpack = nullptr;
+ ops->nvbufunpack = nullptr;
+
+ /* debugging functions (called when SUNDIALS_DEBUG_PRINTVEC is defined) */
+ ops->nvprint = nullptr;
+ ops->nvprintfile = nullptr;
+# endif
+
+ /* attach ops and initialize content to nullptr */
+ v->ops = ops;
+ v->content = nullptr;
+
+ return v;
+ }
+
+
+
+ void
+ N_VFreeEmpty(N_Vector v)
+ {
+ if (v == nullptr)
+ return;
+
+ /* free non-nullptr ops structure */
+ if (v->ops)
+ delete v->ops;
+ v->ops = nullptr;
+
+ /* free overall N_Vector object and return */
+ delete v;
+ }
+
+
+
+ int
+ N_VCopyOps(N_Vector w, N_Vector v)
+ {
+ /* Check that ops structures exist */
+ if (w == nullptr || v == nullptr)
+ return (-1);
+ if (w->ops == nullptr || v->ops == nullptr)
+ return (-1);
+
+ /* Copy ops from w to v */
+
+ /* constructors, destructors, and utility operations */
+ v->ops->nvgetvectorid = w->ops->nvgetvectorid;
+ v->ops->nvclone = w->ops->nvclone;
+ v->ops->nvcloneempty = w->ops->nvcloneempty;
+ v->ops->nvdestroy = w->ops->nvdestroy;
+ v->ops->nvspace = w->ops->nvspace;
+ v->ops->nvgetarraypointer = w->ops->nvgetarraypointer;
+ v->ops->nvsetarraypointer = w->ops->nvsetarraypointer;
+# if DEAL_II_SUNDIALS_VERSION_GTE(5, 0, 0)
+ v->ops->nvgetcommunicator = w->ops->nvgetcommunicator;
+ v->ops->nvgetlength = w->ops->nvgetlength;
+# endif
+
+ /* standard vector operations */
+ v->ops->nvlinearsum = w->ops->nvlinearsum;
+ v->ops->nvconst = w->ops->nvconst;
+ v->ops->nvprod = w->ops->nvprod;
+ v->ops->nvdiv = w->ops->nvdiv;
+ v->ops->nvscale = w->ops->nvscale;
+ v->ops->nvabs = w->ops->nvabs;
+ v->ops->nvinv = w->ops->nvinv;
+ v->ops->nvaddconst = w->ops->nvaddconst;
+ v->ops->nvdotprod = w->ops->nvdotprod;
+ v->ops->nvmaxnorm = w->ops->nvmaxnorm;
+ v->ops->nvwrmsnormmask = w->ops->nvwrmsnormmask;
+ v->ops->nvwrmsnorm = w->ops->nvwrmsnorm;
+ v->ops->nvmin = w->ops->nvmin;
+ v->ops->nvwl2norm = w->ops->nvwl2norm;
+ v->ops->nvl1norm = w->ops->nvl1norm;
+ v->ops->nvcompare = w->ops->nvcompare;
+ v->ops->nvinvtest = w->ops->nvinvtest;
+ v->ops->nvconstrmask = w->ops->nvconstrmask;
+ v->ops->nvminquotient = w->ops->nvminquotient;
+
+# if DEAL_II_SUNDIALS_VERSION_GTE(5, 0, 0)
+ /* fused vector operations */
+ v->ops->nvlinearcombination = w->ops->nvlinearcombination;
+ v->ops->nvscaleaddmulti = w->ops->nvscaleaddmulti;
+ v->ops->nvdotprodmulti = w->ops->nvdotprodmulti;
+
+ /* vector array operations */
+ v->ops->nvlinearsumvectorarray = w->ops->nvlinearsumvectorarray;
+ v->ops->nvscalevectorarray = w->ops->nvscalevectorarray;
+ v->ops->nvconstvectorarray = w->ops->nvconstvectorarray;
+ v->ops->nvwrmsnormvectorarray = w->ops->nvwrmsnormvectorarray;
+ v->ops->nvwrmsnormmaskvectorarray = w->ops->nvwrmsnormmaskvectorarray;
+ v->ops->nvscaleaddmultivectorarray = w->ops->nvscaleaddmultivectorarray;
+ v->ops->nvlinearcombinationvectorarray =
+ w->ops->nvlinearcombinationvectorarray;
+
+ /* local reduction operations */
+ v->ops->nvdotprodlocal = w->ops->nvdotprodlocal;
+ v->ops->nvmaxnormlocal = w->ops->nvmaxnormlocal;
+ v->ops->nvminlocal = w->ops->nvminlocal;
+ v->ops->nvl1normlocal = w->ops->nvl1normlocal;
+ v->ops->nvinvtestlocal = w->ops->nvinvtestlocal;
+ v->ops->nvconstrmasklocal = w->ops->nvconstrmasklocal;
+ v->ops->nvminquotientlocal = w->ops->nvminquotientlocal;
+ v->ops->nvwsqrsumlocal = w->ops->nvwsqrsumlocal;
+ v->ops->nvwsqrsummasklocal = w->ops->nvwsqrsummasklocal;
+
+ /* XBraid interface operations */
+ v->ops->nvbufsize = w->ops->nvbufsize;
+ v->ops->nvbufpack = w->ops->nvbufpack;
+ v->ops->nvbufunpack = w->ops->nvbufunpack;
+
+ /* debugging functions (called when SUNDIALS_DEBUG_PRINTVEC is defined) */
+ v->ops->nvprint = w->ops->nvprint;
+ v->ops->nvprintfile = w->ops->nvprintfile;
+# endif
+
+ return (0);
+ }
+ } // namespace internal
+} // namespace SUNDIALS
+DEAL_II_NAMESPACE_CLOSE
+
+#endif // DEAL_II_WITH_SUNDIALS
+#endif // dealii_sundials_sunlinsol_newempty_h
#include <deal.II/sundials/n_vector.templates.h>
#ifdef DEAL_II_WITH_SUNDIALS
-# if DEAL_II_SUNDIALS_VERSION_GTE(5, 0, 0)
DEAL_II_NAMESPACE_OPEN
-# include "n_vector.inst"
+# include "n_vector.inst"
DEAL_II_NAMESPACE_CLOSE
-# endif
#endif
\ No newline at end of file
template V<S> * SUNDIALS::internal::unwrap_nvector<V<S>>(N_Vector);
template const V<S> *SUNDIALS::internal::unwrap_nvector_const<V<S>>(
N_Vector);
+
+ template class SUNDIALS::internal::NVectorView<V<S>>;
+ template class SUNDIALS::internal::NVectorView<const V<S>>;
}
// parallel Vector and BlockVector
N_Vector);
template const LinearAlgebra::distributed::V<S> *SUNDIALS::internal::
unwrap_nvector_const<LinearAlgebra::distributed::V<S>>(N_Vector);
+
+ template class SUNDIALS::internal::NVectorView<
+ LinearAlgebra::distributed::V<S>>;
+ template class SUNDIALS::internal::NVectorView<
+ const LinearAlgebra::distributed::V<S>>;
}
+#ifdef DEAL_II_WITH_TRILINOS
// TrilinosWrappers Vector and BlockVector
for (V : DEAL_II_VEC_TEMPLATES)
{
template const TrilinosWrappers::MPI::V
*SUNDIALS::internal::unwrap_nvector_const<TrilinosWrappers::MPI::V>(
N_Vector);
+
+ template class SUNDIALS::internal::NVectorView<TrilinosWrappers::MPI::V>;
+ template class SUNDIALS::internal::NVectorView<
+ const TrilinosWrappers::MPI::V>;
}
+#endif
+template <typename VectorType>
+void
+test_min_element()
+{
+ const auto vector_a = create_test_vector<VectorType>(2.0);
+ const auto vector_b = create_test_vector<VectorType>(-3.0);
+
+ auto nv_a = make_nvector_view(vector_a);
+ auto nv_b = make_nvector_view(vector_b);
+
+ auto result = N_VMin(nv_a);
+ std::cout << "result: " << result << std::endl;
+ vector_a.print(std::cout);
+ Assert(std::fabs(result - 2.0) < 1e-12, NVectorTestError());
+
+ result = N_VMin(nv_b);
+ Assert(std::fabs(result - (-3.0)) < 1e-12, NVectorTestError());
+
+ deallog << "test_min_element OK" << std::endl;
+}
+
+
+
template <typename VectorType>
void
test_scale()
test_elementwise_abs<VectorType>();
test_weighted_rms_norm<VectorType>();
test_max_norm<VectorType>();
+ test_min_element<VectorType>();
test_scale<VectorType>();
}
DEAL:0:Vector<double>::test_elementwise_abs OK
DEAL:0:Vector<double>::test_weighted_rms_norm OK
DEAL:0:Vector<double>::test_max_norm OK
+DEAL:0:Vector<double>::test_min_element OK
DEAL:0:Vector<double>::test_scale OK
DEAL:0:BlockVector<double>::test_nvector_view_unwrap OK
DEAL:0:BlockVector<double>::test_get_vector_id OK
DEAL:0:BlockVector<double>::test_elementwise_abs OK
DEAL:0:BlockVector<double>::test_weighted_rms_norm OK
DEAL:0:BlockVector<double>::test_max_norm OK
+DEAL:0:BlockVector<double>::test_min_element OK
DEAL:0:BlockVector<double>::test_scale OK
DEAL:0:LinearAlgebra::distributed::Vector<double>::test_nvector_view_unwrap OK
DEAL:0:LinearAlgebra::distributed::Vector<double>::test_get_vector_id OK
DEAL:0:LinearAlgebra::distributed::Vector<double>::test_elementwise_abs OK
DEAL:0:LinearAlgebra::distributed::Vector<double>::test_weighted_rms_norm OK
DEAL:0:LinearAlgebra::distributed::Vector<double>::test_max_norm OK
+DEAL:0:LinearAlgebra::distributed::Vector<double>::test_min_element OK
DEAL:0:LinearAlgebra::distributed::Vector<double>::test_scale OK
DEAL:0:LinearAlgebra::distributed::BlockVector<double>::test_nvector_view_unwrap OK
DEAL:0:LinearAlgebra::distributed::BlockVector<double>::test_get_vector_id OK
DEAL:0:LinearAlgebra::distributed::BlockVector<double>::test_elementwise_abs OK
DEAL:0:LinearAlgebra::distributed::BlockVector<double>::test_weighted_rms_norm OK
DEAL:0:LinearAlgebra::distributed::BlockVector<double>::test_max_norm OK
+DEAL:0:LinearAlgebra::distributed::BlockVector<double>::test_min_element OK
DEAL:0:LinearAlgebra::distributed::BlockVector<double>::test_scale OK
DEAL:0:TrilinosWrappers::MPI::Vector::test_nvector_view_unwrap OK
DEAL:0:TrilinosWrappers::MPI::Vector::test_get_vector_id OK
DEAL:0:TrilinosWrappers::MPI::Vector::test_elementwise_abs OK
DEAL:0:TrilinosWrappers::MPI::Vector::test_weighted_rms_norm OK
DEAL:0:TrilinosWrappers::MPI::Vector::test_max_norm OK
+DEAL:0:TrilinosWrappers::MPI::Vector::test_min_element OK
DEAL:0:TrilinosWrappers::MPI::Vector::test_scale OK
DEAL:0:Vector<double>::test_elementwise_abs OK
DEAL:0:Vector<double>::test_weighted_rms_norm OK
DEAL:0:Vector<double>::test_max_norm OK
+DEAL:0:Vector<double>::test_min_element OK
DEAL:0:Vector<double>::test_scale OK
DEAL:0:BlockVector<double>::test_nvector_view_unwrap OK
DEAL:0:BlockVector<double>::test_get_vector_id OK
DEAL:0:BlockVector<double>::test_elementwise_abs OK
DEAL:0:BlockVector<double>::test_weighted_rms_norm OK
DEAL:0:BlockVector<double>::test_max_norm OK
+DEAL:0:BlockVector<double>::test_min_element OK
DEAL:0:BlockVector<double>::test_scale OK
DEAL:0:LinearAlgebra::distributed::Vector<double>::test_nvector_view_unwrap OK
DEAL:0:LinearAlgebra::distributed::Vector<double>::test_get_vector_id OK
DEAL:0:LinearAlgebra::distributed::Vector<double>::test_elementwise_abs OK
DEAL:0:LinearAlgebra::distributed::Vector<double>::test_weighted_rms_norm OK
DEAL:0:LinearAlgebra::distributed::Vector<double>::test_max_norm OK
+DEAL:0:LinearAlgebra::distributed::Vector<double>::test_min_element OK
DEAL:0:LinearAlgebra::distributed::Vector<double>::test_scale OK
DEAL:0:LinearAlgebra::distributed::BlockVector<double>::test_nvector_view_unwrap OK
DEAL:0:LinearAlgebra::distributed::BlockVector<double>::test_get_vector_id OK
DEAL:0:LinearAlgebra::distributed::BlockVector<double>::test_elementwise_abs OK
DEAL:0:LinearAlgebra::distributed::BlockVector<double>::test_weighted_rms_norm OK
DEAL:0:LinearAlgebra::distributed::BlockVector<double>::test_max_norm OK
+DEAL:0:LinearAlgebra::distributed::BlockVector<double>::test_min_element OK
DEAL:0:LinearAlgebra::distributed::BlockVector<double>::test_scale OK
DEAL:0:TrilinosWrappers::MPI::Vector::test_nvector_view_unwrap OK
DEAL:0:TrilinosWrappers::MPI::Vector::test_get_vector_id OK
DEAL:0:TrilinosWrappers::MPI::Vector::test_elementwise_abs OK
DEAL:0:TrilinosWrappers::MPI::Vector::test_weighted_rms_norm OK
DEAL:0:TrilinosWrappers::MPI::Vector::test_max_norm OK
+DEAL:0:TrilinosWrappers::MPI::Vector::test_min_element OK
DEAL:0:TrilinosWrappers::MPI::Vector::test_scale OK
DEAL:1:Vector<double>::test_nvector_view_unwrap OK
DEAL:1:Vector<double>::test_elementwise_abs OK
DEAL:1:Vector<double>::test_weighted_rms_norm OK
DEAL:1:Vector<double>::test_max_norm OK
+DEAL:1:Vector<double>::test_min_element OK
DEAL:1:Vector<double>::test_scale OK
DEAL:1:BlockVector<double>::test_nvector_view_unwrap OK
DEAL:1:BlockVector<double>::test_get_vector_id OK
DEAL:1:BlockVector<double>::test_elementwise_abs OK
DEAL:1:BlockVector<double>::test_weighted_rms_norm OK
DEAL:1:BlockVector<double>::test_max_norm OK
+DEAL:1:BlockVector<double>::test_min_element OK
DEAL:1:BlockVector<double>::test_scale OK
DEAL:1:LinearAlgebra::distributed::Vector<double>::test_nvector_view_unwrap OK
DEAL:1:LinearAlgebra::distributed::Vector<double>::test_get_vector_id OK
DEAL:1:LinearAlgebra::distributed::Vector<double>::test_elementwise_abs OK
DEAL:1:LinearAlgebra::distributed::Vector<double>::test_weighted_rms_norm OK
DEAL:1:LinearAlgebra::distributed::Vector<double>::test_max_norm OK
+DEAL:1:LinearAlgebra::distributed::Vector<double>::test_min_element OK
DEAL:1:LinearAlgebra::distributed::Vector<double>::test_scale OK
DEAL:1:LinearAlgebra::distributed::BlockVector<double>::test_nvector_view_unwrap OK
DEAL:1:LinearAlgebra::distributed::BlockVector<double>::test_get_vector_id OK
DEAL:1:LinearAlgebra::distributed::BlockVector<double>::test_elementwise_abs OK
DEAL:1:LinearAlgebra::distributed::BlockVector<double>::test_weighted_rms_norm OK
DEAL:1:LinearAlgebra::distributed::BlockVector<double>::test_max_norm OK
+DEAL:1:LinearAlgebra::distributed::BlockVector<double>::test_min_element OK
DEAL:1:LinearAlgebra::distributed::BlockVector<double>::test_scale OK
DEAL:1:TrilinosWrappers::MPI::Vector::test_nvector_view_unwrap OK
DEAL:1:TrilinosWrappers::MPI::Vector::test_get_vector_id OK
DEAL:1:TrilinosWrappers::MPI::Vector::test_elementwise_abs OK
DEAL:1:TrilinosWrappers::MPI::Vector::test_weighted_rms_norm OK
DEAL:1:TrilinosWrappers::MPI::Vector::test_max_norm OK
+DEAL:1:TrilinosWrappers::MPI::Vector::test_min_element OK
DEAL:1:TrilinosWrappers::MPI::Vector::test_scale OK