V3FIT
main.cpp
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
2 // The @fixed_width, @begin_table, @item2 and @end_table commands are custom
3 // defined commands in Doxygen.in. They are defined under ALIASES. For the page
4 // created here, the 80 column limit is exceeded. Arguments of aliases are
5 // separated by ','. If you intended ',' to be a string you must use an escaped
6 // comma '\,'.
7 //
67 //------------------------------------------------------------------------------
68 //******************************************************************************
71 //
77 //******************************************************************************
78 
79 #include <algorithm>
80 #include <array>
81 #include <cmath>
82 #include <fstream>
83 #include <iostream>
84 #include <map>
85 #include <netcdf.h>
86 #include <vector>
87 
88 #include "vertex.hpp"
89 
91 const std::string new_limiter_deg = "new_limiter_deg";
93 const std::string new_limiter_rad = "new_limiter_rad";
94 
100  degrees,
101  radians,
102  eof
103 };
104 
105 //------------------------------------------------------------------------------
113 //------------------------------------------------------------------------------
114 const limiter_type get_next_keyword(std::ifstream &file) {
115  std::string line;
116 
117  for (file >> line; !file.eof() && !file.fail() && !file.bad(); file >> line) {
118  if (line.compare(new_limiter_deg) == 0) {
119  return degrees;
120  } else if (line.compare(new_limiter_rad) == 0) {
121  return radians;
122  }
123  }
124  return eof;
125 }
126 
127 //------------------------------------------------------------------------------
138 //------------------------------------------------------------------------------
139 void parse_limiter(std::ifstream &file, std::map<const double, std::vector<vertex *> > &limiters, const limiter_type type) {
140  size_t num_phi;
141  file >> num_phi;
142 
143  std::vector<double> phi_angles;
144  for (size_t i = 0; i < num_phi; i++) {
145  double phi;
146  file >> phi;
147 
148  if (type == degrees) {
149  phi *= M_PI/180.0;
150  }
151 
152  phi_angles.push_back(phi);
153  }
154 
155  double r;
156  double z;
157 
158  vertex *limiter = nullptr;
159 
160  for (file >> r >> z; !file.eof() && !file.fail() && !file.bad(); file >> r >> z) {
161  if (limiter == nullptr) {
162  limiter = new vertex(vector3d(r, z, 0.0));
163  } else {
164  limiter->insert(new vertex(vector3d(r, z, 0.0)));
165  }
166  }
167 
168 // Clear the bad and fail bits so the parsing can continue. This bits get set
169 // when the file fails to read two doubles. Clear doesn't actually clear error
170 // bits instead see if the eof bit is set then set only that bit.
171  file.eof() ? file.clear(std::iostream::eofbit) : file.clear();
172 
173  for (double phi : phi_angles) {
174  limiters[phi].push_back(limiter);
175  }
176 }
177 
178 //------------------------------------------------------------------------------
185 //------------------------------------------------------------------------------
186 std::map<const double, std::vector<vertex *> > parse_limiter_file(const std::string &file_name) {
187 
188  std::ifstream file(file_name);
189 
190  std::map<const double, std::vector<vertex *> > limiters;
191 
192  for (limiter_type type = get_next_keyword(file); type != eof; type = get_next_keyword(file)) {
193  parse_limiter(file, limiters, type);
194  }
195 
196  file.close();
197 
198  return limiters;
199 }
200 
201 //------------------------------------------------------------------------------
219 //------------------------------------------------------------------------------
220 int main(int argc, const char * argv[]) {
221 
222  if (argc != 8) {
223  std::cout << "Expected 7 arguments." << std::endl;
224  std::cout << "lgrid filename r0 dr numr z0 dz numz" << std::endl;
225  }
226 
227  std::map<const double, std::vector<vertex *> > limiters = parse_limiter_file(argv[1]);
228 
229  const double r0 = atof(argv[2]);
230  const double dr = atof(argv[3]);
231  const size_t num_r = atoll(argv[4]);
232 
233  const double z0 = atof(argv[5]);
234  const double dz = atof(argv[6]);
235  const size_t num_z = atoll(argv[7]);
236 
237  std::vector<double> grids;
238 
239  int ncid;
240  nc_create((std::string(argv[1]) + std::string(".nc")).c_str(), NC_WRITE, &ncid);
241 
242  int num_phi_dimid;
243  nc_def_dim(ncid, "num_phi", limiters.size(), &num_phi_dimid);
244  int num_r_dimid;
245  nc_def_dim(ncid, "num_r", num_r, &num_r_dimid);
246  int num_z_dimid;
247  nc_def_dim(ncid, "num_z", num_z, &num_z_dimid);
248 
249  std::vector<double> phi_angles;
250 
251  for (std::pair<const double, std::vector<vertex *> > &phi : limiters) {
252  phi_angles.push_back(phi.first);
253  for (size_t j = 0; j < num_z; j++) {
254  const double z = z0 + j*dz;
255  for (size_t i = 0; i < num_r; i++) {
256  const double r = r0 + i*dr;
257  std::vector<double> d;
258  for (vertex *limiter : phi.second) {
259  vertex::distance(limiter, vector3d(r, z, 0.0), d);
260  }
261  std::sort(d.begin(), d.end(), [](double a, double b) {
262  return fabs(a) < fabs(b);
263  });
264  grids.push_back(d[0]);
265  }
266  }
267  }
268 
269  int phi_angles_varid;
270  nc_def_var(ncid, "phi_angles", NC_DOUBLE, 1, &num_phi_dimid, &phi_angles_varid);
271  int r0_varid;
272  nc_def_var(ncid, "r0", NC_DOUBLE, 0, nullptr, &r0_varid);
273  int dr_varid;
274  nc_def_var(ncid, "dr", NC_DOUBLE, 0, nullptr, &dr_varid);
275  int z0_varid;
276  nc_def_var(ncid, "z0", NC_DOUBLE, 0, nullptr, &z0_varid);
277  int dz_varid;
278  nc_def_var(ncid, "dz", NC_DOUBLE, 0, nullptr, &dz_varid);
279 
280  int grids_varid;
281  std::array<int, 3> grid_dims;
282  grid_dims[0] = num_phi_dimid;
283  grid_dims[1] = num_z_dimid;
284  grid_dims[2] = num_r_dimid;
285  nc_def_var(ncid, "iso_grids", NC_DOUBLE, 3, grid_dims.data(), &grids_varid);
286 
287  nc_enddef(ncid);
288 
289  nc_put_var(ncid, phi_angles_varid, phi_angles.data());
290  nc_put_var(ncid, r0_varid, &r0);
291  nc_put_var(ncid, dr_varid, &dr);
292  nc_put_var(ncid, z0_varid, &z0);
293  nc_put_var(ncid, dz_varid, &dz);
294  nc_put_var(ncid, grids_varid, grids.data());
295 
296  nc_close(ncid);
297 
298  return 0;
299 }
vertex
A vertex.
Definition: vertex.hpp:21
new_limiter_rad
const std::string new_limiter_rad
Limiter plane keyword specified in radians.
Definition: main.cpp:93
get_next_keyword
const limiter_type get_next_keyword(std::ifstream &file)
Finds the next keyword.
Definition: main.cpp:114
vector3d
A vector.
Definition: vector3d.hpp:19
limiter_type
limiter_type
Definition: main.cpp:99
main
int main(int argc, const char *argv[])
Main program.
Definition: main.cpp:220
vertex::distance
static void distance(vertex *start, const vector3d &p, std::vector< double > &d)
Find the distances to the limiter.
Definition: vertex.cpp:225
limiter
Defines the base class of the type limiter_class.
Definition: limiter.f:15
parse_limiter_file
std::map< const double, std::vector< vertex * > > parse_limiter_file(const std::string &file_name)
Parses a limiter specification.
Definition: main.cpp:186
new_limiter_deg
const std::string new_limiter_deg
Limiter plane keyword specified in degrees.
Definition: main.cpp:91
parse_limiter
void parse_limiter(std::ifstream &file, std::map< const double, std::vector< vertex * > > &limiters, const limiter_type type)
Parses a limiter specification.
Definition: main.cpp:139