Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_DEV_LaTexDoc.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_LaTexDoc.C,v $
27 //
28 // Purpose :
29 //
30 // Special Notes :
31 //
32 // Creator : David Baur
33 //
34 // Creation Date : 3/20/2013
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision: 1.2 $
40 //
41 // Revision Date : $Date: 2014/03/19 17:23:28 $
42 //
43 // Current Owner : $Author: tvrusso $
44 //-------------------------------------------------------------------------
45 
46 // All Xyce source files must include this!
47 #include <Xyce_config.h>
48 
49 #include <string>
50 #include <map>
51 #include <vector>
52 
53 // need this on Losedows for "std::tolower"
54 #ifdef HAVE_CCTYPE
55 #include <cctype>
56 #endif
57 
58 #include <N_DEV_LaTexDoc.h>
59 
60 #include <N_DEV_fwd.h>
61 #include <N_DEV_Units.h>
62 #include <N_DEV_Const.h>
63 #include <N_DEV_DeviceEntity.h>
64 #include <N_DEV_DeviceModel.h>
65 #include <N_DEV_DeviceInstance.h>
66 #include <N_DEV_DeviceOptions.h>
67 #include <N_DEV_SolverState.h>
68 #include <N_UTL_Misc.h>
69 #include <N_UTL_IndentStreamBuf.h>
70 #include <N_ERH_Message.h>
71 
72 namespace Xyce {
73 namespace Device {
74 
75 namespace {
76 
77 //-----------------------------------------------------------------------------
78 // Function : DeviceEntity::escape
79 // Purpose : Add escape backslash before underscore for LaTeX
80 // Special Notes :
81 // Scope : private
82 // Creator : Dave Shirley, PSSI
83 // Creation Date : 05/16/06
84 //-----------------------------------------------------------------------------
85 struct laTexProtect {
86  laTexProtect(const std::string &t)
87  : text(t)
88  {}
89 
90  const std::string &text;
91 };
92 
93 
94 std::ostream &operator<<(std::ostream &os, const laTexProtect &laTex_protect)
95 {
96  for (std::string::const_iterator cit = laTex_protect.text.begin(); cit != laTex_protect.text.end(); ++cit) {
97  if ((*cit) == '_')
98  os << "\\_\\-";
99  else
100  os << (*cit);
101  }
102 
103  return os;
104 }
105 
106 
107 struct laTexClean {
108  laTexClean(const std::string &t)
109  : text(t)
110  {}
111 
112  const std::string &text;
113 };
114 
115 
116 std::ostream &operator<<(std::ostream &os, const laTexClean &laTex_clean)
117 {
118  for (std::string::const_iterator cit = laTex_clean.text.begin(); cit != laTex_clean.text.end(); ++cit) {
119  if ((*cit) != '_')
120  os << (*cit);
121  }
122 
123  return os;
124 }
125 
126 
127 const std::string &categoryName(int category) {
128  static std::vector<std::string> s_categoryList;
129 
130  if (s_categoryList.empty()) {
131  s_categoryList.resize(CAT_MAX);
132  s_categoryList[CAT_NONE] = "";
133  s_categoryList[CAT_AC] = "AC Parameters";
134  s_categoryList[CAT_BASIC] = "Basic Parameters";
135  s_categoryList[CAT_BIN] = "Bin Parameters";
136  s_categoryList[CAT_CAP] = "Capacitance Parameters";
137  s_categoryList[CAT_CONTROL] = "Control Parameters";
138  s_categoryList[CAT_CURRENT] = "Current Parameters";
139  s_categoryList[CAT_DC] = "DC Parameters";
140  s_categoryList[CAT_DEPENDENCY] = "Dependency Parameters";
141  s_categoryList[CAT_DOPING] = "Doping Parameters";
142  s_categoryList[CAT_FLICKER] = "Flicker Parameters";
143  s_categoryList[CAT_GEOMETRY] = "Geometry Parameters";
144  s_categoryList[CAT_INITIAL] = "Initial Condition Parameters";
145  s_categoryList[CAT_MATERIAL] = "Material Parameters";
146  s_categoryList[CAT_NQS] = "NQS Parameters";
147  s_categoryList[CAT_RADP] = "Radiation Pulse Parameters";
148  s_categoryList[CAT_RES] = "Resistance Parameters";
149  s_categoryList[CAT_PROCESS] = "Process Parameters";
150  s_categoryList[CAT_RF] = "RF Parameters";
151  s_categoryList[CAT_RAD] = "Radiation Parameters";
152  s_categoryList[CAT_TEMP] = "Temperature Parameters";
153  s_categoryList[CAT_TUNNEL] = "Tunnelling Parameters";
154  s_categoryList[CAT_VBI] = "Built-in Potential Lowering Parameters";
155  s_categoryList[CAT_VOLT] = "Voltage Parameters";
156  s_categoryList[CAT_ASYMRDS] = "Asymmetric and Bias-Dependent $R_{ds}$ Parameters";
157  s_categoryList[CAT_IMPACT] = "Impact Ionization Current Parameters";
158  s_categoryList[CAT_GDLEAKAGE] = "Gate-induced Drain Leakage Model Parameters";
159  }
160 
161  return s_categoryList.size() ? s_categoryList[category] : s_categoryList[CAT_UNKNOWN];
162 }
163 
164 void unitDescription(
165  const std::string & name,
166  const ParameterMap & parameter_map,
167  const Descriptor & descriptor,
168  ParameterUnit & unit,
169  ParameterCategory & category,
170  std::string & description)
171 {
172  unit = descriptor.getUnit();
173  if (unit == STANDARD)
174  {
176  if (name == (*it).Name)
177  {
178  description = (*it).Description;
179  category = (*it).Category;
180  unit = (*it).Unit;
181  break;
182  }
183  }
184 
185  if (description.empty())
186  {
187  Report::UserWarning0() << "No description given for " << name << ". Setting category and unit as UNKNOWN.";
188 
189  description = "Unspecified";
190  category = CAT_UNKNOWN;
191  unit = U_UNKNOWN;
192  }
193  }
194  else
195  {
196  category = descriptor.getCategory();
197  if (category == CAT_DEPENDENCY)
198  {
199  int num;
200  std::string base_name = name.substr(1);
201  if (name[0] == 'L')
202  {
203  description = "Length";
204  num = 1;
205  }
206  else if (name[0] == 'W')
207  {
208  description = "Width";
209  num = 1;
210  }
211  else if (name[0] == 'P')
212  {
213  description = "Cross-term";
214  num = 2;
215  }
216  description += " dependence of ";
217  description += base_name;
218 
219  ParameterMap::const_iterator it = parameter_map.find(base_name);
220  if (it == parameter_map.end())
221  {
222  Report::DevelFatal().in("DeviceEntity::getUnitDescription")
223  << "Base parameter not found for " << name << " in " << base_name;
224  }
225 
226  else {
227  const Descriptor &base_descriptor = *(*it).second;
228 
229  std::string base_description;
230  ParameterUnit base_unit = U_INVALID;
231  ParameterCategory base_category = CAT_UNKNOWN;
232 
233  unitDescription(base_name, parameter_map, base_descriptor, base_unit, base_category, base_description);
234  if (base_unit != U_INVALID && base_unit != U_UNKNOWN)
235  {
236  for (int i = 0; i < num; ++i)
237  {
238  for (const UnitInfo *it = Units::unitTable; it != Units::unitTable + Units::unitTableSize; ++it)
239  {
240  if ((*it).Unit == base_unit)
241  {
242  unit = (*it).UnitM;
243  if (unit == U_INVALID)
244  {
245  Report::UserWarning0() << "Need unit for " << (*it).description << " times m";
246  }
247  break;
248  }
249  }
250  }
251  }
252  }
253  }
254  else
255  {
256  description = descriptor.getDescription();
257  }
258  }
259 }
260 
261 const UnitInfo &findUnit(const int unit)
262 {
263  for (const UnitInfo *it = Units::unitTable; it != Units::unitTable + Units::unitTableSize; ++it)
264  if ((*it).Unit == unit)
265  return *it;
266  return *(Units::unitTable);
267 }
268 
269 std::ostream &documentParameter(std::ostream &os, const std::string &name, const int parameter_unit, const std::string &description, const Descriptor &descriptor)
270 {
271  os << laTexProtect(name) << " & " << laTexProtect(description) << " & ";
272 
273  const UnitInfo &unit_info = findUnit(parameter_unit);
274  os << unit_info.doc;
275  os << " & ";
276 
277  if ((descriptor.isType<double>() && name == "TNOM") || name == "TEMP")
278  {
279  double default_value = getDefaultValue<double>(descriptor);
280  // os << default_value - CONSTCtoK;
281  // os << CONSTREFTEMP - CONSTCtoK;
282  if (default_value == 0.0)
283  {
284  os << "Ambient Temperature";
285  }
286  else if (default_value - CONSTCtoK < 0.0)
287  {
288  os << default_value;
289  }
290  else
291  {
292  os << default_value - CONSTCtoK;
293  }
294  }
295  else
296  {
297  descriptor.getEntry().print(os);
298  }
299 
300  os << " \\\\ \\hline" << std::endl;
301 
302  return os;
303 }
304 
305 } // namespace <unnamed>
306 
307 
308 std::ostream &laTexDevice(std::ostream &os, const std::string &device_name, const int device_level, const int type, const std::string &device_description, const ParametricData<void> &parameters, OutputMode::Mode format)
309 {
310  // Place caption on table and add index entry
311  std::string device_description_lc = device_description;
312  std::transform(device_description_lc.begin(), device_description_lc.end(), device_description_lc.begin(), (int (*)(int)) std::tolower);
313 
314  os << "\\index{" << laTexClean(device_description_lc) << "!" << (type ? "device model parameters" : "device instance parameters") << "}" << std::endl
315  << "\\begin{DeviceParamTableGenerated}{" << laTexProtect(device_description) << " " << (type ? "Device Model Parameters" : "Device Instance Parameters") << "}"
316  << "{" << device_name << "_" << device_level << (type ? "_Device_Model_Params" : "_Device_Instance_Params") << "}" << std::endl;
317 
318  // If catagorical listing, group by category
319  if (format == OutputMode::DOC_CAT) {
320  const ParameterMap &parameter_map = parameters.getMap();
321  for (int category = CAT_NONE; category != CAT_MAX; ++category) {
322  const std::string &header = categoryName(category);
323  bool header_printed = false;
324 
325  for (ParameterMap::const_iterator it = parameter_map.begin(); it != parameter_map.end(); ++it) {
326  std::string parameter_name = (*it).first;
327  const Descriptor &descriptor = *(*it).second;
328 
329  if ((descriptor.getExpressionAccess() & ParameterType::NO_DOC) == 0) {
330  std::string parameter_description;
331  ParameterUnit parameter_unit = U_INVALID;
332  ParameterCategory parameter_category = CAT_UNKNOWN;
333  unitDescription((*it).first, parameter_map, descriptor, parameter_unit, parameter_category, parameter_description);
334 
335  if (parameter_category == category) {
336  if (!header.empty() && !header_printed) {
337  header_printed = true;
338 
339  os << std::endl
340  << "\\category{" << header << "}" << "\\\\ \\hline" << std::endl;
341  }
342  documentParameter(os, parameter_name, parameter_unit, parameter_description, descriptor);
343  }
344  }
345  }
346  }
347  }
348  else {
349  const ParameterMap &parameter_map = parameters.getMap();
350  for (ParameterMap::const_iterator it = parameter_map.begin(); it != parameter_map.end(); ++it) {
351  std::string parameter_name = (*it).first;
352  const Descriptor &descriptor = *(*it).second;
353 
354  if ((descriptor.getExpressionAccess() & ParameterType::NO_DOC) == 0) {
355 
356  std::string parameter_description;
357  ParameterUnit parameter_unit = U_INVALID;
358  ParameterCategory parameter_category = CAT_UNKNOWN;
359  unitDescription((*it).first, parameter_map, descriptor, parameter_unit, parameter_category, parameter_description);
360 
361  documentParameter(os, parameter_name, parameter_unit, parameter_description, descriptor);
362  }
363  }
364  }
365 
366  os << "\\end{DeviceParamTableGenerated}" << std::endl;
367 
368  return os;
369 }
370 
371 } // namespace Device
372 } // namespace Xyce