/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see .
Description
Multiply a given vector (second argument) by the matrix or its transpose
and return the result in the first argument.
\*---------------------------------------------------------------------------*/
#include "lduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void Foam::lduMatrix::Amul
(
solveScalarField& Apsi,
const tmp& tpsi,
const FieldField& interfaceBouCoeffs,
const lduInterfaceFieldPtrsList& interfaces,
const direction cmpt
) const
{
solveScalar* __restrict__ ApsiPtr = Apsi.begin();
const solveScalarField& psi = tpsi();
const solveScalar* const __restrict__ psiPtr = psi.begin();
const scalar* const __restrict__ diagPtr = diag().begin();
const label* const __restrict__ uPtr = lduAddr().upperAddr().begin();
const label* const __restrict__ lPtr = lduAddr().lowerAddr().begin();
const scalar* const __restrict__ upperPtr = upper().begin();
const scalar* const __restrict__ lowerPtr = lower().begin();
const label startRequest = Pstream::nRequests();
// Initialise the update of interfaced interfaces
initMatrixInterfaces
(
true,
interfaceBouCoeffs,
interfaces,
psi,
Apsi,
cmpt
);
const label nCells = diag().size();
for (label cell=0; cell& tpsi,
const FieldField& interfaceIntCoeffs,
const lduInterfaceFieldPtrsList& interfaces,
const direction cmpt
) const
{
solveScalar* __restrict__ TpsiPtr = Tpsi.begin();
const solveScalarField& psi = tpsi();
const solveScalar* const __restrict__ psiPtr = psi.begin();
const scalar* const __restrict__ diagPtr = diag().begin();
const label* const __restrict__ uPtr = lduAddr().upperAddr().begin();
const label* const __restrict__ lPtr = lduAddr().lowerAddr().begin();
const scalar* const __restrict__ lowerPtr = lower().begin();
const scalar* const __restrict__ upperPtr = upper().begin();
const label startRequest = Pstream::nRequests();
// Initialise the update of interfaced interfaces
initMatrixInterfaces
(
true,
interfaceIntCoeffs,
interfaces,
psi,
Tpsi,
cmpt
);
const label nCells = diag().size();
for (label cell=0; cell& interfaceBouCoeffs,
const lduInterfaceFieldPtrsList& interfaces
) const
{
solveScalar* __restrict__ sumAPtr = sumA.begin();
const scalar* __restrict__ diagPtr = diag().begin();
const label* __restrict__ uPtr = lduAddr().upperAddr().begin();
const label* __restrict__ lPtr = lduAddr().lowerAddr().begin();
const scalar* __restrict__ lowerPtr = lower().begin();
const scalar* __restrict__ upperPtr = upper().begin();
const label nCells = diag().size();
const label nFaces = upper().size();
for (label cell=0; cell& interfaceBouCoeffs,
const lduInterfaceFieldPtrsList& interfaces,
const direction cmpt
) const
{
solveScalar* __restrict__ rAPtr = rA.begin();
const solveScalar* const __restrict__ psiPtr = psi.begin();
const scalar* const __restrict__ diagPtr = diag().begin();
const scalar* const __restrict__ sourcePtr = source.begin();
const label* const __restrict__ uPtr = lduAddr().upperAddr().begin();
const label* const __restrict__ lPtr = lduAddr().lowerAddr().begin();
const scalar* const __restrict__ upperPtr = upper().begin();
const scalar* const __restrict__ lowerPtr = lower().begin();
// Parallel boundary initialisation.
// Note: there is a change of sign in the coupled
// interface update. The reason for this is that the
// internal coefficients are all located at the l.h.s. of
// the matrix whereas the "implicit" coefficients on the
// coupled boundaries are all created as if the
// coefficient contribution is of a source-kind (i.e. they
// have a sign as if they are on the r.h.s. of the matrix.
// To compensate for this, it is necessary to turn the
// sign of the contribution.
const label startRequest = Pstream::nRequests();
// Initialise the update of interfaced interfaces
initMatrixInterfaces
(
false,
interfaceBouCoeffs,
interfaces,
psi,
rA,
cmpt
);
const label nCells = diag().size();
for (label cell=0; cell> Foam::lduMatrix::residual
(
const solveScalarField& psi,
const scalarField& source,
const FieldField& interfaceBouCoeffs,
const lduInterfaceFieldPtrsList& interfaces,
const direction cmpt
) const
{
tmp trA(new solveScalarField(psi.size()));
residual(trA.ref(), psi, source, interfaceBouCoeffs, interfaces, cmpt);
return trA;
}
Foam::tmp Foam::lduMatrix::H1() const
{
auto tH1 = tmp::New(lduAddr().size(), Zero);
if (lowerPtr_ || upperPtr_)
{
scalar* __restrict__ H1Ptr = tH1.ref().begin();
const label* __restrict__ uPtr = lduAddr().upperAddr().begin();
const label* __restrict__ lPtr = lduAddr().lowerAddr().begin();
const scalar* __restrict__ lowerPtr = lower().begin();
const scalar* __restrict__ upperPtr = upper().begin();
const label nFaces = upper().size();
for (label face=0; face