CFD Online Logo CFD Online URL
Home > Forums > OpenFOAM Running, Solving & CFD

Improved solver data output / tracking / visualization

Register Blogs Members List Search Today's Posts Mark Forums Read

Like Tree1Likes
  • 1 Post By chriss85

LinkBack Thread Tools Display Modes
Old   May 6, 2015, 09:01
Lightbulb Improved solver data output / tracking / visualization
Senior Member
Join Date: Oct 2013
Posts: 321
Rep Power: 6
chriss85 is on a distinguished road
I have been somewhat unhappy with the way solver output works in OpenFOAM. The common approach is that the solver writes a log file which is then parsed with external tools. However, atleast when creating a solver oneself, better control over the output might be desireable. In my case, this results in writing csv files with lots of output data for analysis.

I've created a solution for this that I would like to present here. I wrote a class that can be used in the solver to store values. The class has support for structured output based on time steps and two nested loops, so the results may be viewed for each time step, each outer loop or every inner loop iteration. Separate csv files will be written for these cases so they are easier to plot.

The solver only needs some tiny adjustments, namely, you need to tell the csv file when a new timestep, outer loop step or inner loop substep occurs. Apart from that, you can use the class anywhere to output any kind of data you like.

For plotting I use kst plot. It's a handy tool that can be used to configure different views on the result data, so I can look at the whole data, only the last x steps, etc. For me it's much more flexible than gnuplot for data visualization.

Attached you can find the files for the csv class. Below is an example use case in a solver. It's not tested or useful in any real way but serves to demonstrate the usage of this class:
#include "AllKindsOfThings.H"
#include "csvWriter.H"

int main(int argc, char *argv[])
    #include "someStuff.H"
    //Create the csvWriter objects on the heap so they can be initialized later
    autoPtr<csvWriter> csv;
    autoPtr<csvWriter> residuals;

    Info << "Start time: " << runTime.startTime() << endl;
    Info << "End time: " << runTime.endTime() << endl;
    Info << "dt: " << runTime.deltaT() << endl;
    Info << "\nStarting time loop\n" << endl;
    while (
    //Start time of the current time step for profiling
    scalar timeStepStart = runTime.elapsedCpuTime();

        Info << "Time = " << runTime.timeName() << nl << endl;
        Info << "deltaT = " << runTime.deltaT().value() << endl;

    //Initialize the csv objects on the first step and set the current times on further steps
    //If you want to put the calls to increaseTime at the end of the time loop you need to initialize the csvWriter objects before the time lop with startTime + deltaT instead
    if(runTime.timeIndex() == runTime.startTimeIndex() + 1)
      csv.set(new csvWriter("output", runTime.time().value() * 1e6, true));
      residuals.set(new csvWriter("residuals", runTime.time().value() * 1e6, false)); //Stored residuals shouldn't be printed by default
      csv->increaseTime(runTime.time().value() * 1e6);
      residuals->increaseTime(runTime.time().value() * 1e6);

    //Main outer convergence loop
        while (pimple.loop())
          //Solve some equation and write the convergence results to the csv files.
          solverPerformance perf = solve(SomeEquation);
          residuals->store("SomeEquation_initial", perf.initialResidual(), "SomeEquation_final", perf.finalResidual(), "SomeEquation_iterations", perf.nIterations());
          //store some field values and print them
          csv->store("Somefield_min", gMin(someField), "Somefield_max", gMax(someField));

          //here we increase the index of the substep loop
          //Store the time of the current outer loop iteration in ms
          csv->store("OuterLoopTime", (runTime.elapsedCpuTime() - timeStepStart) * 1000);

          //Here we increase the index of the step loop
    //Store the total runtime but don't print it
    csv->store("Runtime", runTime.elapsedCpuTime(), false);

        Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
            << ", ClockTime = " << runTime.elapsedClockTime() << " s"
        << ", Time step duration = " << runTime.elapsedClockTime() - timeStepStart << " s"
            << nl << endl;
    Info << "Last write at t=" << runTime.timeName() << endl;
    Info<< "\nEnd\n" << endl;

    return 0;
Attached Images
File Type: jpg residuals.jpg (66.3 KB, 17 views)
File Type: jpg fields.jpg (54.2 KB, 13 views)
Attached Files
File Type: zip (3.5 KB, 1 views)
aminem likes this.

Last edited by chriss85; May 13, 2015 at 07:51.
chriss85 is offline   Reply With Quote

Old   May 13, 2015, 07:55
Senior Member
Join Date: Oct 2013
Posts: 321
Rep Power: 6
chriss85 is on a distinguished road
I've added an example code for demonstration.

This method has proved to be quite useful for me in monitoring the convergence behavior of my code and optimizing the performance. Being able to quickly view all kinds of convergence and performance data in realtime makes it much easier to make the solver code work as best as possible

Let me know if you feel there is anything missing in this approach!
chriss85 is offline   Reply With Quote


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Similar Threads
Thread Thread Starter Forum Replies Last Post
which solver for particle tracking through a fluid for lagrangian based method? ranasa OpenFOAM Running, Solving & CFD 0 August 9, 2014 03:09
solver stop problem in Lagrangian Particle Tracking sakurabogoda CFX 3 October 5, 2012 06:09
Quarter Burner mesh with periosic condition SamCanuck FLUENT 2 August 31, 2011 11:34
Working directory via command line Luiz CFX 4 March 6, 2011 21:02
why the solver reject it? Anyone with experience? bearcat CFX 6 April 28, 2008 14:08

All times are GMT -4. The time now is 02:39.