/* * Multigrid solver for a 2nd order 2D linear PDE. * Copyright 2018 Anton Khirnov * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MG2D_H #define MG2D_H #include #include #include "mg2d_boundary.h" #include "mg2d_constants.h" typedef struct MG2DInternal MG2DInternal; typedef struct MG2DContext { /** * Solver private data, not to be accessed in any way by the caller. */ MG2DInternal *priv; /** * A callback that will be used to print diagnostic messages. * * The default implementation prints to stderr. * * May be set to NULL to disable logging. */ void (*log_callback)(const struct MG2DContext *ctx, int level, const char *fmt, va_list); /** * Arbitrary user data, e.g. to be used by the log callback. */ void *opaque; /** * Number of grid points in each direction, set by mg2d_solver_alloc(). * Read-only for the caller. */ size_t domain_size; /** * Distance between the neighbouring grid points. * Must be set by the caller. */ double step[2]; /** * Order of the finite difference operators used for approximating derivatives. * Must be set by the caller. */ size_t fd_stencil; /** * Boundary specification, indexed by MG2DBoundaryLoc. * To be filled by the caller. */ MG2DBoundary *boundaries[4]; /** * Maximum number of solver iterations. */ unsigned int maxiter; /** * Value of the residual at which to consider the equation solved. */ double tol; /** * Number of cycles on each subgrid. */ unsigned int nb_cycles; /** * Number of relaxation steps before and after each coarser-grid solve. */ unsigned int nb_relax_pre; unsigned int nb_relax_post; /** * Values of the unknown function. * * Allocated and initialized to zero by the solver in mg2d_solver_alloc(), * owned by the solver. * May be filled by the caller before solving to set the initial guess. * Afterwards updated in mg2d_solve(). */ double *u; /** * Distance between neighbouring gridpoints along coord1. */ ptrdiff_t u_stride; /** * Values of the right-hand side. * * Allocated by the solver in mg2d_solver_alloc(), owned by the solver. * Must be filled by the caller before solving. */ double *rhs; /** * Distance between neighbouring gridpoints along coord1. */ ptrdiff_t rhs_stride; /** * Coefficients C_{*} that define the differential equation. * * Allocated by the solver in mg2d_solver_alloc(), owned by the solver. * Must be filled by the caller before solving. */ double *diff_coeffs[MG2D_DIFF_COEFF_NB]; /** * Distance between neighbouring gridpoints along coord1. */ ptrdiff_t diff_coeffs_stride; /** * Number of threads to use for processing. * * Set to 0 to autodetect. Defaults to 1. */ unsigned int nb_threads; /** * Time-stepping factor to use for relaxation. */ double cfl_factor; /** * Maximum level of messages printed by the default logging callback. Has no * 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; /** * Allocate the solver for the given domain size. * * @return The solver context on success, NULL on failure. */ MG2DContext *mg2d_solver_alloc(size_t domain_size); /** * Solve the equation, after all the required fields have been filled by the * caller. * * This function may be called more than once. * * @return 0 on success, a negative error code on failure. */ int mg2d_solve(MG2DContext *ctx); /** * Free the solver and write NULL to the provided pointer. */ void mg2d_solver_free(MG2DContext **ctx); /** * Print the solver timing statistics using the logging callback. * * @param prefix the string prepended to each output line, may be NULL to mean * none */ void mg2d_print_stats(MG2DContext *ctx, const char *prefix); /** * @return maximum supported value of fd_stencil. */ unsigned int mg2d_max_fd_stencil(void); int mg2d_init_guess(MG2DContext *ctx, const double *src, ptrdiff_t src_stride, const size_t src_size[2], const double src_step[2]); #endif /* MG2D_H */