Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
GlobalLinSysIterativeFull.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File GlobalLinSys.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: GlobalLinSys definition
33 //
34 ///////////////////////////////////////////////////////////////////////////////
35 
36 #include <map>
39 
40 using namespace std;
41 
42 namespace Nektar
43 {
44  namespace MultiRegions
45  {
46  /**
47  * @class GlobalLinSysIterativeCG
48  *
49  * This class implements a conjugate gradient matrix solver.
50  * Preconditioning is implemented using a Jacobi (diagonal)
51  * preconditioner.
52  */
53 
54  /**
55  * Registers the class with the Factory.
56  */
57  string GlobalLinSysIterativeFull::className
59  "IterativeFull",
60  GlobalLinSysIterativeFull::create,
61  "Iterative solver for full matrix system.");
62 
63 
64  /**
65  * Constructor for full direct matrix solve.
66  * @param pKey Key specifying matrix to solve.
67  * @param pExp Shared pointer to expansion list for applying
68  * matrix evaluations.
69  * @param pLocToGloMap Local to global mapping.
70  */
71  GlobalLinSysIterativeFull::GlobalLinSysIterativeFull(
72  const GlobalLinSysKey &pKey,
73  const boost::weak_ptr<ExpList> &pExp,
74  const boost::shared_ptr<AssemblyMap> &pLocToGloMap)
75  : GlobalLinSys (pKey, pExp, pLocToGloMap),
76  GlobalLinSysIterative(pKey, pExp, pLocToGloMap)
77  {
79  "This routine should only be used when using an Iterative "
80  "conjugate gradient matrix solve.");
81  }
82 
83 
84  /**
85  *
86  */
88  {
89 
90  }
91 
92 
93  /**
94  * Solve a global linear system with Dirichlet forcing using a
95  * conjugate gradient method. This routine performs handling of the
96  * Dirichlet forcing terms and wraps the underlying iterative solver
97  * used for the remaining degrees of freedom.
98  *
99  * Consider solving for \f$x\f$, the matrix system \f$Ax=b\f$, where
100  * \f$b\f$ is known. To enforce the Dirichlet terms we instead solve
101  * \f[A(x-x_0) = b - Ax_0 \f]
102  * where \f$x_0\f$ is the Dirichlet forcing.
103  *
104  * @param pInput RHS of linear system, \f$b\f$.
105  * @param pOutput On input, values of dirichlet degrees
106  * of freedom with initial guess on other values.
107  * On output, the solution \f$x\f$.
108  * @param pLocToGloMap Local to global mapping.
109  * @param pDirForcing Precalculated Dirichlet forcing.
110  */
112  const Array<OneD, const NekDouble> &pInput,
113  Array<OneD, NekDouble> &pOutput,
114  const AssemblyMapSharedPtr &pLocToGloMap,
115  const Array<OneD, const NekDouble> &pDirForcing)
116  {
117  boost::shared_ptr<MultiRegions::ExpList> expList = m_expList.lock();
118  bool vCG;
119  if ((m_locToGloMap = boost::dynamic_pointer_cast<AssemblyMapCG>(
120  pLocToGloMap)))
121  {
122  vCG = true;
123  }
124  else if ((m_locToGloMap = boost::dynamic_pointer_cast<
125  AssemblyMapDG>(pLocToGloMap)))
126  {
127  vCG = false;
128  }
129  else
130  {
131  ASSERTL0(false, "Unknown map type");
132  }
133 
134  bool dirForcCalculated = (bool) pDirForcing.num_elements();
135  int nDirDofs = pLocToGloMap->GetNumGlobalDirBndCoeffs();
136  int nGlobDofs = pLocToGloMap->GetNumGlobalCoeffs();
137  int nDirTotal = nDirDofs;
138 
139  expList->GetComm()->GetRowComm()
140  ->AllReduce(nDirTotal, LibUtilities::ReduceSum);
141 
142  Array<OneD, NekDouble> tmp(nGlobDofs), tmp2;
143 
144  if(nDirTotal)
145  {
146  // calculate the Dirichlet forcing
147  if(dirForcCalculated)
148  {
149  Vmath::Vsub(nGlobDofs, pInput.get(), 1,
150  pDirForcing.get(), 1,
151  tmp.get(), 1);
152  }
153  else
154  {
155  // Calculate the dirichlet forcing B_b (== X_b) and
156  // substract it from the rhs
157  expList->GeneralMatrixOp(
158  m_linSysKey, pOutput, tmp, eGlobal);
159 
160  Vmath::Vsub(nGlobDofs, pInput.get(), 1,
161  tmp.get(), 1,
162  tmp.get(), 1);
163  }
164  if (vCG)
165  {
166  Array<OneD, NekDouble> out(nGlobDofs,0.0);
167 
168  // solve for perturbation from intiial guess in pOutput
170  nGlobDofs, tmp, out, pLocToGloMap, nDirDofs);
171  Vmath::Vadd(nGlobDofs-nDirDofs, &out [nDirDofs], 1,
172  &pOutput[nDirDofs], 1, &pOutput[nDirDofs], 1);
173  }
174  else
175  {
176  ASSERTL0(false, "Need DG solve if using Dir BCs");
177  }
178  }
179  else
180  {
181  Vmath::Vcopy(nGlobDofs, pInput, 1, tmp, 1);
182  SolveLinearSystem(nGlobDofs, tmp, pOutput, pLocToGloMap);
183  }
184  }
185 
186 
187  /**
188  *
189  */
191  const Array<OneD, NekDouble>& pInput,
192  Array<OneD, NekDouble>& pOutput)
193  {
194  boost::shared_ptr<MultiRegions::ExpList> expList = m_expList.lock();
195  // Perform matrix-vector operation A*d_i
196  expList->GeneralMatrixOp(m_linSysKey,
197  pInput, pOutput, eGlobal);
198 
199  // Apply robin boundary conditions to the solution.
200  if(m_robinBCInfo.size() > 0)
201  {
202  ASSERTL0(false,
203  "Robin boundaries not set up in IterativeFull solver.");
204  int nGlobal = m_locToGloMap->GetNumGlobalCoeffs();
205  int nLocal = m_locToGloMap->GetNumLocalCoeffs();
206  int nDir = m_locToGloMap->GetNumGlobalDirBndCoeffs();
207  int nNonDir = nGlobal - nDir;
208  Array<OneD, NekDouble> robin_A(nGlobal, 0.0);
209  Array<OneD, NekDouble> robin_l(nLocal, 0.0);
211  NekVector<NekDouble> robin(nNonDir,
212  tmp = robin_A + nDir, eWrapper);
213 
214  // Operation: p_A = A * d_A
215  // First map d_A to local solution
216  m_locToGloMap->GlobalToLocal(pInput, robin_l);
217 
218  // Iterate over all the elements computing Robin BCs where
219  // necessary
220  for (int n = 0; n < expList->GetNumElmts(); ++n)
221  {
222  int nel = expList->GetOffset_Elmt_Id(n);
223  int offset = expList->GetCoeff_Offset(n);
224  int ncoeffs = expList->GetExp(nel)->GetNcoeffs();
225 
226  if(m_robinBCInfo.count(nel) != 0) // add robin mass matrix
227  {
230  StdRegions::StdExpansionSharedPtr vExp = expList->GetExp(nel);
231 
232  // add local matrix contribution
233  for(rBC = m_robinBCInfo.find(nel)->second;rBC; rBC = rBC->next)
234  {
235  vExp->AddRobinEdgeContribution(rBC->m_robinID,rBC->m_robinPrimitiveCoeffs, tmp = robin_l + offset);
236  }
237  }
238  else
239  {
240  Vmath::Zero(ncoeffs, &robin_l[offset], 1);
241  }
242  }
243 
244  // Map local Robin contribution back to global coefficients
245  m_locToGloMap->LocalToGlobal(robin_l, robin_A);
246  // Add them to the output of the GeneralMatrixOp
247  Vmath::Vadd(nGlobal, pOutput, 1, robin_A, 1, pOutput, 1);
248  }
249 
250  }
251 
252  /**
253  *
254  */
256  {
257  m_map = m_locToGloMap->GetGlobalToUniversalMapUnique();
258  }
259 
260  }
261 }
GlobalSysSolnType GetGlobalSysSolnType() const
Return the associated solution type.
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:198
boost::shared_ptr< AssemblyMap > AssemblyMapSharedPtr
Definition: AssemblyMap.h:53
boost::shared_ptr< RobinBCInfo > RobinBCInfoSharedPtr
void SolveLinearSystem(const int pNumRows, const Array< OneD, const NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const AssemblyMapSharedPtr &locToGloMap, const int pNumDir=0)
Solve the linear system for given input and output vectors.
Definition: GlobalLinSys.h:201
STL namespace.
Global coefficients.
Array< OneD, int > m_map
Global to universal unique map.
Describe a linear system.
const GlobalLinSysKey m_linSysKey
Key associated with this linear system.
Definition: GlobalLinSys.h:127
void Vsub(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Subtract vector z = x-y.
Definition: Vmath.cpp:343
A global linear system.
Definition: GlobalLinSys.h:74
virtual void v_Solve(const Array< OneD, const NekDouble > &in, Array< OneD, NekDouble > &out, const AssemblyMapSharedPtr &locToGloMap, const Array< OneD, const NekDouble > &dirForcing=NullNekDouble1DArray)
Solve the linear system for given input and output vectors using a specified local to global map...
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:373
GlobalLinSysFactory & GetGlobalLinSysFactory()
boost::shared_ptr< StdExpansion > StdExpansionSharedPtr
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:228
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1061
const std::map< int, RobinBCInfoSharedPtr > m_robinBCInfo
Robin boundary info.
Definition: GlobalLinSys.h:131
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
Definition: Vmath.cpp:299
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, tDescription pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:215
virtual void v_DoMatrixMultiply(const Array< OneD, NekDouble > &pInput, Array< OneD, NekDouble > &pOutput)
const boost::weak_ptr< ExpList > m_expList
Local Matrix System.
Definition: GlobalLinSys.h:129