From 73807ab0626b3e0a446b1864bfeddcabb854ddf0 Mon Sep 17 00:00:00 2001 From: David Seus <david.seus@ians.uni-stuttgart.de> Date: Fri, 31 May 2019 15:35:46 +0200 Subject: [PATCH] implement general _normal_vector_norms_for_common_dofs with linear combinations of normal vectors --- LDDsimulation/domainPatch.py | 42 ++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/LDDsimulation/domainPatch.py b/LDDsimulation/domainPatch.py index 6f873c3..d2de50b 100644 --- a/LDDsimulation/domainPatch.py +++ b/LDDsimulation/domainPatch.py @@ -391,7 +391,7 @@ class DomainPatch(df.SubDomain): return form_and_rhs - def calc_gl0_term(self, debug: bool = False) -> None: # tp.Dict[str, fl.Form] + def calc_gl0_term(self, debug: bool = True) -> None: # tp.Dict[str, fl.Form] """calculate the gl0 terms for all interfaces of the subdomain. assemble the gl0 terms for all interfaces of the subdomain and save them @@ -503,15 +503,21 @@ class DomainPatch(df.SubDomain): # since we are looping over the interfaces we correct each dof # that is common with another interfaces with the corresponding # factor norm(n_1 + 1_2). + # We take the mean of the pressure on both interfaces, so + # we multiply these by 1/2 if dofs_in_common_with_other_interfaces[phase].size != 0: if debug: print(f"the following dofs (phase = {phase}) of interface{interf_ind} are in common with \n", f" other interfaces: {dofs_in_common_with_other_interfaces[phase]}") for common_dof in dofs_in_common_with_other_interfaces[phase]: + n_norm = self._normal_vector_norms_for_common_dofs[interf_ind][phase][common_dof] # from the standpoint of the subdomain we are currently on, # each dof can belong maximally to two interfaces. # because we have not - gl0_assembled[common_dof] = 0.5*gl0_assembled[common_dof] + neumann_flux_assembled[common_dof] = neumann_flux_assembled[common_dof]/n_norm + robin_pressure_assembled[common_dof] = robin_pressure_assembled[common_dof]/2 + + gl0_assembled = neumann_flux_assembled - robin_pressure_assembled # now, add the just assembled and corrected term to the Global # gli_assembled_tmp vector gli_assembled_tmp[phase] += gl0_assembled @@ -652,12 +658,16 @@ class DomainPatch(df.SubDomain): phi_a = self.testfunction[phase] gli_pressure_part = df.assemble(-2*dt*Lambda[phase]*pa_prev*phi_a*ds) gli_pressure_part_array = gli_pressure_part.get_local() - gli = gli_pressure_part_array - gli_prev_of_neighbour # check if there are shared dofs with another interface. if dofs_in_common_with_other_interfaces[phase].size != 0: for common_dof in dofs_in_common_with_other_interfaces[phase]: + # n_norm = self._normal_vector_norms_for_common_dofs[ind][phase][common_dof] + gli_prev_of_neighbour[common_dof] = gli_prev_of_neighbour[common_dof]/2 + # see previous case. - gli[common_dof] = 0.5*gli[common_dof] + gli_pressure_part_array[common_dof] = 0.5*gli_pressure_part_array[common_dof] + + gli = gli_pressure_part_array - gli_prev_of_neighbour # now, add the just assembled and corrected term to the Global # gli_assembled_tmp vector gli_assembled_tmp[phase] += gli @@ -897,6 +907,7 @@ class DomainPatch(df.SubDomain): interfaces. This is used by the functions calc_gli_term and calc_gl0_term """ self._normal_vector_norms_for_common_dofs = dict() + self.mesh.init(0) for interface_ind in self.has_interface: # if one phase has common dofs to two interfaces, the both phases # have, so it suffices to check for the wetting phase as it is always @@ -908,10 +919,27 @@ class DomainPatch(df.SubDomain): {phase: dict()} ) for dof in self._interface_has_common_dof_indices[interface_ind][phase]: - # at the moment we only determine this correctly if the patch - # is rectangular and parallel to the x and y axis. + common_vertex_index = self.dof2vertex[phase][dof] + for index, vertex in enumerate(df.vertices(self.mesh)): + if index == common_vertex_index: + common_vertex = vertex + # print(f"\non subdomain{self.subdomain_index}, interface{interface_ind} and phase {phase}") + # print(f"vertex_{index} = {vertex.point()[:]}, type(vertex) = {type(vertex)}") + linear_combination_of_normals = np.zeros(np.size(vertex.point()[:]), dtype=float) + # normals = [] + # print(f"common_vertex = {common_vertex}", + # f"common_vertex_index = {common_vertex_index}") + for facet_containing_vertex in df.facets(common_vertex):#df.cells(common_vertex): + if facet_containing_vertex.exterior(): + # normals.append(facet_containing_vertex.normal()[:]) + # print(f"type(facet_normal) = {type(facet_containing_vertex.normal()[:])}") + linear_combination_of_normals += facet_containing_vertex.normal()[:] + + # print(f"normals of common_vertex: {common_vertex} are ", normals) + # print(f"linear combination is: {linear_combination_of_normals[:]}.") + # print(f"with length {np.linalg.norm(linear_combination_of_normals, ord=2, axis=None)}. For comparison, np.sqrt(2) = {np.sqrt(2)}.") self._normal_vector_norms_for_common_dofs[interface_ind][phase].update( - {dof: np.sqrt(2)} + {dof: np.linalg.norm(linear_combination_of_normals)} ) -- GitLab