Nektar++
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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> &pLocInput,
89  Array<OneD, NekDouble> &pLocOutput,
90  const AssemblyMapSharedPtr &pLocToGloMap,
91  const Array<OneD, const NekDouble> &pDirForcing)
92  {
93  bool dirForcCalculated = (bool) pDirForcing.size();
94  int nDirDofs = pLocToGloMap->GetNumGlobalDirBndCoeffs();
95  int nGlobDofs = pLocToGloMap->GetNumGlobalCoeffs();
96  int nLocDofs = pLocToGloMap->GetNumLocalCoeffs();
97 
98  Array<OneD, NekDouble> tmp (nLocDofs);
99  Array<OneD, NekDouble> tmp1(nLocDofs);
100  Array<OneD, NekDouble> global(nGlobDofs,0.0);
101 
102  if(nDirDofs)
103  {
104  // calculate the dirichlet forcing
105  if(dirForcCalculated)
106  {
107  // assume pDirForcing is in local space
108  ASSERTL0(pDirForcing.size() >= nLocDofs,
109  "DirForcing is not of sufficient size. Is it in local space?");
110  Vmath::Vsub(nLocDofs, pLocInput, 1,
111  pDirForcing, 1,tmp1, 1);
112  }
113  else
114  {
115  // Calculate the dirichlet forcing and substract it
116  // from the rhs
117  m_expList.lock()->GeneralMatrixOp(
118  m_linSysKey, pLocOutput, tmp);
119 
120  Vmath::Vsub(nLocDofs, pLocInput, 1, tmp, 1, tmp1, 1);
121 
122  }
123 
124  pLocToGloMap->Assemble(tmp1,tmp);
125 
126  SolveLinearSystem(pLocToGloMap->GetNumLocalCoeffs(),
127  tmp, global, pLocToGloMap);
128  pLocToGloMap->GlobalToLocal(global,tmp);
129 
130  // Add back initial and boundary condition
131  Vmath::Vadd(nLocDofs, tmp, 1, pLocOutput, 1, pLocOutput, 1);
132  }
133  else
134  {
135  pLocToGloMap->Assemble(pLocInput,tmp);
136  SolveLinearSystem(pLocToGloMap->GetNumLocalCoeffs(),
137  tmp,global, pLocToGloMap);
138  pLocToGloMap->GlobalToLocal(global,pLocOutput);
139  }
140  }
141 
142 
143  /**
144  * Create the inverse multiplicity map.
145  * @param locToGloMap Local to global mapping information.
146  */
148  const std::shared_ptr<AssemblyMap> &pLocToGloMap)
149  {
150  const Array<OneD, const int> &vMap
151  = pLocToGloMap->GetLocalToGlobalMap();
152  unsigned int nGlo = pLocToGloMap->GetNumGlobalCoeffs();
153  unsigned int nEntries = pLocToGloMap->GetNumLocalCoeffs();
154  unsigned int i;
155 
156  // Count the multiplicity of each global DOF on this process
157  Array<OneD, NekDouble> vCounts(nGlo, 0.0);
158  for (i = 0; i < nEntries; ++i)
159  {
160  vCounts[vMap[i]] += 1.0;
161  }
162 
163  // Get universal multiplicity by globally assembling counts
164  pLocToGloMap->UniversalAssemble(vCounts);
165 
166  // Construct a map of 1/multiplicity for use in XXT solve
168  for (i = 0; i < nEntries; ++i)
169  {
170  m_locToGloSignMult[i] = 1.0/vCounts[vMap[i]];
171  }
172 
173  m_map = pLocToGloMap->GetLocalToGlobalMap();
174  }
175 
176 
177  /**
178  * Construct the local matrix row index, column index and value index
179  * arrays and initialize the XXT data structure with this information.
180  * @param locToGloMap Local to global mapping information.
181  */
183  const std::shared_ptr<AssemblyMap> &pLocToGloMap)
184  {
185  ExpListSharedPtr vExp = m_expList.lock();
186  unsigned int nElmt = vExp->GetNumElmts();
187  DNekScalMatSharedPtr loc_mat;
188  unsigned int iCount = 0;
189  unsigned int rCount = 0;
190  unsigned int nRows = 0;
191  unsigned int nEntries = 0;
192  unsigned int numDirBnd = pLocToGloMap->GetNumGlobalDirBndCoeffs();
193  unsigned int nLocal = pLocToGloMap->GetNumLocalCoeffs();
194  const Array<OneD, NekDouble> &vMapSign
195  = pLocToGloMap->GetLocalToGlobalSign();
196  bool doSign = pLocToGloMap->GetSignChange();
197  unsigned int i = 0, j = 0, k = 0, n = 0;
198  int gid1;
199  Array<OneD, unsigned int> vSizes(nElmt);
200 
201  // First construct a map of the number of local DOFs in each block
202  // and the number of matrix entries for each block
203 
204  // Dimension of matrix is just the linear vertex space
207  {
208  for (n = 0; n < nElmt; ++n)
209  {
210  vSizes[n] = vExp->GetExp(n)->GetNverts();
211  nEntries += vSizes[n]*vSizes[n];
212  }
213  }
214  else
215  {
216  for (n = 0; n < nElmt; ++n)
217  {
218  vSizes[n] = vExp->GetExp(n)->GetNcoeffs();
219  nEntries += vSizes[n]*vSizes[n];
220  }
221  }
222 
223  // Set up i-index, j-index and value arrays
224  m_Ai = Array<OneD, unsigned int>(nEntries);
225  m_Aj = Array<OneD, unsigned int>(nEntries);
226  m_Ar = Array<OneD, double>(nEntries, 0.0);
227 
228  // Set up the universal ID array for XXT
229  Array<OneD, unsigned long> vId(nLocal);
230 
231  // Loop over each elemental block, extract matrix indices and value
232  // and set the universal ID array
233  for(n = iCount = 0; n < nElmt; ++n)
234  {
235  loc_mat = GetBlock(n);
236  nRows = loc_mat->GetRows();
237 
238  for(i = 0; i < nRows; ++i)
239  {
240  gid1 = pLocToGloMap->GetLocalToGlobalMap(iCount + i);
241  for(j = 0; j < nRows; ++j)
242  {
243  k = rCount + i*vSizes[n] + j;
244  m_Ai[k] = iCount + i;
245  m_Aj[k] = iCount + j;
246  m_Ar[k] = (*loc_mat)(i,j);
247  if (doSign)
248  {
249  m_Ar[k] *= vMapSign[iCount+i]*vMapSign[iCount+j];
250  }
251  }
252 
253  // Dirichlet DOFs are not included in the solve, so we set
254  // these to the special XXT id=0.
255  if (gid1 < numDirBnd)
256  {
257  vId[iCount + i] = 0;
258  }
259  else
260  {
261  vId[iCount + i]
262  = pLocToGloMap->GetGlobalToUniversalMap(gid1);
263  }
264  }
265  iCount += vSizes[n];
266  rCount += vSizes[n]*vSizes[n];
267  }
268 
269  // Set up XXT and output some stats
270  LibUtilities::CommSharedPtr vComm = pLocToGloMap->GetComm();
271  m_crsData = Xxt::Init(nLocal, vId, m_Ai, m_Aj, m_Ar, vComm);
272  if (m_verbose)
273  {
275  }
276  }
277  }
278 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:250
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:200
A global linear system.
Definition: GlobalLinSys.h:73
const std::weak_ptr< ExpList > m_expList
Local Matrix System.
Definition: GlobalLinSys.h:127
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
const GlobalLinSysKey m_linSysKey
Key associated with this linear system.
Definition: GlobalLinSys.h:125
DNekScalMatSharedPtr GetBlock(unsigned int n)
Definition: GlobalLinSys.h:222
GlobalSysSolnType GetGlobalSysSolnType() const
Return the associated solution type.
void CreateMap(const std::shared_ptr< AssemblyMap > &pLocToGloMap)
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 AssembleMatrixArrays(const std::shared_ptr< AssemblyMap > &pLocToGloMap)
Array< OneD, NekDouble > m_locToGloSignMult
Array< OneD, unsigned int > m_Aj
Array< OneD, unsigned int > m_Ai
StdRegions::MatrixType GetMatrixType() const
Return the matrix type.
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:54
GlobalLinSysFactory & GetGlobalLinSysFactory()
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
std::shared_ptr< AssemblyMap > AssemblyMapSharedPtr
Definition: AssemblyMap.h:52
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:1
std::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
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:322
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:372
void nektar_crs_stats(struct crs_data *data)
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