realtype
dot_product(N_Vector x, N_Vector y);
+ template <typename VectorType>
+ realtype
+ weighted_l2_norm(N_Vector x, N_Vector y);
+
+ template <typename VectorType>
+ realtype
+ l1_norm(N_Vector x);
+
template <typename VectorType>
void
elementwise_product(N_Vector x, N_Vector y, N_Vector z);
+template <typename VectorType>
+realtype
+SUNDIALS::internal::NVectorOperations::weighted_l2_norm(N_Vector x, N_Vector w)
+{
+ // TODO copy can be avoided by a custom kernel
+ VectorType tmp = *unwrap_nvector_const<VectorType>(x);
+ auto * w_dealii = unwrap_nvector_const<VectorType>(w);
+ tmp.scale(*w_dealii);
+ return tmp.l2_norm();
+}
+
+
+
+template <typename VectorType>
+realtype
+SUNDIALS::internal::NVectorOperations::l1_norm(N_Vector x)
+{
+ return unwrap_nvector_const<VectorType>(x)->l1_norm();
+}
+
+
+
template <typename VectorType>
void
SUNDIALS::internal::NVectorOperations::set_constant(realtype c, N_Vector v)
v->ops->nvmaxnorm = NVectorOperations::max_norm<VectorType>;
v->ops->nvwrmsnorm = NVectorOperations::weighted_rms_norm<VectorType>;
// v->ops->nvwrmsnormmask = undef;
- v->ops->nvmin = NVectorOperations::min_element<VectorType>;
- // v->ops->nvwl2norm = undef;
- // v->ops->nvl1norm = undef;
+ v->ops->nvmin = NVectorOperations::min_element<VectorType>;
+ v->ops->nvwl2norm = NVectorOperations::weighted_l2_norm<VectorType>;
+ v->ops->nvl1norm = NVectorOperations::l1_norm<VectorType>;
+ ;
// v->ops->nvcompare = undef;
// v->ops->nvinvtest = undef;
// v->ops->nvconstrmask = undef;
# include <deal.II/lac/petsc_vector.h>
# endif
-# include <deal.II/sundials/copy.h>
+# include <deal.II/sundials/n_vector.h>
// Make sure we #include the SUNDIALS config file...
# include <sundials/sundials_config.h>
{
KINSOL<VectorType> &solver =
*static_cast<KINSOL<VectorType> *>(user_data);
- GrowingVectorMemory<VectorType> mem;
- typename VectorMemory<VectorType>::Pointer src_yy(mem);
- solver.reinit_vector(*src_yy);
-
- typename VectorMemory<VectorType>::Pointer dst_FF(mem);
- solver.reinit_vector(*dst_FF);
-
- copy(*src_yy, yy);
+ auto *src_yy = internal::unwrap_nvector_const<VectorType>(yy);
+ auto *dst_FF = internal::unwrap_nvector<VectorType>(FF);
int err = 0;
if (solver.residual)
else
Assert(false, ExcInternalError());
- copy(FF, *dst_FF);
-
return err;
}
{
KINSOL<VectorType> &solver =
*static_cast<KINSOL<VectorType> *>(kinsol_mem->kin_user_data);
- GrowingVectorMemory<VectorType> mem;
- typename VectorMemory<VectorType>::Pointer src_ycur(mem);
- solver.reinit_vector(*src_ycur);
-
- typename VectorMemory<VectorType>::Pointer src_fcur(mem);
- solver.reinit_vector(*src_fcur);
-
- copy(*src_ycur, kinsol_mem->kin_uu);
- copy(*src_fcur, kinsol_mem->kin_fval);
+ auto *src_ycur =
+ internal::unwrap_nvector_const<VectorType>(kinsol_mem->kin_uu);
+ auto *src_fcur =
+ internal::unwrap_nvector_const<VectorType>(kinsol_mem->kin_fval);
int err = solver.setup_jacobian(*src_ycur, *src_fcur);
return err;
{
KINSOL<VectorType> &solver =
*static_cast<KINSOL<VectorType> *>(kinsol_mem->kin_user_data);
- GrowingVectorMemory<VectorType> mem;
-
- typename VectorMemory<VectorType>::Pointer src_ycur(mem);
- solver.reinit_vector(*src_ycur);
- typename VectorMemory<VectorType>::Pointer src_fcur(mem);
- solver.reinit_vector(*src_fcur);
-
- copy(*src_ycur, kinsol_mem->kin_uu);
- copy(*src_fcur, kinsol_mem->kin_fval);
-
- typename VectorMemory<VectorType>::Pointer src(mem);
- solver.reinit_vector(*src);
-
- typename VectorMemory<VectorType>::Pointer dst(mem);
- solver.reinit_vector(*dst);
-
- copy(*src, b);
+ auto *src_ycur =
+ internal::unwrap_nvector_const<VectorType>(kinsol_mem->kin_uu);
+ auto *src_fcur =
+ internal::unwrap_nvector_const<VectorType>(kinsol_mem->kin_fval);
+ auto *src = internal::unwrap_nvector_const<VectorType>(b);
+ auto *dst = internal::unwrap_nvector<VectorType>(x);
int err = solver.solve_jacobian_system(*src_ycur, *src_fcur, *src, *dst);
- copy(x, *dst);
*sJpnorm = N_VWL2Norm(b, kinsol_mem->kin_fscale);
N_VProd(b, kinsol_mem->kin_fscale, b);
const KINSOL<VectorType> &solver =
*static_cast<const KINSOL<VectorType> *>(user_data);
- // Allocate temporary (deal.II-type) vectors into which to copy the
- // N_vectors
- GrowingVectorMemory<VectorType> mem;
- typename VectorMemory<VectorType>::Pointer ycur(mem);
- typename VectorMemory<VectorType>::Pointer fcur(mem);
- solver.reinit_vector(*ycur);
- solver.reinit_vector(*fcur);
-
- copy(*ycur, u);
- copy(*fcur, f);
+ auto *ycur = internal::unwrap_nvector_const<VectorType>(u);
+ auto *fcur = internal::unwrap_nvector_const<VectorType>(f);
// Call the user-provided setup function with these arguments:
solver.setup_jacobian(*ycur, *fcur);
// signals to call. Let's first check the more modern one:
if (solver.solve_with_jacobian)
{
- // Allocate temporary (deal.II-type) vectors into which to copy the
- // N_vectors
- GrowingVectorMemory<VectorType> mem;
- typename VectorMemory<VectorType>::Pointer src_b(mem);
- typename VectorMemory<VectorType>::Pointer dst_x(mem);
-
- solver.reinit_vector(*src_b);
- solver.reinit_vector(*dst_x);
-
- copy(*src_b, b);
+ auto *src_b = internal::unwrap_nvector<VectorType>(b);
+ auto *dst_x = internal::unwrap_nvector<VectorType>(x);
const int err = solver.solve_with_jacobian(*src_b, *dst_x, tol);
- copy(x, *dst_x);
-
return err;
}
else
GrowingVectorMemory<VectorType> mem;
typename VectorMemory<VectorType>::Pointer src_ycur(mem);
typename VectorMemory<VectorType>::Pointer src_fcur(mem);
- typename VectorMemory<VectorType>::Pointer src_b(mem);
- typename VectorMemory<VectorType>::Pointer dst_x(mem);
-
- solver.reinit_vector(*src_b);
- solver.reinit_vector(*dst_x);
- copy(*src_b, b);
+ auto *src_b = internal::unwrap_nvector_const<VectorType>(b);
+ auto *dst_x = internal::unwrap_nvector<VectorType>(x);
// Call the user-provided setup function with these arguments. Note
// that Sundials 4.x and later no longer provide values for
const int err =
solver.solve_jacobian_system(*src_ycur, *src_fcur, *src_b, *dst_x);
- copy(x, *dst_x);
-
return err;
}
}
const MPI_Comm & mpi_comm)
: data(data)
, kinsol_mem(nullptr)
- , solution(nullptr)
- , u_scale(nullptr)
- , f_scale(nullptr)
, communicator(is_serial_vector<VectorType>::value ?
MPI_COMM_SELF :
Utilities::MPI::duplicate_communicator(mpi_comm))
{
unsigned int system_size = initial_guess_and_solution.size();
- // The solution is stored in
- // solution. Here we take only a
- // view of it.
-# ifdef DEAL_II_WITH_MPI
- if (is_serial_vector<VectorType>::value == false)
- {
- const IndexSet is = initial_guess_and_solution.locally_owned_elements();
- const unsigned int local_system_size = is.n_elements();
-
- solution =
- N_VNew_Parallel(communicator, local_system_size, system_size);
+ NVectorView<VectorType> u_scale, f_scale;
- u_scale = N_VNew_Parallel(communicator, local_system_size, system_size);
- N_VConst_Parallel(1.e0, u_scale);
+ VectorType u_scale_temp, f_scale_temp;
- f_scale = N_VNew_Parallel(communicator, local_system_size, system_size);
- N_VConst_Parallel(1.e0, f_scale);
- }
+ if (get_solution_scaling)
+ u_scale = internal::make_nvector_view(get_solution_scaling());
else
-# endif
{
- Assert(is_serial_vector<VectorType>::value,
- ExcInternalError(
- "Trying to use a serial code with a parallel vector."));
- solution = N_VNew_Serial(system_size);
- u_scale = N_VNew_Serial(system_size);
- N_VConst_Serial(1.e0, u_scale);
- f_scale = N_VNew_Serial(system_size);
- N_VConst_Serial(1.e0, f_scale);
+ reinit_vector(u_scale_temp);
+ u_scale_temp = 1.0;
+ u_scale = internal::make_nvector_view(u_scale_temp);
}
- if (get_solution_scaling)
- copy(u_scale, get_solution_scaling());
-
if (get_function_scaling)
- copy(f_scale, get_function_scaling());
+ f_scale = internal::make_nvector_view(get_function_scaling());
+ else
+ {
+ reinit_vector(f_scale_temp);
+ f_scale_temp = 1.0;
+ f_scale = internal::make_nvector_view(f_scale_temp);
+ }
- copy(solution, initial_guess_and_solution);
+ auto solution = internal::make_nvector_view(initial_guess_and_solution);
if (kinsol_mem)
KINFree(&kinsol_mem);
status = KINSol(kinsol_mem, solution, data.strategy, u_scale, f_scale);
AssertKINSOL(status);
- copy(initial_guess_and_solution, solution);
-
- // Free the vectors which are no longer used.
-# ifdef DEAL_II_WITH_MPI
- if (is_serial_vector<VectorType>::value == false)
- {
- N_VDestroy_Parallel(solution);
- N_VDestroy_Parallel(u_scale);
- N_VDestroy_Parallel(f_scale);
- }
- else
-# endif
- {
- N_VDestroy_Serial(solution);
- N_VDestroy_Serial(u_scale);
- N_VDestroy_Serial(f_scale);
- }
-
long nniters;
status = KINGetNumNonlinSolvIters(kinsol_mem, &nniters);
AssertKINSOL(status);