The implementation exercise¶
The object of the implementation exercise is to gain an understanding of the finite element method by producing a working one and two dimensional finite element solver library. Along the way you will have the opportunity to pick up valuable scientific computing skills in coding, software engineering and rigorous testing.
This part of the module is very practical, and there are never conventional lectures for it, even when everything is taught on campus. Each week you should work through the notes and videos until you come to an exercise. Each exercise will invite you to implement another part of a finite element implementation, so that by the end of the term we will be solving finite element problems.
Along the way, there will be the opportunity to get help and feedback through the module Piazza board, weekly online labs, and through pull requests for feedback in weeks 4 and 7.
Formalities and marking scheme¶
The implementation exercise is due at 1300 on Friday 22 March 2024. Submission is via GitHub: the last commit pushed to GitHub and dated before the deadline will be marked.
The marking scheme will be as follows:
- First/distinction (70-100)
All parts of the implementation are correct and all tests pass. The code style is always very clear and the implementation of every exercise is transparent and elegant.
- Upper second/merit (60-70)
The implementation is correct but let down somewhat by poor coding style. Alternatively, submissions which are correct and well written up to and including solving the Helmholtz problem but which do not include a correct solution to boundary conditions will earn an upper second.
- Lower second/pass (50-60)
There are significant failings in the implementation resulting in many test failures, and/or the coding style is sufficiently poor that the code is hard to understand.
- Fail (0-50)
The implementation is substantially incomplete. Correct implementations may have been provided for some of the earlier exercises but the more advanced parts of the implementation exercise have not been attempted or do not work.
Code execution performance is not a primary concern of this module, however the code must still be algorithmically correct. This means not just returning the correct answer but also having the correct algorithmic complexity. Occasionally students submit code that uses quadratic algorithms where linear ones would be possible. The result is that examples that should run in seconds and take megabytes of memory instead take gigabytes of memory and many hours to complete. Such submissions are incorrect, and will be marked as such.
Extension (mastery) exercise¶
Fourth year and masters students must also complete the mastery exercise, which is Section 9 This will be worth 20% of the implementation exercise marks and will be marked on the same scheme as above.
Obtaining the skeleton code¶
A video recording of the following material is available here.
Imperial students can also watch this video on Panopto
This section assumes you’ve already done everything to set up the software tools you need.
Set up a folder to hold the repository and virtual environment¶
You can call this folder anything you like, and store it anywhere that suits
you, though don’t move it once you’ve created it as this will break the virtual
environment. Suppose you would like to keep the new folder in a folder called
docs
in your home directory. We first open a
terminal and switch to the folder:
$ cd docs
Note that $ is the command prompt (which might be a different character such
as % or > for you). You don’t type the prompt. Start with cd. Next we
create the folder we’ll use for this course. Suppose we choose to call it
finite-element
, then we would type:
$ mkdir finite-element
mkdir stands for “make directory”. Directory is an alternative term to folder. Finally we switch (“change directory”) into that folder:
$ cd finite-element
Setting up your venv¶
We’re going to use a Python venv. This is a private Python environment in which we’ll install the packages we need, including our own implementation exercise. This minimises interference between this project and anything else which might be using Python on the system. With your current working folder set to the course folder, run:
$ python3 -m venv fe_venv
If your Python interpreter has a different name (e.g. python3.11 or py) then you type that instead.
Activating your venv¶
Every time you want to work on the implementation exercise, you need to activate the venv. On Linux or Mac do this with:
$ source fe_venv/bin/activate
while on Windows the command is:
> source fe_venv/Scripts/activate
Obviously if you are typing this in a directory other than the one containing the venv, you need to modify the path accordingly.
Setting up your repository¶
We’re using a tool called GitHub classroom to automate the creation of your copies of the repository. To create your repository, click here.
Cloning a local copy¶
At the command line on your working machine type:
$ git clone <url> finite-element-course
Substituting your git repository url for <url>. Your git repository url can be found by clicking on clone or download at the top right of your repository page on GitHub.
Installing the course Python package¶
Your git repository contains a Python package. Installing this will cause the other Python packages on which it depends to be installed into your venv, and will create various visualisation scripts you’ll need later in the module. Run:
$ python -m pip install -e finite-element-course/
Skeleton code documentation¶
There is web documentation for the complete fe_utils package. There is also an alphabetical index and a search page.
How to do the implementation exercises¶
The implementation exercises build up a finite element library from its component parts. Quite a lot of the coding infrastructure you will need is provided already. Your task is to write the crucial mathematical operations at key points. The mathematical operations required are described on this website, interspersed with exercises which require you to implement and test parts of the mathematics.
The code on which you will build is in the fe_utils
directory of
your repository. The code has embedded documentation which is used to
build the fe_utils package web documentation.
As you do the exercises, commit your code to your repository. This will build up your finite element library. You should commit code early and often - small commits are easier to understand and debug than large ones.
Testing your work¶
As you complete the exercises, there will often be test scripts which
exercise the code you have just written. These are located in the
test
directory and employ the pytest
testing framework. You run the tests with:
$ py.test test_script.py
from the bash command line, replacing test_script.py
with the appropriate
test file name. The -x
option to py.test
will cause the test
to stop at the first failure it finds, which is often the best place
to start fixing a problem. For those familiar with debuggers, the
--pdb
option will drop you into the Python debugger at the first
error.
You can also run all the tests by running py.test
on the tests
directory. This works particularly well with the -x option, resulting
in the tests being run in course order and stopping at the first
failing test:
$ py.test -x tests/
Coding style and commenting¶
Computer code is not just functional, it also conveys information to the reader. It is important to write clear, intelligible code. The readability and clarity of your code will count for marks.
The Python community has agreed standards for coding, which are documented in PEP8. There are programs and editor modes which can help you with this. The skeleton implementation follows PEP8 quite closely. You are encouraged, especially if you are a more experienced programmer, to follow PEP8 in your implementation. However nobody is going to lose marks for PEP8 failures.
Getting help¶
It’s expected that you will find there are tasks in the implementation exercise that you don’t know how to do. Your first port of call should be the Ed forum, followed by the weekly live lab sessions.
Using Ed¶
The key advantage of asking for help on Ed is that you can do this at any point during the week, whenever you are stuck. The whole class can see the forum, but you can choose to publish anonymously so nobody need know who asked the question. You should also watch the other questions as they appear on Ed, because you will find that you learn a lot from what other people ask, as well as the answers they get. Other students might notice issues that didn’t even occur to you!
Do please try to answer other students’ questions. Doing so is actually a really effective way of understanding the work better, since you will be looking at the tasks from another student’s perspective.
Formulating a good question¶
One of the key skills in getting help with code is to ask the question in a structured way which provides all the information required by the person helping you. Not only does this radically increase the chances of getting a useful response first time, but often the process of thinking through how to ask the question leads you to its solution before you even ask. Please review the information from the second year Principles of Programming instructions on raising an issue.
Note
Please don’t post large pieces of code to Piazza. Just post minimal examples if they help. However always commit and push your work, and post the git commit hash in the repository. The lecturer can always find your work from the git hash, so long as you’ve pushed to GitHub.
Tips and tricks for the implementation exercise¶
- Work from the documentation.
The notes, and particularly the exercise specifications, contain important information about how and what to implement. If you just read the source code then you will miss out on important information.
- Read the hints
The pink sections in the notes starting with a lightbulb are hints. Usually they contain suggestions about how to go about writing your answer, or suggest Python functions which you might find useful.
- Don’t forget the 1D case
Your finite element library needs to work in one and two dimensions.
- Return a
numpy.array()
Many of the functions you have to write return arrays. Make sure you actually return an array and not a list (it’s usually fine to build the answer as a list, but convert it to an array before you return it).