In this guide, we show you how to compile, run and plot for the course.
We use CMake for compiling, and we will utilize Python or Matlab for plotting (It is also possible to plot through C++, but it is not recommended , nor supported).
We usually distribute handout code (templates) for you to get started. For most coding exercises, there is usually an accompanying handout file.
In the zip file, there is one folder per exercise . For example, for Series 0, we have
[series0_handout]$ ls
2d-poissonlFEM linear-transp-1d
and each of these contains a seperate CMake (and git) project.
Make sure you unzip the contents first. This can be done from the command line on most Linux systems using the
unzip
command:
unzip series0_handout.zip
On OS X , Windows and Linux there is also graphical tools to do this.
Open each exercise individually by pressing
"File -> Open -> CMake ...
and selecting the
CMakeLists.txt
.
And now let the magic start: Build the target. Edit
CMakeLists.txt
from inside VS2019 to use C++11, e.g. replace
cxx_std_17
with cxx_std_11
. Build the target (it's
okay if it fails). Revert the edit in CMakeLists.txt
. And with
any luck you have C++17 linting! (Check lines with structured bindings, e.g.
auto [a, b] = ...
).
Or use CLion instead.
Install QtCreator directly from the package manager.
Load each exercise by opening QtCreator. Then go to
File->Open File or Project
and open the
CMakeLists.txt
file. Go through the prompts and everything should be fine.
File -> Open ... ->
and selecting the
CMakeLists.txt
directly.
You can generate an Xcode project from cmake. Use
from the
build
directory
cmake .. -G Xcode
then open the resulting project in Xcode.
.../series0_handout/2d-poissonlFEM
.../series0_handout/2d-poissonlFEM/build
.sln
file in your build
directory, that you can
open with Visual Studio, XCode, or your favorite IDE (probably!).
On all platforms, including Windows, it is possible to run CMake from the command line.
Open a terminal, eg:
Open the shell in the folder containing the project you want to compile, eg
cd series0_handout/2d-poissonlFEM
then create a
build
directory:
mkdir build
and move to the newly created directory
cd build
then run
cmake ..
On Linux and OS X
you can compile it using
from the
build
directory
make
on Windows (and technically OS X and Linux as well), you can compile using
from the
build
directory
cmake --build .
You can now run the generated executable. Eg
./fem2d
Plotting directly in C++ can be a pain, and does not offer a lot of real benefits. In addition, for most real world use cases, the computational code will run much longer than any plotting code. For plotting, you will often want flexibility and ease of use, while for computations you will prefer raw speed. For even larger datasets, plotting directly from C++ using your own code is just infeasible.
We strongly recommend that you use Python (or MATLAB) to plot .
We follow the following procedure:
1) Run your C++ program
2) Write the results to file (ascii text file for now)
3) Load the results in Python or Matlab using
numpy.loadtxt
or
load
Say we have the following C++ program
#include <vector>
#include "writer.hpp" // To use the write-to-file function
#include <cmath>
int main(int,char**) {
int N = 128;
// Initialize vector of x-points
std::vector<double> x(N);
// For our values
std::vector<double> values(N);
// Create vector of sine values
for (int i = 0; i < N; ++i) {
x[i] = double(i)/N;
values[i] = std::sin(x[i]);
}
// Write the data to two text files ('x.txt' and 'values.txt')
writeToFile("x.txt", x);
writeToFile("values.txt", values);
return 0;
}
We compile and run this program as normal:
cmake ..
make
./example
And then we can use the following Python script to plot it
# Needed imports
import numpy
import matplotlib
import matplotlib.pyplot as plt
# Load x values
x = numpy.loadtxt('x.txt')
# Load y values
values = numpy.loadtxt('values.txt')
plt.plot(x, values, label='$\sin(x)$')
plt.xlabel('$x$')
plt.ylabel('$y$')
plt.legend()
plt.show()
or correspondingly in MATLAB (May contain errors):
% Load x values
x = load('x.txt')
% Load y values
values = load('values.txt')
plot(x, values)
xlabel('$x$')
ylabel('$y$')
legend(['\sin(x)'])
We get the following nice plot
#pragma once
#include <vector>
#include <string>
#include <fstream>
#include <limits>
#include <iomanip>
///
/// Writes the contents of the vector 'data' to the textfile filename
/// The output format should be load-able in MATLAB and Numpy using the
/// load-command.
///
template<typename T>
void writeToFile(const std::string& filename,
const std::vector<T>& data) {
std::ofstream file(filename.c_str());
// Set highest possible precision, this way we are sure we are printing
// enough digits
file << std::setprecision(std::numeric_limits<long double>::digits10 + 1);
// Loop over vector and write output to file
for(int i = 0; i < data.size(); ++i) {
file << data[i] << " ";
}
file << std::endl;
// File closes automatically at end of scope!
}