Skip to content

Commit 643e84c

Browse files
Merge branch 'fenicsx' into logger
2 parents 08f01a6 + 6620bd7 commit 643e84c

3 files changed

Lines changed: 180 additions & 20 deletions

File tree

src/festim/hydrogen_transport_problem.py

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
SnesMonitor,
4444
KSPMonitor,
4545
convergenceTest,
46+
nmm_interpolate,
4647
)
4748
from festim.material import SolubilityLaw
4849

@@ -1254,20 +1255,27 @@ def create_initial_conditions(self):
12541255
the previous solution of the condition's species"""
12551256

12561257
for condition in self.initial_conditions:
1257-
V = condition.species.subdomain_to_function_space[condition.volume]
1258+
idx = self.species.index(condition.species)
12581259

1259-
condition.create_expr_fenics(
1260-
mesh=self.mesh.mesh,
1261-
temperature=self.temperature_fenics,
1262-
function_space=V,
1263-
)
1260+
# if the value given is a function, then directly interpolate it on the
1261+
# previous solution of the species
1262+
if isinstance(condition.value, fem.Function):
1263+
nmm_interpolate(condition.volume.u_n.sub(idx), condition.value)
12641264

1265-
# assign to previous solution of species
1266-
entities = self.volume_meshtags.find(condition.volume.id)
1267-
idx = self.species.index(condition.species)
1268-
condition.volume.u_n.sub(idx).interpolate(
1269-
condition.expr_fenics, cells1=entities
1270-
)
1265+
else:
1266+
V = condition.species.subdomain_to_function_space[condition.volume]
1267+
1268+
condition.create_expr_fenics(
1269+
mesh=self.mesh.mesh,
1270+
temperature=self.temperature_fenics,
1271+
function_space=V,
1272+
)
1273+
1274+
# assign to previous solution of species
1275+
entities = self.volume_meshtags.find(condition.volume.id)
1276+
condition.volume.u_n.sub(idx).interpolate(
1277+
condition.expr_fenics, cells1=entities
1278+
)
12711279

12721280
def define_function_spaces(
12731281
self, subdomain: _subdomain.VolumeSubdomain, element_degree=1
@@ -1742,9 +1750,9 @@ def initialise_exports(self):
17421750
engine="BP5",
17431751
)
17441752
else:
1745-
raise NotImplementedError(
1746-
f"Export type {type(export)} not implemented for "
1747-
f"mixed-domain approach"
1753+
adios4dolfinx.write_mesh(
1754+
export.filename,
1755+
mesh=functions[0].function_space.mesh,
17481756
)
17491757

17501758
# compute diffusivity function for surface fluxes
@@ -1794,11 +1802,20 @@ def post_processing(self):
17941802
)
17951803
if isinstance(export, exports.VTXSpeciesExport):
17961804
if export._checkpoint:
1797-
raise NotImplementedError(
1798-
f"Export type {type(export)} not implemented "
1799-
f"for mixed-domain approach"
1800-
)
1801-
export.writer.write(float(self.t))
1805+
for species in export.field:
1806+
post_processing_solution = (
1807+
species.subdomain_to_post_processing_solution[
1808+
export._subdomain
1809+
]
1810+
)
1811+
adios4dolfinx.write_function(
1812+
export.filename,
1813+
post_processing_solution,
1814+
time=float(self.t),
1815+
name=species.name,
1816+
)
1817+
else:
1818+
export.writer.write(float(self.t))
18021819

18031820
# handle derived quantities
18041821
if isinstance(export, exports.SurfaceQuantity):

test/test_h_transport_problem.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,3 +1457,45 @@ def test_surface_reaction_BC_discontinuous():
14571457

14581458
# TEST
14591459
assert np.isclose(permeation_flux.data[-1], -inlet_flux.data[-1], rtol=1e-5)
1460+
1461+
1462+
def test_temperature_as_function_in_discontinuous():
1463+
"""Test that a discontinuous problem can be initialised with a temperature field
1464+
given as a function"""
1465+
1466+
# BUILD
1467+
my_model = F.HydrogenTransportProblemDiscontinuous()
1468+
1469+
mat = F.Material(D_0=1, E_D=0, K_S_0=1, E_K_S=0)
1470+
vol1 = F.VolumeSubdomain1D(id=1, borders=[0, 1], material=mat)
1471+
vol2 = F.VolumeSubdomain1D(id=2, borders=[1, 2], material=mat)
1472+
1473+
vertices_left = np.linspace(0, 1, num=100, endpoint=False)
1474+
vertices_right = np.linspace(1, 2, num=100)
1475+
vertices = np.concatenate([vertices_left, vertices_right])
1476+
my_model.mesh = F.Mesh1D(vertices)
1477+
my_model.mesh = F.Mesh1D(vertices)
1478+
1479+
my_model.subdomains = [vol1, vol2]
1480+
1481+
my_model.method_interface = F.InterfaceMethod.penalty
1482+
my_model.interfaces = [
1483+
F.Interface(id=5, subdomains=[vol1, vol2], penalty_term=100),
1484+
]
1485+
1486+
H = F.Species("H", subdomains=my_model.volume_subdomains)
1487+
my_model.species = [H]
1488+
1489+
V = fem.functionspace(my_model.mesh.mesh, ("CG", 1))
1490+
u = fem.Function(V)
1491+
u.interpolate(lambda x: 100 + x[0])
1492+
u.x.array[:] = 100
1493+
my_model.temperature = u
1494+
1495+
my_model.settings = F.Settings(
1496+
atol=1e-10,
1497+
rtol=1e-09,
1498+
transient=False,
1499+
)
1500+
1501+
my_model.initialise()

