/* Copyright 2024, SINTEF Digital This file is part of the Open Porous Media project (OPM). OPM 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. OPM 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 for more details. You should have received a copy of the GNU General Public License along with OPM. If not, see . */ #include "config.h" #include #include #include #include #include #include "../FlowExpNewtonMethod.hpp" #include #include #include #include #include // TODO: not understanding why we need FlowGenericProblem here #include #include #include // // the current code use eclnewtonmethod adding other conditions to proceed_ should do the trick for KA // // adding linearshe sould be chaning the update_ function in the same class with condition that the error is reduced. // the trick is to be able to recalculate the residual from here. // unsure where the timestepping is done from suggestedtime?? // suggestTimeStep is taken from newton solver in problem.limitTimestep namespace Opm{ template class EmptyModel : public BaseAuxiliaryModule { using Scalar = GetPropType; using GridView = GetPropType; using GlobalEqVector = GetPropType; using SparseMatrixAdapter = GetPropType; public: using Simulator = GetPropType; EmptyModel(Simulator& /*simulator*/){ }; void init(){} template void init(Something /*A*/){} void prepareTracerBatches(){}; using NeighborSet = std::set; void linearize(SparseMatrixAdapter& /*matrix*/, GlobalEqVector& /*residual*/){}; unsigned numDofs() const{return 0;}; void addNeighbors(std::vector& /*neighbors*/) const{}; //void applyInitial(){}; void initialSolutionApplied(){}; //void initFromRestart(const data::Aquifers& aquiferSoln); template void serialize(Restarter& /*res*/){}; template void deserialize(Restarter& /*res*/){}; void beginEpisode(){}; void beginTimeStep(){}; void beginIteration(){}; // add the water rate due to aquifers to the source term. template void addToSource(RateVector& /*rates*/, const Context& /*context*/, unsigned /*spaceIdx*/, unsigned /*timeIdx*/) const {} template void addToSource(RateVector& /*rates*/, unsigned /*globalSpaceIdx*/, unsigned /*timeIdx*/) const {} void endIteration()const{}; void endTimeStep(){}; void endEpisode(){}; void applyInitial(){}; template void computeTotalRatesForDof(RateType& /*rate*/, unsigned /*globalIdx*/) const{}; }; } namespace Opm::Properties { namespace TTag { template struct FlowExpCompProblem { using InheritsFrom = std::tuple; }; } template struct SparseMatrixAdapter> { private: using Scalar = GetPropType; enum { numEq = getPropValue() }; using Block = MatrixBlock; public: using type = typename Linear::IstlSparseMatrixAdapter; }; #if 0 template struct SolidEnergyLaw { private: using Scalar = GetPropType; using FluidSystem = GetPropType; public: using EclThermalLawManager = ::Opm::EclThermalLawManager; using type = typename EclThermalLawManager::SolidEnergyLaw; }; // Set the material law for thermal conduction template struct ThermalConductionLaw { private: using Scalar = GetPropType; using FluidSystem = GetPropType; public: using EclThermalLawManager = ::Opm::EclThermalLawManager; using type = typename EclThermalLawManager::ThermalConductionLaw; }; template struct SpatialDiscretizationSplice { using type = TTag::EcfvDiscretization; }; template struct LocalLinearizerSplice { using type = TTag::AutoDiffLocalLinearizer; }; #endif // Set the problem property template struct Problem> { using type = FlowProblemComp; }; template struct AquiferModel> { using type = EmptyModel; }; template struct WellModel> { using type = EmptyModel; }; template struct TracerModel> { using type = EmptyModel; }; template struct FlashSolver> { private: using Scalar = GetPropType; using FluidSystem = GetPropType; using Evaluation = GetPropType; public: using type = Opm::PTFlash; }; template struct NumComp { using type = UndefinedProperty; }; // TODO: this is unfortunate, have to check why we need to hard-code it template struct NumComp> { static constexpr int value = NumComp_; }; #if 0 struct Temperature { using type = UndefinedProperty; }; template struct Temperature { using type = GetPropType; static constexpr type value = 423.25; }; #endif template struct FluidSystem> { private: using Scalar = GetPropType; static constexpr int num_comp = getPropValue(); public: using type = Opm::GenericOilGasFluidSystem; }; template struct EnableMech> { static constexpr bool value = false; }; template struct EnableDisgasInWater> { static constexpr bool value = false; }; template struct Stencil> { private: using Scalar = GetPropType; using GridView = GetPropType; public: using type = EcfvStencil; }; template struct EnableApiTracking> { static constexpr bool value = false; }; template struct EnableTemperature> { static constexpr bool value = false; }; template struct EnableSaltPrecipitation> { static constexpr bool value = false; }; template struct EnablePolymerMW> { static constexpr bool value = false; }; template struct EnablePolymer> { static constexpr bool value = false; }; template struct EnableDispersion> { static constexpr bool value = false; }; template struct EnableBrine> { static constexpr bool value = false; }; template struct EnableVapwat> { static constexpr bool value = false; }; template struct EnableSolvent> { static constexpr bool value = false; }; template struct EnableEnergy> { static constexpr bool value = false; }; template struct EnableFoam> { static constexpr bool value = false; }; template struct EnableExtbo> { static constexpr bool value = false; }; template struct EnableMICP> { static constexpr bool value = false; }; // disable thermal flux boundaries by default #if 0 template struct EnableThermalFluxBoundaries { static constexpr bool value = false; }; #endif } // namespace Opm::Properties //! @brief Runs the simulator with the correct number of components //! //! This function will compile-time recurse from numComponentsCompileTime //! down to (inclusive) minimumNumberOfComponents and check if //! //! numComponentsCompileTime == numComponentsRuntime //! //! and if this is the case, it will star the simulator with numComponentsRuntime. //! //! @tparam minimumNumberOfComponents the minimum number of components supported //! @tparam numCompnentsCompileTime the maximum number of components supported //! @param numComponentsRuntime the number of components found the in the deck file //! @param argc argc argument from CLI //! @param argv argv argument from CLI //! //! @return error code template int startSimulationComponents(int numComponentsRuntime, int argc, char** argv) { OPM_ERROR_IF(numComponentsCompileTime < numComponentsRuntime || numComponentsRuntime < minimumNumberOfComponents, fmt::format("Deck has {} components, not supported. We support a maximum of {} components, " "and a minimum of {}.", numComponentsRuntime, numComponentsCompileTime, minimumNumberOfComponents)); if (numComponentsCompileTime == numComponentsRuntime) { return Opm::start>(argc, argv, false); } if constexpr (numComponentsCompileTime > minimumNumberOfComponents) { return startSimulationComponents(numComponentsRuntime, argc, argv); } // It will never actually reach this, but the compiler does not seem to realize, so keeping // this to avoid warnings. return EXIT_FAILURE; } int main(int argc, char** argv) { using TypeTag = Opm::Properties::TTag::FlowExpCompProblem<0>; Opm::registerEclTimeSteppingParameters(); // This is a bit cumbersome, but we need to read the input file // first to figure out the number of components (I think) in order // to select the correct type tag. // // TODO: Do a more dynamic dispatch approach similar to the normal // flow application auto comm = Dune::MPIHelper::instance(argc, argv).getCommunication(); auto commPtr = std::make_unique(comm); Opm::setupParameters_(argc, const_cast(argv), true); auto inputFilename = Opm::FlowGenericVanguard::canonicalDeckPath(Opm::Parameters::Get()); Opm::FlowGenericVanguard::setCommunication(std::move(commPtr)); Opm::FlowGenericVanguard::readDeck(inputFilename); Opm::FlowGenericVanguard vanguard; const auto numComps = vanguard.eclState().compositionalConfig().numComps(); return startSimulationComponents<2, 7>(numComps, argc, argv); }