Commit 0eba1226 authored by Gerrit Erichsen's avatar Gerrit Erichsen
Browse files

Squashed commit of the following branch: theses_integration

as it contains many wip and workstation change commits, these were deemed not helpful.
Integrated were the master thesis of Reimer and the work of Wiegel so far.
It got all debugged to a point, where the calculation actually yields results again, which is also the reason for the in-between merge.
parent 2b6e8436
......@@ -2,7 +2,7 @@
#include <cmath>
#include "InterpolationImplements.h"
#include "Utilities.h"
CSP::CSP(string name, double nominalPower, double nominalReferencePower,
double referenceMirrorArea, double solarMultiple,
......
......@@ -41,7 +41,7 @@ using namespace std;
using namespace std;
class CSP
class CHARLALGORITHMSHARED_EXPORT CSP
{
public:
CSP(string name, double nominalPower,
......
......@@ -24,7 +24,7 @@
#include <vector>
#include "Network.h"
#include "Node.h"
#include "Result.h"
#include "SimulationPreferences.h"
#include "Grid.h"
......@@ -54,7 +54,7 @@ public:
void transferWindData(int node,
const vector<float> * windData);
void transferWindData(int node, int location,
void transferWindData(size_t node, size_t location,
const vector<float> * windData1,
const vector<float> * windData2,
bool data2areDirections = true);
......@@ -69,8 +69,8 @@ public:
int location,
const vector<float> * solarData,
bool isWeatherData);
void transferSolarData(int node,
int location,
void transferSolarData(size_t node,
size_t location,
const vector<float> * diffIrrData,
const vector<float> * dirIrrData);
void transferSolarForecastData(int node,
......@@ -121,10 +121,16 @@ public:
const vector<pair<double, double> > &moduleEfficiency, bool arePortraitOriented, double tiltInDeg,
double azimuthInDeg, double groundCoverageRatio, const vector<pair<double, double> > &inverterEfficiency,
double specificInvestCost, double specificFixOaMcost, int lifeTime);
void addWindPark(size_t network, size_t location, string name, double nominalPowerOfPark, double hubHeight,
double rotorDiameter, double areaOfPark, vector<pair<double, double> > powerCurve,
vector<pair<double, double> > ctCurve, double investCost, double fixedOM_Cost,
double specOM_Cost, int lifeTime);
const Wind * addWindPark(size_t network, size_t location, string name, double nominalPowerOfPark,
double hubHeight, double rotorDiameter, double areaOfPark,
vector<pair<double, double> > powerCurve,
vector<pair<double, double> > ctCurve,
double investCost, double fixedOM_Cost,
double specOM_Cost, int lifeTime);
void addWindPark(size_t network, size_t location, string name, double nominalPowerOfPark,
const vector<pair<double, double>> & powerCurve,
const EfficiencyField & efficiencies,
double investCost, double fixedOM_Cost, double specOM_Cost, int lifeTime);
void setGenericWindCapacity(size_t node, double capacity);
void setGenericSolarCapacity(size_t node, double capacity);
......@@ -220,7 +226,7 @@ private:
//////////////////////////
/// network information
/////////////////////////
vector<Network *> m_networks; // all networks, that hold their own plant configurations, data and stuff
vector<Node *> m_nodes; // all networks, that hold their own plant configurations, data and stuff
Grid * m_grid; // how the networks work together
};
......
......@@ -17,16 +17,17 @@ DEFINES += CHARLALGORITHM_LIBRARY
SOURCES += CharLAlgorithm.cpp \
EfficiencyField.cpp \
Location.cpp \
Node.cpp \
PowerFlowSolver.cpp \
Storage.cpp \
Solar.cpp \
Conventional.cpp \
Utilities.cpp \
Wind.cpp \
Biomass.cpp \
Network.cpp \
Result.cpp \
InternalResult.cpp \
SimulationPreferences.cpp \
InterpolationImplements.cpp \
OptimisationSchedule.cpp \
CSP.cpp\
Grid.cpp\
......@@ -36,16 +37,17 @@ HEADERS += CharLAlgorithm.h \
CharLAlgorithm_global.h \
EfficiencyField.h \
Location.h \
Node.h \
PowerFlowSolver.h \
Storage.h \
Solar.h \
Conventional.h \
Utilities.h \
Wind.h \
Biomass.h \
Network.h \
Result.h \
InternalResult.h \
SimulationPreferences.h \
InterpolationImplements.h \
OptimisationSchedule.h \
CSP.h\
Grid.h\
......
......@@ -2,7 +2,7 @@
#include <algorithm>
#include "InterpolationImplements.h"
#include "Utilities.h"
#include "OptimisationSchedule.h" //tz - needed for optimisation of efficiency curve parameters
......
......@@ -27,7 +27,7 @@
using namespace std;
class Conventional
class CHARLALGORITHMSHARED_EXPORT Conventional
{
public:
Conventional(const SimulationPreferences * preferences);
......
#include "EfficiencyField.h"
#include "InterpolationImplements.h"
#include <string>
#include "Utilities.h"
EfficiencyField::EfficiencyField()
{
......@@ -192,3 +194,28 @@ double EfficiencyField::getEfficiencyBottomRight() const
{
return m_values.back().back();
}
string EfficiencyField::getFieldAsText() const
{
string txt = "";
for (size_t y = 0; y < m_yAxis.size(); y++)
{
if (y == 0)
{
for (size_t x = 0; x < m_xAxis.size(); x++)
{
txt += ";";
txt += to_string(m_xAxis[x]);
}
txt += "\n";
}
txt += to_string(m_yAxis[y]);
for (size_t x = 0; x < m_xAxis.size(); x++)
{
txt += ";";
txt += to_string(m_values[x][y]);
}
if (y < m_yAxis.size() - 1) txt += "\n";
}
return txt;
}
......@@ -29,6 +29,7 @@ public:
double getEfficiency(double x, double y) const;
double getEfficiencyTopLeft() const;
double getEfficiencyBottomRight() const;
string getFieldAsText() const;
private:
vector<double> m_xAxis;
......
This diff is collapsed.
......@@ -23,7 +23,7 @@
#include <vector>
#include <iomanip>
#include "Network.h"
#include "Node.h"
#include "Line.h"
#include "SimulationPreferences.h"
#include "OptimisationSchedule.h"
......@@ -35,18 +35,22 @@ using namespace Eigen;
class Grid {
public:
/********************************************************************************************************** CONSTRUCTOR */
Grid(vector<vector<double> > capacities, vector<vector<double> > impedances, vector<vector<double>> inducitivity, vector< Network * > gridNetworks, const SimulationPreferences * preferences);
Grid(vector<vector<double> > capacities,
vector<vector<double> > impedances,
vector<vector<double>> inducitivity,
vector< Node * > gridNetworks,
const SimulationPreferences * preferences);
/*********************************************************************************************************** DESTRUCTOR */
virtual ~Grid();
//get functions
double getLineCapacity(int row, int col);
double getPowerOfNode(int node);
double getReactivePowerOfNode(int node);
double getLoadsRealPart(int node, int timeStep);
double getLoadsImaginaryPart(int node, int timeStep);
double getLineCapacity(size_t row, size_t col);
double getPowerOfNode(size_t node);
double getReactivePowerOfNode(size_t node);
double getLoadsRealPart(size_t node, size_t timeStep);
double getLoadsImaginaryPart(size_t node, size_t timeStep);
double getAdimittanceRealPart(unsigned int i, unsigned int j);
double getAdmittanceImaginaryPart(unsigned int i, unsigned int j);
vector<string> getErrors() const {return m_errors;}
......@@ -280,7 +284,7 @@ public:
void setMaximumOfNodeReactive(vector<double> maximumReactivePower);
double getVoltageDefault() const {return m_realPartVoltageDefault;}
bool optimization() const {return co2Optimization;}
bool optimization() const {return m_optimizeForCO2;}
bool didPowerFlowConverge();
void changeX(int timeStep);
......@@ -297,7 +301,7 @@ private:
double deltaVgen = 3800.;
double deltaPgen = 20. * 1e6;
bool co2Optimization = false;
bool m_optimizeForCO2 = false;
bool isVoltageVariable = true;//
bool changePVToPQNodes = false;
double miniMumAccectableError = 1000.; //dv
......@@ -321,7 +325,7 @@ private:
double calculateNred(int i, int j); //* 1/Vj
void assignIndexVectors();
void generateInitialSolution(int timeStep, bool keepLastSolution = false);//Generates the initial solution
void generateInitialSolution(int timeStep);//Generates the initial solution
void solvePolar(int timeStep);
void solveStepPolar();
void updatedPowerPolar();
......@@ -386,8 +390,8 @@ private:
double getNewError(int step, string errorType, int nodeIndex);//dv Fehler aus probelastflussrechnungen
double getNewDeltaLinePower(int firstNodeIndex);
double getNewDeltaOverQ(int nodeIndex, int timeStep);
double getNewDeltaUnderQ(int nodeIndex, int timeStep);
double getNewDeltaOverQ(const size_t & node, int timeStep);
double getNewDeltaUnderQ(const size_t & node, int timeStep);
double getNewDeltaOverVoltage(int nodeIndex);
double getNewDeltaUnderVoltage(int nodeIndex);
double getNewDeltaOverPRef(int timeStep);
......@@ -626,7 +630,7 @@ private:
//Values entered by user
vector<Network *> m_gridNodes;
vector<Node *> m_gridNodes;
vector<vector<double>> m_impedances;
vector<vector<double>> m_capacities;
vector<vector<double>> m_inducitivity;//dv: X
......
......@@ -2,7 +2,7 @@
#include <algorithm>
#include "InterpolationImplements.h"
#include "Utilities.h"
InternalResult::InternalResult(string name, int nTimeSteps, double stepTime) :
m_name(name),
......@@ -142,6 +142,8 @@ string InternalResult::getStringForCsvFile() const //dvresult: for only one netw
for (int i = 0; i < int(m_wind.size()); i++)
{
text += "\"" + m_wind[i]->getName() + "_" + to_string(i) + "\";";
text += "\"Wind speed at " + m_wind[i]->getName() + "_" + to_string(i) + "\";";
text += "\"eta at " + m_wind[i]->getName() + "_" + to_string(i) + "\";";
}
}
text += "\"Wind cumulated\";";
......@@ -150,6 +152,8 @@ string InternalResult::getStringForCsvFile() const //dvresult: for only one netw
for (int i = 0; i < int(m_solar.size()); i++)
{
text += "\"" + m_solar[i]->getName() + "_" + to_string(i) + "\";";
text += "\"Effective PoA at " + m_solar[i]->getName() + "_" + to_string(i) + "\";";
text += "\"GHI at " + m_solar[i]->getName() + "_" + to_string(i) + "\";";
// text += "\"" + m_solar[i]->getName() + "_" + to_string(i) + " POA beam\";"; //tb - debug/validation of solar
// text += "\"" + m_solar[i]->getName() + "_" + to_string(i) + " POA diffuse\";"; //tb - debug/validation of solar
// text += "\"" + m_solar[i]->getName() + "_" + to_string(i) + " POA ground\";"; //tb - debug/validation of solar
......@@ -221,6 +225,10 @@ string InternalResult::getStringForCsvFile() const //dvresult: for only one netw
{
text += to_string(m_wind[j]->getPowerFeedAtTimeStep(i));
text += ";";
text += to_string(m_wind[j]->getWindSpeedAtTimeStep(i));
text += ";";
text += to_string(m_wind[j]->getEfficiencyAtTimeStep(i));
text += ";";
}
text += to_string(m_windLoad[i]) + ";";
}
......@@ -230,6 +238,10 @@ string InternalResult::getStringForCsvFile() const //dvresult: for only one netw
{
text += to_string(m_solar[j]->getPowerFeedAtTimeStep(i));
text += ";";
text += to_string(m_solar[j]->getEffectiveIrradiationAtTimeStep(i));
text += ";";
text += to_string(m_solar[j]->getGlobalHorizontalIrradiationAtTimeStep(i));
text += ";";
//previous debug info (TODO: connect to logLevel)
// text += to_string(m_solar[j]->getPOAbeamIrradianceAtTimeStep(i));
// text += ";";
......
......@@ -31,6 +31,7 @@
#include "Storage.h"
#include "Wind.h"
//#include "Grid.h"
#include "Location.h"
//dv
......@@ -153,15 +154,16 @@ private:
//////////////////////////
/// config
//////////////////////////
bool m_holdsResults; //whether or not the config has all results
vector<Biomass *> m_biomass; //all biomass plants in network
vector<Conventional *> m_conventional; //all conventional plants in network
vector<Storage *> m_storage; //all storage plants in network
vector<Solar *> m_solar; //all solar parks in network
vector<CSP *> m_csp; //all CSP plants in network
vector<Wind *> m_wind; //all wind parks in network
double m_solarCapacityGeneric; //value needed for default-option (non-weather data)
double m_windCapacityGeneric; //value needed for default-option (non-weather data)
bool m_holdsResults; //!< whether or not the config has all results
vector<Biomass *> m_biomass; //!< all biomass plants in network
vector<Conventional *> m_conventional; //!< all conventional plants in network
vector<Storage *> m_storage; //!< all storage plants in network
vector<Solar *> m_solar; //!< all solar parks in network
vector<CSP *> m_csp; //!< all CSP plants in network
vector<Wind *> m_wind; //!< all wind parks in network
const Location * m_location; //!< location used for that node
double m_solarCapacityGeneric; //!< value needed for default-option (non-weather data)
double m_windCapacityGeneric; //!< value needed for default-option (non-weather data)
//////////////////////////
/// demands
......
......@@ -33,7 +33,7 @@
* Returns the component admittance matrix in sparse format, this way
* the composition of the circuit admittance matrix is straight forward
*/
void Line::getAdmittance(int n, Eigen::MatrixXcd & admittancesGrid)
void Line::applyAdmittanceToMatrix(int n, Eigen::MatrixXcd & admittancesGrid)
{
if (n > m_indexNode1 && n > m_indexNode2)
{
......
......@@ -36,7 +36,7 @@ public:
virtual ~Line();
void getAdmittance(int n, Eigen::MatrixXcd & admittancesGrid);
void applyAdmittanceToMatrix(int n, Eigen::MatrixXcd & admittancesGrid);
private:
......
#include "Location.h"
#include <cmath>
#include <iostream>
#include <QFile>
#include <QTextStream>
#define PI 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803
......@@ -30,6 +34,12 @@ Location::Location(string name, double lat , double lon, double areaSolar, doubl
{
}
Location::~Location()
{
// Do not delete pointers, as this might be used again. The data is only referenced to and
// where it is referenced from is also the place to delete the data, if need be
}
//set functions (all the same, setting with a security request againt nullptr) --------------------
void Location::setPowerDemand(const vector<float> * demand)
{
......@@ -64,11 +74,29 @@ void Location::setSolarDataMode(bool isDNI)
void Location::setGHI_DiffHI(const vector<float> * ghi_dhi)
{
if (ghi_dhi != nullptr) m_ghi_dhi = ghi_dhi;
QFile f("F:/AutoResults/Data/" + QString::fromStdString(m_name) + "_diffIrrL.csv");
f.open(QIODevice::WriteOnly);
QTextStream stream(&f);
for (size_t i = 0; i < m_ghi_dhi->size(); i++)
{
stream << m_ghi_dhi->at(i) << "\n";
}
f.close();
}
void Location::setDirIrr(const vector<float> * dirHI)
{
if (dirHI != nullptr) m_dirIrr = dirHI;
QFile f("F:/AutoResults/Data/" + QString::fromStdString(m_name) + "_dirIrrL.csv");
f.open(QIODevice::WriteOnly);
QTextStream stream(&f);
for (size_t i = 0; i < m_dirIrr->size(); i++)
{
stream << m_dirIrr->at(i) << "\n";
}
f.close();
}
void Location::setTemperatures(const vector<float> * temps)
......@@ -101,6 +129,16 @@ void Location::setTemperaturesForecast(const vector<vector<float> > * temps)
if (temps != nullptr) m_forecastTemperature = temps;
}
double Location::getLatitude() const
{
return m_lat;
}
double Location::getLongitude() const
{
return m_lon;
}
bool Location::hasDemandData() const
{
return m_powerDemand != nullptr;
......@@ -171,24 +209,25 @@ vector<double> Location::getPowerDemandForecast(size_t index) const
* @see <a href="MasterThesisAmmon.pdf#page=25">Master Thesis Ammon eq. 2.10</a>
* @see <a href="https://pvpmc.sandia.gov/modeling-steps/1-weather-design-inputs/sun-position/simple-models/"> Sandia SPA Simple Models </a>
*/
double Location::calculateEquationOfTimeInHours(double timeInDays)
double Location::calculateEquationOfTimeInHours(double timeInDays) const
{
int day = static_cast<int>(timeInDays);
double minutesPerHour = 60.;
if (timeInDays < 107.)
if (day < 107)
{
return -14.2 * sin(PI * (timeInDays + 7.) / 111.) / minutesPerHour;
return -14.2 * sin(PI * (day + 7.) / 111.) / minutesPerHour;
}
else if((timeInDays >= 107.) && (timeInDays < 167.))
else if((day >= 107) && (day < 167))
{
return 4. * sin(PI * (timeInDays - 106.) / 59.) / minutesPerHour;
return 4. * sin(PI * (day - 106.) / 59.) / minutesPerHour;
}
else if((timeInDays >= 167.) && (timeInDays < 246.))
else if((day >= 167) && (day < 247))
{
return -6.5 * sin(PI * (timeInDays - 166.) / 80.) / minutesPerHour;
return -6.5 * sin(PI * (day - 166.) / 80.) / minutesPerHour;
}
else
{
return 16.4 * sin(PI * (timeInDays - 247.) / 113.) / minutesPerHour;
return 16.4 * sin(PI * (day - 247.) / 113.) / minutesPerHour;
}
}
......@@ -203,10 +242,11 @@ double Location::calculateEquationOfTimeInHours(double timeInDays)
* (modified by replacing \f$ t_{h} \f$ by \f$ d_{l,sec} / secPerHour \f$)
* @see <a href="https://pvpmc.sandia.gov/modeling-steps/1-weather-design-inputs/sun-position/simple-models/"> Sandia SPA Simple Models </a>
*/
double Location::calculateLocalMeanTimeInHours(double timeInDays)
double Location::calculateLocalMeanTimeInHours(double timeInDays) const
{
double localHour = (timeInDays - std::floor(timeInDays)) * 24.;
return localHour - (m_preferences->getLongitudeReference() - m_lon) / 15.; //15. as there are 15° between each time zone
localHour += calculateEquationOfTimeInHours(timeInDays);
return localHour + (m_preferences->getLongitudeReference() - m_lon) / 15.; //15. as there are 15° between each time zone
}
/**
......@@ -219,18 +259,19 @@ double Location::calculateLocalMeanTimeInHours(double timeInDays)
*/
double Location::getSolarDeclinationInDeg(double localDayTimeInDays) const
{
return 23.45 * sin(2. * PI * (284. + localDayTimeInDays) / 365.);
return 23.45 * sin(2. * PI * (284. + std::floor(localDayTimeInDays)) / 365.)
* PI / 180.;
}
/**
* @brief \f$ \theta_h = \left(12 - t_{h,tl} \right) \cdot 15 \f$
* @param trueLocalTimeInHours \f$ t_{h,tl} \f$
* @return solarDeclinationInDeg \f$ \theta_h \f$
* @return true hour angle in deg \f$ \theta_h \f$
* @see <a href="MasterThesisAmmon.pdf#page=25">Master Thesis Ammon eq. 2.7</a>
* (modified by replacing factor \f$ 180/12 \f$ by \f$ 15 \f$)
* @see <a href="https://pvpmc.sandia.gov/modeling-steps/1-weather-design-inputs/sun-position/simple-models/"> Sandia SPA Simple Models </a>
*/
double Location::calculateTrueHourAngleInDeg(double trueLocalTimeInHours)
double Location::calculateTrueHourAngleInDeg(double trueLocalTimeInHours) const
{
return (12. - trueLocalTimeInHours) * 15.;
}
......@@ -247,14 +288,11 @@ double Location::getSolarElevationInDeg(double trueHourAngleInDeg, double solarD
{
double dTR = PI / 180.; // convert degree to radiant
double rTD = 180. / PI; // convert radiant to degree
double solarZenithInDeg = rTD * acos(cos(trueHourAngleInDeg * dTR)
* cos(m_lat * dTR)
* cos(solarDeclinationInDeg * dTR)
+ sin(m_lat * dTR)
* sin(solarDeclinationInDeg * dTR));
double solarElevationInDeg = 90. - solarZenithInDeg;
return solarElevationInDeg;
return rTD * asin(cos(trueHourAngleInDeg * dTR)
* cos(m_lat * dTR)
* cos(solarDeclinationInDeg * dTR)
+ sin(m_lat * dTR)
* sin(solarDeclinationInDeg * dTR));
}
/**
......@@ -442,6 +480,11 @@ double Location::getDirectNormalIrridiation(size_t timeStep, double solarElevati
/ sin(solarElevationInDeg * PI / 180.);
}
double Location::getHorizontalDiffuseIrridiation(size_t timeStep) const
{
return m_ghi_dhi->at(timeStep);
}
double Location::getWindSpeed(size_t step) const
{
if (m_meridionalIsDirection && m_windSpeedsZonal
......
......@@ -23,13 +23,14 @@
#include <tuple>
#include <string>
class Location
class CHARLALGORITHMSHARED_EXPORT Location
{
enum DiffuseIrradianceMode{Perez, Sandia, SandiaSimple};
public:
Location(string name, double lat , double lon,
double areaSolar, double areaWind,
const SimulationPreferences * preferences);
virtual ~Location();
//set functions ---------------------------------------
void setPowerDemand(const vector<float> * demand);
......@@ -48,14 +49,16 @@ public:
void setTemperaturesForecast(const vector<vector<float>> * temps);
//get functions ---------------------------------------
double getLatitude() const;
double getLongitude() const;
bool hasDemandData() const;
double getPowerDemand(size_t step) const;
double getReactivePowerDemand(size_t step) const;
vector<double> getPowerDemandForecast(size_t index) const;
//solar utilities -------------------------------------
double calculateEquationOfTimeInHours(double timeInDays);
double calculateLocalMeanTimeInHours(double timeInDays);
double calculateTrueHourAngleInDeg(double trueLocalTimeInHours);
double calculateEquationOfTimeInHours(double timeInDays) const;
double calculateLocalMeanTimeInHours(double timeInDays) const;
double calculateTrueHourAngleInDeg(double trueLocalTimeInHours) const;
double getSolarDeclinationInDeg(double localDayTimeInDays) const;
double getSolarElevationInDeg(double trueHourAngleInDeg,
double solarDeclinationInDeg) const;
......@@ -85,6 +88,7 @@ public:
size_t timeStep) const;
double getDirectNormalIrridiation(size_t timeStep,
double solarElevationInDeg) const;
double getHorizontalDiffuseIrridiation(size_t timeStep) const;
//wind utitilities ------------------------------------
double getWindSpeed(size_t step) const;
double getWindDirection(size_t step) const;
......
#ifndef NETWORK_H
#define NETWORK_H
#ifndef NODE_H
#define NODE_H
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
......@@ -36,10 +36,12 @@ using namespace std;