Test-fieldMapping.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 2013-2015 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 Application
25  Test-fieldMapping
26 
27 Description
28  Test app for mapping of fields.
29 
30 \*---------------------------------------------------------------------------*/
31 
32 #include "argList.H"
33 #include "fvMesh.H"
34 #include "volFields.H"
35 #include "Time.H"
36 #include "OFstream.H"
37 #include "meshTools.H"
38 #include "removeFaces.H"
39 #include "mapPolyMesh.H"
40 #include "polyTopoChange.H"
41 #include "fvcDiv.H"
42 #include "Random.H"
43 
44 using namespace Foam;
45 
46 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
47 
48 bool notEqual(const scalar s1, const scalar s2, const scalar tol)
49 {
50  return mag(s1-s2) > tol;
51 }
52 
53 
54 // Main program:
55 
56 int main(int argc, char *argv[])
57 {
58  #include "addTimeOptions.H"
59  argList::validArgs.append("inflate (true|false)");
60  #include "setRootCase.H"
61  #include "createTime.H"
62  #include "createMesh.H"
63 
64  const Switch inflate(args.args()[1]);
65 
66  if (inflate)
67  {
68  Info<< "Deleting cells using inflation/deflation" << nl << endl;
69  }
70  else
71  {
72  Info<< "Deleting cells, introducing points at new position" << nl
73  << endl;
74  }
75 
76 
77  Random rndGen(0);
78 
79 
80 
81  // Test mapping
82  // ------------
83  // Mapping is volume averaged
84 
85 
86  // 1. uniform field stays uniform
88  (
89  IOobject
90  (
91  "one",
92  runTime.timeName(),
93  mesh,
96  ),
97  mesh,
98  dimensionedScalar("one", dimless, 1.0),
99  zeroGradientFvPatchScalarField::typeName
100  );
101  Info<< "Writing one field "
102  << one.name() << " in " << runTime.timeName() << endl;
103  one.write();
104 
105 
106  // 2. linear profile gets preserved
107  volScalarField ccX
108  (
109  IOobject
110  (
111  "ccX",
112  runTime.timeName(),
113  mesh,
116  ),
117  mesh.C().component(0)
118  );
119  Info<< "Writing x component of cell centres to "
120  << ccX.name()
121  << " in " << runTime.timeName() << endl;
122  ccX.write();
123 
124 
125  // Uniform surface field
126  surfaceScalarField surfaceOne
127  (
128  IOobject
129  (
130  "surfaceOne",
131  runTime.timeName(),
132  mesh,
135  ),
136  mesh,
137  dimensionedScalar("one", dimless, 1.0),
138  calculatedFvsPatchScalarField::typeName
139  );
140  Info<< "Writing surface one field "
141  << surfaceOne.name() << " in " << runTime.timeName() << endl;
142  surfaceOne.write();
143 
144 
145 
146 
147  // Force allocation of V. Important for any mesh changes since otherwise
148  // old time volumes are not stored
149  const scalar totalVol = gSum(mesh.V());
150 
151  // Face removal engine. No checking for not merging boundary faces.
152  removeFaces faceRemover(mesh, GREAT);
153 
154 
155  while (runTime.loop())
156  {
157  Info<< "Time = " << runTime.timeName() << nl << endl;
158 
159  if (!mesh.nInternalFaces())
160  {
161  break;
162  }
163 
164  // Remove face
165  label candidateFaceI = rndGen.integer(0, mesh.nInternalFaces()-1);
166  Info<< "Wanting to delete face " << mesh.faceCentres()[candidateFaceI]
167  << nl << endl;
168 
169  labelList candidates(1, candidateFaceI);
170 
171 
172  // Get compatible set of faces and connected sets of cells.
173  labelList cellRegion;
174  labelList cellRegionMaster;
175  labelList facesToRemove;
176 
177  faceRemover.compatibleRemoves
178  (
179  candidates,
180  cellRegion,
181  cellRegionMaster,
182  facesToRemove
183  );
184 
185  // Topo changes container
186  polyTopoChange meshMod(mesh);
187 
188  // Insert mesh refinement into polyTopoChange.
189  faceRemover.setRefinement
190  (
191  facesToRemove,
192  cellRegion,
193  cellRegionMaster,
194  meshMod
195  );
196 
197  // Change mesh and inflate
198  Info<< "Actually changing mesh" << nl << endl;
199  autoPtr<mapPolyMesh> morphMap = meshMod.changeMesh(mesh, inflate);
200 
201  Info<< "Mapping fields" << nl << endl;
202  mesh.updateMesh(morphMap);
203 
204  // Move mesh (since morphing does not do this)
205  if (morphMap().hasMotionPoints())
206  {
207  Info<< "Moving mesh" << nl << endl;
208  mesh.movePoints(morphMap().preMotionPoints());
209  }
210 
211  // Update numbering of cells/vertices.
212  faceRemover.updateMesh(morphMap);
213 
214 
215  Info<< "Writing fields" << nl << endl;
216  runTime.write();
217 
218 
219  // Check mesh volume conservation
220  if (mesh.moving())
221  {
222  #include "volContinuity.H"
223  }
224  else
225  {
226  if (mesh.V().size() != mesh.nCells())
227  {
229  << "Volume not mapped. V:" << mesh.V().size()
230  << " nCells:" << mesh.nCells()
231  << exit(FatalError);
232  }
233 
234  const scalar newVol = gSum(mesh.V());
235  Info<< "Initial volume = " << totalVol
236  << " New volume = " << newVol
237  << endl;
238 
239  if (mag(newVol-totalVol)/totalVol > 1e-10)
240  {
242  << "Volume loss: old volume:" << totalVol
243  << " new volume:" << newVol
244  << exit(FatalError);
245  }
246  else
247  {
248  Info<< "Volume check OK" << nl << endl;
249  }
250  }
251 
252 
253  // Check constant profile
254  {
255  const scalar max = gMax(one);
256  const scalar min = gMin(one);
257 
258  Info<< "Uniform one field min = " << min
259  << " max = " << max << endl;
260 
261  if (notEqual(max, 1.0, 1e-10) || notEqual(min, 1.0, 1e-10))
262  {
264  << "Uniform volVectorField not preserved."
265  << " Min and max should both be 1.0. min:" << min
266  << " max:" << max
267  << exit(FatalError);
268  }
269  else
270  {
271  Info<< "Uniform field mapping check OK" << nl << endl;
272  }
273  }
274 
275  // Check linear profile
276  {
277  const scalarField diff = ccX-mesh.C().component(0);
278 
279  const scalar max = gMax(diff);
280  const scalar min = gMin(diff);
281 
282  Info<< "Linear profile field min = " << min
283  << " max = " << max << endl;
284 
285  if (notEqual(max, 0.0, 1e-10) || notEqual(min, 0.0, 1e-10))
286  {
288  << "Linear profile not preserved."
289  << " Min and max should both be 0.0. min:" << min
290  << " max:" << max
291  << exit(FatalError);
292  }
293  else
294  {
295  Info<< "Linear profile mapping check OK" << nl << endl;
296  }
297  }
298 
299  // Check face field mapping
300  if (surfaceOne.size())
301  {
302  const scalar max = gMax(surfaceOne.internalField());
303  const scalar min = gMin(surfaceOne.internalField());
304 
305  Info<< "Uniform surface field min = " << min
306  << " max = " << max << endl;
307 
308  if (notEqual(max, 1.0, 1e-10) || notEqual(min, 1.0, 1e-10))
309  {
311  << "Uniform surfaceScalarField not preserved."
312  << " Min and max should both be 1.0. min:" << min
313  << " max:" << max
314  << exit(FatalError);
315  }
316  else
317  {
318  Info<< "Uniform surfaceScalarField mapping check OK" << nl
319  << endl;
320  }
321  }
322 
323 
324  Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
325  << " ClockTime = " << runTime.elapsedClockTime() << " s"
326  << nl << endl;
327  }
328 
329  Info<< "End\n" << endl;
330 
331  return 0;
332 }
333 
334 
335 // ************************************************************************* //
Foam::argList::validArgs
static SLList< string > validArgs
A list of valid (mandatory) arguments.
Definition: argList.H:143
volFields.H
Foam::Random
Simple random number generator.
Definition: Random.H:49
Foam::IOobject
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:91
meshTools.H
Foam::GeometricField::component
tmp< GeometricField< cmptType, PatchField, GeoMesh > > component(const direction) const
Return a component of the field.
Foam::Switch
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition: Switch.H:60
Foam::dimless
const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:47
Foam::argList::args
const stringList & args() const
Return arguments.
Definition: argListI.H:66
Foam::IOobject::AUTO_WRITE
@ AUTO_WRITE
Definition: IOobject.H:117
Foam::polyTopoChange::changeMesh
autoPtr< mapPolyMesh > changeMesh(polyMesh &mesh, const bool inflate, const bool syncParallel=true, const bool orderCells=false, const bool orderPoints=false)
Inplace changes mesh without change of patches.
Definition: polyTopoChange.C:3039
Foam::polyMesh::moving
bool moving() const
Is mesh moving.
Definition: polyMesh.H:493
mapPolyMesh.H
polyTopoChange.H
Foam::polyTopoChange
Direct mesh changes based on v1.3 polyTopoChange syntax.
Definition: polyTopoChange.H:97
fvcDiv.H
Calculate the divergence of the given field.
Foam::one
A class representing the concept of 1 (scalar(1.0)) used to avoid unnecessary manipulations for objec...
Definition: one.H:45
Foam::fvMesh::movePoints
virtual tmp< scalarField > movePoints(const pointField &)
Move points, returns volumes swept by faces in motion.
Definition: fvMesh.C:726
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::gSum
Type gSum(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:564
Foam::removeFaces::setRefinement
void setRefinement(const labelList &piercedFaces, const labelList &cellRegion, const labelList &cellRegionMaster, polyTopoChange &) const
Play commands into polyTopoChange to remove faces.
Definition: removeFaces.C:762
Foam::mag
dimensioned< scalar > mag(const dimensioned< Type > &)
addTimeOptions.H
OFstream.H
Foam::primitiveMesh::nCells
label nCells() const
Definition: primitiveMeshI.H:64
Foam::diff
scalar diff(const triad &A, const triad &B)
Return a quantity of the difference between two triads.
Definition: triad.C:407
main
int main(int argc, char *argv[])
Definition: Test-fieldMapping.C:53
Foam::fvMesh::V
const DimensionedField< scalar, volMesh > & V() const
Return cell volumes.
Definition: fvMeshGeometry.C:199
Foam::label
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
Foam::removeFaces
Given list of faces to remove insert all the topology changes. Contains helper function to get consis...
Definition: removeFaces.H:62
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::Ostream::write
virtual Ostream & write(const token &)=0
Write next token to stream.
Foam::IOobject::NO_READ
@ NO_READ
Definition: IOobject.H:111
Foam::nl
static const char nl
Definition: Ostream.H:260
Foam::Info
messageStream Info
argList.H
Foam::removeFaces::updateMesh
void updateMesh(const mapPolyMesh &)
Force recalculation of locally stored data on topological change.
Definition: removeFaces.H:207
Foam::fvMesh::updateMesh
virtual void updateMesh(const mapPolyMesh &mpm)
Update mesh corresponding to the given map.
Definition: fvMesh.C:802
Foam::GeometricField::internalField
InternalField & internalField()
Return internal field.
Definition: GeometricField.C:724
removeFaces.H
Foam::FatalError
error FatalError
Foam::primitiveMesh::nInternalFaces
label nInternalFaces() const
Definition: primitiveMeshI.H:52
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:18
Foam::dimensioned
Generic dimensioned Type class.
Definition: dimensionedScalarFwd.H:41
fvMesh.H
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::e
const double e
Elementary charge.
Definition: doubleFloat.H:94
Random.H
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Foam::max
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
Foam::autoPtr
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:117
setRootCase.H
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
Foam::fvMesh::C
const volVectorField & C() const
Return cell centres as volVectorField.
Definition: fvMeshGeometry.C:369
volContinuity.H
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::primitiveMesh::faceCentres
const vectorField & faceCentres() const
Definition: primitiveMeshFaceCentresAndAreas.C:130
createMesh.H
createTime.H
Foam::gMin
Type gMin(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:563
Foam::removeFaces::compatibleRemoves
label compatibleRemoves(const labelList &inPiercedFaces, labelList &cellRegion, labelList &cellRegionMaster, labelList &outPiercedFaces) const
Find faces including those with cells which have the same mastercell.
Definition: removeFaces.C:581
Foam::GeometricField
Generic GeometricField class.
Definition: surfaceFieldsFwd.H:52
args
Foam::argList args(argc, argv)
Foam::notEqual
bool notEqual(const Scalar s1, const Scalar s2)
Definition: Scalar.H:155
Foam::min
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
rndGen
cachedRandom rndGen(label(0), -1)
Foam::gMax
Type gMax(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:562