lumpedPointMovement.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-2021 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 Application
27  lumpedPointMovement
28 
29 Description
30  This utility can be used to produce VTK files to visualize the response
31  points/rotations and the corresponding movement of the building surfaces.
32 
33  Uses the tabulated responses from the specified file.
34  Optionally, it can also be used to a dummy responder for the
35  externalFileCoupler logic, which makes it useful as a debugging facility
36  as well demonstrating how an external application could communicate
37  with the lumpedPointMovement point-patch boundary condition.
38 
39 \*---------------------------------------------------------------------------*/
40 
41 #include "argList.H"
42 #include "Time.H"
43 #include "OFstream.H"
44 #include "foamVtkSeriesWriter.H"
45 #include "lumpedPointTools.H"
46 #include "lumpedPointIOMovement.H"
47 
48 using namespace Foam;
49 
50 
51 inline List<lumpedPointStateTuple> getResponseTable
52 (
53  const fileName& file,
54  const lumpedPointState& state0
55 )
56 {
58  (
59  file,
60  state0.rotationOrder(),
61  state0.degrees()
62  );
63 }
64 
65 
66 void echoTableLimits
67 (
68  const List<lumpedPointStateTuple>& tbl,
69  const label span,
70  const label maxOut
71 )
72 {
73  Info<< "Using response table with " << tbl.size() << " entries" << nl;
74 
75  if (span)
76  {
77  Info<< "Increment input by " << span << nl;
78  }
79 
80  if (maxOut)
81  {
82  Info<< "Stopping after " << maxOut << " outputs" << nl;
83  }
84 }
85 
86 
87 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
88 
89 int main(int argc, char *argv[])
90 {
92  (
93  "Visualize lumpedPoint movements or provide a slave responder"
94  " for diagnostic purposes."
95  );
96 
97  argList::noFunctionObjects(); // Never use function objects
99  (
100  "max",
101  "N",
102  "Maximum number of outputs"
103  );
105  (
106  "span",
107  "N",
108  "Increment each input by N (default: 1)"
109  );
111  (
112  "scale",
113  "factor",
114  "Relaxation/scaling factor for movement (default: 1)"
115  );
117  (
118  "visual-length",
119  "len",
120  "Visualization length for planes (visualized as triangles)"
121  );
123  (
124  "Test movement without a mesh"
125  );
127  (
128  "removeLock",
129  "Remove lock-file on termination of slave"
130  );
132  (
133  "slave",
134  "Invoke as a slave responder for testing"
135  );
136  argList::addArgument("responseFile");
137 
138  #include "setRootCase.H"
139 
140  const label maxOut = Foam::max(0, args.getOrDefault<label>("max", 0));
141  const label span = Foam::max(1, args.getOrDefault<label>("span", 1));
142 
143  // Control parameters
144  const bool dryrun = args.dryRun();
145  const bool slave = args.found("slave");
146  const bool removeLock = args.found("removeLock");
147 
148  const scalar relax = args.getOrDefault<scalar>("scale", 1);
149 
151 
152  const auto responseFile = args.get<fileName>(1);
153 
154  // ----------------------------------------------------------------------
155  // Slave mode
156  // ----------------------------------------------------------------------
157 
158  if (slave)
159  {
160  Info<< "Running as slave responder" << endl;
161 
162  if (Pstream::parRun())
163  {
165  << "Running as slave responder is not permitted in parallel"
166  << nl
167  << exit(FatalError);
168  }
169 
170  #include "createTime.H"
171 
172  // Create movement without a mesh
173  autoPtr<lumpedPointIOMovement> movementPtr =
175 
176  if (!movementPtr)
177  {
178  Info<< "No valid movement found" << endl;
179  return 1;
180  }
181  auto& movement = *movementPtr;
182 
183  // Reference state0
184  const lumpedPointState& state0 = movement.state0();
185 
186  List<lumpedPointStateTuple> responseTable =
187  getResponseTable(responseFile, state0);
188 
189  echoTableLimits(responseTable, span, maxOut);
190 
191  if (dryrun)
192  {
193  Info<< "dry-run: response table with " << responseTable.size()
194  << " entries" << nl
195  << "\nEnd\n" << endl;
196  return 0;
197  }
198 
199  externalFileCoupler& coupler = movement.coupler();
200 
201  for
202  (
203  label timei = 0, outputCount = 0;
204  timei < responseTable.size();
205  timei += span
206  )
207  {
208  Info<< args.executable() << ": waiting for master" << endl;
209 
210  // Wait for master, but stop if status=done was seen
211  if (!coupler.waitForMaster())
212  {
213  Info<< args.executable()
214  << ": stopping status=done was detected" << endl;
215  break;
216  }
217 
218  lumpedPointState state = responseTable[timei].second();
219  state.relax(relax, state0);
220 
221  // Generate input for OpenFOAM
222  OFstream os(coupler.resolveFile(movement.inputName()));
223  if
224  (
225  movement.inputFormat()
227  )
228  {
229  state.writePlain(os);
230  }
231  else
232  {
233  os.writeEntry("time", responseTable[timei].first());
234  state.writeDict(os);
235  }
236 
237  Info<< args.executable()
238  << ": updated to state " << timei
239  << " - switch to master"
240  << endl;
241 
242  // Let OpenFOAM know that it can continue
243  coupler.useMaster();
244 
245  ++outputCount;
246 
247  if (maxOut && outputCount >= maxOut)
248  {
249  Info<< args.executable()
250  << ": stopping after " << maxOut << " outputs" << endl;
251  break;
252  }
253  }
254 
255  if (removeLock)
256  {
257  Info<< args.executable() << ": removing lock file" << endl;
258  coupler.useSlave(); // This removes the lock-file
259  }
260 
261  Info<< args.executable() << ": finishing" << nl;
262 
263  Info<< "\nEnd\n" << endl;
264  return 0;
265  }
266 
267 
268  // ----------------------------------------------------------------------
269  // dry-run
270  // ----------------------------------------------------------------------
271 
272  if (dryrun)
273  {
274  Info<< "dry-run: creating states only" << nl;
275 
276  #include "createTime.H"
277 
278  // Create movement without a mesh
279  autoPtr<lumpedPointIOMovement> movementPtr =
281 
282  if (!movementPtr)
283  {
284  Info<< "No valid movement found" << endl;
285  return 1;
286  }
287  auto& movement = *movementPtr;
288 
289  // Reference state0
290  const lumpedPointState& state0 = movement.state0();
291 
292  List<lumpedPointStateTuple> responseTable =
293  getResponseTable(responseFile, state0);
294 
295  echoTableLimits(responseTable, span, maxOut);
296 
297 
298  vtk::seriesWriter stateSeries;
299 
300  for
301  (
302  label timei = 0, outputCount = 0;
303  timei < responseTable.size();
304  timei += span
305  )
306  {
307  lumpedPointState state = responseTable[timei].second();
308 
309  state += movement.origin();
310  movement.scalePoints(state);
311  state.relax(relax, state0);
312 
313  Info<< "output [" << timei << '/' << responseTable.size() << ']';
314 
315  // State/response = what comes back from FEM
316  {
317  const word outputName =
318  word::printf("state_%06d.vtp", outputCount);
319 
320  Info<< " " << outputName;
321 
322  movement.writeStateVTP(state, outputName);
323  stateSeries.append(outputCount, outputName);
324  }
325 
326  Info<< endl;
327 
328  ++outputCount;
329 
330  if (maxOut && outputCount >= maxOut)
331  {
332  Info<< "Max output " << maxOut << " ... stopping" << endl;
333  break;
334  }
335  }
336 
337  // Write file series
338 
339  if (stateSeries.size())
340  {
341  Info<< nl << "write state.vtp.series" << nl;
342  stateSeries.write("state.vtp");
343  }
344 
345  Info<< "\nEnd\n" << endl;
346  return 0;
347  }
348 
349 
350  // ----------------------------------------------------------------------
351  // test patch movement
352  // ----------------------------------------------------------------------
353 
354  #include "createTime.H"
355 
357 
358  #include "createNamedMesh.H"
359 
360  // Create movement with mesh
361  autoPtr<lumpedPointIOMovement> movementPtr =
363 
364  if (!movementPtr)
365  {
366  Info<< "No valid movement found" << endl;
367  return 1;
368  }
369  auto& movement = *movementPtr;
370 
371  // Reference state0
372  const lumpedPointState& state0 = movement.state0();
373 
374  List<lumpedPointStateTuple> responseTable =
375  getResponseTable(responseFile, state0);
376 
377  echoTableLimits(responseTable, span, maxOut);
378 
380 
382  if (!nPatches)
383  {
384  Info<< "No point patches with lumped movement found" << endl;
385  return 2;
386  }
387 
388  Info<< "Lumped point patch controls set on "
389  << nPatches << " patches" << nl;
390 
392 
393 
394  // Output vtk file series
395  vtk::seriesWriter stateSeries;
396  vtk::seriesWriter geomSeries;
397 
398  // Initial geometry
399  movement.writeVTP("geom_init.vtp", state0, mesh, points0);
400 
402 
403  for
404  (
405  label timei = 0, outputCount = 0;
406  timei < responseTable.size();
407  timei += span
408  )
409  {
410  lumpedPointState state = responseTable[timei].second();
411 
412  state += movement.origin();
413  movement.scalePoints(state);
414  state.relax(relax, state0);
415 
416  Info<< "output [" << timei << '/' << responseTable.size() << ']';
417 
418  // State/response = what comes back from FEM
419  {
420  const word outputName =
421  word::printf("state_%06d.vtp", outputCount);
422 
423  Info<< " " << outputName;
424 
425  movement.writeStateVTP(state, outputName);
426  stateSeries.append(outputCount, outputName);
427  }
428 
429  {
430  const word outputName =
431  word::printf("geom_%06d.vtp", outputCount);
432 
433  Info<< " " << outputName;
434 
435  movement.writeVTP(outputName, state, mesh, points0);
436  geomSeries.append(outputCount, outputName);
437  }
438 
439  Info<< endl;
440 
441  ++outputCount;
442 
443  if (maxOut && outputCount >= maxOut)
444  {
445  Info<< "Max output " << maxOut << " ... stopping" << endl;
446  break;
447  }
448  }
449 
450 
451  // Write file series
452 
453  if (geomSeries.size())
454  {
455  Info<< nl << "write geom.vtp.series" << nl;
456  geomSeries.write("geom.vtp");
457  }
458  if (stateSeries.size())
459  {
460  Info<< nl << "write state.vtp.series" << nl;
461  stateSeries.write("state.vtp");
462  }
463 
464  Info<< "\nEnd\n" << endl;
465 
466  return 0;
467 }
468 
469 
470 // ************************************************************************* //
runTime
engineTime & runTime
Definition: createEngineTime.H:13
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:63
Foam::lumpedPointState::writeDict
void writeDict(Ostream &os) const
Definition: lumpedPointState.C:333
Foam::fileName
A class for handling file names.
Definition: fileName.H:71
Foam::IOField
A primitive field of type <T> with automated input and output.
Definition: foamVtkLagrangianWriter.H:57
Foam::lumpedPointTools::setPatchControls
label setPatchControls(const pointVectorField &pvf, const pointField &points0)
Definition: lumpedPointTools.C:172
Foam::argList::getOrDefault
T getOrDefault(const word &optName, const T &deflt) const
Definition: argListI.H:300
Foam::lumpedPointState::relax
void relax(const scalar alpha, const lumpedPointState &prev)
Definition: lumpedPointState.C:239
Foam::externalFileCoupler::useMaster
enum Time::stopAtControls useMaster(const bool wait=false) const
Definition: externalFileCoupler.C:179
Foam::argList::addNote
static void addNote(const string &note)
Definition: argList.C:405
Foam::endl
Ostream & endl(Ostream &os)
Definition: Ostream.H:381
Foam::externalFileCoupler::waitForMaster
enum Time::stopAtControls waitForMaster() const
Definition: externalFileCoupler.C:243
Foam::argList::get
T get(const label index) const
Definition: argListI.H:271
Foam::argList::readIfPresent
bool readIfPresent(const word &optName, T &val) const
Definition: argListI.H:316
OFstream.H
Foam::lumpedPointState::inputFormatType::PLAIN
@ PLAIN
"plain" is a simple ASCII format
Foam::argList::addArgument
static void addArgument(const string &argName, const string &usage="")
Definition: argList.C:294
outputName
word outputName("finiteArea-edges.obj")
Foam::lumpedPointState
The state of lumped points corresponds to positions and rotations.
Definition: lumpedPointState.H:108
Foam::argList::noFunctionObjects
static void noFunctionObjects(bool addWithOption=false)
Definition: argList.C:466
Foam::lumpedPointState::scalePoints
void scalePoints(const scalar scaleFactor)
Definition: lumpedPointState.C:229
nPatches
const label nPatches
Definition: printMeshSummary.H:24
lumpedPointTools.H
Foam::argList::dryRun
int dryRun() const noexcept
Definition: argListI.H:109
Foam::Info
messageStream Info
argList.H
Foam::lumpedPointState::writePlain
void writePlain(Ostream &os) const
Definition: lumpedPointState.C:348
Foam::lumpedPointTools::lumpedPointStates
List< lumpedPointStateTuple > lumpedPointStates(const dictionary &dict, quaternion::eulerOrder rotOrder=quaternion::eulerOrder::ZXZ, bool degrees=false)
Definition: lumpedPointTools.C:68
Foam::lumpedPointState::rotationOrder
quaternion::eulerOrder rotationOrder() const
Definition: lumpedPointStateI.H:63
foamVtkSeriesWriter.H
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Definition: hashSets.C:40
Foam::lumpedPointTools::setInterpolators
label setInterpolators(const pointVectorField &pvf, const pointField &points0)
Definition: lumpedPointTools.C:225
Foam::FatalError
error FatalError
Foam::externalFileCoupler::resolveFile
fileName resolveFile(const word &file) const
Definition: externalFileCouplerI.H:42
createNamedMesh.H
Required Variables.
os
OBJstream os(runTime.globalPath()/outputName)
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::vtk::seriesWriter
Provides a means of accumulating and generating VTK file series.
Definition: foamVtkSeriesWriter.H:71
Foam::vtk::seriesWriter::write
static void write(const fileName &base, const UList< instant > &series, const char sep='_')
Definition: foamVtkSeriesWriter.C:226
Foam
Definition: atmBoundaryLayer.C:26
lumpedPointIOMovement.H
Foam::argList::addDryRunOption
static void addDryRunOption(const string &usage, bool advanced=false)
Definition: argList.C:447
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:49
Foam::externalFileCoupler::useSlave
enum Time::stopAtControls useSlave(const bool wait=false) const
Definition: externalFileCoupler.C:215
Foam::argList::addBoolOption
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Definition: argList.C:317
Time.H
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:49
points0
pointField points0(pointIOField(IOobject("points", mesh.time().constant(), polyMesh::meshSubDir, mesh, IOobject::MUST_READ, IOobject::NO_WRITE, false)))
setRootCase.H
Foam::externalFileCoupler
Encapsulates the logic for coordinating between OpenFOAM and an external application.
Definition: externalFileCoupler.H:103
FatalErrorInFunction
#define FatalErrorInFunction
Definition: error.H:465
Foam::nl
constexpr char nl
Definition: Ostream.H:424
Foam::vtk::seriesWriter::size
label size() const noexcept
Definition: foamVtkSeriesWriterI.H:29
Foam::argList::executable
const word & executable() const noexcept
Definition: argListI.H:44
Foam::UPstream::parRun
static bool & parRun() noexcept
Definition: UPstream.H:429
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:58
Foam::Time::setTime
virtual void setTime(const Time &t)
Definition: Time.C:996
createTime.H
Foam::Ostream::writeEntry
Ostream & writeEntry(const keyType &key, const T &value)
Definition: Ostream.H:232
Foam::word::printf
static word printf(const char *fmt, const PrimitiveType &val)
Foam::lumpedPointTools::points0Field
pointIOField points0Field(const polyMesh &mesh)
Definition: lumpedPointTools.C:131
Foam::vtk::seriesWriter::append
bool append(const fileNameInstant &inst)
Definition: foamVtkSeriesWriterI.H:42
Foam::instant
An instant of time. Contains the time value and name.
Definition: instant.H:48
Foam::TimePaths::constant
const word & constant() const
Definition: TimePathsI.H:89
Foam::argList::addOption
static void addOption(const word &optName, const string &param="", const string &usage="", bool advanced=false)
Definition: argList.C:328
args
Foam::argList args(argc, argv)
Foam::lumpedPointState::degrees
bool degrees() const
Definition: lumpedPointStateI.H:69
Foam::lumpedPointState::visLength
static scalar visLength
Definition: lumpedPointState.H:167
Foam::lumpedPointIOMovement::New
static autoPtr< lumpedPointIOMovement > New(const objectRegistry &obr, label ownerId=-1)
Definition: lumpedPointIOMovement.C:46
Foam::argList::found
bool found(const word &optName) const
Definition: argListI.H:171
relax
UEqn relax()