| ... | ... | @@ -5,9 +5,60 @@ This page details how to add your own features to the code. Everything has been |
|
|
|
|
|
|
|
## Adding Problem
|
|
|
|
|
|
|
|
Adding a new problem to the code is probably the most difficult/time-consuming feature to add, mostly because it requires you to understand both how to use FEniCS in general, as well as how our specific code handles solving. Before attempting this, it is recommended that you refresh yourself on the AbstractProblem class (documentation for it can be found in [Base Classes](Base Classes). Always remember that you can look to existing [Problems](Problems) for guidance on general formatting.
|
|
|
|
Adding a new problem to the code is probably the most difficult/time-consuming feature to add, mostly because it requires you to understand both how to use FEniCS in general, as well as how our specific code handles solving. Before attempting this, it is recommended that you refresh yourself on the AbstractProblem class (documentation for it can be found in [Base Classes](Base Classes)). Always remember that you can look to existing [Problems](Problems) for guidance on general formatting.
|
|
|
|
|
|
|
|
[TODO: finish writing this section]
|
|
|
|
To create a new problem, these are the general steps to follow:
|
|
|
|
|
|
|
|
1. Create a new python file in src and name it something unique and descriptive, then go edit it
|
|
|
|
|
|
|
|
2. Add all relevant import statements, in all cases you will need at least these lines:
|
|
|
|
```
|
|
|
|
import dolfin as d
|
|
|
|
import numpy as np
|
|
|
|
from BaseClasses import AbstractProblem
|
|
|
|
```
|
|
|
|
|
|
|
|
3. Add any classes you will need for solving your equations with FEniCS, these may be classes for periodic boundary, or
|
|
|
|
initial conditions of solutions, or expressions you want for your equations. If you don't know yet which of these you will
|
|
|
|
need, that's okay, you can go back and add them later when you need them
|
|
|
|
|
|
|
|
4. Create the class for your new problem, name it something unique and descriptive and make sure that it inherits from
|
|
|
|
AbstractProblem
|
|
|
|
|
|
|
|
5. Create an `__init__(self, params, mesh_factory)` method, and add these lines to it:
|
|
|
|
```
|
|
|
|
super().__init__(params, mesh_factory)
|
|
|
|
self.mesh = mesh_factory.mesh
|
|
|
|
```
|
|
|
|
|
|
|
|
6. Add whatever other variables/parameters you need for solving, at the very least time dependent problems will typically need
|
|
|
|
a time variable, an integer variable to count the step the problem is currently on, and a time_step so it knows how much to
|
|
|
|
increment the time on each step
|
|
|
|
|
|
|
|
7. Set up the finite element function spaces you want using FEniCS and then call `super().add_function_space()` passing this
|
|
|
|
function the associated solution name and the function space.
|
|
|
|
|
|
|
|
8. Create the necessary functions, test functions, trial functions. Then with these set up your equations, and if you wish you
|
|
|
|
can also configure solvers for each of the equations. Once you have done all this, call `super().add_solution()` for each
|
|
|
|
solution, passing it a string with a label for the solution, the function object associated with the solution, the left-
|
|
|
|
hand side of the equation, the right-hand side of the equation, and the solver if you configured it.
|
|
|
|
|
|
|
|
9. Call `super().add_bc()` for however many boundary conditions you want, passing in the tag associated with the solution this
|
|
|
|
boundary condition is being applied on (it should be the same tag as assigned in step 8), the function space for this
|
|
|
|
solution, the expression for what you want the boundary condition to be (Dirichlet BCs only), and an expression for the
|
|
|
|
boundary itself. If you are solving TDGL, the boundary condition should be on 'sigma' (the magnetic field) and you can use
|
|
|
|
`*mesh_factory.get_dbc_args()` as the boundary argument (note the use of the unpacking operator * here is important).
|
|
|
|
|
|
|
|
10. Create a method `solve(self)`. For time-dependent problems you should increment the time here, as well as the solution
|
|
|
|
counter, and update any time-dependent quantities. You can also have it print out info here, like what the current step is
|
|
|
|
or other useful problem-specific info. Make sure to put `super().solve()` at the end of this method so that the rest of
|
|
|
|
the solving can take place.
|
|
|
|
|
|
|
|
11. Once you are sure the problem works correctly, commit your changes and merge the branch you are working on back into dev
|
|
|
|
and push your changes to the remote repository
|
|
|
|
|
|
|
|
12. Add your new problem to the [Problems](Problems) page on the wiki and follow the formatting of the other problems on that
|
|
|
|
page (give a description of what the problem is, what solutions it has, and what parameters are needed for it).
|
|
|
|
|
|
|
|
## Adding Observers
|
|
|
|
|
| ... | ... | |