#include "common_pastix.h"
#ifdef FORCE_NOMPI
#include "nompi.h"
#else		  
#include <mpi.h>	  
#endif              
#include "murge.h"

/** Macro from Scotch **/

#define FORTRAN_NAME(nu,nl,pl,pc) \
void nu pl;                       \
void nl pl                        \
{ nu pc; }                        \
void nl##_ pl                     \
{ nu pc; }                        \
void nl##__ pl                    \
{ nu pc; }                        \
void nu pl

FORTRAN_NAME(MURGE_INITIALIZE,
             murge_initialize,
             (INTS *idnbr,  INTS *ierror),
             (idnbr,  ierror))
{
  *ierror = MURGE_Initialize(*idnbr);
}

FORTRAN_NAME(MURGE_SETDEFAULTOPTIONS,
             murge_setdefaultoptions,
             (INTS *id,  INTS *stratnum,  INTS *ierror),
             (id, stratnum,  ierror))
{
  *ierror = MURGE_SetDefaultOptions(*id, *stratnum);
}

FORTRAN_NAME(MURGE_SETOPTIONINT,
             murge_setoptionint,
             (INTS *id,  INTS *number,  INTS *value,  INTS *ierror),
             (id, number, value,  ierror))
{
  int my_number = *number - 1;
  *ierror = MURGE_SetOptionINT(*id, my_number, *value);
}

FORTRAN_NAME(MURGE_SETOPTIONREAL,
             murge_setoptionreal,
             (INTS *id,  INTS *number,  REAL *value,  INTS *ierror),
             (id, number, value,  ierror))
{
  int my_number = *number - 1;
  *ierror = MURGE_SetOptionREAL(*id, my_number, *value);
}

#ifdef MPI_VERSION
FORTRAN_NAME(MURGE_SETCOMMUNICATOR,
             murge_setcommunicator,
             (INTS *id, MPI_Fint *mpicom,  INTS *ierror),
             (id, mpicom,  ierror))
{
  MPI_Comm tmpcomm;
  tmpcomm = MPI_Comm_f2c(*mpicom);
  *ierror = MURGE_SetCommunicator(*id, tmpcomm);
}
#endif /* MPI_VERSION */

FORTRAN_NAME(MURGE_GRAPHBEGIN,
             murge_graphbegin,
             (INTS *id,  INTS *N,  INTL *edgenbr,  INTS *ierror),
             (id, N, edgenbr,  ierror))
{
  *ierror = MURGE_GraphBegin(*id, *N, *edgenbr);
}

FORTRAN_NAME(MURGE_GRAPHEDGE,
             murge_graphedge,
             (INTS *id,  INTS *COL,  INTS *ROW,  INTS *ierror),
             (id, COL, ROW,  ierror))
{
  *ierror = MURGE_GraphEdge(*id, *COL, *ROW);
}

FORTRAN_NAME(MURGE_GRAPHEND,
             murge_graphend,
             (INTS *id,  INTS *ierror),
             (id,  ierror))
{
  *ierror = MURGE_GraphEnd(*id);
}

FORTRAN_NAME(MURGE_GRAPHGLOBALCSR,
             murge_graphglobalcsr,
             (INTS *id,  INTS *N,  INTL *rowptr,  INTS *COLS,  INTS *root,  INTS *ierror),
             (id, N, rowptr, COLS, root,  ierror))
{
  *ierror = MURGE_GraphGlobalCSR(*id, *N, rowptr, COLS, *root);
}

FORTRAN_NAME(MURGE_GRAPHGLOBALCSC,
             murge_graphglobalcsc,
             (INTS *id,  INTS *N,  INTL *colptr,  INTS *ROWS,  INTS *root,  INTS *ierror),
             (id, N, colptr, ROWS, root,  ierror))
{
  *ierror = MURGE_GraphGlobalCSC(*id, *N, colptr, ROWS, *root);
}

