Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_DEV_DeviceEntity.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-2014 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_DeviceEntity.C,v $
27 //
28 // Purpose :
29 //
30 // Special Notes :
31 //
32 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
33 //
34 // Creation Date : 04/03/00
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision: 1.223.2.3 $
40 //
41 // Revision Date : $Date: 2014/03/12 16:50:27 $
42 //
43 // Current Owner : $Author: dgbaur $
44 //-------------------------------------------------------------------------
45 
46 #include <Xyce_config.h>
47 
48 #include <string>
49 #include <iostream>
50 #include <map>
51 
52 #include <N_DEV_fwd.h>
53 #include <N_DEV_CompositeParam.h>
54 #include <N_DEV_Const.h>
55 #include <N_DEV_DeviceEntity.h>
56 #include <N_DEV_DeviceOptions.h>
57 #include <N_DEV_Message.h>
58 #include <N_DEV_Param.h>
59 #include <N_DEV_SolverState.h>
60 #include <N_UTL_BreakPoint.h>
61 #include <N_UTL_Expression.h>
62 
63 
64 namespace Xyce {
65 namespace Device {
66 
67 //-----------------------------------------------------------------------------
68 // Function : DeviceEntity::DeviceEntity
69 // Purpose : constructor
70 // Special Notes :
71 // Scope : public
72 // Creator : Dave Shirley, PSSI
73 // Creation Date : 12/13/04
74 //-----------------------------------------------------------------------------
76  const char * const entity_type,
77  const std::string & device_name,
78  ParametricData<void> & parametric_data,
79  const SolverState & solver_state,
80  const DeviceOptions & device_options,
81  const std::string & netlist_path,
82  int netlist_line)
83  : entityType_(entity_type),
84  name_(device_name),
85  parametricData_(parametric_data),
86  solState_(solver_state),
87  devOptions_(device_options),
88  defaultParamName_(),
89  netlistLocation_(netlist_path, netlist_line)
90 {}
91 
92 //-----------------------------------------------------------------------------
93 // Function : DeviceEntity::~DeviceEntity
94 // Purpose : destructor
95 // Special Notes :
96 // Scope : public
97 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
98 // Creation Date : 3/30/00
99 //-----------------------------------------------------------------------------
101 {
102  std::vector<Depend>::iterator d = dependentParams.begin();
103  std::vector<Depend>::iterator end = dependentParams.end();
104  for ( ; d != end; ++d)
105  {
106  delete d->expr;
107  }
108 }
109 
110 //-----------------------------------------------------------------------------
111 // Function : DeviceEntity::scaleParam
112 //
113 // Purpose : Scales the original value of the specified parameter by the specified value.
114 // The parameter is never specified by the user so errors are developer caused.
115 //
116 // Special Notes :
117 //
118 // Scope : public
119 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
120 // Creation Date : 02/21/04
121 //-----------------------------------------------------------------------------
122 bool DeviceEntity::scaleParam( const std::string & paramName, double val, double val0)
123 {
124  ParameterMap::const_iterator p_i = getParameterMap().find(paramName);
125  if (p_i == getParameterMap().end())
126  {
127  DevelFatal(*this).in("DeviceEntity::scaleParam") << "Unrecognized parameter " << paramName;
128  return false;
129  }
130 
131  const Descriptor &param = *(*p_i).second;
132  if (!param.hasOriginalValueStored())
133  {
134  DevelFatal(*this).in("DeviceEntity::scaleParam") << "Original value not available for parameter " << paramName;
135  return false;
136  }
137 
138  if (!param.isType<double>())
139  {
140  DevelFatal(*this).in("DeviceEntity::scaleParam") << "Can scale only double parameters, parameter " << paramName << " is not double";
141  return false;
142  }
143 
144  // Scale the parameter
145  setValue<double, DeviceEntity>(*this, param, Xyce::Device::getOriginalValue(*this, param.getSerialNumber())*val + val0*(1.0-val));
146 
147  if (param.hasGivenMember())
148  param.setGiven(*this, true);
149 
150  Xyce::Device::setValueGiven(*this, param.getSerialNumber(), true);
151 
152  return true;
153 }
154 
155 //-----------------------------------------------------------------------------
156 // Function : DeviceEntity::scaleParam
157 //
158 // Purpose : Scales the specified parameter by a specified value.
159 // The parameter is never specified by the user so errors are developer caused.
160 //
161 // Special Notes :
162 //
163 // Scope : public
164 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
165 // Creation Date : 02/21/04
166 //-----------------------------------------------------------------------------
167 bool DeviceEntity::scaleParam( const std::string & paramName, double val)
168 {
169  ParameterMap::const_iterator p_i = getParameterMap().find(paramName);
170  if (p_i == getParameterMap().end())
171  {
172  DevelFatal(*this).in("DeviceEntity::scaleParam") << "Unrecognized parameter " << paramName;
173  return false;
174  }
175 
176  const Descriptor &param = *(*p_i).second;
177  if (!param.hasOriginalValueStored())
178  {
179  DevelFatal(*this).in("DeviceEntity::scaleParam") << "Original value not available for parameter " << paramName;
180  return false;
181  }
182 
183  if (!param.isType<double>())
184  {
185  DevelFatal(*this).in("DeviceEntity::scaleParam") << "Can scale only double parameters, parameter " << paramName << " is not double";
186  return false;
187  }
188 
189  // Scale the parameter
190  param.value<double>(*this) = Xyce::Device::getOriginalValue(*this, param.getSerialNumber())*val;
191 
192  if (param.hasGivenMember())
193  param.setGiven(*this, true);
194 
195  Xyce::Device::setValueGiven(*this, param.getSerialNumber(), true);
196 
197  return true;
198 }
199 
200 //-----------------------------------------------------------------------------
201 // Function : DeviceEntity::scaleDefaultParam
202 // Purpose :
203 // The parameter is never specified by the user so errors are developer caused.
204 // Special Notes :
205 // Scope : public
206 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
207 // Creation Date : 50/19/05
208 //-----------------------------------------------------------------------------
210 {
211  if (defaultParamName_.empty())
212  {
213  DevelFatal(*this).in("DeviceEntity::scaleDefaultParam") << "Device " << getName() << " does not have a default parameter";
214  return false;
215  }
216 
217  return scaleParam(defaultParamName_, val);
218 }
219 
220 //-----------------------------------------------------------------------------
221 // Function : DeviceEntity::setParam
222 //
223 // Purpose : This function loops over the vector of parameters, and
224 // sets the specified one (if found) to a specified value.
225 //
226 // Special Notes : This is kind of tricky, b/c some parameters are actually
227 // deep inside other classes (like a source class, for
228 // example)
229 //
230 // This function always returns a true, b/c there are many
231 // instances, (for example running in parallel), where one
232 // could set a param that didn't exist locally on
233 // processor.
234 //
235 // Scope : public
236 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
237 // Creation Date : 07/25/03
238 //-----------------------------------------------------------------------------
239 bool DeviceEntity::setParam(const std::string & paramName, double val)
240 {
241  ParameterMap::const_iterator p_i = getParameterMap().find(paramName);
242  if (p_i == getParameterMap().end())
243  return false;
244 
245  if (isTempParam(paramName))
246  val += CONSTCtoK;
247 
248  const Descriptor &param = *(*p_i).second;
249 
250  if (param.isType<double>())
251  param.value<double>(*this) = val;
252  else if (param.isType<int>())
253  param.value<int>(*this) = static_cast <int> (val);
254  else if (param.isType<long>())
255  param.value<long>(*this) = static_cast <long> (val);
256  else if (param.isType<bool>())
257  param.value<bool>(*this) = (val != 0);
258  else
259  DevelFatal0(*this) << "Illegal type for parameter " << paramName;
260 
261  if (param.hasGivenMember())
262  param.setGiven(*this, true);
263 
264  Xyce::Device::setValueGiven(*this, param.getSerialNumber(), true);
265 
266  return true;
267 }
268 
269 //-----------------------------------------------------------------------------
270 // Function : DeviceEntity::getParam
271 //
272 // Purpose : returns the value of the requested param.
273 //
274 // Special Notes : This function currently assumes that the requested
275 // param is a double-precision number.
276 //
277 // Parameters are not case-dependent.
278 //
279 // Scope : public
280 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
281 // Creation Date : 07/25/03
282 //-----------------------------------------------------------------------------
283 bool DeviceEntity::getParam ( const std::string & paramName, double & result)
284 {
285  double val = 0.0;
286  bool found = false;
287 
288  ParameterMap::const_iterator p_i = getParameterMap().find(paramName);
289  if (p_i != getParameterMap().end())
290  {
291  found = true;
292  const Descriptor &param = *(*p_i).second;
293  if (param.isType<double>())
294  val = param.value<double>(*this);
295  else if (param.isType<int>())
296  val = static_cast <double> (param.value<int>(*this));
297  else if (param.isType<long>())
298  val = static_cast <double> (param.value<long>(*this));
299  else if (param.isType<bool>())
300  {
301  if (param.value<bool>(*this))
302  val = 1;
303  else
304  val = 0;
305  }
306  else
307  {
308  DevelFatal(*this).in("DeviceEntity::getParam") << "Illegal type for parameter " << paramName;
309  }
310  if (isTempParam(paramName))
311  val -= CONSTCtoK;
312  }
313  else
314  {
315  // If not recognized, just do nothing
316  }
317  result = val;
318 
319  return found;
320 }
321 
322 //-----------------------------------------------------------------------------
323 // Function : DeviceEntity::setDefaultParam
324 // Purpose :
325 // Special Notes :
326 // Scope : public
327 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
328 // Creation Date : 11/06/03
329 //-----------------------------------------------------------------------------
331 {
332  if (defaultParamName_.empty())
333  {
334  DevelFatal(*this).in("DeviceEntity::setDefaultParam") << getName() << " does not have a default parameter";
335  }
336 
337  return setParam(defaultParamName_, val);
338 }
339 
340 //-----------------------------------------------------------------------------
341 // Function : DeviceEntity::getDefaultParam
342 // Purpose :
343 // Special Notes :
344 // Scope : public
345 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
346 // Creation Date : 11/06/03
347 //-----------------------------------------------------------------------------
349 {
350  if (defaultParamName_.empty())
351  {
352  return 0.0;
353  }
354 
355  double result = 0.0;
356 
357  getParam(defaultParamName_, result);
358 
359  return result;
360 }
361 
362 //-----------------------------------------------------------------------------
363 // Function : DeviceEntity::setDependentParameter
364 // Purpose : Add expression, param pairs for future updates
365 // Special Notes : This is an overloaded method, used instead of the old
366 // monolithic one.
367 // Scope : protected
368 // Creator : Tom Russo
369 // Creation Date : 6 Nov 07
370 //-----------------------------------------------------------------------------
371 double DeviceEntity::setDependentParameter (Util::Param & par,
372  double *res,
374 
375 {
376  Depend dependentParam;
377  setDependentParameter(par, dependentParam, depend);
378 
379  dependentParam.resultU.result = res;
380  dependentParam.vectorIndex = -1;
381  dependentParams.push_back(dependentParam);
382 
383  double rval;
384  dependentParam.expr->evaluateFunction (rval);
385  dependentParam.expr->set_sim_time( getSolverState().currTime );
386 
387  return rval;
388 }
389 
390 //-----------------------------------------------------------------------------
391 // Function : DeviceEntity::setDependentParameter
392 // Purpose : Add expression, param pairs for future updates
393 // Special Notes : This is an overloaded method, used instead of the old
394 // monolithic one, and is specifically to set an element
395 // of a double vector.
396 // Scope : protected
397 // Creator : Tom Russo
398 // Creation Date : 6 Nov 07
399 //-----------------------------------------------------------------------------
400 double DeviceEntity::setDependentParameter (Util::Param & par,
401  std::vector<double> *res,
402  int ind,
404 
405 {
406  Depend dependentParam;
407  setDependentParameter(par,dependentParam, depend);
408 
409  dependentParam.resultU.resVec = res;
410  dependentParam.vectorIndex = ind;
411  dependentParams.push_back(dependentParam);
412 
413  double rval;
414  dependentParam.expr->evaluateFunction (rval);
415  dependentParam.expr->set_sim_time( getSolverState().currTime );
416 
417  return rval;
418 }
419 
420 //-----------------------------------------------------------------------------
421 // Function : DeviceEntity::setDependentParameter
422 // Purpose : Add expression, param pairs for future updates
423 // Special Notes : This is a utility version, used by overloaded methods.
424 // Scope : protected
425 // Creator : Dave Shirley, PSSI
426 // Creation Date : 11/18/04
427 //-----------------------------------------------------------------------------
428 
429 void DeviceEntity::setDependentParameter (Util::Param & par,
430  Depend & dependentParam,
432 {
433  std::vector<std::string> instances, leads, names, variables;
434 
435  dependentParam.name = par.tag();
436  if (isTempParam(par.tag()))
437  {
438  dependentParam.expr = new Util::Expression ("(" + par.stringValue() + ")+CONSTCtoK");
439  dependentParam.expr->make_constant (std::string("CONSTCTOK"), CONSTCtoK);
440  }
441  else
442  {
443  dependentParam.expr = new Util::Expression (par.getValue<Util::Expression>());
444  }
445 
446  names.clear();
447  leads.clear();
448  instances.clear();
449  variables.clear();
450 
451  dependentParam.expr->get_names(XEXP_NODE, names);
452  dependentParam.expr->get_names(XEXP_LEAD, leads);
453  dependentParam.expr->get_names(XEXP_INSTANCE, instances);
454  dependentParam.expr->get_names(XEXP_VARIABLE, variables);
455 
456  //std::vector<std::string>::iterator s;
457  std::vector<std::string>::iterator iterS;
458 
459  if (!(depend & ParameterType::SOLN_DEP))
460  {
461  if (names.size() > 0 || instances.size() > 0)
462  {
463  UserError0(*this) << "Parameter " << par.tag() << " is not allowed to depend on voltage/current values";
464  return;
465  }
466  if (depend & ParameterType::NO_DEP)
467  {
468  if (dependentParam.expr->get_num(XEXP_SPECIAL) > 0)
469  {
470  UserError0(*this) << "Parameter " << par.tag() << " is not allowed to depend on time";
471  return;
472  }
473  }
474  }
475 
476  if (leads.size() > 0)
477  {
478  char type;
479  int index;
480  for (std::vector<std::string>::const_iterator n_i=leads.begin(); n_i != leads.end(); ++n_i)
481  {
482  index = n_i->find_last_of(":");
483  if (index == std::string::npos )
484  type = (*n_i)[0];
485  else
486  type = (*n_i)[index+1];
487 
488  if (type != 'B' && type != 'E' && type != 'H')
489  {
490  UserError(*this) << "Illegal use of lead current specification in expression '" << dependentParam.expr->get_expression()
491  << "' in parameter " << par.tag();
492  }
493  }
494  names.insert( names.end(), leads.begin(), leads.end() );
495  }
496 
497  names.insert( names.end(), instances.begin(), instances.end() );
498 
499  dependentParam.lo_var = expVarNames.size();
500  dependentParam.n_vars = names.size();
501  dependentParam.vals.resize(dependentParam.n_vars);
502  int expVarLen = dependentParam.lo_var+dependentParam.n_vars;
503  expVarGIDs.resize(expVarLen);
504  expVarLIDs.resize(expVarLen);
505  expVarVals.resize(expVarLen);
506 
507  if (!variables.empty())
508  names.insert( names.end(), variables.begin(), variables.end() );
509 
510  if ( !names.empty() )
511  {
512  // Order the names in the expression so that it agrees with the order
513  // in names.
514  dependentParam.expr->order_names( names );
515  }
516  for (int i=0 ; i<dependentParam.n_vars ; ++i)
517  expVarNames.push_back(names[i]);
518 
519  if (dependentParam.n_vars > 0)
520  {
521  std::vector<double> zeros;
522  zeros.resize(dependentParam.n_vars);
523  for (int i=0 ; i<dependentParam.n_vars ; ++i)
524  zeros[i] = 0;
525  dependentParam.expr->set_vars(zeros);
526  }
527 
528  dependentParam.global_params.clear();
529  if (!variables.empty())
530  {
531  for (iterS=variables.begin() ; iterS!=variables.end() ; ++iterS)
532  {
533  if (getSolverState().global_params.find(*iterS) == getSolverState().global_params.end())
534  {
535  UserError0(*this) << "Global parameter " << *iterS << " not found";
536  }
537  else {
538  dependentParam.expr->set_var(*iterS, getSolverState().global_params[*iterS]);
539  dependentParam.global_params.push_back(*iterS);
540  }
541  }
542  }
543 }
544 
545 //-----------------------------------------------------------------------------
546 // Function : DeviceEntity::updateDependentParameters
547 // Purpose : Update values of parameters defined as expressions
548 // Special Notes :
549 // Scope : protected
550 // Creator : Dave Shirley, PSSI
551 // Creation Date : 03/15/05
552 //-----------------------------------------------------------------------------
554 {
555  std::vector<Depend>::iterator dpIter = dependentParams.begin();
556  std::vector<Depend>::iterator end = dependentParams.end();
557  double rval(0.0);
558  int i, hi;
559  bool changed = false;
560 
561  for ( ; dpIter != end ; ++dpIter)
562  {
563  if (dpIter->expr->set_sim_time( getSolverState().currTime ))
564  changed = true;
565  eVarVals.resize(dpIter->n_vars);
566  if (dpIter->n_vars > 0)
567  {
568  hi = dpIter->lo_var+dpIter->n_vars;
569  for (i=dpIter->lo_var ; i<hi ; ++i)
570  {
571  expVarVals[i] =vars[expVarLIDs[i]];
572  eVarVals[i-dpIter->lo_var] = expVarVals[i];
573  }
574  if (dpIter->expr->set_vars(eVarVals))
575  changed = true;
576  }
577  dpIter->expr->evaluateFunction (rval);
578  if (dpIter->vectorIndex==-1)
579  *(dpIter->resultU.result) = rval;
580  else
581  (*(dpIter->resultU.resVec))[dpIter->vectorIndex] = rval;
582  }
583 
584  return changed;
585 }
586 
587 //-----------------------------------------------------------------------------
588 // Function : DeviceEntity::updateGlobalParameters
589 // Purpose : Update values of global parameters in expressions
590 // Special Notes :
591 // Scope : protected
592 // Creator : Dave Shirley, PSSI
593 // Creation Date : 11/17/05
594 //-----------------------------------------------------------------------------
595 bool DeviceEntity::updateGlobalParameters(std::map<std::string,double> & global_map)
596 {
597  std::vector<Depend>::iterator dpIter = dependentParams.begin();
598  std::vector<Depend>::iterator end = dependentParams.end();
599  double rval;
600  int i, hi;
601  bool changed = false;
602 
603  for ( ; dpIter != end ; ++dpIter)
604  {
605  if (!dpIter->global_params.empty())
606  {
607  std::vector<std::string>::iterator gp=dpIter->global_params.begin();
608  std::vector<std::string>::iterator gend=dpIter->global_params.end();
609  for ( ; gp != gend; ++gp)
610  {
611  if (global_map.find(*gp) == global_map.end())
612  {
613  DevelFatal(*this).in("DeviceEntity::updateGlobalParameters") << "Failed to find global parameter " << *gp;
614  }
615  if (dpIter->expr->set_var(*gp, global_map[*gp]))
616  changed = true;
617  }
618  }
619  }
620 
621  return changed;
622 }
623 
624 //-----------------------------------------------------------------------------
625 // Function : DeviceEntity::updateDependentParameters
626 // Purpose : Update values of parameters defined as expressions
627 // Special Notes :
628 // Scope : protected
629 // Creator : Dave Shirley, PSSI
630 // Creation Date : 11/18/04
631 //-----------------------------------------------------------------------------
633 {
634  double rval;
635  bool changed = false;
636 
637  std::vector<Depend>::iterator dpIter = dependentParams.begin();
638  std::vector<Depend>::iterator end = dependentParams.end();
639  for ( ; dpIter != end; ++dpIter)
640  {
641  if (dpIter->expr->set_sim_time( getSolverState().currTime ))
642  changed = true;
643  dpIter->expr->evaluateFunction (rval);
644  if (dpIter->vectorIndex == -1)
645  *(dpIter->resultU.result) = rval;
646  else
647  (*(dpIter->resultU.resVec))[dpIter->vectorIndex] = rval;
648  }
649 
650  return changed;
651 }
652 
653 //-----------------------------------------------------------------------------
654 // Function : DeviceEntity::updateDependentParameters
655 // Purpose : Update values of parameters defined as expressions with a
656 // specified temperature
657 // Special Notes :
658 // Scope : protected
659 // Creator : Dave Shirley, PSSI
660 // Creation Date : 01/11/06
661 //-----------------------------------------------------------------------------
663 {
664  double rval;
665  bool changed = false;
666 
667  std::vector<Depend>::iterator dpIter = dependentParams.begin();
668  std::vector<Depend>::iterator end = dependentParams.end();
669  for ( ; dpIter != end; ++dpIter)
670  {
671  if (dpIter->expr->set_sim_time( getSolverState().currTime ) || dpIter->expr->set_temp(tempIn))
672  changed = true;
673  dpIter->expr->evaluateFunction (rval);
674  if (dpIter->vectorIndex == -1)
675  *(dpIter->resultU.result) = rval;
676  else
677  (*(dpIter->resultU.resVec))[dpIter->vectorIndex] = rval;
678 
679  }
680 
681  return changed;
682 }
683 
684 //-----------------------------------------------------------------------------
685 // Function : DeviceEntity::getParamBreakpoints
686 // Purpose : Add breakpoints caused by discontinuities in computed params
687 // Special Notes :
688 // Scope : protected
689 // Creator : Dave Shirley, PSSI
690 // Creation Date : 11/18/04
691 //-----------------------------------------------------------------------------
692 bool DeviceEntity::getParamBreakpoints( std::vector<Util::BreakPoint> & breakPointTimes )
693 {
694  double bTime;
695 
696  std::vector<Depend>::iterator dpIter = dependentParams.begin();
697  std::vector<Depend>::iterator end = dependentParams.end();
698  for ( ; dpIter != end; ++dpIter)
699  {
700  bTime = dpIter->expr->get_break_time();
701  if (bTime > getSolverState().currTime)
702  breakPointTimes.push_back(bTime);
703  }
704 
705  return true;
706 }
707 
708 //-----------------------------------------------------------------------------
709 // Function : DeviceEntity::given
710 // Purpose : Return whether param was given
711 // Special Notes :
712 // Scope : protected
713 // Creator : Dave Shirley, PSSI
714 // Creation Date : 11/23/04
715 //-----------------------------------------------------------------------------
716 bool DeviceEntity::given( const std::string & parameter_name ) const
717 {
718  ParameterMap::const_iterator it = getParameterMap().find(parameter_name);
719  if (it == getParameterMap().end())
720  DevelFatal0(*this).in("DeviceEntity::given") << "Unrecognized parameter " << parameter_name;
721 
722  return Xyce::Device::wasValueGiven(*this, (*it).second->getSerialNumber());
723 }
724 
725 //-----------------------------------------------------------------------------
726 // Function : setParameters
727 // Purpose : Set parameters according to a vector of params. Used to
728 // set instance or model parameter sets to netlist values
729 // Special Notes :
730 // Scope : protected
731 // Creator : Dave Shirley, PSSI
732 // Creation Date : 11/20/04
733 //-----------------------------------------------------------------------------
734 void setParameters(DeviceEntity &entity, std::vector<Param>::const_iterator begin, std::vector<Param>::const_iterator end, const DeviceOptions &device_options)
735 {
736  std::vector<std::string> composite_name_list;
737  std::map<std::string, std::vector<CompositeParam *>, LessNoCase> composite_parameter_map;
738 
739  if (DEBUG_DEVICE && device_options.debugLevel > 0)
740  {
741  Xyce::dout() << std::endl << "In DeviceEntity::setParams, for " << entity.getEntityType()
742  << ": " << entity.getName() << " parameters are:" << std::endl;
743  for (std::vector<Param>::const_iterator it = begin; it != end; ++it)
744  {
745  const Param &param = *it;
746  Xyce::dout() << "Param = " << param.tag() << ", Type = ";
747  int tmpType = param.getType();
748  switch (tmpType)
749  {
750  case Util::STR:
751  Xyce::dout() << "STR";
752  break;
753  case Util::DBLE:
754  Xyce::dout() << "DBLE";
755  break;
756  case Util::INT:
757  Xyce::dout() << "INT";
758  break;
759  case Util::LNG:
760  Xyce::dout() << "LNG";
761  break;
762  case Util::EXPR:
763  Xyce::dout() << "EXPR";
764  break;
765  case Util::BOOL:
766  Xyce::dout() << "BOOL";
767  break;
768  case Util::STR_VEC:
769  Xyce::dout() << "STR_VEC";
770  break;
771  case Util::INT_VEC:
772  Xyce::dout() << "INT_VEC";
773  break;
774  case Util::DBLE_VEC:
775  Xyce::dout() << "DBLE_VEC";
776  break;
777  case Util::DBLE_VEC_IND:
778  Xyce::dout() << "DBLE_VEC_IND";
779  break;
780  case Util::COMPOSITE:
781  Xyce::dout() << "COMPOSITE";
782  break;
783  default:
784  Xyce::dout() << "Unknown";
785  }
786  Xyce::dout() << ", Value = " << param.stringValue();
787 
788  if (param.given())
789  {
790  Xyce::dout() << " given=TRUE";
791  }
792  else
793  {
794  Xyce::dout() << " given=FALSE";
795  }
796 
797  if (param.default_val())
798  {
799  Xyce::dout() << " default=TRUE" << std::endl;
800  }
801  else
802  {
803  Xyce::dout() << " default=FALSE" << std::endl;
804  }
805  }
806  Xyce::dout() << std::endl;
807  }
808 
809  for (std::vector<Param>::const_iterator param_it = begin; param_it != end; ++param_it)
810  {
811  Param &param = const_cast<Param &>(*param_it);
812 
813  const std::string &tag = param.tag();
814 
815  // Is this parameter in the Entity?
816  ParameterMap::const_iterator entity_parameter_it = entity.getParameterMap().find(tag);
817  if (entity_parameter_it != entity.getParameterMap().end())
818  {
819  const Descriptor &descriptor = *(*entity_parameter_it).second;
820  if (descriptor.hasGivenMember())
821  {
822  if (param.given())
823  {
824  descriptor.setGiven(entity, true);
825  }
826  else if (descriptor.getGiven(entity))
827  {
828  continue;
829  }
830  }
831 
832  Xyce::Device::setValueGiven(entity, descriptor.getSerialNumber(), param.given());
833  if (param.given() || param.default_val())
834  {
835  if ( param.getType() == Util::EXPR )
836  {
837  if (descriptor.isType<double>())
838  {
839  double val = entity.setDependentParameter(param, &(descriptor.value<double>(entity)), descriptor.getExpressionAccess());
840  param.setVal(val);
841  }
842  else if (descriptor.isType<std::vector<double> >())
843  {
844  int ind = (descriptor.value<std::vector<double> >(entity)).size();
845  double val = entity.setDependentParameter (param, &(descriptor.value<std::vector<double> >(entity)), ind, descriptor.getExpressionAccess());
846  (descriptor.value<std::vector<double> >(entity)).push_back(val);
847  }
848  else
849  {
850  DevelFatal(entity).in("DeviceEntity::setParams") << "Non double param " << tag << " cannot be set to expression";
851  }
852  }
853  else
854  {
855  if (descriptor.isType<double>())
856  {
857  if (!param.isNumeric())
858  {
859  UserFatal(entity) << "Cannot convert parameter " << tag << " to a numeric value from " << param.stringValue();
860  }
861 
862  descriptor.value<double>(entity) = param.getImmutableValue<double>();
863  if (isTempParam(tag))
864  {
865  descriptor.value<double>(entity) += CONSTCtoK;
866  }
867  if (descriptor.hasOriginalValueStored())
868  {
869  Xyce::Device::setOriginalValue(entity, descriptor.getSerialNumber(), descriptor.value<double>(entity));
870  }
871  }
872  else if (descriptor.isType<std::string>())
873  {
874  descriptor.value<std::string>(entity) = param.stringValue();
875  }
876  else if (descriptor.isType<int>())
877  {
878  if (!param.isInteger())
879  {
880  UserFatal(entity) << "Cannot convert parameter " << tag << " to an integer value from " << param.stringValue();
881  }
882  descriptor.value<int>(entity) = param.getImmutableValue<int>();
883  if (descriptor.hasOriginalValueStored())
884  {
885  Xyce::Device::setOriginalValue(entity, descriptor.getSerialNumber(), static_cast<double> (descriptor.value<int>(entity)));
886  }
887  }
888  else if (descriptor.isType<long>())
889  {
890  if (!param.isInteger())
891  {
892  UserFatal(entity) << "Cannot convert parameter " << tag << " to an integer value from " << param.stringValue();
893  }
894  descriptor.value<long>(entity) = param.getImmutableValue<long>();
895  if (descriptor.hasOriginalValueStored())
896  {
897  Xyce::Device::setOriginalValue(entity, descriptor.getSerialNumber(), static_cast<double> (descriptor.value<long>(entity)));
898  }
899  }
900  else if (descriptor.isType<bool>())
901  {
902  if (!param.isBool())
903  {
904  UserFatal(entity) << "Cannot convert parameter " << tag << " to a logical value from " << param.stringValue();
905  }
906  descriptor.value<bool>(entity) = param.getImmutableValue<bool>();
907  if (descriptor.hasOriginalValueStored())
908  {
909  if (descriptor.value<bool>(entity))
910  {
911  Xyce::Device::setOriginalValue(entity, descriptor.getSerialNumber(), 1.0);
912  }
913  else
914  {
915  Xyce::Device::setOriginalValue(entity, descriptor.getSerialNumber(), 0.0);
916  }
917  }
918  }
919  else if (descriptor.isType<std::vector<int> >())
920  {
921  if (param.getType() == Util::INT_VEC)
922  {
923  (descriptor.value<std::vector<int> >(entity)) = param.getValue<std::vector<int> >();
924  }
925  else if (param.getType() == Util::INT)
926  {
927  (descriptor.value<std::vector<int> >(entity)).push_back(param.getImmutableValue<int>());
928  }
929  }
930  else if (descriptor.isType<std::vector<double> >())
931  {
932  if (param.getType() == Util::DBLE_VEC)
933  {
934  (descriptor.value<std::vector<double> >(entity)) = param.getValue<std::vector<double> >();
935  }
936  else if (param.getType() == Util::DBLE)
937  {
938  (descriptor.value<std::vector<double> >(entity)).push_back(param.getImmutableValue<double>());
939  }
940  }
941  else if (descriptor.isType<std::vector<std::string> >())
942  {
943  if (param.getType() == Util::STR_VEC)
944  {
945  (descriptor.value<std::vector<std::string> >(entity)) = param.getValue<std::vector<std::string> >();
946  }
947  else if (param.getType() == Util::STR)
948  {
949  (descriptor.value<std::vector<std::string> >(entity)).push_back(param.stringValue());
950  }
951  }
952  else if (descriptor.isComposite())
953  {
954  composite_parameter_map[tag].clear();
955  composite_name_list.push_back(tag);
956 
957  // Note: ERK. This push-back is done to process the base-param tag of a vector composite.
958  // For example, if the composite parameters are things like REGION0.XWIDTH, where REGION
959  // is the base parameter tag, 0 is the index, and XWIDTH is the subcomponent, the
960  // tag that should be pushed back is tagES=REGION.
961  //
962  // Note: ERK: This function seems to implicitly rely on the base parameter always preceeding
963  // subcomponent parameters. So REGION (alone) should preceed REGION0.XWIDTH in the
964  // STL vector params that is passed into this function. If it doesn't then vc_stat will
965  // stay false and a fatal error will get thrown.
966  if (DEBUG_DEVICE && device_options.debugLevel > 0)
967  {
968  Xyce::dout() << "pushing back composite " << tag << std::endl;
969  }
970  }
971  else
972  {
973  DevelFatal(entity).in("DeviceEntity::setParams") << "Unknown type";
974  }
975  }
976  }
977  }
978 
979  // Is it a vector (why do nothing?)
980  else if (param.stringValue() == "VECTOR")
981  {
982  }
983 
984  // Must be a composite
985  else
986  {
987  bool vc_stat = false;
988 
989  std::string::size_type dot = tag.find_first_of('.');
990  if (dot != std::string::npos)
991  {
992  for (std::vector<std::string>::const_iterator it = composite_name_list.begin(); it != composite_name_list.end(); ++it)
993  {
994  const std::string &composite_name = *it;
995 
996  if (tag.find(composite_name) == 0) // Tag starts with the composite parameter name
997  {
998  std::string param_name(tag.begin() + dot + 1, tag.end());
999 
1000  vc_stat = true;
1001 
1002  int n = 0;
1003  {
1004  std::istringstream is(std::string(tag.begin() + composite_name.size(), tag.begin() + dot));
1005  is >> n;
1006  }
1007 
1008  if (param_name == "NAME")
1009  {
1010  if (n != composite_parameter_map[composite_name].size())
1011  {
1012  DevelFatal(entity).in("DeviceEntity::setParams") << "Error filling 'NAME' vector param " << composite_name;
1013  }
1014 
1015  std::string name = param.stringValue();
1016  CompositeParam *composite = entity.constructComposite(composite_name, name);
1017  composite_parameter_map[composite_name].push_back(composite);
1018  setDefaultParameters(*composite, composite->getParameterMap().begin(), composite->getParameterMap().end(), device_options);
1019  }
1020  else
1021  {
1022  if (n >= composite_parameter_map[composite_name].size())
1023  {
1024  DevelFatal(entity).in("DeviceEntity::setParams") << "Internal error in vector-composite, 'NAME' must come first " << composite_name;
1025  }
1026  }
1027  Xyce::Device::setParameters(*composite_parameter_map[composite_name][n], param_name, param);
1028  }
1029  }
1030  }
1031  if (!vc_stat)
1032  {
1033  UserError(entity) << "Undefined parameter " << tag << ", this parameter is in metadata, but not recognized in constructor";
1034  }
1035  }
1036  }
1037 
1038  if (!composite_name_list.empty())
1039  {
1040  for (std::vector<std::string>::const_iterator name_it = composite_name_list.begin(); name_it != composite_name_list.end(); ++name_it)
1041  {
1042  const std::string &vcs = *name_it;
1043 
1044  for (std::vector<CompositeParam *>::iterator it = composite_parameter_map[vcs].begin(); it != composite_parameter_map[vcs].end(); ++it)
1045  {
1046  (*it)->processParams();
1047  }
1048  }
1049  }
1050 }
1051 
1052 
1053 //-----------------------------------------------------------------------------
1054 // Function : setParameters
1055 // Purpose : Set parameter according to input Param. Used to
1056 // set instance or model parameter sets to netlist values
1057 // Special Notes :
1058 // Scope : public
1059 // Creator : Dave Shirley, PSSI
1060 // Creation Date : 05/06/05
1061 //-----------------------------------------------------------------------------
1062 
1063 void setParameters(CompositeParam &composite_param, const std::string & pName, const Param & ndParam )
1064 {
1065  ParameterMap::const_iterator p_i = composite_param.getParameterMap().find(pName);
1066  if (p_i != composite_param.getParameterMap().end())
1067  {
1068  const Descriptor &p = *(*p_i).second;
1069  if (p.hasGivenMember())
1070  {
1071  if (ndParam.given())
1072  p.setGiven(composite_param, true);
1073  else if (p.getGiven(composite_param))
1074  return;
1075  }
1076  Xyce::Device::setValueGiven(composite_param, p.getSerialNumber(), ndParam.given());
1077  if (ndParam.given() || ndParam.default_val())
1078  {
1079  if (p.isType<double>())
1080  {
1081  p.value<double>(composite_param) = ndParam.getImmutableValue<double>();
1082  if (isTempParam(pName))
1083  p.value<double>(composite_param) += CONSTCtoK;
1084  if (p.hasOriginalValueStored())
1085  Xyce::Device::setOriginalValue(composite_param, p.getSerialNumber(), p.value<double>(composite_param));
1086  }
1087  else if (p.isType<std::string>())
1088  {
1089  p.value<std::string>(composite_param) = ndParam.stringValue();
1090  }
1091  else if (p.isType<int>())
1092  {
1093  p.value<int>(composite_param) = ndParam.getImmutableValue<int>();
1094  if (p.hasOriginalValueStored())
1095  Xyce::Device::setOriginalValue(composite_param, p.getSerialNumber(), static_cast<double>(p.value<int>(composite_param)));
1096  }
1097  else if (p.isType<long>())
1098  {
1099  p.value<long>(composite_param) = ndParam.getImmutableValue<long>();
1100  if (p.hasOriginalValueStored())
1101  Xyce::Device::setOriginalValue(composite_param, p.getSerialNumber(), static_cast<double>(p.value<long>(composite_param)));
1102  }
1103  else if (p.isType<bool>())
1104  {
1105  p.value<bool>(composite_param) = (ndParam.getImmutableValue<double>() != 0.0);
1106  if (p.hasOriginalValueStored())
1107  {
1108  if (p.value<bool>(composite_param))
1109  Xyce::Device::setOriginalValue(composite_param, p.getSerialNumber(), 1.0);
1110  else
1111  Xyce::Device::setOriginalValue(composite_param, p.getSerialNumber(), 0.0);
1112  }
1113  }
1114  else if (p.isType<std::vector<double> >())
1115  {
1116  (p.value<std::vector<double> >(composite_param)).push_back(ndParam.getImmutableValue<double>());
1117  }
1118  else if (p.isType<std::vector<std::string> >())
1119  {
1120  p.value<std::vector<std::string> >(composite_param).push_back(ndParam.stringValue());
1121  }
1122  else
1123  {
1124  Report::DevelFatal().in("CompositeParam::setParams") << "Unknown parameter type for " << pName;
1125  }
1126  }
1127  }
1128  else
1129  {
1130  Report::DevelFatal().in("CompositeParam::setParams") << "Undefined parameter " << pName << std::endl
1131  << "This parameter is in metadata, but not recognized in constructor";
1132  }
1133 }
1134 
1135 
1136 void populateParams(const ParameterMap &parameter_map, std::vector<Param> &param_list, CompositeParamMap &composite_param_map)
1137 {
1138  for (ParameterMap::const_iterator it = parameter_map.begin(); it != parameter_map.end(); ++it)
1139  {
1140  const Descriptor &param = *(*it).second;
1141 
1142  if (param.isType<double>())
1143  {
1144  if (param.getVec() == 0)
1145  {
1146  double val;
1147  if (isTempParam((*it).first))
1148  val = getDefaultValue<double>(param) - CONSTCtoK;
1149  else
1150  val = getDefaultValue<double>(param);
1151  param_list.push_back(Param((*it).first, val));
1152  }
1153  else if (param.getVec() > 0)
1154  {
1155  if (param.getVec() == 1)
1156  {
1157  // This converts parameters link IC1, IC2 to just IC and type vector
1158  std::string vPar((*it).first.substr(0, (*it).first.size()-1));
1159  param_list.push_back(Param(vPar, "VECTOR"));
1160  }
1161  // We will also output IC1, IC2 as type double so they can
1162  // be specified as individual elements
1163  // This allows TC=a, b to also be specified as TC1=a TC2=b
1164  double val = getDefaultValue<double>(param);
1165  param_list.push_back(Param((*it).first, val));
1166  }
1167  }
1168  else if (param.isType<bool>())
1169  {
1170  if (param.getVec() == 0)
1171  param_list.push_back(Param((*it).first, getDefaultValue<bool>(param)));
1172  else if (param.getVec() > 0)
1173  {
1174  if (param.getVec() == 1)
1175  {
1176  std::string vPar((*it).first.substr(0, (*it).first.size()-1));
1177  param_list.push_back(Param(vPar, "VECTOR"));
1178  }
1179  // We will also output IC1, IC2 as type double so they can
1180  // be specified as individual elements
1181  // This allows TC=a, b to also be specified as TC1=a TC2=b
1182  bool val = getDefaultValue<bool>(param);
1183  param_list.push_back(Param((*it).first, val));
1184  }
1185  }
1186  else if (param.isType<int>())
1187  {
1188  if (param.getVec() == 0)
1189  param_list.push_back(Param((*it).first, getDefaultValue<int>(param)));
1190  else if (param.getVec() > 0)
1191  {
1192  if (param.getVec() == 1)
1193  {
1194  std::string vPar((*it).first.substr(0, (*it).first.size()-1));
1195  param_list.push_back(Param(vPar, "VECTOR"));
1196  }
1197  int val = getDefaultValue<int>(param);
1198  param_list.push_back(Param((*it).first, val));
1199  }
1200  }
1201  else if (param.isType<std::string>())
1202  {
1203  if (param.getVec() == 0)
1204  param_list.push_back(Param((*it).first, getDefaultValue<std::string>(param)));
1205  else if (param.getVec() > 0)
1206  {
1207  if (param.getVec() == 1)
1208  {
1209  std::string vPar((*it).first.substr(0, (*it).first.size()-1));
1210  param_list.push_back(Param(vPar, "VECTOR"));
1211  }
1212  std::string val = getDefaultValue<std::string>(param);
1213  param_list.push_back(Param((*it).first, val));
1214  }
1215  }
1216  else if (param.isType<std::vector<std::string> >())
1217  {
1218  Param vc((*it).first, std::vector<std::string>()); // param.value<std::vector<std::string> >(entity));
1219  param_list.push_back(vc);
1220  }
1221  else if (param.isType<std::vector<double> >())
1222  {
1223  Param vc((*it).first, std::vector<double>()); // param.value<std::vector<double> >(entity));
1224  param_list.push_back(vc);
1225  }
1226  else if (param.isComposite())
1227  {
1228  Param vc2((*it).first, "VECTOR-COMPOSITE");
1229  vc2.setDefault(true);
1230  param_list.push_back(vc2);
1231 
1232  std::vector<Param> compositeParams;
1234 
1235  if (c == 0)
1236  {
1237  Report::DevelFatal().in("populateParams") << "Vector-composite map for device type entity empty.";
1238  }
1239 
1240  // TODO: [DGB] I think when the Descriptor is refactored this will be clearer. But this basically adds the
1241  // type to the composite list with 'NAME' first.
1242  const ParametricData<CompositeParam> &d = *c;
1243  const ParameterMap &e = d.getMap();
1244 
1245  for (ParameterMap::const_iterator it4 = e.find("NAME"); it4 != e.end();) {
1246  const Descriptor &p = *(*it4).second;
1247  if (p.isType<double>())
1248  compositeParams.push_back(Param((*it4).first, getDefaultValue<double>(p)));
1249  else if (p.isType<bool>())
1250  compositeParams.push_back(Param((*it4).first, getDefaultValue<bool>(p)));
1251  else if (p.isType<int>())
1252  compositeParams.push_back(Param((*it4).first, getDefaultValue<int>(p)));
1253  else if (p.isType<std::string>())
1254  compositeParams.push_back(Param((*it4).first, getDefaultValue<std::string>(p)));
1255  if ((*it4).first == "NAME")
1256  it4 = e.begin();
1257  else
1258  it4++;
1259  if (it4 != e.end() && (*it4).first == "NAME")
1260  it4++;
1261  }
1262 
1263  composite_param_map[(*it).first] = compositeParams;
1264  }
1265  else
1266  {
1267 // Just skip these, like list of coupled inductors because not needed for metadata
1268 // std::string msg("DeviceEntity::getParams: Type not supported");
1269 // N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
1270  Xyce::dout() << "In final else clause of DeviceEntity::getParams().";
1271  if( param.isType<std::vector<std::string> >() )
1272  Xyce::dout() << " type is STR_VEC ";
1273  if( param.isType<std::vector<double> >() )
1274  Xyce::dout() << " type is DBLE_VEC ";
1275  Xyce::dout() << it->first << " this item is NOT being added to default parameter list." << std::endl;
1276  }
1277  }
1278 }
1279 
1280 
1281 //-----------------------------------------------------------------------------
1282 // Function : printParameter
1283 //
1284 // Purpose : This function finds a parameter in the par table, and then
1285 // formats its value in a string.
1286 //
1287 // Special Notes :
1288 // Scope : public
1289 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1290 // Creation Date : 5/4/12
1291 //-----------------------------------------------------------------------------
1292 std::ostream &printParameter(std::ostream &os, const DeviceEntity &entity, const std::string &name, const Descriptor &param)
1293 {
1294  if (param.isType<double>())
1295  {
1296  if (isTempParam(name))
1297  {
1298  os << param.value<double>(entity) - CONSTCtoK;
1299  }
1300  else
1301  {
1302  os << param.value<double>(entity);
1303  }
1304  }
1305  else if (param.isType<bool>())
1306  {
1307  os << param.value<bool>(entity);
1308  }
1309  else if (param.isType<int>())
1310  {
1311  os << param.value<int>(entity);
1312  }
1313  else if (param.isType<long>())
1314  {
1315  os << param.value<long>(entity);
1316  }
1317  else if (param.isType<std::string>())
1318  {
1319  os << param.value<std::string>(entity);
1320  }
1321  else if (param.isType<std::vector<std::string> >())
1322  {
1323  os << " (string vector) : ";
1324  os << "length = " << (param.value<std::vector<std::string> >(entity)).size();
1325  if ((param.value<std::vector<std::string> >(entity)).size() > 0)
1326  {
1327  os << " :";
1328  std::vector<std::string>::const_iterator iterStringVec = (param.value<std::vector<std::string> >(entity)).begin();
1329  for ( ; iterStringVec != (param.value<std::vector<std::string> >(entity)).end() ; ++iterStringVec)
1330  {
1331  os << " " << *iterStringVec;
1332  }
1333  }
1334  }
1335  else if (param.isType<std::vector<int> >())
1336  {
1337  os << " (int vector) : ";
1338  os << "length = " << (param.value<std::vector<int> >(entity)).size();
1339  if ((param.value<std::vector<int> >(entity)).size() > 0)
1340  {
1341  os << " :";
1342  std::vector<int>::const_iterator v_i = (param.value<std::vector<int> >(entity)).begin();
1343  for ( ; v_i != (param.value<std::vector<int> >(entity)).end() ; ++v_i)
1344  {
1345  os << " " << *v_i;
1346  }
1347  }
1348  }
1349  else if (param.isType<std::vector<double> >())
1350  {
1351  os << " (double vector) : ";
1352  os << "length = " << (param.value<std::vector<double> >(entity)).size();
1353  if ((param.value<std::vector<double> >(entity)).size() > 0)
1354  {
1355  os << " :";
1356  std::vector<double>::const_iterator iterDoubleVec = (param.value<std::vector<double> >(entity)).begin();
1357  for ( ; iterDoubleVec != (param.value<std::vector<double> >(entity)).end() ; ++iterDoubleVec)
1358  {
1359  os << " " << *iterDoubleVec;
1360  }
1361  }
1362  }
1363  else if (param.isComposite())
1364  {
1365  os << " (composite) : " << (param.value<CompositeMap>(entity)).size();
1366  if ((param.value<CompositeMap>(entity)).size() > 0)
1367  {
1368  std::map<std::string, CompositeParam *>::const_iterator c_i = (param.value<CompositeMap>(entity)).begin();
1369  // (*c_i).second->printParams(os);
1370  printCompositeParameters(os, *(*c_i).second);
1371  }
1372  }
1373 
1374  return os;
1375 }
1376 
1377 std::ostream &printCompositeParameters(std::ostream &os, const CompositeParam &composite)
1378 {
1379  for (ParameterMap::const_iterator it_parameter = composite.getParameterMap().find("NAME"); it_parameter != composite.getParameterMap().end() ; )
1380  {
1381  os << std::endl << " " <<(*it_parameter).first << " ";
1382  const Descriptor &p = *(*it_parameter).second;
1383  if (p.isType<double>())
1384  os << "(double) : " << p.value<double>(composite);
1385  else if (p.isType<bool>())
1386  os << "(bool) : " << p.value<bool>(composite);
1387  else if (p.isType<int>())
1388  os << "(int) : " << p.value<int>(composite);
1389  else if (p.isType<long>())
1390  os << "(long) : " << p.value<long>(composite);
1391  else if (p.isType<std::string>())
1392  os << "(string) : " << p.value<std::string>(composite);
1393  else if (p.isType<std::vector<std::string> >())
1394  {
1395  const std::vector<std::string> &string_vector = p.value<std::vector<std::string> >(composite);
1396 
1397  for (std::vector<std::string>::const_iterator it = string_vector.begin(); it != string_vector.end(); ++it)
1398  os << " " << *it;
1399  }
1400  else if (p.isType<std::vector<double> >())
1401  {
1402  const std::vector<double> &string_vector = p.value<std::vector<double> >(composite);
1403 
1404  for (std::vector<double>::const_iterator it = string_vector.begin(); it != string_vector.end(); ++it)
1405  os << " " << *it;
1406  }
1407 
1408  if ((*it_parameter).first == "NAME")
1409  it_parameter = composite.getParameterMap().begin();
1410  else
1411  it_parameter++;
1412 
1413  if (it_parameter != composite.getParameterMap().end() && (*it_parameter).first == "NAME")
1414  it_parameter++;
1415  }
1416 
1417  return os;
1418 }
1419 
1420 // //-----------------------------------------------------------------------------
1421 // // Function : DeviceEntity::perturbSensParam
1422 // // Purpose :
1423 // // Special Notes :
1424 // // Scope : public
1425 // // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1426 // // Creation Date : 05/02/03
1427 // //-----------------------------------------------------------------------------
1428 // bool DeviceEntity::perturbSensParam (Param & ndParam)
1429 // {
1430 // if ( !ndParam.isTimeDependent() )
1431 // {
1432 // double paramOld = ndParam.dVal();
1433 // getDeviceOptions().deviceSens_dp = getDeviceOptions().testJac_SqrtEta * (1.0 + fabs(ndParam.dVal()));
1434 // double paramNew = paramOld + getDeviceOptions().deviceSens_dp;
1435 
1436 // ndParam.setVal (paramNew);
1437 // }
1438 // else
1439 // {
1440 // UserWarning0(*this) << "Time dependent parameter (" << ndParam.uTag()
1441 // << ") not allowed as a sensitivity parameter, continuing analysis without perturubing this parameter.";
1442 // }
1443 
1444 // if (Xyce::DEBUG_DEVICE && getDeviceOptions().debugLevel > 0)
1445 // {
1446 // Xyce::dout() << "DeviceEntity::perturbSensParams" << std::endl
1447 // << "paramNew = " << paramNew <<std::endl
1448 // << "paramOld = " << paramOld <<std::endl
1449 // << "dp = " << getDeviceOptions().deviceSens_dp << std::endl;
1450 // }
1451 
1452 // return true;
1453 // }
1454 
1455 } // namespace Device
1456 } // namespace Xyce