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.9.2.1 $
40 //
41 // Revision Date : $Date: 2015/04/02 18:29:36 $
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_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  os << laTexProtect(name) << " & " << laTexProtect(description) << " & ";
287 
288  const UnitInfo &unit_info = findUnit(parameter_unit);
289  os << unit_info.doc;
290  os << " & ";
291 
292  if ((descriptor.isType<double>() && name == "TNOM") || name == "TEMP")
293  {
294  double default_value = getDefaultValue<double>(descriptor);
295  // os << default_value - CONSTCtoK;
296  // os << CONSTREFTEMP - CONSTCtoK;
297  if (default_value == 0.0)
298  {
299  os << "Ambient Temperature";
300  }
301  else if (default_value - CONSTCtoK < 0.0)
302  {
303  os << default_value;
304  }
305  else
306  {
307  os << default_value - CONSTCtoK;
308  }
309  }
310  else
311  {
312  descriptor.getEntry().print(os);
313  }
314 
315  if (descriptor.getCompositeParametricData<void>()) {
316  const ParametricData<void> &composite_parametric_data = *descriptor.getCompositeParametricData<void>();
317  const OrderedParameterMap composite_parametric_map(composite_parametric_data.getMap().begin(), composite_parametric_data.getMap().end());
318 
319  std::ostringstream path;
320  path << name << "_Composite_Params.tex";
321 
322  std::ofstream os(path.str().c_str(), std::ios_base::out);
323 
324  os << "% This table was generated by Xyce" << std::endl;
325 
326  laTexComposite(os, name, name, composite_parametric_data);
327  }
328 
329  os << " \\\\ \\hline" << std::endl;
330 
331  return os;
332 }
333 
334 std::ostream &
335 laTexComposite(
336  std::ostream & os,
337  const std::string & composite_name,
338  const std::string & composite_description,
339  const ParametricData<void> & parameters)
340 {
341  // Place caption on table and add index entry
342  std::string composite_description_lc = composite_description;
343  std::transform(composite_description_lc.begin(), composite_description_lc.end(), composite_description_lc.begin(), (int (*)(int)) std::tolower);
344 
345  os << "\\index{" << laTexClean(composite_description_lc) << "!" << "composite parameters}" << std::endl
346  << "\\begin{CompositeParamTableGenerated}{" << laTexProtect(composite_description) << " " << "Composite Parameters}"
347  << "{" << composite_name << "_Composite_Params}" << std::endl;
348 
349  const OrderedParameterMap parameter_map(parameters.getMap().begin(), parameters.getMap().end());
350  for (OrderedParameterMap::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  std::string parameter_description;
356  ParameterUnit parameter_unit = U_INVALID;
357  ParameterCategory parameter_category = CAT_UNKNOWN;
358  unitDescription((*it).first, parameter_map, descriptor, parameter_unit, parameter_category, parameter_description);
359 
360  documentParameter(os, parameter_name, parameter_unit, parameter_description, descriptor);
361  }
362  }
363 
364  os << "\\end{CompositeParamTableGenerated}" << std::endl;
365 
366  return os;
367 }
368 
369 } // namespace <unnamed>
370 
371 std::ostream &
373  std::ostream & os,
374  const std::string & device_name,
375  const int device_level,
376  const int type,
377  const std::string & device_description,
378  const ParametricData<void> & parameters,
379  OutputMode::Mode format)
380 {
381  // Place caption on table and add index entry
382  std::string device_description_lc = device_description;
383  std::transform(device_description_lc.begin(), device_description_lc.end(), device_description_lc.begin(), (int (*)(int)) std::tolower);
384 
385  os << "\\index{" << laTexClean(device_description_lc) << "!" << (type ? "device model parameters" : "device instance parameters") << "}" << std::endl
386  << "\\begin{DeviceParamTableGenerated}{" << laTexProtect(device_description) << " " << (type ? "Device Model Parameters" : "Device Instance Parameters") << "}"
387  << "{" << device_name << "_" << device_level << (type ? "_Device_Model_Params" : "_Device_Instance_Params") << "}" << std::endl;
388 
389  // If catagorical listing, group by category
390  if (format == OutputMode::DOC_CAT) {
391  const OrderedParameterMap parameter_map(parameters.getMap().begin(), parameters.getMap().end());
392  for (int category = CAT_NONE; category != CAT_MAX; ++category) {
393  const std::string &header = categoryName(category);
394  bool header_printed = false;
395 
396  for (OrderedParameterMap::const_iterator it = parameter_map.begin(); it != parameter_map.end(); ++it) {
397  std::string parameter_name = (*it).first;
398  const Descriptor &descriptor = *(*it).second;
399 
400  if ((descriptor.getExpressionAccess() & ParameterType::NO_DOC) == 0) {
401  std::string parameter_description;
402  ParameterUnit parameter_unit = U_INVALID;
403  ParameterCategory parameter_category = CAT_UNKNOWN;
404  unitDescription((*it).first, parameter_map, descriptor, parameter_unit, parameter_category, parameter_description);
405 
406  if (parameter_category == category) {
407  if (!header.empty() && !header_printed) {
408  header_printed = true;
409 
410  os << std::endl
411  << "\\category{" << header << "}" << "\\\\ \\hline" << std::endl;
412  }
413  documentParameter(os, parameter_name, parameter_unit, parameter_description, descriptor);
414  }
415  }
416  }
417  }
418  }
419  else {
420  const OrderedParameterMap parameter_map(parameters.getMap().begin(), parameters.getMap().end());
421  for (OrderedParameterMap::const_iterator it = parameter_map.begin(); it != parameter_map.end(); ++it) {
422  std::string parameter_name = (*it).first;
423  const Descriptor &descriptor = *(*it).second;
424 
425  if ((descriptor.getExpressionAccess() & ParameterType::NO_DOC) == 0) {
426  std::string parameter_description;
427  ParameterUnit parameter_unit = U_INVALID;
428  ParameterCategory parameter_category = CAT_UNKNOWN;
429  unitDescription((*it).first, parameter_map, descriptor, parameter_unit, parameter_category, parameter_description);
430 
431  documentParameter(os, parameter_name, parameter_unit, parameter_description, descriptor);
432  }
433  }
434  }
435 
436  os << "\\end{DeviceParamTableGenerated}" << std::endl;
437 
438  return os;
439 }
440 
441 } // namespace Device
442 } // 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:189
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:257
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)