diff --git a/src/cluster/cluster.cpp b/src/cluster/cluster.cpp
index 7d2533eac1e1f313fcd14b29e8805c0aeb229534..8c499689ef27676671b5d05f2a9ddd3d0d117b05 100644
--- a/src/cluster/cluster.cpp
+++ b/src/cluster/cluster.cpp
@@ -95,9 +95,11 @@
 #include "../include/outputs.h"
 #endif
 
-using namespace std;
+#ifndef INCLUDE_ITERATION_DATA_H_
+#include "../include/IterationData.h"
+#endif
 
-// 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...
+using namespace std;
 
 /*! \brief Main calculation loop.
  *
@@ -1531,3 +1533,536 @@ int cluster_jxi488_cycle(int jxi488, ScattererConfiguration *sconf, GeometryConf
 
   return jer;
 }
+
+// >>> IMPLEMENTATION OF ClusterIterationData CLASS <<<
+ClusterIterationData::ClusterIterationData(GeometryConfiguration *gconf, ScattererConfiguration *sconf, const mixMPI *mpidata, const int device_count) {
+  c1 = new ParticleDescriptorCluster(gconf, sconf);
+  const int ndi = c1->nsph * c1->nlim;
+  const np_int ndit = 2 * ndi;
+  gaps = new double[c1->nsph]();
+  tqev = new double[3]();
+  tqsv = new double[3]();
+  tqse = new double*[2];
+  tqspe = new dcomplex*[2];
+  tqss = new double*[2];
+  tqsps = new dcomplex*[2];
+  tqce = new double*[2];
+  tqcpe = new dcomplex*[2];
+  tqcs = new double*[2];
+  tqcps = new dcomplex*[2];
+  for (int ti = 0; ti < 2; ti++) {
+    tqse[ti] = new double[c1->nsph]();
+    tqspe[ti] = new dcomplex[c1->nsph]();
+    tqss[ti] = new double[c1->nsph]();
+    tqsps[ti] = new dcomplex[c1->nsph]();
+    tqce[ti] = new double[3]();
+    tqcpe[ti] = new dcomplex[3]();
+    tqcs[ti] = new double[3]();
+    tqcps[ti] = new dcomplex[3]();
+  }
+  gapv = new double[3]();
+  gapp = new dcomplex*[3];
+  gappm = new dcomplex*[3];
+  gap = new double*[3];
+  gapm = new double*[3];
+  for (int gi = 0; gi < 3; gi++) {
+    gapp[gi] = new dcomplex[2]();
+    gappm[gi] = new dcomplex[2]();
+    gap[gi] = new double[2]();
+    gapm[gi] = new double[2]();
+  }
+  u = new double[3]();
+  us = new double[3]();
+  un = new double[3]();
+  uns = new double[3]();
+  up = new double[3]();
+  ups = new double[3]();
+  unmp = new double[3]();
+  unsmp = new double[3]();
+  upmp = new double[3]();
+  upsmp = new double[3]();
+  argi = new double[1]();
+  args = new double[1]();
+  duk = new double[3]();
+  cextlr = new double*[4];
+  cext = new double*[4];
+  cmullr = new double*[4];;
+  cmul = new double*[4];
+  for (int ci = 0; ci < 4; ci++) {
+    cextlr[ci] = new double[4]();
+    cext[ci] = new double[4]();
+    cmullr[ci] = new double[4]();
+    cmul[ci] = new double[4]();
+  }
+  zpv = new double***[c1->lm];
+  for (int zi = 0; zi < c1->lm; zi++) {
+    zpv[zi] = new double**[3];
+    for (int zj = 0; zj < 3; zj++) {
+      zpv[zi][zj] = new double*[2];
+      for (int zk = 0; zk < 2; zk++) {
+	zpv[zi][zj][zk] = new double[2]();
+      }
+    }
+  }
+  am_vector = new dcomplex[ndit * ndit]();
+  am = new dcomplex*[ndit];
+  for (int ai = 0; ai < ndit; ai++) {
+    am[ai] = (am_vector + ai * ndit);
+  }
+  
+  arg = 0.0 + 0.0 * I;
+  // These are suspect initializations
+  scan = 0.0;
+  cfmp = 0.0;
+  sfmp = 0.0;
+  cfsp = 0.0;
+  sfsp = 0.0;
+  // End of suspect initializations
+  wn = sconf->wp / 3.0e8;
+  xip = sconf->xip;
+  sqsfi = 1.0;
+  vk = 0.0;
+  number_of_scales = sconf->number_of_scales;
+  xiblock = (int) ceil(((double) (sconf->number_of_scales-1))/((double) mpidata->nprocs));
+  lastxi = ((mpidata->rank+1) * xiblock)+1;
+  firstxi = lastxi-xiblock+1;
+  if (lastxi > sconf->number_of_scales) lastxi = sconf->number_of_scales;
+
+#ifdef USE_MAGMA
+  proc_device = mpidata->rank % device_count;
+#else
+  proc_device = 0;
+#endif
+
+  // In the first iteration, if refinement is enabled, determine the number of refinement iterations required to arrive at the target accuracy (if achievable in a reasonable number of iterations)
+  refinemode = 2;
+  // maxrefiters and accuracygoal should be configurable and preferably set somewhere else
+  maxrefiters = 20;
+  accuracygoal = 1e-6;
+}
+
+ClusterIterationData::ClusterIterationData(const ClusterIterationData& rhs) {
+  c1 = new ParticleDescriptorCluster(reinterpret_cast<ParticleDescriptorCluster &>(*(rhs.c1)));
+  const int ndi = c1->nsph * c1->nlim;
+  const np_int ndit = 2 * ndi;
+  gaps = new double[c1->nsph]();
+  for (int gi = 0; gi < c1->nsph; gi++) gaps[gi] = rhs.gaps[gi];
+  tqev = new double[3]();
+  tqsv = new double[3]();
+  for (int ti = 0; ti < 3; ti++) {
+    tqev[ti] = rhs.tqev[ti];
+    tqsv[ti] = rhs.tqsv[ti];
+  }
+  tqse = new double*[2];
+  tqspe = new dcomplex*[2];
+  tqss = new double*[2];
+  tqsps = new dcomplex*[2];
+  tqce = new double*[2];
+  tqcpe = new dcomplex*[2];
+  tqcs = new double*[2];
+  tqcps = new dcomplex*[2];
+  for (int ti = 0; ti < 2; ti++) {
+    tqse[ti] = new double[c1->nsph]();
+    tqspe[ti] = new dcomplex[c1->nsph]();
+    tqss[ti] = new double[c1->nsph]();
+    tqsps[ti] = new dcomplex[c1->nsph]();
+    for (int tj = 0; tj < c1->nsph; tj++) {
+      tqse[ti][tj] = rhs.tqse[ti][tj];
+      tqspe[ti][tj] = rhs.tqspe[ti][tj];
+      tqss[ti][tj] = rhs.tqss[ti][tj];
+      tqsps[ti][tj] = rhs.tqsps[ti][tj];
+    }
+    tqce[ti] = new double[3]();
+    tqcpe[ti] = new dcomplex[3]();
+    tqcs[ti] = new double[3]();
+    tqcps[ti] = new dcomplex[3]();
+    for (int tj = 0; tj < 3; tj++) {
+      tqce[ti][tj] = rhs.tqce[ti][tj];
+      tqcpe[ti][tj] = rhs.tqcpe[ti][tj];
+      tqcs[ti][tj] = rhs.tqcs[ti][tj];
+      tqcps[ti][tj] = rhs.tqcps[ti][tj];
+    }
+  }
+  gapv = new double[3]();
+  gapp = new dcomplex*[3];
+  gappm = new dcomplex*[3];
+  gap = new double*[3];
+  gapm = new double*[3];
+  for (int gi = 0; gi < 3; gi++) {
+    gapv[gi] = rhs.gapv[gi];
+    gapp[gi] = new dcomplex[2]();
+    gappm[gi] = new dcomplex[2]();
+    gap[gi] = new double[2]();
+    gapm[gi] = new double[2]();
+    for (int gj = 0; gj < 2; gj++) {
+      gapp[gi][gj] = rhs.gapp[gi][gj];
+      gappm[gi][gj] = rhs.gappm[gi][gj];
+      gap[gi][gj] = rhs.gap[gi][gj];
+      gapm[gi][gj] = rhs.gapm[gi][gj];
+    }
+  }
+  u = new double[3]();
+  us = new double[3]();
+  un = new double[3]();
+  uns = new double[3]();
+  up = new double[3]();
+  ups = new double[3]();
+  unmp = new double[3]();
+  unsmp = new double[3]();
+  upmp = new double[3]();
+  upsmp = new double[3]();
+  duk = new double[3]();
+  for (int ui = 0; ui < 3; ui++) {
+    u[ui] = rhs.u[ui];
+    us[ui] = rhs.us[ui];
+    un[ui] = rhs.un[ui];
+    uns[ui] = rhs.uns[ui];
+    up[ui] = rhs.up[ui];
+    ups[ui] = rhs.ups[ui];
+    unmp[ui] = rhs.unmp[ui];
+    unsmp[ui] = rhs.unsmp[ui];
+    upmp[ui] = rhs.upmp[ui];
+    upsmp[ui] = rhs.upsmp[ui];
+    duk[ui] = rhs.duk[ui];
+  }
+  argi = new double[1]();
+  args = new double[1]();
+  argi[0] = rhs.argi[0];
+  args[0] = rhs.args[0];
+  cextlr = new double*[4];
+  cext = new double*[4];
+  cmullr = new double*[4];;
+  cmul = new double*[4];
+  for (int ci = 0; ci < 4; ci++) {
+    cextlr[ci] = new double[4]();
+    cext[ci] = new double[4]();
+    cmullr[ci] = new double[4]();
+    cmul[ci] = new double[4]();
+    for (int cj = 0; cj < 4; cj++) {
+      cextlr[ci][cj] = rhs.cextlr[ci][cj];
+      cext[ci][cj] = rhs.cext[ci][cj];
+      cmullr[ci][cj] = rhs.cmullr[ci][cj];
+      cmul[ci][cj] = rhs.cmul[ci][cj];
+    }
+  }
+  zpv = new double***[c1->lm];
+  for (int zi = 0; zi < c1->lm; zi++) {
+    zpv[zi] = new double**[3];
+    for (int zj = 0; zj < 3; zj++) {
+      zpv[zi][zj] = new double*[2];
+      for (int zk = 0; zk < 2; zk++) {
+	zpv[zi][zj][zk] = new double[2]();
+	zpv[zi][zj][zk][0] = rhs.zpv[zi][zj][zk][0];
+	zpv[zi][zj][zk][1] = rhs.zpv[zi][zj][zk][1];
+      }
+    }
+  }
+  am_vector = new dcomplex[ndit * ndit]();
+  for (np_int ai = 0; ai < ndit * ndit; ai++) am_vector[ai] = rhs.am_vector[ai];
+  am = new dcomplex*[ndit];
+  for (np_int ai = 0; ai < ndit; ai++) {
+    am[ai] = (am_vector + ai * ndit);
+  }
+  
+  arg = rhs.arg;
+  // These are suspect initializations
+  scan = rhs.scan;
+  cfmp = rhs.cfmp;
+  sfmp = rhs.sfmp;
+  cfsp = rhs.cfsp;
+  sfsp = rhs.sfsp;
+  // End of suspect initializations
+  wn = rhs.wn;
+  xip = rhs.xip;
+  sqsfi = rhs.sqsfi;
+  vk = rhs.vk;
+  firstxi = rhs.firstxi;
+  lastxi = rhs.lastxi;
+  xiblock = rhs.xiblock;
+  number_of_scales = rhs.number_of_scales;
+
+  proc_device = rhs.proc_device;
+  refinemode = rhs.refinemode;
+  maxrefiters = rhs.maxrefiters;
+  accuracygoal = rhs.accuracygoal;
+}
+
+#ifdef MPI_VERSION
+ClusterIterationData::ClusterIterationData(const mixMPI *mpidata, const int device_count) {
+  c1 = new ParticleDescriptorCluster(mpidata);
+  const int ndi = c1->nsph * c1->nlim;
+  const np_int ndit = 2 * ndi;
+  gaps = new double[c1->nsph]();
+  MPI_Bcast(gaps, c1->nsph, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  tqev = new double[3]();
+  tqsv = new double[3]();
+  MPI_Bcast(tqev, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(tqsv, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  tqse = new double*[2];
+  tqspe = new dcomplex*[2];
+  tqss = new double*[2];
+  tqsps = new dcomplex*[2];
+  tqce = new double*[2];
+  tqcpe = new dcomplex*[2];
+  tqcs = new double*[2];
+  tqcps = new dcomplex*[2];
+  for (int ti = 0; ti < 2; ti++) {
+    tqse[ti] = new double[c1->nsph]();
+    tqspe[ti] = new dcomplex[c1->nsph]();
+    tqss[ti] = new double[c1->nsph]();
+    tqsps[ti] = new dcomplex[c1->nsph]();
+    MPI_Bcast(tqse[ti], c1->nsph, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+    MPI_Bcast(tqspe[ti], c1->nsph, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
+    MPI_Bcast(tqss[ti], c1->nsph, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+    MPI_Bcast(tqsps[ti], c1->nsph, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
+    tqce[ti] = new double[3]();
+    tqcpe[ti] = new dcomplex[3]();
+    tqcs[ti] = new double[3]();
+    tqcps[ti] = new dcomplex[3]();
+    MPI_Bcast(tqce[ti], 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+    MPI_Bcast(tqcpe[ti], 3, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
+    MPI_Bcast(tqcs[ti], 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+    MPI_Bcast(tqcps[ti], 3, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
+  }
+  gapv = new double[3]();
+  gapp = new dcomplex*[3];
+  gappm = new dcomplex*[3];
+  gap = new double*[3];
+  gapm = new double*[3];
+  MPI_Bcast(gapv, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  for (int gi = 0; gi < 3; gi++) {
+    gapp[gi] = new dcomplex[2]();
+    gappm[gi] = new dcomplex[2]();
+    gap[gi] = new double[2]();
+    gapm[gi] = new double[2]();
+    MPI_Bcast(gapp[gi], 2, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
+    MPI_Bcast(gappm[gi], 2, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
+    MPI_Bcast(gap[gi], 2, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+    MPI_Bcast(gapm[gi], 2, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  }
+  u = new double[3]();
+  us = new double[3]();
+  un = new double[3]();
+  uns = new double[3]();
+  up = new double[3]();
+  ups = new double[3]();
+  unmp = new double[3]();
+  unsmp = new double[3]();
+  upmp = new double[3]();
+  upsmp = new double[3]();
+  duk = new double[3]();
+  MPI_Bcast(u, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(us, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(un, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(uns, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(up, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(ups, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(unmp, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(unsmp, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(upmp, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(upsmp, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(duk, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  argi = new double[1]();
+  args = new double[1]();
+  MPI_Bcast(argi, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(args, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  cextlr = new double*[4];
+  cext = new double*[4];
+  cmullr = new double*[4];;
+  cmul = new double*[4];
+  for (int ci = 0; ci < 4; ci++) {
+    cextlr[ci] = new double[4]();
+    cext[ci] = new double[4]();
+    cmullr[ci] = new double[4]();
+    cmul[ci] = new double[4]();
+    MPI_Bcast(cextlr[ci], 4, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+    MPI_Bcast(cext[ci], 4, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+    MPI_Bcast(cmullr[ci], 4, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+    MPI_Bcast(cmul[ci], 4, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  }
+  zpv = new double***[c1->lm];
+  for (int zi = 0; zi < c1->lm; zi++) {
+    zpv[zi] = new double**[3];
+    for (int zj = 0; zj < 3; zj++) {
+      zpv[zi][zj] = new double*[2];
+      for (int zk = 0; zk < 2; zk++) {
+	zpv[zi][zj][zk] = new double[2]();
+	MPI_Bcast(zpv[zi][zj][zk], 2, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+      }
+    }
+  }
+  am_vector = new dcomplex[ndit * ndit]();
+  am = new dcomplex*[ndit];
+  for (np_int ai = 0; ai < ndit; ai++) {
+    am[ai] = (am_vector + ai * ndit);
+    MPI_Bcast(am[ai], ndit, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
+  }
+  MPI_Bcast(&arg, 1, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&scan, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&cfmp, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&sfmp, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&cfsp, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&sfsp, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&wn, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&xip, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&sqsfi, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&vk, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&xiblock, 1, MPI_INT, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&number_of_scales, 1, MPI_INT, 0, MPI_COMM_WORLD);
+  lastxi = ((mpidata->rank+1) * xiblock)+1;
+  firstxi = lastxi-xiblock+1;
+  if (lastxi > number_of_scales) lastxi = number_of_scales;
+
+#ifdef USE_MAGMA
+  proc_device = mpidata->rank % device_count;
+#else
+  proc_device = 0;
+#endif
+  MPI_Bcast(&refinemode, 1, MPI_INT, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&maxrefiters, 1, MPI_INT, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&accuracygoal, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+}
+
+void ClusterIterationData::mpibcast(const mixMPI *mpidata) {
+  c1->mpibcast(mpidata);
+  const int ndi = c1->nsph * c1->nlim;
+  const np_int ndit = 2 * ndi;
+  MPI_Bcast(gaps, c1->nsph, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(tqev, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(tqsv, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  for (int ti = 0; ti < 2; ti++) {
+    MPI_Bcast(tqse[ti], c1->nsph, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+    MPI_Bcast(tqspe[ti], c1->nsph, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
+    MPI_Bcast(tqss[ti], c1->nsph, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+    MPI_Bcast(tqsps[ti], c1->nsph, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
+    MPI_Bcast(tqce[ti], 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+    MPI_Bcast(tqcpe[ti], 3, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
+    MPI_Bcast(tqcs[ti], 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+    MPI_Bcast(tqcps[ti], 3, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
+  }
+  MPI_Bcast(gapv, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  for (int gi = 0; gi < 3; gi++) {
+    MPI_Bcast(gapp[gi], 2, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
+    MPI_Bcast(gappm[gi], 2, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
+    MPI_Bcast(gap[gi], 2, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+    MPI_Bcast(gapm[gi], 2, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  }
+  MPI_Bcast(u, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(us, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(un, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(uns, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(up, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(ups, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(unmp, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(unsmp, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(upmp, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(upsmp, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(duk, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(argi, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(args, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  for (int ci = 0; ci < 4; ci++) {
+    MPI_Bcast(cextlr[ci], 4, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+    MPI_Bcast(cext[ci], 4, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+    MPI_Bcast(cmullr[ci], 4, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+    MPI_Bcast(cmul[ci], 4, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  }
+  for (int zi = 0; zi < c1->lm; zi++) {
+    for (int zj = 0; zj < 3; zj++) {
+      for (int zk = 0; zk < 2; zk++) {
+	MPI_Bcast(zpv[zi][zj][zk], 2, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+      }
+    }
+  }
+  // since MPI expects an int argument for the number of elements to transfer in one go, transfer am one row at a time
+  for (int ai = 0; ai < ndit; ai++) {
+    MPI_Bcast(am[ai], ndit, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
+  }
+  MPI_Bcast(&arg, 1, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&scan, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&cfmp, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&sfmp, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&cfsp, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&sfsp, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&wn, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&xip, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&sqsfi, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&vk, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&xiblock, 1, MPI_INT, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&number_of_scales, 1, MPI_INT, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&refinemode, 1, MPI_INT, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&maxrefiters, 1, MPI_INT, 0, MPI_COMM_WORLD);
+  MPI_Bcast(&accuracygoal, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
+}
+#endif
+
+ClusterIterationData::~ClusterIterationData() {
+  const int nsph = c1->nsph;
+  delete[] am_vector;
+  delete[] am;
+  for (int zi = c1->lm - 1; zi > -1; zi--) {
+    for (int zj = 2; zj > -1; zj--) {
+      delete[] zpv[zi][zj][1];
+      delete[] zpv[zi][zj][0];
+      delete[] zpv[zi][zj];
+    }
+    delete[] zpv[zi];
+  }
+  delete[] zpv;
+  delete c1;
+  delete[] gaps;
+  for (int ti = 1; ti > -1; ti--) {
+    delete[] tqse[ti];
+    delete[] tqss[ti];
+    delete[] tqspe[ti];
+    delete[] tqsps[ti];
+    delete[] tqce[ti];
+    delete[] tqcpe[ti];
+    delete[] tqcs[ti];
+    delete[] tqcps[ti];
+  }
+  delete[] tqse;
+  delete[] tqss;
+  delete[] tqspe;
+  delete[] tqsps;
+  delete[] tqce;
+  delete[] tqcpe;
+  delete[] tqcs;
+  delete[] tqcps;
+  delete[] tqev;
+  delete[] tqsv;
+  for (int gi = 2; gi > -1; gi--) {
+    delete[] gapp[gi];
+    delete[] gappm[gi];
+    delete[] gap[gi];
+    delete[] gapm[gi];
+  }
+  delete[] gapp;
+  delete[] gappm;
+  delete[] gap;
+  delete[] gapm;
+  delete[] gapv;
+  delete[] u;
+  delete[] us;
+  delete[] un;
+  delete[] uns;
+  delete[] up;
+  delete[] ups;
+  delete[] unmp;
+  delete[] unsmp;
+  delete[] upmp;
+  delete[] upsmp;
+  delete[] argi;
+  delete[] args;
+  delete[] duk;
+  for (int ci = 3; ci > -1; ci--) {
+    delete[] cextlr[ci];
+    delete[] cext[ci];
+    delete[] cmullr[ci];
+    delete[] cmul[ci];
+  }
+  delete[] cextlr;
+  delete[] cext;
+  delete[] cmullr;
+  delete[] cmul;
+}
+// >>> END OF ClusterIterationData CLASS IMPLEMENTATION <<<
diff --git a/src/include/Commons.h b/src/include/Commons.h
index 2012d7f86ce35a1d3c770e38eb4ac16087b9594a..a2e8fee9642773c404301ce3056a20b9881dab47 100644
--- a/src/include/Commons.h
+++ b/src/include/Commons.h
@@ -65,162 +65,6 @@ public:
   ~mixMPI();
 };
 
-/*! \brief A data structure representing the information used for a single scale
- * of the CLUSTER case.
- */
-class ClusterIterationData {
-public:
-  //! \brief Pointer to a ParticleDescriptor structure.
-  ParticleDescriptor *c1;
-  //! \brief Vector of geometric asymmetry factors.
-  double *gaps;
-  //! \brief Components of extinction contribution to radiation torque on a single sphere along k.
-  double **tqse;
-  //! \brief Components of polarized extinction contribution to radiation torque on a single sphere along k.
-  dcomplex **tqspe;
-  //! \brief Components of scattering contribution to radiation torque on a single sphere along k.
-  double **tqss;
-  //! \brief Components of polarized scattering contribution to radiation torque on a single sphere along k.
-  dcomplex **tqsps;
-  //! \brief L-dependent coefficients of the geometric asymmetry parameter.
-  double ****zpv;
-  //! \brief Mean geometric asymmetry parameters.
-  double **gapm;
-  //! \brief Mean geometric asymmetry parameters referred to polarization plane.
-  dcomplex **gappm;
-  //! \brief Imaginary part of the harmonic functions argument.
-  double *argi;
-  //! \brief Argument of the harmonic functions referred to the scattering plane.
-  double *args;
-  //! \brief Geometric asymmetry parameters.
-  double **gap;
-  //! \brief Geometric asymmetry parameters referred to polarization plane.
-  dcomplex **gapp;
-  //! \brief Components of extinction contribution to radiation torque on the cluster along k.
-  double **tqce;
-  //! \brief Components of extinction contribution to radiation torque on the cluster along k referred to polarization plane.
-  dcomplex **tqcpe;
-  //! \brief Components of scattering contribution to radiation torque on the cluster along k.
-  double **tqcs;
-  //! \brief Components of scattering contribution to radiation torque on the cluster along k referred to polarization plane.
-  dcomplex **tqcps;
-  //! \brief Variation of unitary radiation vector. QUESTION: correct?
-  double *duk;
-  //! \brief Cluster extinction cross-section components referred to scattering plane.
-  double **cextlr;
-  //! \brief Cluster extinction cross-section components referred to meridional plane.
-  double **cext;
-  //! \brief Cluster Mueller Transformation Matrix components referred to scattering plane.
-  double **cmullr;
-  //! \brief Cluster Mueller Transformation Matrix components referred to meridional plane.
-  double **cmul;
-  //! \brief Geometric asymmetry parameter components.
-  double *gapv;
-  //! \brief Radiation extinction torque components.
-  double *tqev;
-  //! \brief Radiation scattering torque components.
-  double *tqsv;
-  //! \brief Incident unitary vector components.
-  double *u;
-  //! \brief Scattered unitary vector components.
-  double *us;
-  //! \brief Normal unitary vector components.
-  double *un;
-  //! \brief Normal scattered unitary vector components.
-  double *uns;
-  //! \brief Incident unitary vector components on polarization plane.
-  double *up;
-  //! \brief Scattered unitary vector components on polarization plane.
-  double *ups;
-  //! \brief Mean unitary vector components normal to polarization plane.
-  double *unmp;
-  //! \brief Mean scattered unitary vector components normal to polarization plane.
-  double *unsmp;
-  //! \brief Mean incident unitary vector components on polarization plane.
-  double *upmp;
-  //! \brief Mean scattered unitary vector components on polarization plane.
-  double *upsmp;
-  //! \brief Scattering angle.
-  double scan;
-  //! \brief Control parameter on incidence direction referred to meridional plane.
-  double cfmp;
-  //! \brief Control parameter on scattering direction referred to meridional plane.
-  double sfmp;
-  //! \brief Control parameter on incidence direction referred to scattering plane.
-  double cfsp;
-  //! \brief Control parameter on scattering direction referred to scattering plane.
-  double sfsp;
-  //! \brief SQSFI = XI^-2
-  double sqsfi;
-  //! \brief Vectorized scattering coefficient matrix.
-  dcomplex *am_vector;
-  //! \brief Scattering coefficient matrix.
-  dcomplex **am;
-  //! \brief Argument of harmonic functions. QUESTION: correct?
-  dcomplex arg;
-  //! \brief Vacuum magnitude of wave vector.
-  double vk;
-  //! \brief Wave number.
-  double wn;
-  //! \brief Normalization scale. QUESTION: correct?
-  double xip;
-  //! \brief Number of scales (wavelengths) to be computed.
-  int number_of_scales;
-  //! \brief Size of the block of scales handled by the current process.
-  int xiblock;
-  //! \brief Index of the first scale handled by the current process.
-  int firstxi;
-  //! \brief Index of the last scale handled by the current process.
-  int lastxi;
-  //! \brief ID of the GPU used by one MPI process.
-  int proc_device;
-  //! \brief Refinement mode selction flag.
-  int refinemode;
-  //! \brief Maximum number of refinement iterations.
-  int maxrefiters;
-  //! \brief Required accuracy level.
-  double accuracygoal;
-
-  /*! \brief `ClusterIterationData` default instance constructor.
-   *
-   * \param gconf: `GeometryConfiguration *` Pointer to a `GeometryConfiguration` object.
-   * \param sconf: `ScattererConfiguration *` Pointer to a `ScattererConfiguration` object.
-   * \param mpidata: `mixMPI *` Pointer to a `mixMPI` object.
-   * \param device_count: `const int` Number of offload devices available on the system.
-   */
-  ClusterIterationData(GeometryConfiguration *gconf, ScattererConfiguration *sconf, const mixMPI *mpidata, const int device_count);
-  
-  /*! \brief `ClusterIterationData` copy constructor.
-   *
-   * \param rhs: `const ClusterIterationData &` Reference to the `ClusterIterationData` object to be copied.
-   */
-  ClusterIterationData(const ClusterIterationData& rhs);
-
-#ifdef MPI_VERSION
-  /*! \brief `ClusterIterationData` MPI constructor.
-   *
-   * \param mpidata: `const mixMPI *` Pointer to a `mixMPI` instance.
-   * \param device_count: `const int` Number of offload devices available on the system.
-   */
-  ClusterIterationData(const mixMPI *mpidata, const int device_count);
-
-  /*! \brief Broadcast over MPI the ClusterIterationData instance from MPI process 0 to all others.
-   *
-   * When using MPI, the initial ClusterIterationData instance created by MPI process 0
-   * needs to be replicated on all other processes. This function sends it using
-   * MPI broadcast calls. The MPI broadcast calls in this function must match those
-   * in the constructor using the mixMPI pointer.
-   *
-   * \param mpidata: `mixMPI *` Pointer to the mpi structure used to do the MPI broadcast.
-   */
-  void mpibcast(const mixMPI *mpidata);
-#endif // MPI_VERSION
-
-  /*! \brief `ClusterIterationData` instance destroyer.
-   */
-  ~ClusterIterationData();
-};
-
 /*! \brief Basic data structure describing the particle model and its interaction with fields.
  *
  * This class forms a base of the data structure collections that are used by the
diff --git a/src/include/IterationData.h b/src/include/IterationData.h
new file mode 100644
index 0000000000000000000000000000000000000000..46ebcee36ab9666511cd005795e035c32f22036d
--- /dev/null
+++ b/src/include/IterationData.h
@@ -0,0 +1,184 @@
+/* Copyright (C) 2024   INAF - Osservatorio Astronomico di Cagliari
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   A copy of the GNU General Public License is distributed along with
+   this program in the COPYING file. If not, see: <https://www.gnu.org/licenses/>.
+ */
+
+/*! \file IterationData.h
+ *
+ * \brief Multi-process communication data structures.
+ *
+ */
+
+#ifndef INCLUDE_ITERATION_DATA_H_
+#define INCLUDE_ITERATION_DATA_H_
+
+// >>> DEFINITION OF ClusterIterationData CLASS <<<
+/*! \brief A data structure representing the information used for a single scale
+ * of the CLUSTER case.
+ */
+class ClusterIterationData {
+public:
+  //! \brief Pointer to a ParticleDescriptor structure.
+  ParticleDescriptor *c1;
+  //! \brief Vector of geometric asymmetry factors.
+  double *gaps;
+  //! \brief Components of extinction contribution to radiation torque on a single sphere along k.
+  double **tqse;
+  //! \brief Components of polarized extinction contribution to radiation torque on a single sphere along k.
+  dcomplex **tqspe;
+  //! \brief Components of scattering contribution to radiation torque on a single sphere along k.
+  double **tqss;
+  //! \brief Components of polarized scattering contribution to radiation torque on a single sphere along k.
+  dcomplex **tqsps;
+  //! \brief L-dependent coefficients of the geometric asymmetry parameter.
+  double ****zpv;
+  //! \brief Mean geometric asymmetry parameters.
+  double **gapm;
+  //! \brief Mean geometric asymmetry parameters referred to polarization plane.
+  dcomplex **gappm;
+  //! \brief Imaginary part of the harmonic functions argument.
+  double *argi;
+  //! \brief Argument of the harmonic functions referred to the scattering plane.
+  double *args;
+  //! \brief Geometric asymmetry parameters.
+  double **gap;
+  //! \brief Geometric asymmetry parameters referred to polarization plane.
+  dcomplex **gapp;
+  //! \brief Components of extinction contribution to radiation torque on the cluster along k.
+  double **tqce;
+  //! \brief Components of extinction contribution to radiation torque on the cluster along k referred to polarization plane.
+  dcomplex **tqcpe;
+  //! \brief Components of scattering contribution to radiation torque on the cluster along k.
+  double **tqcs;
+  //! \brief Components of scattering contribution to radiation torque on the cluster along k referred to polarization plane.
+  dcomplex **tqcps;
+  //! \brief Variation of unitary radiation vector. QUESTION: correct?
+  double *duk;
+  //! \brief Cluster extinction cross-section components referred to scattering plane.
+  double **cextlr;
+  //! \brief Cluster extinction cross-section components referred to meridional plane.
+  double **cext;
+  //! \brief Cluster Mueller Transformation Matrix components referred to scattering plane.
+  double **cmullr;
+  //! \brief Cluster Mueller Transformation Matrix components referred to meridional plane.
+  double **cmul;
+  //! \brief Geometric asymmetry parameter components.
+  double *gapv;
+  //! \brief Radiation extinction torque components.
+  double *tqev;
+  //! \brief Radiation scattering torque components.
+  double *tqsv;
+  //! \brief Incident unitary vector components.
+  double *u;
+  //! \brief Scattered unitary vector components.
+  double *us;
+  //! \brief Normal unitary vector components.
+  double *un;
+  //! \brief Normal scattered unitary vector components.
+  double *uns;
+  //! \brief Incident unitary vector components on polarization plane.
+  double *up;
+  //! \brief Scattered unitary vector components on polarization plane.
+  double *ups;
+  //! \brief Mean unitary vector components normal to polarization plane.
+  double *unmp;
+  //! \brief Mean scattered unitary vector components normal to polarization plane.
+  double *unsmp;
+  //! \brief Mean incident unitary vector components on polarization plane.
+  double *upmp;
+  //! \brief Mean scattered unitary vector components on polarization plane.
+  double *upsmp;
+  //! \brief Scattering angle.
+  double scan;
+  //! \brief Control parameter on incidence direction referred to meridional plane.
+  double cfmp;
+  //! \brief Control parameter on scattering direction referred to meridional plane.
+  double sfmp;
+  //! \brief Control parameter on incidence direction referred to scattering plane.
+  double cfsp;
+  //! \brief Control parameter on scattering direction referred to scattering plane.
+  double sfsp;
+  //! \brief SQSFI = XI^-2
+  double sqsfi;
+  //! \brief Vectorized scattering coefficient matrix.
+  dcomplex *am_vector;
+  //! \brief Scattering coefficient matrix.
+  dcomplex **am;
+  //! \brief Argument of harmonic functions. QUESTION: correct?
+  dcomplex arg;
+  //! \brief Vacuum magnitude of wave vector.
+  double vk;
+  //! \brief Wave number.
+  double wn;
+  //! \brief Normalization scale. QUESTION: correct?
+  double xip;
+  //! \brief Number of scales (wavelengths) to be computed.
+  int number_of_scales;
+  //! \brief Size of the block of scales handled by the current process.
+  int xiblock;
+  //! \brief Index of the first scale handled by the current process.
+  int firstxi;
+  //! \brief Index of the last scale handled by the current process.
+  int lastxi;
+  //! \brief ID of the GPU used by one MPI process.
+  int proc_device;
+  //! \brief Refinement mode selction flag.
+  int refinemode;
+  //! \brief Maximum number of refinement iterations.
+  int maxrefiters;
+  //! \brief Required accuracy level.
+  double accuracygoal;
+
+  /*! \brief `ClusterIterationData` default instance constructor.
+   *
+   * \param gconf: `GeometryConfiguration *` Pointer to a `GeometryConfiguration` object.
+   * \param sconf: `ScattererConfiguration *` Pointer to a `ScattererConfiguration` object.
+   * \param mpidata: `mixMPI *` Pointer to a `mixMPI` object.
+   * \param device_count: `const int` Number of offload devices available on the system.
+   */
+  ClusterIterationData(GeometryConfiguration *gconf, ScattererConfiguration *sconf, const mixMPI *mpidata, const int device_count);
+  
+  /*! \brief `ClusterIterationData` copy constructor.
+   *
+   * \param rhs: `const ClusterIterationData &` Reference to the `ClusterIterationData` object to be copied.
+   */
+  ClusterIterationData(const ClusterIterationData& rhs);
+
+#ifdef MPI_VERSION
+  /*! \brief `ClusterIterationData` MPI constructor.
+   *
+   * \param mpidata: `const mixMPI *` Pointer to a `mixMPI` instance.
+   * \param device_count: `const int` Number of offload devices available on the system.
+   */
+  ClusterIterationData(const mixMPI *mpidata, const int device_count);
+
+  /*! \brief Broadcast over MPI the ClusterIterationData instance from MPI process 0 to all others.
+   *
+   * When using MPI, the initial ClusterIterationData instance created by MPI process 0
+   * needs to be replicated on all other processes. This function sends it using
+   * MPI broadcast calls. The MPI broadcast calls in this function must match those
+   * in the constructor using the mixMPI pointer.
+   *
+   * \param mpidata: `mixMPI *` Pointer to the mpi structure used to do the MPI broadcast.
+   */
+  void mpibcast(const mixMPI *mpidata);
+#endif // MPI_VERSION
+
+  /*! \brief `ClusterIterationData` instance destroyer.
+   */
+  ~ClusterIterationData();
+};
+// >>> END OF DEFINITION OF ClusterIterationData CLASS <<<
+
+#endif // INCLUDE_ITERATION_DATA_H_
diff --git a/src/libnptm/Commons.cpp b/src/libnptm/Commons.cpp
index e3b7eea555653d1186c28044ec36f177c90a87f7..cfdec141721873bb3ecddaaa80614fefa6a87959 100644
--- a/src/libnptm/Commons.cpp
+++ b/src/libnptm/Commons.cpp
@@ -61,537 +61,6 @@ mixMPI::mixMPI(const mixMPI& rhs) {
 mixMPI::~mixMPI() {
 }
 
-ClusterIterationData::ClusterIterationData(GeometryConfiguration *gconf, ScattererConfiguration *sconf, const mixMPI *mpidata, const int device_count) {
-  c1 = new ParticleDescriptorCluster(gconf, sconf);
-  const int ndi = c1->nsph * c1->nlim;
-  const np_int ndit = 2 * ndi;
-  gaps = new double[c1->nsph]();
-  tqev = new double[3]();
-  tqsv = new double[3]();
-  tqse = new double*[2];
-  tqspe = new dcomplex*[2];
-  tqss = new double*[2];
-  tqsps = new dcomplex*[2];
-  tqce = new double*[2];
-  tqcpe = new dcomplex*[2];
-  tqcs = new double*[2];
-  tqcps = new dcomplex*[2];
-  for (int ti = 0; ti < 2; ti++) {
-    tqse[ti] = new double[c1->nsph]();
-    tqspe[ti] = new dcomplex[c1->nsph]();
-    tqss[ti] = new double[c1->nsph]();
-    tqsps[ti] = new dcomplex[c1->nsph]();
-    tqce[ti] = new double[3]();
-    tqcpe[ti] = new dcomplex[3]();
-    tqcs[ti] = new double[3]();
-    tqcps[ti] = new dcomplex[3]();
-  }
-  gapv = new double[3]();
-  gapp = new dcomplex*[3];
-  gappm = new dcomplex*[3];
-  gap = new double*[3];
-  gapm = new double*[3];
-  for (int gi = 0; gi < 3; gi++) {
-    gapp[gi] = new dcomplex[2]();
-    gappm[gi] = new dcomplex[2]();
-    gap[gi] = new double[2]();
-    gapm[gi] = new double[2]();
-  }
-  u = new double[3]();
-  us = new double[3]();
-  un = new double[3]();
-  uns = new double[3]();
-  up = new double[3]();
-  ups = new double[3]();
-  unmp = new double[3]();
-  unsmp = new double[3]();
-  upmp = new double[3]();
-  upsmp = new double[3]();
-  argi = new double[1]();
-  args = new double[1]();
-  duk = new double[3]();
-  cextlr = new double*[4];
-  cext = new double*[4];
-  cmullr = new double*[4];;
-  cmul = new double*[4];
-  for (int ci = 0; ci < 4; ci++) {
-    cextlr[ci] = new double[4]();
-    cext[ci] = new double[4]();
-    cmullr[ci] = new double[4]();
-    cmul[ci] = new double[4]();
-  }
-  zpv = new double***[c1->lm];
-  for (int zi = 0; zi < c1->lm; zi++) {
-    zpv[zi] = new double**[3];
-    for (int zj = 0; zj < 3; zj++) {
-      zpv[zi][zj] = new double*[2];
-      for (int zk = 0; zk < 2; zk++) {
-	zpv[zi][zj][zk] = new double[2]();
-      }
-    }
-  }
-  am_vector = new dcomplex[ndit * ndit]();
-  am = new dcomplex*[ndit];
-  for (int ai = 0; ai < ndit; ai++) {
-    am[ai] = (am_vector + ai * ndit);
-  }
-  
-  arg = 0.0 + 0.0 * I;
-  // These are suspect initializations
-  scan = 0.0;
-  cfmp = 0.0;
-  sfmp = 0.0;
-  cfsp = 0.0;
-  sfsp = 0.0;
-  // End of suspect initializations
-  wn = sconf->wp / 3.0e8;
-  xip = sconf->xip;
-  sqsfi = 1.0;
-  vk = 0.0;
-  number_of_scales = sconf->number_of_scales;
-  xiblock = (int) ceil(((double) (sconf->number_of_scales-1))/((double) mpidata->nprocs));
-  lastxi = ((mpidata->rank+1) * xiblock)+1;
-  firstxi = lastxi-xiblock+1;
-  if (lastxi > sconf->number_of_scales) lastxi = sconf->number_of_scales;
-
-#ifdef USE_MAGMA
-  proc_device = mpidata->rank % device_count;
-#else
-  proc_device = 0;
-#endif
-
-  // In the first iteration, if refinement is enabled, determine the number of refinement iterations required to arrive at the target accuracy (if achievable in a reasonable number of iterations)
-  refinemode = 2;
-  // maxrefiters and accuracygoal should be configurable and preferably set somewhere else
-  maxrefiters = 20;
-  accuracygoal = 1e-6;
-}
-
-ClusterIterationData::ClusterIterationData(const ClusterIterationData& rhs) {
-  c1 = new ParticleDescriptorCluster(reinterpret_cast<ParticleDescriptorCluster &>(*(rhs.c1)));
-  const int ndi = c1->nsph * c1->nlim;
-  const np_int ndit = 2 * ndi;
-  gaps = new double[c1->nsph]();
-  for (int gi = 0; gi < c1->nsph; gi++) gaps[gi] = rhs.gaps[gi];
-  tqev = new double[3]();
-  tqsv = new double[3]();
-  for (int ti = 0; ti < 3; ti++) {
-    tqev[ti] = rhs.tqev[ti];
-    tqsv[ti] = rhs.tqsv[ti];
-  }
-  tqse = new double*[2];
-  tqspe = new dcomplex*[2];
-  tqss = new double*[2];
-  tqsps = new dcomplex*[2];
-  tqce = new double*[2];
-  tqcpe = new dcomplex*[2];
-  tqcs = new double*[2];
-  tqcps = new dcomplex*[2];
-  for (int ti = 0; ti < 2; ti++) {
-    tqse[ti] = new double[c1->nsph]();
-    tqspe[ti] = new dcomplex[c1->nsph]();
-    tqss[ti] = new double[c1->nsph]();
-    tqsps[ti] = new dcomplex[c1->nsph]();
-    for (int tj = 0; tj < c1->nsph; tj++) {
-      tqse[ti][tj] = rhs.tqse[ti][tj];
-      tqspe[ti][tj] = rhs.tqspe[ti][tj];
-      tqss[ti][tj] = rhs.tqss[ti][tj];
-      tqsps[ti][tj] = rhs.tqsps[ti][tj];
-    }
-    tqce[ti] = new double[3]();
-    tqcpe[ti] = new dcomplex[3]();
-    tqcs[ti] = new double[3]();
-    tqcps[ti] = new dcomplex[3]();
-    for (int tj = 0; tj < 3; tj++) {
-      tqce[ti][tj] = rhs.tqce[ti][tj];
-      tqcpe[ti][tj] = rhs.tqcpe[ti][tj];
-      tqcs[ti][tj] = rhs.tqcs[ti][tj];
-      tqcps[ti][tj] = rhs.tqcps[ti][tj];
-    }
-  }
-  gapv = new double[3]();
-  gapp = new dcomplex*[3];
-  gappm = new dcomplex*[3];
-  gap = new double*[3];
-  gapm = new double*[3];
-  for (int gi = 0; gi < 3; gi++) {
-    gapv[gi] = rhs.gapv[gi];
-    gapp[gi] = new dcomplex[2]();
-    gappm[gi] = new dcomplex[2]();
-    gap[gi] = new double[2]();
-    gapm[gi] = new double[2]();
-    for (int gj = 0; gj < 2; gj++) {
-      gapp[gi][gj] = rhs.gapp[gi][gj];
-      gappm[gi][gj] = rhs.gappm[gi][gj];
-      gap[gi][gj] = rhs.gap[gi][gj];
-      gapm[gi][gj] = rhs.gapm[gi][gj];
-    }
-  }
-  u = new double[3]();
-  us = new double[3]();
-  un = new double[3]();
-  uns = new double[3]();
-  up = new double[3]();
-  ups = new double[3]();
-  unmp = new double[3]();
-  unsmp = new double[3]();
-  upmp = new double[3]();
-  upsmp = new double[3]();
-  duk = new double[3]();
-  for (int ui = 0; ui < 3; ui++) {
-    u[ui] = rhs.u[ui];
-    us[ui] = rhs.us[ui];
-    un[ui] = rhs.un[ui];
-    uns[ui] = rhs.uns[ui];
-    up[ui] = rhs.up[ui];
-    ups[ui] = rhs.ups[ui];
-    unmp[ui] = rhs.unmp[ui];
-    unsmp[ui] = rhs.unsmp[ui];
-    upmp[ui] = rhs.upmp[ui];
-    upsmp[ui] = rhs.upsmp[ui];
-    duk[ui] = rhs.duk[ui];
-  }
-  argi = new double[1]();
-  args = new double[1]();
-  argi[0] = rhs.argi[0];
-  args[0] = rhs.args[0];
-  cextlr = new double*[4];
-  cext = new double*[4];
-  cmullr = new double*[4];;
-  cmul = new double*[4];
-  for (int ci = 0; ci < 4; ci++) {
-    cextlr[ci] = new double[4]();
-    cext[ci] = new double[4]();
-    cmullr[ci] = new double[4]();
-    cmul[ci] = new double[4]();
-    for (int cj = 0; cj < 4; cj++) {
-      cextlr[ci][cj] = rhs.cextlr[ci][cj];
-      cext[ci][cj] = rhs.cext[ci][cj];
-      cmullr[ci][cj] = rhs.cmullr[ci][cj];
-      cmul[ci][cj] = rhs.cmul[ci][cj];
-    }
-  }
-  zpv = new double***[c1->lm];
-  for (int zi = 0; zi < c1->lm; zi++) {
-    zpv[zi] = new double**[3];
-    for (int zj = 0; zj < 3; zj++) {
-      zpv[zi][zj] = new double*[2];
-      for (int zk = 0; zk < 2; zk++) {
-	zpv[zi][zj][zk] = new double[2]();
-	zpv[zi][zj][zk][0] = rhs.zpv[zi][zj][zk][0];
-	zpv[zi][zj][zk][1] = rhs.zpv[zi][zj][zk][1];
-      }
-    }
-  }
-  am_vector = new dcomplex[ndit * ndit]();
-  for (np_int ai = 0; ai < ndit * ndit; ai++) am_vector[ai] = rhs.am_vector[ai];
-  am = new dcomplex*[ndit];
-  for (np_int ai = 0; ai < ndit; ai++) {
-    am[ai] = (am_vector + ai * ndit);
-  }
-  
-  arg = rhs.arg;
-  // These are suspect initializations
-  scan = rhs.scan;
-  cfmp = rhs.cfmp;
-  sfmp = rhs.sfmp;
-  cfsp = rhs.cfsp;
-  sfsp = rhs.sfsp;
-  // End of suspect initializations
-  wn = rhs.wn;
-  xip = rhs.xip;
-  sqsfi = rhs.sqsfi;
-  vk = rhs.vk;
-  firstxi = rhs.firstxi;
-  lastxi = rhs.lastxi;
-  xiblock = rhs.xiblock;
-  number_of_scales = rhs.number_of_scales;
-
-  proc_device = rhs.proc_device;
-  refinemode = rhs.refinemode;
-  maxrefiters = rhs.maxrefiters;
-  accuracygoal = rhs.accuracygoal;
-}
-
-#ifdef MPI_VERSION
-ClusterIterationData::ClusterIterationData(const mixMPI *mpidata, const int device_count) {
-  c1 = new ParticleDescriptorCluster(mpidata);
-  const int ndi = c1->nsph * c1->nlim;
-  const np_int ndit = 2 * ndi;
-  gaps = new double[c1->nsph]();
-  MPI_Bcast(gaps, c1->nsph, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  tqev = new double[3]();
-  tqsv = new double[3]();
-  MPI_Bcast(tqev, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(tqsv, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  tqse = new double*[2];
-  tqspe = new dcomplex*[2];
-  tqss = new double*[2];
-  tqsps = new dcomplex*[2];
-  tqce = new double*[2];
-  tqcpe = new dcomplex*[2];
-  tqcs = new double*[2];
-  tqcps = new dcomplex*[2];
-  for (int ti = 0; ti < 2; ti++) {
-    tqse[ti] = new double[c1->nsph]();
-    tqspe[ti] = new dcomplex[c1->nsph]();
-    tqss[ti] = new double[c1->nsph]();
-    tqsps[ti] = new dcomplex[c1->nsph]();
-    MPI_Bcast(tqse[ti], c1->nsph, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-    MPI_Bcast(tqspe[ti], c1->nsph, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
-    MPI_Bcast(tqss[ti], c1->nsph, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-    MPI_Bcast(tqsps[ti], c1->nsph, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
-    tqce[ti] = new double[3]();
-    tqcpe[ti] = new dcomplex[3]();
-    tqcs[ti] = new double[3]();
-    tqcps[ti] = new dcomplex[3]();
-    MPI_Bcast(tqce[ti], 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-    MPI_Bcast(tqcpe[ti], 3, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
-    MPI_Bcast(tqcs[ti], 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-    MPI_Bcast(tqcps[ti], 3, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
-  }
-  gapv = new double[3]();
-  gapp = new dcomplex*[3];
-  gappm = new dcomplex*[3];
-  gap = new double*[3];
-  gapm = new double*[3];
-  MPI_Bcast(gapv, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  for (int gi = 0; gi < 3; gi++) {
-    gapp[gi] = new dcomplex[2]();
-    gappm[gi] = new dcomplex[2]();
-    gap[gi] = new double[2]();
-    gapm[gi] = new double[2]();
-    MPI_Bcast(gapp[gi], 2, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
-    MPI_Bcast(gappm[gi], 2, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
-    MPI_Bcast(gap[gi], 2, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-    MPI_Bcast(gapm[gi], 2, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  }
-  u = new double[3]();
-  us = new double[3]();
-  un = new double[3]();
-  uns = new double[3]();
-  up = new double[3]();
-  ups = new double[3]();
-  unmp = new double[3]();
-  unsmp = new double[3]();
-  upmp = new double[3]();
-  upsmp = new double[3]();
-  duk = new double[3]();
-  MPI_Bcast(u, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(us, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(un, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(uns, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(up, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(ups, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(unmp, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(unsmp, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(upmp, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(upsmp, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(duk, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  argi = new double[1]();
-  args = new double[1]();
-  MPI_Bcast(argi, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(args, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  cextlr = new double*[4];
-  cext = new double*[4];
-  cmullr = new double*[4];;
-  cmul = new double*[4];
-  for (int ci = 0; ci < 4; ci++) {
-    cextlr[ci] = new double[4]();
-    cext[ci] = new double[4]();
-    cmullr[ci] = new double[4]();
-    cmul[ci] = new double[4]();
-    MPI_Bcast(cextlr[ci], 4, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-    MPI_Bcast(cext[ci], 4, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-    MPI_Bcast(cmullr[ci], 4, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-    MPI_Bcast(cmul[ci], 4, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  }
-  zpv = new double***[c1->lm];
-  for (int zi = 0; zi < c1->lm; zi++) {
-    zpv[zi] = new double**[3];
-    for (int zj = 0; zj < 3; zj++) {
-      zpv[zi][zj] = new double*[2];
-      for (int zk = 0; zk < 2; zk++) {
-	zpv[zi][zj][zk] = new double[2]();
-	MPI_Bcast(zpv[zi][zj][zk], 2, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-      }
-    }
-  }
-  am_vector = new dcomplex[ndit * ndit]();
-  am = new dcomplex*[ndit];
-  for (np_int ai = 0; ai < ndit; ai++) {
-    am[ai] = (am_vector + ai * ndit);
-    MPI_Bcast(am[ai], ndit, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
-  }
-  MPI_Bcast(&arg, 1, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&scan, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&cfmp, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&sfmp, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&cfsp, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&sfsp, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&wn, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&xip, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&sqsfi, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&vk, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&xiblock, 1, MPI_INT, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&number_of_scales, 1, MPI_INT, 0, MPI_COMM_WORLD);
-  lastxi = ((mpidata->rank+1) * xiblock)+1;
-  firstxi = lastxi-xiblock+1;
-  if (lastxi > number_of_scales) lastxi = number_of_scales;
-
-#ifdef USE_MAGMA
-  proc_device = mpidata->rank % device_count;
-#else
-  proc_device = 0;
-#endif
-  MPI_Bcast(&refinemode, 1, MPI_INT, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&maxrefiters, 1, MPI_INT, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&accuracygoal, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-}
-
-void ClusterIterationData::mpibcast(const mixMPI *mpidata) {
-  c1->mpibcast(mpidata);
-  const int ndi = c1->nsph * c1->nlim;
-  const np_int ndit = 2 * ndi;
-  MPI_Bcast(gaps, c1->nsph, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(tqev, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(tqsv, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  for (int ti = 0; ti < 2; ti++) {
-    MPI_Bcast(tqse[ti], c1->nsph, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-    MPI_Bcast(tqspe[ti], c1->nsph, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
-    MPI_Bcast(tqss[ti], c1->nsph, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-    MPI_Bcast(tqsps[ti], c1->nsph, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
-    MPI_Bcast(tqce[ti], 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-    MPI_Bcast(tqcpe[ti], 3, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
-    MPI_Bcast(tqcs[ti], 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-    MPI_Bcast(tqcps[ti], 3, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
-  }
-  MPI_Bcast(gapv, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  for (int gi = 0; gi < 3; gi++) {
-    MPI_Bcast(gapp[gi], 2, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
-    MPI_Bcast(gappm[gi], 2, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
-    MPI_Bcast(gap[gi], 2, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-    MPI_Bcast(gapm[gi], 2, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  }
-  MPI_Bcast(u, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(us, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(un, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(uns, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(up, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(ups, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(unmp, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(unsmp, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(upmp, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(upsmp, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(duk, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(argi, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(args, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  for (int ci = 0; ci < 4; ci++) {
-    MPI_Bcast(cextlr[ci], 4, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-    MPI_Bcast(cext[ci], 4, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-    MPI_Bcast(cmullr[ci], 4, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-    MPI_Bcast(cmul[ci], 4, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  }
-  for (int zi = 0; zi < c1->lm; zi++) {
-    for (int zj = 0; zj < 3; zj++) {
-      for (int zk = 0; zk < 2; zk++) {
-	MPI_Bcast(zpv[zi][zj][zk], 2, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-      }
-    }
-  }
-  // since MPI expects an int argument for the number of elements to transfer in one go, transfer am one row at a time
-  for (int ai = 0; ai < ndit; ai++) {
-    MPI_Bcast(am[ai], ndit, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
-  }
-  MPI_Bcast(&arg, 1, MPI_C_DOUBLE_COMPLEX, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&scan, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&cfmp, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&sfmp, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&cfsp, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&sfsp, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&wn, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&xip, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&sqsfi, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&vk, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&xiblock, 1, MPI_INT, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&number_of_scales, 1, MPI_INT, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&refinemode, 1, MPI_INT, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&maxrefiters, 1, MPI_INT, 0, MPI_COMM_WORLD);
-  MPI_Bcast(&accuracygoal, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
-}
-#endif
-
-ClusterIterationData::~ClusterIterationData() {
-  const int nsph = c1->nsph;
-  delete[] am_vector;
-  delete[] am;
-  for (int zi = c1->lm - 1; zi > -1; zi--) {
-    for (int zj = 2; zj > -1; zj--) {
-      delete[] zpv[zi][zj][1];
-      delete[] zpv[zi][zj][0];
-      delete[] zpv[zi][zj];
-    }
-    delete[] zpv[zi];
-  }
-  delete[] zpv;
-  delete c1;
-  delete[] gaps;
-  for (int ti = 1; ti > -1; ti--) {
-    delete[] tqse[ti];
-    delete[] tqss[ti];
-    delete[] tqspe[ti];
-    delete[] tqsps[ti];
-    delete[] tqce[ti];
-    delete[] tqcpe[ti];
-    delete[] tqcs[ti];
-    delete[] tqcps[ti];
-  }
-  delete[] tqse;
-  delete[] tqss;
-  delete[] tqspe;
-  delete[] tqsps;
-  delete[] tqce;
-  delete[] tqcpe;
-  delete[] tqcs;
-  delete[] tqcps;
-  delete[] tqev;
-  delete[] tqsv;
-  for (int gi = 2; gi > -1; gi--) {
-    delete[] gapp[gi];
-    delete[] gappm[gi];
-    delete[] gap[gi];
-    delete[] gapm[gi];
-  }
-  delete[] gapp;
-  delete[] gappm;
-  delete[] gap;
-  delete[] gapm;
-  delete[] gapv;
-  delete[] u;
-  delete[] us;
-  delete[] un;
-  delete[] uns;
-  delete[] up;
-  delete[] ups;
-  delete[] unmp;
-  delete[] unsmp;
-  delete[] upmp;
-  delete[] upsmp;
-  delete[] argi;
-  delete[] args;
-  delete[] duk;
-  for (int ci = 3; ci > -1; ci--) {
-    delete[] cextlr[ci];
-    delete[] cext[ci];
-    delete[] cmullr[ci];
-    delete[] cmul[ci];
-  }
-  delete[] cextlr;
-  delete[] cext;
-  delete[] cmullr;
-  delete[] cmul;
-}
-
 // >>> ParticleDescriptor class implementation. <<< //
 ParticleDescriptor::ParticleDescriptor(GeometryConfiguration *gconf, ScattererConfiguration *sconf) {
   _class_type = BASE_TYPE;