test/test_initial_condition.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,3 +434,104 @@ def test_initial_condition_continuous_multimaterial():
434434
# assert value of spe1 is not all the same across the domain
435435

436436
assert not np.allclose(my_model.u_n.x.array[:], intial_cond_value)
437+
438+
439+
def test_initial_condition_mixed_domain():
440+
"""Test the initial condition in a multi-material discontinous case"""
441+
442+
my_model = F.HydrogenTransportProblemDiscontinuous()
443+
444+
vertices_left = np.linspace(0, 0.5, 500)
445+
vertices_right = np.linspace(0.5, 1, 500)
446+
vertices = np.concatenate((vertices_left, vertices_right))
447+
my_model.mesh = F.Mesh1D(vertices)
448+
449+
# assumes the same diffusivity for all species
450+
material_left = F.Material(D_0=1e-01, E_D=0, K_S_0=1, E_K_S=0)
451+
material_right = F.Material(D_0=1e-01, E_D=0, K_S_0=2, E_K_S=0)
452+
453+
vol1 = F.VolumeSubdomain1D(id=1, borders=[0, 0.5], material=material_left)
454+
vol2 = F.VolumeSubdomain1D(id=2, borders=[0.5, 1], material=material_right)
455+
my_model.subdomains = [vol1, vol2]
456+
457+
spe1 = F.Species("1", mobile=True, subdomains=[vol1, vol2])
458+
my_model.species = [spe1]
459+
460+
my_model.temperature = 300
461+
462+
intial_cond_value = 100
463+
V = fem.functionspace(my_model.mesh.mesh, ("CG", 1))
464+
u = fem.Function(V)
465+
u.x.array[:] = intial_cond_value
466+
467+
my_model.initial_conditions = [
468+
F.InitialConcentration(value=u, species=spe1, volume=vol1),
469+
]
470+
471+
dt = F.Stepsize(0.1)
472+
my_model.settings = F.Settings(
473+
atol=1e-10, rtol=1e-10, final_time=5, transient=True, stepsize=dt
474+
)
475+
476+
my_model.initialise()
477+
478+
# assert value of spe1 in vol1
479+
left_spe1_un = vol1.u.sub(0)
480+
481+
assert not np.allclose(left_spe1_un.x.array[:], intial_cond_value)
482+
483+
484+
def test_initial_condition_mixed_domain_multispecies():
485+
"""Test the initial condition in a multispecies multi-material discontinous case"""
486+
487+
my_model = F.HydrogenTransportProblemDiscontinuous()
488+
489+
vertices_left = np.linspace(0, 0.5, 500)
490+
vertices_right = np.linspace(0.5, 1, 500)
491+
vertices = np.concatenate((vertices_left, vertices_right))
492+
my_model.mesh = F.Mesh1D(vertices)
493+
494+
# assumes the same diffusivity for all species
495+
material_left = F.Material(D_0=1e-01, E_D=0, K_S_0=1, E_K_S=0)
496+
material_right = F.Material(D_0=1e-01, E_D=0, K_S_0=2, E_K_S=0)
497+
498+
vol1 = F.VolumeSubdomain1D(id=1, borders=[0, 0.5], material=material_left)
499+
vol2 = F.VolumeSubdomain1D(id=2, borders=[0.5, 1], material=material_right)
500+
my_model.subdomains = [vol1, vol2]
501+
502+
spe1 = F.Species("1", mobile=True, subdomains=[vol1, vol2])
503+
spe2 = F.Species("2", mobile=True, subdomains=[vol1, vol2])
504+
my_model.species = [spe1, spe2]
505+
506+
my_model.temperature = 300
507+
508+
intial_cond_value_1 = 100
509+
intial_cond_value_2 = 200
510+
V = fem.functionspace(my_model.mesh.mesh, ("CG", 1))
511+
u = fem.Function(V)
512+
u.x.array[:] = intial_cond_value_1
513+
514+
V2 = fem.functionspace(my_model.mesh.mesh, ("CG", 1))
515+
u2 = fem.Function(V2)
516+
u2.x.array[:] = intial_cond_value_2
517+
518+
my_model.initial_conditions = [
519+
F.InitialConcentration(value=u, species=spe1, volume=vol1),
520+
F.InitialConcentration(value=u2, species=spe2, volume=vol1),
521+
]
522+
523+
dt = F.Stepsize(0.1)
524+
my_model.settings = F.Settings(
525+
atol=1e-10, rtol=1e-10, final_time=5, transient=True, stepsize=dt
526+
)
527+
528+
my_model.initialise()
529+
530+
spe1_left, spe1_to_vol1 = vol1.u_n.function_space.sub(0).collapse()
531+
spe2_left, spe2_to_vol1 = vol1.u_n.function_space.sub(1).collapse()
532+
533+
prev_solution_spe1_left = vol1.u_n.x.array[spe1_to_vol1]
534+
prev_solution_spe2_left = vol1.u_n.x.array[spe2_to_vol1]
535+
536+
assert np.allclose(prev_solution_spe1_left, intial_cond_value_1)
537+
assert np.allclose(prev_solution_spe2_left, intial_cond_value_2)

0 commit comments

Comments
 (0)