diff options
author | Anton Khirnov <anton@khirnov.net> | 2019-03-11 09:58:15 +0100 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2019-03-11 09:58:15 +0100 |
commit | 8a139859d22012436be404388fd611fb6126bc7f (patch) | |
tree | 6b3bafc9bf6244b70efe6e005239abe2a546ac2d | |
parent | 12f4d2fb11aaab5b1dbe2606ff09bc1bb7410cc0 (diff) |
mg2d: make the refinement depth/exact solve size configurable
API bump
-rw-r--r-- | libmg2d.v | 2 | ||||
-rw-r--r-- | mg2d.c | 27 | ||||
-rw-r--r-- | mg2d.h | 12 |
3 files changed, 30 insertions, 11 deletions
@@ -1,4 +1,4 @@ -LIBMG2D_10 { +LIBMG2D_11 { global: mg2d_*; local: *; }; @@ -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; @@ -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; /** |