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.27 $
41 //
42 // Revision Date : $Date: 2014/05/13 14:50:41 $
43 //
44 // Current Owner : $Author: dgbaur $
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  for (int i=0; i<numLumps; i++)
727  {
729  {
730  if (i != 0)
731  intNameMap[lumpVec[i].li_V1] = spiceInternalName(getName(), "v1_lump" + Teuchos::Utils::toString(i));
732  intNameMap[lumpVec[i].li_V2] = spiceInternalName(getName(), "v2_lump" + Teuchos::Utils::toString(i));
733  intNameMap[lumpVec[i].li_I ] = spiceInternalName(getName(), "I__lump" + Teuchos::Utils::toString(i));
734  }
735  else if ( model_.specialCase == TRANS_MOD_LC)
736  {
737  if (i != 0)
738  intNameMap[lumpVec[i].li_V1] = spiceInternalName(getName(), "v1_lump" + Teuchos::Utils::toString(i));
739  intNameMap[lumpVec[i].li_I ] = spiceInternalName(getName(), "I__lump" + Teuchos::Utils::toString(i));
740  }
741  }
742  }
743 
744  return intNameMap;
745 }
746 
747 
748 //-----------------------------------------------------------------------------
749 // Function : Instance::jacobianStamp
750 // Purpose :
751 // Special Notes :
752 // Scope : public
753 // Creator : Eric Keiter, SNL
754 // Creation Date : 9/17/2013
755 //-----------------------------------------------------------------------------
756 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
757 {
758  return jacStamp;
759 }
760 
761 //-----------------------------------------------------------------------------
762 // Function : Instance::registerJacLIDs
763 // Purpose :
764 // Special Notes :
765 // Scope : public
766 // Creator : Eric Keiter, SNL
767 // Creation Date : 9/17/2013
768 //-----------------------------------------------------------------------------
769 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
770 {
771  DeviceInstance::registerJacLIDs( jacLIDVec );
772 
773 
775  {
776  // do jacStamp for the exterior lumps
777  {
778  int lump=0;
779  int n1 = lumpVec[lump].indexV1;
780  int n2 = lumpVec[lump].indexV2;
781  int ii = lumpVec[lump].indexI;
782  int n3 = lumpVec[lump].indexV3;
783 
784  lumpVec[lump].offset_v1_ii = jacLIDVec[n1][0];
785 
786  lumpVec[lump].offset_v2_v2 = jacLIDVec[n2][0];
787  lumpVec[lump].offset_v2_ii = jacLIDVec[n2][1];
788  lumpVec[lump].offset_v2_v3 = jacLIDVec[n2][2];
789 
790  lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
791  lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][1];
792  lumpVec[lump].offset_ii_ii = jacLIDVec[ii][2];
793 
794  if (numLumps==1)
795  {
796  lumpVec[lump].offset_v3_v2 = jacLIDVec[n3][0];
797  lumpVec[lump].offset_v3_v3 = jacLIDVec[n3][1];
798  }
799  }
800 
801  if (numLumps>1)
802  {
803  int lump=numLumps-1;
804  int n1 = lumpVec[lump].indexV1;
805  int n2 = lumpVec[lump].indexV2;
806  int ii = lumpVec[lump].indexI;
807  int n3 = lumpVec[lump].indexV3;
808 
809  lumpVec[lump].offset_v1_v2m1 = jacLIDVec[n1][0];
810  lumpVec[lump].offset_v1_v1 = jacLIDVec[n1][1];
811  lumpVec[lump].offset_v1_ii = jacLIDVec[n1][2];
812 
813  lumpVec[lump].offset_v2_v2 = jacLIDVec[n2][0];
814  lumpVec[lump].offset_v2_ii = jacLIDVec[n2][1];
815  lumpVec[lump].offset_v2_v3 = jacLIDVec[n2][2];
816 
817  lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
818  lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][1];
819  lumpVec[lump].offset_ii_ii = jacLIDVec[ii][2];
820 
821  lumpVec[lump].offset_v3_v2 = jacLIDVec[n3][0];
822  lumpVec[lump].offset_v3_v3 = jacLIDVec[n3][1];
823  }
824 
825  // do jacLIDVec for the interior lumps
826  for (int lump=1;lump<numLumps-1;++lump)
827  {
828  int n1 = lumpVec[lump].indexV1;
829  int n2 = lumpVec[lump].indexV2;
830  int ii = lumpVec[lump].indexI;
831  int n3 = lumpVec[lump].indexV3;
832 
833  lumpVec[lump].offset_v1_v2m1 = jacLIDVec[n1][0];
834  lumpVec[lump].offset_v1_v1 = jacLIDVec[n1][1];
835  lumpVec[lump].offset_v1_ii = jacLIDVec[n1][2];
836 
837  lumpVec[lump].offset_v2_v2 = jacLIDVec[n2][0];
838  lumpVec[lump].offset_v2_ii = jacLIDVec[n2][1];
839  lumpVec[lump].offset_v2_v3 = jacLIDVec[n2][2];
840 
841  lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
842  lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][1];
843  lumpVec[lump].offset_ii_ii = jacLIDVec[ii][2];
844  }
845 
846  // add the v3 offsets
847  for (int lump=0; lump<numLumps-1; ++lump)
848  {
849  lumpVec[lump].offset_v3_v2 = lumpVec[lump+1].offset_v1_v2m1;
850  lumpVec[lump].offset_v3_v3 = lumpVec[lump+1].offset_v1_v1;
851  }
852  }
853  else if ( model_.specialCase == TRANS_MOD_LC)
854  {
855  // do jacStamp for the exterior lumps
856  {
857  int lump=0;
858  int n1 = lumpVec[lump].indexV1;
859  int n2 = lumpVec[lump].indexV2;
860  int ii = lumpVec[lump].indexI;
861 
862  lumpVec[lump].offset_v1_ii = jacLIDVec[n1][0];
863 
864  lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
865  lumpVec[lump].offset_ii_ii = jacLIDVec[ii][1];
866  lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][2];
867 
868  if (numLumps==1)
869  {
870  lumpVec[lump].offset_v2_ii = jacLIDVec[n2][0];
871  lumpVec[lump].offset_v2_v2 = jacLIDVec[n2][1];
872  }
873  }
874 
875  if (numLumps>1)
876  {
877  int lump=numLumps-1;
878  int n1 = lumpVec[lump].indexV1;
879  int n2 = lumpVec[lump].indexV2;
880  int ii = lumpVec[lump].indexI;
881 
882  lumpVec[lump].offset_v1_iim1 = jacLIDVec[n1][0];
883  lumpVec[lump].offset_v1_v1 = jacLIDVec[n1][1];
884  lumpVec[lump].offset_v1_ii = jacLIDVec[n1][2];
885 
886  lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
887  lumpVec[lump].offset_ii_ii = jacLIDVec[ii][1];
888  lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][2];
889 
890  lumpVec[lump].offset_v2_ii = jacLIDVec[n2][0];
891  lumpVec[lump].offset_v2_v2 = jacLIDVec[n2][1];
892  }
893 
894  // do jacLIDVec for the interior lumps
895  for (int lump=1;lump<numLumps-1;++lump)
896  {
897  int n1 = lumpVec[lump].indexV1;
898  int n2 = lumpVec[lump].indexV2;
899  int ii = lumpVec[lump].indexI;
900 
901  lumpVec[lump].offset_v1_iim1 = jacLIDVec[n1][0];
902  lumpVec[lump].offset_v1_v1 = jacLIDVec[n1][1];
903  lumpVec[lump].offset_v1_ii = jacLIDVec[n1][2];
904 
905  lumpVec[lump].offset_ii_v1 = jacLIDVec[ii][0];
906  lumpVec[lump].offset_ii_ii = jacLIDVec[ii][1];
907  lumpVec[lump].offset_ii_v2 = jacLIDVec[ii][2];
908  }
909 
910  // add the v2 offsets
911  for (int lump=0; lump<numLumps-1; ++lump)
912  {
913  lumpVec[lump].offset_v2_ii = lumpVec[lump+1].offset_v1_iim1;
914  lumpVec[lump].offset_v2_v2 = lumpVec[lump+1].offset_v1_v1;
915  }
916  }
917 
918 
919  if (DEBUG_DEVICE)
920  {
921  if (getDeviceOptions().debugLevel > 0)
922  {
924  {
925  for (int i=0;i<numLumps;++i)
926  {
927  std::cout << "lump = " << i <<std::endl;
928 
929  std::cout << "offset_v1_v2m1 = " << lumpVec[i].offset_v1_v2m1 << std::endl;
930  std::cout << "offset_v1_v1 = " << lumpVec[i].offset_v1_v1 << std::endl;
931  std::cout << "offset_v1_ii = " << lumpVec[i].offset_v1_ii << std::endl;
932 
933 
934  std::cout << "offset_v2_v2 = " << lumpVec[i].offset_v2_v2 << std::endl;
935  std::cout << "offset_v2_ii = " << lumpVec[i].offset_v2_ii << std::endl;
936  std::cout << "offset_v2_v3 = " << lumpVec[i].offset_v2_v3 << std::endl;
937 
938 
939  std::cout << "offset_ii_v1 = " << lumpVec[i].offset_ii_v1 << std::endl;
940  std::cout << "offset_ii_v2 = " << lumpVec[i].offset_ii_v2 << std::endl;
941  std::cout << "offset_ii_ii = " << lumpVec[i].offset_ii_ii << std::endl;
942 
943  std::cout << "offset_v3_v2 = " << lumpVec[i].offset_v3_v2 << std::endl;
944  std::cout << "offset_v3_v3 = " << lumpVec[i].offset_v3_v3 << std::endl;
945  }
946  }
947  else if ( model_.specialCase == TRANS_MOD_LC)
948  {
949  for (int i=0;i<numLumps;++i)
950  {
951  std::cout << "lump = " << i <<std::endl;
952 
953  std::cout << "offset_v1_iim1 = " << lumpVec[i].offset_v1_iim1 << std::endl;
954  std::cout << "offset_v1_v1 = " << lumpVec[i].offset_v1_v1 << std::endl;
955  std::cout << "offset_v1_ii = " << lumpVec[i].offset_v1_ii << std::endl;
956 
957  std::cout << "offset_ii_v1 = " << lumpVec[i].offset_ii_v1 << std::endl;
958  std::cout << "offset_ii_ii = " << lumpVec[i].offset_ii_ii << std::endl;
959  std::cout << "offset_ii_v2 = " << lumpVec[i].offset_ii_v2 << std::endl;
960 
961  std::cout << "offset_v2_ii = " << lumpVec[i].offset_v2_ii << std::endl;
962  std::cout << "offset_v2_v2 = " << lumpVec[i].offset_v2_v2 << std::endl;
963  }
964  }
965  }
966  }
967 }
968 
969 //-----------------------------------------------------------------------------
970 // Function : Instance::setupPointers
971 // Purpose :
972 // Special Notes :
973 // Scope : public
974 // Creator : Eric Keiter, SNL
975 // Creation Date : 9/17/2013
976 //-----------------------------------------------------------------------------
978 {
979 
980 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
981 #endif
982 }
983 
984 //-----------------------------------------------------------------------------
985 // Function : Instance::updateIntermediateVars ()
986 // Purpose :
987 // Special Notes :
988 // Scope : public
989 // Creator : Eric Keiter, SNL
990 // Creation Date : 10/30/2013
991 //-----------------------------------------------------------------------------
993 {
994  double * solVec = extData.nextSolVectorRawPtr;
996  {
997  for (int i=0;i<numLumps;++i)
998  {
999  // inductor
1000  double current = solVec[lumpVec[i].li_I];
1001  double v_pos = solVec[lumpVec[i].li_V1];
1002  double v_neg = solVec[lumpVec[i].li_V2];
1003  double vind = v_pos-v_neg;
1004  lumpVec[i].i0_ind = current;
1005  lumpVec[i].f0_ind = L*current;
1006  lumpVec[i].coef_ind = -vind;
1007 
1008  // resistor
1009  v_pos = solVec[lumpVec[i].li_V2];
1010  v_neg = solVec[lumpVec[i].li_V3];
1011  lumpVec[i].i0_res = (v_pos-v_neg)*G;
1012 
1013  // capacitor
1014  double vcap = solVec[lumpVec[i].li_V3];
1015  lumpVec[i].q0_cap = C*vcap;
1016  }
1017  }
1018  else if ( model_.specialCase == TRANS_MOD_LC)
1019  {
1020  for (int i=0;i<numLumps;++i)
1021  {
1022  // inductor
1023  double current = solVec[lumpVec[i].li_I];
1024  double v_pos = solVec[lumpVec[i].li_V1];
1025  double v_neg = solVec[lumpVec[i].li_V2];
1026  double vind = v_pos-v_neg;
1027  lumpVec[i].i0_ind = current;
1028  lumpVec[i].f0_ind = L*current;
1029  lumpVec[i].coef_ind = -vind;
1030 
1031  // capacitor
1032  double vcap = solVec[lumpVec[i].li_V2];
1033  lumpVec[i].q0_cap = C*vcap;
1034  }
1035  }
1036 
1037  return true;
1038 }
1039 
1040 //-----------------------------------------------------------------------------
1041 // Function : Instance::updatePrimaryState
1042 // Purpose :
1043 // Special Notes :
1044 // Scope : public
1045 // Creator : Eric Keiter, SNL
1046 // Creation Date : 9/17/2013
1047 //-----------------------------------------------------------------------------
1049 {
1050  return updateIntermediateVars();
1051 
1052  return true;
1053 }
1054 
1055 //-----------------------------------------------------------------------------
1056 // Function : Instance::loadDeviceMask
1057 //
1058 // Purpose : Loads the zero elements of the device mask
1059 //
1060 // Special Notes : elements of the error std::vector associated with zero
1061 // elements of the mask will not be included in weighted
1062 // norms by the time integrator.
1063 //
1064 // Scope : public
1065 // Creator : Eric Keiter, SNL
1066 // Creation Date : 9/17/2013
1067 //-----------------------------------------------------------------------------
1069 {
1070  return (true);
1071 }
1072 
1073 //-----------------------------------------------------------------------------
1074 // Function : Instance::loadDAEQVector
1075 //
1076 // Purpose : Loads the Q-vector contributions for a single
1077 // TransLine instance.
1078 //
1079 // Special Notes : The "Q" std::vector is part of a standard DAE formalism in
1080 // which the system of equations is represented as:
1081 //
1082 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
1083 //
1084 // Scope : public
1085 // Creator : Eric Keiter, SNL
1086 // Creation Date : 9/17/2013
1087 //-----------------------------------------------------------------------------
1089 {
1090  double * qVec = extData.daeQVectorRawPtr;
1092  {
1093  for (int i=0; i<numLumps;++i)
1094  {
1095  qVec[lumpVec[i].li_I] += lumpVec[i].f0_ind;
1096  qVec[lumpVec[i].li_V3] += lumpVec[i].q0_cap;
1097  }
1098  }
1099  else if ( model_.specialCase == TRANS_MOD_LC)
1100  {
1101  for (int i=0; i<numLumps;++i)
1102  {
1103  qVec[lumpVec[i].li_I] += lumpVec[i].f0_ind;
1104  qVec[lumpVec[i].li_V2] += lumpVec[i].q0_cap;
1105  }
1106  }
1107  return true;
1108 }
1109 
1110 //-----------------------------------------------------------------------------
1111 // Function : Instance::loadDAEFVector
1112 //
1113 // Purpose : Loads the F-vector contributions for a single
1114 // TransLine instance.
1115 //
1116 // Special Notes :
1117 //
1118 // Scope : public
1119 // Creator : Eric Keiter, SNL
1120 // Creation Date : 9/17/2013
1121 //-----------------------------------------------------------------------------
1123 {
1124  double * fVec = extData.daeFVectorRawPtr;
1125 
1127  {
1128  for (int i=0; i<numLumps; i++)
1129  {
1130  // inductor
1131  fVec[lumpVec[i].li_V1] += lumpVec[i].i0_ind;
1132  fVec[lumpVec[i].li_V2] += -lumpVec[i].i0_ind;
1133  fVec[lumpVec[i].li_I ] += lumpVec[i].coef_ind;
1134 
1135  // resistor
1136  fVec[lumpVec[i].li_V2] += lumpVec[i].i0_res;
1137  fVec[lumpVec[i].li_V3] -= lumpVec[i].i0_res;
1138  }
1139  }
1140  else if ( model_.specialCase == TRANS_MOD_LC)
1141  {
1142  for (int i=0; i<numLumps; i++)
1143  {
1144  // inductor
1145  fVec[lumpVec[i].li_V1] += lumpVec[i].i0_ind;
1146  fVec[lumpVec[i].li_V2] += -lumpVec[i].i0_ind;
1147  fVec[lumpVec[i].li_I ] += lumpVec[i].coef_ind;
1148  }
1149  }
1150 
1151  return true;
1152 }
1153 
1154 //-----------------------------------------------------------------------------
1155 // Function : Instance::loadDAEdQdx
1156 //
1157 // Purpose : Loads the dQdx-matrix contributions for a single
1158 // TransLine instance.
1159 //
1160 // Special Notes : The "Q" std::vector is part of a standard DAE formalism in
1161 // which the system of equations is represented as:
1162 //
1163 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
1164 //
1165 // Scope : public
1166 // Creator : Eric Keiter, SNL
1167 // Creation Date : 9/17/2013
1168 //-----------------------------------------------------------------------------
1170 {
1171  N_LAS_Matrix & dQdx = *(extData.dQdxMatrixPtr);
1173  {
1174  for (int i=0; i<numLumps; i++)
1175  {
1176  // inductor
1177  dQdx[lumpVec[i].li_I][lumpVec[i].offset_ii_ii] += L;
1178 
1179  // capacitor
1180  dQdx[lumpVec[i].li_V3][lumpVec[i].offset_v3_v3] += C;
1181  }
1182  }
1183  else if ( model_.specialCase == TRANS_MOD_LC)
1184  {
1185  for (int i=0; i<numLumps; i++)
1186  {
1187  // inductor
1188  dQdx[lumpVec[i].li_I][lumpVec[i].offset_ii_ii] += L;
1189 
1190  // capacitor
1191  dQdx[lumpVec[i].li_V2][lumpVec[i].offset_v2_v2] += C;
1192  }
1193  }
1194 
1195  return true;
1196 }
1197 
1198 //-----------------------------------------------------------------------------
1199 // Function : Instance::loadDAEdFdx ()
1200 //
1201 // Purpose : Loads the F-vector contributions for a single
1202 // TransLine instance.
1203 //
1204 // Special Notes :
1205 //
1206 // Scope : public
1207 // Creator : Eric Keiter, SNL
1208 // Creation Date : 9/17/2013
1209 //-----------------------------------------------------------------------------
1211 {
1212  N_LAS_Matrix & dFdx = *(extData.dFdxMatrixPtr);
1213 
1215  {
1216  for (int i=0; i<numLumps; i++)
1217  {
1218  // inductor
1219  dFdx[lumpVec[i].li_V1][lumpVec[i].offset_v1_ii] += 1.0;
1220  dFdx[lumpVec[i].li_V2][lumpVec[i].offset_v2_ii] -= 1.0;
1221  dFdx[lumpVec[i].li_I ][lumpVec[i].offset_ii_v1] -= 1.0;
1222  dFdx[lumpVec[i].li_I ][lumpVec[i].offset_ii_v2] += 1.0;
1223 
1224  // resistor
1225  dFdx[lumpVec[i].li_V2][lumpVec[i].offset_v2_v2] += G;
1226  dFdx[lumpVec[i].li_V2][lumpVec[i].offset_v2_v3] -= G;
1227  dFdx[lumpVec[i].li_V3][lumpVec[i].offset_v3_v2] -= G;
1228  dFdx[lumpVec[i].li_V3][lumpVec[i].offset_v3_v3] += G;
1229  }
1230  }
1231  else if ( model_.specialCase == TRANS_MOD_LC)
1232  {
1233  for (int i=0; i<numLumps; i++)
1234  {
1235  // inductor
1236  dFdx[lumpVec[i].li_V1][lumpVec[i].offset_v1_ii] += 1.0;
1237  dFdx[lumpVec[i].li_V2][lumpVec[i].offset_v2_ii] -= 1.0;
1238  dFdx[lumpVec[i].li_I ][lumpVec[i].offset_ii_v1] -= 1.0;
1239  dFdx[lumpVec[i].li_I ][lumpVec[i].offset_ii_v2] += 1.0;
1240  }
1241  }
1242 
1243  return true;
1244 }
1245 
1246 //-----------------------------------------------------------------------------
1247 // Function : Instance::varTypes
1248 // Purpose :
1249 // Special Notes :
1250 // Scope : public
1251 // Creator : Eric Keiter, SNL
1252 // Creation Date : 9/17/2013
1253 //-----------------------------------------------------------------------------
1254 void Instance::varTypes( std::vector<char> & varTypeVec )
1255 {
1256 }
1257 
1258 
1259 // Class Model
1260 
1261 //-----------------------------------------------------------------------------
1262 // Function : Model::processParams
1263 // Purpose :
1264 // Special Notes :
1265 // Scope : public
1266 // Creator : Eric Keiter, SNL
1267 // Creation Date : 9/17/2013
1268 //-----------------------------------------------------------------------------
1270 {
1271  return true;
1272 }
1273 
1274 //----------------------------------------------------------------------------
1275 // Function : Model::processInstanceParams
1276 // Purpose :
1277 // Special Notes :
1278 // Scope : public
1279 // Creator : Eric Keiter, SNL
1280 // Creation Date : 9/17/2013
1281 //----------------------------------------------------------------------------
1283 {
1284  std::vector<Instance*>::iterator iter;
1285  std::vector<Instance*>::iterator first = instanceContainer.begin();
1286  std::vector<Instance*>::iterator last = instanceContainer.end();
1287 
1288  for (iter=first; iter!=last; ++iter)
1289  {
1290  (*iter)->processParams();
1291  }
1292 
1293  return true;
1294 }
1295 
1296 //-----------------------------------------------------------------------------
1297 // Function : Model::Model
1298 // Purpose : block constructor
1299 // Special Notes :
1300 // Scope : public
1301 // Creator : Eric Keiter, SNL
1302 // Creation Date : 9/17/2013
1303 //-----------------------------------------------------------------------------
1304 
1306  const Configuration & configuration,
1307  const ModelBlock & MB,
1308  const FactoryBlock & factory_block)
1309  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
1310  elevNumber(2),
1311  resist(0.0),
1312  induct(0.0),
1313  conduct(0.0),
1314  capac(0.0),
1315 
1316  elevNumberGiven(false),
1317  resistGiven(false),
1318  inductGiven(false),
1319  conductGiven(false),
1320  capacGiven(false),
1321  specialCase(TRANS_MOD_RLC)
1322 {
1323 
1324  // Set params to constant default values:
1325  setDefaultParams ();
1326 
1327  // Set params according to .model line and constant defaults from metadata:
1328  setModParams (MB.params);
1329 
1330  // Calculate any parameters specified as expressions:
1332 
1333  // calculate dependent (ie computed) params and check for errors:
1334  processParams ();
1335 }
1336 
1337 //-----------------------------------------------------------------------------
1338 // Function : Model::Model
1339 // Purpose : destructor
1340 // Special Notes :
1341 // Scope : public
1342 // Creator : Eric Keiter, SNL
1343 // Creation Date : 9/17/2013
1344 //-----------------------------------------------------------------------------
1345 
1347 {
1348  std::vector<Instance*>::iterator iter;
1349  std::vector<Instance*>::iterator first = instanceContainer.begin();
1350  std::vector<Instance*>::iterator last = instanceContainer.end();
1351 
1352  for (iter=first; iter!=last; ++iter)
1353  {
1354  delete (*iter);
1355  }
1356 
1357 }
1358 
1359 //-----------------------------------------------------------------------------
1360 // Function : Model::printOutInstances
1361 // Purpose : debugging tool.
1362 // Special Notes :
1363 // Scope : public
1364 // Creator : Eric Keiter, SNL
1365 // Creation Date : 9/17/2013
1366 //-----------------------------------------------------------------------------
1367 
1368 std::ostream &Model::printOutInstances(std::ostream &os) const
1369 {
1370  std::vector<Instance*>::const_iterator iter;
1371  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
1372  std::vector<Instance*>::const_iterator last = instanceContainer.end();
1373 
1374  int i,isize;
1375 
1376  isize = instanceContainer.size();
1377  os << std::endl;
1378  os << "Number of TransLine instances: " << isize << std::endl;
1379  os << " name\t\tmodelName\tParameters" << std::endl;
1380 
1381  for (i = 0, iter = first; iter != last; ++iter, ++i)
1382  {
1383  os << " " << i << ": " << (*iter)->getName() << "\t";
1384  os << getName();
1385  os << std::endl;
1386  }
1387 
1388  os << std::endl;
1389 
1390  return os;
1391 }
1392 
1393 //-----------------------------------------------------------------------------
1394 // Function : Model::forEachInstance
1395 // Purpose :
1396 // Special Notes :
1397 // Scope : public
1398 // Creator : David Baur
1399 // Creation Date : 2/4/2014
1400 //-----------------------------------------------------------------------------
1401 /// Apply a device instance "op" to all instances associated with this
1402 /// model
1403 ///
1404 /// @param[in] op Operator to apply to all instances.
1405 ///
1406 ///
1407 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
1408 {
1409  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1410  op(*it);
1411 }
1412 
1413 
1414 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
1415 {
1416 
1417  return new DeviceMaster<Traits> ( configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
1418 
1419 }
1420 
1422 {
1424  .registerDevice("transline", 1)
1425  .registerModelType("transline", 1);
1426 }
1427 
1428 } // namespace TransLine
1429 } // namespace Device
1430 } // namespace Xyce