Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator 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 // 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: GlobalLinSysXxtFull definition
33 //
34 ///////////////////////////////////////////////////////////////////////////////
35 
38 #include <MultiRegions/ExpList.h>
39 
40 using namespace std;
41 
42 namespace Nektar
43 {
44  namespace MultiRegions
45  {
46  /**
47  * @class GlobalLinSysXxtFull
48  */
49 
50  /**
51  * Registers the class with the Factory.
52  */
53  string GlobalLinSysXxtFull::className
55  "XxtFull",
56  GlobalLinSysXxtFull::create,
57  "Xxt Full Matrix.");
58 
59 
60  /// Constructor for full direct matrix solve.
61  GlobalLinSysXxtFull::GlobalLinSysXxtFull(
62  const GlobalLinSysKey &pLinSysKey,
63  const boost::weak_ptr<ExpList> &pExp,
64  const boost::shared_ptr<AssemblyMap>
65  &pLocToGloMap)
66  : GlobalLinSys (pLinSysKey, pExp, pLocToGloMap),
67  GlobalLinSysXxt(pLinSysKey, pExp, pLocToGloMap)
68  {
69 
71  "This routine should only be used when using a Full XXT"
72  " matrix solve");
73 
74  CreateMap(pLocToGloMap);
75  AssembleMatrixArrays(pLocToGloMap);
76  }
77 
78 
80  {
81 
82  }
83 
84 
85  /**
86  * Solve the linear system using a full global matrix system.
87  */
89  const Array<OneD, const NekDouble> &pInput,
90  Array<OneD, NekDouble> &pOutput,
91  const AssemblyMapSharedPtr &pLocToGloMap,
92  const Array<OneD, const NekDouble> &pDirForcing)
93  {
94  bool dirForcCalculated = (bool) pDirForcing.num_elements();
95  int nDirDofs = pLocToGloMap->GetNumGlobalDirBndCoeffs();
96  int nGlobDofs = pLocToGloMap->GetNumGlobalCoeffs();
97 
98  Array<OneD, NekDouble> tmp (nGlobDofs);
99  Array<OneD, NekDouble> tmp2(nGlobDofs);
100  Array<OneD, NekDouble> tmp3 = pOutput + nDirDofs;
101 
102  if(nDirDofs)
103  {
104  // calculate the dirichlet forcing
105  if(dirForcCalculated)
106  {
107  Vmath::Vsub(nGlobDofs, pInput.get(), 1,
108  pDirForcing.get(), 1,
109  tmp.get(), 1);
110  }
111  else
112  {
113  // Calculate the dirichlet forcing and substract it
114  // from the rhs
115  //int nLocDofs = pLocToGloMap->GetNumLocalCoeffs();
116 
117  m_expList.lock()->GeneralMatrixOp(
118  m_linSysKey,
119  pOutput, tmp, eGlobal);
120 
121  Vmath::Vsub( nGlobDofs, pInput.get(),1,
122  tmp.get(), 1,
123  tmp.get(), 1);
124  }
125 
126  SolveLinearSystem(pLocToGloMap->GetNumLocalCoeffs(),
127  tmp, tmp2, pLocToGloMap);
128 
129  // Enforce the Dirichlet boundary conditions on the solution
130  // array as XXT discards them.
131  Vmath::Vcopy(nDirDofs, pOutput, 1,
132  tmp2, 1);
133  }
134  else
135  {
136  Vmath::Vcopy(nGlobDofs, pInput, 1, tmp, 1);
137  SolveLinearSystem(pLocToGloMap->GetNumLocalCoeffs(),
138  tmp,tmp2, pLocToGloMap);
139  }
140 
141  // Perturb the output array (previous solution) by the result of
142  // this solve to get full solution.
143  Vmath::Vadd(nGlobDofs - nDirDofs,
144  tmp2 + nDirDofs, 1, tmp3, 1, tmp3, 1);
145 
146  }
147 
148 
149  /**
150  * Create the inverse multiplicity map.
151  * @param locToGloMap Local to global mapping information.
152  */
154  const boost::shared_ptr<AssemblyMap> &pLocToGloMap)
155  {
156  const Array<OneD, const int> &vMap
157  = pLocToGloMap->GetLocalToGlobalMap();
158  unsigned int nGlo = pLocToGloMap->GetNumGlobalCoeffs();
159  unsigned int nEntries = pLocToGloMap->GetNumLocalCoeffs();
160  unsigned int i;
161 
162  // Count the multiplicity of each global DOF on this process
163  Array<OneD, NekDouble> vCounts(nGlo, 0.0);
164  for (i = 0; i < nEntries; ++i)
165  {
166  vCounts[vMap[i]] += 1.0;
167  }
168 
169  // Get universal multiplicity by globally assembling counts
170  pLocToGloMap->UniversalAssemble(vCounts);
171 
172  // Construct a map of 1/multiplicity for use in XXT solve
174  for (i = 0; i < nEntries; ++i)
175  {
176  m_locToGloSignMult[i] = 1.0/vCounts[vMap[i]];
177  }
178 
179  m_map = pLocToGloMap->GetLocalToGlobalMap();
180  }
181 
182 
183  /**
184  * Construct the local matrix row index, column index and value index
185  * arrays and initialize the XXT data structure with this information.
186  * @param locToGloMap Local to global mapping information.
187  */
189  const boost::shared_ptr<AssemblyMap> &pLocToGloMap)
190  {
191  ExpListSharedPtr vExp = m_expList.lock();
192  unsigned int nElmt = vExp->GetNumElmts();
193  DNekScalMatSharedPtr loc_mat;
194  unsigned int iCount = 0;
195  unsigned int rCount = 0;
196  unsigned int nRows = 0;
197  unsigned int nEntries = 0;
198  unsigned int numDirBnd = pLocToGloMap->GetNumGlobalDirBndCoeffs();
199  unsigned int nLocal = pLocToGloMap->GetNumLocalCoeffs();
200  const Array<OneD, NekDouble> &vMapSign
201  = pLocToGloMap->GetLocalToGlobalSign();
202  bool doSign = pLocToGloMap->GetSignChange();
203  unsigned int i = 0, j = 0, k = 0, n = 0;
204  int gid1;
205  Array<OneD, unsigned int> vSizes(nElmt);
206 
207  // First construct a map of the number of local DOFs in each block
208  // and the number of matrix entries for each block
209 
210  // Dimension of matrix is just the linear vertex space
213  {
214  for (n = 0; n < nElmt; ++n)
215  {
216  i = vExp->GetOffset_Elmt_Id(n);
217  vSizes[n] = vExp->GetExp(i)->GetNverts();
218  nEntries += vSizes[n]*vSizes[n];
219  }
220  }
221  else
222  {
223  for (n = 0; n < nElmt; ++n)
224  {
225  i = vExp->GetOffset_Elmt_Id(n);
226  vSizes[n] = vExp->GetExp(i)->GetNcoeffs();
227  nEntries += vSizes[n]*vSizes[n];
228  }
229  }
230 
231  // Set up i-index, j-index and value arrays
232  m_Ai = Array<OneD, unsigned int>(nEntries);
233  m_Aj = Array<OneD, unsigned int>(nEntries);
234  m_Ar = Array<OneD, double>(nEntries, 0.0);
235 
236  // Set up the universal ID array for XXT
237  Array<OneD, unsigned long> vId(nLocal);
238 
239  // Loop over each elemental block, extract matrix indices and value
240  // and set the universal ID array
241  for(n = iCount = 0; n < nElmt; ++n)
242  {
243  loc_mat = GetBlock(vExp->GetOffset_Elmt_Id(n));
244  nRows = loc_mat->GetRows();
245 
246  for(i = 0; i < nRows; ++i)
247  {
248  gid1 = pLocToGloMap->GetLocalToGlobalMap(iCount + i);
249  for(j = 0; j < nRows; ++j)
250  {
251  k = rCount + i*vSizes[n] + j;
252  m_Ai[k] = iCount + i;
253  m_Aj[k] = iCount + j;
254  m_Ar[k] = (*loc_mat)(i,j);
255  if (doSign)
256  {
257  m_Ar[k] *= vMapSign[iCount+i]*vMapSign[iCount+j];
258  }
259  }
260 
261  // Dirichlet DOFs are not included in the solve, so we set
262  // these to the special XXT id=0.
263  if (gid1 < numDirBnd)
264  {
265  vId[iCount + i] = 0;
266  }
267  else
268  {
269  vId[iCount + i]
270  = pLocToGloMap->GetGlobalToUniversalMap(gid1);
271  }
272  }
273  iCount += vSizes[n];
274  rCount += vSizes[n]*vSizes[n];
275  }
276 
277  // Set up XXT and output some stats
278  LibUtilities::CommSharedPtr vComm = pLocToGloMap->GetComm();
279  m_crsData = Xxt::Init(nLocal, vId, m_Ai, m_Aj, m_Ar, vComm);
280  if (m_verbose)
281  {
283  }
284  }
285  }
286 }
GlobalSysSolnType GetGlobalSysSolnType() const
Return the associated solution type.
boost::shared_ptr< AssemblyMap > AssemblyMapSharedPtr
Definition: AssemblyMap.h:53
void CreateMap(const boost::shared_ptr< AssemblyMap > &pLocToGloMap)
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.
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...
boost::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
Global coefficients.
DNekScalMatSharedPtr GetBlock(unsigned int n)
Definition: GlobalLinSys.h:222
boost::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:53
boost::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
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:158
StdRegions::MatrixType GetMatrixType() const
Return the matrix type.
const GlobalLinSysKey m_linSysKey
Key associated with this linear system.
Definition: GlobalLinSys.h:127
void AssembleMatrixArrays(const boost::shared_ptr< AssemblyMap > &pLocToGloMap)
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:329
Array< OneD, unsigned int > m_Aj
A global linear system.
Definition: GlobalLinSys.h:74
Array< OneD, unsigned int > m_Ai
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:218
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1047
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:285
Array< OneD, NekDouble > m_locToGloSignMult
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, tDescription pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:215
const boost::weak_ptr< ExpList > m_expList
Local Matrix System.
Definition: GlobalLinSys.h:129