Xyce  6.1
N_DEV_Configuration.C
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 // Copyright Notice
3 //
4 // Copyright 2002 Sandia Corporation. Under the terms
5 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
6 // Government retains certain rights in this software.
7 //
8 // Xyce(TM) Parallel Electrical Simulator
9 // Copyright (C) 2002-2015 Sandia Corporation
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //-----------------------------------------------------------------------------
24 
25 //-------------------------------------------------------------------------
26 // Filename : $RCSfile: N_DEV_Configuration.C,v $
27 //
28 // Purpose :
29 //
30 // Special Notes :
31 //
32 // Creator : David Baur
33 //
34 // Creation Date : 04/18/2013
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision: 1.19.2.1 $
40 //
41 // Revision Date : $Date: 2015/04/02 18:29:36 $
42 //
43 // Current Owner : $Author: tvrusso $
44 //-------------------------------------------------------------------------
45 
46 #include <Xyce_config.h>
47 
48 #include <algorithm>
49 #include <iomanip>
50 #include <ostream>
51 #include <stdexcept>
52 
53 #include <N_DEV_Configuration.h>
54 #include <N_DEV_DeviceMgr.h>
55 #include <N_ERH_Message.h>
56 #include <N_UTL_Demangle.h>
57 
58 namespace Xyce {
59 namespace Device {
60 
61 namespace {
62 
63 typedef Configuration::ConfigurationMap ConfigurationMap;
64 typedef std::map<EntityTypeId, Configuration *> EntityTypeIdConfigurationMap;
65 
66 typedef unordered_map<std::string, EntityTypeId, HashNoCase, EqualNoCase> NameEntityTypeIdMap;
67 typedef unordered_map<NameLevelKey, EntityTypeId> NameLevelKeyEntityTypeIdMap;
68 
69 //-----------------------------------------------------------------------------
70 // Class :
71 // Purpose :
72 // Special Notes :
73 // Scope : public
74 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
75 // Creation Date : Fri Mar 14 13:38:33 2014
76 //-----------------------------------------------------------------------------
77 ///
78 /// Container for the name, model and level forward and backward maps.
79 ///
80 struct Data
81 {
82  ConfigurationMap configurationMap_; ///< Device registration: Maps (name, level) -> configuration
83  EntityTypeIdConfigurationMap modelTypeConfigurationMap_; ///< Device registration: Maps model_type_id -> configuration
84  NameEntityTypeIdMap modelTypeNameModelGroupMap_; ///< Model registration: Maps model_group_name -> model_group_id
85  NameLevelKeyEntityTypeIdMap modelTypeNameLevelModelTypeMap_; ///< Model registration: Maps (name, level) -> model_type_id
86 
87 
88  //-----------------------------------------------------------------------------
89  // Function : ~Data
90  // Purpose :
91  // Special Notes :
92  // Scope : public
93  // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
94  // Creation Date : Fri Mar 14 13:39:41 2014
95  //-----------------------------------------------------------------------------
96  ///
97  /// Free all the created device configurations.
98  ///
99  ~Data()
100  {
101  std::vector<Configuration *> c;
102  for (ConfigurationMap::const_iterator it = configurationMap_.begin(); it != configurationMap_.end(); ++it)
103  c.push_back((*it).second);
104  std::sort(c.begin(), c.end());
105  c.erase(std::unique(c.begin(), c.end()), c.end());
106  for (std::vector<Configuration *>::iterator it = c.begin(); it != c.end(); ++it)
107  delete *it;
108  }
109 };
110 
111 //-----------------------------------------------------------------------------
112 // Function : getData
113 // Purpose :
114 // Special Notes :
115 // Scope : public
116 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
117 // Creation Date : Wed Feb 5 11:49:42 2014
118 //-----------------------------------------------------------------------------
119 /// returns the configuration data singleton.
120 ///
121 /// @return reference to the configuration data singleton.
122 ///
123 Data &getData()
124 {
125  static Data data_;
126 
127  return data_;
128 }
129 
130 } // namespace <unnamed>
131 
132 //-----------------------------------------------------------------------------
133 // Function : Configuration::getConfigurationMap
134 // Purpose :
135 // Special Notes :
136 // Scope : public
137 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
138 // Creation Date : Fri Mar 14 13:23:31 2014
139 //-----------------------------------------------------------------------------
142  return getData().configurationMap_;
143 }
144 
145 //-----------------------------------------------------------------------------
146 // Function : Configuration::findConfiguration
147 // Purpose :
148 // Special Notes :
149 // Scope : public
150 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
151 // Creation Date : Fri Mar 14 13:23:52 2014
152 //-----------------------------------------------------------------------------
153 const Configuration *
155  ModelTypeId model_type_id)
156 {
157  EntityTypeIdConfigurationMap::const_iterator it = getData().modelTypeConfigurationMap_.find(model_type_id);
158  return it == getData().modelTypeConfigurationMap_.end() ? 0 : (*it).second;
159 }
160 
161 //-----------------------------------------------------------------------------
162 // Function : Configuration::findConfiguration
163 // Purpose :
164 // Special Notes :
165 // Scope : public
166 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
167 // Creation Date : Fri Mar 14 13:23:52 2014
168 //-----------------------------------------------------------------------------
169 const Configuration *
171  const std::string & device_name,
172  const int level)
173 {
174  ConfigurationMap::const_iterator it = getData().configurationMap_.find(ConfigurationMap::key_type(device_name, level));
175  return it == getData().configurationMap_.end() ? 0 : (*it).second;
176 }
177 
178 //-----------------------------------------------------------------------------
179 // Function : Configuration::createDevice
180 // Purpose :
181 // Special Notes :
182 // Scope : public
183 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
184 // Creation Date : Fri Mar 14 13:24:07 2014
185 //-----------------------------------------------------------------------------
186 Device *
188  const FactoryBlock & factory_block) const
189 {
190  return factory(factory_block);
191 }
192 
193 //-----------------------------------------------------------------------------
194 // Function : Configuration::getModelType
195 // Purpose :
196 // Special Notes :
197 // Scope : public
198 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
199 // Creation Date : Fri Mar 14 13:24:19 2014
200 //-----------------------------------------------------------------------------
202 Configuration::getModelType(const std::string &model_type_name, const int level)
203 {
204  NameLevelKeyEntityTypeIdMap::const_iterator it = getData().modelTypeNameLevelModelTypeMap_.find(NameLevelKey(model_type_name, level));
205  if (it == getData().modelTypeNameLevelModelTypeMap_.end())
206  return EntityTypeId();
207  else
208  return (*it).second;
209 }
210 
211 //-----------------------------------------------------------------------------
212 // Function : Configuration::getModelGroup
213 // Purpose :
214 // Special Notes :
215 // Scope : public
216 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
217 // Creation Date : Fri Mar 14 13:37:53 2014
218 //-----------------------------------------------------------------------------
220 Configuration::getModelGroup(const std::string &device_name)
221 {
222  NameEntityTypeIdMap::const_iterator it = getData().modelTypeNameModelGroupMap_.find(device_name);
223  if (it == getData().modelTypeNameModelGroupMap_.end())
224  return EntityTypeId();
225  else
226  return (*it).second;
227 }
228 
229 //-----------------------------------------------------------------------------
230 // Function : Configuration::addDevice
231 // Purpose :
232 // Special Notes :
233 // Scope : public
234 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
235 // Creation Date : Fri Mar 14 13:38:03 2014
236 //-----------------------------------------------------------------------------
237 void
239  const char * model_name,
240  const int model_level,
241  ModelTypeId model_type_id,
242  ModelTypeId model_group_id,
243  int model_type_nodes,
244  int model_group_nodes)
245 {
246  if (model_type_id == model_group_id) {
247  std::pair<NameEntityTypeIdMap::iterator, bool> result = getData().modelTypeNameModelGroupMap_.insert(NameEntityTypeIdMap::value_type(model_name, model_type_id));
248  if (!result.second && (*result.first).second != model_type_id)
249  Report::DevelFatal0().in("Configuration::addDevice")
250  << "Attempt to register more than one device model group to the name " << model_name;
251  }
252  else {
253  if (model_type_nodes < model_group_nodes) {
254  // Report::DevelWarning0().in("Configuration::addDevice")
255  // << "Registering " << model_name << " level " << model_level << " with " << model_type_nodes
256  // << " nodes which is less than the model group of " << model_group_nodes
257  // << " nodes, effects model name search which skips the model group value before searching for model name";
258  }
259  }
260 
261  {
262  std::pair<ConfigurationMap::iterator, bool> result
263  = getData().configurationMap_.insert(ConfigurationMap::value_type(NameLevelKey(model_name, model_level), this));
264  if (!result.second)
265  Report::DevelFatal0().in("Configuration::addDevice")
266  << "Device with name " << model_name << " level " << model_level
267  << " already registered as " << (*result.first).second->getName();
268  }
269 
270  {
271  std::pair<EntityTypeIdConfigurationMap::iterator, bool> result
272  = getData().modelTypeConfigurationMap_.insert(EntityTypeIdConfigurationMap::value_type(model_type_id, this));
273  if (!result.second && (*result.first).second != this)
274  Report::DevelFatal().in("Configuration::addDevice")
275  << "Model " << demangle(model_type_id.type().name()) << " already registered to device " << (*result.first).second->getName()
276  << " while trying to register with device " << model_name << " level " << model_level;
277  }
278 }
279 
280 
281 //-----------------------------------------------------------------------------
282 // Function : Configuration::addModel
283 // Purpose :
284 // Special Notes :
285 // Scope : public
286 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
287 // Creation Date : Fri Mar 14 13:38:16 2014
288 //-----------------------------------------------------------------------------
289 void
291  const char * model_name,
292  const int level,
293  ModelTypeId model_type_id,
294  ModelTypeId model_group_id)
295 {
296  if (model_type_id == model_group_id) {
297  std::pair<NameEntityTypeIdMap::iterator, bool> result = getData().modelTypeNameModelGroupMap_.insert(NameEntityTypeIdMap::value_type(model_name, model_type_id));
298  if (!result.second && (*result.first).second != model_type_id)
299  Report::DevelFatal0().in("Configuration::addDevice")
300  << "Attempt to register more than one device model group to the name " << model_name;
301  }
302 
303  std::pair<NameLevelKeyEntityTypeIdMap::iterator, bool> result
304  = getData().modelTypeNameLevelModelTypeMap_.insert(NameLevelKeyEntityTypeIdMap::value_type(NameLevelKey(model_name, level), model_type_id));
305  if (!result.second && (*result.first).second != model_type_id)
306  Report::DevelFatal0() << "Attempt to register more than one model type to the device " << model_name << " level " << level;
307 
308  if (std::find_if(modelTypeNames_.begin(), modelTypeNames_.end(), EqualNoCasePred(model_name)) == modelTypeNames_.end())
309  modelTypeNames_.push_back(model_name);
310 }
311 
312 } // namespace Device
313 } // namespace Xyce
NameLevelKeyEntityTypeIdMap modelTypeNameLevelModelTypeMap_
Model registration: Maps (name, level) -> model_type_id.
NameEntityTypeIdMap modelTypeNameModelGroupMap_
Model registration: Maps model_group_name -> model_group_id.
void addDevice(const char *model_name, const int model_level, ModelTypeId model_type_id, ModelTypeId model_group_id, int model_type_nodes, int model_group_nodes)
Adds the device to the configuration.
Pure virtual class to augment a linear system.
Device * createDevice(const FactoryBlock &factory_block) const
Creates the specified device.
type_index EntityTypeId
Definition: N_DEV_fwd.h:153
virtual Device * factory(const FactoryBlock &factory_block) const =0
Overriding function creates an instance this device.
static const Configuration * findConfiguration(ModelTypeId model_type_id)
Returns the configuration associated with the device name and level or 0 if not found.
EntityTypeIdConfigurationMap modelTypeConfigurationMap_
Device registration: Maps model_type_id -> configuration.
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
static ModelTypeId getModelGroup(const std::string &device_name)
Returns the model group of the device name.
The Device class is an interface for device implementations.
Definition: N_DEV_Device.h:101
std::vector< std::string > modelTypeNames_
Vector of defined model type of this device's model.
type_index ModelTypeId
Definition: N_DEV_fwd.h:154
Class Configuration contains device configuration data.
static const ConfigurationMap & getConfigurationMap()
Returns the configuration map of the system.
unordered_map< NameLevelKey, Configuration * > ConfigurationMap
static ModelTypeId getModelType(const std::string &model_name, const int level)
Returns the model type identifier for the specified device, if the model type and level is not found...
void addModel(const char *model_name, const int level, ModelTypeId model_type_id, ModelTypeId model_group_id)
Adds a model name for the device to the configuration.
ConfigurationMap configurationMap_
Device registration: Maps (name, level) -> configuration.