diff --git a/dumux/implicit/model.hh b/dumux/implicit/model.hh index 00747bb700a2f737770ffe5d9ea18b4ef68833dc..397a34f28dff9415d51a5b9b49aadeaa295b0acc 100644 --- a/dumux/implicit/model.hh +++ b/dumux/implicit/model.hh @@ -52,13 +52,19 @@ class ImplicitModel typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables; typedef typename GET_PROP_TYPE(TypeTag, JacobianAssembler) JacobianAssembler; typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables; + typedef typename GET_PROP_TYPE(TypeTag, VolumeVariablesVector) VolumeVariablesVector; typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables; + typedef typename GET_PROP_TYPE(TypeTag, SubControlVolume) SubControlVolume; + typedef typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace) SubControlVolumeFace; + typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables; + typedef typename GET_PROP_TYPE(TypeTag, FluxVariablesVector) FluxVariablesVector; enum { numEq = GET_PROP_VALUE(TypeTag, NumEq), dim = GridView::dimension }; + typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometryVector) FVElementGeometryVector; typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry; typedef typename GET_PROP_TYPE(TypeTag, LocalJacobian) LocalJacobian; typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) LocalResidual; @@ -95,10 +101,11 @@ public: updateBoundaryIndices_(); + fvGeometries_ = std::make_shared<FVElementGeometryVector>(gridView_()); + fvGeometries_.update(); + int numDofs = asImp_().numDofs(); uCur_.resize(numDofs); - volVars_.resize(numDofs); - fvGeometries_.resize(numDofs); if (isBox) boxVolume_.resize(numDofs); @@ -109,21 +116,12 @@ public: asImp_().applyInitialSolution_(); // update the volVars with the initial solution - for (const auto& element : elements(gridView_())) - { - int dofIdxGlobal = elementMapper().index(element); - volVars_[dofIdxGlobal].update(uCur_[dofIdxGlobal], - this->problem_(), - element, - fvGeometries_[dofIdxGlobal], - 0, - false); - } + volVarsVector_.update(problem_(), curSol()); // also set the solution of the "previous" time step to the // initial solution. uPrev_ = uCur_; - prevVolVars_ = volVars_; + prevVolVarsVector_ = volVarsVector_; } /*! @@ -386,7 +384,7 @@ public: if(GET_PROP_VALUE(TypeTag, AdaptiveGrid) && problem_().gridAdapt().wasAdapted()) { uPrev_ = uCur_; - prevVolVars_ = volVars_; + prevVolVarsVector_ = volVarsVector_; updateBoundaryIndices_(); @@ -410,19 +408,7 @@ public: { } void updateVolVars() - { - // update the volVars with the computed solution - for (const auto& element : Dune::elements(gridView_())) - { - int dofIdxGlobal = dofMapper().subIndex(element, 0, dofCodim); - this->volVars(dofIdxGlobal).update(curSol()[dofIdxGlobal], - this->problem_(), - element, - fvGeometries_[dofIdxGlobal], - 0, - false); - } - } + { volVarsVector_.update(problem_(), curSol()); } /*! * \brief Called by the update() method if it was @@ -435,7 +421,7 @@ public: // previous time step so that we can start the next // update at a physically meaningful solution. uCur_ = uPrev_; - volVars_ = prevVolVars_; + volVarsVector_ = prevVolVarsVector_; jacAsm_->reassembleAll(); } @@ -451,7 +437,7 @@ public: { // make the current solution the previous one. uPrev_ = uCur_; - prevVolVars_ = volVars_; + prevVolVarsVector_ = volVarsVector_; } /*! @@ -745,37 +731,59 @@ public: * \param scvIdx The index of the subcontrol volume. * \param fluidState The fluid state to fill. */ - template <class FluidState> - static void completeFluidState(const PrimaryVariables& priVars, - const Problem& problem, - const Element& element, - const FVElementGeometry& fvGeometry, - const int scvIdx, - FluidState& fluidState) - { - VolumeVariables::completeFluidState(priVars, problem, element, - fvGeometry, scvIdx, fluidState); - } + // template <class FluidState> + // static void completeFluidState(const PrimaryVariables& priVars, + // const Problem& problem, + // const Element& element, + // const FVElementGeometry& fvGeometry, + // const int scvIdx, + // FluidState& fluidState) + // { + // VolumeVariables::completeFluidState(priVars, problem, element, + // fvGeometry, scvIdx, fluidState); + // } + + const FluxVariables& fluxVars(const SubControlVolumeFace& scvf) const + { return fluxVarsVector_[scvf.index()]; } + + const FluxVariables& fluxVars(unsigned int scvfIdx) const + { return fluxVarsVector_[scvfIdx]; } + + const VolumeVariables& volVars(const SubControlVolume& scv) const + { return volVarsVector_[scv.index()]; } - const VolumeVariables& volVars(unsigned int dofIdxGlobal) const - { return volVars_[dofIdxGlobal]; } + const VolumeVariables& volVars(unsigned int scvIdx) const + { return volVarsVector_[scvIdx]; } - VolumeVariables& volVars(unsigned int dofIdxGlobal) - { return volVars_[dofIdxGlobal]; } + const VolumeVariables& prevVolVars(const SubControlVolume& scv) const + { return prevVolVarsVector_[scv.index()]; } - const VolumeVariables& prevVolVars(unsigned int dofIdxGlobal) const - { return prevVolVars_[dofIdxGlobal]; } + const VolumeVariables& prevVolVars(unsigned int scvIdx) const + { return prevVolVarsVector_[scvIdx]; } - VolumeVariables& prevVolVars(unsigned int dofIdxGlobal) - { return prevVolVars_[dofIdxGlobal]; } + const FVElementGeometryVector& fvGeometries() const + { return fvGeometries_; } - const FVElementGeometry& fvGeometries(unsigned int dofIdxGlobal) const - { return fvGeometries_[dofIdxGlobal]; } + const FVElementGeometry& fvGeometries(const Element& element) const + { return fvGeometries_.fvGeometry(elementMapper().index(element)); } - FVElementGeometry& fvGeometries(unsigned int dofIdxGlobal) - { return fvGeometries_[dofIdxGlobal]; } + const FVElementGeometry& fvGeometries(unsigned int eIdx) const + { return fvGeometries_.fvGeometry(eIdx); } protected: + // only to be called by friends and deriving classes + VolumeVariables& volVars_(const SubControlVolume& scv) + { return volVarsVector_[scv.index()]; } + + VolumeVariables& volVars_(unsigned int scvIdx) + { return volVarsVector_[scvIdx]; } + + VolumeVariables& prevVolVars_(const SubControlVolume& scv) + { return prevVolVarsVector_[scv.index()]; } + + VolumeVariables& prevVolVars_(unsigned int scvIdx) + { return prevVolVarsVector_[scvIdx]; } + /*! * \brief A reference to the problem on which the model is applied. */ @@ -813,39 +821,27 @@ protected: // iterate through leaf grid and evaluate initial // condition at the center of each sub control volume - for (const auto& element : elements(gridView_())) { + for (const auto& element : elements(gridView_())) + { // deal with the current element - int eIdx = elementMapper().index(element); - fvGeometries_[eIdx].update(gridView_(), element); - const auto& fvGeometry = fvGeometries_[eIdx]; - // loop over all element vertices, i.e. sub control volumes - for (int scvIdx = 0; scvIdx < fvGeometry.numScv; scvIdx++) + for(auto&& scv : fvGeometries(element).scvs()) { - // get the global index of the degree of freedom - int dofIdxGlobal = dofMapper().subIndex(element, scvIdx, dofCodim); - // let the problem do the dirty work of nailing down // the initial solution. - PrimaryVariables initPriVars; - Valgrind::SetUndefined(initPriVars); - problem_().initial(initPriVars, - element, - fvGeometry, - scvIdx); - Valgrind::CheckDefined(initPriVars); + auto initPriVars = problem_().initial(scv); + auto dofIdxGlobal = scv.dofIndex(); if (isBox) { // add up the initial values of all sub-control // volumes. If the initial values disagree for // different sub control volumes, the initial value // will be the arithmetic mean. - initPriVars *= fvGeometry.subContVol[scvIdx].volume; - boxVolume_[dofIdxGlobal] += fvGeometry.subContVol[scvIdx].volume; + initPriVars *= scv.volume(); + boxVolume_[dofIdxGlobal] += scv.volume(); } uCur_[dofIdxGlobal] += initPriVars; - Valgrind::CheckDefined(uCur_[dofIdxGlobal]); } } @@ -930,15 +926,21 @@ protected: // the set of all indices of vertices on the boundary std::vector<bool> boundaryIndices_; - std::vector<VolumeVariables> volVars_; - std::vector<VolumeVariables> prevVolVars_; - std::vector<FVElementGeometry> fvGeometries_; - // cur is the current iterative solution, prev the converged // solution of the previous time step SolutionVector uCur_; SolutionVector uPrev_; + // the current and previous variables (primary and secondary variables) + VolumeVariablesVector volVarsVector_; + VolumeVariablesVector prevVolVarsVector_; + + // the flux variables vector + FluxVariablesVector fluxVarsVector_; + + // the finite volume element geometries + std::shared_ptr<FVElementGeometryVector> fvGeometries_; + Dune::BlockVector<Dune::FieldVector<Scalar, 1> > boxVolume_; private: diff --git a/dumux/implicit/properties.hh b/dumux/implicit/properties.hh index 46d1b6a65deb1ff983bf17314b439fca45e8bb58..d9760735aea7e4366b6e6d9cd5fb1cabf56d3722 100644 --- a/dumux/implicit/properties.hh +++ b/dumux/implicit/properties.hh @@ -59,6 +59,11 @@ NEW_PROP_TAG(BaseLocalResidual); //!< The type of the base class of the local re NEW_PROP_TAG(LocalResidual); //!< The type of the local residual function NEW_PROP_TAG(LocalJacobian); //!< The type of the local jacobian operator +NEW_PROP_TAG(SubControlVolume);//!< The type of the sub control volume +NEW_PROP_TAG(SubControlVolumeFace); //!< The type of the sub control volume face +NEW_PROP_TAG(FVElementGeometry); //!< The type of the finite volume geometry (iterators over scvs, scvfs) +NEW_PROP_TAG(FVElementGeometryVector); //!< The type of the finite volume geometry vector + NEW_PROP_TAG(JacobianAssembler); //!< Assembles the global jacobian matrix NEW_PROP_TAG(JacobianMatrix); //!< Type of the global jacobian matrix NEW_PROP_TAG(BoundaryTypes); //!< Stores the boundary types of a single degree of freedom @@ -69,8 +74,10 @@ NEW_PROP_TAG(SolutionVector); //!< Vector containing all primary variable vector NEW_PROP_TAG(ElementSolutionVector); //!< A vector of primary variables within a sub-control volume NEW_PROP_TAG(VolumeVariables); //!< The secondary variables within a sub-control volume +NEW_PROP_TAG(VolumeVariablesVector); //!< The type for a container of volume variables NEW_PROP_TAG(ElementVolumeVariables); //!< The secondary variables of all sub-control volumes in an element NEW_PROP_TAG(FluxVariables); //!< Data required to calculate a flux over a face +NEW_PROP_TAG(FluxVariablesVector); //!< The global vector of flux variables NEW_PROP_TAG(BoundaryVariables); //!< Data required to calculate fluxes over boundary faces (outflow) // high level simulation control diff --git a/dumux/implicit/propertydefaults.hh b/dumux/implicit/propertydefaults.hh index 896f7fc9567b652b09be861be4873e34e1f39051..93e67d7a40ba55b92062b85db3c254f9b7b23e57 100644 --- a/dumux/implicit/propertydefaults.hh +++ b/dumux/implicit/propertydefaults.hh @@ -39,6 +39,9 @@ #include "model.hh" #include "localjacobian.hh" #include "volumevariables.hh" +#include "volumevariablesvector.hh" +#include "fluxvariablesvector.hh" +#include "fvelementgeometry.hh" namespace Dumux { @@ -84,9 +87,18 @@ SET_TYPE_PROP(ImplicitBase, //! Set the BaseModel to ImplicitModel SET_TYPE_PROP(ImplicitBase, BaseModel, ImplicitModel<TypeTag>); +//! The finite volume element geometry providing iterators over scvs and scv faces +SET_TYPE_PROP(ImplicitBase, FVElementGeometry, Dumux::FVElementGeometry<TypeTag>); + //! The volume variable class, to be overloaded by the model SET_TYPE_PROP(ImplicitBase, VolumeVariables, ImplicitVolumeVariables<TypeTag>); +//! The global volume variables vector class +SET_TYPE_PROP(ImplicitBase, VolumeVariablesVector, Dumux::VolumeVariablesVector<TypeTag>); + +//! The global volume variables vector class +SET_TYPE_PROP(ImplicitBase, FluxVariablesVector, Dumux::FluxVariablesVector<TypeTag>); + //! The local jacobian operator SET_TYPE_PROP(ImplicitBase, LocalJacobian, ImplicitLocalJacobian<TypeTag>);