aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README4
-rw-r--r--param.ccl18
-rw-r--r--src/driver/Newton.cc27
-rw-r--r--src/driver/driver.hh11
-rw-r--r--src/driver/find_horizons.cc54
-rw-r--r--src/driver/initial_guess.cc6
-rw-r--r--src/driver/io.cc15
-rw-r--r--src/driver/setup.cc33
-rw-r--r--src/make.configuration.defn5
9 files changed, 108 insertions, 65 deletions
diff --git a/README b/README
index 31720d3..a08658f 100644
--- a/README
+++ b/README
@@ -96,8 +96,8 @@ g2c:
Note that all of these settings are of shell environment variables,
using the syntax (eg)
- $ export LAPACK_DIR=/usr/bin # bash
- % setenv LAPACK_DIR /usr/bin # csh,tcsh
+ % export LAPACK_DIR=/usr/lib # bash
+ % setenv LAPACK_DIR /usr/lib # csh,tcsh
Alas, setting these in your ~/.cactus/config file doesn't work. :(
diff --git a/param.ccl b/param.ccl
index 9a00a45..befc0b3 100644
--- a/param.ccl
+++ b/param.ccl
@@ -214,9 +214,11 @@ boolean output_initial_guess \
{
} "false"
-# if this is used, the file names are the usual ones with ".it%d" appended
-boolean output_h_and_H_at_each_Newton_iteration \
- "should we output h and H at each Newton iteration (for debugging)?"
+# for debugging failure to converge, we can optionally output
+# h, H, and delta_h at each Newton iteration
+# (the file names are the usual ones with ".it%d" appended)
+boolean debugging_output_at_each_Newton_iteration \
+ "should we output {h, H, delta_h} at each Newton iteration?"
{
} "false"
@@ -264,14 +266,20 @@ string HDF5_file_name_extension "extension for HDF5 data files"
string h_base_file_name \
"base file name for horizon shape h input/output file(s)"
{
-.* :: "any string"
+.+ :: "any nonempty string"
} "h.dat"
string H_of_h_base_file_name "base file name for H(h) output file(s)"
{
-.* :: "any string"
+.+ :: "any nonempty string"
} "H.dat"
+string Delta_h_base_file_name \
+ "base file name for horizon-shape-update Delta_h output file(s)"
+{
+.+ :: "any nonempty string"
+} "Delta_h.dat"
+
string Jacobian_base_file_name "base file name for Jacobian output file(s)"
{
.+ :: "any valid file name"
diff --git a/src/driver/Newton.cc b/src/driver/Newton.cc
index aa31876..f3efb56 100644
--- a/src/driver/Newton.cc
+++ b/src/driver/Newton.cc
@@ -44,6 +44,12 @@ using jtutil::error_exit;
// This function solves H(h) = 0 for h via Newton's method.
//
// Arguments:
+// initial_find_flag = true ==> This is the first attempt to find this
+// horizon, or this is a subsequent attempt
+// and the immediately previous attempt failed.
+// false ==> This isn't the first attempt to find this
+// horizon, and we found it successfully on
+// the immediately previous attempt.
// hn = the horizon number (used only in naming output files)
//
// Results:
@@ -57,18 +63,23 @@ bool Newton_solve(patch_system& ps,
const struct geometry_info& gi,
const struct Jacobian_info& Jacobian_info,
const struct solver_info& solver_info,
+ bool initial_find_flag,
struct IO_info& IO_info,
int hn, const struct verbose_info& verbose_info)
{
+const int max_Newton_iterations
+ = initial_find_flag ? solver_info.max_Newton_iterations__initial
+ : solver_info.max_Newton_iterations__subsequent;
for (int iteration = 1 ;
- iteration <= solver_info.max_Newton_iterations ;
+ iteration <= max_Newton_iterations ;
++iteration)
{
if (verbose_info.print_algorithm_details)
then CCTK_VInfo(CCTK_THORNSTRING,
- "Newton iteration %d", iteration);
+ "Newton iteration %d of %d",
+ iteration, max_Newton_iterations);
- if (IO_info.output_h_and_H_at_each_Newton_iteration)
+ if (solver_info.debugging_output_at_each_Newton_iteration)
then output_gridfn(ps, gfns::gfn__h,
IO_info, IO_info.h_base_file_name,
hn, verbose_info.print_algorithm_details,
@@ -87,7 +98,7 @@ bool Newton_solve(patch_system& ps,
iteration,
H_norms.rms_norm(), H_norms.infinity_norm());
- if (IO_info.output_h_and_H_at_each_Newton_iteration)
+ if (solver_info.debugging_output_at_each_Newton_iteration)
then output_gridfn(ps, gfns::gfn__H,
IO_info, IO_info.H_base_file_name,
hn, verbose_info.print_algorithm_details,
@@ -129,6 +140,12 @@ bool Newton_solve(patch_system& ps,
"done solving linear system");
}
+ if (solver_info.debugging_output_at_each_Newton_iteration)
+ then output_gridfn(ps, gfns::gfn__Delta_h,
+ IO_info, IO_info.Delta_h_base_file_name,
+ hn, verbose_info.print_algorithm_details,
+ iteration);
+
// if the Newton step is too large, scale it down
jtutil::norm<fp> h_norms;
ps.ghosted_gridfn_norms(gfns::gfn__h, h_norms);
@@ -199,7 +216,7 @@ bool Newton_solve(patch_system& ps,
CCTK_VWarn(1, __LINE__, __FILE__, CCTK_THORNSTRING,
"Newton_solve: no convergence in %d iterations!",
- solver_info.max_Newton_iterations);
+ max_Newton_iterations);
if (solver_info.final_H_update_if_exit_x_H_small)
then {
if (verbose_info.print_algorithm_details)
diff --git a/src/driver/driver.hh b/src/driver/driver.hh
index 84134da..d5f9ea7 100644
--- a/src/driver/driver.hh
+++ b/src/driver/driver.hh
@@ -91,7 +91,11 @@ struct initial_guess_info
//
struct solver_info
{
- int max_Newton_iterations;
+ bool output_initial_guess;
+ bool output_h, output_H;
+ bool debugging_output_at_each_Newton_iteration;
+ int max_Newton_iterations__initial,
+ max_Newton_iterations__subsequent;
fp max_Delta_h_over_h;
fp H_norm_for_convergence;
fp Delta_h_norm_for_convergence;
@@ -103,15 +107,13 @@ struct solver_info
//
struct IO_info
{
- bool output_initial_guess;
- bool output_h_and_H_at_each_Newton_iteration;
- bool output_h, output_H;
enum file_format file_format;
bool output_ghost_zones_for_h;
const char* ASCII_file_name_extension;
const char* HDF5_file_name_extension;
const char* h_base_file_name;
const char* H_base_file_name;
+ const char* Delta_h_base_file_name;
const char* Jacobian_base_file_name;
// this is used to choose file names
@@ -212,6 +214,7 @@ bool Newton_solve(patch_system& ps,
const struct geometry_info& gi,
const struct Jacobian_info& Jacobian_info,
const struct solver_info& solver_info,
+ bool initial_find_flag,
struct IO_info& IO_info,
int hn, const struct verbose_info& verbose_info);
diff --git a/src/driver/find_horizons.cc b/src/driver/find_horizons.cc
index 7df1fb3..7d38b34 100644
--- a/src/driver/find_horizons.cc
+++ b/src/driver/find_horizons.cc
@@ -61,7 +61,7 @@ bool find_horizon(enum method method,
const struct verbose_info& verbose_info, int timer_handle,
struct IO_info& IO_info,
struct Jacobian_info& Jac_info,
- struct solver_info& solver_info,
+ const struct solver_info& solver_info, bool initial_find_flag,
struct cactus_grid_info& cgi, struct geometry_info& gi,
patch_system& ps, Jacobian* Jac_ptr,
int hn, int N_horizons);
@@ -83,7 +83,10 @@ extern "C"
{
DECLARE_CCTK_ARGUMENTS
DECLARE_CCTK_PARAMETERS
+
const struct verbose_info& verbose_info = state.verbose_info;
+ struct IO_info& IO_info = state.IO_info;
+const struct solver_info& solver_info = state.solver_info;
if (state.timer_handle >= 0)
then CCTK_TimerResetI(state.timer_handle);
@@ -105,24 +108,13 @@ if (state.cgi.Cactus_conformal_metric)
then state.cgi.psi_data = Cactus_gridfn_data_ptr(cctkGH,
"StaticConformal::psi");
-state.IO_info.time_iteration = cctk_iteration;
+IO_info.time_iteration = cctk_iteration;
for (int hn = 1 ; hn <= state.N_horizons ; ++hn)
{
struct AH_info& AH_info = * state.AH_info_ptrs[hn];
patch_system& ps = *AH_info.ps_ptr;
//
- // The first time we (try to) find a given horizon, our initial
- // guess is likely to be rather inaccurate, so we may need a
- // larger number of iterations. But if we've found this horizon
- // before, then we have its previous position as an initial guess,
- // so we shouldn't need as many iterations.
- //
- state.solver_info.max_Newton_iterations
- = AH_info.AH_found ? max_Newton_iterations__subsequent
- : max_Newton_iterations__initial;
-
- //
// If this is our first attempt to find this horizon, or
// if we've tried to find it before but we failed on our
// immediately previous attempt, then we need to (re)set
@@ -132,16 +124,25 @@ state.IO_info.time_iteration = cctk_iteration;
// then we can just reuse the previous horizon position as
// our initial guess for this time around.
//
- if (! AH_info.AH_found)
- then setup_initial_guess(ps,
+ const bool initial_find_flag = ! AH_info.AH_found;
+ if (initial_find_flag)
+ then {
+ setup_initial_guess(ps,
AH_info.initial_guess_info,
- state.IO_info,
+ IO_info,
hn, verbose_info);
+ if (solver_info.output_initial_guess)
+ then output_gridfn(ps, gfns::gfn__h,
+ IO_info, IO_info.h_base_file_name,
+ hn, verbose_info
+ .print_algorithm_highlights);
+ }
AH_info.AH_found
= find_horizon(state.method,
verbose_info, state.timer_handle,
- state.IO_info, state.Jac_info, state.solver_info,
+ IO_info, state.Jac_info,
+ solver_info, initial_find_flag,
state.cgi, state.gi,
ps, AH_info.Jac_ptr,
hn, state.N_horizons);
@@ -184,6 +185,12 @@ if (state.timer_handle >= 0)
// timer_handle = a valid Cactus timer handle if we want to time the
// apparent horizon process, or -ve to skip this
// (we only time the computation, not the file I/O)
+// initial_find_flag = true ==> This is the first attempt to find this
+// horizon, or this is a subsequent attempt
+// and the immediately previous attempt failed.
+// false ==> This isn't the first attempt to find this
+// horizon, and we found it successfully on
+// the immediately previous attempt.
// Jac_ptr = may be NULL if no Jacobian is needed (depending on method)
// hn = the horizon number (used only in naming output files)
// N_horizons = the total number of horizon(s) being searched for number
@@ -201,7 +208,7 @@ bool find_horizon(enum method method,
const struct verbose_info& verbose_info, int timer_handle,
struct IO_info& IO_info,
struct Jacobian_info& Jac_info,
- struct solver_info& solver_info,
+ const struct solver_info& solver_info, bool initial_find_flag,
struct cactus_grid_info& cgi, struct geometry_info& gi,
patch_system& ps, Jacobian* Jac_ptr,
int hn, int N_horizons)
@@ -226,7 +233,7 @@ case method__horizon_function:
then CCTK_VInfo(CCTK_THORNSTRING,
" H(h) rms-norm %.2e, infinity-norm %.2e",
H_norms.rms_norm(), H_norms.infinity_norm());
- if (IO_info.output_H)
+ if (solver_info.output_H)
then output_gridfn(ps, gfns::gfn__H,
IO_info, IO_info.H_base_file_name,
hn, true);
@@ -297,18 +304,19 @@ case method__Newton_solve:
const bool status
= Newton_solve(ps, Jac,
cgi, gi,
- Jac_info, solver_info, IO_info,
- hn, verbose_info);
+ Jac_info,
+ solver_info, initial_find_flag,
+ IO_info, hn, verbose_info);
if (timer_handle >= 0)
then CCTK_TimerStopI(timer_handle);
if (! status)
then return false; // *** ERROR RETURN ***
- if (IO_info.output_h)
+ if (solver_info.output_h)
then output_gridfn(ps, gfns::gfn__h,
IO_info, IO_info.h_base_file_name,
hn, verbose_info.print_algorithm_details);
- if (IO_info.output_H)
+ if (solver_info.output_H)
then output_gridfn(ps, gfns::gfn__H,
IO_info, IO_info.H_base_file_name,
hn, verbose_info.print_algorithm_details);
diff --git a/src/driver/initial_guess.cc b/src/driver/initial_guess.cc
index 73de3e6..0c11742 100644
--- a/src/driver/initial_guess.cc
+++ b/src/driver/initial_guess.cc
@@ -134,12 +134,6 @@ default:
"unknown initial guess method=(int)%d!",
int(igi.method)); /*NOTREACHED*/
}
-
-// write initial guess back to the data file?
-if (IO_info.output_initial_guess)
- then output_gridfn(ps, gfns::gfn__h,
- IO_info, IO_info.h_base_file_name,
- hn, verbose_info.print_algorithm_highlights);
}
//******************************************************************************
diff --git a/src/driver/io.cc b/src/driver/io.cc
index 9a9e01d..af7d5f9 100644
--- a/src/driver/io.cc
+++ b/src/driver/io.cc
@@ -139,15 +139,20 @@ case file_format__ASCII:
if (print_msg_flag)
then CCTK_VInfo(CCTK_THORNSTRING,
" writing H to \"%s\"", file_name);
- ps.print_gridfn(unknown_gfn,
- file_name);
+ ps.print_gridfn(unknown_gfn, file_name);
+ break;
+ case gfns::gfn__Delta_h:
+ if (print_msg_flag)
+ then CCTK_VInfo(CCTK_THORNSTRING,
+ " writing Delta_h to \"%s\"", file_name);
+ ps.print_gridfn(unknown_gfn, file_name);
break;
default:
if (print_msg_flag)
then CCTK_VInfo(CCTK_THORNSTRING,
- " writing \"%s\"", file_name);
- ps.print_gridfn(unknown_gfn,
- file_name);
+ " writing gfn=%d to \"%s\"",
+ unknown_gfn, file_name);
+ ps.print_gridfn(unknown_gfn, file_name);
break;
}
break;
diff --git a/src/driver/setup.cc b/src/driver/setup.cc
index daf3963..f3e859d 100644
--- a/src/driver/setup.cc
+++ b/src/driver/setup.cc
@@ -98,35 +98,32 @@ CCTK_VInfo(CCTK_THORNSTRING,
//
state.method = decode_method(method);
-state.verbose_info.verbose_level = decode_verbose_level(verbose_level);
-state.verbose_info.print_physics_highlights
+
+struct verbose_info& verbose_info = state.verbose_info;
+verbose_info.verbose_level = decode_verbose_level(verbose_level);
+verbose_info.print_physics_highlights
= (state.verbose_info.verbose_level >= verbose_level__physics_highlights);
-state.verbose_info.print_physics_details
+verbose_info.print_physics_details
= (state.verbose_info.verbose_level >= verbose_level__physics_details);
-state.verbose_info.print_algorithm_highlights
+verbose_info.print_algorithm_highlights
= (state.verbose_info.verbose_level >= verbose_level__algorithm_highlights);
-state.verbose_info.print_algorithm_details
+verbose_info.print_algorithm_details
= (state.verbose_info.verbose_level >= verbose_level__algorithm_details);
+
state.timer_handle = (print_timing_stats != 0)
? CCTK_TimerCreateI()
: -1;
state.surface_integral_method
= patch::decode_integration_method(surface_integral_method);
-const struct verbose_info& verbose_info = state.verbose_info;
-
struct IO_info& IO_info = state.IO_info;
-IO_info.output_initial_guess = (output_initial_guess != 0);
-IO_info.output_h_and_H_at_each_Newton_iteration
- = (output_h_and_H_at_each_Newton_iteration != 0);
-IO_info.output_h = (output_h != 0);
-IO_info.output_H = (output_H_of_h != 0);
IO_info.file_format = decode_file_format(file_format);
IO_info.output_ghost_zones_for_h = (output_ghost_zones_for_h != 0);
IO_info.ASCII_file_name_extension = ASCII_file_name_extension;
IO_info.HDF5_file_name_extension = HDF5_file_name_extension;
IO_info.h_base_file_name = h_base_file_name;
IO_info.H_base_file_name = H_of_h_base_file_name;
+IO_info.Delta_h_base_file_name = Delta_h_base_file_name;
IO_info.Jacobian_base_file_name = Jacobian_base_file_name;
IO_info.time_iteration = 0;
@@ -137,9 +134,15 @@ Jac_info.Jacobian_storage_method
Jac_info.perturbation_amplitude = Jacobian_perturbation_amplitude;
struct solver_info& solver_info = state.solver_info;
-solver_info.max_Newton_iterations = 0; // dummy value; actual value
- // will be filled in by
- // AHFinderDirect_find_horizons()
+solver_info.output_initial_guess = (output_initial_guess != 0);
+solver_info.output_h = (output_h != 0);
+solver_info.output_H = (output_H_of_h != 0);
+solver_info.debugging_output_at_each_Newton_iteration
+ = (debugging_output_at_each_Newton_iteration != 0);
+solver_info.max_Newton_iterations__initial
+ = max_Newton_iterations__initial;
+solver_info.max_Newton_iterations__subsequent
+ = max_Newton_iterations__subsequent;
solver_info.max_Delta_h_over_h = max_Delta_h_over_h;
solver_info.H_norm_for_convergence = H_norm_for_convergence;
solver_info.Delta_h_norm_for_convergence = Delta_h_norm_for_convergence;
diff --git a/src/make.configuration.defn b/src/make.configuration.defn
index 932a37a..f5ab6fb 100644
--- a/src/make.configuration.defn
+++ b/src/make.configuration.defn
@@ -27,6 +27,11 @@ MissingLAPACK_DIR:
@echo '*** LAPACK_EXTRA_LIBS = g2c'
@echo '*** LAPACK_EXTRA_LIBDIRS = `g77 --print-file-name=libg2c.a | xargs dirname`'
@echo '***'
+ @echo '*** Note that all of these settings are shell environment variables, e.g.,'
+ @echo '*** % export LAPACK_DIR=/usr/lib # bash'
+ @echo '*** % setenv LAPACK_DIR /usr/lib # csh, tcsh'
+ @echo '*** Alas, setting these in your ~/.cactus/config file doesn'\''t work. :('
+ @echo '***'
exit 2
endif