Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_DEV_SourceData.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-2014 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_SourceData.C,v $
27 //
28 // Purpose : This file contains the member functions of the
29 // N_DEV_SourceData class, which is used by the Vsrc
30 // and ISRC devices.
31 //
32 // Special Notes :
33 //
34 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
35 //
36 // Creation Date : 02/28/00
37 //
38 // Revision Information:
39 // ---------------------
40 //
41 // Revision Number: $Revision: 1.127 $
42 //
43 // Revision Date : $Date: 2014/07/31 19:56:16 $
44 //
45 // Current Owner : $Author: peshola $
46 //-------------------------------------------------------------------------
47 
48 #include <Xyce_config.h>
49 
50 
51 // ---------- Standard Includes ----------
52 
53 #ifdef HAVE_CMATH
54 #include <cmath>
55 #else
56 #include <math.h>
57 #endif
58 
59 // ---------- Xyce Includes ----------
60 #include <N_DEV_SourceData.h>
61 #include <N_DEV_DeviceInstance.h>
62 #include <N_DEV_SolverState.h>
63 #include <N_DEV_DeviceOptions.h>
64 
65 #include <N_ERH_ErrorMgr.h>
66 
67 #include <N_UTL_BreakPoint.h>
68 
69 namespace Xyce {
70 namespace Device {
71 
73 {
74  std::vector<Param> sourceFcnParamList;
75  // Source function metadata.
76  sourceFcnParamList.resize(7);
77  sourceFcnParamList[0].set("V1", 0.0);
78  sourceFcnParamList[1].set("V2", 0.0);
79  sourceFcnParamList[2].set("TD", 0.0);
80  sourceFcnParamList[3].set("TR", 0.0);
81  sourceFcnParamList[4].set("TF", 0.0);
82  sourceFcnParamList[5].set("PW", 0.0);
83  sourceFcnParamList[6].set("PER", 0.0);
84  sourceFcnMap[ "PULSE" ] = sourceFcnParamList;
85 
86  sourceFcnParamList.resize(6);
87  sourceFcnParamList[0].set("V0", 0.0);
88  sourceFcnParamList[1].set("VA", 0.0);
89  sourceFcnParamList[2].set("FREQ", 0.0);
90  sourceFcnParamList[3].set("TD", 0.0);
91  sourceFcnParamList[4].set("THETA", 0.0);
92  sourceFcnParamList[5].set("PHASE", 0.0);
93  sourceFcnMap[ "SIN" ] = sourceFcnParamList;
94 
95  sourceFcnParamList.resize(6);
96  sourceFcnParamList[0].set("V1", 0.0);
97  sourceFcnParamList[1].set("V2", 0.0);
98  sourceFcnParamList[2].set("TD1", 0.0);
99  sourceFcnParamList[3].set("TAU1", 0.0);
100  sourceFcnParamList[4].set("TD2", 0.0);
101  sourceFcnParamList[5].set("TAU2", 0.0);
102  sourceFcnMap[ "EXP" ] = sourceFcnParamList;
103  sourceFcnParamList.resize(5);
104  sourceFcnParamList[0].set("V0", 0.0);
105  sourceFcnParamList[1].set("VA", 0.0);
106  sourceFcnParamList[2].set("FC", 0.0);
107  sourceFcnParamList[3].set("MDI", 0.0);
108  sourceFcnParamList[4].set("FS", 0.0);
109  sourceFcnMap[ "SFFM" ] = sourceFcnParamList;
110 
111 // sourceFcnParamList is empty for source function "PWL" indicating
112  // that it needs special handling in NetlistHandler.C
113  sourceFcnParamList.clear();
114  sourceFcnMap[ "PWL" ] = sourceFcnParamList;
115 
116  sourceFcnParamList.resize(8);
117  sourceFcnParamList[0].set("V1", 0.0);
118  sourceFcnParamList[1].set("V2", 0.0);
119  sourceFcnParamList[2].set("TD", 0.0);
120  sourceFcnParamList[3].set("TR", 0.0);
121  sourceFcnParamList[4].set("TF", 0.0);
122  sourceFcnParamList[5].set("PW", 0.0);
123  sourceFcnParamList[6].set("PER", 0.0);
124  sourceFcnParamList[7].set("SF", 0.0);
125  sourceFcnMap[ "SMOOTHPULSE" ] = sourceFcnParamList;
126 }
127 
128 
129 //-----------------------------------------------------------------------------
130 // Function : SourceData::SourceData
131 // Purpose : constructor
132 // Special Notes :
133 // Scope : public
134 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
135 // Creation Date : 4/24/00
136 //-----------------------------------------------------------------------------
138  const DeviceOptions & do1)
139  : SourceValue(0.0),
140  initializeFlag_(false),
141  resetFlag_(true),
142  solState_(ss1),
143  time(0.0),
144  devOptions_(do1),
145  typeName_(""),
146  sourceName_(""),
147  defaultParamName_("") ,
148  fastTimeScaleFlag_(false),
149  realFlag_(true)
150 {}
151 
152 //-----------------------------------------------------------------------------
153 // Function : SourceData::SourceData
154 // Purpose : copy constructor
155 // Special Notes :
156 // Scope : public
157 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
158 // Creation Date : 4/24/00
159 //-----------------------------------------------------------------------------
161  : SourceValue (right.SourceValue),
162  initializeFlag_(right.initializeFlag_),
163  resetFlag_(right.resetFlag_),
164  solState_(right.solState_),
165  time(right.time),
166  devOptions_(right.devOptions_),
167  typeName_(right.typeName_),
168  sourceName_(right.sourceName_),
169  defaultParamName_(right.defaultParamName_)
170 {}
171 
172 //-----------------------------------------------------------------------------
173 // Function : SourceData::~SourceData
174 // Purpose : destructor
175 // Special Notes :
176 // Scope : public
177 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
178 // Creation Date : 4/24/00
179 //-----------------------------------------------------------------------------
181 {}
182 
183 //-----------------------------------------------------------------------------
184 // Function : SourceData::initializeSource
185 // Purpose : Base class initialization function.
186 // Special Notes :
187 // Scope : public
188 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
189 // Creation Date : 9/04/01
190 //-----------------------------------------------------------------------------
192 {
193  initializeFlag_ = true;
194  return true;
195 }
196 
197 //-----------------------------------------------------------------------------
198 // Function : SourceData::returnSource
199 // Purpose :
200 // Special Notes :
201 // Scope : public
202 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
203 // Creation Date : 4/24/00
204 //-----------------------------------------------------------------------------
206 {
207  return SourceValue;
208 }
209 
210 //-----------------------------------------------------------------------------
211 // Function : SourceData::returnSource
212 // Purpose :
213 // Special Notes :
214 // Scope : public
215 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
216 // Creation Date : 4/24/00
217 //-----------------------------------------------------------------------------
219 {
220  return typeName_;
221 }
222 
223 
224 
225 #ifdef Xyce_DEBUG_DEVICE
226 //-----------------------------------------------------------------------------
227 // Function : SourceData::printOutParams
228 // Purpose :
229 // Special Notes :
230 // Scope : public
231 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
232 // Creation Date : 6/21/00
233 //-----------------------------------------------------------------------------
234 void SourceData::printOutParams()
235 {
236 
237 }
238 #endif
239 
240 //-----------------------------------------------------------------------------
241 // Function : SourceData::getMaxTimeStepSize
242 // Purpose :
243 // Special Notes :
244 // Scope : public
245 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
246 // Creation Date : 4/01/02
247 //-----------------------------------------------------------------------------
249 {
251 }
252 
253 //-----------------------------------------------------------------------------
254 // Function : SourceData::getTime_
255 // Purpose :
256 // Special Notes :
257 // Scope : protected
258 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
259 // Creation Date : 3/25/04
260 //-----------------------------------------------------------------------------
262 {
263  double tmpTime = 0.0;
264 
265 //#ifdef Xyce_MPDE
266  if (fastTimeScaleFlag_)
267  tmpTime = solState_.currFastTime;
268  else
269 //#endif // Xyce_MPDE
270  tmpTime = solState_.currTime;
271 
272 #ifdef Xyce_DEBUG_DEVICE
273 //#ifdef Xyce_MPDE
275  {
276  Xyce::dout() << "SourceData::getTime. time = ";
277  Xyce::dout() << tmpTime << std::endl;
278  Xyce::dout() << "SourceData::getTime. currFastTime = ";
279  Xyce::dout() << solState_.currFastTime<< std::endl;
280  Xyce::dout() << "SourceData::getTime. currTime = ";
281  Xyce::dout() << solState_.currTime << std::endl;
282  }
283 //#endif // Xyce_MPDE
284 #endif
285  return tmpTime;
286 }
287 
288 // Class SinData
289 
290 //-----------------------------------------------------------------------------
291 // Function : SinData::SinData
292 // Purpose : copy constructor
293 // Special Notes :
294 // Scope : public
295 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
296 // Creation Date : 3/16/00
297 //-----------------------------------------------------------------------------
298 SinData::SinData(const SinData & right)
299  : SourceData(right),
300  V0(right.V0),
301  VA(right.VA),
302  FREQ(right.FREQ),
303  TD(right.TD),
304  THETA(right.THETA),
305  PHASE(right.PHASE),
306  V0given(right.V0given),
307  VAgiven(right.VAgiven),
308  FREQgiven(right.FREQgiven),
309  TDgiven(right.TDgiven),
310  THETAgiven(right.THETAgiven),
311  PHASEgiven(right.PHASEgiven)
312 {
313 
314 }
315 
316 //-----------------------------------------------------------------------------
317 // Function : SinData::SinData
318 // Purpose : constructor
319 // Special Notes :
320 // Scope : public
321 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
322 // Creation Date : 3/16/00
323 //
324 // From 3f5: remember to incorporate this later:
325 //
326 //-----------------------------------------------------------------------------
327 #if 0
328  // this is from 3f5:
329  #define FREQ (((here->VSRCfunctionOrder >=3) && (*(here->VSRCcoeffs+2)))? \
330  (*(here->VSRCcoeffs+2)):(1/ckt->CKTfinalTime))
331 #endif
332 
333 SinData::SinData( const std::vector<Param> & paramRef,
334  const SolverState & ss1,
335  const DeviceOptions & do1)
336  : SourceData(ss1,do1),
337  V0(0.0),
338  VA(0.0),
339  FREQ(0.0),
340  TD(0.0),
341  THETA(0.0),
342  PHASE(0.0),
343  V0given(false),
344  VAgiven(false),
345  FREQgiven(false),
346  TDgiven(false),
347  THETAgiven(false),
348  PHASEgiven(false)
349 {
350  std::vector<Param>::const_iterator iter = paramRef.begin();
351  std::vector<Param>::const_iterator last = paramRef.end();
352 
353  for ( ; iter != last; ++iter)
354  {
355  const std::string & tmpname = iter->tag();
356 
357  if (tmpname == "V0") { V0 = iter->getImmutableValue<double>(); V0given = iter->given();}
358  if (tmpname == "VA") { VA = iter->getImmutableValue<double>(); VAgiven = iter->given();}
359  if (tmpname == "FREQ") { FREQ = iter->getImmutableValue<double>(); FREQgiven = iter->given();}
360  if (tmpname == "TD") { TD = iter->getImmutableValue<double>(); TDgiven = iter->given();}
361  if (tmpname == "THETA") { THETA = iter->getImmutableValue<double>(); THETAgiven = iter->given();}
362  if (tmpname == "PHASE") { PHASE = iter->getImmutableValue<double>(); PHASEgiven = iter->given();}
363  }
364 
365  if (!(V0given && VAgiven && FREQgiven))
366  Report::UserError() << "V0, VA and FREQ are required for the SIN source function";
367 
368  typeName_ = "SIN";
369  defaultParamName_ = "V0";
370 }
371 
372 //-----------------------------------------------------------------------------
373 // Function : SinData::initializeSource
374 // Purpose :
375 // Special Notes :
376 // Scope : public
377 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
378 // Creation Date : 9/04/01
379 //-----------------------------------------------------------------------------
381 {
382 
383  // If neccessary, set defaults:
384  double tstop = solState_.finalTime;
385 
386  if (!FREQgiven) FREQ = 1.0/tstop;
387  if (!TDgiven) TD = 0.0;
388  if (!THETAgiven) THETA = 0.0;
389 
390  initializeFlag_ = true;
391 
392  return true;
393 }
394 
395 //-----------------------------------------------------------------------------
396 // Function : SinData::~SinData
397 // Purpose : destructor
398 // Special Notes :
399 // Scope : public
400 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
401 // Creation Date : 3/16/00
402 //-----------------------------------------------------------------------------
404 {
405 
406 }
407 
408 #ifdef Xyce_DEBUG_DEVICE
409 //-----------------------------------------------------------------------------
410 // Function : SinData::printOutParams
411 // Purpose :
412 // Special Notes :
413 // Scope : public
414 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
415 // Creation Date : 6/21/00
416 //-----------------------------------------------------------------------------
417 
418 void SinData::printOutParams()
419 
420 {
421  Xyce::dout() << "SinData:\n";
422  Xyce::dout() << "V0 = " << V0 << std::endl;
423  Xyce::dout() << "VA = " << VA << std::endl;
424  Xyce::dout() << "FREQ = " << FREQ << std::endl;
425  Xyce::dout() << "TD = " << TD << std::endl;
426  Xyce::dout() << "THETA = " << THETA << std::endl;
427  Xyce::dout() << "PHASE = " << PHASE << std::endl;
428 }
429 #endif
430 
431 // Additional Declarations
432 
433 //-----------------------------------------------------------------------------
434 // Function : SinData::updateSource
435 // Purpose : Update the sinwave source.
436 // Special Notes :
437 //
438 // V0 - offset (V or A)
439 // VA - Amplitude (V or A)
440 // FREQ - frequency in Hz
441 // TD - delay in seconds
442 // THETA - damping factor (Hz).
443 // PHASE - phase (degrees)
444 //
445 // Scope : public
446 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
447 // Creation Date : 4/24/00
448 //-----------------------------------------------------------------------------
450 {
451  bool bsuccess = true;
452 
453  if (!initializeFlag_) bsuccess = initializeSource ();
454 
455 //#ifdef Xyce_MPDE
456  time = getTime_();
457 //#else
458 // time = solState_.currTime;
459 //#endif // Xyce_MPDE
460 
461  time -= TD;
462  double mpi = M_PI;
463  if (time <= 0)
464  {
465  //SourceValue = V0;
466  SourceValue = V0 + VA * sin (2.0*mpi*(PHASE/360)) ;
467  }
468  else
469  {
470  // 2PI to convert from hz to radians/sec
471  SourceValue = V0 + VA * sin (2.0*mpi*(FREQ*time + PHASE/360)) *
472  exp( -(time*THETA));
473  }
474 
475  resetFlag_ = false;
476  return bsuccess;
477 }
478 
479 //-----------------------------------------------------------------------------
480 // Function : SinData::getParams
481 // Purpose : Pass back the sine source params.
482 // Special Notes : TD and FREQ are interchanged from their normal order
483 // to accomodate the storage layout in the device classes
484 //
485 // Scope : public
486 // Creator : Dave Shirley, PSSI
487 // Creation Date : 4/14/05
488 //-----------------------------------------------------------------------------
489 void SinData::getParams(double *params)
490 {
491  params[0] = V0;
492  params[1] = VA;
493  params[2] = TD;
494  params[3] = FREQ;
495  params[4] = THETA;
496  params[5] = PHASE;
497 }
498 
499 //-----------------------------------------------------------------------------
500 // Function : SinData::setParams
501 // Purpose : Update the sine source params.
502 // Special Notes : TD and FREQ are interchanged from their normal order
503 // to accomodate the storage layout in the device classes
504 //
505 // Scope : public
506 // Creator : Dave Shirley, PSSI
507 // Creation Date : 4/14/05
508 //-----------------------------------------------------------------------------
509 void SinData::setParams(double *params)
510 {
511  bool reset=false;
512  if (V0 != params[0])
513  {
514  V0 = params[0];
515  reset = true;
516  }
517  if (VA != params[1])
518  {
519  VA = params[1];
520  reset = true;
521  }
522  if (TD != params[2])
523  {
524  TD = params[2];
525  reset = true;
526  }
527  if (FREQ != params[3])
528  {
529  FREQ = params[3];
530  reset = true;
531  }
532  if (THETA != params[4])
533  {
534  THETA = params[4];
535  reset = true;
536  }
537  if (PHASE != params[5])
538  {
539  PHASE = params[5];
540  reset = true;
541  }
542  if (reset)
543  {
544  updateSource();
545  }
546 }
547 
548 // Class ExpData
549 
550 //-----------------------------------------------------------------------------
551 // Function : ExpData::ExpData
552 // Purpose : copy constructor
553 // Special Notes :
554 // Scope : public
555 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
556 // Creation Date : 3/16/00
557 //-----------------------------------------------------------------------------
559  : SourceData(right),
560  V1 (right.V1),
561  V2 (right.V2),
562  TD1 (right.TD1),
563  TAU1 (right.TAU1),
564  TD2 (right.TD2),
565  TAU2 (right.TAU2),
566  V1given (right.V1given),
567  V2given (right.V2given),
568  TD1given (right.TD1given),
569  TAU1given (right.TAU1given),
570  TD2given (right.TD2given),
571  TAU2given (right.TAU2given)
572 {}
573 
574 //-----------------------------------------------------------------------------
575 // Function : ExpData::ExpData
576 // Purpose : constructor
577 // Special Notes :
578 // Scope : public
579 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
580 // Creation Date : 3/16/00
581 //-----------------------------------------------------------------------------
582 ExpData::ExpData(const std::vector<Param> & paramRef,
583  const SolverState & ss1,
584  const DeviceOptions & do1)
585  : SourceData(ss1,do1),
586  V1 (0.0),
587  V2 (0.0),
588  TD1 (0.0),
589  TAU1 (0.0),
590  TD2 (0.0),
591  TAU2 (0.0),
592  V1given (false),
593  V2given (false),
594  TD1given (false),
595  TAU1given (false),
596  TD2given (false),
597  TAU2given (false)
598 {
599  // Set the user-defined params:
600  std::vector<Param>::const_iterator iter = paramRef.begin();
601  std::vector<Param>::const_iterator last = paramRef.end();
602 
603  for ( ; iter != last; ++iter)
604  {
605  const std::string & tmpname = iter->tag();
606 
607  if (tmpname == "V1") { V1 = iter->getImmutableValue<double>(); V1given = iter->given();}
608  if (tmpname == "V2") { V2 = iter->getImmutableValue<double>(); V2given = iter->given();}
609  if (tmpname == "TD1") { TD1 = iter->getImmutableValue<double>(); TD1given = iter->given();}
610  if (tmpname == "TAU1") { TAU1 = iter->getImmutableValue<double>(); TAU1given = iter->given();}
611  if (tmpname == "TD2") { TD2 = iter->getImmutableValue<double>(); TD2given = iter->given();}
612  if (tmpname == "TAU2") { TAU2 = iter->getImmutableValue<double>(); TAU2given = iter->given();}
613  }
614 
615  if (!(V1given && V2given))
616  Report::UserError() << "V1 and V2 are required for the EXP source function";
617 
618  typeName_ = "EXP";
619  defaultParamName_ = "V1";
620 }
621 
622 //-----------------------------------------------------------------------------
623 // Function : ExpData::~ExpData
624 // Purpose : destructor
625 // Special Notes :
626 // Scope : public
627 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
628 // Creation Date : 3/16/00
629 //-----------------------------------------------------------------------------
631 {
632 
633 }
634 
635 // Additional Declarations
636 
637 #ifdef Xyce_DEBUG_DEVICE
638 //-----------------------------------------------------------------------------
639 // Function : ExpData::printOutParams
640 // Purpose :
641 // Special Notes :
642 // Scope : public
643 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
644 // Creation Date : 6/21/00
645 //-----------------------------------------------------------------------------
646 void ExpData::printOutParams()
647 {
648  Xyce::dout() << "ExpData:\n";
649 
650  Xyce::dout() << "V1 = " << V1 << std::endl;
651  Xyce::dout() << "V2 = " << V2 << std::endl;
652 
653  Xyce::dout() << "TD1 = " << TD1 << std::endl;
654  Xyce::dout() << "TAU1 = " << TAU1 << std::endl;
655 
656  Xyce::dout() << "TD2 = " << TD2 << std::endl;
657  Xyce::dout() << "TAU2 = " << TAU2 << std::endl;
658 
659 }
660 #endif
661 
662 //-----------------------------------------------------------------------------
663 // Function : ExpData::initializeSource
664 // Purpose :
665 // Special Notes :
666 // Scope : public
667 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
668 // Creation Date : 9/04/01
669 //-----------------------------------------------------------------------------
671 {
672  // If neccessary, set defaults:
673  double tstep = solState_.startingTimeStep;
674 
675  if (!TD1given) TD1 = 0.0;
676  if (!TAU1given) TAU1 = tstep;
677  if (!TD2given) TD2 = TD1 + tstep;
678  if (!TAU2given) TAU2 = tstep;
679 
680  initializeFlag_ = true;
681 
682  return true;
683 }
684 
685 //-----------------------------------------------------------------------------
686 // Function : ExpData::updateSource
687 // Purpose : Updates an exponential source:
688 // Special Notes :
689 //
690 // V1 - Initial value (V or A)
691 // V2 - Pulsed value (V or A).
692 // TD1 - Rise delay time (seconds).
693 // TAU1 - Rise time constant (seconds)
694 // TD2 - Fall delay time (seconds).
695 // TAU2 - Fall time constant (seconds)
696 //
697 // Scope : public
698 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
699 // Creation Date : 4/24/00
700 //-----------------------------------------------------------------------------
701 
703 
704 {
705  bool bsuccess = true;
706 
707  if (!initializeFlag_) bsuccess = initializeSource ();
708 
709 //#ifdef Xyce_MPDE
710  time = getTime_();
711 //#else
712 // time = solState_.currTime;
713 //#endif // Xyce_MPDE
714 
715  if (time <= TD1)
716  {
717  SourceValue = V1;
718  }
719  else if (time <= TD2)
720  {
721  SourceValue = V1 + (V2-V1)*(1-exp(-(time-TD1)/TAU1));
722  }
723  else
724  {
725  SourceValue = V1 + (V2-V1)*(1-exp(-(time-TD1)/TAU1)) +
726  (V1-V2)*(1-exp(-(time-TD2)/TAU2)) ;
727  }
728 
729  resetFlag_ = false;
730 
731  return bsuccess;
732 
733 }
734 
735 //-----------------------------------------------------------------------------
736 // Function : ExpData::getParams
737 // Purpose : Pass back the exponential source params.
738 // Special Notes :
739 //
740 // Scope : public
741 // Creator : Dave Shirley, PSSI
742 // Creation Date : 4/14/05
743 //-----------------------------------------------------------------------------
744 void ExpData::getParams(double *params)
745 {
746  params[0] = V1;
747  params[1] = V2;
748  params[2] = TD1;
749  params[3] = TAU1;
750  params[4] = TD2;
751  params[5] = TAU2;
752 }
753 
754 //-----------------------------------------------------------------------------
755 // Function : ExpData::setParams
756 // Purpose : Update the exponential source params.
757 // Special Notes :
758 //
759 // Scope : public
760 // Creator : Dave Shirley, PSSI
761 // Creation Date : 4/14/05
762 //-----------------------------------------------------------------------------
763 void ExpData::setParams(double *params)
764 {
765  bool reset=false;
766  if (V1 != params[0])
767  {
768  V1 = params[0];
769  reset = true;
770  }
771  if (V2 != params[1])
772  {
773  V2 = params[1];
774  reset = true;
775  }
776  if (TD1 != params[2])
777  {
778  TD1 = params[2];
779  reset = true;
780  }
781  if (TAU1 != params[3])
782  {
783  TAU1 = params[3];
784  reset = true;
785  }
786  if (TD2 != params[4])
787  {
788  TD2 = params[4];
789  reset = true;
790  }
791  if (TAU2 != params[5])
792  {
793  TAU2 = params[5];
794  reset = true;
795  }
796  if (reset)
797  {
798  updateSource();
799  }
800 }
801 
802 // Class PulseData
803 //-----------------------------------------------------------------------------
804 // Function : PulseData::PulseData
805 // Purpose : copy constructor
806 // Special Notes :
807 // Scope : public
808 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
809 // Creation Date : 3/16/00
810 //-----------------------------------------------------------------------------
812  : SourceData(right),
813  V1 (right.V1),
814  V2 (right.V2),
815  TD (right.TD),
816  TR (right.TR),
817  TF (right.TF),
818  PW (right.PW),
819  PER (right.PER),
820  V1given (right.V1given),
821  V2given (right.V2given),
822  TDgiven (right.TDgiven),
823  TRgiven (right.TRgiven),
824  TFgiven (right.TFgiven),
825  PWgiven (right.PWgiven),
826  PERgiven (right.PERgiven)
827 {
828 
829 }
830 
831 //-----------------------------------------------------------------------------
832 // Function : PulseData::PulseData
833 // Purpose : constructor
834 // Special Notes :
835 // Scope : public
836 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
837 // Creation Date : 3/16/00
838 //-----------------------------------------------------------------------------
839 PulseData::PulseData( const std::vector<Param> & paramRef,
840  const SolverState & ss1,
841  const DeviceOptions & do1)
842  : SourceData (ss1,do1),
843  V1 (0.0),
844  V2 (0.0),
845  TD (0.0),
846  TR (0.0),
847  TF (0.0),
848  PW (0.0),
849  PER (0.0),
850  V1given (false),
851  V2given (false),
852  TDgiven (false),
853  TRgiven (false),
854  TFgiven (false),
855  PWgiven (false),
856  PERgiven (false)
857 {
858 
859  // Get the user-defined values:
860  std::vector<Param>::const_iterator iter = paramRef.begin();
861  std::vector<Param>::const_iterator last = paramRef.end();
862 
863  for ( ; iter != last; ++iter)
864  {
865  const std::string & tmpname = iter->tag();
866 
867  if (tmpname == "V1") { V1 = iter->getImmutableValue<double>(); V1given = iter->given();}
868  if (tmpname == "V2") { V2 = iter->getImmutableValue<double>(); V2given = iter->given();}
869  if (tmpname == "TD") { TD = iter->getImmutableValue<double>(); TDgiven = iter->given();}
870  if (tmpname == "TR") { TR = iter->getImmutableValue<double>(); TRgiven = iter->given();}
871  if (tmpname == "TF") { TF = iter->getImmutableValue<double>(); TFgiven = iter->given();}
872  if (tmpname == "PW") { PW = iter->getImmutableValue<double>(); PWgiven = iter->given();}
873  if (tmpname == "PER") { PER = iter->getImmutableValue<double>(); PERgiven = iter->given();}
874  }
875 
876  typeName_ = "PULSE";
877  defaultParamName_ = "V2";
878 }
879 
880 //-----------------------------------------------------------------------------
881 // Function : PulseData::~PulseData
882 // Purpose : destructor
883 // Special Notes :
884 // Scope : public
885 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
886 // Creation Date : 3/16/00
887 //-----------------------------------------------------------------------------
889 {
890 
891 }
892 
893 // Additional Declarations
894 
895 #ifdef Xyce_DEBUG_DEVICE
896 //-----------------------------------------------------------------------------
897 // Function : PulseData::printOutParams
898 // Purpose :
899 // Special Notes :
900 // Scope : public
901 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
902 // Creation Date : 6/21/00
903 //-----------------------------------------------------------------------------
904 void PulseData::printOutParams()
905 {
906  Xyce::dout() << std::endl;
907  Xyce::dout() << " PulseData::printOutParams\n";
908  Xyce::dout() << " V1 = " << V1 << std::endl;
909  Xyce::dout() << " V2 = " << V2 << std::endl;
910 
911  Xyce::dout() << " TD = " << TD << std::endl;
912  Xyce::dout() << " TR = " << TR << std::endl;
913  Xyce::dout() << " TF = " << TF << std::endl;
914  Xyce::dout() << " PW = " << PW << std::endl;
915  Xyce::dout() << " PER = " << PER << std::endl;
916  Xyce::dout() << std::endl;
917 
918 }
919 #endif
920 
921 //-----------------------------------------------------------------------------
922 // Function : PulseData::initializeSource
923 // Purpose :
924 // Special Notes :
925 // Scope : public
926 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
927 // Creation Date : 9/04/01
928 //-----------------------------------------------------------------------------
930 {
931  // If neccessary, set the defaults:
932 
933  double tstep = solState_.startingTimeStep;
934  double tstop = solState_.finalTime;
935 
936  if (!TDgiven) TD = 0.0;
937  if (!TRgiven) TR = tstep;
938  if (!TFgiven) TF = tstep;
939  if (!PWgiven) PW = tstop;
940  if (!PERgiven) PER = tstop;
941 
942  initializeFlag_ = true;
943 
944  return true;
945 }
946 
947 //-----------------------------------------------------------------------------
948 // Function : PulseData::updateSource
949 // Purpose :
950 // Special Notes :
951 // Scope : public
952 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
953 // Creation Date : 4/24/00
954 //-----------------------------------------------------------------------------
956 
957 {
958 //notused: double tstep = solState_.startingTimeStep;
959 //notused: double tstop = solState_.finalTime;
960  bool bsuccess = true;
961 
962  if (!initializeFlag_) bsuccess = initializeSource ();
963 
964  double basetime = 0;
965 
966 #ifdef Xyce_DEBUG_DEVICE
968  {
969  Xyce::dout() << " PulseData::updateSources\n";
970  printOutParams();
971  }
972 #endif
973 
974 //#ifdef Xyce_MPDE
975  time = getTime_();
976 //#else
977 // time = solState_.currTime;
978 //#endif // Xyce_MPDE
979 
980 #ifdef Xyce_DEBUG_DEVICE
982  {
983  Xyce::dout() << " Time = " << time << std::endl;
984  }
985 #endif
986 
987  time -= TD;
988 
989  if (time > PER && PER != 0.0)
990  {
991  // repeating signal - figure out where we are in period
992  basetime = PER * floor(time/PER);
993  time -= basetime;
994  }
995 
996  // This section got ugly because of a nasty roundoff bug.
997  // Instead of doing "time > X" you need also check that time
998  // is not within bptol of X.
999  // So the following translation is used:
1000  // Instead of: we do:
1001  // time > X time>X && fabs(time-x)>bptol
1002  // time <= X time<X || fabs(time-x)<bptol
1003 
1004  if (time <= 0 || (time > (TR + PW + TF) &&
1005  (fabs (time - (TR+PW+TF)) > solState_.bpTol) ) )
1006  {
1007  SourceValue = V1;
1008  }
1009  else if ((time > TR && fabs(time-TR) > solState_.bpTol)
1010  && (time < (TR + PW) || fabs (time-(TR+PW))<solState_.bpTol) )
1011  {
1012  SourceValue = V2;
1013  }
1014  else if (time > 0 &&
1015  (time < TR || fabs(time-TR) < solState_.bpTol))
1016  {
1017  if (TR != 0.0)
1018  {
1019  SourceValue = V1 + (V2 - V1) * (time) / TR;
1020  }
1021  else
1022  {
1023  SourceValue = V1;
1024  }
1025  }
1026  else
1027  { // time > (TR + PW) && <= (TR + PW + TF)
1028  if (TF != 0.0)
1029  {
1030  SourceValue = V2 + (V1 - V2) * (time - (TR + PW)) / TF;
1031  }
1032  else
1033  {
1034  SourceValue = V2; // SourceValue = 0.5 * (V1 + V2);
1035  }
1036  }
1037 
1038 #ifdef Xyce_DEBUG_DEVICE
1040  {
1041  Xyce::dout() << " SourceValue = " << SourceValue << std::endl;
1042  }
1043 #endif
1044 
1045  resetFlag_ = false;
1046 
1047  return bsuccess;
1048 }
1049 
1050 //-----------------------------------------------------------------------------
1051 // Function : PulseData::getParams
1052 // Purpose : Pass back the pulse source params.
1053 // Special Notes :
1054 //
1055 // Scope : public
1056 // Creator : Dave Shirley, PSSI
1057 // Creation Date : 4/14/05
1058 //-----------------------------------------------------------------------------
1059 void PulseData::getParams(double *params)
1060 {
1061  params[0] = V1;
1062  params[1] = V2;
1063  params[2] = TD;
1064  params[3] = TR;
1065  params[4] = TF;
1066  params[5] = PW;
1067  params[6] = PER;
1068 }
1069 
1070 //-----------------------------------------------------------------------------
1071 // Function : PulseData::setParams
1072 // Purpose : Update the pulse source params.
1073 // Special Notes :
1074 //
1075 // Scope : public
1076 // Creator : Dave Shirley, PSSI
1077 // Creation Date : 4/14/05
1078 //-----------------------------------------------------------------------------
1079 void PulseData::setParams(double *params)
1080 {
1081  bool reset=false;
1082  if (V1 != params[0])
1083  {
1084  V1 = params[0];
1085  reset = true;
1086  }
1087  if (V2 != params[1])
1088  {
1089  V2 = params[1];
1090  reset = true;
1091  }
1092  if (TD != params[2])
1093  {
1094  TD = params[2];
1095  reset = true;
1096  }
1097  if (TR != params[3])
1098  {
1099  TR = params[3];
1100  reset = true;
1101  }
1102  if (TF != params[4])
1103  {
1104  TF = params[4];
1105  reset = true;
1106  }
1107  if (PW != params[5])
1108  {
1109  PW = params[5];
1110  reset = true;
1111  }
1112  if (PER != params[6])
1113  {
1114  PER = params[6];
1115  reset = true;
1116  }
1117  if (reset)
1118  {
1119  updateSource();
1120  }
1121 }
1122 
1123 //-----------------------------------------------------------------------------
1124 // Function : PulseData::getBreakPoints
1125 // Purpose : This function adds break points to a vector of breakpoints.
1126 //
1127 // It does not bother to check them in any way, or put them
1128 // in order. It only adds them in.
1129 //
1130 // Special Notes : Like much of this file, this is adapted from spice 3f5.
1131 // Some of the stuff in it is a little hokey, and may get
1132 // removed or modified later.
1133 //
1134 // Scope : public
1135 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1136 // Creation Date : 06/08/01
1137 //-----------------------------------------------------------------------------
1139  (std::vector<N_UTL_BreakPoint> & breakPointTimes )
1140 {
1141  bool bsuccess = true;
1142 
1143  if (!initializeFlag_) bsuccess = initializeSource ();
1144 
1145  // currPeriodIndex is the integer index representing the period of
1146  // the current circuit time.
1147  int currPeriodIndex = 0;
1148 
1149  // subtract out the delay.
1150  double basetime = 0.0;
1151 
1152 //#ifdef Xyce_MPDE
1153  time = getTime_() - TD;
1154 //#else
1155 // time = solState_.currTime - TD;
1156 //#endif // Xyce_MPDE
1157 
1158 #ifdef Xyce_DEBUG_DEVICE
1159  if (devOptions_.debugLevel > 0 && solState_.debugTimeFlag)
1160  {
1161  Xyce::dout() << std::endl;
1162  Xyce::dout() << " In PulseData::getBreakPoints\n";
1163  Xyce::dout() << " time = " << time << std::endl;
1164  Xyce::dout() << " TD = " << TD << std::endl;
1165  Xyce::dout() << " PER = " << PER << std::endl;
1166  }
1167 #endif
1168 
1169  // repeating signal - figure out where we are in period
1170  if(time >= PER)
1171  {
1172  if (PER != 0.0)
1173  {
1174  currPeriodIndex = (static_cast<int> (floor(time/PER)));
1175  basetime = PER * (static_cast<double> (currPeriodIndex));
1176  time -= basetime;
1177  }
1178  }
1179 
1180 #ifdef Xyce_DEBUG_DEVICE
1181  if (devOptions_.debugLevel > 0 && solState_.debugTimeFlag)
1182  {
1183  Xyce::dout() << " time = " << time << std::endl;
1184  Xyce::dout() << " basetime = " << basetime << std::endl;
1185  Xyce::dout() << " currPeriodIndex = " << currPeriodIndex << std::endl;
1186  Xyce::dout() << std::endl;
1187  }
1188 #endif
1189 
1190  // now that we know which period this is, push_back all breakpoints
1191  // in this period and the next. If we are still in the delay, then
1192  // just use first two periods.
1193 
1194  // current period:
1195  breakPointTimes.push_back(basetime+TD);
1196  breakPointTimes.push_back(basetime+TD+TR);
1197  breakPointTimes.push_back(basetime+TD+TR+PW);
1198  breakPointTimes.push_back(basetime+TD+TR+PW+TF);
1199 
1200  if (PER != 0.0)
1201  {
1202  breakPointTimes.push_back(basetime+TD+PER);
1203 
1204  // next period:
1205  breakPointTimes.push_back(basetime+TD+PER+TR);
1206  breakPointTimes.push_back(basetime+TD+PER+TR+PW);
1207  breakPointTimes.push_back(basetime+TD+PER+TR+PW+TF);
1208  breakPointTimes.push_back(basetime+TD+PER+PER);
1209  }
1210 
1211  return bsuccess;
1212 }
1213 
1214 //-----------------------------------------------------------------------------
1215 // Function : PulseData::getMaxTimeStepSize
1216 // Purpose :
1217 // Special Notes :
1218 // Scope : public
1219 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1220 // Creation Date : 9/25/01
1221 //-----------------------------------------------------------------------------
1223 {
1224  double maxTimeStep = devOptions_.defaultMaxTimeStep;
1225 
1226  // check if we are still in the delay or not.
1227 //#ifdef Xyce_MPDE
1228  time = getTime_();
1229 //#else
1230 // time = solState_.currTime;
1231 //#endif // Xyce_MPDE
1232 
1233  if (time < TD) maxTimeStep = (0.1*TD );
1234  else maxTimeStep = (0.1*PER);
1235 
1236 #ifdef Xyce_DEBUG_DEVICE
1238  {
1239  Xyce::dout() << "\nIn PulseData::getMaxTimeStepSize. ";
1240  Xyce::dout() << " maxTimeStep = "<< maxTimeStep;
1241  Xyce::dout() << " TD = " << TD << " PER = " <<PER;
1242  Xyce::dout() << " time = "<< time << std::endl;
1243  }
1244 #endif
1245 
1246  return maxTimeStep;
1247 }
1248 
1249 // Class PWLinData
1250 
1251 //-----------------------------------------------------------------------------
1252 // Function : PWLinData::PWLinData
1253 // Purpose : copy constructor
1254 // Special Notes :
1255 // Scope : public
1256 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1257 // Creation Date : 3/16/00
1258 //-----------------------------------------------------------------------------
1260  : SourceData(right),
1261  NUM(right.NUM),
1262  REPEAT(right.REPEAT),
1263  REPEATTIME(right.REPEATTIME),
1264  TD(right.TD),
1265  TVVEC(right.TVVEC),
1266  loc_(right.loc_),
1267  starttime_(right.starttime_)
1268 {}
1269 
1270 //-----------------------------------------------------------------------------
1271 // Function : PWLinData::PWLinData
1272 // Purpose : constructor
1273 // Special Notes :
1274 // Scope : public
1275 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1276 // Creation Date : 3/16/00
1277 //-----------------------------------------------------------------------------
1278 PWLinData::PWLinData( const std::vector<Param> & paramRef,
1279  const SolverState & ss1,
1280  const DeviceOptions & do1)
1281  : SourceData(ss1,do1),
1282  NUM(0),
1283  REPEAT(false),
1284  REPEATTIME(0.0),
1285  TD(0.0),
1286  loc_(0),
1287  starttime_(0.0)
1288 {
1289  std::vector<Param>::const_iterator iter = paramRef.begin();
1290  std::vector<Param>::const_iterator last = paramRef.end();
1291 
1292  for ( ; iter != last; ++iter)
1293  {
1294  const std::string & tmpname = iter->tag();
1295  const bool & tmpgiven = iter->given();
1296 
1297  if (tmpname == "NUM") NUM = iter->getImmutableValue<int>();
1298  if (tmpname == "R" && tmpgiven == true)
1299  {
1300  REPEAT = true;
1301  REPEATTIME = iter->getImmutableValue<double>();
1302  }
1303  if (tmpname == "TD") TD = iter->getImmutableValue<double>();
1304 
1305  if ( tmpname == "T" && iter->given() )
1306  {
1307  time = iter->getImmutableValue<double>();
1308  ++iter;
1309 
1310  TVVEC.push_back(std::pair<double,double>(time, iter->getImmutableValue<double>()));
1311  }
1312  }
1313 
1314  if (NUM == 0)
1315  Report::UserError() << "At least one voltage/time pair must be specified for the PWL source function";
1316  if (REPEATTIME < 0 || REPEATTIME >=TVVEC[NUM-1].first)
1317  Report::UserError() << "PWL source's repeat value (R) must be >= 0 and < last value in Time-Voltage list";
1318 
1319  typeName_ = "PWL";
1320 }
1321 
1322 //-----------------------------------------------------------------------------
1323 // Function : PWLinData::PWLinData
1324 // Purpose : destructor
1325 // Special Notes :
1326 // Scope : public
1327 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1328 // Creation Date : 3/16/00
1329 //-----------------------------------------------------------------------------
1331 {
1332 }
1333 
1334 #ifdef Xyce_DEBUG_DEVICE
1335 //-----------------------------------------------------------------------------
1336 // Function : PWLinData::printOutParams
1337 // Purpose :
1338 // Special Notes :
1339 // Scope : public
1340 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1341 // Creation Date : 6/21/00
1342 //-----------------------------------------------------------------------------
1343 void PWLinData::printOutParams()
1344 {
1345  Xyce::dout() << std::endl;
1346  Xyce::dout() << " NUM = " << NUM << std::endl;
1347  Xyce::dout() << " REPEAT = " << REPEAT << std::endl;
1348  Xyce::dout() << " REPEATTIME = " << REPEATTIME << std::endl;
1349  Xyce::dout() << " TD = " << TD << std::endl;
1350  Xyce::dout() << " loc_ = " << loc_ << std::endl;
1351  Xyce::dout() << " starttime_ = " << starttime_ << std::endl;
1352 
1353  Xyce::dout() << " Time Voltage" << std::endl;
1354  for( int i = 0; i < NUM; ++i )
1355  Xyce::dout() << " " << TVVEC[i].first << " " << TVVEC[i].second << std::endl;
1356 
1357  Xyce::dout() << std::endl;
1358 }
1359 #endif
1360 
1361 // Additional Declarations
1362 
1363 //-----------------------------------------------------------------------------
1364 // Function : PWLinData::updateSource
1365 // Purpose :
1366 // Special Notes :
1367 // Scope : public
1368 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1369 // Creation Date : 4/24/00
1370 //-----------------------------------------------------------------------------
1372 {
1373 
1374  bool bsuccess = true;
1375 
1376  if (!initializeFlag_) bsuccess = initializeSource ();
1377 
1378 #ifdef Xyce_DEBUG_DEVICE
1380  {
1381  Xyce::dout() << std::endl;
1382  Xyce::dout() << " PWLinData::updateSource\n";
1383  printOutParams();
1384  }
1385 #endif
1386 
1387 //#ifdef Xyce_MPDE
1388  time = getTime_();
1389 //#else
1390 // time = solState_.currTime;
1391 //#endif // Xyce_MPDE
1392 
1393 #ifdef Xyce_DEBUG_DEVICE
1395  {
1396  Xyce::dout() << Xyce::section_divider << std::endl;
1397  Xyce::dout() << " Time = " << time << std::endl;
1398  }
1399 #endif
1400 
1401  double time1, time2, voltage1, voltage2;
1402  double simtime = time;
1403 
1404  if( time >= TD )
1405  {
1406  time -= TD;
1407 
1408  if( time <= TVVEC[NUM-1].first )
1409  {
1410  for( int i = 0; i < NUM; ++i )
1411  if( time < TVVEC[i].first ) {loc_ = i;break;}
1412 
1413  if( loc_ == 0 )
1414  {
1415  time1 = 0.0;
1416  voltage1 = 0.0;
1417  }
1418  else
1419  {
1420  time1 = TVVEC[loc_-1].first;
1421  voltage1 = TVVEC[loc_-1].second;
1422  }
1423  time2 = TVVEC[loc_].first;
1424  voltage2 = TVVEC[loc_].second;
1425 
1426  }
1427  else if( !REPEAT )
1428  {
1429  // this has the net-effect of setting SourceValue = voltage2
1430  // when combined with the next if-else block
1431  time1 = 0.0;
1432  time2 = 1.0;
1433  voltage1 = voltage2 = TVVEC[NUM-1].second;
1434  }
1435  else
1436  {
1437  double looptime = TVVEC[NUM-1].first - REPEATTIME;
1438  time -= TVVEC[NUM-1].first;
1439  time -= looptime * floor(time / looptime);
1440  time += REPEATTIME;
1441 
1442  for( int i = 0; i < NUM; ++i )
1443  {
1444  if( time < TVVEC[i].first ) {loc_ = i;break;}
1445  }
1446  if (time == REPEATTIME)
1447  {
1448  time1 = 0.0;
1449  time2 = 1.0;
1450  voltage1 = voltage2 = TVVEC[NUM-1].second;
1451  }
1452  else
1453  {
1454  if( loc_ == 0 )
1455  {
1456  time1 = REPEATTIME;
1457  voltage1 = TVVEC[NUM-1].second;
1458  }
1459  else
1460  {
1461  time1 = TVVEC[loc_-1].first;
1462  voltage1 = TVVEC[loc_-1].second;
1463  }
1464  time2 = TVVEC[loc_].first;
1465  voltage2 = TVVEC[loc_].second;
1466  }
1467 
1468  }
1469 
1470  if( time1 == time2 )
1471  SourceValue = voltage2;
1472  else
1473  {
1474  double length = time2 - time1;
1475  SourceValue = ( time2 - time ) * voltage1 / length;
1476  SourceValue += ( -time1 + time ) * voltage2 / length;
1477  }
1478 
1479 #ifdef Xyce_DEBUG_DEVICE
1481  {
1482  Xyce::dout() << "time: " << time << std::endl;
1483  Xyce::dout() << "time1: " << time1 << std::endl;
1484  Xyce::dout() << "time2: " << time2 << std::endl;
1485  Xyce::dout() << "voltage1: " << voltage1 << std::endl;
1486  Xyce::dout() << "voltage2: " << voltage2 << std::endl;
1487  Xyce::dout() << "Src: " << SourceValue << std::endl;
1488  Xyce::dout() << Xyce::section_divider << std::endl;
1489  }
1490 #endif
1491 
1492  }
1493  else
1494  {
1495  SourceValue = 0.0;
1496  }
1497 
1498 
1499  resetFlag_ = false;
1500 
1501  return bsuccess;
1502 }
1503 
1504 //-----------------------------------------------------------------------------
1505 // Function : PWLinData::getBreakPoints
1506 // Purpose :
1507 // Special Notes :
1508 // Scope : public
1509 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1510 // Creation Date : 06/08/01
1511 //-----------------------------------------------------------------------------
1513  (std::vector<N_UTL_BreakPoint> & breakPointTimes )
1514 {
1515  bool bsuccess = true;
1516 
1517 #ifdef Xyce_DEBUG_DEVICE
1518  if (devOptions_.debugLevel > 0 && solState_.debugTimeFlag)
1519  {
1520  Xyce::dout() << " In PWLinData::getBreakPoints\n";
1521  }
1522 #endif
1523 
1524  if (!initializeFlag_) bsuccess = initializeSource ();
1525 
1526  time = solState_.currTime;
1527 
1528  time -= TD;
1529 
1530  // if it's a repeating signal, figure out what period we are in
1531  if (REPEAT && time >= TVVEC[NUM - 1].first)
1532  {
1533  double loopBaseTime = 0.0;
1534  double bp_time;
1535 
1536  double looptime = TVVEC[NUM-1].first - REPEATTIME;
1537  loopBaseTime = looptime * (1.0 + floor((time - TVVEC[NUM - 1].first) / looptime));
1538 #ifdef Xyce_DEBUG_DEVICE
1539  if (devOptions_.debugLevel > 0 && solState_.debugTimeFlag)
1540  {
1541  Xyce::dout() << "loopBaseTime: " << loopBaseTime << std::endl;
1542  Xyce::dout() << "floor function: " << floor((time - TVVEC[NUM - 1].first) / (TVVEC[NUM - 1].first - REPEATTIME)) << std::endl;
1543  }
1544 #endif
1545 
1546  for (int i = 0; i < NUM; ++i)
1547  {
1548  bp_time = TVVEC[i].first;
1549  if (bp_time >= REPEATTIME)
1550  {
1551  breakPointTimes.push_back(bp_time + loopBaseTime + TD);
1552 #ifdef Xyce_DEBUG_DEVICE
1553  if (devOptions_.debugLevel > 0 && solState_.debugTimeFlag)
1554  {
1555  Xyce::dout() << "bp_time + loopBaseTime + TD: " << bp_time + loopBaseTime + TD << std::endl;
1556  }
1557 #endif
1558  }
1559  }
1560  }
1561  else
1562  {
1563  for (int i = 0; i < NUM; ++i)
1564  {
1565  double bp_time = TVVEC[i].first;
1566  breakPointTimes.push_back(bp_time+TD);
1567 #ifdef Xyce_DEBUG_DEVICE
1568  if (devOptions_.debugLevel > 0 && solState_.debugTimeFlag)
1569  {
1570  Xyce::dout() << "bp_time + TD: " << bp_time + TD << std::endl;
1571  }
1572 #endif
1573  }
1574  }
1575  // now that we know which period this is, push_back all breakpoints
1576  // in this period and the next.
1577 
1578  return bsuccess;
1579 }
1580 
1581 // Class SFFMData
1582 
1583 //-----------------------------------------------------------------------------
1584 // Function : SFFMData::SFFMData
1585 // Purpose : copy constructor
1586 // Special Notes : SFFM = spice frequency modulation
1587 // Scope : public
1588 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1589 // Creation Date : 3/16/00
1590 //-----------------------------------------------------------------------------
1591 
1593  : SourceData(right),
1594  V0(right.V0),
1595  VA(right.VA),
1596  FC(right.FC),
1597  MDI(right.MDI),
1598  FS(right.FS),
1599  V0given (right.V0given),
1600  VAgiven (right.VAgiven),
1601  FCgiven (right.FCgiven),
1602  MDIgiven (right.MDIgiven),
1603  FSgiven (right.FSgiven)
1604 {}
1605 
1606 //-----------------------------------------------------------------------------
1607 // Function : SFFMData::SFFMData
1608 // Purpose : constructor
1609 // Special Notes :
1610 // Scope : public
1611 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1612 // Creation Date : 3/16/00
1613 //-----------------------------------------------------------------------------
1614 
1615 SFFMData::SFFMData( const std::vector<Param> & paramRef,
1616  const SolverState & ss1,
1617  const DeviceOptions & do1)
1618  : SourceData(ss1,do1),
1619  V0 (0.0),
1620  VA (0.0),
1621  FC (0.0),
1622  MDI (0.0),
1623  FS (0.0),
1624  V0given (false),
1625  VAgiven (false),
1626  FCgiven (false),
1627  MDIgiven (false),
1628  FSgiven (false)
1629 
1630 {
1631  std::vector<Param>::const_iterator iter = paramRef.begin();
1632  std::vector<Param>::const_iterator last = paramRef.end();
1633 
1634  for ( ; iter != last; ++iter)
1635  {
1636  const std::string & tmpname = iter->tag();
1637 
1638  if (tmpname == "V0") { V0 = iter->getImmutableValue<double>(); V0given = iter->given(); }
1639  if (tmpname == "VA") { VA = iter->getImmutableValue<double>(); VAgiven = iter->given(); }
1640  if (tmpname == "FC") { FC = iter->getImmutableValue<double>(); FCgiven = iter->given(); }
1641  if (tmpname == "MDI") { MDI = iter->getImmutableValue<double>(); MDIgiven = iter->given(); }
1642  if (tmpname == "FS") { FS = iter->getImmutableValue<double>(); FSgiven = iter->given(); }
1643  }
1644 
1645  if (!(V0given && VAgiven))
1646  Report::UserError() << "V0 and VA are required for the SFFM source function";
1647 
1648  typeName_ = "SFFM";
1649 }
1650 
1651 //-----------------------------------------------------------------------------
1652 // Function : SFFMData::~SFFMData
1653 // Purpose : destructor
1654 // Special Notes :
1655 // Scope : public
1656 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1657 // Creation Date : 3/16/00
1658 //-----------------------------------------------------------------------------
1659 
1661 {
1662 
1663 }
1664 
1665 // Additional Declarations
1666 
1667 #ifdef Xyce_DEBUG_DEVICE
1668 //-----------------------------------------------------------------------------
1669 // Function : SFFMData::printOutParams
1670 // Purpose :
1671 // Special Notes :
1672 // Scope : public
1673 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1674 // Creation Date : 5/01/00
1675 //-----------------------------------------------------------------------------
1676 
1677 void SFFMData::printOutParams()
1678 {
1679  Xyce::dout() << "SFFMData:\n";
1680  Xyce::dout() << "V0 = " << V0 << std::endl;
1681  Xyce::dout() << "VA = " << VA << std::endl;
1682  Xyce::dout() << "FC = " << FC << std::endl;
1683  Xyce::dout() << "MDI = " << MDI << std::endl;
1684  Xyce::dout() << "FS = " << FS << std::endl;
1685 }
1686 #endif
1687 
1688 //-----------------------------------------------------------------------------
1689 // Function : SFFMData::initializeSource
1690 // Purpose :
1691 // Special Notes :
1692 // Scope : public
1693 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1694 // Creation Date : 9/04/01
1695 //-----------------------------------------------------------------------------
1696 
1698 {
1699  // If neccessary, set the defaults:
1700  double tstop = solState_.finalTime;
1701 
1702  if (!FCgiven) FC = 1.0/tstop;
1703  if (!FSgiven) FS = 1.0/tstop;
1704 
1705  initializeFlag_ = true;
1706 
1707  return true;
1708 }
1709 
1710 //-----------------------------------------------------------------------------
1711 // Function : SFFMData::updateSource
1712 // Purpose :
1713 // Special Notes :
1714 //
1715 // V0 - offset (V or A)
1716 // VA - Amplitude (V or A)
1717 // FC - carrier frequency
1718 // MDI - modulation index
1719 // FS - signal frequency
1720 //
1721 // Scope : public
1722 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1723 // Creation Date : 4/24/00
1724 //-----------------------------------------------------------------------------
1725 
1727 {
1728  bool bsuccess = true;
1729 
1730  if (!initializeFlag_) bsuccess = initializeSource ();
1731 
1732 //#ifdef Xyce_MPDE
1733  time = getTime_();
1734 //#else
1735 // time = solState_.currTime;
1736 //#endif // Xyce_MPDE
1737 
1738  double mpi = M_PI;
1739  SourceValue = V0 + VA * sin((2 * mpi * FC * time) +
1740  MDI * sin (2 * mpi * FS * time));
1741 
1742  resetFlag_ = false;
1743 
1744  return bsuccess;
1745 }
1746 
1747 //-----------------------------------------------------------------------------
1748 // Function : SFFMData::getParams
1749 // Purpose : Pass back the SFFM source params.
1750 // Special Notes :
1751 //
1752 // Scope : public
1753 // Creator : Dave Shirley, PSSI
1754 // Creation Date : 4/14/05
1755 //-----------------------------------------------------------------------------
1756 void SFFMData::getParams(double *params)
1757 {
1758  params[0] = V0;
1759  params[1] = VA;
1760  params[2] = FC;
1761  params[3] = MDI;
1762  params[4] = FS;
1763 }
1764 
1765 //-----------------------------------------------------------------------------
1766 // Function : SFFMData::setParams
1767 // Purpose : Update the SFFM source params.
1768 // Special Notes :
1769 //
1770 // Scope : public
1771 // Creator : Dave Shirley, PSSI
1772 // Creation Date : 4/14/05
1773 //-----------------------------------------------------------------------------
1774 void SFFMData::setParams(double *params)
1775 {
1776  bool reset=false;
1777  if (V0 != params[0])
1778  {
1779  V0 = params[0];
1780  reset = true;
1781  }
1782  if (VA != params[1])
1783  {
1784  VA = params[1];
1785  reset = true;
1786  }
1787  if (FC != params[2])
1788  {
1789  FC = params[2];
1790  reset = true;
1791  }
1792  if (MDI != params[3])
1793  {
1794  MDI = params[3];
1795  reset = true;
1796  }
1797  if (FS != params[4])
1798  {
1799  FS = params[4];
1800  reset = true;
1801  }
1802  if (reset)
1803  updateSource();
1804 }
1805 
1806 // Class ACData
1807 
1808 //-----------------------------------------------------------------------------
1809 // Function : ACData::ACData
1810 // Purpose : copy constructor
1811 // Special Notes :
1812 // Scope : public
1813 // Creator : Ting Mei, SNL
1814 // Creation Date :
1815 //-----------------------------------------------------------------------------
1816 
1817 ACData::ACData(const ACData & right)
1818  : SourceData(right),
1819  ACMAG(right.ACMAG),
1820  ACPHASE(right.ACPHASE),
1821  ACMAGgiven(right.ACMAGgiven),
1822  ACPHASEgiven(right.ACPHASEgiven)
1823 {
1824 
1825 }
1826 
1827 
1828 //-----------------------------------------------------------------------------
1829 // Function : ACData::ACData
1830 // Purpose : constructor
1831 // Special Notes :
1832 // Scope : public
1833 // Creator : Ting Mei, SNL
1834 // Creation Date :
1835 //-----------------------------------------------------------------------------
1836 
1837 ACData::ACData( const std::vector<Param> & paramRef,
1838  const SolverState & ss1,
1839  const DeviceOptions & do1)
1840  : SourceData(ss1,do1),
1841  ACMAG(1.0),
1842  ACPHASE(0.0),
1843  ACMAGgiven(false),
1844  ACPHASEgiven(false)
1845 {
1846  std::vector<Param>::const_iterator iter = paramRef.begin();
1847  std::vector<Param>::const_iterator last = paramRef.end();
1848 
1849  for ( ; iter != last; ++iter)
1850  {
1851  const std::string & tmpname = iter->tag();
1852 
1853  if (tmpname == "ACMAG") { ACMAG = iter->getImmutableValue<double>(); ACMAGgiven = iter->given();}
1854  if (tmpname == "ACPHASE") { ACPHASE = iter->getImmutableValue<double>(); ACPHASEgiven = iter->given();}
1855  }
1856 
1857  typeName_ = "AC";
1858  defaultParamName_ = "ACMAG";
1859 }
1860 
1861 //-----------------------------------------------------------------------------
1862 // Function : ACData::~ACData
1863 // Purpose : destructor
1864 // Special Notes :
1865 // Scope : public
1866 // Creator : Ting Mei, SNL
1867 // Creation Date : 3/16/00
1868 //-----------------------------------------------------------------------------
1869 
1871 {}
1872 
1873 #ifdef Xyce_DEBUG_DEVICE
1874 //-----------------------------------------------------------------------------
1875 // Function : ACData::printOutParams
1876 // Purpose :
1877 // Special Notes :
1878 // Scope : public
1879 // Creator : Ting Mei, SNL
1880 // Creation Date : 6/21/00
1881 //-----------------------------------------------------------------------------
1882 
1883 void ACData::printOutParams()
1884 
1885 {
1886  Xyce::dout() << "ACData:\n";
1887  Xyce::dout() << "ACMAG = " << ACMAG << std::endl;
1888  Xyce::dout() << "ACPHASE = " << ACPHASE << std::endl;
1889 }
1890 #endif
1891 
1892 //-----------------------------------------------------------------------------
1893 // Function : ACData::updateSource
1894 // Purpose : Update the sinwave source.
1895 // Special Notes :
1896 //
1897 // Scope : public
1898 // Creator : Ting Mei, SNL
1899 // Creation Date :
1900 //-----------------------------------------------------------------------------
1901 
1903 {
1904  bool bsuccess = true;
1905 
1906  double mpi = M_PI;
1907 
1908  if (!initializeFlag_) bsuccess = initializeSource ();
1909 
1910  if (realFlag_)
1911  {
1912  SourceValue = ACMAG * cos(2.0*mpi*ACPHASE/360);
1913  }
1914  else
1915  {
1916  SourceValue = ACMAG * sin(2.0*mpi*ACPHASE/360);
1917  }
1918 
1919 #ifdef Xyce_DEBUG_DEVICE
1920  if (devOptions_.debugLevel > 0)
1921  {
1922  Xyce::dout() << " SourceValue = " << SourceValue << std::endl;
1923  }
1924 #endif
1925 
1926  resetFlag_ = false;
1927 
1928  return bsuccess;
1929 }
1930 
1931 //-----------------------------------------------------------------------------
1932 // Function : ACData::getParams
1933 // Purpose : Pass back the AC source params.
1934 // Special Notes :
1935 // Scope : public
1936 // Creator : Ting Mei
1937 // Creation Date :
1938 //-----------------------------------------------------------------------------
1939 void ACData::getParams(double *params)
1940 {
1941  params[0] = ACMAG;
1942  params[1] = ACPHASE;
1943 }
1944 
1945 //-----------------------------------------------------------------------------
1946 // Function : ACData::setParams
1947 // Purpose : Update the AC source params.
1948 // Special Notes :
1949 //
1950 // Scope : public
1951 // Creator : Ting Mei
1952 // Creation Date :
1953 //-----------------------------------------------------------------------------
1954 void ACData::setParams(double *params)
1955 {
1956  bool reset=false;
1957  if (ACMAG!= params[0])
1958  {
1959  ACMAG = params[0];
1960  reset = true;
1961  }
1962  if ( ACPHASE != params[1])
1963  {
1964  ACPHASE = params[1];
1965  reset = true;
1966  }
1967  if (reset)
1968  updateSource();
1969 }
1970 
1971 
1972 // Class ConstData
1973 
1974 //-----------------------------------------------------------------------------
1975 // Function : ConstData::ConstData
1976 // Purpose : copy constructor
1977 // Special Notes :
1978 // Scope : public
1979 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
1980 // Creation Date : 10/5/00
1981 //-----------------------------------------------------------------------------
1983  : SourceData(right),
1984  V0(right.V0)
1985 {
1986 
1987 }
1988 
1989 //-----------------------------------------------------------------------------
1990 // Function : ConstData::ConstData
1991 // Purpose : constructor
1992 // Special Notes :
1993 // Scope : public
1994 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
1995 // Creation Date : 10/5/00
1996 //-----------------------------------------------------------------------------
1997 
1998 ConstData::ConstData( const std::vector<Param> & paramRef,
1999  const SolverState & ss1,
2000  const DeviceOptions & do1)
2001  : SourceData(ss1,do1),
2002  V0(0.0)
2003 {
2004  std::vector<Param>::const_iterator iter = paramRef.begin();
2005  std::vector<Param>::const_iterator last = paramRef.end();
2006 
2007  for ( ; iter != last; ++iter)
2008  {
2009  const std::string & tmpname = iter->tag();
2010  if (tmpname == "DCV0")
2011  {
2012  V0 = iter->getImmutableValue<double>();
2013  }
2014  }
2015 
2016  typeName_ = "CONST";
2017  defaultParamName_ = "DCV0";
2018 // SourceValue = V0; // updateSource function is a no-op, essentially.
2019 }
2020 
2021 //-----------------------------------------------------------------------------
2022 // Function : ConstData::~ConstData
2023 // Purpose : destructor
2024 // Special Notes :
2025 // Scope : public
2026 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
2027 // Creation Date : 10/5/00
2028 //-----------------------------------------------------------------------------
2030 {
2031 
2032 }
2033 
2034 #ifdef Xyce_DEBUG_DEVICE
2035 //-----------------------------------------------------------------------------
2036 // Function : ConstData::printOutParams
2037 // Purpose :
2038 // Special Notes :
2039 // Scope : public
2040 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
2041 // Creation Date : 10/5/00
2042 //-----------------------------------------------------------------------------
2043 
2044 void ConstData::printOutParams()
2045 
2046 {
2047  Xyce::dout() << "ConstData:\n";
2048  Xyce::dout() << "V0: " << V0 << std::endl;
2049 }
2050 #endif
2051 
2052 // Additional Declarations
2053 
2054 //-----------------------------------------------------------------------------
2055 // Function : ConstData::updateSource
2056 // Purpose : Update the const source.
2057 // Special Notes : ERK: this is now a no-op, as the source value is set in
2058 // the constructor. The value for this source never changes,
2059 // so there isn't any point is re-setting the same value
2060 // over and over.
2061 //
2062 // Scope : public
2063 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
2064 // Creation Date : 10/5/00
2065 //-----------------------------------------------------------------------------
2067 {
2068 
2069  bool bsuccess = true;
2070 
2071  if (!initializeFlag_) bsuccess = initializeSource ();
2072 
2073  SourceValue = V0;
2074 
2075  resetFlag_ = false;
2076 
2077  return bsuccess;
2078 
2079 }
2080 
2081 //-----------------------------------------------------------------------------
2082 // Function : ConstData::getParams
2083 // Purpose : Pass back the const source params.
2084 // Special Notes :
2085 //
2086 // Scope : public
2087 // Creator : Dave Shirley, PSSI
2088 // Creation Date : 4/13/05
2089 //-----------------------------------------------------------------------------
2090 void ConstData::getParams(double *params)
2091 {
2092  params[0] = V0;
2093 }
2094 
2095 //-----------------------------------------------------------------------------
2096 // Function : ConstData::setParams
2097 // Purpose : Update the const source params.
2098 // Special Notes :
2099 //
2100 // Scope : public
2101 // Creator : Dave Shirley, PSSI
2102 // Creation Date : 4/13/05
2103 //-----------------------------------------------------------------------------
2104 void ConstData::setParams(double *params)
2105 {
2106  if (V0 != params[0])
2107  {
2108  V0 = params[0];
2109 // SourceValue = V0;
2110  updateSource();
2111  }
2112 }
2113 
2114 
2115 // Class SmoothPulseData
2116 //-----------------------------------------------------------------------------
2117 // Function : SmoothPulseData::SmoothPulseData
2118 // Purpose : copy constructor
2119 // Special Notes :
2120 // Scope : public
2121 // Creator : Richard Schiek, Electrical Systems Modeling
2122 // Creation Date : 04/13/11
2123 //-----------------------------------------------------------------------------
2124 
2126  : SourceData(right),
2127  V1 (right.V1),
2128  V2 (right.V2),
2129  TD (right.TD),
2130  TR (right.TR),
2131  TF (right.TF),
2132  PW (right.PW),
2133  PER (right.PER),
2134  riseScaleFactor_(right.riseScaleFactor_),
2135  fallScaleFactor_(right.fallScaleFactor_),
2136  functionScaleFactor_(right.functionScaleFactor_),
2137  V1given (right.V1given),
2138  V2given (right.V2given),
2139  TDgiven (right.TDgiven),
2140  TRgiven (right.TRgiven),
2141  TFgiven (right.TFgiven),
2142  PWgiven (right.PWgiven),
2143  PERgiven (right.PERgiven),
2144  functionScaleFactorGiven_(right.functionScaleFactorGiven_)
2145 {
2146 
2147 }
2148 
2149 //-----------------------------------------------------------------------------
2150 // Function : SmoothPulseData::SmoothPulseData
2151 // Purpose : constructor
2152 // Special Notes :
2153 // Scope : public
2154 // Creator : Richard Schiek, Electrical Systems Modeling
2155 // Creation Date : 04/13/11
2156 //-----------------------------------------------------------------------------
2157 
2158 SmoothPulseData::SmoothPulseData( const std::vector<Param> & paramRef,
2159  const SolverState & ss1,
2160  const DeviceOptions & do1)
2161  : SourceData (ss1,do1),
2162  V1 (0.0),
2163  V2 (0.0),
2164  TD (0.0),
2165  TR (0.0),
2166  TF (0.0),
2167  PW (0.0),
2168  PER (0.0),
2169  riseScaleFactor_(0.0),
2170  fallScaleFactor_(0.0),
2171  functionScaleFactor_(20.0),
2172  V1given (false),
2173  V2given (false),
2174  TDgiven (false),
2175  TRgiven (false),
2176  TFgiven (false),
2177  PWgiven (false),
2178  PERgiven (false),
2179  functionScaleFactorGiven_(false)
2180 {
2181 
2182  // Get the user-defined values:
2183  std::vector<Param>::const_iterator iter = paramRef.begin();
2184  std::vector<Param>::const_iterator last = paramRef.end();
2185 
2186  for ( ; iter != last; ++iter)
2187  {
2188  const std::string & tmpname = iter->tag();
2189 
2190  if (tmpname == "V1") { V1 = iter->getImmutableValue<double>(); V1given = iter->given();}
2191  if (tmpname == "V2") { V2 = iter->getImmutableValue<double>(); V2given = iter->given();}
2192  if (tmpname == "TD") { TD = iter->getImmutableValue<double>(); TDgiven = iter->given();}
2193  if (tmpname == "TR") { TR = iter->getImmutableValue<double>(); TRgiven = iter->given();}
2194  if (tmpname == "TF") { TF = iter->getImmutableValue<double>(); TFgiven = iter->given();}
2195  if (tmpname == "PW") { PW = iter->getImmutableValue<double>(); PWgiven = iter->given();}
2196  if (tmpname == "PER") { PER = iter->getImmutableValue<double>(); PERgiven = iter->given();}
2197  if (tmpname == "SF") { functionScaleFactor_ = iter->getImmutableValue<double>(); functionScaleFactorGiven_ = iter->given();}
2198  }
2199 
2200  typeName_ = "SMOOTHPULSE";
2201  defaultParamName_ = "V2";
2202 }
2203 
2204 //-----------------------------------------------------------------------------
2205 // Function : SmoothPulseData::~SmoothPulseData
2206 // Purpose : destructor
2207 // Special Notes :
2208 // Scope : public
2209 // Creator : Richard Schiek, Electrical Systems Modeling
2210 // Creation Date : 04/13/11
2211 //-----------------------------------------------------------------------------
2212 
2214 {
2215 
2216 }
2217 
2218 // Additional Declarations
2219 
2220 #ifdef Xyce_DEBUG_DEVICE
2221 //-----------------------------------------------------------------------------
2222 // Function : SmoothPulseData::printOutParams
2223 // Purpose :
2224 // Special Notes :
2225 // Scope : public
2226 // Creator : Richard Schiek, Electrical Systems Modeling
2227 // Creation Date : 04/13/11
2228 //-----------------------------------------------------------------------------
2229 
2230 void SmoothPulseData::printOutParams()
2231 {
2232 
2233  Xyce::dout() << std::endl;
2234  Xyce::dout() << " SmoothPulseData::printOutParams\n";
2235  Xyce::dout() << " V1 = " << V1 << std::endl;
2236  Xyce::dout() << " V2 = " << V2 << std::endl;
2237 
2238  Xyce::dout() << " TD = " << TD << std::endl;
2239  Xyce::dout() << " TR = " << TR << std::endl;
2240  Xyce::dout() << " TF = " << TF << std::endl;
2241  Xyce::dout() << " PW = " << PW << std::endl;
2242  Xyce::dout() << " PER = " << PER << std::endl;
2243  Xyce::dout() << " SF = " << functionScaleFactor_ << std::endl;
2244  Xyce::dout() << std::endl;
2245 
2246 }
2247 #endif
2248 
2249 //-----------------------------------------------------------------------------
2250 // Function : SmoothPulseData::initializeSource
2251 // Purpose :
2252 // Special Notes :
2253 // Scope : public
2254 // Creator : Richard Schiek, Electrical Systems Modeling
2255 // Creation Date : 04/13/11
2256 //-----------------------------------------------------------------------------
2257 
2259 {
2260 
2261  // If neccessary, set the defaults:
2262 
2263  double tstep = solState_.startingTimeStep;
2264  double tstop = solState_.finalTime;
2265 
2266  if (!TDgiven) TD = 0.0;
2267  if (!TRgiven) TR = tstep;
2268  if (!TFgiven) TF = tstep;
2269  if (!PWgiven) PW = tstop;
2270  if (!PERgiven) PER = tstop;
2271  // scale the amplitude of the response so it better joins the low and hi value
2272  // riseFallScaleFactor_ = M_PI;
2273  riseScaleFactor_ = 2.0*fabs( atan(M_PI * functionScaleFactor_ * (0.5*TR) / TR) );
2274  fallScaleFactor_ = 2.0*fabs( atan(M_PI * functionScaleFactor_ * (0.5*TF) / TF) );
2275  initializeFlag_ = true;
2276 
2277  return true;
2278 }
2279 
2280 //-----------------------------------------------------------------------------
2281 // Function : SmoothPulseData::updateSource
2282 // Purpose :
2283 // Special Notes :
2284 // Scope : public
2285 // Creator : Richard Schiek, Electrical Systems Modeling
2286 // Creation Date : 04/13/11
2287 //-----------------------------------------------------------------------------
2288 
2290 
2291 {
2292  bool bsuccess = true;
2293 
2294  if (!initializeFlag_) bsuccess = initializeSource ();
2295 
2296  double basetime = 0;
2297 
2298 #ifdef Xyce_DEBUG_DEVICE
2300  {
2301  Xyce::dout() << " SmoothPulseData::updateSources\n";
2302  printOutParams();
2303  }
2304 #endif
2305 
2306  time = getTime_();
2307 
2308 #ifdef Xyce_DEBUG_DEVICE
2310  {
2311  Xyce::dout() << " Time = " << time << std::endl;
2312  }
2313 #endif
2314 
2315  time -= TD;
2316 
2317  if (time > PER && PER != 0.0)
2318  {
2319  // repeating signal - figure out where we are in period
2320  basetime = PER * floor(time/PER);
2321  time -= basetime;
2322  }
2323 
2324  // This section got ugly because of a nasty roundoff bug.
2325  // Instead of doing "time > X" you need also check that time
2326  // is not within bptol of X.
2327  // So the following translation is used:
2328  // Instead of: we do:
2329  // time > X time>X && fabs(time-x)>bptol
2330  // time <= X time<X || fabs(time-x)<bptol
2331 
2332  if (time <= 0 || (time > (TR + PW + TF) &&
2333  (fabs (time - (TR+PW+TF)) > solState_.bpTol) ) )
2334  {
2335  SourceValue = V1;
2336  }
2337  else if ((time > TR && fabs(time-TR) > solState_.bpTol)
2338  && (time < (TR + PW) || fabs (time-(TR+PW))<solState_.bpTol) )
2339  {
2340  SourceValue = V2;
2341  }
2342  else if (time > 0 &&
2343  (time < TR || fabs(time-TR) < solState_.bpTol))
2344  {
2345  if (TR != 0.0)
2346  SourceValue = V1 + (V2 - V1) *
2347  (((atan(M_PI * functionScaleFactor_ * (time-0.5*TR) / TR))/riseScaleFactor_) + 0.5);
2348  else
2349  SourceValue = V1;
2350  }
2351  else
2352  { // time > (TR + PW) && <= (TR + PW + TF)
2353  if (TF != 0.0)
2354  SourceValue = V2 + (V1 - V2) *
2355  (((atan(M_PI * functionScaleFactor_ * (time - (TR + PW + 0.5*TF)) / TF))/fallScaleFactor_) + 0.5);
2356  else
2357  SourceValue = V2;
2358  }
2359 
2360 #ifdef Xyce_DEBUG_DEVICE
2362  {
2363  Xyce::dout() << " SourceValue = " << SourceValue << std::endl;
2364  }
2365 #endif
2366 
2367  resetFlag_ = false;
2368 
2369  return bsuccess;
2370 }
2371 
2372 //-----------------------------------------------------------------------------
2373 // Function : SmoothPulseData::getParams
2374 // Purpose : Pass back the pulse source params.
2375 // Special Notes :
2376 //
2377 // Scope : public
2378 // Creator : Richard Schiek, Electrical Systems Modeling
2379 // Creation Date : 04/13/11
2380 //-----------------------------------------------------------------------------
2381 void SmoothPulseData::getParams(double *params)
2382 {
2383  params[0] = V1;
2384  params[1] = V2;
2385  params[2] = TD;
2386  params[3] = TR;
2387  params[4] = TF;
2388  params[5] = PW;
2389  params[6] = PER;
2390 }
2391 
2392 //-----------------------------------------------------------------------------
2393 // Function : SmoothPulseData::setParams
2394 // Purpose : Update the pulse source params.
2395 // Special Notes :
2396 //
2397 // Scope : public
2398 // Creator : Richard Schiek, Electrical Systems Modeling
2399 // Creation Date : 04/13/11
2400 //-----------------------------------------------------------------------------
2401 void SmoothPulseData::setParams(double *params)
2402 {
2403  bool reset=false;
2404  if (V1 != params[0])
2405  {
2406  V1 = params[0];
2407  reset = true;
2408  }
2409  if (V2 != params[1])
2410  {
2411  V2 = params[1];
2412  reset = true;
2413  }
2414  if (TD != params[2])
2415  {
2416  TD = params[2];
2417  reset = true;
2418  }
2419  if (TR != params[3])
2420  {
2421  TR = params[3];
2422  reset = true;
2423  }
2424  if (TF != params[4])
2425  {
2426  TF = params[4];
2427  reset = true;
2428  }
2429  if (PW != params[5])
2430  {
2431  PW = params[5];
2432  reset = true;
2433  }
2434  if (PER != params[6])
2435  {
2436  PER = params[6];
2437  reset = true;
2438  }
2439  if (reset)
2440  updateSource();
2441 }
2442 
2443 //-----------------------------------------------------------------------------
2444 // Function : SmoothPulseData::getBreakPoints
2445 // Purpose : This function adds break points to a vector of breakpoints.
2446 //
2447 // It does not bother to check them in any way, or put them
2448 // in order. It only adds them in.
2449 //
2450 // Special Notes : Like much of this file, this is adapted from spice 3f5.
2451 // Some of the stuff in it is a little hokey, and may get
2452 // removed or modified later.
2453 //
2454 // Scope : public
2455 // Creator : Richard Schiek, Electrical Systems Modeling
2456 // Creation Date : 04/13/11
2457 //-----------------------------------------------------------------------------
2459  (std::vector<N_UTL_BreakPoint> & breakPointTimes )
2460 {
2461  bool bsuccess = true;
2462 
2463  if (!initializeFlag_) bsuccess = initializeSource ();
2464 
2465  return bsuccess;
2466 }
2467 
2468 //-----------------------------------------------------------------------------
2469 // Function : SmoothPulseData::getMaxTimeStepSize
2470 // Purpose :
2471 // Special Notes :
2472 // Scope : public
2473 // Creator : Richard Schiek, Electrical Systems Modeling
2474 // Creation Date : 04/13/11
2475 //-----------------------------------------------------------------------------
2477 {
2478  double maxTimeStep = devOptions_.defaultMaxTimeStep;
2479 
2480  // check if we are still in the delay or not.
2481  time = getTime_();
2482 
2483  if (time < TD) maxTimeStep = (0.1*TD );
2484  else maxTimeStep = (0.1*PER);
2485 
2486 #ifdef Xyce_DEBUG_DEVICE
2488  {
2489  Xyce::dout() << "\nIn SmoothPulseData::getMaxTimeStepSize. ";
2490  Xyce::dout() << " maxTimeStep = "<< maxTimeStep;
2491  Xyce::dout() << " TD = " << TD << " PER = " <<PER;
2492  Xyce::dout() << " time = "<< time << std::endl;
2493  }
2494 #endif
2495 
2496  return maxTimeStep;
2497 }
2498 
2499 } // namespace Device
2500 } // namespace Xyce