CoarseGeometry.cpp 6.09 KB
Newer Older
1
#include "M_IOFiles.hpp"
2
#include "CoarseGeometry.hpp"
3

4

5
6
7
8
M_ifstream CoarseGeometry::loadGeometryFile(const std::string &name) {
  std::string GeoPath = Config::getSearchPath() + "conf/geo/";
  config.get<std::string>("GeoPath", GeoPath);
  std::string GeoName = name + ".geo";
9
10
11
  if (!FileExists(GeoName))
    GeoName = GeoPath + GeoName;
  if (!FileExists(GeoName)) Exit("no mesh with name: " + name);
12
  return {GeoName.c_str()};
13
14
}

15
16
17
18
19
20
21
22
23
24
25
26
27
bool CoarseGeometry::readGeometryFile(std::istream &geoFileStream) {
  char L[len];
  geoFileStream.getline(L, len);
  if (strncasecmp("points", L, 6) == 0) geoFileStream.getline(L, len);
  while (insertCoordinate(L, coordinates)) geoFileStream.getline(L, len);
  if (strncasecmp("cells", L, 5) == 0) geoFileStream.getline(L, len);
  while (insertID(L, cellIds)) geoFileStream.getline(L, len);
  if (strncasecmp("faces", L, 5) == 0) geoFileStream.getline(L, len);
  while (insertID(L, faceIds)) geoFileStream.getline(L, len);
  if (strncasecmp("vdata", L, 5) == 0) geoFileStream.getline(L, len);
  while (insertData(L, vdataList)) geoFileStream.getline(L, len);
  if (strncasecmp("cdata", L, 5) == 0) geoFileStream.getline(L, len);
  while (insertData(L, cdataList)) geoFileStream.getline(L, len);
28
29
30
31
  if (strncasecmp("times", L, 5) == 0) {
    geoFileStream.getline(L, len);
    insertTimeSteps(L, timeSteps);
  }
32
  return true;
33
34
}

35
void CoarseGeometry::initIds(const vector<vector<int>> &values, vector<Ids> &ids) {
36
37
38
39
40
41
42
43
44
  for (const auto &value : values) {
    if (value.size() < 3) continue;
    int n = value[0];
    int f = value[1];
    int tmp[27];
    for (int j = 2; j < value.size(); ++j)
      tmp[j - 2] = value[j];
    ids.emplace_back(Ids(n, value.size() - 2, f, tmp));
  }
45
46
}

47
48
49
50
51
52
53
bool CoarseGeometry::insertCoordinate(char *L, vector<Point> &coordinateList) {
  dout(100) << L << "\n";
  double z[4] = {0, 0, 0, 0};
  int d = sscanf(L, "%lf %lf %lf %lf", z, z + 1, z + 2, z + 3);
  if (d < 1) return false;
  coordinates.emplace_back(Point(z));
  return true;
54
55
}

56
void CoarseGeometry::insertTimeSteps(char *L, std::vector<double> &timeSteps) {
57
  std::string content(L);
58
59
60
61
62
63
64
65
  std::vector<string> ts_strings = split(content, " ");
  ts_strings = ft::filter(ts_strings, [](auto &s) { return !s.empty(); });
  timeSteps.resize(ts_strings.size(), 0.0);
  std::transform(ts_strings.begin(), ts_strings.end(), timeSteps.begin(), ft::stod);
}

std::vector<double> CoarseGeometry::refineTimeSteps(const std::vector<double> &timeSteps) {
  // refining scale times the time steps
66
  Exit("Not tested!");
67
68
69
70
71
72
  vector<vector<double>> init_timesteps(refineTimeStepCount + 1);
  init_timesteps[0] = timeSteps;
  int SF_inv = 2.0;
  for (unsigned int S = 1; S < refineTimeStepCount + 1; ++S) {
    unsigned int m = init_timesteps[S - 1].size();
    init_timesteps[S].resize(2 * m - 1);
73
    init_timesteps[S][0] = init_timesteps[S - 1][0];
74
75
76
77
78
79
    init_timesteps[S][m + (m - 1) * (SF_inv - 1) - 1] = init_timesteps[S - 1][m - 1];
    for (unsigned int k = 0; k < m - 1; ++k) {
      init_timesteps[S][k * SF_inv + 1] = init_timesteps[S - 1][k + 1];
      double dt = init_timesteps[S - 1][k + 2] - init_timesteps[S - 1][k + 1];
      for (unsigned int l = 1; l < SF_inv; ++l)
        init_timesteps[S][k * SF_inv + l + 1] =
80
            init_timesteps[S - 1][k + 1] + dt * 1 / double(SF_inv) * l;
81
82
    }
  }
83
  return init_timesteps[refineTimeStepCount];
84
85
}

