FreeFOAM The Cross-Platform CFD Toolkit
polyTopoChanger.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) 1991-2010 OpenCFD Ltd.
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 "polyTopoChanger.H"
27 #include <OpenFOAM/polyMesh.H>
29 #include <OpenFOAM/Time.H>
30 
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
35  defineTypeNameAndDebug(polyTopoChanger, 0);
36 }
37 
38 
39 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
40 
41 void Foam::polyTopoChanger::readModifiers()
42 {
43  if
44  (
47  )
48  {
49  PtrList<polyMeshModifier>& modifiers = *this;
50 
51  // Read modifiers
52  Istream& is = readStream(typeName);
53 
54  PtrList<entry> patchEntries(is);
55  modifiers.setSize(patchEntries.size());
56 
57  forAll(modifiers, modifierI)
58  {
59  modifiers.set
60  (
61  modifierI,
63  (
64  patchEntries[modifierI].keyword(),
65  patchEntries[modifierI].dict(),
66  modifierI,
67  *this
68  )
69  );
70  }
71 
72  // Check state of IOstream
73  is.check
74  (
75  "polyTopoChanger::polyTopoChanger"
76  "(const IOobject&, const polyMesh&)"
77  );
78 
79  close();
80  }
81 }
82 
83 
84 // Read constructor given IOobject and a polyMesh reference
85 Foam::polyTopoChanger::polyTopoChanger
86 (
87  const IOobject& io,
88  polyMesh& mesh
89 )
90 :
92  regIOobject(io),
93  mesh_(mesh)
94 {
95  readModifiers();
96 }
97 
98 
99 // Read constructor given IOobject and a polyMesh reference
100 Foam::polyTopoChanger::polyTopoChanger(polyMesh& mesh)
101 :
104  (
105  IOobject
106  (
107  "meshModifiers",
108  mesh.time().findInstance
109  (
110  mesh.meshDir(),
111  "meshModifiers",
112  IOobject::READ_IF_PRESENT
113  ),
114  mesh.meshSubDir,
115  mesh,
116  IOobject::READ_IF_PRESENT,
117  IOobject::NO_WRITE
118  )
119  ),
120  mesh_(mesh)
121 {
122  readModifiers();
123 }
124 
125 
126 // Return a list of modifier types
128 {
129  const PtrList<polyMeshModifier>& modifiers = *this;
130 
131  wordList t(modifiers.size());
132 
133  forAll (modifiers, modifierI)
134  {
135  t[modifierI] = modifiers[modifierI].type();
136  }
137 
138  return t;
139 }
140 
141 
142 // Return a list of modifier names
144 {
145  const PtrList<polyMeshModifier>& modifiers = *this;
146 
147  wordList t(modifiers.size());
148 
149  forAll (modifiers, modifierI)
150  {
151  t[modifierI] = modifiers[modifierI].name();
152  }
153 
154  return t;
155 }
156 
157 
158 // Is topology change required
160 {
161  // Go through all mesh modifiers and accumulate the morphing information
162  const PtrList<polyMeshModifier>& topoChanges = *this;
163 
164  bool triggerChange = false;
165 
166  forAll (topoChanges, morphI)
167  {
168  if (topoChanges[morphI].active())
169  {
170  bool curTriggerChange = topoChanges[morphI].changeTopology();
171 
172  if (debug)
173  {
174  Info<< "Modifier " << morphI << " named "
175  << topoChanges[morphI].name();
176 
177  if (curTriggerChange)
178  {
179  Info << " morphing" << endl;
180  }
181  else
182  {
183  Info << " unchanged" << endl;
184  }
185  }
186 
187  triggerChange = triggerChange || curTriggerChange;
188  }
189  else
190  {
191  if (debug)
192  {
193  Info<< "Modifier " << morphI << " named "
194  << topoChanges[morphI].name() << " inactive" << endl;
195  }
196  }
197 
198  }
199 
200  return triggerChange;
201 }
202 
203 
204 // Return topology change request
207 {
208  // Collect changes from all modifiers
209  const PtrList<polyMeshModifier>& topoChanges = *this;
210 
211  polyTopoChange* refPtr(new polyTopoChange(mesh()));
212  polyTopoChange& ref = *refPtr;
213 
214  forAll (topoChanges, morphI)
215  {
216  if (topoChanges[morphI].active())
217  {
218  topoChanges[morphI].setRefinement(ref);
219  }
220  }
221 
222  return autoPtr<polyTopoChange>(refPtr);
223 }
224 
225 
226 // Correct polyTopoChanger after moving points
228 {
229  const PtrList<polyMeshModifier>& topoChanges = *this;
230 
231  forAll (topoChanges, morphI)
232  {
233  if (topoChanges[morphI].active())
234  {
235  topoChanges[morphI].modifyMotionPoints(p);
236  }
237  }
238 }
239 
240 
241 // Force recalculation of locally stored data on topological change
243 {
244  // Go through all mesh modifiers and accumulate the morphing information
245  PtrList<polyMeshModifier>& topoChanges = *this;
246 
247  forAll (topoChanges, morphI)
248  {
249  topoChanges[morphI].updateMesh(m);
250  }
251 
252  // Force the mesh modifiers to auto-write. This allows us to
253  // preserve the current state of modifiers corresponding with
254  // the mesh.
255  writeOpt() = IOobject::AUTO_WRITE;
256  instance() = mesh_.time().timeName();
257 }
258 
259 
261 (
262  const bool inflate,
263  const bool syncParallel,
264  const bool orderCells,
265  const bool orderPoints
266 )
267 {
268  if (changeTopology())
269  {
270  autoPtr<polyTopoChange> ref = topoChangeRequest();
271 
272  autoPtr<mapPolyMesh> topoChangeMap = ref().changeMesh
273  (
274  mesh_,
275  inflate,
276  syncParallel,
277  orderCells,
278  orderPoints
279  );
280 
281  update(topoChangeMap());
282  mesh_.updateMesh(topoChangeMap());
283  return topoChangeMap;
284  }
285  else
286  {
287  return autoPtr<mapPolyMesh>(NULL);
288  }
289 }
290 
291 
292 // Add mesh modifiers to the morph engine
294 (
295  const List<polyMeshModifier*>& tm
296 )
297 {
298  setSize(tm.size());
299 
300  // Copy the patch pointers
301  forAll (tm, tmI)
302  {
303  if (tm[tmI]->topoChanger() != *this)
304  {
306  (
307  "void polyTopoChanger::addTopologyModifiers("
308  "const List<polyMeshModifier*>& tm)"
309  ) << "Mesh modifier created with different mesh reference."
310  << abort(FatalError);
311  }
312  set(tmI, tm[tmI]);
313  }
314 
315  writeOpt() = IOobject::AUTO_WRITE;
316 }
317 
318 
320 (
321  const word& modName
322 ) const
323 {
324  const PtrList<polyMeshModifier>& topoChanges = *this;
325 
326  forAll (topoChanges, morphI)
327  {
328  if (topoChanges[morphI].name() == modName)
329  {
330  return morphI;
331  }
332  }
333 
334  // Modifier not found
335  if (debug)
336  {
337  Info<< "label polyTopoChanger::::findModifierID(const word& "
338  << "modName) const"
339  << "Modifier named " << modName << " not found. "
340  << "List of available modifier names: " << names() << endl;
341  }
342 
343  // Not found, return -1
344  return -1;
345 }
346 
347 
348 // writeData member function required by regIOobject
350 {
351  os << *this;
352  return os.good();
353 }
354 
355 
356 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
357 
359 {
360  return &me != this;
361 }
362 
363 
365 {
366  return &me == this;
367 }
368 
369 
370 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
371 
373 {
374  os << mme.size() << nl << token::BEGIN_LIST;
375 
376  forAll(mme, mmeI)
377  {
378  mme[mmeI].writeDict(os);
379  }
380 
381  os << token::END_LIST;
382 
383  return os;
384 }
385 
386 
387 // ************************ vim: set sw=4 sts=4 et: ************************ //