Xyce  6.1
N_DEV_OpAmp.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 : N_DEV_OpAmp.C
27 //
28 // Purpose : An Ideal OpAmp Model
29 //
30 // Special Notes : This model assumes infinite gain
31 // and unbounded output voltages
32 //
33 // Creator : Brian Fett, SNL
34 //
35 // Creation Date : 07/27/05
36 //
37 //-------------------------------------------------------------------------
38 #include <Xyce_config.h>
39 
40 // ---------- Standard Includes ----------
41 
42 // ---------- Xyce Includes ----------
43 #include <N_DEV_DeviceOptions.h>
44 #include <N_DEV_DeviceMaster.h>
45 #include <N_DEV_ExternData.h>
46 #include <N_DEV_MatrixLoadData.h>
47 #include <N_DEV_OpAmp.h>
48 #include <N_DEV_SolverState.h>
49 #include <N_DEV_Message.h>
50 #include <N_ERH_ErrorMgr.h>
51 
52 #include <N_LAS_Vector.h>
53 #include <N_LAS_Matrix.h>
54 #include <N_UTL_FeatureTest.h>
55 
56 namespace Xyce {
57 namespace Device {
58 
59 namespace OpAmp {
60 
62 {
63  p.addPar ("FAKEPARAM", 0.0, &OpAmp::Instance::FAKEPARAM)
64  .setUnit(U_NONE)
65  .setCategory(CAT_NONE)
66  .setDescription("");
67 }
68 
70 {
71 }
72 
73 std::vector< std::vector<int> > Instance::jacStamp;
74 
75 // Class Instance
76 //-----------------------------------------------------------------------------
77 // Function : Instance::Instance
78 // Purpose : instance block constructor
79 // Special Notes :
80 // Scope : public
81 // Creator : Brian Fett, SNL
82 // Creation Date : 08/05/07
83 //-----------------------------------------------------------------------------
85  const Configuration & configuration,
86  const InstanceBlock & IB,
87  Model & iter,
88  const FactoryBlock & factory_block)
89  : DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
90  model_(iter),
91  outCurrent(0.0),
92  deltaVoltage(0.0),
93 
94  FAKEPARAM(0.0),
95 
96  li_Pos(-1),
97  li_Neg(-1),
98  li_Out(-1),
99  li_Bra(-1),
100 
101  ABraEquPosNodeOffset(-1),
102  ABraEquNegNodeOffset(-1),
103  AOutEquBraVarOffset(-1),
104 
105  v_pos(0.0),
106  v_neg(0.0),
107  v_out(0.0),
108  i_bra(0.0)
109 {
110  numIntVars = 1;
111  numExtVars = 3;
112  numStateVars = 0;
113 
114  if( jacStamp.empty() )
115  {
116  jacStamp.resize(4); // V1 V2 V3 I
117  jacStamp[2].resize(1); // N1
118  jacStamp[2][0] = 3; // N2
119  jacStamp[3].resize(2); // N3 X
120  jacStamp[3][0] = 0; // Br X X
121  jacStamp[3][1] = 1;
122  }
123 
124 
125  // Set params to constant default values:
126  setDefaultParams ();
127 
128  // Set params according to instance line and constant defaults from metadata:
129  setParams (IB.params);
130 
131  // calculate dependent (ie computed) params and check for errors:
132 
133 }
134 
135 //-----------------------------------------------------------------------------
136 // Function : Instance::~Instance
137 // Purpose : destructor
138 // Special Notes :
139 // Scope : public
140 // Creator : Brian Fett
141 // Creation Date : 07/28/05
142 //-----------------------------------------------------------------------------
144 {
145 }
146 //-----------------------------------------------------------------------------
147 // Function : Instance::processParams
148 // Purpose :
149 // Special Notes :
150 // Scope : public
151 // Creator : Brian Fett, SNL
152 // Creation Date : 08/05/05
153 //-----------------------------------------------------------------------------
155 {
156 
157  return true;
158 }
159 
160 
161 // Additional Declarations
162 
163 //-----------------------------------------------------------------------------
164 // Function : Instance::registerLIDs
165 // Purpose :
166 // Special Notes :
167 // Scope : public
168 // Creator : Brian Fett, SNL
169 // Creation Date : 08/05/05
170 //-----------------------------------------------------------------------------
171 void Instance::registerLIDs ( const std::vector<int> & intLIDVecRef,
172  const std::vector<int> & extLIDVecRef)
173 {
174  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) )
175  {
176  Xyce::dout() << std::endl << section_divider << std::endl;
177  Xyce::dout() << " OpAmpInstance::registerLIDs" << std::endl;
178  Xyce::dout() << " name = " << getName() << std::endl;
179  }
180 
181  // Check if the size of the ID lists corresponds to the
182  // proper number of internal and external variables.
183  int numInt = intLIDVecRef.size();
184  int numExt = extLIDVecRef.size();
185 
186  if (numInt != numIntVars)
187  {
188  std::string msg = "Instance::registerLIDs:";
189  msg += "numInt != numIntVars";
190  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL_0,msg);
191  }
192 
193  if (numExt != numExtVars)
194  {
195  std::string msg = "Instance::registerLIDs:";
196  msg += "numExt != numExtVars";
197  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL_0,msg);
198  }
199 
200  // copy over the global ID lists.
201  intLIDVec = intLIDVecRef;
202  extLIDVec = extLIDVecRef;
203 
204  // Now use these lists to obtain the indices into the
205  // linear algebra entities. This assumes an order.
206  // For the matrix indices, first do the rows.
207 
208  li_Pos = extLIDVec[0];
209  li_Neg = extLIDVec[1];
210  li_Out = extLIDVec[2];
211  li_Bra = intLIDVec[0];
212 
213  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) )
214  {
215  Xyce::dout() << " li_Pos = " << li_Pos << std::endl;
216  Xyce::dout() << " li_Neg = " << li_Neg << std::endl;
217  Xyce::dout() << " li_Out = " << li_Out << std::endl;
218  Xyce::dout() << " li_Bra = " << li_Bra << std::endl;
219  Xyce::dout() << section_divider << std::endl;
220  }
221 }
222 
223 //-----------------------------------------------------------------------------
224 // Function : Instance::registerStateLIDs
225 // Purpose :
226 // Special Notes :
227 // Scope : public
228 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
229 // Creation Date : 6/20/02
230 //-----------------------------------------------------------------------------
231 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
232 {
233  AssertLIDs(staLIDVecRef.size() == numStateVars);
234 }
235 
236 //-----------------------------------------------------------------------------
237 // Function : Instance::jacobianStamp
238 // Purpose :
239 // Special Notes :
240 // Scope : public
241 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
242 // Creation Date : 8/21/02
243 //-----------------------------------------------------------------------------
244 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
245 {
246  return jacStamp;
247 }
248 
249 //-----------------------------------------------------------------------------
250 // Function : Instance::registerJacLIDs
251 // Purpose :
252 // Special Notes :
253 // Scope : public
254 // Creator : Brian Fett, SNL
255 // Creation Date : 08/05/05
256 //-----------------------------------------------------------------------------
257 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
258 {
259  DeviceInstance::registerJacLIDs( jacLIDVec );
260 
261  AOutEquBraVarOffset = jacLIDVec[2][0];
262  ABraEquPosNodeOffset = jacLIDVec[3][0];
263  ABraEquNegNodeOffset = jacLIDVec[3][1];
264 }
265 
266 //-----------------------------------------------------------------------------
267 // Function : Instance::loadNodeSymbols
268 // Purpose :
269 // Special Notes :
270 // Scope : public
271 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
272 // Creation Date : 05/13/05
273 //-----------------------------------------------------------------------------
274 void Instance::loadNodeSymbols(Util::SymbolTable &symbol_table) const
275 {}
276 
277 //-----------------------------------------------------------------------------
278 // Function : Instance::updateIntermediateVars
279 // Purpose :
280 // Special Notes :
281 // Scope : public
282 // Creator : Brian Fett, SNL
283 // Creation Date : 08/05/05
284 //-----------------------------------------------------------------------------
286 {
287  Linear::Vector * solVectorPtr = extData.nextSolVectorPtr;
288 
289  // get the value for v_pos, v_neg, v_out, i_bra
290 
291  v_pos = (*solVectorPtr)[li_Pos];
292  v_neg = (*solVectorPtr)[li_Neg];
293  v_out = (*solVectorPtr)[li_Out];
294  i_bra = (*solVectorPtr)[li_Bra];
295 
296  outCurrent = i_bra;
298 
299  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
300  {
301  Xyce::dout() << subsection_divider << std::endl;
302  Xyce::dout() << " Instance::updateIntermediateVars" << std::endl;
303  Xyce::dout() << " name = " << getName() <<std::endl;
304  Xyce::dout() << " v_pos = " << v_pos << std::endl;
305  Xyce::dout() << " v_neg = " << v_neg << std::endl;
306  Xyce::dout() << " v_out = " << v_out << std::endl;
307  Xyce::dout() << " i_bra = " << i_bra << std::endl;
308  Xyce::dout() << std::endl;
309  Xyce::dout() << subsection_divider << std::endl;
310  }
311 
312  return true;
313 }
314 
315 //-----------------------------------------------------------------------------
316 // Function : Instance::updatePrimaryState
317 // Purpose :
318 // Special Notes :
319 // Scope : public
320 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
321 // Creation Date : 01/29/01
322 //-----------------------------------------------------------------------------
324 {
325  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
326  {
327  Xyce::dout() << " Instance::updatePrimaryState" << std::endl;
328  }
329  bool bsuccess = true;
330  bsuccess = updateIntermediateVars ();
331  return bsuccess;
332 }
333 
334 //-----------------------------------------------------------------------------
335 // Function : Instance::loadDAEFVector
336 //
337 // Purpose : Loads the F-vector contributions for a single
338 // OpAmp instance.
339 //
340 // Special Notes :
341 //
342 // Scope : public
343 // Creator : Brian Fett, SNL
344 // Creation Date : 08/05/05
345 //-----------------------------------------------------------------------------
347 {
348  // bool bsuccess = true;
349  // int i_pos_rhs, i_neg_rhs, i_bra_rhs;
350 
351  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
352  {
353  Xyce::dout() << subsection_divider << std::endl;
354  Xyce::dout() << " Instance::loadDAEFVector" << std::endl;
355  Xyce::dout() << " name = " << getName() <<std::endl;
356  Xyce::dout() << " Output Current = " << outCurrent << std::endl;
357  Xyce::dout() << " Delta Voltage = " << deltaVoltage << std::endl;
358  }
359 
360  // Using values determined during the loadRHS function call.
361  // (outCurrent, deltaVoltage).
362 
363  //(*extData.daeFVectorPtr)[li_Pos] += 0;
364  //(*extData.daeFVectorPtr)[li_Neg] += 0;
365 
367 
369 
370  return true;
371 }
372 
373 //-----------------------------------------------------------------------------
374 // Function : Instance::loadDAEdFdx ()
375 //
376 // Purpose : Loads the F-vector contributions for a single
377 // resistor instance.
378 //
379 // Special Notes :
380 //
381 // Scope : public
382 // Creator : Brian Fett, SNL
383 // Creation Date : 08/02/05
384 //-----------------------------------------------------------------------------
386 {
387  // bool bsuccess = true;
388 
389  Linear::Matrix * dFdxMatPtr = extData.dFdxMatrixPtr;
390 
391  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
392  {
393  Xyce::dout() << subsection_divider << std::endl;
394  Xyce::dout() << "name = " << getName() << std::endl;
395  Xyce::dout() << "\nOPAMP dFdx LOADS\n";
396  Xyce::dout() << "Pos,Bra: " << li_Out << ",";
397  Xyce::dout() << AOutEquBraVarOffset << ": " << 1.0 << std::endl;
398  Xyce::dout() << "Bra,Pos: " << li_Bra << ",";
399  Xyce::dout() << ABraEquPosNodeOffset << ": " << 1.0 << std::endl;
400  Xyce::dout() << "Bra,Neg: " << li_Bra << ",";
401  Xyce::dout() << ABraEquNegNodeOffset << ": " << -1.0 << std::endl;
402  Xyce::dout() << "DONE OPAMP dFdx LOAD\n";
403  }
404 
405  (*dFdxMatPtr)[li_Out][AOutEquBraVarOffset] += 1.0;
406  (*dFdxMatPtr)[li_Bra][ABraEquPosNodeOffset] += 1.0;
407  (*dFdxMatPtr)[li_Bra][ABraEquNegNodeOffset] -= 1.0;
408 
409  return true;
410 }
411 
412 // end of new-DAE functions
413 
414 // Class Model
415 
416 //-----------------------------------------------------------------------------
417 // Function : Model::Model
418 // Purpose : model block constructor
419 // Special Notes :
420 // Scope : public
421 // Creator : Brian Fett, SNL
422 // Creation Date : 08/05/05
423 //-----------------------------------------------------------------------------
425  const Configuration & configuration,
426  const ModelBlock & MB,
427  const FactoryBlock & factory_block)
428  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
429  FAKEPARAM(0.0)
430 {
431 }
432 
433 //-----------------------------------------------------------------------------
434 // Function : Model::~Model
435 // Purpose : destructor
436 // Special Notes :
437 // Scope : public
438 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
439 // Creation Date : 04/06/00
440 //-----------------------------------------------------------------------------
442 {
443  std::vector<Instance*>::iterator iter = instanceContainer.begin();
444  std::vector<Instance*>::iterator last = instanceContainer.end();
445 
446  for ( ; iter!=last; ++iter)
447  {
448  delete (*iter);
449  }
450 }
451 
452 // Additional Declarations
453 
454 //-----------------------------------------------------------------------------
455 // Function : Model::printOutInstances
456 // Purpose : debugging tool.
457 // Special Notes :
458 // Scope : public
459 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
460 // Creation Date : 4/03/00
461 //-----------------------------------------------------------------------------
462 std::ostream &Model::printOutInstances(std::ostream &os) const
463 {
464  std::vector<Instance*>::const_iterator iter = instanceContainer.begin();
465  std::vector<Instance*>::const_iterator last = instanceContainer.end();
466 
467  os << std::endl;
468  os << " name model name Parameters" << std::endl;
469  for (int i=0; iter!=last; ++iter, ++i)
470  {
471  os << " " << i << ": " << (*iter)->getName() << " ";
472  os << getName();
473  os << std::endl;
474  }
475 
476  os << std::endl;
477 
478  return os;
479 }
480 
481 //-----------------------------------------------------------------------------
482 // Function : Model::forEachInstance
483 // Purpose :
484 // Special Notes :
485 // Scope : public
486 // Creator : David Baur
487 // Creation Date : 2/4/2014
488 //-----------------------------------------------------------------------------
489 /// Apply a device instance "op" to all instances associated with this
490 /// model
491 ///
492 /// @param[in] op Operator to apply to all instances.
493 ///
494 ///
495 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
496 {
497  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
498  op(*it);
499 }
500 
501 
502 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
503 {
504 
505  return new DeviceMaster<Traits>(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
506 }
507 
509 {
511  .registerDevice("opamp", 1)
512  .registerModelType("opamp", 1);
513 }
514 
515 } // namespace OpAmp
516 } // namespace Device
517 } // namespace Xyce
const InstanceName & getName() const
const SolverState & solverState_
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
Linear::Vector * nextSolVectorPtr
Pure virtual class to augment a linear system.
void registerJacLIDs(const std::vector< std::vector< int > > &jacLIDVec)
Definition: N_DEV_OpAmp.C:257
virtual void forEachInstance(DeviceInstanceOp &op) const
Apply a device instance "op" to all instances associated with this model.
Definition: N_DEV_OpAmp.C:495
virtual std::ostream & printOutInstances(std::ostream &os) const
Definition: N_DEV_OpAmp.C:462
#define AssertLIDs(cmp)
virtual void registerJacLIDs(const JacobianStamp &jacLIDVec)
const std::vector< std::vector< int > > & jacobianStamp() const
Definition: N_DEV_OpAmp.C:244
void setParams(const std::vector< Param > &params)
const std::string & getName() const
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
std::vector< Instance * > instanceContainer
Definition: N_DEV_OpAmp.h:221
const DeviceOptions & deviceOptions_
virtual void loadNodeSymbols(Util::SymbolTable &symbol_table) const
Populates and returns the store name map.
Definition: N_DEV_OpAmp.C:274
void registerLIDs(const std::vector< int > &intLIDVecRef, const std::vector< int > &extLIDVecRef)
Definition: N_DEV_OpAmp.C:171
static Config< T > & addConfiguration()
Adds the device to the Xyce device configuration.
Linear::Matrix * dFdxMatrixPtr
The Device class is an interface for device implementations.
Definition: N_DEV_Device.h:101
static Device * factory(const Configuration &configuration, const FactoryBlock &factory_block)
Definition: N_DEV_OpAmp.C:502
Class Configuration contains device configuration data.
const SolverState & getSolverState() const
Instance(const Configuration &configuration, const InstanceBlock &IB, Model &iter, const FactoryBlock &factory_block)
Definition: N_DEV_OpAmp.C:84
static void loadModelParameters(ParametricData< Model > &model_parameters)
Definition: N_DEV_OpAmp.C:69
Linear::Vector * daeFVectorPtr
static std::vector< std::vector< int > > jacStamp
Definition: N_DEV_OpAmp.h:134
ModelBlock represents a .MODEL line from the netlist.
Manages parameter binding for class C.
Definition: N_DEV_Pars.h:214
InstanceBlock represent a device instance line from the netlist.
static void loadInstanceParameters(ParametricData< Instance > &instance_parameters)
Definition: N_DEV_OpAmp.C:61
std::vector< Param > params
void registerStateLIDs(const std::vector< int > &staLIDVecRef)
Definition: N_DEV_OpAmp.C:231