FORTRAN_NAME(MURGE_GRAPHGLOBALIJV,
             murge_graphglobalijv,
             (INTS *id,  INTS *N,  INTL *NNZ,  INTS *ROW,  INTS *COL,  INTS *root,  INTS *ierror),
             (id, N, NNZ, ROW, COL, root,  ierror))
{
  *ierror = MURGE_GraphGlobalIJV(*id, *N, *NNZ, ROW, COL, *root);
}

FORTRAN_NAME(MURGE_SAVE,
             murge_save,
             (INTS *id,  char* directory, INTS *stringlength,  INTS *ierror),
             (id,  directory, stringlength,  ierror))
{
  char * tmp = NULL;
  tmp = (char *) malloc ((*stringlength+1)*sizeof(char));
  strncpy(tmp, directory, *stringlength);
  tmp[*stringlength] = '\0';
  *ierror = MURGE_Save(*id,  tmp);
}

FORTRAN_NAME(MURGE_LOAD,
             murge_load,
             (INTS *id,  char* directory, INTS *stringlength,  INTS *ierror),
             (id,  directory, stringlength,  ierror))
{
  char * tmp = NULL;
  tmp = (char *) malloc ((*stringlength+1)*sizeof(char));
  strncpy(tmp, directory, *stringlength);
  tmp[*stringlength] = '\0';
  *ierror = MURGE_Load(*id,  tmp);
}

FORTRAN_NAME(MURGE_GETLOCALNODENBR,
             murge_getlocalnodenbr,
             (INTS *id,  INTS *nodenbr,  INTS *ierror),
             (id, nodenbr,  ierror))
{
  *ierror = MURGE_GetLocalNodeNbr(*id, nodenbr);
}

FORTRAN_NAME(MURGE_GETLOCALNODELIST,
             murge_getlocalnodelist,
             (INTS *id,  INTS *nodelist,  INTS *ierror),
             (id, nodelist,  ierror))
{
  *ierror = MURGE_GetLocalNodeList(*id, nodelist);
}

FORTRAN_NAME(MURGE_GETLOCALUNKNOWNNBR,
             murge_getlocalunknownnbr,
             (INTS *id,  INTS *unkownnbr,  INTS *ierror),
             (id, unkownnbr,  ierror))
{
  *ierror = MURGE_GetLocalUnknownNbr(*id, unkownnbr);
}

FORTRAN_NAME(MURGE_GETLOCALUNKNOWNLIST,
             murge_getlocalunknownlist,
             (INTS *id,  INTS *unkownlist,  INTS *ierror),
             (id, unkownlist,  ierror))
{
  *ierror = MURGE_GetLocalUnknownList(*id, unkownlist);
}

FORTRAN_NAME(MURGE_ASSEMBLYBEGIN,
             murge_assemblybegin,
             (INTS *id,  INTS *N,  INTL *coefnbr,  INTS *op,  INTS *op2,  INTS *mode,  INTS *sym,  INTS *ierror),
             (id, N, coefnbr, op, op2, mode, sym,  ierror))
{
  *ierror = MURGE_AssemblyBegin(*id, *N, *coefnbr, *op, *op2, *mode, *sym);
}

FORTRAN_NAME(MURGE_ASSEMBLYSETVALUE,
             murge_assemblysetvalue,
             (INTS *id,  INTS *ROW,  INTS *COL,  COEF *value,  INTS *ierror),
             (id, ROW, COL, value,  ierror))
{
  *ierror = MURGE_AssemblySetValue(*id, *ROW, *COL, *value);
}

FORTRAN_NAME(MURGE_ASSEMBLYSETNODEVALUES,
             murge_assemblysetnodevalues,
             (INTS *id,  INTS *ROW,  INTS *COL,  COEF *values,  INTS *ierror),
             (id, ROW, COL, values,  ierror))
{
  *ierror = MURGE_AssemblySetNodeValues(*id, *ROW, *COL, values);
}

