From 49a261a8f61738bb50a5d0bbae819514d2848bae Mon Sep 17 00:00:00 2001 From: Bernd Flemisch <bernd@iws.uni-stuttgart.de> Date: Wed, 5 Dec 2012 13:47:51 +0000 Subject: [PATCH] implicit branch: add cell-centered treatment to the 3p3c model, unify the test. git-svn-id: svn://svn.iws.uni-stuttgart.de/DUMUX/dumux/branches/implicit@9783 2fb0f335-1f38-0410-981e-8018bf24f1b0 --- dumux/implicit/2p2c/2p2cmodel.hh | 4 +- dumux/implicit/2p2c/2p2cvolumevariables.hh | 8 +- dumux/implicit/3p3c/3p3cmodel.hh | 316 +++++++++++------- dumux/implicit/3p3c/3p3cvolumevariables.hh | 11 +- test/implicit/3p3c/Makefile.am | 5 +- test/implicit/3p3c/infiltrationproblem.hh | 48 +-- test/implicit/3p3c/test_box3p3c.cc | 59 ++++ test/implicit/3p3c/test_box3p3c.input | 31 ++ .../3p3c/{test_3p3c.cc => test_cc3p3c.cc} | 2 +- .../{test_3p3c.input => test_cc3p3c.input} | 3 + 10 files changed, 331 insertions(+), 156 deletions(-) create mode 100644 test/implicit/3p3c/test_box3p3c.cc create mode 100644 test/implicit/3p3c/test_box3p3c.input rename test/implicit/3p3c/{test_3p3c.cc => test_cc3p3c.cc} (98%) rename test/implicit/3p3c/{test_3p3c.input => test_cc3p3c.input} (96%) diff --git a/dumux/implicit/2p2c/2p2cmodel.hh b/dumux/implicit/2p2c/2p2cmodel.hh index 82a91f9e16..19e9475954 100644 --- a/dumux/implicit/2p2c/2p2cmodel.hh +++ b/dumux/implicit/2p2c/2p2cmodel.hh @@ -266,9 +266,9 @@ public: } /*! - * \brief Returns the phase presence of the current or the old solution of a vertex. + * \brief Returns the phase presence of the current or the old solution of a degree of freedom. * - * \param globalIdx The global vertex index + * \param globalIdx The global index of the degree of freedom * \param oldSol Evaluate function with solution of current or previous time step */ int phasePresence(int globalIdx, bool oldSol) const diff --git a/dumux/implicit/2p2c/2p2cvolumevariables.hh b/dumux/implicit/2p2c/2p2cvolumevariables.hh index ac9719c58b..9591cae3f7 100644 --- a/dumux/implicit/2p2c/2p2cvolumevariables.hh +++ b/dumux/implicit/2p2c/2p2cvolumevariables.hh @@ -101,6 +101,8 @@ class TwoPTwoCVolumeVariables : public ImplicitVolumeVariables<TypeTag> typedef Dumux::MiscibleMultiPhaseComposition<Scalar, FluidSystem> MiscibleMultiPhaseComposition; typedef Dumux::ComputeFromReferencePhase<Scalar, FluidSystem> ComputeFromReferencePhase; + enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) }; + public: //! The type of the object returned by the fluidState() method typedef Dumux::CompositionalFluidState<Scalar, FluidSystem> FluidState; @@ -186,10 +188,10 @@ public: unsigned numVertices = problem.gridView().size(dim); int globalIdx; - if (numDofs != numVertices) // element data - globalIdx = problem.model().dofMapper().map(element); - else + if (isBox) // vertex data globalIdx = problem.model().dofMapper().map(element, scvIdx, dim); + else + globalIdx = problem.model().dofMapper().map(element); int phasePresence = problem.model().phasePresence(globalIdx, isOldSol); diff --git a/dumux/implicit/3p3c/3p3cmodel.hh b/dumux/implicit/3p3c/3p3cmodel.hh index c12cadbb93..bc8da5efe6 100644 --- a/dumux/implicit/3p3c/3p3cmodel.hh +++ b/dumux/implicit/3p3c/3p3cmodel.hh @@ -139,6 +139,8 @@ class ThreePThreeCModel: public GET_PROP_TYPE(TypeTag, BaseModel) typedef typename GridView::template Codim<dim>::Iterator VertexIterator; typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition; + enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) }; + public: /*! * \brief Initialize the static data with the initial solution. @@ -149,25 +151,47 @@ public: { ParentType::init(problem); - staticVertexDat_.resize(this->gridView_().size(dim)); + staticDat_.resize(this->numDofs()); setSwitched_(false); - VertexIterator it = this->gridView_().template begin<dim> (); - const VertexIterator &endit = this->gridView_().template end<dim> (); - for (; it != endit; ++it) + if (isBox) { - int globalIdx = this->dofMapper().map(*it); - const GlobalPosition &globalPos = it->geometry().corner(0); + VertexIterator it = this->gridView_().template begin<dim> (); + const VertexIterator &endit = this->gridView_().template end<dim> (); + for (; it != endit; ++it) + { + int globalIdx = this->dofMapper().map(*it); + const GlobalPosition &globalPos = it->geometry().corner(0); - // initialize phase presence - staticVertexDat_[globalIdx].phasePresence - = this->problem_().initialPhasePresence(*it, globalIdx, + // initialize phase presence + staticDat_[globalIdx].phasePresence + = this->problem_().initialPhasePresence(*it, globalIdx, globalPos); - staticVertexDat_[globalIdx].wasSwitched = false; + staticDat_[globalIdx].wasSwitched = false; - staticVertexDat_[globalIdx].oldPhasePresence - = staticVertexDat_[globalIdx].phasePresence; + staticDat_[globalIdx].oldPhasePresence + = staticDat_[globalIdx].phasePresence; + } + } + else + { + ElementIterator it = this->gridView_().template begin<0> (); + const ElementIterator &endit = this->gridView_().template end<0> (); + for (; it != endit; ++it) + { + int globalIdx = this->dofMapper().map(*it); + const GlobalPosition &globalPos = it->geometry().center(); + + // initialize phase presence + staticDat_[globalIdx].phasePresence + = this->problem_().initialPhasePresence(*this->gridView_().template begin<dim> (), + globalIdx, globalPos); + staticDat_[globalIdx].wasSwitched = false; + + staticDat_[globalIdx].oldPhasePresence + = staticDat_[globalIdx].phasePresence; + } } } @@ -175,26 +199,27 @@ public: * \brief Compute the total storage inside one phase of all * conservation quantities. * - * \param dest Contains the storage of each component for one phase + * \param storage Contains the storage of each component for one phase * \param phaseIdx The phase index */ - void globalPhaseStorage(PrimaryVariables &dest, int phaseIdx) + void globalPhaseStorage(PrimaryVariables &storage, const int phaseIdx) { - dest = 0; + storage = 0; - ElementIterator elemIt = this->gridView_().template begin<0>(); - const ElementIterator elemEndIt = this->gridView_().template end<0>(); - for (; elemIt != elemEndIt; ++elemIt) { - this->localResidual().evalPhaseStorage(*elemIt, phaseIdx); + ElementIterator eIt = this->gridView_().template begin<0>(); + const ElementIterator eEndIt = this->gridView_().template end<0>(); + for (; eIt != eEndIt; ++eIt) { + this->localResidual().evalPhaseStorage(*eIt, phaseIdx); - for (int i = 0; i < elemIt->template count<dim>(); ++i) - dest += this->localResidual().residual(i); + for (unsigned int i = 0; i < this->localResidual().storageTerm().size(); ++i) + storage += this->localResidual().storageTerm()[i]; } if (this->gridView_().comm().size() > 1) - dest = this->gridView_().comm().sum(dest); + storage = this->gridView_().comm().sum(storage); } + /*! * \brief Called by the update() method if applying the newton * method was unsuccessful. @@ -233,17 +258,17 @@ public: } /*! - * \brief Returns the phase presence of the current or the old solution of a vertex. + * \brief Returns the phase presence of the current or the old solution of a degree of freedom. * - * \param globalVertexIdx The global vertex index + * \param globalIdx The global index of the degree of freedom * \param oldSol Evaluate function with solution of current or previous time step */ - int phasePresence(int globalVertexIdx, bool oldSol) const + int phasePresence(int globalIdx, bool oldSol) const { return oldSol - ? staticVertexDat_[globalVertexIdx].oldPhasePresence - : staticVertexDat_[globalVertexIdx].phasePresence; + ? staticDat_[globalIdx].oldPhasePresence + : staticDat_[globalIdx].phasePresence; } /*! @@ -260,27 +285,28 @@ public: { typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField; - // create the required scalar fields - unsigned numVertices = this->problem_().gridView().size(dim); + // get the number of degrees of freedom + unsigned numDofs = this->numDofs(); + // create the required scalar fields ScalarField *saturation[numPhases]; ScalarField *pressure[numPhases]; ScalarField *density[numPhases]; for (int phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) { - saturation[phaseIdx] = writer.allocateManagedBuffer(numVertices); - pressure[phaseIdx] = writer.allocateManagedBuffer(numVertices); - density[phaseIdx] = writer.allocateManagedBuffer(numVertices); + saturation[phaseIdx] = writer.allocateManagedBuffer(numDofs); + pressure[phaseIdx] = writer.allocateManagedBuffer(numDofs); + density[phaseIdx] = writer.allocateManagedBuffer(numDofs); } - ScalarField *phasePresence = writer.allocateManagedBuffer (numVertices); + ScalarField *phasePresence = writer.allocateManagedBuffer (numDofs); ScalarField *moleFraction[numPhases][numComponents]; for (int i = 0; i < numPhases; ++i) for (int j = 0; j < numComponents; ++j) - moleFraction[i][j] = writer.allocateManagedBuffer (numVertices); - ScalarField *temperature = writer.allocateManagedBuffer (numVertices); - ScalarField *poro = writer.allocateManagedBuffer(numVertices); - ScalarField *perm = writer.allocateManagedBuffer(numVertices); + moleFraction[i][j] = writer.allocateManagedBuffer (numDofs); + ScalarField *temperature = writer.allocateManagedBuffer (numDofs); + ScalarField *poro = writer.allocateManagedBuffer(numDofs); + ScalarField *perm = writer.allocateManagedBuffer(numDofs); unsigned numElements = this->gridView_().size(0); ScalarField *rank = @@ -297,15 +323,19 @@ public: (*rank)[idx] = this->gridView_().comm().rank(); fvGeometry.update(this->gridView_(), *elemIt); - int numVerts = elemIt->template count<dim> (); - for (int i = 0; i < numVerts; ++i) + for (int scvIdx = 0; scvIdx < fvGeometry.numSCV; ++scvIdx) { - int globalIdx = this->vertexMapper().map(*elemIt, i, dim); + int globalIdx; + if (numDofs == numElements) // element data + globalIdx = idx; + else + globalIdx = this->vertexMapper().map(*elemIt, scvIdx, dim); + volVars.update(sol[globalIdx], this->problem_(), *elemIt, fvGeometry, - i, + scvIdx, false); for (int phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) { @@ -327,79 +357,113 @@ public: (*poro)[globalIdx] = volVars.porosity(); (*perm)[globalIdx] = volVars.permeability(); (*temperature)[globalIdx] = volVars.temperature(); - (*phasePresence)[globalIdx] = staticVertexDat_[globalIdx].phasePresence; + (*phasePresence)[globalIdx] = staticDat_[globalIdx].phasePresence; } } - writer.attachVertexData(*saturation[wPhaseIdx], "Sw"); - writer.attachVertexData(*saturation[nPhaseIdx], "Sn"); - writer.attachVertexData(*saturation[gPhaseIdx], "Sg"); - writer.attachVertexData(*pressure[wPhaseIdx], "pw"); - writer.attachVertexData(*pressure[nPhaseIdx], "pn"); - writer.attachVertexData(*pressure[gPhaseIdx], "pg"); - writer.attachVertexData(*density[wPhaseIdx], "rhow"); - writer.attachVertexData(*density[nPhaseIdx], "rhon"); - writer.attachVertexData(*density[gPhaseIdx], "rhog"); - - for (int i = 0; i < numPhases; ++i) + if (isBox) // vertex data { - for (int j = 0; j < numComponents; ++j) - { - std::ostringstream oss; - oss << "x^" - << FluidSystem::phaseName(i) - << "_" - << FluidSystem::componentName(j); - writer.attachVertexData(*moleFraction[i][j], oss.str().c_str()); + writer.attachVertexData(*saturation[wPhaseIdx], "Sw"); + writer.attachVertexData(*saturation[nPhaseIdx], "Sn"); + writer.attachVertexData(*saturation[gPhaseIdx], "Sg"); + writer.attachVertexData(*pressure[wPhaseIdx], "pw"); + writer.attachVertexData(*pressure[nPhaseIdx], "pn"); + writer.attachVertexData(*pressure[gPhaseIdx], "pg"); + writer.attachVertexData(*density[wPhaseIdx], "rhow"); + writer.attachVertexData(*density[nPhaseIdx], "rhon"); + writer.attachVertexData(*density[gPhaseIdx], "rhog"); + + for (int i = 0; i < numPhases; ++i) + { + for (int j = 0; j < numComponents; ++j) + { + std::ostringstream oss; + oss << "x^" + << FluidSystem::phaseName(i) + << "_" + << FluidSystem::componentName(j); + writer.attachVertexData(*moleFraction[i][j], oss.str().c_str()); + } } + writer.attachVertexData(*poro, "porosity"); + writer.attachVertexData(*perm, "permeability"); + writer.attachVertexData(*temperature, "temperature"); + writer.attachVertexData(*phasePresence, "phase presence"); } - writer.attachVertexData(*poro, "porosity"); - writer.attachVertexData(*perm, "permeability"); - writer.attachVertexData(*temperature, "temperature"); - writer.attachVertexData(*phasePresence, "phase presence"); + else // cell data + { + writer.attachCellData(*saturation[wPhaseIdx], "Sw"); + writer.attachCellData(*saturation[nPhaseIdx], "Sn"); + writer.attachCellData(*saturation[gPhaseIdx], "Sg"); + writer.attachCellData(*pressure[wPhaseIdx], "pw"); + writer.attachCellData(*pressure[nPhaseIdx], "pn"); + writer.attachCellData(*pressure[gPhaseIdx], "pg"); + writer.attachCellData(*density[wPhaseIdx], "rhow"); + writer.attachCellData(*density[nPhaseIdx], "rhon"); + writer.attachCellData(*density[gPhaseIdx], "rhog"); + + for (int i = 0; i < numPhases; ++i) + { + for (int j = 0; j < numComponents; ++j) + { + std::ostringstream oss; + oss << "x^" + << FluidSystem::phaseName(i) + << "_" + << FluidSystem::componentName(j); + writer.attachCellData(*moleFraction[i][j], oss.str().c_str()); + } + } + writer.attachCellData(*poro, "porosity"); + writer.attachCellData(*perm, "permeability"); + writer.attachCellData(*temperature, "temperature"); + writer.attachCellData(*phasePresence, "phase presence"); + } + writer.attachCellData(*rank, "process rank"); } /*! * \brief Write the current solution to a restart file. * - * \param outStream The output stream of one vertex for the restart file - * \param vert The vertex + * \param outStream The output stream of one entity for the restart file + * \param entity The entity, either a vertex or an element */ - void serializeEntity(std::ostream &outStream, const Vertex &vert) + template<class Entity> + void serializeEntity(std::ostream &outStream, const Entity &entity) { // write primary variables - ParentType::serializeEntity(outStream, vert); + ParentType::serializeEntity(outStream, entity); - int vertIdx = this->dofMapper().map(vert); + int globalIdx = this->dofMapper().map(entity); if (!outStream.good()) - DUNE_THROW(Dune::IOError, "Could not serialize vertex " << vertIdx); + DUNE_THROW(Dune::IOError, "Could not serialize entity " << globalIdx); - outStream << staticVertexDat_[vertIdx].phasePresence << " "; + outStream << staticDat_[globalIdx].phasePresence << " "; } /*! - * \brief Reads the current solution for a vertex from a restart - * file. + * \brief Reads the current solution from a restart file. * - * \param inStream The input stream of one vertex from the restart file - * \param vert The vertex + * \param inStream The input stream of one entity from the restart file + * \param entity The entity, either a vertex or an element */ - void deserializeEntity(std::istream &inStream, const Vertex &vert) + template<class Entity> + void deserializeEntity(std::istream &inStream, const Entity &entity) { // read primary variables - ParentType::deserializeEntity(inStream, vert); + ParentType::deserializeEntity(inStream, entity); // read phase presence - int vertIdx = this->dofMapper().map(vert); + int globalIdx = this->dofMapper().map(entity); if (!inStream.good()) DUNE_THROW(Dune::IOError, - "Could not deserialize vertex " << vertIdx); + "Could not deserialize entity " << globalIdx); - inStream >> staticVertexDat_[vertIdx].phasePresence; - staticVertexDat_[vertIdx].oldPhasePresence - = staticVertexDat_[vertIdx].phasePresence; + inStream >> staticDat_[globalIdx].phasePresence; + staticDat_[globalIdx].oldPhasePresence + = staticDat_[globalIdx].phasePresence; } @@ -414,36 +478,44 @@ public: { bool wasSwitched = false; - for (unsigned i = 0; i < staticVertexDat_.size(); ++i) - staticVertexDat_[i].visited = false; + for (unsigned i = 0; i < staticDat_.size(); ++i) + staticDat_[i].visited = false; FVElementGeometry fvGeometry; static VolumeVariables volVars; - ElementIterator it = this->gridView_().template begin<0> (); - const ElementIterator &endit = this->gridView_().template end<0> (); - for (; it != endit; ++it) + ElementIterator eIt = this->gridView_().template begin<0> (); + const ElementIterator &eEndIt = this->gridView_().template end<0> (); + for (; eIt != eEndIt; ++eIt) { - fvGeometry.update(this->gridView_(), *it); - for (int i = 0; i < fvGeometry.numVertices; ++i) + fvGeometry.update(this->gridView_(), *eIt); + for (int scvIdx = 0; scvIdx < fvGeometry.numSCV; ++scvIdx) { - int globalIdx = this->vertexMapper().map(*it, i, dim); + int globalIdx; + + if (isBox) + globalIdx = this->vertexMapper().map(*eIt, scvIdx, dim); + else + globalIdx = this->elementMapper().map(*eIt); - if (staticVertexDat_[globalIdx].visited) + if (staticDat_[globalIdx].visited) continue; - staticVertexDat_[globalIdx].visited = true; + staticDat_[globalIdx].visited = true; volVars.update(curGlobalSol[globalIdx], this->problem_(), - *it, + *eIt, fvGeometry, - i, + scvIdx, false); - const GlobalPosition &global = it->geometry().corner(i); + const GlobalPosition &globalPos = fvGeometry.subContVol[scvIdx].global; if (primaryVarSwitch_(curGlobalSol, volVars, globalIdx, - global)) + globalPos)) + { + this->jacobianAssembler().markDofRed(globalIdx); wasSwitched = true; + } } } @@ -477,12 +549,11 @@ protected: */ void resetPhasePresence_() { - int numVertices = this->gridView_().size(dim); - for (int i = 0; i < numVertices; ++i) + for (int i = 0; i < this->numDofs(); ++i) { - staticVertexDat_[i].phasePresence - = staticVertexDat_[i].oldPhasePresence; - staticVertexDat_[i].wasSwitched = false; + staticDat_[i].phasePresence + = staticDat_[i].oldPhasePresence; + staticDat_[i].wasSwitched = false; } } @@ -491,12 +562,11 @@ protected: */ void updateOldPhasePresence_() { - int numVertices = this->gridView_().size(dim); - for (int i = 0; i < numVertices; ++i) + for (int i = 0; i < this->numDofs(); ++i) { - staticVertexDat_[i].oldPhasePresence - = staticVertexDat_[i].phasePresence; - staticVertexDat_[i].wasSwitched = false; + staticDat_[i].oldPhasePresence + = staticDat_[i].phasePresence; + staticDat_[i].wasSwitched = false; } } @@ -518,14 +588,14 @@ protected: { // evaluate primary variable switch bool wouldSwitch = false; - int phasePresence = staticVertexDat_[globalIdx].phasePresence; + int phasePresence = staticDat_[globalIdx].phasePresence; int newPhasePresence = phasePresence; // check if a primary var switch is necessary if (phasePresence == threePhases) { Scalar Smin = 0; - if (staticVertexDat_[globalIdx].wasSwitched) + if (staticDat_[globalIdx].wasSwitched) Smin = -0.01; if (volVars.saturation(gPhaseIdx) <= Smin) @@ -583,7 +653,7 @@ protected: Scalar xgMax = 1.0; if (xwg + xgg + xng > xgMax) wouldSwitch = true; - if (staticVertexDat_[globalIdx].wasSwitched) + if (staticDat_[globalIdx].wasSwitched) xgMax *= 1.02; // if the sum of the mole fractions would be larger than @@ -609,7 +679,7 @@ protected: Scalar xnMax = 1.0; if (xnn > xnMax) wouldSwitch = true; - if (staticVertexDat_[globalIdx].wasSwitched) + if (staticDat_[globalIdx].wasSwitched) xnMax *= 1.02; // if the sum of the hypothetical mole fractions would be larger than @@ -649,7 +719,7 @@ protected: bool wettingFlag = 0; Scalar Smin = 0.0; - if (staticVertexDat_[globalIdx].wasSwitched) + if (staticDat_[globalIdx].wasSwitched) Smin = -0.01; if (volVars.saturation(nPhaseIdx) <= Smin) @@ -672,7 +742,7 @@ protected: Scalar xwMax = 1.0; if (xww > xwMax) wouldSwitch = true; - if (staticVertexDat_[globalIdx].wasSwitched) + if (staticDat_[globalIdx].wasSwitched) xwMax *= 1.02; // if the sum of the mole fractions would be larger than @@ -714,7 +784,7 @@ protected: bool gasFlag = 0; Scalar Smin = 0.0; - if (staticVertexDat_[globalIdx].wasSwitched) + if (staticDat_[globalIdx].wasSwitched) Smin = -0.01; if (volVars.saturation(nPhaseIdx) <= Smin) @@ -740,7 +810,7 @@ protected: Scalar xgMax = 1.0; if (xwg + xgg + xng > xgMax) wouldSwitch = true; - if (staticVertexDat_[globalIdx].wasSwitched) + if (staticDat_[globalIdx].wasSwitched) xgMax *= 1.02; // if the sum of the mole fractions would be larger than @@ -791,7 +861,7 @@ protected: Scalar xnMax = 1.0; if (xnn > xnMax) wouldSwitch = true; - if (staticVertexDat_[globalIdx].wasSwitched) + if (staticDat_[globalIdx].wasSwitched) xnMax *= 1.02; // if the sum of the hypothetical mole fraction would be larger than @@ -813,7 +883,7 @@ protected: Scalar xwMax = 1.0; if (xww > xwMax) wouldSwitch = true; - if (staticVertexDat_[globalIdx].wasSwitched) + if (staticDat_[globalIdx].wasSwitched) xwMax *= 1.02; // if the sum of the mole fractions would be larger than @@ -862,7 +932,7 @@ protected: Scalar xnMax = 1.0; if (xnn > xnMax) wouldSwitch = true; - if (staticVertexDat_[globalIdx].wasSwitched) + if (staticDat_[globalIdx].wasSwitched) xnMax *= 1.02; // if the sum of the hypothetical mole fraction would be larger than @@ -877,7 +947,7 @@ protected: } Scalar Smin = -1.e-6; - if (staticVertexDat_[globalIdx].wasSwitched) + if (staticDat_[globalIdx].wasSwitched) Smin = -0.01; if (volVars.saturation(gPhaseIdx) <= Smin) @@ -891,7 +961,7 @@ protected: } Smin = 0.0; - if (staticVertexDat_[globalIdx].wasSwitched) + if (staticDat_[globalIdx].wasSwitched) Smin = -0.01; if (volVars.saturation(wPhaseIdx) <= Smin) @@ -935,13 +1005,13 @@ protected: } } - staticVertexDat_[globalIdx].phasePresence = newPhasePresence; - staticVertexDat_[globalIdx].wasSwitched = wouldSwitch; + staticDat_[globalIdx].phasePresence = newPhasePresence; + staticDat_[globalIdx].wasSwitched = wouldSwitch; return phasePresence != newPhasePresence; } // parameters given in constructor - std::vector<StaticVars> staticVertexDat_; + std::vector<StaticVars> staticDat_; bool switchFlag_; }; diff --git a/dumux/implicit/3p3c/3p3cvolumevariables.hh b/dumux/implicit/3p3c/3p3cvolumevariables.hh index 0049fe5290..edbbf9ebc8 100644 --- a/dumux/implicit/3p3c/3p3cvolumevariables.hh +++ b/dumux/implicit/3p3c/3p3cvolumevariables.hh @@ -100,6 +100,8 @@ class ThreePThreeCVolumeVariables : public ImplicitVolumeVariables<TypeTag> static const Scalar R; // universial gas constant + enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) }; + public: //! The type of the object returned by the fluidState() method typedef Dumux::CompositionalFluidState<Scalar, FluidSystem> FluidState; @@ -128,8 +130,13 @@ public: const MaterialLawParams &materialParams = problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx); - int globalVertIdx = problem.model().dofMapper().map(element, scvIdx, dim); - int phasePresence = problem.model().phasePresence(globalVertIdx, isOldSol); + int globalIdx; + if (isBox) // vertex data + globalIdx = problem.model().dofMapper().map(element, scvIdx, dim); + else + globalIdx = problem.model().dofMapper().map(element); + + int phasePresence = problem.model().phasePresence(globalIdx, isOldSol); Scalar temp = Implementation::temperature_(priVars, problem, element, fvGeometry, scvIdx); fluidState_.setTemperature(temp); diff --git a/test/implicit/3p3c/Makefile.am b/test/implicit/3p3c/Makefile.am index 8d4fe42cbc..ca3ec4c029 100644 --- a/test/implicit/3p3c/Makefile.am +++ b/test/implicit/3p3c/Makefile.am @@ -1,8 +1,9 @@ -check_PROGRAMS = test_3p3c +check_PROGRAMS = test_box3p3c test_cc3p3c noinst_HEADERS = *.hh EXTRA_DIST=*reference.vtu *.input grids/*.dgf CMakeLists.txt -test_3p3c_SOURCES = test_3p3c.cc +test_box3p3c_SOURCES = test_box3p3c.cc +test_cc3p3c_SOURCES = test_cc3p3c.cc include $(top_srcdir)/am/global-rules diff --git a/test/implicit/3p3c/infiltrationproblem.hh b/test/implicit/3p3c/infiltrationproblem.hh index 3c5736ec11..a168f9d629 100644 --- a/test/implicit/3p3c/infiltrationproblem.hh +++ b/test/implicit/3p3c/infiltrationproblem.hh @@ -43,7 +43,9 @@ class InfiltrationProblem; namespace Properties { -NEW_TYPE_TAG(InfiltrationProblem, INHERITS_FROM(BoxThreePThreeC, InfiltrationSpatialParams)); +NEW_TYPE_TAG(InfiltrationProblem, INHERITS_FROM(ThreePThreeC, InfiltrationSpatialParams)); +NEW_TYPE_TAG(InfiltrationBoxProblem, INHERITS_FROM(BoxModel, InfiltrationProblem)); +NEW_TYPE_TAG(InfiltrationCCProblem, INHERITS_FROM(CCModel, InfiltrationProblem)); // Set the grid type SET_TYPE_PROP(InfiltrationProblem, Grid, Dune::YaspGrid<2>); @@ -143,6 +145,8 @@ class InfiltrationProblem : public ImplicitPorousMediaProblem<TypeTag> typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition; + enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) }; + public: /*! * \brief The constructor @@ -161,6 +165,8 @@ public: /*pressMin=*/0.8*1e5, /*pressMax=*/3*1e5, /*nPress=*/200); + + name_ = GET_RUNTIME_PARAM(TypeTag, std::string, Problem.Name); } /*! @@ -173,8 +179,8 @@ public: * * This is used as a prefix for files generated by the simulation. */ - const char *name() const - { return "infiltration"; } + const std::string name() const + { return name_; } /*! * \brief Returns the temperature within the domain. @@ -210,12 +216,11 @@ public: * used for which equation on a given boundary segment. * * \param values The boundary types for the conservation equations - * \param vertex The vertex for which the boundary type is set + * \param globalPos The position for which the bc type should be evaluated */ - void boundaryTypes(BoundaryTypes &values, const Vertex &vertex) const + void boundaryTypesAtPos(BoundaryTypes &values, + const GlobalPosition &globalPos) const { - const GlobalPosition globalPos = vertex.geometry().center(); - if(globalPos[0] > 500. - eps_) values.setAllDirichlet(); else if(globalPos[0] < eps_) @@ -229,14 +234,12 @@ public: * boundary segment. * * \param values The dirichlet values for the primary variables - * \param vertex The vertex for which the boundary type is set + * \param globalPos The position for which the bc type should be evaluated * * For this method, the \a values parameter stores primary variables. */ - void dirichlet(PrimaryVariables &values, const Vertex &vertex) const + void dirichletAtPos(PrimaryVariables &values, const GlobalPosition &globalPos) const { - const GlobalPosition globalPos = vertex.geometry().center(); - Scalar y = globalPos[1]; Scalar x = globalPos[0]; Scalar Sw, Swr=0.12, Sgr=0.03; @@ -286,8 +289,13 @@ public: int scvIdx, const int boundaryFaceIdx) const { - const GlobalPosition &globalPos = element.geometry().corner(scvIdx); values = 0; + + GlobalPosition globalPos; + if (isBox) + globalPos = element.geometry().corner(scvIdx); + else + globalPos = is.geometry().center(); // negative values for injection if ((globalPos[0] <= 75.+eps_) && (globalPos[0] >= 50.+eps_) && (globalPos[1] >= 10.-eps_)) @@ -309,21 +317,14 @@ public: * \brief Evaluate the initial value for a control volume. * * \param values The initial values for the primary variables - * \param element The finite element - * \param fvGeometry The finite-volume geometry in the box scheme - * \param scvIdx The local vertex index + * \param globalPos The position for which the initial condition should be evaluated * * For this method, the \a values parameter stores primary * variables. */ - void initial(PrimaryVariables &values, - const Element &element, - const FVElementGeometry &fvGeometry, - int scvIdx) const + void initialAtPos(PrimaryVariables &values, const GlobalPosition &globalPos) const { - const GlobalPosition &globalPos = element.geometry().corner(scvIdx); - - initial_(values, globalPos, element); + initial_(values, globalPos); } /*! @@ -345,7 +346,7 @@ private: // internal method for the initial condition (reused for the // dirichlet conditions!) void initial_(PrimaryVariables &values, - const GlobalPosition &globalPos, const Element &element) const + const GlobalPosition &globalPos) const { Scalar y = globalPos[1]; Scalar x = globalPos[0]; @@ -400,6 +401,7 @@ private: Scalar temperature_; Scalar eps_; + std::string name_; }; } //end namespace diff --git a/test/implicit/3p3c/test_box3p3c.cc b/test/implicit/3p3c/test_box3p3c.cc new file mode 100644 index 0000000000..49e2db460a --- /dev/null +++ b/test/implicit/3p3c/test_box3p3c.cc @@ -0,0 +1,59 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program 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 2 of the License, or * + * (at your option) any later version. * + * * + * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +/*! + * \file + * + * \brief test for the 3p3c box model + */ +#include "config.h" +#include "infiltrationproblem.hh" +#include <dumux/common/start.hh> + +/*! + * \brief Provides an interface for customizing error messages associated with + * reading in parameters. + * + * \param progName The name of the program, that was tried to be started. + * \param errorMsg The error message that was issued by the start function. + * Comprises the thing that went wrong and a general help message. + */ +void usage(const char *progName, const std::string &errorMsg) +{ + if (errorMsg.size() > 0) { + std::string errorMessageOut = "\nUsage: "; + errorMessageOut += progName; + errorMessageOut += " [options]\n"; + errorMessageOut += errorMsg; + errorMessageOut += "\n\nThe list of mandatory options for this program is:\n" + "\t-TimeManager.TEnd End of the simulation [s] \n" + "\t-TimeManager.DtInitial Initial timestep size [s] \n" + "\t-Grid.File Name of the file containing the grid \n" + "\t definition in DGF format\n"; + + std::cout << errorMessageOut + << "\n"; + } +} + +int main(int argc, char** argv) +{ + typedef TTAG(InfiltrationBoxProblem) ProblemTypeTag; + return Dumux::start<ProblemTypeTag>(argc, argv, usage); +} + diff --git a/test/implicit/3p3c/test_box3p3c.input b/test/implicit/3p3c/test_box3p3c.input new file mode 100644 index 0000000000..954b95f8f8 --- /dev/null +++ b/test/implicit/3p3c/test_box3p3c.input @@ -0,0 +1,31 @@ +############################################################### +# Parameter file for test_3p3c. +# Everything behind a '#' is a comment. +# Type "./test_3p3c --help" for more information. +############################################################### + +############################################################### +# Mandatory arguments +############################################################### + +[TimeManager] +DtInitial = 60 # [s] +TEnd = 864000 # [s] + +[Grid] +File = ./grids/test_3p3c.dgf + +[Problem] +Name = infiltrationbox + +############################################################### +# Simulation restart +# +# DuMux simulations can be restarted from *.drs files +# Set Restart to the value of a specific file, +# e.g.: 'Restart = 27184.1' for the restart file +# name_time=27184.1_rank=0.drs +# Please comment in the two lines below, if restart is desired. +############################################################### +# [TimeManager] +# Restart = ... diff --git a/test/implicit/3p3c/test_3p3c.cc b/test/implicit/3p3c/test_cc3p3c.cc similarity index 98% rename from test/implicit/3p3c/test_3p3c.cc rename to test/implicit/3p3c/test_cc3p3c.cc index eaa2a7b5e5..d60dcee9b2 100644 --- a/test/implicit/3p3c/test_3p3c.cc +++ b/test/implicit/3p3c/test_cc3p3c.cc @@ -53,7 +53,7 @@ void usage(const char *progName, const std::string &errorMsg) int main(int argc, char** argv) { - typedef TTAG(InfiltrationProblem) ProblemTypeTag; + typedef TTAG(InfiltrationCCProblem) ProblemTypeTag; return Dumux::start<ProblemTypeTag>(argc, argv, usage); } diff --git a/test/implicit/3p3c/test_3p3c.input b/test/implicit/3p3c/test_cc3p3c.input similarity index 96% rename from test/implicit/3p3c/test_3p3c.input rename to test/implicit/3p3c/test_cc3p3c.input index 2d36d05c82..b6ddf71376 100644 --- a/test/implicit/3p3c/test_3p3c.input +++ b/test/implicit/3p3c/test_cc3p3c.input @@ -15,6 +15,9 @@ TEnd = 864000 # [s] [Grid] File = ./grids/test_3p3c.dgf +[Problem] +Name = infiltrationcc + ############################################################### # Simulation restart # -- GitLab