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

/**
 * @file VoltageVector.h
 * Power System Voltage Vector class header.
 */
#ifndef PowerFlower_VoltageVector_h
#define PowerFlower_VoltageVector_h

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

POWERFLOWER_NAMESPACE_BEGIN

/**
 * Power System Voltage Vector class.
 * Implements the power system voltage vector class,
 * describing the voltage angle and magnitude in each bus in the power system.
 */
class VoltageVector
{
public:
	friend class PowerFlowProblem;		// PowerFlowProblem::CalculateVoltage() needs write access to internal PETSc vectors.

	// LIFECYCLE

	VoltageVector(void);										// Constructor
	VoltageVector(const VoltageVector& rSource);				// Copy constructor
	~VoltageVector(void);										// Destructor

	// OPERATORS

	VoltageVector& operator=(const VoltageVector& rSource);		// Assignment operator

	// OPERATIONS

	/**
	 * Clears the voltage vector object.
	 */
	void Clear(void);

	/**
	 * Builds the voltage vector.
	 * Sets the vector dimension, allocates the memory,
	 * and sets the voltage values from the given power system.
	 * @param rPowerSystem power system to get the dimension and voltage values from.
	 * @return \c true on success, \c false otherwise.
	 */
	bool Build(const POWERSYSTEM_NAMESPACE_NAME::PowerSystem& rPowerSystem);

	/**
	 * Builds the voltage vector with flag values.
	 * Sets the vector dimension, allocates the memory,
	 * and sets the slack and generator bus voltage values from the given power system,
	 * while setting the load bus voltage values to 1 p.u.
	 * @param rPowerSystem power system to get the dimension and voltage values from.
	 * @return \c true on success, \c false otherwise.
	 */
	bool BuildFlat(const POWERSYSTEM_NAMESPACE_NAME::PowerSystem& rPowerSystem);

	// ACCESS

	/**
	 * Gets the vector with voltage angles.
	 * @return vector with voltage angles.
	 */
	PetscUtils::ConstVec GetAng(void) const;

	/**
	 * Gets the vector with voltage magnitudes.
	 * @return vector with voltage magnitudes.
	 */
	PetscUtils::ConstVec GetMag(void) const;

private:

	/**
	 * Makes this a copy of an existing voltage vector.
	 * @param rSource voltage vector to copy from.
	 * @return \c true on success, \c false otherwise.
	 */
	bool Copy_Private(const VoltageVector& rSource);

	/**
	 * Builds the voltage vector.
	 * Sets the vector dimension, allocates the memory,
	 * and sets the voltage values from the given power system.
	 * If the flat voltage flag is set, the voltages of load busses are set to 1 p.u.
	 * @param rPowerSystem power system to get the dimension and voltage values from.
	 * @param isFlat flat voltage flag.
	 * @return \c true on success, \c false otherwise.
	 */
	bool Build_Private(const POWERSYSTEM_NAMESPACE_NAME::PowerSystem& rPowerSystem, bool isFlat);

	/**
	 * Gets the vector with voltage angles.
	 * Used by PowerFlowProblem::CalculateVoltage().
	 * @return vector with voltage angles.
	 */
	Vec GetAngPrivate(void);

	/**
	 * Gets the vector with voltage magnitudes.
	 * Used by PowerFlowProblem::CalculateVoltage().
	 * @return vector with voltage magnitudes.
	 */
	Vec GetMagPrivate(void);

	PetscErrorCode mErr;		///< Most recent PETSc error code.
	Vec mVa;					///< Voltage angle.
	Vec mVm;					///< Voltage magnitude.
};

POWERFLOWER_NAMESPACE_END

#endif // PowerFlower_VoltageVector_h
