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