diff --git a/src/meshTools/coordSet/writers/nastran/nastranCoordSetWriter.C b/src/meshTools/coordSet/writers/nastran/nastranCoordSetWriter.C index 14dbfc8cb1..a25cba89b2 100644 --- a/src/meshTools/coordSet/writers/nastran/nastranCoordSetWriter.C +++ b/src/meshTools/coordSet/writers/nastran/nastranCoordSetWriter.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018-2022 OpenCFD Ltd. + Copyright (C) 2018-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -250,12 +250,12 @@ Foam::fileName Foam::coordSetWriters::nastranWriter::writeTemplate Info<< "Writing nastran geometry to " << outputFile << endl; } - if (!isDir(outputFile.path())) + if (!Foam::isDir(outputFile.path())) { - mkDir(outputFile.path()); + Foam::mkDir(outputFile.path()); } - OFstream os(outputFile); + OFstream os(IOstreamOption::ATOMIC, outputFile); fileFormats::NASCore::setPrecision(os, writeFormat_); os << "TITLE=OpenFOAM " << outputFile.stem() @@ -293,12 +293,12 @@ Foam::fileName Foam::coordSetWriters::nastranWriter::writeTemplate Info<< "Writing nastran geometry to " << outputFile << endl; } - if (!isDir(outputFile.path())) + if (!Foam::isDir(outputFile.path())) { - mkDir(outputFile.path()); + Foam::mkDir(outputFile.path()); } - OFstream os(outputFile); + OFstream os(IOstreamOption::ATOMIC, outputFile); fileFormats::NASCore::setPrecision(os, writeFormat_); os << "TITLE=OpenFOAM " << outputFile.stem() diff --git a/src/surfMesh/writers/nastran/nastranSurfaceWriter.C b/src/surfMesh/writers/nastran/nastranSurfaceWriter.C index e2e0534264..dc4d7a3363 100644 --- a/src/surfMesh/writers/nastran/nastranSurfaceWriter.C +++ b/src/surfMesh/writers/nastran/nastranSurfaceWriter.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2012-2016 OpenFOAM Foundation - Copyright (C) 2015-2022 OpenCFD Ltd. + Copyright (C) 2015-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -307,16 +307,10 @@ void Foam::surfaceWriters::nastranWriter::writeGeometry Foam::surfaceWriters::nastranWriter::nastranWriter() : surfaceWriter(), - writeFormat_(fieldFormat::SHORT), - fieldMap_(), + writeFormat_(fieldFormat::FREE), commonGeometry_(false), - separator_() -{ - // if (writeFormat_ == fieldFormat::FREE) - // { - // separator_ = ","; - // } -} + separator_(",") // FREE format +{} Foam::surfaceWriters::nastranWriter::nastranWriter @@ -331,29 +325,40 @@ Foam::surfaceWriters::nastranWriter::nastranWriter ( "format", options, - fieldFormat::LONG + fieldFormat::FREE ) ), - fieldMap_(), - commonGeometry_(options.getOrDefault("commonGeometry", false)), - separator_() + commonGeometry_(options.getOrDefault("commonGeometry", false)) { if (writeFormat_ == fieldFormat::FREE) { separator_ = ","; } + // Explicit PLOAD2, PLOAD4 field specification + options.readIfPresent("PLOAD2", pload2_); + options.readIfPresent("PLOAD4", pload4_); + + // Compatibility: + // Optional pairs of (field name => load format) + // Could make conditional on (pload2_.empty() && pload4_.empty()) + List> fieldPairs; - options.readEntry("fields", fieldPairs); + options.readIfPresent("fields", fieldPairs); for (const Pair& item : fieldPairs) { - // (field name => load format) - fieldMap_.insert - ( - item.first(), - fileFormats::NASCore::loadFormatNames[item.second()] - ); + const loadFormat format = + fileFormats::NASCore::loadFormatNames[item.second()]; + + if (format == loadFormat::PLOAD2) + { + pload2_.push_back(item.first()); + } + else if (format == loadFormat::PLOAD4) + { + pload4_.push_back(item.first()); + } } } @@ -414,12 +419,12 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::write() if (UPstream::master() || !parallel_) { - if (!isDir(outputFile.path())) + if (!Foam::isDir(outputFile.path())) { - mkDir(outputFile.path()); + Foam::mkDir(outputFile.path()); } - OFstream os(outputFile); + OFstream os(IOstreamOption::ATOMIC, outputFile); fileFormats::NASCore::setPrecision(os, writeFormat_); os << "TITLE=OpenFOAM " << outputPath_.name() << " geometry" << nl diff --git a/src/surfMesh/writers/nastran/nastranSurfaceWriter.H b/src/surfMesh/writers/nastran/nastranSurfaceWriter.H index 1cc4a4d8d2..be653a5dac 100644 --- a/src/surfMesh/writers/nastran/nastranSurfaceWriter.H +++ b/src/surfMesh/writers/nastran/nastranSurfaceWriter.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2012-2016 OpenFOAM Foundation - Copyright (C) 2015-2022 OpenCFD Ltd. + Copyright (C) 2015-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -33,13 +33,15 @@ Description The formatOptions for nastran: \table Property | Description | Reqd | Default - fields | Field pairs for PLOAD2/PLOAD4 | yes | - format | Nastran format (short/long/free) | no | long + format | Nastran format (short/long/free) | no | free scale | Output geometry scaling | no | 1 transform | Output coordinate transform | no | fieldLevel | Subtract field level before scaling | no | empty dict fieldScale | Output field scaling | no | empty dict commonGeometry | use separate geometry files | no | false + PLOAD2 | Field selection (words/regex) for PLOAD2 | no | + PLOAD4 | Field selection (words/regex) for PLOAD4 | no | + fields | Compat: Field pairs for PLOAD2/PLOAD4 | no | \endtable For example, @@ -48,13 +50,6 @@ Description { nastran { - // OpenFOAM field name to NASTRAN load types - fields - ( - (pMean PLOAD2) - (p PLOAD4) - ); - format free; // format type scale 1000; // [m] -> [mm] @@ -62,10 +57,27 @@ Description { "p.*" 0.01; // [Pa] -> [mbar] } + + // Specific NASTRAN load types + PLOAD2 ( pMean ); + PLOAD4 ( "p.*" ); + + // old style specification + fields + ( + (pMean PLOAD2) + (p PLOAD4) + ); } } \endverbatim + Unless otherwise specified, all fields will be treated as PLOAD2 + output. Can optionally specify PLOAD4 output using a combination + of \c PLOAD4 (accept) and \c PLOAD2 (deny) entries. The older \c fields + specification is also accepted and will be transcribed to + corresponding PLOAD4, PLOAD2 entries. + \section Output file locations The \c rootdir normally corresponds to something like @@ -93,7 +105,6 @@ Description Note Output variable scaling does not apply to integer types such as Ids. - Field pairs default to PLOAD2 for scalars and PLOAD4 for vectors etc. SourceFiles nastranSurfaceWriter.C @@ -106,7 +117,7 @@ SourceFiles #include "surfaceWriter.H" #include "NASCore.H" -#include "HashTable.H" +#include "wordRes.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -139,15 +150,18 @@ private: //- Field format (width and separator) fieldFormat writeFormat_; - //- Mapping from field name to data format enumeration - HashTable fieldMap_; - //- Use common geometry file bool commonGeometry_; //- Separator (used for free format) word separator_; + //- Explicit selection for PLOAD2 output (deselects for PLOAD4) + wordRes pload2_; + + //- Explicit selection for PLOAD4 output + wordRes pload4_; + // Private Member Functions @@ -221,10 +235,10 @@ public: // Constructors - //- Default construct. Default SHORT format + //- Default construct. Default FREE format nastranWriter(); - //- Construct with some output options. Default LONG format + //- Construct with some output options. Default FREE format explicit nastranWriter(const dictionary& options); //- Construct from components diff --git a/src/surfMesh/writers/nastran/nastranSurfaceWriterImpl.C b/src/surfMesh/writers/nastran/nastranSurfaceWriterImpl.C index 543b7c97fe..f534d915c7 100644 --- a/src/surfMesh/writers/nastran/nastranSurfaceWriterImpl.C +++ b/src/surfMesh/writers/nastran/nastranSurfaceWriterImpl.C @@ -103,13 +103,13 @@ Foam::Ostream& Foam::surfaceWriters::nastranWriter::writeFaceValue { case loadFormat::PLOAD2 : { - if (pTraits::nComponents == 1) + if (pTraits::nComponents > 1) { - writeValue(os, value); + writeValue(os, Foam::mag(value)); } else { - writeValue(os, mag(value)); + writeValue(os, value); } os << separator_; @@ -121,6 +121,9 @@ Foam::Ostream& Foam::surfaceWriters::nastranWriter::writeFaceValue { writeValue(os, elemId); + // NOTE: these should actually be vertex values, + // but misused here to provide vector quantities! + for (direction d = 0; d < pTraits::nComponents; ++d) { os << separator_; @@ -156,43 +159,23 @@ Foam::fileName Foam::surfaceWriters::nastranWriter::writeTemplate checkOpen(); - const loadFormat format - ( - fieldMap_.lookup - ( - fieldName, - // Default format - ( - pTraits::nComponents == 1 - ? loadFormat::PLOAD2 - : loadFormat::PLOAD4 - ) - ) - ); + // Default is PLOAD2 + loadFormat format = loadFormat::PLOAD2; if ( !std::is_integral::value // Handle 'Ids' etc silently - && !fieldMap_.empty() - && !fieldMap_.found(fieldName) + && !pload4_.empty() ) { - WarningInFunction - << "No mapping found between field " << fieldName - << " and corresponding Nastran field. Available types:" - << fieldMap_ << nl; - } + const wordRes::filter matcher(pload4_, pload2_); - // Emit any common warnings - if (format == loadFormat::PLOAD2 && pTraits::nComponents != 1) - { - WarningInFunction - << fileFormats::NASCore::loadFormatNames[format] - << " cannot be used for higher rank values" - << " - reverting to mag()" << endl; + if (matcher(fieldName)) + { + format = loadFormat::PLOAD4; + } } - // Common geometry // Field: rootdir/