/*
 * Copyright (C) 2022 NHR@FAU, University Erlangen-Nuremberg.
 * All rights reserved. This file is part of nusif-solver.
 * Use of this source code is governed by a MIT style
 * license that can be found in the LICENSE file.
 */
#ifndef __SOLVER_H_
#define __SOLVER_H_
#include "parameter.h"
#include <mpi.h>

#define NDIMS 2

enum BC { NOSLIP = 1, SLIP, OUTFLOW, PERIODIC };

typedef struct {
    /* geometry and grid information */
    double dx, dy;
    int imax, jmax;
    double xlength, ylength;
    /* arrays */
    double *p, *rhs;
    double *f, *g;
    double *u, *v;
    /* parameters */
    double eps, omega, rho;
    double re, tau, gamma;
    double gx, gy;
    /* time stepping */
    int itermax;
    double dt, te;
    double dtBound;
    char* problem;
    int bcLeft, bcRight, bcBottom, bcTop;
    /* mpi */
    int rank;
    int size;
    MPI_Comm comm;
    MPI_Datatype bufferTypes[NDIMS * 2];
    MPI_Aint sdispls[NDIMS * 2], rdispls[NDIMS * 2];
    int iNeighbours[NDIMS], jNeighbours[NDIMS];
    int coords[NDIMS], dims[NDIMS];
    int imaxLocal, jmaxLocal;
} Solver;

void initSolver(Solver*, Parameter*);
void computeRHS(Solver*);
int solve(Solver*);
int solveRB(Solver*);
int solveRBA(Solver*);
void computeTimestep(Solver*);
void setBoundaryConditions(Solver*);
void setSpecialBoundaryCondition(Solver*);
void computeFG(Solver*);
void adaptUV(Solver*);
void collectResult(Solver*);
void writeResult(Solver*, double*, double*, double*);
void debugExchange(Solver*);
void print(Solver*, double*);
#endif
