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

/**
 * @file AdmittanceMatrix.h
 * Power System Admittance Matrix class header.
 */
#ifndef PowerFlower_AdmittanceMatrix_h
#define PowerFlower_AdmittanceMatrix_h

#include "../PetscUtils/PetscUtils.h"	// USES PetscUtils
#include "../PowerSystem/PowerSystem.h"	// USES PowerSystem
#include "PowerFlower.def"

POWERFLOWER_NAMESPACE_BEGIN

// FORWARD DECLARATIONS
class LogEvents;

/**
 * Power System Admittance Matrix class.
 * Implements the power system admittance matrix class,
 * describing the complex admittance matrix of a power system.
 */
class AdmittanceMatrix
{
public:
	// LIFECYCLE
	AdmittanceMatrix(void);
	AdmittanceMatrix(const LogEvents* pLogEvents);
	~AdmittanceMatrix(void);

	// OPERATIONS

	/**
	 * Clears the admittance matrix object.
	 */
	void Clear(void);

	/**
	 * Builds the admittance matrix.
	 * Sets the matrix dimensions, and non-zero structure, allocates the memory,
	 * and calculates the admittance values from the given power system.
	 * @param rPowerSystem power system to get the dimensions and admittance values from.
	 * @return \c true on success, \c false otherwise.
	 */
	bool Build(const POWERSYSTEM_NAMESPACE_NAME::PowerSystem& rPowerSystem);

	bool AddBranch(const POWERSYSTEM_NAMESPACE_NAME::Branch& rBranch);

	bool RemoveBranch(const POWERSYSTEM_NAMESPACE_NAME::Branch& rBranch);


	// ACCESS

	/**
	 * Gets the real part of the admittance matrix.
	 * @return real part of the admittance matrix.
	 */
	PetscUtils::ConstMat GetReal(void) const;

	/**
	 * Gets the imaginary part of the admittance matrix.
	 * @return imaginary part of the admittance matrix.
	 */
	PetscUtils::ConstMat GetImag(void) const;

private:

	/**
	 * Builds the admittance matrix.
	 * Sets the matrix dimensions, and non-zero structure, allocates the memory,
	 * and calculates the admittance values from the given power system.
	 * @param rPowerSystem power system to get the dimensions and admittance values from.
	 * @return \c true on success, \c false otherwise.
	 */
	bool Build_Private(const POWERSYSTEM_NAMESPACE_NAME::PowerSystem& rPowerSystem);


	void AddValues(const POWERSYSTEM_NAMESPACE_NAME::Branch& rBranch,
			PetscScalar& rGii, PetscScalar& rGij, PetscScalar& rGji, PetscScalar& rGjj,
			PetscScalar& rBii, PetscScalar& rBij, PetscScalar& rBji, PetscScalar& rBjj);



	PetscErrorCode mErr;			///< Most recent PETSc error code.
	const LogEvents* mpLogEvents;	///< PETSc log events.
	Mat mG;							///< Real part of the admittance matrix.
	Mat mB;							///< Imaginary part of the admittance matrix.
};

POWERFLOWER_NAMESPACE_END

#endif // PowerFlower_AdmittanceMatrix_h
