diff --git a/src/OpenFOAM/meshes/MeshObject/MeshObject.C b/src/OpenFOAM/meshes/MeshObject/MeshObject.C index c089e0e531ead8fc903bd0641b73a97b1297d7af..fddfadfa59e0c50e6037488a8c8398db5fc2d26e 100644 --- a/src/OpenFOAM/meshes/MeshObject/MeshObject.C +++ b/src/OpenFOAM/meshes/MeshObject/MeshObject.C @@ -83,6 +83,26 @@ const Type& Foam::MeshObject<Mesh, Type>::New } +template<class Mesh, class Type> +template<class Data1, class Data2> +const Type& Foam::MeshObject<Mesh, Type>::New +( + const Mesh& mesh, + const Data1& d1, + const Data2& d2 +) +{ + if (!mesh.db().objectRegistry::foundObject<Type>(Type::typeName)) + { + return store(new Type(mesh, d1, d2)); + } + else + { + return mesh.db().objectRegistry::lookupObject<Type>(Type::typeName); + } +} + + // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * // template<class Mesh, class Type> diff --git a/src/OpenFOAM/meshes/MeshObject/MeshObject.H b/src/OpenFOAM/meshes/MeshObject/MeshObject.H index 595f2f1df4edf577495bb277686e2632c2c0c46c..b142b47f968a7d165fec3adf0025fede3687e556 100644 --- a/src/OpenFOAM/meshes/MeshObject/MeshObject.H +++ b/src/OpenFOAM/meshes/MeshObject/MeshObject.H @@ -72,6 +72,9 @@ public: template<class Data> static const Type& New(const Mesh& mesh, const Data& d); + template<class Data1, class Data2> + static const Type& New(const Mesh& mesh, const Data1&, const Data2&); + // Destructor diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C index 5421b328d8e5d585bd0d0d55d3ef13977a86ba3c..5ef7b693a560a736933fbcd70d0e213890184377 100644 --- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C +++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.C @@ -271,4 +271,144 @@ Foam::mapDistribute::mapDistribute } +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::mapDistribute::compact(const boolList& elemIsUsed) +{ + // 1. send back to sender. Have him delete the corresponding element + // from the submap and do the same to the constructMap locally + // (and in same order). + + // Send elemIsUsed field to neighbour. Use nonblocking code from + // mapDistribute but in reverse order. + { + List<boolList> sendFields(Pstream::nProcs()); + + for (label domain = 0; domain < Pstream::nProcs(); domain++) + { + const labelList& map = constructMap_[domain]; + + if (domain != Pstream::myProcNo() && map.size() > 0) + { + boolList& subField = sendFields[domain]; + subField.setSize(map.size()); + forAll(map, i) + { + subField[i] = elemIsUsed[map[i]]; + } + + OPstream::write + ( + Pstream::nonBlocking, + domain, + reinterpret_cast<const char*>(subField.begin()), + subField.size()*sizeof(bool) + ); + } + } + + // Set up receives from neighbours + + List<boolList> recvFields(Pstream::nProcs()); + + for (label domain = 0; domain < Pstream::nProcs(); domain++) + { + const labelList& map = subMap_[domain]; + + if (domain != Pstream::myProcNo() && map.size() > 0) + { + recvFields[domain].setSize(map.size()); + IPstream::read + ( + Pstream::nonBlocking, + domain, + reinterpret_cast<char*>(recvFields[domain].begin()), + recvFields[domain].size()*sizeof(bool) + ); + } + } + + + // Set up 'send' to myself - write directly into recvFields + + { + const labelList& map = constructMap_[Pstream::myProcNo()]; + + recvFields[Pstream::myProcNo()].setSize(map.size()); + forAll(map, i) + { + recvFields[Pstream::myProcNo()][i] = elemIsUsed[map[i]]; + } + } + + + // Wait for all to finish + + OPstream::waitRequests(); + IPstream::waitRequests(); + + + // Compact out all submap entries that are referring to unused elements + for (label domain = 0; domain < Pstream::nProcs(); domain++) + { + const labelList& map = subMap_[domain]; + + labelList newMap(map.size()); + label newI = 0; + + forAll(map, i) + { + if (recvFields[domain][i]) + { + // So element is used on destination side + newMap[newI++] = map[i]; + } + } + if (newI < map.size()) + { + newMap.setSize(newI); + subMap_[domain].transfer(newMap); + } + } + } + + + // 2. remove from construct map - since end-result (element in elemIsUsed) + // not used. + + label maxConstructIndex = -1; + + for (label domain = 0; domain < Pstream::nProcs(); domain++) + { + const labelList& map = constructMap_[domain]; + + labelList newMap(map.size()); + label newI = 0; + + forAll(map, i) + { + label destinationI = map[i]; + + // Is element is used on destination side + if (elemIsUsed[destinationI]) + { + maxConstructIndex = max(maxConstructIndex, destinationI); + + newMap[newI++] = destinationI; + } + } + if (newI < map.size()) + { + newMap.setSize(newI); + constructMap_[domain].transfer(newMap); + } + } + + constructSize_ = maxConstructIndex+1; + + // Clear the schedule (note:not necessary if nothing changed) + schedulePtr_.clear(); +} + + // ************************************************************************* // diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H index 748834ca4d28ef43dcab1816d451f43d4bfdacb7..8427670a25c77705dfadd8b32da2c0e2acb976d3 100644 --- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H +++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistribute.H @@ -51,6 +51,7 @@ SourceFiles #include "labelList.H" #include "labelPair.H" #include "Pstream.H" +#include "boolList.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -155,6 +156,12 @@ public: // Other + //- Compact maps. Gets per field a bool whether it is used (locally) + // and works out itself what this side and sender side can remove + // from maps. + void compact(const boolList& elemIsUsed); + + //- Distribute data. Note:schedule only used for Pstream::scheduled // for now, all others just use send-to-all, receive-from-all. template<class T> @@ -168,6 +175,21 @@ public: List<T>& ); + //- Distribute data. If multiple processors writing to same + // position adds contributions using cop. + template<class T, class CombineOp> + static void distribute + ( + const Pstream::commsTypes commsType, + const List<labelPair>& schedule, + const label constructSize, + const labelListList& subMap, + const labelListList& constructMap, + List<T>&, + const CombineOp& cop, + const T& nullValue + ); + //- Distribute data using default commsType. template<class T> void distribute(List<T>& fld) const diff --git a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C index 5f16ad1335fb2eb58c07f2c38b5f05214dfaee4d..8b4598bfb8ad0ffec1661a184ddc21290e20e842 100644 --- a/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C +++ b/src/OpenFOAM/meshes/polyMesh/mapPolyMesh/mapDistribute/mapDistributeTemplates.C @@ -268,8 +268,122 @@ void Foam::mapDistribute::distribute } + // Set up 'send' to myself + + { + const labelList& map = subMap[Pstream::myProcNo()]; + + List<T>& subField = sendFields[Pstream::myProcNo()]; + subField.setSize(map.size()); + forAll(map, i) + { + subField[i] = field[map[i]]; + } + } + + // Combine bits. Note that can reuse field storage + field.setSize(constructSize); + + + // Receive sub field from myself (sendFields[Pstream::myProcNo()]) + { + const labelList& map = constructMap[Pstream::myProcNo()]; + const List<T>& subField = sendFields[Pstream::myProcNo()]; + + forAll(map, i) + { + field[map[i]] = subField[i]; + } + } + + + // Wait for all to finish + + OPstream::waitRequests(); + IPstream::waitRequests(); + + // Collect neighbour fields + + for (label domain = 0; domain < Pstream::nProcs(); domain++) + { + const labelList& map = constructMap[domain]; + + if (domain != Pstream::myProcNo() && map.size() > 0) + { + if (recvFields[domain].size() != map.size()) + { + FatalErrorIn + ( + "template<class T>\n" + "void mapDistribute::distribute\n" + "(\n" + " const Pstream::commsTypes commsType,\n" + " const List<labelPair>& schedule,\n" + " const label constructSize,\n" + " const labelListList& subMap,\n" + " const labelListList& constructMap,\n" + " List<T>& field\n" + ")\n" + ) << "Expected from processor " << domain + << " " << map.size() << " but received " + << recvFields[domain].size() << " elements." + << abort(FatalError); + } + + forAll(map, i) + { + field[map[i]] = recvFields[domain][i]; + } + } + } + } + else + { + FatalErrorIn("mapDistribute::distribute(..)") + << "Unknown communication schedule " << commsType + << abort(FatalError); + } +} + + +// Distribute list. +template<class T, class CombineOp> +void Foam::mapDistribute::distribute +( + const Pstream::commsTypes commsType, + const List<labelPair>& schedule, + const label constructSize, + const labelListList& subMap, + const labelListList& constructMap, + List<T>& field, + const CombineOp& cop, + const T& nullValue +) +{ + if (commsType == Pstream::blocking) + { + // Since buffered sending can reuse the field to collect the + // received data. + + // Send sub field to neighbour + for (label domain = 0; domain < Pstream::nProcs(); domain++) + { + const labelList& map = subMap[domain]; + + if (domain != Pstream::myProcNo() && map.size() > 0) + { + List<T> subField(map.size()); + forAll(map, i) + { + subField[i] = field[map[i]]; + } + OPstream toNbr(Pstream::blocking, domain); + toNbr << subField; + } + } + // Subset myself const labelList& mySubMap = subMap[Pstream::myProcNo()]; @@ -279,14 +393,231 @@ void Foam::mapDistribute::distribute subField[i] = field[mySubMap[i]]; } + // Receive sub field from myself (subField) + const labelList& map = constructMap[Pstream::myProcNo()]; + field.setSize(constructSize); + field = nullValue; + + forAll(map, i) + { + cop(field[map[i]], subField[i]); + } + + // Receive sub field from neighbour + for (label domain = 0; domain < Pstream::nProcs(); domain++) + { + const labelList& map = constructMap[domain]; + + if (domain != Pstream::myProcNo() && map.size() > 0) + { + IPstream fromNbr(Pstream::blocking, domain); + List<T> subField(fromNbr); + + if (subField.size() != map.size()) + { + FatalErrorIn + ( + "template<class T>\n" + "void mapDistribute::distribute\n" + "(\n" + " const Pstream::commsTypes commsType,\n" + " const List<labelPair>& schedule,\n" + " const label constructSize,\n" + " const labelListList& subMap,\n" + " const labelListList& constructMap,\n" + " List<T>& field\n" + ")\n" + ) << "Expected from processor " << domain + << " " << map.size() << " but received " + << subField.size() << " elements." + << abort(FatalError); + } + + forAll(map, i) + { + cop(field[map[i]], subField[i]); + } + } + } + } + else if (commsType == Pstream::scheduled) + { + // Need to make sure I don't overwrite field with received data + // since the data might need to be sent to another processor. So + // allocate a new field for the results. + List<T> newField(constructSize, nullValue); + + // Subset myself + const labelList& mySubMap = subMap[Pstream::myProcNo()]; + + List<T> subField(mySubMap.size()); + forAll(mySubMap, i) + { + subField[i] = field[mySubMap[i]]; + } // Receive sub field from myself (subField) const labelList& map = constructMap[Pstream::myProcNo()]; forAll(map, i) { - field[map[i]] = subField[i]; + cop(newField[map[i]], subField[i]); + } + + // Schedule will already have pruned 0-sized comms + forAll(schedule, i) + { + const labelPair& twoProcs = schedule[i]; + label sendProc = twoProcs[0]; + label recvProc = twoProcs[1]; + + if (Pstream::myProcNo() == sendProc) + { + // I am sender. Send to recvProc. + const labelList& map = subMap[recvProc]; + + List<T> subField(map.size()); + forAll(map, i) + { + subField[i] = field[map[i]]; + } + + OPstream toNbr(Pstream::scheduled, recvProc); + toNbr << subField; + } + else + { + // I am receiver. Receive from sendProc. + IPstream fromNbr(Pstream::scheduled, sendProc); + List<T> subField(fromNbr); + + const labelList& map = constructMap[sendProc]; + + if (subField.size() != map.size()) + { + FatalErrorIn + ( + "template<class T>\n" + "void mapDistribute::distribute\n" + "(\n" + " const Pstream::commsTypes commsType,\n" + " const List<labelPair>& schedule,\n" + " const label constructSize,\n" + " const labelListList& subMap,\n" + " const labelListList& constructMap,\n" + " List<T>& field\n" + ")\n" + ) << "Expected from processor " << sendProc + << " " << map.size() << " but received " + << subField.size() << " elements." + << abort(FatalError); + } + + forAll(map, i) + { + cop(newField[map[i]], subField[i]); + } + } + } + field.transfer(newField); + } + else if (commsType == Pstream::nonBlocking) + { + if (!contiguous<T>()) + { + FatalErrorIn + ( + "template<class T>\n" + "void mapDistribute::distribute\n" + "(\n" + " const Pstream::commsTypes commsType,\n" + " const List<labelPair>& schedule,\n" + " const label constructSize,\n" + " const labelListList& subMap,\n" + " const labelListList& constructMap,\n" + " List<T>& field\n" + ")\n" + ) << "Non-blocking only supported for contiguous data." + << exit(FatalError); + } + + // Set up sends to neighbours + + List<List<T > > sendFields(Pstream::nProcs()); + + for (label domain = 0; domain < Pstream::nProcs(); domain++) + { + const labelList& map = subMap[domain]; + + if (domain != Pstream::myProcNo() && map.size() > 0) + { + List<T>& subField = sendFields[domain]; + subField.setSize(map.size()); + forAll(map, i) + { + subField[i] = field[map[i]]; + } + + OPstream::write + ( + Pstream::nonBlocking, + domain, + reinterpret_cast<const char*>(subField.begin()), + subField.size()*sizeof(T) + ); + } + } + + // Set up receives from neighbours + + List<List<T > > recvFields(Pstream::nProcs()); + + for (label domain = 0; domain < Pstream::nProcs(); domain++) + { + const labelList& map = constructMap[domain]; + + if (domain != Pstream::myProcNo() && map.size() > 0) + { + recvFields[domain].setSize(map.size()); + IPstream::read + ( + Pstream::nonBlocking, + domain, + reinterpret_cast<char*>(recvFields[domain].begin()), + recvFields[domain].size()*sizeof(T) + ); + } + } + + // Set up 'send' to myself + + { + const labelList& map = subMap[Pstream::myProcNo()]; + + List<T>& subField = sendFields[Pstream::myProcNo()]; + subField.setSize(map.size()); + forAll(map, i) + { + subField[i] = field[map[i]]; + } + } + + + // Combine bits. Note that can reuse field storage + + field.setSize(constructSize); + field = nullValue; + + // Receive sub field from myself (subField) + { + const labelList& map = constructMap[Pstream::myProcNo()]; + const List<T>& subField = sendFields[Pstream::myProcNo()]; + + forAll(map, i) + { + cop(field[map[i]], subField[i]); + } } @@ -325,7 +656,7 @@ void Foam::mapDistribute::distribute forAll(map, i) { - field[map[i]] = recvFields[domain][i]; + cop(field[map[i]], recvFields[domain][i]); } } } diff --git a/src/finiteVolume/Make/files b/src/finiteVolume/Make/files index 923e4c50e60b14f7b95c7daad7b1ab04a90e98aa..7bf27115a57beb33d3ce99c1b17b5204e9b60038 100644 --- a/src/finiteVolume/Make/files +++ b/src/finiteVolume/Make/files @@ -40,6 +40,24 @@ $(fvMeshMapper)/fvSurfaceMapper.C extendedStencil = fvMesh/extendedStencil $(extendedStencil)/extendedStencil.C +$(extendedStencil)/extendedUpwindStencil.C +$(extendedStencil)/extendedCentredStencil.C + +$(extendedStencil)/faceStencil/faceStencil.C +$(extendedStencil)/faceStencil/faceEdgeCellStencil.C +$(extendedStencil)/faceStencil/cellFaceCellStencil.C +$(extendedStencil)/faceStencil/cellPointCellStencil.C +$(extendedStencil)/faceStencil/cellEdgeCellStencil.C + +$(extendedStencil)/extendedStencilMeshObjects/centredCECStencilObject.C +$(extendedStencil)/extendedStencilMeshObjects/centredCFCStencilObject.C +$(extendedStencil)/extendedStencilMeshObjects/centredCPCStencilObject.C +$(extendedStencil)/extendedStencilMeshObjects/centredFECStencilObject.C + +$(extendedStencil)/extendedStencilMeshObjects/upwindCECStencilObject.C +$(extendedStencil)/extendedStencilMeshObjects/upwindCFCStencilObject.C +$(extendedStencil)/extendedStencilMeshObjects/upwindCPCStencilObject.C +$(extendedStencil)/extendedStencilMeshObjects/upwindFECStencilObject.C fvPatchFields = fields/fvPatchFields $(fvPatchFields)/fvPatchField/fvPatchFields.C @@ -168,6 +186,8 @@ $(schemes)/harmonic/harmonic.C $(schemes)/localBlended/localBlended.C $(schemes)/localMax/localMax.C $(schemes)/localMin/localMin.C +//$(schemes)/linearFit/linearFit.C +//$(schemes)/linearFit/linearFitData.C $(schemes)/quadraticFit/quadraticFit.C $(schemes)/quadraticFit/quadraticFitData.C @@ -251,8 +271,8 @@ $(snGradSchemes)/snGradScheme/snGradSchemes.C $(snGradSchemes)/correctedSnGrad/correctedSnGrads.C $(snGradSchemes)/limitedSnGrad/limitedSnGrads.C $(snGradSchemes)/uncorrectedSnGrad/uncorrectedSnGrads.C -$(snGradSchemes)/quadraticFitSnGrad/quadraticFitSnGradData.C -$(snGradSchemes)/quadraticFitSnGrad/quadraticFitSnGrads.C +//$(snGradSchemes)/quadraticFitSnGrad/quadraticFitSnGradData.C +//$(snGradSchemes)/quadraticFitSnGrad/quadraticFitSnGrads.C convectionSchemes = finiteVolume/convectionSchemes $(convectionSchemes)/convectionScheme/convectionSchemes.C diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedCentredStencil.C b/src/finiteVolume/fvMesh/extendedStencil/extendedCentredStencil.C new file mode 100644 index 0000000000000000000000000000000000000000..956e796e18245219970be90dee4f7a06dce13118 --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedCentredStencil.C @@ -0,0 +1,65 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "mapDistribute.H" +#include "extendedCentredStencil.H" +#include "faceStencil.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::extendedCentredStencil::extendedCentredStencil(const faceStencil& stencil) +: + extendedStencil(stencil.mesh()) +{ + stencil_ = stencil; + + // Calculate distribute map (also renumbers stencil) + mapPtr_ = calcDistributeMap(stencil.globalNumbering(), stencil_); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +// Per face which elements of the stencil to keep. +void Foam::extendedCentredStencil::compact() +{ + boolList isInStencil(map().constructSize(), false); + + forAll(stencil_, faceI) + { + const labelList& stencilCells = stencil_[faceI]; + + forAll(stencilCells, i) + { + isInStencil[stencilCells[i]] = true; + } + } + + mapPtr_().compact(isInStencil); +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedCentredStencil.H b/src/finiteVolume/fvMesh/extendedStencil/extendedCentredStencil.H new file mode 100644 index 0000000000000000000000000000000000000000..0ae37d5eb6c8e83ea015117fe2d1a429d35badc5 --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedCentredStencil.H @@ -0,0 +1,137 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::extendedCentredStencil + +Description + +SourceFiles + extendedCentredStencil.C + +\*---------------------------------------------------------------------------*/ + +#ifndef extendedCentredStencil_H +#define extendedCentredStencil_H + +#include "extendedStencil.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +class faceStencil; + +/*---------------------------------------------------------------------------*\ + Class extendedCentredStencil Declaration +\*---------------------------------------------------------------------------*/ + +class extendedCentredStencil +: + public extendedStencil +{ + // Private data + + //- Swap map for getting neigbouring data + autoPtr<mapDistribute> mapPtr_; + + //- Per face the stencil. + labelListList stencil_; + + + // Private Member Functions + + //- Disallow default bitwise copy construct + extendedCentredStencil(const extendedCentredStencil&); + + //- Disallow default bitwise assignment + void operator=(const extendedCentredStencil&); + + +public: + + // Constructors + + //- Construct from uncompacted face stencil + explicit extendedCentredStencil(const faceStencil&); + + + // Member Functions + + //- Return reference to the parallel distribution map + const mapDistribute& map() const + { + return mapPtr_(); + } + + //- Return reference to the stencil + const labelListList& stencil() const + { + return stencil_; + } + + //- After removing elements from the stencil adapt the schedule (map). + void compact(); + + //- Use map to get the data into stencil order + template<class T> + void collectData + ( + const GeometricField<T, fvPatchField, volMesh>& fld, + List<List<T> >& stencilFld + ) const + { + extendedStencil::collectData(map(), stencil(), fld, stencilFld); + } + + //- Sum vol field contributions to create face values + template<class Type> + tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > weightedSum + ( + const GeometricField<Type, fvPatchField, volMesh>& fld, + const List<List<scalar> >& stencilWeights + ) const + { + return extendedStencil::weightedSum + ( + map(), + stencil(), + fld, + stencilWeights + ); + } + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedStencil.C b/src/finiteVolume/fvMesh/extendedStencil/extendedStencil.C index bb4c6c1534c66c5f32911fd57bd62cd2acd040e5..c2273d4a52f44ccbd104f5e526ac59729f87f3cf 100644 --- a/src/finiteVolume/fvMesh/extendedStencil/extendedStencil.C +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedStencil.C @@ -32,154 +32,83 @@ License // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // Calculates per face a list of global cell/face indices. -void Foam::extendedStencil::calcFaceStencils +void Foam::extendedStencil::calcFaceStencil ( - const polyMesh& mesh, - const globalIndex& globalNumbering + const labelListList& globalCellCells, + labelListList& faceStencil ) { - const polyBoundaryMesh& patches = mesh.boundaryMesh(); - const label nBnd = mesh.nFaces()-mesh.nInternalFaces(); - const labelList& own = mesh.faceOwner(); - const labelList& nei = mesh.faceNeighbour(); + const polyBoundaryMesh& patches = mesh_.boundaryMesh(); + const label nBnd = mesh_.nFaces()-mesh_.nInternalFaces(); + const labelList& own = mesh_.faceOwner(); + const labelList& nei = mesh_.faceNeighbour(); - // Determine neighbouring global cell or boundary face - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Determine neighbouring global cell Cells + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - labelList neiGlobal(nBnd); + labelListList neiGlobalCellCells(nBnd); forAll(patches, patchI) { const polyPatch& pp = patches[patchI]; - label faceI = pp.start(); if (pp.coupled()) { - // For coupled faces get the cell on the other side - forAll(pp, i) - { - label bFaceI = faceI-mesh.nInternalFaces(); - neiGlobal[bFaceI] = globalNumbering.toGlobal(own[faceI]); - faceI++; - } - } - else if (isA<emptyPolyPatch>(pp)) - { - forAll(pp, i) - { - label bFaceI = faceI-mesh.nInternalFaces(); - neiGlobal[bFaceI] = -1; - faceI++; - } - } - else - { - // For noncoupled faces get the boundary face. + label faceI = pp.start(); + forAll(pp, i) { - label bFaceI = faceI-mesh.nInternalFaces(); - neiGlobal[bFaceI] = - globalNumbering.toGlobal(mesh.nCells()+bFaceI); + neiGlobalCellCells[faceI-mesh_.nInternalFaces()] = + globalCellCells[own[faceI]]; faceI++; } } } - syncTools::swapBoundaryFaceList(mesh, neiGlobal, false); - - - // Determine cellCells in global numbering - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - labelListList globalCellCells(mesh.nCells()); - forAll(globalCellCells, cellI) - { - const cell& cFaces = mesh.cells()[cellI]; - - labelList& cCells = globalCellCells[cellI]; - - cCells.setSize(cFaces.size()); - - // Collect neighbouring cells/faces - label nNbr = 0; - forAll(cFaces, i) - { - label faceI = cFaces[i]; - - if (mesh.isInternalFace(faceI)) - { - label nbrCellI = own[faceI]; - if (nbrCellI == cellI) - { - nbrCellI = nei[faceI]; - } - cCells[nNbr++] = globalNumbering.toGlobal(nbrCellI); - } - else - { - label nbrCellI = neiGlobal[faceI-mesh.nInternalFaces()]; - if (nbrCellI != -1) - { - cCells[nNbr++] = nbrCellI; - } - } - } - cCells.setSize(nNbr); - } - - - // Determine neighbouring global cell Cells - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - labelListList neiGlobalCellCells(nBnd); - for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++) - { - neiGlobalCellCells[faceI-mesh.nInternalFaces()] = - globalCellCells[own[faceI]]; - } - syncTools::swapBoundaryFaceList(mesh, neiGlobalCellCells, false); + syncTools::swapBoundaryFaceList(mesh_, neiGlobalCellCells, false); // Construct stencil in global numbering // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - stencil_.setSize(mesh.nFaces()); + faceStencil.setSize(mesh_.nFaces()); - labelHashSet faceStencil; + labelHashSet faceStencilSet; - for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++) + for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++) { - faceStencil.clear(); - label globalOwn = globalNumbering.toGlobal(own[faceI]); - faceStencil.insert(globalOwn); + faceStencilSet.clear(); + const labelList& ownCCells = globalCellCells[own[faceI]]; + label globalOwn = ownCCells[0]; + // Insert cellCells forAll(ownCCells, i) { - faceStencil.insert(ownCCells[i]); + faceStencilSet.insert(ownCCells[i]); } - label globalNei = globalNumbering.toGlobal(nei[faceI]); - faceStencil.insert(globalNei); const labelList& neiCCells = globalCellCells[nei[faceI]]; + label globalNei = neiCCells[0]; + // Insert cellCells forAll(neiCCells, i) { - faceStencil.insert(neiCCells[i]); + faceStencilSet.insert(neiCCells[i]); } // Guarantee owner first, neighbour second. - stencil_[faceI].setSize(faceStencil.size()); + faceStencil[faceI].setSize(faceStencilSet.size()); label n = 0; - stencil_[faceI][n++] = globalOwn; - stencil_[faceI][n++] = globalNei; - forAllConstIter(labelHashSet, faceStencil, iter) + faceStencil[faceI][n++] = globalOwn; + faceStencil[faceI][n++] = globalNei; + forAllConstIter(labelHashSet, faceStencilSet, iter) { if (iter.key() != globalOwn && iter.key() != globalNei) { - stencil_[faceI][n++] = iter.key(); + faceStencil[faceI][n++] = iter.key(); } } - //Pout<< "internalface:" << faceI << " toc:" << faceStencil.toc() - // << " stencil:" << stencil_[faceI] << endl; + //Pout<< "internalface:" << faceI << " toc:" << faceStencilSet.toc() + // << " faceStencil:" << faceStencil[faceI] << endl; } forAll(patches, patchI) { @@ -190,41 +119,40 @@ void Foam::extendedStencil::calcFaceStencils { forAll(pp, i) { - faceStencil.clear(); - label globalOwn = globalNumbering.toGlobal(own[faceI]); - faceStencil.insert(globalOwn); + faceStencilSet.clear(); + const labelList& ownCCells = globalCellCells[own[faceI]]; + label globalOwn = ownCCells[0]; forAll(ownCCells, i) { - faceStencil.insert(ownCCells[i]); + faceStencilSet.insert(ownCCells[i]); } - // Get the coupled cell - label globalNei = neiGlobal[faceI-mesh.nInternalFaces()]; - faceStencil.insert(globalNei); + // And the neighbours of the coupled cell const labelList& neiCCells = - neiGlobalCellCells[faceI-mesh.nInternalFaces()]; + neiGlobalCellCells[faceI-mesh_.nInternalFaces()]; + label globalNei = neiCCells[0]; forAll(neiCCells, i) { - faceStencil.insert(neiCCells[i]); + faceStencilSet.insert(neiCCells[i]); } // Guarantee owner first, neighbour second. - stencil_[faceI].setSize(faceStencil.size()); + faceStencil[faceI].setSize(faceStencilSet.size()); label n = 0; - stencil_[faceI][n++] = globalOwn; - stencil_[faceI][n++] = globalNei; - forAllConstIter(labelHashSet, faceStencil, iter) + faceStencil[faceI][n++] = globalOwn; + faceStencil[faceI][n++] = globalNei; + forAllConstIter(labelHashSet, faceStencilSet, iter) { if (iter.key() != globalOwn && iter.key() != globalNei) { - stencil_[faceI][n++] = iter.key(); + faceStencil[faceI][n++] = iter.key(); } } //Pout<< "coupledface:" << faceI - // << " toc:" << faceStencil.toc() - // << " stencil:" << stencil_[faceI] << endl; + // << " toc:" << faceStencilSet.toc() + // << " faceStencil:" << faceStencil[faceI] << endl; faceI++; } @@ -233,31 +161,30 @@ void Foam::extendedStencil::calcFaceStencils { forAll(pp, i) { - faceStencil.clear(); - label globalOwn = globalNumbering.toGlobal(own[faceI]); - faceStencil.insert(globalOwn); + faceStencilSet.clear(); + const labelList& ownCCells = globalCellCells[own[faceI]]; + label globalOwn = ownCCells[0]; forAll(ownCCells, i) { - faceStencil.insert(ownCCells[i]); + faceStencilSet.insert(ownCCells[i]); } - // Guarantee owner first, neighbour second. - stencil_[faceI].setSize(faceStencil.size()); + faceStencil[faceI].setSize(faceStencilSet.size()); label n = 0; - stencil_[faceI][n++] = globalOwn; - forAllConstIter(labelHashSet, faceStencil, iter) + faceStencil[faceI][n++] = globalOwn; + forAllConstIter(labelHashSet, faceStencilSet, iter) { if (iter.key() != globalOwn) { - stencil_[faceI][n++] = iter.key(); + faceStencil[faceI][n++] = iter.key(); } } //Pout<< "boundaryface:" << faceI - // << " toc:" << faceStencil.toc() - // << " stencil:" << stencil_[faceI] << endl; + // << " toc:" << faceStencilSet.toc() + // << " faceStencil:" << faceStencil[faceI] << endl; faceI++; } @@ -266,34 +193,13 @@ void Foam::extendedStencil::calcFaceStencils } -// Calculates extended stencil. This is per face -// - owner -// - cellCells of owner -// - neighbour -// - cellCells of neighbour -// It comes in two parts: -// - a map which collects/distributes all necessary data in a compact array -// - the stencil (a labelList per face) which is a set of indices into this -// compact array. -// The compact array is laid out as follows: -// - first data for current processor (Pstream::myProcNo()) -// - all cells -// - all boundary faces -// - then per processor -// - all used cells and boundary faces -void Foam::extendedStencil::calcExtendedFaceStencil(const polyMesh& mesh) +Foam::autoPtr<Foam::mapDistribute> Foam::extendedStencil::calcDistributeMap +( + const globalIndex& globalNumbering, + labelListList& faceStencil +) { - const label nBnd = mesh.nFaces()-mesh.nInternalFaces(); - - // Global numbering for cells and boundary faces - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - globalIndex globalNumbering(mesh.nCells()+nBnd); - - - // Calculate stencil in global cell indices - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - calcFaceStencils(mesh, globalNumbering); + const label nBnd = mesh_.nFaces()-mesh_.nInternalFaces(); // Convert stencil to schedule @@ -309,8 +215,8 @@ void Foam::extendedStencil::calcExtendedFaceStencil(const polyMesh& mesh) // these are always all needed. List<Map<label> > globalToProc(Pstream::nProcs()); { - const labelList& procPatchMap = mesh.globalData().procPatchMap(); - const polyBoundaryMesh& patches = mesh.boundaryMesh(); + const labelList& procPatchMap = mesh_.globalData().procPatchMap(); + const polyBoundaryMesh& patches = mesh_.boundaryMesh(); // Presize with (as estimate) size of patch to neighbour. forAll(procPatchMap, procI) @@ -325,9 +231,9 @@ void Foam::extendedStencil::calcExtendedFaceStencil(const polyMesh& mesh) } // Collect all (non-local) globalcells/faces needed. - forAll(stencil_, faceI) + forAll(faceStencil, faceI) { - const labelList& stencilCells = stencil_[faceI]; + const labelList& stencilCells = faceStencil[faceI]; forAll(stencilCells, i) { @@ -359,17 +265,17 @@ void Foam::extendedStencil::calcExtendedFaceStencil(const polyMesh& mesh) } - // forAll(globalToProc, procI) - // { - // Pout<< "From processor:" << procI << " want cells/faces:" << endl; - // forAllConstIter(Map<label>, globalToProc[procI], iter) - // { - // Pout<< " global:" << iter.key() - // << " local:" << globalNumbering.toLocal(procI, iter.key()) - // << endl; - // } - // Pout<< endl; - // } + //forAll(globalToProc, procI) + //{ + // Pout<< "From processor:" << procI << " want cells/faces:" << endl; + // forAllConstIter(Map<label>, globalToProc[procI], iter) + // { + // Pout<< " global:" << iter.key() + // << " local:" << globalNumbering.toLocal(procI, iter.key()) + // << endl; + // } + // Pout<< endl; + //} } @@ -379,19 +285,15 @@ void Foam::extendedStencil::calcExtendedFaceStencil(const polyMesh& mesh) labelList compactStart(Pstream::nProcs()); compactStart[Pstream::myProcNo()] = 0; - label nCompact = mesh.nCells()+nBnd; + label nCompact = mesh_.nCells()+nBnd; forAll(compactStart, procI) { if (procI != Pstream::myProcNo()) { compactStart[procI] = nCompact; nCompact += globalToProc[procI].size(); - - // Pout<< "Data wanted from " << procI << " starts at " - // << compactStart[procI] << endl; } } - // Pout<< "Overall cells needed:" << nCompact << endl; // 3. Find out what to receive/send in compact addressing. @@ -411,11 +313,6 @@ void Foam::extendedStencil::calcExtendedFaceStencil(const polyMesh& mesh) i++; } - // Pout<< "From proc:" << procI - // << " I need (globalcells):" << wantedGlobals - // << " which are my compact:" << recvCompact[procI] - // << endl; - // Send the global cell numbers I need from procI OPstream str(Pstream::blocking, procI); str << wantedGlobals; @@ -424,7 +321,7 @@ void Foam::extendedStencil::calcExtendedFaceStencil(const polyMesh& mesh) { recvCompact[procI] = compactStart[procI] - + identity(mesh.nCells()+nBnd); + + identity(mesh_.nCells()+nBnd); } } labelListList sendCompact(Pstream::nProcs()); @@ -455,9 +352,9 @@ void Foam::extendedStencil::calcExtendedFaceStencil(const polyMesh& mesh) } // Convert stencil to compact numbering - forAll(stencil_, faceI) + forAll(faceStencil, faceI) { - labelList& stencilCells = stencil_[faceI]; + labelList& stencilCells = faceStencil[faceI]; forAll(stencilCells, i) { @@ -476,10 +373,9 @@ void Foam::extendedStencil::calcExtendedFaceStencil(const polyMesh& mesh) } } - // Pout<< "***stencil_:" << stencil_ << endl; // Constuct map for distribution of compact data. - mapPtr_.reset + return autoPtr<mapDistribute> ( new mapDistribute ( @@ -494,32 +390,10 @@ void Foam::extendedStencil::calcExtendedFaceStencil(const polyMesh& mesh) // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::extendedStencil::extendedStencil -( - const mapDistribute& map, - const labelListList& stencil -) +Foam::extendedStencil::extendedStencil(const polyMesh& mesh) : - mapPtr_ - ( - autoPtr<mapDistribute> - ( - new mapDistribute - ( - map.constructSize(), - map.subMap(), - map.constructMap() - ) - ) - ), - stencil_(stencil) + mesh_(mesh) {} -Foam::extendedStencil::extendedStencil(const polyMesh& mesh) -{ - calcExtendedFaceStencil(mesh); -} - - // ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedStencil.H b/src/finiteVolume/fvMesh/extendedStencil/extendedStencil.H index ad2f4e1b0b0c98ff746733e2b247bbe8fc907ac3..12d3179e62fc1f2a7ffdca439e0164887a952816 100644 --- a/src/finiteVolume/fvMesh/extendedStencil/extendedStencil.H +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedStencil.H @@ -42,6 +42,7 @@ Description SourceFiles extendedStencil.C + extendedStencilTemplates.C \*---------------------------------------------------------------------------*/ @@ -65,22 +66,33 @@ class globalIndex; class extendedStencil { - // Private data +protected: - //- Swap map for getting neigbouring data - autoPtr<mapDistribute> mapPtr_; + // Protected data - //- Per face the stencil. - labelListList stencil_; + const polyMesh& mesh_; - // Private Member Functions + // Protected Member Functions + + //- Collect cell neighbours into extended stencil + void calcFaceStencil + ( + const labelListList& globalCellCells, + labelListList& faceStencil + ); + + //- Calculate distribute map + autoPtr<mapDistribute> calcDistributeMap + ( + const globalIndex& globalNumbering, + labelListList& faceStencil + ); - void calcFaceStencils(const polyMesh&, const globalIndex&); - //- Calculate the stencil (but not weights) - void calcExtendedFaceStencil(const polyMesh&); +private: + // Private Member Functions //- Disallow default bitwise copy construct extendedStencil(const extendedStencil&); @@ -93,43 +105,32 @@ public: // Constructors - //- Construct from components - extendedStencil(const mapDistribute& map, const labelListList&); - - //- Construct from all cells and boundary faces - extendedStencil(const polyMesh&); - + //- Construct from mesh + explicit extendedStencil(const polyMesh&); // Member Functions - //- Return reference to the parallel distribution map - const mapDistribute& map() const - { - return mapPtr_(); - } - - //- Return reference to the stencil - const labelListList& stencil() const - { - return stencil_; - } - //- Use map to get the data into stencil order template<class T> - void collectData + static void collectData ( + const mapDistribute& map, + const labelListList& stencil, const GeometricField<T, fvPatchField, volMesh>& fld, List<List<T> >& stencilFld - ) const; + ); - //- Calculate weighted sum of vol field + //- Sum vol field contributions to create face values template<class Type> - tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > weightedSum + static tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > + weightedSum ( + const mapDistribute& map, + const labelListList& stencil, const GeometricField<Type, fvPatchField, volMesh>& fld, const List<List<scalar> >& stencilWeights - ) const; + ); }; diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredCECStencilObject.C b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredCECStencilObject.C new file mode 100644 index 0000000000000000000000000000000000000000..2c5333bd92fc1082ef4f0ce2f46289e064055039 --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredCECStencilObject.C @@ -0,0 +1,38 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "centredCECStencilObject.H" + + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(centredCECStencilObject, 0); +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredCECStencilObject.H b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredCECStencilObject.H new file mode 100644 index 0000000000000000000000000000000000000000..adbc9ec5b3b750ef44527821591d31821688ab8b --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredCECStencilObject.H @@ -0,0 +1,88 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::centredCECStencilObject + +Description + +SourceFiles + +\*---------------------------------------------------------------------------*/ + +#ifndef centredCECStencilObject_H +#define centredCECStencilObject_H + +#include "extendedCentredStencil.H" +#include "cellEdgeCellStencil.H" +#include "MeshObject.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class centredCECStencilObject Declaration +\*---------------------------------------------------------------------------*/ + +class centredCECStencilObject +: + public MeshObject<fvMesh, centredCECStencilObject>, + public extendedCentredStencil +{ + +public: + + TypeName("centredCECStencil"); + + // Constructors + + //- Construct from uncompacted face stencil + explicit centredCECStencilObject + ( + const fvMesh& mesh + ) + : + MeshObject<fvMesh, centredCECStencilObject>(mesh), + extendedCentredStencil(cellEdgeCellStencil(mesh)) + {} + + + // Destructor + + virtual ~centredCECStencilObject() + {} +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredCFCStencilObject.C b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredCFCStencilObject.C new file mode 100644 index 0000000000000000000000000000000000000000..e55e3ed2c165ede70fda44abc1a8720ddbda230c --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredCFCStencilObject.C @@ -0,0 +1,38 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "centredCFCStencilObject.H" + + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(centredCFCStencilObject, 0); +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredCFCStencilObject.H b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredCFCStencilObject.H new file mode 100644 index 0000000000000000000000000000000000000000..704f9a92d459394366abf605d3f301276495c0b0 --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredCFCStencilObject.H @@ -0,0 +1,88 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::centredCFCStencilObject + +Description + +SourceFiles + +\*---------------------------------------------------------------------------*/ + +#ifndef centredCFCStencilObject_H +#define centredCFCStencilObject_H + +#include "extendedCentredStencil.H" +#include "cellFaceCellStencil.H" +#include "MeshObject.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class centredCFCStencilObject Declaration +\*---------------------------------------------------------------------------*/ + +class centredCFCStencilObject +: + public MeshObject<fvMesh, centredCFCStencilObject>, + public extendedCentredStencil +{ + +public: + + TypeName("centredCFCStencil"); + + // Constructors + + //- Construct from uncompacted face stencil + explicit centredCFCStencilObject + ( + const fvMesh& mesh + ) + : + MeshObject<fvMesh, centredCFCStencilObject>(mesh), + extendedCentredStencil(cellFaceCellStencil(mesh)) + {} + + + // Destructor + + virtual ~centredCFCStencilObject() + {} +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredCPCStencilObject.C b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredCPCStencilObject.C new file mode 100644 index 0000000000000000000000000000000000000000..09af9fb3ef8b3bdd7c8f6e23bd6f08698c89e8d4 --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredCPCStencilObject.C @@ -0,0 +1,38 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "centredCPCStencilObject.H" + + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(centredCPCStencilObject, 0); +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredCPCStencilObject.H b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredCPCStencilObject.H new file mode 100644 index 0000000000000000000000000000000000000000..049d214437ae2441d77d30b95ff22b3231a9c57c --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredCPCStencilObject.H @@ -0,0 +1,88 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::centredCPCStencilObject + +Description + +SourceFiles + +\*---------------------------------------------------------------------------*/ + +#ifndef centredCPCStencilObject_H +#define centredCPCStencilObject_H + +#include "extendedCentredStencil.H" +#include "cellPointCellStencil.H" +#include "MeshObject.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class centredCPCStencilObject Declaration +\*---------------------------------------------------------------------------*/ + +class centredCPCStencilObject +: + public MeshObject<fvMesh, centredCPCStencilObject>, + public extendedCentredStencil +{ + +public: + + TypeName("centredCFCStencil"); + + // Constructors + + //- Construct from uncompacted face stencil + explicit centredCPCStencilObject + ( + const fvMesh& mesh + ) + : + MeshObject<fvMesh, centredCPCStencilObject>(mesh), + extendedCentredStencil(cellPointCellStencil(mesh)) + {} + + + // Destructor + + virtual ~centredCPCStencilObject() + {} +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredFECStencilObject.C b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredFECStencilObject.C new file mode 100644 index 0000000000000000000000000000000000000000..f589b90ff101c640164e3de2bc11a19bd7700425 --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredFECStencilObject.C @@ -0,0 +1,38 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "centredFECStencilObject.H" + + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(centredFECStencilObject, 0); +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredFECStencilObject.H b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredFECStencilObject.H new file mode 100644 index 0000000000000000000000000000000000000000..6f7acf78adfb15d03e6f5b93019c40cb65467fe4 --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/centredFECStencilObject.H @@ -0,0 +1,88 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::centredFECStencilObject + +Description + +SourceFiles + +\*---------------------------------------------------------------------------*/ + +#ifndef centredFECStencilObject_H +#define centredFECStencilObject_H + +#include "extendedCentredStencil.H" +#include "faceEdgeCellStencil.H" +#include "MeshObject.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class centredFECStencilObject Declaration +\*---------------------------------------------------------------------------*/ + +class centredFECStencilObject +: + public MeshObject<fvMesh, centredFECStencilObject>, + public extendedCentredStencil +{ + +public: + + TypeName("centredCFCStencil"); + + // Constructors + + //- Construct from uncompacted face stencil + explicit centredFECStencilObject + ( + const fvMesh& mesh + ) + : + MeshObject<fvMesh, centredFECStencilObject>(mesh), + extendedCentredStencil(faceEdgeCellStencil(mesh)) + {} + + + // Destructor + + virtual ~centredFECStencilObject() + {} +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindCECStencilObject.C b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindCECStencilObject.C new file mode 100644 index 0000000000000000000000000000000000000000..a869b71d7e133b2c46a466f975a2eac00b5e3782 --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindCECStencilObject.C @@ -0,0 +1,38 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "upwindCECStencilObject.H" + + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(upwindCECStencilObject, 0); +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindCECStencilObject.H b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindCECStencilObject.H new file mode 100644 index 0000000000000000000000000000000000000000..f964faf9d0019fbd37ba5c070e697f6663ea3d8a --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindCECStencilObject.H @@ -0,0 +1,89 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::upwindCECStencilObject + +Description + +SourceFiles + +\*---------------------------------------------------------------------------*/ + +#ifndef upwindCECStencilObject_H +#define upwindCECStencilObject_H + +#include "extendedUpwindStencil.H" +#include "cellEdgeCellStencil.H" +#include "MeshObject.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class upwindCECStencilObject Declaration +\*---------------------------------------------------------------------------*/ + +class upwindCECStencilObject +: + public MeshObject<fvMesh, upwindCECStencilObject>, + public extendedUpwindStencil +{ + +public: + + TypeName("upwindCFCStencil"); + + // Constructors + + //- Construct from uncompacted face stencil + explicit upwindCECStencilObject + ( + const fvMesh& mesh, + const scalar minOpposedness + ) + : + MeshObject<fvMesh, upwindCECStencilObject>(mesh), + extendedUpwindStencil(cellEdgeCellStencil(mesh), minOpposedness) + {} + + + // Destructor + + virtual ~upwindCECStencilObject() + {} +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindCFCStencilObject.C b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindCFCStencilObject.C new file mode 100644 index 0000000000000000000000000000000000000000..5637b4f9ea10b70e2bd5cdf643d7fc9126652d5b --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindCFCStencilObject.C @@ -0,0 +1,38 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "upwindCFCStencilObject.H" + + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(upwindCFCStencilObject, 0); +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindCFCStencilObject.H b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindCFCStencilObject.H new file mode 100644 index 0000000000000000000000000000000000000000..a38d274b487b466af2b2190e014c984f337176c0 --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindCFCStencilObject.H @@ -0,0 +1,89 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::upwindCFCStencilObject + +Description + +SourceFiles + +\*---------------------------------------------------------------------------*/ + +#ifndef upwindCFCStencilObject_H +#define upwindCFCStencilObject_H + +#include "extendedUpwindStencil.H" +#include "cellFaceCellStencil.H" +#include "MeshObject.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class upwindCFCStencilObject Declaration +\*---------------------------------------------------------------------------*/ + +class upwindCFCStencilObject +: + public MeshObject<fvMesh, upwindCFCStencilObject>, + public extendedUpwindStencil +{ + +public: + + TypeName("upwindCFCStencil"); + + // Constructors + + //- Construct from uncompacted face stencil + explicit upwindCFCStencilObject + ( + const fvMesh& mesh, + const scalar minOpposedness + ) + : + MeshObject<fvMesh, upwindCFCStencilObject>(mesh), + extendedUpwindStencil(cellFaceCellStencil(mesh), minOpposedness) + {} + + + // Destructor + + virtual ~upwindCFCStencilObject() + {} +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindCPCStencilObject.C b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindCPCStencilObject.C new file mode 100644 index 0000000000000000000000000000000000000000..f75571f3e768bd3bbe8f34f9ac0a58b753ef01de --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindCPCStencilObject.C @@ -0,0 +1,38 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "upwindCPCStencilObject.H" + + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(upwindCPCStencilObject, 0); +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindCPCStencilObject.H b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindCPCStencilObject.H new file mode 100644 index 0000000000000000000000000000000000000000..0d86ef6422b7598447689abbc9befaf5d5a782d1 --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindCPCStencilObject.H @@ -0,0 +1,89 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::upwindCPCStencilObject + +Description + +SourceFiles + +\*---------------------------------------------------------------------------*/ + +#ifndef upwindCPCStencilObject_H +#define upwindCPCStencilObject_H + +#include "extendedUpwindStencil.H" +#include "cellPointCellStencil.H" +#include "MeshObject.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class upwindCPCStencilObject Declaration +\*---------------------------------------------------------------------------*/ + +class upwindCPCStencilObject +: + public MeshObject<fvMesh, upwindCPCStencilObject>, + public extendedUpwindStencil +{ + +public: + + TypeName("upwindCFCStencil"); + + // Constructors + + //- Construct from uncompacted face stencil + explicit upwindCPCStencilObject + ( + const fvMesh& mesh, + const scalar minOpposedness + ) + : + MeshObject<fvMesh, upwindCPCStencilObject>(mesh), + extendedUpwindStencil(cellPointCellStencil(mesh), minOpposedness) + {} + + + // Destructor + + virtual ~upwindCPCStencilObject() + {} +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindFECStencilObject.C b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindFECStencilObject.C new file mode 100644 index 0000000000000000000000000000000000000000..43b71817c2103ca7ea8809f4bd76adbd9aea861e --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindFECStencilObject.C @@ -0,0 +1,38 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "upwindFECStencilObject.H" + + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(upwindFECStencilObject, 0); +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindFECStencilObject.H b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindFECStencilObject.H new file mode 100644 index 0000000000000000000000000000000000000000..5b2627ebbe2acb4083fddf5274e481e84f8dac73 --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilMeshObjects/upwindFECStencilObject.H @@ -0,0 +1,89 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::upwindFECStencilObject + +Description + +SourceFiles + +\*---------------------------------------------------------------------------*/ + +#ifndef upwindFECStencilObject_H +#define upwindFECStencilObject_H + +#include "extendedUpwindStencil.H" +#include "faceEdgeCellStencil.H" +#include "MeshObject.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class upwindFECStencilObject Declaration +\*---------------------------------------------------------------------------*/ + +class upwindFECStencilObject +: + public MeshObject<fvMesh, upwindFECStencilObject>, + public extendedUpwindStencil +{ + +public: + + TypeName("upwindCFCStencil"); + + // Constructors + + //- Construct from uncompacted face stencil + explicit upwindFECStencilObject + ( + const fvMesh& mesh, + const scalar minOpposedness + ) + : + MeshObject<fvMesh, upwindFECStencilObject>(mesh), + extendedUpwindStencil(faceEdgeCellStencil(mesh), minOpposedness) + {} + + + // Destructor + + virtual ~upwindFECStencilObject() + {} +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedStencilTemplates.C b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilTemplates.C index 31adb48392ac34d125b7592394ffc1b1d7f57ab6..480cf15a2a9412224c5e465dafde0fb9fc766b31 100644 --- a/src/finiteVolume/fvMesh/extendedStencil/extendedStencilTemplates.C +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedStencilTemplates.C @@ -31,12 +31,14 @@ License template<class Type> void Foam::extendedStencil::collectData ( + const mapDistribute& map, + const labelListList& stencil, const GeometricField<Type, fvPatchField, volMesh>& fld, List<List<Type> >& stencilFld -) const +) { // 1. Construct cell data in compact addressing - List<Type> compactFld(map().constructSize(), pTraits<Type>::zero); + List<Type> compactFld(map.constructSize(), pTraits<Type>::zero); // Insert my internal values forAll(fld, cellI) @@ -56,14 +58,14 @@ void Foam::extendedStencil::collectData } // Do all swapping - map().distribute(compactFld); + map.distribute(compactFld); // 2. Pull to stencil - stencilFld.setSize(stencil_.size()); + stencilFld.setSize(stencil.size()); - forAll(stencil_, faceI) + forAll(stencil, faceI) { - const labelList& compactCells = stencil_[faceI]; + const labelList& compactCells = stencil[faceI]; stencilFld[faceI].setSize(compactCells.size()); @@ -79,15 +81,17 @@ template<class Type> Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> > Foam::extendedStencil::weightedSum ( + const mapDistribute& map, + const labelListList& stencil, const GeometricField<Type, fvPatchField, volMesh>& fld, const List<List<scalar> >& stencilWeights -) const +) { const fvMesh& mesh = fld.mesh(); // Collect internal and boundary values List<List<Type> > stencilFld; - collectData(fld, stencilFld); + collectData(map, stencil, fld, stencilFld); tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsfCorr ( @@ -110,6 +114,7 @@ Foam::extendedStencil::weightedSum ); GeometricField<Type, fvsPatchField, surfaceMesh>& sf = tsfCorr(); + // Internal faces for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++) { const List<Type>& stField = stencilFld[faceI]; @@ -121,33 +126,30 @@ Foam::extendedStencil::weightedSum } } - // Coupled boundaries - /* + // Boundaries. Either constrained or calculated so assign value + // directly (instead of nicely using operator==) typename GeometricField<Type, fvsPatchField, surfaceMesh>:: GeometricBoundaryField& bSfCorr = sf.boundaryField(); + forAll(bSfCorr, patchi) { fvsPatchField<Type>& pSfCorr = bSfCorr[patchi]; - if (pSfCorr.coupled()) + label faceI = pSfCorr.patch().patch().start(); + + forAll(pSfCorr, i) { - label faceI = pSfCorr.patch().patch().start(); + const List<Type>& stField = stencilFld[faceI]; + const List<scalar>& stWeight = stencilWeights[faceI]; - forAll(pSfCorr, i) + forAll(stField, j) { - const List<Type>& stField = stencilFld[faceI]; - const List<scalar>& stWeight = stencilWeights[faceI]; - - forAll(stField, j) - { - pSfCorr[i] += stField[j]*stWeight[j]; - } - - faceI++; + pSfCorr[i] += stField[j]*stWeight[j]; } + + faceI++; } } - */ return tsfCorr; } diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedUpwindStencil.C b/src/finiteVolume/fvMesh/extendedStencil/extendedUpwindStencil.C new file mode 100644 index 0000000000000000000000000000000000000000..64991775ba354cbe5e16ea74c3e6aa5aee978b39 --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedUpwindStencil.C @@ -0,0 +1,429 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "extendedUpwindStencil.H" +#include "faceStencil.H" +#include "syncTools.H" +#include "SortableList.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::extendedUpwindStencil::selectOppositeFaces +( + const boolList& nonEmptyFace, + const scalar minOpposedness, + const label faceI, + const label cellI, + DynamicList<label>& oppositeFaces +) const +{ + const vectorField& areas = mesh_.faceAreas(); + const labelList& own = mesh_.faceOwner(); + const cell& cFaces = mesh_.cells()[cellI]; + + SortableList<scalar> opposedness(cFaces.size(), -GREAT); + + // Pick up all the faces that oppose this one. + forAll(cFaces, i) + { + label otherFaceI = cFaces[i]; + + if (otherFaceI != faceI && nonEmptyFace[otherFaceI]) + { + if ((own[otherFaceI] == cellI) == (own[faceI] == cellI)) + { + opposedness[i] = -(areas[otherFaceI] & areas[faceI]); + } + else + { + opposedness[i] = (areas[otherFaceI] & areas[faceI]); + } + } + } + + label sz = opposedness.size(); + + oppositeFaces.clear(); + + scalar myAreaSqr = magSqr(areas[faceI]); + + if (myAreaSqr > VSMALL) + { + forAll(opposedness, i) + { + opposedness[i] /= myAreaSqr; + } + // Sort in incrementing order + opposedness.sort(); + + // Pick largest no matter what + oppositeFaces.append(cFaces[opposedness.indices()[sz-1]]); + + for (label i = sz-2; i >= 0; --i) + { + if (opposedness[i] < minOpposedness) + { + break; + } + oppositeFaces.append(cFaces[opposedness.indices()[i]]); + } + } + else + { + // Sort in incrementing order + opposedness.sort(); + + // Tiny face. Do what? + // Pick largest no matter what + oppositeFaces.append(cFaces[opposedness.indices()[sz-1]]); + } +} + + +void Foam::extendedUpwindStencil::transportStencil +( + const boolList& nonEmptyFace, + const labelListList& faceStencil, + const scalar minOpposedness, + const label faceI, + const label cellI, + const bool stencilHasNeighbour, + + DynamicList<label>& oppositeFaces, + labelHashSet& faceStencilSet, + labelList& transportedStencil +) const +{ + label globalOwn = faceStencil[faceI][0]; + label globalNei = -1; + if (stencilHasNeighbour && faceStencil[faceI].size() >= 2) + { + globalNei = faceStencil[faceI][1]; + } + + + selectOppositeFaces + ( + nonEmptyFace, + minOpposedness, + faceI, + cellI, + oppositeFaces + ); + + // Collect all stencils of oppositefaces + faceStencilSet.clear(); + forAll(oppositeFaces, i) + { + const labelList& fStencil = faceStencil[oppositeFaces[i]]; + + forAll(fStencil, j) + { + label globalI = fStencil[j]; + + if (globalI != globalOwn && globalI != globalNei) + { + faceStencilSet.insert(globalI); + } + } + } + + // Add my owner and neighbour first. + if (stencilHasNeighbour) + { + transportedStencil.setSize(faceStencilSet.size()+2); + label n = 0; + transportedStencil[n++] = globalOwn; + transportedStencil[n++] = globalNei; + + forAllConstIter(labelHashSet, faceStencilSet, iter) + { + if (iter.key() != globalOwn && iter.key() != globalNei) + { + transportedStencil[n++] = iter.key(); + } + } + if (n != transportedStencil.size()) + { + FatalErrorIn("extendedUpwindStencil::transportStencil(..)") + << "problem:" << faceStencilSet + << abort(FatalError); + } + } + else + { + transportedStencil.setSize(faceStencilSet.size()+1); + label n = 0; + transportedStencil[n++] = globalOwn; + + forAllConstIter(labelHashSet, faceStencilSet, iter) + { + if (iter.key() != globalOwn) + { + transportedStencil[n++] = iter.key(); + } + } + if (n != transportedStencil.size()) + { + FatalErrorIn("extendedUpwindStencil::transportStencil(..)") + << "problem:" << faceStencilSet + << abort(FatalError); + } + } +} + + +void Foam::extendedUpwindStencil::transportStencils +( + const labelListList& faceStencil, + const scalar minOpposedness, + labelListList& ownStencil, + labelListList& neiStencil +) +{ + const polyBoundaryMesh& patches = mesh_.boundaryMesh(); + const label nBnd = mesh_.nFaces()-mesh_.nInternalFaces(); + const labelList& own = mesh_.faceOwner(); + const labelList& nei = mesh_.faceNeighbour(); + + // Work arrays + DynamicList<label> oppositeFaces; + labelHashSet faceStencilSet; + + + // For quick detection of empty faces + boolList nonEmptyFace(mesh_.nFaces(), true); + forAll(patches, patchI) + { + const polyPatch& pp = patches[patchI]; + + if (isA<emptyPolyPatch>(pp)) + { + label faceI = pp.start(); + forAll(pp, i) + { + nonEmptyFace[faceI++] = false; + } + } + } + + + // Do the owner side + // ~~~~~~~~~~~~~~~~~ + // stencil is synchronised at entry so no need to swap. + + ownStencil.setSize(mesh_.nFaces()); + + // Internal faces + for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++) + { + transportStencil + ( + nonEmptyFace, + faceStencil, + minOpposedness, + faceI, + own[faceI], + true, //stencilHasNeighbour + oppositeFaces, + faceStencilSet, + ownStencil[faceI] + ); + } + // Boundary faces + forAll(patches, patchI) + { + const polyPatch& pp = patches[patchI]; + label faceI = pp.start(); + + if (pp.coupled()) + { + forAll(pp, i) + { + transportStencil + ( + nonEmptyFace, + faceStencil, + minOpposedness, + faceI, + own[faceI], + true, //stencilHasNeighbour + + oppositeFaces, + faceStencilSet, + ownStencil[faceI] + ); + faceI++; + } + } + else if (!isA<emptyPolyPatch>(pp)) + { + forAll(pp, i) + { + // faceStencil does not contain neighbour + transportStencil + ( + nonEmptyFace, + faceStencil, + minOpposedness, + faceI, + own[faceI], + false, //stencilHasNeighbour + + oppositeFaces, + faceStencilSet, + ownStencil[faceI] + ); + faceI++; + } + } + } + + + // Swap coupled boundary stencil + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + labelListList neiBndStencil(nBnd); + for (label faceI = mesh_.nInternalFaces(); faceI < mesh_.nFaces(); faceI++) + { + neiBndStencil[faceI-mesh_.nInternalFaces()] = ownStencil[faceI]; + } + syncTools::swapBoundaryFaceList(mesh_, neiBndStencil, false); + + + // Do the neighbour side + // ~~~~~~~~~~~~~~~~~~~~~ + // - internal faces : get opposite faces on neighbour side + // - boundary faces : empty + // - coupled faces : in neiBndStencil + + neiStencil.setSize(mesh_.nFaces()); + + // Internal faces + for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++) + { + transportStencil + ( + nonEmptyFace, + faceStencil, + minOpposedness, + faceI, + nei[faceI], + true, //stencilHasNeighbour + + oppositeFaces, + faceStencilSet, + neiStencil[faceI] + ); + } + + // Boundary faces + forAll(patches, patchI) + { + const polyPatch& pp = patches[patchI]; + label faceI = pp.start(); + + if (pp.coupled()) + { + forAll(pp, i) + { + neiStencil[faceI].transfer + ( + neiBndStencil[faceI-mesh_.nInternalFaces()] + ); + faceI++; + } + } + else + { + // Boundary has empty neighbour stencil + } + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::extendedUpwindStencil::extendedUpwindStencil +( + const faceStencil& stencil, + const scalar minOpposedness +) +: + extendedStencil(stencil.mesh()) +{ + //forAll(stencil, faceI) + //{ + // const labelList& fCells = stencil[faceI]; + // + // Pout<< "Face:" << faceI << " at:" << mesh_.faceCentres()[faceI] + // << endl; + // + // forAll(fCells, i) + // { + // label globalI = fCells[i]; + // + // if (globalI < mesh_.nCells()) + // { + // Pout<< " cell:" << globalI + // << " at:" << mesh_.cellCentres()[globalI] << endl; + // } + // else + // { + // label faceI = globalI-mesh_.nCells() + mesh_.nInternalFaces(); + // + // Pout<< " boundary:" << faceI + // << " at:" << mesh_.faceCentres()[faceI] << endl; + // } + // } + //} + //Pout<< endl << endl; + + + // Transport centred stencil to upwind/downwind face + transportStencils + ( + stencil, + minOpposedness, + ownStencil_, + neiStencil_ + ); + + ownMapPtr_ = calcDistributeMap + ( + stencil.globalNumbering(), + ownStencil_ + ); + + neiMapPtr_ = calcDistributeMap + ( + stencil.globalNumbering(), + neiStencil_ + ); +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedUpwindStencil.H b/src/finiteVolume/fvMesh/extendedStencil/extendedUpwindStencil.H new file mode 100644 index 0000000000000000000000000000000000000000..62976f893da9f95fa39866d5a7b00af7eefc6019 --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedUpwindStencil.H @@ -0,0 +1,177 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::extendedUpwindStencil + +Description + +SourceFiles + extendedUpwindStencil.C + extendedUpwindStencilTemplates.C + +\*---------------------------------------------------------------------------*/ + +#ifndef extendedUpwindStencil_H +#define extendedUpwindStencil_H + +#include "extendedStencil.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +class faceStencil; + +/*---------------------------------------------------------------------------*\ + Class extendedUpwindStencil Declaration +\*---------------------------------------------------------------------------*/ + +class extendedUpwindStencil +: + public extendedStencil +{ + // Private data + + //- Swap map for getting neigbouring data + autoPtr<mapDistribute> ownMapPtr_; + autoPtr<mapDistribute> neiMapPtr_; + + //- Per face the stencil. + labelListList ownStencil_; + labelListList neiStencil_; + + + + // Private Member Functions + + //- Find most 'opposite' faces of cell + void selectOppositeFaces + ( + const boolList& nonEmptyFace, + const scalar minOpposedness, + const label faceI, + const label cellI, + DynamicList<label>& oppositeFaces + ) const; + + //- Transport (centred) face stencil to 'opposite' face. + void transportStencil + ( + const boolList& nonEmptyFace, + const labelListList& faceStencil, + const scalar minOpposedness, + const label faceI, + const label cellI, + const bool stencilHasNeighbour, + + DynamicList<label>& oppositeFaces, + labelHashSet& faceStencilSet, + labelList& transportedStencil + ) const; + + //- Transport (centred) face stencil to 'opposite' faces. + void transportStencils + ( + const labelListList& faceStencil, + const scalar minOpposedness, + labelListList& ownStencil, + labelListList& neiStencil + ); + + + //- Disallow default bitwise copy construct + extendedUpwindStencil(const extendedUpwindStencil&); + + //- Disallow default bitwise assignment + void operator=(const extendedUpwindStencil&); + + +public: + + // Constructors + + //- Construct from mesh and uncompacted face stencil + extendedUpwindStencil + ( + const faceStencil&, + const scalar minOpposedness + ); + + + // Member Functions + + //- Return reference to the parallel distribution map + const mapDistribute& ownMap() const + { + return ownMapPtr_(); + } + + //- Return reference to the parallel distribution map + const mapDistribute& neiMap() const + { + return neiMapPtr_(); + } + + //- Return reference to the stencil + const labelListList& ownStencil() const + { + return ownStencil_; + } + + //- Return reference to the stencil + const labelListList& neiStencil() const + { + return neiStencil_; + } + + //- Sum vol field contributions to create face values + template<class Type> + tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > weightedSum + ( + const surfaceScalarField& phi, + const GeometricField<Type, fvPatchField, volMesh>& fld, + const List<List<scalar> >& ownWeights, + const List<List<scalar> >& neiWeights + ) const; + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "extendedUpwindStencilTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/extendedUpwindStencilTemplates.C b/src/finiteVolume/fvMesh/extendedStencil/extendedUpwindStencilTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..1cfa79eaa55ff6154579a2db7cbc7f200d6ae20d --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/extendedUpwindStencilTemplates.C @@ -0,0 +1,138 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "extendedStencil.H" + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class Type> +Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> > +Foam::extendedUpwindStencil::weightedSum +( + const surfaceScalarField& phi, + const GeometricField<Type, fvPatchField, volMesh>& fld, + const List<List<scalar> >& ownWeights, + const List<List<scalar> >& neiWeights +) const +{ + const fvMesh& mesh = fld.mesh(); + + // Collect internal and boundary values + List<List<Type> > ownFld; + collectData(ownMap(), ownStencil(), fld, ownFld); + List<List<Type> > neiFld; + collectData(neiMap(), neiStencil(), fld, neiFld); + + tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tsfCorr + ( + new GeometricField<Type, fvsPatchField, surfaceMesh> + ( + IOobject + ( + fld.name(), + mesh.time().timeName(), + mesh + ), + mesh, + dimensioned<Type> + ( + fld.name(), + fld.dimensions(), + pTraits<Type>::zero + ) + ) + ); + GeometricField<Type, fvsPatchField, surfaceMesh>& sf = tsfCorr(); + + // Internal faces + for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++) + { + if (phi[faceI] > 0) + { + // Flux out of owner. Use upwind (= owner side) stencil. + const List<Type>& stField = ownFld[faceI]; + const List<scalar>& stWeight = ownWeights[faceI]; + + forAll(stField, i) + { + sf[faceI] += stField[i]*stWeight[i]; + } + } + else + { + const List<Type>& stField = neiFld[faceI]; + const List<scalar>& stWeight = neiWeights[faceI]; + + forAll(stField, i) + { + sf[faceI] += stField[i]*stWeight[i]; + } + } + } + + // Boundaries. Either constrained or calculated so assign value + // directly (instead of nicely using operator==) + typename GeometricField<Type, fvsPatchField, surfaceMesh>:: + GeometricBoundaryField& bSfCorr = sf.boundaryField(); + + forAll(bSfCorr, patchi) + { + fvsPatchField<Type>& pSfCorr = bSfCorr[patchi]; + + label faceI = pSfCorr.patch().patch().start(); + + forAll(pSfCorr, i) + { + if (phi[faceI] > 0) + { + // Flux out of owner. Use upwind (= owner side) stencil. + const List<Type>& stField = ownFld[faceI]; + const List<scalar>& stWeight = ownWeights[faceI]; + + forAll(stField, j) + { + pSfCorr[i] += stField[j]*stWeight[j]; + } + } + else + { + const List<Type>& stField = neiFld[faceI]; + const List<scalar>& stWeight = neiWeights[faceI]; + + forAll(stField, j) + { + pSfCorr[i] += stField[j]*stWeight[j]; + } + } + faceI++; + } + } + + return tsfCorr; +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/faceStencil/cellEdgeCellStencil.C b/src/finiteVolume/fvMesh/extendedStencil/faceStencil/cellEdgeCellStencil.C new file mode 100644 index 0000000000000000000000000000000000000000..a7189c44ed11bc9e278385d7326187cc6686daa9 --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/faceStencil/cellEdgeCellStencil.C @@ -0,0 +1,209 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "cellEdgeCellStencil.H" +#include "syncTools.H" +//#include "meshTools.H" +//#include "OFstream.H" +//#include "Time.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +// Calculates per edge the neighbour data (= edgeCells) +void Foam::cellEdgeCellStencil::calcEdgeBoundaryData +( + const boolList& isValidBFace, + const labelList& boundaryEdges, + EdgeMap<labelList>& neiGlobal +) const +{ + neiGlobal.resize(2*boundaryEdges.size()); + + labelHashSet edgeGlobals; + + forAll(boundaryEdges, i) + { + label edgeI = boundaryEdges[i]; + + neiGlobal.insert + ( + mesh().edges()[edgeI], + calcFaceCells + ( + isValidBFace, + mesh().edgeFaces(edgeI), + edgeGlobals + ) + ); + } + + syncTools::syncEdgeMap + ( + mesh(), + neiGlobal, + unionEqOp(), + false // apply separation + ); +} + + +// Calculates per cell the neighbour data (= cell or boundary in global +// numbering). First element is always cell itself! +void Foam::cellEdgeCellStencil::calcCellStencil +( + labelListList& globalCellCells +) const +{ + // Calculate edges on coupled patches + labelList boundaryEdges + ( + allCoupledFacesPatch()().meshEdges + ( + mesh().edges(), + mesh().pointEdges() + ) + ); + + //{ + // OFstream str(mesh().time().path()/"boundaryEdges.obj"); + // Pout<< "DUmping boundary edges to " << str.name() << endl; + // + // label vertI = 0; + // forAll(boundaryEdges, i) + // { + // label edgeI = boundaryEdges[i]; + // const edge& e = mesh().edges()[edgeI]; + // const point& p0 = mesh().points()[e[0]]; + // const point& p1 = mesh().points()[e[1]]; + // + // Pout<< "boundary edge " << edgeI << " between " << p0 << p1 + // << endl; + // + // meshTools::writeOBJ(str, p0); + // vertI++; + // meshTools::writeOBJ(str, p1); + // vertI++; + // str << "l " << vertI-1 << ' ' << vertI << nl; + // } + //} + + + // Mark boundary faces to be included in stencil (i.e. not coupled or empty) + boolList isValidBFace; + validBoundaryFaces(isValidBFace); + + + // Swap edgeCells for coupled edges. Note: use EdgeMap for now since we've + // got syncTools::syncEdgeMap for those. Should be replaced with Map and + // syncTools functionality to handle those. + EdgeMap<labelList> neiGlobal; + calcEdgeBoundaryData + ( + isValidBFace, + boundaryEdges, + neiGlobal + ); + + globalCellCells.setSize(mesh().nCells()); + + // Do coupled edges first + + forAll(boundaryEdges, i) + { + label edgeI = boundaryEdges[i]; + + const labelList& eGlobals = neiGlobal[mesh().edges()[edgeI]]; + + // Distribute to all edgeCells + const labelList& eCells = mesh().edgeCells(edgeI); + + forAll(eCells, j) + { + label cellI = eCells[j]; + + // Insert pGlobals into globalCellCells + merge + ( + globalNumbering().toGlobal(cellI), + eGlobals, + globalCellCells[cellI] + ); + } + } + neiGlobal.clear(); + + // Do remaining edges cells + labelHashSet edgeGlobals; + + for (label edgeI = 0; edgeI < mesh().nEdges(); edgeI++) + { + labelList eGlobals + ( + calcFaceCells + ( + isValidBFace, + mesh().edgeFaces(edgeI), + edgeGlobals + ) + ); + + const labelList& eCells = mesh().edgeCells(edgeI); + + forAll(eCells, j) + { + label cellI = eCells[j]; + + merge + ( + globalNumbering().toGlobal(cellI), + eGlobals, + globalCellCells[cellI] + ); + } + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::cellEdgeCellStencil::cellEdgeCellStencil(const polyMesh& mesh) +: + faceStencil(mesh) +{ + // Calculate per cell the (edge) connected cells (in global numbering) + labelListList globalCellCells; + calcCellStencil(globalCellCells); + + // Add stencils of neighbouring cells to create faceStencil + labelListList faceStencil; + calcFaceStencil(globalCellCells, faceStencil); + + // Transfer to *this + transfer(faceStencil); +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/faceStencil/cellEdgeCellStencil.H b/src/finiteVolume/fvMesh/extendedStencil/faceStencil/cellEdgeCellStencil.H new file mode 100644 index 0000000000000000000000000000000000000000..4091ffb40f6ab16c9d5a2a2a48624982268f77cd --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/faceStencil/cellEdgeCellStencil.H @@ -0,0 +1,95 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::cellEdgeCellStencil + +Description + +SourceFiles + cellEdgeCellStencil.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cellEdgeCellStencil_H +#define cellEdgeCellStencil_H + +#include "faceStencil.H" +#include "boolList.H" +#include "labelHashSet.H" +#include "Map.H" +#include "EdgeMap.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class cellEdgeCellStencil Declaration +\*---------------------------------------------------------------------------*/ + +class cellEdgeCellStencil +: + public faceStencil +{ + // Private Member Functions + + //- Calculates per edge the neighbour data (= edgeCells) + void calcEdgeBoundaryData + ( + const boolList& isValidBFace, + const labelList& boundaryEdges, + EdgeMap<labelList>& neiGlobal + ) const; + + void calcCellStencil(labelListList& globalCellCells) const; + + + //- Disallow default bitwise copy construct + cellEdgeCellStencil(const cellEdgeCellStencil&); + + //- Disallow default bitwise assignment + void operator=(const cellEdgeCellStencil&); + + +public: + + // Constructors + + //- Construct from all cells and boundary faces + explicit cellEdgeCellStencil(const polyMesh&); + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/faceStencil/cellFaceCellStencil.C b/src/finiteVolume/fvMesh/extendedStencil/faceStencil/cellFaceCellStencil.C new file mode 100644 index 0000000000000000000000000000000000000000..cbcc8f1696dc12bdeb6e5b3bc714bf88ada9f77a --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/faceStencil/cellFaceCellStencil.C @@ -0,0 +1,167 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "cellFaceCellStencil.H" +#include "syncTools.H" +#include "SortableList.H" +#include "emptyPolyPatch.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +// Calculates per face the neighbour data (= cell or boundary face) +void Foam::cellFaceCellStencil::calcFaceBoundaryData +( + labelList& neiGlobal +) const +{ + const polyBoundaryMesh& patches = mesh().boundaryMesh(); + const label nBnd = mesh().nFaces()-mesh().nInternalFaces(); + const labelList& own = mesh().faceOwner(); + + neiGlobal.setSize(nBnd); + + forAll(patches, patchI) + { + const polyPatch& pp = patches[patchI]; + label faceI = pp.start(); + + if (pp.coupled()) + { + // For coupled faces get the cell on the other side + forAll(pp, i) + { + label bFaceI = faceI-mesh().nInternalFaces(); + neiGlobal[bFaceI] = globalNumbering().toGlobal(own[faceI]); + faceI++; + } + } + else if (isA<emptyPolyPatch>(pp)) + { + forAll(pp, i) + { + label bFaceI = faceI-mesh().nInternalFaces(); + neiGlobal[bFaceI] = -1; + faceI++; + } + } + else + { + // For noncoupled faces get the boundary face. + forAll(pp, i) + { + label bFaceI = faceI-mesh().nInternalFaces(); + neiGlobal[bFaceI] = + globalNumbering().toGlobal(mesh().nCells()+bFaceI); + faceI++; + } + } + } + syncTools::swapBoundaryFaceList(mesh(), neiGlobal, false); +} + + +// Calculates per cell the neighbour data (= cell or boundary in global +// numbering). First element is always cell itself! +void Foam::cellFaceCellStencil::calcCellStencil(labelListList& globalCellCells) + const +{ + const label nBnd = mesh().nFaces()-mesh().nInternalFaces(); + const labelList& own = mesh().faceOwner(); + const labelList& nei = mesh().faceNeighbour(); + + + // Calculate coupled neighbour (in global numbering) + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + labelList neiGlobal(nBnd); + calcFaceBoundaryData(neiGlobal); + + + // Determine cellCells in global numbering + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + globalCellCells.setSize(mesh().nCells()); + forAll(globalCellCells, cellI) + { + const cell& cFaces = mesh().cells()[cellI]; + + labelList& cCells = globalCellCells[cellI]; + + cCells.setSize(cFaces.size()+1); + + label nNbr = 0; + + // Myself + cCells[nNbr++] = globalNumbering().toGlobal(cellI); + + // Collect neighbouring cells/faces + forAll(cFaces, i) + { + label faceI = cFaces[i]; + + if (mesh().isInternalFace(faceI)) + { + label nbrCellI = own[faceI]; + if (nbrCellI == cellI) + { + nbrCellI = nei[faceI]; + } + cCells[nNbr++] = globalNumbering().toGlobal(nbrCellI); + } + else + { + label nbrCellI = neiGlobal[faceI-mesh().nInternalFaces()]; + if (nbrCellI != -1) + { + cCells[nNbr++] = nbrCellI; + } + } + } + cCells.setSize(nNbr); + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::cellFaceCellStencil::cellFaceCellStencil(const polyMesh& mesh) +: + faceStencil(mesh) +{ + // Calculate per cell the (face) connected cells (in global numbering) + labelListList globalCellCells; + calcCellStencil(globalCellCells); + + // Add stencils of neighbouring cells to create faceStencil + labelListList faceStencil; + calcFaceStencil(globalCellCells, faceStencil); + + // Transfer to *this + transfer(faceStencil); +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/faceStencil/cellFaceCellStencil.H b/src/finiteVolume/fvMesh/extendedStencil/faceStencil/cellFaceCellStencil.H new file mode 100644 index 0000000000000000000000000000000000000000..93e9d9117aba8dd73803079c0683c05751290d1f --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/faceStencil/cellFaceCellStencil.H @@ -0,0 +1,83 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::cellFaceCellStencil + +Description + +SourceFiles + cellFaceCellStencil.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cellFaceCellStencil_H +#define cellFaceCellStencil_H + +#include "faceStencil.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class cellFaceCellStencil Declaration +\*---------------------------------------------------------------------------*/ + +class cellFaceCellStencil +: + public faceStencil +{ + // Private Member Functions + + void calcFaceBoundaryData(labelList& neiGlobal) const; + + void calcCellStencil(labelListList& globalCellCells) const; + + //- Disallow default bitwise copy construct + cellFaceCellStencil(const cellFaceCellStencil&); + + //- Disallow default bitwise assignment + void operator=(const cellFaceCellStencil&); + +public: + + // Constructors + + //- Construct from mesh + explicit cellFaceCellStencil(const polyMesh& mesh); + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/faceStencil/cellPointCellStencil.C b/src/finiteVolume/fvMesh/extendedStencil/faceStencil/cellPointCellStencil.C new file mode 100644 index 0000000000000000000000000000000000000000..d284c2634104cfa1e4fcfc69edaedbd6c625910e --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/faceStencil/cellPointCellStencil.C @@ -0,0 +1,174 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "cellPointCellStencil.H" +#include "syncTools.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +// Calculates per point the neighbour data (= pointCells) +void Foam::cellPointCellStencil::calcPointBoundaryData +( + const boolList& isValidBFace, + const labelList& boundaryPoints, + Map<labelList>& neiGlobal +) const +{ + neiGlobal.resize(2*boundaryPoints.size()); + + labelHashSet pointGlobals; + + forAll(boundaryPoints, i) + { + label pointI = boundaryPoints[i]; + + neiGlobal.insert + ( + pointI, + calcFaceCells + ( + isValidBFace, + mesh().pointFaces()[pointI], + pointGlobals + ) + ); + } + + syncTools::syncPointMap + ( + mesh(), + neiGlobal, + unionEqOp(), + false // apply separation + ); +} + + +// Calculates per cell the neighbour data (= cell or boundary in global +// numbering). First element is always cell itself! +void Foam::cellPointCellStencil::calcCellStencil +( + labelListList& globalCellCells +) const +{ + // Calculate points on coupled patches + labelList boundaryPoints(allCoupledFacesPatch()().meshPoints()); + + + // Mark boundary faces to be included in stencil (i.e. not coupled or empty) + boolList isValidBFace; + validBoundaryFaces(isValidBFace); + + + // Swap pointCells for coupled points + Map<labelList> neiGlobal; + calcPointBoundaryData + ( + isValidBFace, + boundaryPoints, + neiGlobal + ); + + globalCellCells.setSize(mesh().nCells()); + + // Do coupled points first + + forAll(boundaryPoints, i) + { + label pointI = boundaryPoints[i]; + + const labelList& pGlobals = neiGlobal[pointI]; + + // Distribute to all pointCells + const labelList& pCells = mesh().pointCells(pointI); + + forAll(pCells, j) + { + label cellI = pCells[j]; + + // Insert pGlobals into globalCellCells + merge + ( + globalNumbering().toGlobal(cellI), + pGlobals, + globalCellCells[cellI] + ); + } + } + neiGlobal.clear(); + + // Do remaining points cells + labelHashSet pointGlobals; + + for (label pointI = 0; pointI < mesh().nPoints(); pointI++) + { + labelList pGlobals + ( + calcFaceCells + ( + isValidBFace, + mesh().pointFaces()[pointI], + pointGlobals + ) + ); + + const labelList& pCells = mesh().pointCells(pointI); + + forAll(pCells, j) + { + label cellI = pCells[j]; + + merge + ( + globalNumbering().toGlobal(cellI), + pGlobals, + globalCellCells[cellI] + ); + } + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::cellPointCellStencil::cellPointCellStencil(const polyMesh& mesh) +: + faceStencil(mesh) +{ + // Calculate per cell the (point) connected cells (in global numbering) + labelListList globalCellCells; + calcCellStencil(globalCellCells); + + // Add stencils of neighbouring cells to create faceStencil + labelListList faceStencil; + calcFaceStencil(globalCellCells, faceStencil); + + // Transfer to *this + transfer(faceStencil); +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/faceStencil/cellPointCellStencil.H b/src/finiteVolume/fvMesh/extendedStencil/faceStencil/cellPointCellStencil.H new file mode 100644 index 0000000000000000000000000000000000000000..301a430899847a0843c28dadf4b0b923e591a501 --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/faceStencil/cellPointCellStencil.H @@ -0,0 +1,94 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::cellPointCellStencil + +Description + +SourceFiles + cellPointCellStencil.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cellPointCellStencil_H +#define cellPointCellStencil_H + +#include "faceStencil.H" +#include "boolList.H" +#include "labelHashSet.H" +#include "Map.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class cellPointCellStencil Declaration +\*---------------------------------------------------------------------------*/ + +class cellPointCellStencil +: + public faceStencil +{ + // Private Member Functions + + //- Calculates per point the neighbour data (= pointCells) + void calcPointBoundaryData + ( + const boolList& isValidBFace, + const labelList& boundaryPoints, + Map<labelList>& neiGlobal + ) const; + + void calcCellStencil(labelListList& globalCellCells) const; + + + //- Disallow default bitwise copy construct + cellPointCellStencil(const cellPointCellStencil&); + + //- Disallow default bitwise assignment + void operator=(const cellPointCellStencil&); + + +public: + + // Constructors + + //- Construct from all cells and boundary faces + explicit cellPointCellStencil(const polyMesh&); + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/faceStencil/faceEdgeCellStencil.C b/src/finiteVolume/fvMesh/extendedStencil/faceStencil/faceEdgeCellStencil.C new file mode 100644 index 0000000000000000000000000000000000000000..ac78ba76a41409f0e7bcc9bca06271e963eefcb3 --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/faceStencil/faceEdgeCellStencil.C @@ -0,0 +1,445 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "faceEdgeCellStencil.H" +#include "syncTools.H" +#include "emptyPolyPatch.H" +//#include "meshTools.H" +//#include "OFstream.H" +//#include "Time.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +// Calculates per edge the neighbour data (= edgeCells) +void Foam::faceEdgeCellStencil::calcEdgeBoundaryData +( + const boolList& isValidBFace, + const labelList& boundaryEdges, + EdgeMap<labelList>& neiGlobal +) const +{ + neiGlobal.resize(2*boundaryEdges.size()); + + labelHashSet edgeGlobals; + + forAll(boundaryEdges, i) + { + label edgeI = boundaryEdges[i]; + + neiGlobal.insert + ( + mesh().edges()[edgeI], + calcFaceCells + ( + isValidBFace, + mesh().edgeFaces(edgeI), + edgeGlobals + ) + ); + } + + syncTools::syncEdgeMap + ( + mesh(), + neiGlobal, + unionEqOp(), + false // apply separation + ); +} + + +// Calculates per face the edge connected data (= cell or boundary in global +// numbering). +void Foam::faceEdgeCellStencil::calcFaceStencil +( + labelListList& faceStencil +) const +{ + const polyBoundaryMesh& patches = mesh().boundaryMesh(); + const label nBnd = mesh().nFaces()-mesh().nInternalFaces(); + const labelList& own = mesh().faceOwner(); + const labelList& nei = mesh().faceNeighbour(); + + + + // Determine neighbouring global cell + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + labelList neiGlobalCell(nBnd); + forAll(patches, patchI) + { + const polyPatch& pp = patches[patchI]; + + if (pp.coupled()) + { + label faceI = pp.start(); + + forAll(pp, i) + { + neiGlobalCell[faceI-mesh().nInternalFaces()] = + globalNumbering().toGlobal(own[faceI]); + faceI++; + } + } + } + syncTools::swapBoundaryFaceList(mesh(), neiGlobalCell, false); + + + + // Determine on coupled edges the edge cells on the other side + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + // Calculate edges on coupled patches + labelList boundaryEdges + ( + allCoupledFacesPatch()().meshEdges + ( + mesh().edges(), + mesh().pointEdges() + ) + ); + + // Mark boundary faces to be included in stencil (i.e. not coupled or empty) + boolList isValidBFace; + validBoundaryFaces(isValidBFace); + + // Swap edgeCells for coupled edges. Note: use EdgeMap for now since we've + // got syncTools::syncEdgeMap for those. Should be replaced with Map and + // syncTools functionality to handle those. + EdgeMap<labelList> neiGlobal; + calcEdgeBoundaryData + ( + isValidBFace, + boundaryEdges, + neiGlobal + ); + + + + // Construct stencil in global numbering + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + faceStencil.setSize(mesh().nFaces()); + + // Do coupled edges first + + forAll(boundaryEdges, i) + { + label edgeI = boundaryEdges[i]; + + const labelList& eGlobals = neiGlobal[mesh().edges()[edgeI]]; + + // Distribute to all edgeFaces + const labelList& eFaces = mesh().edgeFaces(edgeI); + + forAll(eFaces, j) + { + label faceI = eFaces[j]; + + // Insert eGlobals into faceStencil. + merge(-1, -1, eGlobals, faceStencil[faceI]); + } + } + neiGlobal.clear(); + + + // Do remaining edges by looping over all faces + + // Work arrays + DynamicList<label> fEdgesSet; + DynamicList<label> eFacesSet; + labelHashSet faceStencilSet; + + for (label faceI = 0; faceI < mesh().nInternalFaces(); faceI++) + { + label globalOwn = globalNumbering().toGlobal(own[faceI]); + label globalNei = globalNumbering().toGlobal(nei[faceI]); + + // Convert any existing faceStencil (from coupled edges) into + // set and operate on this. + + faceStencilSet.clear(); + + // Insert all but global owner and neighbour + forAll(faceStencil[faceI], i) + { + label globalI = faceStencil[faceI][i]; + if (globalI != globalOwn && globalI != globalNei) + { + faceStencilSet.insert(globalI); + } + } + faceStencil[faceI].clear(); + + // Collect all edge connected (internal) cells + const labelList& fEdges = mesh().faceEdges(faceI, fEdgesSet); + + forAll(fEdges, i) + { + label edgeI = fEdges[i]; + + insertFaceCells + ( + globalOwn, + globalNei, + isValidBFace, + mesh().edgeFaces(edgeI, eFacesSet), + faceStencilSet + ); + } + + // Extract, guarantee owner first, neighbour second. + faceStencil[faceI].setSize(faceStencilSet.size()+2); + label n = 0; + faceStencil[faceI][n++] = globalOwn; + faceStencil[faceI][n++] = globalNei; + forAllConstIter(labelHashSet, faceStencilSet, iter) + { + if (iter.key() == globalOwn || iter.key() == globalNei) + { + FatalErrorIn("faceEdgeCellStencil::calcFaceStencil(..)") + << "problem:" << faceStencilSet + << abort(FatalError); + } + faceStencil[faceI][n++] = iter.key(); + } + } + forAll(patches, patchI) + { + const polyPatch& pp = patches[patchI]; + label faceI = pp.start(); + + if (pp.coupled()) + { + forAll(pp, i) + { + label globalOwn = globalNumbering().toGlobal(own[faceI]); + label globalNei = neiGlobalCell[faceI-mesh().nInternalFaces()]; + + // Convert any existing faceStencil (from coupled edges) into + // set and operate on this. + + faceStencilSet.clear(); + + // Insert all but global owner and neighbour + forAll(faceStencil[faceI], i) + { + label globalI = faceStencil[faceI][i]; + if (globalI != globalOwn && globalI != globalNei) + { + faceStencilSet.insert(globalI); + } + } + faceStencil[faceI].clear(); + + // Collect all edge connected (internal) cells + const labelList& fEdges = mesh().faceEdges(faceI, fEdgesSet); + + forAll(fEdges, i) + { + label edgeI = fEdges[i]; + + insertFaceCells + ( + globalOwn, + globalNei, + isValidBFace, + mesh().edgeFaces(edgeI, eFacesSet), + faceStencilSet + ); + } + + // Extract, guarantee owner first, neighbour second. + faceStencil[faceI].setSize(faceStencilSet.size()+2); + label n = 0; + faceStencil[faceI][n++] = globalOwn; + faceStencil[faceI][n++] = globalNei; + forAllConstIter(labelHashSet, faceStencilSet, iter) + { + if (iter.key() == globalOwn || iter.key() == globalNei) + { + FatalErrorIn("faceEdgeCellStencil::calcFaceStencil(..)") + << "problem:" << faceStencilSet + << abort(FatalError); + } + faceStencil[faceI][n++] = iter.key(); + } + + if (n != faceStencil[faceI].size()) + { + FatalErrorIn("problem") << "n:" << n + << " size:" << faceStencil[faceI].size() + << abort(FatalError); + } + + faceI++; + } + } + else if (!isA<emptyPolyPatch>(pp)) + { + forAll(pp, i) + { + label globalOwn = globalNumbering().toGlobal(own[faceI]); + + // Convert any existing faceStencil (from coupled edges) into + // set and operate on this. + + faceStencilSet.clear(); + + // Insert all but global owner and neighbour + forAll(faceStencil[faceI], i) + { + label globalI = faceStencil[faceI][i]; + if (globalI != globalOwn) + { + faceStencilSet.insert(globalI); + } + } + faceStencil[faceI].clear(); + + // Collect all edge connected (internal) cells + const labelList& fEdges = mesh().faceEdges(faceI, fEdgesSet); + + forAll(fEdges, i) + { + label edgeI = fEdges[i]; + + insertFaceCells + ( + globalOwn, + -1, + isValidBFace, + mesh().edgeFaces(edgeI, eFacesSet), + faceStencilSet + ); + } + + // Extract, guarantee owner first, neighbour second. + faceStencil[faceI].setSize(faceStencilSet.size()+1); + label n = 0; + faceStencil[faceI][n++] = globalOwn; + forAllConstIter(labelHashSet, faceStencilSet, iter) + { + if (iter.key() == globalOwn) + { + FatalErrorIn("faceEdgeCellStencil::calcFaceStencil(..)") + << "problem:" << faceStencilSet + << abort(FatalError); + } + faceStencil[faceI][n++] = iter.key(); + } + + faceI++; + } + } + } + + + for (label faceI = 0; faceI < mesh().nInternalFaces(); faceI++) + { + label globalOwn = globalNumbering().toGlobal(own[faceI]); + if (faceStencil[faceI][0] != globalOwn) + { + FatalErrorIn("faceEdgeCellStencil::calcFaceStencil(..)") + << "problem:" << faceStencil[faceI] + << " globalOwn:" << globalOwn + << abort(FatalError); + } + label globalNei = globalNumbering().toGlobal(nei[faceI]); + if (faceStencil[faceI][1] != globalNei) + { + FatalErrorIn("faceEdgeCellStencil::calcFaceStencil(..)") + << "problem:" << faceStencil[faceI] + << " globalNei:" << globalNei + << abort(FatalError); + } + } + + + forAll(patches, patchI) + { + const polyPatch& pp = patches[patchI]; + + if (pp.coupled()) + { + forAll(pp, i) + { + label faceI = pp.start()+i; + + label globalOwn = globalNumbering().toGlobal(own[faceI]); + if (faceStencil[faceI][0] != globalOwn) + { + FatalErrorIn("faceEdgeCellStencil::calcFaceStencil(..)") + << "problem:" << faceStencil[faceI] + << " globalOwn:" << globalOwn + << abort(FatalError); + } + label globalNei = neiGlobalCell[faceI-mesh().nInternalFaces()]; + if (faceStencil[faceI][1] != globalNei) + { + FatalErrorIn("faceEdgeCellStencil::calcFaceStencil(..)") + << "problem:" << faceStencil[faceI] + << " globalNei:" << globalNei + << abort(FatalError); + } + } + } + else if (!isA<emptyPolyPatch>(pp)) + { + forAll(pp, i) + { + label faceI = pp.start()+i; + + label globalOwn = globalNumbering().toGlobal(own[faceI]); + if (faceStencil[faceI][0] != globalOwn) + { + FatalErrorIn("faceEdgeCellStencil::calcFaceStencil(..)") + << "problem:" << faceStencil[faceI] + << " globalOwn:" << globalOwn + << abort(FatalError); + } + } + } + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::faceEdgeCellStencil::faceEdgeCellStencil(const polyMesh& mesh) +: + faceStencil(mesh) +{ + // Calculate per face the (edge) connected cells (in global numbering) + labelListList faceStencil; + calcFaceStencil(faceStencil); + + // Transfer to *this + transfer(faceStencil); +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/faceStencil/faceEdgeCellStencil.H b/src/finiteVolume/fvMesh/extendedStencil/faceStencil/faceEdgeCellStencil.H new file mode 100644 index 0000000000000000000000000000000000000000..be5ab855a041ad41a9a19d9b2d4d6824635f073f --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/faceStencil/faceEdgeCellStencil.H @@ -0,0 +1,96 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::faceEdgeCellStencil + +Description + All cells connected via edge to face. + +SourceFiles + faceEdgeCellStencil.C + +\*---------------------------------------------------------------------------*/ + +#ifndef faceEdgeCellStencil_H +#define faceEdgeCellStencil_H + +#include "faceStencil.H" +#include "boolList.H" +#include "labelHashSet.H" +#include "Map.H" +#include "EdgeMap.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class faceEdgeCellStencil Declaration +\*---------------------------------------------------------------------------*/ + +class faceEdgeCellStencil +: + public faceStencil +{ + // Private Member Functions + + //- Calculates per edge the neighbour data (= edgeCells) + void calcEdgeBoundaryData + ( + const boolList& isValidBFace, + const labelList& boundaryEdges, + EdgeMap<labelList>& neiGlobal + ) const; + + void calcFaceStencil(labelListList& faceStencil) const; + + + //- Disallow default bitwise copy construct + faceEdgeCellStencil(const faceEdgeCellStencil&); + + //- Disallow default bitwise assignment + void operator=(const faceEdgeCellStencil&); + + +public: + + // Constructors + + //- Construct from all cells and boundary faces + explicit faceEdgeCellStencil(const polyMesh&); + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/faceStencil/faceStencil.C b/src/finiteVolume/fvMesh/extendedStencil/faceStencil/faceStencil.C new file mode 100644 index 0000000000000000000000000000000000000000..b3d72c3b5a1d258a49d74cef6f995c05ef6440ec --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/faceStencil/faceStencil.C @@ -0,0 +1,512 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "faceStencil.H" +#include "syncTools.H" +#include "SortableList.H" +#include "emptyPolyPatch.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +// Merge two list and guarantee global0,global1 are first. +void Foam::faceStencil::merge +( + const label global0, + const label global1, + const labelList& listA, + labelList& listB +) +{ + sort(listB); + + // See if global0, global1 already present in listB + label nGlobalInsert = 0; + + if (global0 != -1) + { + label index0 = findSortedIndex(listB, global0); + if (index0 == -1) + { + nGlobalInsert++; + } + } + + if (global1 != -1) + { + label index1 = findSortedIndex(listB, global1); + if (index1 == -1) + { + nGlobalInsert++; + } + } + + + // For all in listA see if they are present + label nInsert = 0; + + forAll(listA, i) + { + label elem = listA[i]; + + if (elem != global0 && elem != global1) + { + if (findSortedIndex(listB, elem) == -1) + { + nInsert++; + } + } + } + + // Extend B with nInsert and whether global0,global1 need to be inserted. + labelList result(listB.size() + nGlobalInsert + nInsert); + + label resultI = 0; + + // Insert global0,1 first + if (global0 != -1) + { + result[resultI++] = global0; + } + if (global1 != -1) + { + result[resultI++] = global1; + } + + + // Insert listB + forAll(listB, i) + { + label elem = listB[i]; + + if (elem != global0 && elem != global1) + { + result[resultI++] = elem; + } + } + + + // Insert listA + forAll(listA, i) + { + label elem = listA[i]; + + if (elem != global0 && elem != global1) + { + if (findSortedIndex(listB, elem) == -1) + { + result[resultI++] = elem; + } + } + } + + if (resultI != result.size()) + { + FatalErrorIn("faceStencil::merge(..)") + << "problem" << abort(FatalError); + } + + listB.transfer(result); +} + + +// Merge two list and guarantee globalI is first. +void Foam::faceStencil::merge +( + const label globalI, + const labelList& pGlobals, + labelList& cCells +) +{ + labelHashSet set; + forAll(cCells, i) + { + if (cCells[i] != globalI) + { + set.insert(cCells[i]); + } + } + + forAll(pGlobals, i) + { + if (pGlobals[i] != globalI) + { + set.insert(pGlobals[i]); + } + } + + cCells.setSize(set.size()+1); + label n = 0; + cCells[n++] = globalI; + + forAllConstIter(labelHashSet, set, iter) + { + cCells[n++] = iter.key(); + } +} + + +void Foam::faceStencil::validBoundaryFaces(boolList& isValidBFace) const +{ + const polyBoundaryMesh& patches = mesh().boundaryMesh(); + + isValidBFace.setSize(mesh().nFaces()-mesh().nInternalFaces(), true); + + forAll(patches, patchI) + { + const polyPatch& pp = patches[patchI]; + + if (pp.coupled() || isA<emptyPolyPatch>(pp)) + { + label bFaceI = pp.start()-mesh().nInternalFaces(); + forAll(pp, i) + { + isValidBFace[bFaceI++] = false; + } + } + } +} + + +Foam::autoPtr<Foam::indirectPrimitivePatch> +Foam::faceStencil::allCoupledFacesPatch() const +{ + const polyBoundaryMesh& patches = mesh().boundaryMesh(); + + label nCoupled = 0; + + forAll(patches, patchI) + { + const polyPatch& pp = patches[patchI]; + + if (pp.coupled()) + { + nCoupled += pp.size(); + } + } + labelList coupledFaces(nCoupled); + nCoupled = 0; + + forAll(patches, patchI) + { + const polyPatch& pp = patches[patchI]; + + if (pp.coupled()) + { + label faceI = pp.start(); + + forAll(pp, i) + { + coupledFaces[nCoupled++] = faceI++; + } + } + } + + return autoPtr<indirectPrimitivePatch> + ( + new indirectPrimitivePatch + ( + IndirectList<face> + ( + mesh().faces(), + coupledFaces + ), + mesh().points() + ) + ); +} + + +void Foam::faceStencil::unionEqOp::operator() +( + labelList& x, + const labelList& y +) const +{ + if (y.size() > 0) + { + if (x.size() == 0) + { + x = y; + } + else + { + labelHashSet set(x); + forAll(y, i) + { + set.insert(y[i]); + } + x = set.toc(); + } + } +} + + +void Foam::faceStencil::insertFaceCells +( + const label exclude0, + const label exclude1, + const boolList& isValidBFace, + const labelList& faceLabels, + labelHashSet& globals +) const +{ + const labelList& own = mesh().faceOwner(); + const labelList& nei = mesh().faceNeighbour(); + + forAll(faceLabels, i) + { + label faceI = faceLabels[i]; + + label globalOwn = globalNumbering().toGlobal(own[faceI]); + if (globalOwn != exclude0 && globalOwn != exclude1) + { + globals.insert(globalOwn); + } + + if (mesh().isInternalFace(faceI)) + { + label globalNei = globalNumbering().toGlobal(nei[faceI]); + if (globalNei != exclude0 && globalNei != exclude1) + { + globals.insert(globalNei); + } + } + else + { + label bFaceI = faceI-mesh().nInternalFaces(); + + if (isValidBFace[bFaceI]) + { + label globalI = globalNumbering().toGlobal + ( + mesh().nCells() + + bFaceI + ); + + if (globalI != exclude0 && globalI != exclude1) + { + globals.insert(globalI); + } + } + } + } +} + + +Foam::labelList Foam::faceStencil::calcFaceCells +( + const boolList& isValidBFace, + const labelList& faceLabels, + labelHashSet& globals +) const +{ + globals.clear(); + + insertFaceCells + ( + -1, + -1, + isValidBFace, + faceLabels, + globals + ); + + return globals.toc(); +} + + +// Calculates per face a list of global cell/face indices. +void Foam::faceStencil::calcFaceStencil +( + const labelListList& globalCellCells, + labelListList& faceStencil +) const +{ + const polyBoundaryMesh& patches = mesh_.boundaryMesh(); + const label nBnd = mesh_.nFaces()-mesh_.nInternalFaces(); + const labelList& own = mesh_.faceOwner(); + const labelList& nei = mesh_.faceNeighbour(); + + + // Determine neighbouring global cell Cells + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + labelListList neiGlobalCellCells(nBnd); + forAll(patches, patchI) + { + const polyPatch& pp = patches[patchI]; + + if (pp.coupled()) + { + label faceI = pp.start(); + + forAll(pp, i) + { + neiGlobalCellCells[faceI-mesh_.nInternalFaces()] = + globalCellCells[own[faceI]]; + faceI++; + } + } + } + syncTools::swapBoundaryFaceList(mesh_, neiGlobalCellCells, false); + + + + // Construct stencil in global numbering + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + faceStencil.setSize(mesh_.nFaces()); + + labelHashSet faceStencilSet; + + for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++) + { + faceStencilSet.clear(); + + const labelList& ownCCells = globalCellCells[own[faceI]]; + label globalOwn = ownCCells[0]; + // Insert cellCells + forAll(ownCCells, i) + { + faceStencilSet.insert(ownCCells[i]); + } + + const labelList& neiCCells = globalCellCells[nei[faceI]]; + label globalNei = neiCCells[0]; + // Insert cellCells + forAll(neiCCells, i) + { + faceStencilSet.insert(neiCCells[i]); + } + + // Guarantee owner first, neighbour second. + faceStencil[faceI].setSize(faceStencilSet.size()); + label n = 0; + faceStencil[faceI][n++] = globalOwn; + faceStencil[faceI][n++] = globalNei; + forAllConstIter(labelHashSet, faceStencilSet, iter) + { + if (iter.key() != globalOwn && iter.key() != globalNei) + { + faceStencil[faceI][n++] = iter.key(); + } + } + //Pout<< "internalface:" << faceI << " toc:" << faceStencilSet.toc() + // << " faceStencil:" << faceStencil[faceI] << endl; + } + forAll(patches, patchI) + { + const polyPatch& pp = patches[patchI]; + label faceI = pp.start(); + + if (pp.coupled()) + { + forAll(pp, i) + { + faceStencilSet.clear(); + + const labelList& ownCCells = globalCellCells[own[faceI]]; + label globalOwn = ownCCells[0]; + forAll(ownCCells, i) + { + faceStencilSet.insert(ownCCells[i]); + } + + // And the neighbours of the coupled cell + const labelList& neiCCells = + neiGlobalCellCells[faceI-mesh_.nInternalFaces()]; + label globalNei = neiCCells[0]; + forAll(neiCCells, i) + { + faceStencilSet.insert(neiCCells[i]); + } + + // Guarantee owner first, neighbour second. + faceStencil[faceI].setSize(faceStencilSet.size()); + label n = 0; + faceStencil[faceI][n++] = globalOwn; + faceStencil[faceI][n++] = globalNei; + forAllConstIter(labelHashSet, faceStencilSet, iter) + { + if (iter.key() != globalOwn && iter.key() != globalNei) + { + faceStencil[faceI][n++] = iter.key(); + } + } + + //Pout<< "coupledface:" << faceI + // << " toc:" << faceStencilSet.toc() + // << " faceStencil:" << faceStencil[faceI] << endl; + + faceI++; + } + } + else if (!isA<emptyPolyPatch>(pp)) + { + forAll(pp, i) + { + faceStencilSet.clear(); + + const labelList& ownCCells = globalCellCells[own[faceI]]; + label globalOwn = ownCCells[0]; + forAll(ownCCells, i) + { + faceStencilSet.insert(ownCCells[i]); + } + + // Guarantee owner first + faceStencil[faceI].setSize(faceStencilSet.size()); + label n = 0; + faceStencil[faceI][n++] = globalOwn; + forAllConstIter(labelHashSet, faceStencilSet, iter) + { + if (iter.key() != globalOwn) + { + faceStencil[faceI][n++] = iter.key(); + } + } + + //Pout<< "boundaryface:" << faceI + // << " toc:" << faceStencilSet.toc() + // << " faceStencil:" << faceStencil[faceI] << endl; + + faceI++; + } + } + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::faceStencil::faceStencil(const polyMesh& mesh) +: + mesh_(mesh), + globalNumbering_(mesh_.nCells()+mesh_.nFaces()-mesh_.nInternalFaces()) +{} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/extendedStencil/faceStencil/faceStencil.H b/src/finiteVolume/fvMesh/extendedStencil/faceStencil/faceStencil.H new file mode 100644 index 0000000000000000000000000000000000000000..058d1e61ce56cec2ef8e159e1804d6b5dbd8583b --- /dev/null +++ b/src/finiteVolume/fvMesh/extendedStencil/faceStencil/faceStencil.H @@ -0,0 +1,160 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + Foam::faceStencil + +Description + baseclass for extended face-cell addressing. + +SourceFiles + faceStencil.C + +\*---------------------------------------------------------------------------*/ + +#ifndef faceStencil_H +#define faceStencil_H + +#include "globalIndex.H" +#include "boolList.H" +#include "labelHashSet.H" +#include "indirectPrimitivePatch.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +class polyMesh; + +/*---------------------------------------------------------------------------*\ + Class faceStencil Declaration +\*---------------------------------------------------------------------------*/ + +class faceStencil +: + public labelListList +{ + // Private data + + const polyMesh& mesh_; + + //- Global numbering for cells and boundary faces + const globalIndex globalNumbering_; + + + // Private Member Functions + + //- Disallow default bitwise assignment + void operator=(const faceStencil&); + + + +protected: + + //- Merge two lists. + static void merge + ( + const label, + const label, + const labelList&, + labelList& + ); + + //- Merge two lists. + static void merge(const label, const labelList&, labelList&); + + //- Valid boundary faces (not empty and not coupled) + void validBoundaryFaces(boolList& isValidBFace) const; + + //- Return patch of all coupled faces. + autoPtr<indirectPrimitivePatch> allCoupledFacesPatch() const; + + //- Combine operator for labelLists + class unionEqOp + { + public: + void operator()( labelList& x, const labelList& y ) const; + }; + + //- Collect cell neighbours of faces in global numbering + void insertFaceCells + ( + const label exclude0, + const label exclude1, + const boolList& nonEmptyFace, + const labelList& faceLabels, + labelHashSet& globals + ) const; + + //- Collect cell neighbours of faces in global numbering + labelList calcFaceCells + ( + const boolList& nonEmptyFace, + const labelList& faceLabels, + labelHashSet& globals + ) const; + + + //- Collect cell neighbours into extended stencil + void calcFaceStencil + ( + const labelListList& globalCellCells, + labelListList& faceStencil + ) const; + + +public: + + // Constructors + + //- Construct from mesh + explicit faceStencil(const polyMesh&); + + + // Member Functions + + const polyMesh& mesh() const + { + return mesh_; + } + + //- Global numbering for cells and boundary faces + const globalIndex& globalNumbering() const + { + return globalNumbering_; + } + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/linearFit/linearFit.C b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/linearFit/linearFit.C new file mode 100644 index 0000000000000000000000000000000000000000..a7dead621f9dfa472a2ad370487a990511a72e2c --- /dev/null +++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/linearFit/linearFit.C @@ -0,0 +1,36 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "linearFit.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + makeSurfaceInterpolationScheme(linearFit); +} + +// ************************************************************************* // diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/linearFit/linearFit.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/linearFit/linearFit.H new file mode 100644 index 0000000000000000000000000000000000000000..882f3e94bcc2dc046c226062820b1144a1a4e5ff --- /dev/null +++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/linearFit/linearFit.H @@ -0,0 +1,138 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + linearFit + +Description + Linear fit interpolation scheme which applies an explicit correction to + linear. + +SourceFiles + linearFit.C + +\*---------------------------------------------------------------------------*/ + +#ifndef linearFit_H +#define linearFit_H + +#include "linear.H" +#include "linearFitData.H" +#include "extendedStencil.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class linearFit Declaration +\*---------------------------------------------------------------------------*/ + +template<class Type> +class linearFit +: + public linear<Type> +{ + // Private Data + const scalar centralWeight_; + + // Private Member Functions + + //- Disallow default bitwise copy construct + linearFit(const linearFit&); + + //- Disallow default bitwise assignment + void operator=(const linearFit&); + + +public: + + //- Runtime type information + TypeName("linearFit"); + + + // Constructors + + //- Construct from mesh and Istream + linearFit(const fvMesh& mesh, Istream& is) + : + linear<Type>(mesh), + centralWeight_(readScalar(is)) + {} + + + //- Construct from mesh, faceFlux and Istream + linearFit + ( + const fvMesh& mesh, + const surfaceScalarField& faceFlux, + Istream& is + ) + : + linear<Type>(mesh), + centralWeight_(readScalar(is)) + {} + + + // Member Functions + + //- Return true if this scheme uses an explicit correction + virtual bool corrected() const + { + return true; + } + + //- Return the explicit correction to the face-interpolate + virtual tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > + correction + ( + const GeometricField<Type, fvPatchField, volMesh>& vf + ) const + { + const fvMesh& mesh = this->mesh(); + + const linearFitData& cfd = linearFitData::New + ( + mesh, + centralWeight_ + ); + + const extendedStencil& stencil = cfd.stencil(); + const List<scalarList>& f = cfd.fit(); + + return stencil.weightedSum(vf, f); + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/linearFit/linearFitData.C b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/linearFit/linearFitData.C new file mode 100644 index 0000000000000000000000000000000000000000..996d915e1cc56aad3734772bbf7be4e5667f0e90 --- /dev/null +++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/linearFit/linearFitData.C @@ -0,0 +1,371 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "linearFitData.H" +#include "surfaceFields.H" +#include "volFields.H" +#include "SVD.H" +#include "syncTools.H" + + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(linearFitData, 0); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +static int count = 0; + +Foam::linearFitData::linearFitData +( + const fvMesh& mesh, + const scalar cWeight +) +: + MeshObject<fvMesh, linearFitData>(mesh), + centralWeight_(cWeight), +# ifdef SPHERICAL_GEOMETRY + dim_(2), +# else + dim_(mesh.nGeometricD()), +# endif + minSize_ + ( + dim_ == 1 ? 2 : + dim_ == 2 ? 3 : + dim_ == 3 ? 4 : 0 + ), + stencil_(mesh), + fit_(mesh.nInternalFaces()) +{ + if (debug) + { + Info << "Contructing linearFitData" << endl; + } + + // check input + if (centralWeight_ < 1 - SMALL) + { + FatalErrorIn("linearFitData::linearFitData") + << "centralWeight requested = " << centralWeight_ + << " should not be less than one" + << exit(FatalError); + } + + if (minSize_ == 0) + { + FatalErrorIn("linearFitSnGradData") + << " dimension must be 1,2 or 3, not" << dim_ << exit(FatalError); + } + + // store the polynomial size for each cell to write out + surfaceScalarField interpPolySize + ( + IOobject + ( + "linearFitInterpPolySize", + "constant", + mesh, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + mesh, + dimensionedScalar("linearFitInterpPolySize", dimless, scalar(0)) + ); + + // Get the cell/face centres in stencil order. + // Centred face stencils no good for triangles of tets. Need bigger stencils + List<List<point> > stencilPoints(stencil_.stencil().size()); + stencil_.collectData + ( + mesh.C(), + stencilPoints + ); + + // find the fit coefficients for every face in the mesh + + for(label faci = 0; faci < mesh.nInternalFaces(); faci++) + { + interpPolySize[faci] = calcFit(stencilPoints[faci], faci); + } + + Pout<< "count = " << count << endl; + + if (debug) + { + Info<< "linearFitData::linearFitData() :" + << "Finished constructing polynomialFit data" + << endl; + + interpPolySize.write(); + } +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::linearFitData::findFaceDirs +( + vector& idir, // value changed in return + vector& jdir, // value changed in return + vector& kdir, // value changed in return + const fvMesh& mesh, + const label faci +) +{ + idir = mesh.Sf()[faci]; + //idir = mesh.C()[mesh.neighbour()[faci]] - mesh.C()[mesh.owner()[faci]]; + idir /= mag(idir); + +# ifndef SPHERICAL_GEOMETRY + if (mesh.nGeometricD() <= 2) // find the normal direcion + { + if (mesh.directions()[0] == -1) + { + kdir = vector(1, 0, 0); + } + else if (mesh.directions()[1] == -1) + { + kdir = vector(0, 1, 0); + } + else + { + kdir = vector(0, 0, 1); + } + } + else // 3D so find a direction in the place of the face + { + const face& f = mesh.faces()[faci]; + kdir = mesh.points()[f[0]] - mesh.points()[f[1]]; + } +# else + // Spherical geometry so kdir is the radial direction + kdir = mesh.Cf()[faci]; +# endif + + if (mesh.nGeometricD() == 3) + { + // Remove the idir component from kdir and normalise + kdir -= (idir & kdir)*idir; + + scalar magk = mag(kdir); + + if (magk < SMALL) + { + FatalErrorIn("findFaceDirs") << " calculated kdir = zero" + << exit(FatalError); + } + else + { + kdir /= magk; + } + } + + jdir = kdir ^ idir; +} + + +Foam::label Foam::linearFitData::calcFit +( + const List<point>& C, + const label faci +) +{ + vector idir(1,0,0); + vector jdir(0,1,0); + vector kdir(0,0,1); + findFaceDirs(idir, jdir, kdir, mesh(), faci); + + scalarList wts(C.size(), scalar(1)); + wts[0] = centralWeight_; + wts[1] = centralWeight_; + + point p0 = mesh().faceCentres()[faci]; + scalar scale = 0; + + // calculate the matrix of the polynomial components + scalarRectangularMatrix B(C.size(), minSize_, scalar(0)); + + for(label ip = 0; ip < C.size(); ip++) + { + const point& p = C[ip]; + + scalar px = (p - p0)&idir; + scalar py = (p - p0)&jdir; +# ifndef SPHERICAL_GEOMETRY + scalar pz = (p - p0)&kdir; +# else + scalar pz = mag(p) - mag(p0); +# endif + + if (ip == 0) + { + scale = max(max(mag(px), mag(py)), mag(pz)); + } + + px /= scale; + py /= scale; + pz /= scale; + + label is = 0; + + B[ip][is++] = wts[0]*wts[ip]; + B[ip][is++] = wts[0]*wts[ip]*px; + + if (dim_ >= 2) + { + B[ip][is++] = wts[ip]*py; + } + if (dim_ == 3) + { + B[ip][is++] = wts[ip]*pz; + } + } + + // Set the fit + label stencilSize = C.size(); + fit_[faci].setSize(stencilSize); + scalarList singVals(minSize_); + label nSVDzeros = 0; + + const GeometricField<scalar, fvsPatchField, surfaceMesh>& w = + mesh().surfaceInterpolation::weights(); + + bool goodFit = false; + for(int iIt = 0; iIt < 10 && !goodFit; iIt++) + { + SVD svd(B, SMALL); + + scalar fit0 = wts[0]*wts[0]*svd.VSinvUt()[0][0]; + scalar fit1 = wts[0]*wts[1]*svd.VSinvUt()[0][1]; + + //goodFit = (fit0 > 0 && fit1 > 0); + + goodFit = + (mag(fit0 - w[faci])/w[faci] < 0.5) + && (mag(fit1 - (1 - w[faci]))/(1 - w[faci]) < 0.5); + + //scalar w0Err = fit0/w[faci]; + //scalar w1Err = fit1/(1 - w[faci]); + + //goodFit = + // (w0Err > 0.5 && w0Err < 1.5) + // && (w1Err > 0.5 && w1Err < 1.5); + + if (goodFit) + { + fit_[faci][0] = fit0; + fit_[faci][1] = fit1; + + for(label i=2; i<stencilSize; i++) + { + fit_[faci][i] = wts[0]*wts[i]*svd.VSinvUt()[0][i]; + } + + singVals = svd.S(); + nSVDzeros = svd.nZeros(); + } + else // (not good fit so increase weight in the centre and for linear) + { + wts[0] *= 10; + wts[1] *= 10; + + for(label i = 0; i < B.n(); i++) + { + B[i][0] *= 10; + B[i][1] *= 10; + } + + for(label j = 0; j < B.m(); j++) + { + B[0][j] *= 10; + B[1][j] *= 10; + } + } + } + + // static const scalar L = 0.1; + // static const scalar R = 0.2; + + // static const scalar beta = 1.0/(R - L); + // static const scalar alpha = R*beta; + + if (goodFit) + { + if ((mag(fit_[faci][0] - w[faci])/w[faci] < 0.15) + && (mag(fit_[faci][1] - (1 - w[faci]))/(1 - w[faci]) < 0.15)) + { + count++; + //Pout<< "fit " << mag(fit_[faci][0] - w[faci])/w[faci] << " " << mag(fit_[faci][1] - (1 - w[faci]))/(1 - w[faci]) << endl; + } + + // scalar limiter = + // max + // ( + // min + // ( + // min(alpha - beta*mag(fit_[faci][0] - w[faci])/w[faci], 1), + // min(alpha - beta*mag(fit_[faci][1] - (1 - w[faci]))/(1 - w[faci]), 1) + // ), 0 + // ); + + // Remove the uncorrected linear coefficients + fit_[faci][0] -= w[faci]; + fit_[faci][1] -= 1 - w[faci]; + + // if (limiter < 0.99) + // { + // for(label i = 0; i < stencilSize; i++) + // { + // fit_[faci][i] *= limiter; + // } + // } + } + else + { + Pout<< "Could not fit face " << faci + << " " << fit_[faci][0] << " " << w[faci] + << " " << fit_[faci][1] << " " << 1 - w[faci]<< endl; + fit_[faci] = 0; + } + + return minSize_ - nSVDzeros; +} + + +bool Foam::linearFitData::movePoints() +{ + notImplemented("linearFitData::movePoints()"); + + return true; +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/linearFit/linearFitData.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/linearFit/linearFitData.H new file mode 100644 index 0000000000000000000000000000000000000000..7a2bc7d28e31888f059dec2e35e862daf72fc95c --- /dev/null +++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/linearFit/linearFitData.H @@ -0,0 +1,140 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + linearFitData + +Description + Data for the linear fit correction interpolation scheme + +SourceFiles + linearFitData.C + +\*---------------------------------------------------------------------------*/ + +#ifndef linearFitData_H +#define linearFitData_H + +#include "MeshObject.H" +#include "fvMesh.H" +#include "extendedStencil.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +class globalIndex; + +/*---------------------------------------------------------------------------*\ + Class linearFitData Declaration +\*---------------------------------------------------------------------------*/ + +class linearFitData +: + public MeshObject<fvMesh, linearFitData> +{ + // Private data + + //- weights for central stencil + const scalar centralWeight_; + + //- dimensionality of the geometry + const label dim_; + + //- minimum stencil size + const label minSize_; + + //- Extended stencil addressing + extendedStencil stencil_; + + //- For each cell in the mesh store the values which multiply the + // values of the stencil to obtain the gradient for each direction + List<scalarList> fit_; + + + // Private member functions + + //- Find the normal direction and i, j and k directions for face faci + static void findFaceDirs + ( + vector& idir, // value changed in return + vector& jdir, // value changed in return + vector& kdir, // value changed in return + const fvMesh& mesh, + const label faci + ); + + label calcFit(const List<point>&, const label faci); + + +public: + + TypeName("linearFitData"); + + + // Constructors + + explicit linearFitData + ( + const fvMesh& mesh, + scalar cWeightDim + ); + + + // Destructor + + virtual ~linearFitData() + {} + + + // Member functions + + + //- Return reference to the stencil + const extendedStencil& stencil() const + { + return stencil_; + } + + //- Return reference to fit coefficients + const List<scalarList>& fit() const + { + return fit_; + } + + //- Delete the data when the mesh moves not implemented + virtual bool movePoints(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticFit/quadraticFit.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticFit/quadraticFit.H index 9db4996862881c924150ceaf3bbc762087a955e4..ff9a668f3d30a1264fe2cfb2da240595a3b79c2f 100644 --- a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticFit/quadraticFit.H +++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticFit/quadraticFit.H @@ -37,9 +37,9 @@ SourceFiles #ifndef quadraticFit_H #define quadraticFit_H -#include "linear.H" #include "quadraticFitData.H" -#include "extendedStencil.H" +#include "linear.H" +#include "centredCFCStencilObject.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -113,13 +113,19 @@ public: { const fvMesh& mesh = this->mesh(); + const extendedCentredStencil& stencil = + centredCFCStencilObject::New + ( + mesh + ); + const quadraticFitData& cfd = quadraticFitData::New ( mesh, + stencil, centralWeight_ ); - const extendedStencil& stencil = cfd.stencil(); const List<scalarList>& f = cfd.fit(); return stencil.weightedSum(vf, f); diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticFit/quadraticFitData.C b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticFit/quadraticFitData.C index 52cf371c70caf34814d99c9e32d2d13ff22df2e2..c5269877d8d9741295e80c2dba77703f9ed5944c 100644 --- a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticFit/quadraticFitData.C +++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticFit/quadraticFitData.C @@ -29,7 +29,7 @@ License #include "volFields.H" #include "SVD.H" #include "syncTools.H" - +#include "extendedCentredStencil.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -46,6 +46,7 @@ static int count = 0; Foam::quadraticFitData::quadraticFitData ( const fvMesh& mesh, + const extendedCentredStencil& stencil, const scalar cWeight ) : @@ -62,7 +63,6 @@ Foam::quadraticFitData::quadraticFitData dim_ == 2 ? 6 : dim_ == 3 ? 9 : 0 ), - stencil_(mesh), fit_(mesh.nInternalFaces()) { if (debug) @@ -102,8 +102,8 @@ Foam::quadraticFitData::quadraticFitData // Get the cell/face centres in stencil order. // Centred face stencils no good for triangles of tets. Need bigger stencils - List<List<point> > stencilPoints(stencil_.stencil().size()); - stencil_.collectData + List<List<point> > stencilPoints(mesh.nFaces()); + stencil.collectData ( mesh.C(), stencilPoints diff --git a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticFit/quadraticFitData.H b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticFit/quadraticFitData.H index 19859ea621cde6d18e6461f60aae6a7c49387d04..b44a2e4d90f4ff84d36dc360f97e34bd7ec000da 100644 --- a/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticFit/quadraticFitData.H +++ b/src/finiteVolume/interpolation/surfaceInterpolation/schemes/quadraticFit/quadraticFitData.H @@ -38,14 +38,13 @@ SourceFiles #include "MeshObject.H" #include "fvMesh.H" -#include "extendedStencil.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { -class globalIndex; +class extendedCentredStencil; /*---------------------------------------------------------------------------*\ Class quadraticFitData Declaration @@ -66,9 +65,6 @@ class quadraticFitData //- minimum stencil size const label minSize_; - //- Extended stencil addressing - extendedStencil stencil_; - //- For each cell in the mesh store the values which multiply the // values of the stencil to obtain the gradient for each direction List<scalarList> fit_; @@ -99,6 +95,7 @@ public: explicit quadraticFitData ( const fvMesh& mesh, + const extendedCentredStencil& stencil, scalar cWeightDim ); @@ -112,12 +109,6 @@ public: // Member functions - //- Return reference to the stencil - const extendedStencil& stencil() const - { - return stencil_; - } - //- Return reference to fit coefficients const List<scalarList>& fit() const { diff --git a/src/sampling/probes/probes.C b/src/sampling/probes/probes.C index e0576b60348c4c4c2bb70df5e98bdbee1d24103b..26b07afc595ac313e425116ff082dafd22fd5504 100644 --- a/src/sampling/probes/probes.C +++ b/src/sampling/probes/probes.C @@ -240,7 +240,7 @@ bool Foam::probes::checkFieldTypes() forAll(probeLocations_, probeI) { - *sPtr<< setw(w) << probeLocations_[probeI][cmpt]; + *sPtr<< ' ' << setw(w) << probeLocations_[probeI][cmpt]; } *sPtr << endl; } diff --git a/src/sampling/probes/probesTemplates.C b/src/sampling/probes/probesTemplates.C index 109f290ce1fc2c9d9e856e55cc3a5828a046f05d..fc90ed1dcab5bf86fb1abb1723e6f287157d5ba4 100644 --- a/src/sampling/probes/probesTemplates.C +++ b/src/sampling/probes/probesTemplates.C @@ -109,7 +109,7 @@ void Foam::probes::sampleAndWrite forAll(values, probeI) { - probeStream << setw(w) << values[probeI]; + probeStream << ' ' << setw(w) << values[probeI]; } probeStream << endl; }