Canoe
Comprehensive Atmosphere N' Ocean Engine
index_map.cpp
Go to the documentation of this file.
1 // C/C++
2 #include <mutex>
3 #include <string>
4 
5 // canoe
6 #include <configure.hpp>
7 
8 // athena
9 #include <athena/athena.hpp>
10 #include <athena/parameter_input.hpp>
11 
12 // application
13 #include <application/application.hpp>
14 #include <application/exceptions.hpp>
15 
16 // utils
17 #include <utils/vectorize.hpp>
18 
19 // canoe
20 #include "index_map.hpp"
21 
22 static std::mutex imap_mutex;
23 
25  Application::Logger app("canoe");
26  app->Log("Destroy IndexMap");
27 }
28 
30  // RAII
31  std::unique_lock<std::mutex> lock(imap_mutex);
32 
33  if (myindex_map_ == nullptr) {
34  myindex_map_ = new IndexMap();
35  }
36 
37  return myindex_map_;
38 }
39 
40 IndexMap const* IndexMap::InitFromAthenaInput(ParameterInput* pin) {
41  if (myindex_map_ != nullptr) {
42  throw RuntimeError("IndexMap", "IndexMap has been initialized");
43  }
44 
45  Application::Logger app("canoe");
46  app->Log("Initialize IndexMap");
47 
48  myindex_map_ = new IndexMap();
49 
50  auto& vapor_index_map = myindex_map_->vapor_index_map_;
51  auto& cloud_index_map = myindex_map_->cloud_index_map_;
52  auto& chemistry_index_map = myindex_map_->chemistry_index_map_;
53  auto& tracer_index_map = myindex_map_->tracer_index_map_;
54  auto& particle_index_map = myindex_map_->particle_index_map_;
55 
56  // vapor id
57  std::string str = pin->GetOrAddString("species", "vapor", "");
58  std::vector<std::string> names = Vectorize<std::string>(str.c_str(), " ,");
59 
60  if (names.size() > NVAPOR) {
61  throw ValueError("IndexMap", "Number of vapors", NVAPOR, names.size());
62  }
63 
64  for (size_t i = 0; i < names.size(); ++i) {
65  vapor_index_map[names[i]] = 1 + i;
66  }
67 
68  // cloud id
69  str = pin->GetOrAddString("species", "cloud", "");
70  names = Vectorize<std::string>(str.c_str(), " ,");
71 
72  if (names.size() > NCLOUD) {
73  throw ValueError("IndexMap", "Number of clouds", NCLOUD, names.size());
74  }
75 
76  for (size_t i = 0; i < names.size(); ++i) {
77  cloud_index_map[names[i]] = i;
78  }
79 
80  // chemistry id
81  str = pin->GetOrAddString("species", "chemistry", "");
82  names = Vectorize<std::string>(str.c_str(), " ,");
83 
84  if (names.size() > NCHEMISTRY) {
85  throw ValueError("IndexMap", "Number of chemistry", NCHEMISTRY,
86  names.size());
87  }
88 
89  for (size_t i = 0; i < names.size(); ++i) {
90  chemistry_index_map[names[i]] = i;
91  }
92 
93  // tracer id
94  str = pin->GetOrAddString("species", "tracer", "");
95  names = Vectorize<std::string>(str.c_str(), " ,");
96 
97  if (names.size() > NTRACER) {
98  throw ValueError("IndexMap", "Number of tracers", NTRACER, names.size());
99  }
100 
101  for (size_t i = 0; i < names.size(); ++i) {
102  tracer_index_map[names[i]] = i;
103  }
104 
105  // particle id
106  str = pin->GetOrAddString("species", "particle", "");
107  names = Vectorize<std::string>(str.c_str(), " ,");
108 
109  for (size_t i = 0; i < names.size(); ++i) {
110  particle_index_map[names[i]] = i;
111  }
112 
113  return myindex_map_;
114 }
115 
116 size_t IndexMap::GetSpeciesId(std::string category_name) const {
117  std::string delimiter = ".";
118 
119  // Find the position of the delimiter
120  size_t delimiter_pos = category_name.find(delimiter);
121 
122  if (delimiter_pos == std::string::npos) {
123  throw NotFoundError("GetSpeciesId",
124  "Delimiter '" + delimiter + "' in " + category_name);
125  }
126 
127  // Extract the substrings
128  std::string category = category_name.substr(0, delimiter_pos);
129  std::string name = category_name.substr(delimiter_pos + delimiter.length());
130 
131  if (category == "vapor") {
132  return GetVaporId(name);
133  } else if (category == "cloud") {
134  return NHYDRO + GetCloudId(name);
135  } else if (category == "chemistry") {
136  return NHYDRO + NCLOUD + GetChemistryId(name);
137  } else if (category == "tracer") {
138  return NHYDRO + NCLOUD + NCHEMISTRY + GetTracerId(name);
139  } else {
140  throw NotFoundError("GetSpeciesId", "Category " + category);
141  }
142 }
143 
145  std::unique_lock<std::mutex> lock(imap_mutex);
146 
147  if (IndexMap::myindex_map_ != nullptr) {
148  delete IndexMap::myindex_map_;
149  IndexMap::myindex_map_ = nullptr;
150  }
151 }
152 
153 std::string IndexMap::GetVaporName(size_t i) const {
154  for (auto const& [name, id] : vapor_index_map_) {
155  if (id == i) return name;
156  }
157  throw NotFoundError("GetVaporName", "Vapor id " + std::to_string(i));
158 }
159 
160 std::string IndexMap::GetCloudName(size_t i) const {
161  for (auto const& [name, id] : cloud_index_map_) {
162  if (id == i) return name;
163  }
164  throw NotFoundError("GetCloudName", "Cloud id " + std::to_string(i));
165 }
166 
167 std::string IndexMap::GetTracerName(size_t i) const {
168  for (auto const& [name, id] : tracer_index_map_) {
169  if (id == i) return name;
170  }
171  throw NotFoundError("GetTracerName", "Tracer id " + std::to_string(i));
172 }
173 
size_t GetTracerId(std::string const &name) const
Definition: index_map.hpp:56
std::map< std::string, size_t > chemistry_index_map_
Definition: index_map.hpp:67
size_t GetVaporId(std::string const &name) const
Definition: index_map.hpp:28
size_t GetSpeciesId(std::string category_name) const
Definition: index_map.cpp:116
std::string GetCloudName(size_t i) const
Definition: index_map.cpp:160
std::map< std::string, size_t > tracer_index_map_
Definition: index_map.hpp:68
std::string GetTracerName(size_t i) const
Definition: index_map.cpp:167
static IndexMap const * InitFromAthenaInput(ParameterInput *pin)
Definition: index_map.cpp:40
std::map< std::string, size_t > vapor_index_map_
Definition: index_map.hpp:65
static IndexMap * myindex_map_
Pointer to the single IndexMap instance.
Definition: index_map.hpp:72
IndexMap()
Protected ctor access thru static member function Instance.
Definition: index_map.hpp:13
static void Destroy()
Definition: index_map.cpp:144
size_t GetCloudId(std::string const &name) const
Definition: index_map.hpp:38
std::map< std::string, size_t > cloud_index_map_
Definition: index_map.hpp:66
std::string GetVaporName(size_t i) const
Definition: index_map.cpp:153
static IndexMap const * GetInstance()
Definition: index_map.cpp:29
size_t GetChemistryId(std::string const &name) const
Definition: index_map.hpp:48
std::map< std::string, size_t > particle_index_map_
Definition: index_map.hpp:69
static std::mutex imap_mutex
Definition: index_map.cpp:22