diff --git a/CITATION.cff b/CITATION.cff index b1ba02421..a51d8c048 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -10,7 +10,7 @@ authors: - given-names: James family-names: Dark -repository-code: 'https://github.com/RemDelaporteMathurin/FESTIM' +repository-code: 'https://github.com/festim-dev/FESTIM' version: 0.8.1 preferred-citation: authors: diff --git a/docs/source/api/settings.rst b/docs/source/api/settings.rst index 01f3ee508..3f4f82b9d 100644 --- a/docs/source/api/settings.rst +++ b/docs/source/api/settings.rst @@ -1,3 +1,5 @@ +.. _settings_api: + Settings ======== diff --git a/docs/source/conf.py b/docs/source/conf.py index 0844d3491..9aaeac26e 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -43,6 +43,8 @@ "matplotlib.sphinxext.plot_directive", ] +napoleon_use_ivar = True # needed to correctly format class attributes + # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] diff --git a/docs/source/devguide/index.rst b/docs/source/devguide/index.rst index 064f770d3..56c793d77 100644 --- a/docs/source/devguide/index.rst +++ b/docs/source/devguide/index.rst @@ -26,22 +26,21 @@ And/or contribute to the source code by: Contributing to the code ------------------------ -.. admonition:: Tip - :class: tip +.. tip:: - If you're a beginner, look for `issues tagged with "Good first issue" `_. + If you're a beginner, look for `issues tagged with "Good first issue" `_. - These issues are usually fairly easy to tackle and therefore perfect for newcomers. + These issues are usually relatively easy to tackle and perfect for newcomers. -1) `Fork the repository `_ +1) `Fork the repository `_ -By forking the repository, you create a copy of it where you can safely make changes. +By forking the repository, you create a copy where you can safely make changes. 2) Make your changes -3) `Open a PR `_ +3) `Open a PR `_ 4) Wait for a maintainer to review your PR -Before merging your changes, they have to be reviewed. During the review, we make sure the changes don't break anything and eventually propose/request improvements. +Before merging your changes, they have to be reviewed. We ensure the changes don't break anything during the review and eventually propose/request improvements. The time before the review will depend on the maintainers' availability. 5) When everything is in order, the maintainers will merge your PR! @@ -50,17 +49,16 @@ The time before the review will depend on the maintainers' availability. Test suite ---------- -FESTIM uses continuous integration (CI) to ensure code quality and eliminate as much bugs as possible. +FESTIM uses continuous integration (CI) to ensure code quality and eliminate as many bugs as possible. In a nutshell, every time a change is pushed to the repository (or to a PR), a suite of tests is automatically triggered. This is to make sure the changes don't break existing functionalities. It is also very useful to catch bugs that developers could have missed. Click `here `_ for more information on CI. -All the tests can be found in the `test folder `_ at the root of the FESTIM repository. +All the tests can be found in the `test folder `_ at the root of the FESTIM repository. -.. admonition:: Tip - :class: tip +.. note:: If you have installed the FEniCS Anaconda python package, make sure to install pytest to run the test suite locally: @@ -85,7 +83,7 @@ Debugging When you find a bug in the code, there are several steps to follow to make things easier for maintainers. -#. | `Raise an issue `_ +#. | `Raise an issue `_ | | This is important to keep track of things. | The issue is a place to talk about the bug, troubleshoot users and sometimes find workarounds. @@ -102,7 +100,7 @@ When you find a bug in the code, there are several steps to follow to make thing Implementing a new feature -------------------------- -#. | `Raise an issue `_ +#. | `Raise an issue `_ | | Before spending time implementing a new great feature, it is better to open an issue first to discuss with the maintainers. | For all you know, someone is already working at implementing it and all your time would be spent for nothing. diff --git a/docs/source/userguide/beginners_guide.rst b/docs/source/userguide/beginners_guide.rst index 341da97f5..277eb6c48 100644 --- a/docs/source/userguide/beginners_guide.rst +++ b/docs/source/userguide/beginners_guide.rst @@ -6,16 +6,31 @@ A beginner's guide to FESTIM What do I need to know? ----------------------- -To make the most out of FESTIM, a basic knowledge of `Python `_ is required. - -Depending on how you install FESTIM, new users should familiarise with either `Docker `_ or `Conda `_. - -FESTIM is under version control with `git `_. Even though users don't need git to install FESTIM, it is convenient to have a basic understanding of how it works. You can fin `git turorials `_ to help you getting started. The `FESTIM source code `_ is hosted on GitHub. It is recommended to sign up for free to GitHub in order to receive the latest updates, follow the development and submit `bug reports `_. +Basic knowledge of `Python `_ is required to make the most out of FESTIM. +New users should familiarise themselves with `Conda `_. +FESTIM is under version control with `git `_. Even though users don't need git to install FESTIM, it is convenient to understand how it works. You can find `git tutorials `_ to help you getting started. The `FESTIM source code `_ is hosted on GitHub. Signing up for free to GitHub is recommended to receive the latest updates, follow the development and submit `bug reports `_. ---------------------- Where can I find help? ---------------------- -If you're having an issue, the best way to find help is to join the `FESTIM discourse `_. Engage in discussions, ask questions, and connect with other users. This is a collaborative space where you can share your experiences and seek assistance. +If you're having an issue, the best way to find help is to join the `FESTIM discourse `_. Engage in discussions, ask questions, and connect with other users. This collaborative space allows you to share your experiences and seek assistance. + + +-------------- +Install FESTIM +-------------- + +Follow the :ref:`installation instructions` to install FESTIM on your computer. + +------------------------ +Your first FESTIM script +------------------------ + + +Follow `this tutorial `_ to learn how +to run a simple 1D diffusion problem in steady state with an homogeneous temperature, a volumetric source of hydrogen, +and the concentration fixed at zero at boundaries. + diff --git a/docs/source/userguide/boundary_conditions.rst b/docs/source/userguide/boundary_conditions.rst index a48e49899..cde7f9942 100644 --- a/docs/source/userguide/boundary_conditions.rst +++ b/docs/source/userguide/boundary_conditions.rst @@ -14,14 +14,15 @@ These BCs can be used for heat transfer or hydrogen transport simulations. Imposing the solution ^^^^^^^^^^^^^^^^^^^^^ +The value of solutions (concentration, temperature) can be imposed on boundaries with :class:`festim.DirichletBC`: + .. code-block:: python my_bc = DirichletBC(surfaces=[2, 4], value=10, field=0) -.. admonition:: Note - :class: tip +.. note:: - Here, we set :code:`field=0` to specify this BC applies to the mobile hydrogen concentration. :code:`1` would stand for the trap 1 concentration and :code:`"T"` for temperature. + Here, we set :code:`field=0` to specify that this BC applies to the mobile hydrogen concentration. :code:`1` would stand for the trap 1 concentration, and :code:`"T"` for temperature. The `value` argument can be space and time dependent by making use of the FESTIM variables ``x``, ``y``, ``z`` and ``t``: @@ -42,7 +43,7 @@ To use more complicated mathematical expressions, you can use the sympy package: - CustomDirichlet -The value of the concentration field can be temperature-dependent (useful when dealing with heat-transfer solvers) with :code:`CustomDirichlet`: +The value of the concentration field can be temperature-dependent (useful when dealing with heat-transfer solvers) with :class:`festim.CustomDirichlet`: .. code-block:: python @@ -54,7 +55,7 @@ The value of the concentration field can be temperature-dependent (useful when d Imposing the flux ^^^^^^^^^^^^^^^^^ -When the flux needs to be imposed on a boundary, use the :code:`FluxBC` class. +When the flux needs to be imposed on a boundary, use the :class:`festim.FluxBC` class. .. code-block:: python @@ -81,7 +82,7 @@ Some BCs are specific to hydrogen transport. FESTIM provides a handful of conven Recombination flux ^^^^^^^^^^^^^^^^^^ -Recombination flux can be set on boundaries as: :math:`Kr \, c_\mathrm{m}^n`. +A recombination flux can be set on boundaries as follows: :math:`Kr \, c_\mathrm{m}^n` (See :class:`festim.RecombinationFlux`). Where :math:`Kr` is the recombination coefficient, :math:`c_\mathrm{m}` is the mobile hydrogen concentration and :math:`n` is the recombination order. .. code-block:: python @@ -92,7 +93,7 @@ Where :math:`Kr` is the recombination coefficient, :math:`c_\mathrm{m}` is the m Dissociation flux ^^^^^^^^^^^^^^^^^^ -Dissociation flux can be set on boundaries as: :math:`Kd \, P`. +Dissociation flux can be set on boundaries as: :math:`Kd \, P` (see :class:`festim.DissociationFlux`). Where :math:`Kd` is the dissociation coefficient, :math:`P` is the partial pressure of hydrogen. .. code-block:: python @@ -103,7 +104,7 @@ Where :math:`Kd` is the dissociation coefficient, :math:`P` is the partial press Sievert's law of solubility ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Impose the mobile concentration of hydrogen as :math:`c_\mathrm{m} = S(T) \sqrt{P}` where :math:`S` is the Sievert's solubility and :math:`P` is the partial pressure of hydrogen. +Impose the mobile concentration of hydrogen as :math:`c_\mathrm{m} = S(T) \sqrt{P}` where :math:`S` is the Sievert's solubility and :math:`P` is the partial pressure of hydrogen (see :class:`festim.SievertsBC`). .. code-block:: python @@ -115,7 +116,7 @@ Impose the mobile concentration of hydrogen as :math:`c_\mathrm{m} = S(T) \sqrt{ Henry's law of solubility ^^^^^^^^^^^^^^^^^^^^^^^^^ -Similarily, the mobile concentration can be set from Henry's law of solubility :math:`c_\mathrm{m} = K_H P` where :math:`K_H` is the Henry solubility. +Similarly, the mobile concentration can be set from Henry's law of solubility :math:`c_\mathrm{m} = K_H P` where :math:`K_H` is the Henry solubility (see :class:`festim.HenrysBC`). .. code-block:: python @@ -127,28 +128,8 @@ Similarily, the mobile concentration can be set from Henry's law of solubility : Plasma implantation approximation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -A plasma implantation can be approximated by: - -.. math:: - - c_\mathrm{m} = \frac{\varphi_\mathrm{imp} \, R_p}{D} + \sqrt{\frac{\varphi_\mathrm{imp} + Kd \cdot P}{Kr}} - -Where :math:`\varphi_\mathrm{imp}` is the implanted flux, :math:`R_p` is the implantation depth, :math:`D` is the diffusion coefficient, :math:`Kd` is the dissociation coefficient, :math:`P` is the partial pressure of hydrogen, and :math:`Kr` is the recombination coefficient. - -When :math:`P = 0`: - -.. math:: - c_\mathrm{m} = \frac{\varphi_\mathrm{imp} \, R_p}{D} + \sqrt{\frac{\varphi_\mathrm{imp}}{Kr}} - -Moreover, assuming an instantaneous recombination :math:`Kr = \infty`: - -.. math:: - c_\mathrm{m} = \frac{\varphi_\mathrm{imp} \, R_p}{D} - -.. admonition:: Note - :class: tip +Plasma implantation can be approximated by a Dirichlet boundary condition with the class :class:`festim.ImplantationDirichlet` . Refer to the :ref:`theory` section for more details. - Refer to the :ref:`theory` section for more details. .. code-block:: python @@ -166,7 +147,7 @@ Heat transfer BCs ----------------- -A convective heat flux can be set as :math:`\mathrm{flux} = - h (T - T_\mathrm{ext})`. +A convective heat flux can be set as :math:`\mathrm{flux} = - h (T - T_\mathrm{ext})` (see :class:`festim.ConvectiveFlux`). .. code-block:: python diff --git a/docs/source/userguide/export_post_processing.rst b/docs/source/userguide/export_post_processing.rst index b6a5601bc..5fbcbb5b1 100644 --- a/docs/source/userguide/export_post_processing.rst +++ b/docs/source/userguide/export_post_processing.rst @@ -1,3 +1,229 @@ =============== Post-processing -=============== \ No newline at end of file +=============== + +Exports are added to the simulation object as a list of :class:`festim.Export` objects: + +.. code-block:: python + + import festim as F + + my_model = F.Simulation() + + my_model.exports = [..., ...] + +------------------- +Exporting solutions +------------------- + +^^^^^^^^^^^ +XDMF export +^^^^^^^^^^^ + +The most straightforward way to export solutions (concentrations, temperature) with FESTIM is to use the :class:`festim.XDMFExport` class. +This class leverages the ``XDMFFile`` class of ``fenics`` and allows solutions to be exported in the XDMF format. +The following example shows how to export the solution of a 1D problem: + +.. code-block:: python + + import festim as F + + my_model = F.Simulation() + my_model.mesh = F.MeshFromVertices([0, 1, 2, 3]) + my_model.materials = F.Material(id=1, D_0=1, E_D=0) + my_model.boundary_conditions = [ + F.DirichletBC(surfaces=[1, 2], value=0, field="solute"), + ] + my_model.sources = [F.Source(value=1, volume=1, field="solute")] + + my_model.T = F.Temperature(500) + + my_model.exports = [ + F.XDMFExport( + "solute", # the field we want to export + label="mobile", # how the field will be labelled in the XDMF file + filename="./mobile_conc.xdmf", + checkpoint=False, # needed in 1D + ) + ] + + my_model.settings = F.Settings( + absolute_tolerance=1e-10, relative_tolerance=1e-10, transient=False + ) + + my_model.initialise() + my_model.run() + + +Running this should produce a file called ``mobile_conc.xdmf`` in the current directory. +The file can then be opened in Paraview or any other software that can read XDMF files. + +For transient simulations, by default, :class:`festim.XDMFExport` will export the solution at each timestep. +It is possible to change this behaviour to limit the number of times the file is written to. +By setting the ``mode`` attribute to ``10``, for example, the solution will be exported every 10 timesteps. +Setting it to ``last`` will export the solution only at the last timestep. + +.. code-block:: python + + my_model.exports = [ + F.XDMFExport( + "solute", + label="mobile", + filename="./mobile_conc.xdmf", + checkpoint=False, + mode=10, + ) + ] + +The ``checkpoint`` attribute must be set to ``True`` for the XDMF file to be readable by Paraveiw. + +^^^^^^^^^^^^^^^ +TXT export (1D) +^^^^^^^^^^^^^^^ + +The ``TXTExport`` class allows solutions to be exported in a simple text format. +It works in 1D only. For multi-dimensional problems, use the :class:`festim.XDMFExport` class instead. + +.. code-block:: python + + import festim as F + + my_export = F.TXTExport(field="solute", filename="./mobile_conc.txt") + +Adding this export to the simulation object will produce a file called ``mobile_conc.txt`` in the current directory. +This file will contain the solution of the ``solute`` field at the degrees of freedom of the mesh and at each timestep. + +To only export at specific times in the simulation, use the ``times`` argument: + +.. code-block:: python + + my_export = F.TXTExport( + field="solute", filename="./mobile_conc.txt", times=[0, 1, 2, 3] + ) + +^^^^^^^^^^^ +Point value +^^^^^^^^^^^ + +If information about the solution at a specific point is needed, the :class:`festim.PointValue` class can be used. +It is implemented as a derived quantity. See :ref:`Derived quantities` for more information. Here are a few examples: + +.. code-block:: python + + import festim as F + + my_export = F.PointValue(field="solute", x=[0.5, 0.5, 0.5]) + my_export = F.PointValue(field="solute", x=(0.5, 0.5, 0.5)) + my_export = F.PointValue(field="solute", x=[0.5, 0.5]) + my_export = F.PointValue(field="solute", x=[0.5]) + my_export = F.PointValue(field="solute", x=0.5) + +------------------ +Derived quantities +------------------ + +In addition to exporting the actual solutions, it is possible to export derived quantities. +For instance, you may want to compute the flux of mobile particles at a given boundary. + +First, you want to create a :class:`festim.DerivedQuantities` object. This will encompass all the derived quantities you want to compute. +Then, you can add the derived quantities you want to compute to this object. +Finally, you can add the :class:`festim.DerivedQuantities` object to the simulation object. + +.. code-block:: python + + my_derived_quantities = F.DerivedQuantities( + [ + F.SurfaceFlux(field="solute", surface=3), + F.SurfaceFlux(field="T", surface=1), + F.AverageVolume(field="retention", volume=1), + F.TotalVolume(field="retention", volume=2), + ] + ) + + my_model.exports = [my_derived_quantities, ....] + + +The complete list of derived quantities can be found at: :ref:`Exports`. + +The data can be accessed in three different ways: +- directly from the :class:`festim.DerivedQuantities` (plural) object: + +.. code-block:: python + + my_derived_quantities = F.DerivedQuantities( + [ + F.SurfaceFlux(field="solute", surface=3), + F.SurfaceFlux(field="T", surface=1), + F.AverageVolume(field="retention", volume=1), + F.TotalVolume(field="retention", volume=2), + ] + ) + + my_model.exports = [my_derived_quantities, ....] + + my_model.initialise() + my_model.run() + + print(my_derived_quantities.t) + print(my_derived_quantities.data) + +- from the :class:`festim.DerivedQuantity` (singular) object (eg. ``F.SurfaceFlux(...)``): + +.. code-block:: python + + flux_surf_3 = F.SurfaceFlux(field="solute", surface=3) + + my_derived_quantities = F.DerivedQuantities( + [ + flux_surf_3, + F.SurfaceFlux(field="T", surface=1), + F.AverageVolume(field="retention", volume=1), + F.TotalVolume(field="retention", volume=2), + ] + ) + + my_model.exports = [my_derived_quantities, ....] + + my_model.initialise() + my_model.run() + + print(flux_surf_3.t) + print(flux_surf_3.data) + print(my_derived_quantities.derived_quantities[2].data) + +- export and read from a .csv file: + +.. code-block:: python + + my_derived_quantities = F.DerivedQuantities( + [ + F.SurfaceFlux(field="solute", surface=3), + F.SurfaceFlux(field="T", surface=1), + F.AverageVolume(field="retention", volume=1), + F.TotalVolume(field="retention", volume=2), + ], + filename="./my_derived_quantities.csv", + ) + + my_model.exports = [my_derived_quantities, ....] + + my_model.initialise() + my_model.run() + + +By default, the derived quantities will be computed at each timestep and exported at the last timestep. +This behaviour can be changed by setting the ``nb_iterations_between_compute`` and ``nb_iterations_between_exports`` attributes of the :class:`festim.DerivedQuantities` object. + +.. code-block:: python + + my_derived_quantities = F.DerivedQuantities( + [ + F.SurfaceFlux(field="solute", surface=3), + F.SurfaceFlux(field="T", surface=1), + F.AverageVolume(field="retention", volume=1), + F.TotalVolume(field="retention", volume=2), + ], + filename="./my_derived_quantities.csv", + nb_iterations_between_compute=3, # compute quantities every 3 timesteps + nb_iterations_between_exports=10, # export every 10 timesteps + ) diff --git a/docs/source/userguide/index.rst b/docs/source/userguide/index.rst index 094df1ce3..891cc9c0c 100644 --- a/docs/source/userguide/index.rst +++ b/docs/source/userguide/index.rst @@ -10,11 +10,12 @@ User's Guide units materials boundary_conditions + initial_conditions sources temperature mesh traps settings + stepsize export_post_processing - simulations troubleshooting \ No newline at end of file diff --git a/docs/source/userguide/initial_conditions.rst b/docs/source/userguide/initial_conditions.rst new file mode 100644 index 000000000..11f590a36 --- /dev/null +++ b/docs/source/userguide/initial_conditions.rst @@ -0,0 +1,44 @@ +================== +Initial conditions +================== + +The initial conditions are essential to transient FESTIM simulations. They describe the mathematical problem at the beginning of the simulation. +By default, the initial conditions are set to zero. +However, it is possible to set the initial conditions with the :class:`festim.InitialCondition` class. + +.. code-block:: python + + import festim as F + + my_ic = F.InitialCondition(value=10, field=0) + +The value can also be a function of space: + +.. code-block:: python + + import festim as F + from festim import x, y, z + + my_ic = F.InitialCondition(value=x**2 + y**2 + z**2, field=0) + +Initial conditions can also be read from a previously written XDMF file. This is useful when restarting a simulation. + +.. code-block:: python + + import festim as F + + my_ic = F.InitialCondition( + filename="ic_file.xdmf", + label="mobile", + timestep=-1, + field=0 + ) + +In the snippet above, the initial condition is read from the file ``ic_file.xdmf``. +The label ``mobile`` is used to identify the mesh in the file. +The timestep ``-1`` indicates that the last timestep of the file should be read. + +.. note:: + + The XDMF file must be readable. To do so, the XDMF file must be created with checkpointing. See :class:`festim.XDMFExport`. + For more information on checkpointing in FEniCS, see `this page `_. diff --git a/docs/source/userguide/materials.rst b/docs/source/userguide/materials.rst index 7781253ff..6b06f3271 100644 --- a/docs/source/userguide/materials.rst +++ b/docs/source/userguide/materials.rst @@ -2,9 +2,9 @@ Materials ========= -Materials are key components of hydrogen transport simulations. They hold the properties like diffusivity, solubility and even thermal properties like thermal conductivity or heat capacity. +Materials are vital components of hydrogen transport simulations. They hold diffusivity, solubility and thermal properties like thermal conductivity or heat capacity. -To define a material, use the :code:`Material` class: +To define a material, use the :class:`festim.Material` class: .. code-block:: python @@ -22,9 +22,9 @@ Materials are then assigned to the model: Parameters description ---------------------- -The :code:`Material` class has three required arguments: +The :class:`festim.Material` class has three required arguments: -* :code:`id`: a unique id given to the material/volume. It is useful when defining volumetric source terms or exports. Several ids can be given to the same material if multiple volumes have the same material. +* :code:`id`: a unique id given to the material/volume. It is useful when defining volumetric source terms or exports. Several id's can be given to the same material if multiple volumes have the same material. * :code:`D_0`: the diffusivity pre-exponential factor expressed in m2/s * :code:`E_D`: the diffusivity activation energy in eV @@ -35,12 +35,12 @@ Some other parameters are optional and are only required for some types of simul * :code:`thermal_cond`: the thermal conductivity in W/m/K * :code:`heat_capacity`: the heat capacity in J/kg/K * :code:`rho`: the volumetric density in kg/m3 - +* :code:`H`: the heat of transport in J/mol that takes a dictionary {"free_enthalpy": …, "entropy": …} so that H = free_enthalpy + entropy*T. For more information see :ref:`Soret effect`. -------------------- Integration with HTM -------------------- -H-transport-materials (HTM) is a python database of hydrogen transport properties. +H-transport-materials (HTM) is a Python database of hydrogen transport properties. Using this database will avoid making copy-pasting errors and add consistency across simulations by making sure the same properties are used. -HTM can be easily `integrated with FESTIM `_. +HTM can be easily `integrated with FESTIM `_. diff --git a/docs/source/userguide/mesh.rst b/docs/source/userguide/mesh.rst index f7b40b879..c2b7a2a4c 100644 --- a/docs/source/userguide/mesh.rst +++ b/docs/source/userguide/mesh.rst @@ -9,7 +9,7 @@ As FESTIM is not a meshing tool, the meshing capabilities are limited to simple 1D meshes --------- -The easiest way to define a 1D mesh in FESTIM is to define it from a list of vertices: +The easiest way to define a 1D mesh in FESTIM is to define it from a list of vertices (see :class:`festim.MeshFromVertices`): .. code-block:: python @@ -42,7 +42,7 @@ Numpy arrays can be combined to have local refinements: Meshes from XDMF ---------------- -More complex meshes can be read from XDMF files: +More complex meshes can be read from XDMF files (see :class:`festim.MeshFromXDMF`): .. code-block:: python @@ -56,7 +56,7 @@ GMSH example The DOLFINx tutorial gives an `example `_ of mesh generation with gmsh. ------------------ -meshes from FEniCS +Meshes from FEniCS ------------------ See the `FEniCS documentation `_ for more built-in meshes. diff --git a/docs/source/userguide/settings.rst b/docs/source/userguide/settings.rst index 4c99a64c1..0284fc503 100644 --- a/docs/source/userguide/settings.rst +++ b/docs/source/userguide/settings.rst @@ -2,7 +2,7 @@ Settings ======== -The settings of a FESTIM simulation are defined with a :code:`Settings` object. +The settings of a FESTIM simulation are defined with a :class:`festim.Settings` object. .. code-block:: python @@ -30,3 +30,5 @@ More advanced settings are also available: * the type of finite elements for traps (DG elements can be useful to account for discontinuities) * Wether to update the jacobian at each iteration or not * the linear solver + +See :ref:`settings_api` for more details. \ No newline at end of file diff --git a/docs/source/userguide/simulations.rst b/docs/source/userguide/simulations.rst deleted file mode 100644 index d7e5805f9..000000000 --- a/docs/source/userguide/simulations.rst +++ /dev/null @@ -1,10 +0,0 @@ -=========== -Simulations -=========== - - -WIP - ------------------ -Adaptive timestep ------------------ diff --git a/docs/source/userguide/sources.rst b/docs/source/userguide/sources.rst index d0ccbc192..8ae5ecc27 100644 --- a/docs/source/userguide/sources.rst +++ b/docs/source/userguide/sources.rst @@ -5,4 +5,62 @@ Sources ======= -WIP \ No newline at end of file +Volumetric sources +------------------ + +Volumetric sources can be set in a simulation by using the :class:`festim.Source` class. + +.. code:: python + + import festim as F + + my_model = F.Simulation() + + my_model.sources = [ + F.Source(value=1e20, volume=1, field=0), + F.Source(value=1e19 * F.x, volume=2, field=0), + ] + +For more information, see :class:`festim.Source`. + +Implantation flux +----------------- + +Hydrogen implanted in a material can be simulated by a Gaussian-shaped volumetric source with the :class:`festim.ImplantationFlux` class. + +.. code:: python + + import festim as F + + my_model = F.Simulation() + + my_model.sources = [ + F.ImplantationFlux( + flux=1e20, + imp_depth=1e-9, + width=1e-9, + volume=1, + ), + ] + +This class is used in `this tutorial `_. + + +Radioactive decay +----------------- + +Radioactive decay can be simulated by a volumetric source with the :class:`festim.RadioactiveDecay` class. + +.. code:: python + + import festim as F + + my_model = F.Simulation() + + my_model.sources = [ + F.RadioactiveDecay( + decay_constant=1.78e-9, + volume=1, + fields="all", + ), + ] diff --git a/docs/source/userguide/stepsize.rst b/docs/source/userguide/stepsize.rst new file mode 100644 index 000000000..bd7d34e1e --- /dev/null +++ b/docs/source/userguide/stepsize.rst @@ -0,0 +1,43 @@ +Stepsize +======== + + +For transient problems, a :class:`festim.Stepsize` is required. +It represents the time discretisation of the problem. +Here is an example creating a stepsize of 1.2 seconds: + +.. code-block:: python + + import festim as F + my_stepsize = F.Stepsize(initial_value=1.2) + +To use of the adaptive time stepping implemented in FESTIM, the arguments ``stepsize_change_ratio`` needs to be set to a value above 1. + +.. code-block:: python + + my_stepsize = F.Stepsize(initial_value=1.2, stepsize_change_ratio=1.5) + +When doing so, the stepsize will grow according to this ratio when the numerical solver converges in 4 iterations or less. +It will shrink by the same ratio when the solver needs more than 4 iterations to converge. +This is extremely useful when solving transient problems with a large time range, as the time step will be large when the solution is smooth and small when the solution is changing rapidly. +Moreover, if the solver doesn't converge, the stepsize will be reduced and the solver will be called again. +Setting the ``dt_min`` argument will prevent the stepsize from becoming too small and will stop the simulation when this happens. +To cap the stepsize after some time, the parameters ``t_stop`` and ``stepsize_stop_max`` can be used. + +.. code-block:: python + + my_stepsize = F.Stepsize(initial_value=1.2, stepsize_change_ratio=1.5, dt_min=1e-6, t_stop=10, stepsize_stop_max=1.5) + +The ``milestones`` argument can be used to make sure the simulation passes through specific times. +This will modify the stepsize as needed. + +.. code-block:: python + + my_stepsize = F.Stepsize( + initial_value=1.2, + stepsize_change_ratio=1.5, + dt_min=1e-6, + t_stop=10, + stepsize_stop_max=1.5, + milestones=[1, 5, 6, 10] + ) \ No newline at end of file diff --git a/docs/source/userguide/temperature.rst b/docs/source/userguide/temperature.rst index 934ee5a8d..c2d6c450d 100644 --- a/docs/source/userguide/temperature.rst +++ b/docs/source/userguide/temperature.rst @@ -46,12 +46,14 @@ would be passed to FESTIM as: my_temp = Temperature(sp.exp(x)*sp.sin(t)) +For more details, see :class:`festim.Temperature`. + --------------------------- From a heat transfer solver --------------------------- Temperature can also be obtained by solving the heat equation. -Users can define heat transfer problems using :code:`HeatTransferProblem`. +Users can define heat transfer problems using :class:`festim.HeatTransferProblem`. .. code-block:: python @@ -65,3 +67,18 @@ For a steady-state problem: my_temp = HeatTransferProblem(transient=False) :ref:`Boundary conditions` and :ref:`heat sources` can then be applied to this heat transfer problem. + +---------------- +From a XDMF file +---------------- + +Temperature can also be read from a XDMF file (see :class:`festim.TemperatureFromXDMF`). + +.. code-block:: python + + my_temp = TemperatureFromXDMF('temperature.xdmf', label='temperature') + +.. note:: + + The XDMF file must contain a scalar field named 'temperature'. + Moreover, it has to have been exported in "checkpoint" mode (see :ref:`XDMF export`). diff --git a/docs/source/userguide/traps.rst b/docs/source/userguide/traps.rst index cc85f78ea..6cc7dcb7f 100644 --- a/docs/source/userguide/traps.rst +++ b/docs/source/userguide/traps.rst @@ -24,7 +24,7 @@ A trap in FESTIM is defined by: my_trap = F.Trap(k_0=1e-16, E_k=0.2, p_0=1e13, E_p=0.8, density=1e16, materials=my_material) -If the trap is located in several materials, instead of creating another :code:`Trap` object, simply use a list of materials: +If the trap is located in several materials, instead of creating another :class:`festim.Trap` object, simply use a list of materials: .. code-block:: python @@ -90,11 +90,9 @@ If the temporal evolution of the trap's density is known `a priori`, then a "nor Grouped-trap ------------ -Let's imaging a case where you have two subdomains. Trap 1 is defined only in the first subdomain, whereas Trap 2 is defined in the second. -It would be possible to simply define one trap in each subdomain. - - -But grouping traps together helps saving computational time. +Let's imagine a case where you have two subdomains. Trap 1 is defined only in the first subdomain, whereas Trap 2 is defined in the second. +It would be possible to define one trap in each subdomain. +Grouping traps together helps save computational time by reducing the number of degrees of freedom. .. code-block:: python diff --git a/docs/source/userguide/troubleshooting.rst b/docs/source/userguide/troubleshooting.rst index af6f1dd1e..a999a8884 100644 --- a/docs/source/userguide/troubleshooting.rst +++ b/docs/source/userguide/troubleshooting.rst @@ -2,18 +2,64 @@ Troubleshooting =============== -WIP +---------------------- +Where can I find help? +---------------------- -------------------- -Where to find help? -------------------- +If you're having an issue, the best way to find help is to join the `FESTIM discourse `_. Engage in discussions, ask questions, and connect with other users. This collaborative space allows you to share your experiences and seek assistance. -- Github issues +------------- +Common issues +------------- ------------------- -Convergence issues ------------------- +Although FESTIM is designed to be easy to use, users may encounter some common issues. This section provides some guidance on how to resolve these issues. +We are simply solving a set of equations using the finite element method, and are, therefore, subject to the same issues that other FEM codes face. -- Converges with 0 iterations -- Try and visualise the fields -- Mesh refinement or time refinement \ No newline at end of file +^^^^^^^^^^^^^^^^^^^^^^^ +Solver doesn't converge +^^^^^^^^^^^^^^^^^^^^^^^ + +The first thing to check is the details of the Newton solver iterations. +To do so, you must set the ``log_level`` to ``20`` (default is ``40``). +This will provide more information during the solving stage. + +.. code-block:: python + + import festim as F + + my_model = F.Simulation() + + my_model.log_level = 20 + +From there, depending on the behaviour of the solver, you can try the following: +- if the solver diverges, try reducing the time step and/or mesh refinement. It is often + helpful to inspect the fields to see if there are any obvious issues (like lack of refinement). +- If the solver converges to a value above the tolerance, try increasing the tolerance. +Sometimes, the absolute tolerance is too low for the problem at hand, especially when dealing with large numbers. + + +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Solution is zero everywhere +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Sometimes, the solver converges fine but the solution is zero everywhere. +This is often due to an excessively high absolute tolerance. +The Newton solver then converges in zero iterations. In other words, nothing is solved. +First, check that this is the case by setting the log level to 20: + +.. code-block:: python + + import festim as F + + my_model = F.Simulation() + + my_model.log_level = 20 + +Then increase the absolute tolerance of the solver: + +.. code-block:: python + + my_model.settings = F.Settings( + ..., + absolute_tolerance=1e10, + ) \ No newline at end of file diff --git a/festim/exports/derived_quantities/derived_quantities.py b/festim/exports/derived_quantities/derived_quantities.py index a7798c6ee..5d7528d93 100644 --- a/festim/exports/derived_quantities/derived_quantities.py +++ b/festim/exports/derived_quantities/derived_quantities.py @@ -20,7 +20,8 @@ class DerivedQuantities: iterations between each derived quantities computation. Defaults to 1. nb_iterations_between_exports (int, optional): number of - iterations between each export. Defaults to None. + iterations between each export. If None, the file will be + exported at the last timestep. Defaults to None. """ def __init__( diff --git a/festim/exports/xdmf_export.py b/festim/exports/xdmf_export.py index f1205e085..6e8afeacf 100644 --- a/festim/exports/xdmf_export.py +++ b/festim/exports/xdmf_export.py @@ -127,7 +127,7 @@ def write(self, t): if dimension == 1: msg = "in 1D, checkpoint needs to be set to False to " msg += "visualise the XDMF file in Paraview (see issue " - msg += "https://github.com/RemDelaporteMathurin/festim/issues/134)" + msg += "https://github.com/festim-dev/festim/issues/134)" warnings.warn(msg) self.file.write_checkpoint( diff --git a/setup.cfg b/setup.cfg index 57de6f86a..dfb5b643c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -7,7 +7,7 @@ author_email = rdelaportemathurin@gmail.com description = Finite element simulations of hydrogen transport long_description = file: README.md long_description_content_type = text/markdown -url = https://github.com/RemDelaporteMathurin/FESTIM +url = https://github.com/festim-dev/FESTIM license = Apache-2.0 license_file = LICENSE classifiers = @@ -21,8 +21,8 @@ classifiers = License :: OSI Approved :: Apache Software License Operating System :: OS Independent project_urls = - Source = https://github.com/RemDelaporteMathurin/FESTIM - Tracker = https://github.com/RemDelaporteMathurin/FESTIM/issues + Source = https://github.com/festim-dev/FESTIM + Tracker = https://github.com/festim-dev/FESTIM/issues [options] packages = find: