ccmWriter.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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2016-2020 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*----------------------------------------------------------------------------*/
27 
28 #include "ccmWriter.H"
29 #include "cellModel.H"
30 #include "demandDrivenData.H"
31 #include "ccmInternal.H" // include last to avoid any strange interactions
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 // Name for the topology file reference
37 
38 
39 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
40 
41 // Create a filled linear map with 'size' from 'start + 1'
42 void Foam::ccm::writer::addLinearMap
43 (
44  const string& mapName,
45  ccmID& mapId,
46  label size,
47  label start
48 ) const
49 {
50  if (globalState_->hasError() || size <= 0)
51  {
52  return;
53  }
54 
55  CCMIONewEntity
56  (
57  &(globalState_->error),
58  (globalState_->root),
59  kCCMIOMap,
60  mapName.c_str(),
61  &mapId
62  );
63  assertNoError("creating linearMap '" + mapName + "' node");
64 
65  List<int> data(size);
66  forAll(data, i)
67  {
68  data[i] = start + 1 + i;
69  }
70 
71  CCMIOWriteMap
72  (
73  &(globalState_->error),
74  mapId,
75  size,
76  (start + size),
77  data.begin(),
78  kCCMIOStart,
79  kCCMIOEnd
80  );
81  assertNoError("writing linearMap '" + mapName + "' data");
82 }
83 
84 
85 Foam::label Foam::ccm::writer::findDefaultBoundary() const
86 {
87  return mesh_.boundaryMesh().findPatchID(defaultBoundaryName);
88 }
89 
90 
91 void Foam::ccm::writer::writeBoundaryRegion
92 (
93  const ccmID& probNode
94 ) const
95 {
96  // Create dictionary lookup for constant/boundaryRegion
97  dictionary typeDict;
98 
99  forAllConstIters(boundaryRegion_, iter)
100  {
101  const dictionary& dict = iter();
102  word nameEntry;
103  word typeEntry;
104 
105  if
106  (
107  dict.readIfPresent("Label", nameEntry)
108  && dict.readIfPresent("BoundaryType", typeEntry)
109  && !typeDict.found(nameEntry)
110  )
111  {
112  typeDict.add(nameEntry, typeEntry);
113  }
114  }
115 
116  const polyBoundaryMesh& patches = mesh_.boundaryMesh();
117 
118  label defaultId = findDefaultBoundary();
119 
120  // Force write Default_Boundary_Region as BoundaryRegion-0
121  {
122  ccmID nodeId;
123  CCMIONewIndexedEntity
124  (
125  &(globalState_->error),
126  probNode,
127  kCCMIOBoundaryRegion,
128  0,
129  nullptr,
130  &nodeId
131  );
132  CCMIOWriteOptstr
133  (
134  nullptr,
135  nodeId,
136  "Label",
137  defaultBoundaryName
138  );
139  CCMIOWriteOptstr
140  (
141  nullptr,
142  nodeId,
143  "BoundaryType",
144  "wall"
145  );
146  }
147 
148  forAll(patches, patchI)
149  {
150  word patchName = patches[patchI].name();
151  word patchType = patches[patchI].type();
152 
153  label regionId = patchI;
154  if (regionId == defaultId)
155  {
156  continue; // Skip - already written
157  }
158  else if (defaultId == -1 || regionId < defaultId)
159  {
160  ++regionId;
161  }
162 
163  // Use BoundaryType from constant/boundaryRegion
164  typeDict.readIfPresent(patchName, patchType);
165 
166  ccmID nodeId;
167  CCMIONewIndexedEntity
168  (
169  &(globalState_->error),
170  probNode,
171  kCCMIOBoundaryRegion,
172  regionId,
173  nullptr,
174  &nodeId
175  );
176  CCMIOWriteOptstr
177  (
178  nullptr,
179  nodeId,
180  "Label",
181  patchName.c_str()
182  );
183  CCMIOWriteOptstr
184  (
185  nullptr,
186  nodeId,
187  "BoundaryType",
188  patchType.c_str()
189  );
190  }
191 }
192 
193 
194 void Foam::ccm::writer::writeCellTable
195 (
196  const ccmID& probNode
197 ) const
198 {
199  if (!cellTable_.size())
200  {
201  Info<< "No cellTable" << endl;
202  return;
203  }
204 
205  ccmID nodeId;
206 
207  forAllConstIters(cellTable_, iter)
208  {
209  label intVal = iter.key();
210  const dictionary& dict = iter();
211 
212  CCMIONewIndexedEntity
213  (
214  &(globalState_->error),
215  probNode,
216  kCCMIOCellType,
217  intVal,
218  nullptr,
219  &nodeId
220  );
221 
222  wordList toc = dict.toc();
223  for (const word& keyword : toc)
224  {
225  int pos = keyword.find("Id");
226 
227  // Tags containing 'Id' are integers
228  if (pos > 0)
229  {
230  dict.readEntry(keyword, intVal);
231 
232  CCMIOWriteOpti
233  (
234  nullptr,
235  nodeId,
236  keyword.c_str(),
237  intVal
238  );
239  }
240  else if (pos < 0)
241  {
242  const word strVal(dict.get<word>(keyword));
243 
244  CCMIOWriteOptstr
245  (
246  nullptr,
247  nodeId,
248  keyword.c_str(),
249  strVal.c_str()
250  );
251  }
252  }
253  }
254 }
255 
256 
257 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
258 
259 // Write out problem description
260 void Foam::ccm::writer::writeProblem
261 (
262  const ccmID& stateNode
263 ) const
264 {
265  ccmID probNode;
266  CCMIONewEntity
267  (
268  &(globalState_->error),
269  (globalState_->root),
270  kCCMIOProblemDescription,
271  nullptr,
272  &probNode
273  );
274 
275  writeCellTable(probNode);
276  writeBoundaryRegion(probNode);
277 
278  // let the state know about our problem
279  CCMIOWriteState
280  (
281  &(globalState_->error),
282  stateNode,
283  probNode,
284  nullptr
285  );
286 }
287 
288 
289 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
290 
291 Foam::ccm::writer::writer
292 (
293  const fileName& file,
294  const polyMesh& mesh,
295  const bool backup
296 )
297 :
298  base(),
299  maps_(new ccmMaps),
300  mesh_(mesh),
301  // Mapping between OpenFOAM and PROSTAR primitives
302  prostarShapeLookup_
303  {
304  { cellModel::ref(cellModel::HEX).index(), STARCDCore::starcdHex },
305  { cellModel::ref(cellModel::PRISM).index(), STARCDCore::starcdPrism },
306  { cellModel::ref(cellModel::TET).index(), STARCDCore::starcdTet },
307  { cellModel::ref(cellModel::PYR).index(), STARCDCore::starcdPyr }
308  },
309  boundaryRegion_(mesh),
310  cellTable_(mesh)
311 {
312  // Writing/re-writing existing files is too annoying - start anew
313  if (backup)
314  {
315  if (Foam::mvBak(file))
316  {
317  Info<< "moved existing file -> " << fileName(file + ".bak*") << nl;
318  }
319  }
320  else if (exists(file, false))
321  {
322  Foam::rm(file);
323  Info<< "removed existing file: " << file << nl;
324  }
325 
326  // Reinitialize error state from the return value
327  globalState_->error = CCMIOOpenFile
328  (
329  nullptr,
330  file.c_str(),
331  kCCMIOWrite,
332  &(globalState_->root)
333  );
334  assertNoError("Error opening file for writing");
335 
336  // We always need the cell map
337  addLinearMap
338  (
339  "cell Map",
340  maps_->cells,
341  mesh_.nCells()
342  );
343 
344  // We often need the internalFaces map
345  addLinearMap
346  (
347  "internalFaces Map",
348  maps_->internalFaces,
349  mesh_.nInternalFaces()
350  );
351 
352  const polyBoundaryMesh& patches = mesh_.boundaryMesh();
353  maps_->boundary.setSize(patches.size());
354 
355  // We always need maps for the boundary regions
356  forAll(patches, patchI)
357  {
358  if (patches[patchI].size() > 0)
359  {
360  string mapName = "boundaryMap-" + Foam::name(patchI);
361 
362  addLinearMap
363  (
364  mapName,
365  maps_->boundary[patchI],
366  patches[patchI].size(),
367  patches[patchI].start()
368  );
369  }
370  }
371 }
372 
373 
374 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
375 
377 {
378  close();
379 }
380 
381 
382 // ************************************************************************* //
Foam::exists
bool exists(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist (as DIRECTORY or FILE) in the file system?
Definition: MSwindows.C:625
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
demandDrivenData.H
Template functions to aid in the implementation of demand driven data.
Foam::cellModel::HEX
hex
Definition: cellModel.H:81
Foam::ccm::base::globalState_
std::unique_ptr< ccmGlobalState > globalState_
Maintain overall global states (error, root-node)
Definition: ccmBase.H:69
Foam::ccm::writer::defaultMeshName
static string defaultMeshName
The name for the topology file reference.
Definition: ccmWriter.H:217
Foam::rm
bool rm(const fileName &file)
Remove a file (or its gz equivalent), returning true if successful.
Definition: MSwindows.C:994
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::ccm::base::assertNoError
static bool assertNoError(int err, const char *msg)
Die with msg if there is an error.
Definition: ccmBase.C:35
Foam::string
A class for handling character strings derived from std::string.
Definition: string.H:73
Foam::cellModel::TET
tet
Definition: cellModel.H:85
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::wordList
List< word > wordList
A List of words.
Definition: fileName.H:59
cellModel.H
Foam::ccm::writer::~writer
~writer()
Destructor (closes file)
Definition: ccmWriter.C:376
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
ccmInternal.H
Internal bits for wrapping libccmio - do not use directly.
Foam::cellModel::PRISM
prism
Definition: cellModel.H:83
Foam::cellModel::ref
static const cellModel & ref(const modelType model)
Look up reference to cellModel by enumeration. Fatal on failure.
Definition: cellModels.C:157
dict
dictionary dict
Definition: searchingEngine.H:14
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
ccmWriter.H
Foam::mvBak
bool mvBak(const fileName &src, const std::string &ext="bak")
Rename to a corresponding backup file.
Definition: MSwindows.C:958
Foam::cellModel::PYR
pyr
Definition: cellModel.H:84
Foam::nl
constexpr char nl
Definition: Ostream.H:385
forAllConstIters
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
patches
const polyBoundaryMesh & patches
Definition: convertProcessorPatches.H:65
Foam::cellModel::index
label index() const
Return index of model in the model list.
Definition: cellModelI.H:36
Foam::ccm::base
Base functionality common to reader and writer classes.
Definition: ccmBase.H:62
Foam::pos
dimensionedScalar pos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:177