diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 1290ed98787377eea7d54f12d05b94eff0aeaf2f..7e740501f0df7b92289c89887a28468526627343 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -63,6 +63,8 @@ compatibility_stage:
       - make clean && PATH=/opt/intel/oneapi/compiler/latest/bin:$PATH BUILDDIR=$PWD/../build_ifort-icpx CXX=icpx FC=ifort FCFLAGS="-O3 -diag-disable=10448" make -j
       - echo "Running make with Intel ifx and Intel icpx..."
       - make clean && LD_LIBRARY_PATH=/opt/intel/oneapi/compiler/latest/lib PATH=/opt/intel/oneapi/compiler/latest/bin:$PATH BUILDDIR=$PWD/../build_ifx-icpx CXX=icpx FC=ifx FCFLAGS=-O3 make -j
+      - echo "Running make with default MPI compilers"
+      - make clean && BUILDDIR=$PWD/../build_mpi CXX=mpicxx FC=mpif90 USE_MPI=1 make -j
    
 building_stage:
    stage: build
diff --git a/containers/docker/Dockerfile b/containers/docker/Dockerfile
index 2f528d227e1881262a3297663a697b13d9ef5ffe..0b45614849d1230f676f436a799e2093a00ad6e4 100644
--- a/containers/docker/Dockerfile
+++ b/containers/docker/Dockerfile
@@ -20,6 +20,8 @@ RUN apt update
 RUN DEBIAN_FRONTEND=noninteractive apt -y install intel-oneapi-compiler-fortran intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic intel-oneapi-compiler-dpcpp-cpp
 # install lapacke and its dependencies, both standard and the version with 64 bit integers
 RUN DEBIAN_FRONTEND=noninteractive apt -y install liblapacke-dev liblapacke64-dev libopenblas-dev libopenblas-openmp-dev libopenblas64-dev libopenblas64-openmp-dev
+# install MPI stack
+RUN DEBIAN_FRONTEND=noninteractive apt -y install mpi-default-dev mpi-default-bin
 # install packages needed to run python scripts for checks
 RUN DEBIAN_FRONTEND=noninteractive apt -y install python3 python-is-python3 python3-regex
 # install packages needed to run doxygen to create html docs
@@ -53,7 +55,7 @@ FROM  debian:bookworm-slim AS np-tmcode-run-minimal
 WORKDIR /root
 # install the strictly needed runtime libraries needed to run the executables
 # and the python check scripts
