aboutsummaryrefslogtreecommitdiff
path: root/CarpetDev/CarpetMG/src/mg.cc
diff options
context:
space:
mode:
Diffstat (limited to 'CarpetDev/CarpetMG/src/mg.cc')
-rw-r--r--CarpetDev/CarpetMG/src/mg.cc205
1 files changed, 94 insertions, 111 deletions
diff --git a/CarpetDev/CarpetMG/src/mg.cc b/CarpetDev/CarpetMG/src/mg.cc
index ab1132758..aba03edd2 100644
--- a/CarpetDev/CarpetMG/src/mg.cc
+++ b/CarpetDev/CarpetMG/src/mg.cc
@@ -28,6 +28,7 @@ namespace CarpetMG {
struct options_t {
+
// Width of outer boundary
CCTK_INT bndwidth;
@@ -38,17 +39,19 @@ namespace CarpetMG {
// Coarsest level on which the full multigrid algorithm should start
CCTK_INT firstlevel;
- // Maximum number of direct solver iterations
- CCTK_INT maxiters;
+ // Direct solver
+ CCTK_INT maxiters; // Maximum number of iterations
+ CCTK_REAL sor_factor; // SOR factor
// Weight factors for the equations
CCTK_REAL factor;
vector<CCTK_REAL> factors;
- // Maximum number of multigrid iterations (per level) and smoothing steps
- CCTK_INT mgiters;
- CCTK_INT presteps;
- CCTK_INT poststeps;
+ // Multigrid iterations
+ CCTK_INT mgiters; // maximum number of iterations (per level)
+ CCTK_INT presteps; // number of presmoothing steps
+ CCTK_INT poststeps; // number of postsmoothing steps
+
};
@@ -111,7 +114,8 @@ namespace CarpetMG {
vector<CCTK_INT> const & wgt,
options_t const & options,
CCTK_REAL const old_error,
- CCTK_REAL & error);
+ CCTK_REAL & error,
+ bool const use_sor = false);
void
norm (cGH const * restrict const cctkGH,
@@ -338,19 +342,22 @@ namespace CarpetMG {
// Get symmetry information
{
- int icnt;
int const symtable = SymmetryTableHandleForGrid (cctkGH);
assert (symtable >= 0);
-
- icnt = (Util_TableGetIntArray
- (symtable, 6,
- options.symmetry_handle, "symmetry_handle"));
- assert (icnt == 6);
-
- icnt = (Util_TableGetIntArray
- (symtable, 6,
- options.symmetry_zone_width, "symmetry_zone_width"));
- assert (icnt == 6);
+ {
+ int const icnt
+ = (Util_TableGetIntArray
+ (symtable, 6,
+ options.symmetry_handle, "symmetry_handle"));
+ assert (icnt == 6);
+ }
+ {
+ int const icnt
+ = (Util_TableGetIntArray
+ (symtable, 6,
+ options.symmetry_zone_width, "symmetry_zone_width"));
+ assert (icnt == 6);
+ }
}
// Get full multigrid information
@@ -368,40 +375,49 @@ namespace CarpetMG {
= Util_TableGetInt (options_table, &options.maxiters, "maxiters");
assert (icnt == 1 or icnt == UTIL_ERROR_TABLE_NO_SUCH_KEY);
}
+ {
+ options.sor_factor = 1.0;
+ int const icnt
+ = Util_TableGetReal (options_table, &options.sor_factor, "sor_factor");
+ assert (icnt == 1 or icnt == UTIL_ERROR_TABLE_NO_SUCH_KEY);
+ }
// Get equation information
{
- int icnt;
-
options.factor = 0.5;
- icnt = Util_TableGetReal (options_table, &options.factor, "factor");
+ int const icnt
+ = Util_TableGetReal (options_table, &options.factor, "factor");
assert (icnt == 1 or icnt == UTIL_ERROR_TABLE_NO_SUCH_KEY);
-
+ }
+ {
options.factors.resize (var.size());
for (int n=0; n<options.factors.size(); ++n) {
options.factors.at(n) = 1.0;
}
- icnt = (Util_TableGetRealArray
- (options_table, options.factors.size(),
- &options.factors.front(), "factors"));
+ int const icnt = (Util_TableGetRealArray
+ (options_table, options.factors.size(),
+ &options.factors.front(), "factors"));
assert (icnt == options.factors.size()
or icnt == UTIL_ERROR_TABLE_NO_SUCH_KEY);
}
// Get multigrid information
{
- int icnt;
-
- options.mgiters = 100;
- icnt = Util_TableGetInt (options_table, &options.mgiters, "mgiters");
+ options.mgiters = 10;
+ int const icnt
+ = Util_TableGetInt (options_table, &options.mgiters, "mgiters");
assert (icnt == 1 or icnt == UTIL_ERROR_TABLE_NO_SUCH_KEY);
-
+ }
+ {
options.presteps = 2;
- icnt = Util_TableGetInt (options_table, &options.presteps, "presteps");
+ int const icnt
+ = Util_TableGetInt (options_table, &options.presteps, "presteps");
assert (icnt == 1 or icnt == UTIL_ERROR_TABLE_NO_SUCH_KEY);
-
+ }
+ {
options.poststeps = 2;
- icnt = Util_TableGetInt (options_table, &options.poststeps, "poststeps");
+ int const icnt
+ = Util_TableGetInt (options_table, &options.poststeps, "poststeps");
assert (icnt == 1 or icnt == UTIL_ERROR_TABLE_NO_SUCH_KEY);
}
@@ -471,34 +487,11 @@ namespace CarpetMG {
options_t const & options,
CCTK_REAL const minerror)
{
-#if 0
- DECLARE_CCTK_ARGUMENTS;
-#endif
DECLARE_CCTK_PARAMETERS;
// Solve on this and some coarser levels
assert (is_level_mode());
-#if 0
- // Calculate the domain size
- int minsize = INT_MAX;
- int size = 1;
- int maxsize = INT_MAX;
- for (d=0; d<dim; ++d) {
- int const gsize = cctk_gsh[d];
- assert (gsize >= 0);
- minsize = min (minsize, gsize);
-
- int const lsize = (cctk_lsh[d]
- - (cctk_bbox[2*d ] ? 0 : cctk_nghostzones[d])
- - (cctk_bbox[2*d+1] ? 0 : cctk_nghostzones[d]));
- assert (lsize >= 0);
- assert (lsize <= maxsize);
- size *= lsize;
- maxsize /= lsize;
- }
-#endif
-
// Solve directly when on the coarsest level
if (reflevel == 0) {
return direct_solve (cctkGH,
@@ -515,8 +508,8 @@ namespace CarpetMG {
if (verbose) {
CCTK_VInfo (CCTK_THORNSTRING,
- "%*s[%d] beginning multigrid solve",
- indwidth(), "", reflevel);
+ "%*s[%d] beginning multigrid solve, desired residual %g",
+ indwidth(), "", reflevel, double(minerror));
}
// Loop until converged
@@ -564,70 +557,40 @@ namespace CarpetMG {
// Restrict
- // solve L(u) = r
- // set f := L(u) - r
- //
- // given: f = L(u ) - r
- // wanted: 0 = L(u') - r
- // known: R(f) - f is small
- // assume: R(u'-u) is also small
- // define: fc = R(f)
- // uc = R(u)
- // fc = L(uc) - rc (defines rc)
- // solve: L(uc') = rc
- // use: R(u'-u) = uc'-uc (defines u')
- // yields: f' = L(u') - r
- // where f' is smaller than f
- //
- // uc <- R(u)
- // fc <- R(f)
- // rc <- fc
- // fc <- L(uc) - rc
- // rc <- fc
- // then solve L(uc) = rc
- //
- // the above is identical to:
- // uc <- R(u)
- // rc <- R(f)
- // rc <- L(uc) - rc
- // then solve L(uc) = rc
- //
- // now change the notation:
- // varc <- R(var)
- // resc-rhsc <- R(res-rhs)
- // rhsc <- resc-rhsc
- // resc-rhsc <- L(varc) - rhsc
- // rhsc <- resc-rhsc
- // then solve L(varc) = rhsc
- //
- // the above is identical to:
- // varc <- R(var)
- // rhsc <- R(res-rhs)
- // rhsc <- L(varc) - rhsc
- // then solve L(varc) = rhsc
-
residual (cctkGH, options_table, calcres, userdata);
norm (cctkGH, res, rhs, options, error);
subtract (cctkGH, res, rhs, options);
// TODO: restrict and fixup aux
- assert (aux.size() == 0);
+ assert (aux.empty());
int const coarse_reflevel = reflevel - 1;
BEGIN_GLOBAL_MODE (cctkGH) {
enter_level_mode (const_cast<cGH *>(cctkGH), coarse_reflevel);
try {
+ // Restrict variable
restrict_var (cctkGH, var, options);
boundary (cctkGH, options_table, applybnds, userdata);
copy (cctkGH, sav, var, options);
+
+ // Restrict residual
zero (cctkGH, res, options);
restrict_var (cctkGH, res, options);
copy (cctkGH, rhs, res, options);
residual (cctkGH, options_table, calcres, userdata);
subtract (cctkGH, rhs, res, options);
+ CCTK_REAL coarse_error;
+ norm (cctkGH, res, rhs, options, coarse_error);
+ if (veryverbose) {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "%*s[%d] iteration %d, initial coarse residual %g",
+ indwidth(), "", reflevel,
+ iter, double(coarse_error));
+ }
+
// Recurse
- CCTK_REAL const coarse_minerror = error / ipow(reflevelfact, dim);
+ CCTK_REAL const coarse_minerror = error / ipow(reffact, dim);
int const ierr
= multigrid (cctkGH,
var, res, rhs, sav, wgt, aux,
@@ -649,11 +612,29 @@ namespace CarpetMG {
leave_level_mode (const_cast<cGH *>(cctkGH));
} END_GLOBAL_MODE;
+#warning "TODO"
+ // save old solution
+ copy (cctkGH, sav, var, options);
+
zero (cctkGH, res, options);
prolongate_var (cctkGH, res, options);
add (cctkGH, var, res, options);
boundary (cctkGH, options_table, applybnds, userdata);
+ CCTK_REAL const old_error = error;
+
+ try {
+ residual (cctkGH, options_table, calcres, userdata);
+ } catch (char const *) {
+ assert (0);
+ }
+ norm (cctkGH, res, rhs, options, error);
+ if (error > old_error) {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Residual increased during recursion at level %d from %g to %g",
+ reflevel, double(old_error), double(error));
+ }
+
if (veryverbose) {
CCTK_VInfo (CCTK_THORNSTRING,
"%*s[%d] iteration %d, after recursion, residual %g",
@@ -733,8 +714,8 @@ namespace CarpetMG {
if (verbose) {
CCTK_VInfo (CCTK_THORNSTRING,
- "%*s[%d] beginning direct solve",
- indwidth(), "", reflevel);
+ "%*s[%d] beginning direct solve, desired residual %g",
+ indwidth(), "", reflevel, double(minerror));
}
assert (is_level_mode());
@@ -759,7 +740,7 @@ namespace CarpetMG {
residual (cctkGH, options_table, calcres, userdata);
CCTK_REAL const old_error = error;
- smooth (cctkGH, var, res, rhs, wgt, options, old_error, error);
+ smooth (cctkGH, var, res, rhs, wgt, options, old_error, error, true);
boundary (cctkGH, options_table, applybnds, userdata);
if (veryverbose) {
@@ -799,7 +780,8 @@ namespace CarpetMG {
vector<CCTK_INT> const & wgt,
options_t const & options,
CCTK_REAL const old_error,
- CCTK_REAL & error)
+ CCTK_REAL & error,
+ bool const use_sor)
{
DECLARE_CCTK_ARGUMENTS;
@@ -810,7 +792,7 @@ namespace CarpetMG {
// Calculate grid spacings
- CCTK_REAL dxinv2 = 0;
+ CCTK_REAL dxinv2 = 0.0;
CCTK_REAL dx[dim];
for (int d=0; d<dim; ++d) {
// TODO: correct this for solving on grid arrays instead of grid
@@ -845,10 +827,11 @@ namespace CarpetMG {
? (static_cast<CCTK_REAL const *>
(CCTK_VarDataPtrI (cctkGH, 0, wgt.at(n))))
: NULL);
- assert (wgt.size() == 0 or wgtptr);
+ assert (wgt.empty() or wgtptr);
CCTK_REAL const fac
- = options.factor * (wgtptr ? 1.0 : options.factors.at(n));
+ = ((use_sor ? options.sor_factor : options.factor)
+ * (wgtptr ? 1.0 : options.factors.at(n) * mdxinv2inv));
int imin[3], imax[3];
interior_shape (cctkGH, options, imin, imax);
@@ -859,9 +842,9 @@ namespace CarpetMG {
int const ind = CCTK_GFINDEX3D (cctkGH, i, j, k);
CCTK_REAL const diff = resptr[ind] - rhsptr[ind];
- CCTK_REAL const w = wgtptr ? 1.0 / wgtptr[ind] : mdxinv2inv;
+ CCTK_REAL const w = wgtptr ? fac / wgtptr[ind] : fac;
- varptr[ind] -= fac * w * diff;
+ varptr[ind] -= w * diff;
++ count;
error2 += pow(diff, 2);