Documentation 6b54b78464
Loading...
Searching...
No Matches
CCGNSFileWriter.hpp
Go to the documentation of this file.
1/*!
2 * \file CCGNSFileWriter.hpp
3 * \brief Headers for CGNS file writer class.
4 * \author G. Baldan
5 * \version 8.5.0 "Harrier"
6 *
7 * SU2 Project Website: https://su2code.github.io
8 *
9 * The SU2 Project is maintained by the SU2 Foundation
10 * (http://su2foundation.org)
11 *
12 * Copyright 2012-2026, SU2 Contributors (cf. AUTHORS.md)
13 *
14 * SU2 is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Lesser General Public
16 * License as published by the Free Software Foundation; either
17 * version 2.1 of the License, or (at your option) any later version.
18 *
19 * SU2 is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with SU2. If not, see <http://www.gnu.org/licenses/>.
26 */
27
28#pragma once
29
30#ifdef HAVE_CGNS
31#ifdef __MINGW32__
32#include <basetsd.h>
33#endif
34#include "cgnslib.h"
35#ifdef HAVE_MPI
36#include "pcgnslib.h"
37#endif
38#endif
39
40#include <cstdint>
41#include <limits>
42#include <map>
43
44#include "CFileWriter.hpp"
45
46class CConfig;
47class CGeometry;
48class CFVMDataSorter;
49
50class CCGNSFileWriter final : public CFileWriter {
51 private:
52 const bool isSurface; /*!< \brief True if surface file. */
53 const bool doublePrecisionFields; /*!< \brief True to write the fields in double precision instead of single. */
54
55 /*!
56 * \brief Boundary elements of one marker owned by this rank, written as a boundary section of a volume file.
57 */
58 struct BoundaryMarker {
59 string name; /*!< \brief Marker tag. */
60 unsigned short kindBC; /*!< \brief SU2 boundary condition kind. */
61 vector<unsigned long> conn; /*!< \brief VTK type followed by the (1-based) output ids of the nodes, per element. */
62 };
63 vector<BoundaryMarker> boundaryMarkers; /*!< \brief Markers written as boundaries of a volume file. */
64
65 vector<string> surfaceMarkers; /*!< \brief Markers written as one zone each in a surface file. */
66
67 /*--- Names of the CGNS nodes, decided by PrepareNames before the file is opened. ---*/
68 vector<string> boundaryNames; /*!< \brief Boundary sections, BCs and families, per marker. */
69 string volumeZoneName = "Zone"; /*!< \brief Zone of a volume file. */
70 string solutionName = "Fields"; /*!< \brief Flow solution node of each zone. */
71 std::map<unsigned short, string> sectionNames; /*!< \brief Element sections of the zones, per element type. */
72
73 CConfig* config = nullptr; /*!< \brief Config, to sort the surface data of each marker. */
74 CGeometry* geometry = nullptr; /*!< \brief Geometry, to sort the surface data of each marker. */
75
76#ifdef HAVE_CGNS
77 int cgnsFileID; /*!< \brief CGNS file identifier. */
78 int cgnsBase; /*!< \brief CGNS database index. */
79 int cgnsZone; /*!< \brief CGNS zone index. */
80 int cgnsFields; /*!< \brief CGNS flow solution index. */
81
82 int nZones; /*!< \brief Total number of zones in the CGNS file. */
83 int nSections; /*!< \brief Total number of sections in the CGNS file. */
84
85 unsigned short nDim; /*!< \brief Problem dimension. */
86 unsigned long nLocalPoints; /*!< \brief Local number of points. */
87 cgsize_t GlobalPoint; /*!< \brief Total number of points. */
88 cgsize_t GlobalElem; /*!< \brief Total number of elements. */
89
90 cgsize_t cumulative; /*!< \brief Cumulative number of elements written. */
91
92 /*--- Max connectivity entries per section, so that readers using 32-bit sizes can read it. ---*/
93 static constexpr cgsize_t maxSectionEntries = std::numeric_limits<int32_t>::max();
94
95 /*--- Max length of the names of the CGNS nodes (zones, sections, BCs, families). ---*/
96 static constexpr size_t maxNameLength = 32;
97#endif
98 public:
99 /*!
100 * \brief File extension
101 */
102 const static string fileExt;
103
104 /*!
105 * \brief Construct a file writer using field names and the data sorter.
106 * \param[in] valDataSorter - The parallel sorted data to write.
107 * \param[in] isSurf - True if it is a surface file.
108 */
109 CCGNSFileWriter(CParallelDataSorter* valDataSorter, bool isSurf = false, bool doublePrecision = false);
110
111 /*!
112 * \brief Write sorted data to file in CGNS file format.
113 * \param[in] val_filename - The name of the file.
114 */
115 void WriteData(string val_filename) override ;
116
117 /*!
118 * \brief Add the boundaries to a volume file: one boundary section, BC and family per marker, named as the marker.
119 * \param[in] valConfig - Definition of the problem.
120 * \param[in] valGeometry - Geometrical definition of the problem.
121 * \param[in] volumeSorter - The volume data sorter, to find the boundary elements owned by this rank.
122 */
123 void SetBoundaryMarkers(const CConfig* valConfig, const CGeometry* valGeometry, const CFVMDataSorter* volumeSorter);
124
125 /*!
126 * \brief Write a surface file with one zone per plotted marker, named as the marker. The data of the surface
127 * sorter is sorted again for each marker when the file is written.
128 * \param[in] valConfig - Definition of the problem.
129 * \param[in] valGeometry - Geometrical definition of the problem.
130 */
131 void SetSurfaceMarkers(CConfig* valConfig, CGeometry* valGeometry);
132
133 private:
134#ifdef HAVE_CGNS
135 /*!
136 * \brief Create the CGNS file and its base.
137 * \param[in] val_filename - The name of the file.
138 */
139 void InitializeMeshFile(const string& val_filename);
140
141 /*!
142 * \brief Write a zone with the data currently held by the data sorter.
143 * \param[in] zoneName - Name of the zone.
144 */
145 void WriteZone(const string& zoneName);
146
147 /*!
148 * \brief Create a zone for the data currently held by the data sorter.
149 * \param[in] zoneName - Name of the zone, at most maxNameLength characters.
150 */
151 void InitializeZone(const string& zoneName);
152
153 /*!
154 * \brief Get the names of CGNS nodes named as the markers. Tags longer than maxNameLength characters are truncated,
155 * and a number is appended to a truncated tag equal to a previous name, so that the names are unique.
156 * \param[in] tags - Marker tags.
157 * \param[in] taken - Names that are already used.
158 * \return The names, in the order of the tags.
159 */
160 vector<string> GetUniqueNames(const vector<string>& tags, vector<string> taken = {}) const;
161
162 /*!
163 * \brief Decide the names of the CGNS nodes before the file is opened. The children of a node need unique names:
164 * in a zone the element sections (volume and boundary), GridCoordinates, ZoneBC, ZoneType and the solution,
165 * in the base the zone and the families. The boundary sections, BCs and families keep the marker names,
166 * which the SU2 CGNS reader takes as marker tags after removing the spaces: a marker named GridCoordinates,
167 * ZoneBC or ZoneType is written with a space ("Zone BC") and read back unchanged. An internal node (a volume
168 * section, the solution "Fields" or the zone "Zone") whose name equals a marker name gets the prefix "SU2 ",
169 * with a space, which marker names cannot contain.
170 */
171 void PrepareNames();
172
173 /*!
174 * \brief Number of sections the elements of a type are split into (see WriteConnectivity).
175 */
176 cgsize_t SectionCount(GEO_TYPE type) const;
177
178 /*!
179 * \brief Write the boundary sections, BCs and families of the markers set with SetBoundaryMarkers.
180 */
181 void WriteBoundaries();
182
183 /*!
184 * \brief Write i-th coordinate to file in CGNS file format. Coordinates are always written in double precision,
185 * the fields follow the precision requested by the user.
186 * \param[in] iField - the output field ID.
187 * \param[in] FieldName - Field name in the CGNS.
188 */
189 void WriteField(int iField, const string& FieldName);
190
191 /*!
192 * \brief Write i-th coordinate or field to file with the given data type.
193 * \param[in] iField - the output field ID.
194 * \param[in] FieldName - Field name in the CGNS.
195 * \param[in] dataType - CGNS data type matching T, i.e. RealSingle for float and RealDouble for double.
196 */
197 template <class T>
198 void WriteFieldOfType(int iField, const string& FieldName, DataType_t dataType);
199
200 /*!
201 * \brief Write connectivity to file for GEO_TYPE in CGNS file format.
202 * \param[in] type - GEO_TYPE.
203 * \param[in] SectionName - Section name in the CGNS file.
204 */
205 void WriteConnectivity(GEO_TYPE type, const string& SectionName);
206
207 /*!
208 * \brief Initialize flow solution in the CGNS file.
209 */
210 void InitializeFields();
211
212 /*!
213 * \brief Create an element section, collectively when built with MPI.
214 * \param[in] name - Name of the section.
215 * \param[in] type - CGNS element type of the section.
216 * \param[in] start - First element of the section.
217 * \param[in] end - Last element of the section.
218 * \param[out] section - Index of the section.
219 * \returns CGNS error code.
220 */
221 int SectionWrite(const string& name, ElementType_t type, cgsize_t start, cgsize_t end, int* section);
222
223 /*!
224 * \brief Write the connectivity of the elements [start, end] of a section, the elements of this rank.
225 * \param[in] section - Index of the section.
226 * \param[in] start - First element written by this rank.
227 * \param[in] end - Last element written by this rank.
228 * \param[in] elements - Connectivity, nullptr if this rank writes no element of the section.
229 * \returns CGNS error code.
230 */
231 int ElementsWriteData(int section, cgsize_t start, cgsize_t end, const cgsize_t* elements);
232
233 /*!
234 * \brief Call a generic CGNS function.
235 * \param[in] ier - error value.
236 */
237 static inline void CallCGNS(const int& ier) {
238 if (ier) cg_error_exit();
239 }
240
241 /*!
242 * \brief Return the CGNS boundary condition type of an SU2 boundary condition kind.
243 * \param[in] kindBC - SU2 boundary condition kind.
244 */
245 static BCType_t GetCGNSBCType(unsigned short kindBC);
246
247 /*!
248 * \brief Return the CGNS element type (ElementType_t).
249 * \param[in] elementType - GEO_TYPE.
250 */
251 static inline ElementType_t GetCGNSType(unsigned short elementType) {
252 switch (elementType) {
253 case LINE:
254 return BAR_2;
255 case TRIANGLE:
256 return TRI_3;
257 case QUADRILATERAL:
258 return QUAD_4;
259 case TETRAHEDRON:
260 return TETRA_4;
261 case HEXAHEDRON:
262 return HEXA_8;
263 case PYRAMID:
264 return PYRA_5;
265 case PRISM:
266 return PENTA_6;
267 default:
268 assert(false && "Invalid element type.");
269 return ElementTypeNull;
270 }
271 }
272#endif
273};
Headers fo the file writer class.
Definition CCGNSFileWriter.hpp:50
void WriteData(string val_filename) override
Write sorted data to file in CGNS file format.
Definition CCGNSFileWriter.cpp:41
void SetSurfaceMarkers(CConfig *valConfig, CGeometry *valGeometry)
Write a surface file with one zone per plotted marker, named as the marker. The data of the surface s...
Definition CCGNSFileWriter.cpp:122
void SetBoundaryMarkers(const CConfig *valConfig, const CGeometry *valGeometry, const CFVMDataSorter *volumeSorter)
Add the boundaries to a volume file: one boundary section, BC and family per marker,...
Definition CCGNSFileWriter.cpp:86
static const string fileExt
File extension.
Definition CCGNSFileWriter.hpp:102
Main class for defining the problem; basically this class reads the configuration file,...
Definition CConfig.hpp:64
Definition CFVMDataSorter.hpp:33
Definition CFileWriter.hpp:42
Parent class for defining the geometry of the problem (complete geometry, multigrid agglomerated geom...
Definition CGeometry.hpp:75
Definition CParallelDataSorter.hpp:39
GEO_TYPE
Types of geometric entities based on VTK nomenclature.
Definition option_structure.hpp:131
@ TRIANGLE
VTK nomenclature for defining a triangle element.
Definition option_structure.hpp:134
@ PYRAMID
VTK nomenclature for defining a pyramid element.
Definition option_structure.hpp:139
@ PRISM
VTK nomenclature for defining a prism element.
Definition option_structure.hpp:138
@ QUADRILATERAL
VTK nomenclature for defining a quadrilateral element.
Definition option_structure.hpp:135
@ HEXAHEDRON
VTK nomenclature for defining a hexahedron element.
Definition option_structure.hpp:137
@ LINE
VTK nomenclature for defining a line element.
Definition option_structure.hpp:133
@ TETRAHEDRON
VTK nomenclature for defining a tetrahedron element.
Definition option_structure.hpp:136