Loading [MathJax]/extensions/tex2jax.js
ug4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
feti.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3 * Authors: Ingo Heppner, Andreas Vogel
4 *
5 * This file is part of UG4.
6 *
7 * UG4 is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License version 3 (as published by the
9 * Free Software Foundation) with the following additional attribution
10 * requirements (according to LGPL/GPL v3 §7):
11 *
12 * (1) The following notice must be displayed in the Appropriate Legal Notices
13 * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 *
15 * (2) The following notice must be displayed at a prominent place in the
16 * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 *
18 * (3) The following bibliography is recommended for citation and must be
19 * preserved in all covered files:
20 * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 * parallel geometric multigrid solver on hierarchically distributed grids.
22 * Computing and visualization in science 16, 4 (2013), 151-164"
23 * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 * flexible software system for simulating pde based models on high performance
25 * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 *
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU Lesser General Public License for more details.
31 */
32
33/* TODO:
34 * If finished: Check for unnecessary "set zero" operations!
35 *
36 */
37
38#ifndef __H__UG__LIB_DISC__OPERATOR__LINEAR_OPERATOR__FETI__
39#define __H__UG__LIB_DISC__OPERATOR__LINEAR_OPERATOR__FETI__
40
41
42#ifdef UG_PARALLEL
43
44#include <iostream>
45#include <sstream>
46#include <string>
53#include "pcl/pcl.h"
54
55/*
56 * Outline of FETI-DP algorithm (after Klawonn, A., Widlund, O., Dryja, M.:
57 * "Dual-Primal FETI methods for three-dimensional elliptic problems with
58 * heterogeneous coefficients", SIAM J. Numer. Anal., 40/2002a, 159--179.):
59 *
60 * 1. eliminate the primal variables associated with the interior nodes,
61 * the vertex nodes designated as primal (as well as the Lagrange
62 * multipliers related to the optional constraints - if any)
63 * ==> reduced system with Schur complement \tilde{S} related to the subspace
64 * \tilde{W}_{\Delta}, and a reduced right hand side \tilde{f}_{\Delta}.
65 *
66 * 2. Reformulate as a variational problem, with a vector of Lagrange multipliers
67 * ==> saddle point problem.
68 *
69 * 3. Eliminate subvectors u_{\Delta}
70 * ==> system for the dual variables: F \lambda = d
71 *
72 * 4. Instead of solving ... action of the inverse of the Schur complement can be
73 * obtained by solving the entire linear system from which it originates after
74 * augmenting the given right hand side with zeros.
75 * Group all the interior and dual variables of each subdomain together
76 * and factor the resulting blocks in parallel across the subdomains using a
77 * good ordering algorithm.
78 *
79 * The contributions of the remaining Schur complement, of the primal variables,
80 * can also be computed locally prior to subassembly and factorization of this
81 * final, global part of the linear system of equations.
82 */
83
84namespace ug{
85
87
91template <typename TAlgebra>
93{
94 public:
95 // Algebra type
96 typedef TAlgebra algebra_type;
97
98 // Vector type
99 typedef typename TAlgebra::vector_type vector_type;
100
101 // Matrix type
102 typedef typename TAlgebra::matrix_type matrix_type;
103
104 public:
106
107 // assigns standard layouts, creates the feti layouts
109 size_t numIndices,
111 bool bDebug = false)
112 {
113 // if no indices, nothing to do
114 if(numIndices == 0) return;
115
116 m_spStdLayouts = stdLayouts;
118
119 // create FETI Layouts:
120 // \todo: For some documentation info see mail by S. Reiter, 30. Januar 2011 16:10:52 MEZ
121// (if the information therein is not already outdated ...)
124 m_spInnerLayouts->master(), m_spInnerLayouts->slave(),
127 stdLayouts->master(), stdLayouts->slave(),
128 (int)(numIndices - 1), DDInfo);
129 UG_LOG("[BuildDomainDecompositionLayouts done]");
130
131 // create intra feti subdomain communicator
132 int localSubdomID = DDInfo.map_proc_id_to_subdomain_id(pcl::ProcRank());
133 pcl::ProcessCommunicator worldComm;
134 for(int i = 0; i < DDInfo.get_num_subdomains(); ++i){
135 if(localSubdomID == i)
136 m_spInnerLayouts->proc_comm() = worldComm.create_sub_communicator(true);
137 else
138 worldComm.create_sub_communicator(false);
139 }
140 UG_LOG("[intra feti sd comms created]");
141
142 // create set of unique indices (to avoid doubles due to several interfaces)
143 // collect from dual layouts
146
149
152
155 UG_LOG("[CollectElements for duals done]");
156
157 // create union of all dual unknowns
162 UG_LOG("[union of duals created]");
163
164 // collect from primal layouts
167
170
171 // create union of all primal unknowns
174 UG_LOG("[CollectElements for primals done] ");
175
176 // test output
177 if(bDebug && false)
178 {
180 UG_LOG("STANDARD LAYOUTS:\n");
181 PrintLayout(m_spStdLayouts->proc_comm(), comTmp, m_spStdLayouts->master(), m_spStdLayouts->slave());
182 UG_LOG("INNER LAYOUTS:\n");
183 PrintLayout(m_spStdLayouts->proc_comm(), comTmp, m_spInnerLayouts->master(), m_spInnerLayouts->slave());
184 UG_LOG("PRIMAL LAYOUTS:\n");
185 PrintLayout(m_spStdLayouts->proc_comm(), comTmp, m_masterPrimalLayout, m_slavePrimalLayout);
186 UG_LOG("DUAL LAYOUTS:\n");
187 PrintLayout(m_spStdLayouts->proc_comm(), comTmp, m_masterDualLayout, m_slaveDualLayout);
188 UG_LOG("DUAL NBR LAYOUTS:\n");
189 PrintLayout(m_spStdLayouts->proc_comm(), comTmp, m_masterDualNbrLayout, m_slaveDualNbrLayout);
190 }
191 }
192
193 // tests the previously created layouts:
194 void test_layouts(bool bPrint)
195 {
196 if (m_spInnerLayouts.invalid() || m_spInnerLayouts.invalid()) {
197 UG_LOG("LAYOUTS not yet created!\n");
198 return;
199 }
201
202 UG_LOG("TEST STANDARD LAYOUTS:\n");
203 if (TestLayout(m_spStdLayouts->proc_comm(), comTmp, m_spStdLayouts->master(), m_spStdLayouts->slave(), bPrint) != true) {
204 UG_LOG("STANDARD LAYOUTS inconsistent!\n");
205 } else {
206 UG_LOG("STANDARD LAYOUTS are consistent!\n");
207 }
208
209 UG_LOG("TEST INNER LAYOUTS:\n");
210 if (TestLayout(m_spStdLayouts->proc_comm(), comTmp, m_spInnerLayouts->master(), m_spInnerLayouts->slave(), bPrint) != true) {
211 UG_LOG("INNER LAYOUTS inconsistent!\n");
212 } else {
213 UG_LOG("INNER LAYOUTS are consistent!\n");
214 }
215
216 UG_LOG("TEST PRIMAL LAYOUTS:\n");
217 if (TestLayout(m_spStdLayouts->proc_comm(), comTmp, m_masterPrimalLayout, m_slavePrimalLayout, bPrint) != true) {
218 UG_LOG("PRIMAL LAYOUTS inconsistent!\n");
219 } else {
220 UG_LOG("PRIMAL LAYOUTS are consistent!\n");
221 }
222
223 UG_LOG("TEST DUAL LAYOUTS:\n");
224 if (TestLayout(m_spStdLayouts->proc_comm(), comTmp, m_masterDualLayout, m_slaveDualLayout, bPrint) != true) {
225 UG_LOG("DUAL LAYOUTS inconsistent!\n");
226 } else {
227 UG_LOG("DUAL LAYOUTS are consistent!\n");
228 }
229
230 UG_LOG("TEST DUAL NBR LAYOUTS:\n");
231 if (TestLayout(m_spStdLayouts->proc_comm(), comTmp, m_masterDualNbrLayout, m_slaveDualNbrLayout, bPrint) != true) {
232 UG_LOG("DUAL NBR LAYOUTS inconsistent!\n");
233 } else {
234 UG_LOG("DUAL NBR LAYOUTS are consistent!\n");
235 }
236 }
237
238 // standard layouts
242
243 // intra subdomain layouts
247
248 // dual layouts
251 const std::vector<IndexLayout::Element>& get_dual_master_indices() const {return m_vUniqueMasterDualIndex;}
252 const std::vector<IndexLayout::Element>& get_dual_slave_indices() const {return m_vUniqueSlaveDualIndex;}
253
254 // dual nbr layouts
257 const std::vector<IndexLayout::Element>& get_dual_nbr_master_indices() const {return m_vUniqueMasterDualNbrIndex;}
258 const std::vector<IndexLayout::Element>& get_dual_nbr_slave_indices() const {return m_vUniqueSlaveDualNbrIndex;}
259
260 // primal layouts
263 const std::vector<IndexLayout::Element>& get_primal_master_indices() const {return m_vUniquePrimalMasterIndex;}
264 const std::vector<IndexLayout::Element>& get_primal_slave_indices() const {return m_vUniquePrimalSlaveIndex;}
265
266 // union of indices
267 const std::vector<IndexLayout::Element>& get_primal_indices() const {return m_vUniquePrimalIndex;}
268 const std::vector<IndexLayout::Element>& get_dual_indices() const {return m_vUniqueDualIndex;}
269
270 public:
271
272 // sets standard communication layouts and communicators
274 {
275 vec.set_layouts(m_spStdLayouts);
276 }
277
278 // sets intra subdomain communication layouts and communicators
280 {
281 vec.set_layouts(m_spInnerLayouts);
282 }
283
284 public:
287 number alpha1, const vector_type& vecSrc1,
288 number alpha2, const vector_type& vecSrc2)
289 {
290 VecScaleAdd(vecDest, alpha1, vecSrc1, alpha2, vecSrc2, m_vUniqueDualIndex);
291 }
292
295 number alpha1, const vector_type& vecSrc1,
296 number alpha2, const vector_type& vecSrc2)
297 {
298 VecScaleAdd(vecDest, alpha1, vecSrc1, alpha2, vecSrc2, m_vUniquePrimalIndex);
299 }
300
303 const vector_type& vecSrc1, number alpha1)
304 {
305 VecScaleAdd(vecInOut, alpha1, vecSrc1, 1.0, vecInOut, m_vUniqueDualIndex);
306 }
307
310 const vector_type& vecSrc1, number alpha1)
311 {
312 VecScaleAdd(vecInOut, alpha1, vecSrc1, 1.0, vecInOut, m_vUniquePrimalIndex);
313 }
314
316 void vec_set_on_dual(vector_type& vecDest, number alpha)
317 {
318 VecSet(vecDest, alpha, m_vUniqueDualIndex);
319 }
320
323 {
324 VecSet(vecDest, alpha, m_vUniquePrimalIndex);
325 }
326
328 void vec_scale_assign_on_dual(vector_type& vecDest, const vector_type& vecSrc, number alpha)
329 {
330 VecScaleAssign(vecDest, alpha, vecSrc, m_vUniqueDualIndex);
331 }
332
334 void vec_scale_assign_on_primal(vector_type& vecDest, const vector_type& vecSrc, number alpha)
335 {
336 VecScaleAssign(vecDest, alpha, vecSrc, m_vUniquePrimalIndex);
337 }
338
341 {
342 // forward to VecProc
343 return sqrt(vec_prod_on_identified_dual(vec, vec));
344 }
345
347 {
348 // compute norm on dual master indices
349 double tProdLocal = VecProd(vecSrc1, vecSrc2, m_vUniqueMasterDualIndex);
350
351 // global value
352 double tProdGlobal;
353
354 // sum up values
355 m_spStdLayouts->proc_comm().allreduce(&tProdLocal, &tProdGlobal, 1,
357
358 // return result
359 return tProdGlobal;
360 }
361
362 public:
367
372
373 // sets standard communication layouts and communicators
375 {
376 mat.set_slave_layout(get_std_slave_layout());
377 mat.set_master_layout(get_std_master_layout());
378 mat.set_process_communicator(get_std_process_communicator());
379 }
380
381 // sets intra subdomain communication layouts and communicators
383 {
384 mat.set_layouts(m_spInnerLayouts);
385 }
386
387 protected:
388 void sort_and_remove_doubles(std::vector<IndexLayout::Element>& vIndex)
389 {
390 // sort vector
391 std::sort(vIndex.begin(), vIndex.end());
392
393 // remove doubles
394 vIndex.erase(std::unique(vIndex.begin(), vIndex.end()),
395 vIndex.end());
396 }
397
398 void add_merge_sort_remove_doubles(std::vector<IndexLayout::Element>& vOut,
399 const std::vector<IndexLayout::Element>& v)
400 {
401 // on entry, vOut and v are supposed to be sorted
402
403 // original size of vOut
404 size_t mid = vOut.size();
405
406 // add second vector
407 vOut.insert(vOut.end(), v.begin(), v.end() );
408
409 // merge both
410 std::inplace_merge(vOut.begin(), vOut.begin()+mid, vOut.end());
411
412 // remove doubles
413 vOut.erase(std::unique(vOut.begin(), vOut.end()),
414 vOut.end());
415 }
416
417 protected:
418 // Standard Layouts
420
421 // Layouts and Communicator for Inner variables
423
424 // Layouts for Dual variables
427 std::vector<IndexLayout::Element> m_vUniqueMasterDualIndex;
428 std::vector<IndexLayout::Element> m_vUniqueSlaveDualIndex;
429
430 // Layouts for Dual Neighbour variables
433 std::vector<IndexLayout::Element> m_vUniqueMasterDualNbrIndex;
434 std::vector<IndexLayout::Element> m_vUniqueSlaveDualNbrIndex;
435
436 // Layouts for Primal variables
439 std::vector<IndexLayout::Element> m_vUniquePrimalMasterIndex;
440 std::vector<IndexLayout::Element> m_vUniquePrimalSlaveIndex;
441
442 // unique indices for layouts
443 std::vector<IndexLayout::Element> m_vUniqueDualIndex;
444 std::vector<IndexLayout::Element> m_vUniquePrimalIndex;
445
446}; /* end class 'FetiLayouts' */
447
449
466template <typename TVector>
467void ComputeDifferenceOnDelta(TVector& diff, const TVector& u,
468 IndexLayout& dualMasterLayoutIn,
469 IndexLayout& dualSlaveLayoutIn,
470 IndexLayout& dualNbrMasterLayoutIn,
471 IndexLayout& dualNbrSlaveLayoutIn)
472{
473 // Copy all values
474 diff = u;
475
476 // Communicate values:
477 // (a) Slaves send their u values, every master subtracts the value of only
478 // one of his slaves ...
479 VecSubtractOneSlaveFromMaster(&diff, dualMasterLayoutIn, dualSlaveLayoutIn);
480
481 // (b) masters send their diff values to all slaves (but not vice versa)
482 VecCopy(&diff, dualMasterLayoutIn, dualSlaveLayoutIn);
483
484 // (c) and also to the additional slaves living in "Dual neighbour layout"
485 VecCopy(&diff, dualNbrMasterLayoutIn, dualNbrSlaveLayoutIn);
486
487 // now the vector 'diff' should be consistent!
488 return;
489};
490
492
506template <typename TVector>
507void ComputeDifferenceOnDeltaTransposed(TVector& f, const TVector& diff,
508 const std::vector<IndexLayout::Element>& vDualMasterIndex,
509 const std::vector<IndexLayout::Element>& vDualSlaveIndex,
510 const std::vector<IndexLayout::Element>& vDualNbrSlaveIndex)
511{
512 // Copy values (no communication is performed):
513 // (a) set f = +1 * d on masters ...
514 VecScaleAssign(f, 1.0, diff, vDualMasterIndex);
515
516 // (b) set f = -1 * d on slaves
517 VecScaleAssign(f, -1.0, diff, vDualSlaveIndex);
518
519 // (c) set f = +1 * d on slaves living in "Dual neighbour layout"
520 // ("+1" since in this context these dofs play the role of masters!)
521 VecScaleAssign(f, +1.0, diff, vDualNbrSlaveIndex);
522 return;
523
524};
525
527
536template <typename TAlgebra>
538 : public ILinearOperator< typename TAlgebra::vector_type,
539 typename TAlgebra::vector_type>,
540 public DebugWritingObject<TAlgebra>
541{
542 public:
543 // Algebra type
544 typedef TAlgebra algebra_type;
545
546 // Vector type
547 typedef typename TAlgebra::vector_type vector_type;
548
549 // Matrix type
550 typedef typename TAlgebra::matrix_type matrix_type;
551
552 protected:
553 using DebugWritingObject<TAlgebra>::write_debug;
554 using DebugWritingObject<TAlgebra>::debug_writer;
555
556 public:
559
561 virtual const char* name() const {return "Local Schur Complement Solver";}
562
564
587 {
588 // save current operator
589 m_spOperator = A;
590 }
591
593
598 {
599 // remember the Dirichlet Solver
600 m_spDirichletSolver = dirichletSolver;
601 }
602
605 {
606 m_pFetiLayouts = &fetiLayouts;
607 }
608
610 void init(const vector_type& u) {init();}
611
613
620 virtual void init();
621
624 virtual void apply(vector_type& f, const vector_type& u);
625
627 virtual void apply_sub(vector_type& f, const vector_type& u);
628
630 void set_statistic_type(std::string type) {m_statType = type;}
631
633 void print_statistic_of_inner_solver(bool bPrintOnlyAverages); // const;
634
637
638 // destructor
640
641 protected:
642 // Operator that is inverted by this Inverse Operator
644
645 // Parallel Matrix
647
648 // Feti Layouts
650
651 // Copy of matrix
653
654 // Parallel Dirichlet Matrix
656
657 // Linear Solver to invert the local Dirichlet problems
659
660 // Convergence history
661 std::string m_statType;
662
663 struct StepConv
664 {
667 };
668
669 std::map<std::string, std::vector<StepConv> > m_mvStepConv;
670
672
674
675}; /* end class 'LocalSchurComplement' */
676
677/* 1.7 Application of \f${\tilde{S}_{\Delta \Delta}}^{-1}\f$ */
679
683template <typename TAlgebra>
685 : public ILinearOperatorInverse< typename TAlgebra::vector_type,
686 typename TAlgebra::vector_type>,
687 public DebugWritingObject<TAlgebra>
688{
689 public:
690 // Algebra type
691 typedef TAlgebra algebra_type;
692
693 // Vector type
694 typedef typename TAlgebra::vector_type vector_type;
695
696 // Matrix type
697 typedef typename TAlgebra::matrix_type matrix_type;
698
701
702 protected:
704 using DebugWritingObject<TAlgebra>::write_debug;
705 using DebugWritingObject<TAlgebra>::debug_writer;
706
707 public:
710
712 virtual const char* name() const {return "Schur Complement Inverse";}
713
715 virtual bool supports_parallel() const
716 {
717 bool bRet = true;
719 bRet = false;
721 bRet = false;
722 return bRet;
723 }
724
727 {
728 // remember the Dirichlet Solver
729 m_spNeumannSolver = neumannSolver;
730 }
731
734 {
735 // remember the coarse problem Solver
736 m_spCoarseProblemSolver = coarseProblemSolver;
737 }
738
741 {
742 m_pFetiLayouts = &fetiLayouts;
743 }
744
745 // Init for Linear Operator L
747
748
749 // Init for Linear Operator J and Linearization point (current solution)
751 {
752 return init(J);
753 }
754
755 // Solve A*u = f, such that u = A^{-1} f
756 virtual bool apply(vector_type& u, const vector_type& f);
757
758 // Solve A*u = f, such that u = A^{-1} f
759 // This is done by iterating: u := u + B(f - A*u)
760 // In f the last defect f := f - A*u is returned
761 virtual bool apply_return_defect(vector_type& u, vector_type& f);
762
764 void set_statistic_type(std::string type) {m_statType = type;}
765
767 void print_statistic_of_inner_solver(bool bPrintOnlyAverages); // const;
768
771
774
775 // destructor
777
778 protected:
779 // Operator that is inverted by this Inverse Operator ==> from which SC is built (05022011)
781
782 // Parallel Matrix to invert ==> from which SC is built (05022011)
784
785 // Feti Layouts
787
788 // Copy of matrix
790
791 // Parallel Neumann Matrix
793
794 // Neumann Solver
796
797 // Coarse problem Solver on root.
799
800 // Process gathering the Schur Complement w.r.t. Primal unknowns
802
803 // Layouts for all to one communication
807
808 // Schur Complement operator for gathered matrix
810
811 // Matrix for one proc Schur complement
813
814 // Convergence history
815 std::string m_statType;
816
826
827 std::map<std::string, std::vector<StepConv> > m_mvStepConv;
828
829 // testing of 'one-to-many layouts'
831
833
834}; /* end class 'PrimalSubassembledMatrixInverse' */
835
837
842template <typename TAlgebra>
843class FETISolver : public IMatrixOperatorInverse< typename TAlgebra::matrix_type,
844 typename TAlgebra::vector_type>,
845 public DebugWritingObject<TAlgebra>
846{
847 public:
848 // Algebra type
849 typedef TAlgebra algebra_type;
850
851 // Vector type
852 typedef typename TAlgebra::vector_type vector_type;
853
854 // Matrix type
855 typedef typename TAlgebra::matrix_type matrix_type;
856
859
860 protected:
862 using DebugWritingObject<TAlgebra>::write_debug;
863 using DebugWritingObject<TAlgebra>::debug_writer;
864
865 public:
867 FETISolver();
868
870 virtual const char* name() const {return "FETI Solver";}
871
873 virtual bool supports_parallel() const
874 {
877 return false;
880 return false;
883 return false;
884 return true;
885 }
886
889 {
890 // remember the Dirichlet Solver
891 m_spDirichletSolver = dirichletSolver;
892 }
893
896 {
897 // remember the Dirichlet Solver
898 m_spNeumannSolver = neumannSolver;
899 }
900
903 {
904 // remember the coarse problem Solver
905 m_spCoarseProblemSolver = coarseProblemSolver;
906 }
907
908 // set debug output
915
918
920
929 bool apply_F(vector_type& f, const vector_type& v);
930
932
941 bool compute_d(vector_type& d, const vector_type& f);
942
944 bool apply_scaling_matrix(vector_type& s, const vector_type& v) // maybe restrict to layout
945 {
946 // copy values
947 s = v;
948
949 // scale by 1/2
950 s *= 1./2.;
951
952 // \todo: more general: m_Ddelta.apply(s,v), with additional member 'matrix_type m_Ddelta;'
953
954 // we're done
955 return true;
956 }
957
959
966 bool apply_M_inverse(vector_type& z, const vector_type& r);
967
968 // tests layouts:
969 void test_layouts(bool bPrint);
970
971 // set member 'm_bTestOneToManyLayouts' of class 'PrimalSubassembledMatrixInverse':
976
977
981 virtual bool apply_return_defect(vector_type& lambda, vector_type& d);
982
984 virtual bool apply(vector_type& x, const vector_type& b)
985 {
986 // copy defect
987 vector_type d; d.resize(b.size());
988 d = b;
989
990 // solve on copy of defect
991 return apply_return_defect(x, d);
992 }
993
995 void print_statistic_of_inner_solver(bool bPrintOnlyAverages) //const
996 {
997 // sum over all calls of inner solvers is done in the following print functions!
1000 UG_LOG("\n");
1001
1004
1006 totalIterCntOfInnerSolvers += m_LocalSchurComplement.get_total_itercnt_of_inner_solvers();
1007
1008 UG_LOG("Total number of calls of sub problem solvers: " << totalIterCntOfInnerSolvers);
1009 UG_LOG(" in " << std::setw(5) << m_iterCnt << " FETI iterations ");
1010 UG_LOG(" on " << std::setw(5) << m_pDDInfo->get_num_subdomains() << " FETI subdomains, "
1011 << std::fixed << (double)totalIterCntOfInnerSolvers/m_iterCnt
1012 << std::scientific << " per FETI iteration, "
1013 << std::fixed << (double)totalIterCntOfInnerSolvers/m_pDDInfo->get_num_subdomains()
1014 << std::scientific << " per FETI subdomain.\n");
1015
1016 }
1017
1018 // destructor
1019 virtual ~FETISolver() {};
1020
1021 protected:
1022 // Prepare the convergence check
1024 {
1025 convergence_check()->set_name(name());
1026 convergence_check()->set_symbol('%');
1027
1028 // set preconditioner string
1029 std::stringstream ss;
1030 ss << " (Inherent Preconditioner) ";
1031 convergence_check()->set_info(ss.str());
1032 }
1033
1034 protected:
1035 virtual void write_debug(const vector_type& vec, const char* filename)
1036 {
1037 // add iter count to name
1038 std::string name(filename);
1039 char ext[20]; snprintf(ext, 20, "_iter%03d.vec", m_iterCnt);
1040 name.append(ext);
1041
1042 // if no debug writer set, we're done
1043 if(debug_writer() == SPNULL) return;
1044
1045 // write
1046 debug_writer()->write_vector(vec, name.c_str());
1047 }
1048
1050
1051 protected:
1052 // Operator that is inverted by this Inverse Operator
1054
1055 // Parallel Matrix to invert
1057
1058 // Feti Layouts
1060
1061 // Local Schur complement for each feti subdomain
1063
1064 // Dirichlet solver for inverse of \f$A_{II}\f$ in local Schur complement
1066
1067 // PrimalSubassembledMatrixInverse
1069
1070 // Neumann solver for inverse of \f$A_{\{I,\Delta\}, \{I,\Delta\}}\f$ in the
1071 // creation of the S_{\Pi \Pi} Schur complement in PrimalSubassembledMatrixInverse
1073
1074 // Solver used in solving coarse problem on root.
1075 // It solves \f$S_{\Pi \Pi} u_{\Pi} = \tilde{f}_{\Pi}\f$
1077
1078 public:
1080 {
1081 m_pDDInfo = &ddInfo;
1082 }
1083
1084 private:
1085 // pointer to Domain decomposition info object
1087
1088}; /* end class 'FETISolver' */
1089
1090} // end namespace ug
1091
1092#endif /* UG_PARALLEL */
1093
1094#endif /* __H__UG__LIB_DISC__OPERATOR__LINEAR_OPERATOR__FETI__ */
parameterString s
Definition smart_pointer.h:296
Definition smart_pointer.h:108
bool valid() const
returns true if the pointer is valid, false if not.
Definition smart_pointer.h:206
Definition pcl_domain_decomposition.h:43
virtual int get_num_subdomains() const =0
virtual int map_proc_id_to_subdomain_id(int procID) const =0
mapping method "proc-id" ==> "subdomain-id"
Performs communication between interfaces on different processes.
Definition pcl_interface_communicator.h:68
Definition pcl_process_communicator.h:70
ProcessCommunicator create_sub_communicator(bool participate) const
creates a new communicator containing a subset of the current communicator
Definition pcl_process_communicator.cpp:122
Extends the HorizontalAlgebraLayouts by vertical layouts.
Definition algebra_layouts.h:121
Definition debug_writer.h:354
virtual void set_debug(SmartPtr< IDebugWriter< algebra_type > > spDebugWriter)
set debug writer
Definition debug_writer.h:384
void write_debug(const matrix_type &mat, const char *filename)
write debug output for a matrix (if debug writer set)
Definition debug_writer.h:399
SmartPtr< IDebugWriter< algebra_type > > debug_writer()
returns the debug writer
Definition debug_writer.h:391
operator implementation of the FETI-DP solver
Definition feti.h:846
virtual ~FETISolver()
Definition feti.h:1019
ILinearOperatorInverse< vector_type > base_type
Base type.
Definition feti.h:858
virtual bool apply(vector_type &x, const vector_type &b)
solves the system
Definition feti.h:984
TAlgebra::vector_type vector_type
Definition feti.h:852
virtual bool apply_return_defect(vector_type &lambda, vector_type &d)
Definition feti.cpp:1501
void prepare_conv_check()
Definition feti.h:1023
LocalSchurComplement< algebra_type > m_LocalSchurComplement
Definition feti.h:1062
bool apply_scaling_matrix(vector_type &s, const vector_type &v)
function which applies diagonal scaling matrix to a vector
Definition feti.h:944
FETISolver()
constructor
Definition feti.cpp:1363
virtual void write_debug(const vector_type &vec, const char *filename)
Definition feti.h:1035
SmartPtr< ILinearOperatorInverse< vector_type > > m_spCoarseProblemSolver
Definition feti.h:1076
virtual const char * name() const
name of solver
Definition feti.h:870
void set_dirichlet_solver(SmartPtr< ILinearOperatorInverse< vector_type > > dirichletSolver)
sets the Dirichlet solver
Definition feti.h:888
void set_debug(SmartPtr< IDebugWriter< algebra_type > > spDebugWriter)
set debug writer
Definition feti.h:909
int m_iterCnt
Definition feti.h:1049
PrimalSubassembledMatrixInverse< algebra_type > m_PrimalSubassembledMatrixInverse
Definition feti.h:1068
void print_statistic_of_inner_solver(bool bPrintOnlyAverages)
prints some convergence statistic of inner solvers
Definition feti.h:995
void set_domain_decomp_info(pcl::IDomainDecompositionInfo &ddInfo)
Definition feti.h:1079
void set_test_one_to_many_layouts(bool bTest)
Definition feti.h:972
bool apply_M_inverse(vector_type &z, const vector_type &r)
function which applies matrix to a vector
Definition feti.cpp:1820
TAlgebra::matrix_type matrix_type
Definition feti.h:855
virtual bool supports_parallel() const
returns if parallel solving is supported
Definition feti.h:873
bool apply_F(vector_type &f, const vector_type &v)
function which applies matrix of the reduced system ("Delta system") to a vector
Definition feti.cpp:1742
SmartPtr< ILinearOperatorInverse< vector_type > > m_spDirichletSolver
Definition feti.h:1065
SmartPtr< ILinearOperatorInverse< vector_type > > m_spNeumannSolver
Definition feti.h:1072
void test_layouts(bool bPrint)
Definition feti.cpp:1874
SmartPtr< MatrixOperator< matrix_type, vector_type > > m_spOperator
Definition feti.h:1053
void set_neumann_solver(SmartPtr< ILinearOperatorInverse< vector_type > > neumannSolver)
sets the Neumann solver
Definition feti.h:895
bool compute_d(vector_type &d, const vector_type &f)
function which computes right hand side vector 'd' of the dual unknowns
Definition feti.cpp:1783
FetiLayouts< algebra_type > m_fetiLayouts
Definition feti.h:1059
TAlgebra algebra_type
Definition feti.h:849
pcl::IDomainDecompositionInfo * m_pDDInfo
Definition feti.h:1086
void set_coarse_problem_solver(SmartPtr< ILinearOperatorInverse< vector_type > > coarseProblemSolver)
sets the coarse problem solver
Definition feti.h:902
matrix_type * m_pMatrix
Definition feti.h:1056
Auxiliary class for handling of "FETI layouts".
Definition feti.h:93
void vec_use_intra_sd_communication(vector_type &vec)
Definition feti.h:279
const pcl::ProcessCommunicator & get_std_process_communicator()
Definition feti.h:241
void vec_set_on_dual(vector_type &vecDest, number alpha)
sets vecDest = alpha on dual
Definition feti.h:316
void vec_scale_assign_on_primal(vector_type &vecDest, const vector_type &vecSrc, number alpha)
calculates vecDest = alpha*vecSrc on primal
Definition feti.h:334
IndexLayout & get_intra_sd_master_layout()
Definition feti.h:244
IndexLayout m_masterDualNbrLayout
Definition feti.h:431
void mat_use_intra_sd_communication(matrix_type &mat)
Definition feti.h:382
void vec_scale_add_on_primal(vector_type &vecDest, number alpha1, const vector_type &vecSrc1, number alpha2, const vector_type &vecSrc2)
calculates vecDest = alpha1*vecSource1 + alpha2*vecSource2 on primal
Definition feti.h:294
void mat_set_dirichlet_on_dual(matrix_type &mat)
Definition feti.h:363
std::vector< IndexLayout::Element > m_vUniqueSlaveDualIndex
Definition feti.h:428
void vec_set_on_primal(vector_type &vecDest, number alpha)
sets vecDest = alpha on primal
Definition feti.h:322
void test_layouts(bool bPrint)
Definition feti.h:194
const std::vector< IndexLayout::Element > & get_primal_indices() const
Definition feti.h:267
const std::vector< IndexLayout::Element > & get_dual_indices() const
Definition feti.h:268
IndexLayout & get_primal_master_layout()
Definition feti.h:261
void mat_use_std_communication(matrix_type &mat)
Definition feti.h:374
ConstSmartPtr< AlgebraLayouts > m_spStdLayouts
Definition feti.h:419
TAlgebra::matrix_type matrix_type
Definition feti.h:102
number vec_prod_on_identified_dual(const vector_type &vecSrc1, const vector_type &vecSrc2)
Definition feti.h:346
const std::vector< IndexLayout::Element > & get_primal_master_indices() const
Definition feti.h:263
pcl::ProcessCommunicator & get_intra_sd_process_communicator()
Definition feti.h:246
std::vector< IndexLayout::Element > m_vUniquePrimalSlaveIndex
Definition feti.h:440
IndexLayout & get_dual_nbr_slave_layout()
Definition feti.h:256
void mat_set_dirichlet_on_primal(matrix_type &mat)
Definition feti.h:368
IndexLayout & get_dual_slave_layout()
Definition feti.h:250
const std::vector< IndexLayout::Element > & get_primal_slave_indices() const
Definition feti.h:264
IndexLayout m_slaveDualNbrLayout
Definition feti.h:432
void create_layouts(ConstSmartPtr< AlgebraLayouts > stdLayouts, size_t numIndices, pcl::IDomainDecompositionInfo &DDInfo, bool bDebug=false)
Definition feti.h:108
std::vector< IndexLayout::Element > m_vUniqueMasterDualIndex
Definition feti.h:427
number vec_norm_on_identified_dual(vector_type &vec)
calculates norm on dual
Definition feti.h:340
std::vector< IndexLayout::Element > m_vUniquePrimalMasterIndex
Definition feti.h:439
IndexLayout & get_dual_master_layout()
Definition feti.h:249
const IndexLayout & get_std_slave_layout()
Definition feti.h:240
void vec_scale_add_on_dual(vector_type &vecDest, number alpha1, const vector_type &vecSrc1, number alpha2, const vector_type &vecSrc2)
calculates vecDest = alpha1*vecSource1 + alpha2*vecSource2 on dual
Definition feti.h:286
std::vector< IndexLayout::Element > m_vUniquePrimalIndex
Definition feti.h:444
const std::vector< IndexLayout::Element > & get_dual_slave_indices() const
Definition feti.h:252
FetiLayouts()
Definition feti.h:105
SmartPtr< AlgebraLayouts > m_spInnerLayouts
Definition feti.h:422
const std::vector< IndexLayout::Element > & get_dual_nbr_master_indices() const
Definition feti.h:257
void vec_scale_append_on_primal(vector_type &vecInOut, const vector_type &vecSrc1, number alpha1)
calculates vecInOut += alpha1*vecSrc1 on primal
Definition feti.h:309
IndexLayout & get_dual_nbr_master_layout()
Definition feti.h:255
IndexLayout m_masterDualLayout
Definition feti.h:425
void vec_use_std_communication(vector_type &vec)
Definition feti.h:273
IndexLayout & get_intra_sd_slave_layout()
Definition feti.h:245
IndexLayout & get_primal_slave_layout()
Definition feti.h:262
const IndexLayout & get_std_master_layout()
Definition feti.h:239
const std::vector< IndexLayout::Element > & get_dual_nbr_slave_indices() const
Definition feti.h:258
IndexLayout m_slaveDualLayout
Definition feti.h:426
IndexLayout m_slavePrimalLayout
Definition feti.h:438
void vec_scale_assign_on_dual(vector_type &vecDest, const vector_type &vecSrc, number alpha)
calculates vecDest = alpha*vecSrc on dual
Definition feti.h:328
std::vector< IndexLayout::Element > m_vUniqueMasterDualNbrIndex
Definition feti.h:433
std::vector< IndexLayout::Element > m_vUniqueDualIndex
Definition feti.h:443
IndexLayout m_masterPrimalLayout
Definition feti.h:437
TAlgebra algebra_type
Definition feti.h:96
std::vector< IndexLayout::Element > m_vUniqueSlaveDualNbrIndex
Definition feti.h:434
const std::vector< IndexLayout::Element > & get_dual_master_indices() const
Definition feti.h:251
void add_merge_sort_remove_doubles(std::vector< IndexLayout::Element > &vOut, const std::vector< IndexLayout::Element > &v)
Definition feti.h:398
void vec_scale_append_on_dual(vector_type &vecInOut, const vector_type &vecSrc1, number alpha1)
calculates vecInOut += alpha1*vecSrc1 on dual
Definition feti.h:302
TAlgebra::vector_type vector_type
Definition feti.h:99
void sort_and_remove_doubles(std::vector< IndexLayout::Element > &vIndex)
Definition feti.h:388
base class for all debug writer
Definition debug_writer.h:244
describes a linear mapping X->Y
Definition linear_operator.h:80
describes an inverse linear mapping X->Y
Definition linear_operator_inverse.h:80
ConstSmartPtr< IConvergenceCheck< vector_type > > convergence_check() const
returns the convergence check
Definition linear_operator_inverse.h:202
virtual bool supports_parallel() const =0
returns if parallel solving is supported
describes an inverse linear mapping X->Y based on a matrix
Definition matrix_operator_inverse.h:64
operator implementation of the local Schur complement
Definition feti.h:541
SmartPtr< ILinearOperatorInverse< vector_type > > m_spDirichletSolver
Definition feti.h:658
void init(const vector_type &u)
implementation of the operator for the solution dependent initialization.
Definition feti.h:610
SmartPtr< MatrixOperator< matrix_type, vector_type > > m_spOperator
Definition feti.h:643
void set_statistic_type(std::string type)
sets statistic slot where next iterate should be counted
Definition feti.h:630
matrix_type * m_pMatrix
Definition feti.h:646
int get_total_itercnt_of_inner_solvers()
Definition feti.h:636
SmartPtr< MatrixOperator< matrix_type, vector_type > > m_spDirichletOperator
Definition feti.h:652
LocalSchurComplement()
constructor
Definition feti.cpp:98
void print_statistic_of_inner_solver(bool bPrintOnlyAverages)
prints some convergence statistic of inner solvers
Definition feti.cpp:283
std::string m_statType
Definition feti.h:661
virtual void apply_sub(vector_type &f, const vector_type &u)
solves the system
Definition feti.cpp:268
std::map< std::string, std::vector< StepConv > > m_mvStepConv
Definition feti.h:669
matrix_type * m_pDirichletMatrix
Definition feti.h:655
virtual void apply(vector_type &f, const vector_type &u)
Definition feti.cpp:154
int m_totalIterCntOfInnerSolvers
Definition feti.h:673
FetiLayouts< algebra_type > * m_pFetiLayouts
Definition feti.h:649
int m_applyCnt
Definition feti.h:671
TAlgebra algebra_type
Definition feti.h:544
virtual const char * name() const
name of solver
Definition feti.h:561
void set_feti_layouts(FetiLayouts< algebra_type > &fetiLayouts)
sets the primal layouts
Definition feti.h:604
virtual void init()
initializes the solver for operator A
Definition feti.cpp:109
void set_matrix(SmartPtr< MatrixOperator< matrix_type, vector_type > > A)
set original matrix from which the local Schur complement is constructed
Definition feti.h:586
TAlgebra::vector_type vector_type
Definition feti.h:547
void set_dirichlet_solver(SmartPtr< ILinearOperatorInverse< vector_type > > dirichletSolver)
sets a sequential Dirichlet solver
Definition feti.h:597
void clear_total_itercnt_of_inner_solvers()
Definition feti.h:635
virtual ~LocalSchurComplement()
Definition feti.h:639
TAlgebra::matrix_type matrix_type
Definition feti.h:550
Definition matrix_operator.h:49
operator implementation of the inverse of the Schur complement w.r.t. the "Delta unknowns"
Definition feti.h:688
SmartPtr< ILinearOperatorInverse< vector_type > > m_spNeumannSolver
Definition feti.h:795
std::map< std::string, std::vector< StepConv > > m_mvStepConv
Definition feti.h:827
void set_coarse_problem_solver(SmartPtr< ILinearOperatorInverse< vector_type > > coarseProblemSolver)
sets the coarse problem solver
Definition feti.h:733
SmartPtr< ILinearOperatorInverse< vector_type > > m_spCoarseProblemSolver
Definition feti.h:798
SmartPtr< MatrixOperator< matrix_type, vector_type > > m_spOperator
Definition feti.h:780
int m_primalRootProc
Definition feti.h:801
virtual bool init(SmartPtr< ILinearOperator< vector_type > > J, const vector_type &u)
Definition feti.h:750
std::string m_statType
Definition feti.h:815
IndexLayout m_masterAllToOneLayout
Definition feti.h:804
bool m_bTestOneToManyLayouts
Definition feti.h:830
FetiLayouts< algebra_type > * m_pFetiLayouts
Definition feti.h:786
void clear_total_itercnt_of_inner_solvers()
Definition feti.h:769
virtual ~PrimalSubassembledMatrixInverse()
Definition feti.h:776
virtual const char * name() const
name of class
Definition feti.h:712
void print_statistic_of_inner_solver(bool bPrintOnlyAverages)
prints some convergence statistic of inner solvers
Definition feti.cpp:1151
pcl::ProcessCommunicator m_allToOneProcessComm
Definition feti.h:806
int get_total_itercnt_of_inner_solvers()
Definition feti.h:770
matrix_type * m_pNeumannMatrix
Definition feti.h:792
ILinearOperatorInverse< vector_type > base_type
Base type.
Definition feti.h:700
void set_test_one_to_many_layouts(bool bTest)
set 'm_bTestOneToManyLayouts'
Definition feti.h:773
IndexLayout m_slaveAllToOneLayout
Definition feti.h:805
void set_statistic_type(std::string type)
sets statistic slot where next iterate should be counted
Definition feti.h:764
PrimalSubassembledMatrixInverse()
constructor
Definition feti.cpp:367
TAlgebra::vector_type vector_type
Definition feti.h:694
virtual bool supports_parallel() const
returns if parallel solving is supported
Definition feti.h:715
void set_neumann_solver(SmartPtr< ILinearOperatorInverse< vector_type > > neumannSolver)
sets the Neumann solver
Definition feti.h:726
void set_feti_layouts(FetiLayouts< algebra_type > &fetiLayouts)
sets the primal layouts
Definition feti.h:740
int m_totalIterCntOfInnerSolvers
Definition feti.h:832
virtual bool apply_return_defect(vector_type &u, vector_type &f)
applies inverse operator, i.e. returns u = A^{-1} f and returns defect d := f - A*u
Definition feti.cpp:906
TAlgebra algebra_type
Definition feti.h:691
SmartPtr< MatrixOperator< matrix_type, vector_type > > m_spRootSchurComplementOp
Definition feti.h:809
SmartPtr< MatrixOperator< matrix_type, vector_type > > m_spNeumannOperator
Definition feti.h:789
TAlgebra::matrix_type matrix_type
Definition feti.h:697
virtual bool apply(vector_type &u, const vector_type &f)
applies inverse operator, i.e. returns u = A^{-1} f
Definition feti.cpp:1137
matrix_type * m_pMatrix
Definition feti.h:783
matrix_type * m_pRootSchurComplementMatrix
Definition feti.h:812
virtual void set_debug(SmartPtr< IVectorDebugWriter< vector_type > > spDebugWriter)
set debug writer
Definition debug_writer.h:280
void BuildDomainDecompositionLayouts(IndexLayout &subdomMastersOut, IndexLayout &subdomSlavesOut, IndexLayout &processMastersOut, IndexLayout &processSlavesOut, IndexLayout &deltaNbrMastersOut, IndexLayout &deltaNbrSlavesOut, IndexLayout &crossPointMastersOut, IndexLayout &crossPointSlavesOut, const IndexLayout &standardMasters, const IndexLayout &standardSlaves, int highestReferencedIndex, IDomainDecompositionInfo &ddinfo)
Definition parallelization_util.cpp:497
void VecSubtractOneSlaveFromMaster(TVector *pVec, const IndexLayout &masterLayout, const IndexLayout &slaveLayout, pcl::InterfaceCommunicator< IndexLayout > *pCom=NULL)
subtracts values of only one slave dof per master on layout
Definition parallelization_util.h:445
void SetDirichletRow(TSparseMatrix &A, size_t i, size_t alpha)
Definition sparsematrix_util.h:796
#define PCL_RO_SUM
Definition pcl_methods.h:63
int ProcRank()
returns the rank of the process
Definition pcl_base.cpp:83
#define PCL_DT_DOUBLE
Definition pcl_datatype.h:57
virtual void init()
const NullSmartPtr SPNULL
The equivalent to NULL for smart pointers.
Definition smart_pointer.h:90
#define UG_LOG(msg)
Definition log.h:367
double number
Definition types.h:124
void VecCopy(vector_target_t &target, const vector_source_t &source, typename vector_target_t::value_type fill)
Copy contents between vectors of possibly different types.
Definition math_vector_functions_common_impl.hpp:56
void VecSet(vector_t &vInOut, typename vector_t::value_type s)
Set each vector component to scalar (componentwise)
Definition math_vector_functions_common_impl.hpp:539
void VecScaleAdd(vector_t &vOut, typename vector_t::value_type s1, const vector_t &v1, typename vector_t::value_type s2, const vector_t &v2)
Scales two Vectors, adds them and returns the sum in a third vector.
Definition math_vector_functions_common_impl.hpp:265
the ug namespace
void ComputeDifferenceOnDeltaTransposed(TVector &f, const TVector &diff, const std::vector< IndexLayout::Element > &vDualMasterIndex, const std::vector< IndexLayout::Element > &vDualSlaveIndex, const std::vector< IndexLayout::Element > &vDualNbrSlaveIndex)
'ComputeDifferenceOnDeltaTransposed()': Apply
Definition feti.h:507
double VecProd(const double &a, const double &b)
returns scal<a, b>
Definition operations_vec.h:84
void ComputeDifferenceOnDelta(TVector &diff, const TVector &u, IndexLayout &dualMasterLayoutIn, IndexLayout &dualSlaveLayoutIn, IndexLayout &dualNbrMasterLayoutIn, IndexLayout &dualNbrSlaveLayoutIn)
Application of the "jump operator" .
Definition feti.h:467
void VecScaleAssign(double &dest, double alpha1, const double &v1)
calculates dest = alpha1*v1. for doubles
Definition operations_vec.h:49
number lastDef3b
Definition feti.h:666
int numIter3b
Definition feti.h:665