<Cedar5.2>System>spOutput.mesa>> <> DIRECTORY BasicTime USING [GMT, Now], FS USING [StreamOpen], IO USING [int, PutF, PutFR, real, Reset, rope, STREAM, time], Labels USING [Set], Plot USING [AddVector, CreateViewer, Vector, RealSequence, RopeSequence, PlotSpecRec], Rope USING [Concat, ROPE], RopeFrom USING [String], spGlobals USING [argument, argumentPtr, branchPtr, OutputFileRoot, error, findNodeOrBranch, FlushCloseNil, getSignedNumber, Handle, makeStringNB, maxPlots, maxPrints, next, nodePtr, plotBlkPtr, plotBlk, printBlk, printBlkPtr, RefC, RefI, RefL, RefR, RefV, version], ViewerTools USING [GetContents]; spOutput: CEDAR PROGRAM IMPORTS BasicTime, FS, IO, Labels, Plot, Rope, RopeFrom, spGlobals, ViewerTools EXPORTS spGlobals= BEGIN OPEN spGlobals; initPlot: PUBLIC PROC[handle: Handle, tMin, tMax: REAL]= { OPEN handle.vars; iCurve: NAT; rope: Rope.ROPE; pl: plotBlkPtr; FOR i: NAT IN [0..numPlots) DO OPEN plots[i].plotSpec; time_ handle.vars.simTime; file_ Rope.Concat[OutputFileRoot[handle], IO.PutFR[".plot%g", IO.int[i]]]; bounds.xmin_ tMin/plots[i].plotTimeRelTo; bounds.xmax_ tMax/plots[i].plotTimeRelTo; legendEntries_ NEW[Plot.RopeSequence[nCurvesMax]]; FOR j: NAT IN [0..nCurvesMax) DO legendEntries[j]_ NIL; ENDLOOP; iCurve_ 0; pl _ plots[i].plotList; UNTIL pl = NIL DO heading: Rope.ROPE; heading_ SELECT TRUE FROM pl.arg.getComVal => "Value of ", pl.arg.current => "Current through ", pl.arg.dvdt => "Derivative of ", ENDCASE => "Voltage at "; rope_ Rope.Concat[heading, makeStringNB[handle, pl.arg.node, pl.arg.branch]]; legendEntries[iCurve]_ IF pl.relativeTo = 1.0 THEN rope ELSE IO.PutFR["%g/%-9.2f", IO.rope[rope], IO.real[pl.relativeTo]]; pl _ pl.nextBlk; iCurve_ iCurve + 1; ENDLOOP; plots[i].plotViewer_ Plot.CreateViewer[ spec: plots[i].plotSpec, iconic: i # 0, inhibitDestroy: TRUE]; ENDLOOP; }; -- initPlot plotFromList: PUBLIC PROC[handle: Handle, t: REAL] = { OPEN handle.vars; FOR iPlot: NAT IN [0..numPlots) DO iCurve: NAT_ 0; vector: Plot.Vector_ NEW[Plot.RealSequence[plots[iPlot].plotSpec.nCurvesMax + 1]]; p: plotBlkPtr_ plots[iPlot].plotList; vector[0]_ t/plots[iPlot].plotTimeRelTo; UNTIL p = NIL DO iCurve_ iCurve + 1; vector[iCurve]_ evaluateArgument[p.arg]/p.relativeTo; p _ p.nextBlk; ENDLOOP; Plot.AddVector[plots[iPlot].plotViewer, vector]; ENDLOOP; }; -- plotFromList getPlotNum: PROC [handle: Handle] RETURNS[r: REAL_ 1.0] = { r_ getSignedNumber[handle]; IF handle.vars.item = comma THEN next[handle] ELSE error[handle, 603,, FALSE] }; -- getPlotNum makePlotList: PUBLIC PROC[handle: Handle]= { OPEN handle.vars; I, D, cv: BOOL; pb: plotBlkPtr; n: nodePtr; b: branchPtr; IF numPlots >= maxPlots THEN { error[handle, 632, FALSE]; numPlots _ numPlots - 1 }; IF item = leftB THEN next[handle] ELSE error[handle, 600]; plots[numPlots].plotSpec _ NEW[Plot.PlotSpecRec _ []]; IF item = string THEN { plots[numPlots].plotSpec.title _ RopeFrom.String[newString]; next[handle]; IF item = comma THEN next[handle] ELSE error[handle, 603,, FALSE] }; IF item = colon THEN { plots[numPlots].plotTimeRelTo_ scale[handle]; IF item = comma THEN next[handle] ELSE error[handle, 603,, FALSE] } ELSE plots[numPlots].plotTimeRelTo _ 1.0; plots[numPlots].plotSpec.bounds.ymin _ getPlotNum[handle]; plots[numPlots].plotSpec.bounds.ymax _ getPlotNum[handle]; IF plots[numPlots].plotSpec.bounds.ymin >= plots[numPlots].plotSpec.bounds.ymax THEN error[handle, 630, FALSE]; plots[numPlots].plotList _ NIL; <> UNTIL item # name DO plots[numPlots].plotSpec.nCurvesMax _ plots[numPlots].plotSpec.nCurvesMax + 1; [n, b] _ findNodeOrBranch[handle]; IF n = NIL AND b = NIL THEN error[handle, 620] ELSE { I_ b # NIL AND item = upArrow; D_ n # NIL AND item = quote; cv_ b # NIL AND item = atSign; IF I OR D OR cv THEN next[handle]; pb_ NEW[plotBlk_ [nextBlk: plots[numPlots].plotList, relativeTo: scale[handle], arg: NEW[argument_ [FALSE, n, b, cv, D, I]]] ]; plots[numPlots].plotList_ pb; }; IF item = comma THEN next[handle] ELSE EXIT; ENDLOOP; IF item = rightB THEN next[handle] ELSE error[handle, 601, TRUE]; numPlots _ numPlots + 1; }; -- makePlotList PutMsgLine: PUBLIC PROC[handle: Handle, s: Rope.ROPE]= { handle.msgStream.PutF["%g\n", IO.rope[s]]; }; -- PutMsgLine evaluateArgument: PROC[a: argumentPtr] RETURNS[iv: REAL]= { b: branchPtr; IF a.getComVal THEN RETURN[a.branch.comVal]; IF a.node # NIL THEN iv_ IF a.dvdt THEN a.node.nHist.f0 ELSE a.node.nHist.y ELSE { b_ a.branch; IF a.current THEN WITH b.body SELECT FROM r: RefR => iv_ (b.posNode.nHist.y - b.negNode.nHist.y)/b.comVal; c: RefC => iv_ (b.posNode.nHist.f0 - b.negNode.nHist.f0)*b.comVal; l: RefL => iv_ l.iHist.y/b.comVal; v: RefV => iv_ v.vsCurrent; i: RefI => iv_ b.comVal; ENDCASE ELSE iv_ b.posNode.nHist.y - b.negNode.nHist.y; }; }; -- evaluateArgument initPrint: PUBLIC PROC[handle: Handle, time: BasicTime.GMT]= { FOR i: NAT IN [0..handle.vars.numPrints) DO output: IO.STREAM_ handle.vars.prints[i].printStream; output.PutF["* Simulation started at %g.\n", IO.time[time]]; ENDLOOP; }; -- initPrint printFromList: PUBLIC PROC[handle: Handle, ni: INT, t: REAL, printStep: BOOL]= { i: NAT; p: printBlkPtr; r, trel: REAL; FOR i IN [0..handle.vars.numPrints) DO output: IO.STREAM_ handle.vars.prints[i].printStream; p_ handle.vars.prints[i].printList; trel_ t/handle.vars.prints[i].printTimeRelTo; output.PutF["%10.3e", IO.real[trel]]; IF printStep THEN output.PutF["(%2d)", IO.int[ni]]; UNTIL p=NIL DO r_ evaluateArgument[p.arg]/p.relativeTo; output.PutF[" %10.3f", IO.real[r]]; p_ p.nextBlk; ENDLOOP; output.PutF["\n"]; ENDLOOP; }; -- printFromList scale: PROC[handle: Handle] RETURNS[s: REAL_ 1.0]= { IF handle.vars.item=colon THEN {next[handle]; s_ getSignedNumber[handle]}; }; -- scale makePrintList: PUBLIC PROC[handle: Handle]= { OPEN handle.vars; I, D, cv: BOOL; pb, pb2, pb3: printBlkPtr; n: nodePtr; b: branchPtr; outFileNameRoot, outFileName, outFiles: Rope.ROPE; IF numPrints >= maxPrints THEN { error[handle, 631]; numPrints_ numPrints - 1; }; IF item=leftB THEN next[handle] ELSE error[handle, 600]; IF item=colon THEN { prints[numPrints].printTimeRelTo_ scale[handle]; IF item=comma THEN next[handle] ELSE error[handle, 603,, FALSE]; } ELSE prints[numPrints].printTimeRelTo_ 1.0; prints[numPrints].printList_ NIL; UNTIL item # name DO [n, b]_ findNodeOrBranch[handle]; IF n=NIL AND b=NIL THEN error[handle, 620] ELSE { I_ (b # NIL) AND item=upArrow; -- branch current D_ (n # NIL) AND item=quote; -- derivative of node voltage cv_ (b # NIL) AND item=atSign; -- branch value IF I OR D OR cv THEN next[handle]; pb_ NEW[printBlk_ [nextBlk: prints[numPrints].printList, relativeTo: scale[handle], arg: NEW[argument_ [FALSE, n, b, cv, D, I]] ] ]; prints[numPrints].printList_ pb; }; IF item=comma THEN next[handle] ELSE EXIT; ENDLOOP; pb_ NIL; pb3_ prints[numPrints].printList; UNTIL pb3=NIL DO pb2_ pb3; pb3_ pb3.nextBlk; pb2.nextBlk_ pb; pb_ pb2; ENDLOOP; prints[numPrints].printList_ pb; outFileNameRoot_ OutputFileRoot[handle]; outFileName_ IO.PutFR["%g.out%g", IO.rope[outFileNameRoot], IO.int[numPrints]]; prints[numPrints].printStream_ FS.StreamOpen[fileName: outFileName, accessOptions: $create]; prints[numPrints].printStream.Reset[ ]; outFiles_ IF numPrints=0 THEN outFileName ELSE IO.PutFR["%g.out0...out%g", IO.rope[outFileNameRoot], IO.int[numPrints]]; Labels.Set[handle.output, outFiles]; prints[numPrints].printStream.PutF[ "** %g\n*\n* File: %g\n* Input: %g\n* Time: %g\n*\n", IO.rope[version], IO.rope[outFileName], IO.rope[ViewerTools.GetContents[handle.input]], IO.time[simTime] ]; numPrints_ numPrints + 1; IF item=rightB THEN next[handle] ELSE error[handle, 601, TRUE]; }; -- makePrintList dumpAll: PUBLIC PROC[handle: Handle, t: REAL]= { OPEN handle.vars; dname: Rope.ROPE; dump: IO.STREAM; nodes: nodePtr_ nodeList; inds: branchPtr_ inductorList; dname_ IO.PutFR["%g.dump", IO.rope[OutputFileRoot[handle]]]; dump_ FS.StreamOpen[fileName: dname, accessOptions: $create]; dump.Reset[]; dump.PutF["ic[%f,\n", IO.real[t]]; UNTIL nodes=NIL DO dump.PutF["%g_ %f", IO.rope[makeStringNB[handle, nodes, NIL, FALSE]], IO.real[nodes.nHist.y]]; nodes_ nodes.nextNode; IF nodes # NIL THEN dump.PutF[",\n"] ELSE dump.PutF["\n"]; ENDLOOP; UNTIL inds=NIL DO indsBody: RefL_ NARROW[inds.body]; dump.PutF["%g_ %f", IO.rope[makeStringNB[handle, NIL, inds, FALSE]], IO.real[indsBody.iHist.y]]; inds_ indsBody.nextInductor; IF inds # NIL THEN IO.PutF[dump, ",\n"] ELSE IO.PutF[dump, "\n"]; ENDLOOP; dump.PutF["];\n"]; handle.msgStream.PutF["Dumped into file %g at %g.\n", IO.rope[dname], IO.time[]]; dump _ FlushCloseNil[dump]; }; -- dumpAll END. <> <> <> <>