PageRenderTime 49ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/applications/test/hexRef8/Test-hexRef8.C

https://gitlab.com/johnvarv/OpenFOAM-3.0.x
C | 420 lines | 282 code | 81 blank | 57 comment | 27 complexity | 44cccabe21cfefbe04c53e11b7358678 MD5 | raw 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. OpenFOAM is free software: you can redistribute it and/or modify it
  11. under the terms of the GNU General Public License as published by
  12. the Free Software Foundation, either version 3 of the License, or
  13. (at your option) any later version.
  14. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
  15. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  16. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  17. for more details.
  18. You should have received a copy of the GNU General Public License
  19. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
  20. Application
  21. Test-hexRef8
  22. Description
  23. Test app for refinement and unrefinement. Runs a few iterations refining
  24. and unrefining.
  25. \*---------------------------------------------------------------------------*/
  26. #include "argList.H"
  27. #include "Time.H"
  28. #include "volFields.H"
  29. #include "surfaceFields.H"
  30. #include "pointFields.H"
  31. #include "hexRef8.H"
  32. #include "mapPolyMesh.H"
  33. #include "polyTopoChange.H"
  34. #include "Random.H"
  35. #include "zeroGradientFvPatchFields.H"
  36. #include "calculatedPointPatchFields.H"
  37. #include "pointConstraints.H"
  38. #include "fvcDiv.H"
  39. using namespace Foam;
  40. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
  41. bool notEqual(const scalar s1, const scalar s2, const scalar tol)
  42. {
  43. return mag(s1-s2) > tol;
  44. }
  45. // Main program:
  46. int main(int argc, char *argv[])
  47. {
  48. #include "addTimeOptions.H"
  49. argList::validArgs.append("inflate (true|false)");
  50. #include "setRootCase.H"
  51. #include "createTime.H"
  52. #include "createMesh.H"
  53. const pointConstraints& pc = pointConstraints::New(pointMesh::New(mesh));
  54. const Switch inflate(args.args()[1]);
  55. if (inflate)
  56. {
  57. Info<< "Splitting/deleting cells using inflation/deflation" << nl
  58. << endl;
  59. }
  60. else
  61. {
  62. Info<< "Splitting/deleting cells, introducing points at new position"
  63. << nl << endl;
  64. }
  65. Random rndGen(0);
  66. // Force generation of V()
  67. (void)mesh.V();
  68. // Test mapping
  69. // ------------
  70. // 1. uniform field stays uniform
  71. volScalarField one
  72. (
  73. IOobject
  74. (
  75. "one",
  76. runTime.timeName(),
  77. mesh,
  78. IOobject::NO_READ,
  79. IOobject::AUTO_WRITE
  80. ),
  81. mesh,
  82. dimensionedScalar("one", dimless, 1.0),
  83. zeroGradientFvPatchScalarField::typeName
  84. );
  85. Info<< "Writing one field "
  86. << one.name() << " in " << runTime.timeName() << endl;
  87. one.write();
  88. // 2. linear profile gets preserved
  89. volScalarField ccX
  90. (
  91. IOobject
  92. (
  93. "ccX",
  94. runTime.timeName(),
  95. mesh,
  96. IOobject::NO_READ,
  97. IOobject::AUTO_WRITE
  98. ),
  99. mesh.C().component(0)
  100. );
  101. Info<< "Writing x component of cell centres to "
  102. << ccX.name()
  103. << " in " << runTime.timeName() << endl;
  104. ccX.write();
  105. // Uniform surface field
  106. surfaceScalarField surfaceOne
  107. (
  108. IOobject
  109. (
  110. "surfaceOne",
  111. runTime.timeName(),
  112. mesh,
  113. IOobject::NO_READ,
  114. IOobject::AUTO_WRITE
  115. ),
  116. mesh,
  117. dimensionedScalar("one", dimless, 1.0),
  118. calculatedFvsPatchScalarField::typeName
  119. );
  120. Info<< "Writing surface one field "
  121. << surfaceOne.name() << " in " << runTime.timeName() << endl;
  122. surfaceOne.write();
  123. // Uniform point field
  124. pointScalarField pointX
  125. (
  126. IOobject
  127. (
  128. "pointX",
  129. runTime.timeName(),
  130. mesh,
  131. IOobject::NO_READ,
  132. IOobject::AUTO_WRITE
  133. ),
  134. pointMesh::New(mesh),
  135. dimensionedScalar("one", dimless, 1.0),
  136. calculatedPointPatchScalarField::typeName
  137. );
  138. pointX.internalField() = mesh.points().component(0);
  139. pointX.correctBoundaryConditions();
  140. Info<< "Writing x-component field "
  141. << pointX.name() << " in " << runTime.timeName() << endl;
  142. pointX.write();
  143. // Force allocation of V. Important for any mesh changes since otherwise
  144. // old time volumes are not stored
  145. const scalar totalVol = gSum(mesh.V());
  146. // Construct refiner. Read initial cell and point levels.
  147. hexRef8 meshCutter(mesh);
  148. while (runTime.loop())
  149. {
  150. Info<< "Time = " << runTime.timeName() << nl << endl;
  151. if (mesh.globalData().nTotalCells() == 0)
  152. {
  153. break;
  154. }
  155. mesh.moving(false);
  156. mesh.topoChanging(false);
  157. label action = rndGen.integer(0, 5);
  158. if (action == 0)
  159. {
  160. Info<< nl << "-- moving only" << endl;
  161. mesh.movePoints(pointField(mesh.points()));
  162. }
  163. else if (action == 1 || action == 2)
  164. {
  165. // Mesh changing engine.
  166. polyTopoChange meshMod(mesh);
  167. if (action == 1)
  168. {
  169. // Refine
  170. label nRefine = mesh.nCells()/20;
  171. DynamicList<label> refineCandidates(nRefine);
  172. for (label i=0; i<nRefine; i++)
  173. {
  174. refineCandidates.append(rndGen.integer(0, mesh.nCells()-1));
  175. }
  176. labelList cellsToRefine
  177. (
  178. meshCutter.consistentRefinement
  179. (
  180. refineCandidates,
  181. true // buffer layer
  182. )
  183. );
  184. Info<< nl << "-- selected "
  185. << returnReduce(cellsToRefine.size(), sumOp<label>())
  186. << " cells out of " << mesh.globalData().nTotalCells()
  187. << " for refinement" << endl;
  188. // Play refinement commands into mesh changer.
  189. meshCutter.setRefinement(cellsToRefine, meshMod);
  190. }
  191. else
  192. {
  193. // Unrefine
  194. labelList allSplitPoints(meshCutter.getSplitPoints());
  195. label nUnrefine = allSplitPoints.size()/20;
  196. labelHashSet candidates(2*nUnrefine);
  197. for (label i=0; i<nUnrefine; i++)
  198. {
  199. label index = rndGen.integer(0, allSplitPoints.size()-1);
  200. candidates.insert(allSplitPoints[index]);
  201. }
  202. labelList splitPoints = meshCutter.consistentUnrefinement
  203. (
  204. candidates.toc(),
  205. false
  206. );
  207. Info<< nl << "-- selected "
  208. << returnReduce(splitPoints.size(), sumOp<label>())
  209. << " points out of "
  210. << returnReduce(allSplitPoints.size(), sumOp<label>())
  211. << " for unrefinement" << endl;
  212. // Play refinement commands into mesh changer.
  213. meshCutter.setUnrefinement(splitPoints, meshMod);
  214. }
  215. // Create mesh, return map from old to new mesh.
  216. Info<< nl << "-- actually changing mesh" << endl;
  217. autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh, inflate);
  218. // Update fields
  219. Info<< nl << "-- mapping mesh data" << endl;
  220. mesh.updateMesh(map);
  221. // Inflate mesh
  222. if (map().hasMotionPoints())
  223. {
  224. Info<< nl << "-- moving mesh" << endl;
  225. mesh.movePoints(map().preMotionPoints());
  226. }
  227. // Update numbering of cells/vertices.
  228. Info<< nl << "-- mapping hexRef8 data" << endl;
  229. meshCutter.updateMesh(map);
  230. }
  231. Info<< nl<< "-- Mesh : moving:" << mesh.moving()
  232. << " topoChanging:" << mesh.topoChanging()
  233. << " changing:" << mesh.changing()
  234. << endl;
  235. Info<< "Writing fields" << nl << endl;
  236. runTime.write();
  237. // Check mesh volume conservation
  238. if (mesh.moving())
  239. {
  240. #include "volContinuity.H"
  241. }
  242. else
  243. {
  244. if (mesh.V().size() != mesh.nCells())
  245. {
  246. FatalErrorIn(args.executable())
  247. << "Volume not mapped. V:" << mesh.V().size()
  248. << " nCells:" << mesh.nCells()
  249. << exit(FatalError);
  250. }
  251. const scalar newVol = gSum(mesh.V());
  252. Info<< "Initial volume = " << totalVol
  253. << " New volume = " << newVol
  254. << endl;
  255. if (mag(newVol-totalVol)/totalVol > 1e-10)
  256. {
  257. FatalErrorIn(args.executable())
  258. << "Volume loss: old volume:" << totalVol
  259. << " new volume:" << newVol
  260. << exit(FatalError);
  261. }
  262. else
  263. {
  264. Info<< "Volume check OK" << nl << endl;
  265. }
  266. }
  267. // Check constant profile
  268. {
  269. const scalar max = gMax(one);
  270. const scalar min = gMin(one);
  271. Info<< "Uniform one field min = " << min
  272. << " max = " << max << endl;
  273. if (notEqual(max, 1.0, 1e-10) || notEqual(min, 1.0, 1e-10))
  274. {
  275. FatalErrorIn(args.executable())
  276. << "Uniform volVectorField not preserved."
  277. << " Min and max should both be 1.0. min:" << min
  278. << " max:" << max
  279. << exit(FatalError);
  280. }
  281. else
  282. {
  283. Info<< "Uniform field mapping check OK" << nl << endl;
  284. }
  285. }
  286. // Check linear profile
  287. {
  288. const scalarField diff = ccX-mesh.C().component(0);
  289. const scalar max = gMax(diff);
  290. const scalar min = gMin(diff);
  291. Info<< "Linear profile field min = " << min
  292. << " max = " << max << endl;
  293. if (notEqual(max, 0.0, 1e-10) || notEqual(min, 0.0, 1e-10))
  294. {
  295. Info<< "Linear profile not preserved."
  296. << " Min and max should both be 0.0. min:" << min
  297. << " max:" << max << nl << endl;
  298. }
  299. else
  300. {
  301. Info<< "Linear profile mapping check OK" << nl << endl;
  302. }
  303. }
  304. // Check face field mapping
  305. if (surfaceOne.size())
  306. {
  307. const scalar max = gMax(surfaceOne.internalField());
  308. const scalar min = gMin(surfaceOne.internalField());
  309. Info<< "Uniform surface field min = " << min
  310. << " max = " << max << endl;
  311. if (notEqual(max, 1.0, 1e-10) || notEqual(min, 1.0, 1e-10))
  312. {
  313. FatalErrorIn(args.executable())
  314. << "Uniform surfaceScalarField not preserved."
  315. << " Min and max should both be 1.0. min:" << min
  316. << " max:" << max
  317. << exit(FatalError);
  318. }
  319. else
  320. {
  321. Info<< "Uniform surfaceScalarField mapping check OK" << nl
  322. << endl;
  323. }
  324. }
  325. Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
  326. << " ClockTime = " << runTime.elapsedClockTime() << " s"
  327. << nl << endl;
  328. }
  329. Info<< "pc:" << pc.patchPatchPointConstraintPoints().size() << endl;
  330. Info<< "End\n" << endl;
  331. return 0;
  332. }
  333. // ************************************************************************* //