diff --git a/dune/phasefield/base_parameters.hh b/dune/phasefield/base_parameters.hh index 47e93008ed5af59af34f174cad9380c8d72b2ad0..121e32c17dd1638c5138f11a7348f355860a655b 100644 --- a/dune/phasefield/base_parameters.hh +++ b/dune/phasefield/base_parameters.hh @@ -450,17 +450,22 @@ public: Number pf1Forcing; Number pf2Forcing; + Number PCS_Search_VelThreshold; + Number PCS_Search_MaxCHNSIter; + Params_pn_2pflow(const Dune::ParameterTree& ptree) : Params_base<Number, Mobility>(ptree), delta(ptree.get("Phasefield.delta",this->eps)), - mu_ratio(ptree.get("Pnysics.mu_ratio",1)), + mu_ratio(ptree.get("Physics.mu_ratio",(Number)1)), tw(ptree.sub("Phasefield")), htw(ptree.sub("Phasefield")), reaction(ptree.sub("Physics")), vDis(ptree.sub("Physics")), SurfaceTensionScaling(ptree.get("Physics.SurfaceTensionScaling",(Number)1)), pf1Forcing(0), - pf2Forcing(0) + pf2Forcing(0), + PCS_Search_VelThreshold(ptree.get("PCS_Search.VelThreshold",(Number)1e-3)), + PCS_Search_MaxCHNSIter(ptree.get("PCS_Search.MaxCHNSIter",(Number)100)) { } }; diff --git a/dune/phasefield/porenetwork/pn_2pflow.hh b/dune/phasefield/porenetwork/pn_2pflow.hh index a2bcca9a144132849ac9c5dc611c53707e19b8be..9af50e0faef5a1a362423201548197589557f7d7 100644 --- a/dune/phasefield/porenetwork/pn_2pflow.hh +++ b/dune/phasefield/porenetwork/pn_2pflow.hh @@ -161,7 +161,9 @@ private: std::unique_ptr<NSX_T_Newton> nsxtNewton; std::unique_ptr<Dune::VTKSequenceWriter<GV>> vtkwriter; - //------------------------------------------------------------------------------------ +//------------------------------------------------------------------------------------ +// Operators and Solving +//------------------------------------------------------------------------------------ void initializeGridOperators() @@ -238,16 +240,24 @@ private: remesh(); } + +//------------------------------------------------------------------------------------ +//Integration and Helper Functions +//------------------------------------------------------------------------------------ + + void updateKf() { param.pf1Forcing = 1; param.pf2Forcing = 0; applyNsTransmissibility(); updateKf_integration(true); + writeVTK(0); param.pf1Forcing = 0; param.pf2Forcing = 1; applyNsTransmissibility(); updateKf_integration(false); + writeVTK(1); } void updateKf_integration(bool phase1) @@ -318,13 +328,16 @@ private: capillaryPressure = pressureFluid2-pressureFluid1; } -/* RF calculateGrowthSpeed() + RF calculateGrowthSpeed() { auto productFunction = Dune::PDELab::makeGridFunctionFromCallable (gv, [&](const auto& element, const auto& xlocal){ Dune::FieldVector<double,1> phi1; dgf->phiDgf.evaluate(element, xlocal, phi1); + Dune::FieldVector<double,1> phi2; + dgf->phi2Dgf.evaluate(element, xlocal, phi2); + RF phi3 = 1 - phi1[0] - phi2[0]; - RF Rspeed = phi1[0] < 0.95 ? param.dw.eval_q(phi1[0]) : 0.0f; + RF Rspeed = phi1[0] < 0.95 ? param.tw.eval_q(phi1[0],phi2[0],phi3) : 0.0f; RF R1 = -Rspeed/param.eps*param.reaction.eval(1); return Dune::FieldVector<double,1>(-R1); }); @@ -333,7 +346,36 @@ private: return integral[0]; } -*/ + void findStationaryState() + { + + writeVTK(0); + Dune::FieldVector<double,1> integral; + param.reaction.reactionRate = 0; + int iter = 0; + RF dtmax = param.pTree.get("Time.dtMax",0.01); + param.time.dt = dtmax; + + do + { + iter++; + applyChPressureSaturation(1); + applyNsPressureSaturation(1); + auto productFunction = Dune::PDELab::makeGridFunctionFromCallable (gv, [&](const auto& element, const auto& xlocal){ + Dune::FieldVector<double,2> v; + dgf->vDgf.evaluate(element, xlocal, v); + Dune::FieldVector<double,1> phi1; + dgf->phiDgf.evaluate(element, xlocal, phi1); + Dune::FieldVector<double,1> phi2; + dgf->phi2Dgf.evaluate(element, xlocal, phi2); + return Dune::FieldVector<double,1>((phi1+phi2)*std::sqrt(v[0]*v[0]+v[1]*v[1])); + }); + Dune::PDELab::integrateGridFunction(productFunction,integral,2); + //writeVTK(iter+1); + } + while ((integral[0]>param.PCS_Search_VelThreshold) + && (iter < param.PCS_Search_MaxCHNSIter)); + } //------------------------------------------------------------------------------------ @@ -403,146 +445,234 @@ public: initialPhiSolid = phiSolid; updateKf(); */ + //findStationaryState(); + updateKf(); + std::cout << kf_11 << ", " + << kf_12 << ", " + << kf_21 << ", " + << kf_22 << std::endl; + } - RF dtmax = param.pTree.get("Time.dtMax",0.01); - param.time.dt = dtmax; - int InitialGrowthTime = param.pTree.get("test.InitialGrowthTime",0); - int FillTime = param.pTree.get("test.FillTime",100); - int EmptyTime = param.pTree.get("test.EmptyTime",200); +//------------------------------------------------------------------------------------ - param.reaction.reactionRate = 0; - for(int j=0; j<100; j++) + + void writeVTK(RF time) + { + vtkwriter->write(time,Dune::VTK::ascii); + } + + void writeCSV(std::string filename, RF time = 0, int iteration = 0) + { + try { - applyChPressureSaturation(1); - applyNsPressureSaturation(1); + std::ofstream myfile; + myfile.open(filename,std::ofstream::app); + myfile << time << ", " + << iteration << ", " + << phiFluid1 << ", " + << phiFluid2 << ", " + << phiSolid << ", " + << saturation << ", " + << pressureFluid1 << ", " + << pressureFluid2 << ", " + << capillaryPressure << ", " + << kf_11 << ", " + << kf_12 << ", " + << kf_21 << ", " + << kf_22 << std::endl; + myfile.close(); } - for(int j=0; j<InitialGrowthTime; j++) + catch(...) { - param.reaction.reactionRate = 1; - applyChReaction(1); + std::cout << "Error in write CSV File" << std::endl; } - param.reaction.reactionRate = 0; - for(int j=0; j<100; j++) + } + + void writeCSVHeader(std::string filename) + { + try { - applyChPressureSaturation(1); - applyNsPressureSaturation(1); + std::ofstream myfile; + myfile.open(filename,std::ofstream::app); + myfile << "Time" << ", " + << "Iteration" << ", " + << "Area Fluid1" << ", " + << "Area Fluid2" << ", " + << "Area Solid" << ", " + << "Saturation" << ", " + << "Pressure Fluid1" << ", " + << "Pressure Fluid2" << ", " + << "Capillary Pressure" << ", " + << "kf_11" << ", " + << "kf_12" << ", " + << "kf_21" << ", " + << "kf_22" << std::endl; + myfile.close(); } + catch(...) + { + std::cout << "Error in write CSV File" << std::endl; + } + } + - for(int i=0; i<FillTime+EmptyTime; i++) +//------------------------------------------------------------------------------------ + + void calculateFullPCS_Curve() + { + RF dtmax = param.pTree.get("Time.dtMax",0.01); + param.time.dt = dtmax; + + int InitialGrowthIter = param.pTree.get("FullPCS_Curve.InitialGrowthIter",0); + int FillIter = param.pTree.get("FullPCS_Curve.FillIter",100); + int EmptyIter = param.pTree.get("FullPCS_Curve.EmptyIter",200); + + findStationaryState(); + for(int j=0; j<InitialGrowthIter; j++) { - if(i<FillTime) + param.reaction.reactionRate = 1; + applyChReaction(1); + } + findStationaryState(); + + writeCSVHeader("pressuresaturation.csv"); + for(int i=0; i<FillIter+EmptyIter; i++) + { + if(i<FillIter) { param.reaction.reactionRate = 1; + applyChPressureSaturation(1); } else { param.reaction.reactionRate = -1; - } - applyChPressureSaturation(1); - param.reaction.reactionRate = 0; - for(int j=0; j<20; j++) - { applyChPressureSaturation(1); - applyNsPressureSaturation(1); - //writeVTK(i+((RF)j+1)/21); } + + findStationaryState(); + writeVTK(i+1); updateSaturation(); updateCapillaryPressure(); updateKf(); - try - { - std::ofstream myfile; - myfile.open("pressuresaturation.csv",std::ofstream::app); - myfile << i << ", " << phiFluid1 << ", " << phiFluid2 << ", " << phiSolid << ", " << saturation << ", " - << pressureFluid1 << ", " << pressureFluid2 << ", " << capillaryPressure << ", " - << kf_11 << ", " << kf_12 << ", " << kf_21 << ", " << kf_22 << ", " << std::endl; - myfile.close(); - } - catch(...) - { - std::cout << "Error in integration or CSV Files" << std::endl; - } - - - /*if(i < 10) - { - applyChPressureSaturation(1); - } - else if(i<40) - { - param.reaction.reactionRate = 0; - applyChPressureSaturation(1); - applyNsPressureSaturation(1); - } - else - { - param.reaction.reactionRate = 1; - applyChReaction(1); - }*/ + writeCSV("pressuresaturation.csv", 0, i); } } - void writeVTK(RF time) - { - vtkwriter->write(time,Dune::VTK::ascii); - } -/* +//------------------------------------------------------------------------------------ + + void grow(RF length) // How much the the solid-fluid interface should grow in normal direction (in m) { length = length/poreReferenceLength; - if(length <= 0) + if(length > 0) + { + param.reaction.reactionRate = 1; + } + else { - std::cout << "Need positive length (dissolution not yet implemented)" << std::endl; - return; + param.reaction.reactionRate = -1; + length = -length; } + RF dtmax = param.pTree.get("Time.dtMax",0.01); while(length > dtmax) { //writeVTK(1-length); length -= dtmax; param.time.dt = dtmax; - applyCh(0); + applyChReaction(0); } param.time.dt = length; - applyCh(0); - applyNs(0); - updateKf(); - updatePhiSolid(); + applyChReaction(0); } void growArea(RF area) // How much Area the solid phase should grow (in m^2) { RF phiSolid_beforeGrowth = phiSolid; area = area/(poreReferenceLength*poreReferenceLength*4); //4 because of Symmetry - if(area <= 0) + int area_sign = 1; + if(area > 0) { - std::cout << "Need positive area (dissolution not yet implemented)" << std::endl; - return; + param.reaction.reactionRate = 1; } + else + { + param.reaction.reactionRate = -1; + area = -area; + area_sign = -1; + } + RF dtmax = param.pTree.get("Time.dtMax",0.01); - while(area - (phiSolid - phiSolid_beforeGrowth) > dtmax*calculateGrowthSpeed()) + while(area - area_sign*(phiSolid - phiSolid_beforeGrowth) > dtmax*calculateGrowthSpeed()) { //writeVTK(1-length); param.time.dt = dtmax; - applyCh(0); - updatePhiSolid(); + applyChReaction(0); } - param.time.dt = (area - (phiSolid - phiSolid_beforeGrowth)) / calculateGrowthSpeed(); - applyCh(0); - applyNs(0); - updateKf(); - updatePhiSolid(); + param.time.dt = (area - area_sign*(phiSolid - phiSolid_beforeGrowth)) / calculateGrowthSpeed(); + applyChReaction(0); + } + + void growAreaFraction(RF areaFraction) + { + updateSaturation(); + growArea(areaFraction * phiFluid1); + } + +//------------------------------------------------------------------------------------ + +void calculateKf(RF ViscosityRatio = 0) +{ + if(ViscosityRatio == 0) + { + ViscosityRatio = param.pTree.get("Physics.mu_ratio", (RF)1); } + param.mu_ratio = ViscosityRatio; + applyNsTransmissibility(); + updateKf(); +} + +void findSaturation(RF Curvature) +{ + //TODO!!!! +} - RF getKf() +//------------------------------------------------------------------------------------ + + RF getKf_11() { - return kf; + return kf_11; + } + + RF getKf_12() + { + return kf_12; + } + + RF getKf_21() + { + return kf_21; + } + + RF getKf_22() + { + return kf_22; + } + + RF getPhiFluid1() + { + return phiFluid1; + } + + RF getPhiFluid2() + { + return phiFluid2; } RF getPhiSolid() @@ -560,6 +690,11 @@ public: return (1-phiSolid)/(1-initialPhiSolid); } + RF getSaturation() + { + return saturation; + } + void setPoreBaseRadius(RF PoreBaseRadius_) { poreReferenceLength = PoreBaseRadius_ / (1-param.initial.ptree.get("Radius",0.2) ); @@ -570,5 +705,4 @@ public: return poreReferenceLength; } -*/ }; diff --git a/src/pntest/pn2p.ini b/src/pntest/pn2p.ini index b955c96f961bb4b367f99d61e7e29b231489afac..ae77650ff893d6138084944998a11e082014b7e3 100644 --- a/src/pntest/pn2p.ini +++ b/src/pntest/pn2p.ini @@ -11,17 +11,20 @@ SurfaceTensionScaling=1 VelDissipationRate = 4000 CurvatureAlpha=0#0.001 -[test] -InitialGrowthTime = 10 -FillTime = 150 -EmptyTime = 400 +[FullPCS_Curve] +InitialGrowthIter = 10 +FillIter = 150 +EmptyIter = 400 +[PCS_Search] +VelThreshold = 0.0005 #5e-4 +MaxCHNSIter = 100 [domain] filename = grids/square_periodic.msh [output] -filename = outp3 +filename = outp_kf_testing [Phasefield] eps=0.02