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