mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: lumped point motion using local linear basic functions (#1341)
- the earlier implementation of externally controlled lumped point motion (see merge request !120 and OpenFOAM-v1706 release notes) was conceived for the motion of simple structures such as buildings or simple beams. The motion controller was simply defined in terms of an orientation axis and divisions along that axis. To include complex structures, multiple motion controllers are defined in terms of support points and connectivity. The points can have additional node Ids associated with them, which makes it easier to map to/from FEA models. OLD system/lumpedPointMovement specification -------------------------------------------- //- Reference axis for the locations axis (0 0 1); //- Locations of the lumped points locations (0 0.05 .. 0.5); NEW system/lumpedPointMovement specification -------------------------------------------- // Locations of the lumped points points ( (0 0 0.00) (0 0 0.05) ... (0 0 0.50) ); //- Connectivity for motion controllers controllers { vertical { pointLabels (0 1 2 3 4 5 6 7 8 9 10); } } And the controller(s) must be associated with the given pointDisplacement patch. Eg, somePatch { type lumpedPointDisplacement; value uniform (0 0 0); controllers ( vertical ); // <-- NEW } TUT: adjust building motion tutorial - use new controllor definitions - replace building response file with executable - add updateControl in dynamicMeshDict for slowly moving structure
This commit is contained in:
@ -1,5 +1,8 @@
|
||||
#!/bin/sh
|
||||
cd "${0%/*}" || exit # Run from this directory
|
||||
cd "${0%/*}" || exit # Run from this directory
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
(cd code && ./Allclean)
|
||||
|
||||
(cd steady && ./Allclean)
|
||||
|
||||
|
||||
@ -3,94 +3,45 @@ cd "${0%/*}" || exit # Run from this directory
|
||||
. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# 1) First run steady-state to establish a good initial field.
|
||||
# 2) Copy the latest state-state results for the transient case,
|
||||
# 1) Run steady-state to establish a good initial field
|
||||
# 2) Copy state-state results -> transient case,
|
||||
# but need to copy the pointDisplacement from the 0/ directory
|
||||
# since it will not have been used for the steady-state case
|
||||
# 3) Relocate this initial solution to coincide with the first deltaT
|
||||
# to avoid overwriting the 0/ directory at all.
|
||||
|
||||
#
|
||||
# copyParallelPointDisplacement caseDir timeName
|
||||
#
|
||||
# Copy pointDisplacement from caseDir/0/ to caseDir/timeName/
|
||||
#
|
||||
copyParallelPointDisplacement()
|
||||
{
|
||||
local src=$1
|
||||
local dstTime=$2
|
||||
local file=pointDisplacement
|
||||
|
||||
[ -d "$src" ] || {
|
||||
echo "Error: no directory: $src"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Copy select directories
|
||||
echo " copy processor '$file' from 0/ -> $dstTime"
|
||||
if [ -n "$dstTime" ]
|
||||
then
|
||||
(
|
||||
cd "$src" || exit
|
||||
|
||||
for proc in processor*
|
||||
do
|
||||
[ -d "$proc/0" -a -d "$proc/$dstTime" ] && \
|
||||
cp $proc/0/$file $proc/$dstTime/$file
|
||||
done
|
||||
)
|
||||
else
|
||||
echo " no destination time"
|
||||
fi
|
||||
|
||||
# Restart from latestTime
|
||||
foamDictionary $src/system/controlDict \
|
||||
-entry startFrom -set latestTime
|
||||
|
||||
deltaT=$(foamDictionary $src/system/controlDict -entry deltaT -value)
|
||||
latestTime=$(foamListTimes -case $src -noZero -latestTime -processor)
|
||||
|
||||
# Restart using steady results as first deltaT interval
|
||||
echo "deltaT=$deltaT latestTime=$latestTime"
|
||||
if [ -n "$latestTime" -a "$deltaT" != "$latestTime" ]
|
||||
then
|
||||
(
|
||||
cd "$src" || exit
|
||||
|
||||
for proc in processor*
|
||||
do
|
||||
if [ -d "$proc/$latestTime" -a ! -d "$proc/$deltaT" ]
|
||||
then
|
||||
mv $proc/$latestTime $proc/$deltaT
|
||||
rm -rf "$proc/$deltaT/uniform"
|
||||
fi
|
||||
done
|
||||
)
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
# Do steady-state case
|
||||
(cd steady && foamRunTutorials)
|
||||
|
||||
if notTest "$@"
|
||||
then
|
||||
latestTime=$(\cd steady && foamListTimes -noZero -latestTime -processor)
|
||||
if canCompile
|
||||
then
|
||||
(cd code && wmake)
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Clone the steady-state case to transient
|
||||
cloneParallelCase steady transient 0 $latestTime
|
||||
. files/RunFunctions
|
||||
|
||||
copyParallelPointDisplacement transient $latestTime
|
||||
caseName="transient"
|
||||
|
||||
latestTime=$(foamListTimes -case steady -noZero -latestTime -processor)
|
||||
|
||||
# Clone steady-state case to transient
|
||||
cloneParallelCase steady "$caseName" 0 "$latestTime"
|
||||
|
||||
copyParallelPointDisplacement "$caseName" "$latestTime"
|
||||
|
||||
# Adjust application (from simpleFoam -> pimpleFoam)
|
||||
foamDictionary transient/system/controlDict \
|
||||
foamDictionary "$caseName"/system/controlDict \
|
||||
-entry application -set pimpleFoam
|
||||
|
||||
# Do the transient case
|
||||
\cp files/Allrun.transient transient/Allrun
|
||||
(\cd transient && foamRunTutorials)
|
||||
# Copy/link support files
|
||||
linkFiles files "$caseName"
|
||||
|
||||
# Run
|
||||
"$caseName/Allrun.$caseName" $*
|
||||
fi
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
@ -4,62 +4,32 @@ cd "${0%/*}" || exit # Run from this directory
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# 1) Run meshing
|
||||
# 2) Reconstruct
|
||||
# 3) Test input zones and movement
|
||||
# 2) Test input zones and movement
|
||||
|
||||
#
|
||||
# linkParallelCase srcDir dstDir
|
||||
#
|
||||
linkParallelCase()
|
||||
{
|
||||
local src=$1
|
||||
local dst=$2
|
||||
shift 2
|
||||
|
||||
if [ -e "$dst" ]
|
||||
then
|
||||
echo "Case already linked: remove case directory $dst prior to linking"
|
||||
return 1
|
||||
elif [ ! -d "$src" ]
|
||||
then
|
||||
echo "Error: no directory to link: $src"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "Linking $dst parallel case from $src"
|
||||
mkdir $dst
|
||||
|
||||
# Copy system - may wish to change things
|
||||
for i in system 0
|
||||
do
|
||||
echo " copy $i/"
|
||||
( cd $dst && cp -r ../$src/$i . )
|
||||
done
|
||||
|
||||
echo " link constant/"
|
||||
( cd $dst && ln -sf ../$src/constant . )
|
||||
|
||||
echo " link processor*/ with $# times: $@"
|
||||
for proc in $(cd $src && \ls -d processor*)
|
||||
do
|
||||
( cd $dst && ln -sf ../$src/$proc . )
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
# Do steady-state case
|
||||
# Meshing
|
||||
(cd steady && ./Allrun.pre)
|
||||
|
||||
if notTest "$@"
|
||||
if notTest
|
||||
then
|
||||
# Copy/link the steady-state case to movement
|
||||
linkParallelCase steady movement
|
||||
if canCompile
|
||||
then
|
||||
(cd code && wmake)
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Test movement
|
||||
\cp files/Allrun.movement movement/Allrun
|
||||
(cd movement && foamRunTutorials)
|
||||
. files/RunFunctions
|
||||
|
||||
caseName="movement"
|
||||
|
||||
# Copy/link the steady-state case to movement
|
||||
linkParallelCase steady "$caseName"
|
||||
|
||||
# Copy/link support files
|
||||
linkFiles files "$caseName"
|
||||
|
||||
# Run
|
||||
"$caseName/Allrun.$caseName" $*
|
||||
fi
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
13
tutorials/incompressible/lumpedPointMotion/building/code/Allclean
Executable file
13
tutorials/incompressible/lumpedPointMotion/building/code/Allclean
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
cd "${0%/*}" || exit # Run from this directory
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
wclean
|
||||
|
||||
# Remove executable
|
||||
rm -f building-motion
|
||||
|
||||
# Remove known output/debug files
|
||||
rm -f *.txt *.vtp *.vtp.series
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
@ -0,0 +1,3 @@
|
||||
building-motion.C
|
||||
|
||||
EXE = $(PWD)/building-motion
|
||||
@ -0,0 +1,13 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/fileFormats/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/lumpedPointMotion/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-lfileFormats \
|
||||
-lmeshTools \
|
||||
-ldynamicMesh \
|
||||
-llumpedPointMotion
|
||||
@ -0,0 +1,682 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2020 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Application
|
||||
building-motion
|
||||
|
||||
Description
|
||||
Forced oscillation code for fluid-structure interface check.
|
||||
Generates position and rotation angle of each node.
|
||||
The top displacements of the target building calculated as sin() function.
|
||||
Horizontal displacements of each node interpolated to the vertical
|
||||
direction according to cantilever beam theory.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "Fstream.H"
|
||||
#include "unitConversion.H"
|
||||
#include "foamVtkSeriesWriter.H"
|
||||
#include "lumpedPointTools.H"
|
||||
#include "lumpedPointState.H"
|
||||
#include "lumpedPointIOMovement.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
//- Oscillator generator
|
||||
class position_generator
|
||||
{
|
||||
// Private Member Functions
|
||||
|
||||
//- Calculate position/rotation at given time
|
||||
lumpedPointState calc(scalar currTime) const
|
||||
{
|
||||
// Point positions
|
||||
pointField points_(nDivisions+1, Zero);
|
||||
|
||||
// Point rotations
|
||||
vectorField angles_(nDivisions+1, Zero);
|
||||
|
||||
// Set node heights (z)
|
||||
forAll(points_, divi)
|
||||
{
|
||||
points_[divi].z() = (height * divi)/scalar(nDivisions);
|
||||
}
|
||||
|
||||
const vector sines
|
||||
(
|
||||
Foam::sin(2*constant::mathematical::pi * currTime/period.x()),
|
||||
Foam::sin(2*constant::mathematical::pi * currTime/period.y()),
|
||||
Foam::sin(2*constant::mathematical::pi * currTime/period.z())
|
||||
);
|
||||
|
||||
for (label divi = 1; divi <= nDivisions; ++divi)
|
||||
{
|
||||
const scalar zpos = points_[divi].z();
|
||||
const scalar height1 = (height - zpos);
|
||||
|
||||
const scalar pos_factor =
|
||||
(
|
||||
1.0/3.0 / pow4(height)
|
||||
* (
|
||||
3*pow4(height)
|
||||
- 4*pow3(height)*(height1)
|
||||
+ pow4(height1)
|
||||
)
|
||||
);
|
||||
|
||||
const scalar ang_factor =
|
||||
(
|
||||
1.0/3.0 / pow4(height)
|
||||
* (
|
||||
4*pow3(height)
|
||||
- 4*pow3(height1)
|
||||
)
|
||||
);
|
||||
|
||||
vector here
|
||||
(
|
||||
(amplitude.x() * sines.x() * pos_factor),
|
||||
(amplitude.y() * sines.y() * pos_factor),
|
||||
zpos // Z position is invariant
|
||||
);
|
||||
|
||||
vector rot
|
||||
(
|
||||
Foam::atan(amplitude.x() * sines.x() * ang_factor),
|
||||
Foam::atan(amplitude.y() * sines.y() * ang_factor),
|
||||
Foam::atan(amplitude.z() * sines.z() * ang_factor)
|
||||
);
|
||||
|
||||
// Assign
|
||||
points_[divi] = here;
|
||||
|
||||
// The x<->y swap is intentional
|
||||
angles_[divi] = vector{rot.y(), rot.x(), rot.z()};
|
||||
}
|
||||
|
||||
// Return as lumpedPoint state
|
||||
return lumpedPointState{points_, angles_};
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Control parameters
|
||||
|
||||
// The number of oscillating nodes
|
||||
label nDivisions = 10;
|
||||
|
||||
// Height of target building [m]
|
||||
scalar height = 0.5;
|
||||
|
||||
// Proper period (sec)
|
||||
vector period = vector{1, 0.5, 1};
|
||||
|
||||
// Amplitude
|
||||
vector amplitude = vector{0.03, 0.05, 0.3};
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct
|
||||
position_generator() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Calculate position/rotation at given time
|
||||
lumpedPointState state(const scalar currTime) const
|
||||
{
|
||||
return calc(currTime);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::addNote
|
||||
(
|
||||
"Forced oscillation code for fluid-structure interface check."
|
||||
" Generates position and rotation angle of each node."
|
||||
" The top displacements of the target building calculated as sin()"
|
||||
" function."
|
||||
" Horizontal displacements of each node interpolated to the vertical"
|
||||
" direction according to cantilever beam theory."
|
||||
);
|
||||
|
||||
argList::noBanner();
|
||||
argList::noParallel();
|
||||
|
||||
// Geometric
|
||||
argList::addOption
|
||||
(
|
||||
"nodes",
|
||||
"N",
|
||||
"The number of oscillating nodes (default: 10)"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"height",
|
||||
"value",
|
||||
"Height of target building (m)"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"period",
|
||||
"(time time time)",
|
||||
"The proper period (sec)"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"amplitude",
|
||||
"(value value value)",
|
||||
"The amplitude"
|
||||
);
|
||||
|
||||
// Time control
|
||||
argList::addOption
|
||||
(
|
||||
"time",
|
||||
"value",
|
||||
"The time to use"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"deltaT",
|
||||
"value",
|
||||
"The time increment for multiple time loops"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"nTimes",
|
||||
"value",
|
||||
"The number of time loops"
|
||||
);
|
||||
|
||||
// Query, output
|
||||
argList::addBoolOption
|
||||
(
|
||||
"query",
|
||||
"Report values only and exit"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"output",
|
||||
"file",
|
||||
"write to file, with header"
|
||||
);
|
||||
|
||||
argList::addOption
|
||||
(
|
||||
"scale",
|
||||
"factor",
|
||||
"Scaling factor for movement (default: 1)"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"visual-length",
|
||||
"len",
|
||||
"Visualization length for planes (visualized as triangles)"
|
||||
);
|
||||
|
||||
// Run controls
|
||||
argList::addBoolOption
|
||||
(
|
||||
"dry-run",
|
||||
"Test movement without a mesh"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"removeLock",
|
||||
"Remove lock-file on termination of slave"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"slave",
|
||||
"Invoke as a slave responder for testing"
|
||||
);
|
||||
#include "setRootCase.H"
|
||||
|
||||
|
||||
// The oscillator
|
||||
position_generator gen;
|
||||
args.readIfPresent("nodes", gen.nDivisions);
|
||||
args.readIfPresent("height", gen.height);
|
||||
args.readIfPresent("period", gen.period);
|
||||
args.readIfPresent("amplitude", gen.amplitude);
|
||||
|
||||
|
||||
// Control parameters
|
||||
const bool dryrun = args.found("dry-run");
|
||||
const bool slave = args.found("slave");
|
||||
const bool removeLock = args.found("removeLock");
|
||||
|
||||
const bool optQuery = args.found("query");
|
||||
const fileName outputFile(args.getOrDefault<fileName>("output", ""));
|
||||
|
||||
const scalar relax = args.getOrDefault<scalar>("scale", 1);
|
||||
|
||||
args.readIfPresent("visual-length", lumpedPointState::visLength);
|
||||
|
||||
// Time parameters
|
||||
scalar currTime = args.getOrDefault<scalar>("time", 0);
|
||||
const scalar deltaT = args.getOrDefault("deltaT", 0.001);
|
||||
const label nTimes = args.getOrDefault<label>("nTimes", 1);
|
||||
|
||||
// Loop handling for slave
|
||||
const bool infiniteLoop = slave && !args.found("nTimes");
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Slave mode
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
if (slave)
|
||||
{
|
||||
Info<< "Running as slave responder" << endl;
|
||||
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Running as slave responder is not permitted in parallel"
|
||||
<< nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
#include "createTime.H"
|
||||
|
||||
// Create movement without a mesh
|
||||
autoPtr<lumpedPointIOMovement> movementPtr =
|
||||
lumpedPointIOMovement::New(runTime);
|
||||
|
||||
if (!movementPtr)
|
||||
{
|
||||
Info<< "No valid movement found" << endl;
|
||||
return 1;
|
||||
}
|
||||
auto& movement = *movementPtr;
|
||||
|
||||
// Reference state0
|
||||
const lumpedPointState& state0 = movement.state0();
|
||||
|
||||
externalFileCoupler& coupler = movement.coupler();
|
||||
|
||||
for (label timei = 0; infiniteLoop || (timei < nTimes); ++timei)
|
||||
{
|
||||
Info<< args.executable() << ": waiting for master" << endl;
|
||||
|
||||
// Wait for master, but stop if status=done was seen
|
||||
if (!coupler.waitForMaster())
|
||||
{
|
||||
Info<< args.executable()
|
||||
<< ": stopping status=done was detected" << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
scalar timeValue = currTime;
|
||||
|
||||
if (infiniteLoop)
|
||||
{
|
||||
// Get output file
|
||||
IFstream is(coupler.resolveFile(movement.outputName()));
|
||||
|
||||
dictionary dict;
|
||||
is >> dict;
|
||||
|
||||
timeValue = dict.get<scalar>("time");
|
||||
}
|
||||
|
||||
lumpedPointState state(gen.state(timeValue));
|
||||
state.relax(relax, state0);
|
||||
|
||||
// Generate input for OpenFOAM
|
||||
{
|
||||
OFstream os(coupler.resolveFile(movement.inputName()));
|
||||
if
|
||||
(
|
||||
movement.inputFormat()
|
||||
== lumpedPointState::inputFormatType::PLAIN
|
||||
)
|
||||
{
|
||||
state.writePlain(os);
|
||||
}
|
||||
else
|
||||
{
|
||||
os.writeEntry("time", timeValue);
|
||||
state.writeDict(os);
|
||||
}
|
||||
}
|
||||
|
||||
Info<< args.executable()
|
||||
<< ": updating state " << timei
|
||||
<< " - switch to master"
|
||||
<< endl;
|
||||
|
||||
// Let OpenFOAM know that it can continue
|
||||
coupler.useMaster();
|
||||
|
||||
currTime += deltaT;
|
||||
}
|
||||
|
||||
if (removeLock)
|
||||
{
|
||||
Info<< args.executable() << ": removing lock file" << endl;
|
||||
coupler.useSlave(); // This removes the lock-file
|
||||
}
|
||||
|
||||
Info<< args.executable() << ": finishing" << nl;
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// dry-run
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
if (dryrun)
|
||||
{
|
||||
Info<< "dry-run: creating states only" << nl;
|
||||
|
||||
autoPtr<Time> runTimePtr;
|
||||
autoPtr<lumpedPointIOMovement> movementPtr;
|
||||
|
||||
const bool throwingIOError = FatalIOError.throwExceptions();
|
||||
const bool throwingError = FatalError.throwExceptions();
|
||||
|
||||
try
|
||||
{
|
||||
Info<< "Create time" << flush;
|
||||
|
||||
runTimePtr = Time::New(args);
|
||||
|
||||
// Create movement without a mesh
|
||||
movementPtr = lumpedPointIOMovement::New(*runTimePtr);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
Info<< " ... failed (optional for dry-run)";
|
||||
}
|
||||
Info<< nl << endl;
|
||||
|
||||
FatalError.throwExceptions(throwingError);
|
||||
FatalIOError.throwExceptions(throwingIOError);
|
||||
|
||||
if (!movementPtr)
|
||||
{
|
||||
Info<< "No time, run without movement information\n" << endl;
|
||||
}
|
||||
|
||||
const lumpedPointState state0(gen.state(0));
|
||||
|
||||
vtk::seriesWriter stateSeries;
|
||||
|
||||
for
|
||||
(
|
||||
label timei = 0, outputCount = 0;
|
||||
timei < nTimes;
|
||||
++timei
|
||||
)
|
||||
{
|
||||
lumpedPointState state(gen.state(currTime));
|
||||
state.relax(relax, state0);
|
||||
|
||||
Info<< "output [" << timei << '/' << nTimes << ']';
|
||||
|
||||
// State/response = what comes back from FEM
|
||||
{
|
||||
const word outputName =
|
||||
word::printf("state_%06d.vtp", outputCount);
|
||||
|
||||
Info<< " " << outputName;
|
||||
|
||||
if (movementPtr)
|
||||
{
|
||||
movementPtr->writeStateVTP(state, outputName);
|
||||
}
|
||||
else
|
||||
{
|
||||
state.writeVTP(outputName);
|
||||
}
|
||||
stateSeries.append(outputCount, outputName);
|
||||
}
|
||||
|
||||
Info<< endl;
|
||||
|
||||
++outputCount;
|
||||
currTime += deltaT;
|
||||
}
|
||||
|
||||
// Write file series
|
||||
if (stateSeries.size())
|
||||
{
|
||||
Info<< nl << "write state.vtp.series" << nl;
|
||||
stateSeries.write("state.vtp");
|
||||
}
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Report values or generate a file
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
if (optQuery || !outputFile.empty())
|
||||
{
|
||||
autoPtr<OFstream> osPtr;
|
||||
|
||||
if (!outputFile.empty())
|
||||
{
|
||||
osPtr.reset(new OFstream(outputFile));
|
||||
auto& os = *osPtr;
|
||||
|
||||
os.precision(8);
|
||||
|
||||
// One file with everything, output using OpenFOAM syntax
|
||||
|
||||
IOobject::writeBanner(os)
|
||||
<< "FoamFile\n{\n"
|
||||
<< " version " << os.version() << ";\n"
|
||||
<< " format " << os.format() << ";\n"
|
||||
<< " class " << "dictionary" << ";\n"
|
||||
<< " object " << "response" << ";\n"
|
||||
<< "}\n";
|
||||
|
||||
IOobject::writeDivider(os) << nl;
|
||||
|
||||
os << "// angles are Euler angles z-x-z (intrinsic)" << nl;
|
||||
os.writeEntry("degrees", "false");
|
||||
os << nl;
|
||||
os << "response" << nl;
|
||||
os << '(' << nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info().precision(8);
|
||||
}
|
||||
|
||||
|
||||
for (label timei = 0; timei < nTimes; ++timei)
|
||||
{
|
||||
lumpedPointState state(gen.state(currTime));
|
||||
|
||||
if (osPtr)
|
||||
{
|
||||
// Report position/angle
|
||||
auto& os = *osPtr;
|
||||
|
||||
os.beginBlock();
|
||||
|
||||
os.writeEntry("time", currTime);
|
||||
|
||||
state.writeDict(os);
|
||||
|
||||
os.endBlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Report position/angle
|
||||
auto& os = Info();
|
||||
|
||||
os.writeEntry("time", currTime);
|
||||
state.writeDict(os);
|
||||
}
|
||||
|
||||
currTime += deltaT;
|
||||
}
|
||||
|
||||
|
||||
if (osPtr)
|
||||
{
|
||||
auto& os = *osPtr;
|
||||
|
||||
os << ')' << token::END_STATEMENT << nl;
|
||||
|
||||
IOobject::writeEndDivider(os);
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// test patch movement
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#include "createTime.H"
|
||||
|
||||
runTime.setTime(instant(runTime.constant()), 0);
|
||||
|
||||
#include "createNamedMesh.H"
|
||||
|
||||
// Create movement with mesh
|
||||
autoPtr<lumpedPointIOMovement> movementPtr =
|
||||
lumpedPointIOMovement::New(mesh);
|
||||
|
||||
if (!movementPtr)
|
||||
{
|
||||
Info<< "No valid movement found" << endl;
|
||||
return 1;
|
||||
}
|
||||
auto& movement = *movementPtr;
|
||||
|
||||
// Reference state0
|
||||
const lumpedPointState& state0 = movement.state0();
|
||||
|
||||
pointIOField points0(lumpedPointTools::points0Field(mesh));
|
||||
|
||||
const label nPatches = lumpedPointTools::setPatchControls(mesh, points0);
|
||||
if (!nPatches)
|
||||
{
|
||||
Info<< "No point patches with lumped movement found" << endl;
|
||||
return 2;
|
||||
}
|
||||
|
||||
Info<< "Lumped point patch controls set on "
|
||||
<< nPatches << " patches" << nl;
|
||||
|
||||
lumpedPointTools::setInterpolators(mesh, points0);
|
||||
|
||||
|
||||
// Output vtk file series
|
||||
vtk::seriesWriter stateSeries;
|
||||
vtk::seriesWriter geomSeries;
|
||||
|
||||
// Initial geometry
|
||||
movement.writeVTP("geom_init.vtp", state0, mesh, points0);
|
||||
|
||||
lumpedPointTools::setInterpolators(mesh);
|
||||
|
||||
for
|
||||
(
|
||||
label timei = 0, outputCount = 0;
|
||||
timei < nTimes;
|
||||
++timei
|
||||
)
|
||||
{
|
||||
lumpedPointState state(gen.state(currTime));
|
||||
|
||||
state += movement.origin();
|
||||
movement.scalePoints(state);
|
||||
state.relax(relax, state0);
|
||||
|
||||
Info<< "output [" << timei << '/' << nTimes << ']';
|
||||
|
||||
// State/response = what comes back from FEM
|
||||
{
|
||||
const word outputName =
|
||||
word::printf("state_%06d.vtp", outputCount);
|
||||
|
||||
Info<< " " << outputName;
|
||||
|
||||
movement.writeStateVTP(state, outputName);
|
||||
stateSeries.append(outputCount, outputName);
|
||||
}
|
||||
|
||||
{
|
||||
const word outputName =
|
||||
word::printf("geom_%06d.vtp", outputCount);
|
||||
|
||||
Info<< " " << outputName;
|
||||
|
||||
movement.writeVTP(outputName, state, mesh, points0);
|
||||
geomSeries.append(outputCount, outputName);
|
||||
}
|
||||
|
||||
Info<< endl;
|
||||
|
||||
++outputCount;
|
||||
currTime += deltaT;
|
||||
}
|
||||
|
||||
|
||||
// Write file series
|
||||
|
||||
if (geomSeries.size())
|
||||
{
|
||||
Info<< nl << "write geom.vtp.series" << nl;
|
||||
geomSeries.write("geom.vtp");
|
||||
}
|
||||
if (stateSeries.size())
|
||||
{
|
||||
Info<< nl << "write state.vtp.series" << nl;
|
||||
stateSeries.write("state.vtp");
|
||||
}
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
34
tutorials/incompressible/lumpedPointMotion/building/files/Allrun.moveMesh
Executable file
34
tutorials/incompressible/lumpedPointMotion/building/files/Allrun.moveMesh
Executable file
@ -0,0 +1,34 @@
|
||||
#!/bin/sh
|
||||
cd "${0%/*}" || exit # Run from this directory
|
||||
. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# Cleanup old junk that may prevent things from starting
|
||||
rm -f comms/OpenFOAM.lock
|
||||
|
||||
# If OpenFOAM stops prematurely, trigger the external solver to stop
|
||||
trap '[ -e comms/OpenFOAM.lock ] && echo "status=done" > comms/OpenFOAM.lock' EXIT TERM INT
|
||||
|
||||
# Simulated external solver.
|
||||
# Using -scale 0.01 since input movement table included visual scaling
|
||||
|
||||
if false
|
||||
then
|
||||
# Create response file
|
||||
runApplication -overwrite \
|
||||
../code/building-motion -deltaT 0.001 -nTimes 5001 -output response.txt
|
||||
|
||||
# Use response file for states
|
||||
runApplication -overwrite \
|
||||
lumpedPointMovement -scale 0.01 -removeLock -slave response.txt &
|
||||
else
|
||||
|
||||
# Generate states on demand
|
||||
runApplication -overwrite \
|
||||
../code/building-motion -scale 0.01 -removeLock -slave &
|
||||
fi
|
||||
|
||||
# Run moveMesh with deltaT corresponding to dynamicMeshDict updateInterval
|
||||
runParallel moveMesh -deltaT 0.001
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
@ -12,7 +12,22 @@ runApplication reconstructParMesh -constant -withZero -time 0
|
||||
runApplication lumpedPointZones
|
||||
|
||||
# Simulated external solver
|
||||
# Using -scale=1 to see the excessively large movements
|
||||
runApplication lumpedPointMovement -span 25 -scale 1 ../files/response.txt
|
||||
# Use -scale=1 to see the excessively large movements
|
||||
|
||||
if false
|
||||
then
|
||||
# Create response file
|
||||
runApplication -overwrite \
|
||||
../code/building-motion -deltaT 0.001 -nTimes 5001 -output response.txt
|
||||
|
||||
# Use response file for states
|
||||
runApplication -overwrite \
|
||||
lumpedPointMovement -span 25 -scale 1 response.txt
|
||||
else
|
||||
|
||||
# Generate states on demand
|
||||
runApplication -overwrite \
|
||||
../code/building-motion -scale 1 -deltaT 0.025 -nTimes 201
|
||||
fi
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
@ -10,9 +10,23 @@ rm -f comms/OpenFOAM.lock
|
||||
trap '[ -e comms/OpenFOAM.lock ] && echo "status=done" > comms/OpenFOAM.lock' EXIT TERM INT
|
||||
|
||||
# Simulated external solver.
|
||||
# Using -scale since the input movement table is excessively large
|
||||
runApplication -overwrite \
|
||||
lumpedPointMovement -scale 0.01 -removeLock -slave ../files/response.txt &
|
||||
# Using -scale 0.01 since input movement table included visual scaling
|
||||
|
||||
if false
|
||||
then
|
||||
# Create response file
|
||||
runApplication -overwrite \
|
||||
../code/building-motion -deltaT 0.001 -nTimes 5001 -output response.txt
|
||||
|
||||
# Use response file for states
|
||||
runApplication -overwrite \
|
||||
lumpedPointMovement -scale 0.01 -removeLock -slave response.txt &
|
||||
else
|
||||
|
||||
# Generate states on demand
|
||||
runApplication -overwrite \
|
||||
../code/building-motion -scale 0.01 -removeLock -slave &
|
||||
fi
|
||||
|
||||
# Run OpenFOAM
|
||||
runParallel $(getApplication)
|
||||
|
||||
@ -0,0 +1,147 @@
|
||||
#---------------------------------*- sh -*-------------------------------------
|
||||
# ========= |
|
||||
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
# \\ / O peration |
|
||||
# \\ / A nd | www.openfoam.com
|
||||
# \\/ M anipulation |
|
||||
#------------------------------------------------------------------------------
|
||||
# Copyright (C) 2020 OpenCFD Ltd.
|
||||
#------------------------------------------------------------------------------
|
||||
# License
|
||||
# This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||
#
|
||||
# Script
|
||||
# RunFunctions
|
||||
#
|
||||
# Description
|
||||
# Additional functions for copy/linking FSI cases
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# copyParallelPointDisplacement caseDir timeName
|
||||
#
|
||||
# Copy pointDisplacement from caseDir/0/ to caseDir/timeName/
|
||||
#
|
||||
copyParallelPointDisplacement()
|
||||
{
|
||||
local src="$1"
|
||||
local dstTime="$2"
|
||||
local file=pointDisplacement
|
||||
|
||||
[ -d "$src" ] || {
|
||||
echo "Error: no directory: $src"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Copy select directories
|
||||
echo " copy processor '$file' from 0/ -> $dstTime"
|
||||
if [ -n "$dstTime" ]
|
||||
then
|
||||
(
|
||||
cd "$src" || exit
|
||||
|
||||
for proc in processor*
|
||||
do
|
||||
if [ -d "$proc/0" ] && [ -d "$proc/$dstTime" ]
|
||||
then
|
||||
cp "$proc/0/$file" "$proc/$dstTime/$file"
|
||||
if [ -d "$proc/0/include" ]
|
||||
then
|
||||
cp -r "$proc/0/include" "$proc/$dstTime"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
)
|
||||
else
|
||||
echo " no destination time"
|
||||
fi
|
||||
|
||||
# Restart from latestTime
|
||||
foamDictionary "$src"/system/controlDict \
|
||||
-entry startFrom -set latestTime
|
||||
|
||||
deltaT=$(foamDictionary "$src"/system/controlDict -entry deltaT -value)
|
||||
latestTime=$(foamListTimes -case "$src" -noZero -latestTime -processor)
|
||||
|
||||
# Restart using steady results as first deltaT interval
|
||||
echo "deltaT=$deltaT latestTime=$latestTime"
|
||||
if [ -n "$latestTime" ] && [ "$deltaT" != "$latestTime" ]
|
||||
then
|
||||
(
|
||||
cd "$src" || exit
|
||||
|
||||
for proc in processor*
|
||||
do
|
||||
if [ -d "$proc/$latestTime" ] && [ ! -d "$proc/$deltaT" ]
|
||||
then
|
||||
mv "$proc/$latestTime" "$proc/$deltaT"
|
||||
rm -rf "$proc/$deltaT/uniform"
|
||||
fi
|
||||
done
|
||||
)
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
#
|
||||
# linkParallelCase srcDir dstDir
|
||||
#
|
||||
linkParallelCase()
|
||||
{
|
||||
local src="$1"
|
||||
local dst="$2"
|
||||
shift 2
|
||||
|
||||
if [ -e "$dst" ]
|
||||
then
|
||||
echo "Case already linked: remove case directory $dst prior to linking"
|
||||
return 1
|
||||
elif [ ! -d "$src" ]
|
||||
then
|
||||
echo "Error: no directory to link: $src"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "Linking $dst parallel case from $src"
|
||||
mkdir -p "$dst"
|
||||
|
||||
# Copy system - may wish to change things
|
||||
for i in system 0
|
||||
do
|
||||
echo " copy $i/"
|
||||
( cd "$dst" && cp -r "../$src/$i" . )
|
||||
done
|
||||
|
||||
echo " link constant/"
|
||||
( cd "$dst" && ln -sf "../$src/constant" . )
|
||||
|
||||
echo " link processor*/ with $# times: $@"
|
||||
for proc in $(cd "$src" && \ls -d processor*)
|
||||
do
|
||||
( cd "$dst" && ln -sf "../$src/$proc" . )
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
#
|
||||
# linkFiles srcDir dstDir
|
||||
#
|
||||
linkFiles()
|
||||
{
|
||||
local src="$1"
|
||||
local dst="$2"
|
||||
shift
|
||||
|
||||
echo "Linking $dst control files from $src"
|
||||
mkdir -p "$dst"
|
||||
|
||||
( cd "$dst" && ln -sf ../"$src"/* . )
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / O peration | Version: v2006 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -67,6 +67,7 @@ boundaryField
|
||||
{
|
||||
type lumpedPointDisplacement;
|
||||
value uniform (0 0 0);
|
||||
controllers ( vertical );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -8,4 +8,7 @@ cleanCase0
|
||||
# Clean up copied/derived files
|
||||
rm -rf constant/triSurface
|
||||
|
||||
# Clean up debug/setup files
|
||||
rm -f *.txt *.vtp *.vtp.series
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
@ -21,5 +21,4 @@ else
|
||||
|
||||
fi
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
11
tutorials/incompressible/lumpedPointMotion/building/steady/Allrun.init
Executable file
11
tutorials/incompressible/lumpedPointMotion/building/steady/Allrun.init
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
cd "${0%/*}" || exit # Run from this directory
|
||||
. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# Copy geometry from resources directory
|
||||
|
||||
mkdir -p constant/triSurface/
|
||||
cp "$FOAM_TUTORIALS"/resources/geometry/building_wtc2.obj constant/triSurface/
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
@ -3,9 +3,8 @@ cd "${0%/*}" || exit # Run from this directory
|
||||
. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# Copy building from resources directory
|
||||
mkdir -p constant/triSurface/
|
||||
cp $FOAM_TUTORIALS/resources/geometry/building_wtc2.obj constant/triSurface/
|
||||
# Get geometry and other resources
|
||||
./Allrun.init
|
||||
|
||||
# runApplication surfaceFeatureExtract
|
||||
runApplication blockMesh
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / O peration | Version: v2006 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -13,9 +13,13 @@ FoamFile
|
||||
location "system";
|
||||
object dynamicMeshDict;
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Less frequent mesh motion
|
||||
updateControl runTime;
|
||||
|
||||
updateInterval 0.001;
|
||||
|
||||
dynamicFvMesh dynamicMotionSolverFvMesh;
|
||||
|
||||
motionSolverLibs (fvMotionSolvers);
|
||||
|
||||
@ -0,0 +1,44 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2006 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
class dictionary;
|
||||
note "locations and connectivity";
|
||||
object dictionary;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
//- Locations of the lumped points
|
||||
points
|
||||
(
|
||||
(0 0 0.00)
|
||||
(0 0 0.05)
|
||||
(0 0 0.10)
|
||||
(0 0 0.15)
|
||||
(0 0 0.20)
|
||||
(0 0 0.25)
|
||||
(0 0 0.30)
|
||||
(0 0 0.35)
|
||||
(0 0 0.40)
|
||||
(0 0 0.45)
|
||||
(0 0 0.50)
|
||||
);
|
||||
|
||||
//- Connectivity for motion controllers
|
||||
controllers
|
||||
{
|
||||
vertical
|
||||
{
|
||||
pointLabels (0 1 2 3 4 5 6 7 8 9 10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,7 +1,7 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v1912 |
|
||||
| \\ / O peration | Version: v2006 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -15,36 +15,24 @@ FoamFile
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Reference axis for the locations
|
||||
axis (0 0 1);
|
||||
#include "lumpedPointControllers"
|
||||
|
||||
// Locations of the lumped points
|
||||
locations 11(0 0.05 0.1 0.15 0.2 0.25 0.3 0.35 0.4 0.45 0.5);
|
||||
|
||||
// Division for pressure forces (0-1)
|
||||
division 0.5;
|
||||
|
||||
//- If present, the offset of patch points compared to the locations
|
||||
// Otherwise determined from the bounding box
|
||||
// centre (0 0 0);
|
||||
|
||||
//- The interpolation scheme
|
||||
interpolationScheme linear;
|
||||
//- Offset/shift for lumped points
|
||||
origin (0.3 0.15 0);
|
||||
|
||||
//- Relaxation/scaling factor when updating positions
|
||||
relax 1.0;
|
||||
|
||||
relax 1.0;
|
||||
|
||||
forces
|
||||
{
|
||||
//- The pressure name (default: p)
|
||||
p p;
|
||||
p p;
|
||||
|
||||
//- Reference pressure [Pa] (default: 0)
|
||||
pRef 0;
|
||||
pRef 0;
|
||||
|
||||
//- Reference density for incompressible calculations (default: 1)
|
||||
rhoRef 1;
|
||||
rhoRef 1;
|
||||
}
|
||||
|
||||
|
||||
@ -56,6 +44,9 @@ communication
|
||||
|
||||
waitInterval 1;
|
||||
|
||||
// Coupling frequency (default: 1)
|
||||
//calcFrequency 1;
|
||||
|
||||
timeOut 100;
|
||||
|
||||
initByExternal false;
|
||||
@ -78,20 +69,20 @@ communication
|
||||
scaleInput
|
||||
{
|
||||
//- Length multiplier (to metres). Eg 0.001 for [mm] -> [m]
|
||||
length 1;
|
||||
length 1;
|
||||
}
|
||||
|
||||
// Scaling applied to values written to 'outputName'
|
||||
scaleOutput
|
||||
{
|
||||
//- Length multiplier (from metres). Eg 1000 for [m] -> [mm]
|
||||
length 1;
|
||||
length 1;
|
||||
|
||||
//- Force units multiplier (from Pa)
|
||||
force 1;
|
||||
force 1;
|
||||
|
||||
//- Moment units multiplier (from N.m)
|
||||
moment 1;
|
||||
moment 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user