Nektar++
GlobalLinSysXxtFull.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File GlobalLinSysXxtFull.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 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 //
31 // Description: GlobalLinSysXxtFull definition
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
37 #include <MultiRegions/ExpList.h>
38 
39 using namespace std;
40 
41 namespace Nektar
42 {
43  namespace MultiRegions
44  {
45  /**
46  * @class GlobalLinSysXxtFull
47  */
48 
49  /**
50  * Registers the class with the Factory.
51  */
52  string GlobalLinSysXxtFull::className
54  "XxtFull",
55  GlobalLinSysXxtFull::create,
56  "Xxt Full Matrix.");
57 
58 
59  /// Constructor for full direct matrix solve.
60  GlobalLinSysXxtFull::GlobalLinSysXxtFull(
61  const GlobalLinSysKey &pLinSysKey,
62  const std::weak_ptr<ExpList> &pExp,
63  const std::shared_ptr<AssemblyMap>
64  &pLocToGloMap)
65  : GlobalLinSys (pLinSysKey, pExp, pLocToGloMap),
66  GlobalLinSysXxt(pLinSysKey, pExp, pLocToGloMap)
67  {
68 
70  "This routine should only be used when using a Full XXT"
71  " matrix solve");
72 
73  CreateMap(pLocToGloMap);
74  AssembleMatrixArrays(pLocToGloMap);
75  }
76 
77 
79  {
80 
81  }
82 
83 
84  /**
85  * Solve the linear system using a full global matrix system.
86  */
88  const Array<OneD, const NekDouble> &pInput,
89  Array<OneD, NekDouble> &pOutput,
90  const AssemblyMapSharedPtr &pLocToGloMap,
91  const Array<OneD, const NekDouble> &pDirForcing)
92  {
93  bool dirForcCalculated = (bool) pDirForcing.num_elements();
94  int nDirDofs = pLocToGloMap->GetNumGlobalDirBndCoeffs();
95  int nGlobDofs = pLocToGloMap->GetNumGlobalCoeffs();
96 
97  Array<OneD, NekDouble> tmp (nGlobDofs);
98  Array<OneD, NekDouble> tmp2(nGlobDofs);
99  Array<OneD, NekDouble> tmp3 = pOutput + nDirDofs;
100 
101  if(nDirDofs)
102  {
103  // calculate the dirichlet forcing
104  if(dirForcCalculated)
105  {
106  Vmath::Vsub(nGlobDofs, pInput.get(), 1,
107  pDirForcing.get(), 1,
108  tmp.get(), 1);
109  }
110  else
111  {
112  // Calculate the dirichlet forcing and substract it
113  // from the rhs
114  //int nLocDofs = pLocToGloMap->GetNumLocalCoeffs();
115 
116  m_expList.lock()->GeneralMatrixOp(
117  m_linSysKey,
118  pOutput, tmp, eGlobal);
119 
120  Vmath::Vsub( nGlobDofs, pInput.get(),1,
121  tmp.get(), 1,
122  tmp.get(), 1);
123  }
124 
125  SolveLinearSystem(pLocToGloMap->GetNumLocalCoeffs(),
126  tmp, tmp2, pLocToGloMap);
127 
128  // Enforce the Dirichlet boundary conditions on the solution
129  // array as XXT discards them.
130  Vmath::Vcopy(nDirDofs, pOutput, 1,
131  tmp2, 1);
132  }
133  else
134  {
135  Vmath::Vcopy(nGlobDofs, pInput, 1, tmp, 1);
136  SolveLinearSystem(pLocToGloMap->GetNumLocalCoeffs(),
137  tmp,tmp2, pLocToGloMap);
138  }
139 
140  // Perturb the output array (previous solution) by the result of
141  // this solve to get full solution.
142  Vmath::Vadd(nGlobDofs - nDirDofs,
143  tmp2 + nDirDofs, 1, tmp3, 1, tmp3, 1);
144 
145  }
146 
147 
148  /**
149  * Create the inverse multiplicity map.
150  * @param locToGloMap Local to global mapping information.
151  */
153  const std::shared_ptr<AssemblyMap> &pLocToGloMap)
154  {
155  const Array<OneD, const int> &vMap
156  = pLocToGloMap->GetLocalToGlobalMap();
157  unsigned int nGlo = pLocToGloMap->GetNumGlobalCoeffs();
158  unsigned int nEntries = pLocToGloMap->GetNumLocalCoeffs();
159  unsigned int i;
160 
161  // Count the multiplicity of each global DOF on this process
162  Array<OneD, NekDouble> vCounts(nGlo, 0.0);
163  for (i = 0; i < nEntries; ++i)
164  {
165  vCounts[vMap[i]] += 1.0;
166  }
167 
168  // Get universal multiplicity by globally assembling counts
169  pLocToGloMap->UniversalAssemble(vCounts);
170 
171  // Construct a map of 1/multiplicity for use in XXT solve
173  for (i = 0; i < nEntries; ++i)
174  {
175  m_locToGloSignMult[i] = 1.0/vCounts[vMap[i]];
176  }
177 
178  m_map = pLocToGloMap->GetLocalToGlobalMap();
179  }
180 
181 
182  /**
183  * Construct the local matrix row index, column index and value index
184  * arrays and initialize the XXT data structure with this information.
185  * @param locToGloMap Local to global mapping information.
186  */
188  const std::shared_ptr<AssemblyMap> &pLocToGloMap)
189  {
190  ExpListSharedPtr vExp = m_expList.lock();
191  unsigned int nElmt = vExp->GetNumElmts();
192  DNekScalMatSharedPtr loc_mat;
193  unsigned int iCount = 0;
194  unsigned int rCount = 0;
195  unsigned int nRows = 0;
196  unsigned int nEntries = 0;
197  unsigned int numDirBnd = pLocToGloMap->GetNumGlobalDirBndCoeffs();
198  unsigned int nLocal = pLocToGloMap->GetNumLocalCoeffs();
199  const Array<OneD, NekDouble> &vMapSign
200  = pLocToGloMap->GetLocalToGlobalSign();
201  bool doSign = pLocToGloMap->GetSignChange();
202  unsigned int i = 0, j = 0, k = 0, n = 0;
203  int gid1;
204  Array<OneD, unsigned int> vSizes(nElmt);
205 
206  // First construct a map of the number of local DOFs in each block
207  // and the number of matrix entries for each block
208 
209  // Dimension of matrix is just the linear vertex space
212  {
213  for (n = 0; n < nElmt; ++n)
214  {
215  vSizes[n] = vExp->GetExp(n)->GetNverts();
216  nEntries += vSizes[n]*vSizes[n];
217  }
218  }
219  else
220  {
221  for (n = 0; n < nElmt; ++n)
222  {
223  vSizes[n] = vExp->GetExp(n)->GetNcoeffs();
224  nEntries += vSizes[n]*vSizes[n];
225  }
226  }
227 
228  // Set up i-index, j-index and value arrays
229  m_Ai = Array<OneD, unsigned int>(nEntries);
230  m_Aj = Array<OneD, unsigned int>(nEntries);
231  m_Ar = Array<OneD, double>(nEntries, 0.0);
232 
233  // Set up the universal ID array for XXT
234  Array<OneD, unsigned long> vId(nLocal);
235 
236  // Loop over each elemental block, extract matrix indices and value
237  // and set the universal ID array
238  for(n = iCount = 0; n < nElmt; ++n)
239  {
240  loc_mat = GetBlock(n);
241  nRows = loc_mat->GetRows();
242 
243  for(i = 0; i < nRows; ++i)
244  {
245  gid1 = pLocToGloMap->GetLocalToGlobalMap(iCount + i);
246  for(j = 0; j < nRows; ++j)
247  {
248  k = rCount + i*vSizes[n] + j;
249  m_Ai[k] = iCount + i;
250  m_Aj[k] = iCount + j;
251  m_Ar[k] = (*loc_mat)(i,j);
252  if (doSign)
253  {
254  m_Ar[k] *= vMapSign[iCount+i]*vMapSign[iCount+j];
255  }
256  }
257 
258  // Dirichlet DOFs are not included in the solve, so we set
259  // these to the special XXT id=0.
260  if (gid1 < numDirBnd)
261  {
262  vId[iCount + i] = 0;
263  }
264  else
265  {
266  vId[iCount + i]
267  = pLocToGloMap->GetGlobalToUniversalMap(gid1);
268  }
269  }
270  iCount += vSizes[n];
271  rCount += vSizes[n]*vSizes[n];
272  }
273 
274  // Set up XXT and output some stats
275  LibUtilities::CommSharedPtr vComm = pLocToGloMap->GetComm();
276  m_crsData = Xxt::Init(nLocal, vId, m_Ai, m_Aj, m_Ar, vComm);
277  if (m_verbose)
278  {
280  }
281  }
282  }
283 }
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
std::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
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
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:53
STL namespace.
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...
std::shared_ptr< AssemblyMap > AssemblyMapSharedPtr
Definition: AssemblyMap.h:52
Global coefficients.
DNekScalMatSharedPtr GetBlock(unsigned int n)
Definition: GlobalLinSys.h:222
StdRegions::MatrixType GetMatrixType() const
Return the matrix type.
void AssembleMatrixArrays(const std::shared_ptr< AssemblyMap > &pLocToGloMap)
Describe a linear system.
static struct crs_data * Init(unsigned int pRank, const Nektar::Array< OneD, unsigned long > pId, const Nektar::Array< OneD, unsigned int > pAi, const Nektar::Array< OneD, unsigned int > pAj, const Nektar::Array< OneD, NekDouble > pAr, const LibUtilities::CommSharedPtr &pComm)
Initialise the matrix-solve.
Definition: Xxt.hpp:160
const GlobalLinSysKey m_linSysKey
Key associated with this linear system.
Definition: GlobalLinSys.h:125
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:346
Array< OneD, unsigned int > m_Aj
A global linear system.
Definition: GlobalLinSys.h:72
const std::weak_ptr< ExpList > m_expList
Local Matrix System.
Definition: GlobalLinSys.h:127
Array< OneD, unsigned int > m_Ai
GlobalSysSolnType GetGlobalSysSolnType() const
Return the associated solution type.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:199
GlobalLinSysFactory & GetGlobalLinSysFactory()
void nektar_crs_stats(struct crs_data *data)
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:250
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1064
void CreateMap(const std::shared_ptr< AssemblyMap > &pLocToGloMap)
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:302
Array< OneD, NekDouble > m_locToGloSignMult