-RUN DEBIAN_FRONTEND=noninteractive apt update && DEBIAN_FRONTEND=noninteractive apt upgrade && DEBIAN_FRONTEND=noninteractive apt -y install libgfortran5 libgcc-s1 libhdf5-103-1 libstdc++6 libssl3 libcurl4 libsz2 zlib1g libnghttp2-14 libidn2-0 librtmp1 libssh2-1 libpsl5 libgssapi-krb5-2 libldap-2.5-0 libzstd1 libbrotli1 libaec0 libunistring2 libgmp10 libkrb5-3 libk5crypto3 libcom-err2 libkrb5support0 libsasl2-2 libp11-kit0 libtasn1-6 libkeyutils1 libffi8 liblapacke64 libopenblas64-0-openmp python3 python-is-python3 python3-regex hdf5-tools && rm -rf /var/lib/apt/lists/*
+RUN DEBIAN_FRONTEND=noninteractive apt update && DEBIAN_FRONTEND=noninteractive apt upgrade && DEBIAN_FRONTEND=noninteractive apt -y install libgfortran5 libgcc-s1 libhdf5-103-1 libstdc++6 libssl3 libcurl4 libsz2 zlib1g libnghttp2-14 libidn2-0 librtmp1 libssh2-1 libpsl5 libgssapi-krb5-2 libldap-2.5-0 libzstd1 libbrotli1 libaec0 libunistring2 libgmp10 libkrb5-3 libk5crypto3 libcom-err2 libkrb5support0 libsasl2-2 libp11-kit0 libtasn1-6 libkeyutils1 libffi8 liblapacke64 libopenblas64-0-openmp python3 python-is-python3 python3-regex hdf5-tools mpi-default-bin && rm -rf /var/lib/apt/lists/*
 COPY --from=np-tmcode-run-dev /root /root
 # remove everything which is not needed to run the codes
 RUN cd /root/np-tmcode && find build -name "*.o" -exec rm -v \{\} \; && find build -name "*.gcno" -exec rm -v \{\} \; && cd src && rm -rvf cluster libnptm trapping include sphere Makefile make.inc README.md && cd .. && rm -rvf containers && cd doc && rm -rvf src && cd build/latex && rm -rvf *.tex *.out *.sty *.ind *.log *.toc *.ilg *.idx *.aux *.eps Makefile class*.pdf
diff --git a/src/cluster/cluster.cpp b/src/cluster/cluster.cpp
index 306dafa3ee67dfd2978f2de6399d6c64ec628093..6bb1272cbc6d9f4c1638462d1902da145066a09a 100644
--- a/src/cluster/cluster.cpp
+++ b/src/cluster/cluster.cpp
@@ -58,7 +58,7 @@ using namespace std;
 
 // I would like to put it all in a struct, but then I'd have to write a constructor for it, due to members defined as references, creating a worse nightmare than the one I'd like to simplify...
 
-int cluster_jxi488_cycle(int jxi488, ScattererConfiguration *sconf, GeometryConfiguration *gconf, ScatteringAngles *sa, ClusterIterationData *cid, FILE *output, const string& output_path, fstream& tppoan, Logger *logger);
+int cluster_jxi488_cycle(int jxi488, ScattererConfiguration *sconf, GeometryConfiguration *gconf, ScatteringAngles *sa, ClusterIterationData *cid, FILE *output, const string& output_path, fstream& tppoan);
 
 /*! \brief C++ implementation of CLU
  *
@@ -183,7 +183,7 @@ void cluster(const string& config_file, const string& data_file, const string& o
 	// do the first iteration on jxi488 separately, since it seems to be different from the others
 	int jxi488 = 1;
 	chrono::time_point<chrono::high_resolution_clock> start_iter_1 = chrono::high_resolution_clock::now();
-	int jer = cluster_jxi488_cycle(jxi488, sconf, gconf, p_scattering_angles, cid, output, output_path, tppoan, logger);
+	int jer = cluster_jxi488_cycle(jxi488, sconf, gconf, p_scattering_angles, cid, output, output_path, tppoan);
 	chrono::time_point<chrono::high_resolution_clock> end_iter_1 = chrono::high_resolution_clock::now();
 	elapsed = start_iter_1 - t_start;
 	message = "INFO: Calculation setup took " + to_string(elapsed.count()) + "s.\n";
@@ -238,7 +238,7 @@ void cluster(const string& config_file, const string& data_file, const string& o
 	  // ok, now I can actually start the parallel calculations
 #pragma omp for
 	  for (jxi488 = cid_2->firstxi; jxi488 <= cid_2->lastxi; jxi488++) {
-	    int jer = cluster_jxi488_cycle(jxi488, sconf, gconf, p_scattering_angles, cid_2, output_2, output_path, *tppoanp_2, logger);
+	    int jer = cluster_jxi488_cycle(jxi488, sconf, gconf, p_scattering_angles, cid_2, output_2, output_path, *tppoanp_2);
 	  }
 
 #pragma omp barrier
@@ -396,7 +396,7 @@ void cluster(const string& config_file, const string& data_file, const string& o
       // ok, now I can actually start the parallel calculations
 #pragma omp for
       for (int jxi488 = cid_2->firstxi; jxi488 <= cid_2->lastxi; jxi488++) {
-	int jer = cluster_jxi488_cycle(jxi488, sconf, gconf, p_scattering_angles, cid_2, output_2, output_path, *tppoanp_2, logger);
+	int jer = cluster_jxi488_cycle(jxi488, sconf, gconf, p_scattering_angles, cid_2, output_2, output_path, *tppoanp_2);
       }
 
 #pragma omp barrier
@@ -466,10 +466,11 @@ void cluster(const string& config_file, const string& data_file, const string& o
   delete logger;
 }
 
-int cluster_jxi488_cycle(int jxi488, ScattererConfiguration *sconf, GeometryConfiguration *gconf, ScatteringAngles *sa, ClusterIterationData *cid, FILE *output, const string& output_path, fstream& tppoan, Logger *logger)
+int cluster_jxi488_cycle(int jxi488, ScattererConfiguration *sconf, GeometryConfiguration *gconf, ScatteringAngles *sa, ClusterIterationData *cid, FILE *output, const string& output_path, fstream& tppoan)
 {
   int nxi = sconf->number_of_scales;
   string message = "INFO: running scale iteration " + to_string(jxi488) + " of " + to_string(nxi) + ".\n";
+  Logger *logger = new Logger(LOG_INFO);
   logger->log(message);
   chrono::duration<double> elapsed;
   chrono::time_point<chrono::high_resolution_clock> interval_start, interval_end;
@@ -1128,5 +1129,7 @@ int cluster_jxi488_cycle(int jxi488, ScattererConfiguration *sconf, GeometryConf
   
   logger->log("INFO: finished scale iteration " + to_string(jxi488) + " of " + to_string(nxi) + ".\n");
 
+  delete logger;
+
   return jer;
 }