Skip to content
Snippets Groups Projects
Commit a3a9d402 authored by David Seus's avatar David Seus
Browse files

write LDDsolver method.

parent 0c527b8a
No related branches found
No related tags found
No related merge requests found
...@@ -80,6 +80,10 @@ class LDDsimulation(object): ...@@ -80,6 +80,10 @@ class LDDsimulation(object):
self.adjacent_subdomains = None self.adjacent_subdomains = None
## Private variables ## Private variables
# maximal number of L-iterations that the LDD solver uses.
self._max_iter_num = 100
# TODO rewrite this with regard to the mesh sizes
self.calc_tol = 10^-6
# The number of subdomains are counted by self.init_meshes_and_markers() # The number of subdomains are counted by self.init_meshes_and_markers()
self._number_of_subdomains = 0 self._number_of_subdomains = 0
# variable to check if self.set_parameters() has been called # variable to check if self.set_parameters() has been called
...@@ -145,6 +149,83 @@ class LDDsimulation(object): ...@@ -145,6 +149,83 @@ class LDDsimulation(object):
# init Dirichlet Boundary values for the first time # init Dirichlet Boundary values for the first time
self.set_DirichletBC(time = 0, first_init = True) self.set_DirichletBC(time = 0, first_init = True)
def LDDsolver(self, time: float):
""" calulate the solution on all patches for the next timestep
The heart of the simulation. The function LDDsolver implements the LDD
iteration, that is solves the problem given the initial data at timestep
time.
"""
iteration = 0
# dictionary holding bool variables for each subdomain indicating wether
# minimal error has been achieved, i.e. the calculation can be considered
# done or not.
subdomain_calc_isdone = dict()
# before the iteration gets started all iteration numbers must be nulled
# and
for ind, subdomain in self.subdomain.items():
subdomain_calc_isdone.update({ind, False})
# the following only needs to be done when time is not equal 0 since
# our initialisation functions already took care of setting what follows
# for the initial iteration step.
if time > 0:
# this is the beginning of the solver, so iteration must be set
# to 0.
subdomain.iteration_number = 0
# set the solution of the previous timestep as new prev_timestep pressure
subdomain.pressure_prev_timestep = subdomain.pressure
# TODO recheck if
subdomain.pressure_prev_iter = subdomain.pressure
# needs to be set also
### actual iteration starts here
# gobal stopping criterion for the iteration.
all_subdomains_done = False
while iteration < self._max_iter_num and not all_subdomains_done:
# we need to loop over the subdomains and solve an L-scheme type step
# on each subdomain. here it should be possible to parallelise in
# the future.
for sd_index, subdomain in self.subdomain.items():
# check if the calculation on subdomain has already be marked as
# finished.
if not subdomain_calc_isdone[sd_index]:
# solve the problem on subdomain
self.Lsolver_step(subdomain = subdomain,#
iteration = iteration,#
debug = True
)
subsequent_iterations_err = self.calc_iteration_error(
subdomain = subdomain,#
error_type = "L2"
)
# check if error criterion has been met
if subsequent_iterations_err < self.calc_tol:
subdomain_calc_isdone[sd_index] = True
# prepare next iteration
# write the newly calculated solution to the inteface dictionaries
# for communication
subdomain.write_pressure_to_interfaces()
subdomain.pressure_prev_iter = subdomain.pressure
else:
# one subdomain is done. Check if all subdomains are done to
# stop the while loop if needed.
# For this, set
all_subdomains_done = True
# then check if all domains are done. If not, reset
# all_subdomains_done to False.
for subdomain, isdone in subdomain_calc_isdone.items():
if not isdone:
all_subdomains_done = False
#TODO check if maybe I still need to do
# subdomain.iteration_number += 1
# or adapt the calc_gli_term method to reflect that one subdomain
# could be done earlier than others.
# you wouldn't be so stupid as to write an infinite loop, would you?
iteration += 1
# end iteration while loop.
## Private methods ## Private methods
def _init_meshes_and_markers(self, subdomain_def_points: tp.List[tp.List[df.Point]] = None,# def _init_meshes_and_markers(self, subdomain_def_points: tp.List[tp.List[df.Point]] = None,#
mesh_resolution: float = None) -> None: mesh_resolution: float = None) -> None:
......
from . import domainPatch
from . import helpers
from . import LDDsimulation
...@@ -180,7 +180,10 @@ class DomainPatch(df.SubDomain): ...@@ -180,7 +180,10 @@ class DomainPatch(df.SubDomain):
#### PUBLIC METHODS #### PUBLIC METHODS
def write_pressure_to_interfaces(self): def write_pressure_to_interfaces(self):
""" save the interface values of self.pressure to all neighbouring interfaces""" """ save the interface values of self.pressure to all neighbouring interfaces
This method is used by the LDDsimulation.LDDsolver method.
"""
if self.isRichards: if self.isRichards:
for ind in self.has_interface: for ind in self.has_interface:
interface[ind].read_pressure_dofs(from_function = self.pressure['wetting'], # interface[ind].read_pressure_dofs(from_function = self.pressure['wetting'], #
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment