From 5fbf83c2891813f16b6323330d3e07ecd6508bbd Mon Sep 17 00:00:00 2001
From: David Seus <david.seus@ians.uni-stuttgart.de>
Date: Mon, 30 Sep 2019 13:59:24 +0200
Subject: [PATCH] set up new TPR mesh study

---
 LDDsimulation/domainPatch.py                  | 72 ++++++++++++-------
 .../TP-R-2-patch-test.py                      | 45 ++++++------
 .../mesh_studies/TP-R-2-patch-mesh-study.py   | 11 +--
 3 files changed, 77 insertions(+), 51 deletions(-)

diff --git a/LDDsimulation/domainPatch.py b/LDDsimulation/domainPatch.py
index d7bf0ec..061f36e 100644
--- a/LDDsimulation/domainPatch.py
+++ b/LDDsimulation/domainPatch.py
@@ -171,6 +171,16 @@ class DomainPatch(df.SubDomain):
         # determined by the model we are assuming
         if self.isRichards:
             self.has_phases = ['wetting']
+            # in case we are Richards, determin, whether or not we have a TP
+            # neighbour
+            self.has_TP_neighbour = False
+            for interf in self.has_interface:
+                neighbour_assumes_R = self.interface[interf].neighbour_isRichards[self.subdomain_index]
+                if not neighbour_assumes_R:
+                    self.has_TP_neighbour = True
+                    # if only one neighbour assumes TP we ste up the nonwetting
+                    # space.
+                    break
         else:
             self.has_phases = ['wetting', 'nonwetting']  #['nonwetting', 'wetting']
         # dictionary holding the dof indices corresponding to an interface of
@@ -437,15 +447,25 @@ class DomainPatch(df.SubDomain):
 
             # n = df.FacetNormal(self.mesh)
             S = self.saturation
-            for phase in self.has_phases:
+
+            phases_for_gl0 = self.has_phases
+            if self.isRichards and self.has_TP_neighbour:
+                interface_has_TP_neighbour = not interface.neighbour_isRichards[self.subdomain_index]
+                if interface_has_TP_neighbour and self.include_gravity:
+                    phases_for_gl0 = ['wetting', 'nonwetting']
+
+            for phase in phases_for_gl0:
+
                 # viscosity
                 mu_a = self.viscosity[phase]
                 # relative permeability
                 ka = self.relative_permeability[phase]
                 # previous timestep pressure
-                pa_prev = self.pressure_prev_timestep[phase]
-                # testfunction
-                # phi_a = self.testfunction[phase]
+                if self.isRichards and interface_has_TP_neighbour and phase is "nonwetting":
+                    pa_prev = 0
+                else:
+                    pa_prev = self.pressure_prev_timestep[phase]
+
                 if self.include_gravity:
                     z_a = self.gravity_term[phase]
                 if phase == 'wetting':
@@ -459,11 +479,17 @@ class DomainPatch(df.SubDomain):
                         flux = -1/mu_a*ka(S(pc_prev))*df.grad(pa_prev)
                 else:
                     # phase == 'nonwetting'
-                    # we need anothre flux in this case
-                    if self.include_gravity:
-                        flux = -1/mu_a*ka(1-S(pc_prev))*df.grad(pa_prev - z_a)
+                    if self.isRichards and interface_has_TP_neighbour and phase is "nonwetting":
+                        if self.include_gravity:
+                            flux = -1/mu_a*ka(1-S(pc_prev))*df.grad(-z_a)
+                        else:
+                            flux = 0
                     else:
-                        flux = -1/mu_a*ka(1-S(pc_prev))*df.grad(pa_prev)
+                        # we need anothre flux in this case
+                        if self.include_gravity:
+                            flux = -1/mu_a*ka(1-S(pc_prev))*df.grad(pa_prev - z_a)
+                        else:
+                            flux = -1/mu_a*ka(1-S(pc_prev))*df.grad(pa_prev)
 
                 flux_function = df.project(flux, self.function_space["flux"][phase])
                 flux_x, flux_y = flux_function.split()
@@ -492,9 +518,13 @@ class DomainPatch(df.SubDomain):
                         flux_y_dof_index = corresponding_dof_index[local_facet_ind][gli_dof_index]["flux_y"]
                         p_dof_index = corresponding_dof_index[local_facet_ind][gli_dof_index]["pressure"]
 
