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-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 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  "dry-run",
125  "Test movement without a mesh"
126  );
128  (
129  "removeLock",
130  "Remove lock-file on termination of slave"
131  );
133  (
134  "slave",
135  "Invoke as a slave responder for testing"
136  );
137  argList::addArgument("responseFile");
138 
139  #include "setRootCase.H"
140 
141  const label maxOut = Foam::max(0, args.getOrDefault<label>("max", 0));
142  const label span = Foam::max(1, args.getOrDefault<label>("span", 1));
143 
144  // Control parameters
145  const bool dryrun = args.found("dry-run");
146  const bool slave = args.found("slave");
147  const bool removeLock = args.found("removeLock");
148 
149  const scalar relax = args.getOrDefault<scalar>("scale", 1);
150 
152 
153  const fileName responseFile(args[1]);
154 
155  // ----------------------------------------------------------------------
156  // Slave mode
157  // ----------------------------------------------------------------------
158 
159  if (slave)
160  {
161  Info<< "Running as slave responder" << endl;
162 
163  if (Pstream::parRun())
164  {
166  << "Running as slave responder is not permitted in parallel"
167  << nl
168  << exit(FatalError);
169  }
170 
171  #include "createTime.H"
172 
173  // Create movement without a mesh
174  autoPtr<lumpedPointIOMovement> movementPtr =
176 
177  if (!movementPtr)
178  {
179  Info<< "No valid movement found" << endl;
180  return 1;
181  }
182  auto& movement = *movementPtr;
183 
184  // Reference state0
185  const lumpedPointState& state0 = movement.state0();
186 
187  List<lumpedPointStateTuple> responseTable =
188  getResponseTable(responseFile, state0);
189 
190  echoTableLimits(responseTable, span, maxOut);
191 
192  if (dryrun)
193  {
194  Info<< "dry-run: response table with " << responseTable.size()
195  << " entries" << nl
196  << "\nEnd\n" << endl;
197  return 0;
198  }
199 
200  externalFileCoupler& coupler = movement.coupler();
201 
202  for
203  (
204  label timei = 0, outputCount = 0;
205  timei < responseTable.size();
206  timei += span
207  )
208  {
209  Info<< args.executable() << ": waiting for master" << endl;
210 
211  // Wait for master, but stop if status=done was seen
212  if (!coupler.waitForMaster())
213  {
214  Info<< args.executable()
215  << ": stopping status=done was detected" << endl;
216  break;
217  }
218 
219  lumpedPointState state = responseTable[timei].second();
220  state.relax(relax, state0);
221 
222  // Generate input for OpenFOAM
223  OFstream os(coupler.resolveFile(movement.inputName()));
224  if
225  (
226  movement.inputFormat()
228  )
229  {
230  state.writePlain(os);
231  }
232  else
233  {
234  os.writeEntry("time", responseTable[timei].first());
235  state.writeDict(os);
236  }
237 
238  Info<< args.executable()
239  << ": updated to state " << timei
240  << " - switch to master"
241  << endl;
242 
243  // Let OpenFOAM know that it can continue
244  coupler.useMaster();
245 
246  ++outputCount;
247 
248  if (maxOut && outputCount >= maxOut)
249  {
250  Info<< args.executable()
251  << ": stopping after " << maxOut << " outputs" << endl;
252  break;
253  }
254  }
255 
256  if (removeLock)
257  {
258  Info<< args.executable() << ": removing lock file" << endl;
259  coupler.useSlave(); // This removes the lock-file
260  }
261 
262  Info<< args.executable() << ": finishing" << nl;
263 
264  Info<< "\nEnd\n" << endl;
265  return 0;
266  }
267 
268 
269  // ----------------------------------------------------------------------
270  // dry-run
271  // ----------------------------------------------------------------------
272 
273  if (dryrun)
274  {
275  Info<< "dry-run: creating states only" << nl;
276 
277  #include "createTime.H"
278 
279  // Create movement without a mesh
280  autoPtr<lumpedPointIOMovement> movementPtr =
282 
283  if (!movementPtr)
284  {
285  Info<< "No valid movement found" << endl;
286  return 1;
287  }
288  auto& movement = *movementPtr;
289 
290  // Reference state0
291  const lumpedPointState& state0 = movement.state0();
292 
293  List<lumpedPointStateTuple> responseTable =
294  getResponseTable(responseFile, state0);
295 
296  echoTableLimits(responseTable, span, maxOut);
297 
298 
299  vtk::seriesWriter stateSeries;
300 
301  for
302  (
303  label timei = 0, outputCount = 0;
304  timei < responseTable.size();
305  timei += span
306  )
307  {
308  lumpedPointState state = responseTable[timei].second();
309 
310  state += movement.origin();
311  movement.scalePoints(state);
312  state.relax(relax, state0);
313 
314  Info<< "output [" << timei << '/' << responseTable.size() << ']';
315 
316  // State/response = what comes back from FEM
317  {
318  const word outputName =
319  word::printf("state_%06d.vtp", outputCount);
320 
321  Info<< " " << outputName;
322 
323  movement.writeStateVTP(state, outputName);
324  stateSeries.append(outputCount, outputName);
325  }
326 
327  Info<< endl;
328 
329  ++outputCount;
330 
331  if (maxOut && outputCount >= maxOut)
332  {
333  Info<< "Max output " << maxOut << " ... stopping" << endl;
334  break;
335  }
336  }
337 
338  // Write file series
339 
340  if (stateSeries.size())
341  {
342  Info<< nl << "write state.vtp.series" << nl;
343  stateSeries.write("state.vtp");
344  }
345 
346  Info<< "\nEnd\n" << endl;
347  return 0;
348  }
349 
350 
351  // ----------------------------------------------------------------------
352  // test patch movement
353  // ----------------------------------------------------------------------
354 
355  #include "createTime.H"
356 
358 
359  #include "createNamedMesh.H"
360 
361  // Create movement with mesh
362  autoPtr<lumpedPointIOMovement> movementPtr =
364 
365  if (!movementPtr)
366  {
367  Info<< "No valid movement found" << endl;
368  return 1;
369  }
370  auto& movement = *movementPtr;
371 
372  // Reference state0
373  const lumpedPointState& state0 = movement.state0();
374 
375  List<lumpedPointStateTuple> responseTable =
376  getResponseTable(responseFile, state0);
377 
378  echoTableLimits(responseTable, span, maxOut);
379 
381 
383  if (!nPatches)
384  {
385  Info<< "No point patches with lumped movement found" << endl;
386  return 2;
387  }
388 
389  Info<< "Lumped point patch controls set on "
390  << nPatches << " patches" << nl;
391 
393 
394 
395  // Output vtk file series
396  vtk::seriesWriter stateSeries;
397  vtk::seriesWriter geomSeries;
398 
399  // Initial geometry
400  movement.writeVTP("geom_init.vtp", state0, mesh, points0);
401 
403 
404  for
405  (
406  label timei = 0, outputCount = 0;
407  timei < responseTable.size();
408  timei += span
409  )
410  {
411  lumpedPointState state = responseTable[timei].second();
412 
413  state += movement.origin();
414  movement.scalePoints(state);
415  state.relax(relax, state0);
416 
417  Info<< "output [" << timei << '/' << responseTable.size() << ']';
418 
419  // State/response = what comes back from FEM
420  {
421  const word outputName =
422  word::printf("state_%06d.vtp", outputCount);
423 
424  Info<< " " << outputName;
425 
426  movement.writeStateVTP(state, outputName);
427  stateSeries.append(outputCount, outputName);
428  }
429 
430  {
431  const word outputName =
432  word::printf("geom_%06d.vtp", outputCount);
433 
434  Info<< " " << outputName;
435 
436  movement.writeVTP(outputName, state, mesh, points0);
437  geomSeries.append(outputCount, outputName);
438  }
439 
440  Info<< endl;
441 
442  ++outputCount;
443 
444  if (maxOut && outputCount >= maxOut)
445  {
446  Info<< "Max output " << maxOut << " ... stopping" << endl;
447  break;
448  }
449  }
450 
451 
452  // Write file series
453 
454  if (geomSeries.size())
455  {
456  Info<< nl << "write geom.vtp.series" << nl;
457  geomSeries.write("geom.vtp");
458  }
459  if (stateSeries.size())
460  {
461  Info<< nl << "write state.vtp.series" << nl;
462  stateSeries.write("state.vtp");
463  }
464 
465  Info<< "\nEnd\n" << endl;
466 
467  return 0;
468 }
469 
470 
471 // ************************************************************************* //
runTime
engineTime & runTime
Definition: createEngineTime.H:13
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::lumpedPointState::writeDict
void writeDict(Ostream &os) const
Output as dictionary content.
Definition: lumpedPointState.C:340
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::IOField
A primitive field of type <T> with automated input and output.
Definition: foamVtkLagrangianWriter.H:61
Foam::lumpedPointTools::setPatchControls
label setPatchControls(const pointVectorField &pvf, const pointField &points0)
Return the patch-ids associated with a "lumpedPointDisplacement" type.
Definition: lumpedPointTools.C:179
nPatches
label nPatches
Definition: readKivaGrid.H:396
Foam::argList::getOrDefault
T getOrDefault(const word &optName, const T &deflt) const
Get a value from the named option if present, or return default.
Definition: argListI.H:286
Foam::UPstream::parRun
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:415
Foam::lumpedPointState::relax
void relax(const scalar alpha, const lumpedPointState &prev)
Relax the state.
Definition: lumpedPointState.C:246
Foam::externalFileCoupler::useMaster
enum Time::stopAtControls useMaster(const bool wait=false) const
Create lock file to indicate that OpenFOAM is in charge.
Definition: externalFileCoupler.C:186
Foam::argList::addNote
static void addNote(const string &note)
Add extra notes for the usage information.
Definition: argList.C:413
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::externalFileCoupler::waitForMaster
enum Time::stopAtControls waitForMaster() const
Wait for master to complete.
Definition: externalFileCoupler.C:250
Foam::argList::readIfPresent
bool readIfPresent(const word &optName, T &val) const
Read a value from the named option if present.
Definition: argListI.H:302
OFstream.H
Foam::lumpedPointState::inputFormatType::PLAIN
"plain" is a simple ASCII format
Foam::argList::addArgument
static void addArgument(const string &argName, const string &usage="")
Append a (mandatory) argument to validArgs.
Definition: argList.C:302
Foam::lumpedPointState
The state of lumped points corresponds to positions and rotations.
Definition: lumpedPointState.H:112
Foam::argList::noFunctionObjects
static void noFunctionObjects(bool addWithOption=false)
Remove '-noFunctionObjects' option and ignore any occurrences.
Definition: argList.C:454
Foam::lumpedPointState::scalePoints
void scalePoints(const scalar scaleFactor)
Scale points by given factor.
Definition: lumpedPointState.C:236
Foam::argList::executable
const word & executable() const
Name of executable without the path.
Definition: argListI.H:51
lumpedPointTools.H
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
argList.H
Foam::lumpedPointState::writePlain
void writePlain(Ostream &os) const
Output as plain content.
Definition: lumpedPointState.C:355
Foam::lumpedPointTools::lumpedPointStates
List< lumpedPointStateTuple > lumpedPointStates(const dictionary &dict, quaternion::eulerOrder rotOrder=quaternion::eulerOrder::ZXZ, bool degrees=false)
Load a list of states from a dictionary.
Definition: lumpedPointTools.C:75
Foam::lumpedPointState::rotationOrder
quaternion::eulerOrder rotationOrder() const
The Euler-angle rotation order.
Definition: lumpedPointStateI.H:70
foamVtkSeriesWriter.H
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
Foam::lumpedPointTools::setInterpolators
label setInterpolators(const pointVectorField &pvf, const pointField &points0)
Return the patch-ids associated with a "lumpedPointDisplacement" type.
Definition: lumpedPointTools.C:232
Foam::FatalError
error FatalError
Foam::externalFileCoupler::resolveFile
fileName resolveFile(const word &file) const
Return the file path in the communications directory.
Definition: externalFileCouplerI.H:49
createNamedMesh.H
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::vtk::seriesWriter
Provides a means of accumulating and generating VTK file series.
Definition: foamVtkSeriesWriter.H:75
Foam::vtk::seriesWriter::write
static void write(const fileName &base, const UList< instant > &series, const char sep='_')
Write file series (JSON format) to disk, for specified instances.
Definition: foamVtkSeriesWriter.C:236
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
lumpedPointIOMovement.H
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:87
Foam::externalFileCoupler::useSlave
enum Time::stopAtControls useSlave(const bool wait=false) const
Remove lock file to indicate that the external program is in charge.
Definition: externalFileCoupler.C:222
Foam::argList::addBoolOption
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
Definition: argList.C:325
Time.H
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
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:107
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:372
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::vtk::seriesWriter::size
label size() const noexcept
The number of data sets.
Definition: foamVtkSeriesWriterI.H:36
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:102
Foam::Time::setTime
virtual void setTime(const Time &t)
Reset the time and time-index to those of the given time.
Definition: Time.C:1006
createTime.H
Foam::word::printf
static word printf(const char *fmt, const PrimitiveType &val)
Use a printf-style formatter for a primitive.
Foam::lumpedPointTools::points0Field
pointIOField points0Field(const polyMesh &mesh)
Return the 0 or constant points field.
Definition: lumpedPointTools.C:138
Foam::vtk::seriesWriter::append
bool append(const fileNameInstant &inst)
Append the specified file instant.
Definition: foamVtkSeriesWriterI.H:49
Foam::instant
An instant of time. Contains the time value and name.
Definition: instant.H:52
Foam::TimePaths::constant
const word & constant() const
Return constant name.
Definition: TimePathsI.H:88
Foam::argList::addOption
static void addOption(const word &optName, const string &param="", const string &usage="", bool advanced=false)
Add an option to validOptions with usage information.
Definition: argList.C:336
args
Foam::argList args(argc, argv)
Foam::lumpedPointState::degrees
bool degrees() const
Rotation angles in degrees.
Definition: lumpedPointStateI.H:76
Foam::lumpedPointState::visLength
static scalar visLength
The length for visualization triangles.
Definition: lumpedPointState.H:171
Foam::lumpedPointIOMovement::New
static autoPtr< lumpedPointIOMovement > New(const objectRegistry &obr, label ownerId=-1)
Definition: lumpedPointIOMovement.C:53
Foam::argList::found
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:157
relax
UEqn relax()