#/*
#==============================================================================
#
# cg_clover.H
#
#------------------------------------------------------------------------------
#
# Copyright (C) 2016 Hinnerk Stueben
#
# This file is part of BQCD -- Berlin Quantum ChromoDynamics program
#
# BQCD 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.
#
# BQCD 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 BQCD.  If not, see <http://www.gnu.org/licenses/>.
#
#------------------------------------------------------------------------------
#*/

# define Tclover(name) STRCAT9(name, nameBLOCK, CLOVER_TYPE, _, SPINCOL_TYPE, _r, RKIND, nameSIMD, nameUNDERSCORE)

# define ReClover STRCAT(ReClover_, CLOVER_TYPE)
# define ImClover STRCAT(ImClover_, CLOVER_TYPE)

#ifdef LANGUAGE_FORTRAN

# define TYPE_CLOVER STRCAT5(type_clover_, CLOVER_TYPE, _r, RKIND, nameSIMD)

# define clover_FLD type(TYPE_CLOVER), dimension(2,*)

# define Clover_c1(array, block, index, i, j) STRCAT3(array(block, index)%a, i, j)
#ifdef SIMD
# define ReClover_c1(array, block, index, i, j) Real(Clover_c1(array, block, index, i, j))
# define ImClover_c1(array, block, index, i, j) Imag(Clover_c1(array, block, index, i, j))
#else
# define ReClover_c1(array, block, index, i, j) real(Clover_c1(array, block, index, i, j), kind=RKIND)
# define ImClover_c1(array, block, index, i, j) aimag(Clover_c1(array, block, index, i, j))
#endif

# define ReClover_c2(array, block, index, i, j) STRCAT3(array(block, index)%re, i, j)
# define ImClover_c2(array, block, index, i, j) STRCAT3(array(block, index)%im, i, j)

#endif

#ifdef LANGUAGE_C

# define TYPE_CLOVER STRCAT(type_clover_, CLOVER_TYPE)

# define ReClover_c1(array, block, index, i, j) Real(STRCAT3(array[index][block-1].a, i, j))
# define ImClover_c1(array, block, index, i, j) Imag(STRCAT3(array[index][block-1].a, i, j))

# define ReClover_c2(array, block, index, i, j) STRCAT3(array[index][block-1].re, i, j)
# define ImClover_c2(array, block, index, i, j) STRCAT3(array[index][block-1].im, i, j)


typedef struct { 
    SIMD_REAL a11;
    SIMD_REAL a22;

    SIMD_COMPLEX a12;
    SIMD_COMPLEX a13;
    SIMD_COMPLEX a14;
    SIMD_COMPLEX a15;
    SIMD_COMPLEX a16;

    SIMD_COMPLEX a23;
    SIMD_COMPLEX a24;
    SIMD_COMPLEX a25;
    SIMD_COMPLEX a26;

    SIMD_REAL a33;
    SIMD_REAL a44;

    SIMD_COMPLEX a34;
    SIMD_COMPLEX a35;
    SIMD_COMPLEX a36;

    SIMD_COMPLEX a45;
    SIMD_COMPLEX a46;

    SIMD_REAL a55;
    SIMD_REAL a66;

    SIMD_COMPLEX a56;

} type_clover_c1;

typedef struct {
//j=1
    REAL im12[SIMD_WIDTH];
    REAL im13[SIMD_WIDTH];
    REAL im14[SIMD_WIDTH];
    REAL im15[SIMD_WIDTH];
    REAL im16[SIMD_WIDTH];

    REAL re11[SIMD_WIDTH];
    REAL re12[SIMD_WIDTH];
    REAL re13[SIMD_WIDTH];
    REAL re14[SIMD_WIDTH];
    REAL re15[SIMD_WIDTH];
    REAL re16[SIMD_WIDTH];
//j=4
    REAL im24[SIMD_WIDTH];
    REAL im34[SIMD_WIDTH];
    REAL im45[SIMD_WIDTH];
    REAL im46[SIMD_WIDTH];

    REAL re24[SIMD_WIDTH];
    REAL re34[SIMD_WIDTH];
    REAL re44[SIMD_WIDTH];
    REAL re45[SIMD_WIDTH];
    REAL re46[SIMD_WIDTH];
//j=2
    REAL im23[SIMD_WIDTH];
    REAL im25[SIMD_WIDTH];
    REAL im26[SIMD_WIDTH];

    REAL re22[SIMD_WIDTH];
    REAL re23[SIMD_WIDTH];
    REAL re25[SIMD_WIDTH];
    REAL re26[SIMD_WIDTH];
//j=5
    REAL im35[SIMD_WIDTH];
    REAL im56[SIMD_WIDTH];

    REAL re35[SIMD_WIDTH];
    REAL re55[SIMD_WIDTH];
    REAL re56[SIMD_WIDTH];
//j=3
    REAL im36[SIMD_WIDTH];

    REAL re33[SIMD_WIDTH];
    REAL re36[SIMD_WIDTH];
//j=6
    REAL re66[SIMD_WIDTH];

} type_clover_c2;

typedef TYPE_CLOVER (*clover_FLD)[2];

#endif
