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