Skip to content

Commit

Permalink
File read utils (#752)
Browse files Browse the repository at this point in the history
* some read/check from file bypassing the optionals, can quick-plot the cells
  • Loading branch information
mkstoyanov authored Dec 13, 2024
1 parent 44dd116 commit 3de89dc
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 16 deletions.
41 changes: 40 additions & 1 deletion python/asgard.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,27 @@ def __str__(self):
return s

if __name__ == "__main__":
if len(sys.argv) < 2:
if len(sys.argv) < 2 or sys.argv[1] in ("-v", "-version", "--version"):
libasgard.asgard_print_version_help()
elif sys.argv[1] in ("-h", "-help", "--help"):
print("")
print("python -m asgard plt.data")
print(" makes a quick 1D or 2D plot of output contained in out.data")
print("")
print("python -m asgard -g plt.data")
print(" makes a quick 1D or 2D plot of the grid contained in out.data")
print("")
print("python -m asgard -s plt.data")
print(" shows summary of the snapshot contained in the out.data")
print("")
print("options:")
print(" -h, -help, --help : shows this help text")
print(" -v, -version, --version : shows the library version info")
print(" -s, -stat, -stats, -summary : shows the summary of a snapshot")
print(" -g, -grid : plot the grid")
print("")
print("no file and no option provided, shows the version of the")
print("")
elif sys.argv[1] in ("-s", "-stat", "-stats", "-summary"):
if len(sys.argv) < 3:
print("stats summary option requires a filename")
Expand All @@ -274,6 +293,26 @@ def __str__(self):
print("can only print stats-summary, use")
print(" python3 -m asgard -s %s" % sys.argv[2])
libasgard.asgard_print_version_help()
elif sys.argv[1] in ("-grid", "-g"):
if len(sys.argv) < 3:
print("-grid option requires a filename")
else:
shot = pde_snapshot(sys.argv[2])
print("\n", shot)

asgplot.title(shot.title, fontsize = 'large')

cells = shot.cell_centers()
if shot.num_dimensions == 1:
asgplot.plot(cells[:,0], np.zeros(cells[:,0].shape), 'ro')
else:
asgplot.scatter(cells[:,0], cells[:,1], 5 * np.ones(cells[:,0].shape), color='red')

if len(sys.argv) > 3:
asgplot.savefig(sys.argv[3])
else:
asgplot.show()

else:
shot = pde_snapshot(sys.argv[1])
print("\n", shot)
Expand Down
30 changes: 30 additions & 0 deletions src/asgard_program_options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,36 @@ struct prog_opts
return get_val<out_type>(externals, s);
}

//! reads and returns a file_value, skips the optional but throws if the value is missing
template<typename out_type>
out_type file_required(std::string_view const &s) const
{
std::optional<out_type> x = file_value<out_type>(s);
if (infile.empty())
throw std::runtime_error(std::string("missing an input file with required entry '")
+ std::string(s) + std::string("'"));
if (not x)
throw std::runtime_error(std::string("file '") + std::string(infile)
+ std::string("' is missing required entry '")
+ std::string(s) + std::string("'"));
return x.value();
}

//! sets the step-method but issues a warning if a method is already provided
void force_step_method(time_advance::method method)
{
if (step_method)
std::cerr << "warning: overriding the user-requested -step-method" << std::endl;
step_method = method;
}
//! sets the step-method but issues a warning if a method is already provided
void force_solver(solve_opts method)
{
if (solver)
std::cerr << "warning: overriding the user-requested -solver" << std::endl;
solver = method;
}

private:
//! mapping from cli options to variables and actions
enum class optentry
Expand Down
23 changes: 23 additions & 0 deletions src/asgard_program_options_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ TEST_CASE("new program options", "[single options]")
REQUIRE(*prog.step_method == time_advance::method::imp);
REQUIRE(prog_opts(vecstrview({"", "-s", "imex"})).step_method.value()
== time_advance::method::imex);