86
bool CoarseGeometry::insertID(char *L, vector<Ids> &ids) {
87
88
89
90
91
92
93
94
95
96
97
98
99
  int n, f, pos;
  int m = sscanf(L, "%d %d %n", &n, &f, &pos);

  if (m < 2)
    return false;
  int cornerIndices[n];
  for (int i = 0; i < n; i++) {
    int cur;
    assert(sscanf(L + pos, "%d %n", &cornerIndices[i], &cur) == 1);
    pos += cur;
  }
  ids.emplace_back(Ids(n, n, f, cornerIndices));
  return true;
100
101
}

102
103
104
105
106
107
108
109
110
111
112
113
114
115
bool CoarseGeometry::insertData(char *L, vector<DataContainer> &vertexData) {
  int n, pos;
  int m = sscanf(L, "%d %n", &n, &pos);

  if (m < 1 || n < 1)
    return false;
  DataContainer pContainer(n);
  for (int i = 0; i < n; i++) {
    double d;
    int cur;

    assert(sscanf(L + pos, "%lf %n", &d, &cur) == 1);
    pContainer.Set(i, d);
    pos += cur;
116
  }
117
118
  vertexData.emplace_back(pContainer);
  return true;
119
}
120

121
CoarseGeometry::CoarseGeometry(const string &geometryFilename) {
122
123
124
  if (PPM->Master()) {
    M_ifstream geoFileStream = loadGeometryFile(geometryFilename);
    readGeometryFile(geoFileStream);
125
126
127
128
    if (scalingFactor != 1.0) {
      mout << "  scaling geometry by " << scalingFactor << endl;
      Scale(scalingFactor);
    }
129
130
  }
  CommunicateGeometry();
131
  geoName = geometryFilename;
132
133
}

134
135
136
137
138
void CoarseGeometry::CommunicateGeometry() {
  if (PPM->Size() != 1) {
    ExchangeBuffer exBuffer;
    if (PPM->Master()) {
      for (int q = 1; q < PPM->Size(); ++q) {
139
        exBuffer.Send(q) << int(timeSteps.size());
140
141
142
143
144
145
146
147
148
149
        for (double timeStep : timeSteps) {
          exBuffer.Send(q) << double(timeStep);
        }
      }
    }
    exBuffer.Communicate();
    if (!PPM->Master()) {
      int m;
      exBuffer.Receive(0) >> m;
      timeSteps.resize(m);
150
151
152
      for (int i = 0; i < m; i++) {
        exBuffer.Receive(0) >> timeSteps[i];

153
154
155
156
157
158
      }
    }
    exBuffer.ClearBuffers();
  }
};

159
160
CoarseGeometry::CoarseGeometry(const MeshPoints &points, const MeshCells &cells,
                               const MeshFaces &faces, const TimeSteps &timeSteps) :
161
    timeSteps(timeSteps) {
162
  for (const auto &point : points) {
163
    double z[]{0.0, 0.0, 0.0, 0.0};
164
165
166
167
168
169
170
    for (int j = 0; j < min(3, int(point.size())); ++j)
      z[j] = point[j];
    coordinates.emplace_back(Point(z));
  }
  initIds(cells, cellIds);
  initIds(faces, faceIds);
}
171

172
173
174
void CoarseGeometry::Scale(double scalingFactor) {
  for (auto &z : coordinates)
    z *= scalingFactor;
175
}
176
177
178

Logging &operator<<(Logging &s, const CoarseGeometry &M) {
  return s << "POINTS: " << M.coordinates.size() << endl << M.coordinates
179
180
           << "CELLS: " << M.cellIds.size() << endl << M.cellIds
           << "FACES: " << M.faceIds.size() << endl << M.faceIds
181
182
183
184
185
           #ifdef USE_DATAMESH
           << "VDATA: " << M.vdataList.size() << endl << M.vdataList
           << "CDATA: " << M.cdataList.size() << endl << M.cdataList
           #endif
           << endl;
186
187
188
189
190
}

std::string CoarseGeometry::Name() const {
  return geoName;
}