Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_DEV_TransLine.C
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 // Copyright Notice
3 //
4 // Copyright (c) 2002, 2013, Sandia Corporation, Albuquerque, NM, USA. Under the
5 // terms of Contract DE-AC04-94AL85000, there is a non-exclusive license for
6 // use of this work by or on behalf of the U.S. Government. Export of this
7 // program may require a license from the United States Government.
8 //
9 // Xyce(TM) Parallel Electrical Simulator
10 // Copyright (C) 2002-2014 Sandia Corporation
11 //
12 // This program is free software: you can redistribute it and/or modify
13 // it under the terms of the GNU General Public License as published by
14 // the Free Software Foundation, either version 3 of the License, or
15 // (at your option) any later version.
16 //
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU General Public License
23 // along with this program. If not, see <http://www.gnu.org/licenses/>.
24 //-----------------------------------------------------------------------------
25 
26 //-------------------------------------------------------------------------
27 // Filename : $RCSfile: N_DEV_TransLine.C,v $
28 //
29 // Purpose :
30 //
31 // Special Notes :
32 //
33 // Creator : Eric Keiter, SNL
34 //
35 // Creation Date : 9/17/2013
36 //
37 // Revision Information:
38 // ---------------------
39 //
40 // Revision Number: $Revision: 1.25.2.2 $
41 //
42 // Revision Date : $Date: 2014/03/06 23:33:43 $
43 //
44 // Current Owner : $Author: tvrusso $
45 //-------------------------------------------------------------------------
46 
47 #include <Xyce_config.h>
48 
49 
50 // ---------- Standard Includes ----------
51 #include <N_UTL_Misc.h>
52 
53 #include <algorithm>
54 #include <cmath>
55 
56 // ---------- Xyce Includes ----------
57 #include <N_DEV_Const.h>
58 #include <N_DEV_DeviceOptions.h>
59 #include <N_DEV_DeviceMaster.h>
60 #include <N_DEV_ExternData.h>
61 #include <N_DEV_MatrixLoadData.h>
62 #include <N_DEV_TransLine.h>
63 #include <N_DEV_SolverState.h>
64 #include <N_DEV_Message.h>
65 #include <N_ERH_ErrorMgr.h>
66 
67 #include <N_LAS_Vector.h>
68 #include <N_LAS_Matrix.h>
69 
70 #include <N_UTL_Expression.h>
71 #include <N_IO_mmio.h>
72 
73 #include <Teuchos_BLAS.hpp>
74 #include <Teuchos_Utils.hpp>
75 #include <Teuchos_LAPACK.hpp>
76 
77 #undef HAVE_CMATH
78 #undef HAVE_CSTDIO
79 #undef HAVE_CSTDLIB
80 #undef HAVE_INTTYPES_H
81 #undef HAVE_IOSTREAM
82 #undef HAVE_STDINT_H
83 #include <Trilinos_Util.h>
84 
85 namespace Xyce {
86 namespace Device {
87 
88 
89 namespace TransLine {
90 
91 
93 {
94 // Set up variables:
95  p.addPar ("LUMPS", 1, &TransLine::Instance::numLumps)
96  .setGivenMember(&TransLine::Instance::numLumpsGiven);
97 
98  p.addPar ("LEN", 0.0, false, ParameterType::NO_DEP,
101  "length of line");
102 }
103 
105 {
106  p.addPar ("R", 0.0, false, ParameterType::NO_DEP,
109  "Resistance per unit length");
110 
111  p.addPar ("L", 0.0, false, ParameterType::NO_DEP,
114  "Inductance per unit length");
115 
116  p.addPar ("G", 0.0, false, ParameterType::NO_DEP,
119  "Conductance per unit length");
120 
121  p.addPar ("C", 0.0, false, ParameterType::NO_DEP,
124  "Capacitance per unit length");
125 
126  p.addPar ("ELEV", 2,&TransLine::Model::elevNumber)
127  .setGivenMember(&TransLine::Model::elevNumberGiven);
128 }
129 
130 
131 // Class Instance
132 //-----------------------------------------------------------------------------
133 // Function : Instance::processParams
134 // Purpose :
135 // Special Notes :
136 // Scope : public
137 // Creator : Eric Keiter, SNL
138 // Creation Date : 9/17/2013
139 //-----------------------------------------------------------------------------
141 {
142  return true;
143 }
144 
145 //-----------------------------------------------------------------------------
146 // Function : Instance::updateTemperature
147 // Purpose :
148 // Special Notes :
149 // Scope : public
150 // Creator : Eric Keiter, SNL
151 // Creation Date : 9/17/2013
152 //-----------------------------------------------------------------------------
153 bool Instance::updateTemperature ( const double & temp_tmp)
154 {
155  return true;
156 }
157 
158 //-----------------------------------------------------------------------------
159 // Function : Instance::Instance
160 // Purpose : instance block constructor
161 // Special Notes :
162 // Scope : public
163 // Creator : Eric Keiter, SNL
164 // Creation Date : 9/17/2013
165 //-----------------------------------------------------------------------------
167  const Configuration & configuration,
168  const InstanceBlock & IB,
169  Model & TransLineiter,
170  const FactoryBlock & factory_block)
171  : DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
172  model_(TransLineiter),
173  numLumps(1),
174  numTransLineVars(0),
175  length(0.0),
176  numLumpsGiven(false),
177  lengthGiven(false),
178  L(0.0),C(0.0),G(0.0),R(0.0)
179 {
180  numExtVars = IB.numExtVars; // we have as many as were specified on the
181  // instance line
182 
183  // Set params to constant default values:
184  setDefaultParams ();
185 
186  // Set params according to instance line and constant defaults from metadata:
187  setParams (IB.params);
188 
189  // Calculate any parameters specified as expressions:
191 
192  // calculate dependent (ie computed) params:
193  processParams ();
194 
195 
196  // setup R,L,C,G.
197  double dx = (1.0/static_cast<double>(numLumps))*length;
198  if (model_.resistGiven)
199  {
200  R = model_.resist*dx;
201  G = 1/R;
202  }
203  if (model_.capacGiven)
204  {
205  C = model_.capac*dx;
206  }
207  if (model_.inductGiven)
208  {
209  L = model_.induct*dx;
210  }
211 
212  // Initialize which case this is based on the nonzero user-specified
213  // parameters.
214  if ((model_.resist == 0) && (model_.conduct == 0) &&
215  (model_.capac != 0) && (model_.induct != 0))
216  {
218  }
219  else if ((model_.resist != 0) && (model_.conduct == 0) &&
220  (model_.capac != 0) && (model_.induct != 0))
221  {
223  }
224 
225  if (DEBUG_DEVICE)
226  {
227  if (getDeviceOptions().debugLevel > -1)
228  {
229  std::cout << "model_.resist = " << model_.resist <<std::endl;
230  std::cout << "model_.capac = " << model_.capac <<std::endl;
231  std::cout << "model_.induct = " << model_.induct <<std::endl;
232 
233  std::cout << "R = " << R <<std::endl;
234  std::cout << "G = " << G <<std::endl;
235  std::cout << "C = " << C <<std::endl;
236  std::cout << "L = " << L <<std::endl;
237 
239  {
240  std::cout << "RLC line" <<std::endl;
241  }
242  else if (model_.specialCase == TRANS_MOD_LC)
243  {
244  std::cout << "LC line" <<std::endl;
245  }
246  }
247  }
248 
250  {
251  // RLC line.
252  //
253  // each RLC lump has 2 voltage nodes and 1 branch current (3 vars)
254  // there are two external variables, at opposite ends of the line.
255  // One of them has to be subtracted from the numIntVars.
256  //
257  // lump 1 lump 2 lump 3 lump 4
258  // Input --L--1--R--2 --L--3--R--4 --L--5--R--6 --L--7--R--x Output
259  // | | | |
260  // C C C C
261  // | | | |
262  // 0(gnd) 0(gnd) 0(gnd) 0(gnd)
263  //
264  //
265  numIntVars = numLumps*3-1;
266  numExtVars = 2;
267  numStateVars = 0;
268 
269  lumpVec.resize(numLumps);
270 
271  // loop over the lumps, set up nominal indices
272  for (int lump=0;lump<numLumps;++lump)
273  {
274  int varsPerLump=3; // 2 voltage nodes and one branch current.
275  lumpVec[lump].indexV1 = lump*varsPerLump; // voltage node 1
276  lumpVec[lump].indexV2 = lump*varsPerLump+1; // voltage node 2
277  lumpVec[lump].indexI = lump*varsPerLump+2; // branch current
278  lumpVec[lump].indexV3 = (lump+1)*varsPerLump; // voltage node 3
279  }
280 
281  if (DEBUG_DEVICE)
282  {
283  if (getDeviceOptions().debugLevel > 0)
284  {
285  std::cout << "lumps = " << numLumps <<std::endl;
286  for (int lump=0;lump<numLumps;++lump)
287  {
288  std::cout << "lumpVec["<<lump<<"]: v1 = " << lumpVec[lump].indexV1;
289  std::cout << " v2 = " << lumpVec[lump].indexV2;
290  std::cout << " i = " << lumpVec[lump].indexI ;
291  std::cout << " v3 = " << lumpVec[lump].indexV3;
292  std::cout << std::endl;
293  }
294  }
295  }
296 
297  // now correct the lump vector to account for the ends of the
298  // line, which are external vars. The first node (input) will not cause a
299  // correction as it is naturally the first index(0) anyway.
300  //
301  // All nodes that are greater than 0 will need to be incremented by 1,
302  // as the next external node will be index 1.
303  for (int lump=0;lump<numLumps;++lump)
304  {
305  if (lumpVec[lump].indexV1 > 0) lumpVec[lump].indexV1++;
306  if (lumpVec[lump].indexV2 > 0) lumpVec[lump].indexV2++;
307  if (lumpVec[lump].indexI > 0) lumpVec[lump].indexI++;
308  if (lumpVec[lump].indexV3 > 0) lumpVec[lump].indexV3++;
309  }
310 
311  // the last index (being an external var) much be set back to 1.
312  lumpVec[numLumps-1].indexV3 = 1;
313 
314 
315  if (DEBUG_DEVICE)
316  {
317  if (getDeviceOptions().debugLevel > 0)
318  {
319  std::cout << "lumps = " << numLumps <<std::endl;
320  for (int lump=0;lump<numLumps;++lump)
321  {
322  std::cout << "lumpVec["<<lump<<"]: v1 = " << lumpVec[lump].indexV1;
323  std::cout << " v2 = " << lumpVec[lump].indexV2;
324  std::cout << " i = " << lumpVec[lump].indexI ;
325  std::cout << " v3 = " << lumpVec[lump].indexV3;
326  std::cout << std::endl;
327  }
328  }
329  }
330 
331  // setup jacobian stamp
333 
334  // do jacStamp for the exterior lumps
335  {
336  int lump=0;
337  int n1 = lumpVec[lump].indexV1;
338  int n2 = lumpVec[lump].indexV2;
339  int ii = lumpVec[lump].indexI;
340  int n3 = lumpVec[lump].indexV3;
341 
342  jacStamp[n1].resize(1);
343  jacStamp[n1][0] = ii;
344  jacStamp[n2].resize(3);
345  jacStamp[n2][0] = n2;
346  jacStamp[n2][1] = ii;
347  jacStamp[n2][2] = n3;
348  jacStamp[ii].resize(3);
349  jacStamp[ii][0] = n1;
350  jacStamp[ii][1] = n2;
351  jacStamp[ii][2] = ii;
352 
353  if (numLumps==1)
354  {
355  jacStamp[n3].resize(2);
356  jacStamp[n3][0] = n2;
357  jacStamp[n3][1] = n3;
358  }
359  }
360 
361  if (numLumps>1)
362  {
363  int lump=numLumps-1;
364  int n1 = lumpVec[lump].indexV1;
365  int n2 = lumpVec[lump].indexV2;
366  int ii = lumpVec[lump].indexI;
367  int n3 = lumpVec[lump].indexV3;
368 
369  jacStamp[n1].resize(3);
370  jacStamp[n1][0] = lumpVec[lump-1].indexV2;
371  jacStamp[n1][1] = n1;
372  jacStamp[n1][2] = ii;
373 
374  jacStamp[n2].resize(3);
375  jacStamp[n2][0] = n2;
376  jacStamp[n2][1] = ii;
377  jacStamp[n2][2] = n3;
378 
379  jacStamp[ii].resize(3);
380  jacStamp[ii][0] = n1;
381  jacStamp[ii][1] = n2;
382  jacStamp[ii][2] = ii;
383 
384  jacStamp[n3].resize(2);
385  jacStamp[n3][0] = n2;
386  jacStamp[n3][1] = n3;
387 
388  }
389 
390  // do jacStamp for the interior lumps
391  for (int lump=1;lump<numLumps-1;++lump)
392  {
393  int n1 = lumpVec[lump].indexV1;
394  int n2 = lumpVec[lump].indexV2;
395  int ii = lumpVec[lump].indexI;
396  int n3 = lumpVec[lump].indexV3;
397 
398  jacStamp[n1].resize(3);
399  jacStamp[n1][0] = lumpVec[lump-1].indexV2;
400  jacStamp[n1][1] = n1;
401  jacStamp[n1][2] = ii;
402  jacStamp[n2].resize(3);
403  jacStamp[n2][0] = n2;
404  jacStamp[n2][1] = ii;
405  jacStamp[n2][2] = n3;
406  jacStamp[ii].resize(3);
407  jacStamp[ii][0] = n1;
408  jacStamp[ii][1] = n2;
409  jacStamp[ii][2] = ii;
410  }
411  }
412  else if ( model_.specialCase == TRANS_MOD_LC)
413  {
414  // LC line.
415  //
416  // each LC lump has 1 voltage node and 1 branch current (2 vars)
417  // there are two external variables, at opposite ends of the line.
418  // One of them has to be subtracted from the numIntVars.
419  //
420  // lump 1 lump 2 lump 3 lump 4
421  // Input --L--------1----L--------2----L--------3----L--------x Output
422  // | | | |
423  // C C C C
424  // | | | |
425  // 0(gnd) 0(gnd) 0(gnd) 0(gnd)
426  //
427  numIntVars = numLumps*2-1;
428  numExtVars = 2;
429  numStateVars = 0;
430 
431  lumpVec.resize(numLumps);
432 
433  // loop over the lumps, set up nominal indices
434  for (int lump=0;lump<numLumps;++lump)
435  {
436  int varsPerLump=2; // 2 voltage nodes and one branch current.
437  lumpVec[lump].indexV1 = lump*varsPerLump; // voltage node 1
438  lumpVec[lump].indexI = lump*varsPerLump+1; // branch current
439  lumpVec[lump].indexV2 = (lump+1)*varsPerLump; // voltage node 3
440  }
441 
442  if (DEBUG_DEVICE)
443  {
444  if (getDeviceOptions().debugLevel > 0)
445  {
446  std::cout << "lumps = " << numLumps <<std::endl;
447  for (int lump=0;lump<numLumps;++lump)
448  {
449  std::cout << "lumpVec["<<lump<<"]: v1 = " << lumpVec[lump].indexV1;
450  std::cout << " i = " << lumpVec[lump].indexI ;
451  std::cout << " v2 = " << lumpVec[lump].indexV2;
452  std::cout << std::endl;
453  }
454  }
455  }
456 
457  // now correct the lump vector to account for the ends of the
458  // line, which are external vars. The first node (input) will not cause a
459  // correction as it is naturally the first index(0) anyway.
460  //
461  // All nodes that are greater than 0 will need to be incremented by 1,
462  // as the next external node will be index 1.
463  for (int lump=0;lump<numLumps;++lump)
464  {
465  if (lumpVec[lump].indexV1 > 0) lumpVec[lump].indexV1++;
466  if (lumpVec[lump].indexI > 0) lumpVec[lump].indexI++;
467  if (lumpVec[lump].indexV2 > 0) lumpVec[lump].indexV2++;
468  }
469 
470  // the last index (being an external var) much be set back to 1.
471  lumpVec[numLumps-1].indexV2 = 1;
472 
473 
474  if (DEBUG_DEVICE)
475  {
476  if (getDeviceOptions().debugLevel > 0)
477  {
478  std::cout << "lumps = " << numLumps <<std::endl;
479  for (int lump=0;lump<numLumps;++lump)
480  {
481  std::cout << "lumpVec["<<lump<<"]: v1 = " << lumpVec[lump].indexV1;
482  std::cout << " i = " << lumpVec[lump].indexI ;
483  std::cout << " v2 = " << lumpVec[lump].indexV2;
484  std::cout << std::endl;
485  }
486  }
487  }
488 
489  // setup jacobian stamp
491 
492  // do jacStamp for the exterior lumps
493  {
494  int lump=0;
495  int n1 = lumpVec[lump].indexV1;
496  int n2 = lumpVec[lump].indexV2;
497  int ii = lumpVec[lump].indexI;
498 
499  jacStamp[n1].resize(1);
500  jacStamp[n1][0] = ii;
501 
502  jacStamp[ii].resize(3);
503  jacStamp[ii][0] = n1;
504  jacStamp[ii][1] = ii;
505  jacStamp[ii][2] = n2;
506 
507  if (numLumps==1)
508  {
509  jacStamp[n2].resize(2);
510  jacStamp[n2][0] = ii;
511  jacStamp[n2][1] = n2;
512  }
513  }
514 
515  if (numLumps>1)
516  {
517  int lump=numLumps-1;
518  int n1 = lumpVec[lump].indexV1;
519  int n2 = lumpVec[lump].indexV2;
520  int ii = lumpVec[lump].indexI;
521 
522  jacStamp[n1].resize(3);
523  jacStamp[n1][0] = lumpVec[lump-1].indexI;
524  jacStamp[n1][1] = n1;
525  jacStamp[n1][2] = ii;
526 
527  jacStamp[ii].resize(3);
528  jacStamp[ii][0] = n1;
529  jacStamp[ii][1] = ii;
530  jacStamp[ii][2] = n2;
531 
532  jacStamp[n2].resize(2);
533  jacStamp[n2][0] = ii;
534  jacStamp[n2][1] = n2;
535  }
536 
537  // do jacStamp for the interior lumps
538  for (int lump=1;lump<numLumps-1;++lump)
539  {
540  int n1 = lumpVec[lump].indexV1;
541  int n2 = lumpVec[lump].indexV2;
542  int ii = lumpVec[lump].indexI;
543 
544  jacStamp[n1].resize(3);
545  jacStamp[n1][0] = lumpVec[lump-1].indexI;
546  jacStamp[n1][1] = n1;
547  jacStamp[n1][2] = ii;
548 
549  jacStamp[ii].resize(3);
550  jacStamp[ii][0] = n1;
551  jacStamp[ii][1] = ii;
552  jacStamp[ii][2] = n2;
553  }
554  }
555 
556  if (DEBUG_DEVICE)
557  {
558  if (getDeviceOptions().debugLevel > 0)
559  {
560  int size=jacStamp.size();
561  for (int i=0; i<size; ++i)
562  {
563  int sizeJ = jacStamp[i].size();
564  for (int j=0;j<sizeJ;++j)
565  {
566  std::cout << "jacStamp["<<i<<"]["<<j<<"] = " << jacStamp[i][j];
567  std::cout << std::endl;
568  }
569  }
570  }
571 
572  }
573 
574 }
575 
576 //-----------------------------------------------------------------------------
577 // Function : Instance::~Instance
578 // Purpose : destructor
579 // Special Notes :
580 // Scope : public
581 // Creator : Eric Keiter, SNL
582 // Creation Date : 9/17/2013
583 //-----------------------------------------------------------------------------
585 {
586 }
587 
588 // Additional Declarations
589 
590 //-----------------------------------------------------------------------------
591 // Function : Instance::registerLIDs
592 // Purpose :
593 // Special Notes :
594 // Scope : public
595 // Creator : Eric Keiter, SNL
596 // Creation Date : 9/17/2013
597 //-----------------------------------------------------------------------------
598 void Instance::registerLIDs( const std::vector<int> & intLIDVecRef,
599  const std::vector<int> & extLIDVecRef)
600 {
601  AssertLIDs(intLIDVecRef.size() == numIntVars);
602  AssertLIDs(extLIDVecRef.size() == numExtVars);
603 
604  // Copy over the local ID lists:
605  intLIDVec = intLIDVecRef;
606  extLIDVec = extLIDVecRef;
607 
608  // Now use these lists to obtain the indices into the linear algebra entities.
609 
611  {
612  lumpVec[0].li_V1 = extLIDVec[0];
613  lumpVec[numLumps-1].li_V3 = extLIDVec[1];
614 
615  int lid=0;
616  lumpVec[0].li_V2 = intLIDVec[lid++];
617  lumpVec[0].li_I = intLIDVec[lid++];
618 
619  if (numLumps>1)
620  {
621  for (int i=1;i<numLumps-1;++i)
622  {
623  lumpVec[i].li_V1 = intLIDVec[lid++];
624  lumpVec[i].li_V2 = intLIDVec[lid++];
625  lumpVec[i].li_I = intLIDVec[lid++];
626  }
627 
628  lumpVec[numLumps-1].li_V1 = intLIDVec[lid++];
629  lumpVec[numLumps-1].li_V2 = intLIDVec[lid++];
630  lumpVec[numLumps-1].li_I = intLIDVec[lid++];
631 
632  for (int i=0;i<numLumps-1;++i)
633  {
634  lumpVec[i].li_V3 = lumpVec[i+1].li_V1;
635  }
636  }
637  }
638  else if ( model_.specialCase == TRANS_MOD_LC)
639  {
640  lumpVec[0].li_V1 = extLIDVec[0];
641  lumpVec[numLumps-1].li_V2 = extLIDVec[1];
642 
643  int lid=0;
644  lumpVec[0].li_I = intLIDVec[lid++];
645 
646  if (numLumps>1)
647  {
648  for (int i=1;i<numLumps-1;++i)
649  {
650  lumpVec[i].li_V1 = intLIDVec[lid++];
651  lumpVec[i].li_I = intLIDVec[lid++];
652  }
653 
654  lumpVec[numLumps-1].li_V1 = intLIDVec[lid++];
655  lumpVec[numLumps-1].li_I = intLIDVec[lid++];
656 
657  for (int i=0;i<numLumps-1;++i)
658  {
659  lumpVec[i].li_V2 = lumpVec[i+1].li_V1;
660  }
661  }
662  }
663 
664  if (DEBUG_DEVICE)
665  {
666  if (getDeviceOptions().debugLevel > 0)
667  {
668  for (int i=0; i<numIntVars; i++)
669  {
670  std::cout << "intLIDVec["<<i<<"] = " << intLIDVec[i] << std::endl;
671  }
672 
674  {
675  for (int i=0; i<numLumps; i++)
676  {
677  std::cout << "lumpVec["<<i<<"].li_V1 = " << lumpVec[i].li_V1 <<std::endl;
678  std::cout << "lumpVec["<<i<<"].li_V2 = " << lumpVec[i].li_V2 <<std::endl;
679  std::cout << "lumpVec["<<i<<"].li_I = " << lumpVec[i].li_I <<std::endl;
680  std::cout << "lumpVec["<<i<<"].li_V3 = " << lumpVec[i].li_V3 <<std::endl;
681  }
682  }
683  else if ( model_.specialCase == TRANS_MOD_LC)
684  {
685  for (int i=0; i<numLumps; i++)
686  {
687  std::cout << "lumpVec["<<i<<"].li_V1 = " << lumpVec[i].li_V1 <<std::endl;
688  std::cout << "lumpVec["<<i<<"].li_I = " << lumpVec[i].li_I <<std::endl;
689  std::cout << "lumpVec["<<i<<"].li_V2 = " << lumpVec[i].li_V2 <<std::endl;
690  }
691  }
692  }
693  }
694 
695 }
696 
697 //-----------------------------------------------------------------------------
698 // Function : Instance::registerStateLIDs
699 // Purpose :
700 // Special Notes :
701 // Scope : public
702 // Creator : Eric Keiter, SNL
703 // Creation Date : 9/17/2013
704 //-----------------------------------------------------------------------------
705 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef)
706 {
707  AssertLIDs(staLIDVecRef.size() == numStateVars);
708 
709  // Copy over the global ID lists:
710  staLIDVec = staLIDVecRef;
711 }
712 
713 //-----------------------------------------------------------------------------
714 // Function : Instance::getIntNameMap
715 // Purpose :
716 // Special Notes :
717 // Scope : public
718 // Creator : Eric Keiter, SNL
719 // Creation Date : 9/17/2013
720 //-----------------------------------------------------------------------------
721 std::map<int,std::string> & Instance::getIntNameMap ()
722 {
723  // set up the internal name map, if it hasn't been already.
724  if (intNameMap.empty ())
725  {
726  std::string tmpstr1, tmpstr2, tmpstr3;
727 
728  for (int i=0; i<numLumps; i++)
729  {
730 
732  {
733  tmpstr1 = getName()+"_v1_lump"+Teuchos::Utils::toString(i);
734  tmpstr2 = getName()+"_v2_lump"+Teuchos::Utils::toString(i);
735  tmpstr3 = getName()+"_I__lump"+Teuchos::Utils::toString(i);
736  spiceInternalName (tmpstr1);
737  spiceInternalName (tmpstr2);
738  spiceInternalName (tmpstr3);
739 
740  if (i!=0) intNameMap[lumpVec[i].li_V1] = tmpstr1;
741  intNameMap[lumpVec[i].li_V2] = tmpstr2;
742  intNameMap[lumpVec[i].li_I ] = tmpstr3;
743  }
744  else if ( model_.specialCase == TRANS_MOD_LC)
745  {
746  tmpstr1 = getName()+"_v1_lump"+Teuchos::Utils::toString(i);
747  tmpstr3 = getName()+"_I__lump"+Teuchos::Utils::toString(i);
748  spiceInternalName (tmpstr1);
749  spiceInternalName (tmpstr3);
750 
751  if (i!=0) intNameMap[lumpVec[i].li_V1] = tmpstr1;
752  intNameMap[lumpVec[i].li_I ] = tmpstr3;
753  }
754  }
755  }
756 
757  return intNameMap;
758 }
759 
760 
761 //-----------------------------------------------------------------------------
762 // Function : Instance::jacobianStamp
763 // Purpose :
764 // Special Notes :
765 // Scope : public
766 // Creator : Eric Keiter, SNL
767 // Creation Date : 9/17/2013
768 //-----------------------------------------------------------------------------
769 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
770 {
771  return jacStamp;
772 }
773 
774 //-----------------------------------------------------------------------------
775 // Function : Instance::registerJacLIDs
776 // Purpose :
777 // Special Notes :
778 // Scope : public
779 // Creator : Eric Keiter, SNL
780 // Creation Date : 9/17/2013
781 //-----------------------------------------------------------------------------
782 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
783 {
784  DeviceInstance::registerJacLIDs( jacLIDVec );
785 
786 
788  {
789  // do jacStamp for the exterior lumps
790  {
791  int lump=0;
792  int n1 = lumpVec[lump].indexV1;
793  int n2 = lumpVec[lump].indexV2;
794  int ii = lumpVec[lump].indexI;
795  int n3 = lumpVec[lump].indexV3;
796 
797  lumpVec[lump].offset_v1_ii = jacLIDVec[n1][0];
798 
799  lumpVec[lump].offset_v2_v2 = jacLIDVec[n2][0];
800  lumpVec[lump].offset_v2_ii = jacLIDVec[n2][1];
801  lumpVec[lump].offset_v2_v3 = jacLIDVec[n2][2];
802 
803  lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
804  lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][1];
805  lumpVec[lump].offset_ii_ii = jacLIDVec[ii][2];
806 
807  if (numLumps==1)
808  {
809  lumpVec[lump].offset_v3_v2 = jacLIDVec[n3][0];
810  lumpVec[lump].offset_v3_v3 = jacLIDVec[n3][1];
811  }
812  }
813 
814  if (numLumps>1)
815  {
816  int lump=numLumps-1;
817  int n1 = lumpVec[lump].indexV1;
818  int n2 = lumpVec[lump].indexV2;
819  int ii = lumpVec[lump].indexI;
820  int n3 = lumpVec[lump].indexV3;
821 
822  lumpVec[lump].offset_v1_v2m1 = jacLIDVec[n1][0];
823  lumpVec[lump].offset_v1_v1 = jacLIDVec[n1][1];
824  lumpVec[lump].offset_v1_ii = jacLIDVec[n1][2];
825 
826  lumpVec[lump].offset_v2_v2 = jacLIDVec[n2][0];
827  lumpVec[lump].offset_v2_ii = jacLIDVec[n2][1];
828  lumpVec[lump].offset_v2_v3 = jacLIDVec[n2][2];
829 
830  lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
831  lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][1];
832  lumpVec[lump].offset_ii_ii = jacLIDVec[ii][2];
833 
834  lumpVec[lump].offset_v3_v2 = jacLIDVec[n3][0];
835  lumpVec[lump].offset_v3_v3 = jacLIDVec[n3][1];
836  }
837 
838  // do jacLIDVec for the interior lumps
839  for (int lump=1;lump<numLumps-1;++lump)
840  {
841  int n1 = lumpVec[lump].indexV1;
842  int n2 = lumpVec[lump].indexV2;
843  int ii = lumpVec[lump].indexI;
844  int n3 = lumpVec[lump].indexV3;
845 
846  lumpVec[lump].offset_v1_v2m1 = jacLIDVec[n1][0];
847  lumpVec[lump].offset_v1_v1 = jacLIDVec[n1][1];
848  lumpVec[lump].offset_v1_ii = jacLIDVec[n1][2];
849 
850  lumpVec[lump].offset_v2_v2 = jacLIDVec[n2][0];
851  lumpVec[lump].offset_v2_ii = jacLIDVec[n2][1];
852  lumpVec[lump].offset_v2_v3 = jacLIDVec[n2][2];
853 
854  lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
855  lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][1];
856  lumpVec[lump].offset_ii_ii = jacLIDVec[ii][2];
857  }
858 
859  // add the v3 offsets
860  for (int lump=0; lump<numLumps-1; ++lump)
861  {
862  lumpVec[lump].offset_v3_v2 = lumpVec[lump+1].offset_v1_v2m1;
863  lumpVec[lump].offset_v3_v3 = lumpVec[lump+1].offset_v1_v1;
864  }
865  }
866  else if ( model_.specialCase == TRANS_MOD_LC)
867  {
868  // do jacStamp for the exterior lumps
869  {
870  int lump=0;
871  int n1 = lumpVec[lump].indexV1;
872  int n2 = lumpVec[lump].indexV2;
873  int ii = lumpVec[lump].indexI;
874 
875  lumpVec[lump].offset_v1_ii = jacLIDVec[n1][0];
876 
877  lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
878  lumpVec[lump].offset_ii_ii = jacLIDVec[ii][1];
879  lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][2];
880 
881  if (numLumps==1)
882  {
883  lumpVec[lump].offset_v2_ii = jacLIDVec[n2][0];
884  lumpVec[lump].offset_v2_v2 = jacLIDVec[n2][1];
885  }
886  }
887 
888  if (numLumps>1)
889  {
890  int lump=numLumps-1;
891  int n1 = lumpVec[lump].indexV1;
892  int n2 = lumpVec[lump].indexV2;
893  int ii = lumpVec[lump].indexI;
894 
895  lumpVec[lump].offset_v1_iim1 = jacLIDVec[n1][0];
896  lumpVec[lump].offset_v1_v1 = jacLIDVec[n1][1];
897  lumpVec[lump].offset_v1_ii = jacLIDVec[n1][2];
898 
899  lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
900  lumpVec[lump].offset_ii_ii = jacLIDVec[ii][1];
901  lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][2];
902 
903  lumpVec[lump].offset_v2_ii = jacLIDVec[n2][0];
904  lumpVec[lump].offset_v2_v2 = jacLIDVec[n2][1];
905  }
906 
907  // do jacLIDVec for the interior lumps
908  for (int lump=1;lump<numLumps-1;++lump)
909  {
910  int n1 = lumpVec[lump].indexV1;
911  int n2 = lumpVec[lump].indexV2;
912  int ii = lumpVec[lump].indexI;
913 
914  lumpVec[lump].offset_v1_iim1 = jacLIDVec[n1][0];
915  lumpVec[lump].offset_v1_v1 = jacLIDVec[n1][1];
916  lumpVec[lump].offset_v1_ii = jacLIDVec[n1][2];
917 
918  lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
919  lumpVec[lump].offset_ii_ii = jacLIDVec[ii][1];
920  lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][2];
921  }
922 
923  // add the v2 offsets
924  for (int lump=0; lump<numLumps-1; ++lump)
925  {
926  lumpVec[lump].offset_v2_ii = lumpVec[lump+1].offset_v1_iim1;
927  lumpVec[lump].offset_v2_v2 = lumpVec[lump+1].offset_v1_v1;
928  }
929  }
930 
931 
932  if (DEBUG_DEVICE)
933  {
934  if (getDeviceOptions().debugLevel > 0)
935  {
937  {
938  for (int i=0;i<numLumps;++i)
939  {
940  std::cout << "lump = " << i <<std::endl;
941 
942  std::cout << "offset_v1_v2m1 = " << lumpVec[i].offset_v1_v2m1 << std::endl;
943  std::cout << "offset_v1_v1 = " << lumpVec[i].offset_v1_v1 << std::endl;
944  std::cout << "offset_v1_ii = " << lumpVec[i].offset_v1_ii << std::endl;
945 
946 
947  std::cout << "offset_v2_v2 = " << lumpVec[i].offset_v2_v2 << std::endl;
948  std::cout << "offset_v2_ii = " << lumpVec[i].offset_v2_ii << std::endl;
949  std::cout << "offset_v2_v3 = " << lumpVec[i].offset_v2_v3 << std::endl;
950 
951 
952  std::cout << "offset_ii_v1 = " << lumpVec[i].offset_ii_v1 << std::endl;
953  std::cout << "offset_ii_v2 = " << lumpVec[i].offset_ii_v2 << std::endl;
954  std::cout << "offset_ii_ii = " << lumpVec[i].offset_ii_ii << std::endl;
955 
956  std::cout << "offset_v3_v2 = " << lumpVec[i].offset_v3_v2 << std::endl;
957  std::cout << "offset_v3_v3 = " << lumpVec[i].offset_v3_v3 << std::endl;
958  }
959  }
960  else if ( model_.specialCase == TRANS_MOD_LC)
961  {
962  for (int i=0;i<numLumps;++i)
963  {
964  std::cout << "lump = " << i <<std::endl;
965 
966  std::cout << "offset_v1_iim1 = " << lumpVec[i].offset_v1_iim1 << std::endl;
967  std::cout << "offset_v1_v1 = " << lumpVec[i].offset_v1_v1 << std::endl;
968  std::cout << "offset_v1_ii = " << lumpVec[i].offset_v1_ii << std::endl;
969 
970  std::cout << "offset_ii_v1 = " << lumpVec[i].offset_ii_v1 << std::endl;
971  std::cout << "offset_ii_ii = " << lumpVec[i].offset_ii_ii << std::endl;
972  std::cout << "offset_ii_v2 = " << lumpVec[i].offset_ii_v2 << std::endl;
973 
974  std::cout << "offset_v2_ii = " << lumpVec[i].offset_v2_ii << std::endl;
975  std::cout << "offset_v2_v2 = " << lumpVec[i].offset_v2_v2 << std::endl;
976  }
977  }
978  }
979  }
980 }
981 
982 //-----------------------------------------------------------------------------
983 // Function : Instance::setupPointers
984 // Purpose :
985 // Special Notes :
986 // Scope : public
987 // Creator : Eric Keiter, SNL
988 // Creation Date : 9/17/2013
989 //-----------------------------------------------------------------------------
991 {
992 
993 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
994 #endif
995 }
996 
997 //-----------------------------------------------------------------------------
998 // Function : Instance::updateIntermediateVars ()
999 // Purpose :
1000 // Special Notes :
1001 // Scope : public
1002 // Creator : Eric Keiter, SNL
1003 // Creation Date : 10/30/2013
1004 //-----------------------------------------------------------------------------
1006 {
1007  double * solVec = extData.nextSolVectorRawPtr;
1009  {
1010  for (int i=0;i<numLumps;++i)
1011  {
1012  // inductor
1013  double current = solVec[lumpVec[i].li_I];
1014  double v_pos = solVec[lumpVec[i].li_V1];
1015  double v_neg = solVec[lumpVec[i].li_V2];
1016  double vind = v_pos-v_neg;
1017  lumpVec[i].i0_ind = current;
1018  lumpVec[i].f0_ind = L*current;
1019  lumpVec[i].coef_ind = -vind;
1020 
1021  // resistor
1022  v_pos = solVec[lumpVec[i].li_V2];
1023  v_neg = solVec[lumpVec[i].li_V3];
1024  lumpVec[i].i0_res = (v_pos-v_neg)*G;
1025 
1026  // capacitor
1027  double vcap = solVec[lumpVec[i].li_V3];
1028  lumpVec[i].q0_cap = C*vcap;
1029  }
1030  }
1031  else if ( model_.specialCase == TRANS_MOD_LC)
1032  {
1033  for (int i=0;i<numLumps;++i)
1034  {
1035  // inductor
1036  double current = solVec[lumpVec[i].li_I];
1037  double v_pos = solVec[lumpVec[i].li_V1];
1038  double v_neg = solVec[lumpVec[i].li_V2];
1039  double vind = v_pos-v_neg;
1040  lumpVec[i].i0_ind = current;
1041  lumpVec[i].f0_ind = L*current;
1042  lumpVec[i].coef_ind = -vind;
1043 
1044  // capacitor
1045  double vcap = solVec[lumpVec[i].li_V2];
1046  lumpVec[i].q0_cap = C*vcap;
1047  }
1048  }
1049 
1050  return true;
1051 }
1052 
1053 //-----------------------------------------------------------------------------
1054 // Function : Instance::updatePrimaryState
1055 // Purpose :
1056 // Special Notes :
1057 // Scope : public
1058 // Creator : Eric Keiter, SNL
1059 // Creation Date : 9/17/2013
1060 //-----------------------------------------------------------------------------
1062 {
1063  return updateIntermediateVars();
1064 
1065  return true;
1066 }
1067 
1068 //-----------------------------------------------------------------------------
1069 // Function : Instance::loadDeviceMask
1070 //
1071 // Purpose : Loads the zero elements of the device mask
1072 //
1073 // Special Notes : elements of the error std::vector associated with zero
1074 // elements of the mask will not be included in weighted
1075 // norms by the time integrator.
1076 //
1077 // Scope : public
1078 // Creator : Eric Keiter, SNL
1079 // Creation Date : 9/17/2013
1080 //-----------------------------------------------------------------------------
1082 {
1083  return (true);
1084 }
1085 
1086 //-----------------------------------------------------------------------------
1087 // Function : Instance::loadDAEQVector
1088 //
1089 // Purpose : Loads the Q-vector contributions for a single
1090 // TransLine instance.
1091 //
1092 // Special Notes : The "Q" std::vector is part of a standard DAE formalism in
1093 // which the system of equations is represented as:
1094 //
1095 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
1096 //
1097 // Scope : public
1098 // Creator : Eric Keiter, SNL
1099 // Creation Date : 9/17/2013
1100 //-----------------------------------------------------------------------------
1102 {
1103  double * qVec = extData.daeQVectorRawPtr;
1105  {
1106  for (int i=0; i<numLumps;++i)
1107  {
1108  qVec[lumpVec[i].li_I] += lumpVec[i].f0_ind;
1109  qVec[lumpVec[i].li_V3] += lumpVec[i].q0_cap;
1110  }
1111  }
1112  else if ( model_.specialCase == TRANS_MOD_LC)
1113  {
1114  for (int i=0; i<numLumps;++i)
1115  {
1116  qVec[lumpVec[i].li_I] += lumpVec[i].f0_ind;
1117  qVec[lumpVec[i].li_V2] += lumpVec[i].q0_cap;
1118  }
1119  }
1120  return true;
1121 }
1122 
1123 //-----------------------------------------------------------------------------
1124 // Function : Instance::loadDAEFVector
1125 //
1126 // Purpose : Loads the F-vector contributions for a single
1127 // TransLine instance.
1128 //
1129 // Special Notes :
1130 //
1131 // Scope : public
1132 // Creator : Eric Keiter, SNL
1133 // Creation Date : 9/17/2013
1134 //-----------------------------------------------------------------------------
1136 {
1137  double * fVec = extData.daeFVectorRawPtr;
1138 
1140  {
1141  for (int i=0; i<numLumps; i++)
1142  {
1143  // inductor
1144  fVec[lumpVec[i].li_V1] += lumpVec[i].i0_ind;
1145  fVec[lumpVec[i].li_V2] += -lumpVec[i].i0_ind;
1146  fVec[lumpVec[i].li_I ] += lumpVec[i].coef_ind;
1147 
1148  // resistor
1149  fVec[lumpVec[i].li_V2] += lumpVec[i].i0_res;
1150  fVec[lumpVec[i].li_V3] -= lumpVec[i].i0_res;
1151  }
1152  }
1153  else if ( model_.specialCase == TRANS_MOD_LC)
1154  {
1155  for (int i=0; i<numLumps; i++)
1156  {
1157  // inductor
1158  fVec[lumpVec[i].li_V1] += lumpVec[i].i0_ind;
1159  fVec[lumpVec[i].li_V2] += -lumpVec[i].i0_ind;
1160  fVec[lumpVec[i].li_I ] += lumpVec[i].coef_ind;
1161  }
1162  }
1163 
1164  return true;
1165 }
1166 
1167 //-----------------------------------------------------------------------------
1168 // Function : Instance::loadDAEdQdx
1169 //
1170 // Purpose : Loads the dQdx-matrix contributions for a single
1171 // TransLine instance.
1172 //
1173 // Special Notes : The "Q" std::vector is part of a standard DAE formalism in
1174 // which the system of equations is represented as:
1175 //
1176 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
1177 //
1178 // Scope : public
1179 // Creator : Eric Keiter, SNL
1180 // Creation Date : 9/17/2013
1181 //-----------------------------------------------------------------------------
1183 {
1184  N_LAS_Matrix & dQdx = *(extData.dQdxMatrixPtr);
1186  {
1187  for (int i=0; i<numLumps; i++)
1188  {
1189  // inductor
1190  dQdx[lumpVec[i].li_I][lumpVec[i].offset_ii_ii] += L;
1191 
1192  // capacitor
1193  dQdx[lumpVec[i].li_V3][lumpVec[i].offset_v3_v3] += C;
1194  }
1195  }
1196  else if ( model_.specialCase == TRANS_MOD_LC)
1197  {
1198  for (int i=0; i<numLumps; i++)
1199  {
1200  // inductor
1201  dQdx[lumpVec[i].li_I][lumpVec[i].offset_ii_ii] += L;
1202 
1203  // capacitor
1204  dQdx[lumpVec[i].li_V2][lumpVec[i].offset_v2_v2] += C;
1205  }
1206  }
1207 
1208  return true;
1209 }
1210 
1211 //-----------------------------------------------------------------------------
1212 // Function : Instance::loadDAEdFdx ()
1213 //
1214 // Purpose : Loads the F-vector contributions for a single
1215 // TransLine instance.
1216 //
1217 // Special Notes :
1218 //
1219 // Scope : public
1220 // Creator : Eric Keiter, SNL
1221 // Creation Date : 9/17/2013
1222 //-----------------------------------------------------------------------------
1224 {
1225  N_LAS_Matrix & dFdx = *(extData.dFdxMatrixPtr);
1226 
1228  {
1229  for (int i=0; i<numLumps; i++)
1230  {
1231  // inductor
1232  dFdx[lumpVec[i].li_V1][lumpVec[i].offset_v1_ii] += 1.0;
1233  dFdx[lumpVec[i].li_V2][lumpVec[i].offset_v2_ii] -= 1.0;
1234  dFdx[lumpVec[i].li_I ][lumpVec[i].offset_ii_v1] -= 1.0;
1235  dFdx[lumpVec[i].li_I ][lumpVec[i].offset_ii_v2] += 1.0;
1236 
1237  // resistor
1238  dFdx[lumpVec[i].li_V2][lumpVec[i].offset_v2_v2] += G;
1239  dFdx[lumpVec[i].li_V2][lumpVec[i].offset_v2_v3] -= G;
1240  dFdx[lumpVec[i].li_V3][lumpVec[i].offset_v3_v2] -= G;
1241  dFdx[lumpVec[i].li_V3][lumpVec[i].offset_v3_v3] += G;
1242  }
1243  }
1244  else if ( model_.specialCase == TRANS_MOD_LC)
1245  {
1246  for (int i=0; i<numLumps; i++)
1247  {
1248  // inductor
1249  dFdx[lumpVec[i].li_V1][lumpVec[i].offset_v1_ii] += 1.0;
1250  dFdx[lumpVec[i].li_V2][lumpVec[i].offset_v2_ii] -= 1.0;
1251  dFdx[lumpVec[i].li_I ][lumpVec[i].offset_ii_v1] -= 1.0;
1252  dFdx[lumpVec[i].li_I ][lumpVec[i].offset_ii_v2] += 1.0;
1253  }
1254  }
1255 
1256  return true;
1257 }
1258 
1259 //-----------------------------------------------------------------------------
1260 // Function : Instance::varTypes
1261 // Purpose :
1262 // Special Notes :
1263 // Scope : public
1264 // Creator : Eric Keiter, SNL
1265 // Creation Date : 9/17/2013
1266 //-----------------------------------------------------------------------------
1267 void Instance::varTypes( std::vector<char> & varTypeVec )
1268 {
1269 }
1270 
1271 
1272 // Class Model
1273 
1274 //-----------------------------------------------------------------------------
1275 // Function : Model::processParams
1276 // Purpose :
1277 // Special Notes :
1278 // Scope : public
1279 // Creator : Eric Keiter, SNL
1280 // Creation Date : 9/17/2013
1281 //-----------------------------------------------------------------------------
1283 {
1284  return true;
1285 }
1286 
1287 //----------------------------------------------------------------------------
1288 // Function : Model::processInstanceParams
1289 // Purpose :
1290 // Special Notes :
1291 // Scope : public
1292 // Creator : Eric Keiter, SNL
1293 // Creation Date : 9/17/2013
1294 //----------------------------------------------------------------------------
1296 {
1297  std::vector<Instance*>::iterator iter;
1298  std::vector<Instance*>::iterator first = instanceContainer.begin();
1299  std::vector<Instance*>::iterator last = instanceContainer.end();
1300 
1301  for (iter=first; iter!=last; ++iter)
1302  {
1303  (*iter)->processParams();
1304  }
1305 
1306  return true;
1307 }
1308 
1309 //-----------------------------------------------------------------------------
1310 // Function : Model::Model
1311 // Purpose : block constructor
1312 // Special Notes :
1313 // Scope : public
1314 // Creator : Eric Keiter, SNL
1315 // Creation Date : 9/17/2013
1316 //-----------------------------------------------------------------------------
1317 
1319  const Configuration & configuration,
1320  const ModelBlock & MB,
1321  const FactoryBlock & factory_block)
1322  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
1323  elevNumber(2),
1324  resist(0.0),
1325  induct(0.0),
1326  conduct(0.0),
1327  capac(0.0),
1328 
1329  elevNumberGiven(false),
1330  resistGiven(false),
1331  inductGiven(false),
1332  conductGiven(false),
1333  capacGiven(false),
1334  specialCase(TRANS_MOD_RLC)
1335 {
1336 
1337  // Set params to constant default values:
1338  setDefaultParams ();
1339 
1340  // Set params according to .model line and constant defaults from metadata:
1341  setModParams (MB.params);
1342 
1343  // Calculate any parameters specified as expressions:
1345 
1346  // calculate dependent (ie computed) params and check for errors:
1347  processParams ();
1348 }
1349 
1350 //-----------------------------------------------------------------------------
1351 // Function : Model::Model
1352 // Purpose : destructor
1353 // Special Notes :
1354 // Scope : public
1355 // Creator : Eric Keiter, SNL
1356 // Creation Date : 9/17/2013
1357 //-----------------------------------------------------------------------------
1358 
1360 {
1361  std::vector<Instance*>::iterator iter;
1362  std::vector<Instance*>::iterator first = instanceContainer.begin();
1363  std::vector<Instance*>::iterator last = instanceContainer.end();
1364 
1365  for (iter=first; iter!=last; ++iter)
1366  {
1367  delete (*iter);
1368  }
1369 
1370 }
1371 
1372 //-----------------------------------------------------------------------------
1373 // Function : Model::printOutInstances
1374 // Purpose : debugging tool.
1375 // Special Notes :
1376 // Scope : public
1377 // Creator : Eric Keiter, SNL
1378 // Creation Date : 9/17/2013
1379 //-----------------------------------------------------------------------------
1380 
1381 std::ostream &Model::printOutInstances(std::ostream &os) const
1382 {
1383  std::vector<Instance*>::const_iterator iter;
1384  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
1385  std::vector<Instance*>::const_iterator last = instanceContainer.end();
1386 
1387  int i,isize;
1388 
1389  isize = instanceContainer.size();
1390  os << std::endl;
1391  os << "Number of TransLine instances: " << isize << std::endl;
1392  os << " name\t\tmodelName\tParameters" << std::endl;
1393 
1394  for (i = 0, iter = first; iter != last; ++iter, ++i)
1395  {
1396  os << " " << i << ": " << (*iter)->getName() << "\t";
1397  os << getName();
1398  os << std::endl;
1399  }
1400 
1401  os << std::endl;
1402 
1403  return os;
1404 }
1405 
1406 //-----------------------------------------------------------------------------
1407 // Function : Model::forEachInstance
1408 // Purpose :
1409 // Special Notes :
1410 // Scope : public
1411 // Creator : David Baur
1412 // Creation Date : 2/4/2014
1413 //-----------------------------------------------------------------------------
1414 /// Apply a device instance "op" to all instances associated with this
1415 /// model
1416 ///
1417 /// @param[in] op Operator to apply to all instances.
1418 ///
1419 ///
1420 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
1421 {
1422  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1423  op(*it);
1424 }
1425 
1426 
1427 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
1428 {
1429 
1430  return new DeviceMaster<Traits> ( configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
1431 
1432 }
1433 
1435 {
1437  .registerDevice("transline", 1)
1438  .registerModelType("transline", 1);
1439 }
1440 
1441 } // namespace TransLine
1442 } // namespace Device
1443 } // namespace Xyce