Skip to content

Commit

Permalink
Corrections and simplifications
Browse files Browse the repository at this point in the history
  • Loading branch information
TobiasEppacher committed Aug 29, 2024
1 parent dff55b9 commit 8cea45e
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 65 deletions.
111 changes: 54 additions & 57 deletions partitioned-heat-conduction/solver-fenics/heat_pySDC.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,16 @@
u = u_0 at t = 0
u = 1 + x^2 + alpha*y^2 + \beta*t
f = beta - 2 - 2*alpha
This variant of this tutorial example uses the open-source library pySDC for time-stepping.
pySDC can be installed via `pip install pySDC`.
If you want to use the developer version, the source code repository can be cloned from "https://github.com/Parallel-in-Time/pySDC".
For more information on pySDC, see also "https://parallel-in-time.org/pySDC/"
"""

from __future__ import print_function, division
from fenics import Function, FunctionSpace, Expression, Constant, DirichletBC, TrialFunction, TestFunction, \
from fenics import Function, FunctionSpace, Expression, Constant, TrialFunction, TestFunction, \
File, solve, grad, inner, dx, interpolate, VectorFunctionSpace, MeshFunction, MPI
from fenicsprecice import Adapter
from errorcomputation import compute_errors
Expand Down Expand Up @@ -57,40 +63,43 @@ def determine_gradient(V_g, u, flux):


def setup_problem(
participant_name,
domain_mesh,
coupling_boundary,
remaining_boundary,
V,
u_D,
forcing_expr,
precice,
coupling_expression,
dt,
res_tol=1e-11,
maxiter=40,
quad_type='LOBATTO',
num_nodes=4,
logger_level=30):
function_space,
coupling_boundary,
remaining_boundary,
u_D, forcing_expr,
coupling_expression,
precice,
dt,
logger_level=30,
quad_type='LOBATTO',
num_nodes=4,
restol=1e-11,
maxiter=40):

# Create docstring for this function
"""
Setup the problem for pySDC controller
:param participant_name: name of the participant
:param domain_mesh: mesh of the domain
:param coupling_boundary: boundary where coupling happens
:param remaining_boundary: remaining boundary
:param V: function space
:param u_D: initial condition
:param forcing_expr: forcing term
:param precice: preCICE adapter
:param coupling_expression: coupling expression
:param dt: pySDC time step size
:return: controller, problem class
pySDC can be installed via `pip install pySDC`.
If you want to use the developer version, the source code repository can be cloned from "https://github.com/Parallel-in-Time/pySDC".
For more information on pySDC, see also "https://parallel-in-time.org/pySDC/"
Setup the problem and controller for the heat equation problem.
Args:
function_space: FEniCS function space object
coupling_boundary: FEniCS SubDomain object for the coupling boundary
remaining_boundary: FEniCS SubDomain object for the remaining boundary
u_D: FEniCS expression for the manufactured solution
forcing_expr: FEniCS expression for the forcing term
coupling_expression: FEniCS expression for the coupling boundary condition
precice: preCICE-FEniCS adapter object reference
dt: time step size
logger_level: logging level
quad_type: quadrature type
num_nodes: number of nodes
restol: residual tolerance
maxiter: maximum number of iterations
Returns:
controller: pySDC controller object
P: problem object
"""

# initialize controller parameters
controller_params = {
'logger_level': logger_level
Expand All @@ -100,23 +109,21 @@ def setup_problem(
description = {
'problem_class': fenics_heat_2d,
'problem_params': {
'mesh': domain_mesh,
'function_space': V,
'function_space': function_space,
'coupling_boundary': coupling_boundary,
'remaining_boundary': remaining_boundary,
'solution_expr': u_D,
'forcing_term_expr': forcing_expr,
'precice_ref': precice,
'coupling_expr': coupling_expression,
'participant_name': participant_name
'coupling_expr': coupling_expression
},
'sweeper_class': imex_1st_order_mass,
'sweeper_params': {
'quad_type': quad_type,
'num_nodes': num_nodes
'num_nodes': num_nodes,
},
'level_params': {
'restol': res_tol,
'restol': restol,
'dt': dt
},
'step_params': {
Expand All @@ -129,10 +136,10 @@ def setup_problem(

# Reference to problem class for easy access to exact solution
P = controller.MS[0].levels[0].prob

return controller, P



parser = argparse.ArgumentParser(description="Solving heat equation for simple or complex interface case")
parser.add_argument("participantName", help="Name of the solver.", type=str, choices=[p.value for p in ProblemType])
parser.add_argument("-e", "--error-tol", help="set error tolerance", type=float, default=10**-8,)
Expand Down Expand Up @@ -209,23 +216,13 @@ def setup_problem(
coupling_expression = precice.create_coupling_expression()


controller, P = setup_problem(
participant_name=precice.get_participant_name(),
domain_mesh=domain_mesh,
coupling_boundary=coupling_boundary,
remaining_boundary=remaining_boundary,
V=V,
u_D=u_D,
forcing_expr=forcing_expr,
precice=precice,
coupling_expression=coupling_expression,
dt=dt,
res_tol=error_tol,
maxiter=40,
quad_type='LOBATTO',
num_nodes=4,
logger_level=30
)
controller, P = setup_problem(V,
coupling_boundary,
remaining_boundary,
u_D, forcing_expr,
coupling_expression,
precice,
pySDC_dt)


# Time-stepping
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
"""
This file contains the implementation of the pySDC problem class for the 2D heat equation.
This class is used to define the problem pySDC uses in "heat_pySDC.py" for time-stepping.
This class is based on the pySDC tutorial example for its usage with FEniCS.
More about that tutorial can be found at "https://parallel-in-time.org/pySDC/tutorial/step_7.html#part-a-pysdc-and-fenics".
"""

from fenics import TrialFunction, TestFunction, dx, assemble, inner, nabla_grad, DirichletBC, Constant, solve, interpolate
from my_enums import ProblemType


from pySDC.core.Problem import ptype
from pySDC.implementations.datatype_classes.fenics_mesh import fenics_mesh, rhs_fenics_mesh
Expand All @@ -8,33 +18,29 @@ class fenics_heat_2d(ptype):
dtype_u = fenics_mesh
dtype_f = rhs_fenics_mesh

def __init__(self, mesh, function_space, forcing_term_expr, solution_expr, coupling_boundary,
remaining_boundary, coupling_expr, precice_ref, participant_name):
def __init__(self, function_space, forcing_term_expr, solution_expr, coupling_boundary,
remaining_boundary, coupling_expr, precice_ref):
# Add docstring
"""
Constructor of the 2D heat equation problem class.
Args:
mesh: FEniCS mesh object
function_space: FEniCS function space object
forcing_term_expr: FEniCS expression for the forcing term
solution_expr: FEniCS expression for the manufactured solution
coupling_boundary: FEniCS SubDomain object for the coupling boundary
remaining_boundary: FEniCS SubDomain object for the remaining boundary
coupling_expr: FEniCS expression for the coupling boundary condition
precice_ref: preCICE-FEniCS adapter object reference
participant_name: Name of the participant (Dirichlet or Neumann)
"""

# Set precice reference and coupling expression reference to update coupling boundary
# at every step within pySDC
self.precice = precice_ref
self.coupling_expression = coupling_expr
self.t_start = 0.0
self.participant_name = participant_name

# set mesh and function space for future reference
self.mesh = mesh
self.V = function_space

# invoke super init
Expand All @@ -60,7 +66,7 @@ def __init__(self, mesh, function_space, forcing_term_expr, solution_expr, coupl
self.solution_expr = solution_expr

# Currently only for Dirichlet boundary, has to be changed for Neumann boundary
if self.participant_name == 'Dirichlet':
if self.precice.get_participant_name() == ProblemType.DIRICHLET.value:
self.couplingBC = DirichletBC(self.V, coupling_expr, coupling_boundary)

self.remainingBC = DirichletBC(self.V, solution_expr, remaining_boundary)
Expand All @@ -86,7 +92,7 @@ def solve_system(self, rhs, factor, u0, t):
self.remainingBC.apply(T, b.values.vector())

# Update the coupling boundary condition for the Dirichlet participant
if self.participant_name == 'Dirichlet':
if self.precice.get_participant_name() == ProblemType.DIRICHLET.value:
dt = t - self.t_start # This dt is used to read data from the current time window
read_data = self.precice.read_data(dt) # Read the data to update the coupling expression
self.precice.update_coupling_expression(
Expand Down

0 comments on commit 8cea45e

Please sign in to comment.