LagrangianFieldDecomposer.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2025 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
27 #include "remote.H"
28 
29 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
30 
32 (
33  const fvMesh& completeFvMesh,
34  const PtrList<fvMesh>& procFvMeshes,
35  const labelListList& faceProcAddressing,
36  const labelListList& cellProcAddressing,
37  const word& LagrangianName
38 )
39 :
40  completeMesh_(completeFvMesh, LagrangianName),
41  procMeshes_(procFvMeshes.size()),
42  particleProcAddressing_(procFvMeshes.size())
43 {
44  // Construct empty processor meshes
45  forAll(procMeshes_, proci)
46  {
47  procMeshes_.set
48  (
49  proci,
50  new LagrangianMesh
51  (
52  procFvMeshes[proci],
53  LagrangianName,
55  )
56  );
57  }
58 
59  // Create reverse cell addressing
60  List<remote> completeCellProcCell(completeMesh_.mesh().nCells());
61  forAll(cellProcAddressing, proci)
62  {
63  forAll(cellProcAddressing[proci], procCelli)
64  {
65  completeCellProcCell[cellProcAddressing[proci][procCelli]] =
66  remote(proci, procCelli);
67  }
68  }
69 
70  // Create reverse face addressing
71  List<remote> completeFaceOwnerProcFace(completeMesh_.mesh().nFaces());
72  List<remote> completeFaceNeighbourProcFace(completeMesh_.mesh().nFaces());
73  forAll(faceProcAddressing, proci)
74  {
75  forAll(faceProcAddressing[proci], procFacei)
76  {
77  const bool owner = faceProcAddressing[proci][procFacei] > 0;
78  const label completeFacei =
79  mag(faceProcAddressing[proci][procFacei]) - 1;
80 
81  (
82  owner
83  ? completeFaceOwnerProcFace
84  : completeFaceNeighbourProcFace
85  )[completeFacei] = remote(proci, procFacei);
86  }
87  }
88 
89  // Count the number of particles on each processor
90  labelList procMeshSizes(procMeshes_.size(), 0);
91  forAll(completeMesh_, i)
92  {
93  const label proci =
94  completeCellProcCell[completeMesh_.celli()[i]].proci;
95 
96  procMeshSizes[proci] ++;
97  }
98 
99  // Resize the addressing
100  forAll(procMeshes_, proci)
101  {
102  particleProcAddressing_[proci].resize(procMeshSizes[proci], -1);
103  }
104 
105  // Allocate processor geometry and topology
106  PtrList<barycentricField> procCoordinates(procMeshes_.size());
107  PtrList<labelField> procCellIndices(procMeshes_.size());
108  PtrList<labelField> procFaceIndices(procMeshes_.size());
109  PtrList<labelField> procFaceTriIndices(procMeshes_.size());
110  forAll(procMeshes_, proci)
111  {
112  procCoordinates.set(proci, new barycentricField(procMeshSizes[proci]));
113  procCellIndices.set(proci, new labelField(procMeshSizes[proci]));
114  procFaceIndices.set(proci, new labelField(procMeshSizes[proci]));
115  procFaceTriIndices.set(proci, new labelField(procMeshSizes[proci]));
116  }
117 
118  // Distribute the elements to the processor meshes, and simultaneously
119  // build addressing for distributing associated fields
120  const faceList& completeFaces = completeMesh_.mesh().faces();
121  labelList procIs(procMeshes_.size(), 0);
122  forAll(completeMesh_, i)
123  {
124  const label completeCelli = completeMesh_.celli()[i];
125  const label completeFacei = completeMesh_.facei()[i];
126 
127  const label proci = completeCellProcCell[completeCelli].proci;
128  const label procCelli = completeCellProcCell[completeCelli].elementi;
129  const label procFacei =
130  completeFaceOwnerProcFace[completeFacei].proci == proci
131  ? completeFaceOwnerProcFace[completeFacei].elementi
132  : completeFaceNeighbourProcFace[completeFacei].elementi;
133 
134  particleProcAddressing_[proci][procIs[proci]] = i;
135 
136  procCoordinates[proci][procIs[proci]] = completeMesh_.coordinates()[i];
137  procCellIndices[proci][procIs[proci]] = procCelli;
138  procFaceIndices[proci][procIs[proci]] = procFacei;
139  procFaceTriIndices[proci][procIs[proci]] = completeMesh_.faceTrii()[i];
140 
141  // If the owner has changed then the face will be numbered around in
142  // the opposite direction. Change the face triangle index accordingly.
143  if (faceProcAddressing[proci][procFacei] < 0)
144  {
145  const label completeFaceSize = completeFaces[completeFacei].size();
146 
147  procFaceTriIndices[proci][procIs[proci]] =
148  completeFaceSize - 1 - procFaceTriIndices[proci][procIs[proci]];
149  }
150 
151  procIs[proci] ++;
152  }
153 
154  // Inject into the processor meshes
155  forAll(procMeshes_, proci)
156  {
157  procMeshes_[proci].inject
158  (
159  procCoordinates[proci],
160  procCellIndices[proci],
161  procFaceIndices[proci],
162  procFaceTriIndices[proci]
163  );
164  }
165 }
166 
167 
168 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
169 
171 {}
172 
173 
174 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
175 
178 {
179  return procMeshes_;
180 }
181 
182 
184 {
185  forAll(procMeshes_, proci)
186  {
187  procMeshes_[proci].write();
188  }
189 }
190 
191 
192 bool Foam::LagrangianFieldDecomposer::decomposes
193 (
194  const IOobjectList& objects
195 )
196 {
197  bool result = false;
198 
199  #define DECOMPOSES_LAGRANGIAN_FIELDS_TYPE(Type, nullArg) \
200  result = \
201  result \
202  || decomposes<LagrangianField<Type>>(objects) \
203  || decomposes<LagrangianDynamicField<Type>>(objects) \
204  || decomposes<LagrangianInternalField<Type>>(objects) \
205  || decomposes<LagrangianInternalDynamicField<Type>>(objects);
208  #undef DECOMPOSES_LAGRANGIAN_FIELDS_TYPE
209 
210  return result;
211 }
212 
213 
214 // ************************************************************************* //
#define DECOMPOSES_LAGRANGIAN_FIELDS_TYPE(Type, nullArg)
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
List of IOobjects with searching and retrieving facilities.
Definition: IOobjectList.H:53
void decomposePositions() const
Write the decomposed positions.
LagrangianFieldDecomposer(const fvMesh &completeFvMesh, const PtrList< fvMesh > &procFvMeshes, const labelListList &faceProcAddressing, const labelListList &cellProcAddressing, const word &LagrangianName)
Construct from components.
const PtrList< LagrangianMesh > & procMeshes() const
Access the decomposed meshes.
Class containing Lagrangian geometry and topology.
const labelIODynamicField & faceTrii() const
Access the face-tet indices.
const polyMesh & mesh() const
Access the mesh.
const labelIODynamicField & celli() const
Access the cell indices.
const barycentricIODynamicField & coordinates() const
Access the coordinates.
const labelIODynamicField & facei() const
Access the cell-face indices.
void resize(const label)
Alias for setSize(const label)
Definition: ListI.H:138
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: PtrList.H:75
bool set(const label) const
Is element set.
Definition: PtrListI.H:62
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:96
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1344
label nCells() const
label nFaces() const
Struct for keeping processor, element (cell, face, point) index.
Definition: remote.H:57
A class for handling words, derived from string.
Definition: word.H:62
Field< barycentric > barycentricField
Barycentric field.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
void mag(LagrangianPatchField< scalar > &f, const LagrangianPatchField< Type > &f1)
Field< label > labelField
Specialisation of Field<T> for label.
Definition: labelField.H:49
FOR_ALL_FIELD_TYPES(makeFieldSourceTypedef)
objects