///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2023- Equinor ASA // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. // // See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RimFlowDiagnosticsTools.h" #include "RigFlowDiagResults.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RimFlowDiagnosticsTools::TracerComp::operator()( const QString& lhs, const QString& rhs ) const { if ( !lhs.endsWith( "-XF" ) && rhs.endsWith( "-XF" ) ) { return true; } if ( lhs.endsWith( "-XF" ) && !rhs.endsWith( "-XF" ) ) { return false; } return lhs < rhs; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QList RimFlowDiagnosticsTools::calcOptionsForSelectedTracerField( FDS* flowSol, bool isInjector ) { if ( !flowSol ) return {}; QList options; std::set sortedTracers = setOfTracersOfType( flowSol, isInjector ); for ( const QString& tracerName : sortedTracers ) { QString postfix; FDS::TracerStatusType status = flowSol->tracerStatusOverall( tracerName ); if ( status == FDS::TracerStatusType::VARYING ) { postfix = " [I/P]"; } else if ( status == FDS::TracerStatusType::UNDEFINED ) { postfix = " [U]"; } options.push_back( caf::PdmOptionItemInfo( tracerName + postfix, tracerName ) ); } return options; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::set RimFlowDiagnosticsTools::setOfTracersOfType( const FDS* flowSol, bool isInjector ) { if ( !flowSol ) return {}; std::set sortedTracers; std::vector tracerNames = flowSol->tracerNames(); for ( const QString& tracerName : tracerNames ) { FDS::TracerStatusType status = flowSol->tracerStatusOverall( tracerName ); bool includeTracer = status == FDS::TracerStatusType::VARYING || status == FDS::TracerStatusType::UNDEFINED; includeTracer |= isInjector && status == FDS::TracerStatusType::INJECTOR; includeTracer |= !isInjector && status == FDS::TracerStatusType::PRODUCER; if ( includeTracer ) { sortedTracers.insert( tracerName ); } } return sortedTracers; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimFlowDiagnosticsTools::producerTracersInTimeStep( const FDS* flowSol, int timeStepIndex ) { return tracersOfStatusInTimeStep( flowSol, FDS::TracerStatusType::PRODUCER, timeStepIndex ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimFlowDiagnosticsTools::injectorTracersInTimeStep( const FDS* flowSol, int timeStepIndex ) { return tracersOfStatusInTimeStep( flowSol, FDS::TracerStatusType::INJECTOR, timeStepIndex ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimFlowDiagnosticsTools::tracersOfStatusInTimeStep( const FDS* flowSol, FDS::TracerStatusType status, int timeStepIndex ) { if ( !flowSol || timeStepIndex < 0 ) return {}; std::vector tracers; for ( const auto& tracer : flowSol->tracerNames() ) { if ( status == flowSol->tracerStatusInTimeStep( tracer, timeStepIndex ) ) { tracers.push_back( tracer ); } } return tracers; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::set RimFlowDiagnosticsTools::setOfInjectorTracersFromProducers( FDS* flowSol, const std::vector& producerTracers, std::vector timeStepIndices ) { if ( !flowSol ) return {}; const double epsilon = 1.0e-8; const bool isInjector = true; std::set communicatingInjectors; std::set injectors = RimFlowDiagnosticsTools::setOfTracersOfType( flowSol, isInjector ); for ( const QString& producer : producerTracers ) { for ( const QString& injector : injectors ) { for ( const auto& timeStepIndex : timeStepIndices ) { if ( timeStepIndex < 0 ) continue; std::pair commFluxes = flowSol->flowDiagResults()->injectorProducerPairFluxes( injector.toStdString(), producer.toStdString(), timeStepIndex ); if ( std::abs( commFluxes.first ) > epsilon || std::abs( commFluxes.second ) > epsilon ) { communicatingInjectors.insert( injector ); } } } } return communicatingInjectors; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::set RimFlowDiagnosticsTools::setOfInjectorTracersFromProducers( FDS* flowSol, const std::vector& producerTracers, int timeStepIndex ) { if ( timeStepIndex < 0 ) return {}; const auto timeStepIndices = std::vector( { timeStepIndex } ); return setOfInjectorTracersFromProducers( flowSol, producerTracers, timeStepIndices ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::set RimFlowDiagnosticsTools::setOfProducerTracersFromInjectors( FDS* flowSol, const std::vector& injectorTracers, std::vector timeStepIndices ) { if ( !flowSol ) return {}; const double epsilon = 1.0e-8; const bool isInjector = false; std::set communicatingProducers; std::set producers = RimFlowDiagnosticsTools::setOfTracersOfType( flowSol, isInjector ); for ( const QString& injector : injectorTracers ) { for ( const QString& producer : producers ) { for ( const auto& timeStepIndex : timeStepIndices ) { if ( timeStepIndex < 0 ) continue; std::pair commFluxes = flowSol->flowDiagResults()->injectorProducerPairFluxes( injector.toStdString(), producer.toStdString(), timeStepIndex ); if ( std::abs( commFluxes.first ) > epsilon || std::abs( commFluxes.second ) > epsilon ) { communicatingProducers.insert( producer ); } } } } return communicatingProducers; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::set RimFlowDiagnosticsTools::setOfProducerTracersFromInjectors( FDS* flowSol, const std::vector& injectorTracers, int timeStepIndex ) { if ( timeStepIndex < 0 ) return {}; const auto timeStepIndices = std::vector( { timeStepIndex } ); return setOfProducerTracersFromInjectors( flowSol, injectorTracers, timeStepIndices ); }