File: PViewIO_CGNS.cpp

package info (click to toggle)
gmsh 4.8.4%2Bds2-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 87,812 kB
  • sloc: cpp: 378,014; ansic: 99,669; yacc: 7,216; python: 6,680; java: 3,486; lisp: 659; lex: 621; perl: 571; makefile: 470; sh: 440; xml: 415; javascript: 113; pascal: 35; modula3: 32
file content (188 lines) | stat: -rw-r--r-- 6,217 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
// Gmsh - Copyright (C) 1997-2021 C. Geuzaine, J.-F. Remacle
//
// See the LICENSE.txt file for license information. Please report all
// issues on https://gitlab.onelab.info/gmsh/gmsh/issues.

#include "GmshConfig.h"
#include "GmshMessage.h"
#include "PView.h"
#include "PViewData.h"
#include "PViewDataGModel.h"
#include "CGNSCommon.h"
#include "CGNSConventions.h"

#if defined(HAVE_LIBCGNS)

namespace {

  typedef std::pair<std::string, std::string> SolFieldName;

  int readFlowSolutionNames(
    int fileIndex, int baseIndex, int nbZone,
    std::map<SolFieldName, PViewDataGModel::DataType> &fields)
  {
    int cgnsErr;

    for(int iZone = 1; iZone <= nbZone; iZone++) {
      // get number of flow solutions in zone
      int nbZoneSol;
      cgnsErr = cg_nsols(fileIndex, baseIndex, iZone, &nbZoneSol);
      if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__, fileIndex);

      // get names of solution fields in each zone
      for(int iZoneSol = 1; iZoneSol <= nbZoneSol; iZoneSol++) {
        // get FlowSolution info
        char rawSolName[CGNS_MAX_STR_LEN];
        CGNS_ENUMT(GridLocation_t) location;
        cgnsErr = cg_sol_info(fileIndex, baseIndex, iZone, iZoneSol, rawSolName,
                              &location);
        if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__, fileIndex);
        const std::string solName(rawSolName);
        PViewDataGModel::DataType type;
        if(location == CGNS_ENUMV(CellCenter))
          type = PViewDataGModel::ElementData;
        else if(location == CGNS_ENUMV(Vertex)) {
          if(nbZone > 1) {
            Msg::Warning(
              "Multi-zone node-based solutions not supported in CGNS "
              "reader, skipping '%s'",
              rawSolName);
            continue;
          }
          else
            type = PViewDataGModel::NodeData;
        }
#ifdef HAVE_LIBCGNS_CPEX0045
        else if(location == ElementBased) {
          type = PViewDataGModel::ElementNodeData;
        }
#endif
        else {
          Msg::Warning("Unsupported GridLocation in CGNS solution reader, "
                       "skipping '%s'",
                       rawSolName);
          continue;
        }

        // get number of fields in this FlowSolution
        int nbField;
        cgnsErr = cg_nfields(fileIndex, baseIndex, iZone, iZoneSol, &nbField);
        if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__, fileIndex);

        // get names of fields
        for(int iField = 1; iField <= nbField; iField++) {
          CGNS_ENUMT(DataType_t) dataType;
          char rawFieldName[CGNS_MAX_STR_LEN];
          cgnsErr = cg_field_info(fileIndex, baseIndex, iZone, iZoneSol, iField,
                                  &dataType, rawFieldName);
          if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__, fileIndex);
          const std::string fieldName(rawFieldName);
          fields[std::make_pair(solName, fieldName)] = type;
        }
      }
    }

    return 1;
  }

  bool
  readFieldData(const std::vector<std::vector<MVertex *> > &vertPerZone,
                const std::vector<std::vector<MElement *> > &eltPerZone,
                const std::string &fileName, int fileIndex, int baseIndex,
                const std::map<SolFieldName, PViewDataGModel::DataType> &fields)
  {
    int index = -1;
    for(auto it = fields.begin(); it != fields.end(); ++it) {
      // field name and type
      const SolFieldName &solFieldName = it->first;
      const PViewDataGModel::DataType &fieldType = it->second;
      index++;

      // either get existing view data, or create new one
      const std::string fullFieldName =
        solFieldName.first + "_" + solFieldName.second;
      PView *p = PView::getViewByName(
        fullFieldName, -1, -1); // DBGTT: to be checked for multi-file
      PViewDataGModel *d;
      bool create;
      if(p != nullptr) {
        d = dynamic_cast<PViewDataGModel *>(p->getData());
        create = false;
      }
      else {
        d = new PViewDataGModel(fieldType);
        create = true;
      }

      // read view data
      if(!d->readCGNS(solFieldName, fileName, index, fileIndex, baseIndex,
                      vertPerZone, eltPerZone)) {
        Msg::Error("Could not read data in CGNS file '%s'", fileName.c_str());
        if(create) delete d;
        return false;
      }
      else {
        d->setName(fullFieldName);
        d->setFileName(fileName);
        d->setFileIndex(index);
        if(create) new PView(d);
      }
    }

    return true;
  }

} // namespace

bool PView::readCGNS(const std::vector<std::vector<MVertex *> > &vertPerZone,
                     const std::vector<std::vector<MElement *> > &eltPerZone,
                     const std::string &fileName)
{
  int cgnsErr;

  // open CGNS file and read scale
  int fileIndex = 0;
  cgnsErr = cg_open(fileName.c_str(), CG_MODE_READ, &fileIndex);
  if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__, fileIndex);

  // read base node
  const int baseIndex = 1;
  int dim = 0, meshDim = 0;
  char baseName[CGNS_MAX_STR_LEN];
  cgnsErr = cg_base_read(fileIndex, baseIndex, baseName, &meshDim, &dim);
  if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__, fileIndex);

  // read number of zones
  int nbZone = 0;
  cgnsErr = cg_nzones(fileIndex, baseIndex, &nbZone);
  if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__, fileIndex);

  // get flow solutions names
  std::map<SolFieldName, PViewDataGModel::DataType> fields;
  int err = readFlowSolutionNames(fileIndex, baseIndex, nbZone, fields);
  if(err == 0) return 0;

  // read field data
  bool err2 = readFieldData(vertPerZone, eltPerZone, fileName, fileIndex,
                            baseIndex, fields);
  if(!err2) return false;

  // close file
  cgnsErr = cg_close(fileIndex);
  if(cgnsErr != CG_OK) return cgnsError(__FILE__, __LINE__);

  return true;
}

#else

bool PView::readCGNS(const std::vector<std::vector<MVertex *> > &vertPerZone,
                     const std::vector<std::vector<MElement *> > &eltPerZone,
                     const std::string &fileName)
{
  Msg::Error("Gmsh must be compiled with CGNS support to read '%s'",
             fileName.c_str());
  return false;
}

#endif