Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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-2011 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.15.2.2 $
40 //
41 // Revision Date : $Date: 2014/03/14 19:48:40 $
42 //
43 // Current Owner : $Author: dgbaur $
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_ERH_Message.h>
55 #include <N_UTL_Demangle.h>
56 
57 namespace Xyce {
58 namespace Device {
59 
60 namespace {
61 
62 typedef Configuration::ConfigurationMap ConfigurationMap;
63 typedef std::map<EntityTypeId, Configuration *> EntityTypeIdConfigurationMap;
64 typedef std::map<std::string, EntityTypeId, LessNoCase> NameEntityTypeIdMap;
65 typedef std::map<NameLevelKey, EntityTypeId, NameLevelLess> NameLevelKeyEntityTypeIdMap;
66 
67 //-----------------------------------------------------------------------------
68 // Class :
69 // Purpose :
70 // Special Notes :
71 // Scope : public
72 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
73 // Creation Date : Fri Mar 14 13:38:33 2014
74 //-----------------------------------------------------------------------------
75 ///
76 /// Container for the name, model and level forward and backward maps.
77 ///
78 struct Data
79 {
80  ConfigurationMap configurationMap_; ///< Device registration: Maps (name, level) -> configuration
81  EntityTypeIdConfigurationMap modelTypeConfigurationMap_; ///< Device registration: Maps model_type_id -> configuration
82  NameEntityTypeIdMap modelTypeNameModelGroupMap_; ///< Model registration: Maps model_group_name -> model_group_id
83  NameLevelKeyEntityTypeIdMap modelTypeNameLevelModelTypeMap_; ///< Model registration: Maps (name, level) -> model_type_id
84 
85 
86  //-----------------------------------------------------------------------------
87  // Function : ~Data
88  // Purpose :
89  // Special Notes :
90  // Scope : public
91  // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
92  // Creation Date : Fri Mar 14 13:39:41 2014
93  //-----------------------------------------------------------------------------
94  ///
95  /// Free all the created device configurations.
96  ///
97  ~Data()
98  {
99  std::vector<Configuration *> c;
100  for (ConfigurationMap::const_iterator it = configurationMap_.begin(); it != configurationMap_.end(); ++it)
101  c.push_back((*it).second);
102  std::sort(c.begin(), c.end());
103  c.erase(std::unique(c.begin(), c.end()), c.end());
104  for (std::vector<Configuration *>::iterator it = c.begin(); it != c.end(); ++it)
105  delete *it;
106  }
107 };
108 
109 //-----------------------------------------------------------------------------
110 // Function : getData
111 // Purpose :
112 // Special Notes :
113 // Scope : public
114 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
115 // Creation Date : Wed Feb 5 11:49:42 2014
116 //-----------------------------------------------------------------------------
117 /// returns the configuration data singleton.
118 ///
119 /// @return reference to the configuration data singleton.
120 ///
121 Data &getData()
122 {
123  static Data data_;
124 
125  return data_;
126 }
127 
128 } // namespace <unnamed>
129 
130 
131 //-----------------------------------------------------------------------------
132 // Function : Configuration::getConfigurationMap
133 // Purpose :
134 // Special Notes :
135 // Scope : public
136 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
137 // Creation Date : Fri Mar 14 13:23:31 2014
138 //-----------------------------------------------------------------------------
141  return getData().configurationMap_;
142 }
143 
144 //-----------------------------------------------------------------------------
145 // Function : Configuration::findConfiguration
146 // Purpose :
147 // Special Notes :
148 // Scope : public
149 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
150 // Creation Date : Fri Mar 14 13:23:52 2014
151 //-----------------------------------------------------------------------------
152 const Configuration *
153 Configuration::findConfiguration(const std::string &device_name, const int level)
154 {
155  ConfigurationMap::const_iterator it = getData().configurationMap_.find(ConfigurationMap::key_type(device_name, level));
156  return it == getData().configurationMap_.end() ? 0 : (*it).second;
157 }
158 
159 //-----------------------------------------------------------------------------
160 // Function : Configuration::createDevice
161 // Purpose :
162 // Special Notes :
163 // Scope : public
164 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
165 // Creation Date : Fri Mar 14 13:24:07 2014
166 //-----------------------------------------------------------------------------
167 Device *
169  ModelTypeId model_type_id,
170  const FactoryBlock & factory_block)
171 {
172  Device * device = 0;
173 
174  EntityTypeIdConfigurationMap::const_iterator it = getData().modelTypeConfigurationMap_.find(model_type_id);
175  if (it == getData().modelTypeConfigurationMap_.end())
176  throw std::runtime_error("Instance type not found");
177  else {
178  device = (*it).second->factory(factory_block);
179  }
180 
181  return device;
182 }
183 
184 //-----------------------------------------------------------------------------
185 // Function : Configuration::getModelType
186 // Purpose :
187 // Special Notes :
188 // Scope : public
189 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
190 // Creation Date : Fri Mar 14 13:24:19 2014
191 //-----------------------------------------------------------------------------
193 Configuration::getModelType(const std::string &model_type_name, const int level)
194 {
195  NameLevelKeyEntityTypeIdMap::const_iterator it = getData().modelTypeNameLevelModelTypeMap_.find(NameLevelKey(model_type_name, level));
196  if (it == getData().modelTypeNameLevelModelTypeMap_.end())
197  return EntityTypeId();
198  else
199  return (*it).second;
200 }
201 
202 //-----------------------------------------------------------------------------
203 // Function : Configuration::getModelGroup
204 // Purpose :
205 // Special Notes :
206 // Scope : public
207 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
208 // Creation Date : Fri Mar 14 13:37:53 2014
209 //-----------------------------------------------------------------------------
211 Configuration::getModelGroup(const std::string &device_name)
212 {
213  NameEntityTypeIdMap::const_iterator it = getData().modelTypeNameModelGroupMap_.find(device_name);
214  if (it == getData().modelTypeNameModelGroupMap_.end())
215  return EntityTypeId();
216  else
217  return (*it).second;
218 }
219 
220 //-----------------------------------------------------------------------------
221 // Function : Configuration::addDevice
222 // Purpose :
223 // Special Notes :
224 // Scope : public
225 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
226 // Creation Date : Fri Mar 14 13:38:03 2014
227 //-----------------------------------------------------------------------------
228 void
230  const char * model_name,
231  const int model_level,
232  ModelTypeId model_type_id,
233  ModelTypeId model_group_id,
234  int model_type_nodes,
235  int model_group_nodes)
236 {
237  if (model_type_id == model_group_id) {
238  std::pair<NameEntityTypeIdMap::iterator, bool> result = getData().modelTypeNameModelGroupMap_.insert(NameEntityTypeIdMap::value_type(model_name, model_type_id));
239  if (!result.second && (*result.first).second != model_type_id)
240  Report::DevelFatal0().in("Configuration::addDevice")
241  << "Attempt to register more than one device model group to the name " << model_name;
242  }
243  else {
244  if (model_type_nodes < model_group_nodes) {
245  // Report::DevelWarning0().in("Configuration::addDevice")
246  // << "Registering " << model_name << " level " << model_level << " with " << model_type_nodes
247  // << " nodes which is less than the model group of " << model_group_nodes
248  // << " nodes, effects model name search which skips the model group value before searching for model name";
249  }
250  }
251 
252  {
253  std::pair<ConfigurationMap::iterator, bool> result
254  = getData().configurationMap_.insert(ConfigurationMap::value_type(NameLevelKey(model_name, model_level), this));
255  if (!result.second)
256  Report::DevelFatal0().in("Configuration::addDevice")
257  << "Device with name " << model_name << " level " << model_level
258  << " already registered as " << (*result.first).second->getName();
259  }
260 
261  {
262  std::pair<EntityTypeIdConfigurationMap::iterator, bool> result
263  = getData().modelTypeConfigurationMap_.insert(EntityTypeIdConfigurationMap::value_type(model_type_id, this));
264  if (!result.second && (*result.first).second != this)
265  Report::DevelFatal().in("Configuration::addDevice")
266  << "Model " << demangle(model_type_id.type().name()) << " already registered to device " << (*result.first).second->getName()
267  << " while trying to register with device " << model_name << " level " << model_level;
268  }
269 }
270 
271 
272 //-----------------------------------------------------------------------------
273 // Function : Configuration::addModel
274 // Purpose :
275 // Special Notes :
276 // Scope : public
277 // Creator : David G. Baur Raytheon Sandia National Laboratories 1355
278 // Creation Date : Fri Mar 14 13:38:16 2014
279 //-----------------------------------------------------------------------------
280 void
282  const char * model_name,
283  const int level,
284  ModelTypeId model_type_id,
285  ModelTypeId model_group_id)
286 {
287  if (model_type_id == model_group_id) {
288  std::pair<NameEntityTypeIdMap::iterator, bool> result = getData().modelTypeNameModelGroupMap_.insert(NameEntityTypeIdMap::value_type(model_name, model_type_id));
289  if (!result.second && (*result.first).second != model_type_id)
290  Report::DevelFatal0().in("Configuration::addDevice")
291  << "Attempt to register more than one device model group to the name " << model_name;
292  }
293 
294  std::pair<NameLevelKeyEntityTypeIdMap::iterator, bool> result
295  = getData().modelTypeNameLevelModelTypeMap_.insert(NameLevelKeyEntityTypeIdMap::value_type(NameLevelKey(model_name, level), model_type_id));
296  if (!result.second && (*result.first).second != model_type_id)
297  Report::DevelFatal0() << "Attempt to register more than one model type to the device " << model_name << " level " << level;
298 
299  if (std::find_if(modelTypeNames_.begin(), modelTypeNames_.end(), EqualNoCasePred(model_name)) == modelTypeNames_.end())
300  modelTypeNames_.push_back(model_name);
301 }
302 
303 } // namespace Device
304 } // namespace Xyce