summaryrefslogtreecommitdiff
path: root/src/pssolve.h
blob: e6a4c1a2ada377b4b5a898474c3f62dfd50e2e9e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
 * Pseudospectral 2nd order 2D linear PDE solver
 * Copyright (C) 2016 Anton Khirnov <anton@khirnov.net>
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

#ifndef MD_PSSOLVE_H
#define MD_PSSOLVE_H

#include "common.h"

#if HAVE_OPENCL
#include <cl.h>
#else
typedef void* cl_context;
typedef void* cl_command_queue;
#endif

#include <stdint.h>

#include "basis.h"
#include "threadpool.h"

enum PSSolveDiffOrder {
    PSSOLVE_DIFF_ORDER_00,
    PSSOLVE_DIFF_ORDER_10,
    PSSOLVE_DIFF_ORDER_01,
    PSSOLVE_DIFF_ORDER_11,
    PSSOLVE_DIFF_ORDER_20,
    PSSOLVE_DIFF_ORDER_02,
    PSSOLVE_DIFF_ORDER_NB,
};

typedef struct PSSolvePriv PSSolvePriv;

typedef struct PSSolveContext {
    /**
     * Solver private data, not to be touched by the caller.
     */
    PSSolvePriv *priv;

    /**
     * Number of equations/unknown functions in the set.
     * Set by md_pssolve_context_alloc().
     */
    unsigned int nb_equations;

    /**
     * The basis sets.
     *
     * basis[i][j] is the basis set used for i-th variable in j-th direction.
     *
     * The array is allocated by md_pssolve_context_alloc(), must be filled by
     * by the caller before md_pssolve_context_init().
     */
    const MDBasisSetContext *(*basis)[2];

    /**
     * Order of the solver.
     *
     * solve_order[i][j] is the order of the solver (i.e. the number of the
     * basis functions used) for i-th variable in j-th direction.
     *
     * Allocated by md_pssolve_context_alloc(), must be filled by the caller
     * before md_pssolve_context_init().
     */
    unsigned int (*solve_order)[2];

    /**
     * Locations of the collocation points. The equation coefficients passed to
     * md_pssolve_solve() should be evaluated at those grid positions.
     *
     * colloc_grid[i][j] is an array of length solve_order[i][j] and contains
     * the collocation points for the i-th variable in the j-th direction.
     *
     * Set by the solver after md_pssolve_context_init().
     */
    double *(*colloc_grid)[2];

    /**
     * The thread pool used for multithreaded execution. May be set by the
     * caller before md_pssolve_context_init(), otherwise a single thread will
     * be used.
     */
    ThreadPoolContext *tp;

    cl_context       ocl_ctx;
    cl_command_queue ocl_queue;

    uint64_t lu_solves_count;
    uint64_t lu_solves_time;

    uint64_t cg_solve_count;
    uint64_t cg_iter_count;
    uint64_t cg_time_total;

    uint64_t construct_matrix_count;
    uint64_t construct_matrix_time;
} PSSolveContext;

/**
 * Allocate a new solver.
 */
int md_pssolve_context_alloc(PSSolveContext **ctx, unsigned int nb_equations);

/**
 * Initialize the solver for use after all the context options have been set.
 */
int md_pssolve_context_init(PSSolveContext *ctx);

/**
 * Free the solver and all its internal state.
 */
void md_pssolve_context_free(PSSolveContext **ctx);

/**
 * Solve a second order linear PDE in 2D with a pseudospectral method.
 *
 * @param eq_coeffs the equation coefficients.
 * @param rhs the right-hand side of the equation at the collocation points.
 * @param coeffs the spectral coefficients of the solution will be written here.
 */
int md_pssolve_solve(PSSolveContext *ctx,
                     const double *(**eq_coeffs)[PSSOLVE_DIFF_ORDER_NB],
                     const double *rhs, double *coeffs);

#endif /* MD_PSSOLVE_H */