-
Notifications
You must be signed in to change notification settings - Fork 1k
Fix integer overflows and parallelize the output writers for large meshes #2924
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
2d96e81
7ac93b9
704ef0d
0327e49
9bf36fb
cb8430d
918781d
bcec2eb
d63f3d4
1e397c1
b7090e9
834fd29
5509da6
61506cf
ea33583
c3d3f0e
955bca1
58803f5
4fe9b34
4f6729d
d26d407
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -32,13 +32,38 @@ | |
| #include <basetsd.h> | ||
| #endif | ||
| #include "cgnslib.h" | ||
| #ifdef HAVE_MPI | ||
| #include "pcgnslib.h" | ||
| #endif | ||
| #endif | ||
|
|
||
| #include <cstdint> | ||
| #include <limits> | ||
|
|
||
| #include "CFileWriter.hpp" | ||
|
|
||
| class CConfig; | ||
| class CGeometry; | ||
| class CFVMDataSorter; | ||
|
|
||
| class CCGNSFileWriter final : public CFileWriter { | ||
| private: | ||
| const bool isSurface; /*!< \brief True if surface file. */ | ||
| const bool isSurface; /*!< \brief True if surface file. */ | ||
| const bool doublePrecisionFields; /*!< \brief True to write the fields in double precision instead of single. */ | ||
|
|
||
| /*! | ||
| * \brief Boundary elements of one marker owned by this rank, written as a boundary section of a volume file. | ||
| */ | ||
| struct BoundaryMarker { | ||
| string name; /*!< \brief Marker tag. */ | ||
| unsigned short kindBC; /*!< \brief SU2 boundary condition kind. */ | ||
| vector<unsigned long> conn; /*!< \brief VTK type followed by the (1-based) output ids of the nodes, per element. */ | ||
| }; | ||
| vector<BoundaryMarker> boundaryMarkers; /*!< \brief Markers written as boundaries of a volume file. */ | ||
|
|
||
| vector<string> surfaceMarkers; /*!< \brief Markers written as one zone each in a surface file. */ | ||
| CConfig* config = nullptr; /*!< \brief Config, to sort the surface data of each marker. */ | ||
| CGeometry* geometry = nullptr; /*!< \brief Geometry, to sort the surface data of each marker. */ | ||
|
|
||
| #ifdef HAVE_CGNS | ||
| int cgnsFileID; /*!< \brief CGNS file identifier. */ | ||
|
|
@@ -54,15 +79,10 @@ class CCGNSFileWriter final : public CFileWriter { | |
| cgsize_t GlobalPoint; /*!< \brief Total number of points. */ | ||
| cgsize_t GlobalElem; /*!< \brief Total number of elements. */ | ||
|
|
||
| typedef float dataPrecision; /*!< \brief Define data precision of output (float or double). */ | ||
| const DataType_t dataType = RealSingle; /*!< \brief Datatype of fields can be RealSingle or RealDouble. */ | ||
|
|
||
| vector<cgsize_t> sendBufferConnectivity; /*!< \brief Send buffer for connectivity data. */ | ||
| vector<cgsize_t> recvBufferConnectivity; /*!< \brief Receive buffer for connectivity data. */ | ||
| vector<dataPrecision> recvBufferField; /*!< \brief Send buffer for field data. */ | ||
| vector<dataPrecision> sendBufferField; /*!< \brief Receive buffer for field data. */ | ||
|
|
||
| cgsize_t cumulative; /*!< \brief Cumulative number of elements written. */ | ||
|
|
||
| /*--- Max connectivity entries per section, so that readers using 32-bit sizes can read it. ---*/ | ||
| static constexpr cgsize_t maxSectionEntries = std::numeric_limits<int32_t>::max(); | ||
| #endif | ||
| public: | ||
| /*! | ||
|
|
@@ -75,28 +95,72 @@ class CCGNSFileWriter final : public CFileWriter { | |
| * \param[in] valDataSorter - The parallel sorted data to write. | ||
| * \param[in] isSurf - True if it is a surface file. | ||
| */ | ||
| CCGNSFileWriter(CParallelDataSorter* valDataSorter, bool isSurf = false); | ||
| CCGNSFileWriter(CParallelDataSorter* valDataSorter, bool isSurf = false, bool doublePrecision = false); | ||
|
|
||
| /*! | ||
| * \brief Write sorted data to file in CGNS file format. | ||
| * \param[in] val_filename - The name of the file. | ||
| */ | ||
| void WriteData(string val_filename) override ; | ||
|
|
||
| /*! | ||
| * \brief Add the boundaries to a volume file: one boundary section, BC and family per marker, named as the marker. | ||
| * \param[in] valConfig - Definition of the problem. | ||
| * \param[in] valGeometry - Geometrical definition of the problem. | ||
| * \param[in] volumeSorter - The volume data sorter, to find the boundary elements owned by this rank. | ||
| */ | ||
| void SetBoundaryMarkers(CConfig* valConfig, CGeometry* valGeometry, const CFVMDataSorter* volumeSorter); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| /*! | ||
| * \brief Write a surface file with one zone per plotted marker, named as the marker. The data of the surface | ||
| * sorter is sorted again for each marker when the file is written. | ||
| * \param[in] valConfig - Definition of the problem. | ||
| * \param[in] valGeometry - Geometrical definition of the problem. | ||
| */ | ||
| void SetSurfaceMarkers(CConfig* valConfig, CGeometry* valGeometry); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here |
||
|
|
||
| private: | ||
| #ifdef HAVE_CGNS | ||
| /*! | ||
| * \brief Initialize CGNS mesh file. | ||
| * \brief Create the CGNS file and its base. | ||
| * \param[in] val_filename - The name of the file. | ||
| */ | ||
| void InitializeMeshFile(const string& val_filename); | ||
|
|
||
| /*! | ||
| * \brief Write i-th coordinate to file in CGNS file format. | ||
| * \brief Write a zone with the data currently held by the data sorter. | ||
| * \param[in] zoneName - Name of the zone. | ||
| */ | ||
| void WriteZone(const string& zoneName); | ||
|
|
||
| /*! | ||
| * \brief Create a zone for the data currently held by the data sorter. | ||
| * \param[in] zoneName - Name of the zone. | ||
| */ | ||
| void InitializeZone(const string& zoneName); | ||
|
|
||
| /*! | ||
| * \brief Write the boundary sections, BCs and families of the markers set with SetBoundaryMarkers. | ||
| */ | ||
| void WriteBoundaries(); | ||
|
|
||
| /*! | ||
| * \brief Write i-th coordinate to file in CGNS file format. Coordinates are always written in double precision, | ||
| * the fields follow the precision requested by the user. | ||
| * \param[in] iField - the output field ID. | ||
| * \param[in] FieldName - Field name in the CGNS. | ||
| */ | ||
| void WriteField(int iField, const string& FieldName); | ||
|
|
||
| /*! | ||
| * \brief Write i-th coordinate or field to file with the given data type. | ||
| * \param[in] iField - the output field ID. | ||
| * \param[in] FieldName - Field name in the CGNS. | ||
| * \param[in] dataType - CGNS data type matching T, i.e. RealSingle for float and RealDouble for double. | ||
| */ | ||
| template <class T> | ||
| void WriteFieldOfType(int iField, const string& FieldName, DataType_t dataType); | ||
|
|
||
| /*! | ||
| * \brief Write connectivity to file for GEO_TYPE in CGNS file format. | ||
| * \param[in] type - GEO_TYPE. | ||
|
|
@@ -109,6 +173,27 @@ class CCGNSFileWriter final : public CFileWriter { | |
| */ | ||
| void InitializeFields(); | ||
|
|
||
| /*! | ||
| * \brief Create an element section, collectively when built with MPI. | ||
| * \param[in] name - Name of the section. | ||
| * \param[in] type - CGNS element type of the section. | ||
| * \param[in] start - First element of the section. | ||
| * \param[in] end - Last element of the section. | ||
| * \param[out] section - Index of the section. | ||
| * \returns CGNS error code. | ||
| */ | ||
| int SectionWrite(const string& name, ElementType_t type, cgsize_t start, cgsize_t end, int* section); | ||
|
|
||
| /*! | ||
| * \brief Write the connectivity of the elements [start, end] of a section, the elements of this rank. | ||
| * \param[in] section - Index of the section. | ||
| * \param[in] start - First element written by this rank. | ||
| * \param[in] end - Last element written by this rank. | ||
| * \param[in] elements - Connectivity, nullptr if this rank writes no element of the section. | ||
| * \returns CGNS error code. | ||
| */ | ||
| int ElementsWriteData(int section, cgsize_t start, cgsize_t end, const cgsize_t* elements); | ||
|
|
||
| /*! | ||
| * \brief Call a generic CGNS function. | ||
| * \param[in] ier - error value. | ||
|
|
@@ -117,6 +202,12 @@ class CCGNSFileWriter final : public CFileWriter { | |
| if (ier) cg_error_exit(); | ||
| } | ||
|
|
||
| /*! | ||
| * \brief Return the CGNS boundary condition type of an SU2 boundary condition kind. | ||
| * \param[in] kindBC - SU2 boundary condition kind. | ||
| */ | ||
| static BCType_t GetCGNSBCType(unsigned short kindBC); | ||
|
|
||
| /*! | ||
| * \brief Return the CGNS element type (ElementType_t). | ||
| * \param[in] elementType - GEO_TYPE. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -556,7 +556,7 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form | |
| volumeDataSorter->SortConnectivity(config, geometry, true); | ||
|
|
||
| LogOutputFiles("Paraview"); | ||
| fileWriter = new CParaviewXMLFileWriter(volumeDataSorter); | ||
| fileWriter = new CParaviewXMLFileWriter(volumeDataSorter, config->GetWrt_Output_Double_Precision()); | ||
|
|
||
| break; | ||
|
|
||
|
|
@@ -683,7 +683,7 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form | |
| surfaceDataSorter->SortOutputData(); | ||
|
|
||
| LogOutputFiles("Paraview surface"); | ||
| fileWriter = new CParaviewXMLFileWriter(surfaceDataSorter); | ||
| fileWriter = new CParaviewXMLFileWriter(surfaceDataSorter, config->GetWrt_Output_Double_Precision()); | ||
|
|
||
| break; | ||
|
|
||
|
|
@@ -760,7 +760,11 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form | |
| volumeDataSorter->SortConnectivity(config, geometry, true); | ||
|
|
||
| LogOutputFiles("CGNS"); | ||
| fileWriter = new CCGNSFileWriter(volumeDataSorter); | ||
| fileWriter = new CCGNSFileWriter(volumeDataSorter, false, config->GetWrt_Output_Double_Precision()); | ||
|
|
||
| /*--- Add the boundaries, named as the markers (the finite volume sorter knows which elements are halos). ---*/ | ||
| if (const auto* fvmSorter = dynamic_cast<const CFVMDataSorter*>(volumeDataSorter)) | ||
| static_cast<CCGNSFileWriter*>(fileWriter)->SetBoundaryMarkers(config, geometry, fvmSorter); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Keep a typed pointer instead of casting `auto* cgnsWriter = new CCGNSFileWriter(volumeDataSorter, false, config->GetWrt_Output_Double_Precision()); Do the same in the other places similar casting is done |
||
|
|
||
| break; | ||
|
|
||
|
|
@@ -779,7 +783,10 @@ void COutput::WriteToFile(CConfig *config, CGeometry *geometry, OUTPUT_TYPE form | |
| surfaceDataSorter->SortOutputData(); | ||
|
|
||
| LogOutputFiles("CGNS surface"); | ||
| fileWriter = new CCGNSFileWriter(surfaceDataSorter, true); | ||
| fileWriter = new CCGNSFileWriter(surfaceDataSorter, true, config->GetWrt_Output_Double_Precision()); | ||
|
|
||
| /*--- One zone per plotted marker, named as the marker. ---*/ | ||
| static_cast<CCGNSFileWriter*>(fileWriter)->SetSurfaceMarkers(config, geometry); | ||
|
|
||
| break; | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.