Nektar++
GlobalLinSysPETScFull.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File GlobalLinSysPETScFull.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: GlobalLinSysPETScFull definition
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
36 #include <MultiRegions/ExpList.h>
37 
38 #include "petscao.h"
39 #include "petscis.h"
40 
41 using namespace std;
42 
43 namespace Nektar
44 {
45  namespace MultiRegions
46  {
47  /**
48  * @class GlobalLinSysPETScFull
49  */
50 
51  /**
52  * Registers the class with the Factory.
53  */
54  string GlobalLinSysPETScFull::className
56  "PETScFull",
57  GlobalLinSysPETScFull::create,
58  "PETSc Full Matrix.");
59 
60 
61  /// Constructor for full direct matrix solve.
62  GlobalLinSysPETScFull::GlobalLinSysPETScFull(
63  const GlobalLinSysKey &pLinSysKey,
64  const std::weak_ptr<ExpList> &pExp,
65  const std::shared_ptr<AssemblyMap> &pLocToGloMap)
66  : GlobalLinSys (pLinSysKey, pExp, pLocToGloMap),
67  GlobalLinSysPETSc(pLinSysKey, pExp, pLocToGloMap)
68  {
69  const int nDirDofs = pLocToGloMap->GetNumGlobalDirBndCoeffs();
70 
71  int i, j, n, cnt, gid1, gid2, loc_lda;
72  NekDouble sign1, sign2, value;
73  DNekScalMatSharedPtr loc_mat;
74 
75  // CALCULATE REORDERING MAPPING
76  CalculateReordering(pLocToGloMap->GetGlobalToUniversalMap(),
77  pLocToGloMap->GetGlobalToUniversalMapUnique(),
78  pLocToGloMap);
79 
80  // SET UP VECTORS AND MATRIX
81  SetUpMatVec(pLocToGloMap->GetNumGlobalCoeffs(), nDirDofs);
82 
83  // SET UP SCATTER OBJECTS
84  SetUpScatter();
85 
86  // CONSTRUCT KSP OBJECT
87  SetUpSolver(pLocToGloMap->GetIterativeTolerance());
88 
89  // POPULATE MATRIX
90  for(n = cnt = 0; n < m_expList.lock()->GetNumElmts(); ++n)
91  {
92  loc_mat = GetBlock(n);
93  loc_lda = loc_mat->GetRows();
94 
95  for(i = 0; i < loc_lda; ++i)
96  {
97  gid1 = pLocToGloMap->GetLocalToGlobalMap(cnt+i) - nDirDofs;
98  sign1 = pLocToGloMap->GetLocalToGlobalSign(cnt + i);
99  if(gid1 >= 0)
100  {
101  int gid1ro = m_reorderedMap[gid1];
102  for(j = 0; j < loc_lda; ++j)
103  {
104  gid2 = pLocToGloMap->GetLocalToGlobalMap(cnt + j)
105  - nDirDofs;
106  sign2 = pLocToGloMap->GetLocalToGlobalSign(cnt + j);
107  if(gid2 >= 0)
108  {
109  int gid2ro = m_reorderedMap[gid2];
110  value = sign1*sign2*(*loc_mat)(i,j);
111  MatSetValue(
112  m_matrix, gid1ro, gid2ro, value, ADD_VALUES);
113  }
114  }
115  }
116  }
117  cnt += loc_lda;
118  }
119 
120  // ASSEMBLE MATRIX
121  MatAssemblyBegin(m_matrix, MAT_FINAL_ASSEMBLY);
122  MatAssemblyEnd (m_matrix, MAT_FINAL_ASSEMBLY);
123  }
124 
125 
127  {
128 
129  }
130 
131 
132  /**
133  * Solve the linear system using a full global matrix system.
134  */
136  const Array<OneD, const NekDouble> &pLocInput,
137  Array<OneD, NekDouble> &pLocOutput,
138  const AssemblyMapSharedPtr &pLocToGloMap,
139  const Array<OneD, const NekDouble> &pDirForcing)
140  {
141  std::shared_ptr<MultiRegions::ExpList> expList = m_expList.lock();
142  bool dirForcCalculated = (bool) pDirForcing.size();
143  int nDirDofs = pLocToGloMap->GetNumGlobalDirBndCoeffs();
144  int nGlobDofs = pLocToGloMap->GetNumGlobalCoeffs();
145  int nLocDofs = pLocToGloMap->GetNumLocalCoeffs();
146 
147  m_locToGloMap = pLocToGloMap; // required for DoMatrixMultiply
148 
149  Array<OneD, NekDouble> tmp(nLocDofs);
150  Array<OneD, NekDouble> tmp1(nLocDofs);
151  Array<OneD, NekDouble> global(nGlobDofs,0.0);
152 
153  expList->GetComm()->GetRowComm()->AllReduce(
154  nDirDofs, LibUtilities::ReduceSum);
155 
156  if(nDirDofs)
157  {
158  // calculate the dirichlet forcing
159  if(dirForcCalculated)
160  {
161  // assume pDirForcing is in local space
162  ASSERTL0(pDirForcing.size() >= nLocDofs,
163  "DirForcing is not of sufficient size. Is it in local space?");
164  Vmath::Vsub(nLocDofs, pLocInput, 1,
165  pDirForcing, 1,tmp1, 1);
166  }
167  else
168  {
169  // Calculate the dirichlet forcing and substract it
170  // from the rhs
171  expList->GeneralMatrixOp(
172  m_linSysKey, pLocOutput, tmp);
173 
174  // Apply robin boundary conditions to the solution.
175  for(auto &r : m_robinBCInfo) // add robin mass matrix
176  {
178  Array<OneD, NekDouble> tmploc;
179 
180  int n = r.first;
181 
182  int offset = expList->GetCoeff_Offset(n);
183  LocalRegions::ExpansionSharedPtr vExp = expList->GetExp(n);
184 
185  // add local matrix contribution
186  for(rBC = r.second;rBC; rBC = rBC->next)
187  {
188  vExp->AddRobinTraceContribution(rBC->m_robinID,
189  rBC->m_robinPrimitiveCoeffs,
190  pLocOutput + offset,
191  tmploc = tmp + offset);
192  }
193  }
194 
195  Vmath::Vsub(nLocDofs, pLocInput, 1, tmp, 1, tmp1, 1);
196  }
197 
198  pLocToGloMap->Assemble(tmp1,tmp);
199 
200  SolveLinearSystem(nGlobDofs,tmp, global, pLocToGloMap, nDirDofs);
201 
202  pLocToGloMap->GlobalToLocal(global,tmp);
203 
204  // Add back initial and boundary condition
205  Vmath::Vadd(nLocDofs, tmp, 1, pLocOutput, 1, pLocOutput, 1);
206  }
207  else
208  {
209  pLocToGloMap->Assemble(pLocInput,tmp);
210  SolveLinearSystem(nGlobDofs, tmp,global, pLocToGloMap);
211  pLocToGloMap->GlobalToLocal(global,pLocOutput);
212  }
213  }
214 
215  /**
216  * @brief Apply matrix-vector multiplication using local approach and
217  * the assembly map.
218  *
219  * @param input Vector input.
220  * @param output Result of multiplication.
221  */
223  const Array<OneD, const NekDouble> &input,
224  Array<OneD, NekDouble> &output)
225  {
226  std::shared_ptr<MultiRegions::ExpList> expList = m_expList.lock();
227 
228  int nLocDofs = m_locToGloMap->GetNumLocalCoeffs();
229 
230  Array<OneD, NekDouble> tmp (nLocDofs);
231  Array<OneD, NekDouble> tmp1 (nLocDofs);
232 
233  m_locToGloMap->GlobalToLocal(input,tmp);
234 
235  // Perform matrix-vector operation A*d_i
236  expList->GeneralMatrixOp(m_linSysKey, tmp,tmp1);
237 
238  m_locToGloMap->Assemble(tmp1,output);
239 
240  }
241 
242  }
243 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
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
const std::map< int, RobinBCInfoSharedPtr > m_robinBCInfo
Robin boundary info.
Definition: GlobalLinSys.h:129
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
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 > m_locToGloMap
virtual void v_DoMatrixMultiply(const Array< OneD, const NekDouble > &input, Array< OneD, NekDouble > &output)
Apply matrix-vector multiplication using local approach and the assembly map.
A PETSc global linear system.
std::vector< int > m_reorderedMap
Reordering that takes universal IDs to a unique row in the PETSc matrix.
void SetUpScatter()
Set up PETSc local (equivalent to Nektar++ global) and global (equivalent to universal) scatter maps.
void SetUpSolver(NekDouble tolerance)
Set up KSP solver object.
void SetUpMatVec(int nGlobal, int nDir)
Construct PETSc matrix and vector handles.
void CalculateReordering(const Array< OneD, const int > &glo2uniMap, const Array< OneD, const int > &glo2unique, const AssemblyMapSharedPtr &pLocToGloMap)
Calculate a reordering of universal IDs for PETSc.
std::shared_ptr< Expansion > ExpansionSharedPtr
Definition: Expansion.h:68
std::shared_ptr< RobinBCInfo > RobinBCInfoSharedPtr
GlobalLinSysFactory & GetGlobalLinSysFactory()
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
double NekDouble
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