From cee6524c34c3f22932bc92bf8e5fe84025956418 Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@esi-group.com> Date: Tue, 5 Jul 2022 14:14:21 +0200 Subject: [PATCH] ENH: delay writing of ensight case until after geometry/fields (#2512) - in situations where the simulation diverges, the ensight writing can be incomplete. If the case file is updated prior to writing geometry or fields, the generated case may refer to incomplete entries (which make loading problematic). NOTE: if multiple fields are sampled and written, this change cannot entirely prevent case files addressing corrupt fields. For example, 1a. write U field, update case file with new times/fields 1b. write p field, update case file with new times/fields 2a. write U field, update case file with new times 2b. write p field, but fails Since 2a already updates the case file with a new time-step entry (for the U field), the case glob patterns will automatically include the not-yet-written 'p' field. If this write fails with an incomplete/corrupt field, the case file will still be addressing it! --- .../ensight/ensightCoordSetWriterCollated.C | 95 ++++++++-------- .../ensight/ensightCoordSetWriterUncollated.C | 69 ++++++------ .../ensight/ensightSurfaceWriterCollated.C | 106 +++++++++--------- .../ensight/ensightSurfaceWriterUncollated.C | 88 ++++++++------- 4 files changed, 182 insertions(+), 176 deletions(-) diff --git a/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterCollated.C b/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterCollated.C index 3a0cafb27f7..759544e15a6 100644 --- a/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterCollated.C +++ b/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterCollated.C @@ -122,7 +122,53 @@ Foam::fileName Foam::coordSetWriters::ensightWriter::writeCollated ); - // Do case file + // Location for data (and possibly the geometry as well) + fileName dataDir = baseDir/"data"/word::printf(fmt, timeIndex); + + // As per mkdir -p "data/00000000" + mkDir(dataDir); + + + const fileName geomFile(baseDir/geometryName); + + if (!exists(geomFile)) + { + if (verbose_) + { + Info<< "Writing geometry to " << geomFile.name() << endl; + } + + // Two-argument form for path-name to avoid validating base-dir + ensightGeoFile osGeom + ( + geomFile.path(), + geomFile.name(), + writeFormat_ + ); + + writeGeometry(osGeom, elemOutput); + } + + + // Write field + ensightFile osField + ( + dataDir, + varName, + writeFormat_ + ); + + if (verbose_) + { + Info<< "Writing field file to " << osField.name() << endl; + } + + + // Write field (serial only) + writeTrackField<Type>(osField, fieldPtrs); + + + // Update case file if (stateChanged) { OFstream osCase(outputFile, IOstream::ASCII); @@ -216,53 +262,6 @@ Foam::fileName Foam::coordSetWriters::ensightWriter::writeCollated osCase << "# end" << nl; } - - // Location for data (and possibly the geometry as well) - fileName dataDir = baseDir/"data"/word::printf(fmt, timeIndex); - - // As per mkdir -p "data/00000000" - mkDir(dataDir); - - - const fileName geomFile(baseDir/geometryName); - - if (!exists(geomFile)) - { - if (verbose_) - { - Info<< "Writing geometry to " << geomFile.name() << endl; - } - - // Two-argument form for path-name to avoid validating base-dir - ensightGeoFile osGeom - ( - geomFile.path(), - geomFile.name(), - writeFormat_ - ); - - writeGeometry(osGeom, elemOutput); - } - - - // Write field - ensightFile osField - ( - dataDir, - varName, - writeFormat_ - ); - - if (verbose_) - { - Info<< "Writing field file to " << osField.name() << endl; - } - - - // Write field (serial only) - writeTrackField<Type>(osField, fieldPtrs); - - // Timestamp in the directory for future reference { OFstream timeStamp(dataDir/"time"); diff --git a/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterUncollated.C b/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterUncollated.C index f0f89997ede..4849dc1ff9f 100644 --- a/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterUncollated.C +++ b/src/meshTools/coordSet/writers/ensight/ensightCoordSetWriterUncollated.C @@ -97,13 +97,6 @@ Foam::fileName Foam::coordSetWriters::ensightWriter::writeUncollated mkDir(outputFile.path()); } - OFstream osCase(outputFile, IOstream::ASCII); - - // Format options - osCase.setf(ios_base::left); - osCase.setf(ios_base::scientific, ios_base::floatfield); - osCase.precision(5); - // Two-argument form for path-name to avoid validating base-dir ensightGeoFile osGeom ( @@ -118,36 +111,46 @@ Foam::fileName Foam::coordSetWriters::ensightWriter::writeUncollated writeFormat_ ); - osCase - << "FORMAT" << nl - << "type: ensight gold" << nl - << nl - << "GEOMETRY" << nl - << "model: 1 " << osGeom.name().name() << nl - << nl - << "VARIABLE" << nl - << ensightPTraits<Type>::typeName - << - ( - true // this->isPointData() - ? " per node: 1 " // time-set 1 - : " per element: 1 " // time-set 1 - ) - << setw(15) << varName << ' ' - << baseName.c_str() << ".********." << varName << nl; - - osCase - << nl - << "TIME" << nl; - - ensightCase::printTimeset(osCase, 1, timeValue); - osCase << "# end" << nl; - - writeGeometry(osGeom, elemOutput); // Write field (serial only) writeTrackField<Type>(osField, fieldPtrs); + + + // Update case file + { + OFstream osCase(outputFile, IOstream::ASCII); + + // Format options + osCase.setf(ios_base::left); + osCase.setf(ios_base::scientific, ios_base::floatfield); + osCase.precision(5); + + osCase + << "FORMAT" << nl + << "type: ensight gold" << nl + << nl + << "GEOMETRY" << nl + << "model: 1 " << osGeom.name().name() << nl + << nl + << "VARIABLE" << nl + << ensightPTraits<Type>::typeName + << + ( + true // this->isPointData() + ? " per node: 1 " // time-set 1 + : " per element: 1 " // time-set 1 + ) + << setw(15) << varName << ' ' + << baseName.c_str() << ".********." << varName << nl; + + osCase + << nl + << "TIME" << nl; + + ensightCase::printTimeset(osCase, 1, timeValue); + osCase << "# end" << nl; + } } wroteGeom_ = true; diff --git a/src/surfMesh/writers/ensight/ensightSurfaceWriterCollated.C b/src/surfMesh/writers/ensight/ensightSurfaceWriterCollated.C index 511df9159a8..18da1870965 100644 --- a/src/surfMesh/writers/ensight/ensightSurfaceWriterCollated.C +++ b/src/surfMesh/writers/ensight/ensightSurfaceWriterCollated.C @@ -129,7 +129,59 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeCollated ); - // Do case file + // Location for data (and possibly the geometry as well) + fileName dataDir = baseDir/"data"/word::printf(fmt, timeIndex); + + // As per mkdir -p "data/00000000" + mkDir(dataDir); + + + const fileName geomFile(baseDir/geometryName); + + // Ensight Geometry + ensightOutputSurface part + ( + surf.points(), + surf.faces(), + geomFile.name() + ); + + if (!exists(geomFile)) + { + if (verbose_) + { + Info<< "Writing geometry to " << geomFile.name() << endl; + } + + // Two-argument form for path-name to avoid validating base-dir + ensightGeoFile osGeom + ( + geomFile.path(), + geomFile.name(), + writeFormat_ + ); + part.write(osGeom); // serial + } + + // Write field + ensightFile osField + ( + dataDir, + varName, + writeFormat_ + ); + + if (verbose_) + { + Info<< "Writing field file to " << osField.name() << endl; + } + + // Write field (serial only) + osField.writeKeyword(ensightPTraits<Type>::typeName); + part.writeData(osField, tfield(), this->isPointData()); + + + // Update case file if (stateChanged) { OFstream osCase(outputFile, IOstream::ASCII); @@ -223,58 +275,6 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeCollated osCase << "# end" << nl; } - - // Location for data (and possibly the geometry as well) - fileName dataDir = baseDir/"data"/word::printf(fmt, timeIndex); - - // As per mkdir -p "data/00000000" - mkDir(dataDir); - - - const fileName geomFile(baseDir/geometryName); - - // Ensight Geometry - ensightOutputSurface part - ( - surf.points(), - surf.faces(), - geomFile.name() - ); - - if (!exists(geomFile)) - { - if (verbose_) - { - Info<< "Writing geometry to " << geomFile.name() << endl; - } - - // Two-argument form for path-name to avoid validating base-dir - ensightGeoFile osGeom - ( - geomFile.path(), - geomFile.name(), - writeFormat_ - ); - part.write(osGeom); // serial - } - - // Write field - ensightFile osField - ( - dataDir, - varName, - writeFormat_ - ); - - if (verbose_) - { - Info<< "Writing field file to " << osField.name() << endl; - } - - // Write field (serial only) - osField.writeKeyword(ensightPTraits<Type>::typeName); - part.writeData(osField, tfield(), this->isPointData()); - // Timestamp in the directory for future reference { OFstream timeStamp(dataDir/"time"); diff --git a/src/surfMesh/writers/ensight/ensightSurfaceWriterUncollated.C b/src/surfMesh/writers/ensight/ensightSurfaceWriterUncollated.C index fde360edc0c..9d73cc06f79 100644 --- a/src/surfMesh/writers/ensight/ensightSurfaceWriterUncollated.C +++ b/src/surfMesh/writers/ensight/ensightSurfaceWriterUncollated.C @@ -69,7 +69,6 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated() mkDir(outputDir); } - OFstream osCase(outputFile); ensightGeoFile osGeom ( outputDir, @@ -77,6 +76,16 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated() writeFormat_ ); + ensightOutputSurface part + ( + surf.points(), + surf.faces(), + osGeom.name().name() + ); + part.write(osGeom); // serial + + // Update case file + OFstream osCase(outputFile); osCase << "FORMAT" << nl << "type: ensight gold" << nl @@ -87,14 +96,6 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated() << "TIME" << nl; ensightCase::printTimeset(osCase, 1, scalar(0)); - - ensightOutputSurface part - ( - surf.points(), - surf.faces(), - osGeom.name().name() - ); - part.write(osGeom); // serial } wroteGeom_ = true; @@ -170,13 +171,6 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated mkDir(outputFile.path()); } - OFstream osCase(outputFile, IOstream::ASCII); - - // Format options - osCase.setf(ios_base::left); - osCase.setf(ios_base::scientific, ios_base::floatfield); - osCase.precision(5); - // Two-argument form for path-name to avoid validating base-dir ensightGeoFile osGeom ( @@ -191,32 +185,6 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated writeFormat_ ); - osCase - << "FORMAT" << nl - << "type: ensight gold" << nl - << nl - << "GEOMETRY" << nl - << "model: 1 " << osGeom.name().name() << nl - << nl - << "VARIABLE" << nl - << ensightPTraits<Type>::typeName - << - ( - this->isPointData() - ? " per node: 1 " // time-set 1 - : " per element: 1 " // time-set 1 - ) - << setw(15) << varName << ' ' - << baseName.c_str() << ".********." << varName << nl; - - osCase - << nl - << "TIME" << nl; - - ensightCase::printTimeset(osCase, 1, timeValue); - osCase << "# end" << nl; - - // Ensight Geometry ensightOutputSurface part ( @@ -229,6 +197,42 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated // Write field (serial) osField.writeKeyword(ensightPTraits<Type>::typeName); part.writeData(osField, tfield(), this->isPointData()); + + + // Update case file + { + OFstream osCase(outputFile, IOstream::ASCII); + + // Format options + osCase.setf(ios_base::left); + osCase.setf(ios_base::scientific, ios_base::floatfield); + osCase.precision(5); + + osCase + << "FORMAT" << nl + << "type: ensight gold" << nl + << nl + << "GEOMETRY" << nl + << "model: 1 " << osGeom.name().name() << nl + << nl + << "VARIABLE" << nl + << ensightPTraits<Type>::typeName + << + ( + this->isPointData() + ? " per node: 1 " // time-set 1 + : " per element: 1 " // time-set 1 + ) + << setw(15) << varName << ' ' + << baseName.c_str() << ".********." << varName << nl; + + osCase + << nl + << "TIME" << nl; + + ensightCase::printTimeset(osCase, 1, timeValue); + osCase << "# end" << nl; + } } wroteGeom_ = true; -- GitLab