Skip to content

Commit 6620bd7

Browse files
authored
Merge pull request #1066 from jhdark/checkpoint_mixed_domain
Initial conditions in mixed-domain cases
2 parents 1ec8975 + 94d4bd7 commit 6620bd7

File tree

2 files changed

+138
-20
lines changed

2 files changed

+138
-20
lines changed

src/festim/hydrogen_transport_problem.py

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
as_fenics_constant,
4141
get_interpolation_points,
4242
is_it_time_to_export,
43+
nmm_interpolate,
4344
)
4445
from festim.material import SolubilityLaw
4546

@@ -1251,20 +1252,27 @@ def create_initial_conditions(self):
12511252
the previous solution of the condition's species"""
12521253

12531254
for condition in self.initial_conditions:
1254-
V = condition.species.subdomain_to_function_space[condition.volume]
1255+
idx = self.species.index(condition.species)
12551256

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

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

12691277
def define_function_spaces(
12701278
self, subdomain: _subdomain.VolumeSubdomain, element_degree=1
@@ -1735,9 +1743,9 @@ def initialise_exports(self):
17351743
engine="BP5",
17361744
)
17371745
else:
1738-
raise NotImplementedError(
1739-
f"Export type {type(export)} not implemented for "
1740-
f"mixed-domain approach"
1746+
adios4dolfinx.write_mesh(
1747+
export.filename,
1748+
mesh=functions[0].function_space.mesh,
17411749
)
17421750

17431751
# compute diffusivity function for surface fluxes
@@ -1787,11 +1795,20 @@ def post_processing(self):
17871795
)
17881796
if isinstance(export, exports.VTXSpeciesExport):
17891797
if export._checkpoint:
1790-
raise NotImplementedError(
1791-
f"Export type {type(export)} not implemented "
1792-
f"for mixed-domain approach"
1793-
)
1794-
export.writer.write(float(self.t))
1798+
for species in export.field:
1799+
post_processing_solution = (
1800+
species.subdomain_to_post_processing_solution[
1801+
export._subdomain
1802+
]
1803+
)
1804+
adios4dolfinx.write_function(
1805+
export.filename,
1806+
post_processing_solution,
1807+
time=float(self.t),
1808+
name=species.name,
1809+
)
1810+
else:
1811+
export.writer.write(float(self.t))
17951812

17961813
# handle derived quantities
17971814
if isinstance(export, exports.SurfaceQuantity):

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)