Xyce  6.1
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-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_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.11 $
40 //
41 // Revision Date : $Date: 2015/04/27 19:45:12 $
42 //
43 // Current Owner : $Author: dgbaur $
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_IndentStreamBuf.h>
69 #include <N_ERH_Message.h>
70 
71 namespace Xyce {
72 namespace Device {
73 
74 namespace {
75 
76 typedef std::map<std::string, Descriptor *, LessNoCase> OrderedParameterMap;
77 
78 std::ostream &laTexComposite(std::ostream &os, const std::string &composite_name, const std::string &composite_description, const ParametricData<void> &parameters);
79 
80 //-----------------------------------------------------------------------------
81 // Function : DeviceEntity::escape
82 // Purpose : Add escape backslash before underscore for LaTeX
83 // Special Notes :
84 // Scope : private
85 // Creator : Dave Shirley, PSSI
86 // Creation Date : 05/16/06
87 //-----------------------------------------------------------------------------
88 struct laTexProtect {
89  laTexProtect(const std::string &t)
90  : text(t)
91  {}
92 
93  const std::string &text;
94 };
95 
96 
97 std::ostream &operator<<(std::ostream &os, const laTexProtect &laTex_protect)
98 {
99  for (std::string::const_iterator cit = laTex_protect.text.begin(); cit != laTex_protect.text.end(); ++cit) {
100  if ((*cit) == '_')
101  os << "\\_\\-";
102  else
103  os << (*cit);
104  }
105 
106  return os;
107 }
108 
109 
110 struct laTexClean {
111  laTexClean(const std::string &t)
112  : text(t)
113  {}
114 
115  const std::string &text;
116 };
117 
118 
119 std::ostream &operator<<(std::ostream &os, const laTexClean &laTex_clean)
120 {
121  for (std::string::const_iterator cit = laTex_clean.text.begin(); cit != laTex_clean.text.end(); ++cit) {
122  if ((*cit) != '_')
123  os << (*cit);
124  }
125 
126  return os;
127 }
128 
129 
130 const std::string &categoryName(int category) {
131  static std::vector<std::string> s_categoryList;
132 
133  if (s_categoryList.empty()) {
134  s_categoryList.resize(CAT_MAX);
135  s_categoryList[CAT_NONE] = "";
136  s_categoryList[CAT_AC] = "AC Parameters";
137  s_categoryList[CAT_BASIC] = "Basic Parameters";
138  s_categoryList[CAT_BIN] = "Bin Parameters";
139  s_categoryList[CAT_CAP] = "Capacitance Parameters";
140  s_categoryList[CAT_CONTROL] = "Control Parameters";
141  s_categoryList[CAT_CURRENT] = "Current Parameters";
142  s_categoryList[CAT_DC] = "DC Parameters";
143  s_categoryList[CAT_DEPENDENCY] = "Dependency Parameters";
144  s_categoryList[CAT_DOPING] = "Doping Parameters";
145  s_categoryList[CAT_FLICKER] = "Flicker and Thermal Noise Parameters";
146  s_categoryList[CAT_GEOMETRY] = "Geometry Parameters";
147  s_categoryList[CAT_INITIAL] = "Initial Condition Parameters";
148  s_categoryList[CAT_MATERIAL] = "Material Parameters";
149  s_categoryList[CAT_NQS] = "NQS Parameters";
150  s_categoryList[CAT_RADP] = "Radiation Pulse Parameters";
151  s_categoryList[CAT_RES] = "Resistance Parameters";
152  s_categoryList[CAT_PROCESS] = "Process Parameters";
153  s_categoryList[CAT_RF] = "RF Parameters";
154  s_categoryList[CAT_RAD] = "Radiation Parameters";
155  s_categoryList[CAT_TEMP] = "Temperature Parameters";
156  s_categoryList[CAT_TUNNEL] = "Tunnelling Parameters";
157  s_categoryList[CAT_VBI] = "Built-in Potential Lowering Parameters";
158  s_categoryList[CAT_VOLT] = "Voltage Parameters";
159  s_categoryList[CAT_ASYMRDS] = "Asymmetric and Bias-Dependent $R_{ds}$ Parameters";
160  s_categoryList[CAT_ASYMDDS] = "Asymmetric Source/Drain Junction Diode Parameters";
161  s_categoryList[CAT_IMPACT] = "Impact Ionization Current Parameters";
162  s_categoryList[CAT_GDLEAKAGE] = "Gate-induced Drain Leakage Model Parameters";
163  s_categoryList[CAT_STRESS] = "Stress Effect Model Parameters";
164  s_categoryList[CAT_WELL] = "Well-Proximity Effect Model Parameters";
165 
166  s_categoryList[CAT_STATIC] = "Static Model Parameters";
167  s_categoryList[CAT_DYNAMIC] = "Dynamic Model Parameters";
168  s_categoryList[CAT_CARRIER] = "Carrier Model Parameters";
169  s_categoryList[CAT_OUTPUT] = "Model Output Parameters";
170  s_categoryList[CAT_PULSE] = "Pulse Parameters";
171 
172  s_categoryList[CAT_SCALING] = "Scaling Parameters";
173  s_categoryList[CAT_BOUNDARYCONDITIONS] = "Boundary Condition Parameters";
174  }
175 
176  return s_categoryList.size() ? s_categoryList[category] : s_categoryList[CAT_UNKNOWN];
177 }
178 
179 void unitDescription(
180  const std::string & name,
181  const OrderedParameterMap & parameter_map,
182  const Descriptor & descriptor,
183  ParameterUnit & unit,
184  ParameterCategory & category,
185  std::string & description)
186 {
187  unit = descriptor.getUnit();
188  if (unit == STANDARD)
189  {
191  if (name == (*it).Name)
192  {
193  description = (*it).Description;
194  category = (*it).Category;
195  unit = (*it).Unit;
196  break;
197  }
198  }
199 
200  if (description.empty())
201  {
202  Report::UserWarning0() << "No description given for " << name << ". Setting category and unit as UNKNOWN.";
203 
204  description = "Unspecified";
205  category = CAT_UNKNOWN;
206  unit = U_UNKNOWN;
207  }
208  }
209  else
210  {
211  category = descriptor.getCategory();
212  if (category == CAT_DEPENDENCY)
213  {
214  int num;
215  std::string base_name = name.substr(1);
216  if (name[0] == 'L')
217  {
218  description = "Length";
219  num = 1;
220  }
221  else if (name[0] == 'W')
222  {
223  description = "Width";
224  num = 1;
225  }
226  else if (name[0] == 'P')
227  {
228  description = "Cross-term";
229  num = 2;
230  }
231  description += " dependence of ";
232  description += base_name;
233 
234  OrderedParameterMap::const_iterator it = parameter_map.find(base_name);
235  if (it == parameter_map.end())
236  {
237  Report::DevelFatal().in("DeviceEntity::getUnitDescription")
238  << "Base parameter not found for " << name << " in " << base_name;
239  }
240 
241  else {
242  const Descriptor &base_descriptor = *(*it).second;
243 
244  std::string base_description;
245  ParameterUnit base_unit = U_INVALID;
246  ParameterCategory base_category = CAT_UNKNOWN;
247 
248  unitDescription(base_name, parameter_map, base_descriptor, base_unit, base_category, base_description);
249  if (base_unit != U_INVALID && base_unit != U_UNKNOWN)
250  {
251  for (int i = 0; i < num; ++i)
252  {
253  for (const UnitInfo *it = Units::unitTable; it != Units::unitTable + Units::unitTableSize; ++it)
254  {
255  if ((*it).Unit == base_unit)
256  {
257  unit = (*it).UnitM;
258  if (unit == U_INVALID)
259  {
260  Report::UserWarning0() << "Need unit for " << (*it).description << " times m";
261  }
262  break;
263  }
264  }
265  }
266  }
267  }
268  }
269  else
270  {
271  description = descriptor.getDescription();
272  }
273  }
274 }
275 
276 const UnitInfo &findUnit(const int unit)
277 {
278  for (const UnitInfo *it = Units::unitTable; it != Units::unitTable + Units::unitTableSize; ++it)
279  if ((*it).Unit == unit)
280  return *it;
281  return *(Units::unitTable);
282 }
283 
284 std::ostream &documentParameter(std::ostream &os, const std::string &name, const int parameter_unit, const std::string &description, const Descriptor &descriptor)
285 {
286  if (descriptor.getCompositeParametricData<void>()) {
287  os << laTexProtect(name) << " & " << laTexProtect(description) << " & ";
288 
289  const UnitInfo &unit_info = findUnit(parameter_unit);
290  os << "\\multicolumn{2}{c}{See Table~\\ref{" << name << "_Composite_Params}} ";
291  }
292  else {
293  os << laTexProtect(name) << " & " << laTexProtect(description) << " & ";
294 
295  const UnitInfo &unit_info = findUnit(parameter_unit);
296  os << unit_info.doc;
297  os << " & ";
298 
299  if ((descriptor.isType<double>() && name == "TNOM") || name == "TEMP")
300  {
301  double default_value = getDefaultValue<double>(descriptor);
302  // os << default_value - CONSTCtoK;
303  // os << CONSTREFTEMP - CONSTCtoK;
304  if (default_value == 0.0)
305  {
306  os << "Ambient Temperature";
307  }
308  else if (default_value - CONSTCtoK < 0.0)
309  {
310  os << default_value;
311  }
312  else
313  {
314  os << default_value - CONSTCtoK;
315  }
316  }
317  else
318  {
319  descriptor.getEntry().print(os);
320  }
321  }
322 
323  if (descriptor.getCompositeParametricData<void>()) {
324  const ParametricData<void> &composite_parametric_data = *descriptor.getCompositeParametricData<void>();
325  const OrderedParameterMap composite_parametric_map(composite_parametric_data.getMap().begin(), composite_parametric_data.getMap().end());
326 
327  std::ostringstream path;
328  path << name << "_Composite_Params.tex";
329 
330  std::ofstream os(path.str().c_str(), std::ios_base::out);
331 
332  os << "% This table was generated by Xyce" << std::endl;
333 
334  laTexComposite(os, name, name, composite_parametric_data);
335  }
336 
337  os << " \\\\ \\hline" << std::endl;
338 
339  return os;
340 }
341 
342 std::ostream &
343 laTexComposite(
344  std::ostream & os,
345  const std::string & composite_name,
346  const std::string & composite_description,
347  const ParametricData<void> & parameters)
348 {
349  // Place caption on table and add index entry
350  std::string composite_description_lc = composite_description;
351  std::transform(composite_description_lc.begin(), composite_description_lc.end(), composite_description_lc.begin(), (int (*)(int)) std::tolower);
352 
353  os << "\\index{" << laTexClean(composite_description_lc) << "!" << "composite parameters}" << std::endl
354  << "\\begin{CompositeParamTableGenerated}{" << laTexProtect(composite_description) << " " << "Composite Parameters}"
355  << "{" << composite_name << "_Composite_Params}" << std::endl;
356 
357  const OrderedParameterMap parameter_map(parameters.getMap().begin(), parameters.getMap().end());
358  for (OrderedParameterMap::const_iterator it = parameter_map.begin(); it != parameter_map.end(); ++it) {
359  std::string parameter_name = (*it).first;
360  const Descriptor &descriptor = *(*it).second;
361 
362  if ((descriptor.getExpressionAccess() & ParameterType::NO_DOC) == 0) {
363  std::string parameter_description;
364  ParameterUnit parameter_unit = U_INVALID;
365  ParameterCategory parameter_category = CAT_UNKNOWN;
366  unitDescription((*it).first, parameter_map, descriptor, parameter_unit, parameter_category, parameter_description);
367 
368  documentParameter(os, parameter_name, parameter_unit, parameter_description, descriptor);
369  }
370  }
371 
372  os << "\\end{CompositeParamTableGenerated}" << std::endl;
373 
374  return os;
375 }
376 
377 } // namespace <unnamed>
378 
379 std::ostream &
381  std::ostream & os,
382  const std::string & device_name,
383  const int device_level,
384  const int type,
385  const std::string & device_description,
386  const ParametricData<void> & parameters,
387  OutputMode::Mode format)
388 {
389  // Place caption on table and add index entry
390  std::string device_description_lc = device_description;
391  std::transform(device_description_lc.begin(), device_description_lc.end(), device_description_lc.begin(), (int (*)(int)) std::tolower);
392 
393  os << "\\index{" << laTexClean(device_description_lc) << "!" << (type ? "device model parameters" : "device instance parameters") << "}" << std::endl
394  << "\\begin{DeviceParamTableGenerated}{" << laTexProtect(device_description) << " " << (type ? "Device Model Parameters" : "Device Instance Parameters") << "}"
395  << "{" << device_name << "_" << device_level << (type ? "_Device_Model_Params" : "_Device_Instance_Params") << "}" << std::endl;
396 
397  // If catagorical listing, group by category
398  if (format == OutputMode::DOC_CAT) {
399  const OrderedParameterMap parameter_map(parameters.getMap().begin(), parameters.getMap().end());
400  for (int category = CAT_NONE; category != CAT_MAX; ++category) {
401  const std::string &header = categoryName(category);
402  bool header_printed = false;
403 
404  for (OrderedParameterMap::const_iterator it = parameter_map.begin(); it != parameter_map.end(); ++it) {
405  std::string parameter_name = (*it).first;
406  const Descriptor &descriptor = *(*it).second;
407 
408  if ((descriptor.getExpressionAccess() & ParameterType::NO_DOC) == 0) {
409  std::string parameter_description;
410  ParameterUnit parameter_unit = U_INVALID;
411  ParameterCategory parameter_category = CAT_UNKNOWN;
412  unitDescription((*it).first, parameter_map, descriptor, parameter_unit, parameter_category, parameter_description);
413 
414  if (parameter_category == category) {
415  if (!header.empty() && !header_printed) {
416  header_printed = true;
417 
418  os << std::endl
419  << "\\category{" << header << "}" << "\\\\ \\hline" << std::endl;
420  }
421  documentParameter(os, parameter_name, parameter_unit, parameter_description, descriptor);
422  }
423  }
424  }
425  }
426  }
427  else {
428  const OrderedParameterMap parameter_map(parameters.getMap().begin(), parameters.getMap().end());
429  for (OrderedParameterMap::const_iterator it = parameter_map.begin(); it != parameter_map.end(); ++it) {
430  std::string parameter_name = (*it).first;
431  const Descriptor &descriptor = *(*it).second;
432 
433  if ((descriptor.getExpressionAccess() & ParameterType::NO_DOC) == 0) {
434  std::string parameter_description;
435  ParameterUnit parameter_unit = U_INVALID;
436  ParameterCategory parameter_category = CAT_UNKNOWN;
437  unitDescription((*it).first, parameter_map, descriptor, parameter_unit, parameter_category, parameter_description);
438 
439  documentParameter(os, parameter_name, parameter_unit, parameter_description, descriptor);
440  }
441  }
442  }
443 
444  os << "\\end{DeviceParamTableGenerated}" << std::endl;
445 
446  return os;
447 }
448 
449 } // namespace Device
450 } // namespace Xyce
#define CONSTCtoK
Definition: N_DEV_Const.h:52
Pure virtual class to augment a linear system.
UnitInfo unitTable[]
Definition: N_DEV_Units.C:55
const std::string & text
Parameter is not to be documented.
Definition: N_DEV_Pars.h:72
Class ParametricData manages the configuration information and the parameter binding map...
Definition: N_DEV_Pars.h:1303
ExprAccess getExpressionAccess() const
Gets the expression access which describes the usage of the paramter.
Definition: N_DEV_Pars.h:659
Class Descriptor describes the parameters stored in the ParametricData parameter map.
Definition: N_DEV_Pars.h:546
StdDescription descriptionTable[]
Definition: N_DEV_Units.C:190
std::map< std::string, Descriptor *, LessNoCase > OrderedParameterMap
Definition: N_DEV_Dump.C:61
ParameterMap & getMap()
Gets the parameter binding map map.
Definition: N_DEV_Pars.h:1341
size_t descriptionTableSize
Definition: N_DEV_Units.C:258
std::ostream & operator<<(std::ostream &os, const Configuration &configuration)
Definition: N_DEV_Dump.C:134
std::ostream & laTexDevice(std::ostream &os, const std::string &name, const int level, const int type, const std::string &device_description, const ParametricData< void > &parameters, const OutputMode::Mode format)