/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- 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 . \*---------------------------------------------------------------------------*/ #include "LUscalarMatrix.H" #include "lduMatrix.H" #include "procLduMatrix.H" #include "procLduInterface.H" #include "cyclicLduInterface.H" // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::LUscalarMatrix::LUscalarMatrix(const scalarSquareMatrix& matrix) : scalarSquareMatrix(matrix), pivotIndices_(n()) { LUDecompose(*this, pivotIndices_); } Foam::LUscalarMatrix::LUscalarMatrix ( const lduMatrix& ldum, const FieldField& interfaceCoeffs, const lduInterfaceFieldPtrsList& interfaces ) { if (Pstream::parRun()) { PtrList lduMatrices(Pstream::nProcs()); label lduMatrixi = 0; lduMatrices.set ( lduMatrixi++, new procLduMatrix ( ldum, interfaceCoeffs, interfaces ) ); if (Pstream::master()) { for ( int slave=Pstream::firstSlave(); slave<=Pstream::lastSlave(); slave++ ) { lduMatrices.set ( lduMatrixi++, new procLduMatrix(IPstream(Pstream::scheduled, slave)()) ); } } else { OPstream toMaster(Pstream::scheduled, Pstream::masterNo()); procLduMatrix cldum ( ldum, interfaceCoeffs, interfaces ); toMaster<< cldum; } if (Pstream::master()) { label nCells = 0; forAll(lduMatrices, i) { nCells += lduMatrices[i].size(); } scalarSquareMatrix m(nCells, nCells, 0.0); transfer(m); convert(lduMatrices); } } else { label nCells = ldum.lduAddr().size(); scalarSquareMatrix m(nCells, nCells, 0.0); transfer(m); convert(ldum, interfaceCoeffs, interfaces); } if (Pstream::master()) { pivotIndices_.setSize(n()); LUDecompose(*this, pivotIndices_); } } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void Foam::LUscalarMatrix::convert ( const lduMatrix& ldum, const FieldField& interfaceCoeffs, const lduInterfaceFieldPtrsList& interfaces ) { const label* __restrict__ uPtr = ldum.lduAddr().upperAddr().begin(); const label* __restrict__ lPtr = ldum.lduAddr().lowerAddr().begin(); const scalar* __restrict__ diagPtr = ldum.diag().begin(); const scalar* __restrict__ upperPtr = ldum.upper().begin(); const scalar* __restrict__ lowerPtr = ldum.lower().begin(); register const label nCells = ldum.diag().size(); register const label nFaces = ldum.upper().size(); for (register label cell=0; cell(interface); label nbrInt = cycInterface.neighbPatchID(); const label* __restrict__ uPtr = interfaces[nbrInt].interface().faceCells().begin(); const scalar* __restrict__ nbrUpperLowerPtr = interfaceCoeffs[nbrInt].begin(); register label inFaces = interface.faceCells().size(); for (register label face=0; face& lduMatrices ) { procOffsets_.setSize(lduMatrices.size() + 1); procOffsets_[0] = 0; forAll(lduMatrices, ldumi) { procOffsets_[ldumi+1] = procOffsets_[ldumi] + lduMatrices[ldumi].size(); } forAll(lduMatrices, ldumi) { const procLduMatrix& lduMatrixi = lduMatrices[ldumi]; label offset = procOffsets_[ldumi]; const label* __restrict__ uPtr = lduMatrixi.upperAddr_.begin(); const label* __restrict__ lPtr = lduMatrixi.lowerAddr_.begin(); const scalar* __restrict__ diagPtr = lduMatrixi.diag_.begin(); const scalar* __restrict__ upperPtr = lduMatrixi.upper_.begin(); const scalar* __restrict__ lowerPtr = lduMatrixi.lower_.begin(); register const label nCells = lduMatrixi.size(); register const label nFaces = lduMatrixi.upper_.size(); for (register label cell=0; cell& interfaces = lduMatrixi.interfaces_; forAll(interfaces, inti) { const procLduInterface& interface = interfaces[inti]; if (interface.myProcNo_ == interface.neighbProcNo_) { const label* __restrict__ ulPtr = interface.faceCells_.begin(); const scalar* __restrict__ upperLowerPtr = interface.coeffs_.begin(); register label inFaces = interface.faceCells_.size()/2; for (register label face=0; face& neiInterfaces = lduMatrices[interface.neighbProcNo_].interfaces_; label neiInterfacei = -1; forAll(neiInterfaces, ninti) { if ( ( neiInterfaces[ninti].neighbProcNo_ == interface.myProcNo_ ) && (neiInterfaces[ninti].tag_ == interface.tag_) ) { neiInterfacei = ninti; break; } } if (neiInterfacei == -1) { FatalErrorIn("LUscalarMatrix::convert") << exit(FatalError); } const procLduInterface& neiInterface = neiInterfaces[neiInterfacei]; const label* __restrict__ uPtr = interface.faceCells_.begin(); const label* __restrict__ lPtr = neiInterface.faceCells_.begin(); const scalar* __restrict__ upperPtr = interface.coeffs_.begin(); const scalar* __restrict__ lowerPtr = neiInterface.coeffs_.begin(); register label inFaces = interface.faceCells_.size(); label neiOffset = procOffsets_[interface.neighbProcNo_]; for (register label face=0; face