Skip to content
Snippets Groups Projects
Commit d3b3a5a4 authored by Andrew Heather's avatar Andrew Heather Committed by Mark OLESEN
Browse files

ENH: Added new abaqus coordSet writer

Write coordSet(s) as Abaqus point fields

Example usage

    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
            );

            ...
        }
    }
parent 3944c7a6
No related branches found
No related tags found
1 merge request!644Added Abaqus sampling and writing
......@@ -116,6 +116,7 @@ coordSet/coordSet.C
setWriters = coordSet/writers
$(setWriters)/abaqus/abaqusCoordSetWriter.C
$(setWriters)/common/coordSetWriter.C
$(setWriters)/common/coordSetWriterBuffers.C
$(setWriters)/common/coordSetWriterNew.C
......
/*---------------------------------------------------------------------------*\
========= |
\\ / 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);
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / 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
// ************************************************************************* //
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment