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-2018 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  typedef typename outerProduct<Type, vector>::type sumType;
118 
119  tmp<Field<Type>> tResult(new Field<Type>(patch.size(), Zero));
120  Field<Type>& result = tResult.ref();
121 
122  forAll(result, fI)
123  {
124  const face& f = patch.patch().localFaces()[fI];
125 
126  vector a = vector::zero;
127  sumType r = Zero;
128 
129  for(label eI = 0; eI < f.size(); ++ eI)
130  {
131  const edge e = f.faceEdge(eI);
132 
133  const FixedList<point, 3>
134  tri =
135  {
136  patch.patch().faceCentres()[fI],
137  patch.patch().localPoints()[e[0]],
138  patch.patch().localPoints()[e[1]]
139  };
140  const FixedList<scalar, 3>
141  level =
142  {
143  levelF[fI],
144  levelP[e[0]],
145  levelP[e[1]]
146  };
147  const cut::areaIntegrateOp<Type>
148  positive = FixedList<Type, 3>
149  ({
150  positiveF[fI],
151  positiveP[e[0]],
152  positiveP[e[1]]
153  });
154  const cut::areaIntegrateOp<Type>
155  negative = FixedList<Type, 3>
156  ({
157  negativeF[fI],
158  negativeP[e[0]],
159  negativeP[e[1]]
160  });
161 
162  a += cut::areaOp()(tri);
163 
164  r += triCut(tri, level, positive, negative);
165  }
166 
167  result[fI] = a/magSqr(a) & r;
168  }
169 
170  return tResult;
171 }
172 
173 
174 template<class Type>
177 (
178  const volScalarField& levelC,
179  const pointScalarField& levelP,
180  const GeometricField<Type, fvPatchField, volMesh>& positiveC,
181  const GeometricField<Type, pointPatchField, pointMesh>& positiveP,
182  const GeometricField<Type, fvPatchField, volMesh>& negativeC,
183  const GeometricField<Type, pointPatchField, pointMesh>& negativeP
184 )
185 {
186  const fvMesh& mesh = levelC.mesh();
187 
188  tmp<GeometricField<Type, fvPatchField, volMesh>> tResult
189  (
190  new GeometricField<Type, fvPatchField, volMesh>
191  (
192  IOobject
193  (
194  positiveC.name() + ":levelSetAverage",
195  mesh.time().timeName(),
196  mesh
197  ),
198  mesh,
199  dimensioned<Type>("0", positiveC.dimensions(), Zero)
200  )
201  );
202  GeometricField<Type, fvPatchField, volMesh>& result = tResult.ref();
203 
204  result.primitiveFieldRef() =
206  (
207  mesh,
208  levelC.primitiveField(),
209  levelP.primitiveField(),
210  positiveC.primitiveField(),
211  positiveP.primitiveField(),
212  negativeC.primitiveField(),
213  negativeP.primitiveField()
214  );
215 
216  forAll(mesh.boundary(), patchi)
217  {
218  result.boundaryFieldRef()[patchi] =
220  (
221  mesh.boundary()[patchi],
222  levelC.boundaryField()[patchi],
223  levelP.boundaryField()[patchi].patchInternalField()(),
224  positiveC.boundaryField()[patchi],
225  negativeP.boundaryField()[patchi].patchInternalField()(),
226  positiveC.boundaryField()[patchi],
227  negativeP.boundaryField()[patchi].patchInternalField()()
228  );
229  }
230 
231  return tResult;
232 }
233 
234 
235 // ************************************************************************* //
GeometricField< scalar, pointPatchField, pointMesh > pointScalarField
Definition: pointFields.H:49
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
type
Types of root.
Definition: Roots.H:52
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
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.
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:49
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.
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Definition: volFieldsFwd.H:52
dynamicFvMesh & mesh
face triFace(3)
static const zero Zero
Definition: zero.H:97
dimensioned< scalar > magSqr(const dimensioned< Type > &)
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