Program Listing for File output.cpp
↰ Return to documentation for file (output/output.cpp
)
// ***********************************************************************************
// Idefix MHD astrophysical code
// Copyright(C) 2020-2022 Geoffroy R. J. Lesur <geoffroy.lesur@univ-grenoble-alpes.fr>
// and other code contributors
// Licensed under CeCILL 2.1 License, see COPYING for more information
// ***********************************************************************************
#include "output.hpp"
Output::Output(Input &input, DataBlock &data) {
idfx::pushRegion("Output::Output");
// initialise the output objects for each format
if(input.forceNoWrite) {
this->forceNoWrite = true;
}
// Initialise vtk outputs
if(input.CheckEntry("Output","vtk")>0) {
vtkPeriod = input.Get<real>("Output","vtk",0);
if(vtkPeriod>=0.0) { // backward compatibility (negative value means no file)
vtkLast = data.t - vtkPeriod; // write something in the next CheckForWrite()
vtkEnabled = true;
}
}
vtk.Init(input,data); // Always initialised in case of emergency vtk output
// intialise dump outputs
if(input.CheckEntry("Output","dmp")>0) {
dumpPeriod = input.Get<real>("Output","dmp",0);
dumpLast = data.t - dumpPeriod; // dump something in the next CheckForWrite()
dumpEnabled = true;
// Backwards compatibility: negative period means no dump
if(dumpPeriod<0.0) dumpEnabled = false;
}
dump.Init(input,data); // Always initialised since it is required on restarts
// initialise analysis outputs
if(input.CheckEntry("Output","analysis")>0) {
analysisPeriod = input.Get<real>("Output","analysis",0);
analysisLast = data.t - analysisPeriod; //dump something in the next CheckForWrite()
analysisEnabled = true;
}
// Initialise userdefined outputs
if(input.CheckEntry("Output","uservar")>0) {
int nvars = input.CheckEntry("Output","uservar");
for(int var = 0 ; var < nvars ; var++) {
std::string arrayName = input.Get<std::string>("Output","uservar",var);
// Create an array to store this user variable
// and store the whole thing in the container
userDefVariables[arrayName] = IdefixHostArray3D<real>("userVar-"+arrayName,
data.np_tot[KDIR],
data.np_tot[JDIR],
data.np_tot[IDIR]);
}
userDefVariablesEnabled = true;
}
idfx::popRegion();
}
int Output::CheckForWrites(DataBlock &data) {
idfx::pushRegion("Output::CheckForWrites");
int nfiles=0;
// skip everything if forced to disable all writes
if(forceNoWrite) {
idfx::popRegion();
return(0);
}
// Do we need a restart dump?
if(dumpEnabled) {
if(data.t >= dumpLast + dumpPeriod) {
elapsedTime -= timer.seconds();
dumpLast += dumpPeriod;
dump.Write(data,*this);
nfiles++;
elapsedTime += timer.seconds();
// Check if our next predicted output should already have happened
if((dumpLast+dumpPeriod <= data.t) && dumpPeriod>0.0) {
// Move forward dumpLast
while(dumpLast <= data.t - dumpPeriod) {
dumpLast += dumpPeriod;
}
}
}
}
// Do we need a VTK output?
if(vtkEnabled) {
if(data.t >= vtkLast + vtkPeriod) {
elapsedTime -= timer.seconds();
if(userDefVariablesEnabled) {
if(haveUserDefVariablesFunc) {
// Call user-def function to fill the userdefined variable arrays
idfx::pushRegion("UserDef::User-defined variables function");
userDefVariablesFunc(data, userDefVariables);
idfx::popRegion();
} else {
IDEFIX_ERROR("Cannot output user-defined variables without "
"enrollment of your user-defined variables function");
}
}
vtkLast += vtkPeriod;
vtk.Write(data, *this);
nfiles++;
elapsedTime += timer.seconds();
// Check if our next predicted output should already have happened
if((vtkLast+vtkPeriod <= data.t) && vtkPeriod>0.0) {
// Move forward vtkLast
while(vtkLast <= data.t - vtkPeriod) {
vtkLast += vtkPeriod;
}
}
}
}
// Do we need an analysis ?
if(analysisEnabled) {
if(data.t >= analysisLast + analysisPeriod) {
elapsedTime -= timer.seconds();
if(!haveAnalysisFunc) {
IDEFIX_ERROR("Cannot perform a user-defined analysis without "
"enrollment of your analysis function");
}
analysisLast += analysisPeriod;
idfx::pushRegion("UserDef::User-defined analysis function");
analysisFunc(data);
idfx::popRegion();
nfiles++;
elapsedTime += timer.seconds();
// Check if our next predicted output should already have happened
if((analysisLast+analysisPeriod <= data.t) && analysisPeriod>0.0) {
// Move forward analysisLast
while(analysisLast <= data.t - analysisPeriod) {
analysisLast += analysisPeriod;
}
}
}
}
idfx::popRegion();
return(nfiles);
}
void Output::RestartFromDump(DataBlock &data, int readNumber) {
idfx::pushRegion("Output::RestartFromDump");
dump.Read(data, *this, readNumber);
idfx::popRegion();
}
void Output::ForceWriteDump(DataBlock &data) {
idfx::pushRegion("Output::ForceWriteDump");
if(!forceNoWrite) dump.Write(data,*this);
idfx::popRegion();
}
void Output::ForceWriteVtk(DataBlock &data) {
idfx::pushRegion("Output::ForceWriteVtk");
if(!forceNoWrite) {
if(userDefVariablesEnabled) {
if(haveUserDefVariablesFunc) {
// Call user-def function to fill the userdefined variable arrays
idfx::pushRegion("UserDef::User-defined variables function");
userDefVariablesFunc(data, userDefVariables);
idfx::popRegion();
} else {
IDEFIX_ERROR("Cannot output user-defined variables without "
"enrollment of your user-defined variables function");
}
}
vtkLast += vtkPeriod;
vtk.Write(data, *this);
}
idfx::popRegion();
}
void Output::EnrollAnalysis(AnalysisFunc myFunc) {
idfx::pushRegion("Output::EnrollAnalysis");
if(!analysisEnabled) {
IDEFIX_WARNING("You are enrolling an analysis function "
"but analysis are not enabled in the input file,"
"so no analysis will be performed");
}
analysisFunc = myFunc;
haveAnalysisFunc = true;
idfx::popRegion();
}
void Output::EnrollUserDefVariables(UserDefVariablesFunc myFunc) {
idfx::pushRegion("Output::EnrollUserDefVariable");
if(!userDefVariablesEnabled) {
IDEFIX_ERROR("You are enrolling a user-defined variables function "
"but the userdef variables are not set in the input file");
}
userDefVariablesFunc = myFunc;
haveUserDefVariablesFunc = true;
idfx::popRegion();
}
void Output::ResetTimer() {
elapsedTime = 0.0;
}
double Output::GetTimer() {
return(elapsedTime);
}