MATH4063_coursework2
MATH4063_coursework2
MATH4063_coursework2
Submission Date: Monday 6th January 2025, 15:00 (GMT) Assessed Coursework 2
The following questions are to be used for the coursework assessment in the module MATH4063.
A single zip file containing your answers to the questions below and the code you used to obtain these
answers should be submitted electronically via the MATH4063 Moodle page before the deadline at
the top of this page. You should follow the instructions on the accompanying Coursework Submission
template which is also provided on Moodle. Since this work is assessed, your submission must be
entirely your own work (see the University’s policy on Academic Misconduct).
The style and efficiency of your programs is important. A barely-passing solution will include attempts
to write programs which include some of the correct elements of a solution. A borderline distinction
solution will include working code that neatly and efficiently implements the relevant algorithms, and
that shows evidence of testing.
An indication is given of the weighting of each question by means of a figure enclosed by square
brackets, e.g. [12]. All non-integer calculations should be done in double precision.
Background Material
in which xq are the integration nodes and wq are the corresponding weights. In practice, the approxi-
mation of a definite integral would usually be done with a composite quadrature rule: the domain
Ω is divided into nPanels smaller subdomains Ωn , n = 1, . . . , nPanels (referred to from now on as
panels), so the integral can be written as
Z nPanels
X Z
f (x) dx = f (x) dx , (2)
Ω n=1 Ωn
SnPanels
where n=1 Ωn = Ω and the subdomains do not overlap, i.e. the approximation to the integral is
the sum of the approximations over each panel.
in which J = A for a triangle or J = L for a line segment, and xk are the coordinates of the vertices
of the simplex. The normalised barycentric coordinates of the nodes for the quadrature rules to be
used in this coursework are shown in Table 1 with their corresponding weights.
where bj = xj · n, with xj any point on face Fj and n the unit normal to Fj pointing out of
Ω. Equation (8) provides an alternative approach to approximating an integral of a homogeneous
function.
2
(a) (c) x3 (d) x3
L2 L1
x1 x x2
3
(b) A2 A1
x 4
x1 1 2 x2 A3 1 2
x1 x2 x1 x2
Figure 1: (a) Barycentric coordinates (Li ) on a line segment; (b) a line segment panel with uniform refinement; (c)
barycentric coordinates (Ai ) on a triangle; (d) a triangular panel with uniform refinement.
Materials Provided
You should familiarise yourself with some additional code which has been provided in the folder
Templates/ to perform some of the tasks related to this coursework.
• The abstract class IntegralInterface encapsulates an interface to integration problems.
• GenerateMeshes.cpp creates uniform meshes of panels of triangles and line segments for,
respectively, a rectangle and its boundary, and outputs them in a standard format used in
unstructured computational mesh generation:
Row 1 n_dimensions n_panel_vertices n_vertices n_panels
Next n_vertices rows vertex_x vertex_y
Next n_panels rows n_panel_vertices global vertex index values
The resulting triangular meshes can be visualised using plot_triangles.py (using Python) or
plot_triangles.m (using MATLAB).
• The class PanelMesh reads in a panel mesh created by GenerateMeshes.cpp (triangles or line
segments) and provides a facility to extract the vertex coordinates of an individual mesh panel.
wq ξq
1 1
1D, 1-point 1 2, 2
1 1
√ √
1D, 2-point 2 6 (3 − 3), 16 (3 + 3)
1 1
√ √
2 6 (3 + 3), 16 (3 − 3)
1 1 1
2D, 1-point 1 3, 3, 3
1 2 1 1
2D, 3-point 3 3, 6, 6
1 1 2 1
3 6, 3, 6
1 1 1 2
3 6, 6, 3
9 1 1 1
2D, 7-point 40 3, 3, 3
0.132394152788506 (0.059715871789770, 0.470142064105115, 0.470142064105115)
0.132394152788506 (0.470142064105115, 0.059715871789770, 0.470142064105115)
0.132394152788506 (0.470142064105115, 0.470142064105115, 0.059715871789770)
0.125939180544827 (0.797426985353087, 0.101286507323456, 0.101286507323456)
0.125939180544827 (0.101286507323456, 0.797426985353087, 0.101286507323456)
0.125939180544827 (0.101286507323456, 0.101286507323456, 0.797426985353087)
Table 1: Weights and nodes for the quadrature rules to be used in this coursework.
3
Coursework Questions
In Templates/ you will find a set of folders, one for each question. The folders contain a small
amount of code (.hpp, .cpp, .py and .m files) as well as empty files, which you must edit for the
coursework. You can use any software you want to produce the plots requested.
You must keep the folder structure and all file names as they are in the templates: the
folder Q1 in your submission, for instance, should be self-contained, and should include all the code
necessary to compile and reproduce your results for Question 1. The template folders may also
serve as a checklist for your submission. As part of your submission, you may also add files to the
folders (for instance new classes, output files, plotting routines, etc.): if you do so, then write a brief
README.txt file, containing a short description of each new file. When you attempt Question 2, use
a new folder and put all the files necessary to produce your results in it; if needed, copy some files
from Q1 to Q2, etc.
This coursework requires you to implement some two-dimensional numerical integration algorithms in
an object-oriented manner, then use them to approximate a range of integrals using the quadrature
rules defined in Table 1. Your design choices and your ability to implement classes according
to the principles of object orientation will be assessed throughout this coursework.
1. In this question you will use the 2D quadrature rules defined in Table 1 to approximate the
integral over a triangle given by
Z LZ L−y
2Lq+2
I△ = xq + y q dx dy = , (9)
0 0 (q + 1)(q + 2)
in which L is a positive real number and q is a non-negative integer.
(a) Write a class QuadratureRule which contains all the data required to define a general
quadrature rule and allows the user to specify that data.
[10]
(b) Write an abstract class AbstractIntegrator which contains the following members:
• A protected pointer for the integral under consideration
IntegralInterface * mpIntegral ;
4
(d) Write a class TriangleIntegrator, derived from AbstractIntegrator, with the follow-
ing members:
• A public constructor
TriangleIntegrator ( IntegralInterface & anIntegral ,
QuadratureRule & aQuadratureRule ) ;
which takes the coordinates of the vertices of a panel, vertexX and vertexY, and
approximates the integral on that panel.
• Any other member that you choose to implement.
[15]
(e) Write and execute a main Driver.cpp file which approximates I△ in (9) using the 1-point
and 3-point triangle quadrature rules in Table 1 and outputs the approximations and the
errors to the screen. You should provide the approximations and the errors in your report
for integrands with L = 3 and q = 1, 2.
Explain how the tests you have carried out help to verify that your code is working correctly.
[5]
2. In this question you will re-use and modify the classes developed in Question 1 to use composite
integration to approximate integrals of general homogeneous polynomials over rectangles aligned
with the coordinate axes, i.e. integrals of the form
Z ymaxZ xmax X q
I□ = Ci xi y q−i dx dy
ymin xmin i=0
q
X Ci
xmax i+1 − xmin i+1 ymax q−i+1 − ymin q−i+1 ,
= (10)
i=0
(i + 1)(q − i + 1)
5
(b) Write a class RectangleIntegral, derived from IntegralInterface which overrides the
pure virtual method ComputeIntegrand, to evaluate the integrand in (10), and the virtual
method ComputeAnalyticIntegral, to compute the exact value of the integral in (10).
[2]
(c) Write and execute a main Driver.cpp file which approximates I□ in (10) using the 1-point
and 3-point triangle quadrature rules in Table 1 and outputs the approximations and the
errors to the screen. Test this code by approximating the integral of f (x) = (x2 + y 2 )2 over
the rectangle (x, y) ∈ [0, 1] × [2, 4] using both quadrature rules on a panel mesh generated
using GenerateMeshes.cpp with nx_panels=10 and ny_panels=10. You will need to
edit the input file panel_mesh_values.dat to create the appropriate mesh. You should
provide the approximations and the errors in your report.
Describe what happens to the errors in the approximation obtained using the 3-point triangle
quadrature rule in the following cases:
• panel meshes with nx_panels = ny_panels = 10,20,40,80;
• panel meshes with nx_panels = 10,20,40,80 and ny_panels = 10.
Explain any differences you see in the behaviour of the two sets of errors as the number
of panels is increased. You should provide appropriate tables of results and/or plots of the
error to illustrate your answers.
[5]
3. In this question you will re-use and modify the classes developed in Questions 1 and 2 to
approximate an integral using global refinement.
(a) Modify your class AbstractIntegrator so that it contains the following members:
• A protected variable for the maximum level of refinement allowed
int mMaxRefinementLevel ;
which loops through the panels provided by PanelMesh and applies the global refine-
ment algorithm (as outlined in the background material) to each panel.
• Any other member that you choose to implement.
[10]
6
(b) Modify your derived class TriangleIntegrator so that it contains the following members:
• A public virtual method
virtual void GenerateSubpanel ( const int subpanelIndex ,
const double * vertexX , const double * vertexY ,
double * subvertexX , double * subvertexY ) ;
4. In this question you will re-use and modify the classes developed in Questions 1, 2 and 3 to
approximate the same integrals, using the same abstract-level techniques but replacing the
quadrature rules with those derived by applying Euler’s homogeneous function theorem.
(a) Write a class LineIntegrator, derived from AbstractIntegrator, which has the same
functionality and data as TriangleIntegrator, but implements the quadrature obtained
by approximating the boundary integrals in (8) using 1D quadrature rules such as those in
Table 1. The weights bi should be computed inside your modified version of the function
IntegratePanel.
Briefly summarise any changes you had to make to the abstract class AbstractIntegrator
or the class QuadratureRule.
[8]
(b) Write and execute a main Driver.cpp file which approximates I□ in (10) using the 1D
1-point and 2-point quadrature rules in Table 1 to approximate the boundary integral
derived from Euler’s homogeneous function theorem with global refinement, and outputs
the approximations and errors at each level of refinement to the screen. Test this code by
approximating the integral of f (x) = (x2 + y 2 )2 over the rectangle (x, y) ∈ [0, 1] × [2, 4]
using both quadrature rules with global refinement applied on an initial boundary panel
mesh generated using GenerateMeshes.cpp with nx_panels=10 and ny_panels=20.
7
You should provide the approximations and the errors in your report for the initial panel
mesh and 5 levels of refinement. At each level of refinement (including the initial panel
mesh) you should also compute and report the number of times your code has evaluated
the integrand f (x).
Use your results to estimate the orders of convergence of the 1-point and 2-point quadrature
rules. You should provide a brief explanation, which may include error plots, to describe
the evidence you have for these orders of convergence.
[5]
5. In this question you will reflect on the exercises you have completed and investigate the behaviour
of the methods in more complicated situations.
In Questions 1-4 you have implemented 5 different quadrature rules (3 on triangles and 2 on
boundary line segments) and applied composite integration and global refinement. Use the code
you have written to test these 5 rules and rank them in order of preference for approximating
integrals of general homogeneous polynomials over rectangles, of the form I□ in (10). To do
this you should consider the number of evaluations of the integrand f (x) required to get the
approximation error below a specified value. Evaluating f (x) is often the most expensive part
of the code so this is a good indication of the computational efficiency of the algorithm.
Meshes of triangular panels are also used to construct approximations on non-rectangular do-
mains, so consider now the integral over a circle given by
Z
I◦ = x2 + y 2 dx where Ω◦ = {x | x2 + y 2 ≤ 1} , (11)
Ω◦
which has an exact value of I◦ = π2 . Apply the quadrature rules you have implemented to this
integral and investigate the behaviour of the error as h is reduced, using composite integration
and global refinement on the panel meshes provided in the files circle_volume_h0p*.dat and
circle_boundary_h0p*.dat (where the filenames include approximate values for h). Compare
the error behaviour with that seen when approximating I□ and provide brief explanations of any
differences you see. Which of the 5 quadrature rules would you recommend for this problem and
how would you select the panel meshes to get the best results as you reduce h? You should also
suggest a simple mathematical technique which might be applied to significantly improve the
efficiency of the approximation to I◦ , with a brief explanation of why it would be more efficient.
Euler’s homogeneous function theorem also applies to fractional exponents, but more care needs
to be taken. Describe how the error behaves as h is reduced using global refinement for the
integral
Z 1Z 1
1 1 4
x 2 y 2 dx = . (12)
0 0 9
Provide a brief explanation for why this behaviour differs from that you have seen when inte-
grating homogeneous polynomials.
[10]
The output requested in Questions 1e, 2c, 3c, 4b and 5 should be included in your submission, in
the format provided by the solution template file.