Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_DEV_2DPDE_Output.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_2DPDE_Output.C,v $
27 //
28 // Purpose : This file contains just the output functions of the
29 // N_DEV_2DPDE and N_DEV_2DPDEInstance classes.
30 //
31 // Special Notes :
32 //
33 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
34 //
35 // Creation Date : 06/17/03
36 //
37 // Revision Information:
38 // ---------------------
39 //
40 // Revision Number: $Revision: 1.42 $
41 //
42 // Revision Date : $Date: 2014/02/24 23:49:18 $
43 //
44 // Current Owner : $Author: tvrusso $
45 //-------------------------------------------------------------------------
46 
47 #include <Xyce_config.h>
48 
49 
50 // ---------- Standard Includes ----------
51 #include <N_UTL_Misc.h>
52 #ifdef Xyce_DEBUG_DEVICE
53 #include <iostream>
54 #endif
55 
56 #ifdef HAVE_CMATH
57 #include <cmath>
58 #else
59 #include <math.h>
60 #endif
61 
62 // ---------- Xyce Includes ----------
63 #include <N_DEV_2DPDE.h>
64 #include <N_DEV_SolverState.h>
65 #include <N_DEV_DeviceOptions.h>
66 #include <N_DEV_Message.h>
67 
68 #include <N_DEV_PDE_2DMesh.h>
69 #include <N_DEV_SGF_Interface.h>
70 
71 #include <N_LAS_Vector.h>
72 #include <N_LAS_System.h>
73 
74 namespace Xyce {
75 namespace Device {
76 namespace TwoDPDE {
77 
78 //-----------------------------------------------------------------------------
79 // Function : Instance::outputPlotFiles
80 // Purpose :
81 // Special Notes :
82 // Scope : public
83 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
84 // Creation Date : 07/22/03
85 //-----------------------------------------------------------------------------
87 {
88  bool bsuccess = true;
89  bool bs1 = true;
90  bool skipOutput = false;
91 
92  // usually, don't bother outputting nonlinear Poisson result.
93  if (equationSet == 0 && !outputNLPoisson) return bsuccess;
94 
95  // If using output interval, check if enough time has passed to do
96  // another output. (only applies for transient - not DCOP).
97  if ( !(getSolverState().dcopFlag) &&
98  !(getSolverState().forceFinalOutput) &&
99  given("OUTPUTINTERVAL") )
100  {
101  double outMult = static_cast<double> (outputIndex);
102  double nextOutputTime = outMult * outputInterval;
103 
104  if (nextOutputTime > getSolverState().currTime)
105  {
106  skipOutput = true;
107  }
108  }
109 
110  // If this is a "forced" final output, make sure that it didn't already output.
111  // This can happen if the output interval is an exact multiple of the
112  // total simulation time.
114 
115  if (skipOutput) return bsuccess;
116  ++outputIndex;
118 
119 #ifdef Xyce_DEBUG_DEVICE
120  Xyce::dout() << std::endl << "Doing an output at time = " << getSolverState().currTime << std::endl;
121 #endif
122 
123  if (tecplotLevel > 0)
124  {
125  bs1 = outputTecplot ();
126  bsuccess = bsuccess && bs1;
127  }
128 
129  if (tecplotLevel > 2)
130  {
131  bs1 = outputTecplotVectors ();
132  bsuccess = bsuccess && bs1;
133  }
134 
135  if (sgplotLevel > 0)
136  {
137  bs1 = outputSgplot ();
138  bsuccess = bsuccess && bs1;
139  }
140 
141  if (gnuplotLevel > 0)
142  {
143  bs1 = outputGnuplot ();
144  bsuccess = bsuccess && bs1;
145  }
146 
147  if (txtDataLevel > 0)
148  {
149  bs1 = outputTxtData ();
150  bsuccess = bsuccess && bs1;
151  }
152 
153  return bsuccess;
154 }
155 
156 //-----------------------------------------------------------------------------
157 // Function : Instance::tecplotGeomOutput
158 //
159 // Purpose : This function outputs the reactor geometry
160 // information for a tecplot file.
161 // Special Notes :
162 // Scope : public
163 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
164 // Creation Date : 04/25/02
165 //-----------------------------------------------------------------------------
166 
168 {
169  UINT iNodeA,iNodeB;
170 
171  // output the geometries:
172  UINT iE;
173  UINT iNumG = iNumPlotEdges/50 + 1;
174  UINT iNumF = iNumPlotEdges - (iNumG-1)*50;
175 
176  UINT iGnum = 1;
177  fprintf(fp1,"%s","\n GEOMETRY M=GRID, C=BLACK, X= .00, Y= .00,");
178  fprintf(fp1,"%s"," T=LINE, F=POINT, LT=0.8\n");
179 
180  if(iGnum == iNumG) fprintf(fp1,"\t%d\n",iNumF);
181  else fprintf(fp1,"\t%d\n",50);
182 
183  double x1,y1,x2,y2;
184  UINT itmp = 2;
185  UINT icount = 0;
186 
187  for(iE = 0;iE<numMeshEdges;++iE)
188  {
189  if(aiEdge[iE] == 1)
190  {
191  mEdge * edgePtr = meshContainerPtr->getEdge(iE);
192 
193  ++icount;
194  iNodeA = edgePtr->inodeA;
195  iNodeB = edgePtr->inodeB;
196  x1 = xVec[iNodeA];
197  y1 = yVec[iNodeA];
198  x2 = xVec[iNodeB];
199  y2 = yVec[iNodeB];
200 
201  if (variablesScaled)
202  {
203  x1 = x1 * scalingVars.x0;
204  x2 = x2 * scalingVars.x0;
205  y1 = y1 * scalingVars.x0;
206  y2 = y2 * scalingVars.x0;
207  }
208 
209  fprintf(fp1,"%4d\n%11.3e %11.3e\n%11.3e %11.3e\n",
210  itmp,x1,y1,x2,y2);
211  }
212 
213  if(icount >= 50)
214  {
215  icount = 0;
216  ++iGnum;
217  if(iGnum == iNumG)
218  {
219  if(iNumF != 0)
220  {
221  fprintf(fp1,"%s","\n GEOMETRY M=GRID, C=BLACK, X= .00,");
222  fprintf(fp1,"%s"," Y= .00,");
223  fprintf(fp1,"%s"," T=LINE, F=POINT, LT=0.8\n");
224  fprintf(fp1,"\t%d\n",iNumF);}
225  }
226  else
227  {
228  fprintf(fp1,"%s","\n GEOMETRY M=GRID, C=BLACK, X= .00,");
229  fprintf(fp1,"%s"," Y= .00,");
230  fprintf(fp1,"%s"," T=LINE, F=POINT, LT=0.8\n");
231  fprintf(fp1,"\t%d\n",50);
232  }
233  }
234  }
235 
236  fprintf(fp1,"%s","\n");
237 
238  // Now do the "noflux" edges.
239  iNumG = iNumPlotEdges_nf/50 + 1;
240  iNumF = iNumPlotEdges_nf - (iNumG-1)*50;
241 
242  iGnum = 1;
243  fprintf(fp1,"%s","\n GEOMETRY M=GRID, C=RED, X= .00, Y= .00,");
244  fprintf(fp1,"%s"," T=LINE, F=POINT, LT=0.2\n");
245 
246  if(iGnum == iNumG) fprintf(fp1,"\t%d\n",iNumF);
247  else fprintf(fp1,"\t%d\n",50);
248 
249  itmp = 2;
250  icount = 0;
251 
252  for(iE = 0;iE<numMeshEdges;++iE)
253  {
254  if(aiEdge_nf[iE] == 1)
255  {
256  mEdge * edgePtr = meshContainerPtr->getEdge(iE);
257 
258  ++icount;
259  iNodeA = edgePtr->inodeA;
260  iNodeB = edgePtr->inodeB;
261  x1 = xVec[iNodeA];
262  y1 = yVec[iNodeA];
263  x2 = xVec[iNodeB];
264  y2 = yVec[iNodeB];
265 
266  if (variablesScaled)
267  {
268  x1 = x1 * scalingVars.x0;
269  x2 = x2 * scalingVars.x0;
270  y1 = y1 * scalingVars.x0;
271  y2 = y2 * scalingVars.x0;
272  }
273 
274  fprintf(fp1,"%4d\n%11.3e %11.3e\n%11.3e %11.3e\n",
275  itmp,x1,y1,x2,y2);
276  }
277 
278  if(icount >= 50)
279  {
280  icount = 0;
281  ++iGnum;
282  if(iGnum == iNumG)
283  {
284  if(iNumF != 0)
285  {
286  fprintf(fp1,"%s","\n GEOMETRY M=GRID, C=RED, X= .00,");
287  fprintf(fp1,"%s"," Y= .00,");
288  fprintf(fp1,"%s"," T=LINE, F=POINT, LT=0.2\n");
289  fprintf(fp1,"\t%d\n",iNumF);}
290  }
291  else
292  {
293  fprintf(fp1,"%s","\n GEOMETRY M=GRID, C=RED, X= .00,");
294  fprintf(fp1,"%s"," Y= .00,");
295  fprintf(fp1,"%s"," T=LINE, F=POINT, LT=0.2\n");
296  fprintf(fp1,"\t%d\n",50);
297  }
298  }
299  }
300 
301  fprintf(fp1,"%s","\n");
302 
303  return true;
304 }
305 
306 //-----------------------------------------------------------------------------
307 // Function : Instance::outputTecplot
308 // Purpose :
309 // Special Notes : If tecplot level is set to 1, then output each dataset
310 // in a separate file. If not, then append to a single file.
311 // Scope : public
312 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
313 // Creation Date : 11/14/01
314 //-----------------------------------------------------------------------------
316 {
317  bool bsuccess = true;
318  bool bs1 = true;
319 
320  int i;
321  char filename[32]; for(i=0;i<32;++i) filename[i] = static_cast<char>(0);
322 
323  if (tecplotLevel == 1)
324  {
325  sprintf(filename,"%s_%03d.dat",outputName.c_str(),callsOTEC);
326  }
327  else
328  {
329  sprintf(filename,"%s.dat",outputName.c_str());
330  }
331 
332  double time = getSolverState().currTime;
333 
334 #ifdef Xyce_DEBUG_DEVICE
335  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
336  {
337  Xyce::dout() << std::endl;
338  Xyce::dout() << section_divider << std::endl;
339  Xyce::dout() << "In Instance::outputTecplot. filename = ";
340  Xyce::dout() << std::string(filename);
341  Xyce::dout() << std::endl;
342  }
343 #endif
344 
345  FILE *fp1;
346 
347  if (tecplotLevel == 1)
348  {
349  fp1 = fopen(filename,"w");
350  }
351  else
352  {
353  if (callsOTEC <= 0)
354  {
355  fp1 = fopen(filename,"w");
356  }
357  else
358  {
359  fp1 = fopen(filename,"a");
360  }
361  }
362 
363  double Ex, Ey;
364  double V2x, V2y;
365  double V1x, V1y;
366  double V0x, V0y;
367 
368  double dDx_dt, dDy_dt;
369  double D2x, D2y;
370  double D1x, D1y;
371  double D0x, D0y;
372 
373  double xLoc, yLoc;
374  double dx1, dy1;
375 
376  if (tecplotLevel == 1)
377  {
378  if (equationSet == 0)
379  {
380  fprintf(fp1,
381  " TITLE = \"Spatially Dependent data for 2D PDE: %s time = %12.4e seconds. equation set = nonlinear Poisson\",\n",
382  outputName.c_str(),time);
383  }
384  else
385  {
386  fprintf(fp1,
387  " TITLE = \"Spatially Dependent data for 2D PDE: %s time = %12.4e seconds. equation set = drift diffusion\",\n",
388  outputName.c_str(),time);
389  }
390  }
391  else
392  {
393  if (callsOTEC <= 0)
394  {
395  fprintf(fp1,
396  " TITLE = \"Spatially Dependent data for 2D PDE: %s time = %12.4e seconds.\",\n",
397  outputName.c_str(),time);
398  }
399  }
400 
401  if (callsOTEC <= 0 || tecplotLevel == 1)
402  {
403  if (cylGeomFlag)
404  fprintf(fp1,"%s","\tVARIABLES = \"R (cm) \",\"Z (cm)\",\n");
405  else
406  fprintf(fp1,"%s","\tVARIABLES = \"X (cm) \",\"Y (cm)\",\n");
407 
408  fprintf(fp1,"%s","\t \"V \",\n");
409  fprintf(fp1,"%s","\t \"nn (electron dens.) \",\n");
410  fprintf(fp1,"%s","\t \"np (hole dens.) \",\n");
411  fprintf(fp1,"%s","\t \"Dopant dens. \",\n");
412  fprintf(fp1,"%s","\t \"abs(Dopant dens.)\",\n");
413  fprintf(fp1,"%s","\t \"total density\",\n");
414  fprintf(fp1,"%s","\t \"electron lifetime \",\n");
415  fprintf(fp1,"%s","\t \"hole lifetime \",\n");
416  fprintf(fp1,"%s","\t \"electron mobility \",\n");
417  fprintf(fp1,"%s","\t \"hole mobility \",\n");
418 
419  if (tecplotLevel > 1)
420  {
421  fprintf(fp1,"%s","\t \"Ex \",\n");
422  fprintf(fp1,"%s","\t \"Ey \",\n");
423  fprintf(fp1,"%s","\t \"Emag \",\n");
424  fprintf(fp1,"%s","\t \"dDx_dt \",\n");
425  fprintf(fp1,"%s","\t \"dDy_dt \",\n");
426  fprintf(fp1,"%s","\t \"dDmag_dt \",\n");
427  }
428 
429  fprintf(fp1,"%s","\t \"Recombination \",\n");
430  fprintf(fp1,"%s","\t \"photogen \",\n");
431  fprintf(fp1,"%s","\t \"total src \",\n");
432  }
433 
434  fprintf(fp1,"\tZONE F=FEPOINT,ET=QUADRILATERAL,N=%d,E=%d",
436 
437  if (getSolverState().dcopFlag)
438  {
439  fprintf(fp1," T = \"DCOP step = %d\" \n", callsOTEC);
440  }
441  else
442  {
443  fprintf(fp1," T = \"time step = %d\" time = %12.4e seconds\" \n", callsOTEC , time);
444  }
445 
446  if (variablesScaled)
447  {
448  for (i=0;i<numMeshPoints;++i)
449  {
450  xLoc = xVec[i];
451  yLoc = yVec[i];
452 
453  double xLocS = xLoc * scalingVars.x0;
454  double yLocS = yLoc * scalingVars.x0;
455 
456  fprintf(fp1," %12.4e",xLocS);
457  fprintf(fp1," %12.4e",yLocS);
458  fprintf(fp1," %12.4e",VVec[i]*scalingVars.V0);
459  fprintf(fp1," %12.4e",nnVec[i]*scalingVars.C0);
460  fprintf(fp1," %12.4e",npVec[i]*scalingVars.C0);
461  double C = CVec[i]*scalingVars.C0;
462  fprintf(fp1," %12.4e",C);
463  fprintf(fp1," %12.4e",fabs(C));
464  double totCharge = (npVec[i]*scalingVars.C0-nnVec[i]*scalingVars.C0+C);
465  fprintf(fp1," %12.4e",totCharge);
466  fprintf(fp1," %12.4e",tnVec[i]*scalingVars.t0);
467  fprintf(fp1," %12.4e",tpVec[i]*scalingVars.t0);
468  fprintf(fp1," %12.4e",unVec[i]*scalingVars.u0);
469  fprintf(fp1," %12.4e",upVec[i]*scalingVars.u0);
470 
471  if (tecplotLevel > 1)
472  {
473  dx1 = dy1 = 0.5 * minDXVec[i];
474 
476  if (lPtr->uType == TYPE_REGION)
477  {
478  // electric field:
479  V2x = scalingVars.V0* (meshContainerPtr->interp(&(VVec[0]),xLocS+dx1, yLocS));
480  V1x = scalingVars.V0*VVec[i];
481  V0x = scalingVars.V0* (meshContainerPtr->interp(&(VVec[0]),xLocS-dx1, yLocS));
482  Ex = -0.5 * ( (V2x-V1x)+(V1x-V0x) )/dx1;
483 
484  V2y = scalingVars.V0* (meshContainerPtr->interp(&(VVec[0]),xLocS, yLocS+dy1));
485  V1y = scalingVars.V0*VVec[i];
486  V0y = scalingVars.V0* (meshContainerPtr->interp(&(VVec[0]),xLocS, yLocS-dy1));
487  Ey = -0.5 * ( (V2y-V1y)+(V1y-V0y) )/dy1;
488 
489 
490  // displacement current:
491  D2x = (meshContainerPtr->interp(&(displPotential[0]),xLocS+dx1, yLocS));
492  D1x = displPotential[i];
493  D0x = (meshContainerPtr->interp(&(displPotential[0]),xLocS-dx1, yLocS));
494 
495  dDx_dt = -0.5 * ( (D2x-D1x)+(D1x-D0x) )/dx1;
496  dDx_dt *= eSi * e0;
497 
498  D2y = (meshContainerPtr->interp(&(displPotential[0]),xLocS, yLocS+dy1));
499  D1y = displPotential[i];
500  D0y = (meshContainerPtr->interp(&(displPotential[0]),xLocS, yLocS-dy1));
501 
502  dDy_dt = -0.5 * ( (D2y-D1y)+(D1y-D0y) )/dy1;
503  dDy_dt *= eSi * e0;
504 
505  }
506  else
507  {
508  Ex = 0.0;
509  Ey = 0.0;
510  dDx_dt = 0.0;
511  dDy_dt = 0.0;
512  }
513 
514  fprintf(fp1," %12.4e",Ex);
515  fprintf(fp1," %12.4e",Ey);
516  fprintf(fp1," %12.4e",sqrt(Ex*Ex + Ey*Ey) );
517 
518  fprintf(fp1," %12.4e",dDx_dt);
519  fprintf(fp1," %12.4e",dDy_dt);
520  fprintf(fp1," %12.4e",sqrt(dDx_dt*dDx_dt + dDy_dt*dDy_dt) );
521  }
522 
523  fprintf(fp1," %12.4e",RVec[i]*scalingVars.R0);
524  fprintf(fp1," %12.4e",SVec[i]*scalingVars.R0);
525  fprintf(fp1," %12.4e",totSrcVec[i]*scalingVars.R0);
526  fprintf(fp1,"%s","\n");
527  }
528  }
529  else
530  {
531  for (i=0;i<numMeshPoints;++i)
532  {
533  xLoc = xVec[i];
534  yLoc = yVec[i];
535 
536  fprintf(fp1," %12.4e",xLoc);
537  fprintf(fp1," %12.4e",yLoc);
538  fprintf(fp1," %12.4e",VVec[i]);
539  fprintf(fp1," %12.4e",nnVec[i]);
540  fprintf(fp1," %12.4e",npVec[i]);
541  double C = CVec[i];
542  fprintf(fp1," %12.4e",C);
543  fprintf(fp1," %12.4e",fabs(C));
544  double totCharge = (npVec[i]-nnVec[i]+C);
545  fprintf(fp1," %12.4e",totCharge);
546  fprintf(fp1," %12.4e",tnVec[i]);
547  fprintf(fp1," %12.4e",tpVec[i]);
548  fprintf(fp1," %12.4e",unVec[i]);
549  fprintf(fp1," %12.4e",upVec[i]);
550 
551  if (tecplotLevel > 1)
552  {
553  dx1 = dy1 = 0.5 * minDXVec[i];
555 
556  if (lPtr->uType == TYPE_REGION)
557  {
558  // electric field:
559  V2x = (meshContainerPtr->interp(&(VVec[0]),xLoc+dx1, yLoc));
560  V1x = VVec[i];
561  V0x = (meshContainerPtr->interp(&(VVec[0]),xLoc-dx1, yLoc));
562  Ex = -0.5 * ( (V2x-V1x)+(V1x-V0x) )/dx1;
563 
564  V2y = (meshContainerPtr->interp(&(VVec[0]),xLoc, yLoc+dy1));
565  V1y = VVec[i];
566  V0y = (meshContainerPtr->interp(&(VVec[0]),xLoc, yLoc-dy1));
567  Ey = -0.5 * ( (V2y-V1y)+(V1y-V0y) )/dy1;
568 
569  // displacement current:
570  D2x = (meshContainerPtr->interp(&(displPotential[0]),xLoc+dx1, yLoc));
571  D1x = displPotential[i];
572  D0x = (meshContainerPtr->interp(&(displPotential[0]),xLoc-dx1, yLoc));
573 
574  dDx_dt = -0.5 * ( (D2x-D1x)+(D1x-D0x) )/dx1;
575  dDx_dt *= eSi * e0;
576 
577  D2y = (meshContainerPtr->interp(&(displPotential[0]),xLoc, yLoc+dy1));
578  D1y = displPotential[i];
579  D0y = (meshContainerPtr->interp(&(displPotential[0]),xLoc, yLoc-dy1));
580 
581  dDy_dt = -0.5 * ( (D2y-D1y)+(D1y-D0y) )/dy1;
582  dDy_dt *= eSi * e0;
583  }
584  else
585  {
586  Ex = 0.0;
587  Ey = 0.0;
588  dDx_dt = 0.0;
589  dDy_dt = 0.0;
590  }
591 
592  fprintf(fp1," %12.4e",Ex);
593  fprintf(fp1," %12.4e",Ey);
594  fprintf(fp1," %12.4e",sqrt(Ex*Ex + Ey*Ey) );
595 
596  fprintf(fp1," %12.4e",dDx_dt);
597  fprintf(fp1," %12.4e",dDy_dt);
598  fprintf(fp1," %12.4e",sqrt(dDx_dt*dDx_dt + dDy_dt*dDy_dt) );
599  }
600 
601  fprintf(fp1," %12.4e",RVec[i]);
602  fprintf(fp1," %12.4e",SVec[i]);
603  fprintf(fp1," %12.4e",totSrcVec[i]);
604  fprintf(fp1,"%s","\n");
605  }
606  }
607 
608  fprintf(fp1,"%s","\n");
609 
610  for(UINT iTri=0; iTri<numMeshCells; ++iTri)
611  {
612  UINT inodeA,inodeB,inodeC,inodeD;
613 
614  mCell * cellPtr = meshContainerPtr->getCell(iTri);
615 
616  inodeA = cellPtr->inodeA;
617  inodeB = cellPtr->inodeB;
618  inodeC = cellPtr->inodeC;
619  inodeD = cellPtr->inodeD;
620 
621  if(inodeD == -1u) inodeD = inodeC;
622 
623  if((inodeA == -1u || inodeB == -1u ||
624  inodeC == -1u || inodeD == -1u) ||
625  (inodeA == inodeB) || (inodeA == inodeC) ||
626  (inodeB == inodeC))
627  {
628  fprintf(stdout,"%s","Error in ::outputTecplot\n");
629  fprintf(stdout,"inodeA = %d\n",inodeA);
630  fprintf(stdout,"inodeB = %d\n",inodeB);
631  fprintf(stdout,"inodeC = %d\n",inodeC);
632  fprintf(stdout,"inodeD = %d\n",inodeD);
633  exit(0);
634  }
635  // output
636  fprintf(fp1,"%d %d %d %d\n",
637  inodeA+1,
638  inodeB+1,
639  inodeC+1,
640  inodeD+1);
641  }
642 
643  if (tecplotLevel >= 1)
644  {
645  if (callsOTEC<=0)
646  {
647  bs1 = tecplotGeomOutput(fp1);
648  bsuccess = bsuccess && bs1;
649  }
650  }
651 
652  ++callsOTEC;
653  fclose(fp1);
654 
655  return bsuccess;
656 }
657 
658 //-----------------------------------------------------------------------------
659 // Function : Instance::outputTecplotVectors
660 // Purpose : This function outputs a tecplot file which contains vector
661 // data. It does this by performing interpolations on the
662 // unstructured grid. As such, for testing purposed it also
663 // outputs some interpolated scalar data.
664 // Special Notes :
665 // Scope : public
666 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
667 // Creation Date : 11/14/01
668 //-----------------------------------------------------------------------------
670 {
671  bool bsuccess = true;
672 
673  int i, j;
674  char filename[32]; for(i=0;i<32;++i) filename[i] = static_cast<char>(0);
675 
676  sprintf(filename,"%s_%03dVec.dat",outputName.c_str(),callsOTECvec);
677  ++callsOTECvec;
678 
679  double time = getSolverState().currTime;
680 
681 #ifdef Xyce_DEBUG_DEVICE
682  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
683  {
684  Xyce::dout() << std::endl;
685  Xyce::dout() << section_divider << std::endl;
686  Xyce::dout() << "In Instance::outputTecplotVectors. filename = ";
687  Xyce::dout() << std::string(filename);
688  Xyce::dout() << std::endl;
689  }
690 #endif
691 
692  FILE *fp1 = fopen(filename,"w");
693 
694  // set up the cartesian grid with which to perform interpolations:
695  double tmp;
696  double xMax = meshContainerPtr->getXMax ();
697  double xMin = meshContainerPtr->getXMin ();
698  if (xMin > xMax)
699  {
700  tmp = xMax;
701  xMax = xMin;
702  xMin = tmp;
703  }
704 
705  double yMax = meshContainerPtr->getYMax ();
706  double yMin = meshContainerPtr->getYMin ();
707  if (yMin > yMax)
708  {
709  tmp = yMax;
710  yMax = yMin;
711  yMin = tmp;
712  }
713 
714  double DeltaX = xMax - xMin;
715  double DeltaY = yMax - yMin;
716 
717  int inx;
718  int iny;
719 
720  int iNumMeshPoints = interpGridSize;
721 
722  // Have one (the shorter one) of the axes have iNumMeshPoints "mesh" points.
723  if (DeltaX < DeltaY)
724  { inx = iNumMeshPoints; iny = static_cast<int> (iNumMeshPoints * fabs(DeltaY/DeltaX)); }
725  else
726  { iny = iNumMeshPoints; inx = static_cast<int> (iNumMeshPoints * fabs(DeltaX/DeltaY)); }
727 
728  double dx = fabs(DeltaX/static_cast<double>(inx));
729  double dx1 = dx*0.5;
730  double dy = fabs(DeltaY/static_cast<double>(iny));
731  double dy1 = dy*0.5;
732 
733  double Ex, Ey;
734  double V2x, V2y;
735  double V1x, V1y;
736  double V0x, V0y;
737 
738  double dDx_dt, dDy_dt;
739  double D2x, D2y;
740  double D1x, D1y;
741  double D0x, D0y;
742 
743 #ifdef Xyce_DEBUG_DEVICE
744  Xyce::dout() << "outputTecplotVectors:\n";
745  Xyce::dout() << "DeltaX = " << DeltaX << std::endl;
746  Xyce::dout() << "DeltaY = " << DeltaY << std::endl;
747 
748  Xyce::dout() << "xMax = " << xMax << std::endl;
749  Xyce::dout() << "xMin = " << xMin << std::endl;
750  Xyce::dout() << "yMax = " << yMax << std::endl;
751  Xyce::dout() << "yMin = " << yMin << std::endl;
752 
753  Xyce::dout() << "dx = " << dx << std::endl;
754  Xyce::dout() << "dy = " << dy << std::endl;
755 
756  Xyce::dout() << "inx = " << inx << std::endl;
757  Xyce::dout() << "iny = " << iny << std::endl;
758 #endif
759 
760  if (equationSet == 0)
761  {
762  fprintf(fp1,
763  " TITLE = \"Spatially Dependent vector data for 2D PDE: %s time = %12.4e seconds. equation set = nonlinear Poisson\",\n",
764  outputName.c_str(),time);
765  }
766  else
767  {
768  fprintf(fp1,
769  " TITLE = \"Spatially Dependent vector data for 2D PDE: %s time = %12.4e seconds. equation set = drift diffusion\",\n",
770  outputName.c_str(),time);
771  }
772 
773  if (cylGeomFlag)
774  fprintf(fp1,"%s","\tVARIABLES = \"R (cm) \",\"Z (cm)\",\n");
775  else
776  fprintf(fp1,"%s","\tVARIABLES = \"X (cm) \",\"Y (cm)\",\n");
777 
778  fprintf(fp1,"%s","\t \"V \", \n");
779  fprintf(fp1,"%s","\t \"Ex \", \n");
780  fprintf(fp1,"%s","\t \"Ey \", \n");
781  fprintf(fp1,"%s","\t \"Emag \",\n");
782  fprintf(fp1,"%s","\t \"dDx_dt \", \n");
783  fprintf(fp1,"%s","\t \"dDy_dt \", \n");
784  fprintf(fp1,"%s","\t \"Dmag \",\n");
785 
786  fprintf(fp1,"\tZONE I=%d, J=%d, F=POINT\n", iny+1, inx+1);
787 
788  double xLoc, yLoc;
789 
790  if (variablesScaled)
791  {
792  for (i=0;i<inx+1;++i)
793  {
794  xLoc = xMin + static_cast<double>(i) * dx;
795 
796  for (j=0;j<iny+1;++j)
797  {
798  yLoc = yMin + static_cast<double>(j) * dy;
799 
800  fprintf(fp1," %12.4e",xLoc);
801  fprintf(fp1," %12.4e",yLoc);
802  double Vtmp = meshContainerPtr->interp(&(VVec[0]),xLoc,yLoc);
803  double Dtmp = meshContainerPtr->interp(&(displPotential[0]),xLoc,yLoc);
804  fprintf(fp1," %12.4e",Vtmp*scalingVars.V0);
805 
806  if (i>0 && i<inx)
807  {
808  // electric field
809  V2x = scalingVars.V0* (meshContainerPtr->interp(&(VVec[0]),xLoc+dx1, yLoc));
810  V1x = scalingVars.V0*Vtmp;
811  V0x = scalingVars.V0* (meshContainerPtr->interp(&(VVec[0]),xLoc-dx1, yLoc));
812  Ex = -0.5 * ( (V2x-V1x)+(V1x-V0x) )/dx1;
813 
814  // displacement current:
815  D2x = (meshContainerPtr->interp(&(displPotential[0]),xLoc+dx1, yLoc));
816  D1x = Dtmp;
817  D0x = (meshContainerPtr->interp(&(displPotential[0]),xLoc-dx1, yLoc));
818 
819  dDx_dt = -0.5 * ( (D2x-D1x)+(D1x-D0x) )/dx1;
820  dDx_dt *= eSi * e0;
821  }
822  else
823  {
824  Ex = 0.0;
825  dDx_dt = 0.0;
826  }
827 
828  if (j>0 && j<iny)
829  {
830  // electric field:
831  V2y = scalingVars.V0* (meshContainerPtr->interp(&(VVec[0]),xLoc, yLoc+dy1));
832  V1y = scalingVars.V0*Vtmp;
833  V0y = scalingVars.V0* (meshContainerPtr->interp(&(VVec[0]),xLoc, yLoc-dy1));
834  Ey = -0.5 * ( (V2y-V1y)+(V1y-V0y) )/dy1;
835 
836  // displacement current:
837  D2y = (meshContainerPtr->interp(&(displPotential[0]),xLoc, yLoc+dy1));
838  D1y = Dtmp;
839  D0y = (meshContainerPtr->interp(&(displPotential[0]),xLoc, yLoc-dy1));
840 
841  dDy_dt = -0.5 * ( (D2y-D1y)+(D1y-D0y) )/dy1;
842  dDy_dt *= eSi * e0;
843  }
844  else
845  {
846  Ey = 0.0;
847  dDy_dt = 0.0;
848  }
849 
850  fprintf(fp1," %12.4e",Ex);
851  fprintf(fp1," %12.4e",Ey);
852  fprintf(fp1," %12.4e",sqrt(Ex*Ex + Ey*Ey) );
853 
854  fprintf(fp1," %12.4e",dDx_dt);
855  fprintf(fp1," %12.4e",dDy_dt);
856  fprintf(fp1," %12.4e",sqrt(dDx_dt*dDx_dt + dDy_dt*dDy_dt) );
857  fprintf(fp1,"%s","\n");
858  }
859  }
860  }
861  else
862  {
863  for (i=0;i<inx+1;++i)
864  {
865  xLoc = xMin + static_cast<double>(i) * dx;
866  for (j=0;j<iny+1;++j)
867  {
868  yLoc = yMin + static_cast<double>(j) * dy;
869 
870  fprintf(fp1," %12.4e",xLoc);
871  fprintf(fp1," %12.4e",yLoc);
872  double Vtmp = meshContainerPtr->interp(&(VVec[0]),xLoc,yLoc);
873  double Dtmp = meshContainerPtr->interp(&(displPotential[0]),xLoc,yLoc);
874  fprintf(fp1," %12.4e",Vtmp);
875 
876  if (i>0 && i<inx)
877  {
878  // electric field:
879  V2x = (meshContainerPtr->interp(&(VVec[0]),xLoc+dx1, yLoc));
880  V1x = Vtmp;
881  V0x = (meshContainerPtr->interp(&(VVec[0]),xLoc-dx1, yLoc));
882  Ex = -0.5 * ( (V2x-V1x)+(V1x-V0x) )/dx1;
883 
884  // displacement current:
885  D2x = (meshContainerPtr->interp(&(displPotential[0]),xLoc+dx1, yLoc));
886  D1x = Dtmp;
887  D0x = (meshContainerPtr->interp(&(displPotential[0]),xLoc-dx1, yLoc));
888 
889  dDx_dt = -0.5 * ( (D2x-D1x)+(D1x-D0x) )/dx1;
890  dDx_dt *= eSi * e0;
891  }
892  else
893  {
894  Ex = 0.0;
895  dDx_dt = 0.0;
896  }
897 
898  if (j>0 && j<iny)
899  {
900  // electric field:
901  V2y = (meshContainerPtr->interp(&(VVec[0]),xLoc, yLoc+dy1));
902  V1y = Vtmp;
903  V0y = (meshContainerPtr->interp(&(VVec[0]),xLoc, yLoc-dy1));
904  Ey = -0.5 * ( (V2y-V1y)+(V1y-V0y) )/dy1;
905 
906  // displacement current:
907  D2y = (meshContainerPtr->interp(&(displPotential[0]),xLoc, yLoc+dy1));
908  D1y = Dtmp;
909  D0y = (meshContainerPtr->interp(&(displPotential[0]),xLoc, yLoc-dy1));
910 
911  dDy_dt = -0.5 * ( (D2y-D1y)+(D1y-D0y) )/dy1;
912  dDy_dt *= eSi * e0;
913  }
914  else
915  {
916  Ey = 0.0;
917  dDy_dt = 0.0;
918  }
919 
920  fprintf(fp1," %12.4e",Ex);
921  fprintf(fp1," %12.4e",Ey);
922  fprintf(fp1," %12.4e",sqrt(Ex*Ex + Ey*Ey) );
923 
924  fprintf(fp1," %12.4e",dDx_dt);
925  fprintf(fp1," %12.4e",dDy_dt);
926  fprintf(fp1," %12.4e",sqrt(dDx_dt*dDx_dt + dDy_dt*dDy_dt) );
927  fprintf(fp1,"%s","\n");
928  }
929  }
930  }
931 
932  //bool bs1 = true;
933  //bs1 = tecplotGeomOutput(fp1);
934  //bsuccess = bsuccess && bs1;
935 
936  fclose(fp1);
937 
938  return bsuccess;
939 }
940 
941 //-----------------------------------------------------------------------------
942 // Function : Instance::outputGnuplot
943 //
944 // Purpose : This function outputs very simple column data that can
945 // be read by gnuplot, in the form x,y,V,n,p,C.
946 //
947 // Special Notes : It is somewhat easy to do this if we are running with
948 // the internal mesh, which is cartesian in appearance.
949 // If running without a cartesian mesh, then it is
950 // neccessary to do some interpolations.
951 //
952 // Scope : public
953 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
954 // Creation Date : 04/15/03
955 //-----------------------------------------------------------------------------
957 {
958  bool bsuccess = true;
959 
960  int i, j;
961  char filename[32]; for(i=0;i<32;++i) filename[i] = static_cast<char>(0);
962 
963  sprintf(filename,"%s_%03dGnu.dat",outputName.c_str(),callsOGNU);
964  ++callsOGNU;
965 
966  if (!given("NX") || !given("NY"))
967  {
968  bsuccess = false;
969  UserWarning(*this) << "Gnuplot only works if using the internal mesh.";
970  }
971  else
972  {
973  // get the node index vector from the mesh class:
974  int ** nodeIndex = meshContainerPtr->getNodeIndexVector ();
975 
976  int ixMax = numMeshPointsX;
977  int iyMax = numMeshPointsY;
978 
979  FILE *fp1 = fopen(filename,"w");
980 
981  for (j=0;j<iyMax;++j)
982  {
983  for (i=0;i<ixMax;++i)
984  {
985  int index = nodeIndex[i][j];
986  fprintf(fp1,"%12.4e",xVec[index] * scalingVars.x0);
987  fprintf(fp1,"%12.4e",yVec[index] * scalingVars.x0);
988  fprintf(fp1,"%12.4e",VVec[index] * scalingVars.V0);
989  fprintf(fp1,"%12.4e",nnVec[index] * scalingVars.C0);
990  fprintf(fp1,"%12.4e",npVec[index] * scalingVars.C0);
991  fprintf(fp1,"%12.4e",CVec[index] * scalingVars.C0);
992  fprintf(fp1,"%12.4e",fabs(CVec[index] * scalingVars.C0));
993  fprintf(fp1,"%s","\n");
994  }
995  fprintf(fp1,"%s","\n");
996  }
997 
998  fclose (fp1);
999  }
1000 
1001 
1002  return bsuccess;
1003 }
1004 
1005 //-----------------------------------------------------------------------------
1006 // Function : Instance::outputTxtData
1007 // Purpose : This function outputs data about each time step, that is
1008 // easier to read as a text data, than as plotted data.
1009 // Special Notes :
1010 // Scope : public
1011 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1012 // Creation Date : 04/15/03
1013 //-----------------------------------------------------------------------------
1015 {
1016  bool bsuccess = true;
1017 
1018  int i;
1019  char filename[32]; for(i=0;i<32;++i) filename[i] = static_cast<char>(0);
1020 
1021  sprintf(filename,"%s_data.txt",outputName.c_str());
1022 
1023  double time = getSolverState().currTime;
1024 
1025  FILE *fp1;
1026  if (callsOTXT<=0)
1027  fp1 = fopen(filename,"w");
1028  else
1029  fp1 = fopen(filename,"a");
1030  ++callsOTXT;
1031 
1032  // get maxs and mins.
1033  double VminOut = 1.0e+99;
1034  double VmaxOut =-1.0e+99;
1035  double NnMinOut = 1.0e+99;
1036  double NnMaxOut =-1.0e+99;
1037  double NpMinOut = 1.0e+99;
1038  double NpMaxOut =-1.0e+99;
1039 
1040  for (i=0;i<numMeshPoints; ++i)
1041  {
1042  if (VminOut > ( VVec[i]*scalingVars.V0)) VminOut = ( VVec[i]*scalingVars.V0);
1043  if (VmaxOut < ( VVec[i]*scalingVars.V0)) VmaxOut = ( VVec[i]*scalingVars.V0);
1044  if (NnMinOut > (nnVec[i]*scalingVars.C0)) NnMinOut = (nnVec[i]*scalingVars.C0);
1045  if (NnMaxOut < (nnVec[i]*scalingVars.C0)) NnMaxOut = (nnVec[i]*scalingVars.C0);
1046  if (NpMinOut > (npVec[i]*scalingVars.C0)) NpMinOut = (npVec[i]*scalingVars.C0);
1047  if (NpMaxOut < (npVec[i]*scalingVars.C0)) NpMaxOut = (npVec[i]*scalingVars.C0);
1048  }
1049 
1050  fprintf(fp1,"%s","\n");
1051  fprintf(fp1,"%s","---------------------------------------------------------\n");
1052  if (getSolverState().dcopFlag)
1053  {
1054  fprintf(fp1,"Global data for DC step %4d:\n", callsOTXT);
1055  }
1056  else
1057  {
1058  fprintf(fp1,"Global data for time step %4d:\n", callsOTXT);
1059  }
1060  fprintf(fp1,"Current Time = %12.4e\n" , time);
1061  fprintf(fp1," Vmin = %12.4e\n", VminOut);
1062  fprintf(fp1," Vmax = %12.4e\n", VmaxOut);
1063  fprintf(fp1," NnMin = %12.4e\n", NnMinOut);
1064  fprintf(fp1," NnMax = %12.4e\n", NnMaxOut);
1065  fprintf(fp1," NpMin = %12.4e\n", NpMinOut);
1066  fprintf(fp1," NpMax = %12.4e\n", NpMaxOut);
1067 
1068  fprintf(fp1,"%s","\n");
1069 
1070  // loop over the device interface nodes, sum the currents going into each one.
1071  std::vector<DeviceInterfaceNode>::iterator firstDI = dIVec.begin ();
1072  std::vector<DeviceInterfaceNode>::iterator lastDI = dIVec.end ();
1073  std::vector<DeviceInterfaceNode>::iterator iterDI;
1074 
1075  for (iterDI=firstDI; iterDI!=lastDI; ++iterDI)
1076  {
1077  // loop over the nodes of this device interface node:
1078 
1079  if ( !( meshContainerPtr->labelEdgeType (iterDI->eName) ) ) continue;
1080 
1081  mLabel * labelPtr = meshContainerPtr->getLabel(iterDI->eName);
1082 
1083  fprintf(fp1, "Information for electrode: %s\n", iterDI->eName.c_str());
1084  fprintf(fp1, "potential: %12.4e\n", scalingVars.V0* VVec[iterDI->firstMeshNodeIndex] );
1085  fprintf(fp1, " current: %12.4e\n", iterDI->currentSum);
1086  fprintf(fp1, " charge: %12.4e\n", iterDI->chargeSum);
1087  fprintf(fp1, " dIdVckt: %12.4e\n", iterDI->dIdVckt);
1088  fprintf(fp1, " dQdVckt: %12.4e\n", iterDI->dQdVckt);
1089  fprintf(fp1, "%s","\n");
1090  }
1091 
1092  if (!calcConductanceFlag)
1093  {
1094  fprintf(fp1, "%s","NOTE: The two-level Newton algorithm was not used.\n");
1095  fprintf(fp1, "%s"," This means that the condutances and capacitances\n");
1096  fprintf(fp1, "%s"," were not calculated.\n\n");
1097  }
1098 
1099  int iE1,iE2;
1100 
1101  fprintf(fp1, "%s","Conductance array: \n");
1102  fprintf(fp1,"%s"," ");
1103  for (iE2 = 0; iE2 < numElectrodes; ++iE2)
1104  {
1105  fprintf(fp1,"\t%14s",dIVec[iE2].eName.c_str());
1106  }
1107  fprintf(fp1,"%s","\n");
1108 
1109  for (iE1 = 0; iE1 < numElectrodes; ++iE1)
1110  {
1111  fprintf(fp1,"%14s",dIVec[iE1].eName.c_str());
1112  for (iE2 = 0; iE2 < numElectrodes; ++iE2)
1113  {
1114  fprintf(fp1,"\t%14.4e",condVec[iE1][iE2]);
1115  }
1116  fprintf(fp1,"%s","\n");
1117  }
1118  fprintf(fp1,"%s","\n");
1119 
1120  fprintf(fp1, "%s","Capacitance array: \n");
1121  fprintf(fp1,"%s"," ");
1122  for (iE2 = 0; iE2 < numElectrodes; ++iE2)
1123  {
1124  fprintf(fp1,"\t%14s",dIVec[iE2].eName.c_str());
1125  }
1126  fprintf(fp1,"%s","\n");
1127 
1128  for (iE1 = 0; iE1 < numElectrodes; ++iE1)
1129  {
1130  fprintf(fp1,"%14s",dIVec[iE1].eName.c_str());
1131  for (iE2 = 0; iE2 < numElectrodes; ++ iE2)
1132  {
1133  fprintf(fp1,"\t%14.4e",capVec[iE1][iE2]);
1134  }
1135  fprintf(fp1,"%s","\n");
1136  }
1137  fprintf(fp1,"%s","\n");
1138 
1139  fclose(fp1);
1140 
1141  return bsuccess;
1142 }
1143 
1144 
1145 //-----------------------------------------------------------------------------
1146 // Function : Instance::outputSgplot
1147 // Purpose : This function outputs a file that can be read by the
1148 // plotting program sgplot.
1149 // Special Notes :
1150 // Scope : public
1151 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1152 // Creation Date : 09/30/02
1153 //-----------------------------------------------------------------------------
1155 {
1156  int i;
1157 
1158  // note: number of elements = N*Narray + Nvars.
1159  // N = number of nodes
1160  // Narray = number of arrays
1161  // Nvars = number of non-array variables
1162  // Nconst = number of constants
1163 
1164  UINT Narray = 6; // x,y,V,nn,np,C
1165  UINT Nconst = 3;
1166 
1167  RESHEAD resheadxyce =
1168  { "SGFramework Result File Version 1.0\n\x1a", // text logo
1169  "@~!_RES" "ULT_!~@", // signature
1170  "", // mesh file name
1171  Nconst, // number of constants
1172  0, // number of variables
1173  Narray, // number of arrays
1174  Narray*numMeshPoints, // number of elements
1175  Narray, // number of 1D arrays
1176  0, // number of 2D arrays
1177  0, // number of 3D arrays
1178  1}; // number of data sets
1179 
1180  RESHEAD *presheadxyce = &resheadxyce;
1181 
1182  // fix this:
1183  if (usingInternalMesh) meshFileName = outputName + ".msh";
1184 
1185  strcpy(presheadxyce->szMeshFile, meshFileName.c_str());
1186 
1187  // set up empty axlatconstxyce:
1188  XLATCONST axlatconstxyce[] =
1189  { { "NODES", TYPE_ICONST, { numMeshPoints } },
1190  { "EDGES", TYPE_ICONST, { numMeshEdges } },
1191  { "TRIANGLES", TYPE_ICONST, { numMeshCells } }
1192  };
1193 
1194  DAXLATARRAY AxlatArray(numMeshPoints); // see the constructor
1195 
1196  XLATARRAY *paxlat = AxlatArray.GetPointer(0);
1197 
1198  char filename[32]; for(i=0;i<32;++i) filename[i] = static_cast<char>(0);
1199  sprintf(filename,"%s_%03d.res",outputName.c_str(),callsOSG);
1200  ++callsOSG;
1201 
1202  FILE *nHandle = fopen(filename, "w");
1203 
1204  UINT cConst = Nconst;
1205  for(i = 0; i < Nconst; ++i)
1206  axlatconstxyce[i].data.n = static_cast<int> (axlatconstxyce[i].data.r);
1207 
1208  fwrite(presheadxyce, sizeof(RESHEAD),1,nHandle);
1209  if (cConst) fwrite(axlatconstxyce, sizeof(XLATCONST), cConst, nHandle);
1210  if (Narray ) fwrite( paxlat, sizeof(XLATARRAY), Narray, nHandle);
1211 
1212  // In Kevin's original setup, these two lines are in place.
1213  // The reason for this is so that he can keep adding data sets
1214  // to the same file. To do so, he has to update the cSset
1215  // attribute of RESHEAD, but nothing else. So he rewrites that,
1216  // then goes back to the end of the file.
1217  // Anyway, it isn't neccessary here. I only put one data set in
1218  // any file.
1219  //presheadxyce->cSet++;
1220  //fwrite(presheadxyce, sizeof(RESHEAD),1,nHandle);
1221  //fseek(nHandle, 0L, SEEK_END);
1222 
1223  // output all the data arrays:
1224  for (i=0;i<numMeshPoints;++i) outputVec[i] = scalingVars.x0 * xVec[i];
1225  fwrite( &(outputVec[0]), sizeof(double), numMeshPoints, nHandle);
1226 
1227  for (i=0;i<numMeshPoints;++i) outputVec[i] = scalingVars.x0 * yVec[i];
1228  fwrite( &(outputVec[0]), sizeof(double), numMeshPoints, nHandle);
1229 
1230  for (i=0;i<numMeshPoints;++i) outputVec[i] = scalingVars.V0 * VVec[i];
1231  fwrite( &(outputVec[0]), sizeof(double), numMeshPoints, nHandle);
1232 
1233  for (i=0;i<numMeshPoints;++i) outputVec[i] = scalingVars.C0 * nnVec[i];
1234  fwrite( &(outputVec[0]), sizeof(double), numMeshPoints, nHandle);
1235 
1236  for (i=0;i<numMeshPoints;++i) outputVec[i] = scalingVars.C0 * npVec[i];
1237  fwrite( &(outputVec[0]), sizeof(double), numMeshPoints, nHandle);
1238 
1239  for (i=0;i<numMeshPoints;++i) outputVec[i] = scalingVars.C0 * CVec[i];
1240  fwrite( &(outputVec[0]), sizeof(double), numMeshPoints, nHandle);
1241 
1242  fclose(nHandle);
1243 
1244  return true;
1245 }
1246 
1247 } // namespace TwoDPDE
1248 } // namespace Device
1249 } // namespace Xyce
1250 
1251 //-----------------------------------------------------------------------------
1252 // Function : DAXLATARRAY::set
1253 // Purpose : This function (and class) is only used in the context
1254 // of outputting sgplot files.
1255 // Special Notes :
1256 // Scope : public
1257 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1258 // Creation Date : 09/30/02
1259 //-----------------------------------------------------------------------------
1260 void DAXLATARRAY::set (const char *name, UINT uOffset, UINT cDim, UINT ac0, UINT ac1, UINT ac2)
1261 {
1262  XLATARRAY xlattmp;
1263  char tmpname[LEN_IDENT+1];
1264  int istrl = strlen(name);
1265  int imax;
1266 
1267  if(istrl >= LEN_IDENT-1) imax = LEN_IDENT-1;
1268  else imax = istrl;
1269 
1270  int i;
1271  for(i=0;i<LEN_IDENT+1;++i) tmpname[i] = 0;
1272 
1273  for(i=0;i<imax;++i)
1274  tmpname[i] = name[i];
1275 
1276  sprintf(xlattmp.szName,"%s",tmpname);
1277 
1278  xlattmp.uOffset = uOffset;
1279  xlattmp.cDim = cDim;
1280  xlattmp.acElements[0] = ac0;
1281  xlattmp.acElements[1] = ac1;
1282  xlattmp.acElements[2] = ac2;
1283  Add(xlattmp);
1284 
1285 }
1286 
1287 //-----------------------------------------------------------------------------
1288 // Function : DAXLATARRAY::DAXLATARRAY
1289 // Purpose : constructor
1290 // Special Notes : This function (and class) is only used in the context
1291 // of outputting sgplot files.
1292 // Scope : public
1293 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1294 // Creation Date : 09/30/02
1295 //-----------------------------------------------------------------------------
1296 DAXLATARRAY::DAXLATARRAY(int numMeshPoints)
1297 {
1298  int c = 10;
1299  cElements = 0;
1300  uInc = cSize = c;
1301  dynarray = new XLATARRAY[c];
1302 
1303  char tmpArg[16]; for(int i=0;i<16;++i) tmpArg[i] = 0;
1304 
1305  // set up axlatarrayicp:
1306  set( "x" , 0*numMeshPoints,1,numMeshPoints,0,0);
1307  set( "y" , 1*numMeshPoints,1,numMeshPoints,0,0);
1308  set( "V" , 2*numMeshPoints,1,numMeshPoints,0,0);
1309  set( "Ne", 3*numMeshPoints,1,numMeshPoints,0,0);
1310  set( "Np" , 4*numMeshPoints,1,numMeshPoints,0,0);
1311  set( "C" , 5*numMeshPoints,1,numMeshPoints,0,0);
1312 }
1313