-                        gl0.vector()[gli_dof_index] = flux_x.vector()[flux_x_dof_index]*normal[0] \
-                            + flux_y.vector()[flux_y_dof_index]*normal[1] \
-                            - Lambda[phase]*pa_prev.vector()[p_dof_index]
+                        if self.isRichards and interface_has_TP_neighbour and phase is "nonwetting" and self.include_gravity:
+                            gl0.vector()[gli_dof_index] = flux_x.vector()[flux_x_dof_index]*normal[0] \
+                                + flux_y.vector()[flux_y_dof_index]*normal[1]
+                        else:
+                            gl0.vector()[gli_dof_index] = flux_x.vector()[flux_x_dof_index]*normal[0] \
+                                + flux_y.vector()[flux_y_dof_index]*normal[1] \
+                                - Lambda[phase]*pa_prev.vector()[p_dof_index]
                         if debug:
                             print(f"gl0.vector()[gli_dof_ind] = {gl0.vector()[gli_dof_index]}")
 
@@ -779,18 +809,8 @@ class DomainPatch(df.SubDomain):
             gli_space = df.FunctionSpace(self.mesh, 'DG', degree)
             flux_space = df.VectorFunctionSpace(self.mesh, 'DG', degree)
 
-            if self.isRichards:
-                # if our domain assumes Richards but the neighbour of the interface
-                # assumes TP, we need to initialise interface values for the nonwetting
-                # phase, too, for communication, see the article. Therefor we need to
-                # initialise the nonwetting function space too.
-                for interf in self.has_interface:
-                    neighbour_assumes_R = self.interface[interf].neighbour_isRichards[self.subdomain_index]
-                    if not neighbour_assumes_R:
-                        subdom_has_phases = ["wetting", "nonwetting"]
-                        # if only one neighbour assumes TP we ste up the nonwetting
-                        # space.
-                        break
+            if self.isRichards and self.has_TP_neighbour:
+                subdom_has_phases = ["wetting", "nonwetting"]
             else:
                 subdom_has_phases = self.has_phases
 
@@ -1132,7 +1152,11 @@ class DomainPatch(df.SubDomain):
     def _calc_gravity_expressions(self):
         """ calculate the gravity term if it is included"""
         g = df.Constant(self.gravity_acceleration) #
