RECORD( lattice )
{
    long long ndof;
    const long long* map;
    int nx, ny, nz, degree;
};

RECORD( linear_operator )
{
    lattice nodes;
    long long uncut_count, cut_count, constrained_count;
    const long long *uncut, *cut, *constrained;
    const unsigned char* inside;
    const float* weights;
    const double* parameters;
    double volume[8], inverse_spacing[24], alpha;
    const long long* block_starts;
    const int* block_columns;
    const float* blocks;
};

RECORD( preconditioner )
{
    long long mode_cells;
    const long long *cells, *starts;
    const short* modes;
    const float *gamma, *inverse_diagonal, *block_inverse;
};

RECORD( transfer_map )
{
    lattice in, out;
    const int *starts[3], *columns[3];
    const float* values[3];
    const long long* node_starts;
    const int* node_columns;
    const float* node_values;
};

RECORD( level )
{
    linear_operator a;
    preconditioner b;
    const double* chebyshev;
    int steps;
    transfer_map restriction, prolongation;
    float *rhs, *solution, *defect, *product, *direction;
    void ( *apply )( const struct linear_operator* o, const float* b, float* x, float* y,
                     float scale, float keep, int* done, int blocks, int epoch, float* kept );
    void ( *precondition )( const struct linear_operator* o, const struct preconditioner* b,
                            const float* r, float factor, float keep, float* out, int* done,
                            int blocks, int epoch );
    const float* dense_inverse;
};

RECORD( levelset )
{
    const unsigned char *bits, *removed;
    const double* values;
    const short* correction;
    long long region[6], n[3];
    double kernel[4], spacing[3];
    int subdivisions;
};

RECORD( voxel_grid )
{
    const long long* bounds[3];
    int n[3], refinement;
};
