Xyce  6.1
N_DEV_ACC.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_ACC.C,v $
27 //
28 // Purpose : Provide a solution to the simple second order
29 // initial value problem:
30 // d^2x/dt^2 = a(t); x(0) = x0, dx/dt(0) = v0
31 //
32 // Special Notes : Intended for use in FY07 CoilGun LDRD work
33 //
34 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
35 //
36 // Creation Date : 10/25/07
37 //
38 // Revision Information:
39 // ---------------------
40 //
41 // Revision Number: $Revision: 1.57 $
42 //
43 // Revision Date : $Date: 2015/04/24 20:25:45 $
44 //
45 // Current Owner : $Author: dgbaur $
46 //----------------------------------------------------------------------------
47 
48 #include <Xyce_config.h>
49 
50 
51 // ---------- Standard Includes ----------
52 
53 // ---------- Xyce Includes ----------
54 #include <N_DEV_ACC.h>
55 #include <N_DEV_Const.h>
56 #include <N_DEV_DeviceOptions.h>
57 #include <N_DEV_DeviceMaster.h>
58 #include <N_DEV_ExternData.h>
59 #include <N_DEV_MatrixLoadData.h>
60 #include <N_DEV_Message.h>
61 #include <N_DEV_SolverState.h>
62 #include <N_LAS_Matrix.h>
63 #include <N_LAS_Vector.h>
64 #include <N_UTL_FeatureTest.h>
65 #include <N_UTL_IndentStreamBuf.h>
66 
67 namespace Xyce {
68 namespace Device {
69 namespace ACC {
70 
72 {
73  p.addPar("V0", 0.0, &ACC::Instance::v0)
74  .setUnit(U_MSM1)
75  .setDescription("Initial Velocity");
76 
77  p.addPar("X0", 0.0, &ACC::Instance::x0)
78  .setUnit(U_METER)
79  .setDescription("Initial Position");
80 }
81 
83 {}
84 
85 
86 
87 std::vector< std::vector<int> > Instance::jacStamp;
88 
89 // Class Instance
90 //-----------------------------------------------------------------------------
91 // Function : Instance::Instance
92 // Purpose : "instance block" constructor
93 // Special Notes :
94 // Scope : public
95 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
96 // Creation Date : 10/25/07
97 //-----------------------------------------------------------------------------
99  const Configuration & configuration,
100  const InstanceBlock & IB,
101  Model & Miter,
102  const FactoryBlock & factory_block)
103  : DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
104  model_(Miter),
105  v0(0.0),
106  x0(0.0),
107  li_Acc(-1),
108  li_Velocity(-1),
109  li_Position(-1),
110  li_state_vel(-1),
111  li_state_pos(-1),
112  AVelEquAccNodeOffset(-1),
113  AVelEquVelNodeOffset(-1),
114  APosEquVelNodeOffset(-1),
115  APosEquPosNodeOffset(-1)
116 {
117  numIntVars = 0;
118  numExtVars = 3;
119  numStateVars = 2; // position and velocity saved in state so we can get
120  //derivs
121 
122  devConMap.resize(3);
123  devConMap[0]=1;
124  devConMap[1]=1;
125  devConMap[2]=1;
126 
127  if( jacStamp.empty() )
128  {
129  jacStamp.resize(3);
130  //jacStamp[0].resize(0); // the row for acceleration has nothing.
131  jacStamp[1].resize(2); // velocity row
132  jacStamp[1][0]=0; //velocity-acceleration
133  jacStamp[1][1]=1; //velocity-velocity
134  jacStamp[2].resize(2);
135  jacStamp[2][0]=1; // position-velocity
136  jacStamp[2][1]=2; // position-position
137  }
138 
139 
140  // Set params to constant default values:
141  setDefaultParams ();
142 
143  // Set params according to instance line and constant defaults from metadata:
144 
145  setParams (IB.params);
146 
147  // Set any non-constant parameter defaults:
148 
149 
150 }
151 
152 //-----------------------------------------------------------------------------
153 // Function : Instance::~Instance
154 // Purpose : destructor
155 // Special Notes :
156 // Scope : public
157 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
158 // Creation Date : 10/25/07
159 //-----------------------------------------------------------------------------
161 {
162 }
163 
164 //-----------------------------------------------------------------------------
165 // Function : Instance::registerLIDs
166 // Purpose :
167 // Special Notes :
168 // Scope : public
169 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
170 // Creation Date : 10/25/07
171 //-----------------------------------------------------------------------------
172 void Instance::registerLIDs( const std::vector<int> & intLIDVecRef,
173  const std::vector<int> & extLIDVecRef )
174 {
175  AssertLIDs(intLIDVecRef.size() == numIntVars);
176  AssertLIDs(extLIDVecRef.size() == numExtVars);
177 
178  // copy over the global ID lists.
179  intLIDVec = intLIDVecRef;
180  extLIDVec = extLIDVecRef;
181 
182  li_Acc = extLIDVec[0];
183  li_Velocity = extLIDVec[1];
184  li_Position = extLIDVec[2];
185 
186  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
187  {
188  dout() << getName() << " LIDs"
189  << Util::push << std::endl
190  << "li_Acc = " << li_Acc << std::endl
191  << "li_Velocity = " << li_Velocity << std::endl
192  << "li_Position = " << li_Position << std::endl
193  << Util::pop << std::endl;
194  }
195 }
196 
197 //-----------------------------------------------------------------------------
198 // Function : Instance::loadNodeSymbols
199 // Purpose :
200 // Special Notes :
201 // Scope : public
202 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
203 // Creation Date : 05/13/05
204 //-----------------------------------------------------------------------------
205 void Instance::loadNodeSymbols(Util::SymbolTable &symbol_table) const
206 {}
207 
208 //-----------------------------------------------------------------------------
209 // Function : Instance::registerStateLIDs
210 // Purpose : Set up offsets so we can store quantities that need to be
211 // differentiated.
212 // Special Notes :
213 // Scope : public
214 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
215 // Creation Date : 10/25/07
216 //-----------------------------------------------------------------------------
217 void Instance::registerStateLIDs(const std::vector<int> & staLIDVecRef )
218 {
219  AssertLIDs(staLIDVecRef.size() == numStateVars);
220 
221  // Copy over the global ID lists:
222  staLIDVec = staLIDVecRef;
223 
224  li_state_vel = staLIDVec[0];
225  li_state_pos = staLIDVec[1];
226 
227 }
228 
229 //-----------------------------------------------------------------------------
230 // Function : Instance::jacobianStamp
231 // Purpose :
232 // Special Notes :
233 // Scope : public
234 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
235 // Creation Date : 08/20/01
236 //-----------------------------------------------------------------------------
237 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
238 {
239  return jacStamp;
240 }
241 
242 //-----------------------------------------------------------------------------
243 // Function : Instance::registerJacLIDs
244 // Purpose :
245 // Special Notes :
246 // Scope : public
247 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
248 // Creation Date : 08/27/01
249 //-----------------------------------------------------------------------------
250 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
251 {
252  DeviceInstance::registerJacLIDs( jacLIDVec );
253 
254  AVelEquAccNodeOffset = jacLIDVec[1][0];
255  AVelEquVelNodeOffset = jacLIDVec[1][1];
256  APosEquVelNodeOffset = jacLIDVec[2][0];
257  APosEquPosNodeOffset = jacLIDVec[2][1];
258 }
259 
260 //-----------------------------------------------------------------------------
261 // Function : Instance::updateIntermediateVars
262 // Purpose : update intermediate variables for one diode instance
263 // Special Notes :
264 // Scope : public
265 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
266 // Creation Date : 10/25/07
267 //-----------------------------------------------------------------------------
269 {
270  bool bsuccess = true;
271 
272  double * solVec = extData.nextSolVectorRawPtr;
273 
274  position = solVec[li_Position];
275  velocity = solVec[li_Velocity];
276  acceleration = solVec[li_Acc];
277 
278  return bsuccess;
279 }
280 
281 //-----------------------------------------------------------------------------
282 // Function : Instance::updatePrimaryState
283 // Purpose :
284 // Special Notes :
285 // Scope : public
286 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
287 // Creation Date : 10/25/07
288 //-----------------------------------------------------------------------------
290 {
291  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
292  {
293  Xyce::dout() << "Instance::updatePrimaryState" <<std::endl;
294  }
295 
296  bool bsuccess = updateIntermediateVars ();
297  double * staVec = extData.nextStaVectorRawPtr;
298 
299  // We need to save the position and velocity so we can differentiate them
300  // to give what we *think* the velocity and acceleration are.
301  staVec[li_state_pos] = position;
302  staVec[li_state_vel] = velocity;
303 
304  // if this is the first newton step of the first time step
305  // of the transient simulation, we need to enforce that the
306  // time derivatives w.r.t. charge are zero. This is to maintain 3f5
307  // compatibility. ERK.
308 
309  if (!(getSolverState().dcopFlag) && (getSolverState().initTranFlag_) && getSolverState().newtonIter==0)
310  {
311  double * currStaVec = extData.currStaVectorRawPtr;
312  currStaVec[li_state_pos] = position;
313  currStaVec[li_state_vel] = velocity;
314  }
315 
316  return bsuccess;
317 }
318 
319 //-----------------------------------------------------------------------------
320 // Function : Instance::updateSecondaryState
321 // Purpose :
322 // Special Notes :
323 // Scope : public
324 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
325 // Creation Date : 10/25/07
326 //-----------------------------------------------------------------------------
328 {
329  double * staDerivVec = extData.nextStaDerivVectorRawPtr;
330 
331  xdot = staDerivVec[li_state_pos];
332  vdot = staDerivVec[li_state_vel];
333 
334  return true;
335 }
336 
337 //-----------------------------------------------------------------------------
338 // Function : Instance::loadDAEFVector
339 //
340 // Purpose : Loads the F-vector contributions for a single
341 // ACC instance.
342 //
343 // Special Notes :
344 //
345 //
346 // Scope : public
347 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
348 // Creation Date : 10/25/07
349 //-----------------------------------------------------------------------------
351 {
352  double * fVec = extData.daeFVectorRawPtr;
353 
354  // Load DAE F-vector
355  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
356  {
357  Xyce::dout() << subsection_divider << std::endl;
358  Xyce::dout() << " Instance::loadDAEFVector" << std::endl;
359  Xyce::dout() << " name = " << getName() <<std::endl;
360  Xyce::dout() << " velocity = " << velocity << std::endl;
361  Xyce::dout() << " position = " << position << std::endl;
362  }
363 
364  if (getSolverState().dcopFlag)
365  {
366 
367  fVec[li_Velocity] += velocity-v0;
368 
369  fVec[li_Position] += position-x0;
370  }
371  else
372  {
373 
374  fVec[li_Velocity] += -acceleration;
375 
376  fVec[li_Position] += -velocity;
377  }
378 
379  return true;
380 }
381 
382 //-----------------------------------------------------------------------------
383 // Function : Instance::loadDAEQVector
384 //
385 // Purpose : Loads the Q-vector contributions for a single
386 // ACC instance.
387 //
388 // Special Notes :
389 //
390 //
391 // Scope : public
392 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
393 // Creation Date : 10/25/07
394 //-----------------------------------------------------------------------------
396 {
397  double * qVec = extData.daeQVectorRawPtr;
398 
399 
400  qVec[li_Velocity] += velocity;
401 
402  qVec[li_Position] += position;
403 
404  return true;
405 }
406 
407 //-----------------------------------------------------------------------------
408 // Function : Instance::loadDAEdFdx ()
409 //
410 // Purpose : Loads the F-vector contributions for a single
411 // ACC instance.
412 //
413 // Special Notes :
414 //
415 // Scope : public
416 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
417 // Creation Date : 10/25/07
418 //-----------------------------------------------------------------------------
420 {
421  Linear::Matrix & dFdx = *(extData.dFdxMatrixPtr);
422 
423  if (getSolverState().dcopFlag)
424  {
425 
426  dFdx[li_Velocity][AVelEquVelNodeOffset] += 1.0;
427 
428  dFdx[li_Position][APosEquPosNodeOffset] += 1.0;
429  }
430  else
431  {
432 
433  dFdx[li_Velocity][AVelEquAccNodeOffset] += -1.0;
434 
435  dFdx[li_Position][APosEquVelNodeOffset] += -1.0;
436  }
437 
438  return true;
439 }
440 
441 //-----------------------------------------------------------------------------
442 // Function : Instance::loadDAEdQdx ()
443 //
444 // Purpose : Loads the Q-vector contributions for a single
445 // ACC instance.
446 //
447 // Special Notes :
448 //
449 // Scope : public
450 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
451 // Creation Date : 10/25/07
452 //-----------------------------------------------------------------------------
454 {
455  Linear::Matrix & dQdx = *(extData.dQdxMatrixPtr);
456 
457  if (!getSolverState().dcopFlag)
458  {
459 
460  dQdx[li_Velocity][AVelEquVelNodeOffset] += 1.0;
461 
462  dQdx[li_Position][APosEquPosNodeOffset] += 1.0;
463  }
464 
465  return true;
466 }
467 
468 // These are all just placeholder functions, as there is nothing to the model
469 // class.
470 // Class Model
471 
472 //-----------------------------------------------------------------------------
473 // Function : Model::Model
474 // Purpose : "Model block" constructor
475 // Special Notes :
476 // Scope : public
477 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
478 // Creation Date : 10/25/07
479 //-----------------------------------------------------------------------------
481  const Configuration & configuration,
482  const ModelBlock & MB,
483  const FactoryBlock & factory_block)
484  : DeviceModel(MB, configuration.getModelParameters(), factory_block)
485 {
486 }
487 
488 //-----------------------------------------------------------------------------
489 // Function : Model::~Model
490 // Purpose : destructor
491 // Special Notes :
492 // Scope : public
493 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
494 // Creation Date : 10/25/07
495 //-----------------------------------------------------------------------------
497 {
498  std::vector<Instance*>::iterator iter;
499  std::vector<Instance*>::iterator first = instanceContainer.begin();
500  std::vector<Instance*>::iterator last = instanceContainer.end();
501 
502  for (iter=first; iter!=last; ++iter)
503  {
504  delete (*iter);
505  }
506 }
507 
508 //-----------------------------------------------------------------------------
509 // Function : Model::printOutInstances
510 // Purpose : debugging tool.
511 // Special Notes :
512 // Scope : public
513 // Creator : Tom Russo, SNL, Electrical and Microsystems Modeling
514 // Creation Date : 10/25/07
515 //-----------------------------------------------------------------------------
516 std::ostream &Model::printOutInstances(std::ostream &os) const
517 {
518  std::vector<Instance*>::const_iterator iter;
519  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
520  std::vector<Instance*>::const_iterator last = instanceContainer.end();
521 
522  int i;
523  os << std::endl;
524  os << " name model name Parameters" << std::endl;
525  for (i=0, iter=first; iter!=last; ++iter, ++i)
526  {
527  os << " " << i << ": " << (*iter)->getName() << " ";
528  os << getName();
529  os << std::endl;
530  }
531 
532  os << std::endl;
533 
534  return os;
535 }
536 
537 //-----------------------------------------------------------------------------
538 // Function : Model::forEachInstance
539 // Purpose :
540 // Special Notes :
541 // Scope : public
542 // Creator : David Baur
543 // Creation Date : 2/4/2014
544 //-----------------------------------------------------------------------------
545 /// Apply a device instance "op" to all instances associated with this
546 /// model
547 ///
548 /// @param[in] op Operator to apply to all instances.
549 ///
550 ///
551 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
552 {
553  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
554  op(*it);
555 }
556 
557 
558 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
559 {
560 
561  return new DeviceMaster<Traits>(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
562 }
563 
565 {
567  .registerDevice("acc", 1);
568 }
569 
570 } // namespace ACC
571 } // namespace Device
572 } // namespace Xyce
const InstanceName & getName() const
static void loadModelParameters(ParametricData< Model > &model_parameters)
Definition: N_DEV_ACC.C:82
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
Pure virtual class to augment a linear system.
static void loadInstanceParameters(ParametricData< Instance > &instance_parameters)
Definition: N_DEV_ACC.C:71
void loadNodeSymbols(Util::SymbolTable &symbol_table) const
Populates and returns the store name map.
Definition: N_DEV_ACC.C:205
virtual std::ostream & printOutInstances(std::ostream &os) const
Definition: N_DEV_ACC.C:516
#define AssertLIDs(cmp)
virtual void registerJacLIDs(const JacobianStamp &jacLIDVec)
static std::vector< std::vector< int > > jacStamp
Definition: N_DEV_ACC.h:150
void registerLIDs(const std::vector< int > &intLIDVecRef, const std::vector< int > &extLIDVecRef)
Definition: N_DEV_ACC.C:172
const std::vector< std::vector< int > > & jacobianStamp() const
Definition: N_DEV_ACC.C:237
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...
const DeviceOptions & deviceOptions_
virtual void forEachInstance(DeviceInstanceOp &op) const
Apply a device instance "op" to all instances associated with this model.
Definition: N_DEV_ACC.C:551
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
Class Configuration contains device configuration data.
std::vector< Instance * > instanceContainer
Definition: N_DEV_ACC.h:238
Instance(const Configuration &configuration, const InstanceBlock &IB, Model &Riter, const FactoryBlock &factory_block)
Definition: N_DEV_ACC.C:98
const SolverState & getSolverState() const
void registerStateLIDs(const std::vector< int > &staLIDVecRef)
Definition: N_DEV_ACC.C:217
void registerJacLIDs(const std::vector< std::vector< int > > &jacLIDVec)
Definition: N_DEV_ACC.C:250
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.
std::vector< Param > params
Linear::Matrix * dQdxMatrixPtr
void registerDevice()
Definition: N_DEV_ACC.C:564
static Device * factory(const Configuration &configuration, const FactoryBlock &factory_block)
Definition: N_DEV_ACC.C:558