-        for phase in self.has_phases:
+        has_phases = self.has_phases
+        if self.isRichards and self.has_TP_neighbour:
+            has_phases = ["wetting", "nonwetting"]
+
+        for phase in has_phases:
             rho = df.Constant(self.densities[phase])
             self.gravity_term.update(
                 {phase: df.Expression('-g*rho*x[1]',
diff --git a/Two-phase-Richards/two-patch/TP-R-two-patch-test-case/TP-R-2-patch-test.py b/Two-phase-Richards/two-patch/TP-R-two-patch-test-case/TP-R-2-patch-test.py
index cd8315d..6d3495a 100755
--- a/Two-phase-Richards/two-patch/TP-R-two-patch-test-case/TP-R-2-patch-test.py
+++ b/Two-phase-Richards/two-patch/TP-R-two-patch-test-case/TP-R-2-patch-test.py
@@ -38,21 +38,21 @@ resolutions = {
 
 ############ GRID #######################
 # mesh_resolution = 20
-timestep_size = 0.001
-number_of_timesteps = 20
-plot_timestep_every = 1
+timestep_size = 0.0001
+number_of_timesteps = 1200
+plot_timestep_every = 5
 # decide how many timesteps you want analysed. Analysed means, that we write out
 # subsequent errors of the L-iteration within the timestep.
-number_of_timesteps_to_analyse = 10
+number_of_timesteps_to_analyse = 6
 starttimes = [0.0]
 
-Lw = 0.025 #/timestep_size
+Lw = 10 #/timestep_size
 Lnw=Lw
 
-lambda_w = 40
-lambda_nw = 40
+lambda_w = 4
+lambda_nw = 4
 
-include_gravity = False
+include_gravity = True
 debugflag = True
 analyse_condition = True
 
@@ -151,8 +151,8 @@ isRichards = {
 
 viscosity = {#
 # subdom_num : viscosity
-    1 : {'wetting' :1},
-         #'nonwetting': 1}, #
+    1 : {'wetting' :1,
+         'nonwetting': 1/50}, #
     2 : {'wetting' :1,
          'nonwetting': 1/50}
 }
@@ -165,7 +165,8 @@ porosity = {#
 
 # Dict of the form: { subdom_num : density }
 densities = {
-    1: {'wetting': 997},
+    1: {'wetting': 997,
+        'nonwetting': 1.225},
     2: {'wetting': 997,
         'nonwetting': 1.225},
 }
@@ -194,15 +195,15 @@ def rel_perm1w(s):
     # relative permeabilty wetting on subdomain1
     return s**2
 
-# def rel_perm1nw(s):
-#     # relative permeabilty nonwetting on subdomain1
-#     return (1-s)**2
+def rel_perm1nw(s):
+    # relative permeabilty nonwetting on subdomain1
+    return (1-s)**2
 
 _rel_perm1w = ft.partial(rel_perm1w)
-# _rel_perm1nw = ft.partial(rel_perm1nw)
+_rel_perm1nw = ft.partial(rel_perm1nw)
 subdomain1_rel_perm = {
     'wetting': _rel_perm1w,#
-    # 'nonwetting': _rel_perm1nw
+    'nonwetting': _rel_perm1nw
 }
 ## relative permeabilty functions on subdomain 2
 def rel_perm2w(s):
@@ -233,9 +234,9 @@ def rel_perm1w_prime(s):
     # relative permeabilty on subdomain1
     return 2*s
 
-# def rel_perm1nw_prime(s):
-#     # relative permeabilty on subdomain1
-#     return 2*(1-s)
+def rel_perm1nw_prime(s):
+    # relative permeabilty on subdomain1
+    return -2*(1-s)
 
 # definition of the derivatives of the relative permeabilities
 # relative permeabilty functions on subdomain 1
@@ -248,13 +249,13 @@ def rel_perm2nw_prime(s):
     return -3*(1-s)**2
 
 _rel_perm1w_prime = ft.partial(rel_perm1w_prime)
-# _rel_perm1nw_prime = ft.partial(rel_perm1nw_prime)
+_rel_perm1nw_prime = ft.partial(rel_perm1nw_prime)
 _rel_perm2w_prime = ft.partial(rel_perm2w_prime)
 _rel_perm2nw_prime = ft.partial(rel_perm2nw_prime)
 
 subdomain1_rel_perm_prime = {
-    'wetting': _rel_perm1w_prime
-    # 'nonwetting': _rel_perm1nw_prime
+    'wetting': _rel_perm1w_prime,
+    'nonwetting': _rel_perm1nw_prime
 }
 
 
diff --git a/Two-phase-Richards/two-patch/TP-R-two-patch-test-case/mesh_studies/TP-R-2-patch-mesh-study.py b/Two-phase-Richards/two-patch/TP-R-two-patch-test-case/mesh_studies/TP-R-2-patch-mesh-study.py
index bc102a3..f3b556c 100755
--- a/Two-phase-Richards/two-patch/TP-R-two-patch-test-case/mesh_studies/TP-R-2-patch-mesh-study.py
+++ b/Two-phase-Richards/two-patch/TP-R-two-patch-test-case/mesh_studies/TP-R-2-patch-mesh-study.py
@@ -19,7 +19,7 @@ datestr = date.strftime("%Y-%m-%d")
 # init sympy session
 sym.init_printing()
 
-use_case = "TP-R-2-patch-realistic"
+use_case = "TP-R-2-patch-realistic-new-nw-gli"
 # solver_tol = 6E-7
 max_iter_num = 1000
 FEM_Lagrange_degree = 1
@@ -32,12 +32,13 @@ resolutions = { 1: 7e-7,
                 32: 7e-7,
                 64: 7e-7,
                 128: 7e-7,
-                256: 7e-7}
+                #256: 7e-7,
+                }
 
 ############ GRID #######################
 # mesh_resolution = 20
 timestep_size = 0.001
-number_of_timesteps = 600
+number_of_timesteps = 800
 plot_timestep_every = 2
 # decide how many timesteps you want analysed. Analysed means, that we write out
 # subsequent errors of the L-iteration within the timestep.
@@ -182,8 +183,8 @@ L = {#
 
 lambda_param = {#
 # subdom_num : lambda parameter for the L-scheme
-    1 : {'wetting' :lambda_w},
-         # 'nonwetting': lambda},#
+    1 : {'wetting' :lambda_w,
+         'nonwetting': lambda_nw},#
     2 : {'wetting' :lambda_w,
          'nonwetting': lambda_nw}
 }
-- 
GitLab