deal.II version 9.8.0
\(\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
psblas_vector.cc
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) 2019 - 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
15#include <deal.II/base/mpi.h>
16
18
19#ifdef DEAL_II_WITH_PSBLAS
20# include <psb_base_cbind.h>
21# include <psb_c_base.h>
22# include <psb_c_dbase.h>
23
25
26namespace PSCToolkitWrappers
27{
28
30 : psblas_vector(nullptr)
31 , psblas_context(InitFinalize::get_psblas_context())
32 , psblas_descriptor(nullptr)
33 , ghosted(false)
34 , state(internal::State::Default)
35 , last_action(VectorOperation::unknown)
36 {}
37
38
39 Vector::Vector(const Vector &v)
40 : Vector::Vector()
41 {
42 if (v.has_ghost_elements())
43 reinit(v.owned_elements, v.ghost_indices, v.communicator);
44 else
45 reinit(v.owned_elements, v.communicator);
46
47 this->operator=(v);
48 }
49
50
52 {
53 if (state != internal::State::Default)
54 {
55 int ierr;
56 ierr = psb_c_dgefree(psblas_vector, psblas_descriptor.get());
57 AssertNothrow(ierr == 0, ExcFreePSBLASVector(ierr));
58 }
59 }
60
61
62
63 Vector::Vector(const IndexSet &local_partitioning, const MPI_Comm comm)
64 {
65 communicator = comm;
66 psblas_vector = nullptr;
67 ghosted = false;
68 // forward the call to reinit function below.
69 reinit(local_partitioning, communicator);
70 }
71
72
73
74 Vector::Vector(const IndexSet &local_partitioning,
75 const IndexSet &ghost_indices,
76 const MPI_Comm comm)
77 {
78 communicator = comm;
79 psblas_vector = nullptr;
80 ghosted = true;
81 // forward the call to reinit function taking ghost indices.
82 reinit(local_partitioning, ghost_indices, communicator);
83 }
84
85
86
87 void
88 Vector::reinit(const IndexSet &local_partitioning,
89 const MPI_Comm comm,
90 const bool omit_zeroing_entries)
91 {
92 Assert(communicator != MPI_COMM_NULL,
93 ExcMessage("MPI_COMM_NULL passed to Vector::reinit()."));
94 communicator = comm;
95 ghosted = false;
96 const bool is_vector_changed = size() != local_partitioning.size();
97 owned_elements = local_partitioning;
98
99 int ierr;
100 // we do not need to create a new descriptor if the existing one has already
101 // been assembled
102 if (psblas_descriptor.get() == nullptr || is_vector_changed == true)
103 {
104 psblas_descriptor.reset(psb_c_new_descriptor(),
105 internal::DescriptorDeleter());
106
107 // Use get_index_vector() from IndexSet to get the indexes
108 const std::vector<types::global_dof_index> &indexes =
109 local_partitioning.get_index_vector();
110
111 const auto number_of_local_indexes =
112 indexes.size(); // Number of local indexes
113
114 std::vector<psb_l_t> vl(number_of_local_indexes);
115 for (std::size_t i = 0; i < number_of_local_indexes; ++i)
116 {
117 const auto psblas_index = static_cast<psb_l_t>(indexes[i]);
118 AssertIntegerConversion(psblas_index, indexes[i]);
119 vl[i] = psblas_index;
120 }
121
122 // Insert the indexes into the descriptor
123 psblas_context = InitFinalize::get_psblas_context();
124 ierr = psb_c_cdall_vl(number_of_local_indexes,
125 vl.data(),
126 *psblas_context,
127 psblas_descriptor.get());
128
129 // Free the vl array
130 Assert(ierr == 0, ExcInitializePSBLASDescriptor(ierr));
131 }
132
133 // Create a new PSBLAS vector and allocate mem space for vector
134 psblas_vector = psb_c_new_dvector();
135
136 ierr = psb_c_dgeall_remote_options(psblas_vector,
137 psblas_descriptor.get(),
138 PSB_MATBLD_REMOTE,
139 PSB_DUPL_DEF);
140 Assert(ierr == 0, ExcInitializePSBLASVector(ierr));
141
142 if (omit_zeroing_entries == false)
143 {
144 ierr = psb_c_dvect_set_scal(psblas_vector, 0.0);
145 Assert(ierr == 0,
146 ExcCallingPSBLASFunction(ierr, "psb_c_dvect_set_scal"));
147 }
148 state = internal::State::Assembled;
149 last_action = VectorOperation::unknown;
150 }
151
152
153
154 void
155 Vector::reinit(const IndexSet &local_partitioning,
156 const IndexSet &ghosts,
157 const MPI_Comm comm)
158 {
159 Assert(comm != MPI_COMM_NULL,
160 ExcMessage("MPI_COMM_NULL passed to Vector::reinit()."));
161 communicator = comm;
162 ghosted = true;
163 const bool is_vector_changed = size() != local_partitioning.size();
164
165 owned_elements = local_partitioning;
166 ghost_indices = ghosts;
167 ghost_indices.subtract_set(local_partitioning);
168
169 int ierr;
170 if (psblas_descriptor.get() == nullptr || is_vector_changed == true)
171 {
172 psblas_descriptor.reset(psb_c_new_descriptor(),
173 internal::DescriptorDeleter());
174
175 // Use get_index_vector() from IndexSet to get the indexes
176 const std::vector<types::global_dof_index> &indexes =
177 local_partitioning.get_index_vector();
178
179 const auto number_of_local_indexes =
180 indexes.size(); // Number of local indexes
181
182 std::vector<psb_l_t> vl(number_of_local_indexes);
183 std::vector<psb_i_t> lidx(number_of_local_indexes);
184 for (std::size_t i = 0; i < number_of_local_indexes; ++i)
185 {
186 const auto psblas_index = static_cast<psb_l_t>(indexes[i]);
187 const auto idx = static_cast<psb_i_t>(i);
188 AssertIntegerConversion(psblas_index, indexes[i]);
190 vl[i] = psblas_index;
191 lidx[i] = idx;
192 }
193
194 // Ghost case. From the manual:
195 // 1) psb_cdall() with vl (global) and lidx (local)
196 // 2) psb_cdins(nz,ja,desc,info,lidx=lidx), where:
197 // - ja contains halo indices
198 // - lidx: corresponding local indices
199
200 // Insert the indexes into the descriptor
201 psblas_context = InitFinalize::get_psblas_context();
202 ierr = psb_c_cdall_vl_lidx(number_of_local_indexes,
203 vl.data(),
204 lidx.data(),
205 *psblas_context,
206 psblas_descriptor.get());
207
208 Assert(ierr == 0, ExcInitializePSBLASDescriptor(ierr));
209
210 // ... insert the ghost indices ...
211 const std::vector<types::global_dof_index> &ghost_indexes =
212 ghost_indices.get_index_vector();
213 const auto number_of_ghost_indices = ghost_indexes.size();
214
215 std::vector<psb_l_t> global_ghost_indices(number_of_ghost_indices);
216 std::vector<psb_i_t> local_ghost_indices(number_of_ghost_indices);
217
218 psb_i_t extended_idx_counter = number_of_local_indexes;
219 for (std::size_t i = 0; i < number_of_ghost_indices; ++i)
220 {
221 const auto psblas_index = static_cast<psb_l_t>(ghost_indexes[i]);
222 AssertIntegerConversion(psblas_index, ghost_indexes[i]);
223 global_ghost_indices[i] = psblas_index;
224 const auto idx = static_cast<psb_i_t>(extended_idx_counter);
225 AssertIntegerConversion(idx, extended_idx_counter);
226 local_ghost_indices[i] = extended_idx_counter++;
227 }
228
229
230 ierr = psb_c_cdins_lidx(number_of_ghost_indices,
231 global_ghost_indices.data(),
232 local_ghost_indices.data(),
233 psblas_descriptor.get());
234
235 Assert(ierr == 0, ExcCallingPSBLASFunction(ierr, "psb_c_cdins_lidx"));
236 }
237
238 // Assemble the descriptor first so that the halo (ghost) information is
239 // known before the vector is allocated and assembled.
240 ierr = psb_c_cdasb(psblas_descriptor.get());
241 Assert(ierr == 0, ExcAssemblePSBLASDescriptor(ierr));
242
243 // Create a new PSBLAS vector and allocate mem space for it
244 psblas_vector = psb_c_new_dvector();
245
246 ierr = psb_c_dgeall_remote_options(psblas_vector,
247 psblas_descriptor.get(),
248 PSB_MATBLD_REMOTE,
249 PSB_DUPL_DEF);
250 Assert(ierr == 0, ExcInitializePSBLASVector(ierr));
251
252 // Assemble the vector so that storage for the ghost (halo) elements is
253 // allocated. This is required for update_ghost_values() (psb_c_dhalo) to
254 // work correctly.
255 ierr = psb_c_dgeasb_options(psblas_vector,
256 psblas_descriptor.get(),
257 PSB_DUPL_DEF);
258 Assert(ierr == 0, ExcAssemblePSBLASVector(ierr));
259
260 state = internal::State::Assembled;
261 last_action = VectorOperation::unknown;
262 }
263
264
265
266 void
267 Vector::reinit(const Vector &v, const bool omit_zeroing_entries)
268 {
269 psblas_descriptor = v.psblas_descriptor;
270 if (v.has_ghost_elements())
271 {
273 v.ghost_indices,
275 if (!omit_zeroing_entries)
276 {
277 int ierr = psb_c_dvect_set_scal(psblas_vector, 0.0);
278 Assert(ierr == 0,
279 ExcCallingPSBLASFunction(ierr, "psb_c_dvect_set_scal"));
280 }
281 }
282 else
283 {
284 reinit(v.owned_elements,
286 omit_zeroing_entries);
287 }
288 }
289
290
291
292 Vector &
293 Vector::operator=(const Vector &v)
294 {
295 Assert(v.last_action == VectorOperation::unknown,
296 ExcWrongMode(VectorOperation::unknown, v.last_action));
297 Assert(last_action == VectorOperation::unknown,
298 ExcWrongMode(VectorOperation::unknown, last_action));
299 Assert(v.state == internal::State::Assembled,
300 ExcInvalidStateAssembled(v.state));
301
302 // Vectors can have different sizes. If so, we first resize the vector
303 if (size() != v.size())
304 {
305 // since v has been assembled, we can recycle its descriptor
306 psblas_descriptor = v.psblas_descriptor;
307 if (v.has_ghost_elements())
309 v.ghost_indices,
311 else
312 reinit(v.owned_elements, v.get_mpi_communicator(), true);
313 }
314
315 // Copy only the locally owned entries from v into this vector. We use
316 // psb_c_dgeaxpby (this = 1.0 * v + 0.0 * this)
317 int ierr = psb_c_dgeaxpby(value_type(1.0),
318 v.psblas_vector,
319 value_type(0.0),
320 psblas_vector,
321 psblas_descriptor.get());
322 AssertThrow(ierr == 0, ExcAXPBY(ierr));
323
324 // If current vector has ghost elements, update them
325 if (has_ghost_elements())
327
328 state = internal::State::Assembled;
329
330 return *this;
331 }
332
333
334
335 Vector &
337 {
339 Assert(state != internal::State::Default, ExcInvalidState(state));
340 int ierr = psb_c_dvect_set_scal(psblas_vector, s);
341 Assert(ierr == 0, ExcCallingPSBLASFunction(ierr, "psb_c_dvect_set_scal"));
342 return *this;
343 }
344
345
346
349 {
350 return communicator;
351 }
352
353
354
355 psb_c_descriptor *
356 Vector::get_psblas_descriptor() const
357 {
358 return psblas_descriptor.get();
359 }
360
361
362
363 psb_c_dvector *
364 Vector::get_psblas_vector() const
365 {
366 return psblas_vector;
367 }
368
369
370
371 void
372 Vector::clear()
373 {
374 if (state != internal::State::Default)
375 {
376 int ierr = psb_c_dgefree(psblas_vector, psblas_descriptor.get());
377 Assert(ierr == 0, ExcFreePSBLASVector(ierr));
378
379 // Reset the vector
380 psblas_vector = nullptr;
381 owned_elements.clear();
382 owned_elements.set_size(0);
383 ghost_indices.clear();
384 owned_elements.set_size(0);
385 state = internal::State::Default;
386 last_action = VectorOperation::unknown;
387 }
388 }
389
390
391
393 Vector::linfty_norm() const
394 {
395 Assert(state == internal::State::Assembled,
396 ExcInvalidStateAssembled(state));
397 return psb_c_dgenrmi(psblas_vector, psblas_descriptor.get());
398 }
399
400
401
403 Vector::l1_norm() const
404 {
405 Assert(state == internal::State::Assembled,
406 ExcInvalidStateAssembled(state));
407 return psb_c_dgeasum(psblas_vector, psblas_descriptor.get());
408 }
409
410
411
413 Vector::l2_norm() const
414 {
415 Assert(state == internal::State::Assembled,
416 ExcInvalidStateAssembled(state));
417 return psb_c_dgenrm2(psblas_vector, psblas_descriptor.get());
418 }
419
420
421
423 Vector::mean_value() const
424 {
425 const value_type *start_ptr = psb_c_dvect_f_get_pnt(psblas_vector);
426 const value_type *end_ptr = start_ptr + locally_owned_size();
427
428 value_type local_sum_of_values = 0.0;
429 for (const value_type *ptr = start_ptr; ptr != end_ptr; ++ptr)
430 local_sum_of_values += *ptr;
431
432 return Utilities::MPI::sum(local_sum_of_values, communicator) / size();
433 }
434
435
436
437 bool
438 Vector::all_zero() const
439 {
440 // we get a pointer to the underlying vector and check if all
441 // entries are zero.
442 const value_type *start_ptr = psb_c_dvect_f_get_pnt(psblas_vector);
443 Assert(start_ptr != nullptr,
444 ExcMessage("Error getting underlying PSBLAS vector."));
445
446 const bool has_nonzero_local =
447 std::any_of(start_ptr,
448 start_ptr + locally_owned_size(),
449 [](const value_type &val) { return val != value_type(); });
450
451 unsigned int num_nonzero =
452 Utilities::MPI::sum(has_nonzero_local ? 1 : 0, communicator);
453 return num_nonzero == 0;
454 }
455
456
457
458 void
459 Vector::equ(const value_type a, const Vector &v)
460 {
461 AssertDimension(size(), v.size());
464
465 // do the analogous to VecAXPBY(vector, a, 0.0, v.vector) in PETSc
466 int ierr = psb_c_dgeaxpby(
467 a, v.psblas_vector, 0.0, psblas_vector, psblas_descriptor.get());
468 AssertThrow(ierr == 0, ExcAXPBY(ierr));
469 }
470
471
472
475 {
476 return owned_elements.n_elements();
477 }
478
479
480
482 Vector::operator*(const Vector &v) const
483 {
484 AssertDimension(size(), v.size());
485 return psb_c_dgedot(psblas_vector,
486 v.psblas_vector,
487 psblas_descriptor.get());
488 }
489
490
491
492 Vector &
493 Vector::operator+=(const Vector &v)
494 {
495 AssertDimension(size(), v.size());
497 int ierr = psb_c_dgeaxpby(value_type(1.0),
498 v.psblas_vector,
499 1.0,
500 psblas_vector,
501 psblas_descriptor.get());
502 AssertThrow(ierr == 0, ExcAXPBY(ierr));
503 return *this;
504 }
505
506
507 Vector &
508 Vector::operator-=(const Vector &v)
509 {
510 AssertDimension(size(), v.size());
512 int ierr = psb_c_dgeaxpby(value_type(-1.0),
513 v.psblas_vector,
514 1.0,
515 psblas_vector,
516 psblas_descriptor.get());
517 AssertThrow(ierr == 0, ExcAXPBY(ierr));
518 return *this;
519 }
520
521
522 void
523 Vector::set(const std::vector<Vector::size_type> &indices,
524 const std::vector<Vector::value_type> &values)
525 {
527 Assert(state != internal::State::Default, ExcInvalidState(state));
528 AssertDimension(indices.size(), values.size());
529
530 psb_i_t nz = indices.size(); // Number of non-zero entries
531
532 // Allocate memory for row indices and values. We need to subtract the
533 // current value in order to set the value.
534 std::vector<psb_l_t> irw(nz);
535 std::vector<psb_d_t> val(nz);
536 for (psb_i_t i = 0; i < nz; ++i)
537 {
538 const auto psblas_index = static_cast<psb_l_t>(indices[i]);
539 AssertIntegerConversion(psblas_index, indices[i]);
540 irw[i] = psblas_index;
541 val[i] = values[i] -
542 psb_c_dgetelem(psblas_vector, irw[i], psblas_descriptor.get());
543 }
544
545 int ierr = psb_c_dgeins(nz /*nz*/,
546 irw.data(),
547 val.data(),
548 psblas_vector,
549 psblas_descriptor.get());
550
551 // Free allocated memory
552 Assert(ierr == 0, ExcInsertionInPSBLASVector(ierr));
553 }
554
555
556
557 void
558 Vector::add(const std::vector<Vector::size_type> &indices,
559 const std::vector<Vector::value_type> &values)
560 {
562 Assert(state != internal::State::Default, ExcInvalidState(state));
563 Assert(indices.size() == values.size(),
564 ExcMessage("Indices and values size mismatch."));
565
566 psb_i_t nz = indices.size(); // Number of non-zero entries
567
568 // Allocate memory for row indices and values
569 std::vector<psb_l_t> irw(nz);
570 std::vector<psb_d_t> val(nz);
571 for (psb_i_t i = 0; i < nz; ++i)
572 {
573 const auto psblas_index = static_cast<psb_l_t>(indices[i]);
574 AssertIntegerConversion(psblas_index, indices[i]);
575 irw[i] = psblas_index;
576 val[i] = values[i];
577 }
578
579 int ierr = psb_c_dgeins(nz /*nz*/,
580 irw.data(),
581 val.data(),
582 psblas_vector,
583 psblas_descriptor.get());
584
585 Assert(ierr == 0, ExcInsertionInPSBLASVector(ierr));
586 }
587
588
589
590 void
591 Vector::add(const value_type s, const Vector &V)
592 {
595 int ierr = psb_c_dgeaxpby(s,
596 V.psblas_vector,
597 value_type(1.0),
598 psblas_vector,
599 psblas_descriptor.get());
600 Assert(ierr == 0, ExcAXPBY(ierr));
601 }
602
603
604
605 void
606 Vector::add(const value_type s)
607 {
610 value_type *start_ptr = psb_c_dvect_f_get_pnt(psblas_vector);
611 value_type *end_ptr = start_ptr + locally_owned_size();
612 while (start_ptr != end_ptr)
613 {
614 *start_ptr += s;
615 ++start_ptr;
616 }
617 }
618
619
620
621 void
622 Vector::sadd(const value_type s, const Vector &V)
623 {
626 int ierr = psb_c_dgeaxpby(value_type(1.0),
627 V.psblas_vector,
628 s,
629 psblas_vector,
630 psblas_descriptor.get());
631 Assert(ierr == 0, ExcAXPBY(ierr));
632 }
633
634
635 void
636 Vector::sadd(const value_type s, const value_type a, const Vector &V)
637 {
640 int ierr = psb_c_dgeaxpby(
641 a, V.psblas_vector, s, psblas_vector, psblas_descriptor.get());
642 Assert(ierr == 0, ExcAXPBY(ierr));
643 }
644
645
646 void
647 Vector::scale(const Vector &v)
648 {
650 AssertDimension(size(), v.size());
651 value_type *start_ptr = psb_c_dvect_f_get_pnt(psblas_vector);
652 value_type *start_ptr_v = psb_c_dvect_f_get_pnt(v.psblas_vector);
653 value_type *end_ptr = start_ptr + locally_owned_size();
654 while (start_ptr != end_ptr)
655 {
656 *start_ptr *= (*start_ptr_v);
657 ++start_ptr;
658 ++start_ptr_v;
659 }
660 }
661
662
663
665 Vector::add_and_dot(const value_type a, const Vector &V, const Vector &W)
666 {
667 // forward the call to add()...
668 add(a, V);
669 // ... and then do the dot product
670 return psb_c_dgedot(psblas_vector,
671 W.psblas_vector,
672 psblas_descriptor.get());
673 }
674
675
676
677 void
679 {
680 // simply swap pointers
681 std::swap(psblas_vector, v.psblas_vector);
682 std::swap(psblas_descriptor, v.psblas_descriptor);
683 std::swap(ghosted, v.ghosted);
684 std::swap(this->last_action, v.last_action);
685 // We use a temp variable to swap the IndexSets
686 IndexSet temp(ghost_indices);
687 ghost_indices = v.ghost_indices;
688 v.ghost_indices = temp;
689 }
690
691
692
693 void
695 {
696 Assert(has_ghost_elements() == false,
697 ExcMessage("Calling compress() is only useful if a vector "
698 "has been written into, but this is a vector with ghost "
699 "elements and consequently is read-only. It does "
700 "not make sense to call compress() for such "
701 "vectors."));
702
703 // We check the state of the vector...
704 Assert(state != internal::State::Default, ExcInvalidDefault());
705 // ... and if the last action was compatible with what we want to do
707 last_action == VectorOperation::unknown || last_action == operation,
709 "Missing compress() or calling with wrong VectorOperation argument."));
710
711 // We check if the descriptor has already been assembled somewhere
712 int ierr;
713 if (!psb_c_cd_is_asb(psblas_descriptor.get()))
714 {
715 ierr = psb_c_cdasb(psblas_descriptor.get());
716 Assert(ierr == 0, ExcAssemblePSBLASDescriptor(ierr));
717 }
718
719 // finally, we perform the assemble operation
720 if (operation == VectorOperation::add)
721 ierr = psb_c_dgeasb_options(psblas_vector,
722 psblas_descriptor.get(),
723 PSB_DUPL_ADD);
724 else if (operation == VectorOperation::insert)
725 ierr = psb_c_dgeasb_options(psblas_vector,
726 psblas_descriptor.get(),
727 PSB_DUPL_DEF);
728 else
730
731 Assert(ierr == 0, ExcAssemblePSBLASVector(ierr));
732 state = internal::State::Assembled;
733 last_action = VectorOperation::unknown;
734 }
735
736
737
738 void
740 {
741 if (ghosted)
742 {
743 int ierr = psb_c_dhalo(psblas_vector, psblas_descriptor.get());
744 Assert(ierr == 0, ExcMessage("Error while updating ghost values."));
745 }
746 }
747
748
749 std::size_t
751 {
752 std::size_t mem = MemoryConsumption::memory_consumption(ghosted) +
754
755 // mem += psb_c_sizeof(psblas_vector); TODO[MF]: missing from PSBLAS's
756 // interface
757 return mem;
758 }
759
760
761} // namespace PSCToolkitWrappers
762
764#endif
size_type size() const
Definition index_set.h:1783
void subtract_set(const IndexSet &other)
Definition index_set.cc:496
std::vector< size_type > get_index_vector() const
Definition index_set.cc:951
bool has_ghost_elements() const
void add(const std::vector< size_type > &indices, const std::vector< OtherNumber > &values)
Vector< Number > & operator=(const Number s)
Number operator*(const Vector< Number2 > &V) const
Number mean_value() const
Number add_and_dot(const Number a, const Vector< Number > &V, const Vector< Number > &W)
MPI_Comm get_mpi_communicator() const
types::global_dof_index size_type
Definition vector.h:122
virtual size_type size() const override
void equ(const Number a, const Vector< Number > &u)
void sadd(const Number s, const Vector< Number > &V)
friend class Vector
Definition vector.h:1102
real_type l2_norm() const
virtual ~Vector() override=default
real_type linfty_norm() const
Vector< Number > & operator+=(const Vector< Number > &V)
void scale(const Vector< Number > &scaling_factors)
IndexSet locally_owned_elements() const
AlignedVector< Number > values
Definition vector.h:1075
virtual void reinit(const size_type N, const bool omit_zeroing_entries=false)
size_type locally_owned_size() const
virtual void swap(Vector< Number > &v) noexcept
void compress(VectorOperation::values operation=VectorOperation::unknown) const
Vector< Number > & operator-=(const Vector< Number > &V)
void update_ghost_values() const
bool all_zero() const
std::size_t memory_consumption() const
real_type l1_norm() const
Number value_type
Definition vector.h:115
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define AssertIntegerConversion(index1, index2)
#define DEAL_II_NOT_IMPLEMENTED()
static ::ExceptionBase & ExcGhostsPresent()
#define Assert(cond, exc)
#define AssertIsFinite(number)
#define AssertDimension(dim1, dim2)
#define AssertNothrow(cond, exc)
static ::ExceptionBase & ExcInvalidState()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
constexpr char V
std::enable_if_t< std::is_fundamental_v< T >, std::size_t > memory_consumption(const T &t)
T sum(const T &t, const MPI_Comm mpi_communicator)
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
*braid_SplitCommworld & comm