Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Preconditioner.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File Preconditioner.cpp
4 //
5 // For more information, please see: http://www.nektar.info
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: Preconditioner definition
33 //
34 ///////////////////////////////////////////////////////////////////////////////
35 
38 #include <LocalRegions/MatrixKey.h>
39 #include <math.h>
40 
41 namespace Nektar
42 {
43  namespace MultiRegions
44  {
45  std::string Preconditioner::lookupIds[8] = {
47  "Preconditioner", "Null", eNull),
49  "Preconditioner", "Diagonal", eDiagonal),
51  "Preconditioner", "FullLinearSpaceWithDiagonal",
54  "Preconditioner", "FullLinearSpace",eLinear),
56  "Preconditioner", "LowEnergyBlock",eLowEnergy),
58  "Preconditioner", "FullLinearSpaceWithLowEnergyBlock",
61  "Preconditioner", "Block",eBlock),
63  "Preconditioner", "FullLinearSpaceWithBlock",eLinearWithBlock),
64  };
65  std::string Preconditioner::def =
67  "Preconditioner", "Diagonal");
68 
69  /**
70  * @class Preconditioner
71  *
72  * This class implements preconditioning for the conjugate
73  * gradient matrix solver.
74  */
75 
77  const boost::shared_ptr<GlobalLinSys> &plinsys,
78  const AssemblyMapSharedPtr &pLocToGloMap)
79  : m_linsys(plinsys),
80  m_preconType(pLocToGloMap->GetPreconType()),
81  m_locToGloMap(pLocToGloMap)
82  {
83  }
84 
85  /**
86  *
87  */
89  {
90  typedef Loki::SingletonHolder<PreconFactory,
91  Loki::CreateUsingNew,
92  Loki::NoDestroy > Type;
93  return Type::Instance();
94  }
95 
97  {
98  NEKERROR(ErrorUtil::efatal,"Method does not exist" );
99  }
100 
101  /**
102  * \brief Apply a preconditioner to the conjugate gradient method
103  */
105  const Array<OneD, NekDouble>& pInput,
106  Array<OneD, NekDouble>& pOutput)
107  {
108  NEKERROR(ErrorUtil::efatal,"Method does not exist" );
109  }
110 
111  /**
112  * \brief Apply a preconditioner to the conjugate gradient method with
113  * an output for non-vertex degrees of freedom.
114  */
116  const Array<OneD, NekDouble> &pInput,
117  Array<OneD, NekDouble> &pOutput,
118  const Array<OneD, NekDouble> &pNonVertOutput,
119  Array<OneD, NekDouble>& pVertForce)
120  {
121  NEKERROR(ErrorUtil::efatal, "Method does not exist");
122  }
123 
124  /**
125  * \brief Transform from original basis to low energy basis
126  */
128  Array<OneD, NekDouble>& pInOut,
129  int offset)
130  {
131  }
132 
133  /**
134  * \brief Transform from original basis to low energy basis
135  */
137  const Array<OneD, NekDouble> &pInOut,
138  Array<OneD, NekDouble> &pOutput)
139  {
140  }
141 
142  /**
143  * \brief Transform from low energy basis to orignal basis
144  */
146  Array<OneD, NekDouble>& pInput)
147  {
148  Vmath::Smul(pInput.num_elements(), 1.0, pInput, 1, pInput, 1);
149  }
150 
151  /**
152  * \brief Multiply by the block inverse transformation matrix
153  */
155  const Array<OneD, NekDouble> &pInput,
156  Array<OneD, NekDouble> &pOutput)
157  {
158  NEKERROR(ErrorUtil::efatal,"Method does not exist" );
159  }
160 
161  /**
162  * \brief Multiply by the block transposed inverse transformation matrix
163  */
165  const Array<OneD, NekDouble> &pInput,
166  Array<OneD, NekDouble> &pOutput)
167  {
168  NEKERROR(ErrorUtil::efatal,"Method does not exist" );
169  }
170 
172  {
173  }
174 
175  /**
176  * \brief Get block elemental transposed transformation matrix
177  * \f$\mathbf{R}^{T}\f$
178  */
180  int offset, const boost::shared_ptr<DNekScalMat> &loc_mat)
181  {
182  return loc_mat;
183  }
184 
185  /**
186  * @brief Performs global assembly of diagonal entries to global Schur
187  * complement matrix.
188  */
189  Array<OneD, NekDouble>
191  {
192  int nGlobalBnd = m_locToGloMap->GetNumGlobalBndCoeffs();
193  int nDirBnd = m_locToGloMap->GetNumGlobalDirBndCoeffs();
194  int rows = nGlobalBnd - nDirBnd;
195 
196  DNekScalBlkMatSharedPtr loc_mat;
197  DNekScalMatSharedPtr bnd_mat;
198  int sign1, sign2, gid1, gid2, i, j, n, cnt;
199  Array<OneD, NekDouble> diagonals(rows,0.0);
200 
201  // Extract diagonal contributions of globally assembled
202  // schur complement matrix
203  for (cnt = n = 0; n < m_linsys.lock()->GetNumBlocks(); ++n)
204  {
205  // Get statically condensed local matrix.
206  loc_mat = (m_linsys.lock())->GetStaticCondBlock(n);
207 
208  // Extract boundary block.
209  bnd_mat = loc_mat->GetBlock(0, 0);
210 
211  // Offset by number of rows.
212  int bnd_row = bnd_mat->GetRows();
213 
214  for (i = 0; i < bnd_row; ++i)
215  {
216  gid1 = m_locToGloMap->GetLocalToGlobalBndMap (cnt + i)
217  - nDirBnd;
218  sign1 = m_locToGloMap->GetLocalToGlobalBndSign(cnt + i);
219 
220  if (gid1 < 0)
221  {
222  continue;
223  }
224 
225  for (j = 0; j < bnd_row; ++j)
226  {
227  gid2 = m_locToGloMap->GetLocalToGlobalBndMap (cnt + j)
228  - nDirBnd;
229  sign2 = m_locToGloMap->GetLocalToGlobalBndSign(cnt + j);
230 
231  if (gid2 == gid1)
232  {
233  diagonals[gid1] += sign1 * sign2 * (*bnd_mat)(i, j);
234  }
235  }
236  }
237  cnt += bnd_row;
238  }
239 
240  return diagonals;
241  }
242  }
243 }
244 
245 
246 
247 
248 
249