Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_DEV_Bsrc.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_Bsrc.C,v $
27 //
28 // Purpose :
29 //
30 // Special Notes :
31 //
32 // Creator : Robert J Hoekstra, SNL, Parallel Computational Sciences
33 //
34 // Creation Date : 06/05/01
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision: 1.197 $
40 //
41 // Revision Date : $Date: 2014/08/07 21:23:15 $
42 //
43 // Current Owner : $Author: erkeite $
44 //-------------------------------------------------------------------------
45 #include <Xyce_config.h>
46 
47 // ---------- Standard Includes ----------
48 #include <N_UTL_Misc.h>
49 
50 #ifdef HAVE_CMATH
51 #include <cmath>
52 #else
53 #include <math.h>
54 #endif
55 
56 #ifdef HAVE_CSTDIO
57 #include <cstdio>
58 #else
59 #include <stdio.h>
60 #endif
61 
62 // ---------- Xyce Includes ----------
63 #include <N_DEV_Bsrc.h>
64 #include <N_DEV_DeviceOptions.h>
65 #include <N_DEV_ExternData.h>
66 #include <N_DEV_MatrixLoadData.h>
67 #include <N_DEV_SolverState.h>
68 #include <N_DEV_Message.h>
69 #include <N_ERH_ErrorMgr.h>
70 
71 #include <N_LAS_Vector.h>
72 #include <N_LAS_Matrix.h>
73 
74 #include <N_UTL_Expression.h>
75 #include <N_UTL_BreakPoint.h>
76 
77 namespace Xyce {
78 namespace Device {
79 
80 
81 namespace Bsrc {
82 
83 
85 {
86  // Set up configuration constants:
87 // Set up double precision variables:
88  p.addPar ("I", 0.0, &Bsrc::Instance::I)
89  .setExpressionAccess(ParameterType::SOLN_DEP)
90  .setUnit(U_AMP)
91  .setDescription("Current for current source");
92 
93  p.addPar ("V", 0.0, &Bsrc::Instance::V)
94  .setExpressionAccess(ParameterType::SOLN_DEP)
95  .setUnit(U_VOLT)
96  .setDescription("Voltage for voltage source");
97 }
98 
100 {}
101 
102 
103 #define Xyce_NONPOINTER_MATRIX_LOAD 1
104 
105 // Class Instance
106 //-----------------------------------------------------------------------------
107 // Function : Instance::Instance
108 // Purpose : "instance block" constructor
109 // Special Notes :
110 // Scope : public
111 // Creator : Rob Hoekstra, SNL, Parallel Computational Sciences
112 // Creation Date : 06/05/01
113 //-----------------------------------------------------------------------------
115  const Configuration & configuration,
116  const InstanceBlock & IB,
117  Model & BMiter,
118  const FactoryBlock & factory_block)
119  : DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
120  model_(BMiter),
121  IB(IB),
122  li_Pos(-1),
123  li_Neg(-1),
124  li_Bra(-1),
125  li_store_branch(-1),
126  ABraEquPosNodeOffset(-1),
127  ABraEquNegNodeOffset(-1),
128  APosEquBraVarOffset(-1),
129  ANegEquBraVarOffset(-1),
130  fBraEquPosNodePtr(0),
131  fBraEquNegNodePtr(0),
132  fPosEquBraVarPtr(0),
133  fNegEquBraVarPtr(0),
134  Exp_ptr(0),
135  isVSRC(false),
136  scale(1.0),
137  nlstep(-1),
138  expNumVars(0),
139  expBaseVar(0),
140  expNumDdt(0),
141  expVal(0)
142 {
143  numIntVars = 1;
144  numExtVars = 2;
145  numStateVars = 0;
146 
147  // Set params to constant default values:
148  setDefaultParams ();
149 
150  // Set params according to instance line and constant defaults from metadata:
151  setParams (IB.params);
152 
153  // Set any non-constant parameter defaults:
154  if (given("I") && !given("V"))
155  {
156  isVSRC = false;
157  // current source doesn't have current as part of the solution vector
158  // so store it in the store vector
159  setNumStoreVars(1);
160  }
161  else if (!given("I") && given("V"))
162  {
163  isVSRC = true;
164  }
165  else
166  {
167  UserError0(*this) << "Must supply one of V= or I=";
168  }
169 
170  if (isVSRC)
171  {
172  numIntVars = 1;
173  }
174  else
175  {
176  numIntVars = 0;
177  }
178 
179  std::vector<Depend>::const_iterator d;
180  std::vector<Depend>::const_iterator begin = getDependentParams().begin();
181  std::vector<Depend>::const_iterator end = getDependentParams().end();
182 
183  for (d = begin ; d != end ; ++d)
184  {
185  if (d->name == "I" || d->name == "V")
186  {
187  expNumVars = d->n_vars;
188  expBaseVar = d->lo_var;
189  Exp_ptr = d->expr;
190 
191  expNumDdt = Exp_ptr->getNumDdt();
192  ddtVals.resize(expNumDdt);
193  li_ddt.resize(expNumDdt);
195 
196  expVarDerivs.resize(expNumVars);
197  myVarVals.resize(expNumVars);
198  break;
199  }
200  }
201 
202  if( jacStamp.empty() )
203  {
204  if( isVSRC )
205  {
206  jacStamp.resize(3);
207  jacStamp[0].resize(1);
208  jacStamp[0][0]=2;
209  jacStamp[1].resize(1);
210  jacStamp[1][0]=2;
211  jacStamp[2].resize(2+expNumVars);
212  jacStamp[2][0]=0;
213  jacStamp[2][1]=1;
214  for( int i = 0; i < expNumVars; ++i )
215  jacStamp[2][i+2] = i+3;
216  }
217  else
218  {
219  jacStamp.resize( 2 );
220  jacStamp[0].resize(expNumVars);
221  jacStamp[1].resize(expNumVars);
222  for( int i = 0; i < expNumVars; ++i )
223  {
224  jacStamp[0][i] = i+2;
225  jacStamp[1][i] = i+2;
226  }
227  }
228  }
229 
230  // Calculate any parameters specified as expressions:
231 
233 
234  // calculate dependent (ie computed) params and check for errors:
235 
236  processParams();
237 
238 }
239 
240 //-----------------------------------------------------------------------------
241 // Function : Instance::processParams
242 // Purpose :
243 // Special Notes :
244 // Scope : public
245 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
246 // Creation Date : 07/30/03
247 //-----------------------------------------------------------------------------
249 {
250  return true;
251 }
252 
253 //-----------------------------------------------------------------------------
254 // Function : Instance::~Instance
255 // Purpose : destructor
256 // Special Notes :
257 // Scope : public
258 // Creator : Rob Hoekstra, SNL, Parallel Computational Sciences
259 // Creation Date : 06/05/01
260 //-----------------------------------------------------------------------------
262 {
263 }
264 
265 // Additional Declarations
266 //-----------------------------------------------------------------------------
267 // Function : Instance::registerLIDs
268 // Purpose :
269 // Special Notes :
270 // Scope : public
271 // Creator : Rob Hoekstra, SNL, Parallel Computational Sciences
272 // Creation Date : 6/21/02
273 //-----------------------------------------------------------------------------
274 void Instance::registerLIDs( const std::vector<int> & intLIDVecRef,
275  const std::vector<int> & extLIDVecRef )
276 {
277  AssertLIDs(intLIDVecRef.size() == numIntVars);
278  AssertLIDs(extLIDVecRef.size() == numExtVars);
279 
280 #ifdef Xyce_DEBUG_DEVICE
281  Xyce::dout() << std::endl << section_divider << std::endl;
282  Xyce::dout() << " BsrcInstance::registerLIDs" << std::endl;
283  Xyce::dout() << " name = " << getName() << std::endl;
284 #endif
285 
286  // copy over the global ID lists.
287  intLIDVec = intLIDVecRef;
288  extLIDVec = extLIDVecRef;
289 
290  // Now use these lists to obtain the indices into the
291  // linear algebra entities. This assumes an order.
292  // For the matrix indices, first do the rows.
293 
294  li_Pos = extLIDVec[0];
295  li_Neg = extLIDVec[1];
296 
297 #ifdef Xyce_DEBUG_DEVICE
298  Xyce::dout() << " li_Pos = " << li_Pos << std::endl;
299  Xyce::dout() << " li_Neg = " << li_Neg << std::endl;
300 #endif
301 
302  if( isVSRC )
303  {
304  li_Bra = intLIDVec[0];
305 
306 #ifdef Xyce_DEBUG_DEVICE
307  Xyce::dout() << " li_Bra = " << li_Bra << std::endl;
308 #endif
309  }
310 
311 #ifdef Xyce_DEBUG_DEVICE
312  Xyce::dout() << section_divider << std::endl;
313 #endif
314 }
315 
316 //-----------------------------------------------------------------------------
317 // Function : Instance::getIntNameMap
318 // Purpose :
319 // Special Notes :
320 // Scope : public
321 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
322 // Creation Date : 05/13/05
323 //-----------------------------------------------------------------------------
324 std::map<int,std::string> & Instance::getIntNameMap ()
325 {
326  // set up the internal name map, if it hasn't been already.
327  if (isVSRC)
328  {
329  if (intNameMap.empty ())
330  {
331  intNameMap[ li_Bra ] = spiceInternalName(getName(), "branch");
332  }
333  }
334  return intNameMap;
335 }
336 
337 //-----------------------------------------------------------------------------
338 // Function : Instance::registerStoreLIDs
339 // Purpose : One store var for device current if this is a current source
340 // Special Notes :
341 // Scope : public
342 // Creator : Richard Schiek, Electrical Systems Modeling
343 // Creation Date : 01/17/2013
344 //-----------------------------------------------------------------------------
345 void Instance::registerStoreLIDs(const std::vector<int> & stoLIDVecRef )
346 {
347  if (!isVSRC)
348  {
349  AssertLIDs(stoLIDVecRef.size() == getNumStoreVars());
350 
351  li_store_branch = stoLIDVecRef[0];
352  }
353 }
354 
355 //-----------------------------------------------------------------------------
356 // Function : Instance::getStoreNameMap
357 // Purpose :
358 // Special Notes :
359 // Scope : public
360 // Creator : Richard Schiek, Electrical Systems Modeling
361 // Creation Date : 12/18/2012
362 //-----------------------------------------------------------------------------
363 std::map<int,std::string> & Instance::getStoreNameMap ()
364 {
365  if (!isVSRC)
366  {
367  // set up the internal name map, if it hasn't been already.
368  if (storeNameMap.empty ())
369  {
371  }
372  }
373  return storeNameMap;
374 }
375 
376 
377 //-----------------------------------------------------------------------------
378 // Function : Instance::registerStateLIDs
379 // Purpose :
380 // Special Notes :
381 // Scope : public
382 // Creator : Rob Hoekstra, SNL, Parallel Computational Sciences
383 // Creation Date : 06/21/02
384 //-----------------------------------------------------------------------------
385 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
386 {
387  AssertLIDs(staLIDVecRef.size() == numStateVars);
388  AssertLIDs(li_ddt.size() == expNumDdt);
390 
391  for (int i=0 ; i<expNumDdt ; ++i)
392  {
393  li_ddt[i] = staLIDVecRef[i];
394  }
395 }
396 
397 
398 //-----------------------------------------------------------------------------
399 // Function : Instance::getDepSolnVars
400 // Purpose :
401 // Special Notes :
402 // Scope : public
403 // Creator : Rob Hoekstra, SNL, Parallel Computational Sciences
404 // Creation Date : 06/06/01
405 //-----------------------------------------------------------------------------
406 const std::vector<std::string> & Instance::getDepSolnVars()
407 {
409 }
410 
411 
412 //-----------------------------------------------------------------------------
413 // Function : Instance::jacobianStamp
414 // Purpose :
415 // Special Notes :
416 // Scope : public
417 // Creator : Rob Hoekstra, SNL, Parallel Computational Sciences
418 // Creation Date : 9/2/02
419 //-----------------------------------------------------------------------------
420 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
421 {
422  return jacStamp;
423 }
424 
425 //-----------------------------------------------------------------------------
426 // Function : Instance::registerJacLIDs
427 // Purpose :
428 // Special Notes :
429 // Scope : public
430 // Creator : Rob Hoekstra, SNL, Parallel Computational Sciences
431 // Creation Date : 9/2/02
432 //-----------------------------------------------------------------------------
434  const std::vector< std::vector<int> > & jacLIDVec)
435 {
436  DeviceInstance::registerJacLIDs( jacLIDVec );
437  if( isVSRC )
438  {
439  APosEquBraVarOffset = jacLIDVec[0][0];
440  ANegEquBraVarOffset = jacLIDVec[1][0];
441  ABraEquPosNodeOffset = jacLIDVec[2][0];
442  ABraEquNegNodeOffset = jacLIDVec[2][1];
444  for( int i = 0; i < expNumVars; ++i )
445  {
446  ABraEquExpVarOffsets[i] = jacLIDVec[2][i+2];
447  }
448  }
449  else
450  {
453  for( int i = 0; i < expNumVars; ++i )
454  {
455  APosEquExpVarOffsets[i] = jacLIDVec[0][i];
456  ANegEquExpVarOffsets[i] = jacLIDVec[1][i];
457  }
458 
459  }
460 }
461 
462 
463 //-----------------------------------------------------------------------------
464 // Function : Instance::setupPointers
465 // Purpose :
466 // Special Notes :
467 // Scope : public
468 // Creator : Eric Keiter, SNL
469 // Creation Date : 11/30/08
470 //-----------------------------------------------------------------------------
472 {
473 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
474  N_LAS_Matrix & dFdx = *(extData.dFdxMatrixPtr);
475 
476  if( isVSRC )
477  {
482 
483  fBraEquExpVarPtrs.resize( expNumVars );
484  for( int i = 0; i < expNumVars; ++i )
485  {
486  fBraEquExpVarPtrs[i] = &(dFdx[li_Bra][ ABraEquExpVarOffsets[i] ]);
487  }
488  }
489  else
490  {
491  fPosEquExpVarPtrs.resize( expNumVars );
492  fNegEquExpVarPtrs.resize( expNumVars );
493  for( int i = 0; i < expNumVars; ++i )
494  {
495  fPosEquExpVarPtrs[i] = &(dFdx[li_Pos][ APosEquExpVarOffsets[i] ]);
496  fNegEquExpVarPtrs[i] = &(dFdx[li_Neg][ ANegEquExpVarOffsets[i] ]);
497  }
498  }
499 
500 #endif
501 }
502 
503 //-----------------------------------------------------------------------------
504 // Function : Instance::updateIntermediateVars
505 //
506 // Purpose : Calls the expression handler to evaluate the expression
507 // and various derivatives. These quantities are needed
508 // for the vector and matrix loads.
509 //
510 // Special Notes :
511 //
512 // Scope : public
513 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
514 // Creation Date : 06/05/01
515 //-----------------------------------------------------------------------------
517 {
518  if (expNumVars == 0)
519  {
520  if (isVSRC)
521  {
522  expVal = V;
523  }
524  else
525  {
526  expVal = I;
527  }
528  }
529 
530  return true;
531 }
532 
533 //-----------------------------------------------------------------------------
534 // Function : Instance::updatePrimaryState
535 // Purpose :
536 // Special Notes :
537 // Scope : public
538 // Creator : Rob Hoekstra, SNL, Parallel Computational Sciences
539 // Creation Date : 06/05/01
540 //-----------------------------------------------------------------------------
542 {
543  bool bsuccess=updateIntermediateVars ();
544 
545  // Get values of the arguments for ddt() calls in expression so that the derivatives
546  // can be determined by the time integration class
547  if (expNumDdt > 0)
548  {
549  double * staVec = extData.nextStaVectorRawPtr;
550 
551  Exp_ptr->getDdtVals (ddtVals);
552  for (int i=0 ; i<expNumDdt ; ++i)
553  {
554  staVec[li_ddt[i]] = ddtVals[i];
555  }
556  }
557 
558  return bsuccess;
559 }
560 
561 //-----------------------------------------------------------------------------
562 // Function : Instance::updateSecondaryState
563 // Purpose :
564 // Special Notes :
565 // Scope : public
566 // Creator : Rob Hoekstra, SNL, Parallel Computational Sciences
567 // Creation Date : 06/05/01
568 //-----------------------------------------------------------------------------
570 {
571  // Get time derivatives from time integrator, and evaluate expression to get
572  // derivatives with respect to independent quantities
573 
574  if (expNumDdt > 0)
575  {
576  double * staDerivVec = extData.nextStaDerivVectorRawPtr;
577 
578  for (int i=0 ; i<expNumDdt ; ++i)
579  {
580  ddtVals[i] = staDerivVec[li_ddt[i]];
581  }
582  Exp_ptr->setDdtDerivs(ddtVals);
583  }
584  // Evaluate Expression with corrected time derivative values
585  if (expNumVars != 0)
586  {
587  Exp_ptr->evaluate( expVal, expVarDerivs);
588  }
589 
590  // Test derivatives, if too big, zero out
591  for (int i = 0; i < expNumVars; ++i)
592  {
593  double maxMag = 1.0e+10;
594  if (expVarDerivs[i] > maxMag || expVarDerivs[i] < -maxMag)
595  {
596  static Report::MessageCode id;
597 
598  Report::UserWarning(id) << "Expression derivative |" << expVarDerivs[i] << "| exceeds " << maxMag << ", value reduced";
599 
600  expVarDerivs[i] = (expVarDerivs[i] > 0) ? maxMag : -maxMag;
601  }
602  }
603 
604  return true;
605 }
606 
607 //-----------------------------------------------------------------------------
608 // Function : Instance::loadDAEFVector
609 //
610 // Purpose : Loads the F-vector contributions for a single
611 // vsrc instance.
612 //
613 // Special Notes : See the special notes for loadDAEFVector.
614 //
615 // Scope : public
616 // Creator : Rob Hoekstra, SNL, Parallel Computational Sciences
617 // Creation Date : 04/27/04
618 //-----------------------------------------------------------------------------
620 {
621  double source(0.0), v_pos(0.0), v_neg(0.0), i_bra(0.0);
622  double * solVec = extData.nextSolVectorRawPtr;
623  double * fVec = extData.daeFVectorRawPtr;
624  double * stoVec = extData.nextStoVectorRawPtr;
625 
626  source = expVal;
627 
628  //VSRC or ISRC
629  if (isVSRC)
630  {
631  // get the value for v_pos, v_neg, i_bra
632  v_pos = solVec[li_Pos];
633  v_neg = solVec[li_Neg];
634  i_bra = solVec[li_Bra];
635 
636  double c_tmp = i_bra;
637  double v_tmp = (v_pos-v_neg-source);
638 
639  fVec[li_Pos] += c_tmp;
640  fVec[li_Neg] += -c_tmp;
641  fVec[li_Bra] += v_tmp;
642  }
643  else
644  {
645  fVec[li_Pos] += source;
646  fVec[li_Neg] += -source;
647 
648  stoVec[li_store_branch] = source;
649  }
650 
651  return true;
652 }
653 
654 //-----------------------------------------------------------------------------
655 // Function : Instance::loadDAEdFdx ()
656 //
657 // Purpose : Loads the F-vector contributions for a single
658 // resistor instance.
659 //
660 // Special Notes :
661 //
662 // Scope : public
663 // Creator : Rob Hoekstra, SNL, Parallel Computational Sciences
664 // Creation Date : 04/27/04
665 //-----------------------------------------------------------------------------
667 {
668  N_LAS_Matrix & dFdx = *(extData.dFdxMatrixPtr);
669 
670  double coef = 1.0;
671 
672  if( isVSRC )
673  {
674  if( getDeviceOptions().scale_src != 0.0 )
675  {
676  coef *= scale;
677  }
678 
679  dFdx[li_Pos][APosEquBraVarOffset] += coef;
680  dFdx[li_Neg][ANegEquBraVarOffset] -= coef;
681  dFdx[li_Bra][ABraEquPosNodeOffset] += coef;
682  dFdx[li_Bra][ABraEquNegNodeOffset] -= coef;
683 
684  for( int i = 0; i < expNumVars; ++i )
685  {
686  dFdx[li_Bra][ABraEquExpVarOffsets[i]] -= expVarDerivs[i];
687  }
688  }
689  else
690  {
691  if( expNumVars )
692  {
693  for( int i = 0; i < expNumVars; ++i )
694  {
695  dFdx[li_Pos][APosEquExpVarOffsets[i]] += expVarDerivs[i];
696  dFdx[li_Neg][ANegEquExpVarOffsets[i]] -= expVarDerivs[i];
697  }
698  }
699  }
700 
701  return true;
702 }
703 
704 //-----------------------------------------------------------------------------
705 // Function : Instance::varTypes
706 // Purpose :
707 // Special Notes :
708 // Scope : public
709 // Creator : Rob Hoekstra, SNL, Parallel Computational Sciences
710 // Creation Date : 02/17/02
711 //-----------------------------------------------------------------------------
712 void Instance::varTypes( std::vector<char> & varTypeVec )
713 {
714  if( !isVSRC )
715  {
716  varTypeVec.resize(1);
717  varTypeVec[0] = 'I';
718  }
719 }
720 
721 // Class Model
722 
723 //-----------------------------------------------------------------------------
724 // Function : Model::Model
725 // Purpose : constructor
726 // Special Notes :
727 // Scope : public
728 // Creator : Rob Hoekstra, SNL, Parallel Computational Sciences
729 // Creation Date : 06/05/01
730 //-----------------------------------------------------------------------------
732  const Configuration & configuration,
733  const ModelBlock & MB,
734  const FactoryBlock & factory_block)
735  : DeviceModel(MB, configuration.getModelParameters(), factory_block)
736 {
737 }
738 
739 //-----------------------------------------------------------------------------
740 // Function : Model::~Model
741 // Purpose : destructor
742 // Special Notes :
743 // Scope : public
744 // Creator : Rob Hoekstra, SNL, Parallel Computational Sciences
745 // Creation Date : 06/05/01
746 //-----------------------------------------------------------------------------
748 {
749  std::vector<Instance*>::iterator iter;
750  std::vector<Instance*>::iterator first = instanceContainer.begin();
751  std::vector<Instance*>::iterator last = instanceContainer.end();
752 
753  for (iter=first; iter!=last; ++iter)
754  {
755  delete (*iter);
756  }
757 }
758 
759 //-----------------------------------------------------------------------------
760 // Function : DeviceModel::processParams
761 // Purpose :
762 // Special Notes :
763 // Scope : public
764 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
765 // Creation Date : 06/03/02
766 //-----------------------------------------------------------------------------
768 {
769  return true;
770 }
771 
772 //-----------------------------------------------------------------------------
773 // Function : DeviceModel::processInstanceParams
774 // Purpose :
775 // Special Notes :
776 // Scope : public
777 // Creator : Dave Shirley, PSSI
778 // Creation Date : 03/23/06
779 //-----------------------------------------------------------------------------
781 {
782  return true;
783 }
784 
785 // Additional Declarations
786 
787 //-----------------------------------------------------------------------------
788 // Function : Model::printOutInstances
789 // Purpose : debugging tool.
790 // Special Notes :
791 // Scope : public
792 // Creator : Rob Hoekstra, SNL, Parallel Computational Sciences
793 // Creation Date : 6/05/01
794 //-----------------------------------------------------------------------------
795 std::ostream &Model::printOutInstances(std::ostream &os) const
796 {
797  std::vector<Instance*>::const_iterator iter;
798  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
799  std::vector<Instance*>::const_iterator last = instanceContainer.end();
800 
801  int i;
802  os << std::endl;
803  os << " name model name Parameters" << std::endl;
804  for (i=0, iter=first; iter!=last; ++iter, ++i)
805  {
806  os << " " << i << ": " << (*iter)->getName() << " ";
807  os << getName();
808  os << std::endl;
809  }
810 
811  os << std::endl;
812 
813  return os;
814 }
815 
816 //-----------------------------------------------------------------------------
817 // Function : Model::forEachInstance
818 // Purpose :
819 // Special Notes :
820 // Scope : public
821 // Creator : David Baur
822 // Creation Date : 2/4/2014
823 //-----------------------------------------------------------------------------
824 /// Apply a device instance "op" to all instances associated with this
825 /// model
826 ///
827 /// @param[in] op Operator to apply to all instances.
828 ///
829 ///
830 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
831 {
832  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
833  op(*it);
834 }
835 
836 // Bsrc Master functions:
837 
838 //-----------------------------------------------------------------------------
839 // Function : Master::updateState
840 // Purpose :
841 // Special Notes :
842 // Scope : public
843 // Creator : Eric Keiter, SNL
844 // Creation Date : 11/26/08
845 //-----------------------------------------------------------------------------
846 bool Master::updateState (double * solVec, double * staVec, double * stoVec)
847 {
848  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
849  {
850  Instance & bi = *(*it);
851  if (bi.expNumVars == 0)
852  {
853  if (bi.isVSRC)
854  {
855  bi.expVal = bi.V;
856  }
857  else
858  {
859  bi.expVal = bi.I;
860  stoVec[bi.li_store_branch]=bi.I;
861  }
862  }
863  // Get values of the arguments for ddt() calls in expression so that the derivatives
864  // can be determined by the time integration class
865  if (bi.expNumDdt > 0)
866  {
867  bi.Exp_ptr->getDdtVals (bi.ddtVals);
868  for (int j=0 ; j<bi.expNumDdt ; ++j)
869  {
870  staVec[bi.li_ddt[j]] = bi.ddtVals[j];
871  }
872  }
873  }
874 
875  return true;
876 }
877 
878 //-----------------------------------------------------------------------------
879 // Function : Master::updateSecondaryState
880 // Purpose :
881 // Special Notes :
882 // Scope : public
883 // Creator : Eric Keiter, SNL
884 // Creation Date : 11/26/08
885 //-----------------------------------------------------------------------------
886 bool Master::updateSecondaryState ( double * staDerivVec, double * stoVec )
887 {
888  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
889  {
890  Instance & bi = *(*it);
891 
892  // Get time derivatives from time integrator, and evaluate expression to get
893  // derivatives with respect to independent quantities
894 
895  if (bi.expNumDdt > 0)
896  {
897  for (int j=0 ; j<bi.expNumDdt ; ++j)
898  {
899  bi.ddtVals[j] = staDerivVec[bi.li_ddt[j]];
900  }
901  bi.Exp_ptr->setDdtDerivs(bi.ddtVals);
902  }
903  // Evaluate Expression with corrected time derivative values
904  if (bi.expNumVars != 0)
905  {
906  bi.Exp_ptr->evaluate( bi.expVal, bi.expVarDerivs);
907  if (!bi.isVSRC)
908  {
909  stoVec[bi.li_store_branch]=bi.expVal;
910  }
911  }
912 
913  // Test derivatives, if too big, zero out
914  for (int k = 0; k < bi.expNumVars; ++k)
915  {
916  double maxMag = 1.0e+10;
917  if (bi.expVarDerivs[k] > maxMag || bi.expVarDerivs[k] < -maxMag)
918  {
919  static Report::MessageCode id;
920 
921  Report::UserWarning(id) << "Expression derivative |" << bi.expVarDerivs[k] << "| exceeds " << maxMag << ", value reduced";
922  bi.expVarDerivs[k] = (bi.expVarDerivs[k] > 0) ? maxMag : -maxMag;
923  }
924  }
925  }
926 
927  return true;
928 }
929 
930 //-----------------------------------------------------------------------------
931 // Function : Master::loadDAEVectors
932 // Purpose :
933 // Special Notes :
934 // Scope : public
935 // Creator : Eric Keiter, SNL
936 // Creation Date : 11/26/08
937 //-----------------------------------------------------------------------------
938 bool Master::loadDAEVectors (double * solVec, double * fVec, double *qVec, double * bVec, double * storeLeadF, double * storeLeadQ)
939 {
940  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
941  {
942  Instance & bi = *(*it);
943  double v_pos(0.0), v_neg(0.0), i_bra(0.0);
944  double source = bi.expVal;
945 
946  //VSRC or ISRC
947  if (bi.isVSRC)
948  {
949  // get the value for v_pos, v_neg, i_bra
950  v_pos = solVec[bi.li_Pos];
951  v_neg = solVec[bi.li_Neg];
952  i_bra = solVec[bi.li_Bra];
953 
954  double c_tmp = i_bra;
955  double v_tmp = (v_pos-v_neg-source);
956 
957  fVec[bi.li_Pos] += c_tmp;
958  fVec[bi.li_Neg] += -c_tmp;
959  fVec[bi.li_Bra] += v_tmp;
960  }
961  else
962  {
963  fVec[bi.li_Pos] += source;
964  fVec[bi.li_Neg] += -source;
965  }
966  }
967  return true;
968 }
969 
970 //-----------------------------------------------------------------------------
971 // Function : Master::loadDAEMatrices
972 // Purpose :
973 // Special Notes :
974 // Scope : public
975 // Creator : Eric Keiter, SNL
976 // Creation Date : 11/26/08
977 //-----------------------------------------------------------------------------
978 bool Master::loadDAEMatrices (N_LAS_Matrix & dFdx, N_LAS_Matrix & dQdx)
979 {
980  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
981  {
982  Instance & bi = *(*it);
983  double coef = 1.0;
984 
985  if( bi.isVSRC )
986  {
987  if( getDeviceOptions().scale_src != 0.0 )
988  {
989  coef *= bi.scale;
990  }
991 
992 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
993  *bi.fPosEquBraVarPtr += coef;
994  *bi.fNegEquBraVarPtr -= coef;
995  *bi.fBraEquPosNodePtr += coef;
996  *bi.fBraEquNegNodePtr -= coef;
997 
998  for( int j = 0; j < bi.expNumVars; ++j )
999  {
1000  *bi.fBraEquExpVarPtrs[j] -= bi.expVarDerivs[j];
1001  }
1002 #else
1003  dFdx[bi.li_Pos][bi.APosEquBraVarOffset] += coef;
1004  dFdx[bi.li_Neg][bi.ANegEquBraVarOffset] -= coef;
1005  dFdx[bi.li_Bra][bi.ABraEquPosNodeOffset] += coef;
1006  dFdx[bi.li_Bra][bi.ABraEquNegNodeOffset] -= coef;
1007 
1008  for( int j = 0; j < bi.expNumVars; ++j )
1009  {
1010  dFdx[bi.li_Bra][bi.ABraEquExpVarOffsets[j]] -= bi.expVarDerivs[j];
1011  }
1012 #endif
1013  }
1014  else
1015  {
1016  if( bi.expNumVars )
1017  {
1018 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
1019  for( int k = 0; k < bi.expNumVars; ++k )
1020  {
1021  *bi.fPosEquExpVarPtrs[k] += bi.expVarDerivs[k];
1022  *bi.fNegEquExpVarPtrs[k] -= bi.expVarDerivs[k];
1023  }
1024 #else
1025  for( int j = 0; j < bi.expNumVars; ++j )
1026  {
1027  dFdx[bi.li_Pos][bi.APosEquExpVarOffsets[j]] += bi.expVarDerivs[j];
1028  dFdx[bi.li_Neg][bi.ANegEquExpVarOffsets[j]] -= bi.expVarDerivs[j];
1029  }
1030 #endif
1031  }
1032  }
1033  }
1034  return true;
1035 }
1036 
1037 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
1038 {
1039  return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
1040 }
1041 
1043 {
1045  .registerDevice("b", 1)
1046  .registerDevice("f", 1)
1047  .registerDevice("h", 1);
1048 }
1049 
1050 } // namespace Bsrc
1051 } // namespace Device
1052 } // namespace Xyce