deal.II version GIT relicensing-6842-g793a97d2aa 2026-10-02 14:00:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
rol_adaptor.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2017 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_trilinos_rol_adaptor_h
14#define dealii_trilinos_rol_adaptor_h
15
16#include <deal.II/base/config.h>
17
18#ifdef DEAL_II_TRILINOS_WITH_ROL
21# include <deal.II/base/mpi.h>
22# include <deal.II/base/types.h>
23
24# include <ROL_Vector.hpp>
25
26# include <limits>
27# include <tuple>
28# include <type_traits>
29
30#endif // DEAL_II_TRILINOS_WITH_ROL
31
33
34#ifdef DEAL_II_TRILINOS_WITH_ROL
35namespace TrilinosWrappers
36{
125 template <typename VectorType>
126 class ROLAdaptor : public ROL::Vector<typename VectorType::value_type>
127 {
131 using size_type = typename VectorType::size_type;
132
136 using value_type = typename VectorType::value_type;
137
141 using real_type = typename VectorType::real_type;
142
143 static_assert(std::is_convertible_v<real_type, value_type>,
144 "The real_type of the current VectorType is not "
145 "convertible to the value_type.");
146
147 private:
151 ROL::Ptr<VectorType> vector_ptr;
152
157
162
171
172 public:
180 ROLAdaptor(const ROL::Ptr<VectorType> &vector_ptr);
181
192 ROLAdaptor(const ROL::Ptr<VectorType> &vector_ptr,
194
198 ROL::Ptr<VectorType>
200
204 ROL::Ptr<const VectorType>
205 getVector() const;
206
210 int
211 dimension() const override;
212
223 void
224 set(const ROL::Vector<value_type> &rol_vector) override;
225
235 void
236 plus(const ROL::Vector<value_type> &rol_vector) override;
237
247 void
248 axpy(const value_type alpha,
249 const ROL::Vector<value_type> &rol_vector) override;
250
257 void
258 scale(const value_type alpha) override;
259
270 dot(const ROL::Vector<value_type> &rol_vector) const override;
271
285 norm() const override;
286
292 ROL::Ptr<ROL::Vector<value_type>>
293 clone() const override;
294
299 ROL::Ptr<ROL::Vector<value_type>>
300 basis(const int i) const override;
301
308 void
309 applyUnary(const ROL::Elementwise::UnaryFunction<value_type> &f) override;
310
321 void
322 applyBinary(const ROL::Elementwise::BinaryFunction<value_type> &f,
323 const ROL::Vector<value_type> &rol_vector) override;
324
333 reduce(const ROL::Elementwise::ReductionOp<value_type> &r) const override;
334
341 void
342 print(std::ostream &outStream) const override;
343 };
344
345
346 /*------------------------------member definitions--------------------------*/
347# ifndef DOXYGEN
348
349
350 template <typename VectorType>
351 ROLAdaptor<VectorType>::ROLAdaptor(const ROL::Ptr<VectorType> &vector_ptr)
352 : ROLAdaptor(vector_ptr, vector_ptr->locally_owned_elements())
353 {}
354
355
356
357 template <typename VectorType>
358 ROLAdaptor<VectorType>::ROLAdaptor(const ROL::Ptr<VectorType> &vector_ptr,
359 const IndexSet &optimization_space)
360 : vector_ptr(vector_ptr)
361 , optimization_space(optimization_space)
362 {
363 Assert(
364 optimization_space.is_subset_of(vector_ptr->locally_owned_elements()),
366 "Provided IndexSet needs to be a subset of locally owned indices."));
367
370 vector_ptr->get_mpi_communicator());
371
372 // The return type of ROL::Vector::dimension() has to be int,
373 // so we check this requirement of ROL here.
375 std::numeric_limits<int>::max()),
376 ExcMessage("The number of elements to optimize is greater than the "
377 "largest value of type int."));
378 }
379
380
381
382 template <typename VectorType>
383 ROL::Ptr<VectorType>
385 {
386 return vector_ptr;
387 }
388
389
390
391 template <typename VectorType>
392 ROL::Ptr<const VectorType>
394 {
395 return vector_ptr;
396 }
397
398
399
400 template <typename VectorType>
401 void
402 ROLAdaptor<VectorType>::set(const ROL::Vector<value_type> &other_)
403 {
404 Assert(dynamic_cast<const ROLAdaptor *>(&other_) != nullptr,
406 const ROLAdaptor &other = dynamic_cast<const ROLAdaptor &>(other_);
407
408 // Perform a deep copy of the vector pointed to by vector_ptr.
409 (*vector_ptr) = *(other.getVector());
410
411 optimization_space = other.optimization_space;
412 global_opt_dimension = other.global_opt_dimension;
413 local_opt_start_index = other.local_opt_start_index;
414 }
415
416
417
418 template <typename VectorType>
419 void
420 ROLAdaptor<VectorType>::plus(const ROL::Vector<value_type> &other_)
421 {
422 Assert(dynamic_cast<const ROLAdaptor *>(&other_) != nullptr,
424 const ROLAdaptor &other = dynamic_cast<const ROLAdaptor &>(other_);
425
426 Assert(vector_ptr->has_ghost_elements() == false, ExcGhostsPresent());
427 Assert(optimization_space.size() == vector_ptr->size(),
428 ExcMessage("Optimization space is out-of-sync. "
429 "Please create a new wrapper."));
430 Assert(optimization_space == other.optimization_space,
431 ExcMessage("Optimization spaces of vectors do not match."));
432
433 for (const auto i : optimization_space)
434 (*vector_ptr)[i] += (*other.getVector())[i];
435
436 vector_ptr->compress(VectorOperation::add);
437 }
438
439
440
441 template <typename VectorType>
442 void
444 const ROL::Vector<value_type> &other_)
445 {
446 Assert(dynamic_cast<const ROLAdaptor *>(&other_) != nullptr,
448 const ROLAdaptor &other = dynamic_cast<const ROLAdaptor &>(other_);
449
450 Assert(vector_ptr->has_ghost_elements() == false, ExcGhostsPresent());
451 Assert(optimization_space.size() == vector_ptr->size(),
452 ExcMessage("Optimization space is out-of-sync. "
453 "Please create a new wrapper."));
454 Assert(optimization_space == other.optimization_space,
455 ExcMessage("Optimization spaces of vectors do not match."));
456
457 for (const auto i : optimization_space)
458 (*vector_ptr)[i] += alpha * (*other.getVector())[i];
459
460 vector_ptr->compress(VectorOperation::add);
461 }
462
463
464
465 template <typename VectorType>
466 int
468 {
469 Assert(optimization_space.size() == vector_ptr->size(),
470 ExcMessage("Optimization space is out-of-sync. "
471 "Please create a new wrapper."));
472
473 return static_cast<int>(global_opt_dimension);
474 }
475
476
477
478 template <typename VectorType>
479 void
481 {
482 Assert(vector_ptr->has_ghost_elements() == false, ExcGhostsPresent());
483 Assert(optimization_space.size() == vector_ptr->size(),
484 ExcMessage("Optimization space is out-of-sync. "
485 "Please create a new wrapper."));
486
487 for (const auto i : optimization_space)
488 (*vector_ptr)[i] *= alpha;
489
490 vector_ptr->compress(VectorOperation::insert);
491 }
492
493
494
495 template <typename VectorType>
496 typename VectorType::value_type
497 ROLAdaptor<VectorType>::dot(const ROL::Vector<value_type> &other_) const
498 {
499 Assert(dynamic_cast<const ROLAdaptor *>(&other_) != nullptr,
501 const ROLAdaptor &other = dynamic_cast<const ROLAdaptor &>(other_);
502
503 Assert(optimization_space.size() == vector_ptr->size(),
504 ExcMessage("Optimization space is out-of-sync. "
505 "Please create a new wrapper."));
506 Assert(optimization_space == other.optimization_space,
507 ExcMessage("Optimization spaces of vectors do not match."));
508
509 value_type dot(0);
510 for (const auto i : optimization_space)
511 dot += (*vector_ptr)[i] * (*other.getVector())[i];
512
513 return Utilities::MPI::sum<value_type>(dot,
514 vector_ptr->get_mpi_communicator());
515 }
516
517
518
519 template <typename VectorType>
520 typename VectorType::value_type
522 {
523 return std::sqrt(this->dot(*this));
524 }
525
526
527
528 template <typename VectorType>
529 ROL::Ptr<ROL::Vector<typename VectorType::value_type>>
531 {
532 // create new vector with same size as wrapped one
533 ROL::Ptr<VectorType> clone_ptr = ROL::makePtr<VectorType>();
534 clone_ptr->reinit(*vector_ptr, false);
535
536 return ROL::makePtr<ROLAdaptor>(clone_ptr, optimization_space);
537 // TODO: also somehow pass the partial sums etc?
538 }
539
540
541
542 template <typename VectorType>
543 ROL::Ptr<ROL::Vector<typename VectorType::value_type>>
544 ROLAdaptor<VectorType>::basis(const int global_opt_index) const
545 {
546 Assert(optimization_space.size() == vector_ptr->size(),
547 ExcMessage("Optimization space is out-of-sync. "
548 "Please create a new wrapper."));
549 AssertIndexRange(global_opt_index, global_opt_dimension);
550
551 // clone the internal vector as basis
552 ROL::Ptr<VectorType> basis_ptr = ROL::makePtr<VectorType>();
553 basis_ptr->reinit(*vector_ptr, false);
554
555 // check whether the i-th basis corresponds to one of the
556 // locally owned elements of the wrapped vector
557 if ((global_opt_index >= local_opt_start_index) &&
558 (global_opt_index <
559 local_opt_start_index + optimization_space.n_elements()))
560 {
561 const ::types::global_dof_index local_opt_index =
562 global_opt_index - local_opt_start_index;
563
564 // global dof index corresponding to i-th basis in optimization
565 const ::types::global_dof_index global_dof_index =
566 optimization_space.nth_index_in_set(local_opt_index);
567
568 (*basis_ptr)[global_dof_index] = 1.;
569 }
570
571 basis_ptr->compress(VectorOperation::insert);
572
573 return ROL::makePtr<ROLAdaptor>(basis_ptr, optimization_space);
574 // TODO: also somehow pass the partial sums etc?
575 }
576
577
578
579 template <typename VectorType>
580 void
582 const ROL::Elementwise::UnaryFunction<value_type> &f)
583 {
584 Assert(vector_ptr->has_ghost_elements() == false, ExcGhostsPresent());
585 Assert(optimization_space.size() == vector_ptr->size(),
586 ExcMessage("Optimization space is out-of-sync. "
587 "Please create a new wrapper."));
588
589 for (const auto i : optimization_space)
590 (*vector_ptr)[i] = f.apply((*vector_ptr)[i]);
591
592 vector_ptr->compress(VectorOperation::insert);
593 }
594
595
596
597 template <typename VectorType>
598 void
600 const ROL::Elementwise::BinaryFunction<value_type> &f,
601 const ROL::Vector<value_type> &other_)
602 {
603 Assert(dynamic_cast<const ROLAdaptor *>(&other_) != nullptr,
605 const ROLAdaptor &other = dynamic_cast<const ROLAdaptor &>(other_);
606
607 Assert(vector_ptr->has_ghost_elements() == false, ExcGhostsPresent());
608 Assert(optimization_space.size() == vector_ptr->size(),
609 ExcMessage("Optimization space is out-of-sync. "
610 "Please create a new wrapper."));
611 Assert(optimization_space == other.optimization_space,
612 ExcMessage("Optimization spaces of vectors do not match."));
613
614 for (const auto i : optimization_space)
615 (*vector_ptr)[i] = f.apply((*vector_ptr)[i], (*other.getVector())[i]);
616
617 vector_ptr->compress(VectorOperation::insert);
618 }
619
620
621
622 template <typename VectorType>
623 typename VectorType::value_type
625 const ROL::Elementwise::ReductionOp<value_type> &r) const
626 {
627 Assert(optimization_space.size() == vector_ptr->size(),
628 ExcMessage("Optimization space is out-of-sync. "
629 "Please create a new wrapper."));
630
631 value_type result = r.initialValue();
632
633 // local reduction
634 for (const auto i : optimization_space)
635 r.reduce((*vector_ptr)[i], result);
636
637 // global reduction
638 const auto combiner = [&r](const value_type a,
639 const value_type b) -> value_type {
640 auto out = b;
641 r.reduce(a, out);
642 return out;
643 };
644
645 return Utilities::MPI::all_reduce<value_type>(
646 result, vector_ptr->get_mpi_communicator(), combiner);
647 }
648
649
650
651 template <typename VectorType>
652 void
653 ROLAdaptor<VectorType>::print(std::ostream &outStream) const
654 {
655 vector_ptr->print(outStream);
656 }
657
658
659# endif // DOXYGEN
660
661
662} // namespace TrilinosWrappers
663
664#endif // DEAL_II_TRILINOS_WITH_ROL
665
667
668#endif // dealii_trilinos_rol_adaptor_h
bool is_subset_of(const IndexSet &other) const
Definition index_set.cc:691
size_type size() const
Definition index_set.h:1759
size_type n_elements() const
Definition index_set.h:1917
size_type nth_index_in_set(const size_type local_index) const
Definition index_set.h:1958
void applyUnary(const ROL::Elementwise::UnaryFunction< value_type > &f) override
value_type reduce(const ROL::Elementwise::ReductionOp< value_type > &r) const override
::types::global_dof_index global_opt_dimension
void set(const ROL::Vector< value_type > &rol_vector) override
ROL::Ptr< const VectorType > getVector() const
ROL::Ptr< VectorType > vector_ptr
value_type dot(const ROL::Vector< value_type > &rol_vector) const override
void axpy(const value_type alpha, const ROL::Vector< value_type > &rol_vector) override
void print(std::ostream &outStream) const override
int dimension() const override
typename VectorType::size_type size_type
void scale(const value_type alpha) override
::types::global_dof_index local_opt_start_index
void plus(const ROL::Vector< value_type > &rol_vector) override
ROL::Ptr< VectorType > getVector()
value_type norm() const override
typename VectorType::real_type real_type
ROL::Ptr< ROL::Vector< value_type > > clone() const override
ROL::Ptr< ROL::Vector< value_type > > basis(const int i) const override
void applyBinary(const ROL::Elementwise::BinaryFunction< value_type > &f, const ROL::Vector< value_type > &rol_vector) override
ROLAdaptor(const ROL::Ptr< VectorType > &vector_ptr, const IndexSet &optimization_space)
typename VectorType::value_type value_type
ROLAdaptor(const ROL::Ptr< VectorType > &vector_ptr)
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
static ::ExceptionBase & ExcGhostsPresent()
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
void apply(const Kokkos::TeamPolicy< MemorySpace::Default::kokkos_space::execution_space >::member_type &team_member, const Kokkos::View< Number *, ShapeDataMemorySpace > shape_data, const ViewTypeIn in, ViewTypeOut out)
std::pair< T, T > partial_and_total_sum(const T &value, const MPI_Comm comm)
T reduce(const T &local_value, const MPI_Comm comm, const std::function< T(const T &, const T &)> &combiner, const unsigned int root_process=0)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
unsigned int global_dof_index
Definition types.h:92