summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2019-03-11 09:58:15 +0100
committerAnton Khirnov <anton@khirnov.net>2019-03-11 09:58:15 +0100
commit8a139859d22012436be404388fd611fb6126bc7f (patch)
tree6b3bafc9bf6244b70efe6e005239abe2a546ac2d
parent12f4d2fb11aaab5b1dbe2606ff09bc1bb7410cc0 (diff)
mg2d: make the refinement depth/exact solve size configurable
API bump
-rw-r--r--libmg2d.v2
-rw-r--r--mg2d.c27
-rw-r--r--mg2d.h12
3 files changed, 30 insertions, 11 deletions
diff --git a/libmg2d.v b/libmg2d.v
index c01a69f..3e4fb25 100644
--- a/libmg2d.v
+++ b/libmg2d.v
@@ -1,4 +1,4 @@
-LIBMG2D_10 {
+LIBMG2D_11 {
global: mg2d_*;
local: *;
};
diff --git a/mg2d.c b/mg2d.c
index 8c9a15b..a6c6f5d 100644
--- a/mg2d.c
+++ b/mg2d.c
@@ -34,8 +34,6 @@
#include "mg2d_boundary_internal.h"
#include "mg2d_constants.h"
-#define LEVELS_MAX 16
-
typedef struct MG2DLevel {
unsigned int depth;
@@ -523,21 +521,32 @@ static int threadpool_init(MG2DContext *ctx)
return 0;
}
+static int mg_levels_alloc(MG2DContext *ctx, size_t domain_size);
+
int mg2d_solve(MG2DContext *ctx)
{
MG2DInternal *priv = ctx->priv;
- MG2DLevel *root = priv->root;
- EGSContext *s_root = root->solver;
+ MG2DLevel *root;
+ EGSContext *s_root;
int64_t time_start;
double res_orig, res_prev, res_cur;
int ret;
+ if (!priv->root) {
+ ret = mg_levels_alloc(ctx, ctx->domain_size);
+ if (ret < 0)
+ return ret;
+ }
+
if (!priv->tp) {
ret = threadpool_init(ctx);
if (ret < 0)
return ret;
}
+ root = priv->root;
+ s_root = root->solver;
+
time_start = gettime();
ret = mg_levels_init(ctx);
@@ -648,7 +657,7 @@ static int mg_levels_alloc(MG2DContext *ctx, size_t domain_size)
dst = &priv->root;
next_size = domain_size;
- for (int depth = 0; depth < LEVELS_MAX; depth++) {
+ for (int depth = 0; depth < ctx->max_levels; depth++) {
enum EGSType cur_type;
size_t cur_size = next_size;
@@ -662,7 +671,7 @@ static int mg_levels_alloc(MG2DContext *ctx, size_t domain_size)
} else
next_size = (cur_size >> 1) + 1;
- cur_type = (depth == LEVELS_MAX - 1 || cur_size < 9) ? EGS_SOLVER_EXACT : EGS_SOLVER_RELAXATION;
+ cur_type = (cur_size <= ctx->max_exact_size) ? EGS_SOLVER_EXACT : EGS_SOLVER_RELAXATION;
*dst = mg_level_alloc(cur_type, cur_size);
if (!*dst)
@@ -735,12 +744,10 @@ MG2DContext *mg2d_solver_alloc(size_t domain_size)
}
ctx->diff_coeffs_stride = domain_size;
- ret = mg_levels_alloc(ctx, domain_size);
- if (ret < 0)
- goto fail;
-
ctx->domain_size = domain_size;
+ ctx->max_levels = 16;
+ ctx->max_exact_size = 5;
ctx->maxiter = 16;
ctx->tol = 1e-12;
ctx->nb_cycles = 1;
diff --git a/mg2d.h b/mg2d.h
index 234d8cf..6452526 100644
--- a/mg2d.h
+++ b/mg2d.h
@@ -148,6 +148,18 @@ typedef struct MG2DContext {
* effect when log_callback is overridden.
*/
enum MG2DLogLevel log_level;
+
+ /**
+ * Maximum number of refinement levels. May only be modified by the caller
+ * before the first call to mg2d_solve().
+ */
+ unsigned int max_levels;
+
+ /**
+ * Maximum size (along one dimensions) of a refinement level on which an
+ * exact solve is performed.
+ */
+ size_t max_exact_size;
} MG2DContext;
/**