Commit a4da301b authored by Gerrit Erichsen's avatar Gerrit Erichsen
Browse files

Added arbitrary minimum efficiency for storage charging. This fixed divide by...

Added arbitrary minimum efficiency for storage charging. This fixed divide by 0 errors. TODO: Find a better way
parent 083691bb
......@@ -117,16 +117,17 @@ vector<pair<double, double> > EfficiencyField::getFixedCurve(bool front, bool al
return result;
}
double EfficiencyField::getEfficiency(double x, double y) const
double EfficiencyField::getEfficiency(double x, double y,
double minValue) const
{
size_t indexX1, indexX2, indexY1, indexY2;
//set x indices
indexX2 = findUpperIndex(x, m_xAxis);
if (indexX2 > m_xAxis.size()) return 0.;
if (indexX2 > m_xAxis.size()) return minValue;
indexX1 = (indexX2 > 0) ? indexX2 - 1 : 0;
//set y indices
indexY2 = findUpperIndex(y, m_yAxis);
if (indexY2 > m_yAxis.size()) return 0.;
if (indexY2 > m_yAxis.size()) return minValue;
indexY1 = (indexY2 > 0) ? indexY2 - 1 : 0;
//calculate 2-D interpolation, first major case x1 matches x
if (isCloseEnoughToEqual(x, m_xAxis[indexX1])
......
......@@ -27,7 +27,7 @@ public:
double getMinY() const;
double getMaxY() const;
vector<pair<double, double>> getFixedCurve(bool front, bool alongX);
double getEfficiency(double x, double y) const;
double getEfficiency(double x, double y, double minValue = 0.) const;
double getEfficiencyCapped(double x, double y) const;
double getEfficiencyTopLeft() const;
double getEfficiencyBottomRight() const;
......
......@@ -1171,6 +1171,7 @@ void Node::calculateStoragePower(size_t timeStep)
}
//power equal or greater than maxPower
else if (fabs(currentResidual) >= m_storage[i]->getMinPowerChargeConst()
&& m_storage[i]->getMaxPowerCharge(timeStep) > 0.
&& m_storage[i]->getMinPowerChargeConst() <= m_storage[i]->getMaxPowerCharge(timeStep))
{
powerOfPlant = -(m_storage[i]->getMaxPowerCharge(timeStep));
......
......@@ -229,9 +229,17 @@ void Storage::charge(double power, size_t step)
double powerReserve = (m_storageCapacity - lastStorageLevel) / m_preferences->getStepTime();
// this **should** be solved iteratively. But to not waste time, we'll take a random
// guess at the efficiency. This should be somewhat accurate enough
power = powerReserve / getEfficiencyCharge(step,
powerReserve
/ m_efficiencyDischarge.getEfficiencyBottomRight()); //"power" for efficiency not entirely correct, though
double efficiency = getEfficiencyCharge(step,
powerReserve
/ m_efficiencyCharge.getEfficiencyBottomRight());
if (isCloseEnoughToEqual(efficiency, 0.))
{
power = std::min(power, powerReserve / 1e-5); // 1 permille as effictive min efficiency
}
else
{
power = powerReserve / efficiency;
}
m_lastStepOfPower = step;
}
else
......@@ -499,6 +507,8 @@ double Storage::getMaxPowerCharge(size_t step) const
//defining helper value, since previous step of first step is last step
double lastStorageLevel = (step == 0) ? m_initialStorageLevel : m_storageLevel[step - 1];
double power = (m_storageCapacity - lastStorageLevel) / m_preferences->getStepTime();
//safety to charge at least 1 W or m_minPowerCharge
if (power < m_minPowerCharge) return 0.;
return std::min(m_maxPowerCharge, power / getEfficiencyCharge(step, power));
}
......@@ -548,15 +558,7 @@ double Storage::getMaxPowerDischarge(size_t step) const
double Storage::getEfficiencyCharge(size_t step, double power) const
{
double lastStorageLevel;
if (step == 0)
{
lastStorageLevel = m_initialStorageLevel;
}
else
{
lastStorageLevel = m_storageLevel[step - 1];
}
double lastStorageLevel = (step == 0) ? m_initialStorageLevel : m_storageLevel.at(step -1);
double eta = 0.;
if (m_preferences->getLevelOfInterpolation() == 1)
{
......@@ -564,7 +566,8 @@ double Storage::getEfficiencyCharge(size_t step, double power) const
&& lastStorageLevel <= m_storageCapacity)
{
eta = m_efficiencyDischarge.getEfficiency(power / m_nominalPowerCharge,
lastStorageLevel / m_storageCapacity);
lastStorageLevel / m_storageCapacity,
1e-6);
}
else
{
......@@ -585,15 +588,7 @@ double Storage::getEfficiencyCharge(size_t step, double power) const
double Storage::getEfficiencyDischarge(size_t step, double power) const
{
double lastStorageLevel;
if (step == 0)
{
lastStorageLevel = m_initialStorageLevel;
}
else
{
lastStorageLevel = m_storageLevel[step - 1];
}
double lastStorageLevel = (step == 0) ? m_initialStorageLevel : m_storageLevel.at(step -1);
if (m_preferences->getLevelOfInterpolation() == 1)
{
......
......@@ -1066,7 +1066,6 @@ void CharLGui::runAlgorithm()
// CALCULATE ALL OPTIONS //
//////////////////////////////////////
int nMaxThreads = std::max(1, QThreadPool::globalInstance()->maxThreadCount() - 1);
nMaxThreads = 1;
int i = 0;
while (i < nTotalOptions)
{
......@@ -1109,7 +1108,7 @@ void CharLGui::runAlgorithm()
//////////////////////////////////////
// UPDATE TIME ESTIMATE //
//////////////////////////////////////
if (i % 20 == 0 || i >= nTotalOptions)
if (i % 20 == 0 || i >= nTotalOptions || nTotalOptions < 100)
{
averageTime = time.elapsed() / (i );
remainingTimeEstimateMs = (nTotalOptions - i) * averageTime;
......@@ -1371,6 +1370,7 @@ bool CharLGui::configureAlgorithm(CharLAlgorithm * algorithm,
if (turbine->isEfficiencyAvailable(powerDensity,
m_preferences->getPowerDensityEquivalence()))
{
qDebug() << "Added from file";
EfficiencyField field = turbine->getEfficiencyField(powerDensity,
m_preferences->getPowerDensityEquivalence());
algorithm->addWindPark(nodeIndex, locationIndex,
......
......@@ -178,14 +178,14 @@ Qt::ItemFlags ResultTableModel::flags(const QModelIndex &index) const
/// \param item
/// adds an item to the data vector. Emit signals so the change is visible.
/////////////////////////////////////////////////////////////////////////////////////
void ResultTableModel::addItem(Result * result)
void ResultTableModel::addItem(const Result * result)
{
emit layoutAboutToBeChanged();
m_data.append(result);
emit layoutChanged();
}
bool ResultTableModel::insertItem(Result * result, int pos)
bool ResultTableModel::insertItem(const Result * result, int pos)
{
if (pos < 0 || pos >= m_data.count()) return false;
m_data.insert(pos, result);
......@@ -193,7 +193,7 @@ bool ResultTableModel::insertItem(Result * result, int pos)
return true;
}
void ResultTableModel::setEntireVectorData(QVector<Result *> results, bool sort)
void ResultTableModel::setEntireVectorData(QVector<const Result *> results, bool sort)
{
emit layoutAboutToBeChanged();
m_data = results;
......
......@@ -43,9 +43,9 @@ public:
virtual Qt::ItemFlags flags(const QModelIndex &index) const;
// own functions
void addItem(Result * result);
bool insertItem(Result * result, int pos);
void setEntireVectorData(QVector<Result *> results, bool sort);
void addItem(const Result * result);
bool insertItem(const Result * result, int pos);
void setEntireVectorData(QVector<const Result *> results, bool sort);
const Result * getItem(int row);
bool removeItem(const QModelIndex & index);
void sortTableByLCOE();
......@@ -55,7 +55,7 @@ public:
QString copyText(QModelIndexList list);
private:
QVector<Result *> m_data; // collection of table items
QVector<const Result *> m_data; // collection of table items
const Preferences * m_preferences; // contains preferences of program
};
......
......@@ -30,6 +30,7 @@ WindTableItem::WindTableItem(QString name, double height, double diameter, QStri
m_ctCurveFile = "";
}
}
if (doEfficienciesExist()) loadEfficiencies();
}
bool WindTableItem::isEfficiencyAvailable(int powerDensity, int acceptableDiff) const
......@@ -187,7 +188,11 @@ bool WindTableItem::addEfficiencyField(int powerDensity, const EfficiencyField &
bool WindTableItem::doEfficienciesExist() const
{
#ifdef __APPLE__
QDir directory(QDir::currentPath() + "/../../../.windEfficiencyFiles/");
#else
QDir directory(QDir::currentPath() + "/.windEfficiencyFiles/");
#endif
if (!directory.exists())
{
directory.mkpath(directory.path());
......@@ -201,7 +206,11 @@ bool WindTableItem::doEfficienciesExist() const
void WindTableItem::loadEfficiencies()
{
#ifdef __APPLE__
QDir directory(QDir::currentPath() + "/../../../.windEfficiencyFiles/");
#else
QDir directory(QDir::currentPath() + "/.windEfficiencyFiles/");
#endif
if (!directory.exists()) return;
QStringList fileList = directory.entryList(QDir::Filter::Files, QDir::SortFlag::Name);
QString textToFind = this->getName() + "_" + QString::number(m_rotorDiameter)
......@@ -215,7 +224,7 @@ void WindTableItem::loadEfficiencies()
readThread.join();
int lastUnderscorePos = fileName.lastIndexOf("_");
int densityDescriptionLength = fileName.indexOf(".") - lastUnderscorePos - 1;
int powerDensity = fileName.mid(lastUnderscorePos, densityDescriptionLength).toInt();
int powerDensity = fileName.mid(lastUnderscorePos + 1, densityDescriptionLength).toInt();
if (powerDensity > 0)
{
addEfficiencyField(powerDensity, field);
......
......@@ -18,12 +18,12 @@ void RunnableAlgorithm::run()
m_algorithm.run();
}
Result * RunnableAlgorithm::getResult()
const Result * RunnableAlgorithm::getResult()
{
Result * result = m_algorithm.getResult();
if (result->getGridShareResidual() > m_acceptableBlackout)
{
return nullptr;
}
return m_algorithm.getResult();
return result;
}
......@@ -16,7 +16,7 @@ public:
void run() override;
Result * getResult();
const Result * getResult();
private:
CharLAlgorithm m_algorithm;
......
......@@ -207,7 +207,7 @@ bool CalculationWidget::updateOptimisationProgressBar(int newValue)
/// \param result
/// if calculation time is not that important, ResultTable can be updated result by result
///////////////////////////////////////////////////////////////////////////////////////////////////
void CalculationWidget::addResult(Result * result)
void CalculationWidget::addResult(const Result * result)
{
if (result == nullptr) return;
if (m_preferences->keepAllResults())
......@@ -295,7 +295,7 @@ void CalculationWidget::addResult(Result * result)
/// \param results
/// when performance is main issue, results will be come only once in a vector containing them all
///////////////////////////////////////////////////////////////////////////////////////////////////
void CalculationWidget::setResults(QVector<Result *> & results)
void CalculationWidget::setResults(QVector<const Result *> & results)
{
m_modelResultTable->setEntireVectorData(results, m_preferences->keepAllResults());
}
......@@ -394,7 +394,7 @@ void CalculationWidget::onSaveResultsClicked(bool clicked)
/// \param newResult
/// \return
///////////////////////////////////////////////////////////////////////////////////////////////////
int CalculationWidget::getResultPositionInVector(Result * newResult)
int CalculationWidget::getResultPositionInVector(const Result * newResult)
{
//validation question, if hard targets are not met, declare newResult invalid
if (newResult->getGridSpecificCO2() > m_preferences->getTargetEmission()
......
......@@ -38,8 +38,8 @@ public:
bool updateProgressBar(int newValue);
bool updateOptimisationProgressBar(int newValue);
void addResult(Result * result);
void setResults(QVector<Result *> & results);
void addResult(const Result * result);
void setResults(QVector<const Result *> & results);
void clearTable();
QString copyFromTable(QString name);
......@@ -55,7 +55,7 @@ public slots:
void onSaveResultsClicked(bool clicked);
private:
int getResultPositionInVector(Result * newResult);
int getResultPositionInVector(const Result * newResult);
private:
QAction * m_lockAction;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment