-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'fenicsx' into time_as_Constant
- Loading branch information
Showing
6 changed files
with
190 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
from dolfinx.io import VTXWriter | ||
import mpi4py | ||
|
||
import festim as F | ||
|
||
|
||
class VTXExport: | ||
"""Export functions to VTX file | ||
Args: | ||
filename (str): the name of the output file | ||
field (int): the field index to export | ||
Attributes: | ||
filename (str): the name of the output file | ||
writer (dolfinx.io.VTXWriter): the VTX writer | ||
field (festim.Species, list of festim.Species): the field index to export | ||
Usage: | ||
>>> u = dolfinx.fem.Function(V) | ||
>>> my_export = festim.VTXExport("my_export.bp") | ||
>>> my_export.define_writer(mesh.comm, [u]) | ||
>>> for t in range(10): | ||
... u.interpolate(lambda x: t * (x[0] ** 2 + x[1] ** 2 + x[2] ** 2)) | ||
... my_export.write(t) | ||
""" | ||
|
||
def __init__(self, filename: str, field) -> None: | ||
self.filename = filename | ||
self.field = field | ||
|
||
@property | ||
def filename(self): | ||
return self._filename | ||
|
||
@filename.setter | ||
def filename(self, value): | ||
if not isinstance(value, str): | ||
raise TypeError("filename must be of type str") | ||
if not value.endswith(".bp"): | ||
raise ValueError("filename must end with .bp") | ||
self._filename = value | ||
|
||
@property | ||
def field(self): | ||
return self._field | ||
|
||
@field.setter | ||
def field(self, value): | ||
# check that field is festim.Species or list of festim.Species | ||
if not isinstance(value, F.Species) and not isinstance(value, list): | ||
raise TypeError( | ||
"field must be of type festim.Species or list of festim.Species" | ||
) | ||
# check that all elements of list are festim.Species | ||
if isinstance(value, list): | ||
for element in value: | ||
if not isinstance(element, F.Species): | ||
raise TypeError( | ||
"field must be of type festim.Species or list of festim.Species" | ||
) | ||
# if field is festim.Species, convert to list | ||
if not isinstance(value, list): | ||
value = [value] | ||
|
||
self._field = value | ||
|
||
def define_writer(self, comm: mpi4py.MPI.Intracomm, functions: list) -> None: | ||
"""Define the writer | ||
Args: | ||
comm (mpi4py.MPI.Intracomm): the MPI communicator | ||
functions (list): the list of functions to export | ||
""" | ||
self.writer = VTXWriter(comm, self.filename, functions, "BP4") | ||
|
||
def write(self, t: float): | ||
"""Write functions to VTX file | ||
Args: | ||
t (float): the time of export | ||
""" | ||
self.writer.write(t) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import festim as F | ||
import dolfinx | ||
from mpi4py import MPI | ||
import numpy as np | ||
|
||
import pytest | ||
|
||
mesh = dolfinx.mesh.create_unit_cube(MPI.COMM_WORLD, 10, 10, 10) | ||
V = dolfinx.fem.FunctionSpace(mesh, ("Lagrange", 1)) | ||
|
||
|
||
def test_vtx_export_one_function(tmpdir): | ||
"""Test can add one function to a vtx export""" | ||
u = dolfinx.fem.Function(V) | ||
|
||
filename = str(tmpdir.join("my_export.bp")) | ||
my_export = F.VTXExport(filename, field=F.Species("H")) | ||
my_export.define_writer(mesh.comm, [u]) | ||
|
||
for t in range(10): | ||
u.interpolate(lambda x: t * (x[0] ** 2 + x[1] ** 2 + x[2] ** 2)) | ||
|
||
my_export.write(t) | ||
|
||
|
||
def test_vtx_export_two_functions(tmpdir): | ||
"""Test can add two functions to a vtx export""" | ||
u = dolfinx.fem.Function(V) | ||
v = dolfinx.fem.Function(V) | ||
|
||
filename = str(tmpdir.join("my_export.bp")) | ||
my_export = F.VTXExport(filename, field=[F.Species("1"), F.Species("2")]) | ||
|
||
my_export.define_writer(mesh.comm, [u, v]) | ||
|
||
for t in range(10): | ||
u.interpolate(lambda x: t * (x[0] ** 2 + x[1] ** 2 + x[2] ** 2)) | ||
v.interpolate(lambda x: t * (x[0] ** 2 + x[1] ** 2 + x[2] ** 2)) | ||
|
||
my_export.write(t) | ||
|
||
|
||
def test_vtx_integration_with_h_transport_problem(tmpdir): | ||
my_model = F.HydrogenTransportProblem() | ||
my_model.mesh = F.Mesh1D(vertices=np.array([0.0, 1.0, 2.0, 3.0, 4.0])) | ||
my_mat = F.Material(D_0=1, E_D=0, name="mat") | ||
my_model.subdomains = [ | ||
F.VolumeSubdomain1D(1, borders=[0.0, 4.0], material=my_mat), | ||
F.SurfaceSubdomain1D(1, x=0.0), | ||
F.SurfaceSubdomain1D(2, x=4.0), | ||
] | ||
my_model.species = [F.Species("H")] | ||
my_model.temperature = 500 | ||
|
||
filename = str(tmpdir.join("my_export.bp")) | ||
my_export = F.VTXExport(filename, field=my_model.species[0]) | ||
my_model.exports = [my_export] | ||
|
||
my_model.initialise() | ||
|
||
for t in range(10): | ||
my_export.write(t) | ||
|
||
|
||
def test_field_attribute_is_always_list(): | ||
"""Test that the field attribute is always a list""" | ||
my_export = F.VTXExport("my_export.bp", field=F.Species("H")) | ||
assert isinstance(my_export.field, list) | ||
|
||
my_export = F.VTXExport("my_export.bp", field=[F.Species("H")]) | ||
assert isinstance(my_export.field, list) | ||
|
||
|
||
@pytest.mark.parametrize("field", ["H", 1, [F.Species("H"), 1]]) | ||
def test_field_attribute_raises_error_when_invalid_type(field): | ||
"""Test that the field attribute raises an error if the type is not festim.Species or list""" | ||
with pytest.raises(TypeError): | ||
F.VTXExport("my_export.bp", field=field) | ||
|
||
|
||
def test_filename_raises_error_with_wrong_extension(): | ||
"""Test that the filename attribute raises an error if the extension is not .bp""" | ||
with pytest.raises(ValueError): | ||
F.VTXExport("my_export.txt", field=[F.Species("H")]) | ||
|
||
|
||
def test_filename_raises_error_when_wrong_type(): | ||
"""Test that the filename attribute raises an error if the extension is not .bp""" | ||
with pytest.raises(TypeError): | ||
F.VTXExport(1, field=[F.Species("H")]) |