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
37
38#include "petscao.h"
39#include "petscis.h"
40
41using namespace std;
42
44{
45/**
46 * @class GlobalLinSysPETScFull
47 */
48
49/**
50 * Registers the class with the Factory.
51 */
54 "PETScFull", GlobalLinSysPETScFull::create, "PETSc Full Matrix.");
55
56/// Constructor for full direct matrix solve.
58 const GlobalLinSysKey &pLinSysKey, const std::weak_ptr<ExpList> &pExp,
59 const std::shared_ptr<AssemblyMap> &pLocToGloMap)
60 : GlobalLinSys(pLinSysKey, pExp, pLocToGloMap),
61 GlobalLinSysPETSc(pLinSysKey, pExp, pLocToGloMap)
62{
63 const int nDirDofs = pLocToGloMap->GetNumGlobalDirBndCoeffs();
64
65 int i, j, n, cnt, gid1, gid2, loc_lda;
66 NekDouble sign1, sign2, value;
68
69 // CALCULATE REORDERING MAPPING
70 CalculateReordering(pLocToGloMap->GetGlobalToUniversalMap(),
71 pLocToGloMap->GetGlobalToUniversalMapUnique(),
72 pLocToGloMap);
73
74 // SET UP VECTORS AND MATRIX
75 SetUpMatVec(pLocToGloMap->GetNumGlobalCoeffs(), nDirDofs);
76
77 // SET UP SCATTER OBJECTS
79
80 // CONSTRUCT KSP OBJECT
82 m_expList.lock()->GetSession();
83 string variable = pLocToGloMap->GetVariable();
84 NekDouble IterativeSolverTolerance = NekConstants::kNekIterativeTol;
85 if (pSession->DefinesGlobalSysSolnInfo(variable,
86 "IterativeSolverTolerance"))
87 {
88 IterativeSolverTolerance = boost::lexical_cast<double>(
89 pSession->GetGlobalSysSolnInfo(variable, "IterativeSolverTolerance")
90 .c_str());
91 }
92 else if (pSession->DefinesParameter("IterativeSolverTolerance"))
93 {
94 IterativeSolverTolerance =
95 pSession->GetParameter("IterativeSolverTolerance");
96 }
97 SetUpSolver(IterativeSolverTolerance);
98
99 // POPULATE MATRIX
100 for (n = cnt = 0; n < m_expList.lock()->GetNumElmts(); ++n)
101 {
102 loc_mat = GetBlock(n);
103 loc_lda = loc_mat->GetRows();
104
105 for (i = 0; i < loc_lda; ++i)
106 {
107 gid1 = pLocToGloMap->GetLocalToGlobalMap(cnt + i) - nDirDofs;
108 sign1 = pLocToGloMap->GetLocalToGlobalSign(cnt + i);
109 if (gid1 >= 0)
110 {
111 int gid1ro = m_reorderedMap[gid1];
112 for (j = 0; j < loc_lda; ++j)
113 {
114 gid2 =
115 pLocToGloMap->GetLocalToGlobalMap(cnt + j) - nDirDofs;
116 sign2 = pLocToGloMap->GetLocalToGlobalSign(cnt + j);
117 if (gid2 >= 0)
118 {
119 int gid2ro = m_reorderedMap[gid2];
120 value = sign1 * sign2 * (*loc_mat)(i, j);
121 MatSetValue(m_matrix, gid1ro, gid2ro, value,
122 ADD_VALUES);
123 }
124 }
125 }
126 }
127 cnt += loc_lda;
128 }
129
130 // ASSEMBLE MATRIX
131 MatAssemblyBegin(m_matrix, MAT_FINAL_ASSEMBLY);
132 MatAssemblyEnd(m_matrix, MAT_FINAL_ASSEMBLY);
133}
134
135/**
136 * Solve the linear system using a full global matrix system.
137 */
139 const Array<OneD, const NekDouble> &pLocInput,
140 Array<OneD, NekDouble> &pLocOutput,
141 const AssemblyMapSharedPtr &pLocToGloMap,
142 const Array<OneD, const NekDouble> &pDirForcing)
143{
144 m_locToGloMap = pLocToGloMap;
145
146 bool dirForcCalculated = (bool)pDirForcing.size();
147 int nDirDofs = pLocToGloMap->GetNumGlobalDirBndCoeffs();
148 int nGlobDofs = pLocToGloMap->GetNumGlobalCoeffs();
149 int nLocDofs = pLocToGloMap->GetNumLocalCoeffs();
150
151 int nDirTotal = nDirDofs;
152 std::shared_ptr<MultiRegions::ExpList> expList = m_expList.lock();
153 expList->GetComm()->GetRowComm()->AllReduce(nDirTotal,
155
156 if (nDirTotal)
157 {
158 Array<OneD, NekDouble> rhs(nLocDofs);
159
160 // Calculate the Dirichlet forcing
161 if (dirForcCalculated)
162 {
163 // Assume pDirForcing is in local space
164 ASSERTL0(
165 pDirForcing.size() >= nLocDofs,
166 "DirForcing is not of sufficient size. Is it in local space?");
167 Vmath::Vsub(nLocDofs, pLocInput, 1, pDirForcing, 1, rhs, 1);
168 }
169 else
170 {
171 // Calculate initial condition and Dirichlet forcing and subtract it
172 // from the rhs
173 expList->GeneralMatrixOp(m_linSysKey, pLocOutput, rhs);
174
175 // Iterate over all the elements computing Robin BCs where
176 // necessary
177 for (auto &r : m_robinBCInfo) // add robin mass matrix
178 {
181
182 int n = r.first;
183 int offset = expList->GetCoeff_Offset(n);
184
185 LocalRegions::ExpansionSharedPtr vExp = expList->GetExp(n);
186 // Add local matrix contribution
187 for (rBC = r.second; rBC; rBC = rBC->next)
188 {
189 vExp->AddRobinTraceContribution(
190 rBC->m_robinID, rBC->m_robinPrimitiveCoeffs,
191 pLocOutput + offset, rhsloc = rhs + offset);
192 }
193 }
194 Vmath::Vsub(nLocDofs, pLocInput, 1, rhs, 1, rhs, 1);
195 }
196
197 Array<OneD, NekDouble> diff(nLocDofs);
198
199 // Solve for perturbation from initial guess in pOutput
200 SolveLinearSystem(nGlobDofs, rhs, diff, pLocToGloMap, nDirDofs);
201
202 // Add back initial and boundary condition
203 Vmath::Vadd(nLocDofs, diff, 1, pLocOutput, 1, pLocOutput, 1);
204 }
205 else
206 {
207 SolveLinearSystem(nGlobDofs, pLocInput, pLocOutput, pLocToGloMap,
208 nDirDofs);
209 }
210}
211
212/**
213 * @brief Apply matrix-vector multiplication using local approach and
214 * the assembly map.
215 *
216 * @param input Vector input.
217 * @param output Result of multiplication.
218 */
221{
222 std::shared_ptr<MultiRegions::ExpList> expList = m_expList.lock();
223
224 int nLocDofs = m_locToGloMap->GetNumLocalCoeffs();
225
226 Array<OneD, NekDouble> tmp(nLocDofs);
227 Array<OneD, NekDouble> tmp1(nLocDofs);
228
229 m_locToGloMap->GlobalToLocal(input, tmp);
230
231 // Perform matrix-vector operation A*d_i
232 expList->GeneralMatrixOp(m_linSysKey, tmp, tmp1);
233
234 m_locToGloMap->Assemble(tmp1, output);
235}
236
237} // namespace Nektar::MultiRegions
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
A global linear system.
Definition: GlobalLinSys.h:70
const std::weak_ptr< ExpList > m_expList
Local Matrix System.
Definition: GlobalLinSys.h:122
const std::map< int, RobinBCInfoSharedPtr > m_robinBCInfo
Robin boundary info.
Definition: GlobalLinSys.h:124
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:190
const GlobalLinSysKey m_linSysKey
Key associated with this linear system.
Definition: GlobalLinSys.h:120
DNekScalMatSharedPtr GetBlock(unsigned int n)
Definition: GlobalLinSys.h:209
GlobalLinSysPETScFull(const GlobalLinSysKey &pLinSysKey, const std::weak_ptr< ExpList > &pExpList, const std::shared_ptr< AssemblyMap > &pLocToGloMap)
Constructor for full direct matrix solve.
static std::string className
Name of class.
static GlobalLinSysSharedPtr create(const GlobalLinSysKey &pLinSysKey, const std::weak_ptr< ExpList > &pExpList, const std::shared_ptr< AssemblyMap > &pLocToGloMap)
Creates an instance of this class.
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
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< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Expansion > ExpansionSharedPtr
Definition: Expansion.h:66
std::shared_ptr< RobinBCInfo > RobinBCInfoSharedPtr
GlobalLinSysFactory & GetGlobalLinSysFactory()
std::shared_ptr< AssemblyMap > AssemblyMapSharedPtr
Definition: AssemblyMap.h:50
static const NekDouble kNekIterativeTol
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.hpp:180
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.hpp:220
STL namespace.