/*! * \brief SimulationManager::run */ void SimulationManager::run() { if ( useSimpleSimulationFlag ) { simpleSimulation(); CoreFacade::getInstance().simulationFinished(); } else { rangeSimulation(); CoreFacade::getInstance().rangeSimulationFinished(); } }
void model::SimulationWorker::startOptimizationSlot(SimulationSetup *simSetupTemplate, bool overrideTD, double overrideValue, bool useHeatSources) { if(!mapsInitialized || busy) return; busy = true; accessLock.lock(); abort = false; accessLock.unlock(); SimulationSetup simSetup(*simSetupTemplate); emit startedWork(); optimizationN = obsSize*obsSize; simSetup.setN(obsSize); // DeltaX double deltaX = (double) 1 / (double) (simSetup.getN()-1); // Anlegen des Vektors für zu optimierende Temperaturleitkoeffizienten std::vector<AD_TYPE> optimizedCsAD; if(overrideTD) optimizedCsAD.resize(optimizationN,overrideValue); else { optimizedCsAD.resize(optimizationN,simSetup.getAreaBackgroundValue(SimulationSetup::AreaThermalDiffusivity)); // Berechnen welche Punkte von welchem Temperaturleitkoeffizienten-Gebiet // abgedeckt werden, dabei überschreiben neure Gebiete ältere emit beginningOptimizationStage("Initiale Temperaturleitkoeffizienten:",simSetup.getAreaCount(SimulationSetup::AreaThermalDiffusivity)); if(simSetup.getAreaCount(SimulationSetup::AreaThermalDiffusivity) > 0) { QList<Area*>::const_iterator it = simSetup.getAreas(SimulationSetup::AreaThermalDiffusivity).begin(); for(; it != simSetup.getAreas(SimulationSetup::AreaThermalDiffusivity).end(); ++it) { int count = 0; Area* thermalDiffusivity = *it; double diffusivity = thermalDiffusivity->getValue(); double xMin, xMax, yMin, yMax; thermalDiffusivity->getTransitiveRectangle(xMin,xMax,yMin,yMax); long xLBound = ceil(xMin/deltaX), xUBound = floor(xMax/deltaX), yLBound = ceil(yMin/deltaX), yUBound = floor(yMax/deltaX); for(long i = xLBound; i <= xUBound; ++i) for(long j = yLBound; j <= yUBound; ++j) if(thermalDiffusivity->insidePoint(i*deltaX,j*deltaX)) optimizedCsAD[i+j*n] = diffusivity; //thermalDiffusivity.getValue(i*deltaX,j*deltaX); emit finishedOptimizationStep(++count); } } } if(!useHeatSources) while(simSetup.getAreaCount(SimulationSetup::AreaHeatSource) > 0) simSetup.removeLastArea(SimulationSetup::AreaHeatSource); // Berechnen welche Punkte von welcher Wärmequelle abgedeckt werden, // zwischenspeichern als Indizes QList<QList<long> *> heatSourceIndices; if(simSetup.getAreaCount(SimulationSetup::AreaHeatSource) > 0) { emit beginningOptimizationStage("Wärmequellen", simSetup.getAreaCount(SimulationSetup::AreaHeatSource)); int count = 0; QList<Area*>::const_iterator it = simSetup.getAreas(SimulationSetup::AreaHeatSource).begin(); for(; it != simSetup.getAreas(SimulationSetup::AreaHeatSource).end(); ++it) { QList<long> * tmpListPtr = new QList<long>; Area* heatSource = *it; double xMin, xMax, yMin, yMax; heatSource->getTransitiveRectangle(xMin,xMax,yMin,yMax); long xLBound = xMin > 0 ? ceil(xMin/deltaX) : 1, xUBound = xMax < 1 ? floor(xMax/deltaX) : n-2, yLBound = yMin > 0 ? ceil(yMin/deltaX) : 1, yUBound = yMax < 1 ? floor(yMax/deltaX) : n-2; for(long i = xLBound; i <= xUBound; ++i) for(long j = yLBound; j <= yUBound; ++j) if(heatSource->insidePoint(i*deltaX,j*deltaX)) tmpListPtr->append(i+j*n); heatSourceIndices.append(tmpListPtr); emit finishedOptimizationStep(++count); } } QVector<AD_TYPE> * step1 = new QVector<AD_TYPE>(optimizationN,simSetup.getIBV(SimulationSetup::InitialValue)); QVector<AD_TYPE> * step2 = new QVector<AD_TYPE>(optimizationN,simSetup.getIBV(SimulationSetup::InitialValue)); bool tmpAbort = false; #ifndef _WIN32 accessLock.lock(); tmpAbort = abort; accessLock.unlock(); if(tmpAbort) { emit beginningOptimizationStage("Optimierung abbgebrochen",1); } else { emit beginningOptimizationStage("Optimierungschritt berechnen",simSetup.getSolverMaxIt()); int count = 0; AD_MODE::global_tape = AD_MODE::tape_t::create(); AD_TYPE norm; do { AD_MODE::global_tape->register_variable(optimizedCsAD.data(),optimizationN); QVector<AD_TYPE> tmpCs (QVector<AD_TYPE>::fromStdVector(optimizedCsAD)); QVector<AD_TYPE> * result = simpleSimulation(simSetup,step1,step2,tmpCs, heatSourceIndices); AD_TYPE J = 0; for(int i = 0; i < obsSize; ++i) { for(int j = 0; j < obsSize; ++j) { J += ((*result)[i*obsSize + j] - observations[i][j]) *((*result)[i*obsSize + j] - observations[i][j]); } } J *= 1./((obsSize-1)*(obsSize-1)); std::cout << "J" << count+1 << ": " << J << std::endl<< std::endl; dco::derivative(J) = 1; AD_MODE::global_tape->interpret_adjoint(); QVector<AD_TYPE> grad(QVector<AD_TYPE>::fromStdVector(optimizedCsAD)); for(int i = 0; i < optimizationN; ++i) grad[i] = dco::derivative(optimizedCsAD[i]); AD_TYPE s = 1e-11; for(int i = 1; i < obsSize-1; ++i) for(int j = 1; j < obsSize-1; ++j) optimizedCsAD[i*obsSize+j] -= s * grad[i*obsSize+j]; norm = algorithms::norm2(grad); accessLock.lock(); tmpAbort = abort; accessLock.unlock(); if(tmpAbort) break; emit finishedOptimizationStep(++count); AD_MODE::global_tape->reset(); } while(count < simSetup.getSolverMaxIt() && norm-simSetup.getSolverMaxError() > 0); AD_MODE::tape_t::remove(AD_MODE::global_tape); if(tmpAbort) emit beginningOptimizationStage("Optimierung abgebrochen",1); else { optimizedCs.resize(optimizationN); for(int i = 0; i < optimizationN; ++i) optimizedCs[i] = dco::value(optimizedCsAD[i]); emit beginningOptimizationStage("Optimierung abgeschlossen",1); emit finishedOptimizationStep(1); } } #endif //Aufräumen des Speichers QList<QList<long> *>::iterator it = heatSourceIndices.begin(); for(; it != heatSourceIndices.end(); ++it) delete (*it); delete step1; delete step2; optimized = true; busy = false; emit finishedOptimization(!tmpAbort); }