FORTRAN_NAME(MURGE_ASSEMBLYSETBLOCKVALUES,
             murge_assemblysetblockvalues,
             (INTS *id,  INTS *nROW,  INTS *ROWlist,  INTS *nCOL, INTS *COLlist,  COEF *values,  INTS *ierror),
             (id, nROW, ROWlist, nCOL, COLlist, values,  ierror))
{
  *ierror = MURGE_AssemblySetBlockValues(*id, *nROW, ROWlist, *nCOL, COLlist, values);
}

FORTRAN_NAME(MURGE_ASSEMBLYEND,
             murge_assemblyend,
             (INTS *id,  INTS *ierror),
             (id,  ierror))
{
  *ierror = MURGE_AssemblyEnd(*id);
}

FORTRAN_NAME(MURGE_MATRIXRESET,
             murge_matrixreset,
             (INTS *id,  INTS *ierror),
             (id,  ierror))
{
  *ierror = MURGE_MatrixReset(*id);
}

FORTRAN_NAME(MURGE_MATRIXGLOBALCSR,
             murge_matrixglobalcsr,
             (INTS *id,  INTS *N,  INTL *rowptr,  INTS *COLS, COEF *values,  INTS *root,  INTS *op,  INTS *sym,  INTS *ierror),
             (id, N, rowptr, COLS, values, root, op, sym,  ierror))
{
  *ierror = MURGE_MatrixGlobalCSR(*id, *N, rowptr, COLS, values, *root, *op, *sym);
}

FORTRAN_NAME(MURGE_MATRIXGLOBALCSC,
             murge_matrixglobalcsc,
             (INTS *id,  INTS *N,  INTL *COLPTR,  INTS *ROWS, COEF *values,  INTS *root,  INTS *op,  INTS *sym,  INTS *ierror),
             (id, N, COLPTR, ROWS, values, root, op, sym,  ierror))
{
  *ierror = MURGE_MatrixGlobalCSC(*id, *N, COLPTR, ROWS, values, *root, *op, *sym);
}

FORTRAN_NAME(MURGE_MATRIXGLOBALIJV,
             murge_matrixglobalijv,
             (INTS *id,  INTS *N,  INTL *NNZ,  INTS *ROWS,  INTS *COLS, COEF *values,  INTS *root,  INTS *op,  INTS *sym,  INTS *ierror),
             (id, N, NNZ, ROWS, COLS, values, root, op, sym,  ierror))
{
  *ierror = MURGE_MatrixGlobalIJV(*id, *N, *NNZ, ROWS, COLS, values, *root, *op, *sym);
}

FORTRAN_NAME(MURGE_SETGLOBALRHS,
             murge_setglobalrhs,
             (INTS *id,  COEF *b,  INTS *root,  INTS *op,  INTS *ierror),
             (id, b, root, op,  ierror))
{
  *ierror = MURGE_SetGlobalRHS(*id, b, *root, *op);
}

FORTRAN_NAME(MURGE_SETLOCALRHS,
             murge_setlocalrhs,
             (INTS *id,  COEF *b,  INTS *op,  INTS *op2,  INTS *ierror),
             (id, b, op, op2,  ierror))
{
  *ierror = MURGE_SetLocalRHS(*id, b, *op, *op2);
}

FORTRAN_NAME(MURGE_SETRHS,
             murge_setrhs,
             (INTS *id,  INTS *n,  INTS *coefsidx,  COEF *b, INTS *op,  INTS *op2,  INTS *mode,  INTS *ierror),
             (id, n, coefsidx, b, op, op2, mode,  ierror))
{
  *ierror = MURGE_SetRHS(*id, *n, coefsidx, b, *op, *op2, *mode);
}

FORTRAN_NAME(MURGE_RHSRESET,
             murge_rhsreset,
             (INTS *id,  INTS *ierror),
             (id,  ierror))
{
  *ierror = MURGE_RHSReset(*id);
}

