Nektar++
PreconditionerLinearWithLowEnergy.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: PreconditionerLinearWithLowEnergy.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: PreconditionerLinearWithLowEnergy definition
32//
33///////////////////////////////////////////////////////////////////////////////
34
39#include <cmath>
40
41using namespace std;
42
44{
45/**
46 * Registers the class with the Factory.
47 */
48
51 "FullLinearSpaceWithLowEnergyBlock",
53 "Full Linear space and low energy block preconditioning");
54
55/**
56 * @class PreconditionerLinearWithLowEnergy
57 *
58 * This class implements preconditioning for the conjugate
59 * gradient matrix solver.
60 */
61
63 const std::shared_ptr<GlobalLinSys> &plinsys,
64 const AssemblyMapSharedPtr &pLocToGloMap)
65 : Preconditioner(plinsys, pLocToGloMap)
66{
67}
68
69/**
70 *
71 */
73{
75 "FullLinearSpace", m_linsys.lock(), m_locToGloMap.lock());
77 "LowEnergyBlock", m_linsys.lock(), m_locToGloMap.lock());
78
79 // Set up multiplicity array for inverse transposed transformation matrix
80 int nDirBnd = m_locToGloMap.lock()->GetNumGlobalDirBndCoeffs();
81 int nGlobHomBnd = m_locToGloMap.lock()->GetNumGlobalBndCoeffs() - nDirBnd;
82 int nLocBnd = m_locToGloMap.lock()->GetNumLocalBndCoeffs();
83
84 m_invMultiplicity = Array<OneD, NekDouble>(nGlobHomBnd, 1.0);
86
87 // need to scatter from global array to handle sign changes
88 m_locToGloMap.lock()->GlobalToLocalBnd(m_invMultiplicity, loc, nDirBnd);
89
90 // Now assemble values back together to get multiplicity
91 m_locToGloMap.lock()->AssembleBnd(loc, m_invMultiplicity, nDirBnd);
92 Vmath::Sdiv(nGlobHomBnd, 1.0, m_invMultiplicity, 1, m_invMultiplicity, 1);
93}
94
95/**
96 *
97 */
100{
101 m_lowEnergyPrecon->DoTransformBasisToLowEnergy(pInOut);
102}
103
104/**
105 *
106 */
109{
110 m_lowEnergyPrecon->DoTransformCoeffsFromLowEnergy(pInput);
111}
112
113/**
114 *
115 */
117 const Array<OneD, NekDouble> &pInput, Array<OneD, NekDouble> &pOutput)
118{
119 m_lowEnergyPrecon->DoTransformCoeffsToLowEnergy(pInput, pOutput);
120}
121
122/**
123 *
124 */
126 const Array<OneD, NekDouble> &pInput, Array<OneD, NekDouble> &pOutput)
127{
128 m_lowEnergyPrecon->DoTransformBasisFromLowEnergy(pInput, pOutput);
129}
130
132 int n, int offset, const std::shared_ptr<DNekScalMat> &loc_mat)
133{
134 DNekScalMatSharedPtr returnval;
135 returnval = m_lowEnergyPrecon->TransformedSchurCompl(n, offset, loc_mat);
136 return returnval;
137}
138
139/**
140 *
141 */
143{
144 m_linSpacePrecon->BuildPreconditioner();
145 m_lowEnergyPrecon->BuildPreconditioner();
146}
147
148/**
149 *
150 */
152 const Array<OneD, NekDouble> &pInput, Array<OneD, NekDouble> &pOutput,
153 const bool &isLocal)
154{
155 ASSERTL0(isLocal == false, "PreconditionerLinearWithLowEnergy"
156 " is only set up for Global iteratives sovles");
157 int nDirBndDofs = m_locToGloMap.lock()->GetNumGlobalDirBndCoeffs();
158 int nGlobHomBndDofs =
159 m_locToGloMap.lock()->GetNumGlobalBndCoeffs() - nDirBndDofs;
160 int nLocBndDofs = m_locToGloMap.lock()->GetNumLocalBndCoeffs();
161
162 Array<OneD, NekDouble> tmp(nGlobHomBndDofs, 0.0);
163
164 Array<OneD, NekDouble> InputLinear(nGlobHomBndDofs);
165 Array<OneD, NekDouble> OutputLowEnergy(nGlobHomBndDofs);
166 Array<OneD, NekDouble> OutputLinear(nGlobHomBndDofs);
167 Array<OneD, NekDouble> local(nLocBndDofs);
168
169 // Transform input from low energy to original basis
170 Vmath::Vmul(nGlobHomBndDofs, m_invMultiplicity, 1, pInput, 1, OutputLinear,
171 1);
172 m_locToGloMap.lock()->GlobalToLocalBnd(OutputLinear, local, nDirBndDofs);
173 m_lowEnergyPrecon->DoTransformBasisFromLowEnergy(local, local);
174 m_locToGloMap.lock()->AssembleBnd(local, InputLinear, nDirBndDofs);
175
176 // Apply linear space preconditioner
177 m_linSpacePrecon->DoPreconditionerWithNonVertOutput(InputLinear,
178 OutputLinear, tmp);
179
180 // transform coefficients back to low energy space
181 m_locToGloMap.lock()->GlobalToLocalBnd(OutputLinear, local, nDirBndDofs);
182 m_lowEnergyPrecon->DoTransformCoeffsToLowEnergy(local, local);
183 m_locToGloMap.lock()->LocalBndToGlobal(local, pOutput, nDirBndDofs, false);
184
185 // Apply Low Energy preconditioner
186 m_lowEnergyPrecon->DoPreconditioner(pInput, OutputLowEnergy);
187
188 ASSERTL1(pOutput.size() >= nGlobHomBndDofs, "Output array is not correct");
189 Vmath::Vadd(nGlobHomBndDofs, pOutput, 1, OutputLowEnergy, 1, pOutput, 1);
190}
191
192} // namespace Nektar::MultiRegions
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:242
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
const std::weak_ptr< GlobalLinSys > m_linsys
std::weak_ptr< AssemblyMap > m_locToGloMap
void v_DoTransformBasisFromLowEnergy(const Array< OneD, NekDouble > &pInput, Array< OneD, NekDouble > &pOutput) override
Multiply by the block transposed inverse transformation matrix.
void v_DoPreconditioner(const Array< OneD, NekDouble > &pInput, Array< OneD, NekDouble > &pOutput, const bool &isLocal=false) override
Apply a preconditioner to the conjugate gradient method.
PreconditionerLinearWithLowEnergy(const std::shared_ptr< GlobalLinSys > &plinsys, const AssemblyMapSharedPtr &pLocToGloMap)
void v_DoTransformCoeffsFromLowEnergy(Array< OneD, NekDouble > &pInOut) override
Transform from low energy coeffs to orignal basis.
void v_DoTransformCoeffsToLowEnergy(const Array< OneD, NekDouble > &pInput, Array< OneD, NekDouble > &pOutput) override
Multiply by the block inverse transformation matrix.
static PreconditionerSharedPtr create(const std::shared_ptr< GlobalLinSys > &plinsys, const std::shared_ptr< AssemblyMap > &pLocToGloMap)
Creates an instance of this class.
void v_DoTransformBasisToLowEnergy(Array< OneD, NekDouble > &pInOut) override
Transform from original basis to low energy basis.
DNekScalMatSharedPtr v_TransformedSchurCompl(int n, int offset, const std::shared_ptr< DNekScalMat > &loc_mat) override
Get block elemental transposed transformation matrix .
PreconFactory & GetPreconFactory()
std::shared_ptr< AssemblyMap > AssemblyMapSharedPtr
Definition: AssemblyMap.h:50
std::shared_ptr< DNekScalMat > DNekScalMatSharedPtr
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
Definition: Vmath.hpp:72
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 Sdiv(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha/x.
Definition: Vmath.hpp:154
STL namespace.