Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_DEV_Vcvs.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_Vcvs.C,v $
27 //
28 // Purpose :
29 //
30 // Special Notes :
31 //
32 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
33 //
34 // Creation Date : 02/28/00
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision: 1.131.2.2 $
40 //
41 // Revision Date : $Date: 2014/03/06 23:33:43 $
42 //
43 // Current Owner : $Author: tvrusso $
44 //-------------------------------------------------------------------------
45 #include <Xyce_config.h>
46 
47 // ---------- Standard Includes ----------
48 #ifdef HAVE_CSTDIO
49 #include <cstdio>
50 #else
51 #include <stdio.h>
52 #endif
53 
54 // ---------- Xyce Includes ----------
55 #include <N_DEV_DeviceOptions.h>
56 #include <N_DEV_ExternData.h>
57 #include <N_DEV_MatrixLoadData.h>
58 #include <N_DEV_SolverState.h>
59 #include <N_DEV_Vcvs.h>
60 #include <N_DEV_Message.h>
61 #include <N_ERH_ErrorMgr.h>
62 
63 #include <N_LAS_Vector.h>
64 #include <N_LAS_Matrix.h>
65 
66 namespace Xyce {
67 namespace Device {
68 
69 
70 namespace Vcvs {
71 
72 
74 {
75 // Set up double precision variables:
76  p.addPar ("G", 0.0, false, ParameterType::NO_DEP,
78  NULL,U_NONE,CAT_NONE,"Gain");
79 }
80 
82 {
83 }
84 
85 
86 
87 std::vector< std::vector<int> > Instance::jacStamp;
88 
89 //-----------------------------------------------------------------------------
90 // Function : Instance::Instance
91 // Purpose : "instance block" constructor
92 // Special Notes :
93 // Scope : public
94 // Creator : Tom Russo, SNL, Component Information and Models
95 // Creation Date : 12/20/00
96 //-----------------------------------------------------------------------------
98  const Configuration & configuration,
99  const InstanceBlock & IBref,
100  Model & Viter,
101  const FactoryBlock & factory_block)
102  : DeviceInstance(IBref, configuration.getInstanceParameters(), factory_block),
103  IB(IBref),
104  model_(Viter),
105  Gain(1.0),
106  li_Pos(-1),
107  li_Neg(-1),
108  li_Bra(-1),
109  li_ContPos(-1),
110  li_ContNeg(-1),
111  ABraEquPosNodeOffset(-1),
112  ABraEquNegNodeOffset(-1),
113  ABraEquContPosNodeOffset(-1),
114  ABraEquContNegNodeOffset(-1),
115  APosEquBraVarOffset(-1),
116  ANegEquBraVarOffset(-1),
117 
118  f_BraEquPosNodePtr(0),
119  f_BraEquNegNodePtr(0),
120  f_BraEquContPosNodePtr(0),
121  f_BraEquContNegNodePtr(0),
122  f_PosEquBraVarPtr(0),
123  f_NegEquBraVarPtr(0)
124 {
125  numIntVars = 1;
126  numExtVars = 4;
127  numStateVars = 0;
128 
129  std::string prefix(getName() + "-");
130  std::string name2;
131 
132  name2 = prefix + "I_branch";
133 
134 
135  if( jacStamp.empty() )
136  {
137  jacStamp.resize(5);
138  jacStamp[0].resize(1);
139  jacStamp[0][0]=4;
140  jacStamp[1].resize(1);
141  jacStamp[1][0]=4;
142  jacStamp[4].resize(4);
143  jacStamp[4][0]=0;
144  jacStamp[4][1]=1;
145  jacStamp[4][2]=2;
146  jacStamp[4][3]=3;
147  }
148 
149 
150  // Set params to constant default values:
151  setDefaultParams ();
152 
153  // Set params according to instance line and constant defaults from metadata:
154  setParams (IB.params);
155 
156  // Set any non-constant parameter defaults:
157  if (!given("G"))
158  {
159  UserError0(*this) << "Could not find Gain parameter in instance.";
160  }
161 }
162 
163 //-----------------------------------------------------------------------------
164 // Function : Instance::~Instance
165 // Purpose : destructor
166 // Special Notes :
167 // Scope : public
168 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
169 // Creation Date : 3/16/00
170 //-----------------------------------------------------------------------------
172 {
173 
174 }
175 
176 //-----------------------------------------------------------------------------
177 // Function : Instance::registerLIDs
178 // Purpose :
179 // Special Notes :
180 // Scope : public
181 // Creator : Robert Hoekstra, SNL, Computational Science
182 // Creation Date : 6/21/02
183 //-----------------------------------------------------------------------------
184 void Instance::registerLIDs ( const std::vector<int> & intLIDVecRef,
185  const std::vector<int> & extLIDVecRef )
186 {
187  std::string msg;
188 
189 #ifdef Xyce_DEBUG_DEVICE
190  if (getDeviceOptions().debugLevel > 0)
191  {
192  Xyce::dout() << std::endl << section_divider << std::endl;
193  Xyce::dout() << " VcvsInstance::registerLIDs" << std::endl;
194  Xyce::dout() << " name = " << getName() << std::endl;
195  }
196 #endif
197 
198  // Check if the size of the ID lists corresponds to the
199  // proper number of internal and external variables.
200  int numInt = intLIDVecRef.size();
201  int numExt = extLIDVecRef.size();
202 
203  if (numInt != numIntVars)
204  {
205  msg = "Instance::registerLIDs:";
206  msg += "numInt != numIntVars";
207  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
208  }
209 
210  if (numExt != numExtVars)
211  {
212  msg = "Instance::registerLIDs:";
213  msg += "numExt != numExtVars";
214  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
215  }
216 
217  // copy over the global ID lists.
218  intLIDVec = intLIDVecRef;
219  extLIDVec = extLIDVecRef;
220 
221  // Now use these lists to obtain the indices into the
222  // linear algebra entities. This assumes an order.
223  // For the matrix indices, first do the rows.
224 
225  li_Pos = extLIDVec[0];
226  li_Neg = extLIDVec[1];
227  li_ContPos = extLIDVec[2];
228  li_ContNeg = extLIDVec[3];
229 
230 #ifdef Xyce_DEBUG_DEVICE
231  if (getDeviceOptions().debugLevel > 0)
232  {
233  Xyce::dout() << " li_Pos = " << li_Pos << std::endl;
234  Xyce::dout() << " li_Neg = " << li_Neg << std::endl;
235  Xyce::dout() << " li_ContPos = " << li_ContPos << std::endl;
236  Xyce::dout() << " li_ContNeg = " << li_ContNeg << std::endl;
237  }
238 #endif
239 
240  li_Bra = intLIDVec[0];
241 
242 #ifdef Xyce_DEBUG_DEVICE
243  if (getDeviceOptions().debugLevel > 0)
244  Xyce::dout() << " li_Bra = " << li_Bra << std::endl;
245 #endif
246 
247 #ifdef Xyce_DEBUG_DEVICE
248  if (getDeviceOptions().debugLevel > 0)
249  Xyce::dout() << section_divider << std::endl;
250 #endif
251 }
252 
253 //-----------------------------------------------------------------------------
254 // Function : Instance::getIntNameMap
255 // Purpose :
256 // Special Notes :
257 // Scope : public
258 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
259 // Creation Date : 05/13/05
260 //-----------------------------------------------------------------------------
261 std::map<int,std::string> & Instance::getIntNameMap ()
262 {
263  // set up the internal name map, if it hasn't been already.
264  if (intNameMap.empty ())
265  {
266  // set up the internal names map:
267  std::string tmpstr(getName()+"_branch");
268  spiceInternalName (tmpstr);
269  intNameMap[ li_Bra ] = tmpstr;
270  }
271 
272  return intNameMap;
273 }
274 
275 //-----------------------------------------------------------------------------
276 // Function : Instance::registerStateGIDs
277 // Purpose :
278 // Special Notes :
279 // Scope : public
280 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
281 // Creation Date : 6/21/02
282 //-----------------------------------------------------------------------------
283 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
284 {
285  AssertLIDs(staLIDVecRef.size() == numStateVars);
286 }
287 
288 //-----------------------------------------------------------------------------
289 // Function : Instance::jacobianStamp
290 // Purpose :
291 // Special Notes :
292 // Scope : public
293 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
294 // Creation Date : 9/2/02
295 //-----------------------------------------------------------------------------
296 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
297 {
298  return jacStamp;
299 }
300 
301 //-----------------------------------------------------------------------------
302 // Function : Instance::registerJacLIDs
303 // Purpose :
304 // Special Notes :
305 // Scope : public
306 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
307 // Creation Date : 9/2/02
308 //-----------------------------------------------------------------------------
309 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
310 {
311  DeviceInstance::registerJacLIDs( jacLIDVec );
312 
313  APosEquBraVarOffset = jacLIDVec[0][0];
314  ANegEquBraVarOffset = jacLIDVec[1][0];
315  ABraEquPosNodeOffset = jacLIDVec[4][0];
316  ABraEquNegNodeOffset = jacLIDVec[4][1];
317  ABraEquContPosNodeOffset = jacLIDVec[4][2];
318  ABraEquContNegNodeOffset = jacLIDVec[4][3];
319 }
320 
321 //-----------------------------------------------------------------------------
322 // Function : Instance::setupPointers
323 // Purpose :
324 // Special Notes :
325 // Scope : public
326 // Creator : Eric Keiter, SNL
327 // Creation Date : 12/12/08
328 //-----------------------------------------------------------------------------
330 {
331 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
332  N_LAS_Matrix & dFdx = *(extData.dFdxMatrixPtr);
333 
340 #endif
341 }
342 
343 //-----------------------------------------------------------------------------
344 // Function : Instance::updatePrimaryState
345 // Purpose :
346 // Special Notes :
347 // Scope : public
348 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
349 // Creation Date : 01/29/01
350 //-----------------------------------------------------------------------------
352 {
353  return true;
354 }
355 
356 //-----------------------------------------------------------------------------
357 // Function : Instance::loadDAEFVector
358 //
359 // Purpose : Loads the F-vector contributions for a single
360 // Vcvs instance.
361 //
362 // Special Notes :
363 //
364 // Scope : public
365 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
366 // Creation Date : 02/19/05
367 //-----------------------------------------------------------------------------
369 {
370  double * fVec = extData.daeFVectorRawPtr;
371  double * solVec = extData.nextSolVectorRawPtr;
372 
373  double v_pos = solVec[li_Pos];
374  double v_neg = solVec[li_Neg];
375  double v_cont_pos = solVec[li_ContPos];
376  double v_cont_neg = solVec[li_ContNeg];
377 
378  double i_bra = solVec[li_Bra];
379 
380  fVec[li_Pos] += i_bra;
381  fVec[li_Neg] += -i_bra;
382 
383  double src = Gain * ( v_cont_pos - v_cont_neg ) - v_pos + v_neg;
384  fVec[li_Bra] += -src;
385 
386  return true;
387 }
388 
389 //-----------------------------------------------------------------------------
390 // Function : Instance::loadDAEdFdx ()
391 //
392 // Purpose : Loads the F-vector contributions for a single
393 // resistor instance.
394 //
395 // Special Notes : The F-vector is an algebraic constaint.
396 //
397 // Scope : public
398 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
399 // Creation Date : 02/19/05
400 //-----------------------------------------------------------------------------
402 {
403  N_LAS_Matrix & dFdx = *(extData.dFdxMatrixPtr);
404 
405  dFdx[li_Pos][APosEquBraVarOffset] += 1.0;
406  dFdx[li_Neg][ANegEquBraVarOffset] -= 1.0;
407 
408  dFdx[li_Bra][ABraEquPosNodeOffset] += 1.0;
409  dFdx[li_Bra][ABraEquNegNodeOffset] -= 1.0;
412 
413  return true;
414 }
415 
416 //-----------------------------------------------------------------------------
417 // Function : Instance::varTypes
418 // Purpose :
419 // Special Notes :
420 // Scope : public
421 // Creator : Rob Hoekstra, SNL, Parallel Computational Sciences
422 // Creation Date : 02/17/04
423 //-----------------------------------------------------------------------------
424 void Instance::varTypes( std::vector<char> & varTypeVec )
425 {
426  varTypeVec.resize(1);
427  varTypeVec[0] = 'I';
428 }
429 
430 // Class Model
431 
432 //-----------------------------------------------------------------------------
433 // Function : Model::Model
434 // Purpose : "Model block" constructor
435 // Special Notes :
436 // Scope : public
437 // Creator : Tom Russo, SNL, Component Information and Models
438 // Creation Date : 12/21/00
439 //-----------------------------------------------------------------------------
441  const Configuration & configuration,
442  const ModelBlock & MB,
443  const FactoryBlock & factory_block)
444  : DeviceModel(MB, configuration.getModelParameters(), factory_block)
445 {
446 }
447 
448 //-----------------------------------------------------------------------------
449 // Function : Model::~Model
450 // Purpose : destructor
451 // Special Notes :
452 // Scope : public
453 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
454 // Creation Date : 3/16/00
455 //-----------------------------------------------------------------------------
457 {
458  std::vector<Instance*>::iterator iter;
459  std::vector<Instance*>::iterator first = instanceContainer.begin();
460  std::vector<Instance*>::iterator last = instanceContainer.end();
461 
462  for (iter=first; iter!=last; ++iter)
463  {
464  delete (*iter);
465  }
466 }
467 
468 //-----------------------------------------------------------------------------
469 // Function : Model::printOutInstances
470 // Purpose : debugging tool.
471 // Special Notes :
472 // Scope : public
473 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
474 // Creation Date : 4/03/00
475 //-----------------------------------------------------------------------------
476 std::ostream &Model::printOutInstances(std::ostream &os) const
477 {
478  std::vector<Instance*>::const_iterator iter;
479  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
480  std::vector<Instance*>::const_iterator last = instanceContainer.end();
481 
482  int i;
483  os << std::endl;
484  os << " name model name Parameters" << std::endl;
485  for (i=0, iter=first; iter!=last; ++iter, ++i)
486  {
487  os << " " << i << ": " << (*iter)->getName() << " ";
488  os << getName();
489  os << std::endl;
490  }
491 
492  os << std::endl;
493 
494  return os;
495 }
496 
497 //-----------------------------------------------------------------------------
498 // Function : Model::forEachInstance
499 // Purpose :
500 // Special Notes :
501 // Scope : public
502 // Creator : David Baur
503 // Creation Date : 2/4/2014
504 //-----------------------------------------------------------------------------
505 /// Apply a device instance "op" to all instances associated with this
506 /// model
507 ///
508 /// @param[in] op Operator to apply to all instances.
509 ///
510 ///
511 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
512 {
513  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
514  op(*it);
515 }
516 
517 
518 // Vcvs Master functions:
519 
520 //-----------------------------------------------------------------------------
521 // Function : Master::updateState
522 // Purpose :
523 // Special Notes :
524 // Scope : public
525 // Creator : Eric Keiter, SNL
526 // Creation Date : 11/26/08
527 //-----------------------------------------------------------------------------
528 bool Master::updateState (double * solVec, double * staVec, double * stoVec)
529 {
530  return true;
531 }
532 
533 //-----------------------------------------------------------------------------
534 // Function : Master::loadDAEVectors
535 // Purpose :
536 // Special Notes :
537 // Scope : public
538 // Creator : Eric Keiter, SNL
539 // Creation Date : 11/26/08
540 //-----------------------------------------------------------------------------
541 bool Master::loadDAEVectors (double * solVec, double * fVec, double *qVec, double * storeLeadF, double * storeLeadQ)
542 {
543 #ifdef _OMP
544 #pragma omp parallel for
545 #endif
546  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
547  {
548  Instance & vi = *(*it);
549 
550  double v_pos = solVec[vi.li_Pos];
551  double v_neg = solVec[vi.li_Neg];
552  double v_cont_pos = solVec[vi.li_ContPos];
553  double v_cont_neg = solVec[vi.li_ContNeg];
554 
555  double i_bra = solVec[vi.li_Bra];
556 
557  fVec[vi.li_Pos] += i_bra;
558  fVec[vi.li_Neg] += -i_bra;
559 
560  double src = vi.Gain * ( v_cont_pos - v_cont_neg ) - v_pos + v_neg;
561  fVec[vi.li_Bra] += -src;
562 
563  }
564 
565  return true;
566 }
567 
568 //-----------------------------------------------------------------------------
569 // Function : Master::loadDAEMatrices
570 // Purpose :
571 // Special Notes :
572 // Scope : public
573 // Creator : Eric Keiter, SNL
574 // Creation Date : 11/26/08
575 //-----------------------------------------------------------------------------
576 bool Master::loadDAEMatrices (N_LAS_Matrix & dFdx, N_LAS_Matrix & dQdx)
577 {
578  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
579  {
580  Instance & vi = *(*it);
581 
582 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
583 
584  *vi.f_PosEquBraVarPtr += 1.0;
585  *vi.f_NegEquBraVarPtr -= 1.0;
586 
587  *vi.f_BraEquPosNodePtr += 1.0;
588  *vi.f_BraEquNegNodePtr -= 1.0;
589  *vi.f_BraEquContPosNodePtr -= vi.Gain;
590  *vi.f_BraEquContNegNodePtr += vi.Gain;
591 #else
592 
593  dFdx[vi.li_Pos][vi.APosEquBraVarOffset] += 1.0;
594  dFdx[vi.li_Neg][vi.ANegEquBraVarOffset] -= 1.0;
595 
596  dFdx[vi.li_Bra][vi.ABraEquPosNodeOffset] += 1.0;
597  dFdx[vi.li_Bra][vi.ABraEquNegNodeOffset] -= 1.0;
598  dFdx[vi.li_Bra][vi.ABraEquContPosNodeOffset] -= vi.Gain;
599  dFdx[vi.li_Bra][vi.ABraEquContNegNodeOffset] += vi.Gain;
600 #endif
601  }
602  return true;
603 }
604 
605 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
606 {
607 
608  return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
609 }
610 
612 {
614  .registerDevice("e", 1)
615  .registerModelType("e", 1);
616 }
617 
618 } // namespace Vcvs
619 } // namespace Device
620 } // namespace Xyce