FORTRAN_NAME(MURGE_GETGLOBALSOLUTION,
             murge_getglobalsolution,
             (INTS *id,  COEF *x,  INTS *root,  INTS *ierror),
             (id, x, root,  ierror))
{
  *ierror = MURGE_GetGlobalSolution(*id, x, *root);
}

FORTRAN_NAME(MURGE_GETLOCALSOLUTION,
             murge_getlocalsolution,
             (INTS *id,  COEF *x,  INTS *ierror),
             (id, x,  ierror))
{
  *ierror = MURGE_GetLocalSolution(*id, x);
}

FORTRAN_NAME(MURGE_GETSOLUTION,
             murge_getsolution,
             (INTS *id,   INTS *n,  INTS *coefsidx,  COEF *x,  INTS *mode,  INTS *ierror),
             (id, n, coefsidx, x, mode,  ierror))
{
  *ierror = MURGE_GetSolution(*id, *n, coefsidx, x, *mode);
}

FORTRAN_NAME(MURGE_GETGLOBALNORM,
             murge_getglobalnorm,
             (INTS *id,  REAL *norm,  INTS *root,  INTS *rule,  INTS *ierror),
             (id, norm, root, rule,  ierror))
{
  *ierror = MURGE_GetGlobalNorm(*id, norm, *root, *rule);
}

FORTRAN_NAME(MURGE_GETLOCALNORM,
             murge_getlocalnorm,
             (INTS *id,  REAL *norm,  INTS *rule,  INTS *ierror),
             (id, norm, rule,  ierror))
{
  *ierror = MURGE_GetLocalNorm(*id, norm, *rule);
}

FORTRAN_NAME(MURGE_GETNORM,
             murge_getnorm,
             (INTS *id,   INTS *n,  INTS *coefsidx,  REAL *norm,  INTS *rule,  INTS *mode,  INTS *ierror),
             (id, n, coefsidx, norm, rule, mode,  ierror))
{
  *ierror = MURGE_GetNorm(*id, *n, coefsidx, norm, *rule, *mode);
}

FORTRAN_NAME(MURGE_APPLYGLOBALSCALING,
             murge_applyglobalscaling,
             (INTS *id,  REAL *scal,   INTS *root,  INTS *sc_mode,  INTS *ierror),
             (id, scal, root, sc_mode,  ierror))
{
  *ierror = MURGE_ApplyGlobalScaling(*id, scal, *root, *sc_mode);
}

FORTRAN_NAME(MURGE_APPLYLOCALSCALING,
             murge_applylocalscaling,
             (INTS *id,  REAL *scal,  INTS *sc_mode,  INTS *ierror),
             (id, scal, sc_mode,  ierror))
{
  *ierror = MURGE_ApplyLocalScaling(*id, scal, *sc_mode);
}

FORTRAN_NAME(MURGE_APPLYSCALING,
             murge_applyscaling,
             (INTS *id,   INTS *n,  INTS *coefsidx,  REAL *scal,  INTS *sc_mode,  INTS *mode,  INTS *ierror),
             (id, n, coefsidx, scal, sc_mode, mode,  ierror))
{
  *ierror = MURGE_ApplyScaling(*id, *n, coefsidx, scal, *sc_mode, *mode);
}

FORTRAN_NAME(MURGE_CLEAN,
             murge_clean,
             (INTS *id,  INTS *ierror),
             (id,  ierror))
{
  *ierror = MURGE_Clean(*id);
}

FORTRAN_NAME(MURGE_FINALIZE,
             murge_finalize,
             ( INTS *ierror),
             ( ierror))
{
  *ierror = MURGE_Finalize();
}

FORTRAN_NAME(MURGE_GETSOLVER,
             murge_getsolver,
             (INTS * solver,  INTS *ierror),
             ( solver,  ierror))
{
  *ierror = MURGE_GetSolver( solver);
}

FORTRAN_NAME(MURGE_GETINFOINT,
             murge_getinfoint,
             (INTS *id,   INTS *metric,  INTL * value,  INTS *ierror),
             (id, metric,  value,  ierror))
{
  *ierror = MURGE_GetInfoINT(*id, *metric,  value);
}

