DUNE ISTL (unstable)

owneroverlapcopy.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root
2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
4// vi: set et ts=4 sw=2 sts=2:
5#ifndef DUNE_ISTL_OWNEROVERLAPCOPY_HH
6#define DUNE_ISTL_OWNEROVERLAPCOPY_HH
7
8#include <new>
9#include <iostream>
10#include <vector>
11#include <list>
12#include <map>
13#include <set>
14#include <tuple>
15
16#include <cmath>
17
18// MPI header
19#if HAVE_MPI
20#include <mpi.h>
21#endif
22
23#include <dune/common/enumset.hh>
24
25#if HAVE_MPI
26#include <dune/common/parallel/indexset.hh>
27#include <dune/common/parallel/communicator.hh>
28#include <dune/common/parallel/remoteindices.hh>
29#include <dune/common/parallel/mpicommunication.hh>
30#endif
31
32#include "solvercategory.hh"
33#include "istlexception.hh"
34#include <dune/common/parallel/communication.hh>
36
37template<int dim, template<class,class> class Comm>
38void testRedistributed(int s);
39
40
41namespace Dune {
42
59 {
60 enum AttributeSet {
61 owner=1, overlap=2, copy=3
62 };
63 };
64
76 template <class G, class L>
78 {
79 public:
81 typedef G GlobalIdType;
82
84 typedef L LocalIdType;
85
92 typedef std::tuple<GlobalIdType,LocalIdType,int> IndexTripel;
99 typedef std::tuple<int,GlobalIdType,int> RemoteIndexTripel;
100
107 {
108 if (std::get<2>(x)!=OwnerOverlapCopyAttributeSet::owner &&
109 std::get<2>(x)!=OwnerOverlapCopyAttributeSet::overlap &&
110 std::get<2>(x)!=OwnerOverlapCopyAttributeSet::copy)
111 DUNE_THROW(ISTLError,"OwnerOverlapCopyCommunication: global index not in index set");
112 localindices.insert(x);
113 }
114
121 {
122 if (std::get<2>(x)!=OwnerOverlapCopyAttributeSet::owner &&
123 std::get<2>(x)!=OwnerOverlapCopyAttributeSet::overlap &&
124 std::get<2>(x)!=OwnerOverlapCopyAttributeSet::copy)
125 DUNE_THROW(ISTLError,"OwnerOverlapCopyCommunication: global index not in index set");
126 remoteindices.insert(x);
127 }
128
133 const std::set<IndexTripel>& localIndices () const
134 {
135 return localindices;
136 }
137
142 const std::set<RemoteIndexTripel>& remoteIndices () const
143 {
144 return remoteindices;
145 }
146
150 void clear ()
151 {
152 localindices.clear();
153 remoteindices.clear();
154 }
155
156 private:
158 std::set<IndexTripel> localindices;
160 std::set<RemoteIndexTripel> remoteindices;
161 };
162
163
164#if HAVE_MPI
165
172 template <class GlobalIdType, class LocalIdType=int>
174 {
175 template<typename M, typename G, typename L>
176 friend void loadMatrixMarket(M&,
177 const std::string&,
179 bool);
180 // used types
183 typedef typename std::set<IndexTripel>::const_iterator localindex_iterator;
184 typedef typename std::set<RemoteIndexTripel>::const_iterator remoteindex_iterator;
185 typedef typename OwnerOverlapCopyAttributeSet::AttributeSet AttributeSet;
186 typedef Dune::ParallelLocalIndex<AttributeSet> LI;
187 public:
188 typedef Dune::ParallelIndexSet<GlobalIdType,LI,512> PIS;
189 typedef Dune::RemoteIndices<PIS> RI;
190 typedef Dune::RemoteIndexListModifier<PIS,typename RI::Allocator,false> RILM;
191 typedef typename RI::RemoteIndex RX;
192 typedef Dune::BufferedCommunicator BC;
193 typedef Dune::Interface IF;
194 typedef EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::owner> OwnerSet;
195 typedef EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::copy> CopySet;
196 typedef Combine<EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::owner>,EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::overlap>,AttributeSet> OwnerOverlapSet;
197 typedef Dune::AllSet<AttributeSet> AllSet;
198 protected:
199
200
202 template<typename T>
204 {
205 typedef typename CommPolicy<T>::IndexedType V;
206
207 static V gather(const T& a, std::size_t i)
208 {
209 return a[i];
210 }
211
212 static void scatter(T& a, V v, std::size_t i)
213 {
214 a[i] = v;
215 }
216 };
217 template<typename T>
218 struct AddGatherScatter
219 {
220 typedef typename CommPolicy<T>::IndexedType V;
221
222 static V gather(const T& a, std::size_t i)
223 {
224 return a[i];
225 }
226
227 static void scatter(T& a, V v, std::size_t i)
228 {
229 a[i] += v;
230 }
231 };
232
233 void buildOwnerOverlapToAllInterface () const
234 {
235 if (OwnerOverlapToAllInterfaceBuilt)
236 OwnerOverlapToAllInterface.free();
237 OwnerOverlapSet sourceFlags;
238 Combine<OwnerOverlapSet,EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::copy>,AttributeSet>
239 destFlags;
240 OwnerOverlapToAllInterface.build(ri,sourceFlags,destFlags);
241 OwnerOverlapToAllInterfaceBuilt = true;
242 }
243
244 void buildOwnerToAllInterface () const
245 {
246 if (OwnerToAllInterfaceBuilt)
247 OwnerToAllInterface.free();
248 OwnerSet sourceFlags;
249 AllSet destFlags;
250 OwnerToAllInterface.build(ri,sourceFlags,destFlags);
251 OwnerToAllInterfaceBuilt = true;
252 }
253
254 void buildOwnerCopyToAllInterface () const
255 {
256 if (OwnerCopyToAllInterfaceBuilt)
257 OwnerCopyToAllInterface.free();
258
259 typedef Combine<EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::owner>,EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::copy>,AttributeSet> OwnerCopySet;
260 OwnerCopySet sourceFlags;
261 Combine<OwnerCopySet,EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::overlap>,AttributeSet> destFlags;
262 OwnerCopyToAllInterface.build(ri,sourceFlags,destFlags);
263 OwnerCopyToAllInterfaceBuilt = true;
264 }
265
266 void buildOwnerCopyToOwnerCopyInterface () const
267 {
268 if (OwnerCopyToOwnerCopyInterfaceBuilt)
269 OwnerCopyToOwnerCopyInterface.free();
270
271
272 typedef Combine<EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::owner>,EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::copy>,AttributeSet> OwnerCopySet;
273 OwnerCopySet sourceFlags;
274 OwnerCopySet destFlags;
275 OwnerCopyToOwnerCopyInterface.build(ri,sourceFlags,destFlags);
276 OwnerCopyToOwnerCopyInterfaceBuilt = true;
277 }
278
279 void buildCopyToAllInterface () const
280 {
281 if (CopyToAllInterfaceBuilt)
282 CopyToAllInterface.free();
283 CopySet sourceFlags;
284 AllSet destFlags;
285 CopyToAllInterface.build(ri,sourceFlags,destFlags);
286 CopyToAllInterfaceBuilt = true;
287 }
288
289 public:
290
296 return category_;
297 }
298
299 const Communication<MPI_Comm>& communicator() const
300 {
301 return cc;
302 }
303
310 template<class T>
311 void copyOwnerToAll (const T& source, T& dest) const
312 {
313 if (!OwnerToAllInterfaceBuilt)
314 buildOwnerToAllInterface ();
315 BC communicator;
316 communicator.template build<T>(OwnerToAllInterface);
317 communicator.template forward<CopyGatherScatter<T> >(source,dest);
318 communicator.free();
319 }
320
327 template<class T>
328 void copyCopyToAll (const T& source, T& dest) const
329 {
330 if (!CopyToAllInterfaceBuilt)
331 buildCopyToAllInterface ();
332 BC communicator;
333 communicator.template build<T>(CopyToAllInterface);
334 communicator.template forward<CopyGatherScatter<T> >(source,dest);
335 communicator.free();
336 }
337
344 template<class T>
345 void addOwnerOverlapToAll (const T& source, T& dest) const
346 {
347 if (!OwnerOverlapToAllInterfaceBuilt)
348 buildOwnerOverlapToAllInterface ();
349 BC communicator;
350 communicator.template build<T>(OwnerOverlapToAllInterface);
351 communicator.template forward<AddGatherScatter<T> >(source,dest);
352 communicator.free();
353 }
354
361 template<class T>
362 void addOwnerCopyToAll (const T& source, T& dest) const
363 {
364 if (!OwnerCopyToAllInterfaceBuilt)
365 buildOwnerCopyToAllInterface ();
366 BC communicator;
367 communicator.template build<T>(OwnerCopyToAllInterface);
368 communicator.template forward<AddGatherScatter<T> >(source,dest);
369 communicator.free();
370 }
371
378 template<class T>
379 void addOwnerCopyToOwnerCopy (const T& source, T& dest) const
380 {
381 if (!OwnerCopyToOwnerCopyInterfaceBuilt)
382 buildOwnerCopyToOwnerCopyInterface ();
383 BC communicator;
384 communicator.template build<T>(OwnerCopyToOwnerCopyInterface);
385 communicator.template forward<AddGatherScatter<T> >(source,dest);
386 communicator.free();
387 }
388
389
397 template<class T1, class T2>
398 void dot (const T1& x, const T1& y, T2& result) const
399 {
400 using real_type = typename FieldTraits<typename T1::field_type>::real_type;
401 using size_type = typename std::vector<bool>::size_type;
402 // set up mask vector
403 if (mask.size()!=static_cast<size_type>(x.size()))
404 {
405 mask.assign(x.size(), true);
406 for (typename PIS::const_iterator i=pis.begin(); i!=pis.end(); ++i)
407 if (i->local().attribute()!=OwnerOverlapCopyAttributeSet::owner)
408 mask[i->local().local()] = false;
409 }
410 result = T2(0.0);
411
412 for (typename T1::size_type i=0; i<x.size(); i++)
413 result += (x[i]*(y[i]))*static_cast<real_type>(bool(mask[i]));
414 result = cc.sum(result);
415 }
416
423 template<class T1>
424 typename FieldTraits<typename T1::field_type>::real_type norm (const T1& x) const
425 {
426 using real_type = typename FieldTraits<typename T1::field_type>::real_type;
427 using size_type = typename std::vector<bool>::size_type;
428 // set up mask vector
429 if (mask.size()!=static_cast<size_type>(x.size()))
430 {
431 mask.assign(x.size(), true);
432 for (typename PIS::const_iterator i=pis.begin(); i!=pis.end(); ++i)
433 if (i->local().attribute()!=OwnerOverlapCopyAttributeSet::owner)
434 mask[i->local().local()] = false;
435 }
436 auto result = real_type(0.0);
437 for (typename T1::size_type i=0; i<x.size(); i++)
438 result += Impl::asVector(x[i]).two_norm2()*static_cast<real_type>(bool(mask[i]));
439 using std::sqrt;
440 return sqrt(cc.sum(result));
441 }
442
443 typedef Dune::EnumItem<AttributeSet,OwnerOverlapCopyAttributeSet::copy> CopyFlags;
444
446 typedef Dune::ParallelIndexSet<GlobalIdType,LI,512> ParallelIndexSet;
447
449 typedef Dune::RemoteIndices<PIS> RemoteIndices;
450
453 typedef Dune::GlobalLookupIndexSet<ParallelIndexSet> GlobalLookupIndexSet;
454
460 {
461 return pis;
462 }
463
469 {
470 return ri;
471 }
472
478 {
479 return pis;
480 }
481
482
488 {
489 return ri;
490 }
491
492 void buildGlobalLookup()
493 {
494 if(globalLookup_) {
495 if(pis.seqNo()==oldseqNo)
496 // Nothing changed!
497 return;
498 delete globalLookup_;
499 }
500
501 globalLookup_ = new GlobalLookupIndexSet(pis);
502 oldseqNo = pis.seqNo();
503 }
504
505 void buildGlobalLookup(std::size_t size)
506 {
507 if(globalLookup_) {
508 if(pis.seqNo()==oldseqNo)
509 // Nothing changed!
510 return;
511 delete globalLookup_;
512 }
513 globalLookup_ = new GlobalLookupIndexSet(pis, size);
514 oldseqNo = pis.seqNo();
515 }
516
517 void freeGlobalLookup()
518 {
519 delete globalLookup_;
520 globalLookup_=0;
521 }
522
523 const GlobalLookupIndexSet& globalLookup() const
524 {
525 assert(globalLookup_ != 0);
526 return *globalLookup_;
527 }
528
534 template<class T1>
535 void project (T1& x) const
536 {
537 for (typename PIS::const_iterator i=pis.begin(); i!=pis.end(); ++i)
538 if (i->local().attribute()==OwnerOverlapCopyAttributeSet::copy)
539 x[i->local().local()] = 0;
540 }
541
553 bool freecomm_ = false)
554 : comm(comm_), cc(comm_), pis(), ri(pis,pis,comm_),
555 OwnerToAllInterfaceBuilt(false), OwnerOverlapToAllInterfaceBuilt(false),
556 OwnerCopyToAllInterfaceBuilt(false), OwnerCopyToOwnerCopyInterfaceBuilt(false),
557 CopyToAllInterfaceBuilt(false), globalLookup_(0), category_(cat_),
558 freecomm(freecomm_)
559 {}
560
570 : comm(MPI_COMM_WORLD), cc(MPI_COMM_WORLD), pis(), ri(pis,pis,MPI_COMM_WORLD),
571 OwnerToAllInterfaceBuilt(false), OwnerOverlapToAllInterfaceBuilt(false),
572 OwnerCopyToAllInterfaceBuilt(false), OwnerCopyToOwnerCopyInterfaceBuilt(false),
573 CopyToAllInterfaceBuilt(false), globalLookup_(0), category_(cat_), freecomm(false)
574 {}
575
584 MPI_Comm comm_,
586 bool freecomm_ = false)
587 : comm(comm_), cc(comm_), OwnerToAllInterfaceBuilt(false),
588 OwnerOverlapToAllInterfaceBuilt(false), OwnerCopyToAllInterfaceBuilt(false),
589 OwnerCopyToOwnerCopyInterfaceBuilt(false), CopyToAllInterfaceBuilt(false),
590 globalLookup_(0), category_(cat_), freecomm(freecomm_)
591 {
592 // set up an ISTL index set
593 pis.beginResize();
594 for (localindex_iterator i=indexinfo.localIndices().begin(); i!=indexinfo.localIndices().end(); ++i)
595 {
596 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::owner)
597 pis.add(std::get<0>(*i),LI(std::get<1>(*i),OwnerOverlapCopyAttributeSet::owner,true));
598 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::overlap)
599 pis.add(std::get<0>(*i),LI(std::get<1>(*i),OwnerOverlapCopyAttributeSet::overlap,true));
600 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::copy)
601 pis.add(std::get<0>(*i),LI(std::get<1>(*i),OwnerOverlapCopyAttributeSet::copy,true));
602 // std::cout << cc.rank() << ": adding index " << std::get<0>(*i) << " " << std::get<1>(*i) << " " << std::get<2>(*i) << std::endl;
603 }
604 pis.endResize();
605
606 // build remote indices WITHOUT communication
607 // std::cout << cc.rank() << ": build remote indices" << std::endl;
608 ri.setIndexSets(pis,pis,cc);
609 if (indexinfo.remoteIndices().size()>0)
610 {
611 remoteindex_iterator i=indexinfo.remoteIndices().begin();
612 int p = std::get<0>(*i);
613 RILM modifier = ri.template getModifier<false,true>(p);
614 typename PIS::const_iterator pi=pis.begin();
615 for ( ; i!=indexinfo.remoteIndices().end(); ++i)
616 {
617 // handle processor change
618 if (p!=std::get<0>(*i))
619 {
620 p = std::get<0>(*i);
621 modifier = ri.template getModifier<false,true>(p);
622 pi=pis.begin();
623 }
624
625 // position to correct entry in parallel index set
626 while (pi->global()!=std::get<1>(*i) && pi!=pis.end())
627 ++pi;
628 if (pi==pis.end())
629 DUNE_THROW(ISTLError,"OwnerOverlapCopyCommunication: global index not in index set");
630
631 // insert entry
632 // std::cout << cc.rank() << ": adding remote index " << std::get<0>(*i) << " " << std::get<1>(*i) << " " << std::get<2>(*i) << std::endl;
633 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::owner)
634 modifier.insert(RX(OwnerOverlapCopyAttributeSet::owner,&(*pi)));
635 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::overlap)
636 modifier.insert(RX(OwnerOverlapCopyAttributeSet::overlap,&(*pi)));
637 if (std::get<2>(*i)==OwnerOverlapCopyAttributeSet::copy)
638 modifier.insert(RX(OwnerOverlapCopyAttributeSet::copy,&(*pi)));
639 }
640 }else{
641 // Force remote indices to be synced!
642 ri.template getModifier<false,true>(0);
643 }
644 }
645
646 // destructor: free memory in some objects
648 {
649 ri.free();
650 if (OwnerToAllInterfaceBuilt) OwnerToAllInterface.free();
651 if (OwnerOverlapToAllInterfaceBuilt) OwnerOverlapToAllInterface.free();
652 if (OwnerCopyToAllInterfaceBuilt) OwnerCopyToAllInterface.free();
653 if (OwnerCopyToOwnerCopyInterfaceBuilt) OwnerCopyToOwnerCopyInterface.free();
654 if (CopyToAllInterfaceBuilt) CopyToAllInterface.free();
655 if (globalLookup_) delete globalLookup_;
656 if (freecomm && (comm != MPI_COMM_NULL))
657 {
658 // If it is possible to query whether MPI_Finalize
659 // was called, only free the communicator before
660 // calling MPI_Finalize.
661 int wasFinalized = 0;
662 MPI_Finalized(&wasFinalized);
663 if (!wasFinalized) {
664 MPI_Comm_free(&comm);
665 }
666 }
667 }
668
669 private:
671 {}
672 MPI_Comm comm;
673 Communication<MPI_Comm> cc;
674 PIS pis;
675 RI ri;
676 mutable IF OwnerToAllInterface;
677 mutable bool OwnerToAllInterfaceBuilt;
678 mutable IF OwnerOverlapToAllInterface;
679 mutable bool OwnerOverlapToAllInterfaceBuilt;
680 mutable IF OwnerCopyToAllInterface;
681 mutable bool OwnerCopyToAllInterfaceBuilt;
682 mutable IF OwnerCopyToOwnerCopyInterface;
683 mutable bool OwnerCopyToOwnerCopyInterfaceBuilt;
684 mutable IF CopyToAllInterface;
685 mutable bool CopyToAllInterfaceBuilt;
686 mutable std::vector<bool> mask;
687 int oldseqNo;
688 GlobalLookupIndexSet* globalLookup_;
689 const SolverCategory::Category category_;
690 bool freecomm;
691 };
692
693#endif
694
695
698} // end namespace
699
700#endif
derive error class from the base class in common
Definition: istlexception.hh:19
Information about the index distribution.
Definition: owneroverlapcopy.hh:78
std::tuple< GlobalIdType, LocalIdType, int > IndexTripel
A triple describing a local index.
Definition: owneroverlapcopy.hh:92
void addRemoteIndex(const RemoteIndexTripel &x)
Add a new remote index triple to the set of remote indices.
Definition: owneroverlapcopy.hh:120
G GlobalIdType
The type of the global index.
Definition: owneroverlapcopy.hh:81
const std::set< IndexTripel > & localIndices() const
Get the set of indices local to the process.
Definition: owneroverlapcopy.hh:133
const std::set< RemoteIndexTripel > & remoteIndices() const
Get the set of remote indices.
Definition: owneroverlapcopy.hh:142
L LocalIdType
The type of the local index.
Definition: owneroverlapcopy.hh:84
void clear()
Remove all indices from the sets.
Definition: owneroverlapcopy.hh:150
void addLocalIndex(const IndexTripel &x)
Add a new index triple to the set of local indices.
Definition: owneroverlapcopy.hh:106
std::tuple< int, GlobalIdType, int > RemoteIndexTripel
A triple describing a remote index.
Definition: owneroverlapcopy.hh:99
A class setting up standard communication for a two-valued attribute set with owner/overlap/copy sema...
Definition: owneroverlapcopy.hh:174
FieldTraits< typenameT1::field_type >::real_type norm(const T1 &x) const
Compute the global Euclidean norm of a vector.
Definition: owneroverlapcopy.hh:424
OwnerOverlapCopyCommunication(const IndexInfoFromGrid< GlobalIdType, LocalIdType > &indexinfo, MPI_Comm comm_, SolverCategory::Category cat_=SolverCategory::overlapping, bool freecomm_=false)
Constructor.
Definition: owneroverlapcopy.hh:583
SolverCategory::Category category() const
Get Solver Category.
Definition: owneroverlapcopy.hh:295
void addOwnerCopyToOwnerCopy(const T &source, T &dest) const
Communicate values from owner and copy data points to owner and copy data points and add them to thos...
Definition: owneroverlapcopy.hh:379
RemoteIndices & remoteIndices()
Get the underlying remote indices.
Definition: owneroverlapcopy.hh:487
const ParallelIndexSet & indexSet() const
Get the underlying parallel index set.
Definition: owneroverlapcopy.hh:459
void addOwnerOverlapToAll(const T &source, T &dest) const
Communicate values from owner data points to all other data points and add them to those values.
Definition: owneroverlapcopy.hh:345
Dune::RemoteIndices< PIS > RemoteIndices
The type of the remote indices.
Definition: owneroverlapcopy.hh:449
void project(T1 &x) const
Set vector to zero at copy dofs.
Definition: owneroverlapcopy.hh:535
void copyCopyToAll(const T &source, T &dest) const
Communicate values from copy data points to all other data points.
Definition: owneroverlapcopy.hh:328
Dune::GlobalLookupIndexSet< ParallelIndexSet > GlobalLookupIndexSet
The type of the reverse lookup of indices.
Definition: owneroverlapcopy.hh:453
OwnerOverlapCopyCommunication(MPI_Comm comm_, SolverCategory::Category cat_=SolverCategory::overlapping, bool freecomm_=false)
Construct the communication without any indices.
Definition: owneroverlapcopy.hh:551
ParallelIndexSet & indexSet()
Get the underlying parallel index set.
Definition: owneroverlapcopy.hh:477
void dot(const T1 &x, const T1 &y, T2 &result) const
Compute a global dot product of two vectors.
Definition: owneroverlapcopy.hh:398
OwnerOverlapCopyCommunication(SolverCategory::Category cat_=SolverCategory::overlapping)
Construct the communication without any indices using MPI_COMM_WORLD.
Definition: owneroverlapcopy.hh:569
void copyOwnerToAll(const T &source, T &dest) const
Communicate values from owner data points to all other data points.
Definition: owneroverlapcopy.hh:311
const RemoteIndices & remoteIndices() const
Get the underlying remote indices.
Definition: owneroverlapcopy.hh:468
friend void loadMatrixMarket(M &, const std::string &, OwnerOverlapCopyCommunication< G, L > &, bool)
Load a parallel matrix/vector stored in matrix market format.
Definition: matrixmarket.hh:1312
void addOwnerCopyToAll(const T &source, T &dest) const
Communicate values from owner and copy data points to all other data points and add them to those val...
Definition: owneroverlapcopy.hh:362
Dune::ParallelIndexSet< GlobalIdType, LI, 512 > ParallelIndexSet
The type of the parallel index set.
Definition: owneroverlapcopy.hh:446
Provides classes for reading and writing MatrixMarket Files with an extension for parallel matrices.
Attribute set for overlapping Schwarz.
Definition: owneroverlapcopy.hh:59
gather/scatter callback for communication
Definition: owneroverlapcopy.hh:204
Category
Definition: solvercategory.hh:23
@ overlapping
Category for overlapping solvers.
Definition: solvercategory.hh:29
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (May 27, 22:36, 2026)