vtkPVblockMesh.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) 2011-2025 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 "vtkPVblockMesh.H"
27 #include "vtkPVblockMeshReader.h"
28 
29 // OpenFOAM includes
30 #include "blockMesh.H"
31 #include "Time.H"
32 #include "patchZones.H"
33 #include "OStringStream.H"
34 #include "OSspecific.H"
35 
36 // VTK includes
37 #include "vtkDataArraySelection.h"
38 #include "vtkMultiBlockDataSet.h"
39 #include "vtkRenderer.h"
40 #include "vtkTextActor.h"
41 #include "vtkTextProperty.h"
42 
43 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
44 
45 namespace Foam
46 {
47  defineTypeNameAndDebug(vtkPVblockMesh, 0);
48 }
49 
50 
51 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
52 
53 void Foam::vtkPVblockMesh::resetCounters()
54 {
55  // Reset mesh part ids and sizes
56  arrayRangeBlocks_.reset();
57  arrayRangeEdges_.reset();
58  arrayRangeCorners_.reset();
59 }
60 
61 
62 void Foam::vtkPVblockMesh::updateInfoBlocks
63 (
64  vtkDataArraySelection* arraySelection
65 )
66 {
68 
69  if (!meshPtr_.valid()) return;
70 
71  arrayRangeBlocks_.reset(arraySelection->GetNumberOfArrays());
72 
73  const blockMesh& blkMesh = *meshPtr_;
74 
75  const int nBlocks = blkMesh.size();
76  for (int blockI = 0; blockI < nBlocks; ++blockI)
77  {
78  const blockDescriptor& blockDef = blkMesh[blockI];
79 
80  // Display either blockI as a number or with its name
81  // (looked up from blockMeshDict)
82  OStringStream os;
83  blockDescriptor::write(os, blockI, blkMesh.meshDict());
84  word partName(os.str());
85 
86  // append the (optional) zone name
87  if (!blockDef.zoneName().empty())
88  {
89  partName += " - " + blockDef.zoneName();
90  }
91 
92  // Add blockId and zoneName to GUI list
93  arraySelection->AddArray(partName.c_str());
94  }
95 
96  arrayRangeBlocks_ += nBlocks;
97 
98  if (debug) getSelectedArrayEntries(arraySelection);
99 }
100 
101 
102 void Foam::vtkPVblockMesh::updateInfoEdges
103 (
104  vtkDataArraySelection* arraySelection
105 )
106 {
108 
109  if (!meshPtr_.valid()) return;
110 
111  arrayRangeEdges_.reset(arraySelection->GetNumberOfArrays());
112 
113  const blockMesh& blkMesh = *meshPtr_;
114  const blockEdgeList& edges = blkMesh.edges();
115 
116  const int nEdges = edges.size();
117  forAll(edges, edgeI)
118  {
119  OStringStream ostr;
120  blockVertex::write(ostr, edges[edgeI].start(), blkMesh.meshDict());
121  ostr<< ":";
122  blockVertex::write(ostr, edges[edgeI].end(), blkMesh.meshDict());
123  ostr << " - " << edges[edgeI].type();
124 
125  // Add "beg:end - type" to GUI list
126  arraySelection->AddArray(ostr.str().c_str());
127  }
128 
129  arrayRangeEdges_ += nEdges;
130 
131  if (debug) getSelectedArrayEntries(arraySelection);
132 }
133 
134 
135 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
136 
138 (
139  const char* const FileName,
140  vtkPVblockMeshReader* reader
141 )
142 :
143  reader_(reader),
144  dbPtr_(nullptr),
145  meshPtr_(nullptr),
146  meshRegion_(polyMesh::defaultRegion),
147  meshDir_(polyMesh::meshSubDir),
148  arrayRangeBlocks_("block"),
149  arrayRangeEdges_("edges"),
150  arrayRangeCorners_("corners")
151 {
153  << "fileName=" << FileName << endl;
154 
155  // Avoid argList and get rootPath/caseName directly from the file
156  fileName fullCasePath(fileName(FileName).path());
157 
158  if (!isDir(fullCasePath)) return;
159 
160  if (fullCasePath == ".")
161  {
162  fullCasePath = cwd();
163  }
164 
165  if (fullCasePath.name().find("processor", 0) == 0)
166  {
167  const fileName globalCase = fullCasePath.path();
168 
169  setEnv("FOAM_CASE", globalCase, true);
170  setEnv("FOAM_CASENAME", globalCase.name(), true);
171  }
172  else
173  {
174  setEnv("FOAM_CASE", fullCasePath, true);
175  setEnv("FOAM_CASENAME", fullCasePath.name(), true);
176  }
177 
178  // Look for 'case{region}.OpenFOAM'
179  // could be stringent and insist the prefix match the directory name...
180  // Note: cannot use fileName::name() due to the embedded '{}'
181  string caseName(fileName(FileName).lessExt());
182  string::size_type beg = caseName.find_last_of("/{");
183  string::size_type end = caseName.find('}', beg);
184 
185  if
186  (
187  beg != string::npos && caseName[beg] == '{'
188  && end != string::npos && end == caseName.size()-1
189  )
190  {
191  meshRegion_ = caseName.substr(beg+1, end-beg-1);
192 
193  // Some safety
194  if (meshRegion_.empty())
195  {
196  meshRegion_ = polyMesh::defaultRegion;
197  }
198 
199  if (meshRegion_ != polyMesh::defaultRegion)
200  {
201  meshDir_ = meshRegion_/polyMesh::meshSubDir;
202  }
203  }
204 
205  DebugInfo
206  << " fullCasePath=" << fullCasePath << nl
207  << " FOAM_CASE=" << getEnv("FOAM_CASE") << nl
208  << " FOAM_CASENAME=" << getEnv("FOAM_CASENAME") << nl
209  << " region=" << meshRegion_ << endl;
210 
211  // Create time object
212  dbPtr_.reset
213  (
214  new Time
215  (
216  Time::controlDictName,
217  fileName(fullCasePath.path()),
218  fileName(fullCasePath.name()),
219  false
220  )
221  );
222 
223  updateInfo();
224 }
225 
226 
227 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
228 
230 {
231  forAll(pointNumberTextActorsPtrs_, pointi)
232  {
233  pointNumberTextActorsPtrs_[pointi]->Delete();
234  }
235  pointNumberTextActorsPtrs_.clear();
236 }
237 
238 
239 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
240 
242 {
244 
245  resetCounters();
246 
247  vtkDataArraySelection* blockSelection = reader_->GetBlockSelection();
248  vtkDataArraySelection* edgeSelection = reader_->GetCurvedEdgesSelection();
249 
250  // Determine whether or not this is the first update
251  const bool first =
252  !blockSelection->GetNumberOfArrays() && !meshPtr_.valid();
253 
254  // Preserve the enabled selections if this is not the first call
255  stringList enabledBlocks, enabledEdges;
256  if (!first)
257  {
258  enabledBlocks = getSelectedArrayEntries(blockSelection, false);
259  enabledEdges = getSelectedArrayEntries(edgeSelection, false);
260  }
261 
262  // Clear current mesh parts list
263  blockSelection->RemoveAllArrays();
264  edgeSelection->RemoveAllArrays();
265 
266  // Need a blockMesh
267  updateFoamMesh();
268 
269  // Update mesh parts list
270  updateInfoBlocks(blockSelection);
271 
272  // Update curved edges list
273  updateInfoEdges(edgeSelection);
274 
275  // Restore the enabled selections if this is not the first call
276  if (!first)
277  {
278  setSelectedArrayEntries(blockSelection, enabledBlocks);
279  setSelectedArrayEntries(edgeSelection, enabledEdges);
280  }
281 }
282 
283 
284 void Foam::vtkPVblockMesh::updateFoamMesh()
285 {
287 
290 
291  autoPtr<blockMesh> newMeshPtr;
292 
293  try
294  {
295  // Set path for the blockMeshDict
296  const word dictName("blockMeshDict");
297  fileName dictPath(dbPtr_().system()/dictName);
298 
299  // Check if dictionary is present in the constant directory
300  if
301  (
302  exists
303  (
304  dbPtr_().path()/dbPtr_().constant()
305  /polyMesh::meshSubDir/dictName
306  )
307  )
308  {
309  dictPath = dbPtr_().constant()/polyMesh::meshSubDir/dictName;
310  }
311 
312  // Store dictionary since is used as database inside blockMesh class
313  // for names of vertices and blocks
314  IOdictionary* meshDictPtr = new IOdictionary
315  (
316  IOobject
317  (
318  dictPath,
319  dbPtr_(),
322  true
323  )
324  );
325  meshDictPtr->store();
326 
327  newMeshPtr.set
328  (
329  new blockMesh
330  (
331  *meshDictPtr,
332  dbPtr_().constant(),
333  meshRegion_
334  )
335  );
336 
337  meshPtr_.reset(newMeshPtr.ptr());
338  }
339  catch (IOerror& err)
340  {
341  OStringStream oss;
342  oss << err;
343  vtkErrorWithObjectMacro(reader_, << oss.str().c_str());
344  }
345  catch (error& err)
346  {
347  OStringStream oss;
348  oss << err;
349  vtkErrorWithObjectMacro(reader_, << oss.str().c_str());
350  }
351 
354 }
355 
356 
358 (
359  vtkMultiBlockDataSet* output
360 )
361 {
363 
364  reader_->UpdateProgress(0.2);
365 
366  // Set up mesh parts selection(s)
367  updateBoolListStatus(blockStatus_, reader_->GetBlockSelection());
368 
369  // Set up curved edges selection(s)
370  updateBoolListStatus(edgeStatus_, reader_->GetCurvedEdgesSelection());
371 
372  reader_->UpdateProgress(0.5);
373 
374  // Convert mesh element
375  int blockNo = 0;
376 
377  convertMeshCorners(output, blockNo);
378  convertMeshBlocks(output, blockNo);
379  convertMeshEdges(output, blockNo);
380 
381  reader_->UpdateProgress(0.8);
382 }
383 
384 
386 {
388 
389  reader_->UpdateProgress(1.0);
390 }
391 
392 
394 (
395  vtkRenderer* renderer,
396  const bool show
397 )
398 {
400 
401  // Always remove old actors first
402  forAll(pointNumberTextActorsPtrs_, pointi)
403  {
404  renderer->RemoveViewProp(pointNumberTextActorsPtrs_[pointi]);
405  pointNumberTextActorsPtrs_[pointi]->Delete();
406  }
407  pointNumberTextActorsPtrs_.clear();
408 
409  // If not showing then then removing old actors is all we need to do
410  if (!show) return;
411 
412  if (!meshPtr_.valid()) return;
413 
414  const blockMesh& blkMesh = *meshPtr_;
415  const pointField& cornerPts = blkMesh.vertices();
416  const scalar scaleFactor = blkMesh.scaleFactor();
417 
418  pointNumberTextActorsPtrs_.setSize(cornerPts.size());
419  forAll(cornerPts, pointi)
420  {
421  vtkTextActor* txt = vtkTextActor::New();
422 
423  // Display either pointi as a number or with its name
424  // (looked up from blockMeshDict)
425  {
426  OStringStream os;
427  blockVertex::write(os, pointi, blkMesh.meshDict());
428  txt->SetInput(os.str().c_str());
429  }
430 
431  // Set text properties
432  vtkTextProperty* tprop = txt->GetTextProperty();
433  tprop->SetFontFamilyToArial();
434  tprop->BoldOn();
435  tprop->ShadowOff();
436  tprop->SetLineSpacing(1.0);
437  tprop->SetFontSize(14);
438  tprop->SetColor(1.0, 0.0, 1.0);
439  tprop->SetJustificationToCentered();
440 
441  // Set text to use 3-D world co-ordinates
442  txt->GetPositionCoordinate()->SetCoordinateSystemToWorld();
443 
444  txt->GetPositionCoordinate()->SetValue
445  (
446  cornerPts[pointi].x()*scaleFactor,
447  cornerPts[pointi].y()*scaleFactor,
448  cornerPts[pointi].z()*scaleFactor
449  );
450 
451  // Add text to each renderer
452  renderer->AddViewProp(txt);
453 
454  // Maintain a list of text labels added so that they can be
455  // removed later
456  pointNumberTextActorsPtrs_[pointi] = txt;
457  }
458 }
459 
460 
461 void Foam::vtkPVblockMesh::PrintSelf(ostream& os, vtkIndent indent) const
462 {
463  os << indent << "Number of nodes: "
464  << (meshPtr_.valid() ? meshPtr_->vertices().size() : 0) << "\n";
465 
466  os << indent << "Number of cells: "
467  << (meshPtr_.valid() ? meshPtr_->cells().size() : 0) << "\n";
468 
469  os << indent << "Number of available time steps: "
470  << (dbPtr_.valid() ? dbPtr_().times().size() : 0) << "\n";
471 }
472 
473 
474 // ************************************************************************* //
scalar y
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
graph_traits< Graph >::vertices_size_type size_type
Definition: SloanRenumber.C:73
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
@ MUST_READ_IF_MODIFIED
Definition: IOobject.H:119
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:125
void setSize(const label)
Reset size of List.
Definition: List.C:281
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29
static void write(Ostream &, const label blocki, const dictionary &)
Write block index with dictionary lookup.
static void write(Ostream &, const label, const dictionary &)
Write vertex index with optional name backsubstitution.
Definition: blockVertex.C:120
void throwExceptions()
Definition: error.H:115
void dontThrowExceptions()
Definition: error.H:120
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:263
~vtkPVblockMesh()
Destructor.
void Update(vtkMultiBlockDataSet *output)
Update.
void PrintSelf(ostream &, vtkIndent) const
Debug information.
void CleanUp()
Clean any storage.
void renderPointNumbers(vtkRenderer *, const bool show)
Add/remove point numbers to/from the view.
vtkPVblockMesh(const char *const FileName, vtkPVblockMeshReader *reader)
Construct from components.
void updateInfo()
Update information.
#define DebugInfo
Report an information message using Foam::Info.
#define DebugInFunction
Report an information message using Foam::Info.
Namespace for OpenFOAM.
fileName cwd()
Return current working directory path name.
Definition: POSIX.C:241
int system(const std::string &command)
Execute the specified command.
Definition: POSIX.C:1230
bool setEnv(const word &name, const std::string &value, const bool overwrite)
Set an environment variable.
Definition: POSIX.C:115
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
bool exists(const fileName &, const bool checkVariants=true, const bool followLink=true)
Does the name exist (as directory or file) in the file system?
Definition: POSIX.C:520
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
labelList first(const UList< labelPair > &p)
Definition: patchToPatch.C:39
PtrList< blockEdge > blockEdgeList
A PtrList of blockEdges.
Definition: blockEdgeList.H:45
bool isDir(const fileName &, const bool followLink=true)
Does the name exist as a directory in the file system?
Definition: POSIX.C:539
string getEnv(const word &)
Return environment variable of given name.
Definition: POSIX.C:97
IOerror FatalIOError
error FatalError
List< string > stringList
A List of strings.
Definition: stringList.H:50
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:243
tmp< DimensionedField< TypeR, GeoMesh, Field > > New(const tmp< DimensionedField< TypeR, GeoMesh, Field >> &tdf1, const word &name, const dimensionSet &dimensions)
static const char nl
Definition: Ostream.H:297