levelSetTemplates.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) 2017-2019 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 
26 #include "levelSet.H"
27 #include "cut.H"
29 #include "tetIndices.H"
30 
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
32 
33 template<class Type>
35 (
36  const fvMesh& mesh,
37  const scalarField& levelC,
38  const scalarField& levelP,
39  const Field<Type>& positiveC,
40  const Field<Type>& positiveP,
41  const Field<Type>& negativeC,
42  const Field<Type>& negativeP
43 )
44 {
45  tmp<Field<Type>> tResult(new Field<Type>(mesh.nCells(), Zero));
46  Field<Type>& result = tResult.ref();
47 
48  forAll(result, cI)
49  {
50  const List<tetIndices> cellTetIs =
51  polyMeshTetDecomposition::cellTetIndices(mesh, cI);
52 
53  scalar v = 0;
54  Type r = Zero;
55 
56  forAll(cellTetIs, cellTetI)
57  {
58  const triFace triIs = cellTetIs[cellTetI].faceTriIs(mesh);
59 
60  const FixedList<point, 4>
61  tet =
62  {
63  mesh.cellCentres()[cI],
64  mesh.points()[triIs[0]],
65  mesh.points()[triIs[1]],
66  mesh.points()[triIs[2]]
67  };
68  const FixedList<scalar, 4>
69  level =
70  {
71  levelC[cI],
72  levelP[triIs[0]],
73  levelP[triIs[1]],
74  levelP[triIs[2]]
75  };
76  const cut::volumeIntegrateOp<Type>
77  positive = FixedList<Type, 4>
78  ({
79  positiveC[cI],
80  positiveP[triIs[0]],
81  positiveP[triIs[1]],
82  positiveP[triIs[2]]
83  });
84  const cut::volumeIntegrateOp<Type>
85  negative = FixedList<Type, 4>
86  ({
87  negativeC[cI],
88  negativeP[triIs[0]],
89  negativeP[triIs[1]],
90  negativeP[triIs[2]]
91  });
92 
93  v += cut::volumeOp()(tet);
94 
95  r += tetCut(tet, level, positive, negative);
96  }
97 
98  result[cI] = r/v;
99  }
100 
101  return tResult;
102 }
103 
104 
105 template<class Type>
107 (
108  const fvPatch& patch,
109  const scalarField& levelF,
110  const scalarField& levelP,
111  const Field<Type>& positiveF,
112  const Field<Type>& positiveP,
113  const Field<Type>& negativeF,
114  const Field<Type>& negativeP
115 )
116 {
117  tmp<Field<Type>> tResult(new Field<Type>(patch.size(), Zero));
118  Field<Type>& result = tResult.ref();
119 
120  forAll(result, fI)
121  {
122  const face& f = patch.patch().localFaces()[fI];
123 
124  scalar a = 0;
125  Type r = Zero;
126 
127  for(label eI = 0; eI < f.size(); ++ eI)
128  {
129  const edge e = f.faceEdge(eI);
130 
131  const FixedList<point, 3>
132  tri =
133  {
134  patch.patch().faceCentres()[fI],
135  patch.patch().localPoints()[e[0]],
136  patch.patch().localPoints()[e[1]]
137  };
138  const FixedList<scalar, 3>
139  level =
140  {
141  levelF[fI],
142  levelP[e[0]],
143  levelP[e[1]]
144  };
145  const cut::areaMagIntegrateOp<Type>
146  positive = FixedList<Type, 3>
147  ({
148  positiveF[fI],
149  positiveP[e[0]],
150  positiveP[e[1]]
151  });
152  const cut::areaMagIntegrateOp<Type>
153  negative = FixedList<Type, 3>
154  ({
155  negativeF[fI],
156  negativeP[e[0]],
157  negativeP[e[1]]
158  });
159 
160  a += cut::areaMagOp()(tri);
161 
162  r += triCut(tri, level, positive, negative);
163  }
164 
165  result[fI] = r/a;
166  }
167 
168  return tResult;
169 }
170 
171 
172 template<class Type>
175 (
176  const volScalarField& levelC,
177  const pointScalarField& levelP,
178  const GeometricField<Type, fvPatchField, volMesh>& positiveC,
179  const GeometricField<Type, pointPatchField, pointMesh>& positiveP,
180  const GeometricField<Type, fvPatchField, volMesh>& negativeC,
181  const GeometricField<Type, pointPatchField, pointMesh>& negativeP
182 )
183 {
184  const fvMesh& mesh = levelC.mesh();
185 
186  tmp<GeometricField<Type, fvPatchField, volMesh>> tResult
187  (
188  new GeometricField<Type, fvPatchField, volMesh>
189  (
190  IOobject
191  (
192  positiveC.name() + ":levelSetAverage",
193  mesh.time().timeName(),
194  mesh
195  ),
196  mesh,
197  dimensioned<Type>("0", positiveC.dimensions(), Zero)
198  )
199  );
200  GeometricField<Type, fvPatchField, volMesh>& result = tResult.ref();
201 
202  result.primitiveFieldRef() =
204  (
205  mesh,
206  levelC.primitiveField(),
207  levelP.primitiveField(),
208  positiveC.primitiveField(),
209  positiveP.primitiveField(),
210  negativeC.primitiveField(),
211  negativeP.primitiveField()
212  );
213 
214  forAll(mesh.boundary(), patchi)
215  {
216  result.boundaryFieldRef()[patchi] =
218  (
219  mesh.boundary()[patchi],
220  levelC.boundaryField()[patchi],
221  levelP.boundaryField()[patchi].patchInternalField()(),
222  positiveC.boundaryField()[patchi],
223  positiveP.boundaryField()[patchi].patchInternalField()(),
224  negativeC.boundaryField()[patchi],
225  negativeP.boundaryField()[patchi].patchInternalField()()
226  );
227  }
228 
229  return tResult;
230 }
231 
232 
233 // ************************************************************************* //
GeometricField< scalar, pointPatchField, pointMesh > pointScalarField
Definition: pointFields.H:49
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
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
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Definition: volFieldsFwd.H:52
dynamicFvMesh & mesh
cut::opAddResult< AboveOp, BelowOp >::type triCut(const FixedList< Point, 3 > &tri, const FixedList< scalar, 3 > &level, const AboveOp &aboveOp, const BelowOp &belowOp)
Cut a triangle along the zero plane defined by the given levels. Templated.
face triFace(3)
static const zero Zero
Definition: zero.H:97
volScalarField scalarField(fieldObject, mesh)
tmp< Field< Type > > levelSetAverage(const fvMesh &mesh, const scalarField &levelC, const scalarField &levelP, const Field< Type > &positiveC, const Field< Type > &positiveP, const Field< Type > &negativeC, const Field< Type > &negativeP)
Calculate the average value of two fields, one on each side of a level set.
label patchi
A class for managing temporary objects.
Definition: PtrList.H:53
cut::opAddResult< AboveOp, BelowOp >::type tetCut(const FixedList< Point, 4 > &tet, const FixedList< scalar, 4 > &level, const AboveOp &aboveOp, const BelowOp &belowOp)
As triCut, but for a tetrahedron.