diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/immiscibleTwoPhase_GravitySegregation_1d.ats b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/immiscibleTwoPhase_GravitySegregation_1d.ats
new file mode 100644
index 00000000000..b7f470b932f
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/immiscibleTwoPhase_GravitySegregation_1d.ats
@@ -0,0 +1,18 @@
+from geos.ats.test_builder import TestDeck, RestartcheckParameters, generate_geos_tests
+
+restartcheck_params = {}
+restartcheck_params['atol'] = 1.0E-8
+restartcheck_params['rtol'] = 1.0E-8
+
+decks = [
+ TestDeck(
+ name="immiscibleTwoPhase_GravitySegregation_1d",
+ description=
+ 'Test that 2 fluids can be seperated based on gravity.',
+ partitions=((1, 1, 1), ),
+ restart_step=0,
+ check_step=45,
+ restartcheck_params=RestartcheckParameters(**restartcheck_params))
+]
+
+generate_geos_tests(decks)
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/immiscibleTwoPhase_GravitySegregation_1d.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/immiscibleTwoPhase_GravitySegregation_1d.xml
new file mode 100644
index 00000000000..62d4f6cf3bb
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/immiscibleTwoPhase_GravitySegregation_1d.xml
@@ -0,0 +1,203 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/initialPressure.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/initialPressure.txt
new file mode 100644
index 00000000000..85a30e13876
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/initialPressure.txt
@@ -0,0 +1,10 @@
+495.0
+485.0
+475.0
+465.0
+455.0
+400.0
+300.0
+200.0
+100.0
+0.0
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/initialSaturation1.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/initialSaturation1.txt
new file mode 100644
index 00000000000..99f11f6b2e7
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/initialSaturation1.txt
@@ -0,0 +1,10 @@
+0
+0
+0
+0
+0
+1
+1
+1
+1
+1
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/initialSaturation2.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/initialSaturation2.txt
new file mode 100644
index 00000000000..1c03b9c1871
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/initialSaturation2.txt
@@ -0,0 +1,10 @@
+1
+1
+1
+1
+1
+0
+0
+0
+0
+0
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/x.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/x.txt
new file mode 100644
index 00000000000..2eb3c4fe4ee
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/x.txt
@@ -0,0 +1 @@
+0.5
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/y.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/y.txt
new file mode 100644
index 00000000000..2eb3c4fe4ee
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/y.txt
@@ -0,0 +1 @@
+0.5
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/z.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/z.txt
new file mode 100644
index 00000000000..f43a1f14d26
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_GravitySegregation_1d/z.txt
@@ -0,0 +1,10 @@
+0.5
+1.5
+2.5
+3.5
+4.5
+5.5
+6.5
+7.5
+8.5
+9.5
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/initialPressure.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/initialPressure.txt
new file mode 100644
index 00000000000..63943bfa00d
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/initialPressure.txt
@@ -0,0 +1,10 @@
+1e7
+1e7
+1e7
+1e7
+1e7
+1e7
+1e7
+1e7
+1e7
+1e7
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/initialSaturation1.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/initialSaturation1.txt
new file mode 100644
index 00000000000..1859fabae78
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/initialSaturation1.txt
@@ -0,0 +1,10 @@
+0.95
+0.95
+0.95
+0.95
+0.95
+0.95
+0.95
+0.05
+0.05
+0.05
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/initialSaturation2.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/initialSaturation2.txt
new file mode 100644
index 00000000000..d113536f2fd
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/initialSaturation2.txt
@@ -0,0 +1,10 @@
+0.05
+0.05
+0.05
+0.05
+0.05
+0.05
+0.05
+0.95
+0.95
+0.95
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/jFunction_linear.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/jFunction_linear.txt
new file mode 100644
index 00000000000..c3dfd50073f
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/jFunction_linear.txt
@@ -0,0 +1,2 @@
+4.33172935918785
+1.66604975353379
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/permx.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/permx.geos
new file mode 100644
index 00000000000..4d47d8fa568
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/permx.geos
@@ -0,0 +1,10 @@
+50
+50
+50
+50
+50
+200
+200
+200
+200
+200
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/permy.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/permy.geos
new file mode 100644
index 00000000000..4d47d8fa568
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/permy.geos
@@ -0,0 +1,10 @@
+50
+50
+50
+50
+50
+200
+200
+200
+200
+200
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/permz.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/permz.geos
new file mode 100644
index 00000000000..4d47d8fa568
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/permz.geos
@@ -0,0 +1,10 @@
+50
+50
+50
+50
+50
+200
+200
+200
+200
+200
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/phaseVolumeFraction_water_linear.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/phaseVolumeFraction_water_linear.txt
new file mode 100644
index 00000000000..0d66ea1aee9
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/phaseVolumeFraction_water_linear.txt
@@ -0,0 +1,2 @@
+0
+1
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/jFunction b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/jFunction
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/jFunction.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/jFunction.txt
new file mode 100644
index 00000000000..72a78a75b85
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/jFunction.txt
@@ -0,0 +1,76 @@
+99.9980934
+17.78445609
+11.20350909
+8.549878542
+7.057769576
+6.082201546
+5.386086427
+4.86006559
+4.446116454
+4.110353325
+3.831547061
+3.595663494
+3.393021946
+3.216710174
+3.061649542
+2.924017691
+2.800877928
+2.68993357
+2.589360389
+2.497689435
+2.413723433
+2.336475912
+2.265126101
+2.198985069
+2.137469915
+2.080083807
+2.02640045
+1.976051821
+1.928718377
+1.884121218
+1.842015737
+1.802186411
+1.764442543
+1.728614745
+1.694551981
+1.662119113
+1.631194842
+1.601669938
+1.573445757
+1.546432977
+1.520550493
+1.495724483
+1.471887601
+1.448978263
+1.426940034
+1.405721104
+1.385273798
+1.365554178
+1.346521677
+1.328138769
+1.310370692
+1.293185194
+1.276552299
+1.260444114
+1.244834648
+1.229699646
+1.215016445
+1.200763848
+1.186921998
+1.173472275
+1.160397205
+1.147680364
+1.135306301
+1.123260469
+1.111529155
+1.100099423
+1.088959056
+1.078096509
+1.067500858
+1.057161765
+1.047069433
+1.03721457
+1.027588362
+1.018182437
+1.008988837
+0.999999998
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/jFunction_linear.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/jFunction_linear.txt
new file mode 100644
index 00000000000..13036f8fd03
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/jFunction_linear.txt
@@ -0,0 +1,2 @@
+100.00
+1.00
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/phaseVolumeFraction_water.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/phaseVolumeFraction_water.txt
new file mode 100644
index 00000000000..f38627d4e85
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/phaseVolumeFraction_water.txt
@@ -0,0 +1,76 @@
+0.001
+0.013333333
+0.026666667
+0.04
+0.053333333
+0.066666667
+0.08
+0.093333333
+0.106666667
+0.12
+0.133333333
+0.146666667
+0.16
+0.173333333
+0.186666667
+0.2
+0.213333333
+0.226666667
+0.24
+0.253333333
+0.266666667
+0.28
+0.293333333
+0.306666667
+0.32
+0.333333333
+0.346666667
+0.36
+0.373333333
+0.386666667
+0.4
+0.413333333
+0.426666667
+0.44
+0.453333333
+0.466666667
+0.48
+0.493333333
+0.506666667
+0.52
+0.533333333
+0.546666667
+0.56
+0.573333333
+0.586666667
+0.6
+0.613333333
+0.626666667
+0.64
+0.653333333
+0.666666667
+0.68
+0.693333333
+0.706666667
+0.72
+0.733333333
+0.746666667
+0.76
+0.773333333
+0.786666667
+0.8
+0.813333333
+0.826666667
+0.84
+0.853333333
+0.866666667
+0.88
+0.893333333
+0.906666667
+0.92
+0.933333333
+0.946666667
+0.96
+0.973333333
+0.986666667
+1
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/phaseVolumeFraction_water_linear.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/phaseVolumeFraction_water_linear.txt
new file mode 100644
index 00000000000..0a269ee3741
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/tables/phaseVolumeFraction_water_linear.txt
@@ -0,0 +1,2 @@
+0.0
+1.0
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/uni_directional_flow_base.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/uni_directional_flow_base.xml
new file mode 100644
index 00000000000..efbd5b34421
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/uni_directional_flow_base.xml
@@ -0,0 +1,293 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/uni_directional_flow_interface_condition.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/uni_directional_flow_interface_condition.xml
new file mode 100644
index 00000000000..41ba4e3ed92
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/uni_directional_flow_interface_condition.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/x.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/x.txt
new file mode 100644
index 00000000000..2eb3c4fe4ee
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/x.txt
@@ -0,0 +1 @@
+0.5
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/y.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/y.txt
new file mode 100644
index 00000000000..2eb3c4fe4ee
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/y.txt
@@ -0,0 +1 @@
+0.5
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/z.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/z.txt
new file mode 100644
index 00000000000..f43a1f14d26
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/1D_case/z.txt
@@ -0,0 +1,10 @@
+0.5
+1.5
+2.5
+3.5
+4.5
+5.5
+6.5
+7.5
+8.5
+9.5
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/initialPressure.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/initialPressure.txt
new file mode 100644
index 00000000000..6963bb6148c
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/initialPressure.txt
@@ -0,0 +1,1200 @@
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00022072e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00066218e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00110362e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00154508e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00198652e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00242798e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00286942e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00331088e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00375232e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00419378e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00463522e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00507668e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00551812e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00595958e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00640102e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00684248e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00728392e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00772538e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00816682e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
+1.00860828e+07
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/initialSaturation1.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/initialSaturation1.txt
new file mode 100644
index 00000000000..90ddc12151e
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/initialSaturation1.txt
@@ -0,0 +1,1200 @@
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e+00
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
+1.00000000e-02
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/initialSaturation2.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/initialSaturation2.txt
new file mode 100644
index 00000000000..d5ef52f254b
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/initialSaturation2.txt
@@ -0,0 +1,1200 @@
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+0.00000000e+00
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
+9.90000000e-01
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/permx.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/permx.geos
new file mode 100644
index 00000000000..439bd535a86
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/permx.geos
@@ -0,0 +1,1200 @@
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/permy.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/permy.geos
new file mode 100644
index 00000000000..439bd535a86
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/permy.geos
@@ -0,0 +1,1200 @@
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/permz.geos b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/permz.geos
new file mode 100644
index 00000000000..439bd535a86
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/permz.geos
@@ -0,0 +1,1200 @@
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+5.00000000e+01
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
+2.00000000e+02
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/x.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/x.txt
new file mode 100644
index 00000000000..283fc50e7fb
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/x.txt
@@ -0,0 +1,10 @@
+5.00000000e-01
+1.50000000e+00
+2.50000000e+00
+3.50000000e+00
+4.50000000e+00
+5.50000000e+00
+6.50000000e+00
+7.50000000e+00
+8.50000000e+00
+9.50000000e+00
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/y.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/y.txt
new file mode 100644
index 00000000000..a01763bc5d1
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/y.txt
@@ -0,0 +1,6 @@
+5.00000000e-01
+1.50000000e+00
+2.50000000e+00
+3.50000000e+00
+4.50000000e+00
+5.50000000e+00
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/z.txt b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/z.txt
new file mode 100644
index 00000000000..d122a370abe
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/input/z.txt
@@ -0,0 +1,20 @@
+2.50000000e-01
+7.50000000e-01
+1.25000000e+00
+1.75000000e+00
+2.25000000e+00
+2.75000000e+00
+3.25000000e+00
+3.75000000e+00
+4.25000000e+00
+4.75000000e+00
+5.25000000e+00
+5.75000000e+00
+6.25000000e+00
+6.75000000e+00
+7.25000000e+00
+7.75000000e+00
+8.25000000e+00
+8.75000000e+00
+9.25000000e+00
+9.75000000e+00
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml
new file mode 100644
index 00000000000..3982a2b12c6
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_base.xml
@@ -0,0 +1,299 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_interface_condition.xml b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_interface_condition.xml
new file mode 100644
index 00000000000..9bac844ae7b
--- /dev/null
+++ b/inputFiles/immiscibleMultiphaseFlow/immiscibleTwoPhase_interface_conditions/3D_case/uni_directional_flow_interface_condition.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/coreComponents/common/DataLayouts.hpp b/src/coreComponents/common/DataLayouts.hpp
index cd09af18ef0..0f23039b745 100644
--- a/src/coreComponents/common/DataLayouts.hpp
+++ b/src/coreComponents/common/DataLayouts.hpp
@@ -21,6 +21,7 @@
#define GEOS_COMMON_DATALAYOUTS_HPP_
#include "common/GeosxConfig.hpp"
+#include "common/DataTypes.hpp"
#include "LvArray/src/Array.hpp"
#include "RAJA/RAJA.hpp"
diff --git a/src/coreComponents/constitutive/CMakeLists.txt b/src/coreComponents/constitutive/CMakeLists.txt
index 6af439fe23f..f4d46708e56 100644
--- a/src/coreComponents/constitutive/CMakeLists.txt
+++ b/src/coreComponents/constitutive/CMakeLists.txt
@@ -369,6 +369,7 @@ if( ENABLE_PVTPackage )
endif()
if (ENABLE_HPCREACT)
+ if( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/HPCReact/CMakeLists.txt" )
set( constitutive_headers
${constitutive_headers}
fluid/reactivefluid/ReactiveFluidSelector.hpp
@@ -383,8 +384,9 @@ if (ENABLE_HPCREACT)
${constitutive_sources}
fluid/reactivefluid/ReactiveSinglePhaseFluid.cpp
)
- add_subdirectory( HPCReact )
- list( APPEND dependencyList hpcReact )
+ add_subdirectory( HPCReact )
+ list( APPEND dependencyList hpcReact )
+ endif()
endif()
geos_decorate_link_dependencies( LIST decoratedDependencies
diff --git a/src/coreComponents/constitutive/capillaryPressure/BrooksCoreyCapillaryPressure.hpp b/src/coreComponents/constitutive/capillaryPressure/BrooksCoreyCapillaryPressure.hpp
index 39d93e48858..39b61e786f7 100644
--- a/src/coreComponents/constitutive/capillaryPressure/BrooksCoreyCapillaryPressure.hpp
+++ b/src/coreComponents/constitutive/capillaryPressure/BrooksCoreyCapillaryPressure.hpp
@@ -57,6 +57,11 @@ class BrooksCoreyCapillaryPressureUpdate final : public CapillaryPressureBaseUpd
arraySlice1d< real64, cappres::USD_CAPPRES - 2 > const & phaseCapPres,
arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const;
+ GEOS_HOST_DEVICE
+ void computeInv( arraySlice1d< real64, compflow::USD_PHASE - 1 > const & phaseVolFraction,
+ arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres,
+ arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const;
+
GEOS_HOST_DEVICE
virtual void update( localIndex const k,
localIndex const q,
@@ -80,14 +85,32 @@ class BrooksCoreyCapillaryPressureUpdate final : public CapillaryPressureBaseUpd
real64 & phaseCapPressure,
real64 & dPhaseCapPressure_dVolFrac );
+
+ GEOS_HOST_DEVICE
+ GEOS_FORCE_INLINE
+ static void
+ evaluateBrooksCoreyFunctionInv( real64 const phaseCapPressure,
+ int const ip,
+ real64 const volFracScaleInv,
+ real64 const exponentInv,
+ real64 const entryPressure,
+ real64 const maxCapPres_eps,
+ real64 const phaseMinVolumeFraction,
+ arrayView1d< integer const > const phaseOrder,
+ real64 & phaseVolFraction,
+ real64 & dPhaseCapPressure_dVolFrac );
+
arrayView1d< real64 const > m_phaseMinVolumeFraction;
arrayView1d< real64 const > m_phaseCapPressureExponentInv;
arrayView1d< real64 const > m_phaseEntryPressure;
real64 m_capPressureEpsilon;
real64 m_volFracScale;
+
};
+
+
class BrooksCoreyCapillaryPressure : public CapillaryPressureBase
{
public:
@@ -169,11 +192,14 @@ BrooksCoreyCapillaryPressureUpdate::
// compute first gas-oil capillary pressure as a function of gas-phase vol fraction
integer const ip_gas = m_phaseOrder[CapillaryPressureBase::PhaseType::GAS];
- if( ip_gas >= 0 )
+ integer const ip_oil = m_phaseOrder[CapillaryPressureBase::PhaseType::OIL];
+
+ GEOS_UNUSED_VAR( ip_gas );
+ if( ip_oil >= 0 )
{
- real64 const volFracScaled = (phaseVolFraction[ip_gas] - m_phaseMinVolumeFraction[ip_gas]) * volFracScaleInv;
- real64 const exponentInv = m_phaseCapPressureExponentInv[ip_gas];
- real64 const entryPressure = -m_phaseEntryPressure[ip_gas]; // for gas capillary pressure, take the opposite of the
+ real64 const volFracScaled = (phaseVolFraction[ip_oil] - m_phaseMinVolumeFraction[ip_oil]) * volFracScaleInv;
+ real64 const exponentInv = m_phaseCapPressureExponentInv[ip_oil];
+ real64 const entryPressure = -m_phaseEntryPressure[ip_oil]; // for gas capillary pressure, take the opposite of the
// BC function
real64 const wettingVolFracScaled = 1-volFracScaled;
@@ -184,11 +210,103 @@ BrooksCoreyCapillaryPressureUpdate::
exponentInv,
entryPressure,
eps,
- phaseCapPres[ip_gas],
- dPhaseCapPres_dPhaseVolFrac[ip_gas][ip_gas] );
+ phaseCapPres[ip_oil],
+ dPhaseCapPres_dPhaseVolFrac[ip_oil][ip_oil] );
}
}
+GEOS_HOST_DEVICE
+inline void
+BrooksCoreyCapillaryPressureUpdate::
+ computeInv( arraySlice1d< real64, compflow::USD_PHASE - 1 > const & phaseVolFraction,
+ arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres,
+ arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const
+{
+ LvArray::forValuesInSlice( dPhaseCapPres_dPhaseVolFrac, []( real64 & val ){ val = 0.0; } );
+
+ real64 const volFracScaleInv = 1.0 / m_volFracScale;
+
+ // the Brooks-Corey model does not support volFracScaled = 0,
+ // hence we need an epsilon value to avoid a division by zero
+ // TODO: for S < epsilon, replace the original unbounded BC curve with a bounded power-law extension
+ real64 const eps = m_capPressureEpsilon;
+
+
+ // compute first water-oil capillary pressure as a function of water-phase vol fraction
+ integer const ip_water = m_phaseOrder[CapillaryPressureBase::PhaseType::WATER];
+ integer const ip_gas = m_phaseOrder[CapillaryPressureBase::PhaseType::GAS];
+ if( ip_water >= 0 )
+ {
+ real64 const volFracScaled_eps = (eps - m_phaseMinVolumeFraction[ip_water]) * volFracScaleInv;
+ real64 const exponentInv = m_phaseCapPressureExponentInv[ip_water];
+ real64 const entryPressure = m_phaseEntryPressure[ip_water];
+
+ real64 const wettingVolFracScaled_eps = volFracScaled_eps;
+ real64 const dWettingVolFracScaled_dVolFrac = volFracScaleInv;
+
+ real64 maxCapPres_eps = 0.0;
+ real64 max_dpc_eps = 0.0;
+
+ evaluateBrooksCoreyFunction( wettingVolFracScaled_eps,
+ dWettingVolFracScaled_dVolFrac,
+ exponentInv,
+ entryPressure,
+ eps,
+ maxCapPres_eps,
+ max_dpc_eps );
+
+ evaluateBrooksCoreyFunctionInv( phaseCapPres[ip_water],
+ ip_water,
+ volFracScaleInv,
+ exponentInv,
+ entryPressure,
+ maxCapPres_eps,
+ m_phaseMinVolumeFraction[ip_water],
+ m_phaseOrder,
+ phaseVolFraction[ip_water],
+ dPhaseCapPres_dPhaseVolFrac[ip_water][ip_water] );
+ phaseVolFraction[ip_gas] = 1.0 - phaseVolFraction[ip_water];
+ }
+
+
+ // compute first gas-oil capillary pressure as a function of gas-phase vol fraction
+
+
+ // if( ip_gas >= 0 )
+ // {
+ // real64 const volFracScaled_eps = (eps - m_phaseMinVolumeFraction[ip_gas]) * volFracScaleInv;
+ // real64 const exponentInv = m_phaseCapPressureExponentInv[ip_gas];
+ // real64 const entryPressure = -m_phaseEntryPressure[ip_gas]; // for gas capillary pressure, take the opposite of the
+ // // BC function
+
+ // real64 const wettingVolFracScaled_eps = 1-volFracScaled_eps;
+ // real64 const dWettingVolFracScaled_dVolFrac = -volFracScaleInv;
+
+ // real64 maxCapPres_eps = 0.0;
+ // real64 max_dpc_eps = 0.0;
+
+ // evaluateBrooksCoreyFunction( wettingVolFracScaled_eps,
+ // dWettingVolFracScaled_dVolFrac,
+ // exponentInv,
+ // entryPressure,
+ // eps,
+ // maxCapPres_eps,
+ // max_dpc_eps );
+
+ // evaluateBrooksCoreyFunctionInv( phaseCapPres[ip_gas],
+ // ip_gas,
+ // volFracScaleInv,
+ // exponentInv,
+ // entryPressure,
+ // maxCapPres_eps,
+ // m_phaseMinVolumeFraction[ip_gas],
+ // m_phaseOrder,
+ // phaseVolFraction[ip_gas],
+ // dPhaseCapPres_dPhaseVolFrac[ip_gas][ip_gas] );
+ // phaseVolFraction[ip_water] = 1.0 - phaseVolFraction[ip_gas];
+ // }
+}
+
GEOS_HOST_DEVICE
inline void
BrooksCoreyCapillaryPressureUpdate::
@@ -222,6 +340,49 @@ BrooksCoreyCapillaryPressureUpdate::
}
+GEOS_HOST_DEVICE
+inline void
+BrooksCoreyCapillaryPressureUpdate::
+ evaluateBrooksCoreyFunctionInv( real64 const phaseCapPressure,
+ int const ip,
+ real64 const volFracScaleInv,
+ real64 const exponentInv,
+ real64 const entryPressure,
+ real64 const maxCapPres_eps,
+ real64 const phaseMinVolumeFraction,
+ arrayView1d< integer const > const phaseOrder,
+ real64 & phaseVolFraction,
+ real64 & dPhaseCapPressure_dVolFrac )
+{
+
+
+ phaseVolFraction = 0.0;
+ real64 value = 0.0;
+ dPhaseCapPressure_dVolFrac = 0.0;
+ integer const ip_oil = phaseOrder[CapillaryPressureBase::PhaseType::OIL];
+
+ real64 const dScaledWettingPhaseVolFrac_dVolFrac = (ip == ip_oil)
+ ? -volFracScaleInv : volFracScaleInv;
+
+ if( phaseCapPressure <= maxCapPres_eps && phaseCapPressure >= entryPressure )
+ {
+ // intermediate value
+ real64 const val = pow( entryPressure, exponentInv ) / pow( phaseCapPressure, exponentInv + 1 );
+
+ value = (phaseCapPressure * val) * volFracScaleInv + phaseMinVolumeFraction; // entryPressure * (S_w)^( - 1 / exponentInv )
+ dPhaseCapPressure_dVolFrac = -dScaledWettingPhaseVolFrac_dVolFrac * val * exponentInv;
+ phaseVolFraction = (ip == ip_oil) ? 1.0 - value : value;
+ }
+ else // enforce a constant and bounded capillary pressure
+ {
+ real64 const val = (phaseCapPressure > maxCapPres_eps)
+ ? pow( entryPressure, exponentInv ) / pow( maxCapPres_eps, exponentInv ) : 1.0;
+ value = val * volFracScaleInv + phaseMinVolumeFraction;
+ phaseVolFraction = (ip == ip_oil) ? 1.0 - value : value;
+ }
+
+}
+
} // namespace constitutive
diff --git a/src/coreComponents/constitutive/capillaryPressure/CapillaryPressureSelector.hpp b/src/coreComponents/constitutive/capillaryPressure/CapillaryPressureSelector.hpp
index b164f55aa16..c9b96e018b7 100644
--- a/src/coreComponents/constitutive/capillaryPressure/CapillaryPressureSelector.hpp
+++ b/src/coreComponents/constitutive/capillaryPressure/CapillaryPressureSelector.hpp
@@ -36,20 +36,24 @@ template< typename LAMBDA >
void constitutiveUpdatePassThru( CapillaryPressureBase const & capPres,
LAMBDA && lambda )
{
- ConstitutivePassThruHandler< BrooksCoreyCapillaryPressure,
- JFunctionCapillaryPressure,
- TableCapillaryPressure,
- VanGenuchtenCapillaryPressure >::execute( capPres, std::forward< LAMBDA >( lambda ) );
+ ConstitutivePassThruHandler<
+ BrooksCoreyCapillaryPressure,
+ JFunctionCapillaryPressure,
+ TableCapillaryPressure,
+ VanGenuchtenCapillaryPressure
+ >::execute( capPres, std::forward< LAMBDA >( lambda ) );
}
template< typename LAMBDA >
void constitutiveUpdatePassThru( CapillaryPressureBase & capPres,
LAMBDA && lambda )
{
- ConstitutivePassThruHandler< BrooksCoreyCapillaryPressure,
- JFunctionCapillaryPressure,
- TableCapillaryPressure,
- VanGenuchtenCapillaryPressure >::execute( capPres, std::forward< LAMBDA >( lambda ) );
+ ConstitutivePassThruHandler<
+ BrooksCoreyCapillaryPressure,
+ JFunctionCapillaryPressure,
+ TableCapillaryPressure,
+ VanGenuchtenCapillaryPressure
+ >::execute( capPres, std::forward< LAMBDA >( lambda ) );
}
} // namespace constitutive
diff --git a/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.cpp b/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.cpp
index e4eb76d02ba..320c940716c 100644
--- a/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.cpp
+++ b/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.cpp
@@ -119,6 +119,14 @@ JFunctionCapillaryPressure::JFunctionCapillaryPressure( std::string const & name
.setInputFlag( InputFlags::FALSE );
registerField< fields::cappres::jFuncMultiplier >( &m_jFuncMultiplier );
+
+ registerWrapper( viewKeyStruct::jFunctionWrappersString(), &m_jFuncKernelWrappers ).
+ setSizedFromParent( 0 ).
+ setRestartFlags( RestartFlags::NO_WRITE );
+
+ registerWrapper( viewKeyStruct::inverseJFunctionWrappersString(), &m_inverseJFuncKernelWrappers ).
+ setSizedFromParent( 0 ).
+ setRestartFlags( RestartFlags::NO_WRITE );
}
void JFunctionCapillaryPressure::postInputInitialization()
@@ -187,6 +195,7 @@ void JFunctionCapillaryPressure::initializePreSubGroups()
? true // pc on the gas phase, function must be increasing
: false; // pc on the water phase, function must be decreasing
TableCapillaryPressureHelpers::validateCapillaryPressureTable( jFuncTable, getFullName(), jFuncMustBeIncreasing );
+
}
else if( numPhases == 3 )
{
@@ -205,6 +214,7 @@ void JFunctionCapillaryPressure::initializePreSubGroups()
InputError, getDataContext() );
TableFunction const & jFuncTableNWI = functionManager.getGroup< TableFunction >( m_nonWettingIntermediateJFuncTableName );
TableCapillaryPressureHelpers::validateCapillaryPressureTable( jFuncTableNWI, getFullName(), true );
+
}
}
@@ -300,11 +310,48 @@ void JFunctionCapillaryPressure::createAllTableKernelWrappers()
// we want to make sure that the wrappers are always up-to-date, so we recreate them everytime
m_jFuncKernelWrappers.clear();
+ m_inverseJFuncKernelWrappers.clear();
+
if( numPhases == 2 )
{
+
TableFunction const & jFuncTable = functionManager.getGroup< TableFunction >( m_wettingNonWettingJFuncTableName );
m_jFuncKernelWrappers.emplace_back( jFuncTable.createKernelWrapper() );
+ auto const & satArrayView = jFuncTable.getCoordinates()[0];
+ auto const & jArrayView = jFuncTable.getValues();
+
+ std::vector< real64 > satVec( satArrayView.size() );
+ std::vector< real64 > jVec( jArrayView.size() );
+
+ std::copy( satArrayView.begin(), satArrayView.end(), satVec.begin() );
+ std::copy( jArrayView.begin(), jArrayView.end(), jVec.begin() );
+
+ // Reverse both arrays (if original J is decreasing in S)
+ std::reverse( jVec.begin(), jVec.end() );
+ std::reverse( satVec.begin(), satVec.end() );
+
+
+ auto inverseTable = std::make_shared< TableFunction >( "inverseJFunc", this );
+
+ real64_array invJVec( jVec.size() );
+ real64_array invSatVec( satVec.size() );
+ std::copy( jVec.begin(), jVec.end(), invJVec.data() );
+ std::copy( satVec.begin(), satVec.end(), invSatVec.data() );
+
+ array1d< real64_array > coordinates;
+ coordinates.emplace_back( std::move( invJVec ) );
+
+
+ std::vector< units::Unit > dimUnits = { units::Unknown }; // or actual unit if available
+
+ inverseTable->setTableCoordinates( coordinates, dimUnits );
+ inverseTable->setTableValues( std::move( invSatVec ), units::Unknown );
+ inverseTable->setInterpolationMethod( TableFunction::InterpolationType::Linear );
+
+ m_inverseJFuncKernelWrappers.emplace_back( inverseTable->createKernelWrapper() );
+ m_inverseTables.emplace_back( std::move( inverseTable ) );
+
// Populate the end-points from the tables
TableCapillaryPressureHelpers::populateMinPhaseVolumeFraction( m_phaseOrder.toSliceConst(), jFuncTable, m_phaseMinVolumeFraction );
}
@@ -313,8 +360,10 @@ void JFunctionCapillaryPressure::createAllTableKernelWrappers()
// the assumption used everywhere in this class is that the WI information comes before the NWI information
TableFunction const & jFuncTableWI = functionManager.getGroup< TableFunction >( m_wettingIntermediateJFuncTableName );
m_jFuncKernelWrappers.emplace_back( jFuncTableWI.createKernelWrapper() );
+ m_inverseJFuncKernelWrappers.emplace_back( jFuncTableWI.createKernelWrapper() );
TableFunction const & jFuncTableNWI = functionManager.getGroup< TableFunction >( m_nonWettingIntermediateJFuncTableName );
m_jFuncKernelWrappers.emplace_back( jFuncTableNWI.createKernelWrapper() );
+ m_inverseJFuncKernelWrappers.emplace_back( jFuncTableNWI.createKernelWrapper() );
// Populate the end-points from the tables
TableCapillaryPressureHelpers::populateMinPhaseVolumeFraction( m_phaseOrder.toSliceConst(), jFuncTableWI, jFuncTableNWI, m_phaseMinVolumeFraction );
@@ -323,6 +372,7 @@ void JFunctionCapillaryPressure::createAllTableKernelWrappers()
JFunctionCapillaryPressure::KernelWrapper::
KernelWrapper( arrayView1d< TableFunction::KernelWrapper const > const & jFuncKernelWrappers,
+ arrayView1d< TableFunction::KernelWrapper const > const & inverseJFuncKernelWrappers,
arrayView2d< real64 const > const & jFuncMultiplier,
arrayView1d< integer const > const & phaseTypes,
arrayView1d< integer const > const & phaseOrder,
@@ -333,6 +383,7 @@ JFunctionCapillaryPressure::KernelWrapper::
phaseCapPres,
dPhaseCapPres_dPhaseVolFrac ),
m_jFuncKernelWrappers( jFuncKernelWrappers ),
+ m_inverseJFuncKernelWrappers( inverseJFuncKernelWrappers ),
m_jFuncMultiplier( jFuncMultiplier )
{}
@@ -341,6 +392,7 @@ JFunctionCapillaryPressure::createKernelWrapper()
{
createAllTableKernelWrappers();
return KernelWrapper( m_jFuncKernelWrappers,
+ m_inverseJFuncKernelWrappers,
m_jFuncMultiplier,
m_phaseTypes,
m_phaseOrder,
diff --git a/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.hpp b/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.hpp
index 4e42189d92e..5e2f885cbf6 100644
--- a/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.hpp
+++ b/src/coreComponents/constitutive/capillaryPressure/JFunctionCapillaryPressure.hpp
@@ -65,6 +65,7 @@ class JFunctionCapillaryPressure : public CapillaryPressureBase
public:
KernelWrapper( arrayView1d< TableFunction::KernelWrapper const > const & jFuncKernelWrappers,
+ arrayView1d< TableFunction::KernelWrapper const > const & inverseJFuncKernelWrappers,
arrayView2d< real64 const > const & jFuncMultiplier,
arrayView1d< integer const > const & phaseTypes,
arrayView1d< integer const > const & phaseOrder,
@@ -77,6 +78,13 @@ class JFunctionCapillaryPressure : public CapillaryPressureBase
arraySlice1d< real64, cappres::USD_CAPPRES - 2 > const & phaseCapPres,
arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const;
+ GEOS_HOST_DEVICE
+ void computeInv( arraySlice1d< real64, compflow::USD_PHASE - 1 > const & phaseVolFraction,
+ arraySlice1d< real64 const > const & jFuncMultiplier,
+ arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres,
+ arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const;
+
+
GEOS_HOST_DEVICE
virtual void update( localIndex const k,
localIndex const q,
@@ -87,6 +95,7 @@ class JFunctionCapillaryPressure : public CapillaryPressureBase
/// Array of kernel wrappers for the J-function
/// Is of size 1 for two-phase flow, and of size 2 for three-phase flow
arrayView1d< TableFunction::KernelWrapper const > const m_jFuncKernelWrappers;
+ arrayView1d< TableFunction::KernelWrapper const > const m_inverseJFuncKernelWrappers;
/// Array of cell-wise J-function multipliers
/// The second dimension is of size 1 for two-phase flow, and of size 2 for three-phase flow
@@ -112,6 +121,8 @@ class JFunctionCapillaryPressure : public CapillaryPressureBase
static constexpr char const * porosityExponentString() { return "porosityExponent"; }
static constexpr char const * permeabilityExponentString() { return "permeabilityExponent"; }
static constexpr char const * permeabilityDirectionString() { return "permeabilityDirection"; }
+ static constexpr char const * jFunctionWrappersString() { return "jFunctionWrappers"; }
+ static constexpr char const * inverseJFunctionWrappersString() { return "inverseJFunctionWrappers"; }
};
/**
@@ -168,6 +179,9 @@ class JFunctionCapillaryPressure : public CapillaryPressureBase
/// J-function kernel wrapper for the first pair (wetting-intermediate if NP=3, wetting-non-wetting otherwise)
array1d< TableFunction::KernelWrapper > m_jFuncKernelWrappers;
+ array1d< TableFunction::KernelWrapper > m_inverseJFuncKernelWrappers;
+
+ std::vector< std::shared_ptr< TableFunction > > m_inverseTables;
};
@@ -242,6 +256,42 @@ JFunctionCapillaryPressure::KernelWrapper::
}
}
+GEOS_HOST_DEVICE
+inline void
+JFunctionCapillaryPressure::KernelWrapper::
+ computeInv( arraySlice1d< real64, compflow::USD_PHASE - 1 > const & phaseVolFraction,
+ arraySlice1d< real64 const > const & jFuncMultiplier,
+ arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres,
+ arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const
+{
+ LvArray::forValuesInSlice( dPhaseCapPres_dPhaseVolFrac, []( real64 & val ){ val = 0.0; } );
+
+ using PT = CapillaryPressureBase::PhaseType;
+ integer const ipWater = m_phaseOrder[PT::WATER];
+ integer const ipOil = m_phaseOrder[PT::OIL];
+ integer const ipGas = m_phaseOrder[PT::GAS];
+
+ GEOS_UNUSED_VAR( ipOil );
+ // apply multiplier
+ real64 capPresWater_J = phaseCapPres[ipWater] / jFuncMultiplier[0];
+ // std::cout << GEOS_FMT( " JM_2 = ( {:4.2e} )", jFuncMultiplier[0] );
+ array1d< real64 > input( 1 );
+ input[0] = capPresWater_J;
+ // std::cout << GEOS_FMT( " J_int2 = ( {:4.2e} )", input[0] );
+ // std::cout << GEOS_FMT( " Pc_int2 = ( {:4.2e} )", phaseCapPres[ipWater] );
+ auto inputSlice = input.toSliceConst();
+
+
+
+ phaseVolFraction[ipWater] =
+ m_inverseJFuncKernelWrappers[0].compute( inputSlice,
+ &(dPhaseCapPres_dPhaseVolFrac)[ipWater][ipWater] );
+ dPhaseCapPres_dPhaseVolFrac[ipWater][ipWater] /= jFuncMultiplier[0];
+ // std::cout << GEOS_FMT( " S_int2 = ( {:4.2e} )", phaseVolFraction[ipWater] );
+ // std::cout << GEOS_FMT( " dS/dP = ( {:4.2e} )", dPhaseCapPres_dPhaseVolFrac[ipWater][ipWater] );
+ phaseVolFraction[ipGas] = 1.0 - phaseVolFraction[ipWater];
+}
+
GEOS_HOST_DEVICE
inline void
JFunctionCapillaryPressure::KernelWrapper::
diff --git a/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.cpp b/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.cpp
index 17b94f4730f..b925627ff4b 100644
--- a/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.cpp
+++ b/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.cpp
@@ -69,6 +69,10 @@ TableCapillaryPressure::TableCapillaryPressure( std::string const & name,
registerWrapper( viewKeyStruct::capPresWrappersString(), &m_capPresKernelWrappers ).
setSizedFromParent( 0 ).
setRestartFlags( RestartFlags::NO_WRITE );
+
+ registerWrapper( viewKeyStruct::inverseCapPresWrappersString(), &m_inverseCapPresWrappers ).
+ setSizedFromParent( 0 ).
+ setRestartFlags( RestartFlags::NO_WRITE );
}
void TableCapillaryPressure::postInputInitialization()
@@ -154,11 +158,47 @@ void TableCapillaryPressure::createAllTableKernelWrappers()
// we want to make sure that the wrappers are always up-to-date, so we recreate them everytime
m_capPresKernelWrappers.clear();
+ m_inverseCapPresWrappers.clear();
+
if( numPhases == 2 )
{
TableFunction const & capPresTable = functionManager.getGroup< TableFunction >( m_wettingNonWettingCapPresTableName );
m_capPresKernelWrappers.emplace_back( capPresTable.createKernelWrapper() );
+ auto const & satArrayView = capPresTable.getCoordinates()[0];
+ auto const & capPresArrayView = capPresTable.getValues();
+
+ std::vector< real64 > satVec( satArrayView.size() );
+ std::vector< real64 > pcVec( capPresArrayView.size() );
+
+ std::copy( satArrayView.begin(), satArrayView.end(), satVec.begin() );
+ std::copy( capPresArrayView.begin(), capPresArrayView.end(), pcVec.begin() );
+
+ // Reverse both arrays (if original J is decreasing in S)
+ std::reverse( pcVec.begin(), pcVec.end() );
+ std::reverse( satVec.begin(), satVec.end() );
+
+
+ auto inverseTable = std::make_shared< TableFunction >( "inverseCapPres", this );
+
+ real64_array invPcVec( pcVec.size() );
+ real64_array invSatVec( satVec.size() );
+ std::copy( pcVec.begin(), pcVec.end(), invPcVec.data() );
+ std::copy( satVec.begin(), satVec.end(), invSatVec.data() );
+
+ array1d< real64_array > coordinates;
+ coordinates.emplace_back( std::move( invPcVec ) );
+
+
+ std::vector< units::Unit > dimUnits = { units::Unknown }; // or actual unit if available
+
+ inverseTable->setTableCoordinates( coordinates, dimUnits );
+ inverseTable->setTableValues( std::move( invSatVec ), units::Unknown );
+ inverseTable->setInterpolationMethod( TableFunction::InterpolationType::Linear );
+
+ m_inverseCapPresWrappers.emplace_back( inverseTable->createKernelWrapper() );
+ m_inverseTables.emplace_back( std::move( inverseTable ) );
+
// Populate the end-points from the tables
TableCapillaryPressureHelpers::populateMinPhaseVolumeFraction( m_phaseOrder.toSliceConst(), capPresTable, m_phaseMinVolumeFraction );
}
@@ -166,8 +206,10 @@ void TableCapillaryPressure::createAllTableKernelWrappers()
{
TableFunction const & capPresTableWI = functionManager.getGroup< TableFunction >( m_wettingIntermediateCapPresTableName );
m_capPresKernelWrappers.emplace_back( capPresTableWI.createKernelWrapper() );
+ m_inverseCapPresWrappers.emplace_back( capPresTableWI.createKernelWrapper() );
TableFunction const & capPresTableNWI = functionManager.getGroup< TableFunction >( m_nonWettingIntermediateCapPresTableName );
m_capPresKernelWrappers.emplace_back( capPresTableNWI.createKernelWrapper() );
+ m_inverseCapPresWrappers.emplace_back( capPresTableNWI.createKernelWrapper() );
// Populate the end-points from the tables
TableCapillaryPressureHelpers::populateMinPhaseVolumeFraction( m_phaseOrder.toSliceConst(), capPresTableWI, capPresTableNWI, m_phaseMinVolumeFraction );
@@ -177,6 +219,7 @@ void TableCapillaryPressure::createAllTableKernelWrappers()
TableCapillaryPressure::KernelWrapper::
KernelWrapper( arrayView1d< TableFunction::KernelWrapper const > const & capPresKernelWrappers,
+ arrayView1d< TableFunction::KernelWrapper const > const & inverseCapPresWrappers,
arrayView1d< integer const > const & phaseTypes,
arrayView1d< integer const > const & phaseOrder,
arrayView3d< real64, cappres::USD_CAPPRES > const & phaseCapPres,
@@ -185,7 +228,8 @@ TableCapillaryPressure::KernelWrapper::
phaseOrder,
phaseCapPres,
dPhaseCapPres_dPhaseVolFrac ),
- m_capPresKernelWrappers( capPresKernelWrappers )
+ m_capPresKernelWrappers( capPresKernelWrappers ),
+ m_inverseCapPresWrappers( inverseCapPresWrappers )
{}
TableCapillaryPressure::KernelWrapper
@@ -193,6 +237,7 @@ TableCapillaryPressure::createKernelWrapper()
{
createAllTableKernelWrappers();
return KernelWrapper( m_capPresKernelWrappers,
+ m_inverseCapPresWrappers,
m_phaseTypes,
m_phaseOrder,
m_phaseCapPressure,
diff --git a/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.hpp b/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.hpp
index 739b9993083..5d132d3636a 100644
--- a/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.hpp
+++ b/src/coreComponents/constitutive/capillaryPressure/TableCapillaryPressure.hpp
@@ -55,6 +55,7 @@ class TableCapillaryPressure : public CapillaryPressureBase
public:
KernelWrapper( arrayView1d< TableFunction::KernelWrapper const > const & capPresKernelWrappers,
+ arrayView1d< TableFunction::KernelWrapper const > const & inverseCapPresWrappers,
arrayView1d< integer const > const & phaseTypes,
arrayView1d< integer const > const & phaseOrder,
arrayView3d< real64, cappres::USD_CAPPRES > const & phaseCapPres,
@@ -65,6 +66,12 @@ class TableCapillaryPressure : public CapillaryPressureBase
arraySlice1d< real64, cappres::USD_CAPPRES - 2 > const & phaseCapPres,
arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const;
+ GEOS_HOST_DEVICE
+ void computeInv( arraySlice1d< real64, compflow::USD_PHASE - 1 > const & phaseVolFraction,
+ arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres,
+ arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const;
+
+
GEOS_HOST_DEVICE
virtual void update( localIndex const k,
localIndex const q,
@@ -75,6 +82,7 @@ class TableCapillaryPressure : public CapillaryPressureBase
/// Array of kernel wrappers for the capillary pressures
/// Is of size 1 for two-phase flow, and of size 2 for three-phase flow
arrayView1d< TableFunction::KernelWrapper const > const m_capPresKernelWrappers;
+ arrayView1d< TableFunction::KernelWrapper const > const m_inverseCapPresWrappers;
};
@@ -91,6 +99,7 @@ class TableCapillaryPressure : public CapillaryPressureBase
static constexpr char const * wettingIntermediateCapPresTableNameString() { return "wettingIntermediateCapPressureTableName"; }
static constexpr char const * nonWettingIntermediateCapPresTableNameString() { return "nonWettingIntermediateCapPressureTableName"; }
static constexpr char const * capPresWrappersString() { return "capPresWrappers"; }
+ static constexpr char const * inverseCapPresWrappersString() { return "inverseCapPresWrappers"; }
};
@@ -116,6 +125,9 @@ class TableCapillaryPressure : public CapillaryPressureBase
/// Capillary pressure kernel wrapper for the first pair (wetting-intermediate if NP=3, wetting-non-wetting otherwise)
array1d< TableFunction::KernelWrapper > m_capPresKernelWrappers;
+ array1d< TableFunction::KernelWrapper > m_inverseCapPresWrappers;
+
+ std::vector< std::shared_ptr< TableFunction > > m_inverseTables;
};
@@ -173,6 +185,39 @@ TableCapillaryPressure::KernelWrapper::
}
}
+GEOS_HOST_DEVICE
+inline void
+TableCapillaryPressure::KernelWrapper::
+ computeInv( arraySlice1d< real64, compflow::USD_PHASE - 1 > const & phaseVolFraction,
+ arraySlice1d< real64 const, cappres::USD_CAPPRES - 2 > const & phaseCapPres,
+ arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const
+{
+ LvArray::forValuesInSlice( dPhaseCapPres_dPhaseVolFrac, []( real64 & val ){ val = 0.0; } );
+
+ using PT = CapillaryPressureBase::PhaseType;
+ integer const ipWater = m_phaseOrder[PT::WATER];
+ integer const ipOil = m_phaseOrder[PT::OIL];
+ integer const ipGas = m_phaseOrder[PT::GAS];
+
+ GEOS_UNUSED_VAR( ipOil );
+
+ // put capillary pressure on the wetting phase
+ real64 capPresWater = phaseCapPres[ipWater];
+ array1d< real64 > input( 1 );
+ input[0] = capPresWater;
+ auto inputSlice = input.toSliceConst();
+
+ phaseVolFraction[ipWater] =
+ m_capPresKernelWrappers[0].compute( &(phaseCapPres)[ipWater],
+ &(dPhaseCapPres_dPhaseVolFrac)[ipWater][ipWater] );
+ phaseVolFraction[ipWater] =
+ m_inverseCapPresWrappers[0].compute( inputSlice,
+ &(dPhaseCapPres_dPhaseVolFrac)[ipWater][ipWater] );
+ phaseVolFraction[ipGas] = 1.0 - phaseVolFraction[ipWater];
+
+}
+
+
GEOS_HOST_DEVICE
inline void
TableCapillaryPressure::KernelWrapper::
diff --git a/src/coreComponents/constitutive/capillaryPressure/VanGenuchtenCapillaryPressure.hpp b/src/coreComponents/constitutive/capillaryPressure/VanGenuchtenCapillaryPressure.hpp
index f3af8198d60..6ac95221027 100644
--- a/src/coreComponents/constitutive/capillaryPressure/VanGenuchtenCapillaryPressure.hpp
+++ b/src/coreComponents/constitutive/capillaryPressure/VanGenuchtenCapillaryPressure.hpp
@@ -57,6 +57,11 @@ class VanGenuchtenCapillaryPressureUpdate final : public CapillaryPressureBaseUp
arraySlice1d< real64, cappres::USD_CAPPRES - 2 > const & phaseCapPres,
arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const;
+ GEOS_HOST_DEVICE
+ void computeInv( arraySlice1d< real64 const, compflow::USD_PHASE - 1 > const & phaseVolFraction,
+ arraySlice1d< real64, cappres::USD_CAPPRES - 2 > const & phaseCapPres,
+ arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const;
+
GEOS_HOST_DEVICE
virtual void update( localIndex const k,
localIndex const q,
@@ -189,6 +194,69 @@ VanGenuchtenCapillaryPressureUpdate::
}
}
+GEOS_HOST_DEVICE
+inline void
+VanGenuchtenCapillaryPressureUpdate::
+ computeInv( arraySlice1d< real64 const, compflow::USD_PHASE - 1 > const & phaseVolFraction,
+ arraySlice1d< real64, cappres::USD_CAPPRES - 2 > const & phaseCapPres,
+ arraySlice2d< real64, cappres::USD_CAPPRES_DS - 2 > const & dPhaseCapPres_dPhaseVolFrac ) const
+{
+ LvArray::forValuesInSlice( dPhaseCapPres_dPhaseVolFrac, []( real64 & val ){ val = 0.0; } );
+
+ // the VanGenuchten model does not support volFracScaled = 0 and = 1
+ // hence we need an epsilon value to avoid a division by zero
+ // TODO: for S < epsilon and S > 1 - epsilon, replace the original unbounded VG curve with a bounded power-law
+ // extension
+ real64 const eps = m_capPressureEpsilon;
+ real64 const volFracScaleInv = 1.0 / m_volFracScale;
+
+ // compute first water-oil capillary pressure as a function of water-phase vol fraction
+ integer const ip_water = m_phaseOrder[CapillaryPressureBase::PhaseType::WATER];
+ if( ip_water >= 0 )
+ {
+
+ real64 const volFracScaled = (phaseVolFraction[ip_water] - m_phaseMinVolumeFraction[ip_water]) * volFracScaleInv;
+ real64 const exponentInv = m_phaseCapPressureExponentInv[ip_water]; // div by 0 taken care of by initialization
+ // check
+ real64 const multiplier = m_phaseCapPressureMultiplier[ip_water];
+
+ real64 const scaledWettingVolFrac = volFracScaled;
+ real64 const dScaledWettingPhaseVolFrac_dVolFrac = volFracScaleInv;
+
+ evaluateVanGenuchtenFunction( scaledWettingVolFrac,
+ dScaledWettingPhaseVolFrac_dVolFrac,
+ exponentInv,
+ multiplier,
+ eps,
+ phaseCapPres[ip_water],
+ dPhaseCapPres_dPhaseVolFrac[ip_water][ip_water] );
+
+ }
+
+
+ // then compute the oil-gas capillary pressure as a function of gas-phase vol fraction
+ integer const ip_gas = m_phaseOrder[CapillaryPressureBase::PhaseType::GAS];
+ if( ip_gas >= 0 )
+ {
+ real64 const volFracScaled = (phaseVolFraction[ip_gas] - m_phaseMinVolumeFraction[ip_gas]) * volFracScaleInv;
+ real64 const exponentInv = m_phaseCapPressureExponentInv[ip_gas]; // div by 0 taken care of by initialization
+ // check
+ real64 const multiplier = -m_phaseCapPressureMultiplier[ip_gas]; // for gas capillary pressure, take the opposite
+ // of the VG function
+
+ real64 const scaledWettingVolFrac = 1-volFracScaled;
+ real64 const dScaledWettingPhaseVolFrac_dVolFrac = -volFracScaleInv;
+
+ evaluateVanGenuchtenFunction( scaledWettingVolFrac,
+ dScaledWettingPhaseVolFrac_dVolFrac,
+ exponentInv,
+ multiplier,
+ eps,
+ phaseCapPres[ip_gas],
+ dPhaseCapPres_dPhaseVolFrac[ip_gas][ip_gas] );
+ }
+}
+
GEOS_HOST_DEVICE
GEOS_FORCE_INLINE
void
diff --git a/src/coreComponents/constitutive/docs/TwoPhaseFluid.rst b/src/coreComponents/constitutive/docs/TwoPhaseFluid.rst
new file mode 100644
index 00000000000..39b35510c63
--- /dev/null
+++ b/src/coreComponents/constitutive/docs/TwoPhaseFluid.rst
@@ -0,0 +1,90 @@
+.. _TwoPhaseFluid:
+
+############################################
+Two-phase fluid model
+############################################
+
+Overview
+=========================
+
+This model represents a two-phase fluid with pressure-dependent density and viscosity.
+
+For each phase, both density and viscosity are described as tabulated data, either in the form of ``TableFunction`` or text files.
+
+In the case of text files, one file is expected per phase and should consist of three columns: pressure, density and viscosity.
+
+Note that currently, there is no temperature dependence in the model.
+
+
+Parameters
+=========================
+
+The model is represented by ```` node in the input.
+
+The following attributes are supported:
+
+.. include:: /docs/sphinx/datastructure/TwoPhaseFluid.rst
+
+
+Example using TableFunctions
+============================
+
+.. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Example using text files
+=========================
+
+.. code-block:: xml
+
+
+
+
+
+
+with, for example, ``water.txt`` being set as:
+
+.. code-block:: text
+
+ # P(Pa) Dens(kg/m3) Visc(Pa.s)
+ 2068000 980.683 0.0003
+ 5516000 982.07 0.0003
+ 30600000 992.233 0.0003
+ 55160000 1002.265 0.0003
diff --git a/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.cpp b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.cpp
new file mode 100644
index 00000000000..ad6379ea129
--- /dev/null
+++ b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.cpp
@@ -0,0 +1,268 @@
+/*
+ * ------------------------------------------------------------------------------------------------------------
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC
+ * Copyright (c) 2018-2024 Total, S.A
+ * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University
+ * Copyright (c) 2023-2024 Chevron
+ * Copyright (c) 2019- GEOS/GEOSX Contributors
+ * All rights reserved
+ *
+ * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
+ * ------------------------------------------------------------------------------------------------------------
+ */
+
+/**
+ * @file TwoPhaseFluid.cpp
+ */
+
+#include "constitutive/fluid/multifluid/CO2Brine/functions/PVTFunctionHelpers.hpp" // for readTable
+#include "TwoPhaseFluid.hpp"
+#include "TwoPhaseFluidFields.hpp"
+
+#include "functions/FunctionManager.hpp"
+
+
+namespace geos
+{
+
+using namespace dataRepository;
+
+namespace constitutive
+{
+
+
+TwoPhaseFluid::TwoPhaseFluid( string const & name, Group * const parent )
+ : ConstitutiveBase( name, parent )
+{
+ registerWrapper( viewKeyStruct::phaseNamesString(), &m_phaseNames ).
+ setRTTypeName( rtTypes::CustomTypes::groupNameRefArray ).
+ setInputFlag( InputFlags::OPTIONAL ).
+ setDescription( "List of fluid phases" );
+
+ // 1) First option: specify PVT tables from one file per phase, read the files line by line, and populate the internal TableFunctions
+ registerWrapper( viewKeyStruct::tableFilesString(), &m_tableFiles ).
+ setInputFlag( InputFlags::OPTIONAL ).
+ setRestartFlags( RestartFlags::NO_WRITE ).
+ setDescription( "List of filenames with input PVT tables (one per phase)" );
+
+ // 2) Second option: specify TableFunction names for each phase,
+ registerWrapper( viewKeyStruct::densityTableNamesString(), &m_densityTableNames ).
+ setRTTypeName( rtTypes::CustomTypes::groupNameRefArray ).
+ setInputFlag( InputFlags::OPTIONAL ).
+ setDescription( "List of density TableFuncion names from the Function block. \n"
+ "The user must provide one TableFunction per phase, respecting the order provided in \"phaseNames\"." );
+
+ registerWrapper( viewKeyStruct::viscosityTableNamesString(), &m_viscosityTableNames ).
+ setRTTypeName( rtTypes::CustomTypes::groupNameRefArray ).
+ setInputFlag( InputFlags::OPTIONAL ).
+ setDescription( "List of viscosity TableFuncion names from the Function block. \n"
+ "The user must provide one TableFunction per phase, respecting the order provided in \"phaseNames\"." );
+
+ registerField( fields::twophasefluid::phaseDensity{}, &m_phaseDensity.value );
+ registerField( fields::twophasefluid::dPhaseDensity{}, &m_phaseDensity.derivs );
+ registerField( fields::twophasefluid::phaseDensity_n{}, &m_phaseDensity_n );
+
+ registerField( fields::twophasefluid::phaseViscosity{}, &m_phaseViscosity.value );
+ registerField( fields::twophasefluid::dPhaseViscosity{}, &m_phaseViscosity.derivs );
+}
+
+
+std::unique_ptr< ConstitutiveBase >
+TwoPhaseFluid::deliverClone( string const & name, Group * const parent ) const
+{
+ return ConstitutiveBase::deliverClone( name, parent );
+}
+
+
+void TwoPhaseFluid::resizeFields( localIndex const size, localIndex const numPts )
+{
+ // Assume sole dependency on pressure, i.e. one derivative
+ m_phaseDensity.value.resize( size, numPts, 2 );
+ m_phaseDensity.derivs.resize( size, numPts, 2, 1 );
+
+ m_phaseDensity_n.resize( size, numPts, 2 );
+
+ m_phaseViscosity.value.resize( size, numPts, 2 );
+ m_phaseViscosity.derivs.resize( size, numPts, 2, 1 );
+}
+
+
+void TwoPhaseFluid::allocateConstitutiveData( dataRepository::Group & parent,
+ localIndex const numConstitutivePointsPerParentIndex )
+{
+ ConstitutiveBase::allocateConstitutiveData( parent, numConstitutivePointsPerParentIndex );
+ resizeFields( parent.size(), numConstitutivePointsPerParentIndex );
+}
+
+
+void TwoPhaseFluid::postInputInitialization()
+{
+ ConstitutiveBase::postInputInitialization();
+
+ // Input relationships can be provided either as text files or TableFunctions.
+ m_tableFiles.empty() ? readInputDataFromTableFunctions() : readInputDataFromFileTableFunctions();
+
+ checkTableConsistency();
+}
+
+
+void TwoPhaseFluid::fillData( integer const ip,
+ array1d< array1d< real64 > > const & tableValues )
+{
+ array1d< array1d< real64 > > pressureCoords( 1 );
+ pressureCoords[0].resize( tableValues.size() );
+ array1d< real64 > density( tableValues.size() );
+ array1d< real64 > viscosity( tableValues.size() );
+
+ for( localIndex i = 0; i < tableValues.size(); ++i )
+ {
+ GEOS_THROW_IF_NE_MSG( tableValues[i].size(), 3,
+ GEOS_FMT( "{}: three columns (pressure, density, and viscosity) are expected", getFullName() ),
+ InputError );
+
+ pressureCoords[0][i] = tableValues[i][0];
+ density[i] = tableValues[i][1];
+ viscosity[i] = tableValues[i][2];
+ }
+
+ string const densityTableName = getName() + "DensityPhase" + GEOS_FMT( "{}", ip );
+ string const viscosityTableName = getName() + "ViscosityPhase" + GEOS_FMT( "{}", ip );
+ m_densityTableNames.emplace_back( densityTableName );
+ m_viscosityTableNames.emplace_back( viscosityTableName );
+
+ FunctionManager & functionManager = FunctionManager::getInstance();
+
+ TableFunction & tableDensity =
+ dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", densityTableName ) );
+ tableDensity.setTableCoordinates( pressureCoords, { units::Pressure } );
+ tableDensity.setTableValues( density, units::Density );
+ tableDensity.setInterpolationMethod( TableFunction::InterpolationType::Linear );
+
+ TableFunction & tableViscosity =
+ dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", viscosityTableName ) );
+ tableViscosity.setTableCoordinates( pressureCoords, { units::Pressure } );
+ tableViscosity.setTableValues( viscosity, units::Viscosity );
+ tableViscosity.setInterpolationMethod( TableFunction::InterpolationType::Linear );
+}
+
+
+void TwoPhaseFluid::readInputDataFromFileTableFunctions()
+{
+ // Check for ambiguous definition
+ GEOS_THROW_IF( !(m_densityTableNames.empty() && m_viscosityTableNames.empty()),
+ GEOS_FMT( "{}: input is redundant (both TableFunction names and text files)", getFullName() ),
+ InputError );
+
+
+ // Check that we have exactly two table files (one per phase)
+ GEOS_THROW_IF_NE_MSG( m_tableFiles.size(), 2,
+ GEOS_FMT( "{}: expecting two table files (one per phase)", getFullName() ),
+ InputError );
+
+ array1d< array1d< real64 > > tableValues;
+ for( integer ip = 0; ip < 2; ++ip )
+ {
+ tableValues.clear();
+ geos::constitutive::PVTProps::BlackOilTables::readTable( m_tableFiles[ip], 3, tableValues );
+ fillData( ip, tableValues );
+ }
+}
+
+
+void TwoPhaseFluid::readInputDataFromTableFunctions()
+{
+ // Check for ambiguous definition
+ GEOS_THROW_IF( !m_tableFiles.empty(),
+ GEOS_FMT( "{}: input is redundant (both TableFunction names and text files)", getFullName() ),
+ InputError );
+
+ // Since we are considering a two phase fluid, we should have exactly 2 tables per property
+ GEOS_THROW_IF_NE_MSG( m_densityTableNames.size(), 2,
+ GEOS_FMT( "{}: one density table must be provided for each phase", getFullName() ),
+ InputError );
+
+ GEOS_THROW_IF_NE_MSG( m_viscosityTableNames.size(), 2,
+ GEOS_FMT( "{}: one viscosity table must be provided for each phase", getFullName() ),
+ InputError );
+
+
+ FunctionManager const & functionManager = FunctionManager::getInstance();
+
+ for( integer iph = 0; iph < 2; ++iph )
+ {
+ GEOS_THROW_IF( !functionManager.hasGroup( m_densityTableNames[iph] ),
+ GEOS_FMT( "{}: density table '{}' not found", getFullName(), m_densityTableNames[iph] ),
+ InputError );
+
+ GEOS_THROW_IF( !functionManager.hasGroup( m_viscosityTableNames[iph] ),
+ GEOS_FMT( "{}: viscosity table '{}' not found", getFullName(), m_viscosityTableNames[iph] ),
+ InputError );
+ }
+}
+
+
+void TwoPhaseFluid::initializePostSubGroups()
+{
+ ConstitutiveBase::initializePostSubGroups();
+
+ FunctionManager const & functionManager = FunctionManager::getInstance();
+ for( integer iph = 0; iph < 2; ++iph )
+ {
+ // Grab the tables by name from the function manager,
+ // then add them in a list to create their table wrappers when needed
+ TableFunction const & densityTable = functionManager.getGroup< TableFunction const >( m_densityTableNames[iph] );
+ m_densityTables.emplace_back( &densityTable );
+ m_densityTableKernels.emplace_back( m_densityTables[iph]->createKernelWrapper() );
+
+ TableFunction const & viscosityTable = functionManager.getGroup< TableFunction const >( m_viscosityTableNames[iph] );
+ m_viscosityTables.emplace_back( &viscosityTable );
+ m_viscosityTableKernels.emplace_back( m_viscosityTables[iph]->createKernelWrapper() );
+ }
+}
+
+
+void TwoPhaseFluid::checkTableConsistency() const
+{
+ FunctionManager const & functionManager = FunctionManager::getInstance();
+ for( integer iph = 0; iph < 2; ++iph )
+ {
+ TableFunction const & densityTable = functionManager.getGroup< TableFunction const >( m_densityTableNames[iph] );
+ arrayView1d< real64 const > const density = densityTable.getValues();
+
+ for( localIndex i = 1; i < density.size(); ++i )
+ {
+ GEOS_THROW_IF( density[i] - density[i-1] < 0,
+ GEOS_FMT( "{}: in table '{}' density values must be increasing", getFullName(), densityTable.getName() ),
+ InputError );
+ }
+ }
+}
+
+
+TwoPhaseFluid::KernelWrapper
+TwoPhaseFluid::createKernelWrapper()
+{
+ return KernelWrapper( m_densityTableKernels,
+ m_viscosityTableKernels,
+ m_phaseDensity.toView(),
+ m_phaseViscosity.toView());
+}
+
+
+TwoPhaseFluid::KernelWrapper::KernelWrapper(
+ arrayView1d< TableFunction::KernelWrapper const > densityTables,
+ arrayView1d< TableFunction::KernelWrapper const > viscosityTables,
+ PhaseProp::ViewType phaseDensity,
+ PhaseProp::ViewType phaseViscosity )
+ : m_densityTables( std::move( densityTables )),
+ m_viscosityTables( std::move( viscosityTables )),
+ m_phaseDensity( std::move( phaseDensity )),
+ m_phaseViscosity( std::move( phaseViscosity )) {}
+
+
+REGISTER_CATALOG_ENTRY( ConstitutiveBase, TwoPhaseFluid, string const &, Group * const )
+
+} // namespace constitutive
+} // namespace geos
diff --git a/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp
new file mode 100644
index 00000000000..18cdc357bb0
--- /dev/null
+++ b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp
@@ -0,0 +1,344 @@
+/*
+ * ------------------------------------------------------------------------------------------------------------
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC
+ * Copyright (c) 2018-2024 Total, S.A
+ * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University
+ * Copyright (c) 2023-2024 Chevron
+ * Copyright (c) 2019- GEOS/GEOSX Contributors
+ * All rights reserved
+ *
+ * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
+ * ------------------------------------------------------------------------------------------------------------
+ */
+
+/**
+ * @file TwoPhaseFluid.hpp
+ */
+
+#ifndef GEOS_CONSTITUTIVE_FLUID_TWOPHASEFLUID_TWOPHASEFLUID_HPP_
+#define GEOS_CONSTITUTIVE_FLUID_TWOPHASEFLUID_TWOPHASEFLUID_HPP_
+
+#include "common/DataLayouts.hpp"
+#include "functions/TableFunction.hpp"
+#include "constitutive/ConstitutiveBase.hpp"
+
+#include "constitutive/fluid/multifluid/Layouts.hpp"
+#include "constitutive/fluid/multifluid/MultiFluidUtils.hpp"
+
+#include "constitutive/ConstitutivePassThruHandler.hpp"
+
+
+namespace geos
+{
+namespace constitutive
+{
+
+class TwoPhaseFluid : public ConstitutiveBase
+{
+public:
+
+ TwoPhaseFluid( string const & name,
+ Group * const parent );
+
+ virtual std::unique_ptr< ConstitutiveBase >
+ deliverClone( string const & name,
+ Group * const parent ) const override;
+
+ virtual void allocateConstitutiveData( dataRepository::Group & parent,
+ localIndex const numConstitutivePointsPerParentIndex ) override;
+
+ /**
+ * @name Static Factory Catalog members and functions
+ */
+ ///@{
+
+ /**
+ * @brief Static catalog string
+ * @return A string that is used to register/lookup this class in the registry
+ */
+ static std::string catalogName() { return "TwoPhaseFluid"; }
+
+ /**
+ * @brief Get catalog name
+ * @return Name string
+ */
+ virtual string getCatalogName() const override { return catalogName(); }
+
+ ///@}
+
+
+
+ /**
+ * @brief Getter for the fluid phase names
+ * @return an array storing the phase names
+ */
+ string_array const & phaseNames() const { return m_phaseNames; }
+
+ struct viewKeyStruct : ConstitutiveBase::viewKeyStruct
+ {
+ static constexpr char const * tableFilesString() { return "tableFiles"; }
+ static constexpr char const * phaseNamesString() { return "phaseNames"; }
+ static constexpr char const * densityTableNamesString() { return "densityTableNames"; }
+ static constexpr char const * viscosityTableNamesString() { return "viscosityTableNames"; }
+ };
+
+ arrayView3d< real64 const, multifluid::USD_PHASE > phaseDensity_n() const
+ { return m_phaseDensity_n; }
+
+ arrayView3d< real64 const, multifluid::USD_PHASE > phaseDensity() const
+ { return m_phaseDensity.value; }
+
+ arrayView4d< real64 const, multifluid::USD_PHASE_DC > dPhaseDensity() const
+ { return m_phaseDensity.derivs; }
+
+ arrayView3d< real64 const, multifluid::USD_PHASE > phaseViscosity() const
+ { return m_phaseViscosity.value; }
+
+ arrayView4d< real64 const, multifluid::USD_PHASE_DC > dPhaseViscosity() const
+ { return m_phaseViscosity.derivs; }
+
+ using PhaseProp = MultiFluidVar< real64, 3, constitutive::multifluid::LAYOUT_PHASE, constitutive::multifluid::LAYOUT_PHASE_DC >;
+
+
+ class KernelWrapper
+ {
+public:
+
+ /// @cond DO_NOT_DOCUMENT
+ /// We need these SMFs to avoid host-device errors with CUDA.
+ KernelWrapper() = default;
+ KernelWrapper( KernelWrapper const & ) = default;
+ KernelWrapper & operator=( KernelWrapper const & ) = default;
+ KernelWrapper & operator=( KernelWrapper && ) = default;
+ /// @endcond
+
+ /**
+ * @brief Get number of elements in this wrapper.
+ * @return number of elements
+ */
+ GEOS_HOST_DEVICE
+ GEOS_FORCE_INLINE
+ localIndex numElems() const { return m_phaseDensity.value.size( 0 ); }
+
+ /**
+ * @brief Get number of gauss points per element.
+ * @return number of gauss points per element
+ */
+ GEOS_HOST_DEVICE
+ GEOS_FORCE_INLINE
+ localIndex numGauss() const { return m_phaseDensity.value.size( 1 ); }
+
+
+ GEOS_HOST_DEVICE
+ void compute( real64 const pressure,
+ PhaseProp::SliceType const phaseDensity,
+ PhaseProp::SliceType const phaseViscosity ) const;
+
+ GEOS_HOST_DEVICE
+ void update( localIndex const k,
+ localIndex const q,
+ real64 const pressure ) const;
+
+private:
+
+ friend class TwoPhaseFluid;
+
+ /**
+ * @brief Constructor for the class doing in-kernel two-phase fluid updates
+ * @param[in] densityTables density tables
+ * @param[in] viscosityTables viscosity tables
+ * @param[in] phaseDensity phase densities (+ derivatives) in the cell
+ * @param[in] phaseViscosity phase viscosities (+ derivatives) in the cell
+ */
+ KernelWrapper(
+ arrayView1d< TableFunction::KernelWrapper const > densityTables,
+ arrayView1d< TableFunction::KernelWrapper const > viscosityTables,
+ PhaseProp::ViewType phaseDensity,
+ PhaseProp::ViewType phaseViscosity );
+
+
+protected:
+
+ KernelWrapper(
+ arrayView1d< TableFunction::KernelWrapper const > densityTables,
+ arrayView1d< TableFunction::KernelWrapper const > viscosityTables
+ );
+
+ /// Table kernel wrappers to interpolate in the two phase (\rho vs p) tables
+ arrayView1d< TableFunction::KernelWrapper const > m_densityTables;
+
+ /// Table kernel wrappers to interpolate in the two phase (\mu vs p) tables
+ arrayView1d< TableFunction::KernelWrapper const > m_viscosityTables;
+
+ /**
+ * @brief Utility function to compute densities as a function of pressure (keeping derivatives)
+ * @param[in] pressure pressure in the cell
+ * @param[out] phaseDensity the phase density in the cell (+ derivatives)
+ */
+ GEOS_HOST_DEVICE
+ void computeDensities( real64 const pressure,
+ PhaseProp::SliceType const & phaseDensity ) const;
+
+ /**
+ * @brief Utility function to compute viscosities as a function of pressure (keeping derivatives)
+ * @param[in] pressure pressure in the cell
+ * @param[out] phaseViscosity the phase viscosities in the cell (+ derivatives)
+ */
+ GEOS_HOST_DEVICE
+ void computeViscosities( real64 const pressure,
+ PhaseProp::SliceType const & phaseViscosity ) const;
+
+ /// Views on the phase properties
+ PhaseProp::ViewType m_phaseDensity;
+ PhaseProp::ViewType m_phaseViscosity;
+
+ }; //class KernelWrapper
+
+
+ string_array m_phaseNames;
+
+
+ path_array m_tableFiles;
+
+ /// Names of the density tables (one per phase)
+ string_array m_densityTableNames;
+
+ /// Names of the viscosity tables (one per phase)
+ string_array m_viscosityTableNames;
+
+ PhaseProp m_phaseDensity;
+ PhaseProp m_phaseViscosity;
+
+ /// Backup data
+ array3d< real64, multifluid::LAYOUT_PHASE > m_phaseDensity_n;
+
+
+ virtual void resizeFields( localIndex const size, localIndex const numPts );
+
+ virtual void postInputInitialization() override;
+
+ virtual void initializePostSubGroups() override;
+
+ /// Table kernel wrappers to interpolate (\rho vs p) tables
+ array1d< TableFunction const * > m_densityTables;
+ /// Table kernel wrappers of m_densityTables
+ array1d< TableFunction::KernelWrapper > m_densityTableKernels;
+
+ /// Table kernel wrappers to interpolate (\mu vs p) tables
+ array1d< TableFunction const * > m_viscosityTables;
+ /// Table kernel wrappers of m_viscosityTables
+ array1d< TableFunction::KernelWrapper > m_viscosityTableKernels;
+
+ KernelWrapper createKernelWrapper();
+
+
+private:
+ void readInputDataFromTableFunctions();
+ void readInputDataFromFileTableFunctions();
+
+ /**
+ * @brief Fill the fluid data (pressure, density, viscosity)
+ * @param[in] ip the index of the phase
+ * @param[in] tableValues the values in the fluid table
+ */
+ void fillData( integer const ip,
+ array1d< array1d< real64 > > const & tableValues );
+
+ /**
+ * @brief Check the monotonicity of the PVT relationship
+ */
+ void checkTableConsistency() const;
+};
+
+
+GEOS_HOST_DEVICE
+GEOS_FORCE_INLINE
+void TwoPhaseFluid::KernelWrapper::
+ computeDensities( real64 const pressure,
+ PhaseProp::SliceType const & phaseDensity ) const
+{
+ using Deriv = constitutive::multifluid::DerivativeOffset;
+
+ LvArray::forValuesInSlice( phaseDensity.derivs, []( real64 & val ) { val = 0.0; } );
+
+ for( integer iph = 0; iph < 2; ++iph )
+ {
+ // interpolate in the table to get the phase density and derivatives
+ real64 dPhaseDens_dPres = 0.0;
+
+ phaseDensity.value[iph] = m_densityTables[iph].compute( &pressure, &dPhaseDens_dPres );
+ phaseDensity.derivs[iph][Deriv::dP] = dPhaseDens_dPres;
+ }
+}
+
+
+GEOS_HOST_DEVICE
+GEOS_FORCE_INLINE
+void TwoPhaseFluid::KernelWrapper::
+ computeViscosities( real64 const pressure,
+ PhaseProp::SliceType const & phaseViscosity ) const
+{
+ using Deriv = constitutive::multifluid::DerivativeOffset;
+
+ LvArray::forValuesInSlice( phaseViscosity.derivs, []( real64 & val ) { val = 0.0; } );
+
+ for( integer iph = 0; iph < 2; ++iph )
+ {
+ // interpolate in the table to get the phase viscosity and derivatives
+ real64 dPhaseVisc_dPres = 0.0;
+ phaseViscosity.value[iph] = m_viscosityTables[iph].compute( &pressure, &dPhaseVisc_dPres );
+ phaseViscosity.derivs[iph][Deriv::dP] = dPhaseVisc_dPres;
+ }
+}
+
+
+GEOS_HOST_DEVICE
+GEOS_FORCE_INLINE
+void TwoPhaseFluid::KernelWrapper::
+ compute( real64 const pressure,
+ PhaseProp::SliceType const phaseDensity,
+ PhaseProp::SliceType const phaseViscosity ) const
+{
+ computeDensities( pressure,
+ phaseDensity );
+
+ computeViscosities( pressure,
+ phaseViscosity );
+}
+
+
+GEOS_HOST_DEVICE
+GEOS_FORCE_INLINE
+void TwoPhaseFluid::KernelWrapper::
+ update( localIndex const k,
+ localIndex const q,
+ real64 const pressure
+ ) const
+{
+ compute( pressure,
+ m_phaseDensity( k, q ),
+ m_phaseViscosity( k, q ) );
+}
+
+
+template< typename LAMBDA >
+void constitutiveUpdatePassThru( TwoPhaseFluid const & fluid,
+ LAMBDA && lambda )
+{
+ ConstitutivePassThruHandler< TwoPhaseFluid >::execute( fluid, std::forward< LAMBDA >( lambda ) );
+}
+
+
+template< typename LAMBDA >
+void constitutiveUpdatePassThru( TwoPhaseFluid & fluid,
+ LAMBDA && lambda )
+{
+ ConstitutivePassThruHandler< TwoPhaseFluid >::execute( fluid, std::forward< LAMBDA >( lambda ) );
+}
+
+} // namespace constitutive
+} // namespace geos
+
+#endif // GEOS_CONSTITUTIVE_FLUID_TWOPHASEFLUID_TWOPHASEFLUID_HPP_
diff --git a/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluidFields.hpp b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluidFields.hpp
new file mode 100644
index 00000000000..9ce0dc5c33d
--- /dev/null
+++ b/src/coreComponents/constitutive/fluid/twophasefluid/TwoPhaseFluidFields.hpp
@@ -0,0 +1,84 @@
+/*
+ * ------------------------------------------------------------------------------------------------------------
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC
+ * Copyright (c) 2018-2024 Total, S.A
+ * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University
+ * Copyright (c) 2023-2024 Chevron
+ * Copyright (c) 2019- GEOS/GEOSX Contributors
+ * All rights reserved
+ *
+ * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
+ * ------------------------------------------------------------------------------------------------------------
+ */
+
+/**
+ * @file TwoPhaseFluidFields.hpp
+ */
+
+#ifndef GEOS_CONSTITUTIVE_FLUID_TWOPHASEFLUIDFIELDS_HPP_
+#define GEOS_CONSTITUTIVE_FLUID_TWOPHASEFLUIDFIELDS_HPP_
+
+#include "constitutive/fluid/multifluid/Layouts.hpp"
+#include "mesh/MeshFields.hpp"
+
+
+namespace geos
+{
+
+namespace fields
+{
+
+namespace twophasefluid
+{
+
+using array3dLayoutPhase = array3d< real64, constitutive::multifluid::LAYOUT_PHASE >;
+using array4dLayoutPhase_d = array4d< real64, constitutive::multifluid::LAYOUT_PHASE_DC >;
+
+DECLARE_FIELD( phaseDensity,
+ "phaseDensity",
+ array3dLayoutPhase,
+ 0,
+ LEVEL_0,
+ WRITE_AND_READ,
+ "Phase density" );
+
+DECLARE_FIELD( phaseDensity_n,
+ "phaseDensity_n",
+ array3dLayoutPhase,
+ 0,
+ NOPLOT,
+ WRITE_AND_READ,
+ "Phase density at the previous converged time step" );
+
+DECLARE_FIELD( dPhaseDensity,
+ "dPhaseDensity",
+ array4dLayoutPhase_d,
+ 0,
+ NOPLOT,
+ NO_WRITE,
+ "Derivative of phase density with respect to pressure" );
+
+DECLARE_FIELD( phaseViscosity,
+ "phaseViscosity",
+ array3dLayoutPhase,
+ 0,
+ LEVEL_0,
+ WRITE_AND_READ,
+ "Phase viscosity" );
+
+DECLARE_FIELD( dPhaseViscosity,
+ "dPhaseViscosity",
+ array4dLayoutPhase_d,
+ 0,
+ NOPLOT,
+ NO_WRITE,
+ "Derivative of phase viscosity with respect to pressure" );
+
+} // namespace twophasefluid
+
+} // namespace constitutive
+} // namespace geos
+
+#endif // GEOS_CONSTITUTIVE_FLUID_TWOPHASEFLUIDFIELDS_HPP_
diff --git a/src/coreComponents/constitutive/unitTests/FluidModelTest_impl.hpp b/src/coreComponents/constitutive/unitTests/FluidModelTest_impl.hpp
index 72cfec6501c..ce731e6b775 100644
--- a/src/coreComponents/constitutive/unitTests/FluidModelTest_impl.hpp
+++ b/src/coreComponents/constitutive/unitTests/FluidModelTest_impl.hpp
@@ -35,7 +35,7 @@ template< typename FLUID_TYPE, integer NUM_COMP, integer NUM_PHASE >
FluidModelTest< FLUID_TYPE, NUM_COMP, NUM_PHASE >::FluidModelTest():
m_parent( "parent", m_node )
{
- createFunctionManager();
+ // createFunctionManager();
}
template< typename FLUID_TYPE, integer NUM_COMP, integer NUM_PHASE >
diff --git a/src/coreComponents/constitutive/unitTests/testCO2SpycherPruessModels.cpp.uncrustify b/src/coreComponents/constitutive/unitTests/testCO2SpycherPruessModels.cpp.uncrustify
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/src/coreComponents/constitutive/unitTests/testTwoPhaseFluid.cpp b/src/coreComponents/constitutive/unitTests/testTwoPhaseFluid.cpp
new file mode 100644
index 00000000000..207668e29cb
--- /dev/null
+++ b/src/coreComponents/constitutive/unitTests/testTwoPhaseFluid.cpp
@@ -0,0 +1,283 @@
+/*
+ * ------------------------------------------------------------------------------------------------------------
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC
+ * Copyright (c) 2018-2024 TotalEnergies
+ * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University
+ * Copyright (c) 2023-2024 Chevron
+ * Copyright (c) 2019- GEOS/GEOSX Contributors
+ * All rights reserved
+ *
+ * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
+ * ------------------------------------------------------------------------------------------------------------
+ */
+
+#include "constitutive/fluid/twophasefluid/TwoPhaseFluid.hpp"
+#include "constitutive/fluid/twophasefluid/TwoPhaseFluidFields.hpp"
+
+// Only for fill
+#include "unitTests/constitutiveTests/MultiFluidTest.hpp"
+
+// Only for initializeTable
+#include "unitTests/constitutiveTests/constitutiveTestHelpers.hpp"
+
+
+using namespace geos;
+using namespace geos::testing;
+using namespace geos::constitutive;
+using namespace geos::dataRepository; /// Only for group definition
+
+
+static constexpr char const * tableContentPhase0 = "# Pg(Pa) Dens(kg/m3) Visc(Pa.s)\n"
+ "0.22 0.00603 40203\n"
+ "0.3 0.04224 31311\n"
+ "0.5 0.15011 22423\n"
+ "0.6 0.22423 15011\n"
+ "0.8 0.31311 4224\n"
+ "1.0 0.40203 603";
+
+static constexpr char const * tableContentPhase1 = "# Pg(Pa) Dens(kg/m3) Visc(Pa.s)\n"
+ "1.22 0.00603 0.22\n"
+ "1.3 0.04224 0.22\n"
+ "1.5 0.15011 0.22\n"
+ "1.6 0.22423 0.22\n"
+ "1.8 0.31311 0.22\n"
+ "2.0 0.40203 0.22";
+
+template< bool FROM_TABLE >
+class TwoPhaseFluidTest : public ConstitutiveTestBase< TwoPhaseFluid >
+{
+public:
+
+ TwoPhaseFluidTest()
+ {
+ if constexpr (!FROM_TABLE)
+ {
+ writeTableToFile( "phase0.txt", tableContentPhase0 );
+ writeTableToFile( "phase1.txt", tableContentPhase1 );
+ }
+
+ m_parent.resize( 1 );
+ string const fluidName = GEOS_FMT( "fluid{}", (FROM_TABLE ? "Tables" : "Files"));
+ m_model = makeTwoPhaseFluid( fluidName, m_parent );
+
+ m_parent.initialize();
+ m_parent.initializePostInitialConditions();
+ }
+
+ ~TwoPhaseFluidTest()
+ {
+ if constexpr (!FROM_TABLE)
+ {
+ removeFile( "phase0.txt" );
+ removeFile( "phase1.txt" );
+ }
+ }
+
+ constitutive::TwoPhaseFluid & getFluid() const { return *m_model; }
+
+ dataRepository::Group & getParent() { return m_parent; }
+
+
+ void testDerivatives( constitutive::TwoPhaseFluid & fluid,
+ dataRepository::Group * parent,
+ real64 const pressure,
+ real64 const perturbParameter,
+ real64 const relTol,
+ real64 const absTol = std::numeric_limits< real64 >::max() )
+ {
+ auto const & phaseNames = fluid.getReference< string_array >( TwoPhaseFluid::viewKeyStruct::phaseNamesString() );
+
+ // create a clone of the fluid to run updates on
+ string const fluidCopyName = fluid.getName() + "Copy";
+ std::unique_ptr< constitutive::ConstitutiveBase > fluidCopyPtr = fluid.deliverClone( fluidCopyName, parent );
+ constitutive::TwoPhaseFluid & fluidCopy = dynamicCast< constitutive::TwoPhaseFluid & >( *fluidCopyPtr );
+ fluidCopy.initializePostSubGroups();
+
+ fluid.allocateConstitutiveData( fluid.getParent(), 1 );
+ fluidCopy.allocateConstitutiveData( fluid.getParent(), 1 );
+
+ // extract data views from both fluids
+ #define GET_FLUID_DATA( FLUID, TRAIT ) \
+ FLUID.getReference< TRAIT::type >( TRAIT::key() )[0][0]
+
+ constitutive::MultiFluidVarSlice< real64, 1, constitutive::multifluid::USD_PHASE - 2, constitutive::multifluid::USD_PHASE_DC - 2 > phaseVisc {
+ GET_FLUID_DATA( fluid, fields::twophasefluid::phaseViscosity ),
+ GET_FLUID_DATA( fluid, fields::twophasefluid::dPhaseViscosity )
+ };
+
+ constitutive::MultiFluidVarSlice< real64, 1, constitutive::multifluid::USD_PHASE - 2, constitutive::multifluid::USD_PHASE_DC - 2 > phaseDens {
+ GET_FLUID_DATA( fluid, fields::twophasefluid::phaseDensity ),
+ GET_FLUID_DATA( fluid, fields::twophasefluid::dPhaseDensity )
+ };
+
+ auto const & phaseDensCopy = GET_FLUID_DATA( fluidCopy, fields::twophasefluid::phaseDensity );
+ auto const & phaseViscCopy = GET_FLUID_DATA( fluidCopy, fields::twophasefluid::phaseViscosity );
+#undef GET_FLUID_DATA
+
+
+ // set the original fluid state to current
+ constitutive::constitutiveUpdatePassThru( fluid, [&] ( auto & castedFluid )
+ {
+ typename TYPEOFREF( castedFluid ) ::KernelWrapper fluidWrapper = castedFluid.createKernelWrapper();
+ fluidWrapper.update( 0, 0, pressure );
+ } );
+
+ // now perturb variables and update the copied fluid's state
+ constitutive::constitutiveUpdatePassThru( fluidCopy, [&] ( auto & castedFluid )
+ {
+ using Deriv = constitutive::multifluid::DerivativeOffset;
+
+ typename TYPEOFREF( castedFluid ) ::KernelWrapper fluidWrapper = castedFluid.createKernelWrapper();
+
+ // to be able to use the checkDerivative utility function, we have to invert the layout
+ auto dPhaseDens = invertLayout( phaseDens.derivs.toSliceConst(), 2, 1 );
+ auto dPhaseVisc = invertLayout( phaseVisc.derivs.toSliceConst(), 2, 1 );
+
+ // update pressure and check derivatives
+ real64 const dP = perturbParameter * (pressure + perturbParameter);
+ fluidWrapper.update( 0, 0, pressure + dP );
+
+ checkDerivative( phaseDensCopy.toSliceConst(), phaseDens.value.toSliceConst(), dPhaseDens[Deriv::dP].toSliceConst(),
+ dP, relTol, absTol, "phaseDens", "Pressure", phaseNames );
+ checkDerivative( phaseViscCopy.toSliceConst(), phaseVisc.value.toSliceConst(), dPhaseVisc[Deriv::dP].toSliceConst(),
+ dP, relTol, absTol, "phaseVisc", "Pressure", phaseNames );
+ } );
+ } // void testDerivatives
+
+
+protected:
+ static void writeTableToFile( string const & fileName, char const * content )
+ {
+ std::ofstream os( fileName );
+ ASSERT_TRUE( os.is_open() );
+ os << content;
+ os.close();
+ }
+
+ static void removeFile( string const & fileName )
+ {
+ int const ret = std::remove( fileName.c_str() );
+ ASSERT_TRUE( ret == 0 );
+ }
+
+
+private:
+ static TwoPhaseFluid * makeTwoPhaseFluid( string const & name, Group & parent );
+
+}; // class TwoPhaseFluidTest
+
+
+template<>
+TwoPhaseFluid * TwoPhaseFluidTest< true >::makeTwoPhaseFluid( string const & name, Group & parent )
+{
+ // 1D table with linear interpolation
+ localIndex constexpr Naxis = 6;
+ localIndex constexpr NaxisSingle = 1;
+
+ array1d< real64_array > densityCoordPhase0( 1 );
+ fill< Naxis >( densityCoordPhase0[0], { 0.22, 0.3, 0.5, 0.6, 0.8, 1.0 } );
+ real64_array densityValuesPhase0;
+ fill< Naxis >( densityValuesPhase0, { 0.00603, 0.04224, 0.04224, 0.22423, 0.31311, 0.40203 } );
+
+ array1d< real64_array > densityCoordPhase1( 1 );
+ fill< Naxis >( densityCoordPhase1[0], { 1.22, 1.3, 1.5, 1.6, 1.8, 2.0 } );
+ real64_array densityValuesPhase1;
+ fill< Naxis >( densityValuesPhase1, { 0.00603, 0.04224, 0.04224, 0.22423, 0.31311, 0.40203 } );
+
+
+ array1d< real64_array > viscosityCoordPhase0( 1 );
+ fill< Naxis >( viscosityCoordPhase0[0], { 0.22, 0.3, 0.5, 0.6, 0.8, 1.0 } );
+ real64_array viscosityValuesPhase0;
+ fill< Naxis >( viscosityValuesPhase0, { 40203, 31311, 22423, 15011, 4224, 603 } );
+
+ array1d< real64_array > viscosityCoordPhase1( 1 );
+ fill< NaxisSingle >( viscosityCoordPhase1[0], { 0.22 } );
+ real64_array viscosityValuesPhase1;
+ fill< NaxisSingle >( viscosityValuesPhase1, { 45 } );
+
+ initializeTable( "densityTablePhase0", densityCoordPhase0, densityValuesPhase0 );
+ initializeTable( "densityTablePhase1", densityCoordPhase1, densityValuesPhase1 );
+ initializeTable( "viscosityTablePhase0", viscosityCoordPhase0, viscosityValuesPhase0 );
+ initializeTable( "viscosityTablePhase1", viscosityCoordPhase1, viscosityValuesPhase1 );
+
+
+ // 2) Set up the constitutive model
+ TwoPhaseFluid & fluid = parent.registerGroup< TwoPhaseFluid >( name );
+
+ string_array & phaseNames = fluid.getReference< string_array >( TwoPhaseFluid::viewKeyStruct::phaseNamesString() );
+ phaseNames.emplace_back( "oil" );
+ phaseNames.emplace_back( "water" );
+
+ string_array & densityTableNames = fluid.getReference< string_array >( TwoPhaseFluid::viewKeyStruct::densityTableNamesString() );
+ densityTableNames.emplace_back( "densityTablePhase0" );
+ densityTableNames.emplace_back( "densityTablePhase1" );
+
+ string_array & viscosityTableNames = fluid.getReference< string_array >( TwoPhaseFluid::viewKeyStruct::viscosityTableNamesString() );
+ viscosityTableNames.emplace_back( "viscosityTablePhase0" );
+ viscosityTableNames.emplace_back( "viscosityTablePhase1" );
+
+ fluid.postInputInitializationRecursive();
+ return &fluid;
+}
+
+
+template<>
+TwoPhaseFluid * TwoPhaseFluidTest< false >::makeTwoPhaseFluid( string const & name, Group & parent )
+{
+ TwoPhaseFluid & fluid = parent.registerGroup< TwoPhaseFluid >( name );
+
+ path_array & tableNames = fluid.getReference< path_array >( TwoPhaseFluid::viewKeyStruct::tableFilesString() );
+ fill< 2 >( tableNames, {"phase0.txt", "phase1.txt"} );
+
+ fluid.postInputInitializationRecursive();
+ return &fluid;
+}
+
+
+
+using TwoPhaseFluidTestFromFiles = TwoPhaseFluidTest< false >;
+using TwoPhaseFluidTestFromTables = TwoPhaseFluidTest< true >;
+
+
+TEST_F( TwoPhaseFluidTestFromTables, testNumericalDerivative_initFromTables )
+{
+ auto & fluid = getFluid();
+ real64 const eps = std::sqrt( std::numeric_limits< real64 >::epsilon());
+ real64 constexpr relTol = 1.0e-8;
+ real64 constexpr absTol = 1.0e-8;
+
+ for( real64 const pressure : { 0.55, 1.0, 10.0 } )
+ {
+ testDerivatives( fluid, &getParent(), pressure, eps, relTol, absTol );
+ }
+}
+
+
+TEST_F( TwoPhaseFluidTestFromFiles, testNumericalDerivative_initFromFiles )
+{
+ auto & fluid = getFluid();
+ real64 const eps = std::sqrt( std::numeric_limits< real64 >::epsilon());
+ real64 constexpr relTol = 1.0e-8;
+ real64 constexpr absTol = 1.0e-8;
+
+ for( real64 const pressure : { 0.55, 1.0, 10.0 } )
+ {
+ testDerivatives( fluid, &getParent(), pressure, eps, relTol, absTol );
+ }
+}
+
+
+int main( int argc, char * * argv )
+{
+ ::testing::InitGoogleTest( &argc, argv );
+
+ conduit::Node conduitNode;
+ dataRepository::Group rootNode( "root", conduitNode );
+ FunctionManager functionManager( "FunctionManager", &rootNode );
+
+ int const result = RUN_ALL_TESTS();
+
+ return result;
+}
diff --git a/src/coreComponents/finiteVolume/CellElementStencilTPFA.hpp b/src/coreComponents/finiteVolume/CellElementStencilTPFA.hpp
index 88fa3bb2b27..5c468d293cf 100644
--- a/src/coreComponents/finiteVolume/CellElementStencilTPFA.hpp
+++ b/src/coreComponents/finiteVolume/CellElementStencilTPFA.hpp
@@ -70,6 +70,20 @@ class CellElementStencilTPFAWrapper : public StencilWrapperBase< TwoPointStencil
CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar,
real64 ( &weight )[1][2],
real64 ( &dWeight_dVar )[1][2] ) const;
+/**
+ * @brief Compute half weights and derivatives w.r.t to one variable.
+ * @param[in] iconn connection index
+ * @param[in] coefficient view accessor to the coefficient used to compute the weights
+ * @param[in] dCoeff_dVar view accessor to the derivative of the coefficient w.r.t to the variable
+ * @param[out] weight view weights
+ * @param[out] dWeight_dVar derivative of the weights w.r.t to the variable
+ */
+ GEOS_HOST_DEVICE
+ void computeHalfWeights( localIndex const iconn,
+ CoefficientAccessor< arrayView3d< real64 const > > const & coefficient,
+ CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar,
+ real64 ( &weight )[1][2],
+ real64 ( &dWeight_dVar )[1][2] ) const;
/**
* @brief Compute weights and derivatives w.r.t to one variable without coefficient
@@ -293,6 +307,92 @@ CellElementStencilTPFAWrapper::
}
}
+GEOS_HOST_DEVICE
+inline void
+CellElementStencilTPFAWrapper::
+ computeHalfWeights( localIndex const iconn,
+ CoefficientAccessor< arrayView3d< real64 const > > const & coefficient,
+ CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar,
+ real64 (& weight)[1][2],
+ real64 (& dWeight_dVar )[1][2] ) const
+{
+ real64 halfWeight[2];
+ real64 dHalfWeight_dVar[2];
+
+ // real64 const tolerance = 1e-30 * lengthTolerance; // TODO: choice of constant based on physics?
+
+ for( localIndex i = 0; i < 2; ++i )
+ {
+ localIndex const er = m_elementRegionIndices[iconn][i];
+ localIndex const esr = m_elementSubRegionIndices[iconn][i];
+ localIndex const ei = m_elementIndices[iconn][i];
+
+ halfWeight[i] = m_weights[iconn][i];
+ dHalfWeight_dVar[i] = m_weights[iconn][i];
+
+ // Proper computation
+ real64 faceNormal[3];
+ LvArray::tensorOps::copy< 3 >( faceNormal, m_faceNormal[iconn] );
+ if( LvArray::tensorOps::AiBi< 3 >( m_cellToFaceVec[iconn][i], faceNormal ) < 0.0 )
+ {
+ LvArray::tensorOps::scale< 3 >( faceNormal, -1 );
+ }
+
+ real64 faceConormal[3];
+ real64 dFaceConormal_dVar[3];
+ LvArray::tensorOps::hadamardProduct< 3 >( faceConormal, coefficient[er][esr][ei][0], faceNormal );
+ LvArray::tensorOps::hadamardProduct< 3 >( dFaceConormal_dVar, dCoeff_dVar[er][esr][ei][0], faceNormal );
+ halfWeight[i] *= LvArray::tensorOps::AiBi< 3 >( m_cellToFaceVec[iconn][i], faceConormal );
+ dHalfWeight_dVar[i] *= LvArray::tensorOps::AiBi< 3 >( m_cellToFaceVec[iconn][i], dFaceConormal_dVar );
+
+ // correct negative weight issue arising from non-K-orthogonal grids
+ // if( halfWeight[i] < 0.0 )
+ // {
+ // LvArray::tensorOps::hadamardProduct< 3 >( faceConormal,
+ // coefficient[er][esr][ei][0],
+ // m_cellToFaceVec[iconn][i] );
+ // LvArray::tensorOps::hadamardProduct< 3 >( dFaceConormal_dVar,
+ // dCoeff_dVar[er][esr][ei][0],
+ // m_cellToFaceVec[iconn][i] );
+ // halfWeight[i] = m_weights[iconn][i];
+ // dHalfWeight_dVar[i] = m_weights[iconn][i];
+ // halfWeight[i] *= LvArray::tensorOps::AiBi< 3 >( m_cellToFaceVec[iconn][i], faceConormal );
+ // dHalfWeight_dVar[i] *= LvArray::tensorOps::AiBi< 3 >( m_cellToFaceVec[iconn][i], dFaceConormal_dVar );
+ // }
+ }
+
+ // // Do harmonic and arithmetic averaging
+ // real64 const product = halfWeight[0]*halfWeight[1];
+ // real64 const sum = halfWeight[0]+halfWeight[1];
+
+ // real64 const harmonicWeight = sum > 0 ? product / sum : 0.0;
+ // real64 const arithmeticWeight = sum / 2;
+
+ // real64 dHarmonicWeight_dVar[2];
+ // real64 dArithmeticWeight_dVar[2];
+
+ // dHarmonicWeight_dVar[0] = sum > 0 ? (dHalfWeight_dVar[0]*sum*halfWeight[1] - dHalfWeight_dVar[0]*halfWeight[0]*halfWeight[1]) / (
+ // sum*sum ) : 0.0;
+ // dHarmonicWeight_dVar[1] = sum > 0 ? (dHalfWeight_dVar[1]*sum*halfWeight[0] - dHalfWeight_dVar[1]*halfWeight[1]*halfWeight[0]) / (
+ // sum*sum ) : 0.0;
+
+ // dArithmeticWeight_dVar[0] = dHalfWeight_dVar[0] / 2;
+ // dArithmeticWeight_dVar[1] = dHalfWeight_dVar[1] / 2;
+
+ // real64 const meanPermCoeff = 1.0; //TODO make it a member if it is really necessary
+
+ // real64 const value = meanPermCoeff * harmonicWeight + (1 - meanPermCoeff) * arithmeticWeight;
+ for( localIndex ke = 0; ke < 2; ++ke )
+ {
+ // weight[0][ke] = m_transMultiplier[iconn] * value * (ke == 0 ? 1 : -1);
+ weight[0][ke] = m_transMultiplier[iconn] * halfWeight[ke] * (ke == 0 ? 1 : -1);
+
+ // real64 const dValue_dVar = meanPermCoeff * dHarmonicWeight_dVar[ke] + (1 - meanPermCoeff) * dArithmeticWeight_dVar[ke];
+ // dWeight_dVar[0][ke] = m_transMultiplier[iconn] * dValue_dVar;
+ dWeight_dVar[0][ke] = m_transMultiplier[iconn] * dHalfWeight_dVar[ke];
+ }
+}
+
GEOS_HOST_DEVICE
inline void
CellElementStencilTPFAWrapper::
diff --git a/src/coreComponents/finiteVolume/EmbeddedSurfaceToCellStencil.hpp b/src/coreComponents/finiteVolume/EmbeddedSurfaceToCellStencil.hpp
index 7f9c1562366..4a191ca7614 100644
--- a/src/coreComponents/finiteVolume/EmbeddedSurfaceToCellStencil.hpp
+++ b/src/coreComponents/finiteVolume/EmbeddedSurfaceToCellStencil.hpp
@@ -98,6 +98,22 @@ class EmbeddedSurfaceToCellStencilWrapper : public StencilWrapperBase< TwoPointS
real64 ( &weight )[1][2],
real64 ( &dWeight_dVar )[1][2] ) const;
+ /**
+ * @brief Compute half weigths and derivatives w.r.t to one variable.
+ * @param[in] iconn connection index
+ * @param[in] coefficient view accessor to the coefficient used to compute the weights
+ * @param[in] dCoeff_dVar view accessor to the derivative of the coefficient w.r.t to the variable
+ * @param[out] weight view weights
+ * @param[out] dWeight_dVar derivative of the weigths w.r.t to the variable
+ */
+
+ GEOS_HOST_DEVICE
+ void computeHalfWeights( localIndex const iconn,
+ CoefficientAccessor< arrayView3d< real64 const > > const & coefficient,
+ CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar,
+ real64 ( &weight )[1][2],
+ real64 ( &dWeight_dVar )[1][2] ) const;
+
/**
* @brief Compute weigths and derivatives w.r.t to one variable without coefficient
* Used in ReactiveCompositionalMultiphaseOBL solver for thermal transmissibility computation:
@@ -243,6 +259,42 @@ EmbeddedSurfaceToCellStencilWrapper::
dWeight_dVar[0][1] = ( t0 * dt1 * sumOfTrans - dt1 * t0 * t1 ) / ( sumOfTrans * sumOfTrans );
}
+GEOS_HOST_DEVICE
+inline void
+EmbeddedSurfaceToCellStencilWrapper::
+ computeHalfWeights( localIndex iconn,
+ CoefficientAccessor< arrayView3d< real64 const > > const & coefficient,
+ CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar,
+ real64 ( & weight )[1][2],
+ real64 ( & dWeight_dVar )[1][2] ) const
+{
+ localIndex const er0 = m_elementRegionIndices[iconn][0];
+ localIndex const esr0 = m_elementSubRegionIndices[iconn][0];
+ localIndex const ei0 = m_elementIndices[iconn][0];
+
+ localIndex const er1 = m_elementRegionIndices[iconn][1];
+ localIndex const esr1 = m_elementSubRegionIndices[iconn][1];
+ localIndex const ei1 = m_elementIndices[iconn][1];
+
+ // Will change when implementing collocation points. Will use fracture normal to project the permeability
+ real64 const t0 = m_weights[iconn][0] * LvArray::tensorOps::l2Norm< 3 >( coefficient[er0][esr0][ei0][0] );
+ // We consider the 3rd component of the permeability which is the normal one.
+ real64 const t1 = m_weights[iconn][1] * coefficient[er1][esr1][ei1][0][2];
+
+ real64 const sumOfTrans = t0+t1;
+ real64 const value = t0*t1/sumOfTrans;
+
+ weight[0][0] = value;
+ weight[0][1] = -value;
+
+ // We consider the 3rd component of the permeability which is the normal one.
+ real64 const dt0 = m_weights[iconn][0] * dCoeff_dVar[er0][esr0][ei0][0][0];
+ real64 const dt1 = m_weights[iconn][1] * dCoeff_dVar[er1][esr1][ei1][0][2];
+
+ dWeight_dVar[0][0] = ( dt0 * t1 * sumOfTrans - dt0 * t0 * t1 ) / ( sumOfTrans * sumOfTrans );
+ dWeight_dVar[0][1] = ( t0 * dt1 * sumOfTrans - dt1 * t0 * t1 ) / ( sumOfTrans * sumOfTrans );
+}
+
GEOS_HOST_DEVICE
inline void
EmbeddedSurfaceToCellStencilWrapper::
diff --git a/src/coreComponents/finiteVolume/FaceElementToCellStencil.hpp b/src/coreComponents/finiteVolume/FaceElementToCellStencil.hpp
index 6920e52b3bf..e86e6724bed 100644
--- a/src/coreComponents/finiteVolume/FaceElementToCellStencil.hpp
+++ b/src/coreComponents/finiteVolume/FaceElementToCellStencil.hpp
@@ -106,6 +106,21 @@ class FaceElementToCellStencilWrapper : public StencilWrapperBase< TwoPointStenc
real64 ( &weight )[1][2],
real64 ( &dWeight_dVar )[1][2] ) const;
+/**
+ * @brief Compute half weigths and derivatives w.r.t to one variable.
+ * @param[in] iconn connection index
+ * @param[in] coefficient view accessor to the coefficient used to compute the weights
+ * @param[in] dCoeff_dVar view accessor to the derivative of the coefficient w.r.t to the variable
+ * @param[out] weight view weights
+ * @param[out] dWeight_dVar derivative of the weigths w.r.t to the variable
+ */
+ GEOS_HOST_DEVICE
+ void computeHalfWeights( localIndex iconn,
+ CoefficientAccessor< arrayView3d< real64 const > > const & coefficient,
+ CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar,
+ real64 ( &weight )[1][2],
+ real64 ( &dWeight_dVar )[1][2] ) const;
+
/**
* @brief Compute weigths and derivatives w.r.t to one variable without coefficient
* Used in ReactiveCompositionalMultiphaseOBL solver for thermal transmissibility computation:
@@ -297,6 +312,44 @@ inline void FaceElementToCellStencilWrapper::
dWeight_dVar[0][1] = m_transMultiplier[iconn] * ( t0 * dt1 * sumOfTrans - dt1 * t0 * t1 ) / ( sumOfTrans * sumOfTrans );
}
+GEOS_HOST_DEVICE
+inline void FaceElementToCellStencilWrapper::
+ computeHalfWeights( localIndex const iconn,
+ CoefficientAccessor< arrayView3d< real64 const > > const & coefficient,
+ CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar,
+ real64 ( & weight )[1][2],
+ real64 ( & dWeight_dVar )[1][2] ) const
+{
+ localIndex const er0 = m_elementRegionIndices[iconn][0];
+ localIndex const esr0 = m_elementSubRegionIndices[iconn][0];
+ localIndex const ei0 = m_elementIndices[iconn][0];
+
+ localIndex const er1 = m_elementRegionIndices[iconn][1];
+ localIndex const esr1 = m_elementSubRegionIndices[iconn][1];
+ localIndex const ei1 = m_elementIndices[iconn][1];
+
+ real64 faceConormal[3];
+
+ // Will change when implementing collocation points.
+ LvArray::tensorOps::hadamardProduct< 3 >( faceConormal, coefficient[er0][esr0][ei0][0], m_faceNormal[iconn] );
+ real64 const t0 = m_weights[iconn][0] * LvArray::tensorOps::AiBi< 3 >( m_cellToFaceVec[iconn], faceConormal );
+ // We consider the 3rd component of the permeability which is the normal one.
+ real64 const t1 = m_weights[iconn][1] * coefficient[er1][esr1][ei1][0][2];
+
+ real64 const sumOfTrans = t0+t1;
+ real64 const value = m_transMultiplier[iconn]*t0*t1/sumOfTrans;
+
+ weight[0][0] = value;
+ weight[0][1] = -value;
+
+ // We consider the 3rd component of the permeability which is the normal one.
+ real64 const dt0 = m_weights[iconn][0] * dCoeff_dVar[er0][esr0][ei0][0][0];
+ real64 const dt1 = m_weights[iconn][1] * dCoeff_dVar[er1][esr1][ei1][0][2];
+
+ dWeight_dVar[0][0] = ( dt0 * t1 * sumOfTrans - dt0 * t0 * t1 ) / ( sumOfTrans * sumOfTrans );
+ dWeight_dVar[0][1] = ( t0 * dt1 * sumOfTrans - dt1 * t0 * t1 ) / ( sumOfTrans * sumOfTrans );
+}
+
GEOS_HOST_DEVICE
inline void
FaceElementToCellStencilWrapper
diff --git a/src/coreComponents/finiteVolume/SurfaceElementStencil.hpp b/src/coreComponents/finiteVolume/SurfaceElementStencil.hpp
index 5de67fe2f11..4c982dbef4a 100644
--- a/src/coreComponents/finiteVolume/SurfaceElementStencil.hpp
+++ b/src/coreComponents/finiteVolume/SurfaceElementStencil.hpp
@@ -110,6 +110,21 @@ class SurfaceElementStencilWrapper : public StencilWrapperBase< SurfaceElementSt
real64 ( &weight )[maxNumConnections][2],
real64 ( &dWeight_dVar )[maxNumConnections][2] ) const;
+ /**
+ * @brief Compute weights and derivatives w.r.t to one variable.
+ * @param[in] iconn connection index
+ * @param[in] coefficient view accessor to the coefficient used to compute the weights
+ * @param[in] dCoeff_dVar view accessor to the derivative of the coefficient w.r.t to the variable
+ * @param[out] weight view weights
+ * @param[out] dWeight_dVar derivative of the weights w.r.t to the variable
+ */
+ GEOS_HOST_DEVICE
+ void computeHalfWeights( localIndex iconn,
+ CoefficientAccessor< arrayView3d< real64 const > > const & coefficient,
+ CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar,
+ real64 ( &weight )[maxNumConnections][2],
+ real64 ( &dWeight_dVar )[maxNumConnections][2] ) const;
+
/**
* @brief Compute weights and derivatives w.r.t to one variable without coefficient
* Used in ReactiveCompositionalMultiphaseOBL solver for thermal transmissibility computation:
@@ -364,6 +379,70 @@ SurfaceElementStencilWrapper::
}
}
+GEOS_HOST_DEVICE
+inline void
+SurfaceElementStencilWrapper::
+ computeHalfWeights( localIndex iconn,
+ CoefficientAccessor< arrayView3d< real64 const > > const & coefficient,
+ CoefficientAccessor< arrayView3d< real64 const > > const & dCoeff_dVar,
+ real64 ( & weight )[maxNumConnections][2],
+ real64 ( & dWeight_dVar )[maxNumConnections][2] ) const
+{
+
+ real64 sumOfTrans = 0.0;
+ for( localIndex k=0; k
+#include
+
+#include "mainInterface/initialization.hpp"
+#include "mainInterface/GeosxState.hpp"
+#include "constitutive/fluid/twophaseimmisciblefluid/TwoPhaseImmiscibleFluid.hpp"
+#include "physicsSolvers/PhysicsSolverManager.hpp"
+#include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp"
+#include "integrationTests/fluidFlowTests/testCompFlowUtils.hpp"
+#include "constitutive/unitTests/FluidModelTest.hpp"
+#include "constitutive/unitTests/FluidModelTest_impl.hpp"
+#include "common/initializeEnvironment.hpp"
+#include "constitutive/relativePermeability/unitTests/constitutiveTestHelpers.hpp"
+#include "functions/FunctionManager.hpp"
+#include "constitutive/capillaryPressure/CapillaryPressureFields.hpp"
+
+#include
+
+
+
+using namespace geos;
+using namespace geos::dataRepository;
+using namespace geos::constitutive;
+using namespace geos::testing;
+
+CommandLineOptions g_commandLineOptions;
+
+TwoPhaseImmiscibleFluid * makeTwoPhaseImmiscibleFluid( TwoPhaseImmiscibleFluid & fluid )
+{
+
+ FunctionManager & functionManager = FunctionManager::getInstance();
+
+ // 1D table with linear interpolation
+ localIndex constexpr Naxis = 6;
+ localIndex constexpr NaxisSingle = 1;
+
+ real64_array densityCoordPhase0;
+ // fill( densityCoordPhase0, Feed< Naxis >{ 0.22, 0.3, 0.5, 0.6, 0.8, 1.0 } );
+ for( auto v : {0.0} )
+ densityCoordPhase0.emplace_back( v );
+ real64_array densityValuesPhase0;
+ // fill( densityValuesPhase0, Feed< Naxis >{ 0.00603, 0.04224, 0.04224, 0.22423, 0.31311, 0.40203 } );
+ for( auto v : {1000.0} )
+ densityValuesPhase0.emplace_back( v );
+
+ real64_array densityCoordPhase1;
+ // fill( densityCoordPhase1, Feed< Naxis >{ 1.22, 1.3, 1.5, 1.6, 1.8, 2.0 } );
+ for( auto v : {0.0} )
+ densityCoordPhase1.emplace_back( v );
+ real64_array densityValuesPhase1;
+ // fill( densityValuesPhase1, Feed< Naxis >{ 0.00603, 0.04224, 0.04224, 0.22423, 0.31311, 0.40203 } );
+ for( auto v : {100.0} )
+ densityValuesPhase1.emplace_back( v );
+
+ real64_array viscosityCoordPhase0;
+ // fill( viscosityCoordPhase0, Feed< Naxis >{ 0.22, 0.3, 0.5, 0.6, 0.8, 1.0 } );
+ for( auto v : {0.0} )
+ viscosityCoordPhase0.emplace_back( v );
+ real64_array viscosityValuesPhase0;
+ // fill( viscosityValuesPhase0, Feed< Naxis >{ 40203, 31311, 22423, 15011, 4224, 603 } );
+ for( auto v : {0.001} )
+ viscosityValuesPhase0.emplace_back( v );
+
+ real64_array viscosityCoordPhase1;
+ // fill( viscosityCoordPhase1, Feed< NaxisSingle >{ 0.22 } );
+ for( auto v : {0.0} )
+ viscosityCoordPhase1.emplace_back( v );
+
+ real64_array viscosityValuesPhase1;
+ // fill( viscosityValuesPhase1, Feed< NaxisSingle >{ 45 } );
+ for( auto v : {0.001} )
+ viscosityValuesPhase1.emplace_back( v );
+
+ TableFunction & table_density0 = dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", "densityTablePhase0" ) );
+ array1d< real64_array > coords_density0;
+ coords_density0.emplace_back( densityCoordPhase0 );
+ table_density0.setTableCoordinates( coords_density0, { units::Dimensionless } );
+ table_density0.setTableValues( densityValuesPhase0, units::Dimensionless );
+ table_density0.reInitializeFunction();
+
+ table_density0.setInterpolationMethod( TableFunction::InterpolationType::Linear );
+
+ TableFunction & table_density1 = dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", "densityTablePhase1" ) );
+ array1d< real64_array > coords_density1;
+ coords_density1.emplace_back( densityCoordPhase1 );
+ table_density1.setTableCoordinates( coords_density1, { units::Dimensionless } );
+ table_density1.setTableValues( densityValuesPhase1, units::Dimensionless );
+ table_density1.reInitializeFunction();
+
+ table_density1.setInterpolationMethod( TableFunction::InterpolationType::Linear );
+
+ TableFunction & table_viscosity0 = dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", "viscosityTablePhase0" ) );
+ array1d< real64_array > coords_viscosity0;
+ coords_viscosity0.emplace_back( viscosityCoordPhase0 );
+ table_viscosity0.setTableCoordinates( coords_viscosity0, { units::Dimensionless } );
+ table_viscosity0.setTableValues( viscosityValuesPhase0, units::Dimensionless );
+ table_viscosity0.reInitializeFunction();
+
+ table_viscosity0.setInterpolationMethod( TableFunction::InterpolationType::Linear );
+
+ TableFunction & table_viscosity1 = dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", "viscosityTablePhase1" ) );
+ array1d< real64_array > coords_viscosity1;
+ coords_viscosity1.emplace_back( viscosityCoordPhase1 );
+ table_viscosity1.setTableCoordinates( coords_viscosity1, { units::Dimensionless } );
+ table_viscosity1.setTableValues( viscosityValuesPhase1, units::Dimensionless );
+ table_viscosity1.reInitializeFunction();
+
+ table_viscosity1.setInterpolationMethod( TableFunction::InterpolationType::Linear );
+
+
+ // createTable( "densityTablePhase0", densityCoordPhase0, densityValuesPhase0 );
+ // createTable( "densityTablePhase1", densityCoordPhase1, densityValuesPhase1 );
+ // createTable( "viscosityTablePhase0", viscosityCoordPhase0, viscosityValuesPhase0 );
+ // createTable( "viscosityTablePhase1", viscosityCoordPhase1, viscosityValuesPhase1 );
+
+ // 2) Set up the constitutive model
+
+ string_array & phaseNames = fluid.getReference< string_array >( TwoPhaseImmiscibleFluid::viewKeyStruct::phaseNamesString() );
+ phaseNames.emplace_back( "water" );
+ phaseNames.emplace_back( "gas" );
+
+ string_array & densityTableNames = fluid.getReference< string_array >( TwoPhaseImmiscibleFluid::viewKeyStruct::densityTableNamesString() );
+ densityTableNames.emplace_back( "densityTablePhase0" );
+ densityTableNames.emplace_back( "densityTablePhase1" );
+
+ string_array & viscosityTableNames = fluid.getReference< string_array >( TwoPhaseImmiscibleFluid::viewKeyStruct::viscosityTableNamesString() );
+ viscosityTableNames.emplace_back( "viscosityTablePhase0" );
+ viscosityTableNames.emplace_back( "viscosityTablePhase1" );
+
+ fluid.postInputInitializationRecursive();
+ fluid.initialize(); // to test all the checks
+
+ return &fluid;
+}
+
+CapillaryPressureBase & makeJFunctionCapPressureTwoPhase( string const & name, Group & parent )
+{
+ FunctionManager & functionManager = FunctionManager::getInstance();
+
+ // 1) First, define the tables
+
+ // // 1D table, various interpolation methods
+ // localIndex const Naxis = 12;
+
+ // // Setup table
+ // array1d< real64_array > coordinates;
+ // coordinates.resize( 1 );
+ // coordinates[0].resize( Naxis );
+
+ // coordinates[0][0] = 0.0;
+ // coordinates[0][1] = 0.05;
+ // coordinates[0][2] = 0.15;
+ // coordinates[0][3] = 0.25;
+ // coordinates[0][4] = 0.35;
+ // coordinates[0][5] = 0.45;
+ // coordinates[0][6] = 0.55;
+ // coordinates[0][7] = 0.65;
+ // coordinates[0][8] = 0.75;
+ // coordinates[0][9] = 0.85;
+ // coordinates[0][10] = 0.95;
+ // coordinates[0][11] = 1.0;
+
+ // real64_array values( Naxis );
+ // values[0] = 4.331729359;
+ // values[1] = 3.523266264;
+ // values[2] = 2.677103439;
+ // values[3] = 2.356150157;
+ // values[4] = 2.166062360;
+ // values[5] = 2.034158727;
+ // values[6] = 1.934627222;
+ // values[7] = 1.855494313;
+ // values[8] = 1.790286970;
+ // values[9] = 1.735134860;
+ // values[10] = 1.687551617;
+ // values[11] = 1.666049754;
+
+
+ localIndex const Naxis = 2;
+
+ // Setup table
+ array1d< real64_array > coordinates;
+ coordinates.resize( 1 );
+ coordinates[0].resize( Naxis );
+
+ coordinates[0][0] = 0.0;
+ coordinates[0][1] = 1.0;
+
+ real64_array values( Naxis );
+ values[0] = 4.331729359;
+ values[1] = 1.666049754;
+
+
+ TableFunction & table_w = dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", "water_jFunction" ) );
+ table_w.setTableCoordinates( coordinates, { units::Dimensionless } );
+ table_w.setTableValues( values, units::Dimensionless );
+ table_w.reInitializeFunction();
+
+ table_w.setInterpolationMethod( TableFunction::InterpolationType::Linear );
+
+ // 2) Then set up the constitutive model
+
+ JFunctionCapillaryPressure & capPressure = parent.registerGroup< JFunctionCapillaryPressure >( name );
+
+ string_array & phaseNames = capPressure.getReference< string_array >( CapillaryPressureBase::viewKeyStruct::phaseNamesString() );
+ phaseNames.resize( 2 );
+ phaseNames[0] = "water"; phaseNames[1] = "gas";
+
+ auto & waterTableName = capPressure.getReference< string >( JFunctionCapillaryPressure::viewKeyStruct::wettingNonWettingJFuncTableNameString() );
+ waterTableName = "water_jFunction";
+
+ auto & surfaceTension = capPressure.getReference< real64 >( JFunctionCapillaryPressure::viewKeyStruct::wettingNonWettingSurfaceTensionString() );
+ //surfaceTension = 23.86955676433857e-3;
+ surfaceTension = 0.02;
+
+ auto & permeabilityDirection =
+ capPressure.getReference< JFunctionCapillaryPressure::PermeabilityDirection >( JFunctionCapillaryPressure::viewKeyStruct::permeabilityDirectionString() );
+ permeabilityDirection = JFunctionCapillaryPressure::PermeabilityDirection::XY;
+
+ capPressure.postInputInitializationRecursive();
+ capPressure.initialize(); // to test all the checks
+
+ return capPressure;
+}
+
+CapillaryPressureBase & makeTableCapPressureTwoPhase1( string const & name, Group & parent )
+{
+ FunctionManager & functionManager = FunctionManager::getInstance();
+
+ // 1) First, define the tables
+
+ // 1D table, various interpolation methods
+ localIndex Naxis = 12;
+
+ // Setup table
+ array1d< real64_array > coordinates;
+ coordinates.resize( 1 );
+ coordinates[0].resize( Naxis );
+ coordinates[0][0] = 0.0;
+ coordinates[0][1] = 0.05;
+ coordinates[0][2] = 0.15;
+ coordinates[0][3] = 0.25;
+ coordinates[0][4] = 0.35;
+ coordinates[0][5] = 0.45;
+ coordinates[0][6] = 0.55;
+ coordinates[0][7] = 0.65;
+ coordinates[0][8] = 0.75;
+ coordinates[0][9] = 0.85;
+ coordinates[0][10] = 0.95;
+ coordinates[0][11] = 1.0;
+
+ real64_array values( Naxis );
+ values[0] = 130000.0;
+ values[1] = 90572.79;
+ values[2] = 49307.11;
+ values[3] = 33654.85;
+ values[4] = 24384.64;
+ values[5] = 17951.96;
+ values[6] = 13098;
+ values[7] = 9238.84;
+ values[8] = 6058.81;
+ values[9] = 3369.14;
+ values[10] = 1048.6;
+ values[11] = 0.0;
+
+ // localIndex const Naxis = 2;
+
+ // // Setup table
+ // array1d< real64_array > coordinates;
+ // coordinates.resize( 1 );
+ // coordinates[0].resize( Naxis );
+
+ // coordinates[0][0] = 0.0;
+ // coordinates[0][1] = 1.0;
+
+ // real64_array values( Naxis );
+ // values[0] = 129999.999994362;
+ // values[1] = 50000.0000139914;
+
+
+ TableFunction & table_w = dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", "water_pc" ) );
+ table_w.setTableCoordinates( coordinates, { units::Dimensionless } );
+ table_w.setTableValues( values, units::Pressure );
+ table_w.reInitializeFunction();
+
+ table_w.setInterpolationMethod( TableFunction::InterpolationType::Linear );
+
+ // 2) Then set up the constitutive model
+
+ TableCapillaryPressure & capPressure = parent.registerGroup< TableCapillaryPressure >( name );
+
+ string_array & phaseNames = capPressure.getReference< string_array >( CapillaryPressureBase::viewKeyStruct::phaseNamesString() );
+ phaseNames.resize( 2 );
+ phaseNames[0] = "water"; phaseNames[1] = "gas";
+
+ auto & waterTableName = capPressure.getReference< string >( TableCapillaryPressure::viewKeyStruct::wettingNonWettingCapPresTableNameString() );
+ waterTableName = "water_pc";
+
+ capPressure.postInputInitializationRecursive();
+ capPressure.initialize(); // to test all the checks
+ return capPressure;
+}
+
+CapillaryPressureBase & makeTableCapPressureTwoPhase2( string const & name, Group & parent )
+{
+ FunctionManager & functionManager = FunctionManager::getInstance();
+
+ // 1) First, define the tables
+
+ // 1D table, various interpolation methods
+ localIndex Naxis = 12;
+
+ // Setup table
+ array1d< real64_array > coordinates;
+ coordinates.resize( 1 );
+ coordinates[0].resize( Naxis );
+ coordinates[0][0] = 0.0;
+ coordinates[0][1] = 0.05;
+ coordinates[0][2] = 0.15;
+ coordinates[0][3] = 0.25;
+ coordinates[0][4] = 0.35;
+ coordinates[0][5] = 0.45;
+ coordinates[0][6] = 0.55;
+ coordinates[0][7] = 0.65;
+ coordinates[0][8] = 0.75;
+ coordinates[0][9] = 0.85;
+ coordinates[0][10] = 0.95;
+ coordinates[0][11] = 1.0;
+
+ real64_array values( Naxis );
+ values[0] = 195000.0;
+ values[1] = 135859.25;
+ values[2] = 73960.67;
+ values[3] = 50482.28;
+ values[4] = 36576.96;
+ values[5] = 26927.94;
+ values[6] = 19647;
+ values[7] = 13858.26;
+ values[8] = 9088.2;
+ values[9] = 5053.72;
+ values[10] = 1572.9;
+ values[11] = 0.0;
+
+ // localIndex const Naxis = 2;
+
+ // // Setup table
+ // array1d< real64_array > coordinates;
+ // coordinates.resize( 1 );
+ // coordinates[0].resize( Naxis );
+
+ // coordinates[0][0] = 0.0;
+ // coordinates[0][1] = 1.0;
+
+ // real64_array values( Naxis );
+ // values[0] = 129999.999994362;
+ // values[1] = 50000.0000139914;
+
+
+ TableFunction & table_w = dynamicCast< TableFunction & >( *functionManager.createChild( "TableFunction", "water_pc" ) );
+ table_w.setTableCoordinates( coordinates, { units::Dimensionless } );
+ table_w.setTableValues( values, units::Pressure );
+ table_w.reInitializeFunction();
+
+ table_w.setInterpolationMethod( TableFunction::InterpolationType::Linear );
+
+ // 2) Then set up the constitutive model
+
+ TableCapillaryPressure & capPressure = parent.registerGroup< TableCapillaryPressure >( name );
+
+ string_array & phaseNames = capPressure.getReference< string_array >( CapillaryPressureBase::viewKeyStruct::phaseNamesString() );
+ phaseNames.resize( 2 );
+ phaseNames[0] = "water"; phaseNames[1] = "gas";
+
+ auto & waterTableName = capPressure.getReference< string >( TableCapillaryPressure::viewKeyStruct::wettingNonWettingCapPresTableNameString() );
+ waterTableName = "water_pc";
+
+ capPressure.postInputInitializationRecursive();
+ capPressure.initialize(); // to test all the checks
+ return capPressure;
+}
+
+CapillaryPressureBase & makeBrooksCoreyCapPressureTwoPhase1( string const & name, Group & parent )
+{
+ BrooksCoreyCapillaryPressure & capPressure = parent.registerGroup< BrooksCoreyCapillaryPressure >( name );
+
+ string_array & phaseNames = capPressure.getReference< string_array >( CapillaryPressureBase::viewKeyStruct::phaseNamesString() );
+ phaseNames.resize( 2 );
+ phaseNames[0] = "water"; phaseNames[1] = "gas";
+
+ array1d< real64 > & phaseMinSat = capPressure.getReference< array1d< real64 > >( BrooksCoreyCapillaryPressure::viewKeyStruct::phaseMinVolumeFractionString() );
+ phaseMinSat.resize( 2 );
+ phaseMinSat[0] = phase0MinSat1; phaseMinSat[1] = phase1MinSat1;
+
+ array1d< real64 > & phaseCapPressureExpInv =
+ capPressure.getReference< array1d< real64 > >( BrooksCoreyCapillaryPressure::viewKeyStruct::phaseCapPressureExponentInvString() );
+ phaseCapPressureExpInv.resize( 2 );
+ phaseCapPressureExpInv[0] = 4; phaseCapPressureExpInv[1] = 1;
+
+ array1d< real64 > & phaseEntryPressure = capPressure.getReference< array1d< real64 > >( BrooksCoreyCapillaryPressure::viewKeyStruct::phaseEntryPressureString() );
+ phaseEntryPressure.resize( 2 );
+ phaseEntryPressure[0] = 0.75e5; phaseEntryPressure[1] = 0;
+
+ real64 & capPressureEpsilon = capPressure.getReference< real64 >( BrooksCoreyCapillaryPressure::viewKeyStruct::capPressureEpsilonString() );
+ capPressureEpsilon = 1.0e-8;
+
+ capPressure.postInputInitializationRecursive();
+ return capPressure;
+}
+
+CapillaryPressureBase & makeBrooksCoreyCapPressureTwoPhase2( string const & name, Group & parent )
+{
+ BrooksCoreyCapillaryPressure & capPressure = parent.registerGroup< BrooksCoreyCapillaryPressure >( name );
+
+ string_array & phaseNames = capPressure.getReference< string_array >( CapillaryPressureBase::viewKeyStruct::phaseNamesString() );
+ phaseNames.resize( 2 );
+ phaseNames[0] = "water"; phaseNames[1] = "gas";
+
+ array1d< real64 > & phaseMinSat = capPressure.getReference< array1d< real64 > >( BrooksCoreyCapillaryPressure::viewKeyStruct::phaseMinVolumeFractionString() );
+ phaseMinSat.resize( 2 );
+ phaseMinSat[0] = phase0MinSat2; phaseMinSat[1] = phase1MinSat2;
+
+ array1d< real64 > & phaseCapPressureExpInv =
+ capPressure.getReference< array1d< real64 > >( BrooksCoreyCapillaryPressure::viewKeyStruct::phaseCapPressureExponentInvString() );
+ phaseCapPressureExpInv.resize( 2 );
+ phaseCapPressureExpInv[0] = 4; phaseCapPressureExpInv[1] = 1;
+
+ array1d< real64 > & phaseEntryPressure = capPressure.getReference< array1d< real64 > >( BrooksCoreyCapillaryPressure::viewKeyStruct::phaseEntryPressureString() );
+ phaseEntryPressure.resize( 2 );
+ phaseEntryPressure[0] = 0.5e5; phaseEntryPressure[1] = 0;
+
+ real64 & capPressureEpsilon = capPressure.getReference< real64 >( BrooksCoreyCapillaryPressure::viewKeyStruct::capPressureEpsilonString() );
+ capPressureEpsilon = 1e-8;
+
+ capPressure.postInputInitializationRecursive();
+ return capPressure;
+}
+
+RelativePermeabilityBase & makeBrooksCoreyRelPerm( string const & name, Group & parent )
+{
+ BrooksCoreyRelativePermeability & relPerm = parent.registerGroup< BrooksCoreyRelativePermeability >( name );
+
+ string_array & phaseNames = relPerm.getReference< string_array >( RelativePermeabilityBase::viewKeyStruct::phaseNamesString() );
+ phaseNames.resize( 2 );
+ phaseNames[0] = "water"; phaseNames[1] = "gas";
+
+ array1d< real64 > & phaseMinSat = relPerm.getReference< array1d< real64 > >( BrooksCoreyRelativePermeability::viewKeyStruct::phaseMinVolumeFractionString() );
+ phaseMinSat.resize( 2 );
+ phaseMinSat[0] = phase0MinSat1; phaseMinSat[1] = phase1MinSat1;
+
+ array1d< real64 > & phaseRelPermExp = relPerm.getReference< array1d< real64 > >( BrooksCoreyRelativePermeability::viewKeyStruct::phaseRelPermExponentString() );
+ phaseRelPermExp.resize( 2 );
+ phaseRelPermExp[0] = 2.0; phaseRelPermExp[1] = 2.0;
+
+ array1d< real64 > & phaseRelPermMaxVal = relPerm.getReference< array1d< real64 > >( BrooksCoreyRelativePermeability::viewKeyStruct::phaseRelPermMaxValueString() );
+ phaseRelPermMaxVal.resize( 2 );
+ phaseRelPermMaxVal[0] = 1.0; phaseRelPermMaxVal[1] = 1.0;
+
+ relPerm.postInputInitializationRecursive();
+ return relPerm;
+}
+
+class ImmiscibleInterfaceConditionsTest : public FluidModelTest< TwoPhaseImmiscibleFluid, 2 >
+{
+public:
+ ImmiscibleInterfaceConditionsTest(): state( std::make_unique< CommandLineOptions >( g_commandLineOptions )),
+ m_parent( "TestParentGroup", m_node )
+
+ {}
+
+protected:
+
+ static real64 constexpr time = 0.0;
+ static real64 constexpr dt = 1e4;
+ static real64 constexpr eps = std::numeric_limits< real64 >::epsilon();
+
+ GeosxState state;
+ ImmiscibleMultiphaseFlow *solver;
+ conduit::Node m_node;
+ dataRepository::Group m_parent;
+};
+
+real64 constexpr ImmiscibleInterfaceConditionsTest::time;
+real64 constexpr ImmiscibleInterfaceConditionsTest::dt;
+real64 constexpr ImmiscibleInterfaceConditionsTest::eps;
+
+
+
+TEST_F( ImmiscibleInterfaceConditionsTest, LocalNonlinearSolverConvergence )
+{
+
+ // using Base = FluidModelTest< TwoPhaseImmiscibleFluid, 2 >;
+ createFluid( "fluid", [this]( TwoPhaseImmiscibleFluid & fluid ){
+ makeTwoPhaseImmiscibleFluid( fluid );
+
+ // getting constitutive models:
+ RelativePermeabilityBase & relPerm = makeBrooksCoreyRelPerm( "relPerm", this->m_parent );
+ RelativePermeabilityBase * relPermPtr = &relPerm;
+ // CapillaryPressureBase & capPressure0 = makeJFunctionCapPressureTwoPhase( "capPressure0", this->m_parent );
+ // CapillaryPressureBase * capPressurePtr0 = &capPressure0;
+
+ CapillaryPressureBase & capPressure0 = makeTableCapPressureTwoPhase1( "capPressure0", this->m_parent );
+ CapillaryPressureBase * capPressurePtr0 = &capPressure0;
+
+ CapillaryPressureBase & capPressure1 = makeTableCapPressureTwoPhase2( "capPressure1", this->m_parent );
+ CapillaryPressureBase * capPressurePtr1 = &capPressure1;
+ // CapillaryPressureBase & capPressure0 = makeBrooksCoreyCapPressureTwoPhase1( "capPressure0", this->m_parent );
+ // CapillaryPressureBase * capPressurePtr0 = &capPressure0;
+
+ // CapillaryPressureBase & capPressure1 = makeBrooksCoreyCapPressureTwoPhase2( "capPressure1", this->m_parent );
+ // CapillaryPressureBase * capPressurePtr1 = &capPressure1;
+
+ std::vector< RelativePermeabilityBase * > relPerms = {relPermPtr, relPermPtr};
+ std::vector< CapillaryPressureBase * > capPressures = {capPressurePtr0, capPressurePtr1};
+ std::vector< TwoPhaseImmiscibleFluid * > fluids = { &fluid, &fluid };
+ // real64 uT = 3.2864545889999906e-05;
+
+ // real64 uT = -3.3e-5;
+ real64 uT = 1e-17;
+// real64 uT = 1e-7;
+ stdVector< real64 > saturations = {0.2, 0.4};
+ stdVector< real64 > trappedSats1 = {phase0MinSat1, phase1MinSat1};
+ stdVector< real64 > trappedSats2 = {phase0MinSat2, phase1MinSat2};
+ stdVector< real64 > pressures = {1e7, 1e7};
+ stdVector< real64 > JFMultipliers = {45016.662822296035, 30011.108548197357};
+ stdVector< real64 > transHats = {1.9738466000000002e-12, 4.4411548500000007e-12};
+ stdVector< real64 > dTransHats_dP = {0.0, 0.0};
+ stdVector< real64 > gravCoefHats = {490.5, 490.5};
+ stdVector< real64 > gravCoefs = {465.97500000000002, 515.02499999999998};
+
+
+ std::vector< real64 > phi = {0.0, 0.0};
+ std::vector< real64 > grad_phi = {0.0, 0.0, 0.0, 0.0};
+
+ std::ofstream outFile( "local_solver_results.csv" );
+
+
+ // Write data to the file
+ outFile << "Si";
+ outFile << ",";
+ outFile << "Sj";
+ outFile << ",";
+ outFile << "Fw_alpha";
+ outFile << ",";
+ outFile << "Fn_alpha";
+ outFile << ",";
+ outFile << "Residual_initial";
+ outFile << ",";
+ outFile << "Pc_int";
+ outFile << ",";
+ outFile << "Residual";
+ outFile << ",";
+ outFile << "newton";
+ outFile << std::endl;
+
+ real64 const start_sat = 0.0;
+ real64 const end_sat = 1.0;
+ real64 const dS = 1e-2;
+ real64 Si = 0.0;
+ real64 Sj = 0.9;
+
+ // for( real64 Si = start_sat; Si <= end_sat + 1e-8; Si += dS )
+ // {
+ // for( real64 Sj = start_sat; Sj <= end_sat + 1e-8; Sj += dS )
+ // {
+ saturations[0] = Si;
+ saturations[1] = Sj;
+
+ auto t0 = std::chrono::high_resolution_clock::now();
+
+ // Define missing arguments for the updated signature
+ stdVector< real64 > cellCenterDuT = { 0.0, 0.0 };
+ stdVector< real64 > cellCenterDens = { 0.0, 0.0 };
+ stdVector< real64 > cellCenterDens_dP = { 0.0, 0.0 };
+ std::vector< real64 > grad_phi_P = { 0.0, 0.0 };
+ std::vector< real64 > grad_phi_S = { 0.0, 0.0 };
+ bool converged;
+
+ // Call the GEOS local solver
+ geos::immiscibleMultiphaseKernels::local_solver( uT, saturations, pressures, JFMultipliers, trappedSats1, trappedSats2, transHats, dTransHats_dP, gravCoefHats, gravCoefs,
+ cellCenterDuT, cellCenterDens, cellCenterDens_dP,
+ relPerms, capPressures, fluids, phi, grad_phi_P, grad_phi_S, converged );
+
+ auto t1 = std::chrono::high_resolution_clock::now();
+ std::chrono::duration< double > elapsed = t1 - t0;
+ std::cout << "Local solver time: " << elapsed.count() << " s" << std::endl;
+
+
+ // Write data to the file
+ outFile << GEOS_FMT( "{:10.10e}", saturations[0] );
+ outFile << GEOS_FMT( ",{:10.10e}", saturations[1] );
+ outFile << GEOS_FMT( ",{:10.10e}", phi[0] );
+ outFile << GEOS_FMT( ",{:10.10e}", phi[1] );
+ outFile << GEOS_FMT( ",{:10.10e}", grad_phi_P[0] );
+ outFile << GEOS_FMT( ",{:10.10e}", grad_phi_P[1] );
+ outFile << GEOS_FMT( ",{:10.10e}", grad_phi_S[0] );
+ outFile << GEOS_FMT( ",{:10.10e}", grad_phi_S[1] );
+ outFile << std::endl;
+ phi[0] = 0;
+ phi[1] = 0;
+ grad_phi_P[0] = 0;
+ grad_phi_P[1] = 0;
+ grad_phi_S[0] = 0;
+ grad_phi_S[1] = 0;
+
+// }
+// }
+
+ outFile.close();
+
+ } );
+}
+
+int main( int argc, char * *argv )
+{
+ ::testing::InitGoogleTest( &argc, argv );
+ g_commandLineOptions = *geos::basicSetup( argc, argv );
+ int const result = RUN_ALL_TESTS();
+ geos::basicCleanup();
+ return result;
+}
+
+// maybe needed later on
+// TEST_F( CapillaryPressureTest, numericalDerivatives_jFunctionCapPressureTwoPhase )
+// {
+// initialize( makeJFunctionCapPressureTwoPhase( "capPressure", m_parent ) );
+
+// // here, we have to apply a special treatment to this test
+// // to make sure that the J-function multiplier is initialized using initializeRockState
+// // this requires calling allocateConstitutiveData in advance (it will be called again later, in the "test" function)
+
+// // setup some values for porosity and permeability
+// array2d< real64 > porosity;
+// porosity.resize( 1, 1 );
+// porosity[0][0] = 0.13496794266569806;
+// array3d< real64 > permeability;
+// permeability.resize( 1, 1, 3 );
+// permeability[0][0][0] = 0.1722194e-15;
+// permeability[0][0][1] = 0.3423156e-15;
+// permeability[0][0][2] = 0.2324191e-15;
+
+// // initialize the J-function multiplier (done on GPU if GPU is available)
+// m_model->allocateConstitutiveData( m_parent, 1 );
+// m_model->initializeRockState( porosity.toViewConst(), permeability.toViewConst() );
+
+// // move the multiplier back to the CPU since the test is performed on the CPU
+// auto & jFuncMultiplier =
+// m_model->getReference< array2d< real64 > >( fields::cappres::jFuncMultiplier::key() );
+// jFuncMultiplier.move( hostMemorySpace, false );
+
+// // we are ready to proceed to the test
+
+// real64 const eps = std::sqrt( std::numeric_limits< real64 >::epsilon() );
+// real64 const tol = 1e-4;
+
+// real64 const start_sat = 0.3;
+// real64 const end_sat = 0.9;
+// real64 const dS = 1e-1;
+// array1d< real64 > sat( 2 );
+// sat[0] = start_sat; sat[1] = 1-sat[0];
+// while( sat[0] <= end_sat )
+// {
+// test( sat, eps, tol );
+// sat[0] += dS;
+// sat[1] = 1 - sat[0];
+// }
+
+// }
diff --git a/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt b/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt
index 6eb55e9775a..b0bcc0bd271 100644
--- a/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt
+++ b/src/coreComponents/physicsSolvers/fluidFlow/CMakeLists.txt
@@ -29,8 +29,6 @@ set( fluidFlowSolvers_headers
ImmiscibleMultiphaseFlow.hpp
ImmiscibleMultiphaseFlowFields.hpp
LogLevelsInfo.hpp
- ReactiveCompositionalMultiphaseOBL.hpp
- ReactiveCompositionalMultiphaseOBLFields.hpp
SourceFluxStatistics.hpp
SinglePhaseBase.hpp
SinglePhaseBaseFields.hpp
@@ -65,18 +63,6 @@ set( fluidFlowSolvers_headers
kernels/singlePhase/ThermalFluxComputeKernel.hpp
kernels/singlePhase/proppant/ProppantBaseKernels.hpp
kernels/singlePhase/proppant/ProppantFluxKernels.hpp
- kernels/singlePhase/reactive/AccumulationKernels.hpp
- kernels/singlePhase/reactive/DirichletFluxComputeKernel.hpp
- kernels/singlePhase/reactive/FluidUpdateKernel.hpp
- kernels/singlePhase/reactive/FluxComputeKernel.hpp
- kernels/singlePhase/reactive/KernelLaunchSelectors.hpp
- kernels/singlePhase/reactive/ReactionUpdateKernel.hpp
- kernels/singlePhase/reactive/ResidualNormKernel.hpp
- kernels/singlePhase/reactive/SourceFluxComputeKernel.hpp
- kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp
- kernels/singlePhase/reactive/ThermalDirichletFluxComputeKernel.hpp
- kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp
- kernels/singlePhase/reactive/ThermalSourceFluxComputeKernel.hpp
kernels/compositional/AccumulationKernel.hpp
kernels/compositional/AquiferBCKernel.hpp
kernels/compositional/PPUPhaseFlux.hpp
@@ -104,7 +90,6 @@ set( fluidFlowSolvers_headers
kernels/compositional/PotGrad.hpp
kernels/compositional/PPUPhaseFlux.hpp
kernels/compositional/PropertyKernelBase.hpp
- kernels/compositional/ReactiveCompositionalMultiphaseOBLKernels.hpp
kernels/compositional/RelativePermeabilityUpdateKernel.hpp
kernels/compositional/ResidualNormKernel.hpp
kernels/compositional/SolidInternalEnergyUpdateKernel.hpp
@@ -145,14 +130,12 @@ set( fluidFlowSolvers_sources
CompositionalMultiphaseStatistics.cpp
CompositionalMultiphaseHybridFVM.cpp
ImmiscibleMultiphaseFlow.cpp
- ReactiveCompositionalMultiphaseOBL.cpp
FlowSolverBase.cpp
SinglePhaseBase.cpp
SinglePhaseStatistics.cpp
SinglePhaseFVM.cpp
SinglePhaseHybridFVM.cpp
SinglePhaseProppantBase.cpp
- SinglePhaseReactiveTransport.cpp
SourceFluxStatistics.cpp
StencilDataCollection.cpp
kernels/singlePhase/proppant/ProppantFluxKernels.cpp
@@ -174,8 +157,10 @@ file( READ "${CMAKE_CURRENT_LIST_DIR}/kernelSpecs.json" kernelSpecs )
set( kernelTemplateFileList "" )
# Keep only the templates that are unrelated to hybrid flux/dirichlet
-list( APPEND kernelTemplateFileList
- ReactiveCompositionalMultiphaseOBLKernels.cpp.template )
+if( ENABLE_HPCREACT AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../constitutive/HPCReact/CMakeLists.txt" )
+ list( APPEND kernelTemplateFileList
+ ReactiveCompositionalMultiphaseOBLKernels.cpp.template )
+endif()
foreach( kernelTemplateFile ${kernelTemplateFileList} )
get_filename_component( jsonKey ${kernelTemplateFile} NAME_WE )
@@ -188,6 +173,31 @@ foreach( kernelTemplateFile ${kernelTemplateFileList} )
list(APPEND fluidFlowSolvers_sources ${sourceFiles})
endforeach()
+# Conditionally add reactive transport files when HPCReact is available
+if( ENABLE_HPCREACT AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../constitutive/HPCReact/CMakeLists.txt" )
+ list( APPEND fluidFlowSolvers_headers
+ ReactiveCompositionalMultiphaseOBL.hpp
+ ReactiveCompositionalMultiphaseOBLFields.hpp
+ kernels/singlePhase/reactive/AccumulationKernels.hpp
+ kernels/singlePhase/reactive/DirichletFluxComputeKernel.hpp
+ kernels/singlePhase/reactive/FluidUpdateKernel.hpp
+ kernels/singlePhase/reactive/FluxComputeKernel.hpp
+ kernels/singlePhase/reactive/KernelLaunchSelectors.hpp
+ kernels/singlePhase/reactive/ReactionUpdateKernel.hpp
+ kernels/singlePhase/reactive/ResidualNormKernel.hpp
+ kernels/singlePhase/reactive/SourceFluxComputeKernel.hpp
+ kernels/singlePhase/reactive/ThermalAccumulationKernels.hpp
+ kernels/singlePhase/reactive/ThermalDirichletFluxComputeKernel.hpp
+ kernels/singlePhase/reactive/ThermalFluxComputeKernel.hpp
+ kernels/singlePhase/reactive/ThermalSourceFluxComputeKernel.hpp
+ kernels/compositional/ReactiveCompositionalMultiphaseOBLKernels.hpp
+ SinglePhaseReactiveTransport.hpp )
+
+ list( APPEND fluidFlowSolvers_sources
+ ReactiveCompositionalMultiphaseOBL.cpp
+ SinglePhaseReactiveTransport.cpp )
+endif()
+
# TODO: The two kernels below have non-matching file names and JSON keys.
# Either fix them to follow pattern, or come up with another mechanism.
diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp
index a198a78cb17..ec169a7e330 100644
--- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp
+++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.cpp
@@ -17,31 +17,34 @@
* @file ImmiscibleMultiphaseFlow.cpp
*/
-#include "ImmiscibleMultiphaseFlow.hpp"
-
-#include "FlowSolverBaseFields.hpp"
-#include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp"
-#include "physicsSolvers/PhysicsSolverBaseKernels.hpp"
-#include "physicsSolvers/fluidFlow/CompositionalMultiphaseUtilities.hpp"
-#include "physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp"
-#include "physicsSolvers/fluidFlow/kernels/compositional/RelativePermeabilityUpdateKernel.hpp"
-#include "physicsSolvers/fluidFlow/kernels/compositional/CapillaryPressureUpdateKernel.hpp"
-#include "constitutive/capillaryPressure/CapillaryPressureSelector.hpp"
-#include "constitutive/relativePermeability/RelativePermeabilitySelector.hpp"
-
-#include "fieldSpecification/EquilibriumInitialCondition.hpp"
-#include "fieldSpecification/SourceFluxBoundaryCondition.hpp"
-#include "physicsSolvers/fluidFlow/SourceFluxStatistics.hpp"
-#include "physicsSolvers/LogLevelsInfo.hpp"
-
-#include "constitutive/ConstitutivePassThru.hpp"
-#include "constitutive/fluid/twophaseimmisciblefluid/TwoPhaseImmiscibleFluid.hpp"
-
-#include
-
-#if defined( __INTEL_COMPILER )
-#pragma GCC optimize "O0"
-#endif
+ #include "ImmiscibleMultiphaseFlow.hpp"
+
+ #include "FlowSolverBaseFields.hpp"
+ #include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp"
+ #include "physicsSolvers/PhysicsSolverBaseKernels.hpp"
+ #include "physicsSolvers/fluidFlow/CompositionalMultiphaseUtilities.hpp"
+ #include "physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp"
+ #include "physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/CapillaryPressureUpdateKernel.hpp"
+ #include "physicsSolvers/fluidFlow/kernels/compositional/ThermalAccumulationKernel.hpp"
+ #include "physicsSolvers/fluidFlow/kernels/compositional/RelativePermeabilityUpdateKernel.hpp"
+ #include "constitutive/ConstitutiveManager.hpp"
+ #include "constitutive/capillaryPressure/CapillaryPressureFields.hpp"
+ #include "constitutive/capillaryPressure/CapillaryPressureSelector.hpp"
+ #include "constitutive/relativePermeability/RelativePermeabilitySelector.hpp"
+
+ #include "fieldSpecification/EquilibriumInitialCondition.hpp"
+ #include "fieldSpecification/SourceFluxBoundaryCondition.hpp"
+ #include "physicsSolvers/fluidFlow/SourceFluxStatistics.hpp"
+ #include "physicsSolvers/LogLevelsInfo.hpp"
+
+ #include "constitutive/ConstitutivePassThru.hpp"
+ #include "constitutive/fluid/twophaseimmisciblefluid/TwoPhaseImmiscibleFluid.hpp"
+
+ #include
+
+ #if defined( __INTEL_COMPILER )
+ #pragma GCC optimize "O0"
+ #endif
namespace geos
{
@@ -90,7 +93,12 @@ ImmiscibleMultiphaseFlow::ImmiscibleMultiphaseFlow( const string & name,
setSizedFromParent( 0 ).
setInputFlag( InputFlags::OPTIONAL ).
setApplyDefaultValue( 0.2 ).
- setDescription( "Target (absolute) change in the phase volume fraction within a single time step." );
+ setDescription( "Target (absolute) change in phase volume fraction in a time step" );
+
+ this->registerWrapper( viewKeyStruct::interfaceFaceSetNamesString(),
+ &m_interfaceFaceSetNames ).
+ setInputFlag( InputFlags::OPTIONAL ).
+ setDescription( "Names of the interface face sets" );
}
void ImmiscibleMultiphaseFlow::postInputInitialization()
@@ -169,7 +177,7 @@ void ImmiscibleMultiphaseFlow::registerDataOnMesh( Group & meshBodies )
reference().resizeDimension< 1 >( m_numPhases );
subRegion.registerField< dPhaseMobility >( getName() ).
- reference().resizeDimension< 1, 2 >( m_numPhases, m_numPhases ); // dP, dS
+ reference().resizeDimension< 1, 2 >( m_numPhases, m_numPhases ); // dP, dS
} );
@@ -203,6 +211,132 @@ void ImmiscibleMultiphaseFlow::initializePreSubGroups()
temp.setValues< parallelHostPolicy >( m_inputTemperature );
} );
} );
+
+ // ***** Create FaceElements *****
+ forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( string const &,
+ MeshLevel & meshLevel,
+ string_array const & GEOS_UNUSED_PARAM( regionNames ))
+ {
+
+ FaceManager const & faceManager = meshLevel.getFaceManager();
+ Group const & faceSetGroup = faceManager.sets();
+ ElementRegionManager & elemManager = meshLevel.getElemManager();
+ m_interfaceConstitutivePairs.resize( m_interfaceFaceSetNames.size() );
+
+ // this is the FaceElement Level
+ for( size_t surfaceRegionIndex=0; surfaceRegionIndex < m_interfaceFaceSetNames.size(); ++surfaceRegionIndex )
+ {
+ string const & faceSetName = m_interfaceFaceSetNames[surfaceRegionIndex];
+ SortedArrayView< localIndex const > const & faceSet = faceSetGroup.getReference< SortedArray< localIndex > >( faceSetName );
+ SurfaceElementRegion & faceRegion = elemManager.getRegion< SurfaceElementRegion >( faceSetName );
+
+ for( localIndex const faceIndex : faceSet )
+ {
+ localIndex const faceIndices[2] = { faceIndex, faceIndex };
+ faceRegion.addToSurfaceMesh( &faceManager, faceIndices );
+ }
+
+ FaceElementSubRegion const & faceSubRegion = faceRegion.getUniqueSubRegion< FaceElementSubRegion >();
+ FixedToManyElementRelation const & faceElementsToCells = faceSubRegion.getToCellRelation();
+
+ std::function< std::tuple< CellElementSubRegion *, CellElementSubRegion * >(localIndex) > getSubregions = [&]( localIndex surfaceSubRegionIndex ) -> std::tuple< CellElementSubRegion *,
+ CellElementSubRegion * >
+ {
+
+ int regionIdx0 = faceElementsToCells.m_toElementRegion[surfaceSubRegionIndex][0];
+ int regionIdx1 = faceElementsToCells.m_toElementRegion[surfaceSubRegionIndex][1];
+ int subRegionIdx0 = faceElementsToCells.m_toElementSubRegion[surfaceSubRegionIndex][0];
+ int subRegionIdx1 = faceElementsToCells.m_toElementSubRegion[surfaceSubRegionIndex][1];
+
+ CellElementRegion & region0 = elemManager.getRegion< CellElementRegion >( regionIdx0 );
+ CellElementRegion & region1 = elemManager.getRegion< CellElementRegion >( regionIdx1 );
+
+ CellElementSubRegion * subRegion0 = ®ion0.getSubRegion< CellElementSubRegion >( subRegionIdx0 );
+ CellElementSubRegion * subRegion1 = ®ion1.getSubRegion< CellElementSubRegion >( subRegionIdx1 );
+ return std::make_tuple( subRegion0, subRegion1 );
+ };
+
+ // std::tuple< CellElementSubRegion *, CellElementSubRegion * > subRegionPair = getSubregions( surfaceRegionIndex );
+ // CellElementSubRegion * subRegion0 = std::get< 0 >( subRegionPair );
+ // CellElementSubRegion * subRegion1 = std::get< 1 >( subRegionPair );
+
+ // // get constitutives by type and name: relPerms, capPressures, Fluids (three pointers)
+ // std::string & relPermName0 = subRegion0->getReference< std::string >( viewKeyStruct::relPermNamesString());
+ // std::string & relPermName1 = subRegion1->getReference< std::string >( viewKeyStruct::relPermNamesString());
+ // RelativePermeabilityBase * relPerm0 = &getConstitutiveModel< RelativePermeabilityBase >( *subRegion0, relPermName0 );
+ // RelativePermeabilityBase * relPerm1 = &getConstitutiveModel< RelativePermeabilityBase >( *subRegion1, relPermName1 );
+
+ // std::string & cappresName0 = subRegion0->getReference< std::string >( viewKeyStruct::capPressureNamesString());
+ // std::string & cappresName1 = subRegion1->getReference< std::string >( viewKeyStruct::capPressureNamesString());
+ // CapillaryPressureBase * capPressure0 = &getConstitutiveModel< CapillaryPressureBase >( *subRegion0, cappresName0 );
+ // CapillaryPressureBase * capPressure1 = &getConstitutiveModel< CapillaryPressureBase >( *subRegion1, cappresName1 );
+
+ // std::string & fluidName0 = subRegion0->getReference< std::string >( viewKeyStruct::fluidNamesString() );
+ // std::string & fluidName1 = subRegion1->getReference< std::string >( viewKeyStruct::fluidNamesString() );
+
+ // TwoPhaseImmiscibleFluid * fluid0 = &getConstitutiveModel< TwoPhaseImmiscibleFluid >( *subRegion0, fluidName0 );
+ // TwoPhaseImmiscibleFluid * fluid1 = &getConstitutiveModel< TwoPhaseImmiscibleFluid >( *subRegion1, fluidName1 );
+
+ // m_interfaceConstitutivePairs[surfaceRegionIndex][0] = std::make_tuple( relPerm0, capPressure0, fluid0 );
+ // m_interfaceConstitutivePairs[surfaceRegionIndex][1] = std::make_tuple( relPerm1, capPressure1, fluid1 );
+ // Find a representative face element in this surface region with two adjacent cells
+ localIndex fei = -1;
+
+// Prefer face element 0 if valid; otherwise scan
+ if( faceElementsToCells.size() > 0 )
+ {
+ // Check if face element 0 has two adjacent cells
+ if( faceElementsToCells.m_toElementRegion[0].size() >= 2 )
+ {
+ fei = 0;
+ }
+ else
+ {
+ // Scan to find the first interior face element with two neighbors
+ for( localIndex i = 1; i < faceElementsToCells.size(); ++i )
+ {
+ if( faceElementsToCells.m_toElementRegion[i].size() >= 2 )
+ {
+ fei = i;
+ break;
+ }
+ }
+ }
+ }
+
+// If no valid face element, skip this surface region
+ if( fei < 0 )
+ {
+ continue;
+ }
+
+ std::tuple< CellElementSubRegion *, CellElementSubRegion * > subRegionPair = getSubregions( fei );
+ CellElementSubRegion * subRegion0 = std::get< 0 >( subRegionPair );
+ CellElementSubRegion * subRegion1 = std::get< 1 >( subRegionPair );
+
+// get constitutives by type and name: relPerms, capPressures, Fluids (three pointers)
+ std::string & relPermName0 = subRegion0->getReference< std::string >( viewKeyStruct::relPermNamesString());
+ std::string & relPermName1 = subRegion1->getReference< std::string >( viewKeyStruct::relPermNamesString());
+ RelativePermeabilityBase * relPerm0 = &getConstitutiveModel< RelativePermeabilityBase >( *subRegion0, relPermName0 );
+ RelativePermeabilityBase * relPerm1 = &getConstitutiveModel< RelativePermeabilityBase >( *subRegion1, relPermName1 );
+
+ std::string & cappresName0 = subRegion0->getReference< std::string >( viewKeyStruct::capPressureNamesString());
+ std::string & cappresName1 = subRegion1->getReference< std::string >( viewKeyStruct::capPressureNamesString());
+ CapillaryPressureBase * capPressure0 = &getConstitutiveModel< CapillaryPressureBase >( *subRegion0, cappresName0 );
+ CapillaryPressureBase * capPressure1 = &getConstitutiveModel< CapillaryPressureBase >( *subRegion1, cappresName1 );
+
+ std::string & fluidName0 = subRegion0->getReference< std::string >( viewKeyStruct::fluidNamesString() );
+ std::string & fluidName1 = subRegion1->getReference< std::string >( viewKeyStruct::fluidNamesString() );
+
+ TwoPhaseImmiscibleFluid * fluid0 = &getConstitutiveModel< TwoPhaseImmiscibleFluid >( *subRegion0, fluidName0 );
+ TwoPhaseImmiscibleFluid * fluid1 = &getConstitutiveModel< TwoPhaseImmiscibleFluid >( *subRegion1, fluidName1 );
+
+ m_interfaceConstitutivePairs[surfaceRegionIndex][0] = std::make_tuple( relPerm0, capPressure0, fluid0 );
+ m_interfaceConstitutivePairs[surfaceRegionIndex][1] = std::make_tuple( relPerm1, capPressure1, fluid1 );
+
+ }
+ } );
+
}
@@ -265,7 +399,8 @@ void ImmiscibleMultiphaseFlow::updateCapPressureModel( ObjectManagerBase & dataG
{
typename TYPEOFREF( castedCapPres ) ::KernelWrapper capPresWrapper = castedCapPres.createKernelWrapper();
- isothermalCompositionalMultiphaseBaseKernels::
+ // isothermalCompositionalMultiphaseBaseKernels::
+ immiscibleMultiphaseKernels::
CapillaryPressureUpdateKernel::
launch< parallelDevicePolicy<> >( dataGroup.size(),
capPresWrapper,
@@ -373,7 +508,7 @@ void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh,
getConstitutiveModel< PermeabilityBase >( subRegion, subRegion.template getReference< string >( viewKeyStruct::permeabilityNamesString() ) );
permeabilityModel.scaleHorizontalPermeability( netToGross );
porousSolid.scaleReferencePorosity( netToGross );
- saveConvergedState( subRegion ); // necessary for a meaningful porosity update in sequential schemes
+ saveConvergedState( subRegion ); // necessary for a meaningful porosity update in sequential schemes
updatePorosityAndPermeability( subRegion );
// Now, we initialize and update each constitutive model one by one
@@ -402,9 +537,9 @@ void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh,
string const & relpermName = subRegion.template getReference< string >( viewKeyStruct::relPermNamesString() );
RelativePermeabilityBase & relPermMaterial =
getConstitutiveModel< RelativePermeabilityBase >( subRegion, relpermName );
- relPermMaterial.saveConvergedPhaseVolFractionState( phaseVolFrac ); // this needs to happen before calling updateRelPermModel
+ relPermMaterial.saveConvergedPhaseVolFractionState( phaseVolFrac ); // this needs to happen before calling updateRelPermModel
updateRelPermModel( subRegion );
- relPermMaterial.saveConvergedState(); // this needs to happen after calling updateRelPermModel
+ relPermMaterial.saveConvergedState(); // this needs to happen after calling updateRelPermModel
// 4.4 Then, we initialize/update the capillary pressure model
//
@@ -424,7 +559,7 @@ void ImmiscibleMultiphaseFlow::initializeFluidState( MeshLevel & mesh,
string const & capPressureName = subRegion.template getReference< string >( viewKeyStruct::capPressureNamesString() );
CapillaryPressureBase const & capPressureMaterial =
getConstitutiveModel< CapillaryPressureBase >( subRegion, capPressureName );
- capPressureMaterial.initializeRockState( porosity, permeability ); // this needs to happen before calling updateCapPressureModel
+ capPressureMaterial.initializeRockState( porosity, permeability ); // this needs to happen before calling updateCapPressureModel
updateCapPressureModel( subRegion );
}
@@ -473,6 +608,48 @@ void ImmiscibleMultiphaseFlow::initializePostInitialConditionsPreSubGroups()
CommunicationTools::getInstance().synchronizeFields( fieldsToBeSync, mesh, domain.getNeighbors(), false );
} );
+ // Retrieve the numerical methods and finite volume manager
+ FiniteVolumeManager const & fvManager = domain.getNumericalMethodManager().getFiniteVolumeManager();
+ FluxApproximationBase const & fluxApprox = fvManager.getFluxApproximation( m_discretizationName );
+ const geos::string flux_approximation_name = fluxApprox.getName();
+
+ // Clear the existing mapping between connector indices and interface region indices
+ m_interfaceRegionByConnector.clear();
+ forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&]( std::string const &,
+ MeshLevel & meshLevel,
+ string_array const & GEOS_UNUSED_PARAM( regionNames ))
+ {
+ // Access the face manager and retrieve the face set group for the current mesh level
+ FaceManager const & faceManager = meshLevel.getFaceManager();
+ Group const & faceSetGroup = faceManager.sets();
+
+ // Access the connector indices map (face index → connector index)
+ Group & stencilGroup =
+ meshLevel.getGroup( FluxApproximationBase::groupKeyStruct::stencilMeshGroupString())
+ .getGroup( flux_approximation_name );
+ CellElementStencilTPFA & stencil =
+ stencilGroup.getReference< CellElementStencilTPFA >(
+ FluxApproximationBase::viewKeyStruct::cellStencilString());
+ unordered_map< localIndex, localIndex > const & connectorIndices = stencil.getConnectorIndices();
+
+ // for all interface face sets to map connector indices to their corresponding interface region indices
+ for( size_t surfaceRegionIndex = 0; surfaceRegionIndex < m_interfaceFaceSetNames.size(); ++surfaceRegionIndex )
+ {
+ // Iterate over each face and associate its connector index
+ std::string const & faceSetName = m_interfaceFaceSetNames[surfaceRegionIndex];
+ for( localIndex kf : faceSetGroup.getReference< SortedArray< localIndex > >( faceSetName ))
+ {
+ auto it = connectorIndices.find( kf );
+ if( it != connectorIndices.end())
+ {
+ // Map the connector index to the corresponding surface region index
+ m_interfaceRegionByConnector[it->second] = surfaceRegionIndex;
+ }
+ }
+ }
+ } );
+
+
initializeState( domain );
}
@@ -582,7 +759,7 @@ void ImmiscibleMultiphaseFlow::assembleAccumulationTerm( DomainPartition & domai
}
void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt,
- DomainPartition const & domain,
+ DomainPartition & domain,
DofManager const & dofManager,
CRSMatrixView< real64, globalIndex const > const & localMatrix,
arrayView1d< real64 > const & localRhs ) const
@@ -595,30 +772,90 @@ void ImmiscibleMultiphaseFlow::assembleFluxTerms( real64 const dt,
string const & dofKey = dofManager.getKey( viewKeyStruct::elemDofFieldString() );
+
forDiscretizationOnMeshTargets( domain.getMeshBodies(), [&] ( string const &,
- MeshLevel const & mesh,
- string_array const & )
+ MeshLevel & mesh,
+ string_array const & regionNames )
{
- fluxApprox.forAllStencils( mesh, [&]( auto & stencil )
+ if( m_hasCapPressure )
{
- typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper();
- immiscibleMultiphaseKernels::
- FluxComputeKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPhases,
- dofManager.rankOffset(),
- dofKey,
- m_hasCapPressure,
- m_useTotalMassEquation,
- m_gravityDensityScheme == GravityDensityScheme::PhasePresence,
- getName(),
- mesh.getElemManager(),
- stencilWrapper,
- dt,
- localMatrix.toViewConstSizes(),
- localRhs.toView() );
- } );
+ mesh.getElemManager().forElementSubRegions( regionNames,
+ [&]( localIndex const,
+ ElementSubRegionBase & subRegion ) // Check if you need this.
+ {
+ // // Capillary pressure wrapper
+ // string const & cappresName = subRegion.getReference< string >( viewKeyStruct::capPressureNamesString() );
+ // BrooksCoreyCapillaryPressure & capPressure = getConstitutiveModel< BrooksCoreyCapillaryPressure >( subRegion, cappresName );
+ // CapillaryPressureBase * capPressure1 = &getConstitutiveModel< CapillaryPressureBase >( subRegion, cappresName );
+ // BrooksCoreyCapillaryPressure::KernelWrapper capPresWrapper = capPressure.createKernelWrapper();
+
+ // // Relative permeability wrapper
+ // string const & relPermName = subRegion.getReference< string >( viewKeyStruct::relPermNamesString() );
+ // BrooksCoreyRelativePermeability & relPerm = getConstitutiveModel< BrooksCoreyRelativePermeability >( subRegion, relPermName );
+ // RelativePermeabilityBase * relPerm1 = &getConstitutiveModel< RelativePermeabilityBase >( subRegion, relPermName );
+ // BrooksCoreyRelativePermeability::KernelWrapper relPermWrapper = relPerm.createKernelWrapper();
+
+ // // fluid
+ // string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() );
+ // TwoPhaseImmiscibleFluid * fluid = &getConstitutiveModel< TwoPhaseImmiscibleFluid >( subRegion, fluidName );
+
+ // // m_interfaceConstitutivePairs[0][0] = std::make_tuple( relPerm1, capPressure1, fluid );
+ // // m_interfaceConstitutivePairs[0][1] = std::make_tuple( relPerm1, capPressure1, fluid );
+
+ // auto interfaceConstitutivePairs_temp = std::make_tuple( relPerm1, capPressure1, fluid );
+
+ fluxApprox.forAllStencils( mesh, [&]( auto & stencil )
+ {
+ typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper();
+ immiscibleMultiphaseKernels::
+ FluxComputeKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPhases,
+ dofManager.rankOffset(),
+ dofKey,
+ m_hasCapPressure,
+ m_useTotalMassEquation,
+ m_gravityDensityScheme == GravityDensityScheme::PhasePresence,
+ getName(),
+ mesh.getElemManager(),
+ stencilWrapper,
+ // capPresWrapper,
+ // relPermWrapper,
+ m_interfaceFaceSetNames,
+ m_interfaceConstitutivePairs,
+ m_interfaceRegionByConnector,
+ // interfaceConstitutivePairs_temp,
+ subRegion,
+ dt,
+ localMatrix.toViewConstSizes(),
+ localRhs.toView() );
+ } );
+ } );
+ }
+ else
+ {
+ fluxApprox.forAllStencils( mesh, [&]( auto & stencil )
+ {
+ typename TYPEOFREF( stencil ) ::KernelWrapper stencilWrapper = stencil.createKernelWrapper();
+ immiscibleMultiphaseKernels::
+ FluxComputeKernelFactory::createAndLaunch< parallelDevicePolicy<> >( m_numPhases,
+ dofManager.rankOffset(),
+ dofKey,
+ m_hasCapPressure,
+ m_useTotalMassEquation,
+ m_gravityDensityScheme == GravityDensityScheme::PhasePresence,
+ getName(),
+ mesh.getElemManager(),
+ stencilWrapper,
+ dt,
+ localMatrix.toViewConstSizes(),
+ localRhs.toView() );
+ } );
+ }
+
} );
}
+// Ryan: Looks like this will need to be overwritten as well...
+// I have left the CompositionalMultiphaseFVM implementation for reference
void ImmiscibleMultiphaseFlow::setupDofs( DomainPartition const & domain,
DofManager & dofManager ) const
{
@@ -730,7 +967,7 @@ bool ImmiscibleMultiphaseFlow::validateDirichletBC( DomainPartition & domain,
bcConsistent = false;
GEOS_WARNING( BCMessage::invalidComponentIndex( comp, fs.getName(),
fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() ) );
- return; // can't check next part with invalid component id
+ return; // can't check next part with invalid component id
}
ComponentMask< MAX_NP > & compMask = subRegionSetMap[setName];
@@ -1014,7 +1251,7 @@ void ImmiscibleMultiphaseFlow::applySourceFluxBC( real64 const time,
return;
}
- real64 const rhsValue = rhsContributionArrayView[a] / sizeScalingFactor; // scale the contribution by the sizeScalingFactor here!
+ real64 const rhsValue = rhsContributionArrayView[a] / sizeScalingFactor; // scale the contribution by the sizeScalingFactor here!
massProd += rhsValue;
if( useTotalMassEquation > 0 )
{
@@ -1023,7 +1260,7 @@ void ImmiscibleMultiphaseFlow::applySourceFluxBC( real64 const time,
localRhs[totalMassBalanceRow] += rhsValue;
if( fluidPhaseId < numFluidPhases - 1 )
{
- globalIndex const compMassBalanceRow = totalMassBalanceRow + fluidPhaseId + 1; // component mass bal equations are shifted
+ globalIndex const compMassBalanceRow = totalMassBalanceRow + fluidPhaseId + 1; // component mass bal equations are shifted
localRhs[compMassBalanceRow] += rhsValue;
}
}
@@ -1124,8 +1361,6 @@ real64 ImmiscibleMultiphaseFlow::calculateResidualNorm( real64 const & GEOS_UNUS
GEOS_LOG_LEVEL_RANK_0_NLR( logInfo::ResidualNorm, GEOS_FMT( " ( R{} ) = ( {:4.2e} )",
coupledSolverAttributePrefix(), residualNorm ))
- getConvergenceStats().setResidualValue( GEOS_FMT( "R{}", coupledSolverAttributePrefix()), residualNorm );
-
return residualNorm;
}
@@ -1158,7 +1393,7 @@ void ImmiscibleMultiphaseFlow::applySystemSolution( DofManager const & dofManage
MeshLevel & mesh,
string_array const & regionNames )
{
- stdVector< string > fields{ fields::flow::pressure::key(), fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() };
+ std::vector< string > fields{ fields::flow::pressure::key(), fields::immiscibleMultiphaseFlow::phaseVolumeFraction::key() };
FieldIdentifiers fieldsToBeSync;
fieldsToBeSync.addElementFields( fields, regionNames );
@@ -1176,6 +1411,7 @@ void ImmiscibleMultiphaseFlow::updateVolumeConstraint( ElementSubRegionBase & su
forAll< parallelDevicePolicy<> >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const ei )
{
+ phaseVolumeFraction[ei][0] = fmin( 1.0, fmax( phaseVolumeFraction[ei][0], 0.0 ));;
phaseVolumeFraction[ei][1] = 1.0 - phaseVolumeFraction[ei][0];
} );
}
@@ -1254,11 +1490,11 @@ void ImmiscibleMultiphaseFlow::implicitStepComplete( real64 const & time,
CoupledSolidBase const & porousMaterial = getConstitutiveModel< CoupledSolidBase >( subRegion, solidName );
if( m_keepVariablesConstantDuringInitStep )
{
- porousMaterial.ignoreConvergedState(); // newPorosity <- porosity_n
+ porousMaterial.ignoreConvergedState(); // newPorosity <- porosity_n
}
else
{
- porousMaterial.saveConvergedState(); // porosity_n <- porosity
+ porousMaterial.saveConvergedState(); // porosity_n <- porosity
}
// Step 4: save converged state for the relperm model to handle hysteresis
@@ -1287,7 +1523,6 @@ void ImmiscibleMultiphaseFlow::implicitStepComplete( real64 const & time,
}
} );
} );
-
}
void ImmiscibleMultiphaseFlow::saveConvergedState( ElementSubRegionBase & subRegion ) const
@@ -1407,4 +1642,4 @@ real64 ImmiscibleMultiphaseFlow::setNextDtBasedOnStateChange( real64 const & cur
REGISTER_CATALOG_ENTRY( PhysicsSolverBase, ImmiscibleMultiphaseFlow, string const &, Group * const )
-} // namespace geos
+} // namespace geos
diff --git a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp
index 7526130316c..b3769837600 100644
--- a/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp
+++ b/src/coreComponents/physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlow.hpp
@@ -27,6 +27,12 @@
namespace geos
{
+
+namespace constitutive
+{
+class ConstitutiveBase;
+} // namespace constitutive
+
//START_SPHINX_INCLUDE_00
/**
* @class ImmiscibleMultiphaseFlow
@@ -160,12 +166,11 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase
* @param matrix the system matrix
* @param rhs the system right-hand side vector
*/
- virtual void
- assembleFluxTerms( real64 const dt,
- DomainPartition const & domain,
- DofManager const & dofManager,
- CRSMatrixView< real64, globalIndex const > const & localMatrix,
- arrayView1d< real64 > const & localRhs ) const;
+ void assembleFluxTerms( real64 const dt,
+ DomainPartition & domain,
+ DofManager const & dofManager,
+ CRSMatrixView< real64, globalIndex const > const & localMatrix,
+ arrayView1d< real64 > const & localRhs ) const;
/**
* @brief Function to perform the Application of Dirichlet type BC's
@@ -215,6 +220,10 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase
struct viewKeyStruct : public FlowSolverBase::viewKeyStruct
{
// inputs
+ static constexpr char const * capPressureNamesString() { return "capPressureNames"; }
+ static constexpr char const * relPermNamesString() { return "relPermNames"; }
+ static constexpr char const * elemDofFieldString() { return "elemDofField"; }
+ static constexpr char const * interfaceFaceSetNamesString() { return "interfaceFaceSetNames"; }
// density averaging scheme
static constexpr char const * gravityDensitySchemeString() { return "gravityDensityScheme"; }
@@ -228,9 +237,9 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase
static constexpr char const * maxRelativePresChangeString() { return "maxRelativePressureChange"; }
static constexpr char const * useTotalMassEquationString() { return "useTotalMassEquation"; }
- static constexpr char const * capPressureNamesString() { return "capillary_pressure"; }
- static constexpr char const * relPermNamesString() { return "relative_permeability"; }
- static constexpr char const * elemDofFieldString() { return "elemDofField"; }
+// static constexpr char const * capPressureNamesString() { return "capillary_pressure"; }
+// static constexpr char const * relPermNamesString() { return "relative_permeability"; }
+// static constexpr char const * elemDofFieldString() { return "elemDofField"; }
};
@@ -300,6 +309,15 @@ class ImmiscibleMultiphaseFlow : public FlowSolverBase
/// damping factor for solution change targets
real64 m_solutionChangeScalingFactor;
+ string_array m_interfaceFaceSetNames;
+
+ stdVector< std::array< std::tuple< constitutive::RelativePermeabilityBase *,
+ constitutive::CapillaryPressureBase *,
+ constitutive::TwoPhaseImmiscibleFluid * >, 2 > > m_interfaceConstitutivePairs;
+
+ unordered_map< localIndex, localIndex > m_interfaceRegionByConnector;
+ unordered_map< localIndex, localIndex > m_connectorIndicesByInterfaceRegion;
+
private:
diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/CapillaryPressureUpdateKernel.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/CapillaryPressureUpdateKernel.hpp
new file mode 100644
index 00000000000..2a02f536ea9
--- /dev/null
+++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/CapillaryPressureUpdateKernel.hpp
@@ -0,0 +1,73 @@
+/*
+ * ------------------------------------------------------------------------------------------------------------
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC
+ * Copyright (c) 2018-2024 TotalEnergies
+ * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University
+ * Copyright (c) 2023-2024 Chevron
+ * Copyright (c) 2019- GEOS/GEOSX Contributors
+ * All rights reserved
+ *
+ * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
+ * ------------------------------------------------------------------------------------------------------------
+ */
+
+/**
+ * @file CapillaryPressureUpdateKernel.hpp
+ */
+
+#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_IMMISCIBLEMULTIPHASE_CAPILLARYPRESSUREUPDATEKERNEL_HPP
+#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_IMMISCIBLEMULTIPHASE_CAPILLARYPRESSUREUPDATEKERNEL_HPP
+
+#include "common/DataTypes.hpp"
+#include "common/GEOS_RAJA_Interface.hpp"
+
+namespace geos
+{
+
+namespace immiscibleMultiphaseKernels
+{
+
+/******************************** CapillaryPressureUpdateKernel ********************************/
+
+struct CapillaryPressureUpdateKernel
+{
+ template< typename POLICY, typename CAPPRES_WRAPPER >
+ static void
+ launch( localIndex const size,
+ CAPPRES_WRAPPER const & capPresWrapper,
+ arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const & phaseVolFrac )
+ {
+ forAll< POLICY >( size, [=] GEOS_HOST_DEVICE ( localIndex const k )
+ {
+ for( localIndex q = 0; q < capPresWrapper.numGauss(); ++q )
+ {
+ capPresWrapper.update( k, q, phaseVolFrac[k] );
+ }
+ } );
+ }
+
+ template< typename POLICY, typename CAPPRES_WRAPPER >
+ static void
+ launch( SortedArrayView< localIndex const > const & targetSet,
+ CAPPRES_WRAPPER const & capPresWrapper,
+ arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const & phaseVolFrac )
+ {
+ forAll< POLICY >( targetSet.size(), [=] GEOS_HOST_DEVICE ( localIndex const a )
+ {
+ localIndex const k = targetSet[a];
+ for( localIndex q = 0; q < capPresWrapper.numGauss(); ++q )
+ {
+ capPresWrapper.update( k, q, phaseVolFrac[k] );
+ }
+ } );
+ }
+};
+
+} // namespace immiscibleMultiphaseKernels
+
+} // namespace geos
+
+
+#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_IMMISCIBLEMULTIPHASE_CAPILLARYPRESSUREUPDATEKERNEL_HPP
diff --git a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp
index ebb78332b43..d1fdeb72625 100644
--- a/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp
+++ b/src/coreComponents/physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/ImmiscibleMultiphaseKernels.hpp
@@ -17,39 +17,1311 @@
* @file ImmiscibleMultiphaseKernels.hpp
*/
+
#ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_MULTIPHASEKERNELS_HPP
#define GEOS_PHYSICSSOLVERS_FLUIDFLOW_MULTIPHASEKERNELS_HPP
-#include "codingUtilities/Utilities.hpp"
-#include "common/DataLayouts.hpp"
-#include "common/DataTypes.hpp"
-#include "common/GEOS_RAJA_Interface.hpp"
+
+ #include "codingUtilities/Utilities.hpp"
+ #include "common/DataLayouts.hpp"
+ #include "common/DataTypes.hpp"
+ #include "common/GEOS_RAJA_Interface.hpp"
+ #include "constitutive/fluid/twophaseimmisciblefluid/TwoPhaseImmiscibleFluid.hpp"
+ #include "constitutive/solid/CoupledSolidBase.hpp"
+ #include "constitutive/fluid/twophaseimmisciblefluid/TwoPhaseImmiscibleFluidFields.hpp"
+ #include "constitutive/capillaryPressure/CapillaryPressureFields.hpp"
+ #include "constitutive/capillaryPressure/CapillaryPressureBase.hpp"
+ #include "constitutive/capillaryPressure/JFunctionCapillaryPressure.hpp"
+ #include "constitutive/capillaryPressure/TableCapillaryPressure.hpp"
+ #include "constitutive/permeability/PermeabilityBase.hpp"
+ #include "constitutive/permeability/PermeabilityFields.hpp"
+ #include "constitutive/relativePermeability/RelativePermeabilityBase.hpp"
+ #include "constitutive/relativePermeability/RelativePermeabilityFields.hpp"
+ #include "constitutive/ConstitutiveManager.hpp"
+#include "constitutive/capillaryPressure/CapillaryPressureSelector.hpp"
+#include "constitutive/relativePermeability/RelativePermeabilitySelector.hpp"
+
+#include "constitutive/ConstitutivePassThru.hpp"
#include "constitutive/fluid/twophaseimmisciblefluid/TwoPhaseImmiscibleFluid.hpp"
-#include "constitutive/solid/CoupledSolidBase.hpp"
-#include "constitutive/fluid/twophaseimmisciblefluid/TwoPhaseImmiscibleFluidFields.hpp"
-#include "constitutive/capillaryPressure/CapillaryPressureFields.hpp"
-#include "constitutive/capillaryPressure/CapillaryPressureBase.hpp"
-#include "constitutive/permeability/PermeabilityBase.hpp"
-#include "constitutive/permeability/PermeabilityFields.hpp"
-#include "constitutive/relativePermeability/RelativePermeabilityBase.hpp"
-#include "constitutive/relativePermeability/RelativePermeabilityFields.hpp"
-#include "fieldSpecification/AquiferBoundaryCondition.hpp"
-#include "finiteVolume/BoundaryStencil.hpp"
-#include "finiteVolume/FluxApproximationBase.hpp"
-#include "linearAlgebra/interfaces/InterfaceTypes.hpp"
-#include "physicsSolvers/PhysicsSolverBaseKernels.hpp"
-#include "physicsSolvers/fluidFlow/FlowSolverBaseFields.hpp"
-#include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp"
-#include "physicsSolvers/fluidFlow/CompositionalMultiphaseUtilities.hpp"
-#include "physicsSolvers/fluidFlow/StencilAccessors.hpp"
-#include "physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/KernelLaunchSelectors.hpp"
+
+
+ #include "fieldSpecification/AquiferBoundaryCondition.hpp"
+ #include "finiteVolume/BoundaryStencil.hpp"
+ #include "finiteVolume/CellElementStencilTPFA.hpp"
+ #include "finiteVolume/FluxApproximationBase.hpp"
+ #include "linearAlgebra/interfaces/InterfaceTypes.hpp"
+ #include "physicsSolvers/PhysicsSolverBaseKernels.hpp"
+ #include "physicsSolvers/fluidFlow/FlowSolverBaseFields.hpp"
+ #include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp"
+ #include "physicsSolvers/fluidFlow/CompositionalMultiphaseUtilities.hpp"
+ #include "physicsSolvers/fluidFlow/StencilAccessors.hpp"
+ #include "physicsSolvers/fluidFlow/kernels/compositional/RelativePermeabilityUpdateKernel.hpp"
+ #include "physicsSolvers/fluidFlow/kernels/compositional/CapillaryPressureUpdateKernel.hpp"
+ #include "physicsSolvers/PhysicsSolverBaseKernels.hpp"
+ #include "physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/KernelLaunchSelectors.hpp"
+ #include "physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/KernelLaunchSelectors.hpp"
+
namespace geos
{
namespace immiscibleMultiphaseKernels
{
+
using namespace constitutive;
+GEOS_HOST_DEVICE
+inline
+static void local_solver( real64 uT, stdVector< real64 > saturations, stdVector< real64 > pressures, stdVector< real64 > JFMultipliers, stdVector< real64 > trappedSats1,
+ stdVector< real64 > trappedSats2, stdVector< real64 > transHat, stdVector< real64 > dTransHat_dP, stdVector< real64 > gravCoefHat, stdVector< real64 > gravCoef,
+ stdVector< real64 > cellCenterDuT, stdVector< real64 > cellCenterDens, stdVector< real64 > cellCenterDens_dP,
+ std::vector< RelativePermeabilityBase * > relPerms, std::vector< CapillaryPressureBase * > capPressures,
+ std::vector< TwoPhaseImmiscibleFluid * > fluids, std::vector< real64 > & phi, std::vector< real64 > & grad_phi_P, std::vector< real64 > & grad_phi_S, bool & converged )
+{
+
+ // getting wrappers:
+
+ constitutive::constitutiveUpdatePassThru( *capPressures[0], [&] ( auto & castedCapPres1 )
+ {
+ auto capPresWrapper1 = castedCapPres1.createKernelWrapper();
+
+
+ constitutive::constitutiveUpdatePassThru( *capPressures[1], [&] ( auto & castedCapPres2 )
+ {
+ auto capPresWrapper2 = castedCapPres2.createKernelWrapper();
+
+
+ constitutive::constitutiveUpdatePassThru( *relPerms[0], [&] ( auto & castedRelPerm1 )
+ {
+ auto relPermWrapper1 = castedRelPerm1.createKernelWrapper();
+
+
+ constitutive::constitutiveUpdatePassThru( *relPerms[1], [&] ( auto & castedRelPerm2 )
+ {
+ auto relPermWrapper2 = castedRelPerm2.createKernelWrapper();
+
+ auto fluidWrapper1 = fluids[0]->createKernelWrapper();
+ auto fluidWrapper2 = fluids[1]->createKernelWrapper();
+
+ // Create an output file stream object (ofstream) for analyzing the local solver's performance
+ std::ofstream outFile( "iterations2.csv" );
+
+
+ // Write data to the file
+ outFile << "Jacobian";
+ outFile << ",";
+ outFile << "residual";
+ outFile << ",";
+ outFile << "Fw_alpha";
+ outFile << ",";
+ outFile << "Fw_beta";
+ outFile << ",";
+ outFile << "Pc_int";
+ outFile << ",";
+ outFile << "Pc_int1";
+ outFile << ",";
+ outFile << "Pc_int2";
+ outFile << ",";
+ outFile << "Fn_alpha";
+ outFile << ",";
+ outFile << "Fn_beta";
+ outFile << ",";
+ outFile << "Vw_alpha";
+ outFile << ",";
+ outFile << "Vn_alpha";
+ outFile << ",";
+ outFile << "Vw_beta";
+ outFile << ",";
+ outFile << "Vn_beta";
+ outFile << ",";
+ outFile << "Gw_alpha";
+ outFile << ",";
+ outFile << "Gn_alpha";
+ outFile << ",";
+ outFile << "Gw_beta";
+ outFile << ",";
+ outFile << "Gn_beta";
+ outFile << ",";
+ outFile << "Cw_alpha";
+ outFile << ",";
+ outFile << "Cn_alpha";
+ outFile << ",";
+ outFile << "Cw_beta";
+ outFile << ",";
+ outFile << "Cn_beta";
+ outFile << ",";
+ outFile << "Pc1_ip0";
+ outFile << ",";
+ outFile << "Pc1_ip1";
+ outFile << ",";
+ outFile << "S_alpha";
+ outFile << ",";
+ outFile << "S_beta";
+ outFile << std::endl;
+
+ // nonlinear solver's parameters
+ real64 tol = 1.0e-9;
+ int max_iter = 50;
+ converged = 0;
+ bool damping = true;
+ bool bisection = false;
+ // bool lineSearch = false;
+ bool newton_path = false;
+
+ // Local newton loop:
+
+ // Use of the capillary pressure kernel wrapper
+
+ StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > phaseVolFrac1( 1, 2 );
+ StackArray< real64, 3, 2, constitutive::cappres::LAYOUT_CAPPRES > capPres1( 1, 1, 2 );
+ StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dPhaseVolFrac_dCapPres1( 1, 1, 2, 2 );
+ StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dCapPres1_dPhaseVolFrac( 1, 1, 2, 2 );
+ StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > facePhaseVolFrac1( 1, 2 );
+ StackArray< real64, 3, 2, constitutive::cappres::LAYOUT_CAPPRES > faceCapPres1( 1, 1, 2 );
+ StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dfacePhaseVolFrac_dCapPres1( 1, 1, 2, 2 );
+ StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dCapPres1_dfacePhaseVolFrac( 1, 1, 2, 2 );
+ StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > phaseVolFrac2( 1, 2 );
+ StackArray< real64, 3, 2, constitutive::cappres::LAYOUT_CAPPRES > capPres2( 1, 1, 2 );
+ StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dPhaseVolFrac_dCapPres2( 1, 1, 2, 2 );
+ StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dCapPres2_dPhaseVolFrac( 1, 1, 2, 2 );
+ StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > facePhaseVolFrac2( 1, 2 );
+ StackArray< real64, 3, 2, constitutive::cappres::LAYOUT_CAPPRES > faceCapPres2( 1, 1, 2 );
+ StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dfacePhaseVolFrac_dCapPres2( 1, 1, 2, 2 );
+ StackArray< real64, 4, 4, constitutive::cappres::LAYOUT_CAPPRES_DS > dCapPres2_dfacePhaseVolFrac( 1, 1, 2, 2 );
+ StackArray< real64, 1, 2 > JFunc1( 2 );
+ StackArray< real64, 1, 2 > JFunc2( 2 );
+
+ phaseVolFrac1[0][0] = saturations[0];
+ phaseVolFrac1[0][1] = 1.0 - saturations[0];
+
+ phaseVolFrac2[0][0] = saturations[1];
+ phaseVolFrac2[0][1] = 1.0 - saturations[1];
+
+ real64 Pc1_min = 0.0;
+ real64 Pc2_min = 0.0;
+ real64 Pc1_max = 0.0;
+ real64 Pc2_max = 0.0;
+
+ real64 density2[2]{};
+ real64 dDens_dP2[2][2]{};
+
+ density2[0] = cellCenterDens[0];
+ density2[1] = cellCenterDens[1];
+
+ dDens_dP2[0][0] = cellCenterDens_dP[0];
+ dDens_dP2[0][1] = cellCenterDens_dP[1];
+ dDens_dP2[1][0] = cellCenterDens_dP[2];
+ dDens_dP2[1][1] = cellCenterDens_dP[3];
+
+ JFunc1[0] = JFMultipliers[0];
+ JFunc2[0] = JFMultipliers[1];
+
+ using T1 = std::decay_t< decltype(castedCapPres1) >;
+ if constexpr (std::is_same_v< T1, JFunctionCapillaryPressure >) {
+ capPresWrapper1.compute( phaseVolFrac1[0],
+ JFunc1.toSliceConst(),
+ capPres1[0][0],
+ dCapPres1_dPhaseVolFrac[0][0] );
+
+ facePhaseVolFrac1[0][1] = 0.0;
+ facePhaseVolFrac1[0][0] = 1.0;
+ capPresWrapper1.compute( facePhaseVolFrac1[0],
+ JFunc1.toSliceConst(),
+ faceCapPres1[0][0],
+ dCapPres1_dfacePhaseVolFrac[0][0] );
+ Pc1_min = faceCapPres1[0][0][0];
+ facePhaseVolFrac1[0][1] = 1.0;
+ facePhaseVolFrac1[0][0] = 0.0;
+ capPresWrapper1.compute( facePhaseVolFrac1[0],
+ JFunc1.toSliceConst(),
+ faceCapPres1[0][0],
+ dCapPres1_dfacePhaseVolFrac[0][0] );
+ Pc1_max = faceCapPres1[0][0][0];
+
+ }
+ else
+ {
+ capPresWrapper1.compute( phaseVolFrac1[0],
+ capPres1[0][0],
+ dCapPres1_dPhaseVolFrac[0][0] );
+
+ facePhaseVolFrac1[0][1] = 0.0;
+ facePhaseVolFrac1[0][0] = 1.0;
+ capPresWrapper1.compute( facePhaseVolFrac1[0],
+ faceCapPres1[0][0],
+ dCapPres1_dfacePhaseVolFrac[0][0] );
+ Pc1_min = faceCapPres1[0][0][0];
+ facePhaseVolFrac1[0][1] = 1.0;
+ facePhaseVolFrac1[0][0] = 0.0;
+ capPresWrapper1.compute( facePhaseVolFrac1[0],
+ faceCapPres1[0][0],
+ dCapPres1_dfacePhaseVolFrac[0][0] );
+ Pc1_max = faceCapPres1[0][0][0];
+ }
+
+ using T2 = std::decay_t< decltype(castedCapPres2) >;
+ if constexpr (std::is_same_v< T2, JFunctionCapillaryPressure >) {
+ // evaluating cell-center Pc:
+
+ capPresWrapper2.compute( phaseVolFrac2[0],
+ JFunc2.toSliceConst(),
+ capPres2[0][0],
+ dCapPres2_dPhaseVolFrac[0][0] );
+
+// finding endpoints:
+
+ facePhaseVolFrac2[0][1] = 0.0;
+ facePhaseVolFrac2[0][0] = 1.0;
+ capPresWrapper2.compute( facePhaseVolFrac2[0],
+ JFunc2.toSliceConst(),
+ faceCapPres2[0][0],
+ dCapPres2_dfacePhaseVolFrac[0][0] );
+ Pc2_min = faceCapPres2[0][0][0];
+ facePhaseVolFrac2[0][1] = 1.0;
+ facePhaseVolFrac2[0][0] = 0.0;
+ capPresWrapper2.compute( facePhaseVolFrac2[0],
+ JFunc2.toSliceConst(),
+ faceCapPres2[0][0],
+ dCapPres2_dfacePhaseVolFrac[0][0] );
+ Pc2_max = faceCapPres2[0][0][0];
+
+ }
+ else
+ {
+ // evaluating cell-center Pc:
+
+ capPresWrapper2.compute( phaseVolFrac2[0],
+ capPres2[0][0],
+ dCapPres2_dPhaseVolFrac[0][0] );
+
+// finding endpoints:
+
+ facePhaseVolFrac2[0][1] = 0.0;
+ facePhaseVolFrac2[0][0] = 1.0;
+ capPresWrapper2.compute( facePhaseVolFrac2[0],
+ faceCapPres2[0][0],
+ dCapPres2_dfacePhaseVolFrac[0][0] );
+ Pc2_min = faceCapPres2[0][0][0];
+ facePhaseVolFrac2[0][1] = 1.0;
+ facePhaseVolFrac2[0][0] = 0.0;
+ capPresWrapper2.compute( facePhaseVolFrac2[0],
+ faceCapPres2[0][0],
+ dCapPres2_dfacePhaseVolFrac[0][0] );
+ Pc2_max = faceCapPres2[0][0][0];
+ }
+
+ // Use of the relative permeability kernel wrapper
+
+ StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceTrappedVolFrac1( 1, 1, 2 );
+ StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceRelPerm1( 1, 1, 2 );
+ StackArray< real64, 4, 4, constitutive::relperm::LAYOUT_RELPERM_DS > dfacePhaseRelPerm1_dPhaseVolFrac( 1, 1, 2, 2 );
+ StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > trappedVolFrac1( 1, 1, 2 );
+ StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > relPerm1( 1, 1, 2 );
+ StackArray< real64, 4, 4, constitutive::relperm::LAYOUT_RELPERM_DS > dPhaseRelPerm1_dPhaseVolFrac( 1, 1, 2, 2 );
+ StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceTrappedVolFrac2( 1, 1, 2 );
+ StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > faceRelPerm2( 1, 1, 2 );
+ StackArray< real64, 4, 4, constitutive::relperm::LAYOUT_RELPERM_DS > dfacePhaseRelPerm2_dPhaseVolFrac( 1, 1, 2, 2 );
+ StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > trappedVolFrac2( 1, 1, 2 );
+ StackArray< real64, 3, 2, constitutive::relperm::LAYOUT_RELPERM > relPerm2( 1, 1, 2 );
+ StackArray< real64, 4, 4, constitutive::relperm::LAYOUT_RELPERM_DS > dPhaseRelPerm2_dPhaseVolFrac( 1, 1, 2, 2 );
+
+ StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > phaseMaxHistoricalVolFraction1( 1, 2 );
+ StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > phaseMinHistoricalVolFraction1( 1, 2 );
+ StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > phaseMaxHistoricalVolFraction2( 1, 2 );
+ StackArray< real64, 2, 2, immiscibleFlow::LAYOUT_PHASE > phaseMinHistoricalVolFraction2( 1, 2 );
+
+ // compute relative permeability for both cell centers:
+
+ trappedVolFrac1[0][0][0] = trappedSats1[0];
+ trappedVolFrac1[0][0][1] = trappedSats1[1];
+
+ trappedVolFrac2[0][0][0] = trappedSats2[0];
+ trappedVolFrac2[0][0][1] = trappedSats2[1];
+
+ faceTrappedVolFrac1[0][0][0] = trappedSats1[0];
+ faceTrappedVolFrac1[0][0][1] = trappedSats1[1];
+
+ faceTrappedVolFrac2[0][0][0] = trappedSats2[0];
+ faceTrappedVolFrac2[0][0][1] = trappedSats2[1];
+
+ using T5 = std::decay_t< decltype(castedRelPerm1) >;
+ if constexpr (std::is_same_v< T5, constitutive::TableRelativePermeabilityHysteresis >) {
+ relPermWrapper1.compute( phaseVolFrac1[0],
+ phaseMaxHistoricalVolFraction1[0],
+ phaseMinHistoricalVolFraction1[0],
+ trappedVolFrac1[0][0],
+ relPerm1[0][0],
+ dPhaseRelPerm1_dPhaseVolFrac[0][0] );
+
+ }
+ else
+ {
+
+ relPermWrapper1.compute( phaseVolFrac1[0],
+ trappedVolFrac1[0][0],
+ relPerm1[0][0],
+ dPhaseRelPerm1_dPhaseVolFrac[0][0] );
+ }
+
+ using T6 = std::decay_t< decltype(castedRelPerm2) >;
+ if constexpr (std::is_same_v< T6, constitutive::TableRelativePermeabilityHysteresis >) {
+ relPermWrapper2.compute( phaseVolFrac2[0],
+ phaseMaxHistoricalVolFraction2[0],
+ phaseMinHistoricalVolFraction2[0],
+ trappedVolFrac2[0][0],
+ relPerm2[0][0],
+ dPhaseRelPerm2_dPhaseVolFrac[0][0] );
+
+ }
+ else
+ {
+
+ relPermWrapper2.compute( phaseVolFrac2[0],
+ trappedVolFrac2[0][0],
+ relPerm2[0][0],
+ dPhaseRelPerm2_dPhaseVolFrac[0][0] );
+ }
+
+
+ // Use of the fluid model kernel wrapper
+ StackArray< real64, 3, 2, constitutive::multifluid::LAYOUT_PHASE > phaseDensity1( 1, 1, 2 );
+ StackArray< real64, 3, 2, constitutive::multifluid::LAYOUT_PHASE > phaseViscosity1( 1, 1, 2 );
+ StackArray< real64, 4, 4, constitutive::multifluid::LAYOUT_PHASE_DC > dPhaseDens1_dP( 1, 1, 2, 2 );
+ StackArray< real64, 4, 4, constitutive::multifluid::LAYOUT_PHASE_DC > dPhaseVisc1_dP( 1, 1, 2, 2 );
+ StackArray< real64, 3, 2, constitutive::multifluid::LAYOUT_PHASE > phaseDensity2( 1, 1, 2 );
+ StackArray< real64, 3, 2, constitutive::multifluid::LAYOUT_PHASE > phaseViscosity2( 1, 1, 2 );
+ StackArray< real64, 4, 4, constitutive::multifluid::LAYOUT_PHASE_DC > dPhaseDens2_dP( 1, 1, 2, 2 );
+ StackArray< real64, 4, 4, constitutive::multifluid::LAYOUT_PHASE_DC > dPhaseVisc2_dP( 1, 1, 2, 2 );
+
+ // Declare the MultiFluidVar (PhaseProp) type
+ TwoPhaseImmiscibleFluid::PhaseProp phaseDensity_temp1;
+ TwoPhaseImmiscibleFluid::PhaseProp phaseViscosity_temp1;
+ phaseDensity_temp1.value.resize( 1, 1, 2 ); // or whatever sizes you need
+ phaseDensity_temp1.derivs.resize( 1, 1, 2, 2 ); // make sure all dims > 0
+ phaseViscosity_temp1.value.resize( 1, 1, 2 ); // or whatever sizes you need
+ phaseViscosity_temp1.derivs.resize( 1, 1, 2, 2 ); // make sure all dims > 0
+
+ auto phaseDensitySlice0 = TwoPhaseImmiscibleFluid::PhaseProp::SliceType(
+ phaseDensity_temp1.value[0][0], phaseDensity_temp1.derivs[0][0] );
+ auto phaseViscositySlice0 = TwoPhaseImmiscibleFluid::PhaseProp::SliceType(
+ phaseViscosity_temp1.value[0][0], phaseViscosity_temp1.derivs[0][0] );
+ fluidWrapper1.compute( pressures[0], phaseDensitySlice0, phaseViscositySlice0 );
+
+ // Temporary:
+ phaseDensity1[0][0][0] = phaseDensitySlice0.value[0];
+ phaseDensity1[0][0][1] = phaseDensitySlice0.value[1];
+ dPhaseDens1_dP[0][0][0][0] = phaseDensitySlice0.derivs[0][0];
+ dPhaseDens1_dP[0][0][0][1] = 0;
+ dPhaseDens1_dP[0][0][1][0] = phaseDensitySlice0.derivs[1][0];
+ dPhaseDens1_dP[0][0][1][1] = 0;
+
+ phaseViscosity1[0][0][0] = phaseViscositySlice0.value[0];
+ phaseViscosity1[0][0][1] = phaseViscositySlice0.value[1];
+ dPhaseVisc1_dP[0][0][0][0] = phaseViscositySlice0.derivs[0][0];
+ dPhaseVisc1_dP[0][0][0][1] = 0;
+ dPhaseVisc1_dP[0][0][1][0] = phaseViscositySlice0.derivs[1][0];
+ dPhaseVisc1_dP[0][0][1][1] = 0;
+
+ auto phaseDensitySlice1 = TwoPhaseImmiscibleFluid::PhaseProp::SliceType(
+ phaseDensity_temp1.value[0][0], phaseDensity_temp1.derivs[0][0] );
+ auto phaseViscositySlice1 = TwoPhaseImmiscibleFluid::PhaseProp::SliceType(
+ phaseViscosity_temp1.value[0][0], phaseViscosity_temp1.derivs[0][0] );
+ fluidWrapper2.compute( pressures[1], phaseDensitySlice1, phaseViscositySlice1 );
+
+
+ phaseDensity2[0][0][0] = phaseDensitySlice1.value[0];
+ phaseDensity2[0][0][1] = phaseDensitySlice1.value[1];
+ dPhaseDens2_dP[0][0][0][0] = phaseDensitySlice1.derivs[0][0];
+ dPhaseDens2_dP[0][0][0][1] = 0;
+ dPhaseDens2_dP[0][0][1][0] = phaseDensitySlice1.derivs[1][0];
+ dPhaseDens2_dP[0][0][1][1] = 0;
+
+ phaseViscosity2[0][0][0] = phaseViscositySlice1.value[0];
+ phaseViscosity2[0][0][1] = phaseViscositySlice1.value[1];
+ dPhaseVisc2_dP[0][0][0][0] = phaseViscositySlice1.derivs[0][0];
+ dPhaseVisc2_dP[0][0][0][1] = 0;
+ dPhaseVisc2_dP[0][0][1][0] = phaseViscositySlice1.derivs[1][0];
+ dPhaseVisc2_dP[0][0][1][1] = 0;
+
+ // clear working arrays
+ real64 halfFluxVal[2][2]{};
+ real64 dhalfFlux1_dP[2][2]{};
+ real64 dhalfFlux1_dS[2][2]{};
+ real64 dhalfFlux2_dP[2][2]{};
+ real64 dhalfFlux2_dS[2][2]{};
+ real64 dhalfFlux_duT[2][2]{};
+ real64 dhalfFlux_dpc[2][2]{};
+
+ //new
+ real64 fluxVal[2]{};
+ real64 dFlux_dP[2][2]{};
+ real64 dFlux_dS[2][2]{};
+
+ real64 duT_dP[2]{};
+ real64 duT_dS[2]{};
+
+ duT_dP[0] = cellCenterDuT[0];
+ duT_dP[1] = cellCenterDuT[1];
+
+ duT_dS[0] = cellCenterDuT[2];
+ duT_dS[1] = cellCenterDuT[3];
+
+ // initial guess:
+
+ real64 const Pc1 = capPres1[0][0][0];
+ real64 const Pc2 = capPres2[0][0][0];
+
+ real64 Pc_int = ( Pc1 + Pc2 ) / 2.0;
+
+ real64 Pc_min_all = fmax( Pc1_min, Pc2_min );
+ real64 Pc_max_all = fmin( Pc1_max, Pc2_max );
+
+ if( Pc_int < Pc_min_all || Pc_int > Pc_max_all )
+ {
+ Pc_int = ( Pc_min_all + Pc_max_all ) / 2.0;
+ }
+
+ // While loop (newton loop)
+ int iter = 0;
+ int div = 0;
+ // int ext_iter0 = 0;
+ // int ext_iter1 = 0;
+ real64 next_Pc_int = 0.0;
+ real64 old_Pc_int = 0.0;
+ real64 old_residual = 0.0;
+
+ if( bisection )
+ {
+ Pc_int = fmax( Pc1_max, Pc2_max );
+ next_Pc_int = fmin( Pc1_min, Pc2_min );
+ }
+
+ if( newton_path )
+ {
+ Pc_int = fmax( Pc1_max, Pc2_max );
+ Pc_int = 2.0e5;
+ next_Pc_int = (fmax( Pc1_max, Pc2_max ) - fmin( Pc1_min, Pc2_min )) / (max_iter - 1);
+ next_Pc_int = (2.0e5 - 5.0e4) / (max_iter - 1);
+ }
+
+ real64 Pc_int_iterate = Pc_int;
+
+ while( iter < max_iter )
+ {
+
+ Pc_int_iterate = Pc_int;
+
+ // clear working arrays
+ real64 density[2]{};
+ real64 dDens_dP[2][2]{};
+ real64 gravityCof[2]{};
+ real64 viscosity[2]{};
+ real64 dVisc_dP[2][2]{};
+
+ real64 viscous[2][2]{};
+ real64 bouyancy[2][2]{};
+ real64 capillarity[2][2]{};
+
+ real64 dV1_dS[2][2]{};
+ real64 dG1_dS[2][2]{};
+ real64 dC1_dS[2][2]{};
+ real64 dV2_dS[2][2]{};
+ real64 dG2_dS[2][2]{};
+ real64 dC2_dS[2][2]{};
+ real64 dV1_dpc[2][2]{};
+ real64 dG1_dpc[2][2]{};
+ real64 dC1_dpc[2][2]{};
+ real64 dV2_dpc[2][2]{};
+ real64 dG2_dpc[2][2]{};
+ real64 dC2_dpc[2][2]{};
+
+ real64 local_residual = 0;
+ real64 local_jacobian = 0;
+
+ // truncate the capillary pressure iterate (ensures the inverse will compute a saturation bounded between 0 and 1):
+
+ Pc_int = fmin( fmax( Pc1_max, Pc2_max ), fmax( Pc_int, fmin( Pc1_min, Pc2_min ) ));
+
+ faceCapPres1[0][0][0] = fmin( Pc1_max, fmax( Pc_int, Pc1_min ));
+ faceCapPres2[0][0][0] = fmin( Pc2_max, fmax( Pc_int, Pc2_min ));
+
+ // Compute the inverse:
+
+ JFunc1[0] = JFMultipliers[0];
+ JFunc2[0] = JFMultipliers[1];
+
+ using T3 = std::decay_t< decltype(castedCapPres1) >;
+ if constexpr (std::is_same_v< T3, JFunctionCapillaryPressure >) {
+ capPresWrapper1.computeInv( facePhaseVolFrac1[0],
+ JFunc1.toSliceConst(),
+ faceCapPres1[0][0],
+ dfacePhaseVolFrac_dCapPres1[0][0] );
+ facePhaseVolFrac1[0][0] = fmin( 1.0, fmax( facePhaseVolFrac1[0][0], 0.0 ));
+ facePhaseVolFrac1[0][1] = fmin( 1.0, fmax( facePhaseVolFrac1[0][1], 0.0 ));
+ //get derivatives:
+ capPresWrapper1.compute( facePhaseVolFrac1[0],
+ JFunc1.toSliceConst(),
+ faceCapPres1[0][0],
+ dCapPres1_dfacePhaseVolFrac[0][0] );
+
+ }
+ else
+ {
+ capPresWrapper1.computeInv( facePhaseVolFrac1[0],
+ faceCapPres1[0][0],
+ dfacePhaseVolFrac_dCapPres1[0][0] );
+ facePhaseVolFrac1[0][0] = fmin( 1.0, fmax( facePhaseVolFrac1[0][0], 0.0 ));
+ facePhaseVolFrac1[0][1] = fmin( 1.0, fmax( facePhaseVolFrac1[0][1], 0.0 ));
+ //get derivatives:
+ capPresWrapper1.compute( facePhaseVolFrac1[0],
+ faceCapPres1[0][0],
+ dCapPres1_dfacePhaseVolFrac[0][0] );
+ }
+
+ using T4 = std::decay_t< decltype(castedCapPres2) >;
+ if constexpr (std::is_same_v< T4, JFunctionCapillaryPressure >) {
+ // evaluating cell-center Pc:
+ capPresWrapper2.computeInv( facePhaseVolFrac2[0],
+ JFunc2.toSliceConst(),
+ faceCapPres2[0][0],
+ dfacePhaseVolFrac_dCapPres2[0][0] );
+ facePhaseVolFrac2[0][0] = fmin( 1.0, fmax( facePhaseVolFrac2[0][0], 0.0 ));
+ facePhaseVolFrac2[0][1] = fmin( 1.0, fmax( facePhaseVolFrac2[0][1], 0.0 ));
+
+//get derivatives:
+
+ capPresWrapper2.compute( facePhaseVolFrac2[0],
+ JFunc2.toSliceConst(),
+ faceCapPres2[0][0],
+ dCapPres2_dfacePhaseVolFrac[0][0] );
+
+ }
+ else
+ {
+ // evaluating cell-center Pc:
+ capPresWrapper2.computeInv( facePhaseVolFrac2[0],
+ faceCapPres2[0][0],
+ dfacePhaseVolFrac_dCapPres2[0][0] );
+ facePhaseVolFrac2[0][0] = fmin( 1.0, fmax( facePhaseVolFrac2[0][0], 0.0 ));
+ facePhaseVolFrac2[0][1] = fmin( 1.0, fmax( facePhaseVolFrac2[0][1], 0.0 ));
+
+//get derivatives:
+
+ capPresWrapper2.compute( facePhaseVolFrac2[0],
+ faceCapPres2[0][0],
+ dCapPres2_dfacePhaseVolFrac[0][0] );
+ }
+
+ // compute relative permeability for both faces:
+
+ using T7 = std::decay_t< decltype(castedRelPerm1) >;
+ if constexpr (std::is_same_v< T7, constitutive::TableRelativePermeabilityHysteresis >) {
+
+ relPermWrapper1.compute( facePhaseVolFrac1[0],
+ phaseMaxHistoricalVolFraction1[0],
+ phaseMinHistoricalVolFraction1[0],
+ faceTrappedVolFrac1[0][0],
+ faceRelPerm1[0][0],
+ dfacePhaseRelPerm1_dPhaseVolFrac[0][0] );
+
+ }
+ else
+ {
+
+ relPermWrapper1.compute( facePhaseVolFrac1[0],
+ faceTrappedVolFrac1[0][0],
+ faceRelPerm1[0][0],
+ dfacePhaseRelPerm1_dPhaseVolFrac[0][0] );
+ }
+
+ using T8 = std::decay_t< decltype(castedRelPerm2) >;
+ if constexpr (std::is_same_v< T8, constitutive::TableRelativePermeabilityHysteresis >) {
+
+ relPermWrapper2.compute( facePhaseVolFrac2[0],
+ phaseMaxHistoricalVolFraction2[0],
+ phaseMinHistoricalVolFraction2[0],
+ faceTrappedVolFrac2[0][0],
+ faceRelPerm2[0][0],
+ dfacePhaseRelPerm2_dPhaseVolFrac[0][0] );
+
+ }
+ else
+ {
+
+ relPermWrapper2.compute( facePhaseVolFrac2[0],
+ faceTrappedVolFrac2[0][0],
+ faceRelPerm2[0][0],
+ dfacePhaseRelPerm2_dPhaseVolFrac[0][0] );
+ }
+
+
+ // Brenier and Jaffre's PPU upwinding:
+ bool check = false;
+ bool k_up_0_w = 1;
+ bool k_up_1_w = 1;
+ bool k_up_0_n = 1;
+ bool k_up_1_n = 1;
+
+ if( uT < 0.0 )
+ {
+ k_up_0_w = 0;
+ k_up_1_w = 0;
+ k_up_0_n = 0;
+ k_up_1_n = 0;
+ }
+
+ if( std::fabs( uT ) < 1e-20 )
+ {
+ k_up_0_w = 1;
+ k_up_1_w = 1;
+ k_up_0_n = 0;
+ k_up_1_n = 0;
+ }
+
+
+ localIndex k_up_0[2] = {static_cast< localIndex >(!k_up_0_w), static_cast< localIndex >(!k_up_0_n)};
+ localIndex k_up_1[2] = {static_cast< localIndex >(k_up_1_w), static_cast< localIndex >(k_up_1_n)};
+ bool k_up_0_check[2] = {false, false};
+ bool k_up_1_check[2] = {false, false};
+
+ while( !check )
+ {
+ k_up_0_check[0] = false;
+ k_up_0_check[1] = false;
+ k_up_1_check[0] = false;
+ k_up_1_check[1] = false;
+ for( integer ix = 0; ix < 2; ++ix ) // for loop over each half flux
+ {
+
+ // clear working arrays for each half flux:
+ real64 densMean[2]{};
+ real64 dDensMean_dP[2][2]{};
+
+ real64 presGrad[2]{};
+ real64 dPresGrad_dP[2][2]{};
+
+ real64 gravHead[2]{};
+ real64 dGravHead_dP[2][2]{};
+
+ real64 capGrad[2]{};
+ // real64 capPresIC[2][2]{};
+ // real64 jFMultiplier[2][2]{};
+ real64 dCapGrad_dP[2][2]{};
+ real64 dCapGrad_dS[2][2]{};
+
+ real64 mobility[2]{};
+ real64 dMob_dP[2][2]{};
+ real64 dMob_dS[2][2]{};
+
+ real64 total_mobility = 0;
+ gravityCof[0] = 0;
+ gravityCof[1] = 0;
+
+ for( integer ip = 0; ip < 2; ++ip ) // loop over phases
+ {
+ // calculate quantities on primary connected cells
+ if( ix == 0 )
+ {
+ density[ip] = phaseDensity1[0][0][ip];
+ dDens_dP[ip][ix] = dPhaseDens1_dP[0][0][ip][ip];
+
+ viscosity[ip] = phaseViscosity1[0][0][ip];
+ dVisc_dP[ip][ix] = dPhaseVisc1_dP[0][0][ip][ip];
+ }
+ else
+ {
+ density[ip] = phaseDensity2[0][0][ip];
+ dDens_dP[ip][ix] = dPhaseDens2_dP[0][0][ip][ip];
+
+ viscosity[ip] = phaseViscosity2[0][0][ip];
+ dVisc_dP[ip][ix] = dPhaseVisc2_dP[0][0][ip][ip];
+ }
+
+ densMean[ip] = density[ip];
+ dDensMean_dP[ip][0] = dDens_dP[ip][ix];
+ dDensMean_dP[ip][1] = dDens_dP[ip][ix];
+
+ //***** calculation of flux *****
+
+ // compute potential difference
+ real64 potScale = 0.0;
+ real64 dPresGrad_dTrans = 0.0;
+ real64 dGravHead_dTrans = 0.0;
+ real64 dCapGrad_dTrans = 0.0;
+ constexpr int signPotDiff[2] = {1, -1};
+ constexpr int signTix[2] = {1, -1};
+
+ for( integer ke = 0; ke < 2; ++ke )
+ {
+
+ real64 const pressure = pressures[ix];
+ presGrad[ip] += signTix[ke] * transHat[ix] * pressure;
+ dPresGrad_dTrans += signPotDiff[ke] * pressure;
+ dPresGrad_dP[ip][ke] = signTix[ke] * transHat[ix];
+
+ real64 gravD = 0.0;
+
+ if( ke == 0 )
+ {
+ gravD += signTix[ke] * transHat[ix] * gravCoef[ix];
+ }
+ else
+ {
+ gravD += signTix[ke] * transHat[ix] * gravCoefHat[ix];
+ }
+
+ real64 pot = signTix[ke] * transHat[ix] * pressure - densMean[ip] * gravD;
+
+ gravHead[ip] += densMean[ip] * gravD;
+ gravityCof[ip] += gravD;
+
+ dGravHead_dTrans += signPotDiff[ke] * densMean[ip] * gravCoefHat[ix];
+
+ for( integer i = 0; i < 2; ++i )
+ {
+ dGravHead_dP[ip][i] += dDensMean_dP[ip][i] * gravD;
+ }
+
+ real64 capPres = capPres1[0][0][ip];
+
+ if( ke == 1 && ix == 0 )
+ {
+ capPres = faceCapPres1[0][0][ip];
+ }
+ else if( ke == 1 && ix == 1 )
+ {
+ capPres = faceCapPres2[0][0][ip];
+ }
+ else if( ke == 0 && ix == 1 )
+ {
+
+ capPres = capPres2[0][0][ip];
+ }
+
+ dCapGrad_dTrans -= signPotDiff[ke] * capPres;
+ pot -= signTix[ke] * transHat[ix] * capPres;
+
+ capGrad[ip] -= signTix[ke] * transHat[ix] * capPres;
+
+ potScale = fmax( potScale, fabs( pot ) );
+ }
+
+ for( integer ke = 0; ke < 2; ++ke )
+ {
+ dPresGrad_dP[ip][ke] += signTix[ke] * dTransHat_dP[ix] * dPresGrad_dTrans;
+
+ dGravHead_dP[ip][ke] += signTix[ke] * dTransHat_dP[ix] * dGravHead_dTrans;
+
+ // real64 constexpr eps = 1e-18;
+ real64 dCapPres_dS = dCapPres1_dPhaseVolFrac[0][0][ip][ip];
+
+ if( ke == 1 && ix == 0 )
+ {
+ dCapPres_dS = dCapPres1_dfacePhaseVolFrac[0][0][ip][ip];
+ }
+ else if( ke == 1 && ix == 1 )
+ {
+ dCapPres_dS = dCapPres2_dfacePhaseVolFrac[0][0][ip][ip];
+ }
+ else if( ke == 0 && ix == 1 )
+ {
+ dCapPres_dS = dCapPres2_dPhaseVolFrac[0][0][ip][ip];
+ }
+
+ dCapGrad_dP[ip][ke] += signTix[ke] * dTransHat_dP[ix] * dCapGrad_dTrans;
+ dCapGrad_dS[ip][ke] -= signTix[ke] * transHat[ix] * dCapPres_dS;
+ }
+
+ // *** upwinding ***
+ // compute potential gradient
+// real64 potGrad = presGrad[ip] - gravHead[ip];
+
+// potGrad += capGrad[ip];
+
+ // choose upstream cell
+ constexpr int sign[2] = {1, -1};
+
+ if( k_up_0[ip] == 1 && ix == 0 )
+ {
+ mobility[ip] = faceRelPerm1[0][0][ip] / viscosity[ip];
+ dMob_dP[ip][k_up_0[ip]] = mobility[ip] * (-dVisc_dP[ip][ix] / viscosity[ip]);
+
+ dMob_dS[ip][k_up_0[ip]] = sign[ip] * dfacePhaseRelPerm1_dPhaseVolFrac[0][0][ip][ip] / viscosity[ip];
+ }
+ else if( k_up_1[ip] == 0 && ix == 1 )
+ {
+ mobility[ip] = relPerm2[0][0][ip] / viscosity[ip];
+ dMob_dP[ip][0] = mobility[ip] * (-dVisc_dP[ip][ix] / viscosity[ip]);
+ dMob_dS[ip][0] = sign[ip] * dPhaseRelPerm2_dPhaseVolFrac[0][0][ip][ip] / viscosity[ip];
+ }
+ else if( k_up_1[ip] == 1 && ix == 1 )
+ {
+ mobility[ip] = faceRelPerm2[0][0][ip] / viscosity[ip];
+ dMob_dP[ip][1] = mobility[ip] * (-dVisc_dP[ip][ix] / viscosity[ip]);
+ dMob_dS[ip][1] = sign[ip] * dfacePhaseRelPerm2_dPhaseVolFrac[0][0][ip][ip] / viscosity[ip];
+ }
+ else
+ {
+ mobility[ip] = relPerm1[0][0][ip] / viscosity[ip];
+ dMob_dP[ip][ix] = mobility[ip] * (-dVisc_dP[ip][ix] / viscosity[ip]);
+ dMob_dS[ip][ix] = sign[ip] * dPhaseRelPerm1_dPhaseVolFrac[0][0][ip][ip] / viscosity[ip];
+ }
+ real64 constexpr eps = 0.0;
+ total_mobility += mobility[ip] + eps;
+ } // loop over phases
+
+ /// Three Forces Flux Contribution: 1- Viscous 2- Gravitational 3- Capillary
+ constexpr int sign[2] = {1, -1};
+ // real64 constexpr eps = 0.0;
+
+ // loop over phases
+ for( integer ip = 0; ip < 2; ++ip )
+ {
+ // 1- Viscous: pressure gradient depends on all points in the stencil
+ viscous[ip][ix] = mobility[ip] / total_mobility * uT;
+ halfFluxVal[ip][ix] = viscous[ip][ix];
+
+ for( integer ke = 0; ke < 2; ++ke )
+ {
+ real64 dV_dP = sign[ip] * (dMob_dP[0][ke] * mobility[1] - dMob_dP[1][ke] * mobility[0]) / (total_mobility * total_mobility) * uT;
+ real64 dV_dS = sign[ip] * (dMob_dS[0][ke] * mobility[1] - dMob_dS[1][ke] * mobility[0]) / (total_mobility * total_mobility) * uT;
+ real64 dV_du = mobility[ip] / total_mobility;
+
+ if( ix == 0 )
+ {
+ dV1_dS[ip][ke] = dV_dS;
+ dhalfFlux1_dP[ip][ke] = dV_dP;
+ dhalfFlux1_dS[ip][ke] = dV1_dS[ip][ke];
+ dhalfFlux_duT[ip][ix] = dV_du;
+ dV1_dpc[ip][ke] = dV1_dS[ip][ke] * dfacePhaseVolFrac_dCapPres1[0][0][0][0];
+ // GEOS_UNUSED_VAR( dV1_dpc[ip][ke] );
+ GEOS_UNUSED_VAR( dhalfFlux_duT[ip][ix] );
+ }
+ else
+ {
+ dV2_dS[ip][ke] = dV_dS;
+ dhalfFlux2_dP[ip][ke] = dV_dP;
+ dhalfFlux2_dS[ip][ke] = dV2_dS[ip][ke];
+ dhalfFlux_duT[ip][ix]= dV_du;
+ dV2_dpc[ip][ke] = dV2_dS[ip][ke] * dfacePhaseVolFrac_dCapPres2[0][0][0][0];
+ // GEOS_UNUSED_VAR( dV2_dpc[ip][ke] );
+ GEOS_UNUSED_VAR( dhalfFlux_duT[ip][ix] );
+ }
+ }
+
+ // 2- Gravitational: gravitational head depends only on the two cells connected (same as mean density)
+ bouyancy[ip][ix] = -1.0 * sign[ix] * sign[ip] * mobility[0] * mobility[1] / total_mobility * gravityCof[0] * (density[0] - density[1]);
+ halfFluxVal[ip][ix] += bouyancy[ip][ix];
+
+ for( integer ke = 0; ke < 2; ++ke )
+ {
+ real64 dG_dP = sign[ix] * sign[ip] * (dMob_dP[0][ke] * mobility[1] * mobility[1] + dMob_dP[1][ke] * mobility[0] * mobility[0]) / (total_mobility * total_mobility) * gravityCof[0] *
+ (density[0] - density[1]) +
+ sign[ix] * (mobility[0] * mobility[1]) / total_mobility * (dDens_dP[0][ix] - dDens_dP[1][ix]);
+
+ real64 dG_dS = sign[ix] * sign[ip] * (dMob_dS[0][ke] * mobility[1] * mobility[1] + dMob_dS[1][ke] * mobility[0] * mobility[0]) / (total_mobility * total_mobility) *
+ gravityCof[0] * (density[0] - density[1]);
+
+ if( ix == 0 )
+ {
+ dG1_dS[ip][ke] = dG_dS;
+ dhalfFlux1_dP[ip][ke] -= dG_dP;
+ dhalfFlux1_dS[ip][ke] -= dG1_dS[ip][ke];
+ dG1_dpc[ip][ke] = dG1_dS[ip][ke] * dfacePhaseVolFrac_dCapPres1[0][0][0][0];
+ // GEOS_UNUSED_VAR( dG1_dpc[ip][ke] );
+ }
+ else
+ {
+ dG2_dS[ip][ke] = dG_dS;
+ dhalfFlux2_dP[ip][ke] -= dG_dP;
+ dhalfFlux2_dS[ip][ke] -= dG2_dS[ip][ke];
+ dG2_dpc[ip][ke] = dG2_dS[ip][ke] * dfacePhaseVolFrac_dCapPres2[0][0][0][0];
+ // GEOS_UNUSED_VAR( dG2_dpc[ip][ke] );
+ }
+ }
+
+ // 3- Capillary: capillary pressure contribution
+ capillarity[ip][ix] = -1.0 * sign[ix] * sign[ip] * mobility[0] * mobility[1] / total_mobility * (capGrad[1] -capGrad[0]);
+ halfFluxVal[ip][ix] += capillarity[ip][ix];
+
+ for( integer ke = 0; ke < 2; ++ke )
+ {
+ real64 dC_dP = sign[ix] * sign[ip] * (dMob_dP[0][ke] * mobility[1] * mobility[1] + dMob_dP[1][ke] * mobility[0] * mobility[0]) / (total_mobility * total_mobility) *
+ (capGrad[1] -capGrad[0]) +
+ sign[ix] * sign[ip] * mobility[0] * mobility[1] / total_mobility * (dCapGrad_dP[1][ke] - dCapGrad_dP[0][ke]);
+
+ real64 dC_dS_term1 = sign[ix] * sign[ip] * (dMob_dS[0][ke] * mobility[1] * mobility[1] + dMob_dS[1][ke] * mobility[0] * mobility[0]) / (total_mobility * total_mobility) *
+ (capGrad[1] -capGrad[0]);
+
+ real64 dC_dS_term2 = sign[ix] * sign[ip] * (mobility[0] * mobility[1]) / total_mobility;
+
+ real64 dC_dS_term3 = (dCapGrad_dS[1][ke] - dCapGrad_dS[0][ke]);
+
+ if( ix == 0 )
+ {
+ dC1_dS[ip][ke] = dC_dS_term1 + dC_dS_term2 * dC_dS_term3;
+ dhalfFlux1_dP[ip][ke] -= dC_dP;
+ dhalfFlux1_dS[ip][ke] -= dC1_dS[ip][ke];
+ if( std::fabs( facePhaseVolFrac1[0][0] - 1.0 ) > 1e-8 )
+ {
+ dC1_dpc[ip][ke] = dC1_dS[ip][ke] * dfacePhaseVolFrac_dCapPres1[0][0][0][0];
+ }
+ else
+ {
+ dC1_dpc[ip][ke] = dC_dS_term1 * dfacePhaseVolFrac_dCapPres1[0][0][0][0];
+ }
+
+ // GEOS_UNUSED_VAR( dC1_dpc[ip][ke] );
+ }
+ else
+ {
+ dC2_dS[ip][ke] = dC_dS_term1 + dC_dS_term2 * dC_dS_term3;
+ dhalfFlux2_dP[ip][ke] -= dC_dP;
+ dhalfFlux2_dS[ip][ke] -= dC2_dS[ip][ke];
+ if( std::fabs( facePhaseVolFrac2[0][0] - 1.0 ) > 1e-8 )
+ {
+ dC2_dpc[ip][ke] = dC2_dS[ip][ke] * dfacePhaseVolFrac_dCapPres2[0][0][0][0];
+ }
+ else
+ {
+ dC2_dpc[ip][ke] = dC_dS_term1 * dfacePhaseVolFrac_dCapPres2[0][0][0][0];
+ }
+ // GEOS_UNUSED_VAR( dC2_dpc[ip][ke] );
+ }
+
+ }
+
+
+ if( halfFluxVal[ip][0] > 0.0 )
+ {
+ k_up_0_check[ip] = true;
+ }
+ if( halfFluxVal[ip][1] > 0.0 )
+ {
+ k_up_1_check[ip] = true;
+ }
+
+ } // loop over phases
+
+ } // loop over half fluxes
+
+ check = true;
+
+ // Brenier and Jaffre's PPU check:
+ bool flip0[2] = {0, 0};
+ bool flip0_k_up[2] = {0, 0};
+ bool flip1[2] = {0, 0};
+ bool flip1_k_up[2] = {0, 0};
+ // loop over phases
+ for( integer ip = 0; ip < 2; ++ip )
+ {
+ bool k_up_0_b = !static_cast< bool >(k_up_0[ip]);
+ bool k_up_1_b = static_cast< bool >(k_up_1[ip]);
+ flip0_k_up[ip] = k_up_0_b;
+ flip1_k_up[ip] = k_up_1_b;
+
+ if( std::fabs( uT ) < 1e-20 )
+ {
+
+ if((std::fabs( halfFluxVal[ip][0] ) < 1e-20) && (std::fabs( halfFluxVal[ip][1] ) < 1e-20))
+ {
+ k_up_0_check[ip] = !k_up_0_b;
+ k_up_1_check[ip] = !k_up_1_b;
+ }
+ else
+ {
+ k_up_0_check[ip] = k_up_0_b;
+ k_up_1_check[ip] = k_up_1_b;
+ }
+
+ if( k_up_0_check[ip] != k_up_0_b )
+ {
+ flip0[ip] = 1;
+ check = false;
+ }
+
+ if( k_up_1_check[ip] != k_up_1_b )
+ {
+ flip1[ip] = 1;
+ check = false;
+ }
+
+ }
+ else
+ {
+ if( std::fabs( halfFluxVal[ip][0] ) < 1e-20 )
+ {
+ k_up_0_check[ip] = k_up_0_b;
+ }
+
+ if( std::fabs( halfFluxVal[ip][1] ) < 1e-20 )
+ {
+ k_up_1_check[ip] = k_up_1_b;
+ }
+
+ if( k_up_0_check[ip] != k_up_0_b )
+ {
+ k_up_0[ip] = static_cast< localIndex >(k_up_0_b);
+ check = false;
+ }
+
+ if( k_up_1_check[ip] != k_up_1_b )
+ {
+ k_up_1[ip] = static_cast< localIndex >(!k_up_1_b);
+ check = false;
+ }
+ }
+
+ }
+
+ if( flip0[0] || flip0[1] )
+ {
+ k_up_0[0] = static_cast< localIndex >(flip0_k_up[0]);
+ k_up_0[1] = static_cast< localIndex >(flip0_k_up[1]);
+ }
+
+ if( flip1[0] || flip1[1] )
+ {
+ k_up_1[0] = static_cast< localIndex >(!flip1_k_up[0]);
+ k_up_1[1] = static_cast< localIndex >(!flip1_k_up[1]);
+ }
+
+ } // while check for BJ PPU
+
+ real64 constexpr eps2 = 1.0e-18;
+ // newton update
+ dhalfFlux_dpc[0][0] = dhalfFlux1_dS[0][1]*dfacePhaseVolFrac_dCapPres1[0][0][0][0];
+ real64 dhalfFlux_dpc00 = dV1_dpc[0][1] - dG1_dpc[0][1] - dC1_dpc[0][1];
+ dhalfFlux_dpc[0][1] = dhalfFlux2_dS[0][1]*dfacePhaseVolFrac_dCapPres2[0][0][0][0];
+ real64 dhalfFlux_dpc01 = dV2_dpc[0][1] - dG2_dpc[0][1] - dC2_dpc[0][1];
+
+ dhalfFlux_dpc[1][0] = dhalfFlux1_dS[1][1]*dfacePhaseVolFrac_dCapPres1[0][0][0][0];
+ real64 dhalfFlux_dpc10 = dV1_dpc[1][1] - dG1_dpc[1][1] - dC1_dpc[1][1];
+ dhalfFlux_dpc[1][1] = dhalfFlux2_dS[1][1]*dfacePhaseVolFrac_dCapPres2[0][0][0][0];
+ real64 dhalfFlux_dpc11 = dV2_dpc[1][1] - dG2_dpc[1][1] - dC2_dpc[1][1];
+
+ dhalfFlux_dpc[0][0] = dhalfFlux_dpc00;
+ dhalfFlux_dpc[0][1] = dhalfFlux_dpc01;
+ dhalfFlux_dpc[1][0] = dhalfFlux_dpc10;
+ dhalfFlux_dpc[1][1] = dhalfFlux_dpc11;
+
+ local_jacobian = dhalfFlux_dpc[0][0] - dhalfFlux_dpc[0][1] + eps2;
+ local_residual = halfFluxVal[0][0] - halfFluxVal[0][1];
+
+ // if (iter == 1) {
+ // grad_phi[0] = local_residual;
+ // }
+
+ // Check convergence
+ if( std::fabs( local_residual ) < tol )
+ {
+ // if( std::fabs( dhalfFlux_dpc[0][0] - dhalfFlux_dpc[0][1] ) (max_iter - 2)) )
+ {
+ if( div == 0 )
+ {
+ iter = 0;
+ div++;
+ Pc_int = Pc_min_all;
+ }
+ else if( div == 1 )
+ {
+ iter = 0;
+ div++;
+ Pc_int = Pc_max_all;
+ }
+ else if( div > 1 )
+ {
+ local_jacobian = 0.0;
+ std::cout << "**********************Diverged*******************" << std::endl;
+ iter = max_iter;
+ }
+ }
+ else
+ {
+
+ real64 deltaPc = local_residual/local_jacobian;
+
+ if( std::fabs( local_residual ) < tol )
+ {
+ // if( std::fabs( dhalfFlux_dpc[0][0] - dhalfFlux_dpc[0][1] ) < eps2 ) {
+ // std::cout << "**********************ZeroJacobian*******************" << std::endl;
+ // }
+ converged = 1;
+ break; // Converged
+ }
+
+ // Damping option:
+ if( damping )
+ {
+ real64 max_dpc = fmax( fabs( dCapPres1_dfacePhaseVolFrac[0][0][0][0] ), fabs( dCapPres2_dfacePhaseVolFrac[0][0][0][0] ));
+
+ real64 sign = std::copysign( 1.0, deltaPc );
+
+ deltaPc = fmin( fabs( deltaPc ), max_dpc * 0.2 );
+ deltaPc *= sign;
+
+ }
+
+ if( bisection && iter < 7 )
+ {
+ if( iter == 0 )
+ {
+
+ old_Pc_int = Pc_int;
+ Pc_int = next_Pc_int;
+ old_residual = local_residual;
+
+ }
+ else if( old_residual * local_residual < 0.0 )
+ {
+
+ Pc_int = (next_Pc_int + old_Pc_int) / 2.0;
+ old_residual = local_residual;
+ old_Pc_int = next_Pc_int;
+ next_Pc_int = Pc_int;
+
+ }
+ else if( old_residual * local_residual > 0.0 )
+ {
+
+ Pc_int = old_Pc_int;
+ old_residual = local_residual;
+ old_Pc_int = next_Pc_int;
+ next_Pc_int = Pc_int;
+
+ }
+ else
+ {
+
+ Pc_int = old_Pc_int;
+ old_residual = local_residual;
+ old_Pc_int = next_Pc_int;
+ next_Pc_int = Pc_int;
+
+ }
+
+ }
+ else if( newton_path )
+ {
+ Pc_int -= next_Pc_int;
+
+ }
+ else
+ {
+
+ Pc_int -= deltaPc;
+
+ }
+
+
+ // truncate the updated capillary pressure (extended capillary pressure condition) for reporting/plotting:
+
+ real64 faceCapPres1_plot = fmin( Pc1_max, fmax( Pc_int, Pc1_min ));
+ real64 faceCapPres2_plot = fmin( Pc2_max, fmax( Pc_int, Pc2_min ));
+ faceCapPres1_plot = fmin( Pc2_max, fmax( faceCapPres1_plot, Pc2_min ));
+ faceCapPres2_plot = fmin( Pc1_max, fmax( faceCapPres2_plot, Pc1_min ));
+
+ // Write data to the file
+ outFile << GEOS_FMT( "{:10.10e}", local_jacobian );
+ outFile << GEOS_FMT( ",{:10.10e}", local_residual );
+ outFile << GEOS_FMT( ",{:10.10e}", halfFluxVal[0][0] );
+ outFile << GEOS_FMT( ",{:10.10e}", halfFluxVal[0][1] );
+ outFile << GEOS_FMT( ",{:10.10e}", Pc_int_iterate );
+ outFile << GEOS_FMT( ",{:10.10e}", faceCapPres1[0][0][0] );
+ outFile << GEOS_FMT( ",{:10.10e}", faceCapPres2[0][0][0] );
+ outFile << GEOS_FMT( ",{:10.10e}", halfFluxVal[1][0] );
+ outFile << GEOS_FMT( ",{:10.10e}", halfFluxVal[1][1] );
+ outFile << GEOS_FMT( ",{:10.10e}", viscous[0][0] );
+ outFile << GEOS_FMT( ",{:10.10e}", viscous[1][0] );
+ outFile << GEOS_FMT( ",{:10.10e}", viscous[0][1] );
+ outFile << GEOS_FMT( ",{:10.10e}", viscous[1][1] );
+ outFile << GEOS_FMT( ",{:10.10e}", bouyancy[0][0] );
+ outFile << GEOS_FMT( ",{:10.10e}", bouyancy[1][0] );
+ outFile << GEOS_FMT( ",{:10.10e}", bouyancy[0][1] );
+ outFile << GEOS_FMT( ",{:10.10e}", bouyancy[1][1] );
+ outFile << GEOS_FMT( ",{:10.10e}", capillarity[0][0] );
+ outFile << GEOS_FMT( ",{:10.10e}", capillarity[1][0] );
+ outFile << GEOS_FMT( ",{:10.10e}", capillarity[0][1] );
+ outFile << GEOS_FMT( ",{:10.10e}", capillarity[1][1] );
+ outFile << GEOS_FMT( ",{:10.10e}", capPres1[0][0][0] );
+ outFile << GEOS_FMT( ",{:10.10e}", capPres1[0][0][1] );
+ outFile << GEOS_FMT( ",{:10.10e}", facePhaseVolFrac1[0][0] );
+ outFile << GEOS_FMT( ",{:10.10e}", facePhaseVolFrac2[0][0] );
+ outFile << std::endl;
+
+ iter++;
+
+ }
+
+
+ } // while loop
+
+ if( converged )
+ {
+
+ // Global derivatives:
+ real64 constexpr eps3 = 1.0e-18;
+
+ real64 const dPc_int_dS1 =(-1.0) * (dhalfFlux1_dS[0][0] + dhalfFlux_duT[0][0] * duT_dS[0] - dhalfFlux_duT[0][1] * duT_dS[0]) / (dhalfFlux_dpc[0][0] - dhalfFlux_dpc[0][1] + eps3);
+ real64 const dPc_int_dS2 =(-1.0) * (dhalfFlux_duT[0][0] * duT_dS[1] - dhalfFlux2_dS[0][0] - dhalfFlux_duT[0][1] * duT_dS[1]) / (dhalfFlux_dpc[0][0] - dhalfFlux_dpc[0][1] + eps3);
+ real64 const dPc_int_du =(-1.0) * (dhalfFlux_duT[0][0] - dhalfFlux_duT[0][1]) / (dhalfFlux_dpc[0][0] - dhalfFlux_dpc[0][1] + eps3);
+
+ dFlux_dP[0][0] = (dhalfFlux_duT[0][0] * duT_dP[0] + dhalfFlux_dpc[0][0] * dPc_int_du * duT_dP[0]) * density2[0] + halfFluxVal[0][0] * dDens_dP2[0][0];
+ dFlux_dS[0][0] = (dhalfFlux1_dS[0][0] + dhalfFlux_duT[0][0] * duT_dS[0] + dhalfFlux_dpc[0][0] * dPc_int_dS1) * density2[0];
+
+ dFlux_dP[0][1] = (dhalfFlux_duT[0][1] * duT_dP[1] + dhalfFlux_dpc[0][1] * dPc_int_du * duT_dP[1]) * density2[0] + halfFluxVal[0][1] * dDens_dP2[0][1];
+ dFlux_dS[0][1] = (dhalfFlux2_dS[0][0] + dhalfFlux_duT[0][1] * duT_dS[1] + dhalfFlux_dpc[0][1] * dPc_int_dS2) * density2[0];
+
+ dFlux_dP[1][0] = (dhalfFlux_duT[1][0] * duT_dP[0] + dhalfFlux_dpc[1][0] * dPc_int_du * duT_dP[0]) * density2[1] + halfFluxVal[1][0] * dDens_dP2[1][0];
+ dFlux_dS[1][0] = (dhalfFlux1_dS[1][0] + dhalfFlux_duT[1][0] * duT_dS[0] + dhalfFlux_dpc[1][0] * dPc_int_dS1) * density2[1];
+
+ dFlux_dP[1][1] = (dhalfFlux_duT[1][1] * duT_dP[1] + dhalfFlux_dpc[1][1] * dPc_int_du * duT_dP[1]) * density2[1] + halfFluxVal[1][1] * dDens_dP2[1][1];
+ dFlux_dS[1][1] = (dhalfFlux2_dS[1][0] + dhalfFlux_duT[1][1] * duT_dS[1] + dhalfFlux_dpc[1][1] * dPc_int_dS2) * density2[1];
+
+ fluxVal[0] = halfFluxVal[0][0] * density2[0];
+ fluxVal[1] = halfFluxVal[1][0] * density2[1];
+
+ }
+ else
+ {
+ std::cout << "**********************Diverged*******************" << std::endl;
+
+ }
+
+ phi[0] = fluxVal[0];
+ phi[1] = fluxVal[1];
+
+ grad_phi_P[0] = dFlux_dP[0][0];
+ grad_phi_P[1] = dFlux_dP[0][1];
+ grad_phi_P[2] = dFlux_dP[1][0];
+ grad_phi_P[3] = dFlux_dP[1][1];
+
+ grad_phi_S[0] = dFlux_dS[0][0];
+ grad_phi_S[1] = dFlux_dS[0][1];
+ grad_phi_S[2] = dFlux_dS[1][0];
+ grad_phi_S[3] = dFlux_dS[1][1];
+
+ converged = 1;
+ GEOS_UNUSED_VAR( converged );
+// Close the file after writing
+ outFile.close();
+
+ } );
+
+ } );
+
+ } );
+
+ } );
+
+
+}
/******************************** FluxComputeKernelBase ********************************/
@@ -78,17 +1350,23 @@ class FluxComputeKernelBase
fields::flow::gravityCoefficient,
fields::immiscibleMultiphaseFlow::phaseVolumeFraction,
fields::immiscibleMultiphaseFlow::phaseMobility,
+ fields::immiscibleMultiphaseFlow::phaseMass_n,
fields::immiscibleMultiphaseFlow::dPhaseMobility >;
using MultiphaseFluidAccessors =
StencilMaterialAccessors< constitutive::TwoPhaseImmiscibleFluid,
fields::twophaseimmisciblefluid::phaseDensity,
- fields::twophaseimmisciblefluid::dPhaseDensity >;
+ fields::twophaseimmisciblefluid::dPhaseDensity,
+ fields::twophaseimmisciblefluid::phaseViscosity,
+ fields::twophaseimmisciblefluid::dPhaseViscosity >;
using CapPressureAccessors =
- StencilMaterialAccessors< CapillaryPressureBase,
+ StencilMaterialAccessors< BrooksCoreyCapillaryPressure,
fields::cappres::phaseCapPressure,
- fields::cappres::dPhaseCapPressure_dPhaseVolFraction >;
+ fields::cappres::dPhaseCapPressure_dPhaseVolFraction
+ >;
+ // ,fields::cappres::jFuncMultiplier >;
+
using PermeabilityAccessors =
StencilMaterialAccessors< PermeabilityBase,
@@ -135,12 +1413,16 @@ class FluxComputeKernelBase
m_gravCoef( multiPhaseFlowAccessors.get( fields::flow::gravityCoefficient {} ) ),
m_pres( multiPhaseFlowAccessors.get( fields::flow::pressure {} ) ),
m_phaseVolFrac( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::phaseVolumeFraction {} ) ),
+ m_phaseMass_n( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::phaseMass_n {} ) ),
m_mob( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::phaseMobility {} ) ),
m_dMob( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::dPhaseMobility {} ) ),
m_dens( fluidAccessors.get( fields::twophaseimmisciblefluid::phaseDensity {} ) ),
+ m_visc( fluidAccessors.get( fields::twophaseimmisciblefluid::phaseViscosity {} ) ),
m_dDens_dPres( fluidAccessors.get( fields::twophaseimmisciblefluid::dPhaseDensity {} ) ),
+ m_dVisc_dPres( fluidAccessors.get( fields::twophaseimmisciblefluid::dPhaseViscosity {} ) ),
m_phaseCapPressure( capPressureAccessors.get( fields::cappres::phaseCapPressure {} ) ),
m_dPhaseCapPressure_dPhaseVolFrac( capPressureAccessors.get( fields::cappres::dPhaseCapPressure_dPhaseVolFraction {} ) ),
+ // m_jFuncMultiplier( capPressureAccessors.get( fields::cappres::jFuncMultiplier {} ) ),
m_localMatrix( localMatrix ),
m_localRhs( localRhs ),
m_hasCapPressure ( hasCapPressure ),
@@ -174,21 +1456,26 @@ class FluxComputeKernelBase
/// Views on pressure and phase volume fraction
ElementViewConst< arrayView1d< real64 const > > const m_pres;
ElementViewConst< arrayView2d< real64 const, immiscibleFlow::USD_PHASE > > const m_phaseVolFrac;
+ ElementViewConst< arrayView2d< real64 const, immiscibleFlow::USD_PHASE > > const m_phaseMass_n;
/// Views on fluid mobility
ElementViewConst< arrayView2d< real64 const, immiscibleFlow::USD_PHASE > > const m_mob;
ElementViewConst< arrayView3d< real64 const, immiscibleFlow::USD_PHASE_DS > > const m_dMob;
- /// Views on fluid density
+ /// Views on fluid density and viscosity
ElementViewConst< arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > > const m_dens;
+ ElementViewConst< arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > > const m_visc;
ElementViewConst< arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_DC > > const m_dDens_dPres;
+ ElementViewConst< arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_DC > > const m_dVisc_dPres;
/// Views on capillary pressure
ElementViewConst< arrayView3d< real64 const, cappres::USD_CAPPRES > > const m_phaseCapPressure;
ElementViewConst< arrayView4d< real64 const, cappres::USD_CAPPRES_DS > > const m_dPhaseCapPressure_dPhaseVolFrac;
+ // ElementViewConst< arrayView2d< real64 const > > const m_jFuncMultiplier;
// Residual and jacobian
+
/// View on the local CRS matrix
CRSMatrixView< real64, globalIndex const > const m_localMatrix;
/// View on the local RHS
@@ -314,6 +1601,11 @@ class FluxComputeKernel : public FluxComputeKernelBase
/// Derivatives of transmissibility with respect to pressure
real64 dTrans_dPres[maxNumConns][2]{};
+ /// Transmissibility
+ real64 transmissibilityHat[maxNumConns][2]{};
+ /// Derivatives of transmissibility with respect to pressure
+ real64 dTransHat_dPres[maxNumConns][2]{};
+
// Local degrees of freedom and local residual/jacobian
/// Indices of the matrix rows/columns corresponding to the dofs in this face
@@ -372,7 +1664,7 @@ class FluxComputeKernel : public FluxComputeKernelBase
* @param[inout] stack the stack variables
* @param[in] NoOpFunc the function used to customize the computation of the flux
*/
- template< typename FUNC = NoOpFunc > // should change to multiphase
+ template< typename FUNC = NoOpFunc > // should change to multiphase
GEOS_HOST_DEVICE
void computeFlux( localIndex const iconn,
StackVariables & stack,
@@ -437,22 +1729,22 @@ class FluxComputeKernel : public FluxComputeKernelBase
continue;
}
- real64 const density = m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // r = rho1 || rho2
- real64 const dDens_dP = m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || dr2/dP
+ real64 const density = m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // r = rho1 || rho2
+ real64 const dDens_dP = m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || dr2/dP
// average density and derivatives
- densMean[ip] += density; // rho = (rho1 + rho2)
- dDensMean_dP[ip][ke] = dDens_dP; // drho/dP = { (dr1/dP1) , (dr2/dP2) }
+ densMean[ip] += density; // rho = (rho1 + rho2)
+ dDensMean_dP[ip][ke] = dDens_dP; // drho/dP = { (dr1/dP1) , (dr2/dP2) }
denom++;
}
if( denom > 1 )
{
- densMean[ip] /= denom; // rho = (rho1 + rho2) / denom
+ densMean[ip] /= denom; // rho = (rho1 + rho2) / denom
for( integer ke = 0; ke < 2; ++ke )
{
- dDensMean_dP[ip][ke] /= denom; // drho/dP = { (dr1/dP1) / denom , (dr2/dP2) / denom }
+ dDensMean_dP[ip][ke] /= denom; // drho/dP = { (dr1/dP1) / denom , (dr2/dP2) / denom }
}
}
@@ -471,106 +1763,114 @@ class FluxComputeKernel : public FluxComputeKernelBase
localIndex const esr = sesri[ke];
localIndex const ei = sei[ke];
- real64 const pressure = m_pres[er][esr][ei]; // P = P1 || P2
- presGrad[ip] += trans[ke] * pressure; // DPv = T (P1 - P2)
- dPresGrad_dTrans += signPotDiff[ke] * pressure; // dDPv/dT = (P1 - P2)
- dPresGrad_dP[ip][ke] = trans[ke]; // dDPv/dP = { T , -T }
+ real64 const pressure = m_pres[er][esr][ei]; // P = P1 || P2
+ presGrad[ip] += trans[ke] * pressure; // DPv = T (P1 - P2)
+ dPresGrad_dTrans += signPotDiff[ke] * pressure; // dDPv/dT = (P1 - P2)
+ dPresGrad_dP[ip][ke] = trans[ke]; // dDPv/dP = { T , -T }
- real64 const gravD = trans[ke] * m_gravCoef[er][esr][ei]; // D = T g z1 || -T g z2
- real64 pot = trans[ke] * pressure - densMean[ip] * gravD; // Phi = T P1 - rho T g z1 || -T P2 + rho T g z2
+ real64 const gravD = trans[ke] * m_gravCoef[er][esr][ei]; // D = T g z1 || -T g z2
+ real64 pot = trans[ke] * pressure - densMean[ip] * gravD; // Phi = T P1 - rho T g z1 || -T P2 + rho T g z2
- gravHead[ip] += densMean[ip] * gravD; // DPg = rho (T g z1 - T g z2) = T rho g (z1 - z2)
- dGravHead_dTrans += signPotDiff[ke] * densMean[ip] * m_gravCoef[er][esr][ei]; // dDPg/dT = rho g z1 - rho g z2 = rho g (z1 - z2)
+ gravHead[ip] += densMean[ip] * gravD; // DPg = rho (T g z1 - T g z2) = T rho g (z1 -
+ // z2)
+ dGravHead_dTrans += signPotDiff[ke] * densMean[ip] * m_gravCoef[er][esr][ei]; // dDPg/dT = rho g z1 - rho g z2 = rho g (z1 -
+ // z2)
for( integer i = 0; i < 2; ++i )
{
- dGravHead_dP[ip][i] += dDensMean_dP[ip][i] * gravD; // dDPg/dP = {drho/dP1 * T g (z1 - z2) , drho/dP2 * T g (z1 - z2)}
+ dGravHead_dP[ip][i] += dDensMean_dP[ip][i] * gravD; // dDPg/dP = {drho/dP1 * T g (z1 - z2) , drho/dP2 * T g (z1 - z2)}
}
- if( m_hasCapPressure ) // check sign convention
+ if( m_hasCapPressure ) // check sign convention
{
- real64 const capPres = m_phaseCapPressure[er][esr][ei][0][ip]; // Pc = Pc1 || Pc2
- dCapGrad_dTrans -= signPotDiff[ke] * capPres; // dDPc/dT = (-Pc1 + Pc2)
- pot -= trans[ke] * capPres; // Phi = T P1 - rho T g z1 - T Pc1 || -T P2 + rho T g z2 + T
- // Pc2
- capGrad[ip] -= trans[ke] * capPres; // DPc = T (-Pc1 + Pc2)
+ real64 const capPres = m_phaseCapPressure[er][esr][ei][0][ip]; // Pc = Pc1 || Pc2
+ dCapGrad_dTrans -= signPotDiff[ke] * capPres; // dDPc/dT = (-Pc1 + Pc2)
+ pot -= trans[ke] * capPres; // Phi = T P1 - rho T g z1 - T Pc1 || -T P2 + rho T g z2 + T
+ // Pc2
+ capGrad[ip] -= trans[ke] * capPres; // DPc = T (-Pc1 + Pc2)
}
- potScale = fmax( potScale, fabs( pot ) ); // maxPhi = Phi1 > Phi2 ? Phi1 : Phi2
+ potScale = fmax( potScale, fabs( pot ) ); // maxPhi = Phi1 > Phi2 ? Phi1 : Phi2
}
for( integer ke = 0; ke < 2; ++ke )
{
- dPresGrad_dP[ip][ke] += dTrans_dP[ke] * dPresGrad_dTrans; // dDPv/dP = { T + dT/dP1 * (P1 - P2) , -T + dT/dP2 * (P1 - P2)}
- dGravHead_dP[ip][ke] += dTrans_dP[ke] * dGravHead_dTrans; // dDPg/dP = { drho/dP1 * T g (z1 - z2) + dT/dP1 * rho g (z1 - z2) ,
- // drho/dP2 * T g (z1 - z2) + dT/dP2 * rho g (z1 - z2) }
+ dPresGrad_dP[ip][ke] += dTrans_dP[ke] * dPresGrad_dTrans; // dDPv/dP = { T + dT/dP1 * (P1 - P2) , -T + dT/dP2 * (P1 - P2)}
+ dGravHead_dP[ip][ke] += dTrans_dP[ke] * dGravHead_dTrans; // dDPg/dP = { drho/dP1 * T g (z1 - z2) + dT/dP1 * rho g (z1 - z2)
+ // ,
+ // drho/dP2 * T g (z1 - z2) + dT/dP2 * rho g (z1 - z2)
+ // }
if( m_hasCapPressure )
{
- real64 const dCapPres_dS = m_dPhaseCapPressure_dPhaseVolFrac[seri[ke]][sesri[ke]][sei[ke]][0][ip][ip]; // dPc/dS = dPc1/dS1 ||
- // dPc2/dS2
- dCapGrad_dP[ip][ke] += dTrans_dP[ke] * dCapGrad_dTrans; // dDPc/dP = { dT/dP1 *
- // (-Pc1 + Pc2) ,
- // dT/dP2 *
- // (-Pc1 + Pc2) }
- dCapGrad_dS[ip][ke] -= trans[ke] * dCapPres_dS; // dDPc/dS = { -T *
- // dPc1/dS1 , T *
- // dPc2/dS2 }
+ real64 const dCapPres_dS = m_dPhaseCapPressure_dPhaseVolFrac[seri[ke]][sesri[ke]][sei[ke]][0][ip][ip]; // dPc/dS = dPc1/dS1
+ // ||
+ // dPc2/dS2
+ dCapGrad_dP[ip][ke] += dTrans_dP[ke] * dCapGrad_dTrans; // dDPc/dP = { dT/dP1
+ // *
+ // (-Pc1 + Pc2) ,
+ // dT/dP2
+ // *
+ // (-Pc1 + Pc2) }
+ dCapGrad_dS[ip][ke] -= trans[ke] * dCapPres_dS; // dDPc/dS = { -T *
+ // dPc1/dS1 , T *
+ // dPc2/dS2 }
}
}
// *** upwinding ***
// compute potential gradient
- real64 potGrad = presGrad[ip] - gravHead[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2)
+ real64 potGrad = presGrad[ip] - gravHead[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2)
if( m_hasCapPressure )
{
- potGrad += capGrad[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2) + T (-Pc1 + Pc2)
+ potGrad += capGrad[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2) + T (-Pc1 + Pc2)
}
// compute upwinding tolerance
real64 constexpr upwRelTol = 1e-8;
- real64 const upwAbsTol = fmax( potScale * upwRelTol, LvArray::NumericLimits< real64 >::epsilon ); // abstol = maxPhi * tol > eps ?
- // maxPhi * tol : eps
+ real64 const upwAbsTol = fmax( potScale * upwRelTol, LvArray::NumericLimits< real64 >::epsilon ); // abstol = maxPhi * tol > eps
+ // ?
+ // maxPhi * tol : eps
// decide mobility coefficients - smooth variation in [-upwAbsTol; upwAbsTol]
- real64 const alpha = ( potGrad + upwAbsTol ) / ( 2 * upwAbsTol ); // alpha = (DPhi + abstol) / abstol / 2
+ real64 const alpha = ( potGrad + upwAbsTol ) / ( 2 * upwAbsTol ); // alpha = (DPhi + abstol) / abstol / 2
// choose upstream cell
- if( alpha <= 0.0 || alpha >= 1.0 ) // no smoothing needed
+ if( alpha <= 0.0 || alpha >= 1.0 ) // no smoothing needed
{
- localIndex const k_up = 1 - localIndex( fmax( fmin( alpha, 1.0 ), 0.0 ) ); // 1 upwind -> k_up = 0 || 2 upwind -> k_up = 1
+ localIndex const k_up = 1 - localIndex( fmax( fmin( alpha, 1.0 ), 0.0 ) ); // 1 upwind -> k_up = 0 || 2 upwind -> k_up = 1
- mobility[ip] = m_mob[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // M = Mupstream
- dMob_dP[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dP]; // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2}
- dMob_dS[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dS]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2}
+ mobility[ip] = m_mob[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // M = Mupstream
+ dMob_dP[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dP]; // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2}
+ dMob_dS[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dS]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2}
}
- else // perform smoothing
+ else // perform smoothing
{
real64 const mobWeights[2] = { alpha, 1.0 - alpha };
for( integer ke = 0; ke < 2; ++ke )
{
- mobility[ip] += mobWeights[ke] * m_mob[seri[ke]][sesri[ke]][sei[ke]][ip]; // M = alpha * M1 + (1 - alpha) * M2
- dMob_dP[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dP]; // dM/dP = {alpha * dM1/dP1 , (1 -
- // alpha) * dM2/dP2}
- dMob_dS[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dS]; // dM/dP = {alpha * dM1/dS1 , (1 -
- // alpha) * dM2/dS2}
+ mobility[ip] += mobWeights[ke] * m_mob[seri[ke]][sesri[ke]][sei[ke]][ip]; // M = alpha * M1 + (1 - alpha) * M2
+ dMob_dP[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dP]; // dM/dP = {alpha * dM1/dP1 , (1 -
+ // alpha) * dM2/dP2}
+ dMob_dS[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dS]; // dM/dP = {alpha * dM1/dS1 , (1 -
+ // alpha) * dM2/dS2}
}
}
// pressure gradient depends on all points in the stencil
for( integer ke = 0; ke < 2; ++ke )
{
- dFlux_dP[ip][ke] += dPresGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) ,
- // -T + dT/dP2 * (P1 - P2) }
+ dFlux_dP[ip][ke] += dPresGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) ,
+ // -T + dT/dP2 * (P1 - P2) }
}
// gravitational head depends only on the two cells connected (same as mean density)
for( integer ke = 0; ke < 2; ++ke )
{
- dFlux_dP[ip][ke] -= dGravHead_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 -
- // z2) ,
- // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 -
- // z2) }
+ dFlux_dP[ip][ke] -= dGravHead_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 -
+ // z2) ,
+ // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 -
+ // z2) }
}
// capillary pressure contribution
@@ -578,38 +1878,38 @@ class FluxComputeKernel : public FluxComputeKernelBase
{
for( integer ke = 0; ke < 2; ++ke )
{
- dFlux_dP[ip][ke] += dCapGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1
- // - z2) + dT/dP1 * (-Pc1 + Pc2) ,
- // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1
- // - z2) + dT/dP2 * (-Pc1 + Pc2) }
+ dFlux_dP[ip][ke] += dCapGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1
+ // - z2) + dT/dP1 * (-Pc1 + Pc2) ,
+ // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1
+ // - z2) + dT/dP2 * (-Pc1 + Pc2) }
- dFlux_dS[ip][ke] += dCapGrad_dS[ip][ke]; // dF/dS = { T * -dPc/dS1 , T * dPc/dS2 }
+ dFlux_dS[ip][ke] += dCapGrad_dS[ip][ke]; // dF/dS = { T * -dPc/dS1 , T * dPc/dS2 }
}
}
// compute the flux and derivatives using upstream cell mobility
- fluxVal[ip] = mobility[ip] * potGrad; // F = M * DPhi
+ fluxVal[ip] = mobility[ip] * potGrad; // F = M * DPhi
for( integer ke = 0; ke < 2; ++ke )
{
- dFlux_dP[ip][ke] *= mobility[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 -
- // z2) + dT/dP1 * (-Pc1 + Pc2)] ,
- // M [-T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 -
- // z2) + dT/dP2 * (-Pc1 + Pc2)] }
+ dFlux_dP[ip][ke] *= mobility[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 -
+ // z2) + dT/dP1 * (-Pc1 + Pc2)] ,
+ // M [-T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 -
+ // z2) + dT/dP2 * (-Pc1 + Pc2)] }
- dFlux_dS[ip][ke] *= mobility[ip]; // dF/dS = { M [T * -dPc/dS1] , M [T * dPc/dS2] }
+ dFlux_dS[ip][ke] *= mobility[ip]; // dF/dS = { M [T * -dPc/dS1] , M [T * dPc/dS2] }
}
// add contribution from upstream cell mobility derivatives
for( integer ke = 0; ke < 2; ++ke )
{
- dFlux_dP[ip][ke] += dMob_dP[ip][ke] * potGrad; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 *
- // rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] + dM/dP1 * DPhi ,
- // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 *
- // rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi }
+ dFlux_dP[ip][ke] += dMob_dP[ip][ke] * potGrad; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 *
+ // rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] + dM/dP1 * DPhi ,
+ // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 *
+ // rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi }
- dFlux_dS[ip][ke] += dMob_dS[ip][ke] * potGrad; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi
- // }
+ dFlux_dS[ip][ke] += dMob_dS[ip][ke] * potGrad; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi
+ // }
}
// populate local flux vector and derivatives
@@ -630,14 +1930,14 @@ class FluxComputeKernel : public FluxComputeKernelBase
}
// Customize the kernel with this lambda
- kernelOp( k, seri, sesri, sei, connectionIndex, alpha, mobility, potGrad, fluxVal, dFlux_dP, dFlux_dS ); // Not sure what this
- // does
+ kernelOp( k, seri, sesri, sei, connectionIndex, alpha, mobility, potGrad, fluxVal, dFlux_dP, dFlux_dS ); // Not sure what this
+ // does
- } // loop over phases
+ } // loop over phases
connectionIndex++;
}
- } // loop over connection elements
+ } // loop over connection elements
}
/**
@@ -645,7 +1945,7 @@ class FluxComputeKernel : public FluxComputeKernelBase
* @param[in] iconn the connection index
* @param[inout] stack the stack variables
*/
- template< typename FUNC = NoOpFunc > // should change to multiphase
+ template< typename FUNC = NoOpFunc > // should change to multiphase
GEOS_HOST_DEVICE
void complete( localIndex const iconn,
StackVariables & stack,
@@ -732,6 +2032,619 @@ class FluxComputeKernel : public FluxComputeKernelBase
};
+/**
+ * @class FaceBasedAssemblyInterfaceConditionKernel
+ * @tparam NUM_DOF number of degrees of freedom
+ * @tparam STENCILWRAPPER the type of the stencil wrapper
+ * @tparam CAPPRESWRAPPER the type of the capillary pressure wrapper
+ * @tparam RELPERMWRAPPER the type of the realtive permeability wrapper
+ * @brief Define the interface for the assembly kernel in charge of flux terms
+ */
+// template< integer NUM_EQN, integer NUM_DOF, typename STENCILWRAPPER, typename CAPPRESWRAPPER, typename RELPERMWRAPPER >
+template< integer NUM_EQN, integer NUM_DOF, typename STENCILWRAPPER >
+class FluxComputeInterfaceConditionKernel : public FluxComputeKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER >
+{
+public:
+
+ using AbstractBase = FluxComputeKernelBase;
+ using DofNumberAccessor = AbstractBase::DofNumberAccessor;
+ using ImmiscibleMultiphaseFlowAccessors = AbstractBase::ImmiscibleMultiphaseFlowAccessors;
+ using MultiphaseFluidAccessors = AbstractBase::MultiphaseFluidAccessors;
+ using CapPressureAccessors = AbstractBase::CapPressureAccessors;
+ using PermeabilityAccessors = AbstractBase::PermeabilityAccessors;
+
+ using Base = FluxComputeKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER >;
+ using Deriv = typename Base::Deriv;
+ using StackVariables = typename Base::StackVariables;
+ using Base::numEqn;
+ using Base::numDof;
+ using Base::m_stencilWrapper;
+ using Base::m_dofNumber;
+ using Base::m_rankOffset;
+ using Base::m_localMatrix;
+ using Base::m_localRhs;
+ using Base::m_numPhases;
+ using Base::m_permeability;
+ using Base::m_dPerm_dPres;
+ using Base::m_phaseVolFrac;
+ using Base::m_phaseMass_n;
+ using Base::m_phaseCapPressure;
+ // using Base::m_jFuncMultiplier;
+ using Base::m_dPhaseCapPressure_dPhaseVolFrac;
+ using Base::m_dens;
+ using Base::m_dDens_dPres;
+ using Base::m_visc;
+ using Base::m_dVisc_dPres;
+ using Base::m_dMob;
+ using Base::m_mob;
+ using Base::m_gravCoef;
+ using Base::m_ghostRank;
+ using Base::m_dt;
+ using Base::m_hasCapPressure;
+ using Base::m_useTotalMassEquation;
+ using Base::m_checkPhasePresenceInGravity;
+ using Base::m_seri;
+ using Base::m_sesri;
+ using Base::m_sei;
+ using Base::m_pres;
+
+ /**
+ * @brief Constructor for the kernel interface
+ * @param[in] numPhases number of fluid phases
+ * @param[in] rankOffset the offset of my MPI rank
+ * @param[in] stencilWrapper reference to the stencil wrapper
+ * @param[in] capPressureWrapper reference to the capillary pressure wrapper
+ * @param[in] dofNumberAccessor
+ * @param[in] multiPhaseFlowAccessors
+ * @param[in] fluidAccessors
+ * @param[in] capPressureAccessors
+ * @param[in] permeabilityAccessors
+ * @param[in] dt time step size
+ * @param[inout] localMatrix the local CRS matrix
+ * @param[inout] localRhs the local right-hand side vector
+ * @param[in] hasCapPressure flags for capillary pressure
+ * @param[in] useTotalMassEquation flags for using total velocity formulation
+ */
+ FluxComputeInterfaceConditionKernel( integer const numPhases,
+ globalIndex const rankOffset,
+ STENCILWRAPPER const & stencilWrapper,
+ // CAPPRESWRAPPER const & capPressureWrapper,
+ // RELPERMWRAPPER const & relPermWrapper,
+ DofNumberAccessor const & dofNumberAccessor,
+ ImmiscibleMultiphaseFlowAccessors const & multiPhaseFlowAccessors,
+ MultiphaseFluidAccessors const & fluidAccessors,
+ CapPressureAccessors const & capPressureAccessors,
+ PermeabilityAccessors const & permeabilityAccessors,
+ real64 const & dt,
+ CRSMatrixView< real64, globalIndex const > const & localMatrix,
+ arrayView1d< real64 > const & localRhs,
+ integer const hasCapPressure,
+ integer const useTotalMassEquation,
+ integer const checkPhasePresenceInGravity,
+ string_array const & interfaceFaceSetNames,
+ stdVector< std::array< std::tuple< constitutive::RelativePermeabilityBase *,
+ constitutive::CapillaryPressureBase *,
+ constitutive::TwoPhaseImmiscibleFluid * >, 2 > > const & interfaceConstitutivePairs,
+ unordered_map< localIndex, localIndex > const & interfaceRegionByConnector,
+ // std::tuple< constitutive::RelativePermeabilityBase *,
+ // constitutive::CapillaryPressureBase *,
+ // constitutive::TwoPhaseImmiscibleFluid * > const & interfaceConstitutivePairs_temp,
+ localIndex const GEOS_UNUSED_PARAM( domainSize ) )
+ : Base( numPhases,
+ rankOffset,
+ stencilWrapper,
+ dofNumberAccessor,
+ multiPhaseFlowAccessors,
+ fluidAccessors,
+ capPressureAccessors,
+ permeabilityAccessors,
+ dt,
+ localMatrix,
+ localRhs,
+ hasCapPressure,
+ useTotalMassEquation,
+ checkPhasePresenceInGravity ),
+ // m_capPressureWrapper( capPressureWrapper ),
+ // m_relPermWrapper( relPermWrapper ),
+ m_interfaceFaceSetNames( interfaceFaceSetNames ),
+ m_interfaceConstitutivePairs( interfaceConstitutivePairs ),
+ m_interfaceRegionByConnector( interfaceRegionByConnector )
+ // ,
+ // m_interfaceConstitutivePairs_temp( interfaceConstitutivePairs_temp )
+ {}
+
+ /**
+ * @brief Compute the local flux contributions to the residual and Jacobian
+ * @tparam FUNC the type of the function that can be used to customize the computation of the flux
+ * @param[in] iconn the connection index
+ * @param[inout] stack the stack variables
+ * @param[in] NoOpFunc the function used to customize the computation of the flux
+ */
+
+ template< typename FUNC = NoOpFunc > // should change to multiphase
+ GEOS_HOST_DEVICE
+ void computeFlux( localIndex const iconn,
+ StackVariables & stack,
+ FUNC && kernelOp = NoOpFunc{} ) const
+ {
+
+ bool connectorHasInterfaceConditionQ = false;
+ bool anyInterfaceConditionsQ = not m_interfaceConstitutivePairs.empty();
+ if( anyInterfaceConditionsQ )
+ {
+ connectorHasInterfaceConditionQ =
+ m_interfaceRegionByConnector.find( iconn ) != m_interfaceRegionByConnector.end();
+ }
+
+
+
+ // if (connectorHasInterfaceConditionQ){
+ // // Improved transmission conditions
+ // int ammar_code = 0;
+ // }else{
+ // // Regular contribution
+ // int standard_code = 0;
+ // }
+
+ m_stencilWrapper.computeWeights( iconn,
+ m_permeability,
+ m_dPerm_dPres,
+ stack.transmissibility,
+ stack.dTrans_dPres );
+
+ localIndex k[2];
+ localIndex connectionIndex = 0;
+
+ // one-sided transmissibility
+ m_stencilWrapper.computeHalfWeights( iconn,
+ m_permeability,
+ m_dPerm_dPres,
+ stack.transmissibilityHat,
+ stack.dTransHat_dPres );
+
+
+
+ for( k[0] = 0; k[0] < stack.numFluxElems; ++k[0] )
+ {
+ for( k[1] = k[0] + 1; k[1] < stack.numFluxElems; ++k[1] )
+ {
+ // clear working arrays
+ real64 densMean[numEqn]{};
+ real64 dDensMean_dP[numEqn][2]{};
+
+ real64 presGrad[numEqn]{};
+ real64 dPresGrad_dP[numEqn][2]{};
+
+ real64 gravHead[numEqn]{};
+ real64 dGravHead_dP[numEqn][2]{};
+
+ real64 capGrad[numEqn]{};
+ // real64 capPresIC[numEqn][2]{};
+ // real64 jFMultiplier[numEqn][2]{};
+ real64 dCapGrad_dP[numEqn][2]{};
+ real64 dCapGrad_dS[numEqn][2]{};
+
+ real64 fluxVal[numEqn]{};
+ real64 dFlux_dP[numEqn][2]{};
+ real64 dFlux_dS[numEqn][2]{};
+
+ real64 mobility[numEqn]{};
+ real64 dMob_dP[numEqn][2]{};
+ real64 dMob_dS[numEqn][2]{};
+
+ real64 density2[numEqn]{};
+ real64 dDens_dP2[numEqn][2]{};
+ real64 viscosity[numEqn]{};
+ real64 dVisc_dP[numEqn][2]{};
+ real64 gravCoef2[numEqn]{};
+ real64 gravCoefHat[numEqn]{};
+
+ real64 uT = 0;
+ // real64 total_mobility = 0;
+ real64 duT_dP[numEqn]{};
+ real64 duT_dS[numEqn]{};
+
+ real64 potGrad_ip[numEqn]{};
+ real64 alpha_ip[numEqn]{};
+
+ real64 const trans[2] = { stack.transmissibility[connectionIndex][0], stack.transmissibility[connectionIndex][1] };
+ real64 const dTrans_dP[2] = { stack.dTrans_dPres[connectionIndex][0], stack.dTrans_dPres[connectionIndex][1] };
+
+ real64 const transHat[2] = { stack.transmissibilityHat[connectionIndex][0], stack.transmissibilityHat[connectionIndex][1] * -1.0};
+ real64 const dTransHat_dP[2] = { stack.dTransHat_dPres[connectionIndex][0], stack.dTransHat_dPres[connectionIndex][1] * -1.0};
+
+ // cell indices
+ localIndex const seri[2] = {m_seri( iconn, k[0] ), m_seri( iconn, k[1] )};
+ localIndex const sesri[2] = {m_sesri( iconn, k[0] ), m_sesri( iconn, k[1] )};
+ localIndex const sei[2] = {m_sei( iconn, k[0] ), m_sei( iconn, k[1] )};
+
+ stdVector< real64 > saturations = {m_phaseVolFrac[seri[0]][sesri[0]][sei[0]][0], m_phaseVolFrac[seri[1]][sesri[1]][sei[1]][0] };
+ stdVector< real64 > pressures = {m_pres[seri[0]][sesri[0]][sei[0]], m_pres[seri[1]][sesri[1]][sei[1]] };
+ // bool isJfunction = 0;
+
+ // loop over phases
+ for( integer ip = 0; ip < m_numPhases; ++ip )
+ {
+ // calculate quantities on primary connected cells
+ integer denom = 0;
+ for( integer ke = 0; ke < 2; ++ke )
+ {
+ // density
+ bool const phaseExists = (m_phaseVolFrac[seri[ke]][sesri[ke]][sei[ke]][ip] > 0);
+ if( m_checkPhasePresenceInGravity && !phaseExists )
+ {
+ continue;
+ }
+
+ real64 const density = m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // r = rho1 || rho2
+ real64 const dDens_dP = m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || dr2/dP
+ // average density and derivatives
+ densMean[ip] += density; // rho = (rho1 + rho2)
+ dDensMean_dP[ip][ke] = dDens_dP; // drho/dP = { (dr1/dP1) , (dr2/dP2) }
+ denom++;
+ }
+
+ if( denom > 1 )
+ {
+ densMean[ip] /= denom; // rho = (rho1 + rho2) / denom
+ for( integer ke = 0; ke < 2; ++ke )
+ {
+ dDensMean_dP[ip][ke] /= denom; // drho/dP = { (dr1/dP1) / denom , (dr2/dP2) / denom }
+ }
+ }
+
+ //***** calculation of flux *****
+
+ // compute potential difference
+ real64 potScale = 0.0;
+ real64 dPresGrad_dTrans = 0.0;
+ real64 dGravHead_dTrans = 0.0;
+ real64 dCapGrad_dTrans = 0.0;
+ gravCoefHat[0] = 0;
+ gravCoefHat[1] = 0;
+ constexpr int signPotDiff[2] = {1, -1};
+
+ for( integer ke = 0; ke < 2; ++ke )
+ {
+ localIndex const er = seri[ke];
+ localIndex const esr = sesri[ke];
+ localIndex const ei = sei[ke];
+
+ real64 const pressure = m_pres[er][esr][ei]; // P = P1 || P2
+ presGrad[ip] += trans[ke] * pressure; // DPv = T (P1 - P2)
+ dPresGrad_dTrans += signPotDiff[ke] * pressure; // dDPv/dT = (P1 - P2)
+ dPresGrad_dP[ip][ke] = trans[ke]; // dDPv/dP = { T , -T }
+
+ real64 const gravD = trans[ke] * m_gravCoef[er][esr][ei]; // D = T g z1 || -T g z2
+ real64 pot = trans[ke] * pressure - densMean[ip] * gravD; // Phi = T P1 - rho T g z1 || -T P2 + rho T g z2
+ gravCoefHat[0] += m_gravCoef[er][esr][ei] * 0.5;
+ gravCoefHat[1] += m_gravCoef[er][esr][ei] * 0.5;
+
+ gravCoef2[ke] = m_gravCoef[er][esr][ei];
+
+ gravHead[ip] += densMean[ip] * gravD; // DPg = rho (T g z1 - T g z2) = T rho g (z1 - z2)
+ dGravHead_dTrans += signPotDiff[ke] * densMean[ip] * m_gravCoef[er][esr][ei]; // dDPg/dT = rho g z1 - rho g z2 = rho g (z1 - z2)
+
+ for( integer i = 0; i < 2; ++i )
+ {
+ dGravHead_dP[ip][i] += dDensMean_dP[ip][i] * gravD; // dDPg/dP = {drho/dP1 * T g (z1 - z2) , drho/dP2 * T g (z1 - z2)}
+ }
+
+ if( m_hasCapPressure ) // check sign convention
+ {
+ real64 const capPres = m_phaseCapPressure[er][esr][ei][0][ip]; // Pc = Pc1 || Pc2
+ // jFMultiplier[ip][ke] = m_jFuncMultiplier[er][esr][ei][0];
+
+ // capPresIC[ip][ke] = capPres;
+ dCapGrad_dTrans -= signPotDiff[ke] * capPres; // dDPc/dT = (-Pc1 + Pc2)
+ pot -= trans[ke] * capPres; // Phi = T P1 - rho T g z1 - T Pc1 || -T P2 + rho T g z2 + T
+ // Pc2
+ capGrad[ip] -= trans[ke] * capPres; // DPc = T (-Pc1 + Pc2)
+ }
+
+ potScale = fmax( potScale, fabs( pot ) ); // maxPhi = Phi1 > Phi2 ? Phi1 : Phi2
+ }
+
+
+ for( integer ke = 0; ke < 2; ++ke )
+ {
+ dPresGrad_dP[ip][ke] += dTrans_dP[ke] * dPresGrad_dTrans; // dDPv/dP = { T + dT/dP1 * (P1 - P2) , -T + dT/dP2 * (P1 - P2)}
+ dGravHead_dP[ip][ke] += dTrans_dP[ke] * dGravHead_dTrans; // dDPg/dP = { drho/dP1 * T g (z1 - z2) + dT/dP1 * rho g (z1 - z2) ,
+ // drho/dP2 * T g (z1 - z2) + dT/dP2 * rho g (z1 - z2) }
+ if( m_hasCapPressure )
+ {
+ real64 const dCapPres_dS = m_dPhaseCapPressure_dPhaseVolFrac[seri[ke]][sesri[ke]][sei[ke]][0][ip][ip]; // dPc/dS = dPc1/dS1 ||
+ // dPc2/dS2
+ dCapGrad_dP[ip][ke] += dTrans_dP[ke] * dCapGrad_dTrans; // dDPc/dP = { dT/dP1 *
+ // (-Pc1 + Pc2) ,
+ // dT/dP2 *
+ // (-Pc1 + Pc2) }
+ dCapGrad_dS[ip][ke] -= trans[ke] * dCapPres_dS; // dDPc/dS = { -T *
+ // dPc1/dS1 , T *
+ // dPc2/dS2 }
+ }
+ }
+
+ // *** upwinding ***
+ // compute potential gradient
+ real64 potGrad = presGrad[ip] - gravHead[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2)
+ if( m_hasCapPressure )
+ {
+ potGrad += capGrad[ip]; // DPhi = T (P1 - P2) - T rho g (z1 - z2) + T (-Pc1 + Pc2)
+ }
+
+ // compute upwinding tolerance
+ real64 constexpr upwRelTol = 1e-8;
+ real64 const upwAbsTol = fmax( potScale * upwRelTol, LvArray::NumericLimits< real64 >::epsilon ); // abstol = maxPhi * tol > eps ?
+ // maxPhi * tol : eps
+
+ // decide mobility coefficients - smooth variation in [-upwAbsTol; upwAbsTol]
+ real64 alpha = ( potGrad + upwAbsTol ) / ( 2 * upwAbsTol ); // alpha = (DPhi + abstol) / abstol / 2
+
+ // choose upstream cell
+ if( alpha <= 0.0 || alpha >= 1.0 ) // no smoothing needed
+ {
+ localIndex const k_up = 1 - localIndex( fmax( fmin( alpha, 1.0 ), 0.0 ) ); // 1 upwind -> k_up = 0 || 2 upwind -> k_up = 1
+
+ mobility[ip] = m_mob[seri[k_up]][sesri[k_up]][sei[k_up]][ip]; // M = Mupstream
+ density2[ip] = m_dens[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip]; // r = rho1 || rho2
+ dDens_dP2[ip][k_up] = m_dDens_dPres[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 || dr2/dP
+ viscosity[ip] = m_visc[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip];
+ dVisc_dP[ip][k_up] = m_dVisc_dPres[seri[k_up]][sesri[k_up]][sei[k_up]][0][ip][Deriv::dP];
+ dMob_dP[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dP]; // dM/dP = {dM/dP1 , 0} OR {0 , dM/dP2}
+ dMob_dS[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dS]; // dM/dS = {dM/dS1 , 0} OR {0 , dM/dS2}
+ }
+ else // perform smoothing
+ {
+ real64 const mobWeights[2] = { alpha, 1.0 - alpha };
+ for( integer ke = 0; ke < 2; ++ke )
+ {
+ mobility[ip] += mobWeights[ke] * m_mob[seri[ke]][sesri[ke]][sei[ke]][ip]; // M = alpha * M1 + (1 - alpha) * M2
+ density2[ip] += mobWeights[ke] * m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip]; // r = rho1 || rho2
+ dDens_dP2[ip][ke] = mobWeights[ke] * m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP]; // dr/dP = dr1/dP1 ||
+ // dr2/dP
+ viscosity[ip] = m_visc[seri[ke]][sesri[ke]][sei[ke]][0][ip];
+ dVisc_dP[ip][ke] = m_dVisc_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP];
+ dMob_dP[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dP]; // dM/dP = {alpha * dM1/dP1 , (1 -
+ // alpha) * dM2/dP2}
+ dMob_dS[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dS]; // dM/dP = {alpha * dM1/dS1 , (1 -
+ // alpha) * dM2/dS2}
+ }
+ }
+
+ // pressure gradient depends on all points in the stencil
+ for( integer ke = 0; ke < 2; ++ke )
+ {
+ dFlux_dP[ip][ke] += dPresGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) ,
+ // -T + dT/dP2 * (P1 - P2) }
+ }
+
+ // gravitational head depends only on the two cells connected (same as mean density)
+ for( integer ke = 0; ke < 2; ++ke )
+ {
+ dFlux_dP[ip][ke] -= dGravHead_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 -
+ // z2) ,
+ // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 -
+ // z2) }
+ }
+
+ // capillary pressure contribution
+ if( m_hasCapPressure )
+ {
+ for( integer ke = 0; ke < 2; ++ke )
+ {
+ dFlux_dP[ip][ke] += dCapGrad_dP[ip][ke]; // dF/dP = { T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1
+ // - z2) + dT/dP1 * (-Pc1 + Pc2) ,
+ // -T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1
+ // - z2) + dT/dP2 * (-Pc1 + Pc2) }
+
+ dFlux_dS[ip][ke] += dCapGrad_dS[ip][ke]; // dF/dS = { T * -dPc/dS1 , T * dPc/dS2 }
+ }
+ }
+
+ // compute the flux and derivatives using upstream cell mobility
+ fluxVal[ip] = mobility[ip] * potGrad; // F = M * DPhi
+
+ for( integer ke = 0; ke < 2; ++ke )
+ {
+ dFlux_dP[ip][ke] *= mobility[ip]; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho/dP1 * T g (z1 - z2) - dT/dP1 * rho g (z1 -
+ // z2) + dT/dP1 * (-Pc1 + Pc2)] ,
+ // M [-T + dT/dP2 * (P1 - P2) - drho/dP2 * T g (z1 - z2) - dT/dP2 * rho g (z1 -
+ // z2) + dT/dP2 * (-Pc1 + Pc2)] }
+
+ dFlux_dS[ip][ke] *= mobility[ip]; // dF/dS = { M [T * -dPc/dS1] , M [T * dPc/dS2] }
+ }
+
+ // add contribution from upstream cell mobility derivatives
+ for( integer ke = 0; ke < 2; ++ke )
+ {
+
+ real64 dMob_dP2 = mobility[ip] / density2[ip] * (-dVisc_dP[ip][ke] / viscosity[ip]);
+
+ duT_dP[ke] += dFlux_dP[ip][ke] / density2[ip] + dMob_dP2 * potGrad;
+
+ dFlux_dP[ip][ke] += dMob_dP[ip][ke] * potGrad; // dF/dP = { M [ T + dT/dP1 * (P1 - P2) - drho1/dP * T g (z1 - z2) - dT/dP1 *
+ // rho g (z1 - z2) + dT/dP1 * (-Pc1 + Pc2)] + dM/dP1 * DPhi ,
+ // M [-T + dT/dP2 * (P1 - P2) - drho2/dP * T g (z1 - z2) - dT/dP2 *
+ // rho g (z1 - z2) + dT/dP2 * (-Pc1 + Pc2)] + dM/dP2 * DPhi }
+ dFlux_dS[ip][ke] += dMob_dS[ip][ke] * potGrad; // dF/dS = { M [T * -dPc/dS1] + dM/dS1 * DPhi , M [T * dPc/dS2] + dM/dS2 * DPhi
+ // }
+ }
+
+
+ uT += fluxVal[ip] / density2[ip];
+
+ // add contribution from upstream cell mobility derivatives
+ for( integer ke = 0; ke < 2; ++ke )
+ {
+// duT_dP[ke] += dFlux_dP[ip][ke] - fluxVal[ip] * dDens_dP2[ip][ke] / density2[ip];
+// // duT_dP[ke] += dFlux_dP[ip][ke];
+
+// duT_dP[ke] /= density2[ip];
+
+ duT_dS[ke] += dFlux_dS[ip][ke] / density2[ip];
+ // duT_dS[ke] += dFlux_dS[ip][ke];
+
+ }
+
+ potGrad_ip[ip] = potGrad;
+ alpha_ip[ip] = alpha;
+
+ } // loop over phases
+
+
+ // this determines whether the local solver is needed becuase of heterogeneous capillary pressure regions
+ // bool notOnInterface = std::fabs( jFMultiplier[0][0] - jFMultiplier[0][1] ) < 1 && std::fabs( jFMultiplier[1][0] -
+ // jFMultiplier[1][1] ) < 1;
+ bool notOnInterface = !connectorHasInterfaceConditionQ;
+ if( notOnInterface )
+ {
+ for( integer ip = 0; ip < 2; ++ip )
+ {
+ // populate local flux vector and derivatives
+ stack.localFlux[k[0]*numEqn + ip] += m_dt * fluxVal[ip];
+ stack.localFlux[k[1]*numEqn + ip] -= m_dt * fluxVal[ip];
+
+ for( integer ke = 0; ke < 2; ++ke )
+ {
+ // pressure
+ localIndex const localDofIndexPres = k[ke] * numDof;
+ stack.localFluxJacobian[k[0]*numEqn + ip][localDofIndexPres] += m_dt * dFlux_dP[ip][ke];
+ stack.localFluxJacobian[k[1]*numEqn + ip][localDofIndexPres] -= m_dt * dFlux_dP[ip][ke];
+
+ // saturation
+ localIndex const localDofIndexSat = k[ke] * numDof + 1;
+ stack.localFluxJacobian[k[0]*numEqn + ip][localDofIndexSat] += m_dt * dFlux_dS[ip][ke];
+ stack.localFluxJacobian[k[1]*numEqn + ip][localDofIndexSat] -= m_dt * dFlux_dS[ip][ke];
+ }
+
+ // Customize the kernel with this lambda
+ kernelOp( k, seri, sesri, sei, connectionIndex, alpha_ip[ip], mobility, potGrad_ip[ip], fluxVal, dFlux_dP, dFlux_dS );
+
+ }
+ }
+ else
+ {
+
+
+ bool converged = 0;
+
+
+ // clear working arrays
+ real64 halfFluxVal[numEqn][2]{};
+ // real64 dhalfFlux1_dP[numEqn][2]{};
+ // real64 dhalfFlux1_dS[numEqn][2]{};
+ // real64 dhalfFlux2_dP[numEqn][2]{};
+ // real64 dhalfFlux2_dS[numEqn][2]{};
+ // real64 dhalfFlux_duT[numEqn][2]{};
+ // real64 dhalfFlux_dpc[numEqn][2]{};
+
+
+ // stdVector< real64 > JFMultipliers = {jFMultiplier[0][0], jFMultiplier[0][1]};
+ stdVector< real64 > JFMultipliers = {0.0, 0.0};
+ stdVector< real64 > trappedSats1 = {0.0, 0.0};
+ stdVector< real64 > trappedSats2 = {0.0, 0.0};
+ stdVector< real64 > transHats = {transHat[0], transHat[1]};
+ stdVector< real64 > dTransHats_dP = {dTransHat_dP[0], dTransHat_dP[1]};
+ stdVector< real64 > gravCoefHats = {gravCoefHat[0], gravCoefHat[1]};
+ stdVector< real64 > gravCoefs = {gravCoef2[0], gravCoef2[1]};
+ stdVector< real64 > cellCenterDuTdS = {duT_dP[0], duT_dP[1], duT_dS[0], duT_dS[1]};
+ stdVector< real64 > cellCenterDens = {density2[0], density2[1]};
+ stdVector< real64 > cellCenterDens_dP = {dDens_dP2[0][0], dDens_dP2[0][1], dDens_dP2[1][0], dDens_dP2[1][1]};
+ // std::vector< RelativePermeabilityBase * > relPerms = {std::get< 0 >( m_interfaceConstitutivePairs_temp ), std::get< 0 >(
+ // m_interfaceConstitutivePairs_temp )};
+ // std::vector< CapillaryPressureBase * > capPressures = {std::get< 1 >( m_interfaceConstitutivePairs_temp ), std::get< 1 >(
+ // m_interfaceConstitutivePairs_temp )};
+ // std::vector< TwoPhaseImmiscibleFluid * > fluids = {std::get< 2 >( m_interfaceConstitutivePairs_temp ), std::get< 2 >(
+ // m_interfaceConstitutivePairs_temp )};
+
+ // auto const & pairArray = m_interfaceConstitutivePairs[0];
+ localIndex const surfaceRegionIndex = m_interfaceRegionByConnector.at( iconn );
+ auto const & pairArray = m_interfaceConstitutivePairs[surfaceRegionIndex];
+
+ std::vector< constitutive::RelativePermeabilityBase * > relPerms = {
+ std::get< 0 >( pairArray[0] ),
+ std::get< 0 >( pairArray[1] )
+ };
+
+ std::vector< constitutive::CapillaryPressureBase * > capPressures = {
+ std::get< 1 >( pairArray[0] ),
+ std::get< 1 >( pairArray[1] )
+ };
+
+ std::vector< constitutive::TwoPhaseImmiscibleFluid * > fluids = {
+ std::get< 2 >( pairArray[0] ),
+ std::get< 2 >( pairArray[1] )
+ };
+
+ stdVector< real64 > phi = {halfFluxVal[0][0], halfFluxVal[0][1]};
+ stdVector< real64 > grad_phi_P = {0.0, 0.0, 0.0, 0.0};
+ stdVector< real64 > grad_phi_S = {0.0, 0.0, 0.0, 0.0};
+
+ local_solver( uT, saturations, pressures, JFMultipliers, trappedSats1, trappedSats2, transHats, dTransHats_dP, gravCoefHats, gravCoefs,
+ cellCenterDuTdS, cellCenterDens, cellCenterDens_dP, relPerms, capPressures, fluids, phi, grad_phi_P, grad_phi_S, converged );
+
+
+ fluxVal[0] = phi[0];
+ fluxVal[1] = phi[1];
+ dFlux_dP[0][0] = grad_phi_P[0];
+ dFlux_dP[0][1] = grad_phi_P[1];
+ dFlux_dP[1][0] = grad_phi_P[2];
+ dFlux_dP[1][1] = grad_phi_P[3];
+ dFlux_dS[0][0] = grad_phi_S[0];
+ dFlux_dS[0][1] = grad_phi_S[1];
+ dFlux_dS[1][0] = grad_phi_S[2];
+ dFlux_dS[1][1] = grad_phi_S[3];
+
+ // Global residual and jacobian update:
+ for( integer ip = 0; ip < m_numPhases; ++ip )
+ {
+ // populate local flux vector and derivatives
+ stack.localFlux[k[0]*numEqn + ip] += m_dt * fluxVal[ip];
+ stack.localFlux[k[1]*numEqn + ip] -= m_dt * fluxVal[ip];
+
+ for( integer ke = 0; ke < 2; ++ke )
+ {
+ // pressure
+ localIndex const localDofIndexPres = k[ke] * numDof;
+ stack.localFluxJacobian[k[0]*numEqn + ip][localDofIndexPres] += m_dt * dFlux_dP[ip][ke];
+ stack.localFluxJacobian[k[1]*numEqn + ip][localDofIndexPres] -= m_dt * dFlux_dP[ip][ke];
+
+ // saturation
+ localIndex const localDofIndexSat = k[ke] * numDof + 1;
+ stack.localFluxJacobian[k[0]*numEqn + ip][localDofIndexSat] += m_dt * dFlux_dS[ip][ke];
+ stack.localFluxJacobian[k[1]*numEqn + ip][localDofIndexSat] -= m_dt * dFlux_dS[ip][ke];
+ }
+
+ // Customize the kernel with this lambda
+ kernelOp( k, seri, sesri, sei, connectionIndex, alpha_ip[ip], mobility, potGrad_ip[ip], fluxVal, dFlux_dP, dFlux_dS );
+
+ } // loop over phases
+ } // end of else for interface conditions
+
+ connectionIndex++;
+ }
+ } // loop over connection elements
+ }
+
+protected:
+
+ /// Reference to the capillary pressure wrapper
+ // CAPPRESWRAPPER const m_capPressureWrapper;
+ // RELPERMWRAPPER const m_relPermWrapper;
+ string_array const m_interfaceFaceSetNames;
+ stdVector< std::array< std::tuple< constitutive::RelativePermeabilityBase *,
+ constitutive::CapillaryPressureBase *,
+ constitutive::TwoPhaseImmiscibleFluid * >, 2 > > const m_interfaceConstitutivePairs;
+ unordered_map< localIndex, localIndex > const m_interfaceRegionByConnector;
+ // std::tuple< constitutive::RelativePermeabilityBase *,
+ // constitutive::CapillaryPressureBase *,
+ // constitutive::TwoPhaseImmiscibleFluid * > const m_interfaceConstitutivePairs_temp;
+
+};
+
+
+
/****************************************** */
/**
@@ -788,6 +2701,74 @@ class FluxComputeKernelFactory
checkPhasePresenceInGravity );
kernelType::template launch< POLICY >( stencilWrapper.size(), kernel );
}
+
+ /**
+ * @brief Create a new kernel and launch
+ * @tparam POLICY the policy used in the RAJA kernel
+ * @tparam STENCILWRAPPER the type of the stencil wrapper
+ * @tparam CAPPRESWRAPPER the type of the capillary pressure wrapper
+ * @param[in] rankOffset the offset of my MPI rank
+ * @param[in] dofKey string to get the element degrees of freedom numbers
+ * @param[in] solverName name of the solver (to name accessors)
+ * @param[in] elemManager reference to the element region manager
+ * @param[in] stencilWrapper reference to the stencil wrapper
+ * @param[in] capPresWrapper reference to the capillary pressure wrapper
+ * @param[in] dt time step size
+ * @param[inout] localMatrix the local CRS matrix
+ * @param[inout] localRhs the local right-hand side vector
+ */
+ // template< typename POLICY, typename STENCILWRAPPER, typename CAPPRESWRAPPER, typename RELPERMWRAPPER >
+ template< typename POLICY, typename STENCILWRAPPER >
+ static void
+ createAndLaunch( integer const numPhases,
+ globalIndex const rankOffset,
+ string const & dofKey,
+ integer const hasCapPressure,
+ integer const useTotalMassEquation,
+ integer const checkPhasePresenceInGravity,
+ string const & solverName,
+ ElementRegionManager const & elemManager,
+ STENCILWRAPPER const & stencilWrapper,
+ // CAPPRESWRAPPER const & capPresWrapper,
+ // RELPERMWRAPPER const & relPermWrapper,
+ string_array const & interfaceFaceSetNames,
+ stdVector< std::array< std::tuple< constitutive::RelativePermeabilityBase *,
+ constitutive::CapillaryPressureBase *,
+ constitutive::TwoPhaseImmiscibleFluid * >, 2 > > const & interfaceConstitutivePairs,
+ unordered_map< localIndex, localIndex > const & interfaceRegionByConnector,
+ // std::tuple< constitutive::RelativePermeabilityBase *,
+ // constitutive::CapillaryPressureBase *,
+ // constitutive::TwoPhaseImmiscibleFluid * > const & interfaceConstitutivePairs_temp,
+ ElementSubRegionBase const & subRegion,
+ real64 const & dt,
+ CRSMatrixView< real64, globalIndex const > const & localMatrix,
+ arrayView1d< real64 > const & localRhs )
+ {
+ integer constexpr NUM_EQN = 2;
+ integer constexpr NUM_DOF = 2;
+ localIndex const domainSize = subRegion.size();
+ ElementRegionManager::ElementViewAccessor< arrayView1d< globalIndex const > > dofNumberAccessor =
+ elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey );
+ dofNumberAccessor.setName( solverName + "/accessors/" + dofKey );
+
+ // using kernelType = FluxComputeInterfaceConditionKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER, CAPPRESWRAPPER, RELPERMWRAPPER >;
+ using kernelType = FluxComputeInterfaceConditionKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER >;
+ typename kernelType::ImmiscibleMultiphaseFlowAccessors flowAccessors( elemManager, solverName );
+ typename kernelType::MultiphaseFluidAccessors fluidAccessors( elemManager, solverName );
+ typename kernelType::CapPressureAccessors capPressureAccessors( elemManager, solverName );
+ typename kernelType::PermeabilityAccessors permAccessors( elemManager, solverName );
+
+ // kernelType kernel( numPhases, rankOffset, stencilWrapper, capPresWrapper, relPermWrapper, dofNumberAccessor,
+ // flowAccessors, fluidAccessors, capPressureAccessors, permAccessors,
+ // dt, localMatrix, localRhs, hasCapPressure, useTotalMassEquation,
+ // checkPhasePresenceInGravity, interfaceFaceSetNames, interfaceConstitutivePairs, interfaceRegionByConnector,
+ // interfaceConstitutivePairs_temp, domainSize );
+ kernelType kernel( numPhases, rankOffset, stencilWrapper, dofNumberAccessor,
+ flowAccessors, fluidAccessors, capPressureAccessors, permAccessors,
+ dt, localMatrix, localRhs, hasCapPressure, useTotalMassEquation,
+ checkPhasePresenceInGravity, interfaceFaceSetNames, interfaceConstitutivePairs, interfaceRegionByConnector, domainSize );
+ kernelType::template launch< POLICY >( stencilWrapper.size(), kernel );
+ }
};
@@ -795,7 +2776,7 @@ class FluxComputeKernelFactory
enum class KernelFlags
{
- TotalMassEquation = 1 << 0, // 1
+ TotalMassEquation = 1 << 0, // 1
/// Add more flags like that if needed:
// Flag2 = 1 << 1, // 2
@@ -1421,7 +3402,7 @@ class ResidualNormKernelFactory
{
ResidualNormKernel::launchLinf< POLICY >( subRegion.size(), kernel, residualNorm );
}
- else // L2 norm
+ else // L2 norm
{
ResidualNormKernel::launchL2< POLICY >( subRegion.size(), kernel, residualNorm, residualNormalizer );
}
@@ -1431,9 +3412,9 @@ class ResidualNormKernelFactory
-} // namespace immiscible multiphasekernels
+} // namespace immiscible multiphasekernels
-} // namespace geos
+} // namespace geos
-#endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_MULTIPHASEKERNELS_HPP
+ #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_MULTIPHASEKERNELS_HPP