/*
 * Copyright (C) 2008-2012 Delft University of Technology - All rights reserved.
 *
 * Author: Reijer Idema
 */

/*
 * PetscVecSeq source.
 */
#include "../src/vec/vec/impls/dvecimpl.h"	// PETSc VECSEQ declarations
#include "PetscVecSeq.h"

PETSCUTILS_NAMESPACE_BEGIN

#undef __FUNCT__
#define __FUNCT__ "PetscUtils::VecSeqGetSize"
PetscInt VecSeqGetSize(const _p_Vec* vec)
{
	if (vec == PETSC_NULL) return 0;

#if !PETSC_UTILS_IMPL_TRUECONST
	PetscInt size;
	VecGetSize(const_cast<Vec>(vec), &size);
	return size;
#else // PETSC_UTILS_IMPL_TRUECONST
	return vec->map->N;	// :NOTE: Use map->n for local size
#endif

} // VecSeqGetSize


#undef __FUNCT__
#define __FUNCT__ "PetscUtils::VecSeqGetArray"
PetscErrorCode VecSeqGetArray(const _p_Vec* vec, const PetscScalar *a[])
{
	// Validate input vector
	if (vec == PETSC_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Vector is NULL");
	if (strcmp(((PetscObject)vec)->type_name, VECSEQ) != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Only for VECSEQ vectors");

#if !PETSC_UTILS_IMPL_TRUECONST
	PetscErrorCode err = VecGetArray(const_cast<Vec>(vec), const_cast<PetscScalar**>(a)); CHKERRQ(err);
#else // PETSC_UTILS_IMPL_TRUECONST
	// Set pointer to vector data
	const Vec_Seq* v = (Vec_Seq*)vec->data;
	*a =  v->array;
#endif

	return 0;
} // VecSeqGetArray


#undef __FUNCT__
#define __FUNCT__ "PetscUtils::VecSeqRestoreArray"
PetscErrorCode VecSeqRestoreArray(const _p_Vec* vec, const PetscScalar *a[])
{
	// Validate input vector
	if (vec == PETSC_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Vector is NULL");
	if (strcmp(((PetscObject)vec)->type_name, VECSEQ) != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Only for VECSEQ vectors");

#if !PETSC_UTILS_IMPL_TRUECONST
	PetscErrorCode err = VecGetArray(const_cast<Vec>(vec), const_cast<PetscScalar**>(a)); CHKERRQ(err);
#endif

	return 0;
} // VecSeqRestoreArray


#undef __FUNCT__
#define __FUNCT__ "PetscUtils::VecSeqView"
PetscErrorCode VecSeqView(const _p_Vec* vec)
{
	// Validate input vector
	if (vec == PETSC_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Vector is NULL");
	if (strcmp(((PetscObject)vec)->type_name, VECSEQ) != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Only for VECSEQ vectors");

#if !PETSC_UTILS_IMPL_TRUECONST
	PetscErrorCode err = VecView(const_cast<Vec>(vec), PETSC_VIEWER_STDOUT_SELF); CHKERRQ(err);
#else // PETSC_UTILS_IMPL_TRUECONST
	// Print vector to standard out
	PetscErrorCode err;
	PetscInt size = VecSeqGetSize(vec);
	const PetscScalar *pVals;
	err = VecSeqGetArray(vec, &pVals); CHKERRQ(err);
	for (PetscInt i=0; i<size; ++i)
	{
		PetscPrintf(PETSC_COMM_WORLD, "%g\n", pVals[i]);
	}
	err = VecSeqRestoreArray(vec, &pVals); CHKERRQ(err);
#endif

	return 0;
} // VecSeqView

PETSCUTILS_NAMESPACE_END
