G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsScaledDirichletPrec.hpp
Go to the documentation of this file.
1 
14 #pragma once
15 
16 #include <gsSolver/gsProductOp.h>
17 #include <gsSolver/gsSumOp.h>
18 #include <gsSolver/gsAdditiveOp.h>
19 
20 namespace gismo
21 {
22 
23 template <class T>
24 gsSortedVector<index_t>
26 {
28  for (index_t i=0; i<jm.outerSize(); ++i)
29  for (typename JumpMatrix::InnerIterator it(jm, i); it; ++it)
30  result.push_sorted_unique(it.col());
31  return result;
32 }
33 
34 template <class T>
36 gsScaledDirichletPrec<T>::restrictJumpMatrix( const JumpMatrix& jm, const std::vector<index_t>& dofs )
37 {
38  gsVector<index_t> reverse;
39  reverse.setZero( jm.cols() );
40  const index_t sz = dofs.size();
41  for (index_t i=0; i<sz; ++i)
42  reverse[dofs[i]] = i+1;
43 
44  gsSparseEntries<T> triplets;
45  triplets.reserve(jm.nonZeros());
46  for (index_t i=0; i<jm.outerSize(); ++i)
47  for (typename JumpMatrix::InnerIterator it(jm, i); it; ++it)
48  if (reverse[it.col()] > 0)
49  {
50  triplets.add(
51  it.row(),
52  reverse[it.col()]-1,
53  it.value()
54  );
55  }
56 
57  JumpMatrix result(jm.rows(), dofs.size());
58  result.setFrom(triplets);
59  return result;
60 }
61 
62 template <class T>
64 gsScaledDirichletPrec<T>::matrixBlocks( const SparseMatrix& mat, const std::vector<index_t>& dofs )
65 {
66  gsVector<index_t> reverse;
67  reverse.setZero( mat.cols() );
68  const index_t sz = dofs.size();
69  for (index_t i=0; i<sz; ++i)
70  reverse[dofs[i]] = i+1;
71  index_t j=0;
72  for (index_t i=0; i<mat.cols(); ++i)
73  if (reverse[i]==0)
74  reverse[i] = --j;
75 
76  gsSparseEntries<T> se_A00, se_A01, se_A10, se_A11;
77  se_A00.reserve( 2 * mat.nonZeros() * dofs.size() / mat.rows() );
78  se_A01.reserve( 2 * mat.nonZeros() * dofs.size() / mat.rows() );
79  se_A10.reserve( 2 * mat.nonZeros() * dofs.size() / mat.rows() );
80  se_A11.reserve( mat.nonZeros() );
81  for (index_t i=0; i<mat.outerSize(); ++i)
82  for (typename SparseMatrix::InnerIterator it(mat, i); it; ++it)
83  {
84  if (reverse[it.row()] > 0 && reverse[it.col()] > 0)
85  {
86  se_A00.add(
87  reverse[it.row()]-1,
88  reverse[it.col()]-1,
89  it.value()
90  );
91  }
92  else if (reverse[it.row()] > 0 && reverse[it.col()] < 0)
93  {
94  se_A10.add(
95  reverse[it.row()]-1,
96  -reverse[it.col()]-1,
97  it.value()
98  );
99  }
100  else if (reverse[it.row()] < 0 && reverse[it.col()] > 0)
101  {
102  se_A01.add(
103  -reverse[it.row()]-1,
104  reverse[it.col()]-1,
105  it.value()
106  );
107  }
108  else //if (reverse[it.col()] < 0 && reverse[it.row()] < 0)
109  {
110  se_A11.add(
111  -reverse[it.row()]-1,
112  -reverse[it.col()]-1,
113  it.value()
114  );
115  }
116  }
117 
118  Blocks result;
119 
120  result.A00.resize( dofs.size(), dofs.size());
121  result.A00.setFrom(se_A00);
122  result.A01.resize(mat.rows()-dofs.size(), dofs.size());
123  result.A01.setFrom(se_A01);
124  result.A10.resize( dofs.size(), mat.rows()-dofs.size());
125  result.A10.setFrom(se_A10);
126  result.A11.resize(mat.rows()-dofs.size(), mat.rows()-dofs.size());
127  result.A11.setFrom(se_A11);
128 
129  return result;
130 
131 }
132 
133 template <class T>
136 {
137  matrixBlocks.A01 *= -1;
138  return gsSumOp<T>::make(
139  makeMatrixOp(matrixBlocks.A00.moveToPtr()),
141  makeMatrixOp(matrixBlocks.A01.moveToPtr()),
142  give(solver),
143  makeMatrixOp(matrixBlocks.A10.moveToPtr())
144  )
145  );
146 }
147 
148 template <class T>
150 {
151  const index_t pnr = m_jumpMatrices.size();
152 
153  for (index_t k=0; k<pnr; ++k)
154  {
155  const index_t sz = m_localSchurOps[k]->rows();
156  gsMatrix<T> & sc = m_localScaling[k];
157  sc.resize(sz, 1);
158 
159  for (index_t i=0; i<sz; ++i)
160  sc(i,0) = 1;
161 
162  JumpMatrix & jm = *(m_jumpMatrices[k]);
163 
164  for (index_t i=0; i<jm.outerSize(); ++i){
165  for (typename JumpMatrix::InnerIterator it(jm, i); it; ++it)
166  {
167  const index_t c = it.col();
168  sc(c,0) += 1;
169  }
170  }
171  }
172 }
173 
174 template <class T>
177 {
178  const index_t pnr = m_jumpMatrices.size();
179 
180  for (index_t i=0; i<pnr; ++i)
181  {
182  GISMO_ASSERT( m_localScaling[i].rows() > 0 && m_localScaling[i].cols() == 1,
183  "gsScaledDirichletPrec::preconditioner needs the local scaling matrices given. "
184  "Forgot to call setupMultiplicityScaling()?" );
185  }
186 
187  std::vector<OpPtr> scalingOps;
188  scalingOps.reserve(pnr);
189 
190  for (index_t k=0; k<pnr; ++k)
191  {
192  const index_t sz = m_localSchurOps[k]->rows();
193  gsSparseMatrix<T> scaling(sz,sz);
194  for (index_t i=0; i<sz; ++i)
195  scaling(i,i) = (T)1/m_localScaling[k](i,0);
196  scalingOps.push_back(makeMatrixOp(scaling.moveToPtr()));
197  }
198 
199  typename gsAdditiveOp<T>::Ptr result = gsAdditiveOp<T>::make();
200 
201  for (index_t i=0; i<pnr; ++i)
202  {
203  typename gsProductOp<T>::Ptr local = gsProductOp<T>::make();
204  local->addOperator(scalingOps[i]);
205  local->addOperator(m_localSchurOps[i]);
206  local->addOperator(scalingOps[i]);
207  result->addOperator(m_jumpMatrices[i],local);
208  }
209 
210  return result;
211 }
212 
213 
214 } // namespace gismo
static uPtr make()
Make command returning a smart pointer.
Definition: gsProductOp.h:77
static uPtr make()
Make command returning a smart pointer.
Definition: gsSumOp.h:70
Class that provides a container for triplets (i,j,value) to be filled in a sparse matrix...
Definition: gsSparseMatrix.h:33
Definition: gsScaledDirichletPrec.h:148
memory::shared_ptr< Op > OpPtr
Shared pointer to linear operator.
Definition: gsScaledDirichletPrec.h:81
memory::shared_ptr< gsProductOp > Ptr
Shared pointer for gsProductOp.
Definition: gsProductOp.h:39
static OpPtr schurComplement(Blocks matrixBlocks, OpPtr solver)
Computes the Schur complement with respect to the block A11 of matrixBlocks.
Definition: gsScaledDirichletPrec.hpp:135
Allows to set up additive Schwarz type preconditioners.
uPtr moveToPtr()
This function returns a smart pointer to the matrix. After calling it, the matrix object becomes empt...
Definition: gsSparseMatrix.h:249
static JumpMatrix restrictJumpMatrix(const JumpMatrix &jumpMatrix, const std::vector< index_t > &dofs)
Restricts the jump matrix to the given dofs.
Definition: gsScaledDirichletPrec.hpp:36
S give(S &x)
Definition: gsMemory.h:266
#define index_t
Definition: gsConfig.h:32
This class is derived from std::vector, and adds sort tracking.
Definition: gsSortedVector.h:109
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
static Blocks matrixBlocks(const SparseMatrix &localMatrix, const std::vector< index_t > &dofs)
Computes the matrix blocks with respect to the given dofs.
Definition: gsScaledDirichletPrec.hpp:64
Class for representing the product of objects of type gsLinearOperator as gsLinearOperator.
Definition: gsProductOp.h:33
void setupMultiplicityScaling()
This sets up the member vector localScaling based on multiplicity scaling.
Definition: gsScaledDirichletPrec.hpp:149
memory::shared_ptr< gsAdditiveOp > Ptr
Shared pointer.
Definition: gsAdditiveOp.h:62
void addOperator(BasePtr op)
Add another operator at the end.
Definition: gsProductOp.h:93
static uPtr make()
Definition: gsAdditiveOp.h:120
static gsSortedVector< index_t > skeletonDofs(const JumpMatrix &jumpMatrix)
Extracts the skeleton dofs from the jump matrix.
Definition: gsScaledDirichletPrec.hpp:25
A class representing the product of gsLinearOperator s.
OpPtr preconditioner() const
This returns the preconditioner as gsLinearOperator.
Definition: gsScaledDirichletPrec.hpp:176
void addOperator(Transfer transfer, OpPtr op)
Definition: gsAdditiveOp.h:146
Provides the sum of gsLinearOperator s as a gsLinearOperator.