diff --git a/src/fileFormats/nastran/NASCore.C b/src/fileFormats/nastran/NASCore.C index 26c056e391..21842a7723 100644 --- a/src/fileFormats/nastran/NASCore.C +++ b/src/fileFormats/nastran/NASCore.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2017-2022 OpenCFD Ltd. + Copyright (C) 2017-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -122,7 +122,8 @@ std::string Foam::fileFormats::NASCore::nextNasField ( const std::string& str, std::string::size_type& pos, - std::string::size_type len + const std::string::size_type width, + const bool free_format ) { const auto beg = pos; @@ -130,15 +131,23 @@ std::string Foam::fileFormats::NASCore::nextNasField if (end == std::string::npos) { - pos = beg + len; // Continue after field width + if (free_format) + { + // Nothing left + pos = str.size(); + return str.substr(beg); + } + + // Fixed format - continue after field width + pos = beg + width; + return str.substr(beg, width); } else { - len = (end - beg); // Efffective width - pos = end + 1; // Continue after comma + // Free format - continue after comma + pos = end + 1; + return str.substr(beg, (end - beg)); } - - return str.substr(beg, len); } @@ -235,8 +244,8 @@ void Foam::fileFormats::NASCore::writeCoord // 2 ID : point ID - requires starting index of 1 // 3 CP : coordinate system ID (blank) // 4 X1 : point x coordinate - // 5 X2 : point x coordinate - // 6 X3 : point x coordinate + // 5 X2 : point y coordinate + // 6 X3 : point z coordinate // 7 CD : coordinate system for displacements (blank) // 8 PS : single point constraints (blank) // 9 SEID : super-element ID diff --git a/src/fileFormats/nastran/NASCore.H b/src/fileFormats/nastran/NASCore.H index 0fd8e9b160..05a351cbc8 100644 --- a/src/fileFormats/nastran/NASCore.H +++ b/src/fileFormats/nastran/NASCore.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2017-2022 OpenCFD Ltd. + Copyright (C) 2017-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -48,7 +48,6 @@ SourceFiles namespace Foam { - namespace fileFormats { @@ -74,18 +73,18 @@ public: //- Output load format enum loadFormat { - PLOAD2, - PLOAD4 + PLOAD2, //!< Face load (eg, pressure) + PLOAD4 //!< Vertex load }; - //- Selection names for the NASTRAN file field formats + //- Selection names for the NASTRAN load formats static const Enum loadFormatNames; // Constructors //- Default construct - NASCore() = default; + NASCore() noexcept = default; // Public Static Member Functions @@ -93,18 +92,20 @@ public: //- Extract numbers from things like "-2.358-8" (same as "-2.358e-8") static scalar readNasScalar(const std::string& str); - //- A string::substr() to handle fixed-format and free-format NASTRAN. - // Returns the substr to the next comma (if found) or the given length - // - // \param str The string to extract from - // \param pos On input, the position of the first character of the - // substring. On output, advances to the next position to use. - // \param len The fixed-format length to use if a comma is not found. + //- A std::string::substr() variant to handle fixed-format and + //- free-format NASTRAN. + // Returns the substr until the next comma (if found) + // or the given fixed width static std::string nextNasField ( + //! The string to extract from const std::string& str, + //! [in,out] The parse position within \p str std::string::size_type& pos, - std::string::size_type len + //! The fixed-format width to use (if comma is not found) + const std::string::size_type width, + //! The input is known to be free-format + const bool free_format = false ); diff --git a/src/meshTools/edgeMesh/edgeFormats/nastran/NASedgeFormat.C b/src/meshTools/edgeMesh/edgeFormats/nastran/NASedgeFormat.C index 9940ccf093..44b6290cf0 100644 --- a/src/meshTools/edgeMesh/edgeFormats/nastran/NASedgeFormat.C +++ b/src/meshTools/edgeMesh/edgeFormats/nastran/NASedgeFormat.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2017 OpenFOAM Foundation - Copyright (C) 2017 OpenCFD Ltd. + Copyright (C) 2017-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -62,13 +62,17 @@ bool Foam::fileFormats::NASedgeFormat::read while (is.good()) { - string::size_type linei = 0; // parsing position within current line string line; is.getLine(line); - if (line.empty() || line[0] == '$') + if (line.empty()) { - continue; // Skip empty or comment + continue; // Ignore empty + } + else if (line[0] == '$') + { + // Ignore comment + continue; } // Check if character 72 is continuation @@ -94,38 +98,66 @@ bool Foam::fileFormats::NASedgeFormat::read } + // Parsing position within current line + std::string::size_type linei = 0; + + // Is free format if line contains a comma + const bool freeFormat = line.contains(','); + // First word (column 0-8) const word cmd(word::validate(nextNasField(line, linei, 8))); if (cmd == "CBEAM" || cmd == "CROD") { - // discard elementId (8-16) - (void) nextNasField(line, linei, 8); // 8-16 - // discard groupId (16-24) - (void) nextNasField(line, linei, 8); // 16-24 + // Fixed format: + // 8-16 : element id + // 16-24 : group id + // 24-32 : vertex + // 32-40 : vertex - label a = readLabel(nextNasField(line, linei, 8)); // 24-32 - label b = readLabel(nextNasField(line, linei, 8)); // 32-40 + // discard elementId + (void) nextNasField(line, linei, 8, freeFormat); + // discard groupId + (void) nextNasField(line, linei, 8, freeFormat); + + label a = readLabel(nextNasField(line, linei, 8, freeFormat)); + label b = readLabel(nextNasField(line, linei, 8, freeFormat)); dynEdges.append(edge(a,b)); } else if (cmd == "PLOTEL") { - // discard elementId (8-16) - (void) nextNasField(line, linei, 8); // 8-16 + // Fixed format: + // 8-16 : element id + // 16-24 : vertex + // 24-32 : vertex + // 32-40 : vertex - label a = readLabel(nextNasField(line, linei, 8)); // 16-24 - label b = readLabel(nextNasField(line, linei, 8)); // 24-32 + // discard elementId (8-16) + (void) nextNasField(line, linei, 8, freeFormat); + + label a = readLabel(nextNasField(line, linei, 8, freeFormat)); + label b = readLabel(nextNasField(line, linei, 8, freeFormat)); dynEdges.append(edge(a,b)); } else if (cmd == "GRID") { - label index = readLabel(nextNasField(line, linei, 8)); // 8-16 - (void) nextNasField(line, linei, 8); // 16-24 - scalar x = readNasScalar(nextNasField(line, linei, 8)); // 24-32 - scalar y = readNasScalar(nextNasField(line, linei, 8)); // 32-40 - scalar z = readNasScalar(nextNasField(line, linei, 8)); // 40-48 + // Fixed (short) format: + // 8-16 : point id + // 16-24 : coordinate system (unsupported) + // 24-32 : point x coordinate + // 32-40 : point y coordinate + // 40-48 : point z coordinate + // 48-56 : displacement coordinate system (optional, unsupported) + // 56-64 : single point constraints (optional, unsupported) + // 64-70 : super-element id (optional, unsupported) + + label index = readLabel(nextNasField(line, linei, 8, freeFormat)); + (void) nextNasField(line, linei, 8, freeFormat); + scalar x = readNasScalar(nextNasField(line, linei, 8, freeFormat)); + scalar y = readNasScalar(nextNasField(line, linei, 8, freeFormat)); + scalar z = readNasScalar(nextNasField(line, linei, 8, freeFormat)); pointId.append(index); dynPoints.append(point(x, y, z)); @@ -138,6 +170,8 @@ bool Foam::fileFormats::NASedgeFormat::read // GRID* 126 0 -5.55999875E+02 -5.68730474E+02 // * 2.14897901E+02 + // Cannot be long format and free format at the same time! + label index = readLabel(nextNasField(line, linei, 16)); // 8-24 (void) nextNasField(line, linei, 16); // 24-40 scalar x = readNasScalar(nextNasField(line, linei, 16)); // 40-56 diff --git a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C index 225cc3752a..00a84b84ba 100644 --- a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C +++ b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2015 OpenFOAM Foundation - Copyright (C) 2017-2022 OpenCFD Ltd. + Copyright (C) 2017-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -149,7 +149,6 @@ bool Foam::fileFormats::NASsurfaceFormat::read string line; while (is.good()) { - string::size_type linei = 0; // Parsing position within current line is.getLine(line); // ANSA extension @@ -223,16 +222,30 @@ bool Foam::fileFormats::NASsurfaceFormat::read } } + + // Parsing position within current line + std::string::size_type linei = 0; + + // Is free format if line contains a comma + const bool freeFormat = line.contains(','); + // First word (column 0-8) const word cmd(word::validate(nextNasField(line, linei, 8))); if (cmd == "CTRIA3") { - label elemId = readLabel(nextNasField(line, linei, 8)); // 8-16 - label groupId = readLabel(nextNasField(line, linei, 8)); // 16-24 - const auto a = readLabel(nextNasField(line, linei, 8)); // 24-32 - const auto b = readLabel(nextNasField(line, linei, 8)); // 32-40 - const auto c = readLabel(nextNasField(line, linei, 8)); // 40-48 + // Fixed format: + // 8-16 : element id + // 16-24 : group id + // 24-32 : vertex + // 32-40 : vertex + // 40-48 : vertex + + label elemId = readLabel(nextNasField(line, linei, 8, freeFormat)); + label groupId = readLabel(nextNasField(line, linei, 8, freeFormat)); + const auto a = readLabel(nextNasField(line, linei, 8, freeFormat)); + const auto b = readLabel(nextNasField(line, linei, 8, freeFormat)); + const auto c = readLabel(nextNasField(line, linei, 8, freeFormat)); // Convert groupId into zoneId const auto iterZone = zoneLookup.cfind(groupId); @@ -261,12 +274,20 @@ bool Foam::fileFormats::NASsurfaceFormat::read } else if (cmd == "CQUAD4") { - label elemId = readLabel(nextNasField(line, linei, 8)); // 8-16 - label groupId = readLabel(nextNasField(line, linei, 8)); // 16-24 - const auto a = readLabel(nextNasField(line, linei, 8)); // 24-32 - const auto b = readLabel(nextNasField(line, linei, 8)); // 32-40 - const auto c = readLabel(nextNasField(line, linei, 8)); // 40-48 - const auto d = readLabel(nextNasField(line, linei, 8)); // 48-56 + // Fixed format: + // 8-16 : element id + // 16-24 : group id + // 24-32 : vertex + // 32-40 : vertex + // 40-48 : vertex + // 48-56 : vertex + + label elemId = readLabel(nextNasField(line, linei, 8, freeFormat)); + label groupId = readLabel(nextNasField(line, linei, 8, freeFormat)); + const auto a = readLabel(nextNasField(line, linei, 8, freeFormat)); + const auto b = readLabel(nextNasField(line, linei, 8, freeFormat)); + const auto c = readLabel(nextNasField(line, linei, 8, freeFormat)); + const auto d = readLabel(nextNasField(line, linei, 8, freeFormat)); // Convert groupId into zoneId const auto iterZone = zoneLookup.cfind(groupId); @@ -310,11 +331,21 @@ bool Foam::fileFormats::NASsurfaceFormat::read } else if (cmd == "GRID") { - label index = readLabel(nextNasField(line, linei, 8)); // 8-16 - (void) nextNasField(line, linei, 8); // 16-24 - scalar x = readNasScalar(nextNasField(line, linei, 8)); // 24-32 - scalar y = readNasScalar(nextNasField(line, linei, 8)); // 32-40 - scalar z = readNasScalar(nextNasField(line, linei, 8)); // 40-48 + // Fixed (short) format: + // 8-16 : point id + // 16-24 : coordinate system (not supported) + // 24-32 : point x coordinate + // 32-40 : point y coordinate + // 40-48 : point z coordinate + // 48-56 : displacement coordinate system (optional, unsupported) + // 56-64 : single point constraints (optional, unsupported) + // 64-70 : super-element id (optional, unsupported) + + label index = readLabel(nextNasField(line, linei, 8, freeFormat)); + (void) nextNasField(line, linei, 8, freeFormat); + scalar x = readNasScalar(nextNasField(line, linei, 8, freeFormat)); + scalar y = readNasScalar(nextNasField(line, linei, 8, freeFormat)); + scalar z = readNasScalar(nextNasField(line, linei, 8, freeFormat)); pointId.append(index); dynPoints.append(point(x, y, z)); @@ -327,6 +358,8 @@ bool Foam::fileFormats::NASsurfaceFormat::read // GRID* 126 0 -5.55999875E+02 -5.68730474E+02 // * 2.14897901E+02 + // Cannot be long format and free format at the same time! + label index = readLabel(nextNasField(line, linei, 16)); // 8-24 (void) nextNasField(line, linei, 16); // 24-40 scalar x = readNasScalar(nextNasField(line, linei, 16)); // 40-56 diff --git a/src/surfMesh/writers/nastran/nastranSurfaceWriter.C b/src/surfMesh/writers/nastran/nastranSurfaceWriter.C index b1b2c7be57..ad84fb938f 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,12 +325,10 @@ 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) { diff --git a/src/surfMesh/writers/nastran/nastranSurfaceWriter.H b/src/surfMesh/writers/nastran/nastranSurfaceWriter.H index 15d51da629..50c3599296 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,13 @@ 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 + fields | Field pairs for PLOAD2/PLOAD4 | yes | \endtable For example, @@ -48,13 +48,6 @@ Description { nastran { - // OpenFOAM field name to NASTRAN load types - fields - ( - (pMean PLOAD2) - (p PLOAD4) - ); - format free; // format type scale 1000; // [m] -> [mm] @@ -62,6 +55,13 @@ Description { "p.*" 0.01; // [Pa] -> [mbar] } + + // OpenFOAM field name to NASTRAN load types + fields + ( + (pMean PLOAD2) + (p PLOAD4) + ); } } \endverbatim @@ -93,7 +93,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 @@ -221,10 +220,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