/*---------------------------------------------------------------------------*\ ========= | \\ / 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