/*----------------------- BEGIN globchem_solve.cu BEGIN -----------------------*/
/* @file globchem_solve.cu                                                     */
/* @author jlinford                                                            */
/* @date 2014-09-24 15:52:02.032808                                            */
/* @brief Solve Ax=b by forward-backward substitution                          */
/*                                                                             */
/* Solve Ax=b by forward-backward substitution                                 */
/*                                                                             */
/* This file was generated by Kppa: http://www.paratools.com/Kppa              */
/*-----------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
#include "globchem_cu_parameters.h"
#include "globchem_sparse.h"
#include "globchem_solve.h"


/*---------------------------------- d_Solve ----------------------------------*/
/* CUDA kernel for Solve                                                       */
/*                                                                             */
/* @param[in]     ncells32 A multiple of 32 grid cells                         */
/* @param[in]     A        Row-compressed matrix with zero fill                */
/* @param[in,out] x        Input and solution vector                           */
/*-----------------------------------------------------------------------------*/
__global__
void d_Solve(size_t const ncells32, double const * A, double* x)
{

    size_t tidx = blockDim.x*blockIdx.x + threadIdx.x;
    if(tidx < ncells32) {
        A += tidx;
        x += tidx;

        for(int i=1; i<NVAR; ++i) {
            double acc = x[i*ncells32];
            for(int j=JAC_LU_CROW[i]; j<JAC_LU_DIAG[i]; ++j) {
                acc -= A[j*ncells32] * x[JAC_LU_ICOL[j]*ncells32];
            }
            x[i*ncells32] = acc;
        }
                            
        for(int i=NVAR-1; i>=0; --i) {
            double acc = x[i*ncells32];
            for(int j=JAC_LU_DIAG[i]+1; j<JAC_LU_CROW[i+1]; ++j) {
                acc -= A[j*ncells32] * x[JAC_LU_ICOL[j]*ncells32];
            }
            x[i*ncells32] = acc / A[JAC_LU_DIAG[i]*ncells32];
        }
    }
}/* END d_Solve */



/*----------------------------------- Solve -----------------------------------*/
/* Solve Ax=b in place by back substitution                                    */
/*                                                                             */
/* @param[in]     ncells32 A multiple of 32 grid cells                         */
/* @param[in]     d_A      Row-compressed matrix with zero fill in device memory */
/* @param[in,out] d_x      Input and solution vector in device memory          */
/*-----------------------------------------------------------------------------*/
void Solve(size_t const ncells32, double const * d_A, double* d_x)
{
    size_t nBlocks = ((ncells32 + 127) & ~127) >> 7;
    size_t nThreads = 128;
    d_Solve<<<nBlocks, nThreads>>>(ncells32, d_A, d_x);
}/* END Solve */

#


/*-------------------------- END globchem_solve.h END -------------------------*/
