Ginkgo Generated from branch based on master. Ginkgo version 1.7.0
A numerical linear algebra library targeting many-core architectures
Loading...
Searching...
No Matches
solver_base.hpp
1/*******************************<GINKGO LICENSE>******************************
2Copyright (c) 2017-2023, the Ginkgo authors
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions
7are met:
8
91. Redistributions of source code must retain the above copyright
10notice, this list of conditions and the following disclaimer.
11
122. Redistributions in binary form must reproduce the above copyright
13notice, this list of conditions and the following disclaimer in the
14documentation and/or other materials provided with the distribution.
15
163. Neither the name of the copyright holder nor the names of its
17contributors may be used to endorse or promote products derived from
18this software without specific prior written permission.
19
20THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31******************************<GINKGO LICENSE>*******************************/
32
33#ifndef GKO_PUBLIC_CORE_SOLVER_SOLVER_BASE_HPP_
34#define GKO_PUBLIC_CORE_SOLVER_SOLVER_BASE_HPP_
35
36
37#include <memory>
38#include <type_traits>
39#include <utility>
40
41
42#include <ginkgo/core/base/lin_op.hpp>
43#include <ginkgo/core/base/math.hpp>
44#include <ginkgo/core/log/logger.hpp>
45#include <ginkgo/core/matrix/dense.hpp>
46#include <ginkgo/core/matrix/identity.hpp>
47#include <ginkgo/core/solver/workspace.hpp>
48#include <ginkgo/core/stop/combined.hpp>
49#include <ginkgo/core/stop/criterion.hpp>
50
51
52GKO_BEGIN_DISABLE_DEPRECATION_WARNINGS
53
54
55namespace gko {
56namespace solver {
57
58
66 zero,
70 rhs,
75};
76
77
78namespace multigrid {
79namespace detail {
80
81
82class MultigridState;
83
84
85} // namespace detail
86} // namespace multigrid
87
88
95protected:
96 friend class multigrid::detail::MultigridState;
97
111 virtual void apply_with_initial_guess(const LinOp* b, LinOp* x,
112 initial_guess_mode guess) const = 0;
113
114 void apply_with_initial_guess(ptr_param<const LinOp> b, ptr_param<LinOp> x,
116 {
117 apply_with_initial_guess(b.get(), x.get(), guess);
118 }
119
132 virtual void apply_with_initial_guess(const LinOp* alpha, const LinOp* b,
133 const LinOp* beta, LinOp* x,
134 initial_guess_mode guess) const = 0;
135
136
137 void apply_with_initial_guess(ptr_param<const LinOp> alpha,
142 {
143 apply_with_initial_guess(alpha.get(), b.get(), beta.get(), x.get(),
144 guess);
145 }
146
152 initial_guess_mode get_default_initial_guess() const { return guess_; }
153
160 explicit ApplyWithInitialGuess(
162 : guess_(guess)
163 {}
164
170 void set_default_initial_guess(initial_guess_mode guess) { guess_ = guess; }
171
172private:
173 initial_guess_mode guess_;
174};
175
176
189template <typename DerivedType>
191protected:
192 friend class multigrid::detail::MultigridState;
193
197 {}
198
203 void apply_with_initial_guess(const LinOp* b, LinOp* x,
204 initial_guess_mode guess) const override
205 {
206 self()->template log<log::Logger::linop_apply_started>(self(), b, x);
207 auto exec = self()->get_executor();
208 GKO_ASSERT_CONFORMANT(self(), b);
209 GKO_ASSERT_EQUAL_ROWS(self(), x);
210 GKO_ASSERT_EQUAL_COLS(b, x);
211 this->apply_with_initial_guess_impl(make_temporary_clone(exec, b).get(),
212 make_temporary_clone(exec, x).get(),
213 guess);
214 self()->template log<log::Logger::linop_apply_completed>(self(), b, x);
215 }
216
221 void apply_with_initial_guess(const LinOp* alpha, const LinOp* b,
222 const LinOp* beta, LinOp* x,
223 initial_guess_mode guess) const override
224 {
226 self(), alpha, b, beta, x);
227 auto exec = self()->get_executor();
228 GKO_ASSERT_CONFORMANT(self(), b);
229 GKO_ASSERT_EQUAL_ROWS(self(), x);
230 GKO_ASSERT_EQUAL_COLS(b, x);
231 GKO_ASSERT_EQUAL_DIMENSIONS(alpha, dim<2>(1, 1));
232 GKO_ASSERT_EQUAL_DIMENSIONS(beta, dim<2>(1, 1));
233 this->apply_with_initial_guess_impl(
234 make_temporary_clone(exec, alpha).get(),
235 make_temporary_clone(exec, b).get(),
236 make_temporary_clone(exec, beta).get(),
237 make_temporary_clone(exec, x).get(), guess);
239 self(), alpha, b, beta, x);
240 }
241
242 // TODO: should we provide the default implementation?
247 virtual void apply_with_initial_guess_impl(
248 const LinOp* b, LinOp* x, initial_guess_mode guess) const = 0;
249
254 virtual void apply_with_initial_guess_impl(
255 const LinOp* alpha, const LinOp* b, const LinOp* beta, LinOp* x,
256 initial_guess_mode guess) const = 0;
257
258 GKO_ENABLE_SELF(DerivedType);
259};
260
261
266template <typename Solver>
268 // number of vectors used by this workspace
269 static int num_vectors(const Solver&) { return 0; }
270 // number of arrays used by this workspace
271 static int num_arrays(const Solver&) { return 0; }
272 // array containing the num_vectors names for the workspace vectors
273 static std::vector<std::string> op_names(const Solver&) { return {}; }
274 // array containing the num_arrays names for the workspace vectors
275 static std::vector<std::string> array_names(const Solver&) { return {}; }
276 // array containing all scalar vectors (independent of problem size)
277 static std::vector<int> scalars(const Solver&) { return {}; }
278 // array containing all vectors (dependent on problem size)
279 static std::vector<int> vectors(const Solver&) { return {}; }
280};
281
282
298template <typename DerivedType>
300public:
307 void set_preconditioner(std::shared_ptr<const LinOp> new_precond) override
308 {
309 auto exec = self()->get_executor();
310 if (new_precond) {
311 GKO_ASSERT_EQUAL_DIMENSIONS(self(), new_precond);
312 GKO_ASSERT_IS_SQUARE_MATRIX(new_precond);
313 if (new_precond->get_executor() != exec) {
315 }
316 }
318 }
319
325 {
326 if (&other != this) {
327 set_preconditioner(other.get_preconditioner());
328 }
329 return *this;
330 }
331
338 {
339 if (&other != this) {
340 set_preconditioner(other.get_preconditioner());
341 other.set_preconditioner(nullptr);
342 }
343 return *this;
344 }
345
346 EnablePreconditionable() = default;
347
348 EnablePreconditionable(std::shared_ptr<const LinOp> preconditioner)
349 {
350 set_preconditioner(std::move(preconditioner));
351 }
352
360
366 {
367 *this = std::move(other);
368 }
369
370private:
371 DerivedType* self() { return static_cast<DerivedType*>(this); }
372
373 const DerivedType* self() const
374 {
375 return static_cast<const DerivedType*>(this);
376 }
377};
378
379
380namespace detail {
381
382
391class SolverBaseLinOp {
392public:
393 SolverBaseLinOp(std::shared_ptr<const Executor> exec)
394 : workspace_{std::move(exec)}
395 {}
396
397 virtual ~SolverBaseLinOp() = default;
398
404 std::shared_ptr<const LinOp> get_system_matrix() const
405 {
406 return system_matrix_;
407 }
408
409 const LinOp* get_workspace_op(int vector_id) const
410 {
411 return workspace_.get_op(vector_id);
412 }
413
414 virtual int get_num_workspace_ops() const { return 0; }
415
416 virtual std::vector<std::string> get_workspace_op_names() const
417 {
418 return {};
419 }
420
425 virtual std::vector<int> get_workspace_scalars() const { return {}; }
426
431 virtual std::vector<int> get_workspace_vectors() const { return {}; }
432
433protected:
434 void set_system_matrix_base(std::shared_ptr<const LinOp> system_matrix)
435 {
436 system_matrix_ = std::move(system_matrix);
437 }
438
439 void set_workspace_size(int num_operators, int num_arrays) const
440 {
441 workspace_.set_size(num_operators, num_arrays);
442 }
443
444 template <typename LinOpType>
445 LinOpType* create_workspace_op(int vector_id, gko::dim<2> size) const
446 {
447 return workspace_.template create_or_get_op<LinOpType>(
448 vector_id,
449 [&] {
450 return LinOpType::create(this->workspace_.get_executor(), size);
451 },
452 typeid(LinOpType), size, size[1]);
453 }
454
455 template <typename LinOpType>
456 LinOpType* create_workspace_op_with_config_of(int vector_id,
457 const LinOpType* vec) const
458 {
459 return workspace_.template create_or_get_op<LinOpType>(
460 vector_id, [&] { return LinOpType::create_with_config_of(vec); },
461 typeid(*vec), vec->get_size(), vec->get_stride());
462 }
463
464 template <typename LinOpType>
465 LinOpType* create_workspace_op_with_type_of(int vector_id,
466 const LinOpType* vec,
467 dim<2> size) const
468 {
469 return workspace_.template create_or_get_op<LinOpType>(
470 vector_id,
471 [&] {
472 return LinOpType::create_with_type_of(
473 vec, workspace_.get_executor(), size, size[1]);
474 },
475 typeid(*vec), size, size[1]);
476 }
477
478 template <typename LinOpType>
479 LinOpType* create_workspace_op_with_type_of(int vector_id,
480 const LinOpType* vec,
481 dim<2> global_size,
482 dim<2> local_size) const
483 {
484 return workspace_.template create_or_get_op<LinOpType>(
485 vector_id,
486 [&] {
487 return LinOpType::create_with_type_of(
488 vec, workspace_.get_executor(), global_size, local_size,
489 local_size[1]);
490 },
491 typeid(*vec), global_size, local_size[1]);
492 }
493
494 template <typename ValueType>
495 matrix::Dense<ValueType>* create_workspace_scalar(int vector_id,
496 size_type size) const
497 {
498 return workspace_.template create_or_get_op<matrix::Dense<ValueType>>(
499 vector_id,
500 [&] {
501 return matrix::Dense<ValueType>::create(
502 workspace_.get_executor(), dim<2>{1, size});
503 },
504 typeid(matrix::Dense<ValueType>), gko::dim<2>{1, size}, size);
505 }
506
507 template <typename ValueType>
508 array<ValueType>& create_workspace_array(int array_id, size_type size) const
509 {
510 return workspace_.template create_or_get_array<ValueType>(array_id,
511 size);
512 }
513
514 template <typename ValueType>
515 array<ValueType>& create_workspace_array(int array_id) const
516 {
517 return workspace_.template init_or_get_array<ValueType>(array_id);
518 }
519
520private:
521 mutable detail::workspace workspace_;
522
523 std::shared_ptr<const LinOp> system_matrix_;
524};
525
526
527} // namespace detail
528
529
530template <typename MatrixType>
531class
532 // clang-format off
533 GKO_DEPRECATED("This class will be replaced by the template-less detail::SolverBaseLinOp in a future release") SolverBase
534 // clang-format on
535 : public detail::SolverBaseLinOp {
536public:
537 using detail::SolverBaseLinOp::SolverBaseLinOp;
538
546 std::shared_ptr<const MatrixType> get_system_matrix() const
547 {
548 return std::dynamic_pointer_cast<const MatrixType>(
549 SolverBaseLinOp::get_system_matrix());
550 }
551
552protected:
553 void set_system_matrix_base(std::shared_ptr<const MatrixType> system_matrix)
554 {
555 SolverBaseLinOp::set_system_matrix_base(std::move(system_matrix));
556 }
557};
558
559
569template <typename DerivedType, typename MatrixType = LinOp>
570class EnableSolverBase : public SolverBase<MatrixType> {
571public:
577 {
578 if (&other != this) {
579 set_system_matrix(other.get_system_matrix());
580 }
581 return *this;
582 }
583
589 {
590 if (&other != this) {
591 set_system_matrix(other.get_system_matrix());
592 other.set_system_matrix(nullptr);
593 }
594 return *this;
595 }
596
597 EnableSolverBase() : SolverBase<MatrixType>{self()->get_executor()} {}
598
599 EnableSolverBase(std::shared_ptr<const MatrixType> system_matrix)
600 : SolverBase<MatrixType>{self()->get_executor()}
601 {
602 set_system_matrix(std::move(system_matrix));
603 }
604
609 : SolverBase<MatrixType>{other.self()->get_executor()}
610 {
611 *this = other;
612 }
613
619 : SolverBase<MatrixType>{other.self()->get_executor()}
620 {
621 *this = std::move(other);
622 }
623
624 int get_num_workspace_ops() const override
625 {
627 return traits::num_vectors(*self());
628 }
629
630 std::vector<std::string> get_workspace_op_names() const override
631 {
633 return traits::op_names(*self());
634 }
635
640 std::vector<int> get_workspace_scalars() const override
641 {
643 return traits::scalars(*self());
644 }
645
650 std::vector<int> get_workspace_vectors() const override
651 {
653 return traits::vectors(*self());
654 }
655
656protected:
657 void set_system_matrix(std::shared_ptr<const MatrixType> new_system_matrix)
658 {
659 auto exec = self()->get_executor();
660 if (new_system_matrix) {
661 GKO_ASSERT_EQUAL_DIMENSIONS(self(), new_system_matrix);
662 GKO_ASSERT_IS_SQUARE_MATRIX(new_system_matrix);
663 if (new_system_matrix->get_executor() != exec) {
665 }
666 }
667 this->set_system_matrix_base(new_system_matrix);
668 }
669
670 void setup_workspace() const
671 {
673 this->set_workspace_size(traits::num_vectors(*self()),
674 traits::num_arrays(*self()));
675 }
676
677private:
678 DerivedType* self() { return static_cast<DerivedType*>(this); }
679
680 const DerivedType* self() const
681 {
682 return static_cast<const DerivedType*>(this);
683 }
684};
685
686
694public:
700 std::shared_ptr<const stop::CriterionFactory> get_stop_criterion_factory()
701 const
702 {
703 return stop_factory_;
704 }
705
712 std::shared_ptr<const stop::CriterionFactory> new_stop_factory)
713 {
714 stop_factory_ = new_stop_factory;
715 }
716
717private:
718 std::shared_ptr<const stop::CriterionFactory> stop_factory_;
719};
720
721
731template <typename DerivedType>
733public:
739 {
740 if (&other != this) {
741 set_stop_criterion_factory(other.get_stop_criterion_factory());
742 }
743 return *this;
744 }
745
752 {
753 if (&other != this) {
754 set_stop_criterion_factory(other.get_stop_criterion_factory());
755 other.set_stop_criterion_factory(nullptr);
756 }
757 return *this;
758 }
759
760 EnableIterativeBase() = default;
761
763 std::shared_ptr<const stop::CriterionFactory> stop_factory)
764 {
766 }
767
772
778 {
779 *this = std::move(other);
780 }
781
783 std::shared_ptr<const stop::CriterionFactory> new_stop_factory) override
784 {
785 auto exec = self()->get_executor();
786 if (new_stop_factory && new_stop_factory->get_executor() != exec) {
788 }
790 }
791
792private:
793 DerivedType* self() { return static_cast<DerivedType*>(this); }
794
795 const DerivedType* self() const
796 {
797 return static_cast<const DerivedType*>(this);
798 }
799};
800
801
812template <typename ValueType, typename DerivedType>
814 : public EnableSolverBase<DerivedType>,
815 public EnableIterativeBase<DerivedType>,
816 public EnablePreconditionable<DerivedType> {
817public:
819
821 std::shared_ptr<const LinOp> system_matrix,
822 std::shared_ptr<const stop::CriterionFactory> stop_factory,
823 std::shared_ptr<const LinOp> preconditioner)
824 : EnableSolverBase<DerivedType>(std::move(system_matrix)),
826 EnablePreconditionable<DerivedType>{std::move(preconditioner)}
827 {}
828
829 template <typename FactoryParameters>
831 std::shared_ptr<const LinOp> system_matrix,
834 system_matrix, stop::combine(params.criteria),
835 generate_preconditioner(system_matrix, params)}
836 {}
837
838private:
839 template <typename FactoryParameters>
840 static std::shared_ptr<const LinOp> generate_preconditioner(
841 std::shared_ptr<const LinOp> system_matrix,
843 {
844 if (params.generated_preconditioner) {
845 return params.generated_preconditioner;
846 } else if (params.preconditioner) {
847 return params.preconditioner->generate(system_matrix);
848 } else {
850 system_matrix->get_executor(), system_matrix->get_size());
851 }
852 }
853};
854
855
856template <typename Parameters, typename Factory>
858 : enable_parameters_type<Parameters, Factory> {
862 std::vector<std::shared_ptr<const stop::CriterionFactory>>
863 GKO_DEFERRED_FACTORY_VECTOR_PARAMETER(criteria);
864};
865
866
867template <typename Parameters, typename Factory>
869 : enable_iterative_solver_factory_parameters<Parameters, Factory> {
874 std::shared_ptr<const LinOpFactory> GKO_DEFERRED_FACTORY_PARAMETER(
876
881 std::shared_ptr<const LinOp> GKO_FACTORY_PARAMETER_SCALAR(
883};
884
885
886} // namespace solver
887} // namespace gko
888
889
890GKO_END_DISABLE_DEPRECATION_WARNINGS
891
892
893#endif // GKO_PUBLIC_CORE_SOLVER_SOLVER_BASE_HPP_
Definition lin_op.hpp:146
A LinOp implementing this interface can be preconditioned.
Definition lin_op.hpp:711
virtual void set_preconditioner(std::shared_ptr< const LinOp > new_precond)
Sets the preconditioner operator used by the Preconditionable.
Definition lin_op.hpp:731
The enable_parameters_type mixin is used to create a base implementation of the factory parameters st...
Definition abstract_factory.hpp:239
This class is a utility which efficiently implements the identity matrix (a linear operator which map...
Definition identity.hpp:65
This class is used for function parameters in the place of raw pointers.
Definition utils_helper.hpp:71
ApplyWithInitialGuess provides a way to give the input guess for apply function.
Definition solver_base.hpp:94
EnableApplyWithInitialGuess providing default operation for ApplyWithInitialGuess with correct valida...
Definition solver_base.hpp:190
A LinOp deriving from this CRTP class stores a stopping criterion factory and allows applying with a ...
Definition solver_base.hpp:732
EnableIterativeBase & operator=(EnableIterativeBase &&other)
Moves the provided stopping criterion, clones it onto this executor if executors don't match.
Definition solver_base.hpp:751
void set_stop_criterion_factory(std::shared_ptr< const stop::CriterionFactory > new_stop_factory) override
Sets the stopping criterion of the solver.
Definition solver_base.hpp:782
EnableIterativeBase(EnableIterativeBase &&other)
Moves the provided stopping criterion.
Definition solver_base.hpp:777
EnableIterativeBase(const EnableIterativeBase &other)
Creates a shallow copy of the provided stopping criterion.
Definition solver_base.hpp:771
EnableIterativeBase & operator=(const EnableIterativeBase &other)
Creates a shallow copy of the provided stopping criterion, clones it onto this executor if executors ...
Definition solver_base.hpp:738
Mixin providing default operation for Preconditionable with correct value semantics.
Definition solver_base.hpp:299
EnablePreconditionable(const EnablePreconditionable &other)
Creates a shallow copy of the provided preconditioner.
Definition solver_base.hpp:356
EnablePreconditionable & operator=(EnablePreconditionable &&other)
Moves the provided preconditioner, clones it onto this executor if executors don't match.
Definition solver_base.hpp:337
EnablePreconditionable(EnablePreconditionable &&other)
Moves the provided preconditioner.
Definition solver_base.hpp:365
EnablePreconditionable & operator=(const EnablePreconditionable &other)
Creates a shallow copy of the provided preconditioner, clones it onto this executor if executors don'...
Definition solver_base.hpp:324
void set_preconditioner(std::shared_ptr< const LinOp > new_precond) override
Sets the preconditioner operator used by the Preconditionable.
Definition solver_base.hpp:307
A LinOp implementing this interface stores a system matrix and stopping criterion factory.
Definition solver_base.hpp:816
A LinOp deriving from this CRTP class stores a system matrix.
Definition solver_base.hpp:570
EnableSolverBase(EnableSolverBase &&other)
Moves the provided system matrix.
Definition solver_base.hpp:618
std::vector< int > get_workspace_vectors() const override
Returns the IDs of all vectors (workspace vectors with system dimension-dependent size,...
Definition solver_base.hpp:650
std::vector< int > get_workspace_scalars() const override
Returns the IDs of all scalars (workspace vectors with system dimension-independent size,...
Definition solver_base.hpp:640
EnableSolverBase(const EnableSolverBase &other)
Creates a shallow copy of the provided system matrix.
Definition solver_base.hpp:608
EnableSolverBase & operator=(EnableSolverBase &&other)
Moves the provided system matrix, clones it onto this executor if executors don't match.
Definition solver_base.hpp:588
EnableSolverBase & operator=(const EnableSolverBase &other)
Creates a shallow copy of the provided system matrix, clones it onto this executor if executors don't...
Definition solver_base.hpp:576
A LinOp implementing this interface stores a stopping criterion factory.
Definition solver_base.hpp:693
std::shared_ptr< const stop::CriterionFactory > get_stop_criterion_factory() const
Gets the stopping criterion factory of the solver.
Definition solver_base.hpp:700
virtual void set_stop_criterion_factory(std::shared_ptr< const stop::CriterionFactory > new_stop_factory)
Sets the stopping criterion of the solver.
Definition solver_base.hpp:711
Definition solver_base.hpp:535
std::shared_ptr< const MatrixType > get_system_matrix() const
Returns the system matrix, with its concrete type, used by the solver.
Definition solver_base.hpp:546
#define GKO_FACTORY_PARAMETER_SCALAR(_name, _default)
Creates a scalar factory parameter in the factory parameters structure.
Definition abstract_factory.hpp:473
std::shared_ptr< const CriterionFactory > combine(FactoryContainer &&factories)
Combines multiple criterion factories into a single combined criterion factory.
Definition combined.hpp:138
initial_guess_mode
Give a initial guess mode about the input of the apply method.
Definition solver_base.hpp:62
@ provided
the input is provided
@ rhs
the input is right hand side
The Ginkgo namespace.
Definition abstract_factory.hpp:48
constexpr T one()
Returns the multiplicative identity for T.
Definition math.hpp:803
std::size_t size_type
Integral type used for allocation quantities.
Definition types.hpp:120
detail::cloned_type< Pointer > clone(const Pointer &p)
Creates a unique clone of the object pointed to by p.
Definition utils_helper.hpp:203
detail::temporary_clone< detail::pointee< Ptr > > make_temporary_clone(std::shared_ptr< const Executor > exec, Ptr &&ptr)
Creates a temporary_clone.
Definition temporary_clone.hpp:207
A type representing the dimensions of a multidimensional object.
Definition dim.hpp:55
std::vector< std::shared_ptr< const stop::CriterionFactory > > criteria
Stopping criteria to be used by the solver.
Definition solver_base.hpp:863
std::shared_ptr< const LinOp > generated_preconditioner
Already generated preconditioner.
Definition solver_base.hpp:882
std::shared_ptr< const LinOpFactory > preconditioner
The preconditioner to be used by the iterative solver.
Definition solver_base.hpp:875
Traits class providing information on the type and location of workspace vectors inside a solver.
Definition solver_base.hpp:267