// -*- C++ -*- // $RCSfile: plotout.C,v $ // $Revision: 1.3 $ // $Author: langer $ // $Date: 2000/09/06 20:11:11 $ /* This software was produced by NIST, an agency of the U.S. government, * and by statute is not subject to copyright in the United States. * Recipients of this software assume all responsibilities associated * with its operation, modification and maintenance. However, to * facilitate maintenance we ask that before distributing modifed * versions of this software, you first contact the authors at * oof_manager@ctcms.nist.gov. */ #include "nodegroups.h" #include "plotout.h" #include "parameters.h" #include "output.h" #include "menuDef.h" static CharString plotscript; static Menu *plotoutmenu; static MenuStream *filestream = 0; static int ownfilestream = 1; static const int plotmenudepth = 2; /* number of levels in the "plot set" * menu preceding the things to be plotted. */ // Add a function to the list of things being plotted // All commands in the "plot set" submenu are really this one. static CommandFn addtoplot() { int depth = garcon()->get_depth(); for(int i=depth-plotmenudepth-1; i>=0; i--) plotscript = plotscript.spaceappend(garcon()->get_command(i)); plotscript += ";"; } static CommandFn clearplot() { plotscript = ""; } class PlotFileCmd : public FileCmd { public: PlotFileCmd() : FileCmd("file", "select an output file", "plotoutput") {} virtual CommandFn func() { if(filename == "-") { filestream = &garcon()->msout; ownfilestream = 0; } else { FILE *file = fopen(filename, "w"); if(!file) garcon()->msout << ms_error << "Can't open file \"" << filename << "\"" << endl << ms_normal; else { filestream = new FileMenuStream(file); ownfilestream = 1; } } } virtual FileCmd *subclone() const { return new PlotFileCmd; } }; static CommandFn closeplot() { if(ownfilestream) delete filestream; filestream = 0; } static CommandFn labelplot() { if(filestream) *filestream << "## " << plotscript << endl; } static CommandFn showplot() { if(plotscript == "") garcon()->msout << "Not plotting anything." << endl; else garcon()->msout << "Now plotting: " << plotscript << endl; } void doplot() { if(!filestream) return; ScriptWaiter sw(plotscript, garcon()->msout); sw.inhibit_logging(); sw.order(plotoutmenu); *filestream << endl; } static CommandFn do_plot() { doplot(); } // --------------------------------------------------------------- // // Commmands in the plotoutmenu static CommandFn plotenergy() { if(!filestream) return; *filestream << grid->energy() << " "; } static CommandFn plotavgdisp() { NodeGroup *n; if(!filestream) return; if(n = groupname()) { MeshCoord d(grid->avgdisp(n)); *filestream << d.x << " " << d.y << " "; } } static CommandFn plotforce() { NodeGroup *n; if(!filestream) return; if(n = groupname()) { MeshCoord f(grid->force(n)); *filestream << f.x << " " << f.y << " "; } } // --------------------------------------------------------------- // // initialization goes here Menu *plotmenu() { static Menu *pm = 0; if(pm) return pm; pm = new Menu("plot"); pm->AddCommand(new PlotFileCmd); Menu *setmenu = pm->AddSubMenu("set", "add items to plot list"); pm->AddCommand("show", "show functions being plotted", showplot); pm->AddCommand("clear", "clear the list of things being plotted", clearplot); pm->AddCommand("out", "actually plot a line", do_plot); pm->AddCommand("label", "print the plot list to the plot file", labelplot); pm->AddCommand("close", "close the plot file", closeplot); /* the "plot set" submenus must match the plotoutmenu exactly, * except that the "set" commands are all "addtoplot". The * plotoutmenu commands are the things that do the actual plotting. */ setmenu->AddCommand("energy", "plot energy", addtoplot); setmenu->AddSubMenu("displacement", "plot avg displacement", new GroupMenu("displacement", "plot average displacement of group", addtoplot)); setmenu->AddSubMenu("force", "plot avg force", new GroupMenu("force", "plot average force on group", addtoplot)); // plotoutmenu is used w/in the plotscript to do the actual plotting plotoutmenu = new Menu("plotcmds"); plotoutmenu->AddSubMenu("displacement", "", new GroupMenu("displacement", "", plotavgdisp)); plotoutmenu->AddSubMenu("force", "", new GroupMenu("force", "", plotforce)); plotoutmenu->AddCommand("energy", "", plotenergy); #ifdef DEBUG pm->AddSubMenu("debug", "output commands usually only accessed automatically", plotoutmenu); #endif return pm; }