FORTRAN_NAME(MURGE_GETINFOREAL,
             murge_getinforeal,
             (INTS *id,   INTS *metric,  REAL * value,  INTS *ierror),
             (id, metric,  value,  ierror))
{
  *ierror = MURGE_GetInfoREAL(*id, *metric,  value);
}

FORTRAN_NAME(MURGE_PRINTERROR,
             murge_printerror,
             (INTS *error_number,  INTS *ierror),
             (error_number,  ierror))
{
  *ierror = MURGE_PrintError(*error_number);
}

FORTRAN_NAME(MURGE_EXITONERROR,
             murge_exitonerror,
             (INTS *error_number,  INTS *ierror),
             (error_number,  ierror))
{
  *ierror = MURGE_ExitOnError(*error_number);
}

/* Copyright 2008 BORDEAUX I UNIVERSITY & INRIA 
**
** This file is part of the PaStiX parallel sparse matrix package.
**
** This software is governed by the CeCILL-C license under French law
** and abiding by the rules of distribution of free software. You can
** use, modify and/or redistribute the software under the terms of the
** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
** URL: "http://www.cecill.info".
** 
** As a counterpart to the access to the source code and rights to copy,
** modify and redistribute granted by the license, users are provided
** only with a limited warranty and the software's author, the holder of
** the economic rights, and the successive licensors have only limited
** liability.
** 
** In this respect, the user's attention is drawn to the risks associated
** with loading, using, modifying and/or developing or reproducing the
** software by the user in light of its specific status of free software,
** that may mean that it is complicated to manipulate, and that also
** therefore means that it is reserved for developers and experienced
** professionals having in-depth computer knowledge. Users are therefore
** encouraged to load and test the software's suitability as regards
** their requirements in conditions enabling the security of their
** systems and/or data to be ensured and, more generally, to use and
** operate it in the same conditions as regards security.
** 
** The fact that you are presently reading this means that you have had
** knowledge of the CeCILL-C license and that you accept its terms.
*/
#include "murge_pastix.h"

FORTRAN_NAME(MURGE_ANALYZE,
             murge_analyze,
             (INTS *id,  INTS *ierror),
             (id,  ierror))
{
  *ierror = MURGE_Analyze(*id);
}


FORTRAN_NAME(MURGE_FACTORIZE,
             murge_factorize,
             (INTS *id,  INTS *ierror),
             (id,  ierror))
{
  *ierror = MURGE_Factorize(*id);
}

FORTRAN_NAME(MURGE_SETORDERING,
             murge_setordering,
             (INTS *id, INTS * permutation, INTS * ierror),
             (id, permutation, ierror))
{
  *ierror = MURGE_SetOrdering(*id, permutation);
}

FORTRAN_NAME(MURGE_PRODUCTSETLOCALNODENBR,
             murge_productsetlocalnodenbr,
             (INTS *id, INTS *n, INTS * ierror),
             (id, n, ierror))
{
  *ierror =  MURGE_ProductSetLocalNodeNbr(*id, *n);
}

FORTRAN_NAME(MURGE_PRODUCTSETGLOBALNODENBR,
             murge_productsetglobalnodenbr,
             (INTS *id, INTS *n, INTS * ierror),
             (id, n, ierror))
{
  *ierror =  MURGE_ProductSetGlobalNodeNbr(*id, *n);
}

FORTRAN_NAME(MURGE_PRODUCTSETLOCALNODELIST,
             murge_productsetlocalnodelist,
             (INTS *id, INTS *l2g, INTS * ierror),
             (id, l2g, ierror))
{
  *ierror =  MURGE_ProductSetLocalNodeList(*id, l2g);
}
FORTRAN_NAME(MURGE_GETLOCALPRODUCT,
             murge_getlocalproduct,
             (INTS *id,  COEF * x, INTS * ierror),
             (id, x, ierror))
{
  *ierror = MURGE_GetLocalProduct(*id, x);
}

