From a24b4c585cd57c7f86d10af224e1f9cc7eee2b76 Mon Sep 17 00:00:00 2001 From: vcloarec Date: Fri, 1 Sep 2023 20:55:27 -0400 Subject: [PATCH] add option to use last time step of current result for new run --- Tests/core/reos_hydraulic_network_test.cpp | 3 +- .../telemac/test_telemac.cpp | 34 +++++- .../reoshydraulicstructure2d.cpp | 13 +- .../reoshydraulicstructure2d.h | 4 +- .../simulation/reoshydraulicsimulation.cpp | 10 +- .../simulation/reoshydraulicsimulation.h | 8 +- .../reoshydraulicstructure2dproperties.cpp | 26 +++- .../hecras/reoshecrassimulation.h | 2 +- .../telemac/reostelemac2dinitialcondition.cpp | 28 ++++- .../telemac/reostelemac2dinitialcondition.h | 17 ++- .../telemac/reostelemac2dsimulation.cpp | 111 +++++++++++------- .../telemac/reostelemac2dsimulation.h | 2 +- .../reostelemacsimulationeditwidget.cpp | 7 ++ 13 files changed, 196 insertions(+), 69 deletions(-) diff --git a/Tests/core/reos_hydraulic_network_test.cpp b/Tests/core/reos_hydraulic_network_test.cpp index f35e2c8e..b8acf7d1 100644 --- a/Tests/core/reos_hydraulic_network_test.cpp +++ b/Tests/core/reos_hydraulic_network_test.cpp @@ -236,8 +236,9 @@ void ReoHydraulicNetworkTest::calculationPropagation() controller->waitForFinished(); ReosModule::Message message; + ReosSimulationData simData = structure2D->simulationData( mNetwork->currentSchemeId(), message ); std::unique_ptr preparationProcess( - structure2D->getPreparationProcessSimulation( mNetwork->currentScheme()->calculationContext(), message ) ); + structure2D->getPreparationProcessSimulation( simData, mNetwork->currentScheme()->calculationContext(), message ) ); QVERIFY( preparationProcess ); controller = std::make_unique( preparationProcess.get() ); controller->waitForFinished(); diff --git a/Tests/simulationEngines/telemac/test_telemac.cpp b/Tests/simulationEngines/telemac/test_telemac.cpp index 8ba0ab36..268c20c5 100644 --- a/Tests/simulationEngines/telemac/test_telemac.cpp +++ b/Tests/simulationEngines/telemac/test_telemac.cpp @@ -207,7 +207,7 @@ void ReosTelemacTesting::buildStructure() int vertexCount = 86; QCOMPARE( simData.waterLevelIni.count(), vertexCount ); QCOMPARE( simData.waterDepthIni.count(), vertexCount ); - QCOMPARE( simData.velocityIni.count(), vertexCount ); + QCOMPARE( simData.velocityIni.count(), vertexCount * 2 ); for ( int vi = 0; vi < vertexCount; ++vi ) { @@ -216,6 +216,13 @@ void ReosTelemacTesting::buildStructure() QVERIFY( simData.velocityIni.at( vi ) == 0 ); } + telemacSim->setInitialCondition( ReosTelemac2DInitialCondition::Type::LastTimeStep ); + simData = hydraulicStructure->simulationData( scheme->id(), message ); + QVERIFY( message.type == ReosModule::Error ); + QCOMPARE( simData.waterDepthIniLocation, ReosSimulationData::None ); + QCOMPARE( simData.waterLevelIniLocation, ReosSimulationData::None ); + QCOMPARE( simData.velocityIniLocation, ReosSimulationData::None ); + telemacSim->setInitialCondition( ReosTelemac2DInitialCondition::Type::ConstantLevelNoVelocity ); coreModule->saveProject( projectDir.filePath( "telemac_model" ) ); @@ -226,6 +233,31 @@ void ReosTelemacTesting::buildStructure() QVERIFY( result ); QCOMPARE( result->groupCount(), 3 ); QCOMPARE( result->datasetCount( 0 ), 13 ); + + telemacSim->setInitialCondition( ReosTelemac2DInitialCondition::Type::LastTimeStep ); + simData = hydraulicStructure->simulationData( scheme->id(), message ); + QVERIFY( message.type == ReosModule::Simple ); + QCOMPARE( simData.waterDepthIniLocation, ReosSimulationData::Vertex ); + QCOMPARE( simData.waterLevelIniLocation, ReosSimulationData::Vertex ); + QCOMPARE( simData.velocityIniLocation, ReosSimulationData::Vertex ); + QCOMPARE( simData.waterLevelIni.count(), vertexCount ); + QCOMPARE( simData.waterDepthIni.count(), vertexCount ); + QCOMPARE( simData.velocityIni.count(), vertexCount * 2 ); + for ( int vi = 0; vi < vertexCount; ++vi ) + { + QVERIFY( simData.waterLevelIni.at( vi ) <= 4 && simData.waterLevelIni.at( vi ) >= 1.95 ); + QVERIFY( simData.waterDepthIni.at( vi ) <= 4 && simData.waterDepthIni.at( vi ) >= 1.95 ); + QVERIFY( simData.velocityIni.at( vi ) != 0 ); + } + + coreModule->saveProject( projectDir.filePath( "telemac_model" ) ); + QVERIFY( hydraulicStructure->runSimulation( coreModule->hydraulicNetwork()->currentScheme()->calculationContext() ) ); + + QVERIFY( hydraulicStructure->hasResults() ); + result = hydraulicStructure->results( coreModule->hydraulicNetwork()->currentScheme() ); + QVERIFY( result ); + QCOMPARE( result->groupCount(), 3 ); + QCOMPARE( result->datasetCount( 0 ), 13 ); } QTEST_MAIN( ReosTelemacTesting ) diff --git a/src/core/hydraulicNetwork/reoshydraulicstructure2d.cpp b/src/core/hydraulicNetwork/reoshydraulicstructure2d.cpp index 1ef2f4b1..4efd2fa2 100644 --- a/src/core/hydraulicNetwork/reoshydraulicstructure2d.cpp +++ b/src/core/hydraulicNetwork/reoshydraulicstructure2d.cpp @@ -727,7 +727,7 @@ QString ReosHydraulicStructure2D::meshDatasetName( const QString &id ) const return QString(); } -ReosSimulationPreparationProcess *ReosHydraulicStructure2D::getPreparationProcessSimulation( const ReosCalculationContext &context, ReosModule::Message &message ) +ReosSimulationPreparationProcess *ReosHydraulicStructure2D::getPreparationProcessSimulation( const ReosSimulationData &simData, const ReosCalculationContext &context, ReosModule::Message &message ) { if ( mMeshNeedToBeGenerated ) { @@ -748,12 +748,12 @@ ReosSimulationPreparationProcess *ReosHydraulicStructure2D::getPreparationProces return nullptr; } - return new ReosSimulationPreparationProcess( this, currentSimulation(), context, message ); + return new ReosSimulationPreparationProcess( this, currentSimulation(), simData, context ); } -ReosSimulationPreparationProcess *ReosHydraulicStructure2D::getPreparationProcessSimulation( const ReosCalculationContext &context, ReosModule::Message &message, const QDir &directory ) +ReosSimulationPreparationProcess *ReosHydraulicStructure2D::getPreparationProcessSimulation( const ReosSimulationData &simData, const ReosCalculationContext &context, ReosModule::Message &message, const QDir &directory ) { - std::unique_ptr ret( getPreparationProcessSimulation( context, message ) ); + std::unique_ptr ret( getPreparationProcessSimulation( simData, context, message ) ); ret->setDestination( directory ); return ret.release(); } @@ -831,6 +831,7 @@ bool ReosHydraulicStructure2D::runSimulation( const ReosCalculationContext &cont txtStream << QStringLiteral( "*********************************************************************************" ) << Qt::endl; ReosModule::Message message; + const ReosSimulationData simData = simulationData( context.schemeId(), message ); removeResults( context ); updateResults( context.schemeId() ); @@ -847,7 +848,7 @@ bool ReosHydraulicStructure2D::runSimulation( const ReosCalculationContext &cont } txtStream << tr( "Start preparation of simulation" ) << Qt::endl; - std::unique_ptr preparationProcess( getPreparationProcessSimulation( context, message ) ); + std::unique_ptr preparationProcess( getPreparationProcessSimulation( simData, context, message ) ); if ( !preparationProcess ) { txtStream << tr( "Simulation did not start for following reason:\n\n%1" ).arg( message.text ) << Qt::endl; @@ -1259,7 +1260,7 @@ ReosSimulationData ReosHydraulicStructure2D::simulationData( const QString &sche { ReosHydraulicSimulation *sim = simulation( scheme ); if ( sim ) - message = sim->prepareSimulationData( ret ); + message = sim->prepareSimulationData( ret, schemeId ); } else { diff --git a/src/core/hydraulicNetwork/reoshydraulicstructure2d.h b/src/core/hydraulicNetwork/reoshydraulicstructure2d.h index 02a4a686..2bc42010 100644 --- a/src/core/hydraulicNetwork/reoshydraulicstructure2d.h +++ b/src/core/hydraulicNetwork/reoshydraulicstructure2d.h @@ -193,10 +193,10 @@ class REOSCORE_EXPORT ReosHydraulicStructure2D : public ReosHydraulicNetworkElem //**************************** Calculation process related methods //! Returns a process that prepare the current simulation, caller take ownership - ReosSimulationPreparationProcess *getPreparationProcessSimulation( const ReosCalculationContext &context, ReosModule::Message &message ); + ReosSimulationPreparationProcess *getPreparationProcessSimulation( const ReosSimulationData &simData, const ReosCalculationContext &context, ReosModule::Message &message ); //! Returns a process that prepare the current simulation files in a specific \a diectory, caller take ownership - ReosSimulationPreparationProcess *getPreparationProcessSimulation( const ReosCalculationContext &context, ReosModule::Message &message, const QDir &directory ); + ReosSimulationPreparationProcess *getPreparationProcessSimulation( const ReosSimulationData &simData, const ReosCalculationContext &context, ReosModule::Message &message, const QDir &directory ); /** * Creates a new simulation process and returns a pointer to the process, the process is not started. diff --git a/src/core/hydraulicNetwork/simulation/reoshydraulicsimulation.cpp b/src/core/hydraulicNetwork/simulation/reoshydraulicsimulation.cpp index 2694e353..2091b214 100644 --- a/src/core/hydraulicNetwork/simulation/reoshydraulicsimulation.cpp +++ b/src/core/hydraulicNetwork/simulation/reoshydraulicsimulation.cpp @@ -218,12 +218,14 @@ void ReosSimulationEngineRegistery::loadDynamicLibrary() } } -ReosSimulationPreparationProcess::ReosSimulationPreparationProcess( ReosHydraulicStructure2D *hydraulicStructure, - ReosHydraulicSimulation *simulation, - const ReosCalculationContext &context, ReosModule::Message &message ) +ReosSimulationPreparationProcess::ReosSimulationPreparationProcess( + ReosHydraulicStructure2D *hydraulicStructure, + ReosHydraulicSimulation *simulation, + const ReosSimulationData &simData, + const ReosCalculationContext &context ) : mStructure( hydraulicStructure ) , mSimulation( simulation ) - , mSimulationData( hydraulicStructure->simulationData( context.schemeId(), message ) ) + , mSimulationData( simData ) , mContext( context ) , mHasMesh( mStructure->mesh()->faceCount() != 0 ) {} diff --git a/src/core/hydraulicNetwork/simulation/reoshydraulicsimulation.h b/src/core/hydraulicNetwork/simulation/reoshydraulicsimulation.h index 2599cda7..74601ef2 100644 --- a/src/core/hydraulicNetwork/simulation/reoshydraulicsimulation.h +++ b/src/core/hydraulicNetwork/simulation/reoshydraulicsimulation.h @@ -77,8 +77,8 @@ class REOSCORE_EXPORT ReosSimulationPreparationProcess: public ReosProcess ReosSimulationPreparationProcess( ReosHydraulicStructure2D *hydraulicStructure, ReosHydraulicSimulation *simulation, - const ReosCalculationContext &context, - ReosModule::Message &message ); + const ReosSimulationData &simData, + const ReosCalculationContext &context ); void setDestination( const QDir &destination ); void start() override; @@ -148,7 +148,7 @@ class REOSCORE_EXPORT ReosHydraulicSimulation : public ReosDataObject SIP_ABSTRA virtual QString key() const = 0; virtual ReosEncodedElement encode() const = 0 SIP_SKIP; - virtual ReosModule::Message prepareSimulationData( ReosSimulationData &simData ) = 0 SIP_SKIP; + virtual ReosModule::Message prepareSimulationData( ReosSimulationData &simData, const QString &schemeId ) = 0 SIP_SKIP; virtual void prepareInput( const ReosSimulationData &simulationData, const ReosCalculationContext &calculationContext ) = 0 SIP_SKIP; @@ -309,7 +309,7 @@ class REOSCORE_EXPORT ReosHydraulicSimulationDummy : public ReosHydraulicSimulat virtual QString key() const override {return QStringLiteral( "dummy-simulation" );} virtual ReosEncodedElement encode() const override {return ReosEncodedElement();}; - ReosModule::Message prepareSimulationData( ReosSimulationData & ) override {return ReosModule::Message();} + ReosModule::Message prepareSimulationData( ReosSimulationData &, const QString & ) override {return ReosModule::Message();} virtual void prepareInput( const ReosSimulationData &, const ReosCalculationContext & ) override {}; diff --git a/src/gui/hydraulicNetwork/structure2d/reoshydraulicstructure2dproperties.cpp b/src/gui/hydraulicNetwork/structure2d/reoshydraulicstructure2dproperties.cpp index f343de16..feb4b718 100644 --- a/src/gui/hydraulicNetwork/structure2d/reoshydraulicstructure2dproperties.cpp +++ b/src/gui/hydraulicNetwork/structure2d/reoshydraulicstructure2dproperties.cpp @@ -422,6 +422,15 @@ void ReosHydraulicStructure2DProperties::onLaunchCalculation() return; } + ReosModule::Message message; + const ReosSimulationData simData = mStructure2D->simulationData( mCalculationContext.schemeId(), message ); + + if ( message.type == ReosModule::Error ) + { + QMessageBox::warning( this, tr( "Run Simulation" ), tr( "Simulation did not start for following reason:\n\n%1" ).arg( message.text ) ); + emit mStructure2D->network()->emitMessage( message, false ); + return; + } mStructure2D->removeResults( mCalculationContext ); mStructure2D->updateResults( mCalculationContext.schemeId() ); @@ -429,11 +438,12 @@ void ReosHydraulicStructure2DProperties::onLaunchCalculation() ReosHydraulicScheme *scheme = mStructure2D->network()->scheme( mCalculationContext.schemeId() ); mStructure2D->currentSimulation()->saveConfiguration( scheme ); - ReosModule::Message message; - std::unique_ptr preparationProcess( mStructure2D->getPreparationProcessSimulation( mCalculationContext, message ) ); + + std::unique_ptr preparationProcess( mStructure2D->getPreparationProcessSimulation( simData, mCalculationContext, message ) ); if ( !preparationProcess ) { QMessageBox::warning( this, tr( "Run Simulation" ), tr( "Simulation did not start for following reason:\n\n%1" ).arg( message.text ) ); + emit mStructure2D->network()->emitMessage( message, false ); return; } @@ -471,14 +481,22 @@ void ReosHydraulicStructure2DProperties::onLaunchCalculation() void ReosHydraulicStructure2DProperties::onExportSimulation() { const QString dirPath = QFileDialog::getExistingDirectory( this, "Export Simulation File", QString(), QFileDialog::ShowDirsOnly ); - const QDir dir( dirPath ); ReosModule::Message message; - std::unique_ptr preparationProcess( mStructure2D->getPreparationProcessSimulation( mCalculationContext, message, dir ) ); + const ReosSimulationData simData = mStructure2D->simulationData( mCalculationContext.schemeId(), message ); + if ( message.type == ReosModule::Error ) + { + QMessageBox::warning( this, tr( "Run Simulation" ), tr( "Simulation did not start for following reason:\n\n%1" ).arg( message.text ) ); + emit mStructure2D->network()->emitMessage( message, false ); + return; + } + + std::unique_ptr preparationProcess( mStructure2D->getPreparationProcessSimulation( simData, mCalculationContext, message, dir ) ); if ( !preparationProcess ) { QMessageBox::warning( this, tr( "Export Simulation" ), tr( "Simulation can't be exported for following reason:\n\n%1" ).arg( message.text ) ); + emit mStructure2D->network()->emitMessage( message, false ); return; } ReosProcessControler *controler = new ReosProcessControler( preparationProcess.get(), this ); diff --git a/src/simulationEngines/hecras/reoshecrassimulation.h b/src/simulationEngines/hecras/reoshecrassimulation.h index 86f4f7d5..c72f1720 100644 --- a/src/simulationEngines/hecras/reoshecrassimulation.h +++ b/src/simulationEngines/hecras/reoshecrassimulation.h @@ -54,7 +54,7 @@ class ReosHecRasSimulation : public ReosHydraulicSimulation QString key() const override; - ReosModule::Message prepareSimulationData( ReosSimulationData &simData ) override {return ReosModule::Message();} + ReosModule::Message prepareSimulationData( ReosSimulationData &simData, const QString &schemeId ) override {return ReosModule::Message();} void prepareInput( const ReosSimulationData &data, const ReosCalculationContext &calculationContext ) override; void prepareInput( const ReosSimulationData &, const ReosCalculationContext &, const QDir & ) override {} diff --git a/src/simulationEngines/telemac/reostelemac2dinitialcondition.cpp b/src/simulationEngines/telemac/reostelemac2dinitialcondition.cpp index 536c450b..087cae9e 100644 --- a/src/simulationEngines/telemac/reostelemac2dinitialcondition.cpp +++ b/src/simulationEngines/telemac/reostelemac2dinitialcondition.cpp @@ -62,7 +62,6 @@ ReosTelemac2DInitialConstantWaterLevel::ReosTelemac2DInitialConstantWaterLevel( : ReosTelemac2DInitialCondition( element, parent ) { mInitialWaterLevel = new ReosParameterDouble( tr( "Initial water level" ), false, this ); - ReosDataObject::decode( element ); } ReosEncodedElement ReosTelemac2DInitialConstantWaterLevel::encode() const @@ -80,7 +79,6 @@ ReosTelemac2DInitialConditionFromSimulation::ReosTelemac2DInitialConditionFromSi ReosTelemac2DInitialConditionFromSimulation::ReosTelemac2DInitialConditionFromSimulation( const ReosEncodedElement &element, QObject *parent ) : ReosTelemac2DInitialCondition( parent ) { - ReosDataObject::decode( element ); } ReosEncodedElement ReosTelemac2DInitialConditionFromSimulation::encode() const @@ -152,7 +150,6 @@ ReosTelemac2DInitialConditionFromInterpolation::ReosTelemac2DInitialConditionFro { mFirstValue = new ReosParameterDouble( tr( "First water level value" ), false, this ); mSecondValue = new ReosParameterDouble( tr( "Second water level value" ), false, this ); - ReosDataObject::decode( element ); } ReosEncodedElement ReosTelemac2DInitialConditionFromInterpolation::encode() const @@ -212,3 +209,28 @@ QString ReosTelemac2DInitialConditionFromInterpolation::crs() const { return mCrs; } + +ReosTelemac2DInitialConditionUseLastTimeStep::ReosTelemac2DInitialConditionUseLastTimeStep( QObject *parent ) + : ReosTelemac2DInitialCondition( parent ) +{ +} + +ReosTelemac2DInitialConditionUseLastTimeStep::ReosTelemac2DInitialConditionUseLastTimeStep( const ReosEncodedElement &element, QObject *parent ) + : ReosTelemac2DInitialCondition( parent ) +{ +} + +ReosEncodedElement ReosTelemac2DInitialConditionUseLastTimeStep::encode() const +{ + ReosEncodedElement element( QStringLiteral( "telemac-2d-initial-condition-last-time-step" ) ); + ReosDataObject::encode( element ); + return element; +} + +void ReosTelemac2DInitialConditionUseLastTimeStep::saveConfiguration( ReosHydraulicScheme * ) const +{ +} + +void ReosTelemac2DInitialConditionUseLastTimeStep::restoreConfiguration( ReosHydraulicScheme * ) +{ +} diff --git a/src/simulationEngines/telemac/reostelemac2dinitialcondition.h b/src/simulationEngines/telemac/reostelemac2dinitialcondition.h index 377c8d52..58047282 100644 --- a/src/simulationEngines/telemac/reostelemac2dinitialcondition.h +++ b/src/simulationEngines/telemac/reostelemac2dinitialcondition.h @@ -30,7 +30,8 @@ class ReosTelemac2DInitialCondition: public ReosDataObject { FromOtherSimulation, ConstantLevelNoVelocity, - Interpolation + Interpolation, + LastTimeStep }; ReosTelemac2DInitialCondition( QObject *parent = nullptr ); @@ -116,5 +117,19 @@ class ReosTelemac2DInitialConditionFromInterpolation: public ReosTelemac2DInitia QString mCrs; }; +class ReosTelemac2DInitialConditionUseLastTimeStep: public ReosTelemac2DInitialCondition +{ + Q_OBJECT + public: + ReosTelemac2DInitialConditionUseLastTimeStep( QObject *parent = nullptr ); + ReosTelemac2DInitialConditionUseLastTimeStep( const ReosEncodedElement &element, QObject *parent = nullptr ); + + Type initialConditionType() const override {return Type::LastTimeStep;} + ReosEncodedElement encode() const override; + + void saveConfiguration( ReosHydraulicScheme *scheme ) const override; + void restoreConfiguration( ReosHydraulicScheme *scheme ) override; +}; + #endif // REOSTELEMAC2DINITIALCONDITION_H diff --git a/src/simulationEngines/telemac/reostelemac2dsimulation.cpp b/src/simulationEngines/telemac/reostelemac2dsimulation.cpp index 146666a4..6e088282 100644 --- a/src/simulationEngines/telemac/reostelemac2dsimulation.cpp +++ b/src/simulationEngines/telemac/reostelemac2dsimulation.cpp @@ -63,6 +63,9 @@ ReosTelemac2DSimulation::ReosTelemac2DSimulation( const ReosEncodedElement &elem if ( elem.description() == QStringLiteral( "telemac-2d-initial-condition-water-level-interpolation" ) ) mInitialConditions.append( new ReosTelemac2DInitialConditionFromInterpolation( elem, this ) ); + + if ( elem.description() == QStringLiteral( "telemac-2d-initial-condition-last-time-step" ) ) + mInitialConditions.append( new ReosTelemac2DInitialConditionUseLastTimeStep( elem, this ) ); } init(); } @@ -72,12 +75,13 @@ bool ReosTelemac2DSimulation::hasCapability( Capability cap ) const return mCapabilities.testFlag( cap ); } -ReosModule::Message ReosTelemac2DSimulation::prepareSimulationData( ReosSimulationData &simData ) +ReosModule::Message ReosTelemac2DSimulation::prepareSimulationData( ReosSimulationData &simData, const QString &schemeId ) { int vertCount = mStructure->mesh()->vertexCount(); ReosModule::Message retMes; - + std::unique_ptr results; + int timeStepIndex = 0; switch ( initialCondition()->initialConditionType() ) { case ReosTelemac2DInitialCondition::Type::FromOtherSimulation: @@ -85,42 +89,11 @@ ReosModule::Message ReosTelemac2DSimulation::prepareSimulationData( ReosSimulat ReosTelemac2DInitialConditionFromSimulation *cifs = qobject_cast( initialCondition() ); if ( hasResult( cifs->otherSchemeId() ) ) { - std::unique_ptr results( loadSimulationResults( cifs->otherSchemeId() ) ); - int waterlevelGroupIndex = results->groupIndex( ReosHydraulicSimulationResults::DatasetType::WaterLevel ); - if ( results->datasetCount( waterlevelGroupIndex ) > cifs->timeStepIndex() ) - { - simData.waterLevelIniLocation = ReosSimulationData::Vertex; - simData.waterDepthIniLocation = ReosSimulationData::Vertex; - simData.velocityIniLocation = ReosSimulationData::Vertex; - int timeStepIndex = 0; - if ( cifs->useLastTimeStep() ) - timeStepIndex = results->timeSteps().count() - 1; - else - timeStepIndex = cifs->timeStepIndex(); - - const QVector waterLevelvalues = - results->datasetValues( results->groupIndex( ReosHydraulicSimulationResults::DatasetType::WaterLevel ), timeStepIndex ); - - if ( waterLevelvalues.count() == vertCount ) - { - simData.waterLevelIni = waterLevelvalues; - simData.waterDepthIni = - results->datasetValues( results->groupIndex( ReosHydraulicSimulationResults::DatasetType::WaterDepth ), timeStepIndex ); - simData.velocityIni = - results->datasetValues( results->groupIndex( ReosHydraulicSimulationResults::DatasetType::Velocity ), timeStepIndex ); - } - else - { - retMes.type = ReosModule::Error; - retMes.addText( tr( "Other simulation for initial conditions has results incompatible with current mesh." ) ); - } - - } + results.reset( loadSimulationResults( cifs->otherSchemeId() ) ); + if ( cifs->useLastTimeStep() ) + timeStepIndex = results->timeSteps().count() - 1; else - { - retMes.type = ReosModule::Error; - retMes.addText( tr( "Other simulation for initial conditions has results with incompatible time step count." ) ); - } + timeStepIndex = cifs->timeStepIndex(); } else { @@ -132,6 +105,7 @@ ReosModule::Message ReosTelemac2DSimulation::prepareSimulationData( ReosSimulat case ReosTelemac2DInitialCondition::Type::ConstantLevelNoVelocity: break; case ReosTelemac2DInitialCondition::Type::Interpolation: + { ReosTelemac2DInitialConditionFromInterpolation *cifi = qobject_cast( initialCondition() ); if ( cifi && cifi->line().count() > 1 ) { @@ -148,7 +122,7 @@ ReosModule::Message ReosTelemac2DSimulation::prepareSimulationData( ReosSimulat simData.velocityIniLocation = ReosSimulationData::Vertex; simData.waterLevelIni.resize( vertCount ); simData.waterDepthIni.resize( vertCount ); - simData.velocityIni.fill( 0, vertCount ); + simData.velocityIni.fill( 0, vertCount * 2 ); for ( int i = 0; i < vertCount; ++i ) { double position = ReosGeometryUtils::projectedPointDistanceFromBegining( mesh->vertexPosition( i ), mInterLine ); @@ -165,7 +139,56 @@ ReosModule::Message ReosTelemac2DSimulation::prepareSimulationData( ReosSimulat retMes.type = ReosModule::Error; retMes.addText( tr( "Interpolation line for initial conditions is not defined." ) ); } - break; + } + break; + case ReosTelemac2DInitialCondition::Type::LastTimeStep: + { + if ( hasResult( schemeId ) ) + { + results.reset( loadSimulationResults( schemeId ) ); + timeStepIndex = results->datasetCount( results->groupIndex( ReosHydraulicSimulationResults::DatasetType::WaterLevel ) ) - 1; + } + else + { + retMes.type = ReosModule::Error; + retMes.addText( tr( "Last time step of result for this scheme does not exist." ) ); + } + } + break; + } + + if ( results ) + { + int waterlevelGroupIndex = results->groupIndex( ReosHydraulicSimulationResults::DatasetType::WaterLevel ); + if ( results->datasetCount( waterlevelGroupIndex ) > timeStepIndex ) + { + + const QVector waterLevelvalues = + results->datasetValues( results->groupIndex( ReosHydraulicSimulationResults::DatasetType::WaterLevel ), timeStepIndex ); + + if ( waterLevelvalues.count() == vertCount ) + { + simData.waterLevelIniLocation = ReosSimulationData::Vertex; + simData.waterDepthIniLocation = ReosSimulationData::Vertex; + simData.velocityIniLocation = ReosSimulationData::Vertex; + simData.waterLevelIni = waterLevelvalues; + simData.waterDepthIni = + results->datasetValues( results->groupIndex( ReosHydraulicSimulationResults::DatasetType::WaterDepth ), timeStepIndex ); + simData.velocityIni = + results->datasetValues( results->groupIndex( ReosHydraulicSimulationResults::DatasetType::Velocity ), timeStepIndex ); + } + else + { + retMes.type = ReosModule::Error; + retMes.addText( tr( "Results incompatible with current mesh." ) ); + } + + } + else + { + retMes.type = ReosModule::Error; + retMes.addText( tr( "Results with incompatible time step count." ) ); + } } return retMes; @@ -1063,7 +1086,7 @@ void ReosTelemac2DSimulation::createSelafinInitialConditionFile( const ReosSimul if ( simulationData.waterLevelIni.count() != size || simulationData.waterDepthIni.count() != size || - simulationData.velocityIni.count() * 2 != size ) + simulationData.velocityIni.count() != size * 2 ) return; for ( int i = 0; i < size; ++i ) @@ -1270,6 +1293,7 @@ void ReosTelemac2DSimulation::createSteeringFile( { case ReosTelemac2DInitialCondition::Type::FromOtherSimulation: case ReosTelemac2DInitialCondition::Type::Interpolation: + case ReosTelemac2DInitialCondition::Type::LastTimeStep: stream << QStringLiteral( "COMPUTATION CONTINUED : YES\n" ); stream << QStringLiteral( "PREVIOUS COMPUTATION FILE : %1\n" ).arg( mInitialConditionFile ); break; @@ -1333,6 +1357,7 @@ void ReosTelemac2DSimulation::createSteeringFile( { case ReosTelemac2DInitialCondition::Type::FromOtherSimulation: case ReosTelemac2DInitialCondition::Type::Interpolation: + case ReosTelemac2DInitialCondition::Type::LastTimeStep: createSelafinInitialConditionFile( simulationData, verticesPosInBoundary, directory ); break; case ReosTelemac2DInitialCondition::Type::ConstantLevelNoVelocity: @@ -1429,7 +1454,8 @@ void ReosTelemac2DSimulation::initInitialCondition() types << ReosTelemac2DInitialCondition::Type::ConstantLevelNoVelocity << ReosTelemac2DInitialCondition::Type::FromOtherSimulation - << ReosTelemac2DInitialCondition::Type::Interpolation; + << ReosTelemac2DInitialCondition::Type::Interpolation + << ReosTelemac2DInitialCondition::Type::LastTimeStep; for ( ReosTelemac2DInitialCondition::Type type : std::as_const( types ) ) { @@ -1454,6 +1480,9 @@ void ReosTelemac2DSimulation::initInitialCondition() case ReosTelemac2DInitialCondition::Type::Interpolation: mInitialConditions.append( new ReosTelemac2DInitialConditionFromInterpolation( this ) ); break; + case ReosTelemac2DInitialCondition::Type::LastTimeStep: + mInitialConditions.append( new ReosTelemac2DInitialConditionUseLastTimeStep( this ) ); + break; } } } diff --git a/src/simulationEngines/telemac/reostelemac2dsimulation.h b/src/simulationEngines/telemac/reostelemac2dsimulation.h index 93b1cb44..e968ccb9 100644 --- a/src/simulationEngines/telemac/reostelemac2dsimulation.h +++ b/src/simulationEngines/telemac/reostelemac2dsimulation.h @@ -64,7 +64,7 @@ class ReosTelemac2DSimulation : public ReosHydraulicSimulation QString key() const override {return ReosTelemac2DSimulation::staticKey();} bool hasCapability( Capability cap ) const override; - ReosModule::Message prepareSimulationData( ReosSimulationData &simData ) override; + ReosModule::Message prepareSimulationData( ReosSimulationData &simData, const QString &schemeId ) override; void prepareInput( const ReosSimulationData &simulationData, const ReosCalculationContext &calculationContext ) override; void prepareInput( const ReosSimulationData &simulationData, const ReosCalculationContext &calculationContext, const QDir &directory ) override; ReosSimulationProcess *getProcess( const ReosCalculationContext &calculationContext ) const override; diff --git a/src/simulationEngines/telemac/reostelemacsimulationeditwidget.cpp b/src/simulationEngines/telemac/reostelemacsimulationeditwidget.cpp index 5a7e9475..2f1e3773 100644 --- a/src/simulationEngines/telemac/reostelemacsimulationeditwidget.cpp +++ b/src/simulationEngines/telemac/reostelemacsimulationeditwidget.cpp @@ -51,6 +51,8 @@ ReosTelemacSimulationEditWidget::ReosTelemacSimulationEditWidget( static_cast( ReosTelemac2DInitialCondition::Type::FromOtherSimulation ) ); ui->mInitialConditionTypeCombo->addItem( tr( "Interpolation line" ), static_cast( ReosTelemac2DInitialCondition::Type::Interpolation ) ); + ui->mInitialConditionTypeCombo->addItem( tr( "Use last time step of current result" ), + static_cast( ReosTelemac2DInitialCondition::Type::LastTimeStep ) ); ui->mInitialConditionTypeCombo->setCurrentIndex( ui->mInitialConditionTypeCombo->findData( @@ -250,6 +252,11 @@ QWidget *ReosTelemac2DInitialConditionWidgetFactory::createWidget( qobject_cast( initialCondition ), guiContext ); } break; + case ReosTelemac2DInitialCondition::Type::LastTimeStep: + { + return new QWidget( guiContext.parent() ); + } + break; } return nullptr;