prog = prog_opts(vecstrview({"", "-s", "impl"}));
std::cerr << "generating a warning about -step-method, ignore since it is part of the test\n";
prog.force_step_method(time_advance::method::imex);
REQUIRE(prog.step_method);
REQUIRE(*prog.step_method == time_advance::method::imex);
}
SECTION("-adapt-norm")
{
Expand Down Expand Up @@ -184,6 +190,12 @@ TEST_CASE("new program options", "[single options]")
REQUIRE(prog_opts(vecstrview({"exe", "-solver", "bicgstab"})).solver.value() == solve_opts::bicgstab);
REQUIRE_THROWS_WITH(prog_opts(vecstrview({"exe", "-solver", "dummy"})),
"invalid value for -solver, see exe -help");

prog = prog_opts(vecstrview({"", "-dt", "0.1"}));
REQUIRE_FALSE(prog.solver);
prog.force_solver(solve_opts::gmres);
REQUIRE(prog.solver);
REQUIRE(*prog.solver == solve_opts::gmres);
}
SECTION("-memory")
{
Expand Down Expand Up @@ -280,6 +292,11 @@ TEST_CASE("new program options", "[single options]")
"-of must be followed by a value, see exe -help");
REQUIRE(prog_opts(vecstrview({"exe", "-outfile", "dummy", "-of", ""})).subtitle.empty());
}
SECTION("file_required")
{
REQUIRE_THROWS_WITH(prog_opts(vecstrview({"exe", "-ist", "0.1"})).file_required<int>("none"),
"missing an input file with required entry 'none'");
}
}

TEST_CASE("input file processing", "[file i/o]")
Expand All @@ -306,6 +323,12 @@ TEST_CASE("input file processing", "[file i/o]")
REQUIRE(iint);
REQUIRE(iint.value() == 8);

REQUIRE(prog.file_required<bool>("bb1"));
REQUIRE(prog.file_required<int>("some_int") == 8);

REQUIRE_THROWS_WITH(prog.file_required<std::string>("none"),
"file 'test_input1.txt' is missing required entry 'none'");

prog_opts prog2(vecstrview({"", "-infile", "test_input1.txt", "-l", "3"}));
REQUIRE_FALSE(prog2.start_levels.empty());
REQUIRE(prog2.start_levels[0] == 3);
Expand Down
36 changes: 21 additions & 15 deletions src/asgard_time_advance_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,31 +130,37 @@ TEST_CASE("adaptive time advance")

SECTION("diffusion 2 implicit")
{
auto const tol_factor = get_tolerance<default_precision>(1000);
// the condition number for the difusion PDE is large, use double-precision only
if (std::is_same_v<default_precision, double>)
{
auto const tol_factor = get_tolerance<default_precision>(1000);

auto const gold_base =
time_advance_base_dir / "diffusion2_ad_implicit_sg_l3_d4_t";
auto const gold_base =
time_advance_base_dir / "diffusion2_ad_implicit_sg_l3_d4_t";

auto opts = make_opts("-p diffusion_2 -d 3 -l 3 -n 5 -s impl -a 0.05");
auto opts = make_opts("-p diffusion_2 -d 3 -l 3 -n 5 -s impl -a 0.05 -sv direct");

// temporarily disable test for MPI due to table elements < num ranks
if (get_num_ranks() == 1)
{
time_advance_test(opts, gold_base, tol_factor);
// temporarily disable test for MPI due to table elements < num ranks
if (get_num_ranks() == 1)
time_advance_test(opts, gold_base, tol_factor);
}
else
REQUIRE(true);
}
SECTION("diffusion 2 explicit")
{
auto const tol_factor = get_tolerance<default_precision>(1000);
// the condition number for the difusion PDE is large, use double-precision only
if (std::is_same_v<default_precision, double>)
{
auto const tol_factor = get_tolerance<default_precision>(1000);

auto const gold_base = time_advance_base_dir / "diffusion2_ad_sg_l3_d4_t";
auto const gold_base = time_advance_base_dir / "diffusion2_ad_sg_l3_d4_t";

auto opts = make_opts("-p diffusion_2 -d 3 -l 3 -n 5 -s expl -a 0.05");
auto opts = make_opts("-p diffusion_2 -d 3 -l 3 -n 5 -s expl -a 0.05");

// temporarily disable test for MPI due to table elements < num ranks
if (get_num_ranks() == 1)
{
time_advance_test(opts, gold_base, tol_factor);
// temporarily disable test for MPI due to table elements < num ranks
if (get_num_ranks() == 1)
time_advance_test(opts, gold_base, tol_factor);
}
}

Expand Down

0 comments on commit 3de89dc

Please sign in to comment.