FORTRAN_NAME(MURGE_GETGLOBALPRODUCT,
             murge_getglobalproduct,
             (INTS *id,  COEF * x, INTS *root, INTS * ierror),
             (id, x, root, ierror))
{
  *ierror = MURGE_GetGlobalProduct(*id, x, *root);
}

FORTRAN_NAME(MURGE_FORCENOFACTO,
             murge_forcenofacto,
             (INTS *id, INTS * ierror),
             (id, ierror))
{
  *ierror =  MURGE_ForceNoFacto(*id);
}

FORTRAN_NAME(MURGE_SETLOCALNODELIST,
             murge_setlocalnodelist,
             (INTS *id, INTS * n, INTS * list, INTS * ierror),
             (id, n, list, ierror))
{
  *ierror =  MURGE_SetLocalNodeList(*id, *n, list);
}


FORTRAN_NAME(MURGE_ASSEMBLYSETSEQUENCE,
             murge_assemblysetsequence,
             (INTS *id, INTL *coefnbr, INTS * ROWs, INTS * COLs,
              INTS *op, INTS *op2, INTS *mode, INTS *nodes,
              INTS * id_seq, INTS *ierror),
             (id, coefnbr, ROWs, COLs, op, op2, mode, nodes, id_seq, ierror))
{
  *ierror = MURGE_AssemblySetSequence(*id, *coefnbr, ROWs, COLs,
                                      *op, *op2, *mode, *nodes, id_seq);
}

FORTRAN_NAME(MURGE_ASSEMBLYUSESEQUENCE,
             murge_assemblyusesequence,
             (INTS *id, INTS *id_seq, COEF * values, INTS * ierror),
             (id, id_seq, values, ierror))
{
  *ierror = MURGE_AssemblyUseSequence(*id, *id_seq, values);
}

FORTRAN_NAME(MURGE_ASSEMBLYDELETESEQUENCE,
             murge_assemblydeletesequence,
             (INTS *id, INTS *id_seq, INTS *ierror),
             (id, id_seq, ierror))
{
  *ierror = MURGE_AssemblyDeleteSequence(*id, *id_seq);
}

FORTRAN_NAME(MURGE_SETDROPNODES,
	     murge_setdropnodes,
	     (INTS * id, INTS * nodenbr, INTS * dropmask, INTS * ierror),
	     (id, nodenbr, dropmask, ierror))
{
  *ierror = MURGE_SetDropNodes(*id, *nodenbr, dropmask);
}

FORTRAN_NAME(MURGE_SETDROPCOLS,
	     murge_setdropcols,
	     (INTS * id, INTS * nodenbr, INTS * dropmask, INTS * ierror),
	     (id, nodenbr, dropmask, ierror))
{
  *ierror = MURGE_SetDropCols(*id, *nodenbr, dropmask);
}

FORTRAN_NAME(MURGE_SETDROPROWS,
	     murge_setdroprows,
	     (INTS * id, INTS * nodenbr, INTS * dropmask, INTS * ierror),
	     (id, nodenbr, dropmask, ierror))
{
  *ierror = MURGE_SetDropRows(*id, *nodenbr, dropmask);
}

FORTRAN_NAME(MURGE_COLGETNONZEROSNBR,
	     murge_colgetnonzerosnbr,
	     (INTS * id, INTS * COL, INTS * nnzNbr,INTS * ierror),
	     (id, COL, nnzNbr, ierror))
{
  *ierror = MURGE_ColGetNonZerosNbr(*id, *COL, nnzNbr);
}


FORTRAN_NAME(MURGE_COLGETNONZEROSIDX,
	     murge_colgetnonzerosidx,
	     (INTS * id, INTS * COL, INTS * nnzIdx,INTS * ierror),
	     (id, COL, nnzIdx, ierror))
{
  *ierror = MURGE_ColGetNonZerosIdx(*id, *COL, nnzIdx);
}
