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-2018 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 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 // Name for the topology file reference
38 
39 
40 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
41 
42 // Create a filled linear map with 'size' from 'start + 1'
43 void Foam::ccm::writer::addLinearMap
44 (
45  const string& mapName,
46  ccmID& mapId,
47  label size,
48  label start
49 ) const
50 {
51  if (globalState_->hasError() || size <= 0)
52  {
53  return;
54  }
55 
56  CCMIONewEntity
57  (
58  &(globalState_->error),
59  (globalState_->root),
60  kCCMIOMap,
61  mapName.c_str(),
62  &mapId
63  );
64  assertNoError("creating linearMap '" + mapName + "' node");
65 
66  List<int> data(size);
67  forAll(data, i)
68  {
69  data[i] = start + 1 + i;
70  }
71 
72  CCMIOWriteMap
73  (
74  &(globalState_->error),
75  mapId,
76  size,
77  (start + size),
78  data.begin(),
79  kCCMIOStart,
80  kCCMIOEnd
81  );
82  assertNoError("writing linearMap '" + mapName + "' data");
83 }
84 
85 
86 Foam::label Foam::ccm::writer::findDefaultBoundary() const
87 {
88  return mesh_.boundaryMesh().findPatchID(defaultBoundaryName);
89 }
90 
91 
92 void Foam::ccm::writer::writeBoundaryRegion
93 (
94  const ccmID& probNode
95 ) const
96 {
97  // Create dictionary lookup for constant/boundaryRegion
98  dictionary typeDict;
99 
100  forAllConstIters(boundaryRegion_, iter)
101  {
102  const dictionary& dict = iter();
103  word nameEntry;
104  word typeEntry;
105 
106  if
107  (
108  dict.readIfPresent("Label", nameEntry)
109  && dict.readIfPresent("BoundaryType", typeEntry)
110  && !typeDict.found(nameEntry)
111  )
112  {
113  typeDict.add(nameEntry, typeEntry);
114  }
115  }
116 
117  const polyBoundaryMesh& patches = mesh_.boundaryMesh();
118 
119  label defaultId = findDefaultBoundary();
120 
121  // Force write Default_Boundary_Region as BoundaryRegion-0
122  {
123  ccmID nodeId;
124  CCMIONewIndexedEntity
125  (
126  &(globalState_->error),
127  probNode,
128  kCCMIOBoundaryRegion,
129  0,
130  nullptr,
131  &nodeId
132  );
133  CCMIOWriteOptstr
134  (
135  nullptr,
136  nodeId,
137  "Label",
138  defaultBoundaryName
139  );
140  CCMIOWriteOptstr
141  (
142  nullptr,
143  nodeId,
144  "BoundaryType",
145  "wall"
146  );
147  }
148 
149  forAll(patches, patchI)
150  {
151  word patchName = patches[patchI].name();
152  word patchType = patches[patchI].type();
153 
154  label regionId = patchI;
155  if (regionId == defaultId)
156  {
157  continue; // Skip - already written
158  }
159  else if (defaultId == -1 || regionId < defaultId)
160  {
161  ++regionId;
162  }
163 
164  // Use BoundaryType from constant/boundaryRegion
165  typeDict.readIfPresent(patchName, patchType);
166 
167  ccmID nodeId;
168  CCMIONewIndexedEntity
169  (
170  &(globalState_->error),
171  probNode,
172  kCCMIOBoundaryRegion,
173  regionId,
174  nullptr,
175  &nodeId
176  );
177  CCMIOWriteOptstr
178  (
179  nullptr,
180  nodeId,
181  "Label",
182  patchName.c_str()
183  );
184  CCMIOWriteOptstr
185  (
186  nullptr,
187  nodeId,
188  "BoundaryType",
189  patchType.c_str()
190  );
191  }
192 }
193 
194 
195 void Foam::ccm::writer::writeCellTable
196 (
197  const ccmID& probNode
198 ) const
199 {
200  if (!cellTable_.size())
201  {
202  Info<< "No cellTable" << endl;
203  return;
204  }
205 
206  ccmID nodeId;
207 
208  forAllConstIters(cellTable_, iter)
209  {
210  label intVal = iter.key();
211  const dictionary& dict = iter();
212 
213  CCMIONewIndexedEntity
214  (
215  &(globalState_->error),
216  probNode,
217  kCCMIOCellType,
218  intVal,
219  nullptr,
220  &nodeId
221  );
222 
223  wordList toc = dict.toc();
224  for (const word& keyword : toc)
225  {
226  int pos = keyword.find("Id");
227 
228  // Tags containing 'Id' are integers
229  if (pos > 0)
230  {
231  dict.readEntry(keyword, intVal);
232 
233  CCMIOWriteOpti
234  (
235  nullptr,
236  nodeId,
237  keyword.c_str(),
238  intVal
239  );
240  }
241  else if (pos < 0)
242  {
243  const word strVal(dict.get<word>(keyword));
244 
245  CCMIOWriteOptstr
246  (
247  nullptr,
248  nodeId,
249  keyword.c_str(),
250  strVal.c_str()
251  );
252  }
253  }
254  }
255 }
256 
257 
258 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
259 
260 // Write out problem description
261 void Foam::ccm::writer::writeProblem
262 (
263  const ccmID& stateNode
264 ) const
265 {
266  ccmID probNode;
267  CCMIONewEntity
268  (
269  &(globalState_->error),
270  (globalState_->root),
271  kCCMIOProblemDescription,
272  nullptr,
273  &probNode
274  );
275 
276  writeCellTable(probNode);
277  writeBoundaryRegion(probNode);
278 
279  // let the state know about our problem
280  CCMIOWriteState
281  (
282  &(globalState_->error),
283  stateNode,
284  probNode,
285  nullptr
286  );
287 }
288 
289 
290 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
291 
292 Foam::ccm::writer::writer
293 (
294  const fileName& file,
295  const polyMesh& mesh,
296  const bool backup
297 )
298 :
299  base(),
300  maps_(new ccmMaps),
301  mesh_(mesh),
302  // Mapping between OpenFOAM and PROSTAR primitives
303  prostarShapeLookup_
304  {
305  { cellModel::ref(cellModel::HEX).index(), STARCDCore::starcdHex },
306  { cellModel::ref(cellModel::PRISM).index(), STARCDCore::starcdPrism },
307  { cellModel::ref(cellModel::TET).index(), STARCDCore::starcdTet },
308  { cellModel::ref(cellModel::PYR).index(), STARCDCore::starcdPyr }
309  },
310  boundaryRegion_(mesh),
311  cellTable_(mesh)
312 {
313  // Writing/re-writing existing files is too annoying - start anew
314  if (backup)
315  {
316  if (Foam::mvBak(file))
317  {
318  Info<< "moved existing file -> " << fileName(file + ".bak*") << nl;
319  }
320  }
321  else if (exists(file, false))
322  {
323  Foam::rm(file);
324  Info<< "removed existing file: " << file << nl;
325  }
326 
327  // Reinitialize error state from the return value
328  globalState_->error = CCMIOOpenFile
329  (
330  nullptr,
331  file.c_str(),
332  kCCMIOWrite,
333  &(globalState_->root)
334  );
335  assertNoError("Error opening file for writing");
336 
337  // We always need the cell map
338  addLinearMap
339  (
340  "cell Map",
341  maps_->cells,
342  mesh_.nCells()
343  );
344 
345  // We often need the internalFaces map
346  addLinearMap
347  (
348  "internalFaces Map",
349  maps_->internalFaces,
350  mesh_.nInternalFaces()
351  );
352 
353  const polyBoundaryMesh& patches = mesh_.boundaryMesh();
354  maps_->boundary.setSize(patches.size());
355 
356  // We always need maps for the boundary regions
357  forAll(patches, patchI)
358  {
359  if (patches[patchI].size() > 0)
360  {
361  string mapName = "boundaryMap-" + Foam::name(patchI);
362 
363  addLinearMap
364  (
365  mapName,
366  maps_->boundary[patchI],
367  patches[patchI].size(),
368  patches[patchI].start()
369  );
370  }
371  }
372 }
373 
374 
375 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
376 
378 {
379  close();
380 
381  deleteDemandDrivenData(maps_);
382 }
383 
384 
385 // ************************************************************************* //
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::writer::defaultMeshName
static string defaultMeshName
The name for the topology file reference.
Definition: ccmWriter.H:217
Foam::ccm::base::globalState_
ccmGlobalState * globalState_
Maintain overall global states (error, root-node)
Definition: ccmBase.H:78
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:337
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:290
Foam::wordList
List< word > wordList
A List of words.
Definition: fileName.H:59
Foam::deleteDemandDrivenData
void deleteDemandDrivenData(DataPtr &dataPtr)
Definition: demandDrivenData.H:42
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:62
cellModel.H
Foam::ccm::writer::~writer
~writer()
Destructor (closes file)
Definition: ccmWriter.C:377
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:372
forAllConstIters
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
Foam::start
label ListType::const_reference const label start
Definition: ListOps.H:408
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