Skip to content

Commit

Permalink
Heat Equation restart tutorial (#146)
Browse files Browse the repository at this point in the history
  • Loading branch information
ajnonaka authored Dec 14, 2024
1 parent 65cdc73 commit ffbfc5a
Show file tree
Hide file tree
Showing 8 changed files with 442 additions and 1 deletion.
3 changes: 2 additions & 1 deletion Docs/source/Basic_Tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ that see the Building_libamrex chapter of the amrex docs here. `here <https://am

The HeatEquation examples solve a 2D or 3D (determined by how you set DIM in the GNUmakefile)
heat equation explicitly on a domain-decomposed mesh. This example is described in detail in
the Basics_ chapter of the amrex Documentation
the Basics_ chapter of the amrex Documentation.
There is also an example code, HeadEquation_Restart, that shows how to add restart capability to a time-advancement code.

.. _Basics: https://amrex-codes.github.io/amrex/docs_html/Basics.html

15 changes: 15 additions & 0 deletions ExampleCodes/Basic/HeatEquation_Restart/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
if (AMReX_SPACEDIM EQUAL 1)
return()
endif ()

# List of source files
set(_sources main.cpp checkpoint.cpp myfunc.H)
list(TRANSFORM _sources PREPEND "Source/")

# List of input files
file( GLOB_RECURSE _input_files LIST_DIRECTORIES false Exec/input* )

setup_tutorial(_sources _input_files)

unset( _sources )
unset( _input_files )
18 changes: 18 additions & 0 deletions ExampleCodes/Basic/HeatEquation_Restart/Exec/GNUmakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# AMREX_HOME defines the directory in which we will find all the AMReX code.
AMREX_HOME ?= ../../../../../amrex

DEBUG = FALSE
USE_MPI = FALSE
USE_OMP = FALSE
COMP = gnu
DIM = 3

include $(AMREX_HOME)/Tools/GNUMake/Make.defs

include ../Source/Make.package
VPATH_LOCATIONS += ../Source
INCLUDE_LOCATIONS += ./Source

include $(AMREX_HOME)/Src/Base/Make.package

include $(AMREX_HOME)/Tools/GNUMake/Make.rules
11 changes: 11 additions & 0 deletions ExampleCodes/Basic/HeatEquation_Restart/Exec/inputs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
n_cell = 32
max_grid_size = 16

nsteps = 1000
plot_int = 100
chk_int = 100

dt = 1.e-5

restart = -1
#restart = 200
3 changes: 3 additions & 0 deletions ExampleCodes/Basic/HeatEquation_Restart/Source/Make.package
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CEXE_sources += main.cpp
CEXE_sources += checkpoint.cpp
CEXE_headers += myfunc.H
121 changes: 121 additions & 0 deletions ExampleCodes/Basic/HeatEquation_Restart/Source/checkpoint.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#include "myfunc.H"

namespace {
void GotoNextLine (std::istream& is)
{
constexpr std::streamsize bl_ignore_max { 100000 };
is.ignore(bl_ignore_max, '\n');
}
}

// create a checkpoint directory
// write out time and BoxArray to a Header file
// write out multifab data
void WriteCheckpoint(const int& step,
const Real& time,
const MultiFab& phi)
{


// checkpoint file name, e.g., chk00010
const std::string& checkpointname = Concatenate("chk",step,5);

BoxArray ba = phi.boxArray();

// single level problem
int nlevels = 1;

// ---- prebuild a hierarchy of directories
// ---- dirName is built first. if dirName exists, it is renamed. then build
// ---- dirName/subDirPrefix_0 .. dirName/subDirPrefix_nlevels-1
// ---- if callBarrier is true, call ParallelDescriptor::Barrier()
// ---- after all directories are built
// ---- ParallelDescriptor::IOProcessor() creates the directories
PreBuildDirectorHierarchy(checkpointname, "Level_", nlevels, true);

VisMF::IO_Buffer io_buffer(VisMF::IO_Buffer_Size);

// write Header file to store time and BoxArray
if (ParallelDescriptor::IOProcessor()) {

std::ofstream HeaderFile;
HeaderFile.rdbuf()->pubsetbuf(io_buffer.dataPtr(), io_buffer.size());
std::string HeaderFileName(checkpointname + "/Header");
HeaderFile.open(HeaderFileName.c_str(), std::ofstream::out |
std::ofstream::trunc |
std::ofstream::binary);

if( !HeaderFile.good()) {
FileOpenFailed(HeaderFileName);
}

HeaderFile.precision(17);

// write out title line
HeaderFile << "Checkpoint file for MagneX\n";

// write out time
HeaderFile << time << "\n";

// write the BoxArray
ba.writeOn(HeaderFile);
HeaderFile << '\n';
}

// write the MultiFab data to, e.g., chk00010/Level_0/
VisMF::Write(phi, MultiFabFileFullPrefix(0, checkpointname, "Level_", "phi"));
}

// read in the time and BoxArray, then create a DistributionMapping
// Define phi and fill it with data from the checkpoint file
void ReadCheckpoint(const int& restart,
Real& time,
MultiFab& phi,
BoxArray& ba,
DistributionMapping& dm)
{

// checkpoint file name, e.g., chk00010
const std::string& checkpointname = Concatenate("chk",restart,5);

Print() << "Restart from checkpoint " << checkpointname << "\n";

VisMF::IO_Buffer io_buffer(VisMF::GetIOBufferSize());

std::string line, word;

// Header
{
std::string File(checkpointname + "/Header");
Vector<char> fileCharPtr;
ParallelDescriptor::ReadAndBcastFile(File, fileCharPtr);
std::string fileCharPtrString(fileCharPtr.dataPtr());
std::istringstream is(fileCharPtrString, std::istringstream::in);

// read in title line
std::getline(is, line);

// read in time
is >> time;
GotoNextLine(is);

// read in BoxArray from Header
ba.readFrom(is);
GotoNextLine(is);

// create a distribution mapping
dm.define(ba, ParallelDescriptor::NProcs());

// Nghost = number of ghost cells for each array
int Nghost = 1;

// Ncomp = number of components for each array
int Ncomp = 1;

phi.define(ba, dm, Ncomp, Nghost);
}

// read in the MultiFab data
VisMF::Read(phi, MultiFabFileFullPrefix(0, checkpointname, "Level_", "phi"));

}
Loading

0 comments on commit ffbfc5a

Please sign in to comment.