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