mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'develop-feature-abaqus' into 'develop'
Added Abaqus sampling and writing See merge request Development/openfoam!644
This commit is contained in:
@ -116,6 +116,7 @@ coordSet/coordSet.C
|
|||||||
|
|
||||||
setWriters = coordSet/writers
|
setWriters = coordSet/writers
|
||||||
|
|
||||||
|
$(setWriters)/abaqus/abaqusCoordSetWriter.C
|
||||||
$(setWriters)/common/coordSetWriter.C
|
$(setWriters)/common/coordSetWriter.C
|
||||||
$(setWriters)/common/coordSetWriterBuffers.C
|
$(setWriters)/common/coordSetWriterBuffers.C
|
||||||
$(setWriters)/common/coordSetWriterNew.C
|
$(setWriters)/common/coordSetWriterNew.C
|
||||||
|
|||||||
409
src/meshTools/coordSet/writers/abaqus/abaqusCoordSetWriter.C
Normal file
409
src/meshTools/coordSet/writers/abaqus/abaqusCoordSetWriter.C
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2023 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/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "abaqusCoordSetWriter.H"
|
||||||
|
#include "coordSet.H"
|
||||||
|
#include "IOmanip.H"
|
||||||
|
#include "OFstream.H"
|
||||||
|
#include "OSspecific.H"
|
||||||
|
#include "stringOps.H"
|
||||||
|
#include "coordSetWriterMethods.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace coordSetWriters
|
||||||
|
{
|
||||||
|
defineTypeName(abaqusWriter);
|
||||||
|
addToRunTimeSelectionTable(coordSetWriter, abaqusWriter, word);
|
||||||
|
addToRunTimeSelectionTable(coordSetWriter, abaqusWriter, wordDict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Foam::Enum<Foam::coordSetWriters::abaqusWriter::timeBase>
|
||||||
|
Foam::coordSetWriters::abaqusWriter::timeBaseNames_
|
||||||
|
({
|
||||||
|
{ timeBase::time, "time" },
|
||||||
|
{ timeBase::iter, "iteration" },
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
template<class Type>
|
||||||
|
static inline void putValue(Ostream& os, const Type& value, const int width)
|
||||||
|
{
|
||||||
|
if (width) os << setw(width);
|
||||||
|
os << value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::string Foam::coordSetWriters::abaqusWriter::replaceUserEntries
|
||||||
|
(
|
||||||
|
const string& str,
|
||||||
|
const dictionary& vars
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
string result = str;
|
||||||
|
|
||||||
|
const bool allowEnv = true;
|
||||||
|
const bool allowEmpty = false;
|
||||||
|
|
||||||
|
stringOps::inplaceExpand(result, vars, allowEnv, allowEmpty);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriters::abaqusWriter::appendTimeName
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
fileName& fName
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if (useTimeDir())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (timeBase_)
|
||||||
|
{
|
||||||
|
case timeBase::time:
|
||||||
|
{
|
||||||
|
fName.ext(timeName());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case timeBase::iter:
|
||||||
|
{
|
||||||
|
fName.ext(Foam::name(writeIndex_[fieldName]));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Unhandled enumeration " << timeBaseNames_[timeBase_]
|
||||||
|
<< ". Available options: " << timeBaseNames_.sortedToc()
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::coordSetWriters::abaqusWriter::abaqusWriter()
|
||||||
|
:
|
||||||
|
coordSetWriter(),
|
||||||
|
outputHeader_(),
|
||||||
|
writeGeometry_(false),
|
||||||
|
nullValue_(pTraits<scalar>::min),
|
||||||
|
useLocalTimeDir_(coordSetWriter::useTimeDir()),
|
||||||
|
timeBase_(timeBase::time),
|
||||||
|
writeIndex_(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriters::abaqusWriter::abaqusWriter(const dictionary& options)
|
||||||
|
:
|
||||||
|
coordSetWriter(options),
|
||||||
|
outputHeader_(),
|
||||||
|
writeGeometry_(false),
|
||||||
|
nullValue_(pTraits<scalar>::min),
|
||||||
|
useLocalTimeDir_(coordSetWriter::useTimeDir()),
|
||||||
|
timeBase_(timeBase::time),
|
||||||
|
writeIndex_(0)
|
||||||
|
{
|
||||||
|
options.readIfPresent("header", outputHeader_);
|
||||||
|
|
||||||
|
options.readIfPresent("useTimeDir", useLocalTimeDir_);
|
||||||
|
|
||||||
|
if (!useLocalTimeDir_)
|
||||||
|
{
|
||||||
|
timeBaseNames_.readIfPresent("timeBase", options, timeBase_);
|
||||||
|
options.readIfPresent("writeIndex", writeIndex_);
|
||||||
|
}
|
||||||
|
|
||||||
|
options.readIfPresent("writeGeometry", writeGeometry_);
|
||||||
|
|
||||||
|
options.readIfPresent("nullValue", nullValue_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriters::abaqusWriter::abaqusWriter
|
||||||
|
(
|
||||||
|
const coordSet& coords,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
abaqusWriter(options)
|
||||||
|
{
|
||||||
|
open(coords, outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::coordSetWriters::abaqusWriter::abaqusWriter
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options
|
||||||
|
)
|
||||||
|
:
|
||||||
|
abaqusWriter(options)
|
||||||
|
{
|
||||||
|
open(tracks, outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::coordSetWriters::abaqusWriter::~abaqusWriter()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::fileName Foam::coordSetWriters::abaqusWriter::path() const
|
||||||
|
{
|
||||||
|
// 1) rootdir/<TIME>/setName.{inp}
|
||||||
|
// 2) rootdir/setName.{inp}
|
||||||
|
|
||||||
|
return getExpectedPath("inp");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::coordSetWriters::abaqusWriter::writeGeometry
|
||||||
|
(
|
||||||
|
Ostream& os,
|
||||||
|
label nTracks
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if (!writeGeometry_ || coords_.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
os << "** Geometry" << nl
|
||||||
|
<< "**" << nl
|
||||||
|
<< "** Points" << nl
|
||||||
|
<< "**" << nl;
|
||||||
|
|
||||||
|
// Write points
|
||||||
|
label globalPointi = 1;
|
||||||
|
for (const coordSet& coords : coords_)
|
||||||
|
{
|
||||||
|
for (const point& p : coords)
|
||||||
|
{
|
||||||
|
const point tp = p*geometryScale_;
|
||||||
|
|
||||||
|
os << globalPointi << ", "
|
||||||
|
<< tp[0] << ", " << tp[1] << ", " << tp[2] << nl;
|
||||||
|
|
||||||
|
++globalPointi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nTracks)
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< "Tracks not implemented for " << typeName << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
wroteGeom_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fileName Foam::coordSetWriters::abaqusWriter::writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const Field<Type>& values
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// useTimeDir(options.getOrDefault("useTimeDir", true));
|
||||||
|
useTimeDir(useLocalTimeDir_);
|
||||||
|
|
||||||
|
// Note - invalid samples are set to pTraits<Type>::max in sampledSetsImpl.C
|
||||||
|
|
||||||
|
checkOpen();
|
||||||
|
if (coords_.empty())
|
||||||
|
{
|
||||||
|
return fileName::null;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileName outputFile = path();
|
||||||
|
|
||||||
|
if (!wroteGeom_)
|
||||||
|
{
|
||||||
|
if (!writeIndex_.insert(fieldName, 0))
|
||||||
|
{
|
||||||
|
++writeIndex_[fieldName];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isDir(outputFile.path()))
|
||||||
|
{
|
||||||
|
mkDir(outputFile.path());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (writeGeometry_)
|
||||||
|
{
|
||||||
|
const word geomName("geometry");
|
||||||
|
if (!writeIndex_.insert(geomName, 0))
|
||||||
|
{
|
||||||
|
++writeIndex_[geomName];
|
||||||
|
}
|
||||||
|
|
||||||
|
fileName geomFileName(outputFile.lessExt() + ".inp");
|
||||||
|
|
||||||
|
appendTimeName("geometry", geomFileName);
|
||||||
|
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< "Writing abaqus geometry to " << geomFileName << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
OFstream osGeom(geomFileName);
|
||||||
|
|
||||||
|
writeGeometry(osGeom, (useTracks_ ? coords_.size() : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
fileName fieldFileName(outputFile.lessExt() + ".inp_" + fieldName);
|
||||||
|
appendTimeName(fieldName, fieldFileName);
|
||||||
|
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< "Writing field data to " << fieldFileName << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
OFstream os(fieldFileName);
|
||||||
|
|
||||||
|
if (!outputHeader_.empty())
|
||||||
|
{
|
||||||
|
dictionary vars;
|
||||||
|
vars.add("TIME", timeName());
|
||||||
|
vars.add("FIELD_NAME", fieldName);
|
||||||
|
vars.add("FILE_NAME", fieldFileName);
|
||||||
|
|
||||||
|
for (const auto& s : outputHeader_)
|
||||||
|
{
|
||||||
|
os << replaceUserEntries(s, vars).c_str() << nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
os << "** OpenFOAM " << fieldFileName.nameLessExt() << nl
|
||||||
|
<< "** Project " << outputFile << nl
|
||||||
|
<< "** Field=" << fieldName << " Time=" << timeName() << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp<Field<Type>> tfield(values);
|
||||||
|
tfield = adjustFieldTemplate(fieldName, tfield);
|
||||||
|
const auto& field = tfield();
|
||||||
|
|
||||||
|
forAll(field, samplei)
|
||||||
|
{
|
||||||
|
os << (samplei+1);
|
||||||
|
for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; ++cmpt)
|
||||||
|
{
|
||||||
|
// Work-around to set null values - set to pTraits<Type>::max
|
||||||
|
// by default
|
||||||
|
scalar s = component(field[samplei], cmpt);
|
||||||
|
if (s > 0.5*pTraits<scalar>::max)
|
||||||
|
{
|
||||||
|
s = nullValue_;
|
||||||
|
}
|
||||||
|
|
||||||
|
os << ", " << s;
|
||||||
|
}
|
||||||
|
os << nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return outputFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fileName Foam::coordSetWriters::abaqusWriter::writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const List<Field<Type>>& fieldValues
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Track writing
|
||||||
|
|
||||||
|
checkOpen();
|
||||||
|
if (coords_.empty())
|
||||||
|
{
|
||||||
|
return fileName::null;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileName outputFile = path();
|
||||||
|
|
||||||
|
if (!wroteGeom_)
|
||||||
|
{
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< "Writing abaqus geometry to " << outputFile << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isDir(outputFile.path()))
|
||||||
|
{
|
||||||
|
mkDir(outputFile.path());
|
||||||
|
}
|
||||||
|
|
||||||
|
OFstream osGeom(outputFile.lessExt() + "." + fieldName + ".inp");
|
||||||
|
|
||||||
|
osGeom
|
||||||
|
<< "** Geometry" << nl
|
||||||
|
<< "**" << nl
|
||||||
|
<< "** Points" << nl
|
||||||
|
<< "**" << nl;
|
||||||
|
|
||||||
|
writeGeometry(osGeom, coords_.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
return outputFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Field writing methods
|
||||||
|
defineCoordSetWriterWriteFields(Foam::coordSetWriters::abaqusWriter);
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
251
src/meshTools/coordSet/writers/abaqus/abaqusCoordSetWriter.H
Normal file
251
src/meshTools/coordSet/writers/abaqus/abaqusCoordSetWriter.H
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2023 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/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::coordSetWriters::abaqusWriter
|
||||||
|
|
||||||
|
Description
|
||||||
|
Write coordSet(s) as Abaqus point fields
|
||||||
|
|
||||||
|
Example usage
|
||||||
|
\verbatim
|
||||||
|
T
|
||||||
|
{
|
||||||
|
type sets;
|
||||||
|
setFormat abaqus;
|
||||||
|
fields (T);
|
||||||
|
sets
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
Optional format options
|
||||||
|
\verbatim
|
||||||
|
formatOptions
|
||||||
|
{
|
||||||
|
abaqus
|
||||||
|
{
|
||||||
|
format ascii;
|
||||||
|
|
||||||
|
// Optional entries
|
||||||
|
|
||||||
|
// Custom header: $ entries are substituions
|
||||||
|
header
|
||||||
|
(
|
||||||
|
"** OpenFOAM abaqus output"
|
||||||
|
"** Project $FOAM_CASE"
|
||||||
|
"** File $FILE_NAME"
|
||||||
|
"** $FIELD_NAME Time t=$TIME"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Write geometry in addition to field data
|
||||||
|
writeGeometry yes;
|
||||||
|
|
||||||
|
// Null value when sample value is not found
|
||||||
|
// Default is scalar::min
|
||||||
|
nullValue 0;
|
||||||
|
|
||||||
|
// Insert additional time sub-directory in the output path
|
||||||
|
// - yes : postProcessing/<fo-name>/<time>/<file>
|
||||||
|
// - no : postProcessing/<fo-name>/<file>
|
||||||
|
useTimeDir no;
|
||||||
|
|
||||||
|
// Available when 'useTimeDir' is 'no' to disambiguate file names
|
||||||
|
|
||||||
|
// Time base for output file names:
|
||||||
|
// - 'time' : <base>.inp_<field>.<time>
|
||||||
|
// - 'iteration' : <base>.inp_<field>.<iteration>
|
||||||
|
timeBase iteration;
|
||||||
|
|
||||||
|
// Optional start counters when using timeBase iteration
|
||||||
|
writeIndex
|
||||||
|
(
|
||||||
|
T 1
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
abaqusCoordSetWriter.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef Foam_coordSetWriters_abaqusWriter_H
|
||||||
|
#define Foam_coordSetWriters_abaqusWriter_H
|
||||||
|
|
||||||
|
#include "coordSetWriter.H"
|
||||||
|
#include "Enum.H"
|
||||||
|
#include "HashTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace coordSetWriters
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class abaqusWriter Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class abaqusWriter
|
||||||
|
:
|
||||||
|
public coordSetWriter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Public enumerations
|
||||||
|
|
||||||
|
//- Enumeration for time base
|
||||||
|
enum class timeBase { time, iter };
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- Time base names
|
||||||
|
static const Enum<timeBase> timeBaseNames_;
|
||||||
|
|
||||||
|
//- Optional user-defined header
|
||||||
|
List<string> outputHeader_;
|
||||||
|
|
||||||
|
//- User flag to write the geometry
|
||||||
|
bool writeGeometry_;
|
||||||
|
|
||||||
|
//- Null value; default = scalar::min
|
||||||
|
scalar nullValue_;
|
||||||
|
|
||||||
|
//- Optional override of localTimeDir
|
||||||
|
bool useLocalTimeDir_;
|
||||||
|
|
||||||
|
//- Optional time base when useLocalTimeDir_ = false
|
||||||
|
timeBase timeBase_;
|
||||||
|
|
||||||
|
//- Write index
|
||||||
|
HashTable<label> writeIndex_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Helper to replace $WORD entries in str
|
||||||
|
string replaceUserEntries
|
||||||
|
(
|
||||||
|
const string& str,
|
||||||
|
const dictionary& vars
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Write the formatted keyword to the output stream
|
||||||
|
Ostream& writeKeyword(Ostream& os, const word& keyword) const;
|
||||||
|
|
||||||
|
//- Append time name when useLocalTimeDir_ = false
|
||||||
|
void appendTimeName(const word& fieldName, fileName& fName) const;
|
||||||
|
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName, //!< Name of field
|
||||||
|
const Field<Type>& values //!< Local field values to write
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Templated write operation
|
||||||
|
template<class Type>
|
||||||
|
fileName writeTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const List<Field<Type>>& fieldValues
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Write geometry to file.
|
||||||
|
void writeGeometry(Ostream& os, label nTracks) const;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information (no debug)
|
||||||
|
TypeNameNoDebug("abaqus");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Default construct
|
||||||
|
abaqusWriter();
|
||||||
|
|
||||||
|
//- Default construct with specified options
|
||||||
|
explicit abaqusWriter(const dictionary& options);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
abaqusWriter
|
||||||
|
(
|
||||||
|
const coordSet& coords,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
abaqusWriter
|
||||||
|
(
|
||||||
|
const UPtrList<coordSet>& tracks,
|
||||||
|
const fileName& outputPath,
|
||||||
|
const dictionary& options = dictionary()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor. Calls close()
|
||||||
|
virtual ~abaqusWriter();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Characteristic output file name - information only
|
||||||
|
virtual fileName path() const; // override
|
||||||
|
|
||||||
|
declareCoordSetWriterWriteMethod(label);
|
||||||
|
declareCoordSetWriterWriteMethod(scalar);
|
||||||
|
declareCoordSetWriterWriteMethod(vector);
|
||||||
|
declareCoordSetWriterWriteMethod(sphericalTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(symmTensor);
|
||||||
|
declareCoordSetWriterWriteMethod(tensor);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace coordSetWriters
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -117,7 +117,12 @@ Foam::coordSetWriter::coordSetWriter()
|
|||||||
verbose_(false),
|
verbose_(false),
|
||||||
nFields_(0),
|
nFields_(0),
|
||||||
currTime_(),
|
currTime_(),
|
||||||
outputPath_()
|
outputPath_(),
|
||||||
|
geometryScale_(1),
|
||||||
|
geometryCentre_(Zero),
|
||||||
|
geometryTransform_(),
|
||||||
|
fieldLevel_(),
|
||||||
|
fieldScale_()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -126,6 +131,27 @@ Foam::coordSetWriter::coordSetWriter(const dictionary& options)
|
|||||||
coordSetWriter()
|
coordSetWriter()
|
||||||
{
|
{
|
||||||
options.readIfPresent("verbose", verbose_);
|
options.readIfPresent("verbose", verbose_);
|
||||||
|
|
||||||
|
geometryScale_ = 1;
|
||||||
|
geometryCentre_ = Zero;
|
||||||
|
geometryTransform_.clear();
|
||||||
|
|
||||||
|
options.readIfPresent("scale", geometryScale_);
|
||||||
|
|
||||||
|
// Optional cartesian coordinate system transform
|
||||||
|
const auto* dictptr = options.findDict("transform", keyType::LITERAL);
|
||||||
|
|
||||||
|
if (dictptr)
|
||||||
|
{
|
||||||
|
dictptr->readIfPresent("rotationCentre", geometryCentre_);
|
||||||
|
|
||||||
|
// 'origin' is optional within sub-dictionary
|
||||||
|
geometryTransform_ =
|
||||||
|
coordSystem::cartesian(*dictptr, IOobjectOption::LAZY_READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldLevel_ = options.subOrEmptyDict("fieldLevel");
|
||||||
|
fieldScale_ = options.subOrEmptyDict("fieldScale");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -66,6 +66,7 @@ SourceFiles
|
|||||||
#include "UPtrList.H"
|
#include "UPtrList.H"
|
||||||
#include "instant.H"
|
#include "instant.H"
|
||||||
#include "InfoProxy.H"
|
#include "InfoProxy.H"
|
||||||
|
#include "cartesianCS.H"
|
||||||
#include "runTimeSelectionTables.H"
|
#include "runTimeSelectionTables.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
@ -125,6 +126,21 @@ protected:
|
|||||||
//- The full output directory and file (coords) name
|
//- The full output directory and file (coords) name
|
||||||
fileName outputPath_;
|
fileName outputPath_;
|
||||||
|
|
||||||
|
//- Output geometry scaling after rotate/translate
|
||||||
|
scalar geometryScale_;
|
||||||
|
|
||||||
|
//- The centre of rotation (untranslate, translate)
|
||||||
|
point geometryCentre_;
|
||||||
|
|
||||||
|
//- Local coordinate system transformation
|
||||||
|
coordSystem::cartesian geometryTransform_;
|
||||||
|
|
||||||
|
//- Field level to remove (on output)
|
||||||
|
dictionary fieldLevel_;
|
||||||
|
|
||||||
|
//- Field scaling (on output)
|
||||||
|
dictionary fieldScale_;
|
||||||
|
|
||||||
|
|
||||||
// Buffering
|
// Buffering
|
||||||
|
|
||||||
@ -212,6 +228,13 @@ protected:
|
|||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
tmp<Field<Type>> adjustFieldTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const tmp<Field<Type>>& tfield
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Repackage field into a UPtrList
|
//- Repackage field into a UPtrList
|
||||||
template<class Type>
|
template<class Type>
|
||||||
static UPtrList<const Field<Type>>
|
static UPtrList<const Field<Type>>
|
||||||
|
|||||||
@ -25,8 +25,110 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "transformField.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::tmp<Foam::Field<Type>> Foam::coordSetWriter::adjustFieldTemplate
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const tmp<Field<Type>>& tfield
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< "Writing field " << fieldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp<Field<Type>> tadjusted;
|
||||||
|
|
||||||
|
// Output scaling for the variable, but not for integer types
|
||||||
|
// which are typically ids etc.
|
||||||
|
if (!std::is_integral<Type>::value)
|
||||||
|
{
|
||||||
|
scalar value;
|
||||||
|
|
||||||
|
// Remove *uniform* reference level
|
||||||
|
if
|
||||||
|
(
|
||||||
|
fieldLevel_.readIfPresent(fieldName, value, keyType::REGEX)
|
||||||
|
&& !equal(value, 0)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Could also detect brackets (...) and read accordingly
|
||||||
|
// or automatically scale by 1/sqrt(nComponents) instead ...
|
||||||
|
|
||||||
|
Type refLevel;
|
||||||
|
for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; ++cmpt)
|
||||||
|
{
|
||||||
|
setComponent(refLevel, cmpt) = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< " [level " << refLevel << ']';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tadjusted)
|
||||||
|
{
|
||||||
|
// Steal or clone
|
||||||
|
tadjusted.reset(tfield.ptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove offset level
|
||||||
|
tadjusted.ref() -= refLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply scaling
|
||||||
|
if
|
||||||
|
(
|
||||||
|
fieldScale_.readIfPresent(fieldName, value, keyType::REGEX)
|
||||||
|
&& !equal(value, 1)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< " [scaling " << value << ']';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tadjusted)
|
||||||
|
{
|
||||||
|
// Steal or clone
|
||||||
|
tadjusted.reset(tfield.ptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply scaling
|
||||||
|
tadjusted.ref() *= value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotate fields (vector and non-spherical tensors)
|
||||||
|
if
|
||||||
|
(
|
||||||
|
(pTraits<Type>::rank != 0 && pTraits<Type>::nComponents > 1)
|
||||||
|
&& geometryTransform_.valid()
|
||||||
|
&& !geometryTransform_.R().is_identity()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!tadjusted)
|
||||||
|
{
|
||||||
|
// Steal or clone
|
||||||
|
tadjusted.reset(tfield.ptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
Foam::transform
|
||||||
|
(
|
||||||
|
tadjusted.ref(),
|
||||||
|
geometryTransform_.R(),
|
||||||
|
tadjusted()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (tadjusted ? tadjusted : tfield);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::UPtrList<const Foam::Field<Type>>
|
Foam::UPtrList<const Foam::Field<Type>>
|
||||||
Foam::coordSetWriter::repackageFields(const Field<Type>& field)
|
Foam::coordSetWriter::repackageFields(const Field<Type>& field)
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
probes/probes.C
|
probes/probes.C
|
||||||
probes/patchProbes.C
|
probes/patchProbes.C
|
||||||
|
|
||||||
|
sampledSet/abaqus/abaqusMeshSet.C
|
||||||
sampledSet/circle/circleSet.C
|
sampledSet/circle/circleSet.C
|
||||||
sampledSet/cloud/cloudSet.C
|
sampledSet/cloud/cloudSet.C
|
||||||
sampledSet/patchCloud/patchCloudSet.C
|
sampledSet/patchCloud/patchCloudSet.C
|
||||||
|
|||||||
346
src/sampling/sampledSet/abaqus/abaqusMeshSet.C
Normal file
346
src/sampling/sampledSet/abaqus/abaqusMeshSet.C
Normal file
@ -0,0 +1,346 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2023 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/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "abaqusMeshSet.H"
|
||||||
|
#include "stringOps.H"
|
||||||
|
#include "Fstream.H"
|
||||||
|
#include "SpanStream.H"
|
||||||
|
#include "meshSearch.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(abaqusMeshSet, 0);
|
||||||
|
addToRunTimeSelectionTable(sampledSet, abaqusMeshSet, word);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::abaqusMeshSet::readCoord(ISstream& is, vector& coord) const
|
||||||
|
{
|
||||||
|
string buffer;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
//buffer.clear();
|
||||||
|
|
||||||
|
is.getLine(buffer);
|
||||||
|
|
||||||
|
const auto elems = buffer.find("*ELEMENT");
|
||||||
|
|
||||||
|
if (elems != std::string::npos)
|
||||||
|
{
|
||||||
|
buffer.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trim out any '*' comments
|
||||||
|
const auto pos = buffer.find('*');
|
||||||
|
if (pos != std::string::npos)
|
||||||
|
{
|
||||||
|
buffer.erase(pos);
|
||||||
|
}
|
||||||
|
stringOps::inplaceTrimRight(buffer);
|
||||||
|
}
|
||||||
|
while (buffer.empty() && is.good());
|
||||||
|
|
||||||
|
if (buffer.empty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto strings = stringOps::split(buffer, ',');
|
||||||
|
|
||||||
|
if (strings.size() != 4)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Read error: expected format int, float, float, float"
|
||||||
|
<< " but read buffer " << buffer
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i <= 2; ++i)
|
||||||
|
{
|
||||||
|
// Swallow i=0 for node label
|
||||||
|
const auto& s = strings[i+1].str();
|
||||||
|
ISpanStream buf(s.data(), s.length());
|
||||||
|
buf >> coord[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
coord *= scale_;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::abaqusMeshSet::calcSamples
|
||||||
|
(
|
||||||
|
DynamicList<point>& samplingPts,
|
||||||
|
DynamicList<label>& samplingCells,
|
||||||
|
DynamicList<label>& samplingFaces,
|
||||||
|
DynamicList<label>& samplingSegments,
|
||||||
|
DynamicList<scalar>& samplingCurveDist
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
DebugInfo
|
||||||
|
<< "abaqusMeshSet : sampling " << sampleCoords_.size() << " points"
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
List<bool> found(sampleCoords_.size(), false);
|
||||||
|
|
||||||
|
forAll(sampleCoords_, samplei)
|
||||||
|
{
|
||||||
|
const vector& pt = sampleCoords_[samplei];
|
||||||
|
|
||||||
|
label celli = searchEngine().findCell(pt);
|
||||||
|
if (celli != -1)
|
||||||
|
{
|
||||||
|
found[samplei] = true;
|
||||||
|
|
||||||
|
samplingPts.append(pt);
|
||||||
|
samplingCells.append(celli);
|
||||||
|
samplingFaces.append(-1);
|
||||||
|
samplingSegments.append(0);
|
||||||
|
samplingCurveDist.append(1.0*samplei);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Pstream::listCombineAllGather(found, orEqOp<bool>());
|
||||||
|
|
||||||
|
DynamicList<label> lost;
|
||||||
|
forAll(found, samplei)
|
||||||
|
{
|
||||||
|
if (!found[samplei]) lost.append(samplei);
|
||||||
|
}
|
||||||
|
|
||||||
|
const label nFound = sampleCoords_.size() - lost.size();
|
||||||
|
label nOutOfBounds = 0;
|
||||||
|
|
||||||
|
if (Pstream::parRun())
|
||||||
|
{
|
||||||
|
typedef Tuple2<label, Tuple2<label, scalar>> procCellDist;
|
||||||
|
List<procCellDist> pcd(lost.size(), procCellDist(-1, {-1, GREAT}));
|
||||||
|
forAll(pcd, i)
|
||||||
|
{
|
||||||
|
const label samplei = lost[i];
|
||||||
|
const vector& pt0 = sampleCoords_[samplei];
|
||||||
|
const label celli = searchEngine().findNearestCell(pt0);
|
||||||
|
const vector& pt1 = mesh().cellCentres()[celli];
|
||||||
|
const scalar distSqr = magSqr(pt1 - pt0);
|
||||||
|
pcd[i] = procCellDist(Pstream::myProcNo(), {celli, distSqr});
|
||||||
|
}
|
||||||
|
|
||||||
|
Pstream::listCombineAllGather
|
||||||
|
(
|
||||||
|
pcd,
|
||||||
|
[](procCellDist& x, const procCellDist& y)
|
||||||
|
{
|
||||||
|
// Select item with smallest distance
|
||||||
|
if (y.second().second() < x.second().second())
|
||||||
|
{
|
||||||
|
x = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(pcd, i)
|
||||||
|
{
|
||||||
|
const label samplei = lost[i];
|
||||||
|
|
||||||
|
if (pcd[i].second().second() < maxDistSqr_)
|
||||||
|
{
|
||||||
|
if (pcd[i].first() == Pstream::myProcNo())
|
||||||
|
{
|
||||||
|
const label celli = pcd[i].second().first();
|
||||||
|
const vector& pt1 = mesh().cellCentres()[celli];
|
||||||
|
|
||||||
|
samplingPts.append(pt1);
|
||||||
|
samplingCells.append(celli);
|
||||||
|
samplingFaces.append(-1);
|
||||||
|
samplingSegments.append(0);
|
||||||
|
samplingCurveDist.append(1.0*samplei);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Insert points that have not been found as null points
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
samplingPts.append(sampleCoords_[samplei]);
|
||||||
|
samplingCells.append(-1);
|
||||||
|
samplingFaces.append(-1);
|
||||||
|
samplingSegments.append(0);
|
||||||
|
samplingCurveDist.append(1.0*samplei);
|
||||||
|
++nOutOfBounds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Serial running
|
||||||
|
|
||||||
|
forAll(lost, i)
|
||||||
|
{
|
||||||
|
const label samplei = lost[i];
|
||||||
|
const vector& pt0 = sampleCoords_[samplei];
|
||||||
|
const label celli = searchEngine().findNearestCell(pt0);
|
||||||
|
const vector& pt1 = mesh().cellCentres()[celli];
|
||||||
|
const scalar distSqr = magSqr(pt1 - pt0);
|
||||||
|
|
||||||
|
if (distSqr < maxDistSqr_)
|
||||||
|
{
|
||||||
|
samplingPts.append(pt1);
|
||||||
|
samplingCells.append(celli);
|
||||||
|
samplingFaces.append(-1);
|
||||||
|
samplingSegments.append(0);
|
||||||
|
samplingCurveDist.append(1.0*samplei);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Insert points that have not been found as null points
|
||||||
|
samplingPts.append(sampleCoords_[samplei]);
|
||||||
|
samplingCells.append(-1);
|
||||||
|
samplingFaces.append(-1);
|
||||||
|
samplingSegments.append(0);
|
||||||
|
samplingCurveDist.append(1.0*samplei);
|
||||||
|
++nOutOfBounds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugInFunction
|
||||||
|
<< "Sample size : " << sampleCoords_.size() << nl
|
||||||
|
<< "Lost samples : " << nOutOfBounds << nl
|
||||||
|
<< "Recovered samples : "
|
||||||
|
<< (sampleCoords_.size() - nOutOfBounds - nFound) << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
|
||||||
|
if (nOutOfBounds)
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< "Identified " << nOutOfBounds << " out-of-bounds points"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::abaqusMeshSet::genSamples()
|
||||||
|
{
|
||||||
|
// Storage for sample points
|
||||||
|
DynamicList<point> samplingPts;
|
||||||
|
DynamicList<label> samplingCells;
|
||||||
|
DynamicList<label> samplingFaces;
|
||||||
|
DynamicList<label> samplingSegments;
|
||||||
|
DynamicList<scalar> samplingCurveDist;
|
||||||
|
|
||||||
|
calcSamples
|
||||||
|
(
|
||||||
|
samplingPts,
|
||||||
|
samplingCells,
|
||||||
|
samplingFaces,
|
||||||
|
samplingSegments,
|
||||||
|
samplingCurveDist
|
||||||
|
);
|
||||||
|
|
||||||
|
samplingPts.shrink();
|
||||||
|
samplingCells.shrink();
|
||||||
|
samplingFaces.shrink();
|
||||||
|
samplingSegments.shrink();
|
||||||
|
samplingCurveDist.shrink();
|
||||||
|
|
||||||
|
setSamples
|
||||||
|
(
|
||||||
|
std::move(samplingPts),
|
||||||
|
std::move(samplingCells),
|
||||||
|
std::move(samplingFaces),
|
||||||
|
std::move(samplingSegments),
|
||||||
|
std::move(samplingCurveDist)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (debug > 1)
|
||||||
|
{
|
||||||
|
write(Info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::abaqusMeshSet::abaqusMeshSet
|
||||||
|
(
|
||||||
|
const word& name,
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const meshSearch& searchEngine,
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
sampledSet(name, mesh, searchEngine, dict),
|
||||||
|
scale_(dict.getOrDefault<scalar>("scale", 1)),
|
||||||
|
sampleCoords_(),
|
||||||
|
maxDistSqr_(sqr(dict.getOrDefault<scalar>("maxDist", 0)))
|
||||||
|
{
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
const fileName inputFile(dict.get<fileName>("file").expand());
|
||||||
|
IFstream pointsFile(inputFile);
|
||||||
|
|
||||||
|
if (!pointsFile.good())
|
||||||
|
{
|
||||||
|
FatalIOErrorInFunction(dict)
|
||||||
|
<< "Unable to find file " << pointsFile.name()
|
||||||
|
<< abort(FatalIOError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the points file
|
||||||
|
DynamicList<point> coords;
|
||||||
|
vector c;
|
||||||
|
while (readCoord(pointsFile, c))
|
||||||
|
{
|
||||||
|
coords.append(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
sampleCoords_.transfer(coords);
|
||||||
|
}
|
||||||
|
|
||||||
|
Pstream::broadcast(sampleCoords_);
|
||||||
|
|
||||||
|
DebugInfo
|
||||||
|
<< "Number of sample points: " << sampleCoords_.size() << nl
|
||||||
|
<< "Sample points bounds: " << boundBox(sampleCoords_) << endl;
|
||||||
|
|
||||||
|
genSamples();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
150
src/sampling/sampledSet/abaqus/abaqusMeshSet.H
Normal file
150
src/sampling/sampledSet/abaqus/abaqusMeshSet.H
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2023 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/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::abaqusMeshSet
|
||||||
|
|
||||||
|
Description
|
||||||
|
Generates sample positions from points specified in a file as Abaqus mesh
|
||||||
|
points.
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
|
||||||
|
\verbatim
|
||||||
|
sets
|
||||||
|
{
|
||||||
|
cone25 // user-specified set name
|
||||||
|
{
|
||||||
|
type abaqusMesh;
|
||||||
|
file "abaqusMesh.inp";
|
||||||
|
|
||||||
|
// Optional entries
|
||||||
|
|
||||||
|
// Scale, e.g. mm to m
|
||||||
|
scale 0.001;
|
||||||
|
|
||||||
|
// Search distance when the sample point is not located in a cell
|
||||||
|
maxDist 0.25;
|
||||||
|
|
||||||
|
...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
For a dictionary specification:
|
||||||
|
\table
|
||||||
|
Property | Description | Required | Default
|
||||||
|
type | abaqusMesh | yes |
|
||||||
|
file | Path to Abaqus file | yes |
|
||||||
|
scale | scale input point positions | no | 1
|
||||||
|
maxDist | Search distance for sample points | no | 1
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
abaqusMeshSet.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef Foam_abaqusMeshSet_H
|
||||||
|
#define Foam_abaqusMeshSet_H
|
||||||
|
|
||||||
|
#include "sampledSet.H"
|
||||||
|
#include "vectorList.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class abaqusMeshSet Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class abaqusMeshSet
|
||||||
|
:
|
||||||
|
public sampledSet
|
||||||
|
{
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
//- Scale
|
||||||
|
const scalar scale_;
|
||||||
|
|
||||||
|
//- Sample coordinates
|
||||||
|
vectorList sampleCoords_;
|
||||||
|
|
||||||
|
//- Maximum search distance-squared
|
||||||
|
const scalar maxDistSqr_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
bool readCoord(ISstream& is, vector& coord) const;
|
||||||
|
|
||||||
|
//- Samples all points in sampleCoords.
|
||||||
|
void calcSamples
|
||||||
|
(
|
||||||
|
DynamicList<point>& samplingPts,
|
||||||
|
DynamicList<label>& samplingCells,
|
||||||
|
DynamicList<label>& samplingFaces,
|
||||||
|
DynamicList<label>& samplingSegments,
|
||||||
|
DynamicList<scalar>& samplingCurveDist
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Uses calcSamples to obtain samples. Copies them into *this.
|
||||||
|
void genSamples();
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("abaqusMesh");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from dictionary
|
||||||
|
abaqusMeshSet
|
||||||
|
(
|
||||||
|
const word& name,
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const meshSearch& searchEngine,
|
||||||
|
const dictionary& dict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~abaqusMeshSet() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
Reference in New Issue
Block a user