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 
35 #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", GlobalLinSysPETScFull::create, "PETSc Full Matrix.");
57 
58 /// Constructor for full direct matrix solve.
59 GlobalLinSysPETScFull::GlobalLinSysPETScFull(
60  const GlobalLinSysKey &pLinSysKey, const std::weak_ptr<ExpList> &pExp,
61  const std::shared_ptr<AssemblyMap> &pLocToGloMap)
62  : GlobalLinSys(pLinSysKey, pExp, pLocToGloMap),
63  GlobalLinSysPETSc(pLinSysKey, pExp, pLocToGloMap)
64 {
65  const int nDirDofs = pLocToGloMap->GetNumGlobalDirBndCoeffs();
66 
67  int i, j, n, cnt, gid1, gid2, loc_lda;
68  NekDouble sign1, sign2, value;
69  DNekScalMatSharedPtr loc_mat;
70 
71  // CALCULATE REORDERING MAPPING
72  CalculateReordering(pLocToGloMap->GetGlobalToUniversalMap(),
73  pLocToGloMap->GetGlobalToUniversalMapUnique(),
74  pLocToGloMap);
75 
76  // SET UP VECTORS AND MATRIX
77  SetUpMatVec(pLocToGloMap->GetNumGlobalCoeffs(), nDirDofs);
78 
79  // SET UP SCATTER OBJECTS
80  SetUpScatter();
81 
82  // CONSTRUCT KSP OBJECT
83  SetUpSolver(pLocToGloMap->GetIterativeTolerance());
84 
85  // POPULATE MATRIX
86  for (n = cnt = 0; n < m_expList.lock()->GetNumElmts(); ++n)
87  {
88  loc_mat = GetBlock(n);
89  loc_lda = loc_mat->GetRows();
90 
91  for (i = 0; i < loc_lda; ++i)
92  {
93  gid1 = pLocToGloMap->GetLocalToGlobalMap(cnt + i) - nDirDofs;
94  sign1 = pLocToGloMap->GetLocalToGlobalSign(cnt + i);
95  if (gid1 >= 0)
96  {
97  int gid1ro = m_reorderedMap[gid1];
98  for (j = 0; j < loc_lda; ++j)
99  {
100  gid2 =
101  pLocToGloMap->GetLocalToGlobalMap(cnt + j) - nDirDofs;
102  sign2 = pLocToGloMap->GetLocalToGlobalSign(cnt + j);
103  if (gid2 >= 0)
104  {
105  int gid2ro = m_reorderedMap[gid2];
106  value = sign1 * sign2 * (*loc_mat)(i, j);
107  MatSetValue(m_matrix, gid1ro, gid2ro, value,
108  ADD_VALUES);
109  }
110  }
111  }
112  }
113  cnt += loc_lda;
114  }
115 
116  // ASSEMBLE MATRIX
117  MatAssemblyBegin(m_matrix, MAT_FINAL_ASSEMBLY);
118  MatAssemblyEnd(m_matrix, MAT_FINAL_ASSEMBLY);
119 }
120 
122 {
123 }
124 
125 /**
126  * Solve the linear system using a full global matrix system.
127  */
129  const Array<OneD, const NekDouble> &pLocInput,
130  Array<OneD, NekDouble> &pLocOutput,
131  const AssemblyMapSharedPtr &pLocToGloMap,
132  const Array<OneD, const NekDouble> &pDirForcing)
133 {
134  std::shared_ptr<MultiRegions::ExpList> expList = m_expList.lock();
135  bool dirForcCalculated = (bool)pDirForcing.size();
136  int nDirDofs = pLocToGloMap->GetNumGlobalDirBndCoeffs();
137  int nGlobDofs = pLocToGloMap->GetNumGlobalCoeffs();
138  int nLocDofs = pLocToGloMap->GetNumLocalCoeffs();
139 
140  m_locToGloMap = pLocToGloMap; // required for DoMatrixMultiply
141 
142  Array<OneD, NekDouble> tmp(nLocDofs);
143  Array<OneD, NekDouble> tmp1(nLocDofs);
144  Array<OneD, NekDouble> global(nGlobDofs, 0.0);
145 
146  int nDirTotal = nDirDofs;
147  expList->GetComm()->GetRowComm()->AllReduce(nDirTotal,
149 
150  if (nDirTotal)
151  {
152  // calculate the dirichlet forcing
153  if (dirForcCalculated)
154  {
155  // assume pDirForcing is in local space
156  ASSERTL0(
157  pDirForcing.size() >= nLocDofs,
158  "DirForcing is not of sufficient size. Is it in local space?");
159  Vmath::Vsub(nLocDofs, pLocInput, 1, pDirForcing, 1, tmp1, 1);
160  }
161  else
162  {
163  // Calculate the dirichlet forcing and substract it
164  // from the rhs
165  expList->GeneralMatrixOp(m_linSysKey, pLocOutput, tmp);
166 
167  // Apply robin boundary conditions to the solution.
168  for (auto &r : m_robinBCInfo) // add robin mass matrix
169  {
171  Array<OneD, NekDouble> tmploc;
172 
173  int n = r.first;
174 
175  int offset = expList->GetCoeff_Offset(n);
176  LocalRegions::ExpansionSharedPtr vExp = expList->GetExp(n);
177 
178  // add local matrix contribution
179  for (rBC = r.second; rBC; rBC = rBC->next)
180  {
181  vExp->AddRobinTraceContribution(
182  rBC->m_robinID, rBC->m_robinPrimitiveCoeffs,
183  pLocOutput + offset, tmploc = tmp + offset);
184  }
185  }
186 
187  Vmath::Vsub(nLocDofs, pLocInput, 1, tmp, 1, tmp1, 1);
188  }
189 
190  pLocToGloMap->Assemble(tmp1, tmp);
191 
192  SolveLinearSystem(nGlobDofs, tmp, global, pLocToGloMap, nDirDofs);
193 
194  pLocToGloMap->GlobalToLocal(global, tmp);
195 
196  // Add back initial and boundary condition
197  Vmath::Vadd(nLocDofs, tmp, 1, pLocOutput, 1, pLocOutput, 1);
198  }
199  else
200  {
201  pLocToGloMap->Assemble(pLocInput, tmp);
202  SolveLinearSystem(nGlobDofs, tmp, global, pLocToGloMap);
203  pLocToGloMap->GlobalToLocal(global, pLocOutput);
204  }
205 }
206 
207 /**
208  * @brief Apply matrix-vector multiplication using local approach and
209  * the assembly map.
210  *
211  * @param input Vector input.
212  * @param output Result of multiplication.
213  */
216 {
217  std::shared_ptr<MultiRegions::ExpList> expList = m_expList.lock();
218 
219  int nLocDofs = m_locToGloMap->GetNumLocalCoeffs();
220 
221  Array<OneD, NekDouble> tmp(nLocDofs);
222  Array<OneD, NekDouble> tmp1(nLocDofs);
223 
224  m_locToGloMap->GlobalToLocal(input, tmp);
225 
226  // Perform matrix-vector operation A*d_i
227  expList->GeneralMatrixOp(m_linSysKey, tmp, tmp1);
228 
229  m_locToGloMap->Assemble(tmp1, output);
230 }
231 
232 } // namespace MultiRegions
233 } // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:198
A global linear system.
Definition: GlobalLinSys.h:72
const std::weak_ptr< ExpList > m_expList
Local Matrix System.
Definition: GlobalLinSys.h:124
const std::map< int, RobinBCInfoSharedPtr > m_robinBCInfo
Robin boundary info.
Definition: GlobalLinSys.h:126
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:192
const GlobalLinSysKey m_linSysKey
Key associated with this linear system.
Definition: GlobalLinSys.h:122
DNekScalMatSharedPtr GetBlock(unsigned int n)
Definition: GlobalLinSys.h:211
virtual void v_Solve(const Array< OneD, const NekDouble > &in, Array< OneD, NekDouble > &out, const AssemblyMapSharedPtr &locToGloMap, const Array< OneD, const NekDouble > &dirForcing=NullNekDouble1DArray) override
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) override
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:51
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
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:359
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:419