From 66b62a5964dac3f388947fa4bec34bf0479d1d5d Mon Sep 17 00:00:00 2001
From: Holger Obermaier <holger.obermaier@kit.edu>
Date: Thu, 3 Apr 2025 15:30:23 +0200
Subject: [PATCH 01/15] Add float 3D tensor type

---
 src/fd.hpp             |  1 +
 src/float3DTensorT.cpp | 99 ++++++++++++++++++++++++++++++++++++++++++
 src/float3DTensorT.hpp | 38 ++++++++++++++++
 3 files changed, 138 insertions(+)
 create mode 100644 src/float3DTensorT.cpp
 create mode 100644 src/float3DTensorT.hpp

diff --git a/src/fd.hpp b/src/fd.hpp
index 7967b03..8293bff 100644
--- a/src/fd.hpp
+++ b/src/fd.hpp
@@ -36,6 +36,7 @@
 #include "globvar_struct.hpp"
 #include "macros.hpp"
 #include "kiss_fftr.h"
+#include "float3DTensorT.hpp"
 
 typedef struct Model {
     float ***rho, ***pi, ***u;
diff --git a/src/float3DTensorT.cpp b/src/float3DTensorT.cpp
new file mode 100644
index 0000000..5a7c30e
--- /dev/null
+++ b/src/float3DTensorT.cpp
@@ -0,0 +1,99 @@
+#include "float3DTensorT.hpp"
+#include <cassert>
+#include <cstddef>
+#include <cstdlib>
+#include <iostream>
+
+float3DTensorT::float3DTensorT(
+    const size_t &lb_i, const size_t &ub_i,
+    const size_t &lb_j, const size_t &ub_j,
+    const size_t &lb_k, const size_t &ub_k) : _lb_i(lb_i), _ub_i(ub_i),
+    _lb_j(lb_j), _ub_j(ub_j),
+    _lb_k(lb_k), _ub_k(ub_k),
+    _dim_i(ub_i - lb_i + 1),
+    _dim_j(ub_j - lb_j + 1),
+    _dim_k(ub_k - lb_k + 1),
+    _size(_dim_i * _dim_j * _dim_k),
+    _stride_i(_dim_j * _dim_k),
+    _stride_j(_dim_k),
+    _stride_k(0),
+    offset(lb_i * _stride_i + lb_j * _stride_j + lb_k)
+{
+    assert(lb_i <= ub_i);
+    assert(lb_j <= ub_j);
+    assert(lb_k <= ub_k);
+    data = (float *)malloc(_size * sizeof(float));
+    if (data == NULL) {
+        std::cerr << "Failed to allocate memory" << std::endl;
+        exit(EXIT_FAILURE);
+    }
+    #pragma omp simd
+    for (size_t i = 0; i < _size; i++) {
+        data[i] = 0.0f;
+    }
+};
+
+float3DTensorT::~float3DTensorT()
+{
+    free(data);
+}
+
+// https://en.cppreference.com/w/cpp/language/operators#Array_subscript_operator
+constexpr float &float3DTensorT::operator[](const size_t &i, const size_t &j, const size_t &k) noexcept
+{
+    assert(_lb_i <= i and i <= _ub_i);
+    assert(_lb_j <= j and j <= _ub_j);
+    assert(_lb_k <= k and k <= _ub_k);
+    const size_t index = i * _stride_i + j * _stride_j + k - offset;
+    assert(index < _size);
+    return data[index];
+}
+
+constexpr size_t float3DTensorT::lb_i() noexcept
+{
+    return _lb_i;
+}
+
+constexpr size_t float3DTensorT::ub_i() noexcept
+{
+    return _ub_i;
+}
+
+constexpr size_t float3DTensorT::lb_j() noexcept
+{
+    return _lb_j;
+}
+
+constexpr size_t float3DTensorT::ub_j() noexcept
+{
+    return _ub_j;
+}
+
+constexpr size_t float3DTensorT::lb_k() noexcept
+{
+    return _lb_k;
+}
+constexpr size_t float3DTensorT::ub_k() noexcept
+{
+    return _ub_k;
+}
+
+constexpr size_t float3DTensorT::dim_i() noexcept
+{
+    return _dim_i;
+}
+
+constexpr size_t float3DTensorT::dim_j() noexcept
+{
+    return _dim_j;
+}
+
+constexpr size_t float3DTensorT::dim_k() noexcept
+{
+    return _dim_k;
+}
+
+constexpr size_t float3DTensorT::size() noexcept
+{
+    return _size;
+}
diff --git a/src/float3DTensorT.hpp b/src/float3DTensorT.hpp
new file mode 100644
index 0000000..a495841
--- /dev/null
+++ b/src/float3DTensorT.hpp
@@ -0,0 +1,38 @@
+#ifndef _FLOAT_3D_TENSOR_INCLUDED_
+#define _FLOAT_3D_TENSOR_INCLUDED_
+
+#include <cstddef>
+
+struct float3DTensorT {
+private:
+    const size_t _lb_i, _ub_i,
+                 _lb_j, _ub_j,
+                 _lb_k, _ub_k,
+                 _dim_i, _dim_j, _dim_k, _size,
+                 _stride_i, _stride_j, _stride_k, offset;
+    float *      data;
+
+public:
+    float3DTensorT(const size_t &lb_i, const size_t &ub_i,
+                   const size_t &lb_j, const size_t &ub_j,
+                   const size_t &lb_k, const size_t &ub_k);
+
+    ~float3DTensorT();
+
+    constexpr float &operator[](const size_t &i, const size_t &j, const size_t &k) noexcept;
+
+    constexpr size_t lb_i() noexcept;
+    constexpr size_t ub_i() noexcept;
+    constexpr size_t lb_j() noexcept;
+    constexpr size_t ub_j() noexcept;
+    constexpr size_t lb_k() noexcept;
+    constexpr size_t ub_k() noexcept;
+
+    constexpr size_t dim_i() noexcept;
+    constexpr size_t dim_j() noexcept;
+    constexpr size_t dim_k() noexcept;
+
+    constexpr size_t size() noexcept;
+};
+
+#endif
\ No newline at end of file
-- 
GitLab


From d6305cce0abc1294bd581513f82d1190fd6c9b96 Mon Sep 17 00:00:00 2001
From: Holger Obermaier <holgerob@gmx.de>
Date: Fri, 4 Apr 2025 11:46:37 +0200
Subject: [PATCH 02/15] Use float3DTensorT in type st_velocity

---
 build/Makefile                     |   1 +
 src/disc_fourier.cpp               |  14 +-
 src/exchange_buffer.cpp            |  69 ++++-
 src/exchange_buffer.hpp            |  13 +
 src/exchange_v.cpp                 | 222 +++++++--------
 src/fd.hpp                         |  58 ++--
 src/float3DTensorT.cpp             | 101 ++++---
 src/float3DTensorT.hpp             |  52 ++--
 src/freemem.cpp                    |  26 +-
 src/fsource.cpp                    |  28 +-
 src/ifos3d.cpp                     |  24 +-
 src/initmem.cpp                    |  68 +++--
 src/seismo_ssg.cpp                 |  90 +++---
 src/snap_ssg.cpp                   |  52 ++--
 src/stfi.cpp                       |   2 +-
 src/surface_ssg.cpp                | 144 +++++-----
 src/surface_ssg_elastic.cpp        | 132 ++++-----
 src/timeloop.cpp                   |  25 +-
 src/update_s_ssg_CPML_acoustic.cpp |  74 ++---
 src/update_s_ssg_CPML_elastic.cpp  | 218 +++++++--------
 src/update_s_ssg_acoustic.cpp      | 132 ++++-----
 src/update_s_ssg_elastic.cpp       | 428 ++++++++++++++---------------
 src/update_v_ssg.cpp               |  49 ++--
 src/update_v_ssg_CPML.cpp          |  38 +--
 src/update_v_ssg_CPML_acoustic.cpp |  38 +--
 src/update_v_ssg_acoustic.cpp      |  85 +++---
 src/zero_wavefield.cpp             |   8 +-
 src/zero_wavefield_acoustic.cpp    |   8 +-
 28 files changed, 1160 insertions(+), 1039 deletions(-)

diff --git a/build/Makefile b/build/Makefile
index 0d51ddc..6176be7 100644
--- a/build/Makefile
+++ b/build/Makefile
@@ -214,6 +214,7 @@ IFOS_FILES := absorb.cpp \
               exchange_s_acoustic.cpp \
               exchange_v.cpp \
               filt_seis.cpp \
+	      float3DTensorT.cpp \
               freemem.cpp \
               freemem_seis.cpp \
               fsource.cpp \
diff --git a/src/disc_fourier.cpp b/src/disc_fourier.cpp
index d1a7c9d..ad7c93f 100644
--- a/src/disc_fourier.cpp
+++ b/src/disc_fourier.cpp
@@ -25,7 +25,7 @@
 
 #include "fd.hpp"
 
-void discfourier(const st_boundary *nb, int nt, st_velocity *vel,
+void discfourier(const st_boundary *nb, int nt, st_velocity &vel,
                  st_freq_velocity *fourier_vel, const float *finv,
                  int nf, int ntast, int pshot1, int back, const GlobVar *gv)
 {
@@ -43,12 +43,12 @@ void discfourier(const st_boundary *nb, int nt, st_velocity *vel,
         for (int j = nb->ny1; j <= nb->ny2; j++) {
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    fourier_vel->Fvx_re[m][j][i][k] += vel->vx[j][i][k] * trig1;
-                    fourier_vel->Fvy_re[m][j][i][k] += vel->vy[j][i][k] * trig1;
-                    fourier_vel->Fvz_re[m][j][i][k] += vel->vz[j][i][k] * trig1;
-                    fourier_vel->Fvx_im[m][j][i][k] += vel->vx[j][i][k] * trig2;
-                    fourier_vel->Fvy_im[m][j][i][k] += vel->vy[j][i][k] * trig2;
-                    fourier_vel->Fvz_im[m][j][i][k] += vel->vz[j][i][k] * trig2;
+                    fourier_vel->Fvx_re[m][j][i][k] += vel.vx[j, i, k] * trig1;
+                    fourier_vel->Fvy_re[m][j][i][k] += vel.vy[j, i, k] * trig1;
+                    fourier_vel->Fvz_re[m][j][i][k] += vel.vz[j, i, k] * trig1;
+                    fourier_vel->Fvx_im[m][j][i][k] += vel.vx[j, i, k] * trig2;
+                    fourier_vel->Fvy_im[m][j][i][k] += vel.vy[j, i, k] * trig2;
+                    fourier_vel->Fvz_im[m][j][i][k] += vel.vz[j, i, k] * trig2;
                 }
             }
         }
diff --git a/src/exchange_buffer.cpp b/src/exchange_buffer.cpp
index bf65d28..e4501da 100644
--- a/src/exchange_buffer.cpp
+++ b/src/exchange_buffer.cpp
@@ -1,5 +1,6 @@
-#include <stddef.h>
+#include "float3DTensorT.hpp"
 #include <cstring>
+#include <stddef.h>
 
 // Choose default method to push and pop data to the buffer
 // available methods: OPENMP, MEMCPY
@@ -74,6 +75,72 @@ int buffer_pop(
     }
     return buffer_counter;
 }
+
+int buffer_push(
+    float *__restrict__ buffer, float3DTensorT &src,
+    int i1_start, int i1_end,
+    int i2_start, int i2_end,
+    int i3_start, int i3_end,
+    int buffer_counter)
+{
+    if (i1_end < i1_start) {
+        int swap = i1_start;
+        i1_start = i1_end;
+        i1_end = swap;
+    }
+    if (i2_end < i2_start) {
+        int swap = i2_start;
+        i2_start = i2_end;
+        i2_end = swap;
+    }
+    if (i3_end < i3_start) {
+        int swap = i3_start;
+        i3_start = i3_end;
+        i3_end = swap;
+    }
+    for (int i1 = i1_start; i1 <= i1_end; i1++) {
+        for (int i2 = i2_start; i2 <= i2_end; i2++) {
+            #pragma omp simd
+            for (int i3 = i3_start; i3 <= i3_end; i3++) {
+                buffer[buffer_counter++] = src[i1, i2, i3];
+            }
+        }
+    }
+    return buffer_counter;
+}
+
+int buffer_pop(
+    float3DTensorT &dest, float *__restrict__ buffer,
+    int i1_start, int i1_end,
+    int i2_start, int i2_end,
+    int i3_start, int i3_end,
+    int buffer_counter)
+{
+    if (i1_end < i1_start) {
+        int swap = i1_start;
+        i1_start = i1_end;
+        i1_end = swap;
+    }
+    if (i2_end < i2_start) {
+        int swap = i2_start;
+        i2_start = i2_end;
+        i2_end = swap;
+    }
+    if (i3_end < i3_start) {
+        int swap = i3_start;
+        i3_start = i3_end;
+        i3_end = swap;
+    }
+    for (int i1 = i1_start; i1 <= i1_end; i1++) {
+        for (int i2 = i2_start; i2 <= i2_end; i2++) {
+            #pragma omp simd
+            for (int i3 = i3_start; i3 <= i3_end; i3++) {
+                dest[i1, i2, i3] = buffer[buffer_counter++];
+            }
+        }
+    }
+    return buffer_counter;
+}
 #endif
 
 #ifdef BUFFER_EXCHANGE_USE_METHOD_MEMCPY
diff --git a/src/exchange_buffer.hpp b/src/exchange_buffer.hpp
index f2fba4b..2c2cc46 100644
--- a/src/exchange_buffer.hpp
+++ b/src/exchange_buffer.hpp
@@ -1,6 +1,7 @@
 #ifndef _EXCHANGE_BUFFER_H_INCLUDED_
 #define _EXCHANGE_BUFFER_H_INCLUDED_
 
+#include "float3DTensorT.hpp"
 int buffer_push(float *__restrict__ buffer, float ***__restrict__ src,
                 int i1_start, int i1_end,
                 int i2_start, int i2_end,
@@ -13,4 +14,16 @@ int buffer_pop(float ***__restrict__ dest, float *__restrict__ buffer,
                int i3_start, int i3_end,
                int buffer_counter);
 
+int buffer_push(float *__restrict__ buffer, float3DTensorT &src,
+                int i1_start, int i1_end,
+                int i2_start, int i2_end,
+                int i3_start, int i3_end,
+                int buffer_counter);
+
+int buffer_pop(float3DTensorT &dest, float *__restrict__ buffer,
+               int i1_start, int i1_end,
+               int i2_start, int i2_end,
+               int i3_start, int i3_end,
+               int buffer_counter);
+
 #endif
diff --git a/src/exchange_v.cpp b/src/exchange_v.cpp
index 0163e5f..456df83 100644
--- a/src/exchange_v.cpp
+++ b/src/exchange_v.cpp
@@ -9,7 +9,7 @@
 #include "fd.hpp"
 
 #ifdef MPI_SENDRECV_REPLACE
-double exchange_v(st_velocity *vel, st_buffer_flat *buffer, GlobVar *gv)
+double exchange_v(st_velocity &vel, st_buffer_flat *buffer, GlobVar *gv)
 {
     MPI_Status status;
     int n;
@@ -62,17 +62,17 @@ double exchange_v(st_velocity *vel, st_buffer_flat *buffer, GlobVar *gv)
     /* top-bottom ----------------------------------------------------------- */
 
     if (send_top_to_bot) {
-        n = buffer_push(buffer->top_to_bot, vel->vx, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
-        n = buffer_push(buffer->top_to_bot, vel->vz, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, n);
-        n = buffer_push(buffer->top_to_bot, vel->vy, 1, gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ, n);
+        n = buffer_push(buffer->top_to_bot, vel.vx, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
+        n = buffer_push(buffer->top_to_bot, vel.vz, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, n);
+        n = buffer_push(buffer->top_to_bot, vel.vy, 1, gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ, n);
     }
 
     if (send_bot_to_top) {
-        n = buffer_push(buffer->bot_to_top, vel->vy, gv->NY + 1 - 1, gv->NY + 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ,
+        n = buffer_push(buffer->bot_to_top, vel.vy, gv->NY + 1 - 1, gv->NY + 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ,
                         0);
-        n = buffer_push(buffer->bot_to_top, vel->vx, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1,
+        n = buffer_push(buffer->bot_to_top, vel.vx, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1,
                         gv->NZ, n);
-        n = buffer_push(buffer->bot_to_top, vel->vz, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1,
+        n = buffer_push(buffer->bot_to_top, vel.vz, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1,
                         gv->NZ, n);
     }
 
@@ -84,31 +84,31 @@ double exchange_v(st_velocity *vel, st_buffer_flat *buffer, GlobVar *gv)
                          gv->COMM_SHOT, &status);
 
     if (recv_top_to_bot) {
-        n = buffer_pop(vel->vx, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
-        n = buffer_pop(vel->vz, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, n);
-        n = buffer_pop(vel->vy, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ, n);
+        n = buffer_pop(vel.vx, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
+        n = buffer_pop(vel.vz, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, n);
+        n = buffer_pop(vel.vy, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ, n);
     }
 
     if (recv_bot_to_top) {
-        n = buffer_pop(vel->vy, buffer->bot_to_top, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
-        n = buffer_pop(vel->vx, buffer->bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ, n);
-        n = buffer_pop(vel->vz, buffer->bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ, n);
+        n = buffer_pop(vel.vy, buffer->bot_to_top, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
+        n = buffer_pop(vel.vx, buffer->bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ, n);
+        n = buffer_pop(vel.vz, buffer->bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ, n);
     }
 
     /* left-right ----------------------------------------------------------- */
 
     if (send_lef_to_rig) {
-        n = buffer_push(buffer->lef_to_rig, vel->vy, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, 0);
-        n = buffer_push(buffer->lef_to_rig, vel->vz, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, n);
-        n = buffer_push(buffer->lef_to_rig, vel->vx, 1, gv->NY, 1, gv->FDORDER / 2 - 1, 1, gv->NZ, n);
+        n = buffer_push(buffer->lef_to_rig, vel.vy, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, 0);
+        n = buffer_push(buffer->lef_to_rig, vel.vz, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, n);
+        n = buffer_push(buffer->lef_to_rig, vel.vx, 1, gv->NY, 1, gv->FDORDER / 2 - 1, 1, gv->NZ, n);
     }
 
     if (send_rig_to_lef) {
-        n = buffer_push(buffer->rig_to_lef, vel->vx, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - gv->FDORDER / 2, 1, gv->NZ,
+        n = buffer_push(buffer->rig_to_lef, vel.vx, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - gv->FDORDER / 2, 1, gv->NZ,
                         0);
-        n = buffer_push(buffer->rig_to_lef, vel->vy, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - (gv->FDORDER / 2 - 1), 1,
+        n = buffer_push(buffer->rig_to_lef, vel.vy, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - (gv->FDORDER / 2 - 1), 1,
                         gv->NZ, n);
-        n = buffer_push(buffer->rig_to_lef, vel->vz, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - (gv->FDORDER / 2 - 1), 1,
+        n = buffer_push(buffer->rig_to_lef, vel.vz, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - (gv->FDORDER / 2 - 1), 1,
                         gv->NZ, n);
     }
 
@@ -120,31 +120,31 @@ double exchange_v(st_velocity *vel, st_buffer_flat *buffer, GlobVar *gv)
                          gv->COMM_SHOT, &status);
 
     if (recv_lef_to_rig) {
-        n = buffer_pop(vel->vy, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1, gv->NZ, 0);
-        n = buffer_pop(vel->vz, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1, gv->NZ, n);
-        n = buffer_pop(vel->vx, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2 - 1, 1, gv->NZ, n);
+        n = buffer_pop(vel.vy, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1, gv->NZ, 0);
+        n = buffer_pop(vel.vz, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1, gv->NZ, n);
+        n = buffer_pop(vel.vx, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2 - 1, 1, gv->NZ, n);
     }
 
     if (recv_rig_to_lef) {
-        n = buffer_pop(vel->vx, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NZ, 0);
-        n = buffer_pop(vel->vy, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, n);
-        n = buffer_pop(vel->vz, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, n);
+        n = buffer_pop(vel.vx, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NZ, 0);
+        n = buffer_pop(vel.vy, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, n);
+        n = buffer_pop(vel.vz, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, n);
     }
 
     /* front-back ----------------------------------------------------------- */
 
     if (send_fro_to_bac) {
-        n = buffer_push(buffer->fro_to_bac, vel->vx, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, 0);
-        n = buffer_push(buffer->fro_to_bac, vel->vy, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, n);
-        n = buffer_push(buffer->fro_to_bac, vel->vz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2 - 1, n);
+        n = buffer_push(buffer->fro_to_bac, vel.vx, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, 0);
+        n = buffer_push(buffer->fro_to_bac, vel.vy, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, n);
+        n = buffer_push(buffer->fro_to_bac, vel.vz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2 - 1, n);
     }
 
     if (send_bac_to_fro) {
-        n = buffer_push(buffer->bac_to_fro, vel->vz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1, gv->NZ + 1 - gv->FDORDER / 2,
+        n = buffer_push(buffer->bac_to_fro, vel.vz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1, gv->NZ + 1 - gv->FDORDER / 2,
                         0);
-        n = buffer_push(buffer->bac_to_fro, vel->vx, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
+        n = buffer_push(buffer->bac_to_fro, vel.vx, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
                         gv->NZ + 1 - (gv->FDORDER / 2 - 1), n);
-        n = buffer_push(buffer->bac_to_fro, vel->vy, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
+        n = buffer_push(buffer->bac_to_fro, vel.vy, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
                         gv->NZ + 1 - (gv->FDORDER / 2 - 1), n);
     }
 
@@ -156,15 +156,15 @@ double exchange_v(st_velocity *vel, st_buffer_flat *buffer, GlobVar *gv)
                          gv->COMM_SHOT, &status);
 
     if (recv_fro_to_bac) {
-        n = buffer_pop(vel->vx, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2, 0);
-        n = buffer_pop(vel->vy, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2, n);
-        n = buffer_pop(vel->vz, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2 - 1, n);
+        n = buffer_pop(vel.vx, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2, 0);
+        n = buffer_pop(vel.vy, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2, n);
+        n = buffer_pop(vel.vz, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2 - 1, n);
     }
 
     if (recv_bac_to_fro) {
-        n = buffer_pop(vel->vz, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - gv->FDORDER / 2, 0);
-        n = buffer_pop(vel->vx, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1), n);
-        n = buffer_pop(vel->vy, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1), n);
+        n = buffer_pop(vel.vz, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - gv->FDORDER / 2, 0);
+        n = buffer_pop(vel.vx, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1), n);
+        n = buffer_pop(vel.vy, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1), n);
     }
 
     return time;
@@ -173,7 +173,7 @@ double exchange_v(st_velocity *vel, st_buffer_flat *buffer, GlobVar *gv)
 
 #ifdef MPI_ISENDRECV_REPLACE
 // requires OpenMPI version >= 5.0
-double exchange_v(st_velocity *vel, st_buffer_flat *buffer, GlobVar *gv)
+double exchange_v(st_velocity &vel, st_buffer_flat *buffer, GlobVar *gv)
 {
     MPI_Request requests[] = { MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL,
                                MPI_REQUEST_NULL };
@@ -227,20 +227,20 @@ double exchange_v(st_velocity *vel, st_buffer_flat *buffer, GlobVar *gv)
     const bool send_bac_to_fro = gv->BOUNDARY || gv->POS[3] != gv->NPROCZ - 1;
 
     if (send_top_to_bot) {
-        n = buffer_push(buffer->top_to_bot, vel->vx, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
-        n = buffer_push(buffer->top_to_bot, vel->vz, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, n);
-        n = buffer_push(buffer->top_to_bot, vel->vy, 1, gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ, n);
+        n = buffer_push(buffer->top_to_bot, vel.vx, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
+        n = buffer_push(buffer->top_to_bot, vel.vz, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, n);
+        n = buffer_push(buffer->top_to_bot, vel.vy, 1, gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ, n);
     }
     MPI_Isendrecv_replace(buffer->top_to_bot, gv->NX * gv->NZ * nf1, MPI_FLOAT, gv->INDEX[upper], tag_top_to_bot,
                           gv->INDEX[lower], tag_top_to_bot,
                           gv->COMM_SHOT, request_top_to_bot);
 
     if (send_bot_to_top) {
-        n = buffer_push(buffer->bot_to_top, vel->vy, gv->NY + 1 - 1, gv->NY + 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ,
+        n = buffer_push(buffer->bot_to_top, vel.vy, gv->NY + 1 - 1, gv->NY + 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ,
                         0);
-        n = buffer_push(buffer->bot_to_top, vel->vx, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1,
+        n = buffer_push(buffer->bot_to_top, vel.vx, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1,
                         gv->NZ, n);
-        n = buffer_push(buffer->bot_to_top, vel->vz, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1,
+        n = buffer_push(buffer->bot_to_top, vel.vz, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1,
                         gv->NZ, n);
     }
     MPI_Isendrecv_replace(buffer->bot_to_top, gv->NX * gv->NZ * nf2, MPI_FLOAT, gv->INDEX[lower], tag_bot_to_top,
@@ -248,20 +248,20 @@ double exchange_v(st_velocity *vel, st_buffer_flat *buffer, GlobVar *gv)
                           gv->COMM_SHOT, request_bot_to_top);
 
     if (send_lef_to_rig) {
-        n = buffer_push(buffer->lef_to_rig, vel->vy, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, 0);
-        n = buffer_push(buffer->lef_to_rig, vel->vz, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, n);
-        n = buffer_push(buffer->lef_to_rig, vel->vx, 1, gv->NY, 1, gv->FDORDER / 2 - 1, 1, gv->NZ, n);
+        n = buffer_push(buffer->lef_to_rig, vel.vy, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, 0);
+        n = buffer_push(buffer->lef_to_rig, vel.vz, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, n);
+        n = buffer_push(buffer->lef_to_rig, vel.vx, 1, gv->NY, 1, gv->FDORDER / 2 - 1, 1, gv->NZ, n);
     }
     MPI_Isendrecv_replace(buffer->lef_to_rig, gv->NY * gv->NZ * nf1, MPI_FLOAT, gv->INDEX[left], tag_lef_to_rig,
                           gv->INDEX[right], tag_lef_to_rig,
                           gv->COMM_SHOT, request_lef_to_rig);
 
     if (send_rig_to_lef) {
-        n = buffer_push(buffer->rig_to_lef, vel->vx, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - gv->FDORDER / 2, 1, gv->NZ,
+        n = buffer_push(buffer->rig_to_lef, vel.vx, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - gv->FDORDER / 2, 1, gv->NZ,
                         0);
-        n = buffer_push(buffer->rig_to_lef, vel->vy, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - (gv->FDORDER / 2 - 1), 1,
+        n = buffer_push(buffer->rig_to_lef, vel.vy, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - (gv->FDORDER / 2 - 1), 1,
                         gv->NZ, n);
-        n = buffer_push(buffer->rig_to_lef, vel->vz, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - (gv->FDORDER / 2 - 1), 1,
+        n = buffer_push(buffer->rig_to_lef, vel.vz, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - (gv->FDORDER / 2 - 1), 1,
                         gv->NZ, n);
     }
     MPI_Isendrecv_replace(buffer->rig_to_lef, gv->NY * gv->NZ * nf2, MPI_FLOAT, gv->INDEX[right], tag_rig_to_lef,
@@ -269,20 +269,20 @@ double exchange_v(st_velocity *vel, st_buffer_flat *buffer, GlobVar *gv)
                           gv->COMM_SHOT, request_rig_to_lef);
 
     if (send_fro_to_bac) {
-        n = buffer_push(buffer->fro_to_bac, vel->vx, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, 0);
-        n = buffer_push(buffer->fro_to_bac, vel->vy, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, n);
-        n = buffer_push(buffer->fro_to_bac, vel->vz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2 - 1, n);
+        n = buffer_push(buffer->fro_to_bac, vel.vx, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, 0);
+        n = buffer_push(buffer->fro_to_bac, vel.vy, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, n);
+        n = buffer_push(buffer->fro_to_bac, vel.vz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2 - 1, n);
     }
     MPI_Isendrecv_replace(buffer->fro_to_bac, gv->NX * gv->NY * nf1, MPI_FLOAT, gv->INDEX[front], tag_fro_to_bac,
                           gv->INDEX[back], tag_fro_to_bac,
                           gv->COMM_SHOT, request_fro_to_bac);
 
     if (send_bac_to_fro) {
-        n = buffer_push(buffer->bac_to_fro, vel->vz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1, gv->NZ + 1 - gv->FDORDER / 2,
+        n = buffer_push(buffer->bac_to_fro, vel.vz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1, gv->NZ + 1 - gv->FDORDER / 2,
                         0);
-        n = buffer_push(buffer->bac_to_fro, vel->vx, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
+        n = buffer_push(buffer->bac_to_fro, vel.vx, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
                         gv->NZ + 1 - (gv->FDORDER / 2 - 1), n);
-        n = buffer_push(buffer->bac_to_fro, vel->vy, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
+        n = buffer_push(buffer->bac_to_fro, vel.vy, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
                         gv->NZ + 1 - (gv->FDORDER / 2 - 1), n);
     }
     MPI_Isendrecv_replace(buffer->bac_to_fro, gv->NX * gv->NY * nf2, MPI_FLOAT, gv->INDEX[back], tag_bac_to_fro,
@@ -298,37 +298,37 @@ double exchange_v(st_velocity *vel, st_buffer_flat *buffer, GlobVar *gv)
 
         switch (status.MPI_TAG) {
         case tag_top_to_bot:
-            n = buffer_pop(vel->vx, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
-            n = buffer_pop(vel->vz, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, n);
-            n = buffer_pop(vel->vy, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ,
+            n = buffer_pop(vel.vx, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
+            n = buffer_pop(vel.vz, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, n);
+            n = buffer_pop(vel.vy, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ,
                            n);
             break;
         case tag_bot_to_top:
-            n = buffer_pop(vel->vy, buffer->bot_to_top, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
-            n = buffer_pop(vel->vx, buffer->bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ, n);
-            n = buffer_pop(vel->vz, buffer->bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ, n);
+            n = buffer_pop(vel.vy, buffer->bot_to_top, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
+            n = buffer_pop(vel.vx, buffer->bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ, n);
+            n = buffer_pop(vel.vz, buffer->bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ, n);
             break;
         case tag_lef_to_rig:
-            n = buffer_pop(vel->vy, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1, gv->NZ, 0);
-            n = buffer_pop(vel->vz, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1, gv->NZ, n);
-            n = buffer_pop(vel->vx, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2 - 1, 1, gv->NZ,
+            n = buffer_pop(vel.vy, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1, gv->NZ, 0);
+            n = buffer_pop(vel.vz, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1, gv->NZ, n);
+            n = buffer_pop(vel.vx, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2 - 1, 1, gv->NZ,
                            n);
             break;
         case tag_rig_to_lef:
-            n = buffer_pop(vel->vx, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NZ, 0);
-            n = buffer_pop(vel->vy, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, n);
-            n = buffer_pop(vel->vz, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, n);
+            n = buffer_pop(vel.vx, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NZ, 0);
+            n = buffer_pop(vel.vy, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, n);
+            n = buffer_pop(vel.vz, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, n);
             break;
         case tag_fro_to_bac:
-            n = buffer_pop(vel->vx, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2, 0);
-            n = buffer_pop(vel->vy, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2, n);
-            n = buffer_pop(vel->vz, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2 - 1,
+            n = buffer_pop(vel.vx, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2, 0);
+            n = buffer_pop(vel.vy, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2, n);
+            n = buffer_pop(vel.vz, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2 - 1,
                            n);
             break;
         case tag_bac_to_fro:
-            n = buffer_pop(vel->vz, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - gv->FDORDER / 2, 0);
-            n = buffer_pop(vel->vx, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1), n);
-            n = buffer_pop(vel->vy, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1), n);
+            n = buffer_pop(vel.vz, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - gv->FDORDER / 2, 0);
+            n = buffer_pop(vel.vx, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1), n);
+            n = buffer_pop(vel.vy, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1), n);
             break;
         }
     }
@@ -338,7 +338,7 @@ double exchange_v(st_velocity *vel, st_buffer_flat *buffer, GlobVar *gv)
 #endif
 
 #ifdef MPI_ISEND_IRECV
-double exchange_v(st_velocity *vel, st_buffer_flat *buffer, GlobVar *gv)
+double exchange_v(st_velocity &vel, st_buffer_flat *buffer, GlobVar *gv)
 {
     MPI_Request send_requests[] = { MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL,
                                     MPI_REQUEST_NULL, MPI_REQUEST_NULL };
@@ -434,57 +434,57 @@ double exchange_v(st_velocity *vel, st_buffer_flat *buffer, GlobVar *gv)
 
     // Send in background
     if (send_top_to_bot) {
-        n = buffer_push(buffer->send_top_to_bot, vel->vx, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
-        n = buffer_push(buffer->send_top_to_bot, vel->vz, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, n);
-        n = buffer_push(buffer->send_top_to_bot, vel->vy, 1, gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ, n);
+        n = buffer_push(buffer->send_top_to_bot, vel.vx, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
+        n = buffer_push(buffer->send_top_to_bot, vel.vz, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, n);
+        n = buffer_push(buffer->send_top_to_bot, vel.vy, 1, gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ, n);
         MPI_Isend(buffer->send_top_to_bot, n, MPI_FLOAT, gv->INDEX[upper], tag_top_to_bot, gv->COMM_SHOT,
                   request_send_top_to_bot);
     }
 
     if (send_bot_to_top) {
-        n = buffer_push(buffer->send_bot_to_top, vel->vy, gv->NY + 1 - 1, gv->NY + 1 - gv->FDORDER / 2, 1, gv->NX, 1,
+        n = buffer_push(buffer->send_bot_to_top, vel.vy, gv->NY + 1 - 1, gv->NY + 1 - gv->FDORDER / 2, 1, gv->NX, 1,
                         gv->NZ, 0);
-        n = buffer_push(buffer->send_bot_to_top, vel->vx, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1, gv->NX,
+        n = buffer_push(buffer->send_bot_to_top, vel.vx, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1, gv->NX,
                         1, gv->NZ, n);
-        n = buffer_push(buffer->send_bot_to_top, vel->vz, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1, gv->NX,
+        n = buffer_push(buffer->send_bot_to_top, vel.vz, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1, gv->NX,
                         1, gv->NZ, n);
         MPI_Isend(buffer->send_bot_to_top, n, MPI_FLOAT, gv->INDEX[lower], tag_bot_to_top, gv->COMM_SHOT,
                   request_send_bot_to_top);
     }
 
     if (send_lef_to_rig) {
-        n = buffer_push(buffer->send_lef_to_rig, vel->vy, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, 0);
-        n = buffer_push(buffer->send_lef_to_rig, vel->vz, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, n);
-        n = buffer_push(buffer->send_lef_to_rig, vel->vx, 1, gv->NY, 1, gv->FDORDER / 2 - 1, 1, gv->NZ, n);
+        n = buffer_push(buffer->send_lef_to_rig, vel.vy, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, 0);
+        n = buffer_push(buffer->send_lef_to_rig, vel.vz, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, n);
+        n = buffer_push(buffer->send_lef_to_rig, vel.vx, 1, gv->NY, 1, gv->FDORDER / 2 - 1, 1, gv->NZ, n);
         MPI_Isend(buffer->send_lef_to_rig, n, MPI_FLOAT, gv->INDEX[left], tag_lef_to_rig, gv->COMM_SHOT,
                   request_send_lef_to_rig);
     }
 
     if (send_rig_to_lef) {
-        n = buffer_push(buffer->send_rig_to_lef, vel->vx, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - gv->FDORDER / 2, 1,
+        n = buffer_push(buffer->send_rig_to_lef, vel.vx, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - gv->FDORDER / 2, 1,
                         gv->NZ, 0);
-        n = buffer_push(buffer->send_rig_to_lef, vel->vy, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - (gv->FDORDER / 2 - 1),
+        n = buffer_push(buffer->send_rig_to_lef, vel.vy, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - (gv->FDORDER / 2 - 1),
                         1, gv->NZ, n);
-        n = buffer_push(buffer->send_rig_to_lef, vel->vz, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - (gv->FDORDER / 2 - 1),
+        n = buffer_push(buffer->send_rig_to_lef, vel.vz, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - (gv->FDORDER / 2 - 1),
                         1, gv->NZ, n);
         MPI_Isend(buffer->send_rig_to_lef, n, MPI_FLOAT, gv->INDEX[right], tag_rig_to_lef, gv->COMM_SHOT,
                   request_send_rig_to_lef);
     }
 
     if (send_fro_to_bac) {
-        n = buffer_push(buffer->send_fro_to_bac, vel->vx, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, 0);
-        n = buffer_push(buffer->send_fro_to_bac, vel->vy, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, n);
-        n = buffer_push(buffer->send_fro_to_bac, vel->vz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2 - 1, n);
+        n = buffer_push(buffer->send_fro_to_bac, vel.vx, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, 0);
+        n = buffer_push(buffer->send_fro_to_bac, vel.vy, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, n);
+        n = buffer_push(buffer->send_fro_to_bac, vel.vz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2 - 1, n);
         MPI_Isend(buffer->send_fro_to_bac, n, MPI_FLOAT, gv->INDEX[front], tag_fro_to_bac, gv->COMM_SHOT,
                   request_send_fro_to_bac);
     }
 
     if (send_bac_to_fro) {
-        n = buffer_push(buffer->send_bac_to_fro, vel->vz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
+        n = buffer_push(buffer->send_bac_to_fro, vel.vz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
                         gv->NZ + 1 - gv->FDORDER / 2, 0);
-        n = buffer_push(buffer->send_bac_to_fro, vel->vx, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
+        n = buffer_push(buffer->send_bac_to_fro, vel.vx, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
                         gv->NZ + 1 - (gv->FDORDER / 2 - 1), n);
-        n = buffer_push(buffer->send_bac_to_fro, vel->vy, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
+        n = buffer_push(buffer->send_bac_to_fro, vel.vy, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
                         gv->NZ + 1 - (gv->FDORDER / 2 - 1), n);
         MPI_Isend(buffer->send_bac_to_fro, n, MPI_FLOAT, gv->INDEX[back], tag_bac_to_fro, gv->COMM_SHOT,
                   request_send_bac_to_fro);
@@ -499,43 +499,43 @@ double exchange_v(st_velocity *vel, st_buffer_flat *buffer, GlobVar *gv)
 
         switch (status.MPI_TAG) {
         case tag_top_to_bot:
-            n = buffer_pop(vel->vx, buffer->recv_top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ,
+            n = buffer_pop(vel.vx, buffer->recv_top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ,
                            0);
-            n = buffer_pop(vel->vz, buffer->recv_top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ,
+            n = buffer_pop(vel.vz, buffer->recv_top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ,
                            n);
-            n = buffer_pop(vel->vy, buffer->recv_top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2 - 1, 1, gv->NX, 1,
+            n = buffer_pop(vel.vy, buffer->recv_top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2 - 1, 1, gv->NX, 1,
                            gv->NZ, n);
             break;
         case tag_bot_to_top:
-            n = buffer_pop(vel->vy, buffer->recv_bot_to_top, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
-            n = buffer_pop(vel->vx, buffer->recv_bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ, n);
-            n = buffer_pop(vel->vz, buffer->recv_bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ, n);
+            n = buffer_pop(vel.vy, buffer->recv_bot_to_top, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
+            n = buffer_pop(vel.vx, buffer->recv_bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ, n);
+            n = buffer_pop(vel.vz, buffer->recv_bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ, n);
             break;
         case tag_lef_to_rig:
-            n = buffer_pop(vel->vy, buffer->recv_lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1, gv->NZ,
+            n = buffer_pop(vel.vy, buffer->recv_lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1, gv->NZ,
                            0);
-            n = buffer_pop(vel->vz, buffer->recv_lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1, gv->NZ,
+            n = buffer_pop(vel.vz, buffer->recv_lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1, gv->NZ,
                            n);
-            n = buffer_pop(vel->vx, buffer->recv_lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2 - 1, 1,
+            n = buffer_pop(vel.vx, buffer->recv_lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2 - 1, 1,
                            gv->NZ, n);
             break;
         case tag_rig_to_lef:
-            n = buffer_pop(vel->vx, buffer->recv_rig_to_lef, 1, gv->NY, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NZ, 0);
-            n = buffer_pop(vel->vy, buffer->recv_rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, n);
-            n = buffer_pop(vel->vz, buffer->recv_rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, n);
+            n = buffer_pop(vel.vx, buffer->recv_rig_to_lef, 1, gv->NY, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NZ, 0);
+            n = buffer_pop(vel.vy, buffer->recv_rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, n);
+            n = buffer_pop(vel.vz, buffer->recv_rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, n);
             break;
         case tag_fro_to_bac:
-            n = buffer_pop(vel->vx, buffer->recv_fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2,
+            n = buffer_pop(vel.vx, buffer->recv_fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2,
                            0);
-            n = buffer_pop(vel->vy, buffer->recv_fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2,
+            n = buffer_pop(vel.vy, buffer->recv_fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2,
                            n);
-            n = buffer_pop(vel->vz, buffer->recv_fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1,
+            n = buffer_pop(vel.vz, buffer->recv_fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1,
                            gv->NZ + gv->FDORDER / 2 - 1, n);
             break;
         case tag_bac_to_fro:
-            n = buffer_pop(vel->vz, buffer->recv_bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - gv->FDORDER / 2, 0);
-            n = buffer_pop(vel->vx, buffer->recv_bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1), n);
-            n = buffer_pop(vel->vy, buffer->recv_bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1), n);
+            n = buffer_pop(vel.vz, buffer->recv_bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - gv->FDORDER / 2, 0);
+            n = buffer_pop(vel.vx, buffer->recv_bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1), n);
+            n = buffer_pop(vel.vy, buffer->recv_bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1), n);
             break;
         }
     }
diff --git a/src/fd.hpp b/src/fd.hpp
index 8293bff..ef24d7a 100644
--- a/src/fd.hpp
+++ b/src/fd.hpp
@@ -62,7 +62,7 @@ typedef struct Stress {
 typedef struct Particle_velocity {
     // particle velocity
     // Pointer for dynamic wavefields:
-    float ***__restrict__ vx, ***__restrict__ vy, ***__restrict__ vz;
+    float3DTensorT vx, vy, vz;
 } st_velocity;
 
 typedef struct Freq_Particle_velocity {
@@ -188,7 +188,7 @@ void freemem(int nsrc_loc, st_acquisition *acq, st_model *mod,
              st_gradient *grad, st_gradient *grad_prior1, st_gradient *grad_prior2, st_gradient *grad_halo,
              st_hessian *hessian,
              st_stress *stress, st_buffer_flat *stressbuff, st_freq_velocity *fourier_vel_back,
-             st_freq_velocity *fourier_vel_fw, st_velocity *vel, st_buffer_flat *velbuff, const GlobVar *gv);
+             st_freq_velocity *fourier_vel_fw, st_velocity &vel, st_buffer_flat *velbuff, const GlobVar *gv);
 
 void freemem_seis(int ntr_loc, st_seismogram *section, st_seismogram *section_obs, st_signals *signals,
                   st_acquisition *acq, const GlobVar *gv);
@@ -199,7 +199,7 @@ int initmem(st_model *mod, st_model *testmod, st_model_av *mod_av, st_visc_mem *
             st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, st_gradient *grad, st_gradient *grad_prior1,
             st_gradient *grad_prior2, st_gradient *grad_halo, st_hessian *hessian, st_stress *stress,
             st_buffer_flat *stressbuff,
-            st_freq_velocity *fourier_vel_back, st_freq_velocity *fourier_vel_fw, st_velocity *vel,
+            st_freq_velocity *fourier_vel_back, st_freq_velocity *fourier_vel_fw, st_velocity &vel,
             st_buffer_flat *velbuff, GlobVar *gv);
 
 void initproc(GlobVar *gv);
@@ -243,11 +243,11 @@ void exchange_s_rsg(st_stress *stress, st_buffer *buffer);
 
 double exchange_s(st_stress *stress, st_buffer_flat *buffer, GlobVar *gv);
 
-void readbufv(st_velocity *vel, st_buffer *buffer);
+void readbufv(st_velocity &vel, st_buffer *buffer);
 
-void exchange_v_rsg(st_velocity *vel, st_buffer *buffer);
+void exchange_v_rsg(st_velocity &vel, st_buffer *buffer);
 
-double exchange_v(st_velocity *vel, st_buffer_flat *buffer, GlobVar *gv);
+double exchange_v(st_velocity &vel, st_buffer_flat *buffer, GlobVar *gv);
 
 double exchange_Fv(float ****vx, float ****vy, float ****vz, int nf, st_buffer_flat *buffer, GlobVar *gv);
 
@@ -269,25 +269,25 @@ void savesig(float **signals, st_acquisition *acq, int nsrc_loc, int ishot, int
 
 int **scan_topo(GlobVar *gv);
 
-void seismo(int lsamp, int ntr, int **recpos, st_seismogram *section, st_velocity *vel, st_stress *stress,
+void seismo(int lsamp, int ntr, int **recpos, st_seismogram *section, st_velocity &vel, st_stress *stress,
             st_model *mod, const GlobVar *gv);
 
 void seismo_rsg(int lsamp, int ntr, int **recpos, float **sectionvx, float **sectionvy,
                 float **sectionvz, float **sectiondiv, float **sectioncurl, float **sectionp,
-                st_velocity *vel, st_stress *stress, st_model *mod);
+                st_velocity &vel, st_stress *stress, st_model *mod);
 
-void snap(int nt, int nsnap, st_velocity *vel, st_stress *stress, const st_model *mod,
+void snap(int nt, int nsnap, st_velocity &vel, st_stress *stress, const st_model *mod,
           const st_boundary *nb, GlobVar *gv);
 
 void snap_rsg(FILE *fp, int nt, int nsnap, int format, int type,
-              st_velocity *vel, st_stress *stress, st_model *mod,
+              st_velocity &vel, st_stress *stress, st_model *mod,
               int idx, int idy, int idz, int nx1, int ny1, int nz1, int nx2, int ny2, int nz2);
 
 void snapmerge(int nsnap, GlobVar *gv);
 
 void sources(FILE *fpsrc, int *nsrc, float **srcpos, GlobVar *gv, int **topo);
 
-void stfi(st_acquisition *acq, st_boundary *nb, const st_boundary *nb_fix, st_velocity *vel, st_stress *stress,
+void stfi(st_acquisition *acq, st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress *stress,
           st_model *mod, st_model_av *mod_av, st_visc_mem *visco_mem, st_seismogram *section,
           st_seismogram *section_obs, st_signals *signals, int nsrc_loc, int ntr_loc, st_pml_coeff *pml_coeff,
           st_pml_wfd *pml_wfd, st_buffer_flat *stressbuff, st_buffer_flat *velbuff, st_freq_velocity *fourier_vel,
@@ -310,18 +310,18 @@ void splitrec(int *ntr_loc, st_acquisition *acq, const GlobVar *gv);
 float **splitsrc(float **srcpos, int *nsrc_loc, int nsrc, int *srcswitch, GlobVar *gv);
 
 void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, st_visc_mem *mem,
-             st_stress *stress, st_velocity *vel);
+             st_stress *stress, st_velocity &vel);
 
-void update_s_rsg(st_boundary *nb, st_velocity *vel, st_stress *stress,
+void update_s_rsg(st_boundary *nb, st_velocity &vel, st_stress *stress,
                   st_visc_mem *mem, st_model *mod, float ***taus, float ***taup, float *eta);
 
-void update_v(const st_boundary *nb, st_velocity *vel, st_stress *stress, st_model_av *mod_av,
+void update_v(const st_boundary *nb, st_velocity &vel, st_stress *stress, st_model_av *mod_av,
               float ***absorb_coeff, const GlobVar *gv);
 
-void update_v_CPML(st_boundary *nb, st_velocity *vel, st_stress *stress, st_model_av *mod_av,
+void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress *stress, st_model_av *mod_av,
                    st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, const GlobVar *gv);
 
-void update_v_rsg(st_boundary *nb, int nt, st_velocity *vel, st_stress *stress,
+void update_v_rsg(st_boundary *nb, int nt, st_velocity &vel, st_stress *stress,
                   float ***rho, float **srcpos_loc, float **signals, int nsrc, float ***absorb_coeff);
 
 void wavelet(float **srcpos_loc, int nsrc, int sourceshape, float **signals, float **sig_raw, float freq,
@@ -329,7 +329,7 @@ void wavelet(float **srcpos_loc, int nsrc, int sourceshape, float **signals, flo
 
 void writebufs(st_stress *stress, st_buffer *buffer);
 
-void writebufv(st_velocity *vel, st_buffer *buffer);
+void writebufv(st_velocity &vel, st_buffer *buffer);
 
 void writedsk(FILE *fp_out, float amp, int format);
 
@@ -366,7 +366,7 @@ void readseis(int shot_id, float **section, const st_acquisition *acq, int ntr,
 void residual(float **sectiondata, float **section, float **sectiondiff, int ntr, int ns,
               double *L2, const float *finv, int nf, const GlobVar *gv);
 
-void zero_wavefield(st_velocity *vel, st_stress *stress, st_visc_mem *mem, st_pml_wfd *pml_wfd, const GlobVar *gv);
+void zero_wavefield(st_velocity &vel, st_stress *stress, st_visc_mem *mem, st_pml_wfd *pml_wfd, const GlobVar *gv);
 
 void gradient_F(int nx, int ny, int nz, st_freq_velocity *fw, st_freq_velocity *back, st_gradient *grad,
                 st_hessian *hessian,
@@ -399,19 +399,19 @@ void cpmodel(st_model *mod, st_model *testmod, const GlobVar *gv);
 void conjugate(st_gradient *grad, st_gradient *grad_prior1, st_gradient *grad_prior2,
                float *beta, int cdf, GlobVar *gv);
 
-double update_s_elastic(st_boundary *nb, st_velocity *vel, st_stress *stress,
+double update_s_elastic(st_boundary *nb, st_velocity &vel, st_stress *stress,
                         st_model *mod, st_model_av *mod_av, const GlobVar *gv);
 
-double update_s_CPML_elastic(st_boundary *nb, st_velocity *vel,
+double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                              st_stress *stress, st_model *mod, st_model_av *mod_av, st_pml_coeff *pml_coeff,
                              st_pml_wfd *pml_wfd, const GlobVar *gv);
 
 void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, st_stress *stress,
-                     st_velocity *vel, const GlobVar *gv);
+                     st_velocity &vel, const GlobVar *gv);
 
 void readinv(float *finv, int *nf, int *groupnum, int *itpergroup, int nfmax, GlobVar *gv);
 
-void discfourier(const st_boundary *nb, int nt, st_velocity *vel,
+void discfourier(const st_boundary *nb, int nt, st_velocity &vel,
                  st_freq_velocity *fourier_vel, const float *finv,
                  int nf, int ntast, int pshot1, int back, const GlobVar *gv);
 
@@ -447,22 +447,22 @@ void precon_grad_acoustic(int ishot, st_gradient *grad, st_acquisition *acq, Glo
 
 void surface_acoustic(int ndepth, st_stress *stress, const GlobVar *gv);
 
-double update_s_acoustic(st_boundary *nb, st_velocity *vel, st_stress *stress, st_model *mod, const GlobVar *gv);
+double update_s_acoustic(st_boundary *nb, st_velocity &vel, st_stress *stress, st_model *mod, const GlobVar *gv);
 
-double update_s_CPML_acoustic(st_boundary *nb, st_velocity *vel,
+double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
                               st_stress *stress, st_model *mod, st_pml_coeff *pml_coeff,
                               st_pml_wfd *pml_wfd, const GlobVar *gv);
 
-void update_v_acoustic(const st_boundary *nb, st_velocity *vel, st_stress *stress,
+void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress *stress,
                        st_model_av *mod_av, float ***absorb_coeff, const GlobVar *gv);
 
-void update_v_CPML_acoustic(st_boundary *nb, st_velocity *vel, st_stress *stress, st_model_av *mod_av,
+void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress *stress, st_model_av *mod_av,
                             st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, const GlobVar *gv);
 
-void zero_wavefield_acoustic(st_velocity *vel, st_stress *stress, st_visc_mem *mem, st_pml_wfd *pml_wfd,
+void zero_wavefield_acoustic(st_velocity &vel, st_stress *stress, st_visc_mem *mem, st_pml_wfd *pml_wfd,
                              const GlobVar *gv);
 
-void timeloop(st_boundary *nb, const st_boundary *nb_fix, st_velocity *vel, st_stress *stress,
+void timeloop(st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress *stress,
               st_model *mod, st_model_av *mod_av, st_seismogram *section,
               float **srcpos_loc, int **recpos_loc, st_signals *signals, int nsrc_loc,
               float ***absorb_coeff, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd,
@@ -470,7 +470,7 @@ void timeloop(st_boundary *nb, const st_boundary *nb_fix, st_velocity *vel, st_s
               const float *finv, int nf, int ntast, int ntr, int lsnap, int nsnap, int pshot, int shot_id, int proptype,
               GlobVar *gv);
 
-void fsource(int nt, st_velocity *vel, st_model_av *mod_av, float **srcpos_loc,
+void fsource(int nt, st_velocity &vel, st_model_av *mod_av, float **srcpos_loc,
              st_signals *signals, int nsrc, int back, const GlobVar *gv);
 
 void time_window(float **sectiondata1, float **sectiondata2, int **recpos_loc, int ntr, int ntr_loc, int ishot,
diff --git a/src/float3DTensorT.cpp b/src/float3DTensorT.cpp
index 5a7c30e..2f8d59b 100644
--- a/src/float3DTensorT.cpp
+++ b/src/float3DTensorT.cpp
@@ -4,25 +4,66 @@
 #include <cstdlib>
 #include <iostream>
 
+void float3DTensorT::init()
+{
+    _lb_i = 0;
+    _ub_i = 0;
+    _lb_j = 0;
+    _ub_j = 0;
+    _lb_k = 0;
+    _ub_k = 0;
+
+    _dim_i = 0;
+    _dim_j = 0;
+    _dim_k = 0;
+    _size = 0;
+
+    _stride_i = 0;
+    _stride_j = 0;
+    _stride_k = 0;
+    offset = 0;
+
+    data = NULL;
+}
+
+float3DTensorT::float3DTensorT()
+{
+    float3DTensorT::init();
+};
+
 float3DTensorT::float3DTensorT(
-    const size_t &lb_i, const size_t &ub_i,
-    const size_t &lb_j, const size_t &ub_j,
-    const size_t &lb_k, const size_t &ub_k) : _lb_i(lb_i), _ub_i(ub_i),
-    _lb_j(lb_j), _ub_j(ub_j),
-    _lb_k(lb_k), _ub_k(ub_k),
-    _dim_i(ub_i - lb_i + 1),
-    _dim_j(ub_j - lb_j + 1),
-    _dim_k(ub_k - lb_k + 1),
-    _size(_dim_i * _dim_j * _dim_k),
-    _stride_i(_dim_j * _dim_k),
-    _stride_j(_dim_k),
-    _stride_k(0),
-    offset(lb_i * _stride_i + lb_j * _stride_j + lb_k)
+    const int &lb_i, const int &ub_i,
+    const int &lb_j, const int &ub_j,
+    const int &lb_k, const int &ub_k)
+{
+    float3DTensorT::malloc(lb_i, ub_i, lb_j, ub_j, lb_k, ub_k);
+};
+
+float3DTensorT::~float3DTensorT()
+{
+    assert(_size == 0);
+}
+
+void float3DTensorT::malloc(
+    const int &lb_i, const int &ub_i,
+    const int &lb_j, const int &ub_j,
+    const int &lb_k, const int &ub_k)
 {
     assert(lb_i <= ub_i);
+    _lb_i = lb_i;
+    _ub_i = ub_i;
     assert(lb_j <= ub_j);
+    _lb_j = lb_j;
+    _ub_j = ub_j;
     assert(lb_k <= ub_k);
-    data = (float *)malloc(_size * sizeof(float));
+    _lb_k = lb_k;
+    _ub_k = ub_k;
+
+    _dim_i = ub_i - lb_i + 1;
+    _dim_j = ub_j - lb_j + 1;
+    _dim_k = ub_k - lb_k + 1;
+    _size = _dim_i * _dim_j * _dim_k;
+    data = (float *)std::malloc(_size * sizeof(float));
     if (data == NULL) {
         std::cerr << "Failed to allocate memory" << std::endl;
         exit(EXIT_FAILURE);
@@ -31,49 +72,43 @@ float3DTensorT::float3DTensorT(
     for (size_t i = 0; i < _size; i++) {
         data[i] = 0.0f;
     }
+    _stride_i = _dim_j * _dim_k;
+    _stride_j = _dim_k;
+    _stride_k = 0;
+    offset = lb_i * _stride_i + lb_j * _stride_j + lb_k;
 };
 
-float3DTensorT::~float3DTensorT()
-{
-    free(data);
-}
-
-// https://en.cppreference.com/w/cpp/language/operators#Array_subscript_operator
-constexpr float &float3DTensorT::operator[](const size_t &i, const size_t &j, const size_t &k) noexcept
+void float3DTensorT::free()
 {
-    assert(_lb_i <= i and i <= _ub_i);
-    assert(_lb_j <= j and j <= _ub_j);
-    assert(_lb_k <= k and k <= _ub_k);
-    const size_t index = i * _stride_i + j * _stride_j + k - offset;
-    assert(index < _size);
-    return data[index];
+    std::free(data);
+    float3DTensorT::init();
 }
 
-constexpr size_t float3DTensorT::lb_i() noexcept
+constexpr int float3DTensorT::lb_i() noexcept
 {
     return _lb_i;
 }
 
-constexpr size_t float3DTensorT::ub_i() noexcept
+constexpr int float3DTensorT::ub_i() noexcept
 {
     return _ub_i;
 }
 
-constexpr size_t float3DTensorT::lb_j() noexcept
+constexpr int float3DTensorT::lb_j() noexcept
 {
     return _lb_j;
 }
 
-constexpr size_t float3DTensorT::ub_j() noexcept
+constexpr int float3DTensorT::ub_j() noexcept
 {
     return _ub_j;
 }
 
-constexpr size_t float3DTensorT::lb_k() noexcept
+constexpr int float3DTensorT::lb_k() noexcept
 {
     return _lb_k;
 }
-constexpr size_t float3DTensorT::ub_k() noexcept
+constexpr int float3DTensorT::ub_k() noexcept
 {
     return _ub_k;
 }
diff --git a/src/float3DTensorT.hpp b/src/float3DTensorT.hpp
index a495841..d4ac128 100644
--- a/src/float3DTensorT.hpp
+++ b/src/float3DTensorT.hpp
@@ -1,32 +1,39 @@
 #ifndef _FLOAT_3D_TENSOR_INCLUDED_
 #define _FLOAT_3D_TENSOR_INCLUDED_
 
+#include <cassert>
 #include <cstddef>
 
 struct float3DTensorT {
 private:
-    const size_t _lb_i, _ub_i,
-                 _lb_j, _ub_j,
-                 _lb_k, _ub_k,
-                 _dim_i, _dim_j, _dim_k, _size,
-                 _stride_i, _stride_j, _stride_k, offset;
-    float *      data;
+    int    _lb_i, _ub_i,
+           _lb_j, _ub_j,
+           _lb_k, _ub_k;
+    size_t _dim_i, _dim_j, _dim_k, _size,
+           _stride_i, _stride_j, _stride_k, offset;
+    float *data;
+    void init();
 
 public:
-    float3DTensorT(const size_t &lb_i, const size_t &ub_i,
-                   const size_t &lb_j, const size_t &ub_j,
-                   const size_t &lb_k, const size_t &ub_k);
+    float3DTensorT();
+    float3DTensorT(const int &lb_i, const int &ub_i,
+                   const int &lb_j, const int &ub_j,
+                   const int &lb_k, const int &ub_k);
 
     ~float3DTensorT();
+    void malloc(const int &lb_i, const int &ub_i,
+                const int &lb_j, const int &ub_j,
+                const int &lb_k, const int &ub_k);
+    void free();
 
-    constexpr float &operator[](const size_t &i, const size_t &j, const size_t &k) noexcept;
+    constexpr float &operator[](const int &i, const int &j, const int &k) noexcept;
 
-    constexpr size_t lb_i() noexcept;
-    constexpr size_t ub_i() noexcept;
-    constexpr size_t lb_j() noexcept;
-    constexpr size_t ub_j() noexcept;
-    constexpr size_t lb_k() noexcept;
-    constexpr size_t ub_k() noexcept;
+    constexpr int lb_i() noexcept;
+    constexpr int ub_i() noexcept;
+    constexpr int lb_j() noexcept;
+    constexpr int ub_j() noexcept;
+    constexpr int lb_k() noexcept;
+    constexpr int ub_k() noexcept;
 
     constexpr size_t dim_i() noexcept;
     constexpr size_t dim_j() noexcept;
@@ -35,4 +42,15 @@ public:
     constexpr size_t size() noexcept;
 };
 
-#endif
\ No newline at end of file
+// https://en.cppreference.com/w/cpp/language/operators#Array_subscript_operator
+constexpr float &float3DTensorT::operator[](const int &i, const int &j, const int &k) noexcept
+{
+    assert(_lb_i <= i and i <= _ub_i);
+    assert(_lb_j <= j and j <= _ub_j);
+    assert(_lb_k <= k and k <= _ub_k);
+    const size_t index = i * _stride_i + j * _stride_j + k - offset;
+    assert(index < _size);
+    return data[index];
+}
+
+#endif
diff --git a/src/freemem.cpp b/src/freemem.cpp
index 219ceb2..435fdbd 100644
--- a/src/freemem.cpp
+++ b/src/freemem.cpp
@@ -29,7 +29,7 @@ void freemem(int nsrc_loc, st_acquisition *acq, st_model *mod, st_model *testmod
              st_signals *signals, st_gradient *grad, st_gradient *grad_prior1, st_gradient *grad_prior2,
              st_gradient *grad_halo,
              st_hessian *hessian, st_stress *stress, st_buffer_flat *stressbuff, st_freq_velocity *fourier_vel_back,
-             st_freq_velocity *fourier_vel_fw, st_velocity *vel, st_buffer_flat *velbuff, const GlobVar *gv)
+             st_freq_velocity *fourier_vel_fw, st_velocity &vel, st_buffer_flat *velbuff, const GlobVar *gv)
 {
     int l;
 
@@ -39,15 +39,9 @@ void freemem(int nsrc_loc, st_acquisition *acq, st_model *mod, st_model *testmod
     }
 
     if (gv->POS[2] == 0) {
-        free_f3tensor(vel->vx, 0 - gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                      gv->NX + l * gv->FDORDER / 2,
-                      1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
-        free_f3tensor(vel->vy, 0 - gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                      gv->NX + l * gv->FDORDER / 2,
-                      1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
-        free_f3tensor(vel->vz, 0 - gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                      gv->NX + l * gv->FDORDER / 2,
-                      1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
+        vel.vx.free();
+        vel.vy.free();
+        vel.vz.free();
         if (gv->WEQ != 2) {
             free_f3tensor(stress->sxy, 0 - gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
                           gv->NX + l * gv->FDORDER / 2,
@@ -97,15 +91,9 @@ void freemem(int nsrc_loc, st_acquisition *acq, st_model *mod, st_model *testmod
     }
 
     if (gv->POS[2] > 0) {
-        free_f3tensor(vel->vx, 1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                      gv->NX + l * gv->FDORDER / 2,
-                      1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
-        free_f3tensor(vel->vy, 1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                      gv->NX + l * gv->FDORDER / 2,
-                      1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
-        free_f3tensor(vel->vz, 1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                      gv->NX + l * gv->FDORDER / 2,
-                      1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
+        vel.vx.free();
+        vel.vy.free();
+        vel.vz.free();
         if (gv->WEQ != 2) {
             free_f3tensor(stress->sxy, 1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
                           gv->NX + l * gv->FDORDER / 2,
diff --git a/src/fsource.cpp b/src/fsource.cpp
index 016f1cf..5a762f7 100644
--- a/src/fsource.cpp
+++ b/src/fsource.cpp
@@ -23,7 +23,7 @@
 
 #include "fd.hpp"
 
-void fsource(int nt, st_velocity *vel, st_model_av *mod_av, float **srcpos_loc,
+void fsource(int nt, st_velocity &vel, st_model_av *mod_av, float **srcpos_loc,
              st_signals *signals, int nsrc, int back, const GlobVar *gv)
 {
     /* Adding body force components to corresponding particle velocities */
@@ -46,20 +46,20 @@ void fsource(int nt, st_velocity *vel, st_model_av *mod_av, float **srcpos_loc,
             float alpha_rad, beta_rad;
             switch ((int)srcpos_loc[7][l]) {
             case 2:
-                vel->vx[j][i][k] += amp * mod_av->rip[j][i][k];
+                vel.vx[j, i, k] += amp * mod_av->rip[j][i][k];
                 break;
             case 3:
-                vel->vy[j][i][k] += amp * mod_av->rkp[j][i][k]; /* single force in y, vertical direction */
+                vel.vy[j, i, k] += amp * mod_av->rkp[j][i][k]; /* single force in y, vertical direction */
                 break;
             case 4:
-                vel->vz[j][i][k] += amp * mod_av->rjp[j][i][k]; /* single force in z  */
+                vel.vz[j, i, k] += amp * mod_av->rjp[j][i][k]; /* single force in z  */
                 break;
             case 5:
-                alpha_rad = gv->ALPHA * PI / 180;               /* custom force */
+                alpha_rad = gv->ALPHA * PI / 180;              /* custom force */
                 beta_rad = gv->BETA * PI / 180;
-                vel->vx[j][i][k] += cos(beta_rad) * cos(alpha_rad) * amp;
-                vel->vy[j][i][k] += sin(alpha_rad) * amp;
-                vel->vz[j][i][k] += sin(beta_rad) * cos(alpha_rad) * amp;
+                vel.vx[j, i, k] += cos(beta_rad) * cos(alpha_rad) * amp;
+                vel.vy[j, i, k] += sin(alpha_rad) * amp;
+                vel.vz[j, i, k] += sin(beta_rad) * cos(alpha_rad) * amp;
                 break;
             }
         }
@@ -73,7 +73,7 @@ void fsource(int nt, st_velocity *vel, st_model_av *mod_av, float **srcpos_loc,
                 i = (int)srcpos_loc[1][l];
                 j = (int)srcpos_loc[2][l];
                 k = (int)srcpos_loc[3][l];
-                vel->vx[j][i][k] += signals->sectionvxdiff[l][nt];
+                vel.vx[j, i, k] += signals->sectionvxdiff[l][nt];
             }
             break;
         case 2:                /* vy only */
@@ -81,7 +81,7 @@ void fsource(int nt, st_velocity *vel, st_model_av *mod_av, float **srcpos_loc,
                 i = (int)srcpos_loc[1][l];
                 j = (int)srcpos_loc[2][l];
                 k = (int)srcpos_loc[3][l];
-                vel->vy[j][i][k] += signals->sectionvydiff[l][nt];
+                vel.vy[j, i, k] += signals->sectionvydiff[l][nt];
             }
             break;
         case 3:                /* vz only */
@@ -89,7 +89,7 @@ void fsource(int nt, st_velocity *vel, st_model_av *mod_av, float **srcpos_loc,
                 i = (int)srcpos_loc[1][l];
                 j = (int)srcpos_loc[2][l];
                 k = (int)srcpos_loc[3][l];
-                vel->vz[j][i][k] += signals->sectionvzdiff[l][nt];
+                vel.vz[j, i, k] += signals->sectionvzdiff[l][nt];
             }
             break;
         case 4:                /* particle velocities (vx + vy + vz) */
@@ -97,9 +97,9 @@ void fsource(int nt, st_velocity *vel, st_model_av *mod_av, float **srcpos_loc,
                 i = (int)srcpos_loc[1][l];
                 j = (int)srcpos_loc[2][l];
                 k = (int)srcpos_loc[3][l];
-                vel->vx[j][i][k] += signals->sectionvxdiff[l][nt];
-                vel->vz[j][i][k] += signals->sectionvzdiff[l][nt];
-                vel->vy[j][i][k] += signals->sectionvydiff[l][nt];
+                vel.vx[j, i, k] += signals->sectionvxdiff[l][nt];
+                vel.vz[j, i, k] += signals->sectionvzdiff[l][nt];
+                vel.vy[j, i, k] += signals->sectionvydiff[l][nt];
             }
             break;
         }
diff --git a/src/ifos3d.cpp b/src/ifos3d.cpp
index 06a2544..bf6c57f 100644
--- a/src/ifos3d.cpp
+++ b/src/ifos3d.cpp
@@ -185,7 +185,7 @@ int main(int argc, char **argv)
     /* allocate and initialize buffers */
     buffsize = initmem(&mod, &testmod, &mod_av, &visco_mem, &pml_coeff, &pml_wfd,
                        &grad, &grad_prior1, &grad_prior2, &grad_halo, &hessian, &stress, &stressbuff,
-                       &fourier_vel_back, &fourier_vel_fw, &vel, &velbuff, &gv);
+                       &fourier_vel_back, &fourier_vel_fw, vel, &velbuff, &gv);
 
     /* allocate buffer for buffering messages */
     buff_addr = (char *)malloc(buffsize);
@@ -471,9 +471,9 @@ int main(int argc, char **argv)
 
             /* initialize wavefield with zero */
             if (gv.WEQ != 2) {
-                zero_wavefield(&vel, &stress, &visco_mem, &pml_wfd, &gv);
+                zero_wavefield(vel, &stress, &visco_mem, &pml_wfd, &gv);
             } else {
-                zero_wavefield_acoustic(&vel, &stress, &visco_mem, &pml_wfd, &gv);
+                zero_wavefield_acoustic(vel, &stress, &visco_mem, &pml_wfd, &gv);
             }
             if (gv.METHOD)
                 zero_invers(&fourier_vel_fw, &fourier_vel_back, gv.NFMAX, &gv);
@@ -487,7 +487,7 @@ int main(int argc, char **argv)
                     ntast = 1;
 
                 if (gv.STFI) {
-                    stfi(&acq, &nb, &nb_fix, &vel, &stress, &mod, &mod_av, &visco_mem, &section, &section_obs,
+                    stfi(&acq, &nb, &nb_fix, vel, &stress, &mod, &mod_av, &visco_mem, &section, &section_obs,
                          &signals, nsrc_loc, ntr_loc, &pml_coeff, &pml_wfd, &stressbuff, &velbuff,
                          &fourier_vel_fw, finv, &L2, nf, ntast, lsnap, nsnap, ishot, shot_id, cdf, iteration, groupnum,
                          it_group, ncplx, &gv);
@@ -497,7 +497,7 @@ int main(int argc, char **argv)
             /*****************************************************
             * Timestep loop (simulation)
             *****************************************************/
-            timeloop(&nb, &nb_fix, &vel, &stress, &mod, &mod_av, &section,
+            timeloop(&nb, &nb_fix, vel, &stress, &mod, &mod_av, &section,
                      acq.srcpos_loc, acq.recpos_loc, &signals, nsrc_loc,
                      mod.absorb_coeff, &pml_coeff, &pml_wfd, &stressbuff, &velbuff, &fourier_vel_fw,
                      finv, nf, ntast, ntr_loc, lsnap, nsnap, 0, shot_id, 1, &gv);
@@ -556,15 +556,15 @@ int main(int argc, char **argv)
 
                 /* initialize wavefields */
                 if (gv.WEQ != 2) {
-                    zero_wavefield(&vel, &stress, &visco_mem, &pml_wfd, &gv);
+                    zero_wavefield(vel, &stress, &visco_mem, &pml_wfd, &gv);
                 } else {
-                    zero_wavefield_acoustic(&vel, &stress, &visco_mem, &pml_wfd, &gv);
+                    zero_wavefield_acoustic(vel, &stress, &visco_mem, &pml_wfd, &gv);
                 }
 
                 /*****************************************************
                 *           Timestep loop (back-propagation)
                 *****************************************************/
-                timeloop(&nb, &nb_fix, &vel, &stress, &mod, &mod_av, &section,
+                timeloop(&nb, &nb_fix, vel, &stress, &mod, &mod_av, &section,
                          acq.srcpos_loc_back, acq.recpos_loc, &signals, ntr_loc,
                          mod.absorb_coeff, &pml_coeff, &pml_wfd, &stressbuff, &velbuff, &fourier_vel_back,
                          finv, nf, ntast, ntr_loc, lsnap, nsnap, 0, shot_id, 2, &gv);
@@ -794,15 +794,15 @@ int main(int argc, char **argv)
                         }
 
                         if (gv.WEQ != 2) {
-                            zero_wavefield(&vel, &stress, &visco_mem, &pml_wfd, &gv);
+                            zero_wavefield(vel, &stress, &visco_mem, &pml_wfd, &gv);
                         } else {
-                            zero_wavefield_acoustic(&vel, &stress, &visco_mem, &pml_wfd, &gv);
+                            zero_wavefield_acoustic(vel, &stress, &visco_mem, &pml_wfd, &gv);
                         }
 
                         /*****************************************************
                         * Timestep loop (steplength calculation)
                         *****************************************************/
-                        timeloop(&nb, &nb_fix, &vel, &stress, &testmod, &mod_av, &section,
+                        timeloop(&nb, &nb_fix, vel, &stress, &testmod, &mod_av, &section,
                                  acq.srcpos_loc, acq.recpos_loc, &signals, nsrc_loc,
                                  mod.absorb_coeff, &pml_coeff, &pml_wfd, &stressbuff, &velbuff, &fourier_vel_fw,
                                  finv, nf, ntast, ntr_loc, lsnap, nsnap, 0, shot_id, 3, &gv);
@@ -851,7 +851,7 @@ int main(int argc, char **argv)
     freemem(nsrc_loc, &acq, &mod, &testmod, &mod_av,
             &visco_mem, &pml_coeff, &pml_wfd, &signals, &grad,
             &grad_prior1, &grad_prior2, &grad_halo, &hessian, &stress, &stressbuff,
-            &fourier_vel_back, &fourier_vel_fw, &vel, &velbuff, &gv);
+            &fourier_vel_back, &fourier_vel_fw, vel, &velbuff, &gv);
 
     if (topo) {
         free_imatrix(topo, 1, gv.NXG, 1, gv.NZG);
diff --git a/src/initmem.cpp b/src/initmem.cpp
index af01298..1ea2500 100644
--- a/src/initmem.cpp
+++ b/src/initmem.cpp
@@ -30,7 +30,7 @@ int initmem(st_model *mod, st_model *testmod,
             st_pml_wfd *pml_wfd, st_gradient *grad, st_gradient *grad_prior1,
             st_gradient *grad_prior2, st_gradient *grad_halo, st_hessian *hessian, st_stress *stress,
             st_buffer_flat *stressbuff, st_freq_velocity *fourier_vel_back,
-            st_freq_velocity *fourier_vel_fw, st_velocity *vel, st_buffer_flat *velbuff,
+            st_freq_velocity *fourier_vel_fw, st_velocity &vel, st_buffer_flat *velbuff,
             GlobVar *gv)
 {
     int l, nf1, nf2, nseismograms = 0, buffsize;
@@ -40,34 +40,34 @@ int initmem(st_model *mod, st_model *testmod,
 
     /* number of seismogram sections which have to be stored in core memory */
     switch (gv->SEISMO) {
-    case 1:                    /* particle velocities only */
+    case 1: /* particle velocities only */
         nseismograms = 3;
         break;
-    case 2:                    /* pressure only */
+    case 2: /* pressure only */
         nseismograms = 1;
         break;
-    case 3:                    /* curl and div only */
+    case 3: /* curl and div only */
         nseismograms = 2;
         break;
-    case 4:                    /* everything */
+    case 4: /* everything */
         nseismograms = 6;
         break;
     }
     if (gv->METHOD) {
         switch (gv->ADJOINT_TYPE) {
-        case 1:                      /* vx only */
+        case 1: /* vx only */
             nseismograms += 1;
             break;
-        case 2:                      /* vy only */
+        case 2: /* vy only */
             nseismograms += 1;
             break;
-        case 3:                      /* vz only */
+        case 3: /* vz only */
             nseismograms += 1;
             break;
-        case 4:                      /* particle velocities (vx + vy + vz) */
+        case 4: /* particle velocities (vx + vy + vz) */
             nseismograms += 3;
             break;
-        case 5:                      /* pressure only */
+        case 5: /* pressure only */
             nseismograms += 1;
             break;
         }
@@ -78,10 +78,10 @@ int initmem(st_model *mod, st_model *testmod,
     fac2 = sizeof(float) * pow(2.0, -20.0);
     fac3 = gv->NZ * gv->NY * gv->NX;
 
-    if (gv->L > 0) {            /* viscoelastic case */
+    if (gv->L > 0) { /* viscoelastic case */
         memdyn = 15.0 * fac1 * fac2;
         memmodel = 16.0 * fac1 * fac2;
-    } else {                    /* elastic case */
+    } else {         /* elastic case */
         memdyn = 9.0 * fac1 * fac2;
         memmodel = 10.0 * fac1 * fac2;
     }
@@ -127,18 +127,15 @@ int initmem(st_model *mod, st_model *testmod,
 
     /* memory allocation for dynamic (wavefield) arrays */
     if (gv->POS[2] == 0) {
-        vel->vx =
-            f3tensor(0 - gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                     gv->NX + l * gv->FDORDER / 2,
-                     1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
-        vel->vy =
-            f3tensor(0 - gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                     gv->NX + l * gv->FDORDER / 2,
-                     1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
-        vel->vz =
-            f3tensor(0 - gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                     gv->NX + l * gv->FDORDER / 2,
-                     1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
+        vel.vx.malloc(0 - gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2,
+                      1 - l * gv->FDORDER / 2, gv->NX + l * gv->FDORDER / 2,
+                      1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
+        vel.vy.malloc(0 - gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2,
+                      1 - l * gv->FDORDER / 2, gv->NX + l * gv->FDORDER / 2,
+                      1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
+        vel.vz.malloc(0 - gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2,
+                      1 - l * gv->FDORDER / 2, gv->NX + l * gv->FDORDER / 2,
+                      1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
         /* fvx  =  f4tensor(1,NT,0-gv->FDORDER/2,gv->NY+l*gv->FDORDER/2,1-l*gv->FDORDER/2,gv->NX+l*gv->FDORDER/2,1-l*gv->FDORDER/2,gv->NZ+l*gv->FDORDER/2);
          * fvy  =  f4tensor(1,NT,0-gv->FDORDER/2,gv->NY+l*gv->FDORDER/2,1-l*gv->FDORDER/2,gv->NX+l*gv->FDORDER/2,1-l*gv->FDORDER/2,gv->NZ+l*gv->FDORDER/2);
          * fvz  =  f4tensor(1,NT,0-gv->FDORDER/2,gv->NY+l*gv->FDORDER/2,1-l*gv->FDORDER/2,gv->NX+l*gv->FDORDER/2,1-l*gv->FDORDER/2,gv->NZ+l*gv->FDORDER/2); */
@@ -199,18 +196,15 @@ int initmem(st_model *mod, st_model *testmod,
     }
 
     if (gv->POS[2] > 0) {
-        vel->vx =
-            f3tensor(1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                     gv->NX + l * gv->FDORDER / 2,
-                     1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
-        vel->vy =
-            f3tensor(1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                     gv->NX + l * gv->FDORDER / 2,
-                     1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
-        vel->vz =
-            f3tensor(1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                     gv->NX + l * gv->FDORDER / 2,
-                     1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
+        vel.vx.malloc(1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2,
+                      1 - l * gv->FDORDER / 2, gv->NX + l * gv->FDORDER / 2,
+                      1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
+        vel.vy.malloc(1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2,
+                      1 - l * gv->FDORDER / 2, gv->NX + l * gv->FDORDER / 2,
+                      1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
+        vel.vz.malloc(1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2,
+                      1 - l * gv->FDORDER / 2, gv->NX + l * gv->FDORDER / 2,
+                      1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
         /* fvx  =  f4tensor(1,NT,1-l*gv->FDORDER/2,gv->NY+l*gv->FDORDER/2,1-l*gv->FDORDER/2,gv->NX+l*gv->FDORDER/2,1-l*gv->FDORDER/2,gv->NZ+l*gv->FDORDER/2);
          * fvy  =  f4tensor(1,NT,1-l*gv->FDORDER/2,gv->NY+l*gv->FDORDER/2,1-l*gv->FDORDER/2,gv->NX+l*gv->FDORDER/2,1-l*gv->FDORDER/2,gv->NZ+l*gv->FDORDER/2);
          * fvz  =  f4tensor(1,NT,1-l*gv->FDORDER/2,gv->NY+l*gv->FDORDER/2,1-l*gv->FDORDER/2,gv->NX+l*gv->FDORDER/2,1-l*gv->FDORDER/2,gv->NZ+l*gv->FDORDER/2); */
@@ -419,7 +413,7 @@ int initmem(st_model *mod, st_model *testmod,
         }
         mod->taup = f3tensor(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
 
-        //testmodel dummy (currently no viscoelastic gradients)
+        // testmodel dummy (currently no viscoelastic gradients)
         testmod->taup = f3tensor(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
 
         mod->eta = vector(1, gv->L);
diff --git a/src/seismo_ssg.cpp b/src/seismo_ssg.cpp
index 27c3dcf..1fd445b 100644
--- a/src/seismo_ssg.cpp
+++ b/src/seismo_ssg.cpp
@@ -25,7 +25,7 @@
 #include "fd.hpp"
 
 void seismo(int nt, int ntr, int **recpos, st_seismogram *section,
-            st_velocity *vel, st_stress *stress, st_model *mod, const GlobVar *gv)
+            st_velocity &vel, st_stress *stress, st_model *mod, const GlobVar *gv)
 {
     int i, j, k, itr;
     float amp, dh24x, dh24y, dh24z, vyx, vxy, vxx, vyy, vzx, vyz, vxz, vzy, vzz;
@@ -46,9 +46,9 @@ void seismo(int nt, int ntr, int **recpos, st_seismogram *section,
                 section->vy[itr][0] = 0.0f;
                 section->vz[itr][0] = 0.0f;
             }
-            section->vx[itr][nt] = vel->vx[nyrec][nxrec][nzrec];
-            section->vy[itr][nt] = vel->vy[nyrec][nxrec][nzrec];
-            section->vz[itr][nt] = vel->vz[nyrec][nxrec][nzrec];
+            section->vx[itr][nt] = vel.vx[nyrec, nxrec, nzrec];
+            section->vy[itr][nt] = vel.vy[nyrec, nxrec, nzrec];
+            section->vz[itr][nt] = vel.vz[nyrec, nxrec, nzrec];
             break;
         case 2:
             if (nt == 1) {
@@ -73,32 +73,32 @@ void seismo(int nt, int ntr, int **recpos, st_seismogram *section,
             j = nyrec;
             k = nzrec;
             if (gv->WEQ != 2) {
-                /*vxy=(-vel->vx[j+2][i][k]+27.0*(vel->vx[j+1][i][k]-vel->vx[j][i][k])+vel->vx[j-1][i][k])*(24.0*gv->DY);
-                 * vxz=(-vel->vx[j][i][k+2]+27.0*(vel->vx[j][i][k+1]-vel->vx[j][i][k])+vel->vx[j][i][k-1])*(24.0*gv->DZ);
-                 * vyx=(-vel->vy[j][i+2][k]+27.0*(vel->vy[j][i+1][k]-vel->vy[j][i][k])+vel->vy[j][i-1][k])*(24.0*gv->DX);
-                 * vyz=(-vel->vy[j][i][k+2]+27.0*(vel->vy[j][i][k+1]-vel->vy[j][i][k])+vel->vy[j][i][k-1])*(24.0*gv->DZ);
-                 * vzx=(-vel->vz[j][i+2][k]+27.0*(vel->vz[j][i+1][k]-vel->vz[j][i][k])+vel->vz[j][i-1][k])*(24.0*gv->DX);
-                 * vzy=(-vel->vz[j+2][i][k]+27.0*(vel->vz[j+1][i][k]-vel->vz[j][i][k])+vel->vz[j-1][i][k])*(24.0*gv->DY); */
-
-                vxy = (vel->vx[j + 1][i][k] - vel->vx[j][i][k]) * (dh24y);
-                vxz = (vel->vx[j][i][k + 1] - vel->vx[j][i][k]) * (dh24z);
-                vyx = (vel->vy[j][i + 1][k] - vel->vy[j][i][k]) * (dh24x);
-                vyz = (vel->vy[j][i][k + 1] - vel->vy[j][i][k]) * (dh24z);
-                vzx = (vel->vz[j][i + 1][k] - vel->vz[j][i][k]) * (dh24x);
-                vzy = (vel->vz[j + 1][i][k] - vel->vz[j][i][k]) * (dh24y);
+                /*vxy=(-vel.vx[j+2, i, k]+27.0*(vel.vx[j+1, i, k]-vel.vx[j, i, k])+vel.vx[j-1, i, k])*(24.0*gv->DY);
+                 * vxz=(-vel.vx[j, i, k+2]+27.0*(vel.vx[j, i, k+1]-vel.vx[j, i, k])+vel.vx[j, i, k-1])*(24.0*gv->DZ);
+                 * vyx=(-vel.vy[j, i+2, k]+27.0*(vel.vy[j, i+1, k]-vel.vy[j, i, k])+vel.vy[j, i-1, k])*(24.0*gv->DX);
+                 * vyz=(-vel.vy[j, i, k+2]+27.0*(vel.vy[j, i, k+1]-vel.vy[j, i, k])+vel.vy[j, i, k-1])*(24.0*gv->DZ);
+                 * vzx=(-vel.vz[j, i+2, k]+27.0*(vel.vz[j, i+1, k]-vel.vz[j, i, k])+vel.vz[j, i-1, k])*(24.0*gv->DX);
+                 * vzy=(-vel.vz[j+2, i, k]+27.0*(vel.vz[j+1, i, k]-vel.vz[j, i, k])+vel.vz[j-1, i, k])*(24.0*gv->DY); */
+
+                vxy = (vel.vx[j + 1, i, k] - vel.vx[j, i, k]) * (dh24y);
+                vxz = (vel.vx[j, i, k + 1] - vel.vx[j, i, k]) * (dh24z);
+                vyx = (vel.vy[j, i + 1, k] - vel.vy[j, i, k]) * (dh24x);
+                vyz = (vel.vy[j, i, k + 1] - vel.vy[j, i, k]) * (dh24z);
+                vzx = (vel.vz[j, i + 1, k] - vel.vz[j, i, k]) * (dh24x);
+                vzy = (vel.vz[j + 1, i, k] - vel.vz[j, i, k]) * (dh24y);
 
                 amp = mod->u[j][i][k] * ((vyz - vzy) * fabs(vyz - vzy) +
                                          (vzx - vxz) * fabs(vzx - vxz) + (vxy - vyx) * fabs(vxy - vyx));
                 section->curl[itr][nt] = fsign(amp) * sqrt(fabs(amp));
             }
 
-            /*vxx=(-vel->vx[j][i+1][k]+27.0*(vel->vx[j][i][k]-vel->vx[j][i-1][k])+vel->vx[j][i-2][k])*(24.0*gv->DX);
-             * vyy=(-vel->vy[j+1][i][k]+27.0*(vel->vy[j][i][k]-vel->vy[j-1][i][k])+vel->vy[j-2][i][k])*(24.0*gv->DY);
-             * vzz=(-vel->vz[j][i][k+1]+27.0*(vel->vz[j][i][k]-vel->vz[j][i][k-1])+vel->vz[j][i][k-2])*(24.0*gv->DZ); */
+            /*vxx=(-vel.vx[j, i+1, k]+27.0*(vel.vx[j, i, k]-vel.vx[j, i-1, k])+vel.vx[j, i-2, k])*(24.0*gv->DX);
+             * vyy=(-vel.vy[j+1, i, k]+27.0*(vel.vy[j, i, k]-vel.vy[j-1, i, k])+vel.vy[j-2, i, k])*(24.0*gv->DY);
+             * vzz=(-vel.vz[j, i, k+1]+27.0*(vel.vz[j, i, k]-vel.vz[j, i, k-1])+vel.vz[j, i, k-2])*(24.0*gv->DZ); */
 
-            vxx = (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) * (dh24x);
-            vyy = (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) * (dh24y);
-            vzz = (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) * (dh24z);
+            vxx = (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) * (dh24x);
+            vyy = (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) * (dh24y);
+            vzz = (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) * (dh24z);
 
             section->div[itr][nt] = (vxx + vyy + vzz) * sqrt(mod->pi[j][i][k]);
 
@@ -113,9 +113,9 @@ void seismo(int nt, int ntr, int **recpos, st_seismogram *section,
                 section->div[itr][0] = 0.0f;
                 section->curl[itr][0] = 0.0f;
             }
-            section->vx[itr][nt] = vel->vx[nyrec][nxrec][nzrec];
-            section->vy[itr][nt] = vel->vy[nyrec][nxrec][nzrec];
-            section->vz[itr][nt] = vel->vz[nyrec][nxrec][nzrec];
+            section->vx[itr][nt] = vel.vx[nyrec, nxrec, nzrec];
+            section->vy[itr][nt] = vel.vy[nyrec, nxrec, nzrec];
+            section->vz[itr][nt] = vel.vz[nyrec, nxrec, nzrec];
             if (gv->WEQ != 2) {
                 section->p[itr][nt] = (-stress->sxx[nyrec][nxrec][nzrec]
                                        - stress->syy[nyrec][nxrec][nzrec]
@@ -128,32 +128,32 @@ void seismo(int nt, int ntr, int **recpos, st_seismogram *section,
             k = nzrec;
 
             if (gv->WEQ != 2) {
-                /*vxy=(-vel->vx[j+2][i][k]+27.0*(vel->vx[j+1][i][k]-vel->vx[j][i][k])+vel->vx[j-1][i][k])*(dh24y);
-                 * vxz=(-vel->vx[j][i][k+2]+27.0*(vel->vx[j][i][k+1]-vel->vx[j][i][k])+vel->vx[j][i][k-1])*(dh24z);
-                 * vyx=(-vel->vy[j][i+2][k]+27.0*(vel->vy[j][i+1][k]-vel->vy[j][i][k])+vel->vy[j][i-1][k])*(dh24x);
-                 * vyz=(-vel->vy[j][i][k+2]+27.0*(vel->vy[j][i][k+1]-vel->vy[j][i][k])+vel->vy[j][i][k-1])*(dh24z);
-                 * vzx=(-vel->vz[j][i+2][k]+27.0*(vel->vz[j][i+1][k]-vel->vz[j][i][k])+vel->vz[j][i-1][k])*(dh24x);
-                 * vzy=(-vel->vz[j+2][i][k]+27.0*(vel->vz[j+1][i][k]-vel->vz[j][i][k])+vel->vz[j-1][i][k])*(dh24y); */
-
-                vxy = (vel->vx[j + 1][i][k] - vel->vx[j][i][k]) * (dh24y);
-                vxz = (vel->vx[j][i][k + 1] - vel->vx[j][i][k]) * (dh24z);
-                vyx = (vel->vy[j][i + 1][k] - vel->vy[j][i][k]) * (dh24x);
-                vyz = (vel->vy[j][i][k + 1] - vel->vy[j][i][k]) * (dh24z);
-                vzx = (vel->vz[j][i + 1][k] - vel->vz[j][i][k]) * (dh24x);
-                vzy = (vel->vz[j + 1][i][k] - vel->vz[j][i][k]) * (dh24y);
+                /*vxy=(-vel.vx[j+2, i, k]+27.0*(vel.vx[j+1, i, k]-vel.vx[j, i, k])+vel.vx[j-1, i, k])*(dh24y);
+                 * vxz=(-vel.vx[j, i, k+2]+27.0*(vel.vx[j, i, k+1]-vel.vx[j, i, k])+vel.vx[j, i, k-1])*(dh24z);
+                 * vyx=(-vel.vy[j, i+2, k]+27.0*(vel.vy[j, i+1, k]-vel.vy[j, i, k])+vel.vy[j, i-1, k])*(dh24x);
+                 * vyz=(-vel.vy[j, i, k+2]+27.0*(vel.vy[j, i, k+1]-vel.vy[j, i, k])+vel.vy[j, i, k-1])*(dh24z);
+                 * vzx=(-vel.vz[j, i+2, k]+27.0*(vel.vz[j, i+1, k]-vel.vz[j, i, k])+vel.vz[j, i-1, k])*(dh24x);
+                 * vzy=(-vel.vz[j+2, i, k]+27.0*(vel.vz[j+1, i, k]-vel.vz[j, i, k])+vel.vz[j-1, i, k])*(dh24y); */
+
+                vxy = (vel.vx[j + 1, i, k] - vel.vx[j, i, k]) * (dh24y);
+                vxz = (vel.vx[j, i, k + 1] - vel.vx[j, i, k]) * (dh24z);
+                vyx = (vel.vy[j, i + 1, k] - vel.vy[j, i, k]) * (dh24x);
+                vyz = (vel.vy[j, i, k + 1] - vel.vy[j, i, k]) * (dh24z);
+                vzx = (vel.vz[j, i + 1, k] - vel.vz[j, i, k]) * (dh24x);
+                vzy = (vel.vz[j + 1, i, k] - vel.vz[j, i, k]) * (dh24y);
 
                 amp = mod->u[j][i][k] * ((vyz - vzy) * fabs(vyz - vzy) +
                                          (vzx - vxz) * fabs(vzx - vxz) + (vxy - vyx) * fabs(vxy - vyx));
                 section->curl[itr][nt] = fsign(amp) * sqrt(fabs(amp));
             }
 
-            /*vxx=(-vel->vx[j][i+1][k]+27.0*(vel->vx[j][i][k]-vel->vx[j][i-1][k])+vel->vx[j][i-2][k])*(dh24x);
-             * vyy=(-vel->vy[j+1][i][k]+27.0*(vel->vy[j][i][k]-vel->vy[j-1][i][k])+vel->vy[j-2][i][k])*(dh24y);
-             * vzz=(-vel->vz[j][i][k+1]+27.0*(vel->vz[j][i][k]-vel->vz[j][i][k-1])+vel->vz[j][i][k-2])*(dh24z); */
+            /*vxx=(-vel.vx[j, i+1, k]+27.0*(vel.vx[j, i, k]-vel.vx[j, i-1, k])+vel.vx[j, i-2, k])*(dh24x);
+             * vyy=(-vel.vy[j+1, i, k]+27.0*(vel.vy[j, i, k]-vel.vy[j-1, i, k])+vel.vy[j-2, i, k])*(dh24y);
+             * vzz=(-vel.vz[j, i, k+1]+27.0*(vel.vz[j, i, k]-vel.vz[j, i, k-1])+vel.vz[j, i, k-2])*(dh24z); */
 
-            vxx = (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) * (dh24x);
-            vyy = (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) * (dh24y);
-            vzz = (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) * (dh24z);
+            vxx = (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) * (dh24x);
+            vyy = (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) * (dh24y);
+            vzz = (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) * (dh24z);
 
             section->div[itr][nt] = (vxx + vyy + vzz) * sqrt(mod->pi[j][i][k]);
             break;
diff --git a/src/snap_ssg.cpp b/src/snap_ssg.cpp
index edee4fc..aabccce 100644
--- a/src/snap_ssg.cpp
+++ b/src/snap_ssg.cpp
@@ -24,7 +24,7 @@
 #include "fd.hpp"
 #include "logging.hpp"
 
-void snap(int nt, int nsnap, st_velocity *vel, st_stress *stress, const st_model *mod,
+void snap(int nt, int nsnap, st_velocity &vel, st_stress *stress, const st_model *mod,
           const st_boundary *nb, GlobVar *gv)
 {
     /*
@@ -88,9 +88,9 @@ void snap(int nt, int nsnap, st_velocity *vel, st_stress *stress, const st_model
         for (int j = nb->ny1; j <= nb->ny2; j += gv->IDY) {
             for (int i = nb->nx1; i <= nb->nx2; i += gv->IDX) {
                 for (int k = nb->nz1; k <= nb->nz2; k += gv->IDZ) {
-                    writedsk(fpx1, vel->vx[j][i][k], gv->SNAP_FORMAT);
-                    writedsk(fpy1, vel->vy[j][i][k], gv->SNAP_FORMAT);
-                    writedsk(fpz1, vel->vz[j][i][k], gv->SNAP_FORMAT);
+                    writedsk(fpx1, vel.vx[j, i, k], gv->SNAP_FORMAT);
+                    writedsk(fpy1, vel.vy[j, i, k], gv->SNAP_FORMAT);
+                    writedsk(fpz1, vel.vz[j, i, k], gv->SNAP_FORMAT);
                 }
             }
         }
@@ -120,9 +120,9 @@ void snap(int nt, int nsnap, st_velocity *vel, st_stress *stress, const st_model
         for (int k = nb->ny1; k <= nb->ny2; k += gv->IDY)
             for (int i = nb->nx1; i <= nb->nx2; i += gv->IDX)
                 for (int j = nb->nz1; j <= nb->nz2; j += gv->IDZ) {
-                    writedsk(fpx1, vel->vx[j][i][k], gv->SNAP_FORMAT);
-                    writedsk(fpy1, vel->vy[j][i][k], gv->SNAP_FORMAT);
-                    writedsk(fpz1, vel->vz[j][i][k], gv->SNAP_FORMAT);
+                    writedsk(fpx1, vel.vx[j, i, k], gv->SNAP_FORMAT);
+                    writedsk(fpy1, vel.vy[j, i, k], gv->SNAP_FORMAT);
+                    writedsk(fpz1, vel.vz[j, i, k], gv->SNAP_FORMAT);
                 }
         fclose(fpx1);
         fclose(fpy1);
@@ -142,19 +142,19 @@ void snap(int nt, int nsnap, st_velocity *vel, st_stress *stress, const st_model
             for (int k = nb->ny1; k <= nb->ny2; k += gv->IDY)
                 for (int i = nb->nx1; i <= nb->nx2; i += gv->IDX)
                     for (int j = nb->nz1; j <= nb->nz2; j += gv->IDZ) {
-                        /*vxy=(-vel->vx[j+2][i][k]+27.0*(vel->vx[j+1][i][k]-vel->vx[j][i][k])+vel->vx[j-1][i][k])*(dh24);
-                         * vxz=(-vel->vx[j][i][k+2]+27.0*(vel->vx[j][i][k+1]-vel->vx[j][i][k])+vel->vx[j][i][k-1])*(dh24);
-                         * vyx=(-vel->vy[j][i+2][k]+27.0*(vel->vy[j][i+1][k]-vel->vy[j][i][k])+vel->vy[j][i-1][k])*(dh24);
-                         * vyz=(-vel->vy[j][i][k+2]+27.0*(vel->vy[j][i][k+1]-vel->vy[j][i][k])+vel->vy[j][i][k-1])*(dh24);
-                         * vzx=(-vel->vz[j][i+2][k]+27.0*(vel->vz[j][i+1][k]-vel->vz[j][i][k])+vel->vz[j][i-1][k])*(dh24);
-                         * vzy=(-vel->vz[j+2][i][k]+27.0*(vel->vz[j+1][i][k]-vel->vz[j][i][k])+vel->vz[j-1][i][k])*(dh24); */
-
-                        float vxy = (vel->vx[j + 1][i][k] - vel->vx[j][i][k]) * (dh24y);
-                        float vxz = (vel->vx[j][i][k + 1] - vel->vx[j][i][k]) * (dh24z);
-                        float vyx = (vel->vy[j][i + 1][k] - vel->vy[j][i][k]) * (dh24x);
-                        float vyz = (vel->vy[j][i][k + 1] - vel->vy[j][i][k]) * (dh24z);
-                        float vzx = (vel->vz[j][i + 1][k] - vel->vz[j][i][k]) * (dh24x);
-                        float vzy = (vel->vz[j + 1][i][k] - vel->vz[j][i][k]) * (dh24y);
+                        /*vxy=(-vel.vx[j+2, i, k]+27.0*(vel.vx[j+1, i, k]-vel.vx[j, i, k])+vel.vx[j-1, i, k])*(dh24);
+                         * vxz=(-vel.vx[j, i, k+2]+27.0*(vel.vx[j, i, k+1]-vel.vx[j, i, k])+vel.vx[j, i, k-1])*(dh24);
+                         * vyx=(-vel.vy[j, i+2, k]+27.0*(vel.vy[j, i+1, k]-vel.vy[j, i, k])+vel.vy[j, i-1, k])*(dh24);
+                         * vyz=(-vel.vy[j, i, k+2]+27.0*(vel.vy[j, i, k+1]-vel.vy[j, i, k])+vel.vy[j, i, k-1])*(dh24);
+                         * vzx=(-vel.vz[j, i+2, k]+27.0*(vel.vz[j, i+1, k]-vel.vz[j, i, k])+vel.vz[j, i-1, k])*(dh24);
+                         * vzy=(-vel.vz[j+2, i, k]+27.0*(vel.vz[j+1, i, k]-vel.vz[j, i, k])+vel.vz[j-1, i, k])*(dh24); */
+
+                        float vxy = (vel.vx[j + 1, i, k] - vel.vx[j, i, k]) * (dh24y);
+                        float vxz = (vel.vx[j, i, k + 1] - vel.vx[j, i, k]) * (dh24z);
+                        float vyx = (vel.vy[j, i + 1, k] - vel.vy[j, i, k]) * (dh24x);
+                        float vyz = (vel.vy[j, i, k + 1] - vel.vy[j, i, k]) * (dh24z);
+                        float vzx = (vel.vz[j, i + 1, k] - vel.vz[j, i, k]) * (dh24x);
+                        float vzy = (vel.vz[j + 1, i, k] - vel.vz[j, i, k]) * (dh24y);
 
                         /*amp= absolute value of curl(v)), without sqrt!!! */
                         amp = ((vzy - vyz) * (vzy - vyz) + (vxz - vzx) * (vxz - vzx) + (vyx - vxy) * (vyx - vxy));
@@ -200,13 +200,13 @@ void snap(int nt, int nsnap, st_velocity *vel, st_stress *stress, const st_model
         for (int k = nb->ny1; k <= nb->ny2; k += gv->IDY)
             for (int i = nb->nx1; i <= nb->nx2; i += gv->IDX)
                 for (int j = nb->nz1; j <= nb->nz2; j += gv->IDZ) {
-                    /*vxx=(-vel->vx[j][i+1][k]+27.0*(vel->vx[j][i][k]-vel->vx[j][i-1][k])+vel->vx[j][i-2][k])*(dh24);
-                     * vyy=(-vel->vy[j+1][i][k]+27.0*(vel->vy[j][i][k]-vel->vy[j-1][i][k])+vel->vy[j-2][i][k])*(dh24);
-                     * vzz=(-vel->vz[j][i][k+1]+27.0*(vel->vz[j][i][k]-vel->vz[j][i][k-1])+vel->vz[j][i][k-2])*(dh24); */
+                    /*vxx=(-vel.vx[j, i+1, k]+27.0*(vel.vx[j, i, k]-vel.vx[j, i-1, k])+vel.vx[j, i-2, k])*(dh24);
+                     * vyy=(-vel.vy[j+1, i, k]+27.0*(vel.vy[j, i, k]-vel.vy[j-1, i, k])+vel.vy[j-2, i, k])*(dh24);
+                     * vzz=(-vel.vz[j, i, k+1]+27.0*(vel.vz[j, i, k]-vel.vz[j, i, k-1])+vel.vz[j, i, k-2])*(dh24); */
 
-                    vxx = (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) * (dh24x);
-                    vyy = (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) * (dh24y);
-                    vzz = (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) * (dh24z);
+                    vxx = (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) * (dh24x);
+                    vyy = (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) * (dh24y);
+                    vzz = (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) * (dh24z);
 
                     /*amp= div(v)) */
                     amp = (vxx + vyy + vzz);
diff --git a/src/stfi.cpp b/src/stfi.cpp
index edb3b3c..ffc3954 100644
--- a/src/stfi.cpp
+++ b/src/stfi.cpp
@@ -30,7 +30,7 @@
 #include "seismo_shift.hpp"
 #include "kiss_fftr.h"
 
-void stfi(st_acquisition *acq, st_boundary *nb, const st_boundary *nb_fix, st_velocity *vel, st_stress *stress,
+void stfi(st_acquisition *acq, st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress *stress,
           st_model *mod, st_model_av *mod_av, st_visc_mem *visco_mem, st_seismogram *section,
           st_seismogram *section_obs, st_signals *signals, int nsrc_loc, int ntr_loc, st_pml_coeff *pml_coeff,
           st_pml_wfd *pml_wfd, st_buffer_flat *stressbuff, st_buffer_flat *velbuff, st_freq_velocity *fourier_vel_fw,
diff --git a/src/surface_ssg.cpp b/src/surface_ssg.cpp
index 2837a7f..503dea0 100644
--- a/src/surface_ssg.cpp
+++ b/src/surface_ssg.cpp
@@ -24,7 +24,7 @@
 #include "fd.hpp"
 
 void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, st_visc_mem *mem,
-             st_stress *stress, st_velocity *vel)
+             st_stress *stress, st_velocity &vel)
 {
     int i, k, j, fdoh, m, h1;
     float vxx, vyy, vzz;
@@ -72,18 +72,18 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
 
                 /* first calculate spatial derivatives of components of particle velocities */
                 vxx =
-                    (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                     b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k])) / DX;
+                    (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                     b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k])) / DX;
                 vyy =
-                    (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                     b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k])) / DY;
+                    (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                     b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k])) / DY;
                 vzz =
-                    (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                     b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2])) / DZ;
+                    (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                     b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) / DZ;
 
-                /*vxx=(-vel->vx[j][i+1][k]+27.0*(vel->vx[j][i][k]-vel->vx[j][i-1][k])+vel->vx[j][i-2][k])/(dh24x);
-                 * vyy=(-vel->vy[j+1][i][k]+27.0*(vel->vy[j][i][k]-vel->vy[j-1][i][k])+vel->vy[j-2][i][k])/(dh24x);
-                 * vzz=(-vel->vz[j][i][k+1]+27.0*(vel->vz[j][i][k]-vel->vz[j][i][k-1])+vel->vz[j][i][k-2])/(dh24x); */
+                /*vxx=(-vel.vx[j, i+1, k]+27.0*(vel.vx[j, i, k]-vel.vx[j, i-1, k])+vel.vx[j, i-2, k])/(dh24x);
+                 * vyy=(-vel.vy[j+1, i, k]+27.0*(vel.vy[j, i, k]-vel.vy[j-1, i, k])+vel.vy[j-2, i, k])/(dh24x);
+                 * vzz=(-vel.vz[j, i, k+1]+27.0*(vel.vz[j, i, k]-vel.vz[j, i, k-1])+vel.vz[j, i, k-2])/(dh24x); */
 
                 if (ABS_TYPE == 1) {
                     if ((POS[1] == 0) && (i <= FW)) {
@@ -166,14 +166,14 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
                  * of particle velocities */
 
                 vxx =
-                    (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                     b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k])) / DX;
+                    (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                     b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k])) / DX;
                 vyy =
-                    (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                     b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k])) / DY;
+                    (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                     b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k])) / DY;
                 vzz =
-                    (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                     b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2])) / DZ;
+                    (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                     b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) / DZ;
 
                 if (ABS_TYPE == 1) {
                     if ((POS[1] == 0) && (i <= FW)) {
@@ -256,17 +256,17 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
                 /* first calculate spatial derivatives of components
                  * of particle velocities */
 
-                vxx = (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                       b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k]) +
-                       b3 * (vel->vx[j][i + 2][k] - vel->vx[j][i - 3][k])) / DX;
+                vxx = (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                       b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k]) +
+                       b3 * (vel.vx[j, i + 2, k] - vel.vx[j, i - 3, k])) / DX;
 
-                vyy = (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                       b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k]) +
-                       b3 * (vel->vy[j + 2][i][k] - vel->vy[j - 3][i][k])) / DY;
+                vyy = (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                       b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k]) +
+                       b3 * (vel.vy[j + 2, i, k] - vel.vy[j - 3, i, k])) / DY;
 
-                vzz = (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                       b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2]) +
-                       b3 * (vel->vz[j][i][k + 2] - vel->vz[j][i][k - 3])) / DZ;
+                vzz = (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                       b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2]) +
+                       b3 * (vel.vz[j, i, k + 2] - vel.vz[j, i, k - 3])) / DZ;
 
                 /* partially updating sxx and szz in the same way */
                 f = mod->u[j][i][k] * 2.0f * (1.0f + L * mod->taus[j][i][k]);
@@ -326,20 +326,20 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
                 /* first calculate spatial derivatives of components
                  * of particle velocities */
 
-                vxx = (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                       b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k]) +
-                       b3 * (vel->vx[j][i + 2][k] - vel->vx[j][i - 3][k]) +
-                       b4 * (vel->vx[j][i + 3][k] - vel->vx[j][i - 4][k])) / DX;
+                vxx = (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                       b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k]) +
+                       b3 * (vel.vx[j, i + 2, k] - vel.vx[j, i - 3, k]) +
+                       b4 * (vel.vx[j, i + 3, k] - vel.vx[j, i - 4, k])) / DX;
 
-                vyy = (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                       b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k]) +
-                       b3 * (vel->vy[j + 2][i][k] - vel->vy[j - 3][i][k]) +
-                       b4 * (vel->vy[j + 3][i][k] - vel->vy[j - 4][i][k])) / DY;
+                vyy = (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                       b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k]) +
+                       b3 * (vel.vy[j + 2, i, k] - vel.vy[j - 3, i, k]) +
+                       b4 * (vel.vy[j + 3, i, k] - vel.vy[j - 4, i, k])) / DY;
 
-                vzz = (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                       b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2]) +
-                       b3 * (vel->vz[j][i][k + 2] - vel->vz[j][i][k - 3]) +
-                       b4 * (vel->vz[j][i][k + 3] - vel->vz[j][i][k - 4])) / DZ;
+                vzz = (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                       b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2]) +
+                       b3 * (vel.vz[j, i, k + 2] - vel.vz[j, i, k - 3]) +
+                       b4 * (vel.vz[j, i, k + 3] - vel.vz[j, i, k - 4])) / DZ;
 
                 /* partially updating sxx and szz in the same way */
                 f = mod->u[j][i][k] * 2.0f * (1.0f + L * mod->taus[j][i][k]);
@@ -401,23 +401,23 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
                 /* first calculate spatial derivatives of components
                  * of particle velocities */
 
-                vxx = (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                       b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k]) +
-                       b3 * (vel->vx[j][i + 2][k] - vel->vx[j][i - 3][k]) +
-                       b4 * (vel->vx[j][i + 3][k] - vel->vx[j][i - 4][k]) +
-                       b5 * (vel->vx[j][i + 4][k] - vel->vx[j][i - 5][k])) / DX;
+                vxx = (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                       b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k]) +
+                       b3 * (vel.vx[j, i + 2, k] - vel.vx[j, i - 3, k]) +
+                       b4 * (vel.vx[j, i + 3, k] - vel.vx[j, i - 4, k]) +
+                       b5 * (vel.vx[j, i + 4, k] - vel.vx[j, i - 5, k])) / DX;
 
-                vyy = (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                       b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k]) +
-                       b3 * (vel->vy[j + 2][i][k] - vel->vy[j - 3][i][k]) +
-                       b4 * (vel->vy[j + 3][i][k] - vel->vy[j - 4][i][k]) +
-                       b5 * (vel->vy[j + 4][i][k] - vel->vy[j - 5][i][k])) / DY;
+                vyy = (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                       b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k]) +
+                       b3 * (vel.vy[j + 2, i, k] - vel.vy[j - 3, i, k]) +
+                       b4 * (vel.vy[j + 3, i, k] - vel.vy[j - 4, i, k]) +
+                       b5 * (vel.vy[j + 4, i, k] - vel.vy[j - 5, i, k])) / DY;
 
-                vzz = (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                       b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2]) +
-                       b3 * (vel->vz[j][i][k + 2] - vel->vz[j][i][k - 3]) +
-                       b4 * (vel->vz[j][i][k + 3] - vel->vz[j][i][k - 4]) +
-                       b5 * (vel->vz[j][i][k + 4] - vel->vz[j][i][k - 5])) / DZ;
+                vzz = (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                       b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2]) +
+                       b3 * (vel.vz[j, i, k + 2] - vel.vz[j, i, k - 3]) +
+                       b4 * (vel.vz[j, i, k + 3] - vel.vz[j, i, k - 4]) +
+                       b5 * (vel.vz[j, i, k + 4] - vel.vz[j, i, k - 5])) / DZ;
 
                 /* partially updating sxx and szz in the same way */
                 f = mod->u[j][i][k] * 2.0f * (1.0f + L * mod->taus[j][i][k]);
@@ -483,26 +483,26 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
                 /* first calculate spatial derivatives of components
                  * of particle velocities */
 
-                vxx = (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                       b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k]) +
-                       b3 * (vel->vx[j][i + 2][k] - vel->vx[j][i - 3][k]) +
-                       b4 * (vel->vx[j][i + 3][k] - vel->vx[j][i - 4][k]) +
-                       b5 * (vel->vx[j][i + 4][k] - vel->vx[j][i - 5][k]) +
-                       b6 * (vel->vx[j][i + 5][k] - vel->vx[j][i - 6][k])) / DX;
-
-                vyy = (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                       b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k]) +
-                       b3 * (vel->vy[j + 2][i][k] - vel->vy[j - 3][i][k]) +
-                       b4 * (vel->vy[j + 3][i][k] - vel->vy[j - 4][i][k]) +
-                       b5 * (vel->vy[j + 4][i][k] - vel->vy[j - 5][i][k]) +
-                       b6 * (vel->vy[j + 5][i][k] - vel->vy[j - 6][i][k])) / DY;
-
-                vzz = (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                       b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2]) +
-                       b3 * (vel->vz[j][i][k + 2] - vel->vz[j][i][k - 3]) +
-                       b4 * (vel->vz[j][i][k + 3] - vel->vz[j][i][k - 4]) +
-                       b5 * (vel->vz[j][i][k + 4] - vel->vz[j][i][k - 5]) +
-                       b6 * (vel->vz[j][i][k + 5] - vel->vz[j][i][k - 6])) / DZ;
+                vxx = (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                       b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k]) +
+                       b3 * (vel.vx[j, i + 2, k] - vel.vx[j, i - 3, k]) +
+                       b4 * (vel.vx[j, i + 3, k] - vel.vx[j, i - 4, k]) +
+                       b5 * (vel.vx[j, i + 4, k] - vel.vx[j, i - 5, k]) +
+                       b6 * (vel.vx[j, i + 5, k] - vel.vx[j, i - 6, k])) / DX;
+
+                vyy = (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                       b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k]) +
+                       b3 * (vel.vy[j + 2, i, k] - vel.vy[j - 3, i, k]) +
+                       b4 * (vel.vy[j + 3, i, k] - vel.vy[j - 4, i, k]) +
+                       b5 * (vel.vy[j + 4, i, k] - vel.vy[j - 5, i, k]) +
+                       b6 * (vel.vy[j + 5, i, k] - vel.vy[j - 6, i, k])) / DY;
+
+                vzz = (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                       b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2]) +
+                       b3 * (vel.vz[j, i, k + 2] - vel.vz[j, i, k - 3]) +
+                       b4 * (vel.vz[j, i, k + 3] - vel.vz[j, i, k - 4]) +
+                       b5 * (vel.vz[j, i, k + 4] - vel.vz[j, i, k - 5]) +
+                       b6 * (vel.vz[j, i, k + 5] - vel.vz[j, i, k - 6])) / DZ;
 
                 /* partially updating sxx and szz in the same way */
                 f = mod->u[j][i][k] * 2.0f * (1.0f + L * mod->taus[j][i][k]);
diff --git a/src/surface_ssg_elastic.cpp b/src/surface_ssg_elastic.cpp
index b9090d2..caf41d1 100644
--- a/src/surface_ssg_elastic.cpp
+++ b/src/surface_ssg_elastic.cpp
@@ -24,7 +24,7 @@
 #include "fd.hpp"
 
 void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd,
-                     st_stress *stress, st_velocity *vel, const GlobVar *gv)
+                     st_stress *stress, st_velocity &vel, const GlobVar *gv)
 {
     int h1;
     float vxx, vyy, vzz;
@@ -52,9 +52,9 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
                 stress->syz[j - 1][i][k] = -stress->syz[j][i][k];
                 stress->syz[j - 2][i][k] = -stress->syz[j + 1][i][k];
 
-                vxx = (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) * oodx;
-                vyy = (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) * oody;
-                vzz = (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) * oodz;
+                vxx = (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) * oodx;
+                vyy = (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) * oody;
+                vzz = (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) * oodz;
 
                 if (gv->ABS_TYPE == 1) {
                     if ((gv->POS[1] == 0) && (i <= gv->FW)) {
@@ -113,14 +113,14 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
                     stress->syz[j - m][i][k] = -stress->syz[j + m - 1][i][k];
                 }
                 vxx =
-                    (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                     b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k])) * oodx;
+                    (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                     b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k])) * oodx;
                 vyy =
-                    (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                     b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k])) * oody;
+                    (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                     b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k])) * oody;
                 vzz =
-                    (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                     b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2])) * oodz;
+                    (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                     b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) * oodz;
 
                 if (gv->ABS_TYPE == 1) {
                     if ((gv->POS[1] == 0) && (i <= gv->FW)) {
@@ -180,17 +180,17 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
                     stress->syz[j - m][i][k] = -stress->syz[j + m - 1][i][k];
                 }
 
-                vxx = (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                       b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k]) +
-                       b3 * (vel->vx[j][i + 2][k] - vel->vx[j][i - 3][k])) * oodx;
+                vxx = (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                       b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k]) +
+                       b3 * (vel.vx[j, i + 2, k] - vel.vx[j, i - 3, k])) * oodx;
 
-                vyy = (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                       b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k]) +
-                       b3 * (vel->vy[j + 2][i][k] - vel->vy[j - 3][i][k])) * oody;
+                vyy = (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                       b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k]) +
+                       b3 * (vel.vy[j + 2, i, k] - vel.vy[j - 3, i, k])) * oody;
 
-                vzz = (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                       b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2]) +
-                       b3 * (vel->vz[j][i][k + 2] - vel->vz[j][i][k - 3])) * oodz;
+                vzz = (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                       b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2]) +
+                       b3 * (vel.vz[j, i, k + 2] - vel.vz[j, i, k - 3])) * oodz;
 
                 f = mod->u[j][i][k] * 2.0;
                 g = mod->pi[j][i][k];
@@ -227,20 +227,20 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
                     stress->syz[j - m][i][k] = -stress->syz[j + m - 1][i][k];
                 }
 
-                vxx = (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                       b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k]) +
-                       b3 * (vel->vx[j][i + 2][k] - vel->vx[j][i - 3][k]) +
-                       b4 * (vel->vx[j][i + 3][k] - vel->vx[j][i - 4][k])) * oodx;
+                vxx = (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                       b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k]) +
+                       b3 * (vel.vx[j, i + 2, k] - vel.vx[j, i - 3, k]) +
+                       b4 * (vel.vx[j, i + 3, k] - vel.vx[j, i - 4, k])) * oodx;
 
-                vyy = (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                       b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k]) +
-                       b3 * (vel->vy[j + 2][i][k] - vel->vy[j - 3][i][k]) +
-                       b4 * (vel->vy[j + 3][i][k] - vel->vy[j - 4][i][k])) * oody;
+                vyy = (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                       b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k]) +
+                       b3 * (vel.vy[j + 2, i, k] - vel.vy[j - 3, i, k]) +
+                       b4 * (vel.vy[j + 3, i, k] - vel.vy[j - 4, i, k])) * oody;
 
-                vzz = (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                       b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2]) +
-                       b3 * (vel->vz[j][i][k + 2] - vel->vz[j][i][k - 3]) +
-                       b4 * (vel->vz[j][i][k + 3] - vel->vz[j][i][k - 4])) * oodz;
+                vzz = (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                       b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2]) +
+                       b3 * (vel.vz[j, i, k + 2] - vel.vz[j, i, k - 3]) +
+                       b4 * (vel.vz[j, i, k + 3] - vel.vz[j, i, k - 4])) * oodz;
 
                 f = mod->u[j][i][k] * 2.0;
                 g = mod->pi[j][i][k];
@@ -279,23 +279,23 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
                     stress->syz[j - m][i][k] = -stress->syz[j + m - 1][i][k];
                 }
 
-                vxx = (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                       b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k]) +
-                       b3 * (vel->vx[j][i + 2][k] - vel->vx[j][i - 3][k]) +
-                       b4 * (vel->vx[j][i + 3][k] - vel->vx[j][i - 4][k]) +
-                       b5 * (vel->vx[j][i + 4][k] - vel->vx[j][i - 5][k])) * oodx;
+                vxx = (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                       b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k]) +
+                       b3 * (vel.vx[j, i + 2, k] - vel.vx[j, i - 3, k]) +
+                       b4 * (vel.vx[j, i + 3, k] - vel.vx[j, i - 4, k]) +
+                       b5 * (vel.vx[j, i + 4, k] - vel.vx[j, i - 5, k])) * oodx;
 
-                vyy = (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                       b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k]) +
-                       b3 * (vel->vy[j + 2][i][k] - vel->vy[j - 3][i][k]) +
-                       b4 * (vel->vy[j + 3][i][k] - vel->vy[j - 4][i][k]) +
-                       b5 * (vel->vy[j + 4][i][k] - vel->vy[j - 5][i][k])) * oody;
+                vyy = (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                       b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k]) +
+                       b3 * (vel.vy[j + 2, i, k] - vel.vy[j - 3, i, k]) +
+                       b4 * (vel.vy[j + 3, i, k] - vel.vy[j - 4, i, k]) +
+                       b5 * (vel.vy[j + 4, i, k] - vel.vy[j - 5, i, k])) * oody;
 
-                vzz = (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                       b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2]) +
-                       b3 * (vel->vz[j][i][k + 2] - vel->vz[j][i][k - 3]) +
-                       b4 * (vel->vz[j][i][k + 3] - vel->vz[j][i][k - 4]) +
-                       b5 * (vel->vz[j][i][k + 4] - vel->vz[j][i][k - 5])) * oodz;
+                vzz = (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                       b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2]) +
+                       b3 * (vel.vz[j, i, k + 2] - vel.vz[j, i, k - 3]) +
+                       b4 * (vel.vz[j, i, k + 3] - vel.vz[j, i, k - 4]) +
+                       b5 * (vel.vz[j, i, k + 4] - vel.vz[j, i, k - 5])) * oodz;
 
                 f = mod->u[j][i][k] * 2.0;
                 g = mod->pi[j][i][k];
@@ -338,26 +338,26 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
                     stress->syz[j - m][i][k] = -stress->syz[j + m - 1][i][k];
                 }
 
-                vxx = (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                       b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k]) +
-                       b3 * (vel->vx[j][i + 2][k] - vel->vx[j][i - 3][k]) +
-                       b4 * (vel->vx[j][i + 3][k] - vel->vx[j][i - 4][k]) +
-                       b5 * (vel->vx[j][i + 4][k] - vel->vx[j][i - 5][k]) +
-                       b6 * (vel->vx[j][i + 5][k] - vel->vx[j][i - 6][k])) * oodx;
-
-                vyy = (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                       b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k]) +
-                       b3 * (vel->vy[j + 2][i][k] - vel->vy[j - 3][i][k]) +
-                       b4 * (vel->vy[j + 3][i][k] - vel->vy[j - 4][i][k]) +
-                       b5 * (vel->vy[j + 4][i][k] - vel->vy[j - 5][i][k]) +
-                       b6 * (vel->vy[j + 5][i][k] - vel->vy[j - 6][i][k])) * oody;
-
-                vzz = (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                       b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2]) +
-                       b3 * (vel->vz[j][i][k + 2] - vel->vz[j][i][k - 3]) +
-                       b4 * (vel->vz[j][i][k + 3] - vel->vz[j][i][k - 4]) +
-                       b5 * (vel->vz[j][i][k + 4] - vel->vz[j][i][k - 5]) +
-                       b6 * (vel->vz[j][i][k + 5] - vel->vz[j][i][k - 6])) * oodz;
+                vxx = (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                       b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k]) +
+                       b3 * (vel.vx[j, i + 2, k] - vel.vx[j, i - 3, k]) +
+                       b4 * (vel.vx[j, i + 3, k] - vel.vx[j, i - 4, k]) +
+                       b5 * (vel.vx[j, i + 4, k] - vel.vx[j, i - 5, k]) +
+                       b6 * (vel.vx[j, i + 5, k] - vel.vx[j, i - 6, k])) * oodx;
+
+                vyy = (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                       b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k]) +
+                       b3 * (vel.vy[j + 2, i, k] - vel.vy[j - 3, i, k]) +
+                       b4 * (vel.vy[j + 3, i, k] - vel.vy[j - 4, i, k]) +
+                       b5 * (vel.vy[j + 4, i, k] - vel.vy[j - 5, i, k]) +
+                       b6 * (vel.vy[j + 5, i, k] - vel.vy[j - 6, i, k])) * oody;
+
+                vzz = (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                       b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2]) +
+                       b3 * (vel.vz[j, i, k + 2] - vel.vz[j, i, k - 3]) +
+                       b4 * (vel.vz[j, i, k + 3] - vel.vz[j, i, k - 4]) +
+                       b5 * (vel.vz[j, i, k + 4] - vel.vz[j, i, k - 5]) +
+                       b6 * (vel.vz[j, i, k + 5] - vel.vz[j, i, k - 6])) * oodz;
 
                 f = mod->u[j][i][k] * 2.0;
                 g = mod->pi[j][i][k];
diff --git a/src/timeloop.cpp b/src/timeloop.cpp
index d621f2b..4285f85 100644
--- a/src/timeloop.cpp
+++ b/src/timeloop.cpp
@@ -23,7 +23,7 @@
 #include "fd.hpp"
 #include "logging.hpp"
 
-void timeloop(st_boundary *nb, const st_boundary *nb_fix, st_velocity *vel, st_stress *stress,
+void timeloop(st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress *stress,
               st_model *mod, st_model_av *mod_av, st_seismogram *section,
               float **srcpos_loc, int **recpos_loc, st_signals *signals, int nsrc_loc,
               float ***absorb_coeff, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd,
@@ -42,7 +42,7 @@ void timeloop(st_boundary *nb, const st_boundary *nb_fix, st_velocity *vel, st_s
 
     for (int nt = 1; nt <= gv->NT; nt++) {
         /* Check if simulation is still stable */
-        if (isnan(vel->vy[gv->NY / 2][gv->NX / 2][gv->NZ / 2]))
+        if (isnan(vel.vy[gv->NY / 2, gv->NX / 2, gv->NZ / 2]))
             log_fatal("Simulation is unstable!\n"); /* maybe just breaking the loop would be better */
 
         /* update of particle velocities */
@@ -124,6 +124,27 @@ void timeloop(st_boundary *nb, const st_boundary *nb_fix, st_velocity *vel, st_s
             lsnap = lsnap + iround(gv->TSNAPINC / gv->DT);
         }
 
+        if (nt % gv->LOG_NTSTEP == 0) {
+            double vx_max = 0.0, vy_max = 0.0, vz_max = 0.0;
+            for (int j = nb->ny1; j <= nb->ny2; j++) {
+                for (int i = nb->nx1; i <= nb->nx2; i++) {
+                    #pragma omp simd
+                    for (int k = nb->nz1; k <= nb->nz2; k++) {
+                        vx_max = fmax(vx_max, fabs(vel.vx[j, i, k]));
+                        vy_max = fmax(vy_max, fabs(vel.vy[j, i, k]));
+                        vz_max = fmax(vz_max, fabs(vel.vz[j, i, k]));
+                    }
+                }
+            }
+
+            double max_send[] = { vx_max, vy_max, vz_max };
+            double max_recv[3];
+            MPI_Reduce(max_send, max_recv, 3, MPI_DOUBLE, MPI_MAX, 0, gv->COMM_SHOT);
+            if (gv->MYID_SHOT == 0) {
+                printf("max fabs: vx=%.3g, vy=%.3g, vz=%.3g\n", max_recv[0], max_recv[1], max_recv[2]);
+            }
+        }
+
         if ((nt % gv->LOG_NTSTEP == 0) && (gv->MYID_SHOT == 0)) {
             double time2c = MPI_Wtime();
             if (proptype == 1)
diff --git a/src/update_s_ssg_CPML_acoustic.cpp b/src/update_s_ssg_CPML_acoustic.cpp
index 483b2cd..048553d 100644
--- a/src/update_s_ssg_CPML_acoustic.cpp
+++ b/src/update_s_ssg_CPML_acoustic.cpp
@@ -29,7 +29,7 @@
 
 #define UNUSED(x) (void)(x)
 
-double update_s_CPML_acoustic(st_boundary *nb, st_velocity *vel,
+double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
                               st_stress *stress, st_model *mod, st_pml_coeff *pml_coeff,
                               st_pml_wfd *pml_wfd, const GlobVar *gv)
 {
@@ -51,14 +51,14 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity *vel,
                 #pragma omp simd
                 for (int k = 1; k <= gv->NZ; k++) {
                     vxx =
-                        (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                         b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k])) / gv->DX;
+                        (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                         b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k])) / gv->DX;
                     vyy =
-                        (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                         b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k])) / gv->DY;
+                        (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                         b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k])) / gv->DY;
                     vzz =
-                        (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                         b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2])) / gv->DZ;
+                        (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                         b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) / gv->DZ;
 
                     pml_wfd->psi_vxx[j][i][k] = pml_coeff->b_x[i] * pml_wfd->psi_vxx[j][i][k] + pml_coeff->a_x[i] * vxx;
                     vxx = vxx / pml_coeff->K_x[i] + pml_wfd->psi_vxx[j][i][k];
@@ -107,14 +107,14 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity *vel,
                 #pragma omp simd
                 for (int k = 1; k <= gv->NZ; k++) {
                     vxx =
-                        (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                         b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k])) / gv->DX;
+                        (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                         b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k])) / gv->DX;
                     vyy =
-                        (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                         b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k])) / gv->DY;
+                        (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                         b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k])) / gv->DY;
                     vzz =
-                        (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                         b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2])) / gv->DZ;
+                        (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                         b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) / gv->DZ;
 
                     h1 = i - nb->nx2 + gv->FW;
 
@@ -166,14 +166,14 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity *vel,
                 #pragma omp simd
                 for (int k = 1; k <= gv->NZ; k++) {
                     vxx =
-                        (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                         b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k])) / gv->DX;
+                        (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                         b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k])) / gv->DX;
                     vyy =
-                        (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                         b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k])) / gv->DY;
+                        (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                         b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k])) / gv->DY;
                     vzz =
-                        (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                         b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2])) / gv->DZ;
+                        (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                         b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) / gv->DZ;
 
                     pml_wfd->psi_vyy[j][i][k] = pml_coeff->b_y[j] * pml_wfd->psi_vyy[j][i][k] + pml_coeff->a_y[j] * vyy;
                     vyy = vyy / pml_coeff->K_y[j] + pml_wfd->psi_vyy[j][i][k];
@@ -208,14 +208,14 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity *vel,
                 #pragma omp simd
                 for (int k = 1; k <= gv->NZ; k++) {
                     vxx =
-                        (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                         b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k])) / gv->DX;
+                        (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                         b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k])) / gv->DX;
                     vyy =
-                        (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                         b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k])) / gv->DY;
+                        (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                         b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k])) / gv->DY;
                     vzz =
-                        (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                         b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2])) / gv->DZ;
+                        (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                         b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) / gv->DZ;
 
                     h1 = (j - nb->ny2 + gv->FW);
 
@@ -253,14 +253,14 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity *vel,
                 #pragma omp simd
                 for (int k = 1; k <= gv->FW; k++) {
                     vxx =
-                        (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                         b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k])) / gv->DX;
+                        (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                         b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k])) / gv->DX;
                     vyy =
-                        (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                         b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k])) / gv->DY;
+                        (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                         b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k])) / gv->DY;
                     vzz =
-                        (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                         b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2])) / gv->DZ;
+                        (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                         b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) / gv->DZ;
 
                     pml_wfd->psi_vzz[j][i][k] = pml_coeff->b_z[k] * pml_wfd->psi_vzz[j][i][k] + pml_coeff->a_z[k] * vzz;
                     vzz = vzz / pml_coeff->K_y[k] + pml_wfd->psi_vzz[j][i][k];
@@ -281,14 +281,14 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity *vel,
                 #pragma omp simd
                 for (int k = nb->nz2 + 1; k <= nb->nz2 + gv->FW; k++) {
                     vxx =
-                        (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                         b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k])) / gv->DX;
+                        (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                         b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k])) / gv->DX;
                     vyy =
-                        (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                         b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k])) / gv->DY;
+                        (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                         b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k])) / gv->DY;
                     vzz =
-                        (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                         b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2])) / gv->DZ;
+                        (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                         b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) / gv->DZ;
 
                     h1 = (k - nb->nz2 + gv->FW);
 
diff --git a/src/update_s_ssg_CPML_elastic.cpp b/src/update_s_ssg_CPML_elastic.cpp
index 6c3c430..db8abf7 100644
--- a/src/update_s_ssg_CPML_elastic.cpp
+++ b/src/update_s_ssg_CPML_elastic.cpp
@@ -29,7 +29,7 @@
 
 #define UNUSED(x) (void)(x)
 
-double update_s_CPML_elastic(st_boundary *nb, st_velocity *vel,
+double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                              st_stress *stress, st_model *mod, st_model_av *mod_av,
                              st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, const GlobVar *gv)
 {
@@ -59,32 +59,32 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity *vel,
                 #pragma omp simd
                 for (int k = 1; k <= gv->NZ; k++) {
                     vxx =
-                        (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                         b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k])) * oodx;
+                        (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                         b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k])) * oodx;
                     vxy =
-                        (b1 * (vel->vx[j + 1][i][k] - vel->vx[j][i][k]) +
-                         b2 * (vel->vx[j + 2][i][k] - vel->vx[j - 1][i][k])) * oody;
+                        (b1 * (vel.vx[j + 1, i, k] - vel.vx[j, i, k]) +
+                         b2 * (vel.vx[j + 2, i, k] - vel.vx[j - 1, i, k])) * oody;
                     vxz =
-                        (b1 * (vel->vx[j][i][k + 1] - vel->vx[j][i][k]) +
-                         b2 * (vel->vx[j][i][k + 2] - vel->vx[j][i][k - 1])) * oodz;
+                        (b1 * (vel.vx[j, i, k + 1] - vel.vx[j, i, k]) +
+                         b2 * (vel.vx[j, i, k + 2] - vel.vx[j, i, k - 1])) * oodz;
                     vyx =
-                        (b1 * (vel->vy[j][i + 1][k] - vel->vy[j][i][k]) +
-                         b2 * (vel->vy[j][i + 2][k] - vel->vy[j][i - 1][k])) * oodx;
+                        (b1 * (vel.vy[j, i + 1, k] - vel.vy[j, i, k]) +
+                         b2 * (vel.vy[j, i + 2, k] - vel.vy[j, i - 1, k])) * oodx;
                     vyy =
-                        (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                         b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k])) * oody;
+                        (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                         b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k])) * oody;
                     vyz =
-                        (b1 * (vel->vy[j][i][k + 1] - vel->vy[j][i][k]) +
-                         b2 * (vel->vy[j][i][k + 2] - vel->vy[j][i][k - 1])) * oodz;
+                        (b1 * (vel.vy[j, i, k + 1] - vel.vy[j, i, k]) +
+                         b2 * (vel.vy[j, i, k + 2] - vel.vy[j, i, k - 1])) * oodz;
                     vzx =
-                        (b1 * (vel->vz[j][i + 1][k] - vel->vz[j][i][k]) +
-                         b2 * (vel->vz[j][i + 2][k] - vel->vz[j][i - 1][k])) * oodx;
+                        (b1 * (vel.vz[j, i + 1, k] - vel.vz[j, i, k]) +
+                         b2 * (vel.vz[j, i + 2, k] - vel.vz[j, i - 1, k])) * oodx;
                     vzy =
-                        (b1 * (vel->vz[j + 1][i][k] - vel->vz[j][i][k]) +
-                         b2 * (vel->vz[j + 2][i][k] - vel->vz[j - 1][i][k])) * oody;
+                        (b1 * (vel.vz[j + 1, i, k] - vel.vz[j, i, k]) +
+                         b2 * (vel.vz[j + 2, i, k] - vel.vz[j - 1, i, k])) * oody;
                     vzz =
-                        (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                         b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2])) * oodz;
+                        (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                         b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) * oodz;
 
                     pml_wfd->psi_vxx[j][i][k] = pml_coeff->b_x[i] * pml_wfd->psi_vxx[j][i][k] + pml_coeff->a_x[i] * vxx;
                     vxx = vxx / pml_coeff->K_x[i] + pml_wfd->psi_vxx[j][i][k];
@@ -178,32 +178,32 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity *vel,
                 #pragma omp simd
                 for (int k = 1; k <= gv->NZ; k++) {
                     vxx =
-                        (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                         b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k])) * oodx;
+                        (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                         b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k])) * oodx;
                     vxy =
-                        (b1 * (vel->vx[j + 1][i][k] - vel->vx[j][i][k]) +
-                         b2 * (vel->vx[j + 2][i][k] - vel->vx[j - 1][i][k])) * oody;
+                        (b1 * (vel.vx[j + 1, i, k] - vel.vx[j, i, k]) +
+                         b2 * (vel.vx[j + 2, i, k] - vel.vx[j - 1, i, k])) * oody;
                     vxz =
-                        (b1 * (vel->vx[j][i][k + 1] - vel->vx[j][i][k]) +
-                         b2 * (vel->vx[j][i][k + 2] - vel->vx[j][i][k - 1])) * oodz;
+                        (b1 * (vel.vx[j, i, k + 1] - vel.vx[j, i, k]) +
+                         b2 * (vel.vx[j, i, k + 2] - vel.vx[j, i, k - 1])) * oodz;
                     vyx =
-                        (b1 * (vel->vy[j][i + 1][k] - vel->vy[j][i][k]) +
-                         b2 * (vel->vy[j][i + 2][k] - vel->vy[j][i - 1][k])) * oodx;
+                        (b1 * (vel.vy[j, i + 1, k] - vel.vy[j, i, k]) +
+                         b2 * (vel.vy[j, i + 2, k] - vel.vy[j, i - 1, k])) * oodx;
                     vyy =
-                        (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                         b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k])) * oody;
+                        (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                         b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k])) * oody;
                     vyz =
-                        (b1 * (vel->vy[j][i][k + 1] - vel->vy[j][i][k]) +
-                         b2 * (vel->vy[j][i][k + 2] - vel->vy[j][i][k - 1])) * oodz;
+                        (b1 * (vel.vy[j, i, k + 1] - vel.vy[j, i, k]) +
+                         b2 * (vel.vy[j, i, k + 2] - vel.vy[j, i, k - 1])) * oodz;
                     vzx =
-                        (b1 * (vel->vz[j][i + 1][k] - vel->vz[j][i][k]) +
-                         b2 * (vel->vz[j][i + 2][k] - vel->vz[j][i - 1][k])) * oodx;
+                        (b1 * (vel.vz[j, i + 1, k] - vel.vz[j, i, k]) +
+                         b2 * (vel.vz[j, i + 2, k] - vel.vz[j, i - 1, k])) * oodx;
                     vzy =
-                        (b1 * (vel->vz[j + 1][i][k] - vel->vz[j][i][k]) +
-                         b2 * (vel->vz[j + 2][i][k] - vel->vz[j - 1][i][k])) * oody;
+                        (b1 * (vel.vz[j + 1, i, k] - vel.vz[j, i, k]) +
+                         b2 * (vel.vz[j + 2, i, k] - vel.vz[j - 1, i, k])) * oody;
                     vzz =
-                        (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                         b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2])) * oodz;
+                        (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                         b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) * oodz;
 
                     h1 = i - nb->nx2 + gv->FW;
 
@@ -302,32 +302,32 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity *vel,
                 #pragma omp simd
                 for (int k = 1; k <= gv->NZ; k++) {
                     vxx =
-                        (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                         b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k])) * oodx;
+                        (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                         b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k])) * oodx;
                     vxy =
-                        (b1 * (vel->vx[j + 1][i][k] - vel->vx[j][i][k]) +
-                         b2 * (vel->vx[j + 2][i][k] - vel->vx[j - 1][i][k])) * oody;
+                        (b1 * (vel.vx[j + 1, i, k] - vel.vx[j, i, k]) +
+                         b2 * (vel.vx[j + 2, i, k] - vel.vx[j - 1, i, k])) * oody;
                     vxz =
-                        (b1 * (vel->vx[j][i][k + 1] - vel->vx[j][i][k]) +
-                         b2 * (vel->vx[j][i][k + 2] - vel->vx[j][i][k - 1])) * oodz;
+                        (b1 * (vel.vx[j, i, k + 1] - vel.vx[j, i, k]) +
+                         b2 * (vel.vx[j, i, k + 2] - vel.vx[j, i, k - 1])) * oodz;
                     vyx =
-                        (b1 * (vel->vy[j][i + 1][k] - vel->vy[j][i][k]) +
-                         b2 * (vel->vy[j][i + 2][k] - vel->vy[j][i - 1][k])) * oodx;
+                        (b1 * (vel.vy[j, i + 1, k] - vel.vy[j, i, k]) +
+                         b2 * (vel.vy[j, i + 2, k] - vel.vy[j, i - 1, k])) * oodx;
                     vyy =
-                        (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                         b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k])) * oody;
+                        (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                         b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k])) * oody;
                     vyz =
-                        (b1 * (vel->vy[j][i][k + 1] - vel->vy[j][i][k]) +
-                         b2 * (vel->vy[j][i][k + 2] - vel->vy[j][i][k - 1])) * oodz;
+                        (b1 * (vel.vy[j, i, k + 1] - vel.vy[j, i, k]) +
+                         b2 * (vel.vy[j, i, k + 2] - vel.vy[j, i, k - 1])) * oodz;
                     vzx =
-                        (b1 * (vel->vz[j][i + 1][k] - vel->vz[j][i][k]) +
-                         b2 * (vel->vz[j][i + 2][k] - vel->vz[j][i - 1][k])) * oodx;
+                        (b1 * (vel.vz[j, i + 1, k] - vel.vz[j, i, k]) +
+                         b2 * (vel.vz[j, i + 2, k] - vel.vz[j, i - 1, k])) * oodx;
                     vzy =
-                        (b1 * (vel->vz[j + 1][i][k] - vel->vz[j][i][k]) +
-                         b2 * (vel->vz[j + 2][i][k] - vel->vz[j - 1][i][k])) * oody;
+                        (b1 * (vel.vz[j + 1, i, k] - vel.vz[j, i, k]) +
+                         b2 * (vel.vz[j + 2, i, k] - vel.vz[j - 1, i, k])) * oody;
                     vzz =
-                        (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                         b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2])) * oodz;
+                        (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                         b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) * oodz;
 
                     pml_wfd->psi_vxy[j][i][k] =
                         pml_coeff->b_y_half[j] * pml_wfd->psi_vxy[j][i][k] + pml_coeff->a_y_half[j] * vxy;
@@ -395,32 +395,32 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity *vel,
                 #pragma omp simd
                 for (int k = 1; k <= gv->NZ; k++) {
                     vxx =
-                        (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                         b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k])) * oodx;
+                        (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                         b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k])) * oodx;
                     vxy =
-                        (b1 * (vel->vx[j + 1][i][k] - vel->vx[j][i][k]) +
-                         b2 * (vel->vx[j + 2][i][k] - vel->vx[j - 1][i][k])) * oody;
+                        (b1 * (vel.vx[j + 1, i, k] - vel.vx[j, i, k]) +
+                         b2 * (vel.vx[j + 2, i, k] - vel.vx[j - 1, i, k])) * oody;
                     vxz =
-                        (b1 * (vel->vx[j][i][k + 1] - vel->vx[j][i][k]) +
-                         b2 * (vel->vx[j][i][k + 2] - vel->vx[j][i][k - 1])) * oodz;
+                        (b1 * (vel.vx[j, i, k + 1] - vel.vx[j, i, k]) +
+                         b2 * (vel.vx[j, i, k + 2] - vel.vx[j, i, k - 1])) * oodz;
                     vyx =
-                        (b1 * (vel->vy[j][i + 1][k] - vel->vy[j][i][k]) +
-                         b2 * (vel->vy[j][i + 2][k] - vel->vy[j][i - 1][k])) * oodx;
+                        (b1 * (vel.vy[j, i + 1, k] - vel.vy[j, i, k]) +
+                         b2 * (vel.vy[j, i + 2, k] - vel.vy[j, i - 1, k])) * oodx;
                     vyy =
-                        (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                         b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k])) * oody;
+                        (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                         b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k])) * oody;
                     vyz =
-                        (b1 * (vel->vy[j][i][k + 1] - vel->vy[j][i][k]) +
-                         b2 * (vel->vy[j][i][k + 2] - vel->vy[j][i][k - 1])) * oodz;
+                        (b1 * (vel.vy[j, i, k + 1] - vel.vy[j, i, k]) +
+                         b2 * (vel.vy[j, i, k + 2] - vel.vy[j, i, k - 1])) * oodz;
                     vzx =
-                        (b1 * (vel->vz[j][i + 1][k] - vel->vz[j][i][k]) +
-                         b2 * (vel->vz[j][i + 2][k] - vel->vz[j][i - 1][k])) * oodx;
+                        (b1 * (vel.vz[j, i + 1, k] - vel.vz[j, i, k]) +
+                         b2 * (vel.vz[j, i + 2, k] - vel.vz[j, i - 1, k])) * oodx;
                     vzy =
-                        (b1 * (vel->vz[j + 1][i][k] - vel->vz[j][i][k]) +
-                         b2 * (vel->vz[j + 2][i][k] - vel->vz[j - 1][i][k])) * oody;
+                        (b1 * (vel.vz[j + 1, i, k] - vel.vz[j, i, k]) +
+                         b2 * (vel.vz[j + 2, i, k] - vel.vz[j - 1, i, k])) * oody;
                     vzz =
-                        (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                         b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2])) * oodz;
+                        (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                         b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) * oodz;
 
                     h1 = (j - nb->ny2 + gv->FW);
 
@@ -493,32 +493,32 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity *vel,
                 #pragma omp simd
                 for (int k = 1; k <= gv->FW; k++) {
                     vxx =
-                        (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                         b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k])) * oodx;
+                        (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                         b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k])) * oodx;
                     vxy =
-                        (b1 * (vel->vx[j + 1][i][k] - vel->vx[j][i][k]) +
-                         b2 * (vel->vx[j + 2][i][k] - vel->vx[j - 1][i][k])) * oody;
+                        (b1 * (vel.vx[j + 1, i, k] - vel.vx[j, i, k]) +
+                         b2 * (vel.vx[j + 2, i, k] - vel.vx[j - 1, i, k])) * oody;
                     vxz =
-                        (b1 * (vel->vx[j][i][k + 1] - vel->vx[j][i][k]) +
-                         b2 * (vel->vx[j][i][k + 2] - vel->vx[j][i][k - 1])) * oodz;
+                        (b1 * (vel.vx[j, i, k + 1] - vel.vx[j, i, k]) +
+                         b2 * (vel.vx[j, i, k + 2] - vel.vx[j, i, k - 1])) * oodz;
                     vyx =
-                        (b1 * (vel->vy[j][i + 1][k] - vel->vy[j][i][k]) +
-                         b2 * (vel->vy[j][i + 2][k] - vel->vy[j][i - 1][k])) * oodx;
+                        (b1 * (vel.vy[j, i + 1, k] - vel.vy[j, i, k]) +
+                         b2 * (vel.vy[j, i + 2, k] - vel.vy[j, i - 1, k])) * oodx;
                     vyy =
-                        (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                         b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k])) * oody;
+                        (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                         b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k])) * oody;
                     vyz =
-                        (b1 * (vel->vy[j][i][k + 1] - vel->vy[j][i][k]) +
-                         b2 * (vel->vy[j][i][k + 2] - vel->vy[j][i][k - 1])) * oodz;
+                        (b1 * (vel.vy[j, i, k + 1] - vel.vy[j, i, k]) +
+                         b2 * (vel.vy[j, i, k + 2] - vel.vy[j, i, k - 1])) * oodz;
                     vzx =
-                        (b1 * (vel->vz[j][i + 1][k] - vel->vz[j][i][k]) +
-                         b2 * (vel->vz[j][i + 2][k] - vel->vz[j][i - 1][k])) * oodx;
+                        (b1 * (vel.vz[j, i + 1, k] - vel.vz[j, i, k]) +
+                         b2 * (vel.vz[j, i + 2, k] - vel.vz[j, i - 1, k])) * oodx;
                     vzy =
-                        (b1 * (vel->vz[j + 1][i][k] - vel->vz[j][i][k]) +
-                         b2 * (vel->vz[j + 2][i][k] - vel->vz[j - 1][i][k])) * oody;
+                        (b1 * (vel.vz[j + 1, i, k] - vel.vz[j, i, k]) +
+                         b2 * (vel.vz[j + 2, i, k] - vel.vz[j - 1, i, k])) * oody;
                     vzz =
-                        (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                         b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2])) * oodz;
+                        (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                         b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) * oodz;
 
                     pml_wfd->psi_vxz[j][i][k] =
                         pml_coeff->b_z_half[k] * pml_wfd->psi_vxz[j][i][k] + pml_coeff->a_z_half[k] * vxz;
@@ -560,32 +560,32 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity *vel,
                 #pragma omp simd
                 for (int k = nb->nz2 + 1; k <= nb->nz2 + gv->FW; k++) {
                     vxx =
-                        (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                         b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k])) * oodx;
+                        (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                         b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k])) * oodx;
                     vxy =
-                        (b1 * (vel->vx[j + 1][i][k] - vel->vx[j][i][k]) +
-                         b2 * (vel->vx[j + 2][i][k] - vel->vx[j - 1][i][k])) * oody;
+                        (b1 * (vel.vx[j + 1, i, k] - vel.vx[j, i, k]) +
+                         b2 * (vel.vx[j + 2, i, k] - vel.vx[j - 1, i, k])) * oody;
                     vxz =
-                        (b1 * (vel->vx[j][i][k + 1] - vel->vx[j][i][k]) +
-                         b2 * (vel->vx[j][i][k + 2] - vel->vx[j][i][k - 1])) * oodz;
+                        (b1 * (vel.vx[j, i, k + 1] - vel.vx[j, i, k]) +
+                         b2 * (vel.vx[j, i, k + 2] - vel.vx[j, i, k - 1])) * oodz;
                     vyx =
-                        (b1 * (vel->vy[j][i + 1][k] - vel->vy[j][i][k]) +
-                         b2 * (vel->vy[j][i + 2][k] - vel->vy[j][i - 1][k])) * oodx;
+                        (b1 * (vel.vy[j, i + 1, k] - vel.vy[j, i, k]) +
+                         b2 * (vel.vy[j, i + 2, k] - vel.vy[j, i - 1, k])) * oodx;
                     vyy =
-                        (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                         b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k])) * oody;
+                        (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                         b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k])) * oody;
                     vyz =
-                        (b1 * (vel->vy[j][i][k + 1] - vel->vy[j][i][k]) +
-                         b2 * (vel->vy[j][i][k + 2] - vel->vy[j][i][k - 1])) * oodz;
+                        (b1 * (vel.vy[j, i, k + 1] - vel.vy[j, i, k]) +
+                         b2 * (vel.vy[j, i, k + 2] - vel.vy[j, i, k - 1])) * oodz;
                     vzx =
-                        (b1 * (vel->vz[j][i + 1][k] - vel->vz[j][i][k]) +
-                         b2 * (vel->vz[j][i + 2][k] - vel->vz[j][i - 1][k])) * oodx;
+                        (b1 * (vel.vz[j, i + 1, k] - vel.vz[j, i, k]) +
+                         b2 * (vel.vz[j, i + 2, k] - vel.vz[j, i - 1, k])) * oodx;
                     vzy =
-                        (b1 * (vel->vz[j + 1][i][k] - vel->vz[j][i][k]) +
-                         b2 * (vel->vz[j + 2][i][k] - vel->vz[j - 1][i][k])) * oody;
+                        (b1 * (vel.vz[j + 1, i, k] - vel.vz[j, i, k]) +
+                         b2 * (vel.vz[j + 2, i, k] - vel.vz[j - 1, i, k])) * oody;
                     vzz =
-                        (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                         b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2])) * oodz;
+                        (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                         b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) * oodz;
 
                     h1 = (k - nb->nz2 + gv->FW);
 
diff --git a/src/update_s_ssg_acoustic.cpp b/src/update_s_ssg_acoustic.cpp
index b7528d0..3949182 100644
--- a/src/update_s_ssg_acoustic.cpp
+++ b/src/update_s_ssg_acoustic.cpp
@@ -27,7 +27,7 @@
 
 #define UNUSED(x) (void)(x)
 
-double update_s_acoustic(st_boundary *nb, st_velocity *vel,
+double update_s_acoustic(st_boundary *nb, st_velocity &vel,
                          st_stress *stress, st_model *mod, const GlobVar *gv)
 {
     float vxx, vyy, vzz;
@@ -46,9 +46,9 @@ double update_s_acoustic(st_boundary *nb, st_velocity *vel,
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    float vxx = (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) * oodx;
-                    float vyy = (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) * oody;
-                    float vzz = (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) * oodz;
+                    float vxx = (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) * oodx;
+                    float vyy = (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) * oody;
+                    float vzz = (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) * oodz;
                     stress->sp[j][i][k] += gv->DT * mod->pi[j][i][k] * (vxx + vyy + vzz);
                 }
             }
@@ -68,14 +68,14 @@ double update_s_acoustic(st_boundary *nb, st_velocity *vel,
                 #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
                     float vxx =
-                        (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                         b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k])) * oodx;
+                        (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                         b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k])) * oodx;
                     float vyy =
-                        (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                         b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k])) * oody;
+                        (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                         b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k])) * oody;
                     float vzz =
-                        (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                         b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2])) * oodz;
+                        (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                         b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) * oodz;
                     stress->sp[j][i][k] += gv->DT * mod->pi[j][i][k] * (vxx + vyy + vzz);
                 }
             }
@@ -100,17 +100,17 @@ double update_s_acoustic(st_boundary *nb, st_velocity *vel,
                     /* spatial derivatives of the components of the velocities
                      * are computed */
 
-                    vxx = (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                           b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k]) +
-                           b3 * (vel->vx[j][i + 2][k] - vel->vx[j][i - 3][k])) * oodx;
+                    vxx = (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                           b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k]) +
+                           b3 * (vel.vx[j, i + 2, k] - vel.vx[j, i - 3, k])) * oodx;
 
-                    vyy = (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                           b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k]) +
-                           b3 * (vel->vy[j + 2][i][k] - vel->vy[j - 3][i][k])) * oody;
+                    vyy = (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                           b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k]) +
+                           b3 * (vel.vy[j + 2, i, k] - vel.vy[j - 3, i, k])) * oody;
 
-                    vzz = (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                           b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2]) +
-                           b3 * (vel->vz[j][i][k + 2] - vel->vz[j][i][k - 3])) * oodz;
+                    vzz = (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                           b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2]) +
+                           b3 * (vel.vz[j, i, k + 2] - vel.vz[j, i, k - 3])) * oodz;
 
                     g = mod->pi[j][i][k];
 
@@ -143,20 +143,20 @@ double update_s_acoustic(st_boundary *nb, st_velocity *vel,
                     /* spatial derivatives of the components of the velocities
                      * are computed */
 
-                    vxx = (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                           b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k]) +
-                           b3 * (vel->vx[j][i + 2][k] - vel->vx[j][i - 3][k]) +
-                           b4 * (vel->vx[j][i + 3][k] - vel->vx[j][i - 4][k])) * oodx;
+                    vxx = (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                           b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k]) +
+                           b3 * (vel.vx[j, i + 2, k] - vel.vx[j, i - 3, k]) +
+                           b4 * (vel.vx[j, i + 3, k] - vel.vx[j, i - 4, k])) * oodx;
 
-                    vyy = (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                           b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k]) +
-                           b3 * (vel->vy[j + 2][i][k] - vel->vy[j - 3][i][k]) +
-                           b4 * (vel->vy[j + 3][i][k] - vel->vy[j - 4][i][k])) * oody;
+                    vyy = (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                           b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k]) +
+                           b3 * (vel.vy[j + 2, i, k] - vel.vy[j - 3, i, k]) +
+                           b4 * (vel.vy[j + 3, i, k] - vel.vy[j - 4, i, k])) * oody;
 
-                    vzz = (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                           b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2]) +
-                           b3 * (vel->vz[j][i][k + 2] - vel->vz[j][i][k - 3]) +
-                           b4 * (vel->vz[j][i][k + 3] - vel->vz[j][i][k - 4])) * oodz;
+                    vzz = (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                           b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2]) +
+                           b3 * (vel.vz[j, i, k + 2] - vel.vz[j, i, k - 3]) +
+                           b4 * (vel.vz[j, i, k + 3] - vel.vz[j, i, k - 4])) * oodz;
 
                     /* updating components of the stress tensor, partially */
                     g = mod->pi[j][i][k];
@@ -191,23 +191,23 @@ double update_s_acoustic(st_boundary *nb, st_velocity *vel,
                     /* spatial derivatives of the components of the velocities
                      * are computed */
 
-                    vxx = (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                           b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k]) +
-                           b3 * (vel->vx[j][i + 2][k] - vel->vx[j][i - 3][k]) +
-                           b4 * (vel->vx[j][i + 3][k] - vel->vx[j][i - 4][k]) +
-                           b5 * (vel->vx[j][i + 4][k] - vel->vx[j][i - 5][k])) * oodx;
+                    vxx = (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                           b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k]) +
+                           b3 * (vel.vx[j, i + 2, k] - vel.vx[j, i - 3, k]) +
+                           b4 * (vel.vx[j, i + 3, k] - vel.vx[j, i - 4, k]) +
+                           b5 * (vel.vx[j, i + 4, k] - vel.vx[j, i - 5, k])) * oodx;
 
-                    vyy = (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                           b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k]) +
-                           b3 * (vel->vy[j + 2][i][k] - vel->vy[j - 3][i][k]) +
-                           b4 * (vel->vy[j + 3][i][k] - vel->vy[j - 4][i][k]) +
-                           b5 * (vel->vy[j + 4][i][k] - vel->vy[j - 5][i][k])) * oody;
+                    vyy = (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                           b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k]) +
+                           b3 * (vel.vy[j + 2, i, k] - vel.vy[j - 3, i, k]) +
+                           b4 * (vel.vy[j + 3, i, k] - vel.vy[j - 4, i, k]) +
+                           b5 * (vel.vy[j + 4, i, k] - vel.vy[j - 5, i, k])) * oody;
 
-                    vzz = (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                           b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2]) +
-                           b3 * (vel->vz[j][i][k + 2] - vel->vz[j][i][k - 3]) +
-                           b4 * (vel->vz[j][i][k + 3] - vel->vz[j][i][k - 4]) +
-                           b5 * (vel->vz[j][i][k + 4] - vel->vz[j][i][k - 5])) * oodz;
+                    vzz = (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                           b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2]) +
+                           b3 * (vel.vz[j, i, k + 2] - vel.vz[j, i, k - 3]) +
+                           b4 * (vel.vz[j, i, k + 3] - vel.vz[j, i, k - 4]) +
+                           b5 * (vel.vz[j, i, k + 4] - vel.vz[j, i, k - 5])) * oodz;
 
                     g = mod->pi[j][i][k];
 
@@ -247,26 +247,26 @@ double update_s_acoustic(st_boundary *nb, st_velocity *vel,
                     /* spatial derivatives of the components of the velocities
                      * are computed */
 
-                    vxx = (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                           b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k]) +
-                           b3 * (vel->vx[j][i + 2][k] - vel->vx[j][i - 3][k]) +
-                           b4 * (vel->vx[j][i + 3][k] - vel->vx[j][i - 4][k]) +
-                           b5 * (vel->vx[j][i + 4][k] - vel->vx[j][i - 5][k]) +
-                           b6 * (vel->vx[j][i + 5][k] - vel->vx[j][i - 6][k])) * oodx;
-
-                    vyy = (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                           b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k]) +
-                           b3 * (vel->vy[j + 2][i][k] - vel->vy[j - 3][i][k]) +
-                           b4 * (vel->vy[j + 3][i][k] - vel->vy[j - 4][i][k]) +
-                           b5 * (vel->vy[j + 4][i][k] - vel->vy[j - 5][i][k]) +
-                           b6 * (vel->vy[j + 5][i][k] - vel->vy[j - 6][i][k])) * oody;
-
-                    vzz = (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                           b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2]) +
-                           b3 * (vel->vz[j][i][k + 2] - vel->vz[j][i][k - 3]) +
-                           b4 * (vel->vz[j][i][k + 3] - vel->vz[j][i][k - 4]) +
-                           b5 * (vel->vz[j][i][k + 4] - vel->vz[j][i][k - 5]) +
-                           b6 * (vel->vz[j][i][k + 5] - vel->vz[j][i][k - 6])) * oodz;
+                    vxx = (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                           b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k]) +
+                           b3 * (vel.vx[j, i + 2, k] - vel.vx[j, i - 3, k]) +
+                           b4 * (vel.vx[j, i + 3, k] - vel.vx[j, i - 4, k]) +
+                           b5 * (vel.vx[j, i + 4, k] - vel.vx[j, i - 5, k]) +
+                           b6 * (vel.vx[j, i + 5, k] - vel.vx[j, i - 6, k])) * oodx;
+
+                    vyy = (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                           b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k]) +
+                           b3 * (vel.vy[j + 2, i, k] - vel.vy[j - 3, i, k]) +
+                           b4 * (vel.vy[j + 3, i, k] - vel.vy[j - 4, i, k]) +
+                           b5 * (vel.vy[j + 4, i, k] - vel.vy[j - 5, i, k]) +
+                           b6 * (vel.vy[j + 5, i, k] - vel.vy[j - 6, i, k])) * oody;
+
+                    vzz = (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                           b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2]) +
+                           b3 * (vel.vz[j, i, k + 2] - vel.vz[j, i, k - 3]) +
+                           b4 * (vel.vz[j, i, k + 3] - vel.vz[j, i, k - 4]) +
+                           b5 * (vel.vz[j, i, k + 4] - vel.vz[j, i, k - 5]) +
+                           b6 * (vel.vz[j, i, k + 5] - vel.vz[j, i, k - 6])) * oodz;
 
                     g = mod->pi[j][i][k];
 
diff --git a/src/update_s_ssg_elastic.cpp b/src/update_s_ssg_elastic.cpp
index 0728b8d..1ef7b99 100644
--- a/src/update_s_ssg_elastic.cpp
+++ b/src/update_s_ssg_elastic.cpp
@@ -28,7 +28,7 @@
 
 #define UNUSED(x) (void)(x)
 
-double update_s_elastic(st_boundary *nb, st_velocity *vel,
+double update_s_elastic(st_boundary *nb, st_velocity &vel,
                         st_stress *stress, st_model *mod, st_model_av *mod_av, const GlobVar *gv)
 {
     float vxx, vxy, vxz, vyx, vyy, vyz, vzx, vzy, vzz;
@@ -49,21 +49,21 @@ double update_s_elastic(st_boundary *nb, st_velocity *vel,
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    vxy = (vel->vx[j + 1][i][k] - vel->vx[j][i][k]) * oody;
-                    vyx = (vel->vy[j][i + 1][k] - vel->vy[j][i][k]) * oodx;
+                    vxy = (vel.vx[j + 1, i, k] - vel.vx[j, i, k]) * oody;
+                    vyx = (vel.vy[j, i + 1, k] - vel.vy[j, i, k]) * oodx;
                     stress->sxy[j][i][k] += mod_av->uipjp[j][i][k] * gv->DT * (vxy + vyx);
 
-                    vyz = (vel->vy[j][i][k + 1] - vel->vy[j][i][k]) * oodz;
-                    vzy = (vel->vz[j + 1][i][k] - vel->vz[j][i][k]) * oody;
+                    vyz = (vel.vy[j, i, k + 1] - vel.vy[j, i, k]) * oodz;
+                    vzy = (vel.vz[j + 1, i, k] - vel.vz[j, i, k]) * oody;
                     stress->syz[j][i][k] += mod_av->ujpkp[j][i][k] * gv->DT * (vyz + vzy);
 
-                    vxz = (vel->vx[j][i][k + 1] - vel->vx[j][i][k]) * oodz;
-                    vzx = (vel->vz[j][i + 1][k] - vel->vz[j][i][k]) * oodx;
+                    vxz = (vel.vx[j, i, k + 1] - vel.vx[j, i, k]) * oodz;
+                    vzx = (vel.vz[j, i + 1, k] - vel.vz[j, i, k]) * oodx;
                     stress->sxz[j][i][k] += mod_av->uipkp[j][i][k] * gv->DT * (vxz + vzx);
 
-                    vxx = (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) * oodx;
-                    vyy = (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) * oody;
-                    vzz = (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) * oodz;
+                    vxx = (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) * oodx;
+                    vyy = (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) * oody;
+                    vzz = (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) * oodz;
                     stress->sxx[j][i][k] += gv->DT *
                                             (mod->pi[j][i][k] * (vxx + vyy + vzz) - 2.0f * mod->u[j][i][k] *
                                              (vyy + vzz));
@@ -109,38 +109,38 @@ double update_s_elastic(st_boundary *nb, st_velocity *vel,
                 #pragma omp simd nontemporal(sxy_j_i, syz_j_i, sxz_j_i, sxx_j_i, syy_j_i, szz_j_i)
                 for (int k = k_start; k <= k_end; k++) {
                     vxy =
-                        (b1 * (vel->vx[j + 1][i][k] - vel->vx[j][i][k]) +
-                         b2 * (vel->vx[j + 2][i][k] - vel->vx[j - 1][i][k])) * oody;
+                        (b1 * (vel.vx[j + 1, i, k] - vel.vx[j, i, k]) +
+                         b2 * (vel.vx[j + 2, i, k] - vel.vx[j - 1, i, k])) * oody;
                     vyx =
-                        (b1 * (vel->vy[j][i + 1][k] - vel->vy[j][i][k]) +
-                         b2 * (vel->vy[j][i + 2][k] - vel->vy[j][i - 1][k])) * oodx;
+                        (b1 * (vel.vy[j, i + 1, k] - vel.vy[j, i, k]) +
+                         b2 * (vel.vy[j, i + 2, k] - vel.vy[j, i - 1, k])) * oodx;
                     sxy_j_i[k] += mod_av->uipjp[j][i][k] * gv->DT * (vxy + vyx);
 
                     vyz =
-                        (b1 * (vel->vy[j][i][k + 1] - vel->vy[j][i][k]) +
-                         b2 * (vel->vy[j][i][k + 2] - vel->vy[j][i][k - 1])) * oodz;
+                        (b1 * (vel.vy[j, i, k + 1] - vel.vy[j, i, k]) +
+                         b2 * (vel.vy[j, i, k + 2] - vel.vy[j, i, k - 1])) * oodz;
                     vzy =
-                        (b1 * (vel->vz[j + 1][i][k] - vel->vz[j][i][k]) +
-                         b2 * (vel->vz[j + 2][i][k] - vel->vz[j - 1][i][k])) * oody;
+                        (b1 * (vel.vz[j + 1, i, k] - vel.vz[j, i, k]) +
+                         b2 * (vel.vz[j + 2, i, k] - vel.vz[j - 1, i, k])) * oody;
                     syz_j_i[k] += mod_av->ujpkp[j][i][k] * gv->DT * (vyz + vzy);
 
                     vxz =
-                        (b1 * (vel->vx[j][i][k + 1] - vel->vx[j][i][k]) +
-                         b2 * (vel->vx[j][i][k + 2] - vel->vx[j][i][k - 1])) * oodz;
+                        (b1 * (vel.vx[j, i, k + 1] - vel.vx[j, i, k]) +
+                         b2 * (vel.vx[j, i, k + 2] - vel.vx[j, i, k - 1])) * oodz;
                     vzx =
-                        (b1 * (vel->vz[j][i + 1][k] - vel->vz[j][i][k]) +
-                         b2 * (vel->vz[j][i + 2][k] - vel->vz[j][i - 1][k])) * oodx;
+                        (b1 * (vel.vz[j, i + 1, k] - vel.vz[j, i, k]) +
+                         b2 * (vel.vz[j, i + 2, k] - vel.vz[j, i - 1, k])) * oodx;
                     sxz_j_i[k] += mod_av->uipkp[j][i][k] * gv->DT * (vxz + vzx);
 
                     vxx =
-                        (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                         b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k])) * oodx;
+                        (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                         b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k])) * oodx;
                     vyy =
-                        (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                         b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k])) * oody;
+                        (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                         b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k])) * oody;
                     vzz =
-                        (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                         b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2])) * oodz;
+                        (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                         b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) * oodz;
                     sxx_j_i[k] += gv->DT *
                                   (mod->pi[j][i][k] * (vxx + vyy + vzz) - 2.0f * mod->u[j][i][k] * (vyy + vzz));
                     syy_j_i[k] += gv->DT *
@@ -171,41 +171,41 @@ double update_s_elastic(st_boundary *nb, st_velocity *vel,
                     /* spatial derivatives of the components of the velocities
                      * are computed */
 
-                    vxx = (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                           b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k]) +
-                           b3 * (vel->vx[j][i + 2][k] - vel->vx[j][i - 3][k])) * oodx;
+                    vxx = (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                           b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k]) +
+                           b3 * (vel.vx[j, i + 2, k] - vel.vx[j, i - 3, k])) * oodx;
 
-                    vxy = (b1 * (vel->vx[j + 1][i][k] - vel->vx[j][i][k]) +
-                           b2 * (vel->vx[j + 2][i][k] - vel->vx[j - 1][i][k]) +
-                           b3 * (vel->vx[j + 3][i][k] - vel->vx[j - 2][i][k])) * oody;
+                    vxy = (b1 * (vel.vx[j + 1, i, k] - vel.vx[j, i, k]) +
+                           b2 * (vel.vx[j + 2, i, k] - vel.vx[j - 1, i, k]) +
+                           b3 * (vel.vx[j + 3, i, k] - vel.vx[j - 2, i, k])) * oody;
 
-                    vxz = (b1 * (vel->vx[j][i][k + 1] - vel->vx[j][i][k]) +
-                           b2 * (vel->vx[j][i][k + 2] - vel->vx[j][i][k - 1]) +
-                           b3 * (vel->vx[j][i][k + 3] - vel->vx[j][i][k - 2])) * oodz;
+                    vxz = (b1 * (vel.vx[j, i, k + 1] - vel.vx[j, i, k]) +
+                           b2 * (vel.vx[j, i, k + 2] - vel.vx[j, i, k - 1]) +
+                           b3 * (vel.vx[j, i, k + 3] - vel.vx[j, i, k - 2])) * oodz;
 
-                    vyx = (b1 * (vel->vy[j][i + 1][k] - vel->vy[j][i][k]) +
-                           b2 * (vel->vy[j][i + 2][k] - vel->vy[j][i - 1][k]) +
-                           b3 * (vel->vy[j][i + 3][k] - vel->vy[j][i - 2][k])) * oodx;
+                    vyx = (b1 * (vel.vy[j, i + 1, k] - vel.vy[j, i, k]) +
+                           b2 * (vel.vy[j, i + 2, k] - vel.vy[j, i - 1, k]) +
+                           b3 * (vel.vy[j, i + 3, k] - vel.vy[j, i - 2, k])) * oodx;
 
-                    vyy = (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                           b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k]) +
-                           b3 * (vel->vy[j + 2][i][k] - vel->vy[j - 3][i][k])) * oody;
+                    vyy = (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                           b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k]) +
+                           b3 * (vel.vy[j + 2, i, k] - vel.vy[j - 3, i, k])) * oody;
 
-                    vyz = (b1 * (vel->vy[j][i][k + 1] - vel->vy[j][i][k]) +
-                           b2 * (vel->vy[j][i][k + 2] - vel->vy[j][i][k - 1]) +
-                           b3 * (vel->vy[j][i][k + 3] - vel->vy[j][i][k - 2])) * oodz;
+                    vyz = (b1 * (vel.vy[j, i, k + 1] - vel.vy[j, i, k]) +
+                           b2 * (vel.vy[j, i, k + 2] - vel.vy[j, i, k - 1]) +
+                           b3 * (vel.vy[j, i, k + 3] - vel.vy[j, i, k - 2])) * oodz;
 
-                    vzx = (b1 * (vel->vz[j][i + 1][k] - vel->vz[j][i][k]) +
-                           b2 * (vel->vz[j][i + 2][k] - vel->vz[j][i - 1][k]) +
-                           b3 * (vel->vz[j][i + 3][k] - vel->vz[j][i - 2][k])) * oodx;
+                    vzx = (b1 * (vel.vz[j, i + 1, k] - vel.vz[j, i, k]) +
+                           b2 * (vel.vz[j, i + 2, k] - vel.vz[j, i - 1, k]) +
+                           b3 * (vel.vz[j, i + 3, k] - vel.vz[j, i - 2, k])) * oodx;
 
-                    vzy = (b1 * (vel->vz[j + 1][i][k] - vel->vz[j][i][k]) +
-                           b2 * (vel->vz[j + 2][i][k] - vel->vz[j - 1][i][k]) +
-                           b3 * (vel->vz[j + 3][i][k] - vel->vz[j - 2][i][k])) * oody;
+                    vzy = (b1 * (vel.vz[j + 1, i, k] - vel.vz[j, i, k]) +
+                           b2 * (vel.vz[j + 2, i, k] - vel.vz[j - 1, i, k]) +
+                           b3 * (vel.vz[j + 3, i, k] - vel.vz[j - 2, i, k])) * oody;
 
-                    vzz = (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                           b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2]) +
-                           b3 * (vel->vz[j][i][k + 2] - vel->vz[j][i][k - 3])) * oodz;
+                    vzz = (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                           b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2]) +
+                           b3 * (vel.vz[j, i, k + 2] - vel.vz[j, i, k - 3])) * oodz;
 
                     fipjp = mod_av->uipjp[j][i][k] * gv->DT;
                     fjpkp = mod_av->ujpkp[j][i][k] * gv->DT;
@@ -252,50 +252,50 @@ double update_s_elastic(st_boundary *nb, st_velocity *vel,
                     /* spatial derivatives of the components of the velocities
                      * are computed */
 
-                    vxx = (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                           b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k]) +
-                           b3 * (vel->vx[j][i + 2][k] - vel->vx[j][i - 3][k]) +
-                           b4 * (vel->vx[j][i + 3][k] - vel->vx[j][i - 4][k])) * oodx;
-
-                    vxy = (b1 * (vel->vx[j + 1][i][k] - vel->vx[j][i][k]) +
-                           b2 * (vel->vx[j + 2][i][k] - vel->vx[j - 1][i][k]) +
-                           b3 * (vel->vx[j + 3][i][k] - vel->vx[j - 2][i][k]) +
-                           b4 * (vel->vx[j + 4][i][k] - vel->vx[j - 3][i][k])) * oody;
-
-                    vxz = (b1 * (vel->vx[j][i][k + 1] - vel->vx[j][i][k]) +
-                           b2 * (vel->vx[j][i][k + 2] - vel->vx[j][i][k - 1]) +
-                           b3 * (vel->vx[j][i][k + 3] - vel->vx[j][i][k - 2]) +
-                           b4 * (vel->vx[j][i][k + 4] - vel->vx[j][i][k - 3])) * oodz;
-
-                    vyx = (b1 * (vel->vy[j][i + 1][k] - vel->vy[j][i][k]) +
-                           b2 * (vel->vy[j][i + 2][k] - vel->vy[j][i - 1][k]) +
-                           b3 * (vel->vy[j][i + 3][k] - vel->vy[j][i - 2][k]) +
-                           b4 * (vel->vy[j][i + 4][k] - vel->vy[j][i - 3][k])) * oodx;
-
-                    vyy = (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                           b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k]) +
-                           b3 * (vel->vy[j + 2][i][k] - vel->vy[j - 3][i][k]) +
-                           b4 * (vel->vy[j + 3][i][k] - vel->vy[j - 4][i][k])) * oody;
-
-                    vyz = (b1 * (vel->vy[j][i][k + 1] - vel->vy[j][i][k]) +
-                           b2 * (vel->vy[j][i][k + 2] - vel->vy[j][i][k - 1]) +
-                           b3 * (vel->vy[j][i][k + 3] - vel->vy[j][i][k - 2]) +
-                           b4 * (vel->vy[j][i][k + 4] - vel->vy[j][i][k - 3])) * oodz;
-
-                    vzx = (b1 * (vel->vz[j][i + 1][k] - vel->vz[j][i][k]) +
-                           b2 * (vel->vz[j][i + 2][k] - vel->vz[j][i - 1][k]) +
-                           b3 * (vel->vz[j][i + 3][k] - vel->vz[j][i - 2][k]) +
-                           b4 * (vel->vz[j][i + 4][k] - vel->vz[j][i - 3][k])) * oodx;
-
-                    vzy = (b1 * (vel->vz[j + 1][i][k] - vel->vz[j][i][k]) +
-                           b2 * (vel->vz[j + 2][i][k] - vel->vz[j - 1][i][k]) +
-                           b3 * (vel->vz[j + 3][i][k] - vel->vz[j - 2][i][k]) +
-                           b4 * (vel->vz[j + 4][i][k] - vel->vz[j - 3][i][k])) * oody;
-
-                    vzz = (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                           b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2]) +
-                           b3 * (vel->vz[j][i][k + 2] - vel->vz[j][i][k - 3]) +
-                           b4 * (vel->vz[j][i][k + 3] - vel->vz[j][i][k - 4])) * oodz;
+                    vxx = (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                           b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k]) +
+                           b3 * (vel.vx[j, i + 2, k] - vel.vx[j, i - 3, k]) +
+                           b4 * (vel.vx[j, i + 3, k] - vel.vx[j, i - 4, k])) * oodx;
+
+                    vxy = (b1 * (vel.vx[j + 1, i, k] - vel.vx[j, i, k]) +
+                           b2 * (vel.vx[j + 2, i, k] - vel.vx[j - 1, i, k]) +
+                           b3 * (vel.vx[j + 3, i, k] - vel.vx[j - 2, i, k]) +
+                           b4 * (vel.vx[j + 4, i, k] - vel.vx[j - 3, i, k])) * oody;
+
+                    vxz = (b1 * (vel.vx[j, i, k + 1] - vel.vx[j, i, k]) +
+                           b2 * (vel.vx[j, i, k + 2] - vel.vx[j, i, k - 1]) +
+                           b3 * (vel.vx[j, i, k + 3] - vel.vx[j, i, k - 2]) +
+                           b4 * (vel.vx[j, i, k + 4] - vel.vx[j, i, k - 3])) * oodz;
+
+                    vyx = (b1 * (vel.vy[j, i + 1, k] - vel.vy[j, i, k]) +
+                           b2 * (vel.vy[j, i + 2, k] - vel.vy[j, i - 1, k]) +
+                           b3 * (vel.vy[j, i + 3, k] - vel.vy[j, i - 2, k]) +
+                           b4 * (vel.vy[j, i + 4, k] - vel.vy[j, i - 3, k])) * oodx;
+
+                    vyy = (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                           b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k]) +
+                           b3 * (vel.vy[j + 2, i, k] - vel.vy[j - 3, i, k]) +
+                           b4 * (vel.vy[j + 3, i, k] - vel.vy[j - 4, i, k])) * oody;
+
+                    vyz = (b1 * (vel.vy[j, i, k + 1] - vel.vy[j, i, k]) +
+                           b2 * (vel.vy[j, i, k + 2] - vel.vy[j, i, k - 1]) +
+                           b3 * (vel.vy[j, i, k + 3] - vel.vy[j, i, k - 2]) +
+                           b4 * (vel.vy[j, i, k + 4] - vel.vy[j, i, k - 3])) * oodz;
+
+                    vzx = (b1 * (vel.vz[j, i + 1, k] - vel.vz[j, i, k]) +
+                           b2 * (vel.vz[j, i + 2, k] - vel.vz[j, i - 1, k]) +
+                           b3 * (vel.vz[j, i + 3, k] - vel.vz[j, i - 2, k]) +
+                           b4 * (vel.vz[j, i + 4, k] - vel.vz[j, i - 3, k])) * oodx;
+
+                    vzy = (b1 * (vel.vz[j + 1, i, k] - vel.vz[j, i, k]) +
+                           b2 * (vel.vz[j + 2, i, k] - vel.vz[j - 1, i, k]) +
+                           b3 * (vel.vz[j + 3, i, k] - vel.vz[j - 2, i, k]) +
+                           b4 * (vel.vz[j + 4, i, k] - vel.vz[j - 3, i, k])) * oody;
+
+                    vzz = (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                           b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2]) +
+                           b3 * (vel.vz[j, i, k + 2] - vel.vz[j, i, k - 3]) +
+                           b4 * (vel.vz[j, i, k + 3] - vel.vz[j, i, k - 4])) * oodz;
 
                     /* updating components of the stress tensor, partially */
                     fipjp = mod_av->uipjp[j][i][k] * gv->DT;
@@ -345,59 +345,59 @@ double update_s_elastic(st_boundary *nb, st_velocity *vel,
                     /* spatial derivatives of the components of the velocities
                      * are computed */
 
-                    vxx = (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                           b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k]) +
-                           b3 * (vel->vx[j][i + 2][k] - vel->vx[j][i - 3][k]) +
-                           b4 * (vel->vx[j][i + 3][k] - vel->vx[j][i - 4][k]) +
-                           b5 * (vel->vx[j][i + 4][k] - vel->vx[j][i - 5][k])) * oodx;
-
-                    vxy = (b1 * (vel->vx[j + 1][i][k] - vel->vx[j][i][k]) +
-                           b2 * (vel->vx[j + 2][i][k] - vel->vx[j - 1][i][k]) +
-                           b3 * (vel->vx[j + 3][i][k] - vel->vx[j - 2][i][k]) +
-                           b4 * (vel->vx[j + 4][i][k] - vel->vx[j - 3][i][k]) +
-                           b5 * (vel->vx[j + 5][i][k] - vel->vx[j - 4][i][k])) * oody;
-
-                    vxz = (b1 * (vel->vx[j][i][k + 1] - vel->vx[j][i][k]) +
-                           b2 * (vel->vx[j][i][k + 2] - vel->vx[j][i][k - 1]) +
-                           b3 * (vel->vx[j][i][k + 3] - vel->vx[j][i][k - 2]) +
-                           b4 * (vel->vx[j][i][k + 4] - vel->vx[j][i][k - 3]) +
-                           b5 * (vel->vx[j][i][k + 5] - vel->vx[j][i][k - 4])) * oodz;
-
-                    vyx = (b1 * (vel->vy[j][i + 1][k] - vel->vy[j][i][k]) +
-                           b2 * (vel->vy[j][i + 2][k] - vel->vy[j][i - 1][k]) +
-                           b3 * (vel->vy[j][i + 3][k] - vel->vy[j][i - 2][k]) +
-                           b4 * (vel->vy[j][i + 4][k] - vel->vy[j][i - 3][k]) +
-                           b5 * (vel->vy[j][i + 5][k] - vel->vy[j][i - 4][k])) * oodx;
-
-                    vyy = (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                           b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k]) +
-                           b3 * (vel->vy[j + 2][i][k] - vel->vy[j - 3][i][k]) +
-                           b4 * (vel->vy[j + 3][i][k] - vel->vy[j - 4][i][k]) +
-                           b5 * (vel->vy[j + 4][i][k] - vel->vy[j - 5][i][k])) * oody;
-
-                    vyz = (b1 * (vel->vy[j][i][k + 1] - vel->vy[j][i][k]) +
-                           b2 * (vel->vy[j][i][k + 2] - vel->vy[j][i][k - 1]) +
-                           b3 * (vel->vy[j][i][k + 3] - vel->vy[j][i][k - 2]) +
-                           b4 * (vel->vy[j][i][k + 4] - vel->vy[j][i][k - 3]) +
-                           b5 * (vel->vy[j][i][k + 5] - vel->vy[j][i][k - 4])) * oodz;
-
-                    vzx = (b1 * (vel->vz[j][i + 1][k] - vel->vz[j][i][k]) +
-                           b2 * (vel->vz[j][i + 2][k] - vel->vz[j][i - 1][k]) +
-                           b3 * (vel->vz[j][i + 3][k] - vel->vz[j][i - 2][k]) +
-                           b4 * (vel->vz[j][i + 4][k] - vel->vz[j][i - 3][k]) +
-                           b5 * (vel->vz[j][i + 5][k] - vel->vz[j][i - 4][k])) * oodx;
-
-                    vzy = (b1 * (vel->vz[j + 1][i][k] - vel->vz[j][i][k]) +
-                           b2 * (vel->vz[j + 2][i][k] - vel->vz[j - 1][i][k]) +
-                           b3 * (vel->vz[j + 3][i][k] - vel->vz[j - 2][i][k]) +
-                           b4 * (vel->vz[j + 4][i][k] - vel->vz[j - 3][i][k]) +
-                           b5 * (vel->vz[j + 5][i][k] - vel->vz[j - 4][i][k])) * oody;
-
-                    vzz = (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                           b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2]) +
-                           b3 * (vel->vz[j][i][k + 2] - vel->vz[j][i][k - 3]) +
-                           b4 * (vel->vz[j][i][k + 3] - vel->vz[j][i][k - 4]) +
-                           b5 * (vel->vz[j][i][k + 4] - vel->vz[j][i][k - 5])) * oodz;
+                    vxx = (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                           b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k]) +
+                           b3 * (vel.vx[j, i + 2, k] - vel.vx[j, i - 3, k]) +
+                           b4 * (vel.vx[j, i + 3, k] - vel.vx[j, i - 4, k]) +
+                           b5 * (vel.vx[j, i + 4, k] - vel.vx[j, i - 5, k])) * oodx;
+
+                    vxy = (b1 * (vel.vx[j + 1, i, k] - vel.vx[j, i, k]) +
+                           b2 * (vel.vx[j + 2, i, k] - vel.vx[j - 1, i, k]) +
+                           b3 * (vel.vx[j + 3, i, k] - vel.vx[j - 2, i, k]) +
+                           b4 * (vel.vx[j + 4, i, k] - vel.vx[j - 3, i, k]) +
+                           b5 * (vel.vx[j + 5, i, k] - vel.vx[j - 4, i, k])) * oody;
+
+                    vxz = (b1 * (vel.vx[j, i, k + 1] - vel.vx[j, i, k]) +
+                           b2 * (vel.vx[j, i, k + 2] - vel.vx[j, i, k - 1]) +
+                           b3 * (vel.vx[j, i, k + 3] - vel.vx[j, i, k - 2]) +
+                           b4 * (vel.vx[j, i, k + 4] - vel.vx[j, i, k - 3]) +
+                           b5 * (vel.vx[j, i, k + 5] - vel.vx[j, i, k - 4])) * oodz;
+
+                    vyx = (b1 * (vel.vy[j, i + 1, k] - vel.vy[j, i, k]) +
+                           b2 * (vel.vy[j, i + 2, k] - vel.vy[j, i - 1, k]) +
+                           b3 * (vel.vy[j, i + 3, k] - vel.vy[j, i - 2, k]) +
+                           b4 * (vel.vy[j, i + 4, k] - vel.vy[j, i - 3, k]) +
+                           b5 * (vel.vy[j, i + 5, k] - vel.vy[j, i - 4, k])) * oodx;
+
+                    vyy = (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                           b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k]) +
+                           b3 * (vel.vy[j + 2, i, k] - vel.vy[j - 3, i, k]) +
+                           b4 * (vel.vy[j + 3, i, k] - vel.vy[j - 4, i, k]) +
+                           b5 * (vel.vy[j + 4, i, k] - vel.vy[j - 5, i, k])) * oody;
+
+                    vyz = (b1 * (vel.vy[j, i, k + 1] - vel.vy[j, i, k]) +
+                           b2 * (vel.vy[j, i, k + 2] - vel.vy[j, i, k - 1]) +
+                           b3 * (vel.vy[j, i, k + 3] - vel.vy[j, i, k - 2]) +
+                           b4 * (vel.vy[j, i, k + 4] - vel.vy[j, i, k - 3]) +
+                           b5 * (vel.vy[j, i, k + 5] - vel.vy[j, i, k - 4])) * oodz;
+
+                    vzx = (b1 * (vel.vz[j, i + 1, k] - vel.vz[j, i, k]) +
+                           b2 * (vel.vz[j, i + 2, k] - vel.vz[j, i - 1, k]) +
+                           b3 * (vel.vz[j, i + 3, k] - vel.vz[j, i - 2, k]) +
+                           b4 * (vel.vz[j, i + 4, k] - vel.vz[j, i - 3, k]) +
+                           b5 * (vel.vz[j, i + 5, k] - vel.vz[j, i - 4, k])) * oodx;
+
+                    vzy = (b1 * (vel.vz[j + 1, i, k] - vel.vz[j, i, k]) +
+                           b2 * (vel.vz[j + 2, i, k] - vel.vz[j - 1, i, k]) +
+                           b3 * (vel.vz[j + 3, i, k] - vel.vz[j - 2, i, k]) +
+                           b4 * (vel.vz[j + 4, i, k] - vel.vz[j - 3, i, k]) +
+                           b5 * (vel.vz[j + 5, i, k] - vel.vz[j - 4, i, k])) * oody;
+
+                    vzz = (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                           b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2]) +
+                           b3 * (vel.vz[j, i, k + 2] - vel.vz[j, i, k - 3]) +
+                           b4 * (vel.vz[j, i, k + 3] - vel.vz[j, i, k - 4]) +
+                           b5 * (vel.vz[j, i, k + 4] - vel.vz[j, i, k - 5])) * oodz;
 
                     fipjp = mod_av->uipjp[j][i][k] * gv->DT;
                     fjpkp = mod_av->ujpkp[j][i][k] * gv->DT;
@@ -451,68 +451,68 @@ double update_s_elastic(st_boundary *nb, st_velocity *vel,
                     /* spatial derivatives of the components of the velocities
                      * are computed */
 
-                    vxx = (b1 * (vel->vx[j][i][k] - vel->vx[j][i - 1][k]) +
-                           b2 * (vel->vx[j][i + 1][k] - vel->vx[j][i - 2][k]) +
-                           b3 * (vel->vx[j][i + 2][k] - vel->vx[j][i - 3][k]) +
-                           b4 * (vel->vx[j][i + 3][k] - vel->vx[j][i - 4][k]) +
-                           b5 * (vel->vx[j][i + 4][k] - vel->vx[j][i - 5][k]) +
-                           b6 * (vel->vx[j][i + 5][k] - vel->vx[j][i - 6][k])) * oodx;
-
-                    vxy = (b1 * (vel->vx[j + 1][i][k] - vel->vx[j][i][k]) +
-                           b2 * (vel->vx[j + 2][i][k] - vel->vx[j - 1][i][k]) +
-                           b3 * (vel->vx[j + 3][i][k] - vel->vx[j - 2][i][k]) +
-                           b4 * (vel->vx[j + 4][i][k] - vel->vx[j - 3][i][k]) +
-                           b5 * (vel->vx[j + 5][i][k] - vel->vx[j - 4][i][k]) +
-                           b6 * (vel->vx[j + 6][i][k] - vel->vx[j - 5][i][k])) * oody;
-
-                    vxz = (b1 * (vel->vx[j][i][k + 1] - vel->vx[j][i][k]) +
-                           b2 * (vel->vx[j][i][k + 2] - vel->vx[j][i][k - 1]) +
-                           b3 * (vel->vx[j][i][k + 3] - vel->vx[j][i][k - 2]) +
-                           b4 * (vel->vx[j][i][k + 4] - vel->vx[j][i][k - 3]) +
-                           b5 * (vel->vx[j][i][k + 5] - vel->vx[j][i][k - 4]) +
-                           b6 * (vel->vx[j][i][k + 6] - vel->vx[j][i][k - 5])) * oodz;
-
-                    vyx = (b1 * (vel->vy[j][i + 1][k] - vel->vy[j][i][k]) +
-                           b2 * (vel->vy[j][i + 2][k] - vel->vy[j][i - 1][k]) +
-                           b3 * (vel->vy[j][i + 3][k] - vel->vy[j][i - 2][k]) +
-                           b4 * (vel->vy[j][i + 4][k] - vel->vy[j][i - 3][k]) +
-                           b5 * (vel->vy[j][i + 5][k] - vel->vy[j][i - 4][k]) +
-                           b6 * (vel->vy[j][i + 6][k] - vel->vy[j][i - 5][k])) * oodx;
-
-                    vyy = (b1 * (vel->vy[j][i][k] - vel->vy[j - 1][i][k]) +
-                           b2 * (vel->vy[j + 1][i][k] - vel->vy[j - 2][i][k]) +
-                           b3 * (vel->vy[j + 2][i][k] - vel->vy[j - 3][i][k]) +
-                           b4 * (vel->vy[j + 3][i][k] - vel->vy[j - 4][i][k]) +
-                           b5 * (vel->vy[j + 4][i][k] - vel->vy[j - 5][i][k]) +
-                           b6 * (vel->vy[j + 5][i][k] - vel->vy[j - 6][i][k])) * oody;
-
-                    vyz = (b1 * (vel->vy[j][i][k + 1] - vel->vy[j][i][k]) +
-                           b2 * (vel->vy[j][i][k + 2] - vel->vy[j][i][k - 1]) +
-                           b3 * (vel->vy[j][i][k + 3] - vel->vy[j][i][k - 2]) +
-                           b4 * (vel->vy[j][i][k + 4] - vel->vy[j][i][k - 3]) +
-                           b5 * (vel->vy[j][i][k + 5] - vel->vy[j][i][k - 4]) +
-                           b6 * (vel->vy[j][i][k + 6] - vel->vy[j][i][k - 5])) * oodz;
-
-                    vzx = (b1 * (vel->vz[j][i + 1][k] - vel->vz[j][i][k]) +
-                           b2 * (vel->vz[j][i + 2][k] - vel->vz[j][i - 1][k]) +
-                           b3 * (vel->vz[j][i + 3][k] - vel->vz[j][i - 2][k]) +
-                           b4 * (vel->vz[j][i + 4][k] - vel->vz[j][i - 3][k]) +
-                           b5 * (vel->vz[j][i + 5][k] - vel->vz[j][i - 4][k]) +
-                           b6 * (vel->vz[j][i + 6][k] - vel->vz[j][i - 5][k])) * oodx;
-
-                    vzy = (b1 * (vel->vz[j + 1][i][k] - vel->vz[j][i][k]) +
-                           b2 * (vel->vz[j + 2][i][k] - vel->vz[j - 1][i][k]) +
-                           b3 * (vel->vz[j + 3][i][k] - vel->vz[j - 2][i][k]) +
-                           b4 * (vel->vz[j + 4][i][k] - vel->vz[j - 3][i][k]) +
-                           b5 * (vel->vz[j + 5][i][k] - vel->vz[j - 4][i][k]) +
-                           b6 * (vel->vz[j + 6][i][k] - vel->vz[j - 5][i][k])) * oody;
-
-                    vzz = (b1 * (vel->vz[j][i][k] - vel->vz[j][i][k - 1]) +
-                           b2 * (vel->vz[j][i][k + 1] - vel->vz[j][i][k - 2]) +
-                           b3 * (vel->vz[j][i][k + 2] - vel->vz[j][i][k - 3]) +
-                           b4 * (vel->vz[j][i][k + 3] - vel->vz[j][i][k - 4]) +
-                           b5 * (vel->vz[j][i][k + 4] - vel->vz[j][i][k - 5]) +
-                           b6 * (vel->vz[j][i][k + 5] - vel->vz[j][i][k - 6])) * oodz;
+                    vxx = (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
+                           b2 * (vel.vx[j, i + 1, k] - vel.vx[j, i - 2, k]) +
+                           b3 * (vel.vx[j, i + 2, k] - vel.vx[j, i - 3, k]) +
+                           b4 * (vel.vx[j, i + 3, k] - vel.vx[j, i - 4, k]) +
+                           b5 * (vel.vx[j, i + 4, k] - vel.vx[j, i - 5, k]) +
+                           b6 * (vel.vx[j, i + 5, k] - vel.vx[j, i - 6, k])) * oodx;
+
+                    vxy = (b1 * (vel.vx[j + 1, i, k] - vel.vx[j, i, k]) +
+                           b2 * (vel.vx[j + 2, i, k] - vel.vx[j - 1, i, k]) +
+                           b3 * (vel.vx[j + 3, i, k] - vel.vx[j - 2, i, k]) +
+                           b4 * (vel.vx[j + 4, i, k] - vel.vx[j - 3, i, k]) +
+                           b5 * (vel.vx[j + 5, i, k] - vel.vx[j - 4, i, k]) +
+                           b6 * (vel.vx[j + 6, i, k] - vel.vx[j - 5, i, k])) * oody;
+
+                    vxz = (b1 * (vel.vx[j, i, k + 1] - vel.vx[j, i, k]) +
+                           b2 * (vel.vx[j, i, k + 2] - vel.vx[j, i, k - 1]) +
+                           b3 * (vel.vx[j, i, k + 3] - vel.vx[j, i, k - 2]) +
+                           b4 * (vel.vx[j, i, k + 4] - vel.vx[j, i, k - 3]) +
+                           b5 * (vel.vx[j, i, k + 5] - vel.vx[j, i, k - 4]) +
+                           b6 * (vel.vx[j, i, k + 6] - vel.vx[j, i, k - 5])) * oodz;
+
+                    vyx = (b1 * (vel.vy[j, i + 1, k] - vel.vy[j, i, k]) +
+                           b2 * (vel.vy[j, i + 2, k] - vel.vy[j, i - 1, k]) +
+                           b3 * (vel.vy[j, i + 3, k] - vel.vy[j, i - 2, k]) +
+                           b4 * (vel.vy[j, i + 4, k] - vel.vy[j, i - 3, k]) +
+                           b5 * (vel.vy[j, i + 5, k] - vel.vy[j, i - 4, k]) +
+                           b6 * (vel.vy[j, i + 6, k] - vel.vy[j, i - 5, k])) * oodx;
+
+                    vyy = (b1 * (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) +
+                           b2 * (vel.vy[j + 1, i, k] - vel.vy[j - 2, i, k]) +
+                           b3 * (vel.vy[j + 2, i, k] - vel.vy[j - 3, i, k]) +
+                           b4 * (vel.vy[j + 3, i, k] - vel.vy[j - 4, i, k]) +
+                           b5 * (vel.vy[j + 4, i, k] - vel.vy[j - 5, i, k]) +
+                           b6 * (vel.vy[j + 5, i, k] - vel.vy[j - 6, i, k])) * oody;
+
+                    vyz = (b1 * (vel.vy[j, i, k + 1] - vel.vy[j, i, k]) +
+                           b2 * (vel.vy[j, i, k + 2] - vel.vy[j, i, k - 1]) +
+                           b3 * (vel.vy[j, i, k + 3] - vel.vy[j, i, k - 2]) +
+                           b4 * (vel.vy[j, i, k + 4] - vel.vy[j, i, k - 3]) +
+                           b5 * (vel.vy[j, i, k + 5] - vel.vy[j, i, k - 4]) +
+                           b6 * (vel.vy[j, i, k + 6] - vel.vy[j, i, k - 5])) * oodz;
+
+                    vzx = (b1 * (vel.vz[j, i + 1, k] - vel.vz[j, i, k]) +
+                           b2 * (vel.vz[j, i + 2, k] - vel.vz[j, i - 1, k]) +
+                           b3 * (vel.vz[j, i + 3, k] - vel.vz[j, i - 2, k]) +
+                           b4 * (vel.vz[j, i + 4, k] - vel.vz[j, i - 3, k]) +
+                           b5 * (vel.vz[j, i + 5, k] - vel.vz[j, i - 4, k]) +
+                           b6 * (vel.vz[j, i + 6, k] - vel.vz[j, i - 5, k])) * oodx;
+
+                    vzy = (b1 * (vel.vz[j + 1, i, k] - vel.vz[j, i, k]) +
+                           b2 * (vel.vz[j + 2, i, k] - vel.vz[j - 1, i, k]) +
+                           b3 * (vel.vz[j + 3, i, k] - vel.vz[j - 2, i, k]) +
+                           b4 * (vel.vz[j + 4, i, k] - vel.vz[j - 3, i, k]) +
+                           b5 * (vel.vz[j + 5, i, k] - vel.vz[j - 4, i, k]) +
+                           b6 * (vel.vz[j + 6, i, k] - vel.vz[j - 5, i, k])) * oody;
+
+                    vzz = (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
+                           b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2]) +
+                           b3 * (vel.vz[j, i, k + 2] - vel.vz[j, i, k - 3]) +
+                           b4 * (vel.vz[j, i, k + 3] - vel.vz[j, i, k - 4]) +
+                           b5 * (vel.vz[j, i, k + 4] - vel.vz[j, i, k - 5]) +
+                           b6 * (vel.vz[j, i, k + 5] - vel.vz[j, i, k - 6])) * oodz;
 
                     fipjp = mod_av->uipjp[j][i][k] * gv->DT;
                     fjpkp = mod_av->ujpkp[j][i][k] * gv->DT;
diff --git a/src/update_v_ssg.cpp b/src/update_v_ssg.cpp
index 11fc65b..fe18ae3 100644
--- a/src/update_v_ssg.cpp
+++ b/src/update_v_ssg.cpp
@@ -25,7 +25,7 @@
 #include "fd.hpp"
 #include "loop_blocking.hpp"
 
-void update_v(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *__restrict__ stress, st_model_av *mod_av,
+void update_v(const st_boundary *nb, st_velocity &vel, st_stress *__restrict__ stress, st_model_av *mod_av,
               float ***absorb_coeff, const GlobVar *gv)
 {
     float b1, b2, b3, b4, b5, b6;
@@ -45,7 +45,7 @@ void update_v(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *_
                     sxx_x = dx * (stress->sxx[j][i + 1][k] - stress->sxx[j][i][k]);
                     sxy_y = dy * (stress->sxy[j][i][k] - stress->sxy[j - 1][i][k]);
                     sxz_z = dz * (stress->sxz[j][i][k] - stress->sxz[j][i][k - 1]);
-                    vel->vx[j][i][k] += ((sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k]);
+                    vel.vx[j, i, k] += ((sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k]);
                 }
             }
         }
@@ -56,7 +56,7 @@ void update_v(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *_
                     syy_y = dy * (stress->syy[j + 1][i][k] - stress->syy[j][i][k]);
                     sxy_x = dx * (stress->sxy[j][i][k] - stress->sxy[j][i - 1][k]);
                     syz_z = dz * (stress->syz[j][i][k] - stress->syz[j][i][k - 1]);
-                    vel->vy[j][i][k] += ((syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k]);
+                    vel.vy[j, i, k] += ((syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k]);
                 }
             }
         }
@@ -67,7 +67,7 @@ void update_v(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *_
                     szz_z = dz * (stress->szz[j][i][k + 1] - stress->szz[j][i][k]);
                     sxz_x = dx * (stress->sxz[j][i][k] - stress->sxz[j][i - 1][k]);
                     syz_y = dy * (stress->syz[j][i][k] - stress->syz[j - 1][i][k]);
-                    vel->vz[j][i][k] += ((szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k]);
+                    vel.vz[j, i, k] += ((szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k]);
                 }
             }
         }
@@ -96,10 +96,7 @@ void update_v(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *_
                             gv->LEVEL2_CACHE_SIZE / (160 * min(nb->nz2 - nb->nz1, 1024)), , 1024)
         for (int j = j_start; j <= j_end; j++) {
             for (int i = i_start; i <= i_end; i++) {
-                float *vx_j_i = vel->vx[j][i];
-                float *vy_j_i = vel->vy[j][i];
-                float *vz_j_i = vel->vz[j][i];
-                #pragma omp simd nontemporal(vx_j_i, vy_j_i, vz_j_i)
+                #pragma omp simd
                 for (int k = k_start; k <= k_end; k++) {
                     sxx_x =
                         dx * (b1 * (stress->sxx[j][i + 1][k] - stress->sxx[j][i][k]) +
@@ -110,7 +107,7 @@ void update_v(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *_
                     sxz_z =
                         dz * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i][k - 1]) +
                               b2 * (stress->sxz[j][i][k + 1] - stress->sxz[j][i][k - 2]));
-                    vx_j_i[k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
 
                     syy_y =
                         dy * (b1 * (stress->syy[j + 1][i][k] - stress->syy[j][i][k]) +
@@ -121,7 +118,7 @@ void update_v(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *_
                     syz_z =
                         dz * (b1 * (stress->syz[j][i][k] - stress->syz[j][i][k - 1]) +
                               b2 * (stress->syz[j][i][k + 1] - stress->syz[j][i][k - 2]));
-                    vy_j_i[k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
 
                     szz_z =
                         dz * (b1 * (stress->szz[j][i][k + 1] - stress->szz[j][i][k]) +
@@ -132,7 +129,7 @@ void update_v(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *_
                     syz_y =
                         dy * (b1 * (stress->syz[j][i][k] - stress->syz[j - 1][i][k]) +
                               b2 * (stress->syz[j + 1][i][k] - stress->syz[j - 2][i][k]));
-                    vz_j_i[k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
                 }
             }
         }
@@ -162,7 +159,7 @@ void update_v(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *_
                                   b2 * (stress->sxz[j][i][k + 1] - stress->sxz[j][i][k - 2]) +
                                   b3 * (stress->sxz[j][i][k + 2] - stress->sxz[j][i][k - 3]));
                     /* updating components of particle velocities */
-                    vel->vx[j][i][k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
                     syy_y = dy * (b1 * (stress->syy[j + 1][i][k] - stress->syy[j][i][k]) +
                                   b2 * (stress->syy[j + 2][i][k] - stress->syy[j - 1][i][k]) +
                                   b3 * (stress->syy[j + 3][i][k] - stress->syy[j - 2][i][k]));
@@ -172,7 +169,7 @@ void update_v(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *_
                     syz_z = dz * (b1 * (stress->syz[j][i][k] - stress->syz[j][i][k - 1]) +
                                   b2 * (stress->syz[j][i][k + 1] - stress->syz[j][i][k - 2]) +
                                   b3 * (stress->syz[j][i][k + 2] - stress->syz[j][i][k - 3]));
-                    vel->vy[j][i][k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
                     szz_z = dz * (b1 * (stress->szz[j][i][k + 1] - stress->szz[j][i][k]) +
                                   b2 * (stress->szz[j][i][k + 2] - stress->szz[j][i][k - 1]) +
                                   b3 * (stress->szz[j][i][k + 3] - stress->szz[j][i][k - 2]));
@@ -182,7 +179,7 @@ void update_v(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *_
                     syz_y = dy * (b1 * (stress->syz[j][i][k] - stress->syz[j - 1][i][k]) +
                                   b2 * (stress->syz[j + 1][i][k] - stress->syz[j - 2][i][k]) +
                                   b3 * (stress->syz[j + 2][i][k] - stress->syz[j - 3][i][k]));
-                    vel->vz[j][i][k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
                 }
             }
         }
@@ -215,7 +212,7 @@ void update_v(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *_
                                   b3 * (stress->sxz[j][i][k + 2] - stress->sxz[j][i][k - 3]) +
                                   b4 * (stress->sxz[j][i][k + 3] - stress->sxz[j][i][k - 4]));
                     /* updating components of particle velocities */
-                    vel->vx[j][i][k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
                     syy_y = dy * (b1 * (stress->syy[j + 1][i][k] - stress->syy[j][i][k]) +
                                   b2 * (stress->syy[j + 2][i][k] - stress->syy[j - 1][i][k]) +
                                   b3 * (stress->syy[j + 3][i][k] - stress->syy[j - 2][i][k]) +
@@ -228,7 +225,7 @@ void update_v(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *_
                                   b2 * (stress->syz[j][i][k + 1] - stress->syz[j][i][k - 2]) +
                                   b3 * (stress->syz[j][i][k + 2] - stress->syz[j][i][k - 3]) +
                                   b4 * (stress->syz[j][i][k + 3] - stress->syz[j][i][k - 4]));
-                    vel->vy[j][i][k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
                     szz_z = dz * (b1 * (stress->szz[j][i][k + 1] - stress->szz[j][i][k]) +
                                   b2 * (stress->szz[j][i][k + 2] - stress->szz[j][i][k - 1]) +
                                   b3 * (stress->szz[j][i][k + 3] - stress->szz[j][i][k - 2]) +
@@ -241,7 +238,7 @@ void update_v(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *_
                                   b2 * (stress->syz[j + 1][i][k] - stress->syz[j - 2][i][k]) +
                                   b3 * (stress->syz[j + 2][i][k] - stress->syz[j - 3][i][k]) +
                                   b4 * (stress->syz[j + 3][i][k] - stress->syz[j - 4][i][k]));
-                    vel->vz[j][i][k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
                 }
             }
         }
@@ -279,7 +276,7 @@ void update_v(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *_
                                   b4 * (stress->sxz[j][i][k + 3] - stress->sxz[j][i][k - 4]) +
                                   b5 * (stress->sxz[j][i][k + 4] - stress->sxz[j][i][k - 5]));
                     /* updating components of particle velocities */
-                    vel->vx[j][i][k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
                     syy_y = dy * (b1 * (stress->syy[j + 1][i][k] - stress->syy[j][i][k]) +
                                   b2 * (stress->syy[j + 2][i][k] - stress->syy[j - 1][i][k]) +
                                   b3 * (stress->syy[j + 3][i][k] - stress->syy[j - 2][i][k]) +
@@ -295,7 +292,7 @@ void update_v(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *_
                                   b3 * (stress->syz[j][i][k + 2] - stress->syz[j][i][k - 3]) +
                                   b4 * (stress->syz[j][i][k + 3] - stress->syz[j][i][k - 4]) +
                                   b5 * (stress->syz[j][i][k + 4] - stress->syz[j][i][k - 5]));
-                    vel->vy[j][i][k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
                     szz_z = dz * (b1 * (stress->szz[j][i][k + 1] - stress->szz[j][i][k]) +
                                   b2 * (stress->szz[j][i][k + 2] - stress->szz[j][i][k - 1]) +
                                   b3 * (stress->szz[j][i][k + 3] - stress->szz[j][i][k - 2]) +
@@ -311,7 +308,7 @@ void update_v(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *_
                                   b3 * (stress->syz[j + 2][i][k] - stress->syz[j - 3][i][k]) +
                                   b4 * (stress->syz[j + 3][i][k] - stress->syz[j - 4][i][k]) +
                                   b5 * (stress->syz[j + 4][i][k] - stress->syz[j - 5][i][k]));
-                    vel->vz[j][i][k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
                 }
             }
         }
@@ -356,7 +353,7 @@ void update_v(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *_
                                   b5 * (stress->sxy[j][i][k + 4] - stress->sxy[j][i][k - 5]) +
                                   b6 * (stress->sxy[j][i][k + 5] - stress->sxy[j][i][k - 6]));
                     /* updating components of particle velocities */
-                    vel->vx[j][i][k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
                     syy_y = dy * (b1 * (stress->syy[j + 1][i][k] - stress->syy[j][i][k]) +
                                   b2 * (stress->syy[j + 2][i][k] - stress->syy[j - 1][i][k]) +
                                   b3 * (stress->syy[j + 3][i][k] - stress->syy[j - 2][i][k]) +
@@ -375,7 +372,7 @@ void update_v(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *_
                                   b4 * (stress->syz[j][i][k + 3] - stress->syz[j][i][k - 4]) +
                                   b5 * (stress->syz[j][i][k + 4] - stress->syz[j][i][k - 5]) +
                                   b6 * (stress->syz[j][i][k + 5] - stress->syz[j][i][k - 6]));
-                    vel->vy[j][i][k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
                     szz_z = dz * (b1 * (stress->szz[j][i][k + 1] - stress->szz[j][i][k]) +
                                   b2 * (stress->szz[j][i][k + 2] - stress->szz[j][i][k - 1]) +
                                   b3 * (stress->szz[j][i][k + 3] - stress->szz[j][i][k - 2]) +
@@ -394,7 +391,7 @@ void update_v(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *_
                                   b4 * (stress->syz[j + 3][i][k] - stress->syz[j - 4][i][k]) +
                                   b5 * (stress->syz[j + 4][i][k] - stress->syz[j - 5][i][k]) +
                                   b6 * (stress->syz[j + 5][i][k] - stress->syz[j - 6][i][k]));
-                    vel->vz[j][i][k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
                 }
             }
         }
@@ -407,9 +404,9 @@ void update_v(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *_
         for (int j = nb->ny1; j <= nb->ny2; j++) {
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    vel->vx[j][i][k] *= absorb_coeff[j][i][k];
-                    vel->vy[j][i][k] *= absorb_coeff[j][i][k];
-                    vel->vz[j][i][k] *= absorb_coeff[j][i][k];
+                    vel.vx[j, i, k] *= absorb_coeff[j][i][k];
+                    vel.vy[j, i, k] *= absorb_coeff[j][i][k];
+                    vel.vz[j, i, k] *= absorb_coeff[j][i][k];
                     stress->sxy[j][i][k] *= absorb_coeff[j][i][k];
                     stress->syz[j][i][k] *= absorb_coeff[j][i][k];
                     stress->sxz[j][i][k] *= absorb_coeff[j][i][k];
diff --git a/src/update_v_ssg_CPML.cpp b/src/update_v_ssg_CPML.cpp
index 77449dc..536de09 100644
--- a/src/update_v_ssg_CPML.cpp
+++ b/src/update_v_ssg_CPML.cpp
@@ -30,7 +30,7 @@
 
 #define UNUSED(x) (void)(x)
 
-void update_v_CPML(st_boundary *nb, st_velocity *vel, st_stress *stress, st_model_av *mod_av,
+void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress *stress, st_model_av *mod_av,
                    st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, const GlobVar *gv)
 {
     float sxx_x = 0.0, sxy_y = 0.0, sxz_z = 0.0, syy_y = 0.0, sxy_x = 0.0, syz_z = 0.0;
@@ -143,9 +143,9 @@ void update_v_CPML(st_boundary *nb, st_velocity *vel, st_stress *stress, st_mode
                         szz_z = szz_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_szz_z[j][i][h1];
                     }
 
-                    vel->vx[j][i][k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
-                    vel->vy[j][i][k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
-                    vel->vz[j][i][k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
                 }
             }
         }
@@ -244,9 +244,9 @@ void update_v_CPML(st_boundary *nb, st_velocity *vel, st_stress *stress, st_mode
                         szz_z = szz_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_szz_z[j][i][h1];
                     }
 
-                    vel->vx[j][i][k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
-                    vel->vy[j][i][k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
-                    vel->vz[j][i][k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
                 }
             }
         }
@@ -319,9 +319,9 @@ void update_v_CPML(st_boundary *nb, st_velocity *vel, st_stress *stress, st_mode
                         szz_z = szz_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_szz_z[j][i][h1];
                     }
 
-                    vel->vx[j][i][k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
-                    vel->vy[j][i][k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
-                    vel->vz[j][i][k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
                 }
             }
         }
@@ -395,9 +395,9 @@ void update_v_CPML(st_boundary *nb, st_velocity *vel, st_stress *stress, st_mode
                         szz_z = szz_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_szz_z[j][i][h1];
                     }
 
-                    vel->vx[j][i][k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
-                    vel->vy[j][i][k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
-                    vel->vz[j][i][k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
                 }
             }
         }
@@ -447,9 +447,9 @@ void update_v_CPML(st_boundary *nb, st_velocity *vel, st_stress *stress, st_mode
                         pml_coeff->b_z_half[k] * pml_wfd->psi_szz_z[j][i][k] + pml_coeff->a_z_half[k] * szz_z;
                     szz_z = szz_z / pml_coeff->K_z_half[k] + pml_wfd->psi_szz_z[j][i][k];
 
-                    vel->vx[j][i][k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
-                    vel->vy[j][i][k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
-                    vel->vz[j][i][k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
                 }
             }
         }
@@ -498,9 +498,9 @@ void update_v_CPML(st_boundary *nb, st_velocity *vel, st_stress *stress, st_mode
                         pml_coeff->b_z_half[h1] * pml_wfd->psi_szz_z[j][i][h1] + pml_coeff->a_z_half[h1] * szz_z;
                     szz_z = szz_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_szz_z[j][i][h1];
 
-                    vel->vx[j][i][k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
-                    vel->vy[j][i][k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
-                    vel->vz[j][i][k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
                 }
             }
         }
diff --git a/src/update_v_ssg_CPML_acoustic.cpp b/src/update_v_ssg_CPML_acoustic.cpp
index 3947d20..0bee374 100644
--- a/src/update_v_ssg_CPML_acoustic.cpp
+++ b/src/update_v_ssg_CPML_acoustic.cpp
@@ -30,7 +30,7 @@
 
 #define UNUSED(x) (void)(x)
 
-void update_v_CPML_acoustic(st_boundary *nb, st_velocity *vel, st_stress *stress, st_model_av *mod_av,
+void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress *stress, st_model_av *mod_av,
                             st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, const GlobVar *gv)
 {
     float sp_x = 0.0, sp_y = 0.0, sp_z = 0.0;
@@ -94,9 +94,9 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity *vel, st_stress *stress
                         sp_z = sp_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_sp_z[j][i][h1];
                     }
 
-                    vel->vx[j][i][k] += (sp_x) / mod_av->rip[j][i][k];
-                    vel->vy[j][i][k] += (sp_y) / mod_av->rjp[j][i][k];
-                    vel->vz[j][i][k] += (sp_z) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
+                    vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
+                    vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
                 }
             }
         }
@@ -147,9 +147,9 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity *vel, st_stress *stress
                         sp_z = sp_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_sp_z[j][i][h1];
                     }
 
-                    vel->vx[j][i][k] += (sp_x) / mod_av->rip[j][i][k];
-                    vel->vy[j][i][k] += (sp_y) / mod_av->rjp[j][i][k];
-                    vel->vz[j][i][k] += (sp_z) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
+                    vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
+                    vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
                 }
             }
         }
@@ -186,9 +186,9 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity *vel, st_stress *stress
                         sp_z = sp_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_sp_z[j][i][h1];
                     }
 
-                    vel->vx[j][i][k] += (sp_x) / mod_av->rip[j][i][k];
-                    vel->vy[j][i][k] += (sp_y) / mod_av->rjp[j][i][k];
-                    vel->vz[j][i][k] += (sp_z) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
+                    vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
+                    vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
                 }
             }
         }
@@ -226,9 +226,9 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity *vel, st_stress *stress
                         sp_z = sp_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_sp_z[j][i][h1];
                     }
 
-                    vel->vx[j][i][k] += (sp_x) / mod_av->rip[j][i][k];
-                    vel->vy[j][i][k] += (sp_y) / mod_av->rjp[j][i][k];
-                    vel->vz[j][i][k] += (sp_z) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
+                    vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
+                    vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
                 }
             }
         }
@@ -254,9 +254,9 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity *vel, st_stress *stress
                         pml_coeff->b_z_half[k] * pml_wfd->psi_sp_z[j][i][k] + pml_coeff->a_z_half[k] * sp_z;
                     sp_z = sp_z / pml_coeff->K_z_half[k] + pml_wfd->psi_sp_z[j][i][k];
 
-                    vel->vx[j][i][k] += (sp_x) / mod_av->rip[j][i][k];
-                    vel->vy[j][i][k] += (sp_y) / mod_av->rjp[j][i][k];
-                    vel->vz[j][i][k] += (sp_z) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
+                    vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
+                    vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
                 }
             }
         }
@@ -281,9 +281,9 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity *vel, st_stress *stress
                         pml_coeff->b_z_half[h1] * pml_wfd->psi_sp_z[j][i][h1] + pml_coeff->a_z_half[h1] * sp_z;
                     sp_z = sp_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_sp_z[j][i][h1];
 
-                    vel->vx[j][i][k] += (sp_x) / mod_av->rip[j][i][k];
-                    vel->vy[j][i][k] += (sp_y) / mod_av->rjp[j][i][k];
-                    vel->vz[j][i][k] += (sp_z) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
+                    vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
+                    vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
                 }
             }
         }
diff --git a/src/update_v_ssg_acoustic.cpp b/src/update_v_ssg_acoustic.cpp
index 03dbe73..4632a90 100644
--- a/src/update_v_ssg_acoustic.cpp
+++ b/src/update_v_ssg_acoustic.cpp
@@ -24,7 +24,7 @@
 
 #include "fd.hpp"
 
-void update_v_acoustic(const st_boundary *nb, st_velocity *__restrict__ vel, st_stress *__restrict__ stress,
+void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress *__restrict__ stress,
                        st_model_av *mod_av, float ***absorb_coeff, const GlobVar *gv)
 {
     float b1, b2, b3, b4, b5, b6;
@@ -34,37 +34,31 @@ void update_v_acoustic(const st_boundary *nb, st_velocity *__restrict__ vel, st_
     float dz = gv->DT / gv->DZ;
 
     switch (gv->FDORDER) {
-    case 2:
-    {
+    case 2: {
         for (int j = nb->ny1; j <= nb->ny2; j++) {
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
                     float sp_x = dx * (stress->sp[j][i + 1][k] - stress->sp[j][i][k]);
-                    vel->vx[j][i][k] += sp_x / mod_av->rip[j][i][k];
+                    vel.vx[j, i, k] += sp_x / mod_av->rip[j][i][k];
                     float sp_y = dy * (stress->sp[j + 1][i][k] - stress->sp[j][i][k]);
-                    vel->vy[j][i][k] += sp_y / mod_av->rjp[j][i][k];
+                    vel.vy[j, i, k] += sp_y / mod_av->rjp[j][i][k];
                     float sp_z = dz * (stress->sp[j][i][k + 1] - stress->sp[j][i][k]);
-                    vel->vz[j][i][k] += sp_z / mod_av->rkp[j][i][k];
+                    vel.vz[j, i, k] += sp_z / mod_av->rkp[j][i][k];
                 }
             }
         }
-    }
-    break;
-    case 4:
-    {
-        float b1 = 9.0 / 8.0;          /* Taylor coefficients */
+    } break;
+    case 4: {
+        float b1 = 9.0 / 8.0;   /* Taylor coefficients */
         float b2 = -1.0 / 24.0;
-        if (gv->FDCOEFF == 2) {        /* Holberg coefficients E=0.1 % */
+        if (gv->FDCOEFF == 2) { /* Holberg coefficients E=0.1 % */
             b1 = 1.1382;
             b2 = -0.046414;
         }
         for (int j = nb->ny1; j <= nb->ny2; j++) {
             for (int i = nb->nx1; i <= nb->nx2; i++) {
-                float *vx_j_i = vel->vx[j][i];
-                float *vy_j_i = vel->vy[j][i];
-                float *vz_j_i = vel->vz[j][i];
-                #pragma omp simd nontemporal(vx_j_i, vy_j_i, vz_j_i)
+                #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
                     float sp_x =
                         dx * (b1 * (stress->sp[j][i + 1][k] - stress->sp[j][i][k]) +
@@ -75,23 +69,22 @@ void update_v_acoustic(const st_boundary *nb, st_velocity *__restrict__ vel, st_
                     float sp_z =
                         dz * (b1 * (stress->sp[j][i][k + 1] - stress->sp[j][i][k]) +
                               b2 * (stress->sp[j][i][k + 2] - stress->sp[j][i][k - 1]));
-                    vx_j_i[k] += sp_x / mod_av->rip[j][i][k];
-                    vy_j_i[k] += sp_y / mod_av->rjp[j][i][k];
-                    vz_j_i[k] += sp_z / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += sp_x / mod_av->rip[j][i][k];
+                    vel.vy[j, i, k] += sp_y / mod_av->rjp[j][i][k];
+                    vel.vz[j, i, k] += sp_z / mod_av->rkp[j][i][k];
                 }
             }
         }
-    }
-    break;
+    } break;
     case 6:
         b1 = 75.0 / 64.0;
         b2 = -25.0 / 384.0;
-        b3 = 3.0 / 640.0;     /* Taylor coefficients */
+        b3 = 3.0 / 640.0; /* Taylor coefficients */
         if (gv->FDCOEFF == 2) {
             b1 = 1.1965;
             b2 = -0.078804;
             b3 = 0.0081781;
-        }                     /* Holberg coefficients E=0.1 % */
+        } /* Holberg coefficients E=0.1 % */
         for (int j = nb->ny1; j <= nb->ny2; j++) {
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 #pragma omp simd
@@ -100,15 +93,15 @@ void update_v_acoustic(const st_boundary *nb, st_velocity *__restrict__ vel, st_
                                  b2 * (stress->sp[j][i + 2][k] - stress->sp[j][i - 1][k]) +
                                  b3 * (stress->sp[j][i + 3][k] - stress->sp[j][i - 2][k]));
                     /* updating components of particle velocities */
-                    vel->vx[j][i][k] += (sp_x) / mod_av->rip[j][i][k];
+                    vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
                     sp_y = dy * (b1 * (stress->sp[j + 1][i][k] - stress->sp[j][i][k]) +
                                  b2 * (stress->sp[j + 2][i][k] - stress->sp[j - 1][i][k]) +
                                  b3 * (stress->sp[j + 3][i][k] - stress->sp[j - 2][i][k]));
-                    vel->vy[j][i][k] += (sp_y) / mod_av->rjp[j][i][k];
+                    vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
                     sp_z = dz * (b1 * (stress->sp[j][i][k + 1] - stress->sp[j][i][k]) +
                                  b2 * (stress->sp[j][i][k + 2] - stress->sp[j][i][k - 1]) +
                                  b3 * (stress->sp[j][i][k + 3] - stress->sp[j][i][k - 2]));
-                    vel->vz[j][i][k] += (sp_z) / mod_av->rkp[j][i][k];
+                    vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
                 }
             }
         }
@@ -117,36 +110,33 @@ void update_v_acoustic(const st_boundary *nb, st_velocity *__restrict__ vel, st_
         b1 = 1225.0 / 1024.0;
         b2 = -245.0 / 3072.0;
         b3 = 49.0 / 5120.0;
-        b4 = -5.0 / 7168.0;   /* Taylor coefficients */
+        b4 = -5.0 / 7168.0; /* Taylor coefficients */
         if (gv->FDCOEFF == 2) {
             b1 = 1.2257;
             b2 = -0.099537;
             b3 = 0.018063;
             b4 = -0.0026274;
-        }                     /* Holberg coefficients E=0.1 % */
+        } /* Holberg coefficients E=0.1 % */
         for (int j = nb->ny1; j <= nb->ny2; j++) {
             for (int i = nb->nx1; i <= nb->nx2; i++) {
-                float *vx_j_i = vel->vx[j][i];
-                float *vy_j_i = vel->vy[j][i];
-                float *vz_j_i = vel->vz[j][i];
-                #pragma omp simd nontemporal(vx_j_i, vy_j_i, vz_j_i)
+                #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
                     sp_x = dx * (b1 * (stress->sp[j][i + 1][k] - stress->sp[j][i][k]) +
                                  b2 * (stress->sp[j][i + 2][k] - stress->sp[j][i - 1][k]) +
                                  b3 * (stress->sp[j][i + 3][k] - stress->sp[j][i - 2][k]) +
                                  b4 * (stress->sp[j][i + 4][k] - stress->sp[j][i - 3][k]));
                     /* updating components of particle velocities */
-                    vx_j_i[k] += (sp_x) / mod_av->rip[j][i][k];
+                    vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
                     sp_y = dy * (b1 * (stress->sp[j + 1][i][k] - stress->sp[j][i][k]) +
                                  b2 * (stress->sp[j + 2][i][k] - stress->sp[j - 1][i][k]) +
                                  b3 * (stress->sp[j + 3][i][k] - stress->sp[j - 2][i][k]) +
                                  b4 * (stress->sp[j + 4][i][k] - stress->sp[j - 3][i][k]));
-                    vy_j_i[k] += (sp_y) / mod_av->rjp[j][i][k];
+                    vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
                     sp_z = dz * (b1 * (stress->sp[j][i][k + 1] - stress->sp[j][i][k]) +
                                  b2 * (stress->sp[j][i][k + 2] - stress->sp[j][i][k - 1]) +
                                  b3 * (stress->sp[j][i][k + 3] - stress->sp[j][i][k - 2]) +
                                  b4 * (stress->sp[j][i][k + 4] - stress->sp[j][i][k - 3]));
-                    vz_j_i[k] += (sp_z) / mod_av->rkp[j][i][k];
+                    vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
                 }
             }
         }
@@ -163,7 +153,7 @@ void update_v_acoustic(const st_boundary *nb, st_velocity *__restrict__ vel, st_
             b3 = 0.026191;
             b4 = -0.0064682;
             b5 = 0.001191;
-        }                     /* Holberg coefficients E=0.1 % */
+        } /* Holberg coefficients E=0.1 % */
         for (int j = nb->ny1; j <= nb->ny2; j++) {
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 #pragma omp simd
@@ -174,19 +164,19 @@ void update_v_acoustic(const st_boundary *nb, st_velocity *__restrict__ vel, st_
                                  b4 * (stress->sp[j][i + 4][k] - stress->sp[j][i - 3][k]) +
                                  b5 * (stress->sp[j][i + 5][k] - stress->sp[j][i - 4][k]));
                     /* updating components of particle velocities */
-                    vel->vx[j][i][k] += (sp_x) / mod_av->rip[j][i][k];
+                    vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
                     sp_y = dy * (b1 * (stress->sp[j + 1][i][k] - stress->sp[j][i][k]) +
                                  b2 * (stress->sp[j + 2][i][k] - stress->sp[j - 1][i][k]) +
                                  b3 * (stress->sp[j + 3][i][k] - stress->sp[j - 2][i][k]) +
                                  b4 * (stress->sp[j + 4][i][k] - stress->sp[j - 3][i][k]) +
                                  b5 * (stress->sp[j + 5][i][k] - stress->sp[j - 4][i][k]));
-                    vel->vy[j][i][k] += (sp_y) / mod_av->rjp[j][i][k];
+                    vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
                     sp_z = dz * (b1 * (stress->sp[j][i][k + 1] - stress->sp[j][i][k]) +
                                  b2 * (stress->sp[j][i][k + 2] - stress->sp[j][i][k - 1]) +
                                  b3 * (stress->sp[j][i][k + 3] - stress->sp[j][i][k - 2]) +
                                  b4 * (stress->sp[j][i][k + 4] - stress->sp[j][i][k - 3]) +
                                  b5 * (stress->sp[j][i][k + 5] - stress->sp[j][i][k - 4]));
-                    vel->vz[j][i][k] += (sp_z) / mod_av->rkp[j][i][k];
+                    vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
                 }
             }
         }
@@ -210,10 +200,7 @@ void update_v_acoustic(const st_boundary *nb, st_velocity *__restrict__ vel, st_
         }
         for (int j = nb->ny1; j <= nb->ny2; j++) {
             for (int i = nb->nx1; i <= nb->nx2; i++) {
-                float *vx_j_i = vel->vx[j][i];
-                float *vy_j_i = vel->vy[j][i];
-                float *vz_j_i = vel->vz[j][i];
-                #pragma omp simd nontemporal(vx_j_i, vy_j_i, vz_j_i)
+                #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
                     sp_x = dx * (b1 * (stress->sp[j][i + 1][k] - stress->sp[j][i][k]) +
                                  b2 * (stress->sp[j][i + 2][k] - stress->sp[j][i - 1][k]) +
@@ -222,21 +209,21 @@ void update_v_acoustic(const st_boundary *nb, st_velocity *__restrict__ vel, st_
                                  b5 * (stress->sp[j][i + 5][k] - stress->sp[j][i - 4][k]) +
                                  b6 * (stress->sp[j][i + 6][k] - stress->sp[j][i - 5][k]));
                     /* updating components of particle velocities */
-                    vx_j_i[k] += (sp_x) / mod_av->rip[j][i][k];
+                    vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
                     sp_y = dy * (b1 * (stress->sp[j + 1][i][k] - stress->sp[j][i][k]) +
                                  b2 * (stress->sp[j + 2][i][k] - stress->sp[j - 1][i][k]) +
                                  b3 * (stress->sp[j + 3][i][k] - stress->sp[j - 2][i][k]) +
                                  b4 * (stress->sp[j + 4][i][k] - stress->sp[j - 3][i][k]) +
                                  b5 * (stress->sp[j + 5][i][k] - stress->sp[j - 4][i][k]) +
                                  b6 * (stress->sp[j + 6][i][k] - stress->sp[j - 5][i][k]));
-                    vy_j_i[k] += (sp_y) / mod_av->rjp[j][i][k];
+                    vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
                     sp_z = dz * (b1 * (stress->sp[j][i][k + 1] - stress->sp[j][i][k]) +
                                  b2 * (stress->sp[j][i][k + 2] - stress->sp[j][i][k - 1]) +
                                  b3 * (stress->sp[j][i][k + 3] - stress->sp[j][i][k - 2]) +
                                  b4 * (stress->sp[j][i][k + 4] - stress->sp[j][i][k - 3]) +
                                  b5 * (stress->sp[j][i][k + 5] - stress->sp[j][i][k - 4]) +
                                  b6 * (stress->sp[j][i][k + 6] - stress->sp[j][i][k - 5]));
-                    vz_j_i[k] += (sp_z) / mod_av->rkp[j][i][k];
+                    vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
                 }
             }
         }
@@ -250,9 +237,9 @@ void update_v_acoustic(const st_boundary *nb, st_velocity *__restrict__ vel, st_
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    vel->vx[j][i][k] *= absorb_coeff[j][i][k];
-                    vel->vy[j][i][k] *= absorb_coeff[j][i][k];
-                    vel->vz[j][i][k] *= absorb_coeff[j][i][k];
+                    vel.vx[j, i, k] *= absorb_coeff[j][i][k];
+                    vel.vy[j, i, k] *= absorb_coeff[j][i][k];
+                    vel.vz[j, i, k] *= absorb_coeff[j][i][k];
                     stress->sp[j][i][k] *= absorb_coeff[j][i][k];
                 }
             }
diff --git a/src/zero_wavefield.cpp b/src/zero_wavefield.cpp
index ae3c689..efcdbf9 100644
--- a/src/zero_wavefield.cpp
+++ b/src/zero_wavefield.cpp
@@ -22,7 +22,7 @@
  * -------------------------------------------------------------------------*/
 
 #include "fd.hpp"
-void zero_wavefield(st_velocity *vel, st_stress *stress, st_visc_mem *mem, st_pml_wfd *pml_wfd, const GlobVar *gv)
+void zero_wavefield(st_velocity &vel, st_stress *stress, st_visc_mem *mem, st_pml_wfd *pml_wfd, const GlobVar *gv)
 {
     int l = 1;
 
@@ -50,9 +50,9 @@ void zero_wavefield(st_velocity *vel, st_stress *stress, st_visc_mem *mem, st_pm
         for (int i = nx1; i <= nx2; i++) {
             #pragma omp simd
             for (int k = nz1; k <= nz2; k++) {
-                vel->vx[j][i][k] = 0.0f;
-                vel->vy[j][i][k] = 0.0f;
-                vel->vz[j][i][k] = 0.0f;
+                vel.vx[j, i, k] = 0.0f;
+                vel.vy[j, i, k] = 0.0f;
+                vel.vz[j, i, k] = 0.0f;
                 stress->sxy[j][i][k] = 0.0f;
                 stress->syz[j][i][k] = 0.0f;
             }
diff --git a/src/zero_wavefield_acoustic.cpp b/src/zero_wavefield_acoustic.cpp
index 60a0729..f8285dc 100644
--- a/src/zero_wavefield_acoustic.cpp
+++ b/src/zero_wavefield_acoustic.cpp
@@ -22,7 +22,7 @@
  * -------------------------------------------------------------------------*/
 
 #include "fd.hpp"
-void zero_wavefield_acoustic(st_velocity *vel, st_stress *stress, st_visc_mem *mem,
+void zero_wavefield_acoustic(st_velocity &vel, st_stress *stress, st_visc_mem *mem,
                              st_pml_wfd *pml_wfd, const GlobVar *gv)
 {
     int l = 1;
@@ -51,9 +51,9 @@ void zero_wavefield_acoustic(st_velocity *vel, st_stress *stress, st_visc_mem *m
         for (int i = nx1; i <= nx2; i++) {
             #pragma omp simd
             for (int k = nz1; k <= nz2; k++) {
-                vel->vx[j][i][k] = 0.0f;
-                vel->vy[j][i][k] = 0.0f;
-                vel->vz[j][i][k] = 0.0f;
+                vel.vx[j, i, k] = 0.0f;
+                vel.vy[j, i, k] = 0.0f;
+                vel.vz[j, i, k] = 0.0f;
             }
         }
     }
-- 
GitLab


From 749b13209fae2c9cded7a03454c2728d5837fbaf Mon Sep 17 00:00:00 2001
From: Holger Obermaier <holgerob@gmx.de>
Date: Fri, 4 Apr 2025 14:37:49 +0200
Subject: [PATCH 03/15] Use float3DTensorT in type st_stress

---
 src/exchange_s.cpp                 | 222 ++++++++--------
 src/exchange_s_acoustic.cpp        |  78 +++---
 src/fd.hpp                         |  66 ++---
 src/freemem.cpp                    |  38 +--
 src/ifos3d.cpp                     |  24 +-
 src/initmem.cpp                    |  65 +++--
 src/psource.cpp                    |  10 +-
 src/seismo_ssg.cpp                 |  18 +-
 src/snap_ssg.cpp                   |   6 +-
 src/stfi.cpp                       |   2 +-
 src/surface_ssg.cpp                | 102 ++++----
 src/surface_ssg_acoustic.cpp       |   6 +-
 src/surface_ssg_elastic.cpp        |  78 +++---
 src/timeloop.cpp                   |   2 +-
 src/update_s_ssg_CPML_acoustic.cpp |  14 +-
 src/update_s_ssg_CPML_elastic.cpp  |  74 +++---
 src/update_s_ssg_acoustic.cpp      |  20 +-
 src/update_s_ssg_elastic.cpp       | 103 ++++----
 src/update_v_ssg.cpp               | 392 ++++++++++++++---------------
 src/update_v_ssg_CPML.cpp          | 218 ++++++++--------
 src/update_v_ssg_CPML_acoustic.cpp |  74 +++---
 src/update_v_ssg_acoustic.cpp      | 130 +++++-----
 src/zero_wavefield.cpp             |  14 +-
 src/zero_wavefield_acoustic.cpp    |   4 +-
 24 files changed, 864 insertions(+), 896 deletions(-)

diff --git a/src/exchange_s.cpp b/src/exchange_s.cpp
index 626539d..1cd820c 100644
--- a/src/exchange_s.cpp
+++ b/src/exchange_s.cpp
@@ -26,7 +26,7 @@
 #include "fd.hpp"
 
 #ifdef MPI_SENDRECV_REPLACE
-double exchange_s(st_stress *stress, st_buffer_flat *buffer, GlobVar *gv)
+double exchange_s(st_stress &stress, st_buffer_flat *buffer, GlobVar *gv)
 {
     MPI_Status status;
     int n, nf1, nf2;
@@ -79,17 +79,17 @@ double exchange_s(st_stress *stress, st_buffer_flat *buffer, GlobVar *gv)
     /* top-bottom ----------------------------------------------------------- */
 
     if (send_top_to_bot) {
-        n = buffer_push(buffer->top_to_bot, stress->syy, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
-        n = buffer_push(buffer->top_to_bot, stress->sxy, 1, gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ, n);
-        n = buffer_push(buffer->top_to_bot, stress->syz, 1, gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ, n);
+        n = buffer_push(buffer->top_to_bot, stress.syy, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
+        n = buffer_push(buffer->top_to_bot, stress.sxy, 1, gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ, n);
+        n = buffer_push(buffer->top_to_bot, stress.syz, 1, gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ, n);
     }
 
     if (send_bot_to_top) {
-        n = buffer_push(buffer->bot_to_top, stress->sxy, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2), 1, gv->NX, 1,
+        n = buffer_push(buffer->bot_to_top, stress.sxy, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2), 1, gv->NX, 1,
                         gv->NZ, 0);
-        n = buffer_push(buffer->bot_to_top, stress->syz, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2), 1, gv->NX, 1,
+        n = buffer_push(buffer->bot_to_top, stress.syz, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2), 1, gv->NX, 1,
                         gv->NZ, n);
-        n = buffer_push(buffer->bot_to_top, stress->syy, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1, gv->NX,
+        n = buffer_push(buffer->bot_to_top, stress.syy, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1, gv->NX,
                         1, gv->NZ, n);
     }
 
@@ -101,33 +101,33 @@ double exchange_s(st_stress *stress, st_buffer_flat *buffer, GlobVar *gv)
                          gv->COMM_SHOT, &status);
 
     if (recv_top_to_bot) {
-        n = buffer_pop(stress->syy, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
-        n = buffer_pop(stress->sxy, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ,
+        n = buffer_pop(stress.syy, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
+        n = buffer_pop(stress.sxy, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ,
                        n);
-        n = buffer_pop(stress->syz, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ,
+        n = buffer_pop(stress.syz, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ,
                        n);
     }
 
     if (recv_bot_to_top) {
-        n = buffer_pop(stress->sxy, buffer->bot_to_top, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
-        n = buffer_pop(stress->syz, buffer->bot_to_top, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, n);
-        n = buffer_pop(stress->syy, buffer->bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ, n);
+        n = buffer_pop(stress.sxy, buffer->bot_to_top, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
+        n = buffer_pop(stress.syz, buffer->bot_to_top, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, n);
+        n = buffer_pop(stress.syy, buffer->bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ, n);
     }
 
     /* left-right ----------------------------------------------------------- */
 
     if (send_lef_to_rig) {
-        n = buffer_push(buffer->lef_to_rig, stress->sxx, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, 0);
-        n = buffer_push(buffer->lef_to_rig, stress->sxy, 1, gv->NY, 1, gv->FDORDER / 2 - 1, 1, gv->NZ, n);
-        n = buffer_push(buffer->lef_to_rig, stress->sxz, 1, gv->NY, 1, gv->FDORDER / 2 - 1, 1, gv->NZ, n);
+        n = buffer_push(buffer->lef_to_rig, stress.sxx, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, 0);
+        n = buffer_push(buffer->lef_to_rig, stress.sxy, 1, gv->NY, 1, gv->FDORDER / 2 - 1, 1, gv->NZ, n);
+        n = buffer_push(buffer->lef_to_rig, stress.sxz, 1, gv->NY, 1, gv->FDORDER / 2 - 1, 1, gv->NZ, n);
     }
 
     if (send_rig_to_lef) {
-        n = buffer_push(buffer->rig_to_lef, stress->sxy, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - gv->FDORDER / 2, 1,
+        n = buffer_push(buffer->rig_to_lef, stress.sxy, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - gv->FDORDER / 2, 1,
                         gv->NZ, 0);
-        n = buffer_push(buffer->rig_to_lef, stress->sxz, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - gv->FDORDER / 2, 1,
+        n = buffer_push(buffer->rig_to_lef, stress.sxz, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - gv->FDORDER / 2, 1,
                         gv->NZ, n);
-        n = buffer_push(buffer->rig_to_lef, stress->sxx, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - (gv->FDORDER / 2 - 1),
+        n = buffer_push(buffer->rig_to_lef, stress.sxx, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - (gv->FDORDER / 2 - 1),
                         1, gv->NZ, n);
     }
 
@@ -139,33 +139,33 @@ double exchange_s(st_stress *stress, st_buffer_flat *buffer, GlobVar *gv)
                          gv->COMM_SHOT, &status);
 
     if (recv_lef_to_rig) {
-        n = buffer_pop(stress->sxx, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1, gv->NZ, 0);
-        n = buffer_pop(stress->sxy, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2 - 1, 1, gv->NZ,
+        n = buffer_pop(stress.sxx, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1, gv->NZ, 0);
+        n = buffer_pop(stress.sxy, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2 - 1, 1, gv->NZ,
                        n);
-        n = buffer_pop(stress->sxz, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2 - 1, 1, gv->NZ,
+        n = buffer_pop(stress.sxz, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2 - 1, 1, gv->NZ,
                        n);
     }
 
     if (recv_rig_to_lef) {
-        n = buffer_pop(stress->sxy, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NZ, 0);
-        n = buffer_pop(stress->sxz, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NZ, n);
-        n = buffer_pop(stress->sxx, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, n);
+        n = buffer_pop(stress.sxy, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NZ, 0);
+        n = buffer_pop(stress.sxz, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NZ, n);
+        n = buffer_pop(stress.sxx, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, n);
     }
 
     /* front-back ----------------------------------------------------------- */
 
     if (send_fro_to_bac) {
-        n = buffer_push(buffer->fro_to_bac, stress->szz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, 0);
-        n = buffer_push(buffer->fro_to_bac, stress->syz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2 - 1, n);
-        n = buffer_push(buffer->fro_to_bac, stress->sxz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2 - 1, n);
+        n = buffer_push(buffer->fro_to_bac, stress.szz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, 0);
+        n = buffer_push(buffer->fro_to_bac, stress.syz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2 - 1, n);
+        n = buffer_push(buffer->fro_to_bac, stress.sxz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2 - 1, n);
     }
 
     if (send_bac_to_fro) {
-        n = buffer_push(buffer->bac_to_fro, stress->syz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
+        n = buffer_push(buffer->bac_to_fro, stress.syz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
                         gv->NZ + 1 - gv->FDORDER / 2, 0);
-        n = buffer_push(buffer->bac_to_fro, stress->sxz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
+        n = buffer_push(buffer->bac_to_fro, stress.sxz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
                         gv->NZ + 1 - gv->FDORDER / 2, n);
-        n = buffer_push(buffer->bac_to_fro, stress->szz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
+        n = buffer_push(buffer->bac_to_fro, stress.szz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
                         gv->NZ + 1 - (gv->FDORDER / 2 - 1), n);
     }
 
@@ -177,17 +177,17 @@ double exchange_s(st_stress *stress, st_buffer_flat *buffer, GlobVar *gv)
                          gv->COMM_SHOT, &status);
 
     if (recv_fro_to_bac) {
-        n = buffer_pop(stress->szz, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2, 0);
-        n = buffer_pop(stress->syz, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2 - 1,
+        n = buffer_pop(stress.szz, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2, 0);
+        n = buffer_pop(stress.syz, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2 - 1,
                        n);
-        n = buffer_pop(stress->sxz, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2 - 1,
+        n = buffer_pop(stress.sxz, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2 - 1,
                        n);
     }
 
     if (recv_bac_to_fro) {
-        n = buffer_pop(stress->syz, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - gv->FDORDER / 2, 0);
-        n = buffer_pop(stress->sxz, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - gv->FDORDER / 2, n);
-        n = buffer_pop(stress->szz, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1), n);
+        n = buffer_pop(stress.syz, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - gv->FDORDER / 2, 0);
+        n = buffer_pop(stress.sxz, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - gv->FDORDER / 2, n);
+        n = buffer_pop(stress.szz, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1), n);
     }
 
     return time;
@@ -196,7 +196,7 @@ double exchange_s(st_stress *stress, st_buffer_flat *buffer, GlobVar *gv)
 
 #ifdef MPI_ISENDRECV_REPLACE
 // requires OpenMPI version >= 5.0
-double exchange_s(st_stress *stress, st_buffer_flat *buffer, GlobVar *gv)
+double exchange_s(st_stress &stress, st_buffer_flat *buffer, GlobVar *gv)
 {
     MPI_Request requests[] = { MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL,
                                MPI_REQUEST_NULL };
@@ -250,20 +250,20 @@ double exchange_s(st_stress *stress, st_buffer_flat *buffer, GlobVar *gv)
     const bool send_bac_to_fro = gv->BOUNDARY || gv->POS[3] != gv->NPROCZ - 1;
 
     if (send_top_to_bot) {
-        n = buffer_push(buffer->top_to_bot, stress->syy, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
-        n = buffer_push(buffer->top_to_bot, stress->sxy, 1, gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ, n);
-        n = buffer_push(buffer->top_to_bot, stress->syz, 1, gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ, n);
+        n = buffer_push(buffer->top_to_bot, stress.syy, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
+        n = buffer_push(buffer->top_to_bot, stress.sxy, 1, gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ, n);
+        n = buffer_push(buffer->top_to_bot, stress.syz, 1, gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ, n);
     }
     MPI_Isendrecv_replace(buffer->top_to_bot, gv->NX * gv->NZ * nf2, MPI_FLOAT, gv->INDEX[upper], tag_top_to_bot,
                           gv->INDEX[lower], tag_top_to_bot,
                           gv->COMM_SHOT, request_top_to_bot);
 
     if (send_bot_to_top) {
-        n = buffer_push(buffer->bot_to_top, stress->sxy, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2), 1, gv->NX, 1,
+        n = buffer_push(buffer->bot_to_top, stress.sxy, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2), 1, gv->NX, 1,
                         gv->NZ, 0);
-        n = buffer_push(buffer->bot_to_top, stress->syz, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2), 1, gv->NX, 1,
+        n = buffer_push(buffer->bot_to_top, stress.syz, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2), 1, gv->NX, 1,
                         gv->NZ, n);
-        n = buffer_push(buffer->bot_to_top, stress->syy, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1, gv->NX,
+        n = buffer_push(buffer->bot_to_top, stress.syy, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1, gv->NX,
                         1, gv->NZ, n);
     }
     MPI_Isendrecv_replace(buffer->bot_to_top, gv->NX * gv->NZ * nf1, MPI_FLOAT, gv->INDEX[lower], tag_bot_to_top,
@@ -271,20 +271,20 @@ double exchange_s(st_stress *stress, st_buffer_flat *buffer, GlobVar *gv)
                           gv->COMM_SHOT, request_bot_to_top);
 
     if (send_lef_to_rig) {
-        n = buffer_push(buffer->lef_to_rig, stress->sxx, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, 0);
-        n = buffer_push(buffer->lef_to_rig, stress->sxy, 1, gv->NY, 1, gv->FDORDER / 2 - 1, 1, gv->NZ, n);
-        n = buffer_push(buffer->lef_to_rig, stress->sxz, 1, gv->NY, 1, gv->FDORDER / 2 - 1, 1, gv->NZ, n);
+        n = buffer_push(buffer->lef_to_rig, stress.sxx, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, 0);
+        n = buffer_push(buffer->lef_to_rig, stress.sxy, 1, gv->NY, 1, gv->FDORDER / 2 - 1, 1, gv->NZ, n);
+        n = buffer_push(buffer->lef_to_rig, stress.sxz, 1, gv->NY, 1, gv->FDORDER / 2 - 1, 1, gv->NZ, n);
     }
     MPI_Isendrecv_replace(buffer->lef_to_rig, gv->NY * gv->NZ * nf2, MPI_FLOAT, gv->INDEX[left], tag_lef_to_rig,
                           gv->INDEX[right], tag_lef_to_rig,
                           gv->COMM_SHOT, request_lef_to_rig);
 
     if (send_rig_to_lef) {
-        n = buffer_push(buffer->rig_to_lef, stress->sxy, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - gv->FDORDER / 2, 1,
+        n = buffer_push(buffer->rig_to_lef, stress.sxy, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - gv->FDORDER / 2, 1,
                         gv->NZ, 0);
-        n = buffer_push(buffer->rig_to_lef, stress->sxz, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - gv->FDORDER / 2, 1,
+        n = buffer_push(buffer->rig_to_lef, stress.sxz, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - gv->FDORDER / 2, 1,
                         gv->NZ, n);
-        n = buffer_push(buffer->rig_to_lef, stress->sxx, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - (gv->FDORDER / 2 - 1),
+        n = buffer_push(buffer->rig_to_lef, stress.sxx, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - (gv->FDORDER / 2 - 1),
                         1, gv->NZ, n);
     }
     MPI_Isendrecv_replace(buffer->rig_to_lef, gv->NY * gv->NZ * nf1, MPI_FLOAT, gv->INDEX[right], tag_rig_to_lef,
@@ -292,20 +292,20 @@ double exchange_s(st_stress *stress, st_buffer_flat *buffer, GlobVar *gv)
                           gv->COMM_SHOT, request_rig_to_lef);
 
     if (send_fro_to_bac) {
-        n = buffer_push(buffer->fro_to_bac, stress->szz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, 0);
-        n = buffer_push(buffer->fro_to_bac, stress->syz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2 - 1, n);
-        n = buffer_push(buffer->fro_to_bac, stress->sxz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2 - 1, n);
+        n = buffer_push(buffer->fro_to_bac, stress.szz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, 0);
+        n = buffer_push(buffer->fro_to_bac, stress.syz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2 - 1, n);
+        n = buffer_push(buffer->fro_to_bac, stress.sxz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2 - 1, n);
     }
     MPI_Isendrecv_replace(buffer->fro_to_bac, gv->NX * gv->NY * nf2, MPI_FLOAT, gv->INDEX[front], tag_fro_to_bac,
                           gv->INDEX[back], tag_fro_to_bac,
                           gv->COMM_SHOT, request_fro_to_bac);
 
     if (send_bac_to_fro) {
-        n = buffer_push(buffer->bac_to_fro, stress->syz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
+        n = buffer_push(buffer->bac_to_fro, stress.syz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
                         gv->NZ + 1 - gv->FDORDER / 2, 0);
-        n = buffer_push(buffer->bac_to_fro, stress->sxz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
+        n = buffer_push(buffer->bac_to_fro, stress.sxz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
                         gv->NZ + 1 - gv->FDORDER / 2, n);
-        n = buffer_push(buffer->bac_to_fro, stress->szz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
+        n = buffer_push(buffer->bac_to_fro, stress.szz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
                         gv->NZ + 1 - (gv->FDORDER / 2 - 1), n);
     }
     MPI_Isendrecv_replace(buffer->bac_to_fro, gv->NX * gv->NY * nf1, MPI_FLOAT, gv->INDEX[back], tag_bac_to_fro,
@@ -321,43 +321,43 @@ double exchange_s(st_stress *stress, st_buffer_flat *buffer, GlobVar *gv)
 
         switch (status.MPI_TAG) {
         case tag_top_to_bot:
-            n = buffer_pop(stress->syy, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ,
+            n = buffer_pop(stress.syy, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ,
                            0);
-            n = buffer_pop(stress->sxy, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2 - 1, 1, gv->NX, 1,
+            n = buffer_pop(stress.sxy, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2 - 1, 1, gv->NX, 1,
                            gv->NZ, n);
-            n = buffer_pop(stress->syz, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2 - 1, 1, gv->NX, 1,
+            n = buffer_pop(stress.syz, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2 - 1, 1, gv->NX, 1,
                            gv->NZ, n);
             break;
         case tag_bot_to_top:
-            n = buffer_pop(stress->sxy, buffer->bot_to_top, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
-            n = buffer_pop(stress->syz, buffer->bot_to_top, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, n);
-            n = buffer_pop(stress->syy, buffer->bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ, n);
+            n = buffer_pop(stress.sxy, buffer->bot_to_top, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
+            n = buffer_pop(stress.syz, buffer->bot_to_top, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, n);
+            n = buffer_pop(stress.syy, buffer->bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ, n);
             break;
         case tag_lef_to_rig:
-            n = buffer_pop(stress->sxx, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1, gv->NZ,
+            n = buffer_pop(stress.sxx, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1, gv->NZ,
                            0);
-            n = buffer_pop(stress->sxy, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2 - 1, 1,
+            n = buffer_pop(stress.sxy, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2 - 1, 1,
                            gv->NZ, n);
-            n = buffer_pop(stress->sxz, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2 - 1, 1,
+            n = buffer_pop(stress.sxz, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2 - 1, 1,
                            gv->NZ, n);
             break;
         case tag_rig_to_lef:
-            n = buffer_pop(stress->sxy, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NZ, 0);
-            n = buffer_pop(stress->sxz, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NZ, n);
-            n = buffer_pop(stress->sxx, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, n);
+            n = buffer_pop(stress.sxy, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NZ, 0);
+            n = buffer_pop(stress.sxz, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NZ, n);
+            n = buffer_pop(stress.sxx, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, n);
             break;
         case tag_fro_to_bac:
-            n = buffer_pop(stress->szz, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2,
+            n = buffer_pop(stress.szz, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2,
                            0);
-            n = buffer_pop(stress->syz, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1,
+            n = buffer_pop(stress.syz, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1,
                            gv->NZ + gv->FDORDER / 2 - 1, n);
-            n = buffer_pop(stress->sxz, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1,
+            n = buffer_pop(stress.sxz, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1,
                            gv->NZ + gv->FDORDER / 2 - 1, n);
             break;
         case tag_bac_to_fro:
-            n = buffer_pop(stress->syz, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - gv->FDORDER / 2, 0);
-            n = buffer_pop(stress->sxz, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - gv->FDORDER / 2, n);
-            n = buffer_pop(stress->szz, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1), n);
+            n = buffer_pop(stress.syz, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - gv->FDORDER / 2, 0);
+            n = buffer_pop(stress.sxz, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - gv->FDORDER / 2, n);
+            n = buffer_pop(stress.szz, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1), n);
             break;
         }
     }
@@ -367,7 +367,7 @@ double exchange_s(st_stress *stress, st_buffer_flat *buffer, GlobVar *gv)
 #endif
 
 #ifdef MPI_ISEND_IRECV
-double exchange_s(st_stress *stress, st_buffer_flat *buffer, GlobVar *gv)
+double exchange_s(st_stress &stress, st_buffer_flat *buffer, GlobVar *gv)
 {
     MPI_Request send_requests[] = { MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL,
                                     MPI_REQUEST_NULL, MPI_REQUEST_NULL };
@@ -463,57 +463,57 @@ double exchange_s(st_stress *stress, st_buffer_flat *buffer, GlobVar *gv)
 
     // Send in background
     if (send_top_to_bot) {
-        n = buffer_push(buffer->send_top_to_bot, stress->syy, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
-        n = buffer_push(buffer->send_top_to_bot, stress->sxy, 1, gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ, n);
-        n = buffer_push(buffer->send_top_to_bot, stress->syz, 1, gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ, n);
+        n = buffer_push(buffer->send_top_to_bot, stress.syy, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
+        n = buffer_push(buffer->send_top_to_bot, stress.sxy, 1, gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ, n);
+        n = buffer_push(buffer->send_top_to_bot, stress.syz, 1, gv->FDORDER / 2 - 1, 1, gv->NX, 1, gv->NZ, n);
         MPI_Isend(buffer->send_top_to_bot, n, MPI_FLOAT, gv->INDEX[upper], tag_top_to_bot, gv->COMM_SHOT,
                   request_send_top_to_bot);
     }
 
     if (send_bot_to_top) {
-        n = buffer_push(buffer->send_bot_to_top, stress->sxy, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2), 1, gv->NX,
+        n = buffer_push(buffer->send_bot_to_top, stress.sxy, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2), 1, gv->NX,
                         1, gv->NZ, 0);
-        n = buffer_push(buffer->send_bot_to_top, stress->syz, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2), 1, gv->NX,
+        n = buffer_push(buffer->send_bot_to_top, stress.syz, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2), 1, gv->NX,
                         1, gv->NZ, n);
-        n = buffer_push(buffer->send_bot_to_top, stress->syy, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1,
+        n = buffer_push(buffer->send_bot_to_top, stress.syy, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1,
                         gv->NX, 1, gv->NZ, n);
         MPI_Isend(buffer->send_bot_to_top, n, MPI_FLOAT, gv->INDEX[lower], tag_bot_to_top, gv->COMM_SHOT,
                   request_send_bot_to_top);
     }
 
     if (send_lef_to_rig) {
-        n = buffer_push(buffer->send_lef_to_rig, stress->sxx, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, 0);
-        n = buffer_push(buffer->send_lef_to_rig, stress->sxy, 1, gv->NY, 1, gv->FDORDER / 2 - 1, 1, gv->NZ, n);
-        n = buffer_push(buffer->send_lef_to_rig, stress->sxz, 1, gv->NY, 1, gv->FDORDER / 2 - 1, 1, gv->NZ, n);
+        n = buffer_push(buffer->send_lef_to_rig, stress.sxx, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, 0);
+        n = buffer_push(buffer->send_lef_to_rig, stress.sxy, 1, gv->NY, 1, gv->FDORDER / 2 - 1, 1, gv->NZ, n);
+        n = buffer_push(buffer->send_lef_to_rig, stress.sxz, 1, gv->NY, 1, gv->FDORDER / 2 - 1, 1, gv->NZ, n);
         MPI_Isend(buffer->send_lef_to_rig, n, MPI_FLOAT, gv->INDEX[left], tag_lef_to_rig, gv->COMM_SHOT,
                   request_send_lef_to_rig);
     }
 
     if (send_rig_to_lef) {
-        n = buffer_push(buffer->send_rig_to_lef, stress->sxy, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - gv->FDORDER / 2,
+        n = buffer_push(buffer->send_rig_to_lef, stress.sxy, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - gv->FDORDER / 2,
                         1, gv->NZ, 0);
-        n = buffer_push(buffer->send_rig_to_lef, stress->sxz, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - gv->FDORDER / 2,
+        n = buffer_push(buffer->send_rig_to_lef, stress.sxz, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - gv->FDORDER / 2,
                         1, gv->NZ, n);
-        n = buffer_push(buffer->send_rig_to_lef, stress->sxx, 1, gv->NY, gv->NX + 1 - 1,
+        n = buffer_push(buffer->send_rig_to_lef, stress.sxx, 1, gv->NY, gv->NX + 1 - 1,
                         gv->NX + 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, n);
         MPI_Isend(buffer->send_rig_to_lef, n, MPI_FLOAT, gv->INDEX[right], tag_rig_to_lef, gv->COMM_SHOT,
                   request_send_rig_to_lef);
     }
 
     if (send_fro_to_bac) {
-        n = buffer_push(buffer->send_fro_to_bac, stress->szz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, 0);
-        n = buffer_push(buffer->send_fro_to_bac, stress->syz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2 - 1, n);
-        n = buffer_push(buffer->send_fro_to_bac, stress->sxz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2 - 1, n);
+        n = buffer_push(buffer->send_fro_to_bac, stress.szz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, 0);
+        n = buffer_push(buffer->send_fro_to_bac, stress.syz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2 - 1, n);
+        n = buffer_push(buffer->send_fro_to_bac, stress.sxz, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2 - 1, n);
         MPI_Isend(buffer->send_fro_to_bac, n, MPI_FLOAT, gv->INDEX[front], tag_fro_to_bac, gv->COMM_SHOT,
                   request_send_fro_to_bac);
     }
 
     if (send_bac_to_fro) {
-        n = buffer_push(buffer->send_bac_to_fro, stress->syz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
+        n = buffer_push(buffer->send_bac_to_fro, stress.syz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
                         gv->NZ + 1 - gv->FDORDER / 2, 0);
-        n = buffer_push(buffer->send_bac_to_fro, stress->sxz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
+        n = buffer_push(buffer->send_bac_to_fro, stress.sxz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
                         gv->NZ + 1 - gv->FDORDER / 2, n);
-        n = buffer_push(buffer->send_bac_to_fro, stress->szz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
+        n = buffer_push(buffer->send_bac_to_fro, stress.szz, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
                         gv->NZ + 1 - (gv->FDORDER / 2 - 1), n);
         MPI_Isend(buffer->send_bac_to_fro, n, MPI_FLOAT, gv->INDEX[back], tag_bac_to_fro, gv->COMM_SHOT,
                   request_send_bac_to_fro);
@@ -528,45 +528,45 @@ double exchange_s(st_stress *stress, st_buffer_flat *buffer, GlobVar *gv)
 
         switch (status.MPI_TAG) {
         case tag_top_to_bot:
-            n = buffer_pop(stress->syy, buffer->recv_top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1,
+            n = buffer_pop(stress.syy, buffer->recv_top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1,
                            gv->NZ, 0);
-            n = buffer_pop(stress->sxy, buffer->recv_top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2 - 1, 1, gv->NX, 1,
+            n = buffer_pop(stress.sxy, buffer->recv_top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2 - 1, 1, gv->NX, 1,
                            gv->NZ, n);
-            n = buffer_pop(stress->syz, buffer->recv_top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2 - 1, 1, gv->NX, 1,
+            n = buffer_pop(stress.syz, buffer->recv_top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2 - 1, 1, gv->NX, 1,
                            gv->NZ, n);
             break;
         case tag_bot_to_top:
-            n = buffer_pop(stress->sxy, buffer->recv_bot_to_top, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
-            n = buffer_pop(stress->syz, buffer->recv_bot_to_top, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, n);
-            n = buffer_pop(stress->syy, buffer->recv_bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ,
+            n = buffer_pop(stress.sxy, buffer->recv_bot_to_top, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
+            n = buffer_pop(stress.syz, buffer->recv_bot_to_top, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, n);
+            n = buffer_pop(stress.syy, buffer->recv_bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ,
                            n);
             break;
         case tag_lef_to_rig:
-            n = buffer_pop(stress->sxx, buffer->recv_lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1,
+            n = buffer_pop(stress.sxx, buffer->recv_lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1,
                            gv->NZ, 0);
-            n = buffer_pop(stress->sxy, buffer->recv_lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2 - 1, 1,
+            n = buffer_pop(stress.sxy, buffer->recv_lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2 - 1, 1,
                            gv->NZ, n);
-            n = buffer_pop(stress->sxz, buffer->recv_lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2 - 1, 1,
+            n = buffer_pop(stress.sxz, buffer->recv_lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2 - 1, 1,
                            gv->NZ, n);
             break;
         case tag_rig_to_lef:
-            n = buffer_pop(stress->sxy, buffer->recv_rig_to_lef, 1, gv->NY, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NZ, 0);
-            n = buffer_pop(stress->sxz, buffer->recv_rig_to_lef, 1, gv->NY, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NZ, n);
-            n = buffer_pop(stress->sxx, buffer->recv_rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ,
+            n = buffer_pop(stress.sxy, buffer->recv_rig_to_lef, 1, gv->NY, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NZ, 0);
+            n = buffer_pop(stress.sxz, buffer->recv_rig_to_lef, 1, gv->NY, 1 - 1, 1 - gv->FDORDER / 2, 1, gv->NZ, n);
+            n = buffer_pop(stress.sxx, buffer->recv_rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ,
                            n);
             break;
         case tag_fro_to_bac:
-            n = buffer_pop(stress->szz, buffer->recv_fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1,
+            n = buffer_pop(stress.szz, buffer->recv_fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1,
                            gv->NZ + gv->FDORDER / 2, 0);
-            n = buffer_pop(stress->syz, buffer->recv_fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1,
+            n = buffer_pop(stress.syz, buffer->recv_fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1,
                            gv->NZ + gv->FDORDER / 2 - 1, n);
-            n = buffer_pop(stress->sxz, buffer->recv_fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1,
+            n = buffer_pop(stress.sxz, buffer->recv_fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1,
                            gv->NZ + gv->FDORDER / 2 - 1, n);
             break;
         case tag_bac_to_fro:
-            n = buffer_pop(stress->syz, buffer->recv_bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - gv->FDORDER / 2, 0);
-            n = buffer_pop(stress->sxz, buffer->recv_bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - gv->FDORDER / 2, n);
-            n = buffer_pop(stress->szz, buffer->recv_bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1),
+            n = buffer_pop(stress.syz, buffer->recv_bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - gv->FDORDER / 2, 0);
+            n = buffer_pop(stress.sxz, buffer->recv_bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - gv->FDORDER / 2, n);
+            n = buffer_pop(stress.szz, buffer->recv_bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1),
                            n);
             break;
         }
diff --git a/src/exchange_s_acoustic.cpp b/src/exchange_s_acoustic.cpp
index de9092b..552f5bd 100644
--- a/src/exchange_s_acoustic.cpp
+++ b/src/exchange_s_acoustic.cpp
@@ -26,7 +26,7 @@
 #include "fd.hpp"
 
 #ifdef MPI_SENDRECV_REPLACE
-double exchange_s_acoustic(st_stress *stress, st_buffer_flat *buffer, GlobVar *gv)
+double exchange_s_acoustic(st_stress &stress, st_buffer_flat *buffer, GlobVar *gv)
 {
     MPI_Status status;
     int n;
@@ -79,11 +79,11 @@ double exchange_s_acoustic(st_stress *stress, st_buffer_flat *buffer, GlobVar *g
     /* top-bottom ----------------------------------------------------------- */
 
     if (send_top_to_bot) {
-        n = buffer_push(buffer->top_to_bot, stress->sp, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
+        n = buffer_push(buffer->top_to_bot, stress.sp, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
     }
 
     if (send_bot_to_top) {
-        n = buffer_push(buffer->bot_to_top, stress->sp, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1, gv->NX,
+        n = buffer_push(buffer->bot_to_top, stress.sp, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1, gv->NX,
                         1, gv->NZ, 0);
     }
 
@@ -95,21 +95,21 @@ double exchange_s_acoustic(st_stress *stress, st_buffer_flat *buffer, GlobVar *g
                          gv->COMM_SHOT, &status);
 
     if (recv_top_to_bot) {
-        n = buffer_pop(stress->sp, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
+        n = buffer_pop(stress.sp, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
     }
 
     if (recv_bot_to_top) {
-        n = buffer_pop(stress->sp, buffer->bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ, 0);
+        n = buffer_pop(stress.sp, buffer->bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ, 0);
     }
 
     /* left-right ----------------------------------------------------------- */
 
     if (send_lef_to_rig) {
-        n = buffer_push(buffer->lef_to_rig, stress->sp, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, 0);
+        n = buffer_push(buffer->lef_to_rig, stress.sp, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, 0);
     }
 
     if (send_rig_to_lef) {
-        n = buffer_push(buffer->rig_to_lef, stress->sp, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - (gv->FDORDER / 2 - 1),
+        n = buffer_push(buffer->rig_to_lef, stress.sp, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - (gv->FDORDER / 2 - 1),
                         1, gv->NZ, 0);
     }
 
@@ -121,21 +121,21 @@ double exchange_s_acoustic(st_stress *stress, st_buffer_flat *buffer, GlobVar *g
                          gv->COMM_SHOT, &status);
 
     if (recv_lef_to_rig) {
-        n = buffer_pop(stress->sp, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1, gv->NZ, 0);
+        n = buffer_pop(stress.sp, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1, gv->NZ, 0);
     }
 
     if (recv_rig_to_lef) {
-        n = buffer_pop(stress->sp, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, 0);
+        n = buffer_pop(stress.sp, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, 0);
     }
 
     /* front-back ----------------------------------------------------------- */
 
     if (send_fro_to_bac) {
-        n = buffer_push(buffer->fro_to_bac, stress->sp, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, 0);
+        n = buffer_push(buffer->fro_to_bac, stress.sp, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, 0);
     }
 
     if (send_bac_to_fro) {
-        n = buffer_push(buffer->bac_to_fro, stress->sp, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
+        n = buffer_push(buffer->bac_to_fro, stress.sp, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
                         gv->NZ + 1 - (gv->FDORDER / 2 - 1), 0);
     }
 
@@ -147,11 +147,11 @@ double exchange_s_acoustic(st_stress *stress, st_buffer_flat *buffer, GlobVar *g
                          gv->COMM_SHOT, &status);
 
     if (recv_fro_to_bac) {
-        n = buffer_pop(stress->sp, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2, 0);
+        n = buffer_pop(stress.sp, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2, 0);
     }
 
     if (recv_bac_to_fro) {
-        n = buffer_pop(stress->sp, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 0);
+        n = buffer_pop(stress.sp, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 0);
     }
 
     return time;
@@ -160,7 +160,7 @@ double exchange_s_acoustic(st_stress *stress, st_buffer_flat *buffer, GlobVar *g
 
 #ifdef MPI_ISENDRECV_REPLACE
 // requires OpenMPI version >= 5.0
-double exchange_s_acoustic(st_stress *stress, st_buffer_flat *buffer, GlobVar *gv)
+double exchange_s_acoustic(st_stress &stress, st_buffer_flat *buffer, GlobVar *gv)
 {
     MPI_Request requests[] = { MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL,
                                MPI_REQUEST_NULL };
@@ -214,14 +214,14 @@ double exchange_s_acoustic(st_stress *stress, st_buffer_flat *buffer, GlobVar *g
     const bool send_bac_to_fro = gv->BOUNDARY || gv->POS[3] != gv->NPROCZ - 1;
 
     if (send_top_to_bot) {
-        n = buffer_push(buffer->top_to_bot, stress->sp, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
+        n = buffer_push(buffer->top_to_bot, stress.sp, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
     }
     MPI_Isendrecv_replace(buffer->top_to_bot, gv->NX * gv->NZ * nf2, MPI_FLOAT, gv->INDEX[upper], tag_top_to_bot,
                           gv->INDEX[lower], tag_top_to_bot,
                           gv->COMM_SHOT, request_top_to_bot);
 
     if (send_bot_to_top) {
-        n = buffer_push(buffer->bot_to_top, stress->sp, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1, gv->NX,
+        n = buffer_push(buffer->bot_to_top, stress.sp, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1, gv->NX,
                         1, gv->NZ, 0);
     }
     MPI_Isendrecv_replace(buffer->bot_to_top, gv->NX * gv->NZ * nf1, MPI_FLOAT, gv->INDEX[lower], tag_bot_to_top,
@@ -229,14 +229,14 @@ double exchange_s_acoustic(st_stress *stress, st_buffer_flat *buffer, GlobVar *g
                           gv->COMM_SHOT, request_bot_to_top);
 
     if (send_lef_to_rig) {
-        n = buffer_push(buffer->lef_to_rig, stress->sp, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, 0);
+        n = buffer_push(buffer->lef_to_rig, stress.sp, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, 0);
     }
     MPI_Isendrecv_replace(buffer->lef_to_rig, gv->NY * gv->NZ * nf2, MPI_FLOAT, gv->INDEX[left], tag_lef_to_rig,
                           gv->INDEX[right], tag_lef_to_rig,
                           gv->COMM_SHOT, request_lef_to_rig);
 
     if (send_rig_to_lef) {
-        n = buffer_push(buffer->rig_to_lef, stress->sp, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - (gv->FDORDER / 2 - 1),
+        n = buffer_push(buffer->rig_to_lef, stress.sp, 1, gv->NY, gv->NX + 1 - 1, gv->NX + 1 - (gv->FDORDER / 2 - 1),
                         1, gv->NZ, 0);
     }
     MPI_Isendrecv_replace(buffer->rig_to_lef, gv->NY * gv->NZ * nf1, MPI_FLOAT, gv->INDEX[right], tag_rig_to_lef,
@@ -244,14 +244,14 @@ double exchange_s_acoustic(st_stress *stress, st_buffer_flat *buffer, GlobVar *g
                           gv->COMM_SHOT, request_rig_to_lef);
 
     if (send_fro_to_bac) {
-        n = buffer_push(buffer->fro_to_bac, stress->sp, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, 0);
+        n = buffer_push(buffer->fro_to_bac, stress.sp, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, 0);
     }
     MPI_Isendrecv_replace(buffer->fro_to_bac, gv->NX * gv->NY * nf2, MPI_FLOAT, gv->INDEX[front], tag_fro_to_bac,
                           gv->INDEX[back], tag_fro_to_bac,
                           gv->COMM_SHOT, request_fro_to_bac);
 
     if (send_bac_to_fro) {
-        n = buffer_push(buffer->bac_to_fro, stress->sp, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
+        n = buffer_push(buffer->bac_to_fro, stress.sp, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
                         gv->NZ + 1 - (gv->FDORDER / 2 - 1), 0);
     }
     MPI_Isendrecv_replace(buffer->bac_to_fro, gv->NX * gv->NY * nf1, MPI_FLOAT, gv->INDEX[back], tag_bac_to_fro,
@@ -267,25 +267,25 @@ double exchange_s_acoustic(st_stress *stress, st_buffer_flat *buffer, GlobVar *g
 
         switch (status.MPI_TAG) {
         case tag_top_to_bot:
-            n = buffer_pop(stress->sp, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ,
+            n = buffer_pop(stress.sp, buffer->top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ,
                            0);
             break;
         case tag_bot_to_top:
-            n = buffer_pop(stress->sp, buffer->bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ, 0);
+            n = buffer_pop(stress.sp, buffer->bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ, 0);
             break;
         case tag_lef_to_rig:
-            n = buffer_pop(stress->sp, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1, gv->NZ,
+            n = buffer_pop(stress.sp, buffer->lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1, gv->NZ,
                            0);
             break;
         case tag_rig_to_lef:
-            n = buffer_pop(stress->sp, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, 0);
+            n = buffer_pop(stress.sp, buffer->rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, 0);
             break;
         case tag_fro_to_bac:
-            n = buffer_pop(stress->sp, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2,
+            n = buffer_pop(stress.sp, buffer->fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1, gv->NZ + gv->FDORDER / 2,
                            0);
             break;
         case tag_bac_to_fro:
-            n = buffer_pop(stress->sp, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 0);
+            n = buffer_pop(stress.sp, buffer->bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 0);
             break;
         }
     }
@@ -295,7 +295,7 @@ double exchange_s_acoustic(st_stress *stress, st_buffer_flat *buffer, GlobVar *g
 #endif
 
 #ifdef MPI_ISEND_IRECV
-double exchange_s_acoustic(st_stress *stress, st_buffer_flat *buffer, GlobVar *gv)
+double exchange_s_acoustic(st_stress &stress, st_buffer_flat *buffer, GlobVar *gv)
 {
     MPI_Request send_requests[] = { MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL,
                                     MPI_REQUEST_NULL, MPI_REQUEST_NULL };
@@ -391,39 +391,39 @@ double exchange_s_acoustic(st_stress *stress, st_buffer_flat *buffer, GlobVar *g
 
     // Send in background
     if (send_top_to_bot) {
-        n = buffer_push(buffer->send_top_to_bot, stress->sp, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
+        n = buffer_push(buffer->send_top_to_bot, stress.sp, 1, gv->FDORDER / 2, 1, gv->NX, 1, gv->NZ, 0);
         MPI_Isend(buffer->send_top_to_bot, n, MPI_FLOAT, gv->INDEX[upper], tag_top_to_bot, gv->COMM_SHOT,
                   request_send_top_to_bot);
     }
 
     if (send_bot_to_top) {
-        n = buffer_push(buffer->send_bot_to_top, stress->sp, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1,
+        n = buffer_push(buffer->send_bot_to_top, stress.sp, gv->NY + 1 - 1, gv->NY + 1 - (gv->FDORDER / 2 - 1), 1,
                         gv->NX, 1, gv->NZ, 0);
         MPI_Isend(buffer->send_bot_to_top, n, MPI_FLOAT, gv->INDEX[lower], tag_bot_to_top, gv->COMM_SHOT,
                   request_send_bot_to_top);
     }
 
     if (send_lef_to_rig) {
-        n = buffer_push(buffer->send_lef_to_rig, stress->sp, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, 0);
+        n = buffer_push(buffer->send_lef_to_rig, stress.sp, 1, gv->NY, 1, gv->FDORDER / 2, 1, gv->NZ, 0);
         MPI_Isend(buffer->send_lef_to_rig, n, MPI_FLOAT, gv->INDEX[left], tag_lef_to_rig, gv->COMM_SHOT,
                   request_send_lef_to_rig);
     }
 
     if (send_rig_to_lef) {
-        n = buffer_push(buffer->send_rig_to_lef, stress->sp, 1, gv->NY, gv->NX + 1 - 1,
+        n = buffer_push(buffer->send_rig_to_lef, stress.sp, 1, gv->NY, gv->NX + 1 - 1,
                         gv->NX + 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ, 0);
         MPI_Isend(buffer->send_rig_to_lef, n, MPI_FLOAT, gv->INDEX[right], tag_rig_to_lef, gv->COMM_SHOT,
                   request_send_rig_to_lef);
     }
 
     if (send_fro_to_bac) {
-        n = buffer_push(buffer->send_fro_to_bac, stress->sp, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, 0);
+        n = buffer_push(buffer->send_fro_to_bac, stress.sp, 1, gv->NY, 1, gv->NX, 1, gv->FDORDER / 2, 0);
         MPI_Isend(buffer->send_fro_to_bac, n, MPI_FLOAT, gv->INDEX[front], tag_fro_to_bac, gv->COMM_SHOT,
                   request_send_fro_to_bac);
     }
 
     if (send_bac_to_fro) {
-        n = buffer_push(buffer->send_bac_to_fro, stress->sp, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
+        n = buffer_push(buffer->send_bac_to_fro, stress.sp, 1, gv->NY, 1, gv->NX, gv->NZ + 1 - 1,
                         gv->NZ + 1 - (gv->FDORDER / 2 - 1), 0);
         MPI_Isend(buffer->send_bac_to_fro, n, MPI_FLOAT, gv->INDEX[back], tag_bac_to_fro, gv->COMM_SHOT,
                   request_send_bac_to_fro);
@@ -438,27 +438,27 @@ double exchange_s_acoustic(st_stress *stress, st_buffer_flat *buffer, GlobVar *g
 
         switch (status.MPI_TAG) {
         case tag_top_to_bot:
-            n = buffer_pop(stress->sp, buffer->recv_top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1,
+            n = buffer_pop(stress.sp, buffer->recv_top_to_bot, gv->NY + 1, gv->NY + gv->FDORDER / 2, 1, gv->NX, 1,
                            gv->NZ, 0);
             break;
         case tag_bot_to_top:
-            n = buffer_pop(stress->sp, buffer->recv_bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ,
+            n = buffer_pop(stress.sp, buffer->recv_bot_to_top, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NX, 1, gv->NZ,
                            0);
             break;
         case tag_lef_to_rig:
-            n = buffer_pop(stress->sp, buffer->recv_lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1,
+            n = buffer_pop(stress.sp, buffer->recv_lef_to_rig, 1, gv->NY, gv->NX + 1, gv->NX + gv->FDORDER / 2, 1,
                            gv->NZ, 0);
             break;
         case tag_rig_to_lef:
-            n = buffer_pop(stress->sp, buffer->recv_rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ,
+            n = buffer_pop(stress.sp, buffer->recv_rig_to_lef, 1, gv->NY, 1 - 1, 1 - (gv->FDORDER / 2 - 1), 1, gv->NZ,
                            0);
             break;
         case tag_fro_to_bac:
-            n = buffer_pop(stress->sp, buffer->recv_fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1,
+            n = buffer_pop(stress.sp, buffer->recv_fro_to_bac, 1, gv->NY, 1, gv->NX, gv->NZ + 1,
                            gv->NZ + gv->FDORDER / 2, 0);
             break;
         case tag_bac_to_fro:
-            n = buffer_pop(stress->sp, buffer->recv_bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1),
+            n = buffer_pop(stress.sp, buffer->recv_bac_to_fro, 1, gv->NY, 1, gv->NX, 1 - 1, 1 - (gv->FDORDER / 2 - 1),
                            0);
             break;
         }
diff --git a/src/fd.hpp b/src/fd.hpp
index ef24d7a..46773cf 100644
--- a/src/fd.hpp
+++ b/src/fd.hpp
@@ -53,10 +53,10 @@ typedef struct Model_AV {
 
 typedef struct Stress {
     // pressure
-    float ***         sp;
+    float3DTensorT         sp;
     // stress tensor
-    float ***__restrict__ sxx, ***__restrict__ syy, ***__restrict__ szz;
-    float ***__restrict__ sxy, ***__restrict__ syz, ***__restrict__ sxz;
+    float3DTensorT sxx, syy, szz;
+    float3DTensorT sxy, syz, sxz;
 } st_stress;
 
 typedef struct Particle_velocity {
@@ -187,7 +187,7 @@ void freemem(int nsrc_loc, st_acquisition *acq, st_model *mod,
              st_pml_wfd *pml_wfd, st_signals *signals,
              st_gradient *grad, st_gradient *grad_prior1, st_gradient *grad_prior2, st_gradient *grad_halo,
              st_hessian *hessian,
-             st_stress *stress, st_buffer_flat *stressbuff, st_freq_velocity *fourier_vel_back,
+             st_stress &stress, st_buffer_flat *stressbuff, st_freq_velocity *fourier_vel_back,
              st_freq_velocity *fourier_vel_fw, st_velocity &vel, st_buffer_flat *velbuff, const GlobVar *gv);
 
 void freemem_seis(int ntr_loc, st_seismogram *section, st_seismogram *section_obs, st_signals *signals,
@@ -197,7 +197,7 @@ void globvar_change(GlobVar *gv);
 
 int initmem(st_model *mod, st_model *testmod, st_model_av *mod_av, st_visc_mem *visco_mem,
             st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, st_gradient *grad, st_gradient *grad_prior1,
-            st_gradient *grad_prior2, st_gradient *grad_halo, st_hessian *hessian, st_stress *stress,
+            st_gradient *grad_prior2, st_gradient *grad_halo, st_hessian *hessian, st_stress &stress,
             st_buffer_flat *stressbuff,
             st_freq_velocity *fourier_vel_back, st_freq_velocity *fourier_vel_fw, st_velocity &vel,
             st_buffer_flat *velbuff, GlobVar *gv);
@@ -231,17 +231,17 @@ int plane_wave(float ***force_points);
 
 void CPML_ini_elastic(st_boundary *nb, const GlobVar *gv);
 
-void psource(int nt, st_stress *stress, float **srcpos_loc, float **signals, int nsrc, const GlobVar *gv, int sw);
+void psource(int nt, st_stress &stress, float **srcpos_loc, float **signals, int nsrc, const GlobVar *gv, int sw);
 
-void psource_rsg(st_stress *stress, float **srcpos_loc, float **signals, int nsrc);
+void psource_rsg(st_stress &stress, float **srcpos_loc, float **signals, int nsrc);
 
-void readbufs(st_stress *stress, st_buffer *buffer);
+void readbufs(st_stress &stress, st_buffer *buffer);
 
 void exchange_par(GlobVar *gv);
 
-void exchange_s_rsg(st_stress *stress, st_buffer *buffer);
+void exchange_s_rsg(st_stress &stress, st_buffer *buffer);
 
-double exchange_s(st_stress *stress, st_buffer_flat *buffer, GlobVar *gv);
+double exchange_s(st_stress &stress, st_buffer_flat *buffer, GlobVar *gv);
 
 void readbufv(st_velocity &vel, st_buffer *buffer);
 
@@ -269,25 +269,25 @@ void savesig(float **signals, st_acquisition *acq, int nsrc_loc, int ishot, int
 
 int **scan_topo(GlobVar *gv);
 
-void seismo(int lsamp, int ntr, int **recpos, st_seismogram *section, st_velocity &vel, st_stress *stress,
+void seismo(int lsamp, int ntr, int **recpos, st_seismogram *section, st_velocity &vel, st_stress &stress,
             st_model *mod, const GlobVar *gv);
 
 void seismo_rsg(int lsamp, int ntr, int **recpos, float **sectionvx, float **sectionvy,
                 float **sectionvz, float **sectiondiv, float **sectioncurl, float **sectionp,
-                st_velocity &vel, st_stress *stress, st_model *mod);
+                st_velocity &vel, st_stress &stress, st_model *mod);
 
-void snap(int nt, int nsnap, st_velocity &vel, st_stress *stress, const st_model *mod,
+void snap(int nt, int nsnap, st_velocity &vel, st_stress &stress, const st_model *mod,
           const st_boundary *nb, GlobVar *gv);
 
 void snap_rsg(FILE *fp, int nt, int nsnap, int format, int type,
-              st_velocity &vel, st_stress *stress, st_model *mod,
+              st_velocity &vel, st_stress &stress, st_model *mod,
               int idx, int idy, int idz, int nx1, int ny1, int nz1, int nx2, int ny2, int nz2);
 
 void snapmerge(int nsnap, GlobVar *gv);
 
 void sources(FILE *fpsrc, int *nsrc, float **srcpos, GlobVar *gv, int **topo);
 
-void stfi(st_acquisition *acq, st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress *stress,
+void stfi(st_acquisition *acq, st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress &stress,
           st_model *mod, st_model_av *mod_av, st_visc_mem *visco_mem, st_seismogram *section,
           st_seismogram *section_obs, st_signals *signals, int nsrc_loc, int ntr_loc, st_pml_coeff *pml_coeff,
           st_pml_wfd *pml_wfd, st_buffer_flat *stressbuff, st_buffer_flat *velbuff, st_freq_velocity *fourier_vel,
@@ -310,24 +310,24 @@ void splitrec(int *ntr_loc, st_acquisition *acq, const GlobVar *gv);
 float **splitsrc(float **srcpos, int *nsrc_loc, int nsrc, int *srcswitch, GlobVar *gv);
 
 void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, st_visc_mem *mem,
-             st_stress *stress, st_velocity &vel);
+             st_stress &stress, st_velocity &vel);
 
-void update_s_rsg(st_boundary *nb, st_velocity &vel, st_stress *stress,
+void update_s_rsg(st_boundary *nb, st_velocity &vel, st_stress &stress,
                   st_visc_mem *mem, st_model *mod, float ***taus, float ***taup, float *eta);
 
-void update_v(const st_boundary *nb, st_velocity &vel, st_stress *stress, st_model_av *mod_av,
+void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av *mod_av,
               float ***absorb_coeff, const GlobVar *gv);
 
-void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress *stress, st_model_av *mod_av,
+void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av *mod_av,
                    st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, const GlobVar *gv);
 
-void update_v_rsg(st_boundary *nb, int nt, st_velocity &vel, st_stress *stress,
+void update_v_rsg(st_boundary *nb, int nt, st_velocity &vel, st_stress &stress,
                   float ***rho, float **srcpos_loc, float **signals, int nsrc, float ***absorb_coeff);
 
 void wavelet(float **srcpos_loc, int nsrc, int sourceshape, float **signals, float **sig_raw, float freq,
              const GlobVar *gv);
 
-void writebufs(st_stress *stress, st_buffer *buffer);
+void writebufs(st_stress &stress, st_buffer *buffer);
 
 void writebufv(st_velocity &vel, st_buffer *buffer);
 
@@ -366,7 +366,7 @@ void readseis(int shot_id, float **section, const st_acquisition *acq, int ntr,
 void residual(float **sectiondata, float **section, float **sectiondiff, int ntr, int ns,
               double *L2, const float *finv, int nf, const GlobVar *gv);
 
-void zero_wavefield(st_velocity &vel, st_stress *stress, st_visc_mem *mem, st_pml_wfd *pml_wfd, const GlobVar *gv);
+void zero_wavefield(st_velocity &vel, st_stress &stress, st_visc_mem *mem, st_pml_wfd *pml_wfd, const GlobVar *gv);
 
 void gradient_F(int nx, int ny, int nz, st_freq_velocity *fw, st_freq_velocity *back, st_gradient *grad,
                 st_hessian *hessian,
@@ -399,14 +399,14 @@ void cpmodel(st_model *mod, st_model *testmod, const GlobVar *gv);
 void conjugate(st_gradient *grad, st_gradient *grad_prior1, st_gradient *grad_prior2,
                float *beta, int cdf, GlobVar *gv);
 
-double update_s_elastic(st_boundary *nb, st_velocity &vel, st_stress *stress,
+double update_s_elastic(st_boundary *nb, st_velocity &vel, st_stress &stress,
                         st_model *mod, st_model_av *mod_av, const GlobVar *gv);
 
 double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
-                             st_stress *stress, st_model *mod, st_model_av *mod_av, st_pml_coeff *pml_coeff,
+                             st_stress &stress, st_model *mod, st_model_av *mod_av, st_pml_coeff *pml_coeff,
                              st_pml_wfd *pml_wfd, const GlobVar *gv);
 
-void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, st_stress *stress,
+void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, st_stress &stress,
                      st_velocity &vel, const GlobVar *gv);
 
 void readinv(float *finv, int *nf, int *groupnum, int *itpergroup, int nfmax, GlobVar *gv);
@@ -433,7 +433,7 @@ void constant_boundary(const st_boundary *nb, st_model *mod, const GlobVar *gv);
 
 void constant_boundary_acoustic(const st_boundary *nb, st_model *mod, const GlobVar *gv);
 
-double exchange_s_acoustic(st_stress *stress, st_buffer_flat *buffer, GlobVar *gv);
+double exchange_s_acoustic(st_stress &stress, st_buffer_flat *buffer, GlobVar *gv);
 
 void gradient_F_acoustic(int nx, int ny, int nz, st_freq_velocity *fw, st_freq_velocity *back, st_gradient *grad,
                          st_hessian *hessian,
@@ -445,24 +445,24 @@ void modelupdate_acoustic(st_gradient *grad, st_model *mod, float step, int it_g
 
 void precon_grad_acoustic(int ishot, st_gradient *grad, st_acquisition *acq, GlobVar *gv);
 
-void surface_acoustic(int ndepth, st_stress *stress, const GlobVar *gv);
+void surface_acoustic(int ndepth, st_stress &stress, const GlobVar *gv);
 
-double update_s_acoustic(st_boundary *nb, st_velocity &vel, st_stress *stress, st_model *mod, const GlobVar *gv);
+double update_s_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress, st_model *mod, const GlobVar *gv);
 
 double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
-                              st_stress *stress, st_model *mod, st_pml_coeff *pml_coeff,
+                              st_stress &stress, st_model *mod, st_pml_coeff *pml_coeff,
                               st_pml_wfd *pml_wfd, const GlobVar *gv);
 
-void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress *stress,
+void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress &stress,
                        st_model_av *mod_av, float ***absorb_coeff, const GlobVar *gv);
 
-void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress *stress, st_model_av *mod_av,
+void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av *mod_av,
                             st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, const GlobVar *gv);
 
-void zero_wavefield_acoustic(st_velocity &vel, st_stress *stress, st_visc_mem *mem, st_pml_wfd *pml_wfd,
+void zero_wavefield_acoustic(st_velocity &vel, st_stress &stress, st_visc_mem *mem, st_pml_wfd *pml_wfd,
                              const GlobVar *gv);
 
-void timeloop(st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress *stress,
+void timeloop(st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress &stress,
               st_model *mod, st_model_av *mod_av, st_seismogram *section,
               float **srcpos_loc, int **recpos_loc, st_signals *signals, int nsrc_loc,
               float ***absorb_coeff, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd,
diff --git a/src/freemem.cpp b/src/freemem.cpp
index 435fdbd..c3faf37 100644
--- a/src/freemem.cpp
+++ b/src/freemem.cpp
@@ -28,7 +28,7 @@ void freemem(int nsrc_loc, st_acquisition *acq, st_model *mod, st_model *testmod
              st_model_av *mod_av, st_visc_mem *visco_mem, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd,
              st_signals *signals, st_gradient *grad, st_gradient *grad_prior1, st_gradient *grad_prior2,
              st_gradient *grad_halo,
-             st_hessian *hessian, st_stress *stress, st_buffer_flat *stressbuff, st_freq_velocity *fourier_vel_back,
+             st_hessian *hessian, st_stress &stress, st_buffer_flat *stressbuff, st_freq_velocity *fourier_vel_back,
              st_freq_velocity *fourier_vel_fw, st_velocity &vel, st_buffer_flat *velbuff, const GlobVar *gv)
 {
     int l;
@@ -43,12 +43,8 @@ void freemem(int nsrc_loc, st_acquisition *acq, st_model *mod, st_model *testmod
         vel.vy.free();
         vel.vz.free();
         if (gv->WEQ != 2) {
-            free_f3tensor(stress->sxy, 0 - gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                          gv->NX + l * gv->FDORDER / 2,
-                          1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
-            free_f3tensor(stress->syz, 0 - gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                          gv->NX + l * gv->FDORDER / 2,
-                          1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
+            stress.sxy.free();
+            stress.syz.free();
         }
         if (gv->METHOD) {
             free_f4tensor(fourier_vel_fw->Fvx_re, 1, gv->NFMAX, 0 - gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2,
@@ -95,12 +91,8 @@ void freemem(int nsrc_loc, st_acquisition *acq, st_model *mod, st_model *testmod
         vel.vy.free();
         vel.vz.free();
         if (gv->WEQ != 2) {
-            free_f3tensor(stress->sxy, 1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                          gv->NX + l * gv->FDORDER / 2,
-                          1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
-            free_f3tensor(stress->syz, 1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                          gv->NX + l * gv->FDORDER / 2,
-                          1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
+            stress.sxy.free();
+            stress.syz.free();
         }
         /*free_f4tensor(fvx,1,gv->NT,1-l*gv->FDORDER/2,gv->NY+l*gv->FDORDER/2,1-l*gv->FDORDER/2,gv->NX+l*gv->FDORDER/2,1-l*gv->FDORDER/2,gv->NZ+l*gv->FDORDER/2);
          * free_f4tensor(fvy,1,gv->NT,1-l*gv->FDORDER/2,gv->NY+l*gv->FDORDER/2,1-l*gv->FDORDER/2,gv->NX+l*gv->FDORDER/2,1-l*gv->FDORDER/2,gv->NZ+l*gv->FDORDER/2);
@@ -152,22 +144,12 @@ void freemem(int nsrc_loc, st_acquisition *acq, st_model *mod, st_model *testmod
     }
 
     if (gv->WEQ != 2) {
-        free_f3tensor(stress->sxz, 1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                      gv->NX + l * gv->FDORDER / 2,
-                      1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
-        free_f3tensor(stress->sxx, 1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                      gv->NX + l * gv->FDORDER / 2,
-                      1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
-        free_f3tensor(stress->syy, 1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                      gv->NX + l * gv->FDORDER / 2,
-                      1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
-        free_f3tensor(stress->szz, 1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                      gv->NX + l * gv->FDORDER / 2,
-                      1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
+        stress.sxz.free();
+        stress.sxx.free();
+        stress.syy.free();
+        stress.szz.free();
     } else {
-        free_f3tensor(stress->sp, 1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                      gv->NX + l * gv->FDORDER / 2,
-                      1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
+        stress.sp.free();
     }
 
     if (gv->METHOD) {
diff --git a/src/ifos3d.cpp b/src/ifos3d.cpp
index bf6c57f..7340def 100644
--- a/src/ifos3d.cpp
+++ b/src/ifos3d.cpp
@@ -184,7 +184,7 @@ int main(int argc, char **argv)
 
     /* allocate and initialize buffers */
     buffsize = initmem(&mod, &testmod, &mod_av, &visco_mem, &pml_coeff, &pml_wfd,
-                       &grad, &grad_prior1, &grad_prior2, &grad_halo, &hessian, &stress, &stressbuff,
+                       &grad, &grad_prior1, &grad_prior2, &grad_halo, &hessian, stress, &stressbuff,
                        &fourier_vel_back, &fourier_vel_fw, vel, &velbuff, &gv);
 
     /* allocate buffer for buffering messages */
@@ -471,9 +471,9 @@ int main(int argc, char **argv)
 
             /* initialize wavefield with zero */
             if (gv.WEQ != 2) {
-                zero_wavefield(vel, &stress, &visco_mem, &pml_wfd, &gv);
+                zero_wavefield(vel, stress, &visco_mem, &pml_wfd, &gv);
             } else {
-                zero_wavefield_acoustic(vel, &stress, &visco_mem, &pml_wfd, &gv);
+                zero_wavefield_acoustic(vel, stress, &visco_mem, &pml_wfd, &gv);
             }
             if (gv.METHOD)
                 zero_invers(&fourier_vel_fw, &fourier_vel_back, gv.NFMAX, &gv);
@@ -487,7 +487,7 @@ int main(int argc, char **argv)
                     ntast = 1;
 
                 if (gv.STFI) {
-                    stfi(&acq, &nb, &nb_fix, vel, &stress, &mod, &mod_av, &visco_mem, &section, &section_obs,
+                    stfi(&acq, &nb, &nb_fix, vel, stress, &mod, &mod_av, &visco_mem, &section, &section_obs,
                          &signals, nsrc_loc, ntr_loc, &pml_coeff, &pml_wfd, &stressbuff, &velbuff,
                          &fourier_vel_fw, finv, &L2, nf, ntast, lsnap, nsnap, ishot, shot_id, cdf, iteration, groupnum,
                          it_group, ncplx, &gv);
@@ -497,7 +497,7 @@ int main(int argc, char **argv)
             /*****************************************************
             * Timestep loop (simulation)
             *****************************************************/
-            timeloop(&nb, &nb_fix, vel, &stress, &mod, &mod_av, &section,
+            timeloop(&nb, &nb_fix, vel, stress, &mod, &mod_av, &section,
                      acq.srcpos_loc, acq.recpos_loc, &signals, nsrc_loc,
                      mod.absorb_coeff, &pml_coeff, &pml_wfd, &stressbuff, &velbuff, &fourier_vel_fw,
                      finv, nf, ntast, ntr_loc, lsnap, nsnap, 0, shot_id, 1, &gv);
@@ -556,15 +556,15 @@ int main(int argc, char **argv)
 
                 /* initialize wavefields */
                 if (gv.WEQ != 2) {
-                    zero_wavefield(vel, &stress, &visco_mem, &pml_wfd, &gv);
+                    zero_wavefield(vel, stress, &visco_mem, &pml_wfd, &gv);
                 } else {
-                    zero_wavefield_acoustic(vel, &stress, &visco_mem, &pml_wfd, &gv);
+                    zero_wavefield_acoustic(vel, stress, &visco_mem, &pml_wfd, &gv);
                 }
 
                 /*****************************************************
                 *           Timestep loop (back-propagation)
                 *****************************************************/
-                timeloop(&nb, &nb_fix, vel, &stress, &mod, &mod_av, &section,
+                timeloop(&nb, &nb_fix, vel, stress, &mod, &mod_av, &section,
                          acq.srcpos_loc_back, acq.recpos_loc, &signals, ntr_loc,
                          mod.absorb_coeff, &pml_coeff, &pml_wfd, &stressbuff, &velbuff, &fourier_vel_back,
                          finv, nf, ntast, ntr_loc, lsnap, nsnap, 0, shot_id, 2, &gv);
@@ -794,15 +794,15 @@ int main(int argc, char **argv)
                         }
 
                         if (gv.WEQ != 2) {
-                            zero_wavefield(vel, &stress, &visco_mem, &pml_wfd, &gv);
+                            zero_wavefield(vel, stress, &visco_mem, &pml_wfd, &gv);
                         } else {
-                            zero_wavefield_acoustic(vel, &stress, &visco_mem, &pml_wfd, &gv);
+                            zero_wavefield_acoustic(vel, stress, &visco_mem, &pml_wfd, &gv);
                         }
 
                         /*****************************************************
                         * Timestep loop (steplength calculation)
                         *****************************************************/
-                        timeloop(&nb, &nb_fix, vel, &stress, &testmod, &mod_av, &section,
+                        timeloop(&nb, &nb_fix, vel, stress, &testmod, &mod_av, &section,
                                  acq.srcpos_loc, acq.recpos_loc, &signals, nsrc_loc,
                                  mod.absorb_coeff, &pml_coeff, &pml_wfd, &stressbuff, &velbuff, &fourier_vel_fw,
                                  finv, nf, ntast, ntr_loc, lsnap, nsnap, 0, shot_id, 3, &gv);
@@ -850,7 +850,7 @@ int main(int argc, char **argv)
     /* de-allocation of memory */
     freemem(nsrc_loc, &acq, &mod, &testmod, &mod_av,
             &visco_mem, &pml_coeff, &pml_wfd, &signals, &grad,
-            &grad_prior1, &grad_prior2, &grad_halo, &hessian, &stress, &stressbuff,
+            &grad_prior1, &grad_prior2, &grad_halo, &hessian, stress, &stressbuff,
             &fourier_vel_back, &fourier_vel_fw, vel, &velbuff, &gv);
 
     if (topo) {
diff --git a/src/initmem.cpp b/src/initmem.cpp
index 1ea2500..09eaa06 100644
--- a/src/initmem.cpp
+++ b/src/initmem.cpp
@@ -28,7 +28,7 @@
 int initmem(st_model *mod, st_model *testmod,
             st_model_av *mod_av, st_visc_mem *visco_mem, st_pml_coeff *pml_coeff,
             st_pml_wfd *pml_wfd, st_gradient *grad, st_gradient *grad_prior1,
-            st_gradient *grad_prior2, st_gradient *grad_halo, st_hessian *hessian, st_stress *stress,
+            st_gradient *grad_prior2, st_gradient *grad_halo, st_hessian *hessian, st_stress &stress,
             st_buffer_flat *stressbuff, st_freq_velocity *fourier_vel_back,
             st_freq_velocity *fourier_vel_fw, st_velocity &vel, st_buffer_flat *velbuff,
             GlobVar *gv)
@@ -184,14 +184,12 @@ int initmem(st_model *mod, st_model *testmod,
                          gv->NX + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
         }
         if (gv->WEQ != 2) {
-            stress->sxy =
-                f3tensor(0 - gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                         gv->NX + l * gv->FDORDER / 2,
-                         1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
-            stress->syz =
-                f3tensor(0 - gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                         gv->NX + l * gv->FDORDER / 2,
-                         1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
+            stress.sxy.malloc(0 - gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2,
+                              1 - l * gv->FDORDER / 2, gv->NX + l * gv->FDORDER / 2,
+                              1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
+            stress.syz.malloc(0 - gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2,
+                              1 - l * gv->FDORDER / 2, gv->NX + l * gv->FDORDER / 2,
+                              1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
         }
     }
 
@@ -253,39 +251,32 @@ int initmem(st_model *mod, st_model *testmod,
                          gv->NX + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
         }
         if (gv->WEQ != 2) {
-            stress->sxy =
-                f3tensor(1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                         gv->NX + l * gv->FDORDER / 2,
-                         1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
-            stress->syz =
-                f3tensor(1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                         gv->NX + l * gv->FDORDER / 2,
-                         1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
+            stress.sxy.malloc(1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2,
+                              1 - l * gv->FDORDER / 2, gv->NX + l * gv->FDORDER / 2,
+                              1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
+            stress.syz.malloc(1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2,
+                              1 - l * gv->FDORDER / 2, gv->NX + l * gv->FDORDER / 2,
+                              1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
         }
     }
 
     if (gv->WEQ != 2) {
-        stress->sxz =
-            f3tensor(1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                     gv->NX + l * gv->FDORDER / 2,
-                     1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
-        stress->sxx =
-            f3tensor(1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                     gv->NX + l * gv->FDORDER / 2,
-                     1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
-        stress->syy =
-            f3tensor(1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                     gv->NX + l * gv->FDORDER / 2,
-                     1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
-        stress->szz =
-            f3tensor(1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                     gv->NX + l * gv->FDORDER / 2,
-                     1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
+        stress.sxz.malloc(1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2,
+                          1 - l * gv->FDORDER / 2, gv->NX + l * gv->FDORDER / 2,
+                          1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
+        stress.sxx.malloc(1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2,
+                          1 - l * gv->FDORDER / 2, gv->NX + l * gv->FDORDER / 2,
+                          1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
+        stress.syy.malloc(1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2,
+                          1 - l * gv->FDORDER / 2, gv->NX + l * gv->FDORDER / 2,
+                          1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
+        stress.szz.malloc(1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2,
+                          1 - l * gv->FDORDER / 2, gv->NX + l * gv->FDORDER / 2,
+                          1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
     } else {
-        stress->sp =
-            f3tensor(1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2, 1 - l * gv->FDORDER / 2,
-                     gv->NX + l * gv->FDORDER / 2,
-                     1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
+        stress.sp.malloc(1 - l * gv->FDORDER / 2, gv->NY + l * gv->FDORDER / 2,
+                         1 - l * gv->FDORDER / 2, gv->NX + l * gv->FDORDER / 2,
+                         1 - l * gv->FDORDER / 2, gv->NZ + l * gv->FDORDER / 2);
     }
 
     /* memory allocation for inversion parameter */
diff --git a/src/psource.cpp b/src/psource.cpp
index dc89c65..d22f0c1 100644
--- a/src/psource.cpp
+++ b/src/psource.cpp
@@ -23,7 +23,7 @@
 
 #include "fd.hpp"
 
-void psource(int nt, st_stress *stress, float **srcpos_loc, float **signals, int nsrc, const GlobVar *gv, int sw)
+void psource(int nt, st_stress &stress, float **srcpos_loc, float **signals, int nsrc, const GlobVar *gv, int sw)
 {
     /* adding source wavelet to stress components *
     * (explosive source) at source points        */
@@ -34,11 +34,11 @@ void psource(int nt, st_stress *stress, float **srcpos_loc, float **signals, int
         if ((sw == 0 && (int)srcpos_loc[7][l] == 1) || (sw == 1)) {
             float amp = signals[l][nt];
             if (gv->WEQ == 2) {
-                stress->sp[j][i][k] += amp;
+                stress.sp[j, i, k] += amp;
             } else {
-                stress->sxx[j][i][k] += amp;
-                stress->syy[j][i][k] += amp;
-                stress->szz[j][i][k] += amp;
+                stress.sxx[j, i, k] += amp;
+                stress.syy[j, i, k] += amp;
+                stress.szz[j, i, k] += amp;
             }
         }
     }
diff --git a/src/seismo_ssg.cpp b/src/seismo_ssg.cpp
index 1fd445b..81d3cdc 100644
--- a/src/seismo_ssg.cpp
+++ b/src/seismo_ssg.cpp
@@ -25,7 +25,7 @@
 #include "fd.hpp"
 
 void seismo(int nt, int ntr, int **recpos, st_seismogram *section,
-            st_velocity &vel, st_stress *stress, st_model *mod, const GlobVar *gv)
+            st_velocity &vel, st_stress &stress, st_model *mod, const GlobVar *gv)
 {
     int i, j, k, itr;
     float amp, dh24x, dh24y, dh24z, vyx, vxy, vxx, vyy, vzx, vyz, vxz, vzy, vzz;
@@ -56,11 +56,11 @@ void seismo(int nt, int ntr, int **recpos, st_seismogram *section,
                 section->p[itr][0] = 0.0f;
             }
             if (gv->WEQ != 2) {
-                section->p[itr][nt] = (-stress->sxx[nyrec][nxrec][nzrec]
-                                       - stress->syy[nyrec][nxrec][nzrec]
-                                       - stress->szz[nyrec][nxrec][nzrec]) / 3.0;
+                section->p[itr][nt] = (-stress.sxx[nyrec, nxrec, nzrec]
+                                       - stress.syy[nyrec, nxrec, nzrec]
+                                       - stress.szz[nyrec, nxrec, nzrec]) / 3.0;
             } else {
-                section->p[itr][nt] = -stress->sp[nyrec][nxrec][nzrec];
+                section->p[itr][nt] = -stress.sp[nyrec, nxrec, nzrec];
             }
             break;
         case 3:
@@ -117,11 +117,11 @@ void seismo(int nt, int ntr, int **recpos, st_seismogram *section,
             section->vy[itr][nt] = vel.vy[nyrec, nxrec, nzrec];
             section->vz[itr][nt] = vel.vz[nyrec, nxrec, nzrec];
             if (gv->WEQ != 2) {
-                section->p[itr][nt] = (-stress->sxx[nyrec][nxrec][nzrec]
-                                       - stress->syy[nyrec][nxrec][nzrec]
-                                       - stress->szz[nyrec][nxrec][nzrec]) / 3.0;
+                section->p[itr][nt] = (-stress.sxx[nyrec, nxrec, nzrec]
+                                       - stress.syy[nyrec, nxrec, nzrec]
+                                       - stress.szz[nyrec, nxrec, nzrec]) / 3.0;
             } else {
-                section->p[itr][nt] = -stress->sp[nyrec][nxrec][nzrec];
+                section->p[itr][nt] = -stress.sp[nyrec, nxrec, nzrec];
             }
             i = nxrec;
             j = nyrec;
diff --git a/src/snap_ssg.cpp b/src/snap_ssg.cpp
index aabccce..c17fd3e 100644
--- a/src/snap_ssg.cpp
+++ b/src/snap_ssg.cpp
@@ -24,7 +24,7 @@
 #include "fd.hpp"
 #include "logging.hpp"
 
-void snap(int nt, int nsnap, st_velocity &vel, st_stress *stress, const st_model *mod,
+void snap(int nt, int nsnap, st_velocity &vel, st_stress &stress, const st_model *mod,
           const st_boundary *nb, GlobVar *gv)
 {
     /*
@@ -104,9 +104,9 @@ void snap(int nt, int nsnap, st_velocity &vel, st_stress *stress, const st_model
             for (int i = nb->nx1; i <= nb->nx2; i += gv->IDX)
                 for (int j = nb->nz1; j <= nb->nz2; j += gv->IDZ) {
                     if (gv->WEQ != 2) {
-                        amp = -stress->sxx[j][i][k] - stress->syy[j][i][k] - stress->szz[j][i][k];
+                        amp = -stress.sxx[j, i, k] - stress.syy[j, i, k] - stress.szz[j, i, k];
                     } else {
-                        amp = -stress->sp[j][i][k];
+                        amp = -stress.sp[j, i, k];
                     }
 
                     writedsk(fpx1, amp, gv->SNAP_FORMAT);
diff --git a/src/stfi.cpp b/src/stfi.cpp
index ffc3954..c7ac290 100644
--- a/src/stfi.cpp
+++ b/src/stfi.cpp
@@ -30,7 +30,7 @@
 #include "seismo_shift.hpp"
 #include "kiss_fftr.h"
 
-void stfi(st_acquisition *acq, st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress *stress,
+void stfi(st_acquisition *acq, st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress &stress,
           st_model *mod, st_model_av *mod_av, st_visc_mem *visco_mem, st_seismogram *section,
           st_seismogram *section_obs, st_signals *signals, int nsrc_loc, int ntr_loc, st_pml_coeff *pml_coeff,
           st_pml_wfd *pml_wfd, st_buffer_flat *stressbuff, st_buffer_flat *velbuff, st_freq_velocity *fourier_vel_fw,
diff --git a/src/surface_ssg.cpp b/src/surface_ssg.cpp
index 503dea0..db9cf50 100644
--- a/src/surface_ssg.cpp
+++ b/src/surface_ssg.cpp
@@ -24,7 +24,7 @@
 #include "fd.hpp"
 
 void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, st_visc_mem *mem,
-             st_stress *stress, st_velocity &vel)
+             st_stress &stress, st_velocity &vel)
 {
     int i, k, j, fdoh, m, h1;
     float vxx, vyy, vzz;
@@ -55,13 +55,13 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
             for (i = 1; i <= NX; i++) {
                 /*Mirroring the components of the stress tensor to make
                  * a stress free surface (method of imaging, Levander, 1988) */
-                stress->syy[j][i][k] = mem->ryy[j][i][k] = 0.0;
+                stress.syy[j, i, k] = mem->ryy[j][i][k] = 0.0;
 
-                stress->syy[j - 1][i][k] = -stress->syy[j + 1][i][k];
-                stress->sxy[j - 1][i][k] = -stress->sxy[j][i][k];
-                stress->sxy[j - 2][i][k] = -stress->sxy[j + 1][i][k];
-                stress->syz[j - 1][i][k] = -stress->syz[j][i][k];
-                stress->syz[j - 2][i][k] = -stress->syz[j + 1][i][k];
+                stress.syy[j - 1, i, k] = -stress.syy[j + 1, i, k];
+                stress.sxy[j - 1, i, k] = -stress.sxy[j, i, k];
+                stress.sxy[j - 2, i, k] = -stress.sxy[j + 1, i, k];
+                stress.syz[j - 1, i, k] = -stress.syz[j, i, k];
+                stress.syz[j - 2, i, k] = -stress.syz[j + 1, i, k];
 
                 /* in the case of using several relaxation mechanisms all
                  * memory-variables corresponding to syy must be set to zero
@@ -115,8 +115,8 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
                 f = mod->u[j][i][k] * 2.0f * (1.0f + L * mod->taus[j][i][k]);
                 g = mod->pi[j][i][k] * (1.0f + L * mod->taup[j][i][k]);
                 h = -(DT * (g - f) * (g - f) * (vxx + vzz) / g) - (DT * (g - f) * vyy);
-                stress->sxx[j][i][k] += h - (dthalbe * mem->rxx[j][i][k]);
-                stress->szz[j][i][k] += h - (dthalbe * mem->rzz[j][i][k]);
+                stress.sxx[j, i, k] += h - (dthalbe * mem->rxx[j][i][k]);
+                stress.szz[j, i, k] += h - (dthalbe * mem->rzz[j][i][k]);
 
                 /* updating the memory-variable rxx, rzz at the free surface */
                 b = mod->eta[1] / (1.0 + (mod->eta[1] * 0.5));
@@ -127,8 +127,8 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
                 mem->rzz[j][i][k] += h;
 
                 /*completely updating the stresses sxx and szz */
-                stress->sxx[j][i][k] += (dthalbe * mem->rxx[j][i][k]);
-                stress->szz[j][i][k] += (dthalbe * mem->rzz[j][i][k]);
+                stress.sxx[j, i, k] += (dthalbe * mem->rxx[j][i][k]);
+                stress.szz[j, i, k] += (dthalbe * mem->rzz[j][i][k]);
             }
         }
         break;
@@ -147,12 +147,12 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
             for (i = 1; i <= NX; i++) {
                 /*Mirroring the components of the stress tensor to make
                  * a stress free surface (method of imaging, Levander, 1988) */
-                stress->syy[j][i][k] = mem->ryy[j][i][k] = 0.0;
+                stress.syy[j, i, k] = mem->ryy[j][i][k] = 0.0;
 
                 for (m = 1; m <= fdoh; m++) {
-                    stress->syy[j - m][i][k] = -stress->syy[j + m][i][k];
-                    stress->sxy[j - m][i][k] = -stress->sxy[j + m - 1][i][k];
-                    stress->syz[j - m][i][k] = -stress->syz[j + m - 1][i][k];
+                    stress.syy[j - m, i, k] = -stress.syy[j + m, i, k];
+                    stress.sxy[j - m, i, k] = -stress.sxy[j + m - 1, i, k];
+                    stress.syz[j - m, i, k] = -stress.syz[j + m - 1, i, k];
                 }
 
                 /* in the case of using several relaxation mechanisms all
@@ -205,8 +205,8 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
                 f = mod->u[j][i][k] * 2.0f * (1.0f + L * mod->taus[j][i][k]);
                 g = mod->pi[j][i][k] * (1.0f + L * mod->taup[j][i][k]);
                 h = -(DT * (g - f) * (g - f) * (vxx + vzz) / g) - (DT * (g - f) * vyy);
-                stress->sxx[j][i][k] += h - (dthalbe * mem->rxx[j][i][k]);
-                stress->szz[j][i][k] += h - (dthalbe * mem->rzz[j][i][k]);
+                stress.sxx[j, i, k] += h - (dthalbe * mem->rxx[j][i][k]);
+                stress.szz[j, i, k] += h - (dthalbe * mem->rzz[j][i][k]);
 
                 /* updating the memory-variable rxx, rzz at the free surface */
                 b = mod->eta[1] / (1.0 + (mod->eta[1] * 0.5));
@@ -217,8 +217,8 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
                 mem->rzz[j][i][k] += h;
 
                 /*completely updating the stresses sxx and szz */
-                stress->sxx[j][i][k] += (dthalbe * mem->rxx[j][i][k]);
-                stress->szz[j][i][k] += (dthalbe * mem->rzz[j][i][k]);
+                stress.sxx[j, i, k] += (dthalbe * mem->rxx[j][i][k]);
+                stress.szz[j, i, k] += (dthalbe * mem->rzz[j][i][k]);
             }
         }
         break;
@@ -238,12 +238,12 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
             for (i = 1; i <= NX; i++) {
                 /*Mirroring the components of the stress tensor to make
                  * a stress free surface (method of imaging, Levander, 1988) */
-                stress->syy[j][i][k] = mem->ryy[j][i][k] = 0.0;
+                stress.syy[j, i, k] = mem->ryy[j][i][k] = 0.0;
 
                 for (m = 1; m <= fdoh; m++) {
-                    stress->syy[j - m][i][k] = -stress->syy[j + m][i][k];
-                    stress->sxy[j - m][i][k] = -stress->sxy[j + m - 1][i][k];
-                    stress->syz[j - m][i][k] = -stress->syz[j + m - 1][i][k];
+                    stress.syy[j - m, i, k] = -stress.syy[j + m, i, k];
+                    stress.sxy[j - m, i, k] = -stress.sxy[j + m - 1, i, k];
+                    stress.syz[j - m, i, k] = -stress.syz[j + m - 1, i, k];
                 }
 
                 /* in the case of using several relaxation mechanisms all
@@ -272,8 +272,8 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
                 f = mod->u[j][i][k] * 2.0f * (1.0f + L * mod->taus[j][i][k]);
                 g = mod->pi[j][i][k] * (1.0 + L * mod->taup[j][i][k]);
                 h = -(DT * (g - f) * (g - f) * (vxx + vzz) / g) - (DT * (g - f) * vyy);
-                stress->sxx[j][i][k] += h - (dthalbe * mem->rxx[j][i][k]);
-                stress->szz[j][i][k] += h - (dthalbe * mem->rzz[j][i][k]);
+                stress.sxx[j, i, k] += h - (dthalbe * mem->rxx[j][i][k]);
+                stress.szz[j, i, k] += h - (dthalbe * mem->rzz[j][i][k]);
 
                 /* updating the memory-variable rxx, rzz at the free surface */
                 b = mod->eta[1] / (1.0 + (mod->eta[1] * 0.5));
@@ -284,8 +284,8 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
                 mem->rzz[j][i][k] += h;
 
                 /*completely updating the stresses sxx and szz */
-                stress->sxx[j][i][k] += (dthalbe * mem->rxx[j][i][k]);
-                stress->szz[j][i][k] += (dthalbe * mem->rzz[j][i][k]);
+                stress.sxx[j, i, k] += (dthalbe * mem->rxx[j][i][k]);
+                stress.szz[j, i, k] += (dthalbe * mem->rzz[j][i][k]);
             }
         }
         break;
@@ -308,12 +308,12 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
             for (i = 1; i <= NX; i++) {
                 /*Mirroring the components of the stress tensor to make
                  * a stress free surface (method of imaging, Levander, 1988) */
-                stress->syy[j][i][k] = mem->ryy[j][i][k] = 0.0;
+                stress.syy[j, i, k] = mem->ryy[j][i][k] = 0.0;
 
                 for (m = 1; m <= fdoh; m++) {
-                    stress->syy[j - m][i][k] = -stress->syy[j + m][i][k];
-                    stress->sxy[j - m][i][k] = -stress->sxy[j + m - 1][i][k];
-                    stress->syz[j - m][i][k] = -stress->syz[j + m - 1][i][k];
+                    stress.syy[j - m, i, k] = -stress.syy[j + m, i, k];
+                    stress.sxy[j - m, i, k] = -stress.sxy[j + m - 1, i, k];
+                    stress.syz[j - m, i, k] = -stress.syz[j + m - 1, i, k];
                 }
 
                 /* in the case of using several relaxation mechanisms all
@@ -345,8 +345,8 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
                 f = mod->u[j][i][k] * 2.0f * (1.0f + L * mod->taus[j][i][k]);
                 g = mod->pi[j][i][k] * (1.0f + L * mod->taup[j][i][k]);
                 h = -(DT * (g - f) * (g - f) * (vxx + vzz) / g) - (DT * (g - f) * vyy);
-                stress->sxx[j][i][k] += h - (dthalbe * mem->rxx[j][i][k]);
-                stress->szz[j][i][k] += h - (dthalbe * mem->rzz[j][i][k]);
+                stress.sxx[j, i, k] += h - (dthalbe * mem->rxx[j][i][k]);
+                stress.szz[j, i, k] += h - (dthalbe * mem->rzz[j][i][k]);
 
                 /* updating the memory-variable rxx, rzz at the free surface */
                 b = mod->eta[1] / (1.0 + (mod->eta[1] * 0.5));
@@ -357,8 +357,8 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
                 mem->rzz[j][i][k] += h;
 
                 /*completely updating the stresses sxx and szz */
-                stress->sxx[j][i][k] += (dthalbe * mem->rxx[j][i][k]);
-                stress->szz[j][i][k] += (dthalbe * mem->rzz[j][i][k]);
+                stress.sxx[j, i, k] += (dthalbe * mem->rxx[j][i][k]);
+                stress.szz[j, i, k] += (dthalbe * mem->rzz[j][i][k]);
             }
         }
         break;
@@ -383,12 +383,12 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
             for (i = 1; i <= NX; i++) {
                 /*Mirroring the components of the stress tensor to make
                  * a stress free surface (method of imaging, Levander, 1988) */
-                stress->syy[j][i][k] = mem->ryy[j][i][k] = 0.0;
+                stress.syy[j, i, k] = mem->ryy[j][i][k] = 0.0;
 
                 for (m = 1; m <= fdoh; m++) {
-                    stress->syy[j - m][i][k] = -stress->syy[j + m][i][k];
-                    stress->sxy[j - m][i][k] = -stress->sxy[j + m - 1][i][k];
-                    stress->syz[j - m][i][k] = -stress->syz[j + m - 1][i][k];
+                    stress.syy[j - m, i, k] = -stress.syy[j + m, i, k];
+                    stress.sxy[j - m, i, k] = -stress.sxy[j + m - 1, i, k];
+                    stress.syz[j - m, i, k] = -stress.syz[j + m - 1, i, k];
                 }
 
                 /* in the case of using several relaxation mechanisms all
@@ -423,8 +423,8 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
                 f = mod->u[j][i][k] * 2.0f * (1.0f + L * mod->taus[j][i][k]);
                 g = mod->pi[j][i][k] * (1.0f + L * mod->taup[j][i][k]);
                 h = -(DT * (g - f) * (g - f) * (vxx + vzz) / g) - (DT * (g - f) * vyy);
-                stress->sxx[j][i][k] += h - (dthalbe * mem->rxx[j][i][k]);
-                stress->szz[j][i][k] += h - (dthalbe * mem->rzz[j][i][k]);
+                stress.sxx[j, i, k] += h - (dthalbe * mem->rxx[j][i][k]);
+                stress.szz[j, i, k] += h - (dthalbe * mem->rzz[j][i][k]);
 
                 /* updating the memory-variable rxx, rzz at the free surface */
                 b = mod->eta[1] / (1.0 + (mod->eta[1] * 0.5));
@@ -435,8 +435,8 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
                 mem->rzz[j][i][k] += h;
 
                 /*completely updating the stresses sxx and szz */
-                stress->sxx[j][i][k] += (dthalbe * mem->rxx[j][i][k]);
-                stress->szz[j][i][k] += (dthalbe * mem->rzz[j][i][k]);
+                stress.sxx[j, i, k] += (dthalbe * mem->rxx[j][i][k]);
+                stress.szz[j, i, k] += (dthalbe * mem->rzz[j][i][k]);
             }
         }
         break;
@@ -465,12 +465,12 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
             for (i = 1; i <= NX; i++) {
                 /*Mirroring the components of the stress tensor to make
                  * a stress free surface (method of imaging, Levander, 1988) */
-                stress->syy[j][i][k] = mem->ryy[j][i][k] = 0.0;
+                stress.syy[j, i, k] = mem->ryy[j][i][k] = 0.0;
 
                 for (m = 1; m <= fdoh; m++) {
-                    stress->syy[j - m][i][k] = -stress->syy[j + m][i][k];
-                    stress->sxy[j - m][i][k] = -stress->sxy[j + m - 1][i][k];
-                    stress->syz[j - m][i][k] = -stress->syz[j + m - 1][i][k];
+                    stress.syy[j - m, i, k] = -stress.syy[j + m, i, k];
+                    stress.sxy[j - m, i, k] = -stress.sxy[j + m - 1, i, k];
+                    stress.syz[j - m, i, k] = -stress.syz[j + m - 1, i, k];
                 }
 
                 /* in the case of using several relaxation mechanisms all
@@ -508,8 +508,8 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
                 f = mod->u[j][i][k] * 2.0f * (1.0f + L * mod->taus[j][i][k]);
                 g = mod->pi[j][i][k] * (1.0f + L * mod->taup[j][i][k]);
                 h = -(DT * (g - f) * (g - f) * (vxx + vzz) / g) - (DT * (g - f) * vyy);
-                stress->sxx[j][i][k] += h - (dthalbe * mem->rxx[j][i][k]);
-                stress->szz[j][i][k] += h - (dthalbe * mem->rzz[j][i][k]);
+                stress.sxx[j, i, k] += h - (dthalbe * mem->rxx[j][i][k]);
+                stress.szz[j, i, k] += h - (dthalbe * mem->rzz[j][i][k]);
 
                 /* updating the memory-variable rxx, rzz at the free surface */
                 b = mod->eta[1] / (1.0 + (mod->eta[1] * 0.5));
@@ -520,8 +520,8 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
                 mem->rzz[j][i][k] += h;
 
                 /*completely updating the stresses sxx and szz */
-                stress->sxx[j][i][k] += (dthalbe * mem->rxx[j][i][k]);
-                stress->szz[j][i][k] += (dthalbe * mem->rzz[j][i][k]);
+                stress.sxx[j, i, k] += (dthalbe * mem->rxx[j][i][k]);
+                stress.szz[j, i, k] += (dthalbe * mem->rzz[j][i][k]);
             }
         }
         break;
diff --git a/src/surface_ssg_acoustic.cpp b/src/surface_ssg_acoustic.cpp
index 9b0c978..5a5b33b 100644
--- a/src/surface_ssg_acoustic.cpp
+++ b/src/surface_ssg_acoustic.cpp
@@ -23,7 +23,7 @@
 
 #include "fd.hpp"
 
-void surface_acoustic(int ndepth, st_stress *stress, const GlobVar *gv)
+void surface_acoustic(int ndepth, st_stress &stress, const GlobVar *gv)
 {
     int j = ndepth;                 /* The free surface is located exactly in y=ndepth*dh meter!! */
     int fdoh = gv->FDORDER / 2;
@@ -32,9 +32,9 @@ void surface_acoustic(int ndepth, st_stress *stress, const GlobVar *gv)
         for (int i = 1; i <= gv->NX; i++) {
             /* Mirroring the components of the stress tensor to make     *
             * a stress free surface (method of imaging, Levander, 1988) */
-            stress->sp[j][i][k] = 0.0;
+            stress.sp[j, i, k] = 0.0;
             for (int m = 1; m <= fdoh; m++) {
-                stress->sp[j - m][i][k] = -stress->sp[j + m][i][k];
+                stress.sp[j - m, i, k] = -stress.sp[j + m, i, k];
             }
         }
     }
diff --git a/src/surface_ssg_elastic.cpp b/src/surface_ssg_elastic.cpp
index caf41d1..76de5cc 100644
--- a/src/surface_ssg_elastic.cpp
+++ b/src/surface_ssg_elastic.cpp
@@ -24,7 +24,7 @@
 #include "fd.hpp"
 
 void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd,
-                     st_stress *stress, st_velocity &vel, const GlobVar *gv)
+                     st_stress &stress, st_velocity &vel, const GlobVar *gv)
 {
     int h1;
     float vxx, vyy, vzz;
@@ -44,13 +44,13 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
             for (int i = 1; i <= gv->NX; i++) {
                 /*Mirroring the components of the stress tensor to make
                  * a stress free surface (method of imaging, Levander, 1988) */
-                stress->syy[j][i][k] = 0.0;
+                stress.syy[j, i, k] = 0.0;
 
-                stress->syy[j - 1][i][k] = -stress->syy[j + 1][i][k];
-                stress->sxy[j - 1][i][k] = -stress->sxy[j][i][k];
-                stress->sxy[j - 2][i][k] = -stress->sxy[j + 1][i][k];
-                stress->syz[j - 1][i][k] = -stress->syz[j][i][k];
-                stress->syz[j - 2][i][k] = -stress->syz[j + 1][i][k];
+                stress.syy[j - 1, i, k] = -stress.syy[j + 1, i, k];
+                stress.sxy[j - 1, i, k] = -stress.sxy[j, i, k];
+                stress.sxy[j - 2, i, k] = -stress.sxy[j + 1, i, k];
+                stress.syz[j - 1, i, k] = -stress.syz[j, i, k];
+                stress.syz[j - 2, i, k] = -stress.syz[j + 1, i, k];
 
                 vxx = (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) * oodx;
                 vyy = (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) * oody;
@@ -85,8 +85,8 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
                 f = mod->u[j][i][k] * 2.0;
                 g = mod->pi[j][i][k];
                 h = -(gv->DT * (g - f) * (g - f) * (vxx + vzz) / g) - (gv->DT * (g - f) * vyy);
-                stress->sxx[j][i][k] += h;
-                stress->szz[j][i][k] += h;
+                stress.sxx[j, i, k] += h;
+                stress.szz[j, i, k] += h;
             }
         }
         break;
@@ -105,12 +105,12 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
             for (int i = 1; i <= gv->NX; i++) {
                 /*Mirroring the components of the stress tensor to make
                  * a stress free surface (method of imaging, Levander, 1988) */
-                stress->syy[j][i][k] = 0.0;
+                stress.syy[j, i, k] = 0.0;
 
                 for (int m = 1; m <= fdoh; m++) {
-                    stress->syy[j - m][i][k] = -stress->syy[j + m][i][k];
-                    stress->sxy[j - m][i][k] = -stress->sxy[j + m - 1][i][k];
-                    stress->syz[j - m][i][k] = -stress->syz[j + m - 1][i][k];
+                    stress.syy[j - m, i, k] = -stress.syy[j + m, i, k];
+                    stress.sxy[j - m, i, k] = -stress.sxy[j + m - 1, i, k];
+                    stress.syz[j - m, i, k] = -stress.syz[j + m - 1, i, k];
                 }
                 vxx =
                     (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
@@ -151,8 +151,8 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
                 f = mod->u[j][i][k] * 2.0;
                 g = mod->pi[j][i][k];
                 h = -(gv->DT * (g - f) * (g - f) * (vxx + vzz) / g) - (gv->DT * (g - f) * vyy);
-                stress->sxx[j][i][k] += h;
-                stress->szz[j][i][k] += h;
+                stress.sxx[j, i, k] += h;
+                stress.szz[j, i, k] += h;
             }
         }
         break;
@@ -172,12 +172,12 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
             for (int i = 1; i <= gv->NX; i++) {
                 /*Mirroring the components of the stress tensor to make
                  * a stress free surface (method of imaging, Levander, 1988) */
-                stress->syy[j][i][k] = 0.0;
+                stress.syy[j, i, k] = 0.0;
 
                 for (int m = 1; m <= fdoh; m++) {
-                    stress->syy[j - m][i][k] = -stress->syy[j + m][i][k];
-                    stress->sxy[j - m][i][k] = -stress->sxy[j + m - 1][i][k];
-                    stress->syz[j - m][i][k] = -stress->syz[j + m - 1][i][k];
+                    stress.syy[j - m, i, k] = -stress.syy[j + m, i, k];
+                    stress.sxy[j - m, i, k] = -stress.sxy[j + m - 1, i, k];
+                    stress.syz[j - m, i, k] = -stress.syz[j + m - 1, i, k];
                 }
 
                 vxx = (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
@@ -195,8 +195,8 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
                 f = mod->u[j][i][k] * 2.0;
                 g = mod->pi[j][i][k];
                 h = -(gv->DT * (g - f) * (g - f) * (vxx + vzz) / g) - (gv->DT * (g - f) * vyy);
-                stress->sxx[j][i][k] += h;
-                stress->szz[j][i][k] += h;
+                stress.sxx[j, i, k] += h;
+                stress.szz[j, i, k] += h;
             }
         }
         break;
@@ -219,12 +219,12 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
             for (int i = 1; i <= gv->NX; i++) {
                 /*Mirroring the components of the stress tensor to make
                  * a stress free surface (method of imaging, Levander, 1988) */
-                stress->syy[j][i][k] = 0.0;
+                stress.syy[j, i, k] = 0.0;
 
                 for (int m = 1; m <= fdoh; m++) {
-                    stress->syy[j - m][i][k] = -stress->syy[j + m][i][k];
-                    stress->sxy[j - m][i][k] = -stress->sxy[j + m - 1][i][k];
-                    stress->syz[j - m][i][k] = -stress->syz[j + m - 1][i][k];
+                    stress.syy[j - m, i, k] = -stress.syy[j + m, i, k];
+                    stress.sxy[j - m, i, k] = -stress.sxy[j + m - 1, i, k];
+                    stress.syz[j - m, i, k] = -stress.syz[j + m - 1, i, k];
                 }
 
                 vxx = (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
@@ -245,8 +245,8 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
                 f = mod->u[j][i][k] * 2.0;
                 g = mod->pi[j][i][k];
                 h = -(gv->DT * (g - f) * (g - f) * (vxx + vzz) / g) - (gv->DT * (g - f) * vyy);
-                stress->sxx[j][i][k] += h;
-                stress->szz[j][i][k] += h;
+                stress.sxx[j, i, k] += h;
+                stress.szz[j, i, k] += h;
             }
         }
         break;
@@ -271,12 +271,12 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
             for (int i = 1; i <= gv->NX; i++) {
                 /*Mirroring the components of the stress tensor to make
                  * a stress free surface (method of imaging, Levander, 1988) */
-                stress->syy[j][i][k] = 0.0;
+                stress.syy[j, i, k] = 0.0;
 
                 for (int m = 1; m <= fdoh; m++) {
-                    stress->syy[j - m][i][k] = -stress->syy[j + m][i][k];
-                    stress->sxy[j - m][i][k] = -stress->sxy[j + m - 1][i][k];
-                    stress->syz[j - m][i][k] = -stress->syz[j + m - 1][i][k];
+                    stress.syy[j - m, i, k] = -stress.syy[j + m, i, k];
+                    stress.sxy[j - m, i, k] = -stress.sxy[j + m - 1, i, k];
+                    stress.syz[j - m, i, k] = -stress.syz[j + m - 1, i, k];
                 }
 
                 vxx = (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
@@ -300,8 +300,8 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
                 f = mod->u[j][i][k] * 2.0;
                 g = mod->pi[j][i][k];
                 h = -(gv->DT * (g - f) * (g - f) * (vxx + vzz) / g) - (gv->DT * (g - f) * vyy);
-                stress->sxx[j][i][k] += h;
-                stress->szz[j][i][k] += h;
+                stress.sxx[j, i, k] += h;
+                stress.szz[j, i, k] += h;
             }
         }
         break;
@@ -330,12 +330,12 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
             for (int i = 1; i <= gv->NX; i++) {
                 /*Mirroring the components of the stress tensor to make
                  * a stress free surface (method of imaging, Levander, 1988) */
-                stress->syy[j][i][k] = 0.0;
+                stress.syy[j, i, k] = 0.0;
 
                 for (int m = 1; m <= fdoh; m++) {
-                    stress->syy[j - m][i][k] = -stress->syy[j + m][i][k];
-                    stress->sxy[j - m][i][k] = -stress->sxy[j + m - 1][i][k];
-                    stress->syz[j - m][i][k] = -stress->syz[j + m - 1][i][k];
+                    stress.syy[j - m, i, k] = -stress.syy[j + m, i, k];
+                    stress.sxy[j - m, i, k] = -stress.sxy[j + m - 1, i, k];
+                    stress.syz[j - m, i, k] = -stress.syz[j + m - 1, i, k];
                 }
 
                 vxx = (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
@@ -362,8 +362,8 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
                 f = mod->u[j][i][k] * 2.0;
                 g = mod->pi[j][i][k];
                 h = -(gv->DT * (g - f) * (g - f) * (vxx + vzz) / g) - (gv->DT * (g - f) * vyy);
-                stress->sxx[j][i][k] += h;
-                stress->szz[j][i][k] += h;
+                stress.sxx[j, i, k] += h;
+                stress.szz[j, i, k] += h;
             }
         }
         break;
diff --git a/src/timeloop.cpp b/src/timeloop.cpp
index 4285f85..7a1e512 100644
--- a/src/timeloop.cpp
+++ b/src/timeloop.cpp
@@ -23,7 +23,7 @@
 #include "fd.hpp"
 #include "logging.hpp"
 
-void timeloop(st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress *stress,
+void timeloop(st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress &stress,
               st_model *mod, st_model_av *mod_av, st_seismogram *section,
               float **srcpos_loc, int **recpos_loc, st_signals *signals, int nsrc_loc,
               float ***absorb_coeff, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd,
diff --git a/src/update_s_ssg_CPML_acoustic.cpp b/src/update_s_ssg_CPML_acoustic.cpp
index 048553d..a24b82b 100644
--- a/src/update_s_ssg_CPML_acoustic.cpp
+++ b/src/update_s_ssg_CPML_acoustic.cpp
@@ -30,7 +30,7 @@
 #define UNUSED(x) (void)(x)
 
 double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
-                              st_stress *stress, st_model *mod, st_pml_coeff *pml_coeff,
+                              st_stress &stress, st_model *mod, st_pml_coeff *pml_coeff,
                               st_pml_wfd *pml_wfd, const GlobVar *gv)
 {
     int h1;
@@ -95,7 +95,7 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
 
                     vxxyyzz = vxx + vyy + vzz;
 
-                    stress->sp[j][i][k] += gv->DT * (g * vxxyyzz);
+                    stress.sp[j, i, k] += gv->DT * (g * vxxyyzz);
                 }
             }
         }
@@ -154,7 +154,7 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
 
                     vxxyyzz = vxx + vyy + vzz;
 
-                    stress->sp[j][i][k] += gv->DT * (g * vxxyyzz);
+                    stress.sp[j, i, k] += gv->DT * (g * vxxyyzz);
                 }
             }
         }
@@ -196,7 +196,7 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
 
                     vxxyyzz = vxx + vyy + vzz;
 
-                    stress->sp[j][i][k] += gv->DT * (g * vxxyyzz);
+                    stress.sp[j, i, k] += gv->DT * (g * vxxyyzz);
                 }
             }
         }
@@ -241,7 +241,7 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
 
                     vxxyyzz = vxx + vyy + vzz;
 
-                    stress->sp[j][i][k] += gv->DT * (g * vxxyyzz);
+                    stress.sp[j, i, k] += gv->DT * (g * vxxyyzz);
                 }
             }
         }
@@ -269,7 +269,7 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
 
                     vxxyyzz = vxx + vyy + vzz;
 
-                    stress->sp[j][i][k] += gv->DT * (g * vxxyyzz);
+                    stress.sp[j, i, k] += gv->DT * (g * vxxyyzz);
                 }
             }
         }
@@ -300,7 +300,7 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
 
                     vxxyyzz = vxx + vyy + vzz;
 
-                    stress->sp[j][i][k] += gv->DT * (g * vxxyyzz);
+                    stress.sp[j, i, k] += gv->DT * (g * vxxyyzz);
                 }
             }
         }
diff --git a/src/update_s_ssg_CPML_elastic.cpp b/src/update_s_ssg_CPML_elastic.cpp
index db8abf7..9848f4c 100644
--- a/src/update_s_ssg_CPML_elastic.cpp
+++ b/src/update_s_ssg_CPML_elastic.cpp
@@ -30,7 +30,7 @@
 #define UNUSED(x) (void)(x)
 
 double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
-                             st_stress *stress, st_model *mod, st_model_av *mod_av,
+                             st_stress &stress, st_model *mod, st_model_av *mod_av,
                              st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, const GlobVar *gv)
 {
     int h1;
@@ -161,12 +161,12 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                     vxxzz = vxx + vzz;
                     vxxyy = vxx + vyy;
 
-                    stress->sxy[j][i][k] += (fipjp * vxyyx);
-                    stress->syz[j][i][k] += (fjpkp * vyzzy);
-                    stress->sxz[j][i][k] += (fipkp * vxzzx);
-                    stress->sxx[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vyyzz));
-                    stress->syy[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vxxzz));
-                    stress->szz[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vxxyy));
+                    stress.sxy[j, i, k] += (fipjp * vxyyx);
+                    stress.syz[j, i, k] += (fjpkp * vyzzy);
+                    stress.sxz[j, i, k] += (fipkp * vxzzx);
+                    stress.sxx[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vyyzz));
+                    stress.syy[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vxxzz));
+                    stress.szz[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vxxyy));
                 }
             }
         }
@@ -283,12 +283,12 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                     vxxzz = vxx + vzz;
                     vxxyy = vxx + vyy;
 
-                    stress->sxy[j][i][k] += (fipjp * vxyyx);
-                    stress->syz[j][i][k] += (fjpkp * vyzzy);
-                    stress->sxz[j][i][k] += (fipkp * vxzzx);
-                    stress->sxx[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vyyzz));
-                    stress->syy[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vxxzz));
-                    stress->szz[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vxxyy));
+                    stress.sxy[j, i, k] += (fipjp * vxyyx);
+                    stress.syz[j, i, k] += (fjpkp * vyzzy);
+                    stress.sxz[j, i, k] += (fipkp * vxzzx);
+                    stress.sxx[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vyyzz));
+                    stress.syy[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vxxzz));
+                    stress.szz[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vxxyy));
                 }
             }
         }
@@ -378,12 +378,12 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                     vxxzz = vxx + vzz;
                     vxxyy = vxx + vyy;
 
-                    stress->sxy[j][i][k] += (fipjp * vxyyx);
-                    stress->syz[j][i][k] += (fjpkp * vyzzy);
-                    stress->sxz[j][i][k] += (fipkp * vxzzx);
-                    stress->sxx[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vyyzz));
-                    stress->syy[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vxxzz));
-                    stress->szz[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vxxyy));
+                    stress.sxy[j, i, k] += (fipjp * vxyyx);
+                    stress.syz[j, i, k] += (fjpkp * vyzzy);
+                    stress.sxz[j, i, k] += (fipkp * vxzzx);
+                    stress.sxx[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vyyzz));
+                    stress.syy[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vxxzz));
+                    stress.szz[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vxxyy));
                 }
             }
         }
@@ -474,12 +474,12 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                     vxxzz = vxx + vzz;
                     vxxyy = vxx + vyy;
 
-                    stress->sxy[j][i][k] += (fipjp * vxyyx);
-                    stress->syz[j][i][k] += (fjpkp * vyzzy);
-                    stress->sxz[j][i][k] += (fipkp * vxzzx);
-                    stress->sxx[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vyyzz));
-                    stress->syy[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vxxzz));
-                    stress->szz[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vxxyy));
+                    stress.sxy[j, i, k] += (fipjp * vxyyx);
+                    stress.syz[j, i, k] += (fjpkp * vyzzy);
+                    stress.sxz[j, i, k] += (fipkp * vxzzx);
+                    stress.sxx[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vyyzz));
+                    stress.syy[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vxxzz));
+                    stress.szz[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vxxyy));
                 }
             }
         }
@@ -543,12 +543,12 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                     vxxzz = vxx + vzz;
                     vxxyy = vxx + vyy;
 
-                    stress->sxy[j][i][k] += (fipjp * vxyyx);
-                    stress->syz[j][i][k] += (fjpkp * vyzzy);
-                    stress->sxz[j][i][k] += (fipkp * vxzzx);
-                    stress->sxx[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vyyzz));
-                    stress->syy[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vxxzz));
-                    stress->szz[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vxxyy));
+                    stress.sxy[j, i, k] += (fipjp * vxyyx);
+                    stress.syz[j, i, k] += (fjpkp * vyzzy);
+                    stress.sxz[j, i, k] += (fipkp * vxzzx);
+                    stress.sxx[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vyyzz));
+                    stress.syy[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vxxzz));
+                    stress.szz[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vxxyy));
                 }
             }
         }
@@ -613,12 +613,12 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                     vxxzz = vxx + vzz;
                     vxxyy = vxx + vyy;
 
-                    stress->sxy[j][i][k] += (fipjp * vxyyx);
-                    stress->syz[j][i][k] += (fjpkp * vyzzy);
-                    stress->sxz[j][i][k] += (fipkp * vxzzx);
-                    stress->sxx[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vyyzz));
-                    stress->syy[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vxxzz));
-                    stress->szz[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vxxyy));
+                    stress.sxy[j, i, k] += (fipjp * vxyyx);
+                    stress.syz[j, i, k] += (fjpkp * vyzzy);
+                    stress.sxz[j, i, k] += (fipkp * vxzzx);
+                    stress.sxx[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vyyzz));
+                    stress.syy[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vxxzz));
+                    stress.szz[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vxxyy));
                 }
             }
         }
diff --git a/src/update_s_ssg_acoustic.cpp b/src/update_s_ssg_acoustic.cpp
index 3949182..f91375d 100644
--- a/src/update_s_ssg_acoustic.cpp
+++ b/src/update_s_ssg_acoustic.cpp
@@ -28,7 +28,7 @@
 #define UNUSED(x) (void)(x)
 
 double update_s_acoustic(st_boundary *nb, st_velocity &vel,
-                         st_stress *stress, st_model *mod, const GlobVar *gv)
+                         st_stress &stress, st_model *mod, const GlobVar *gv)
 {
     float vxx, vyy, vzz;
     float vxxyyzz;
@@ -49,7 +49,7 @@ double update_s_acoustic(st_boundary *nb, st_velocity &vel,
                     float vxx = (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) * oodx;
                     float vyy = (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) * oody;
                     float vzz = (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) * oodz;
-                    stress->sp[j][i][k] += gv->DT * mod->pi[j][i][k] * (vxx + vyy + vzz);
+                    stress.sp[j, i, k] += gv->DT * mod->pi[j][i][k] * (vxx + vyy + vzz);
                 }
             }
         }
@@ -76,7 +76,7 @@ double update_s_acoustic(st_boundary *nb, st_velocity &vel,
                     float vzz =
                         (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
                          b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) * oodz;
-                    stress->sp[j][i][k] += gv->DT * mod->pi[j][i][k] * (vxx + vyy + vzz);
+                    stress.sp[j, i, k] += gv->DT * mod->pi[j][i][k] * (vxx + vyy + vzz);
                 }
             }
         }
@@ -116,7 +116,7 @@ double update_s_acoustic(st_boundary *nb, st_velocity &vel,
 
                     vxxyyzz = vxx + vyy + vzz;
 
-                    stress->sp[j][i][k] += gv->DT * (g * vxxyyzz);
+                    stress.sp[j, i, k] += gv->DT * (g * vxxyyzz);
                 }
             }
         }
@@ -137,8 +137,7 @@ double update_s_acoustic(st_boundary *nb, st_velocity &vel,
 
         for (int j = nb->ny1; j <= nb->ny2; j++) {
             for (int i = nb->nx1; i <= nb->nx2; i++) {
-                float *sp_j_i = stress->sp[j][i];
-                #pragma omp simd nontemporal(sp_j_i)
+                #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
                     /* spatial derivatives of the components of the velocities
                      * are computed */
@@ -163,7 +162,7 @@ double update_s_acoustic(st_boundary *nb, st_velocity &vel,
 
                     vxxyyzz = vxx + vyy + vzz;
 
-                    sp_j_i[k] += gv->DT * (g * vxxyyzz);
+                    stress.sp[j, i, k] += gv->DT * (g * vxxyyzz);
                 }
             }
         }
@@ -213,7 +212,7 @@ double update_s_acoustic(st_boundary *nb, st_velocity &vel,
 
                     vxxyyzz = vxx + vyy + vzz;
 
-                    stress->sp[j][i][k] += gv->DT * (g * vxxyyzz);
+                    stress.sp[j, i, k] += gv->DT * (g * vxxyyzz);
                 }
             }
         }
@@ -241,8 +240,7 @@ double update_s_acoustic(st_boundary *nb, st_velocity &vel,
 
         for (int j = nb->ny1; j <= nb->ny2; j++) {
             for (int i = nb->nx1; i <= nb->nx2; i++) {
-                float *sp_j_i = stress->sp[j][i];
-                #pragma omp simd nontemporal(sp_j_i)
+                #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
                     /* spatial derivatives of the components of the velocities
                      * are computed */
@@ -272,7 +270,7 @@ double update_s_acoustic(st_boundary *nb, st_velocity &vel,
 
                     vxxyyzz = vxx + vyy + vzz;
 
-                    sp_j_i[k] += gv->DT * (g * vxxyyzz);
+                    stress.sp[j, i, k] += gv->DT * (g * vxxyyzz);
                 }
             }
         }
diff --git a/src/update_s_ssg_elastic.cpp b/src/update_s_ssg_elastic.cpp
index 1ef7b99..b5c2a97 100644
--- a/src/update_s_ssg_elastic.cpp
+++ b/src/update_s_ssg_elastic.cpp
@@ -29,7 +29,7 @@
 #define UNUSED(x) (void)(x)
 
 double update_s_elastic(st_boundary *nb, st_velocity &vel,
-                        st_stress *stress, st_model *mod, st_model_av *mod_av, const GlobVar *gv)
+                        st_stress &stress, st_model *mod, st_model_av *mod_av, const GlobVar *gv)
 {
     float vxx, vxy, vxz, vyx, vyy, vyz, vzx, vzy, vzz;
     float vxyyx, vyzzy, vxzzx, vxxyyzz, vyyzz, vxxzz, vxxyy;
@@ -51,28 +51,28 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
                     vxy = (vel.vx[j + 1, i, k] - vel.vx[j, i, k]) * oody;
                     vyx = (vel.vy[j, i + 1, k] - vel.vy[j, i, k]) * oodx;
-                    stress->sxy[j][i][k] += mod_av->uipjp[j][i][k] * gv->DT * (vxy + vyx);
+                    stress.sxy[j, i, k] += mod_av->uipjp[j][i][k] * gv->DT * (vxy + vyx);
 
                     vyz = (vel.vy[j, i, k + 1] - vel.vy[j, i, k]) * oodz;
                     vzy = (vel.vz[j + 1, i, k] - vel.vz[j, i, k]) * oody;
-                    stress->syz[j][i][k] += mod_av->ujpkp[j][i][k] * gv->DT * (vyz + vzy);
+                    stress.syz[j, i, k] += mod_av->ujpkp[j][i][k] * gv->DT * (vyz + vzy);
 
                     vxz = (vel.vx[j, i, k + 1] - vel.vx[j, i, k]) * oodz;
                     vzx = (vel.vz[j, i + 1, k] - vel.vz[j, i, k]) * oodx;
-                    stress->sxz[j][i][k] += mod_av->uipkp[j][i][k] * gv->DT * (vxz + vzx);
+                    stress.sxz[j, i, k] += mod_av->uipkp[j][i][k] * gv->DT * (vxz + vzx);
 
                     vxx = (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) * oodx;
                     vyy = (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) * oody;
                     vzz = (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) * oodz;
-                    stress->sxx[j][i][k] += gv->DT *
-                                            (mod->pi[j][i][k] * (vxx + vyy + vzz) - 2.0f * mod->u[j][i][k] *
-                                             (vyy + vzz));
-                    stress->syy[j][i][k] += gv->DT *
-                                            (mod->pi[j][i][k] * (vxx + vyy + vzz) - 2.0f * mod->u[j][i][k] *
-                                             (vxx + vzz));
-                    stress->szz[j][i][k] += gv->DT *
-                                            (mod->pi[j][i][k] * (vxx + vyy + vzz) - 2.0f * mod->u[j][i][k] *
-                                             (vxx + vyy));
+                    stress.sxx[j, i, k] += gv->DT *
+                                           (mod->pi[j][i][k] * (vxx + vyy + vzz) - 2.0f * mod->u[j][i][k] *
+                                            (vyy + vzz));
+                    stress.syy[j, i, k] += gv->DT *
+                                           (mod->pi[j][i][k] * (vxx + vyy + vzz) - 2.0f * mod->u[j][i][k] *
+                                            (vxx + vzz));
+                    stress.szz[j, i, k] += gv->DT *
+                                           (mod->pi[j][i][k] * (vxx + vyy + vzz) - 2.0f * mod->u[j][i][k] *
+                                            (vxx + vyy));
                 }
             }
         }
@@ -100,13 +100,7 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                             gv->LEVEL2_CACHE_SIZE / (160 * min(nb->nz2 - nb->nz1, 1024)), , 1024)
         for (int j = j_start; j <= j_end; j++) {
             for (int i = i_start; i <= i_end; i++) {
-                float *sxy_j_i = stress->sxy[j][i];
-                float *syz_j_i = stress->syz[j][i];
-                float *sxz_j_i = stress->sxz[j][i];
-                float *sxx_j_i = stress->sxx[j][i];
-                float *syy_j_i = stress->syy[j][i];
-                float *szz_j_i = stress->szz[j][i];
-                #pragma omp simd nontemporal(sxy_j_i, syz_j_i, sxz_j_i, sxx_j_i, syy_j_i, szz_j_i)
+                #pragma omp simd
                 for (int k = k_start; k <= k_end; k++) {
                     vxy =
                         (b1 * (vel.vx[j + 1, i, k] - vel.vx[j, i, k]) +
@@ -114,7 +108,7 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                     vyx =
                         (b1 * (vel.vy[j, i + 1, k] - vel.vy[j, i, k]) +
                          b2 * (vel.vy[j, i + 2, k] - vel.vy[j, i - 1, k])) * oodx;
-                    sxy_j_i[k] += mod_av->uipjp[j][i][k] * gv->DT * (vxy + vyx);
+                    stress.sxy[j, i, k] += mod_av->uipjp[j][i][k] * gv->DT * (vxy + vyx);
 
                     vyz =
                         (b1 * (vel.vy[j, i, k + 1] - vel.vy[j, i, k]) +
@@ -122,7 +116,7 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                     vzy =
                         (b1 * (vel.vz[j + 1, i, k] - vel.vz[j, i, k]) +
                          b2 * (vel.vz[j + 2, i, k] - vel.vz[j - 1, i, k])) * oody;
-                    syz_j_i[k] += mod_av->ujpkp[j][i][k] * gv->DT * (vyz + vzy);
+                    stress.syz[j, i, k] += mod_av->ujpkp[j][i][k] * gv->DT * (vyz + vzy);
 
                     vxz =
                         (b1 * (vel.vx[j, i, k + 1] - vel.vx[j, i, k]) +
@@ -130,7 +124,7 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                     vzx =
                         (b1 * (vel.vz[j, i + 1, k] - vel.vz[j, i, k]) +
                          b2 * (vel.vz[j, i + 2, k] - vel.vz[j, i - 1, k])) * oodx;
-                    sxz_j_i[k] += mod_av->uipkp[j][i][k] * gv->DT * (vxz + vzx);
+                    stress.sxz[j, i, k] += mod_av->uipkp[j][i][k] * gv->DT * (vxz + vzx);
 
                     vxx =
                         (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
@@ -141,12 +135,15 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                     vzz =
                         (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
                          b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) * oodz;
-                    sxx_j_i[k] += gv->DT *
-                                  (mod->pi[j][i][k] * (vxx + vyy + vzz) - 2.0f * mod->u[j][i][k] * (vyy + vzz));
-                    syy_j_i[k] += gv->DT *
-                                  (mod->pi[j][i][k] * (vxx + vyy + vzz) - 2.0f * mod->u[j][i][k] * (vxx + vzz));
-                    szz_j_i[k] += gv->DT *
-                                  (mod->pi[j][i][k] * (vxx + vyy + vzz) - 2.0f * mod->u[j][i][k] * (vxx + vyy));
+                    stress.sxx[j, i, k] += gv->DT *
+                                           (mod->pi[j][i][k] * (vxx + vyy + vzz) - 2.0f * mod->u[j][i][k] *
+                                            (vyy + vzz));
+                    stress.syy[j, i, k] += gv->DT *
+                                           (mod->pi[j][i][k] * (vxx + vyy + vzz) - 2.0f * mod->u[j][i][k] *
+                                            (vxx + vzz));
+                    stress.szz[j, i, k] += gv->DT *
+                                           (mod->pi[j][i][k] * (vxx + vyy + vzz) - 2.0f * mod->u[j][i][k] *
+                                            (vxx + vyy));
                 }
             }
         }
@@ -221,12 +218,12 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                     vxxzz = vxx + vzz;
                     vxxyy = vxx + vyy;
 
-                    stress->sxy[j][i][k] += (fipjp * vxyyx);
-                    stress->syz[j][i][k] += (fjpkp * vyzzy);
-                    stress->sxz[j][i][k] += (fipkp * vxzzx);
-                    stress->sxx[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vyyzz));
-                    stress->syy[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vxxzz));
-                    stress->szz[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vxxyy));
+                    stress.sxy[j, i, k] += (fipjp * vxyyx);
+                    stress.syz[j, i, k] += (fjpkp * vyzzy);
+                    stress.sxz[j, i, k] += (fipkp * vxzzx);
+                    stress.sxx[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vyyzz));
+                    stress.syy[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vxxzz));
+                    stress.szz[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vxxyy));
                 }
             }
         }
@@ -312,12 +309,12 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                     vxxzz = vxx + vzz;
                     vxxyy = vxx + vyy;
 
-                    stress->sxy[j][i][k] += (fipjp * vxyyx);
-                    stress->syz[j][i][k] += (fjpkp * vyzzy);
-                    stress->sxz[j][i][k] += (fipkp * vxzzx);
-                    stress->sxx[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vyyzz));
-                    stress->syy[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vxxzz));
-                    stress->szz[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vxxyy));
+                    stress.sxy[j, i, k] += (fipjp * vxyyx);
+                    stress.syz[j, i, k] += (fjpkp * vyzzy);
+                    stress.sxz[j, i, k] += (fipkp * vxzzx);
+                    stress.sxx[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vyyzz));
+                    stress.syy[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vxxzz));
+                    stress.szz[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vxxyy));
                 }
             }
         }
@@ -413,12 +410,12 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                     vxxzz = vxx + vzz;
                     vxxyy = vxx + vyy;
 
-                    stress->sxy[j][i][k] += (fipjp * vxyyx);
-                    stress->syz[j][i][k] += (fjpkp * vyzzy);
-                    stress->sxz[j][i][k] += (fipkp * vxzzx);
-                    stress->sxx[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vyyzz));
-                    stress->syy[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vxxzz));
-                    stress->szz[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vxxyy));
+                    stress.sxy[j, i, k] += (fipjp * vxyyx);
+                    stress.syz[j, i, k] += (fjpkp * vyzzy);
+                    stress.sxz[j, i, k] += (fipkp * vxzzx);
+                    stress.sxx[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vyyzz));
+                    stress.syy[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vxxzz));
+                    stress.szz[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vxxyy));
                 }
             }
         }
@@ -528,12 +525,12 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                     vxxzz = vxx + vzz;
                     vxxyy = vxx + vyy;
 
-                    stress->sxy[j][i][k] += (fipjp * vxyyx);
-                    stress->syz[j][i][k] += (fjpkp * vyzzy);
-                    stress->sxz[j][i][k] += (fipkp * vxzzx);
-                    stress->sxx[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vyyzz));
-                    stress->syy[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vxxzz));
-                    stress->szz[j][i][k] += gv->DT * ((g * vxxyyzz) - (f * vxxyy));
+                    stress.sxy[j, i, k] += (fipjp * vxyyx);
+                    stress.syz[j, i, k] += (fjpkp * vyzzy);
+                    stress.sxz[j, i, k] += (fipkp * vxzzx);
+                    stress.sxx[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vyyzz));
+                    stress.syy[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vxxzz));
+                    stress.szz[j, i, k] += gv->DT * ((g * vxxyyzz) - (f * vxxyy));
                 }
             }
         }
diff --git a/src/update_v_ssg.cpp b/src/update_v_ssg.cpp
index fe18ae3..4580227 100644
--- a/src/update_v_ssg.cpp
+++ b/src/update_v_ssg.cpp
@@ -25,7 +25,7 @@
 #include "fd.hpp"
 #include "loop_blocking.hpp"
 
-void update_v(const st_boundary *nb, st_velocity &vel, st_stress *__restrict__ stress, st_model_av *mod_av,
+void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av *mod_av,
               float ***absorb_coeff, const GlobVar *gv)
 {
     float b1, b2, b3, b4, b5, b6;
@@ -42,9 +42,9 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress *__restrict__ s
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    sxx_x = dx * (stress->sxx[j][i + 1][k] - stress->sxx[j][i][k]);
-                    sxy_y = dy * (stress->sxy[j][i][k] - stress->sxy[j - 1][i][k]);
-                    sxz_z = dz * (stress->sxz[j][i][k] - stress->sxz[j][i][k - 1]);
+                    sxx_x = dx * (stress.sxx[j, i + 1, k] - stress.sxx[j, i, k]);
+                    sxy_y = dy * (stress.sxy[j, i, k] - stress.sxy[j - 1, i, k]);
+                    sxz_z = dz * (stress.sxz[j, i, k] - stress.sxz[j, i, k - 1]);
                     vel.vx[j, i, k] += ((sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k]);
                 }
             }
@@ -53,9 +53,9 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress *__restrict__ s
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    syy_y = dy * (stress->syy[j + 1][i][k] - stress->syy[j][i][k]);
-                    sxy_x = dx * (stress->sxy[j][i][k] - stress->sxy[j][i - 1][k]);
-                    syz_z = dz * (stress->syz[j][i][k] - stress->syz[j][i][k - 1]);
+                    syy_y = dy * (stress.syy[j + 1, i, k] - stress.syy[j, i, k]);
+                    sxy_x = dx * (stress.sxy[j, i, k] - stress.sxy[j, i - 1, k]);
+                    syz_z = dz * (stress.syz[j, i, k] - stress.syz[j, i, k - 1]);
                     vel.vy[j, i, k] += ((syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k]);
                 }
             }
@@ -64,9 +64,9 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress *__restrict__ s
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    szz_z = dz * (stress->szz[j][i][k + 1] - stress->szz[j][i][k]);
-                    sxz_x = dx * (stress->sxz[j][i][k] - stress->sxz[j][i - 1][k]);
-                    syz_y = dy * (stress->syz[j][i][k] - stress->syz[j - 1][i][k]);
+                    szz_z = dz * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]);
+                    sxz_x = dx * (stress.sxz[j, i, k] - stress.sxz[j, i - 1, k]);
+                    syz_y = dy * (stress.syz[j, i, k] - stress.syz[j - 1, i, k]);
                     vel.vz[j, i, k] += ((szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k]);
                 }
             }
@@ -99,36 +99,36 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress *__restrict__ s
                 #pragma omp simd
                 for (int k = k_start; k <= k_end; k++) {
                     sxx_x =
-                        dx * (b1 * (stress->sxx[j][i + 1][k] - stress->sxx[j][i][k]) +
-                              b2 * (stress->sxx[j][i + 2][k] - stress->sxx[j][i - 1][k]));
+                        dx * (b1 * (stress.sxx[j, i + 1, k] - stress.sxx[j, i, k]) +
+                              b2 * (stress.sxx[j, i + 2, k] - stress.sxx[j, i - 1, k]));
                     sxy_y =
-                        dy * (b1 * (stress->sxy[j][i][k] - stress->sxy[j - 1][i][k]) +
-                              b2 * (stress->sxy[j + 1][i][k] - stress->sxy[j - 2][i][k]));
+                        dy * (b1 * (stress.sxy[j, i, k] - stress.sxy[j - 1, i, k]) +
+                              b2 * (stress.sxy[j + 1, i, k] - stress.sxy[j - 2, i, k]));
                     sxz_z =
-                        dz * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i][k - 1]) +
-                              b2 * (stress->sxz[j][i][k + 1] - stress->sxz[j][i][k - 2]));
+                        dz * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i, k - 1]) +
+                              b2 * (stress.sxz[j, i, k + 1] - stress.sxz[j, i, k - 2]));
                     vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
 
                     syy_y =
-                        dy * (b1 * (stress->syy[j + 1][i][k] - stress->syy[j][i][k]) +
-                              b2 * (stress->syy[j + 2][i][k] - stress->syy[j - 1][i][k]));
+                        dy * (b1 * (stress.syy[j + 1, i, k] - stress.syy[j, i, k]) +
+                              b2 * (stress.syy[j + 2, i, k] - stress.syy[j - 1, i, k]));
                     sxy_x =
-                        dx * (b1 * (stress->sxy[j][i][k] - stress->sxy[j][i - 1][k]) +
-                              b2 * (stress->sxy[j][i + 1][k] - stress->sxy[j][i - 2][k]));
+                        dx * (b1 * (stress.sxy[j, i, k] - stress.sxy[j, i - 1, k]) +
+                              b2 * (stress.sxy[j, i + 1, k] - stress.sxy[j, i - 2, k]));
                     syz_z =
-                        dz * (b1 * (stress->syz[j][i][k] - stress->syz[j][i][k - 1]) +
-                              b2 * (stress->syz[j][i][k + 1] - stress->syz[j][i][k - 2]));
+                        dz * (b1 * (stress.syz[j, i, k] - stress.syz[j, i, k - 1]) +
+                              b2 * (stress.syz[j, i, k + 1] - stress.syz[j, i, k - 2]));
                     vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
 
                     szz_z =
-                        dz * (b1 * (stress->szz[j][i][k + 1] - stress->szz[j][i][k]) +
-                              b2 * (stress->szz[j][i][k + 2] - stress->szz[j][i][k - 1]));
+                        dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
+                              b2 * (stress.szz[j, i, k + 2] - stress.szz[j, i, k - 1]));
                     sxz_x =
-                        dx * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i - 1][k]) +
-                              b2 * (stress->sxz[j][i + 1][k] - stress->sxz[j][i - 2][k]));
+                        dx * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i - 1, k]) +
+                              b2 * (stress.sxz[j, i + 1, k] - stress.sxz[j, i - 2, k]));
                     syz_y =
-                        dy * (b1 * (stress->syz[j][i][k] - stress->syz[j - 1][i][k]) +
-                              b2 * (stress->syz[j + 1][i][k] - stress->syz[j - 2][i][k]));
+                        dy * (b1 * (stress.syz[j, i, k] - stress.syz[j - 1, i, k]) +
+                              b2 * (stress.syz[j + 1, i, k] - stress.syz[j - 2, i, k]));
                     vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
                 }
             }
@@ -149,36 +149,36 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress *__restrict__ s
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    sxx_x = dx * (b1 * (stress->sxx[j][i + 1][k] - stress->sxx[j][i][k]) +
-                                  b2 * (stress->sxx[j][i + 2][k] - stress->sxx[j][i - 1][k]) +
-                                  b3 * (stress->sxx[j][i + 3][k] - stress->sxx[j][i - 2][k]));
-                    sxy_y = dy * (b1 * (stress->sxy[j][i][k] - stress->sxy[j - 1][i][k]) +
-                                  b2 * (stress->sxy[j + 1][i][k] - stress->sxy[j - 2][i][k]) +
-                                  b3 * (stress->sxy[j + 2][i][k] - stress->sxy[j - 3][i][k]));
-                    sxz_z = dz * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i][k - 1]) +
-                                  b2 * (stress->sxz[j][i][k + 1] - stress->sxz[j][i][k - 2]) +
-                                  b3 * (stress->sxz[j][i][k + 2] - stress->sxz[j][i][k - 3]));
+                    sxx_x = dx * (b1 * (stress.sxx[j, i + 1, k] - stress.sxx[j, i, k]) +
+                                  b2 * (stress.sxx[j, i + 2, k] - stress.sxx[j, i - 1, k]) +
+                                  b3 * (stress.sxx[j, i + 3, k] - stress.sxx[j, i - 2, k]));
+                    sxy_y = dy * (b1 * (stress.sxy[j, i, k] - stress.sxy[j - 1, i, k]) +
+                                  b2 * (stress.sxy[j + 1, i, k] - stress.sxy[j - 2, i, k]) +
+                                  b3 * (stress.sxy[j + 2, i, k] - stress.sxy[j - 3, i, k]));
+                    sxz_z = dz * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i, k - 1]) +
+                                  b2 * (stress.sxz[j, i, k + 1] - stress.sxz[j, i, k - 2]) +
+                                  b3 * (stress.sxz[j, i, k + 2] - stress.sxz[j, i, k - 3]));
                     /* updating components of particle velocities */
                     vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
-                    syy_y = dy * (b1 * (stress->syy[j + 1][i][k] - stress->syy[j][i][k]) +
-                                  b2 * (stress->syy[j + 2][i][k] - stress->syy[j - 1][i][k]) +
-                                  b3 * (stress->syy[j + 3][i][k] - stress->syy[j - 2][i][k]));
-                    sxy_x = dx * (b1 * (stress->sxy[j][i][k] - stress->sxy[j][i - 1][k]) +
-                                  b2 * (stress->sxy[j][i + 1][k] - stress->sxy[j][i - 2][k]) +
-                                  b3 * (stress->sxy[j][i + 2][k] - stress->sxy[j][i - 3][k]));
-                    syz_z = dz * (b1 * (stress->syz[j][i][k] - stress->syz[j][i][k - 1]) +
-                                  b2 * (stress->syz[j][i][k + 1] - stress->syz[j][i][k - 2]) +
-                                  b3 * (stress->syz[j][i][k + 2] - stress->syz[j][i][k - 3]));
+                    syy_y = dy * (b1 * (stress.syy[j + 1, i, k] - stress.syy[j, i, k]) +
+                                  b2 * (stress.syy[j + 2, i, k] - stress.syy[j - 1, i, k]) +
+                                  b3 * (stress.syy[j + 3, i, k] - stress.syy[j - 2, i, k]));
+                    sxy_x = dx * (b1 * (stress.sxy[j, i, k] - stress.sxy[j, i - 1, k]) +
+                                  b2 * (stress.sxy[j, i + 1, k] - stress.sxy[j, i - 2, k]) +
+                                  b3 * (stress.sxy[j, i + 2, k] - stress.sxy[j, i - 3, k]));
+                    syz_z = dz * (b1 * (stress.syz[j, i, k] - stress.syz[j, i, k - 1]) +
+                                  b2 * (stress.syz[j, i, k + 1] - stress.syz[j, i, k - 2]) +
+                                  b3 * (stress.syz[j, i, k + 2] - stress.syz[j, i, k - 3]));
                     vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
-                    szz_z = dz * (b1 * (stress->szz[j][i][k + 1] - stress->szz[j][i][k]) +
-                                  b2 * (stress->szz[j][i][k + 2] - stress->szz[j][i][k - 1]) +
-                                  b3 * (stress->szz[j][i][k + 3] - stress->szz[j][i][k - 2]));
-                    sxz_x = dx * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i - 1][k]) +
-                                  b2 * (stress->sxz[j][i + 1][k] - stress->sxz[j][i - 2][k]) +
-                                  b3 * (stress->sxz[j][i + 2][k] - stress->sxz[j][i - 3][k]));
-                    syz_y = dy * (b1 * (stress->syz[j][i][k] - stress->syz[j - 1][i][k]) +
-                                  b2 * (stress->syz[j + 1][i][k] - stress->syz[j - 2][i][k]) +
-                                  b3 * (stress->syz[j + 2][i][k] - stress->syz[j - 3][i][k]));
+                    szz_z = dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
+                                  b2 * (stress.szz[j, i, k + 2] - stress.szz[j, i, k - 1]) +
+                                  b3 * (stress.szz[j, i, k + 3] - stress.szz[j, i, k - 2]));
+                    sxz_x = dx * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i - 1, k]) +
+                                  b2 * (stress.sxz[j, i + 1, k] - stress.sxz[j, i - 2, k]) +
+                                  b3 * (stress.sxz[j, i + 2, k] - stress.sxz[j, i - 3, k]));
+                    syz_y = dy * (b1 * (stress.syz[j, i, k] - stress.syz[j - 1, i, k]) +
+                                  b2 * (stress.syz[j + 1, i, k] - stress.syz[j - 2, i, k]) +
+                                  b3 * (stress.syz[j + 2, i, k] - stress.syz[j - 3, i, k]));
                     vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
                 }
             }
@@ -199,45 +199,45 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress *__restrict__ s
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    sxx_x = dx * (b1 * (stress->sxx[j][i + 1][k] - stress->sxx[j][i][k]) +
-                                  b2 * (stress->sxx[j][i + 2][k] - stress->sxx[j][i - 1][k]) +
-                                  b3 * (stress->sxx[j][i + 3][k] - stress->sxx[j][i - 2][k]) +
-                                  b4 * (stress->sxx[j][i + 4][k] - stress->sxx[j][i - 3][k]));
-                    sxy_y = dy * (b1 * (stress->sxy[j][i][k] - stress->sxy[j - 1][i][k]) +
-                                  b2 * (stress->sxy[j + 1][i][k] - stress->sxy[j - 2][i][k]) +
-                                  b3 * (stress->sxy[j + 2][i][k] - stress->sxy[j - 3][i][k]) +
-                                  b4 * (stress->sxy[j + 3][i][k] - stress->sxy[j - 4][i][k]));
-                    sxz_z = dz * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i][k - 1]) +
-                                  b2 * (stress->sxz[j][i][k + 1] - stress->sxz[j][i][k - 2]) +
-                                  b3 * (stress->sxz[j][i][k + 2] - stress->sxz[j][i][k - 3]) +
-                                  b4 * (stress->sxz[j][i][k + 3] - stress->sxz[j][i][k - 4]));
+                    sxx_x = dx * (b1 * (stress.sxx[j, i + 1, k] - stress.sxx[j, i, k]) +
+                                  b2 * (stress.sxx[j, i + 2, k] - stress.sxx[j, i - 1, k]) +
+                                  b3 * (stress.sxx[j, i + 3, k] - stress.sxx[j, i - 2, k]) +
+                                  b4 * (stress.sxx[j, i + 4, k] - stress.sxx[j, i - 3, k]));
+                    sxy_y = dy * (b1 * (stress.sxy[j, i, k] - stress.sxy[j - 1, i, k]) +
+                                  b2 * (stress.sxy[j + 1, i, k] - stress.sxy[j - 2, i, k]) +
+                                  b3 * (stress.sxy[j + 2, i, k] - stress.sxy[j - 3, i, k]) +
+                                  b4 * (stress.sxy[j + 3, i, k] - stress.sxy[j - 4, i, k]));
+                    sxz_z = dz * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i, k - 1]) +
+                                  b2 * (stress.sxz[j, i, k + 1] - stress.sxz[j, i, k - 2]) +
+                                  b3 * (stress.sxz[j, i, k + 2] - stress.sxz[j, i, k - 3]) +
+                                  b4 * (stress.sxz[j, i, k + 3] - stress.sxz[j, i, k - 4]));
                     /* updating components of particle velocities */
                     vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
-                    syy_y = dy * (b1 * (stress->syy[j + 1][i][k] - stress->syy[j][i][k]) +
-                                  b2 * (stress->syy[j + 2][i][k] - stress->syy[j - 1][i][k]) +
-                                  b3 * (stress->syy[j + 3][i][k] - stress->syy[j - 2][i][k]) +
-                                  b4 * (stress->syy[j + 4][i][k] - stress->syy[j - 3][i][k]));
-                    sxy_x = dx * (b1 * (stress->sxy[j][i][k] - stress->sxy[j][i - 1][k]) +
-                                  b2 * (stress->sxy[j][i + 1][k] - stress->sxy[j][i - 2][k]) +
-                                  b3 * (stress->sxy[j][i + 2][k] - stress->sxy[j][i - 3][k]) +
-                                  b4 * (stress->sxy[j][i + 3][k] - stress->sxy[j][i - 4][k]));
-                    syz_z = dz * (b1 * (stress->syz[j][i][k] - stress->syz[j][i][k - 1]) +
-                                  b2 * (stress->syz[j][i][k + 1] - stress->syz[j][i][k - 2]) +
-                                  b3 * (stress->syz[j][i][k + 2] - stress->syz[j][i][k - 3]) +
-                                  b4 * (stress->syz[j][i][k + 3] - stress->syz[j][i][k - 4]));
+                    syy_y = dy * (b1 * (stress.syy[j + 1, i, k] - stress.syy[j, i, k]) +
+                                  b2 * (stress.syy[j + 2, i, k] - stress.syy[j - 1, i, k]) +
+                                  b3 * (stress.syy[j + 3, i, k] - stress.syy[j - 2, i, k]) +
+                                  b4 * (stress.syy[j + 4, i, k] - stress.syy[j - 3, i, k]));
+                    sxy_x = dx * (b1 * (stress.sxy[j, i, k] - stress.sxy[j, i - 1, k]) +
+                                  b2 * (stress.sxy[j, i + 1, k] - stress.sxy[j, i - 2, k]) +
+                                  b3 * (stress.sxy[j, i + 2, k] - stress.sxy[j, i - 3, k]) +
+                                  b4 * (stress.sxy[j, i + 3, k] - stress.sxy[j, i - 4, k]));
+                    syz_z = dz * (b1 * (stress.syz[j, i, k] - stress.syz[j, i, k - 1]) +
+                                  b2 * (stress.syz[j, i, k + 1] - stress.syz[j, i, k - 2]) +
+                                  b3 * (stress.syz[j, i, k + 2] - stress.syz[j, i, k - 3]) +
+                                  b4 * (stress.syz[j, i, k + 3] - stress.syz[j, i, k - 4]));
                     vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
-                    szz_z = dz * (b1 * (stress->szz[j][i][k + 1] - stress->szz[j][i][k]) +
-                                  b2 * (stress->szz[j][i][k + 2] - stress->szz[j][i][k - 1]) +
-                                  b3 * (stress->szz[j][i][k + 3] - stress->szz[j][i][k - 2]) +
-                                  b4 * (stress->szz[j][i][k + 4] - stress->szz[j][i][k - 3]));
-                    sxz_x = dx * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i - 1][k]) +
-                                  b2 * (stress->sxz[j][i + 1][k] - stress->sxz[j][i - 2][k]) +
-                                  b3 * (stress->sxz[j][i + 2][k] - stress->sxz[j][i - 3][k]) +
-                                  b4 * (stress->sxz[j][i + 3][k] - stress->sxz[j][i - 4][k]));
-                    syz_y = dy * (b1 * (stress->syz[j][i][k] - stress->syz[j - 1][i][k]) +
-                                  b2 * (stress->syz[j + 1][i][k] - stress->syz[j - 2][i][k]) +
-                                  b3 * (stress->syz[j + 2][i][k] - stress->syz[j - 3][i][k]) +
-                                  b4 * (stress->syz[j + 3][i][k] - stress->syz[j - 4][i][k]));
+                    szz_z = dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
+                                  b2 * (stress.szz[j, i, k + 2] - stress.szz[j, i, k - 1]) +
+                                  b3 * (stress.szz[j, i, k + 3] - stress.szz[j, i, k - 2]) +
+                                  b4 * (stress.szz[j, i, k + 4] - stress.szz[j, i, k - 3]));
+                    sxz_x = dx * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i - 1, k]) +
+                                  b2 * (stress.sxz[j, i + 1, k] - stress.sxz[j, i - 2, k]) +
+                                  b3 * (stress.sxz[j, i + 2, k] - stress.sxz[j, i - 3, k]) +
+                                  b4 * (stress.sxz[j, i + 3, k] - stress.sxz[j, i - 4, k]));
+                    syz_y = dy * (b1 * (stress.syz[j, i, k] - stress.syz[j - 1, i, k]) +
+                                  b2 * (stress.syz[j + 1, i, k] - stress.syz[j - 2, i, k]) +
+                                  b3 * (stress.syz[j + 2, i, k] - stress.syz[j - 3, i, k]) +
+                                  b4 * (stress.syz[j + 3, i, k] - stress.syz[j - 4, i, k]));
                     vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
                 }
             }
@@ -260,54 +260,54 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress *__restrict__ s
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    sxx_x = dx * (b1 * (stress->sxx[j][i + 1][k] - stress->sxx[j][i][k]) +
-                                  b2 * (stress->sxx[j][i + 2][k] - stress->sxx[j][i - 1][k]) +
-                                  b3 * (stress->sxx[j][i + 3][k] - stress->sxx[j][i - 2][k]) +
-                                  b4 * (stress->sxx[j][i + 4][k] - stress->sxx[j][i - 3][k]) +
-                                  b5 * (stress->sxx[j][i + 5][k] - stress->sxx[j][i - 4][k]));
-                    sxy_y = dy * (b1 * (stress->sxy[j][i][k] - stress->sxy[j - 1][i][k]) +
-                                  b2 * (stress->sxy[j + 1][i][k] - stress->sxy[j - 2][i][k]) +
-                                  b3 * (stress->sxy[j + 2][i][k] - stress->sxy[j - 3][i][k]) +
-                                  b4 * (stress->sxy[j + 3][i][k] - stress->sxy[j - 4][i][k]) +
-                                  b5 * (stress->sxy[j + 4][i][k] - stress->sxy[j - 5][i][k]));
-                    sxz_z = dz * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i][k - 1]) +
-                                  b2 * (stress->sxz[j][i][k + 1] - stress->sxz[j][i][k - 2]) +
-                                  b3 * (stress->sxz[j][i][k + 2] - stress->sxz[j][i][k - 3]) +
-                                  b4 * (stress->sxz[j][i][k + 3] - stress->sxz[j][i][k - 4]) +
-                                  b5 * (stress->sxz[j][i][k + 4] - stress->sxz[j][i][k - 5]));
+                    sxx_x = dx * (b1 * (stress.sxx[j, i + 1, k] - stress.sxx[j, i, k]) +
+                                  b2 * (stress.sxx[j, i + 2, k] - stress.sxx[j, i - 1, k]) +
+                                  b3 * (stress.sxx[j, i + 3, k] - stress.sxx[j, i - 2, k]) +
+                                  b4 * (stress.sxx[j, i + 4, k] - stress.sxx[j, i - 3, k]) +
+                                  b5 * (stress.sxx[j, i + 5, k] - stress.sxx[j, i - 4, k]));
+                    sxy_y = dy * (b1 * (stress.sxy[j, i, k] - stress.sxy[j - 1, i, k]) +
+                                  b2 * (stress.sxy[j + 1, i, k] - stress.sxy[j - 2, i, k]) +
+                                  b3 * (stress.sxy[j + 2, i, k] - stress.sxy[j - 3, i, k]) +
+                                  b4 * (stress.sxy[j + 3, i, k] - stress.sxy[j - 4, i, k]) +
+                                  b5 * (stress.sxy[j + 4, i, k] - stress.sxy[j - 5, i, k]));
+                    sxz_z = dz * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i, k - 1]) +
+                                  b2 * (stress.sxz[j, i, k + 1] - stress.sxz[j, i, k - 2]) +
+                                  b3 * (stress.sxz[j, i, k + 2] - stress.sxz[j, i, k - 3]) +
+                                  b4 * (stress.sxz[j, i, k + 3] - stress.sxz[j, i, k - 4]) +
+                                  b5 * (stress.sxz[j, i, k + 4] - stress.sxz[j, i, k - 5]));
                     /* updating components of particle velocities */
                     vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
-                    syy_y = dy * (b1 * (stress->syy[j + 1][i][k] - stress->syy[j][i][k]) +
-                                  b2 * (stress->syy[j + 2][i][k] - stress->syy[j - 1][i][k]) +
-                                  b3 * (stress->syy[j + 3][i][k] - stress->syy[j - 2][i][k]) +
-                                  b4 * (stress->syy[j + 4][i][k] - stress->syy[j - 3][i][k]) +
-                                  b5 * (stress->syy[j + 5][i][k] - stress->syy[j - 4][i][k]));
-                    sxy_x = dx * (b1 * (stress->sxy[j][i][k] - stress->sxy[j][i - 1][k]) +
-                                  b2 * (stress->sxy[j][i + 1][k] - stress->sxy[j][i - 2][k]) +
-                                  b3 * (stress->sxy[j][i + 2][k] - stress->sxy[j][i - 3][k]) +
-                                  b4 * (stress->sxy[j][i + 3][k] - stress->sxy[j][i - 4][k]) +
-                                  b5 * (stress->sxy[j][i + 4][k] - stress->sxy[j][i - 5][k]));
-                    syz_z = dz * (b1 * (stress->syz[j][i][k] - stress->syz[j][i][k - 1]) +
-                                  b2 * (stress->syz[j][i][k + 1] - stress->syz[j][i][k - 2]) +
-                                  b3 * (stress->syz[j][i][k + 2] - stress->syz[j][i][k - 3]) +
-                                  b4 * (stress->syz[j][i][k + 3] - stress->syz[j][i][k - 4]) +
-                                  b5 * (stress->syz[j][i][k + 4] - stress->syz[j][i][k - 5]));
+                    syy_y = dy * (b1 * (stress.syy[j + 1, i, k] - stress.syy[j, i, k]) +
+                                  b2 * (stress.syy[j + 2, i, k] - stress.syy[j - 1, i, k]) +
+                                  b3 * (stress.syy[j + 3, i, k] - stress.syy[j - 2, i, k]) +
+                                  b4 * (stress.syy[j + 4, i, k] - stress.syy[j - 3, i, k]) +
+                                  b5 * (stress.syy[j + 5, i, k] - stress.syy[j - 4, i, k]));
+                    sxy_x = dx * (b1 * (stress.sxy[j, i, k] - stress.sxy[j, i - 1, k]) +
+                                  b2 * (stress.sxy[j, i + 1, k] - stress.sxy[j, i - 2, k]) +
+                                  b3 * (stress.sxy[j, i + 2, k] - stress.sxy[j, i - 3, k]) +
+                                  b4 * (stress.sxy[j, i + 3, k] - stress.sxy[j, i - 4, k]) +
+                                  b5 * (stress.sxy[j, i + 4, k] - stress.sxy[j, i - 5, k]));
+                    syz_z = dz * (b1 * (stress.syz[j, i, k] - stress.syz[j, i, k - 1]) +
+                                  b2 * (stress.syz[j, i, k + 1] - stress.syz[j, i, k - 2]) +
+                                  b3 * (stress.syz[j, i, k + 2] - stress.syz[j, i, k - 3]) +
+                                  b4 * (stress.syz[j, i, k + 3] - stress.syz[j, i, k - 4]) +
+                                  b5 * (stress.syz[j, i, k + 4] - stress.syz[j, i, k - 5]));
                     vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
-                    szz_z = dz * (b1 * (stress->szz[j][i][k + 1] - stress->szz[j][i][k]) +
-                                  b2 * (stress->szz[j][i][k + 2] - stress->szz[j][i][k - 1]) +
-                                  b3 * (stress->szz[j][i][k + 3] - stress->szz[j][i][k - 2]) +
-                                  b4 * (stress->szz[j][i][k + 4] - stress->szz[j][i][k - 3]) +
-                                  b5 * (stress->szz[j][i][k + 5] - stress->szz[j][i][k - 4]));
-                    sxz_x = dx * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i - 1][k]) +
-                                  b2 * (stress->sxz[j][i + 1][k] - stress->sxz[j][i - 2][k]) +
-                                  b3 * (stress->sxz[j][i + 2][k] - stress->sxz[j][i - 3][k]) +
-                                  b4 * (stress->sxz[j][i + 3][k] - stress->sxz[j][i - 4][k]) +
-                                  b5 * (stress->sxz[j][i + 4][k] - stress->sxz[j][i - 5][k]));
-                    syz_y = dy * (b1 * (stress->syz[j][i][k] - stress->syz[j - 1][i][k]) +
-                                  b2 * (stress->syz[j + 1][i][k] - stress->syz[j - 2][i][k]) +
-                                  b3 * (stress->syz[j + 2][i][k] - stress->syz[j - 3][i][k]) +
-                                  b4 * (stress->syz[j + 3][i][k] - stress->syz[j - 4][i][k]) +
-                                  b5 * (stress->syz[j + 4][i][k] - stress->syz[j - 5][i][k]));
+                    szz_z = dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
+                                  b2 * (stress.szz[j, i, k + 2] - stress.szz[j, i, k - 1]) +
+                                  b3 * (stress.szz[j, i, k + 3] - stress.szz[j, i, k - 2]) +
+                                  b4 * (stress.szz[j, i, k + 4] - stress.szz[j, i, k - 3]) +
+                                  b5 * (stress.szz[j, i, k + 5] - stress.szz[j, i, k - 4]));
+                    sxz_x = dx * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i - 1, k]) +
+                                  b2 * (stress.sxz[j, i + 1, k] - stress.sxz[j, i - 2, k]) +
+                                  b3 * (stress.sxz[j, i + 2, k] - stress.sxz[j, i - 3, k]) +
+                                  b4 * (stress.sxz[j, i + 3, k] - stress.sxz[j, i - 4, k]) +
+                                  b5 * (stress.sxz[j, i + 4, k] - stress.sxz[j, i - 5, k]));
+                    syz_y = dy * (b1 * (stress.syz[j, i, k] - stress.syz[j - 1, i, k]) +
+                                  b2 * (stress.syz[j + 1, i, k] - stress.syz[j - 2, i, k]) +
+                                  b3 * (stress.syz[j + 2, i, k] - stress.syz[j - 3, i, k]) +
+                                  b4 * (stress.syz[j + 3, i, k] - stress.syz[j - 4, i, k]) +
+                                  b5 * (stress.syz[j + 4, i, k] - stress.syz[j - 5, i, k]));
                     vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
                 }
             }
@@ -334,63 +334,63 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress *__restrict__ s
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    sxx_x = dx * (b1 * (stress->sxx[j][i + 1][k] - stress->sxx[j][i][k]) +
-                                  b2 * (stress->sxx[j][i + 2][k] - stress->sxx[j][i - 1][k]) +
-                                  b3 * (stress->sxx[j][i + 3][k] - stress->sxx[j][i - 2][k]) +
-                                  b4 * (stress->sxx[j][i + 4][k] - stress->sxx[j][i - 3][k]) +
-                                  b5 * (stress->sxx[j][i + 5][k] - stress->sxx[j][i - 4][k]) +
-                                  b6 * (stress->sxx[j][i + 6][k] - stress->sxx[j][i - 5][k]));
-                    sxy_y = dy * (b1 * (stress->sxy[j][i][k] - stress->sxy[j - 1][i][k]) +
-                                  b2 * (stress->sxy[j + 1][i][k] - stress->sxy[j - 2][i][k]) +
-                                  b3 * (stress->sxy[j + 2][i][k] - stress->sxy[j - 3][i][k]) +
-                                  b4 * (stress->sxy[j + 3][i][k] - stress->sxy[j - 4][i][k]) +
-                                  b5 * (stress->sxy[j + 4][i][k] - stress->sxy[j - 5][i][k]) +
-                                  b6 * (stress->sxy[j + 5][i][k] - stress->sxy[j - 6][i][k]));
-                    sxz_z = dz * (b1 * (stress->sxy[j][i][k] - stress->sxy[j][i][k - 1]) +
-                                  b2 * (stress->sxy[j][i][k + 1] - stress->sxy[j][i][k - 2]) +
-                                  b3 * (stress->sxy[j][i][k + 2] - stress->sxy[j][i][k - 3]) +
-                                  b4 * (stress->sxy[j][i][k + 3] - stress->sxy[j][i][k - 4]) +
-                                  b5 * (stress->sxy[j][i][k + 4] - stress->sxy[j][i][k - 5]) +
-                                  b6 * (stress->sxy[j][i][k + 5] - stress->sxy[j][i][k - 6]));
+                    sxx_x = dx * (b1 * (stress.sxx[j, i + 1, k] - stress.sxx[j, i, k]) +
+                                  b2 * (stress.sxx[j, i + 2, k] - stress.sxx[j, i - 1, k]) +
+                                  b3 * (stress.sxx[j, i + 3, k] - stress.sxx[j, i - 2, k]) +
+                                  b4 * (stress.sxx[j, i + 4, k] - stress.sxx[j, i - 3, k]) +
+                                  b5 * (stress.sxx[j, i + 5, k] - stress.sxx[j, i - 4, k]) +
+                                  b6 * (stress.sxx[j, i + 6, k] - stress.sxx[j, i - 5, k]));
+                    sxy_y = dy * (b1 * (stress.sxy[j, i, k] - stress.sxy[j - 1, i, k]) +
+                                  b2 * (stress.sxy[j + 1, i, k] - stress.sxy[j - 2, i, k]) +
+                                  b3 * (stress.sxy[j + 2, i, k] - stress.sxy[j - 3, i, k]) +
+                                  b4 * (stress.sxy[j + 3, i, k] - stress.sxy[j - 4, i, k]) +
+                                  b5 * (stress.sxy[j + 4, i, k] - stress.sxy[j - 5, i, k]) +
+                                  b6 * (stress.sxy[j + 5, i, k] - stress.sxy[j - 6, i, k]));
+                    sxz_z = dz * (b1 * (stress.sxy[j, i, k] - stress.sxy[j, i, k - 1]) +
+                                  b2 * (stress.sxy[j, i, k + 1] - stress.sxy[j, i, k - 2]) +
+                                  b3 * (stress.sxy[j, i, k + 2] - stress.sxy[j, i, k - 3]) +
+                                  b4 * (stress.sxy[j, i, k + 3] - stress.sxy[j, i, k - 4]) +
+                                  b5 * (stress.sxy[j, i, k + 4] - stress.sxy[j, i, k - 5]) +
+                                  b6 * (stress.sxy[j, i, k + 5] - stress.sxy[j, i, k - 6]));
                     /* updating components of particle velocities */
                     vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
-                    syy_y = dy * (b1 * (stress->syy[j + 1][i][k] - stress->syy[j][i][k]) +
-                                  b2 * (stress->syy[j + 2][i][k] - stress->syy[j - 1][i][k]) +
-                                  b3 * (stress->syy[j + 3][i][k] - stress->syy[j - 2][i][k]) +
-                                  b4 * (stress->syy[j + 4][i][k] - stress->syy[j - 3][i][k]) +
-                                  b5 * (stress->syy[j + 5][i][k] - stress->syy[j - 4][i][k]) +
-                                  b6 * (stress->syy[j + 6][i][k] - stress->syy[j - 5][i][k]));
-                    sxy_x = dx * (b1 * (stress->sxy[j][i][k] - stress->sxy[j][i - 1][k]) +
-                                  b2 * (stress->sxy[j][i + 1][k] - stress->sxy[j][i - 2][k]) +
-                                  b3 * (stress->sxy[j][i + 2][k] - stress->sxy[j][i - 3][k]) +
-                                  b4 * (stress->sxy[j][i + 3][k] - stress->sxy[j][i - 4][k]) +
-                                  b5 * (stress->sxy[j][i + 4][k] - stress->sxy[j][i - 5][k]) +
-                                  b6 * (stress->sxy[j][i + 5][k] - stress->sxy[j][i - 6][k]));
-                    syz_z = dz * (b1 * (stress->syz[j][i][k] - stress->syz[j][i][k - 1]) +
-                                  b2 * (stress->syz[j][i][k + 1] - stress->syz[j][i][k - 2]) +
-                                  b3 * (stress->syz[j][i][k + 2] - stress->syz[j][i][k - 3]) +
-                                  b4 * (stress->syz[j][i][k + 3] - stress->syz[j][i][k - 4]) +
-                                  b5 * (stress->syz[j][i][k + 4] - stress->syz[j][i][k - 5]) +
-                                  b6 * (stress->syz[j][i][k + 5] - stress->syz[j][i][k - 6]));
+                    syy_y = dy * (b1 * (stress.syy[j + 1, i, k] - stress.syy[j, i, k]) +
+                                  b2 * (stress.syy[j + 2, i, k] - stress.syy[j - 1, i, k]) +
+                                  b3 * (stress.syy[j + 3, i, k] - stress.syy[j - 2, i, k]) +
+                                  b4 * (stress.syy[j + 4, i, k] - stress.syy[j - 3, i, k]) +
+                                  b5 * (stress.syy[j + 5, i, k] - stress.syy[j - 4, i, k]) +
+                                  b6 * (stress.syy[j + 6, i, k] - stress.syy[j - 5, i, k]));
+                    sxy_x = dx * (b1 * (stress.sxy[j, i, k] - stress.sxy[j, i - 1, k]) +
+                                  b2 * (stress.sxy[j, i + 1, k] - stress.sxy[j, i - 2, k]) +
+                                  b3 * (stress.sxy[j, i + 2, k] - stress.sxy[j, i - 3, k]) +
+                                  b4 * (stress.sxy[j, i + 3, k] - stress.sxy[j, i - 4, k]) +
+                                  b5 * (stress.sxy[j, i + 4, k] - stress.sxy[j, i - 5, k]) +
+                                  b6 * (stress.sxy[j, i + 5, k] - stress.sxy[j, i - 6, k]));
+                    syz_z = dz * (b1 * (stress.syz[j, i, k] - stress.syz[j, i, k - 1]) +
+                                  b2 * (stress.syz[j, i, k + 1] - stress.syz[j, i, k - 2]) +
+                                  b3 * (stress.syz[j, i, k + 2] - stress.syz[j, i, k - 3]) +
+                                  b4 * (stress.syz[j, i, k + 3] - stress.syz[j, i, k - 4]) +
+                                  b5 * (stress.syz[j, i, k + 4] - stress.syz[j, i, k - 5]) +
+                                  b6 * (stress.syz[j, i, k + 5] - stress.syz[j, i, k - 6]));
                     vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
-                    szz_z = dz * (b1 * (stress->szz[j][i][k + 1] - stress->szz[j][i][k]) +
-                                  b2 * (stress->szz[j][i][k + 2] - stress->szz[j][i][k - 1]) +
-                                  b3 * (stress->szz[j][i][k + 3] - stress->szz[j][i][k - 2]) +
-                                  b4 * (stress->szz[j][i][k + 4] - stress->szz[j][i][k - 3]) +
-                                  b5 * (stress->szz[j][i][k + 5] - stress->szz[j][i][k - 4]) +
-                                  b6 * (stress->szz[j][i][k + 6] - stress->szz[j][i][k - 5]));
-                    sxz_x = dx * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i - 1][k]) +
-                                  b2 * (stress->sxz[j][i + 1][k] - stress->sxz[j][i - 2][k]) +
-                                  b3 * (stress->sxz[j][i + 2][k] - stress->sxz[j][i - 3][k]) +
-                                  b4 * (stress->sxz[j][i + 3][k] - stress->sxz[j][i - 4][k]) +
-                                  b5 * (stress->sxz[j][i + 4][k] - stress->sxz[j][i - 5][k]) +
-                                  b6 * (stress->sxz[j][i + 5][k] - stress->sxz[j][i - 6][k]));
-                    syz_y = dy * (b1 * (stress->syz[j][i][k] - stress->syz[j - 1][i][k]) +
-                                  b2 * (stress->syz[j + 1][i][k] - stress->syz[j - 2][i][k]) +
-                                  b3 * (stress->syz[j + 2][i][k] - stress->syz[j - 3][i][k]) +
-                                  b4 * (stress->syz[j + 3][i][k] - stress->syz[j - 4][i][k]) +
-                                  b5 * (stress->syz[j + 4][i][k] - stress->syz[j - 5][i][k]) +
-                                  b6 * (stress->syz[j + 5][i][k] - stress->syz[j - 6][i][k]));
+                    szz_z = dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
+                                  b2 * (stress.szz[j, i, k + 2] - stress.szz[j, i, k - 1]) +
+                                  b3 * (stress.szz[j, i, k + 3] - stress.szz[j, i, k - 2]) +
+                                  b4 * (stress.szz[j, i, k + 4] - stress.szz[j, i, k - 3]) +
+                                  b5 * (stress.szz[j, i, k + 5] - stress.szz[j, i, k - 4]) +
+                                  b6 * (stress.szz[j, i, k + 6] - stress.szz[j, i, k - 5]));
+                    sxz_x = dx * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i - 1, k]) +
+                                  b2 * (stress.sxz[j, i + 1, k] - stress.sxz[j, i - 2, k]) +
+                                  b3 * (stress.sxz[j, i + 2, k] - stress.sxz[j, i - 3, k]) +
+                                  b4 * (stress.sxz[j, i + 3, k] - stress.sxz[j, i - 4, k]) +
+                                  b5 * (stress.sxz[j, i + 4, k] - stress.sxz[j, i - 5, k]) +
+                                  b6 * (stress.sxz[j, i + 5, k] - stress.sxz[j, i - 6, k]));
+                    syz_y = dy * (b1 * (stress.syz[j, i, k] - stress.syz[j - 1, i, k]) +
+                                  b2 * (stress.syz[j + 1, i, k] - stress.syz[j - 2, i, k]) +
+                                  b3 * (stress.syz[j + 2, i, k] - stress.syz[j - 3, i, k]) +
+                                  b4 * (stress.syz[j + 3, i, k] - stress.syz[j - 4, i, k]) +
+                                  b5 * (stress.syz[j + 4, i, k] - stress.syz[j - 5, i, k]) +
+                                  b6 * (stress.syz[j + 5, i, k] - stress.syz[j - 6, i, k]));
                     vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
                 }
             }
@@ -407,12 +407,12 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress *__restrict__ s
                     vel.vx[j, i, k] *= absorb_coeff[j][i][k];
                     vel.vy[j, i, k] *= absorb_coeff[j][i][k];
                     vel.vz[j, i, k] *= absorb_coeff[j][i][k];
-                    stress->sxy[j][i][k] *= absorb_coeff[j][i][k];
-                    stress->syz[j][i][k] *= absorb_coeff[j][i][k];
-                    stress->sxz[j][i][k] *= absorb_coeff[j][i][k];
-                    stress->sxx[j][i][k] *= absorb_coeff[j][i][k];
-                    stress->syy[j][i][k] *= absorb_coeff[j][i][k];
-                    stress->szz[j][i][k] *= absorb_coeff[j][i][k];
+                    stress.sxy[j, i, k] *= absorb_coeff[j][i][k];
+                    stress.syz[j, i, k] *= absorb_coeff[j][i][k];
+                    stress.sxz[j, i, k] *= absorb_coeff[j][i][k];
+                    stress.sxx[j, i, k] *= absorb_coeff[j][i][k];
+                    stress.syy[j, i, k] *= absorb_coeff[j][i][k];
+                    stress.szz[j, i, k] *= absorb_coeff[j][i][k];
                 }
             }
         }
diff --git a/src/update_v_ssg_CPML.cpp b/src/update_v_ssg_CPML.cpp
index 536de09..2339388 100644
--- a/src/update_v_ssg_CPML.cpp
+++ b/src/update_v_ssg_CPML.cpp
@@ -30,7 +30,7 @@
 
 #define UNUSED(x) (void)(x)
 
-void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress *stress, st_model_av *mod_av,
+void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av *mod_av,
                    st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, const GlobVar *gv)
 {
     float sxx_x = 0.0, sxy_y = 0.0, sxz_z = 0.0, syy_y = 0.0, sxy_x = 0.0, syz_z = 0.0;
@@ -57,32 +57,32 @@ void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress *stress, st_mode
                 #pragma omp simd
                 for (int k = 1; k <= gv->NZ; k++) {
                     sxx_x =
-                        dx * (b1 * (stress->sxx[j][i + 1][k] - stress->sxx[j][i][k]) +
-                              b2 * (stress->sxx[j][i + 2][k] - stress->sxx[j][i - 1][k]));
+                        dx * (b1 * (stress.sxx[j, i + 1, k] - stress.sxx[j, i, k]) +
+                              b2 * (stress.sxx[j, i + 2, k] - stress.sxx[j, i - 1, k]));
                     sxy_x =
-                        dx * (b1 * (stress->sxy[j][i][k] - stress->sxy[j][i - 1][k]) +
-                              b2 * (stress->sxy[j][i + 1][k] - stress->sxy[j][i - 2][k]));
+                        dx * (b1 * (stress.sxy[j, i, k] - stress.sxy[j, i - 1, k]) +
+                              b2 * (stress.sxy[j, i + 1, k] - stress.sxy[j, i - 2, k]));
                     sxz_x =
-                        dx * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i - 1][k]) +
-                              b2 * (stress->sxz[j][i + 1][k] - stress->sxz[j][i - 2][k]));
+                        dx * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i - 1, k]) +
+                              b2 * (stress.sxz[j, i + 1, k] - stress.sxz[j, i - 2, k]));
                     sxy_y =
-                        dy * (b1 * (stress->sxy[j][i][k] - stress->sxy[j - 1][i][k]) +
-                              b2 * (stress->sxy[j + 1][i][k] - stress->sxy[j - 2][i][k]));
+                        dy * (b1 * (stress.sxy[j, i, k] - stress.sxy[j - 1, i, k]) +
+                              b2 * (stress.sxy[j + 1, i, k] - stress.sxy[j - 2, i, k]));
                     syy_y =
-                        dy * (b1 * (stress->syy[j + 1][i][k] - stress->syy[j][i][k]) +
-                              b2 * (stress->syy[j + 2][i][k] - stress->syy[j - 1][i][k]));
+                        dy * (b1 * (stress.syy[j + 1, i, k] - stress.syy[j, i, k]) +
+                              b2 * (stress.syy[j + 2, i, k] - stress.syy[j - 1, i, k]));
                     syz_y =
-                        dy * (b1 * (stress->syz[j][i][k] - stress->syz[j - 1][i][k]) +
-                              b2 * (stress->syz[j + 1][i][k] - stress->syz[j - 2][i][k]));
+                        dy * (b1 * (stress.syz[j, i, k] - stress.syz[j - 1, i, k]) +
+                              b2 * (stress.syz[j + 1, i, k] - stress.syz[j - 2, i, k]));
                     sxz_z =
-                        dz * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i][k - 1]) +
-                              b2 * (stress->sxz[j][i][k + 1] - stress->sxz[j][i][k - 2]));
+                        dz * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i, k - 1]) +
+                              b2 * (stress.sxz[j, i, k + 1] - stress.sxz[j, i, k - 2]));
                     syz_z =
-                        dz * (b1 * (stress->syz[j][i][k] - stress->syz[j][i][k - 1]) +
-                              b2 * (stress->syz[j][i][k + 1] - stress->syz[j][i][k - 2]));
+                        dz * (b1 * (stress.syz[j, i, k] - stress.syz[j, i, k - 1]) +
+                              b2 * (stress.syz[j, i, k + 1] - stress.syz[j, i, k - 2]));
                     szz_z =
-                        dz * (b1 * (stress->szz[j][i][k + 1] - stress->szz[j][i][k]) +
-                              b2 * (stress->szz[j][i][k + 2] - stress->szz[j][i][k - 1]));
+                        dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
+                              b2 * (stress.szz[j, i, k + 2] - stress.szz[j, i, k - 1]));
                     pml_wfd->psi_sxx_x[j][i][k] =
                         pml_coeff->b_x_half[i] * pml_wfd->psi_sxx_x[j][i][k] + pml_coeff->a_x_half[i] * sxx_x;
                     sxx_x = sxx_x / pml_coeff->K_x_half[i] + pml_wfd->psi_sxx_x[j][i][k];
@@ -157,32 +157,32 @@ void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress *stress, st_mode
                 #pragma omp simd
                 for (int k = 1; k <= gv->NZ; k++) {
                     sxx_x =
-                        dx * (b1 * (stress->sxx[j][i + 1][k] - stress->sxx[j][i][k]) +
-                              b2 * (stress->sxx[j][i + 2][k] - stress->sxx[j][i - 1][k]));
+                        dx * (b1 * (stress.sxx[j, i + 1, k] - stress.sxx[j, i, k]) +
+                              b2 * (stress.sxx[j, i + 2, k] - stress.sxx[j, i - 1, k]));
                     sxy_x =
-                        dx * (b1 * (stress->sxy[j][i][k] - stress->sxy[j][i - 1][k]) +
-                              b2 * (stress->sxy[j][i + 1][k] - stress->sxy[j][i - 2][k]));
+                        dx * (b1 * (stress.sxy[j, i, k] - stress.sxy[j, i - 1, k]) +
+                              b2 * (stress.sxy[j, i + 1, k] - stress.sxy[j, i - 2, k]));
                     sxz_x =
-                        dx * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i - 1][k]) +
-                              b2 * (stress->sxz[j][i + 1][k] - stress->sxz[j][i - 2][k]));
+                        dx * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i - 1, k]) +
+                              b2 * (stress.sxz[j, i + 1, k] - stress.sxz[j, i - 2, k]));
                     sxy_y =
-                        dy * (b1 * (stress->sxy[j][i][k] - stress->sxy[j - 1][i][k]) +
-                              b2 * (stress->sxy[j + 1][i][k] - stress->sxy[j - 2][i][k]));
+                        dy * (b1 * (stress.sxy[j, i, k] - stress.sxy[j - 1, i, k]) +
+                              b2 * (stress.sxy[j + 1, i, k] - stress.sxy[j - 2, i, k]));
                     syy_y =
-                        dy * (b1 * (stress->syy[j + 1][i][k] - stress->syy[j][i][k]) +
-                              b2 * (stress->syy[j + 2][i][k] - stress->syy[j - 1][i][k]));
+                        dy * (b1 * (stress.syy[j + 1, i, k] - stress.syy[j, i, k]) +
+                              b2 * (stress.syy[j + 2, i, k] - stress.syy[j - 1, i, k]));
                     syz_y =
-                        dy * (b1 * (stress->syz[j][i][k] - stress->syz[j - 1][i][k]) +
-                              b2 * (stress->syz[j + 1][i][k] - stress->syz[j - 2][i][k]));
+                        dy * (b1 * (stress.syz[j, i, k] - stress.syz[j - 1, i, k]) +
+                              b2 * (stress.syz[j + 1, i, k] - stress.syz[j - 2, i, k]));
                     sxz_z =
-                        dz * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i][k - 1]) +
-                              b2 * (stress->sxz[j][i][k + 1] - stress->sxz[j][i][k - 2]));
+                        dz * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i, k - 1]) +
+                              b2 * (stress.sxz[j, i, k + 1] - stress.sxz[j, i, k - 2]));
                     syz_z =
-                        dz * (b1 * (stress->syz[j][i][k] - stress->syz[j][i][k - 1]) +
-                              b2 * (stress->syz[j][i][k + 1] - stress->syz[j][i][k - 2]));
+                        dz * (b1 * (stress.syz[j, i, k] - stress.syz[j, i, k - 1]) +
+                              b2 * (stress.syz[j, i, k + 1] - stress.syz[j, i, k - 2]));
                     szz_z =
-                        dz * (b1 * (stress->szz[j][i][k + 1] - stress->szz[j][i][k]) +
-                              b2 * (stress->szz[j][i][k + 2] - stress->szz[j][i][k - 1]));
+                        dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
+                              b2 * (stress.szz[j, i, k + 2] - stress.szz[j, i, k - 1]));
                     h1 = (i - nb->nx2 + gv->FW);
                     pml_wfd->psi_sxx_x[j][h1][k] =
                         pml_coeff->b_x_half[h1] * pml_wfd->psi_sxx_x[j][h1][k] + pml_coeff->a_x_half[h1] * sxx_x;
@@ -258,32 +258,32 @@ void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress *stress, st_mode
                 #pragma omp simd
                 for (int k = 1; k <= gv->NZ; k++) {
                     sxx_x =
-                        dx * (b1 * (stress->sxx[j][i + 1][k] - stress->sxx[j][i][k]) +
-                              b2 * (stress->sxx[j][i + 2][k] - stress->sxx[j][i - 1][k]));
+                        dx * (b1 * (stress.sxx[j, i + 1, k] - stress.sxx[j, i, k]) +
+                              b2 * (stress.sxx[j, i + 2, k] - stress.sxx[j, i - 1, k]));
                     sxy_x =
-                        dx * (b1 * (stress->sxy[j][i][k] - stress->sxy[j][i - 1][k]) +
-                              b2 * (stress->sxy[j][i + 1][k] - stress->sxy[j][i - 2][k]));
+                        dx * (b1 * (stress.sxy[j, i, k] - stress.sxy[j, i - 1, k]) +
+                              b2 * (stress.sxy[j, i + 1, k] - stress.sxy[j, i - 2, k]));
                     sxz_x =
-                        dx * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i - 1][k]) +
-                              b2 * (stress->sxz[j][i + 1][k] - stress->sxz[j][i - 2][k]));
+                        dx * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i - 1, k]) +
+                              b2 * (stress.sxz[j, i + 1, k] - stress.sxz[j, i - 2, k]));
                     sxy_y =
-                        dy * (b1 * (stress->sxy[j][i][k] - stress->sxy[j - 1][i][k]) +
-                              b2 * (stress->sxy[j + 1][i][k] - stress->sxy[j - 2][i][k]));
+                        dy * (b1 * (stress.sxy[j, i, k] - stress.sxy[j - 1, i, k]) +
+                              b2 * (stress.sxy[j + 1, i, k] - stress.sxy[j - 2, i, k]));
                     syy_y =
-                        dy * (b1 * (stress->syy[j + 1][i][k] - stress->syy[j][i][k]) +
-                              b2 * (stress->syy[j + 2][i][k] - stress->syy[j - 1][i][k]));
+                        dy * (b1 * (stress.syy[j + 1, i, k] - stress.syy[j, i, k]) +
+                              b2 * (stress.syy[j + 2, i, k] - stress.syy[j - 1, i, k]));
                     syz_y =
-                        dy * (b1 * (stress->syz[j][i][k] - stress->syz[j - 1][i][k]) +
-                              b2 * (stress->syz[j + 1][i][k] - stress->syz[j - 2][i][k]));
+                        dy * (b1 * (stress.syz[j, i, k] - stress.syz[j - 1, i, k]) +
+                              b2 * (stress.syz[j + 1, i, k] - stress.syz[j - 2, i, k]));
                     sxz_z =
-                        dz * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i][k - 1]) +
-                              b2 * (stress->sxz[j][i][k + 1] - stress->sxz[j][i][k - 2]));
+                        dz * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i, k - 1]) +
+                              b2 * (stress.sxz[j, i, k + 1] - stress.sxz[j, i, k - 2]));
                     syz_z =
-                        dz * (b1 * (stress->syz[j][i][k] - stress->syz[j][i][k - 1]) +
-                              b2 * (stress->syz[j][i][k + 1] - stress->syz[j][i][k - 2]));
+                        dz * (b1 * (stress.syz[j, i, k] - stress.syz[j, i, k - 1]) +
+                              b2 * (stress.syz[j, i, k + 1] - stress.syz[j, i, k - 2]));
                     szz_z =
-                        dz * (b1 * (stress->szz[j][i][k + 1] - stress->szz[j][i][k]) +
-                              b2 * (stress->szz[j][i][k + 2] - stress->szz[j][i][k - 1]));
+                        dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
+                              b2 * (stress.szz[j, i, k + 2] - stress.szz[j, i, k - 1]));
                     pml_wfd->psi_sxy_y[j][i][k] =
                         pml_coeff->b_y[j] * pml_wfd->psi_sxy_y[j][i][k] + pml_coeff->a_y[j] * sxy_y;
                     sxy_y = sxy_y / pml_coeff->K_y[j] + pml_wfd->psi_sxy_y[j][i][k];
@@ -333,32 +333,32 @@ void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress *stress, st_mode
                 #pragma omp simd
                 for (int k = 1; k <= gv->NZ; k++) {
                     sxx_x =
-                        dx * (b1 * (stress->sxx[j][i + 1][k] - stress->sxx[j][i][k]) +
-                              b2 * (stress->sxx[j][i + 2][k] - stress->sxx[j][i - 1][k]));
+                        dx * (b1 * (stress.sxx[j, i + 1, k] - stress.sxx[j, i, k]) +
+                              b2 * (stress.sxx[j, i + 2, k] - stress.sxx[j, i - 1, k]));
                     sxy_x =
-                        dx * (b1 * (stress->sxy[j][i][k] - stress->sxy[j][i - 1][k]) +
-                              b2 * (stress->sxy[j][i + 1][k] - stress->sxy[j][i - 2][k]));
+                        dx * (b1 * (stress.sxy[j, i, k] - stress.sxy[j, i - 1, k]) +
+                              b2 * (stress.sxy[j, i + 1, k] - stress.sxy[j, i - 2, k]));
                     sxz_x =
-                        dx * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i - 1][k]) +
-                              b2 * (stress->sxz[j][i + 1][k] - stress->sxz[j][i - 2][k]));
+                        dx * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i - 1, k]) +
+                              b2 * (stress.sxz[j, i + 1, k] - stress.sxz[j, i - 2, k]));
                     sxy_y =
-                        dy * (b1 * (stress->sxy[j][i][k] - stress->sxy[j - 1][i][k]) +
-                              b2 * (stress->sxy[j + 1][i][k] - stress->sxy[j - 2][i][k]));
+                        dy * (b1 * (stress.sxy[j, i, k] - stress.sxy[j - 1, i, k]) +
+                              b2 * (stress.sxy[j + 1, i, k] - stress.sxy[j - 2, i, k]));
                     syy_y =
-                        dy * (b1 * (stress->syy[j + 1][i][k] - stress->syy[j][i][k]) +
-                              b2 * (stress->syy[j + 2][i][k] - stress->syy[j - 1][i][k]));
+                        dy * (b1 * (stress.syy[j + 1, i, k] - stress.syy[j, i, k]) +
+                              b2 * (stress.syy[j + 2, i, k] - stress.syy[j - 1, i, k]));
                     syz_y =
-                        dy * (b1 * (stress->syz[j][i][k] - stress->syz[j - 1][i][k]) +
-                              b2 * (stress->syz[j + 1][i][k] - stress->syz[j - 2][i][k]));
+                        dy * (b1 * (stress.syz[j, i, k] - stress.syz[j - 1, i, k]) +
+                              b2 * (stress.syz[j + 1, i, k] - stress.syz[j - 2, i, k]));
                     sxz_z =
-                        dz * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i][k - 1]) +
-                              b2 * (stress->sxz[j][i][k + 1] - stress->sxz[j][i][k - 2]));
+                        dz * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i, k - 1]) +
+                              b2 * (stress.sxz[j, i, k + 1] - stress.sxz[j, i, k - 2]));
                     syz_z =
-                        dz * (b1 * (stress->syz[j][i][k] - stress->syz[j][i][k - 1]) +
-                              b2 * (stress->syz[j][i][k + 1] - stress->syz[j][i][k - 2]));
+                        dz * (b1 * (stress.syz[j, i, k] - stress.syz[j, i, k - 1]) +
+                              b2 * (stress.syz[j, i, k + 1] - stress.syz[j, i, k - 2]));
                     szz_z =
-                        dz * (b1 * (stress->szz[j][i][k + 1] - stress->szz[j][i][k]) +
-                              b2 * (stress->szz[j][i][k + 2] - stress->szz[j][i][k - 1]));
+                        dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
+                              b2 * (stress.szz[j, i, k + 2] - stress.szz[j, i, k - 1]));
                     h1 = (j - nb->ny2 + gv->FW);
                     pml_wfd->psi_sxy_y[h1][i][k] =
                         pml_coeff->b_y[h1] * pml_wfd->psi_sxy_y[h1][i][k] + pml_coeff->a_y[h1] * sxy_y;
@@ -411,32 +411,32 @@ void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress *stress, st_mode
                 #pragma omp simd
                 for (int k = 1; k <= gv->FW; k++) {
                     sxx_x =
-                        dx * (b1 * (stress->sxx[j][i + 1][k] - stress->sxx[j][i][k]) +
-                              b2 * (stress->sxx[j][i + 2][k] - stress->sxx[j][i - 1][k]));
+                        dx * (b1 * (stress.sxx[j, i + 1, k] - stress.sxx[j, i, k]) +
+                              b2 * (stress.sxx[j, i + 2, k] - stress.sxx[j, i - 1, k]));
                     sxy_x =
-                        dx * (b1 * (stress->sxy[j][i][k] - stress->sxy[j][i - 1][k]) +
-                              b2 * (stress->sxy[j][i + 1][k] - stress->sxy[j][i - 2][k]));
+                        dx * (b1 * (stress.sxy[j, i, k] - stress.sxy[j, i - 1, k]) +
+                              b2 * (stress.sxy[j, i + 1, k] - stress.sxy[j, i - 2, k]));
                     sxz_x =
-                        dx * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i - 1][k]) +
-                              b2 * (stress->sxz[j][i + 1][k] - stress->sxz[j][i - 2][k]));
+                        dx * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i - 1, k]) +
+                              b2 * (stress.sxz[j, i + 1, k] - stress.sxz[j, i - 2, k]));
                     sxy_y =
-                        dy * (b1 * (stress->sxy[j][i][k] - stress->sxy[j - 1][i][k]) +
-                              b2 * (stress->sxy[j + 1][i][k] - stress->sxy[j - 2][i][k]));
+                        dy * (b1 * (stress.sxy[j, i, k] - stress.sxy[j - 1, i, k]) +
+                              b2 * (stress.sxy[j + 1, i, k] - stress.sxy[j - 2, i, k]));
                     syy_y =
-                        dy * (b1 * (stress->syy[j + 1][i][k] - stress->syy[j][i][k]) +
-                              b2 * (stress->syy[j + 2][i][k] - stress->syy[j - 1][i][k]));
+                        dy * (b1 * (stress.syy[j + 1, i, k] - stress.syy[j, i, k]) +
+                              b2 * (stress.syy[j + 2, i, k] - stress.syy[j - 1, i, k]));
                     syz_y =
-                        dy * (b1 * (stress->syz[j][i][k] - stress->syz[j - 1][i][k]) +
-                              b2 * (stress->syz[j + 1][i][k] - stress->syz[j - 2][i][k]));
+                        dy * (b1 * (stress.syz[j, i, k] - stress.syz[j - 1, i, k]) +
+                              b2 * (stress.syz[j + 1, i, k] - stress.syz[j - 2, i, k]));
                     sxz_z =
-                        dz * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i][k - 1]) +
-                              b2 * (stress->sxz[j][i][k + 1] - stress->sxz[j][i][k - 2]));
+                        dz * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i, k - 1]) +
+                              b2 * (stress.sxz[j, i, k + 1] - stress.sxz[j, i, k - 2]));
                     syz_z =
-                        dz * (b1 * (stress->syz[j][i][k] - stress->syz[j][i][k - 1]) +
-                              b2 * (stress->syz[j][i][k + 1] - stress->syz[j][i][k - 2]));
+                        dz * (b1 * (stress.syz[j, i, k] - stress.syz[j, i, k - 1]) +
+                              b2 * (stress.syz[j, i, k + 1] - stress.syz[j, i, k - 2]));
                     szz_z =
-                        dz * (b1 * (stress->szz[j][i][k + 1] - stress->szz[j][i][k]) +
-                              b2 * (stress->szz[j][i][k + 2] - stress->szz[j][i][k - 1]));
+                        dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
+                              b2 * (stress.szz[j, i, k + 2] - stress.szz[j, i, k - 1]));
                     pml_wfd->psi_sxz_z[j][i][k] =
                         pml_coeff->b_z[k] * pml_wfd->psi_sxz_z[j][i][k] + pml_coeff->a_z[k] * sxz_z;
                     sxz_z = sxz_z / pml_coeff->K_z[k] + pml_wfd->psi_sxz_z[j][i][k];
@@ -461,32 +461,32 @@ void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress *stress, st_mode
                 #pragma omp simd
                 for (int k = nb->nz2 + 1; k <= nb->nz2 + gv->FW; k++) {
                     sxx_x =
-                        dx * (b1 * (stress->sxx[j][i + 1][k] - stress->sxx[j][i][k]) +
-                              b2 * (stress->sxx[j][i + 2][k] - stress->sxx[j][i - 1][k]));
+                        dx * (b1 * (stress.sxx[j, i + 1, k] - stress.sxx[j, i, k]) +
+                              b2 * (stress.sxx[j, i + 2, k] - stress.sxx[j, i - 1, k]));
                     sxy_x =
-                        dx * (b1 * (stress->sxy[j][i][k] - stress->sxy[j][i - 1][k]) +
-                              b2 * (stress->sxy[j][i + 1][k] - stress->sxy[j][i - 2][k]));
+                        dx * (b1 * (stress.sxy[j, i, k] - stress.sxy[j, i - 1, k]) +
+                              b2 * (stress.sxy[j, i + 1, k] - stress.sxy[j, i - 2, k]));
                     sxz_x =
-                        dx * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i - 1][k]) +
-                              b2 * (stress->sxz[j][i + 1][k] - stress->sxz[j][i - 2][k]));
+                        dx * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i - 1, k]) +
+                              b2 * (stress.sxz[j, i + 1, k] - stress.sxz[j, i - 2, k]));
                     sxy_y =
-                        dy * (b1 * (stress->sxy[j][i][k] - stress->sxy[j - 1][i][k]) +
-                              b2 * (stress->sxy[j + 1][i][k] - stress->sxy[j - 2][i][k]));
+                        dy * (b1 * (stress.sxy[j, i, k] - stress.sxy[j - 1, i, k]) +
+                              b2 * (stress.sxy[j + 1, i, k] - stress.sxy[j - 2, i, k]));
                     syy_y =
-                        dy * (b1 * (stress->syy[j + 1][i][k] - stress->syy[j][i][k]) +
-                              b2 * (stress->syy[j + 2][i][k] - stress->syy[j - 1][i][k]));
+                        dy * (b1 * (stress.syy[j + 1, i, k] - stress.syy[j, i, k]) +
+                              b2 * (stress.syy[j + 2, i, k] - stress.syy[j - 1, i, k]));
                     syz_y =
-                        dy * (b1 * (stress->syz[j][i][k] - stress->syz[j - 1][i][k]) +
-                              b2 * (stress->syz[j + 1][i][k] - stress->syz[j - 2][i][k]));
+                        dy * (b1 * (stress.syz[j, i, k] - stress.syz[j - 1, i, k]) +
+                              b2 * (stress.syz[j + 1, i, k] - stress.syz[j - 2, i, k]));
                     sxz_z =
-                        dz * (b1 * (stress->sxz[j][i][k] - stress->sxz[j][i][k - 1]) +
-                              b2 * (stress->sxz[j][i][k + 1] - stress->sxz[j][i][k - 2]));
+                        dz * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i, k - 1]) +
+                              b2 * (stress.sxz[j, i, k + 1] - stress.sxz[j, i, k - 2]));
                     syz_z =
-                        dz * (b1 * (stress->syz[j][i][k] - stress->syz[j][i][k - 1]) +
-                              b2 * (stress->syz[j][i][k + 1] - stress->syz[j][i][k - 2]));
+                        dz * (b1 * (stress.syz[j, i, k] - stress.syz[j, i, k - 1]) +
+                              b2 * (stress.syz[j, i, k + 1] - stress.syz[j, i, k - 2]));
                     szz_z =
-                        dz * (b1 * (stress->szz[j][i][k + 1] - stress->szz[j][i][k]) +
-                              b2 * (stress->szz[j][i][k + 2] - stress->szz[j][i][k - 1]));
+                        dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
+                              b2 * (stress.szz[j, i, k + 2] - stress.szz[j, i, k - 1]));
                     h1 = (k - nb->nz2 + gv->FW);
                     pml_wfd->psi_sxz_z[j][i][h1] =
                         pml_coeff->b_z[h1] * pml_wfd->psi_sxz_z[j][i][h1] + pml_coeff->a_z[h1] * sxz_z;
diff --git a/src/update_v_ssg_CPML_acoustic.cpp b/src/update_v_ssg_CPML_acoustic.cpp
index 0bee374..b364cb6 100644
--- a/src/update_v_ssg_CPML_acoustic.cpp
+++ b/src/update_v_ssg_CPML_acoustic.cpp
@@ -30,7 +30,7 @@
 
 #define UNUSED(x) (void)(x)
 
-void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress *stress, st_model_av *mod_av,
+void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av *mod_av,
                             st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, const GlobVar *gv)
 {
     float sp_x = 0.0, sp_y = 0.0, sp_z = 0.0;
@@ -56,14 +56,14 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress *stress
                 #pragma omp simd
                 for (int k = 1; k <= gv->NZ; k++) {
                     sp_x =
-                        dx * (b1 * (stress->sp[j][i + 1][k] - stress->sp[j][i][k]) +
-                              b2 * (stress->sp[j][i + 2][k] - stress->sp[j][i - 1][k]));
+                        dx * (b1 * (stress.sp[j, i + 1, k] - stress.sp[j, i, k]) +
+                              b2 * (stress.sp[j, i + 2, k] - stress.sp[j, i - 1, k]));
                     sp_y =
-                        dy * (b1 * (stress->sp[j + 1][i][k] - stress->sp[j][i][k]) +
-                              b2 * (stress->sp[j + 2][i][k] - stress->sp[j - 1][i][k]));
+                        dy * (b1 * (stress.sp[j + 1, i, k] - stress.sp[j, i, k]) +
+                              b2 * (stress.sp[j + 2, i, k] - stress.sp[j - 1, i, k]));
                     sp_z =
-                        dz * (b1 * (stress->sp[j][i][k + 1] - stress->sp[j][i][k]) +
-                              b2 * (stress->sp[j][i][k + 2] - stress->sp[j][i][k - 1]));
+                        dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
+                              b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]));
                     pml_wfd->psi_sp_x[j][i][k] =
                         pml_coeff->b_x_half[i] * pml_wfd->psi_sp_x[j][i][k] + pml_coeff->a_x_half[i] * sp_x;
                     sp_x = sp_x / pml_coeff->K_x_half[i] + pml_wfd->psi_sp_x[j][i][k];
@@ -108,14 +108,14 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress *stress
                 #pragma omp simd
                 for (int k = 1; k <= gv->NZ; k++) {
                     sp_x =
-                        dx * (b1 * (stress->sp[j][i + 1][k] - stress->sp[j][i][k]) +
-                              b2 * (stress->sp[j][i + 2][k] - stress->sp[j][i - 1][k]));
+                        dx * (b1 * (stress.sp[j, i + 1, k] - stress.sp[j, i, k]) +
+                              b2 * (stress.sp[j, i + 2, k] - stress.sp[j, i - 1, k]));
                     sp_y =
-                        dy * (b1 * (stress->sp[j + 1][i][k] - stress->sp[j][i][k]) +
-                              b2 * (stress->sp[j + 2][i][k] - stress->sp[j - 1][i][k]));
+                        dy * (b1 * (stress.sp[j + 1, i, k] - stress.sp[j, i, k]) +
+                              b2 * (stress.sp[j + 2, i, k] - stress.sp[j - 1, i, k]));
                     sp_z =
-                        dz * (b1 * (stress->sp[j][i][k + 1] - stress->sp[j][i][k]) +
-                              b2 * (stress->sp[j][i][k + 2] - stress->sp[j][i][k - 1]));
+                        dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
+                              b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]));
                     h1 = (i - nb->nx2 + gv->FW);
                     pml_wfd->psi_sp_x[j][h1][k] =
                         pml_coeff->b_x_half[h1] * pml_wfd->psi_sp_x[j][h1][k] + pml_coeff->a_x_half[h1] * sp_x;
@@ -161,14 +161,14 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress *stress
                 #pragma omp simd
                 for (int k = 1; k <= gv->NZ; k++) {
                     sp_x =
-                        dx * (b1 * (stress->sp[j][i + 1][k] - stress->sp[j][i][k]) +
-                              b2 * (stress->sp[j][i + 2][k] - stress->sp[j][i - 1][k]));
+                        dx * (b1 * (stress.sp[j, i + 1, k] - stress.sp[j, i, k]) +
+                              b2 * (stress.sp[j, i + 2, k] - stress.sp[j, i - 1, k]));
                     sp_y =
-                        dy * (b1 * (stress->sp[j + 1][i][k] - stress->sp[j][i][k]) +
-                              b2 * (stress->sp[j + 2][i][k] - stress->sp[j - 1][i][k]));
+                        dy * (b1 * (stress.sp[j + 1, i, k] - stress.sp[j, i, k]) +
+                              b2 * (stress.sp[j + 2, i, k] - stress.sp[j - 1, i, k]));
                     sp_z =
-                        dz * (b1 * (stress->sp[j][i][k + 1] - stress->sp[j][i][k]) +
-                              b2 * (stress->sp[j][i][k + 2] - stress->sp[j][i][k - 1]));
+                        dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
+                              b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]));
                     pml_wfd->psi_sp_y[j][i][k] =
                         pml_coeff->b_y_half[j] * pml_wfd->psi_sp_y[j][i][k] + pml_coeff->a_y_half[j] * sp_y;
                     sp_y = sp_y / pml_coeff->K_y_half[j] + pml_wfd->psi_sp_y[j][i][k];
@@ -200,14 +200,14 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress *stress
                 #pragma omp simd
                 for (int k = 1; k <= gv->NZ; k++) {
                     sp_x =
-                        dx * (b1 * (stress->sp[j][i + 1][k] - stress->sp[j][i][k]) +
-                              b2 * (stress->sp[j][i + 2][k] - stress->sp[j][i - 1][k]));
+                        dx * (b1 * (stress.sp[j, i + 1, k] - stress.sp[j, i, k]) +
+                              b2 * (stress.sp[j, i + 2, k] - stress.sp[j, i - 1, k]));
                     sp_y =
-                        dy * (b1 * (stress->sp[j + 1][i][k] - stress->sp[j][i][k]) +
-                              b2 * (stress->sp[j + 2][i][k] - stress->sp[j - 1][i][k]));
+                        dy * (b1 * (stress.sp[j + 1, i, k] - stress.sp[j, i, k]) +
+                              b2 * (stress.sp[j + 2, i, k] - stress.sp[j - 1, i, k]));
                     sp_z =
-                        dz * (b1 * (stress->sp[j][i][k + 1] - stress->sp[j][i][k]) +
-                              b2 * (stress->sp[j][i][k + 2] - stress->sp[j][i][k - 1]));
+                        dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
+                              b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]));
                     h1 = (j - nb->ny2 + gv->FW);
                     pml_wfd->psi_sp_y[h1][i][k] =
                         pml_coeff->b_y_half[h1] * pml_wfd->psi_sp_y[h1][i][k] + pml_coeff->a_y_half[h1] * sp_y;
@@ -242,14 +242,14 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress *stress
                 #pragma omp simd
                 for (int k = 1; k <= gv->FW; k++) {
                     sp_x =
-                        dx * (b1 * (stress->sp[j][i + 1][k] - stress->sp[j][i][k]) +
-                              b2 * (stress->sp[j][i + 2][k] - stress->sp[j][i - 1][k]));
+                        dx * (b1 * (stress.sp[j, i + 1, k] - stress.sp[j, i, k]) +
+                              b2 * (stress.sp[j, i + 2, k] - stress.sp[j, i - 1, k]));
                     sp_y =
-                        dy * (b1 * (stress->sp[j + 1][i][k] - stress->sp[j][i][k]) +
-                              b2 * (stress->sp[j + 2][i][k] - stress->sp[j - 1][i][k]));
+                        dy * (b1 * (stress.sp[j + 1, i, k] - stress.sp[j, i, k]) +
+                              b2 * (stress.sp[j + 2, i, k] - stress.sp[j - 1, i, k]));
                     sp_z =
-                        dz * (b1 * (stress->sp[j][i][k + 1] - stress->sp[j][i][k]) +
-                              b2 * (stress->sp[j][i][k + 2] - stress->sp[j][i][k - 1]));
+                        dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
+                              b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]));
                     pml_wfd->psi_sp_z[j][i][k] =
                         pml_coeff->b_z_half[k] * pml_wfd->psi_sp_z[j][i][k] + pml_coeff->a_z_half[k] * sp_z;
                     sp_z = sp_z / pml_coeff->K_z_half[k] + pml_wfd->psi_sp_z[j][i][k];
@@ -268,14 +268,14 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress *stress
                 #pragma omp simd
                 for (int k = nb->nz2 + 1; k <= nb->nz2 + gv->FW; k++) {
                     sp_x =
-                        dx * (b1 * (stress->sp[j][i + 1][k] - stress->sp[j][i][k]) +
-                              b2 * (stress->sp[j][i + 2][k] - stress->sp[j][i - 1][k]));
+                        dx * (b1 * (stress.sp[j, i + 1, k] - stress.sp[j, i, k]) +
+                              b2 * (stress.sp[j, i + 2, k] - stress.sp[j, i - 1, k]));
                     sp_y =
-                        dy * (b1 * (stress->sp[j + 1][i][k] - stress->sp[j][i][k]) +
-                              b2 * (stress->sp[j + 2][i][k] - stress->sp[j - 1][i][k]));
+                        dy * (b1 * (stress.sp[j + 1, i, k] - stress.sp[j, i, k]) +
+                              b2 * (stress.sp[j + 2, i, k] - stress.sp[j - 1, i, k]));
                     sp_z =
-                        dz * (b1 * (stress->sp[j][i][k + 1] - stress->sp[j][i][k]) +
-                              b2 * (stress->sp[j][i][k + 2] - stress->sp[j][i][k - 1]));
+                        dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
+                              b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]));
                     h1 = (k - nb->nz2 + gv->FW);
                     pml_wfd->psi_sp_z[j][i][h1] =
                         pml_coeff->b_z_half[h1] * pml_wfd->psi_sp_z[j][i][h1] + pml_coeff->a_z_half[h1] * sp_z;
diff --git a/src/update_v_ssg_acoustic.cpp b/src/update_v_ssg_acoustic.cpp
index 4632a90..78d8178 100644
--- a/src/update_v_ssg_acoustic.cpp
+++ b/src/update_v_ssg_acoustic.cpp
@@ -24,7 +24,7 @@
 
 #include "fd.hpp"
 
-void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress *__restrict__ stress,
+void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress &stress,
                        st_model_av *mod_av, float ***absorb_coeff, const GlobVar *gv)
 {
     float b1, b2, b3, b4, b5, b6;
@@ -39,11 +39,11 @@ void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress *__res
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    float sp_x = dx * (stress->sp[j][i + 1][k] - stress->sp[j][i][k]);
+                    float sp_x = dx * (stress.sp[j, i + 1, k] - stress.sp[j, i, k]);
                     vel.vx[j, i, k] += sp_x / mod_av->rip[j][i][k];
-                    float sp_y = dy * (stress->sp[j + 1][i][k] - stress->sp[j][i][k]);
+                    float sp_y = dy * (stress.sp[j + 1, i, k] - stress.sp[j, i, k]);
                     vel.vy[j, i, k] += sp_y / mod_av->rjp[j][i][k];
-                    float sp_z = dz * (stress->sp[j][i][k + 1] - stress->sp[j][i][k]);
+                    float sp_z = dz * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]);
                     vel.vz[j, i, k] += sp_z / mod_av->rkp[j][i][k];
                 }
             }
@@ -61,14 +61,14 @@ void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress *__res
                 #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
                     float sp_x =
-                        dx * (b1 * (stress->sp[j][i + 1][k] - stress->sp[j][i][k]) +
-                              b2 * (stress->sp[j][i + 2][k] - stress->sp[j][i - 1][k]));
+                        dx * (b1 * (stress.sp[j, i + 1, k] - stress.sp[j, i, k]) +
+                              b2 * (stress.sp[j, i + 2, k] - stress.sp[j, i - 1, k]));
                     float sp_y =
-                        dy * (b1 * (stress->sp[j + 1][i][k] - stress->sp[j][i][k]) +
-                              b2 * (stress->sp[j + 2][i][k] - stress->sp[j - 1][i][k]));
+                        dy * (b1 * (stress.sp[j + 1, i, k] - stress.sp[j, i, k]) +
+                              b2 * (stress.sp[j + 2, i, k] - stress.sp[j - 1, i, k]));
                     float sp_z =
-                        dz * (b1 * (stress->sp[j][i][k + 1] - stress->sp[j][i][k]) +
-                              b2 * (stress->sp[j][i][k + 2] - stress->sp[j][i][k - 1]));
+                        dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
+                              b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]));
                     vel.vx[j, i, k] += sp_x / mod_av->rip[j][i][k];
                     vel.vy[j, i, k] += sp_y / mod_av->rjp[j][i][k];
                     vel.vz[j, i, k] += sp_z / mod_av->rkp[j][i][k];
@@ -89,18 +89,18 @@ void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress *__res
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    sp_x = dx * (b1 * (stress->sp[j][i + 1][k] - stress->sp[j][i][k]) +
-                                 b2 * (stress->sp[j][i + 2][k] - stress->sp[j][i - 1][k]) +
-                                 b3 * (stress->sp[j][i + 3][k] - stress->sp[j][i - 2][k]));
+                    sp_x = dx * (b1 * (stress.sp[j, i + 1, k] - stress.sp[j, i, k]) +
+                                 b2 * (stress.sp[j, i + 2, k] - stress.sp[j, i - 1, k]) +
+                                 b3 * (stress.sp[j, i + 3, k] - stress.sp[j, i - 2, k]));
                     /* updating components of particle velocities */
                     vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
-                    sp_y = dy * (b1 * (stress->sp[j + 1][i][k] - stress->sp[j][i][k]) +
-                                 b2 * (stress->sp[j + 2][i][k] - stress->sp[j - 1][i][k]) +
-                                 b3 * (stress->sp[j + 3][i][k] - stress->sp[j - 2][i][k]));
+                    sp_y = dy * (b1 * (stress.sp[j + 1, i, k] - stress.sp[j, i, k]) +
+                                 b2 * (stress.sp[j + 2, i, k] - stress.sp[j - 1, i, k]) +
+                                 b3 * (stress.sp[j + 3, i, k] - stress.sp[j - 2, i, k]));
                     vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
-                    sp_z = dz * (b1 * (stress->sp[j][i][k + 1] - stress->sp[j][i][k]) +
-                                 b2 * (stress->sp[j][i][k + 2] - stress->sp[j][i][k - 1]) +
-                                 b3 * (stress->sp[j][i][k + 3] - stress->sp[j][i][k - 2]));
+                    sp_z = dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
+                                 b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]) +
+                                 b3 * (stress.sp[j, i, k + 3] - stress.sp[j, i, k - 2]));
                     vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
                 }
             }
@@ -121,21 +121,21 @@ void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress *__res
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    sp_x = dx * (b1 * (stress->sp[j][i + 1][k] - stress->sp[j][i][k]) +
-                                 b2 * (stress->sp[j][i + 2][k] - stress->sp[j][i - 1][k]) +
-                                 b3 * (stress->sp[j][i + 3][k] - stress->sp[j][i - 2][k]) +
-                                 b4 * (stress->sp[j][i + 4][k] - stress->sp[j][i - 3][k]));
+                    sp_x = dx * (b1 * (stress.sp[j, i + 1, k] - stress.sp[j, i, k]) +
+                                 b2 * (stress.sp[j, i + 2, k] - stress.sp[j, i - 1, k]) +
+                                 b3 * (stress.sp[j, i + 3, k] - stress.sp[j, i - 2, k]) +
+                                 b4 * (stress.sp[j, i + 4, k] - stress.sp[j, i - 3, k]));
                     /* updating components of particle velocities */
                     vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
-                    sp_y = dy * (b1 * (stress->sp[j + 1][i][k] - stress->sp[j][i][k]) +
-                                 b2 * (stress->sp[j + 2][i][k] - stress->sp[j - 1][i][k]) +
-                                 b3 * (stress->sp[j + 3][i][k] - stress->sp[j - 2][i][k]) +
-                                 b4 * (stress->sp[j + 4][i][k] - stress->sp[j - 3][i][k]));
+                    sp_y = dy * (b1 * (stress.sp[j + 1, i, k] - stress.sp[j, i, k]) +
+                                 b2 * (stress.sp[j + 2, i, k] - stress.sp[j - 1, i, k]) +
+                                 b3 * (stress.sp[j + 3, i, k] - stress.sp[j - 2, i, k]) +
+                                 b4 * (stress.sp[j + 4, i, k] - stress.sp[j - 3, i, k]));
                     vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
-                    sp_z = dz * (b1 * (stress->sp[j][i][k + 1] - stress->sp[j][i][k]) +
-                                 b2 * (stress->sp[j][i][k + 2] - stress->sp[j][i][k - 1]) +
-                                 b3 * (stress->sp[j][i][k + 3] - stress->sp[j][i][k - 2]) +
-                                 b4 * (stress->sp[j][i][k + 4] - stress->sp[j][i][k - 3]));
+                    sp_z = dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
+                                 b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]) +
+                                 b3 * (stress.sp[j, i, k + 3] - stress.sp[j, i, k - 2]) +
+                                 b4 * (stress.sp[j, i, k + 4] - stress.sp[j, i, k - 3]));
                     vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
                 }
             }
@@ -158,24 +158,24 @@ void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress *__res
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    sp_x = dx * (b1 * (stress->sp[j][i + 1][k] - stress->sp[j][i][k]) +
-                                 b2 * (stress->sp[j][i + 2][k] - stress->sp[j][i - 1][k]) +
-                                 b3 * (stress->sp[j][i + 3][k] - stress->sp[j][i - 2][k]) +
-                                 b4 * (stress->sp[j][i + 4][k] - stress->sp[j][i - 3][k]) +
-                                 b5 * (stress->sp[j][i + 5][k] - stress->sp[j][i - 4][k]));
+                    sp_x = dx * (b1 * (stress.sp[j, i + 1, k] - stress.sp[j, i, k]) +
+                                 b2 * (stress.sp[j, i + 2, k] - stress.sp[j, i - 1, k]) +
+                                 b3 * (stress.sp[j, i + 3, k] - stress.sp[j, i - 2, k]) +
+                                 b4 * (stress.sp[j, i + 4, k] - stress.sp[j, i - 3, k]) +
+                                 b5 * (stress.sp[j, i + 5, k] - stress.sp[j, i - 4, k]));
                     /* updating components of particle velocities */
                     vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
-                    sp_y = dy * (b1 * (stress->sp[j + 1][i][k] - stress->sp[j][i][k]) +
-                                 b2 * (stress->sp[j + 2][i][k] - stress->sp[j - 1][i][k]) +
-                                 b3 * (stress->sp[j + 3][i][k] - stress->sp[j - 2][i][k]) +
-                                 b4 * (stress->sp[j + 4][i][k] - stress->sp[j - 3][i][k]) +
-                                 b5 * (stress->sp[j + 5][i][k] - stress->sp[j - 4][i][k]));
+                    sp_y = dy * (b1 * (stress.sp[j + 1, i, k] - stress.sp[j, i, k]) +
+                                 b2 * (stress.sp[j + 2, i, k] - stress.sp[j - 1, i, k]) +
+                                 b3 * (stress.sp[j + 3, i, k] - stress.sp[j - 2, i, k]) +
+                                 b4 * (stress.sp[j + 4, i, k] - stress.sp[j - 3, i, k]) +
+                                 b5 * (stress.sp[j + 5, i, k] - stress.sp[j - 4, i, k]));
                     vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
-                    sp_z = dz * (b1 * (stress->sp[j][i][k + 1] - stress->sp[j][i][k]) +
-                                 b2 * (stress->sp[j][i][k + 2] - stress->sp[j][i][k - 1]) +
-                                 b3 * (stress->sp[j][i][k + 3] - stress->sp[j][i][k - 2]) +
-                                 b4 * (stress->sp[j][i][k + 4] - stress->sp[j][i][k - 3]) +
-                                 b5 * (stress->sp[j][i][k + 5] - stress->sp[j][i][k - 4]));
+                    sp_z = dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
+                                 b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]) +
+                                 b3 * (stress.sp[j, i, k + 3] - stress.sp[j, i, k - 2]) +
+                                 b4 * (stress.sp[j, i, k + 4] - stress.sp[j, i, k - 3]) +
+                                 b5 * (stress.sp[j, i, k + 5] - stress.sp[j, i, k - 4]));
                     vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
                 }
             }
@@ -202,27 +202,27 @@ void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress *__res
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    sp_x = dx * (b1 * (stress->sp[j][i + 1][k] - stress->sp[j][i][k]) +
-                                 b2 * (stress->sp[j][i + 2][k] - stress->sp[j][i - 1][k]) +
-                                 b3 * (stress->sp[j][i + 3][k] - stress->sp[j][i - 2][k]) +
-                                 b4 * (stress->sp[j][i + 4][k] - stress->sp[j][i - 3][k]) +
-                                 b5 * (stress->sp[j][i + 5][k] - stress->sp[j][i - 4][k]) +
-                                 b6 * (stress->sp[j][i + 6][k] - stress->sp[j][i - 5][k]));
+                    sp_x = dx * (b1 * (stress.sp[j, i + 1, k] - stress.sp[j, i, k]) +
+                                 b2 * (stress.sp[j, i + 2, k] - stress.sp[j, i - 1, k]) +
+                                 b3 * (stress.sp[j, i + 3, k] - stress.sp[j, i - 2, k]) +
+                                 b4 * (stress.sp[j, i + 4, k] - stress.sp[j, i - 3, k]) +
+                                 b5 * (stress.sp[j, i + 5, k] - stress.sp[j, i - 4, k]) +
+                                 b6 * (stress.sp[j, i + 6, k] - stress.sp[j, i - 5, k]));
                     /* updating components of particle velocities */
                     vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
-                    sp_y = dy * (b1 * (stress->sp[j + 1][i][k] - stress->sp[j][i][k]) +
-                                 b2 * (stress->sp[j + 2][i][k] - stress->sp[j - 1][i][k]) +
-                                 b3 * (stress->sp[j + 3][i][k] - stress->sp[j - 2][i][k]) +
-                                 b4 * (stress->sp[j + 4][i][k] - stress->sp[j - 3][i][k]) +
-                                 b5 * (stress->sp[j + 5][i][k] - stress->sp[j - 4][i][k]) +
-                                 b6 * (stress->sp[j + 6][i][k] - stress->sp[j - 5][i][k]));
+                    sp_y = dy * (b1 * (stress.sp[j + 1, i, k] - stress.sp[j, i, k]) +
+                                 b2 * (stress.sp[j + 2, i, k] - stress.sp[j - 1, i, k]) +
+                                 b3 * (stress.sp[j + 3, i, k] - stress.sp[j - 2, i, k]) +
+                                 b4 * (stress.sp[j + 4, i, k] - stress.sp[j - 3, i, k]) +
+                                 b5 * (stress.sp[j + 5, i, k] - stress.sp[j - 4, i, k]) +
+                                 b6 * (stress.sp[j + 6, i, k] - stress.sp[j - 5, i, k]));
                     vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
-                    sp_z = dz * (b1 * (stress->sp[j][i][k + 1] - stress->sp[j][i][k]) +
-                                 b2 * (stress->sp[j][i][k + 2] - stress->sp[j][i][k - 1]) +
-                                 b3 * (stress->sp[j][i][k + 3] - stress->sp[j][i][k - 2]) +
-                                 b4 * (stress->sp[j][i][k + 4] - stress->sp[j][i][k - 3]) +
-                                 b5 * (stress->sp[j][i][k + 5] - stress->sp[j][i][k - 4]) +
-                                 b6 * (stress->sp[j][i][k + 6] - stress->sp[j][i][k - 5]));
+                    sp_z = dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
+                                 b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]) +
+                                 b3 * (stress.sp[j, i, k + 3] - stress.sp[j, i, k - 2]) +
+                                 b4 * (stress.sp[j, i, k + 4] - stress.sp[j, i, k - 3]) +
+                                 b5 * (stress.sp[j, i, k + 5] - stress.sp[j, i, k - 4]) +
+                                 b6 * (stress.sp[j, i, k + 6] - stress.sp[j, i, k - 5]));
                     vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
                 }
             }
@@ -240,7 +240,7 @@ void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress *__res
                     vel.vx[j, i, k] *= absorb_coeff[j][i][k];
                     vel.vy[j, i, k] *= absorb_coeff[j][i][k];
                     vel.vz[j, i, k] *= absorb_coeff[j][i][k];
-                    stress->sp[j][i][k] *= absorb_coeff[j][i][k];
+                    stress.sp[j, i, k] *= absorb_coeff[j][i][k];
                 }
             }
         }
diff --git a/src/zero_wavefield.cpp b/src/zero_wavefield.cpp
index efcdbf9..a68b013 100644
--- a/src/zero_wavefield.cpp
+++ b/src/zero_wavefield.cpp
@@ -22,7 +22,7 @@
  * -------------------------------------------------------------------------*/
 
 #include "fd.hpp"
-void zero_wavefield(st_velocity &vel, st_stress *stress, st_visc_mem *mem, st_pml_wfd *pml_wfd, const GlobVar *gv)
+void zero_wavefield(st_velocity &vel, st_stress &stress, st_visc_mem *mem, st_pml_wfd *pml_wfd, const GlobVar *gv)
 {
     int l = 1;
 
@@ -53,8 +53,8 @@ void zero_wavefield(st_velocity &vel, st_stress *stress, st_visc_mem *mem, st_pm
                 vel.vx[j, i, k] = 0.0f;
                 vel.vy[j, i, k] = 0.0f;
                 vel.vz[j, i, k] = 0.0f;
-                stress->sxy[j][i][k] = 0.0f;
-                stress->syz[j][i][k] = 0.0f;
+                stress.sxy[j, i, k] = 0.0f;
+                stress.syz[j, i, k] = 0.0f;
             }
         }
     }
@@ -65,10 +65,10 @@ void zero_wavefield(st_velocity &vel, st_stress *stress, st_visc_mem *mem, st_pm
         for (int i = nx1; i <= nx2; i++) {
             #pragma omp simd
             for (int k = nz1; k <= nz2; k++) {
-                stress->sxx[j][i][k] = 0.0f;
-                stress->sxz[j][i][k] = 0.0f;
-                stress->syy[j][i][k] = 0.0f;
-                stress->szz[j][i][k] = 0.0f;
+                stress.sxx[j, i, k] = 0.0f;
+                stress.sxz[j, i, k] = 0.0f;
+                stress.syy[j, i, k] = 0.0f;
+                stress.szz[j, i, k] = 0.0f;
             }
         }
     }
diff --git a/src/zero_wavefield_acoustic.cpp b/src/zero_wavefield_acoustic.cpp
index f8285dc..4334d3d 100644
--- a/src/zero_wavefield_acoustic.cpp
+++ b/src/zero_wavefield_acoustic.cpp
@@ -22,7 +22,7 @@
  * -------------------------------------------------------------------------*/
 
 #include "fd.hpp"
-void zero_wavefield_acoustic(st_velocity &vel, st_stress *stress, st_visc_mem *mem,
+void zero_wavefield_acoustic(st_velocity &vel, st_stress &stress, st_visc_mem *mem,
                              st_pml_wfd *pml_wfd, const GlobVar *gv)
 {
     int l = 1;
@@ -64,7 +64,7 @@ void zero_wavefield_acoustic(st_velocity &vel, st_stress *stress, st_visc_mem *m
         for (int i = nx1; i <= nx2; i++) {
             #pragma omp simd
             for (int k = nz1; k <= nz2; k++) {
-                stress->sp[j][i][k] = 0.0f;
+                stress.sp[j, i, k] = 0.0f;
             }
         }
     }
-- 
GitLab


From 1d8d9a573b2e265459e364a0167fdf2bce05cd74 Mon Sep 17 00:00:00 2001
From: Holger Obermaier <holgerob@gmx.de>
Date: Fri, 4 Apr 2025 14:47:48 +0200
Subject: [PATCH 04/15] Remove no more needed functions for type float ***

---
 src/exchange_buffer.cpp | 66 -----------------------------------------
 src/exchange_buffer.hpp | 12 --------
 2 files changed, 78 deletions(-)

diff --git a/src/exchange_buffer.cpp b/src/exchange_buffer.cpp
index e4501da..9f50f2c 100644
--- a/src/exchange_buffer.cpp
+++ b/src/exchange_buffer.cpp
@@ -10,72 +10,6 @@
 #endif
 
 #ifdef BUFFER_EXCHANGE_USE_METHOD_OPENMP
-int buffer_push(
-    float *__restrict__ buffer, float ***__restrict__ src,
-    int i1_start, int i1_end,
-    int i2_start, int i2_end,
-    int i3_start, int i3_end,
-    int buffer_counter)
-{
-    if (i1_end < i1_start) {
-        int swap = i1_start;
-        i1_start = i1_end;
-        i1_end = swap;
-    }
-    if (i2_end < i2_start) {
-        int swap = i2_start;
-        i2_start = i2_end;
-        i2_end = swap;
-    }
-    if (i3_end < i3_start) {
-        int swap = i3_start;
-        i3_start = i3_end;
-        i3_end = swap;
-    }
-    for (int i1 = i1_start; i1 <= i1_end; i1++) {
-        for (int i2 = i2_start; i2 <= i2_end; i2++) {
-            #pragma omp simd
-            for (int i3 = i3_start; i3 <= i3_end; i3++) {
-                buffer[buffer_counter++] = src[i1][i2][i3];
-            }
-        }
-    }
-    return buffer_counter;
-}
-
-int buffer_pop(
-    float ***__restrict__ dest, float *__restrict__ buffer,
-    int i1_start, int i1_end,
-    int i2_start, int i2_end,
-    int i3_start, int i3_end,
-    int buffer_counter)
-{
-    if (i1_end < i1_start) {
-        int swap = i1_start;
-        i1_start = i1_end;
-        i1_end = swap;
-    }
-    if (i2_end < i2_start) {
-        int swap = i2_start;
-        i2_start = i2_end;
-        i2_end = swap;
-    }
-    if (i3_end < i3_start) {
-        int swap = i3_start;
-        i3_start = i3_end;
-        i3_end = swap;
-    }
-    for (int i1 = i1_start; i1 <= i1_end; i1++) {
-        for (int i2 = i2_start; i2 <= i2_end; i2++) {
-            #pragma omp simd
-            for (int i3 = i3_start; i3 <= i3_end; i3++) {
-                dest[i1][i2][i3] = buffer[buffer_counter++];
-            }
-        }
-    }
-    return buffer_counter;
-}
-
 int buffer_push(
     float *__restrict__ buffer, float3DTensorT &src,
     int i1_start, int i1_end,
diff --git a/src/exchange_buffer.hpp b/src/exchange_buffer.hpp
index 2c2cc46..9c1f2ae 100644
--- a/src/exchange_buffer.hpp
+++ b/src/exchange_buffer.hpp
@@ -2,18 +2,6 @@
 #define _EXCHANGE_BUFFER_H_INCLUDED_
 
 #include "float3DTensorT.hpp"
-int buffer_push(float *__restrict__ buffer, float ***__restrict__ src,
-                int i1_start, int i1_end,
-                int i2_start, int i2_end,
-                int i3_start, int i3_end,
-                int buffer_counter);
-
-int buffer_pop(float ***__restrict__ dest, float *__restrict__ buffer,
-               int i1_start, int i1_end,
-               int i2_start, int i2_end,
-               int i3_start, int i3_end,
-               int buffer_counter);
-
 int buffer_push(float *__restrict__ buffer, float3DTensorT &src,
                 int i1_start, int i1_end,
                 int i2_start, int i2_end,
-- 
GitLab


From 9c1db07f94f83f4283b1bd9587a3da6ef72ae968 Mon Sep 17 00:00:00 2001
From: Holger Obermaier <holgerob@gmx.de>
Date: Fri, 4 Apr 2025 20:17:23 +0200
Subject: [PATCH 05/15] Use std::swap to swap values

---
 src/exchange_buffer.cpp | 73 ++++++++---------------------------------
 1 file changed, 13 insertions(+), 60 deletions(-)

diff --git a/src/exchange_buffer.cpp b/src/exchange_buffer.cpp
index 9f50f2c..f6394a2 100644
--- a/src/exchange_buffer.cpp
+++ b/src/exchange_buffer.cpp
@@ -1,6 +1,7 @@
 #include "float3DTensorT.hpp"
 #include <cstring>
 #include <stddef.h>
+#include <utility> // swap
 
 // Choose default method to push and pop data to the buffer
 // available methods: OPENMP, MEMCPY
@@ -17,21 +18,9 @@ int buffer_push(
     int i3_start, int i3_end,
     int buffer_counter)
 {
-    if (i1_end < i1_start) {
-        int swap = i1_start;
-        i1_start = i1_end;
-        i1_end = swap;
-    }
-    if (i2_end < i2_start) {
-        int swap = i2_start;
-        i2_start = i2_end;
-        i2_end = swap;
-    }
-    if (i3_end < i3_start) {
-        int swap = i3_start;
-        i3_start = i3_end;
-        i3_end = swap;
-    }
+    if (i1_end < i1_start) std::swap(i1_start, i1_end);
+    if (i2_end < i2_start) std::swap(i2_start, i2_end);
+    if (i3_end < i3_start) std::swap(i3_start, i3_end);
     for (int i1 = i1_start; i1 <= i1_end; i1++) {
         for (int i2 = i2_start; i2 <= i2_end; i2++) {
             #pragma omp simd
@@ -50,21 +39,9 @@ int buffer_pop(
     int i3_start, int i3_end,
     int buffer_counter)
 {
-    if (i1_end < i1_start) {
-        int swap = i1_start;
-        i1_start = i1_end;
-        i1_end = swap;
-    }
-    if (i2_end < i2_start) {
-        int swap = i2_start;
-        i2_start = i2_end;
-        i2_end = swap;
-    }
-    if (i3_end < i3_start) {
-        int swap = i3_start;
-        i3_start = i3_end;
-        i3_end = swap;
-    }
+    if (i1_end < i1_start) std::swap(i1_start, i1_end);
+    if (i2_end < i2_start) std::swap(i2_start, i2_end);
+    if (i3_end < i3_start) std::swap(i3_start, i3_end);
     for (int i1 = i1_start; i1 <= i1_end; i1++) {
         for (int i2 = i2_start; i2 <= i2_end; i2++) {
             #pragma omp simd
@@ -85,21 +62,9 @@ int buffer_push(
     int i3_start, int i3_end,
     int buffer_counter)
 {
-    if (i1_end < i1_start) {
-        int swap = i1_start;
-        i1_start = i1_end;
-        i1_end = swap;
-    }
-    if (i2_end < i2_start) {
-        int swap = i2_start;
-        i2_start = i2_end;
-        i2_end = swap;
-    }
-    if (i3_end < i3_start) {
-        int swap = i3_start;
-        i3_start = i3_end;
-        i3_end = swap;
-    }
+    if (i1_end < i1_start) std::swap(i1_start, i1_end);
+    if (i2_end < i2_start) std::swap(i2_start, i2_end);
+    if (i3_end < i3_start) std::swap(i3_start, i3_end);
     const size_t vec_len = i3_end - i3_start + 1;
     for (int i1 = i1_start; i1 <= i1_end; i1++) {
         for (int i2 = i2_start; i2 <= i2_end; i2++) {
@@ -117,21 +82,9 @@ int buffer_pop(
     int i3_start, int i3_end,
     int buffer_counter)
 {
-    if (i1_end < i1_start) {
-        int swap = i1_start;
-        i1_start = i1_end;
-        i1_end = swap;
-    }
-    if (i2_end < i2_start) {
-        int swap = i2_start;
-        i2_start = i2_end;
-        i2_end = swap;
-    }
-    if (i3_end < i3_start) {
-        int swap = i3_start;
-        i3_start = i3_end;
-        i3_end = swap;
-    }
+    if (i1_end < i1_start) std::swap(i1_start, i1_end);
+    if (i2_end < i2_start) std::swap(i2_start, i2_end);
+    if (i3_end < i3_start) std::swap(i3_start, i3_end);
     const size_t vec_len = i3_end - i3_start + 1;
     for (int i1 = i1_start; i1 <= i1_end; i1++) {
         for (int i2 = i2_start; i2 <= i2_end; i2++) {
-- 
GitLab


From 7ac4ce18dd02e8806519509f6b73c04dca15f370 Mon Sep 17 00:00:00 2001
From: Holger Obermaier <holgerob@gmx.de>
Date: Mon, 7 Apr 2025 12:02:46 +0200
Subject: [PATCH 06/15] Modify BUFFER_EXCHANGE_USE_METHOD_MEMCPY methods for
 type float3DTensorT

---
 src/exchange_buffer.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/exchange_buffer.cpp b/src/exchange_buffer.cpp
index f6394a2..e6eeccd 100644
--- a/src/exchange_buffer.cpp
+++ b/src/exchange_buffer.cpp
@@ -56,7 +56,7 @@ int buffer_pop(
 
 #ifdef BUFFER_EXCHANGE_USE_METHOD_MEMCPY
 int buffer_push(
-    float *__restrict__ buffer, float ***__restrict__ src,
+    float *__restrict__ buffer, float3DTensorT &src,
     int i1_start, int i1_end,
     int i2_start, int i2_end,
     int i3_start, int i3_end,
@@ -68,7 +68,7 @@ int buffer_push(
     const size_t vec_len = i3_end - i3_start + 1;
     for (int i1 = i1_start; i1 <= i1_end; i1++) {
         for (int i2 = i2_start; i2 <= i2_end; i2++) {
-            memcpy(buffer + buffer_counter, src[i1][i2] + i3_start, vec_len * sizeof(float));
+            memcpy(buffer + buffer_counter, &src[i1, i2, i3_start], vec_len * sizeof(float));
             buffer_counter += vec_len;
         }
     }
@@ -76,7 +76,7 @@ int buffer_push(
 }
 
 int buffer_pop(
-    float ***__restrict__ dest, float *__restrict__ buffer,
+    float3DTensorT &dest, float *__restrict__ buffer,
     int i1_start, int i1_end,
     int i2_start, int i2_end,
     int i3_start, int i3_end,
@@ -88,7 +88,7 @@ int buffer_pop(
     const size_t vec_len = i3_end - i3_start + 1;
     for (int i1 = i1_start; i1 <= i1_end; i1++) {
         for (int i2 = i2_start; i2 <= i2_end; i2++) {
-            memcpy(dest[i1][i2] + i3_start, buffer + buffer_counter, vec_len * sizeof(float));
+            memcpy(&dest[i1, i2, i3_start], buffer + buffer_counter, vec_len * sizeof(float));
             buffer_counter += vec_len;
         }
     }
-- 
GitLab


From f984031ce2d174946ebb555d63edb6fc6cb0a572 Mon Sep 17 00:00:00 2001
From: Holger Obermaier <holgerob@gmx.de>
Date: Mon, 7 Apr 2025 15:04:12 +0200
Subject: [PATCH 07/15] Use float3DTensorT in type st_model_av

---
 src/av_mat.cpp                     | 20 ++++++++--------
 src/fd.hpp                         | 32 ++++++++++++-------------
 src/freemem.cpp                    | 20 ++++++++--------
 src/fsource.cpp                    |  8 +++----
 src/ifos3d.cpp                     | 16 ++++++-------
 src/initmem.cpp                    | 20 ++++++++--------
 src/stfi.cpp                       |  2 +-
 src/timeloop.cpp                   |  2 +-
 src/update_s_ssg_CPML_elastic.cpp  | 38 +++++++++++++++---------------
 src/update_s_ssg_elastic.cpp       | 38 +++++++++++++++---------------
 src/update_v_ssg.cpp               | 38 +++++++++++++++---------------
 src/update_v_ssg_CPML.cpp          | 38 +++++++++++++++---------------
 src/update_v_ssg_CPML_acoustic.cpp | 38 +++++++++++++++---------------
 src/update_v_ssg_acoustic.cpp      | 38 +++++++++++++++---------------
 14 files changed, 174 insertions(+), 174 deletions(-)

diff --git a/src/av_mat.cpp b/src/av_mat.cpp
index 2220b85..0e94aed 100644
--- a/src/av_mat.cpp
+++ b/src/av_mat.cpp
@@ -25,15 +25,15 @@
 
 #include "fd.hpp"
 
-void av_mat(st_model *mod, st_model_av *mod_av, const GlobVar *gv)
+void av_mat(st_model *mod, st_model_av &mod_av, const GlobVar *gv)
 {
     for (int j = 1; j <= gv->NY; j++) {
         for (int i = 1; i <= gv->NX; i++) {
             #pragma omp simd
             for (int k = 1; k <= gv->NZ; k++) {
-                mod_av->rjp[j][i][k] = 0.5f * (mod->rho[j][i][k] + mod->rho[j + 1][i][k]);
-                mod_av->rkp[j][i][k] = 0.5f * (mod->rho[j][i][k] + mod->rho[j][i][k + 1]);
-                mod_av->rip[j][i][k] = 0.5f * (mod->rho[j][i][k] + mod->rho[j][i + 1][k]);
+                mod_av.rjp[j, i, k] = 0.5f * (mod->rho[j][i][k] + mod->rho[j + 1][i][k]);
+                mod_av.rkp[j, i, k] = 0.5f * (mod->rho[j][i][k] + mod->rho[j][i][k + 1]);
+                mod_av.rip[j, i, k] = 0.5f * (mod->rho[j][i][k] + mod->rho[j][i + 1][k]);
             }
         }
     }
@@ -42,28 +42,28 @@ void av_mat(st_model *mod, st_model_av *mod_av, const GlobVar *gv)
             for (int i = 1; i <= gv->NX; i++) {
                 for (int k = 1; k <= gv->NZ; k++) {
                     /* harmonic averaging of shear modulus */
-                    mod_av->uipjp[j][i][k] =
+                    mod_av.uipjp[j, i, k] =
                         4.0f /
                         ((1.0f / mod->u[j][i][k]) + (1.0f / mod->u[j][i + 1][k]) + (1.0f / mod->u[j + 1][i + 1][k]) +
                          (1.0f / mod->u[j + 1][i][k]));
-                    mod_av->ujpkp[j][i][k] =
+                    mod_av.ujpkp[j, i, k] =
                         4.0f /
                         ((1.0f / mod->u[j][i][k]) + (1.0f / mod->u[j][i][k + 1]) + (1.0f / mod->u[j + 1][i][k + 1]) +
                          (1.0f / mod->u[j + 1][i][k]));
-                    mod_av->uipkp[j][i][k] =
+                    mod_av.uipkp[j, i, k] =
                         4.0f /
                         ((1.0f / mod->u[j][i][k]) + (1.0f / mod->u[j][i][k + 1]) + (1.0f / mod->u[j][i + 1][k + 1]) +
                          (1.0f / mod->u[j][i + 1][k]));
 
                     /* arithmetic averaging of TAU for S-waves and density */
                     if (gv->L) {
-                        mod_av->tausipjp[j][i][k] =
+                        mod_av.tausipjp[j, i, k] =
                             0.25f * (mod->taus[j][i][k] + mod->taus[j][i + 1][k] + mod->taus[j + 1][i + 1][k] +
                                      mod->taus[j + 1][i][k]);
-                        mod_av->tausjpkp[j][i][k] =
+                        mod_av.tausjpkp[j, i, k] =
                             0.25f * (mod->taus[j][i][k] + mod->taus[j + 1][i][k] + mod->taus[j + 1][i][k + 1] +
                                      mod->taus[j][i][k + 1]);
-                        mod_av->tausipkp[j][i][k] =
+                        mod_av.tausipkp[j, i, k] =
                             0.25f * (mod->taus[j][i][k] + mod->taus[j][i + 1][k] + mod->taus[j][i + 1][k + 1] +
                                      mod->taus[j][i][k + 1]);
                     }
diff --git a/src/fd.hpp b/src/fd.hpp
index 46773cf..f227dab 100644
--- a/src/fd.hpp
+++ b/src/fd.hpp
@@ -38,17 +38,17 @@
 #include "kiss_fftr.h"
 #include "float3DTensorT.hpp"
 
-typedef struct Model {
+typedef struct {
     float ***rho, ***pi, ***u;
     /* Variables for viscoelastic modeling */
     float ***taus, ***taup, *eta;
     float ***absorb_coeff;
 } st_model;
 
-typedef struct Model_AV {
-    float ***uipjp, ***ujpkp, ***uipkp, ***rjp, ***rkp, ***rip;
+typedef struct {
+    float3DTensorT uipjp, ujpkp, uipkp, rjp, rkp, rip;
     /* Variables for viscoelastic modeling */
-    float ***tausipjp, ***tausjpkp, ***tausipkp;
+    float3DTensorT tausipjp, tausjpkp, tausipkp;
 } st_model_av;
 
 typedef struct Stress {
@@ -162,7 +162,7 @@ void absorb_PML(float ***absorb_coeffx, float ***absorb_coeffy, float ***absorb_
 
 void CPML_coeff(st_pml_coeff *pml_coeff, const GlobVar *gv);
 
-void av_mat(st_model *mod, st_model_av *mod_av, const GlobVar *gv);
+void av_mat(st_model *mod, st_model_av &mod_av, const GlobVar *gv);
 
 void calc_res(int ishot, int shot_id, st_seismogram *section, st_seismogram *section_obs, st_signals *signals,
               int ntr_loc, const float *finv, int nf, double *L2, int res_switch, int groupnum,
@@ -183,7 +183,7 @@ void comm_ini(st_buffer *buffer, MPI_Request *req_send, MPI_Request *req_rec);
 void comm_ini_s(st_buffer *buffer, MPI_Request *req_send, MPI_Request *req_rec);
 
 void freemem(int nsrc_loc, st_acquisition *acq, st_model *mod,
-             st_model *testmod, st_model_av *mod_av, st_visc_mem *visco_mem, st_pml_coeff *pml_coeff,
+             st_model *testmod, st_model_av &mod_av, st_visc_mem *visco_mem, st_pml_coeff *pml_coeff,
              st_pml_wfd *pml_wfd, st_signals *signals,
              st_gradient *grad, st_gradient *grad_prior1, st_gradient *grad_prior2, st_gradient *grad_halo,
              st_hessian *hessian,
@@ -195,7 +195,7 @@ void freemem_seis(int ntr_loc, st_seismogram *section, st_seismogram *section_ob
 
 void globvar_change(GlobVar *gv);
 
-int initmem(st_model *mod, st_model *testmod, st_model_av *mod_av, st_visc_mem *visco_mem,
+int initmem(st_model *mod, st_model *testmod, st_model_av &mod_av, st_visc_mem *visco_mem,
             st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, st_gradient *grad, st_gradient *grad_prior1,
             st_gradient *grad_prior2, st_gradient *grad_halo, st_hessian *hessian, st_stress &stress,
             st_buffer_flat *stressbuff,
@@ -288,7 +288,7 @@ void snapmerge(int nsnap, GlobVar *gv);
 void sources(FILE *fpsrc, int *nsrc, float **srcpos, GlobVar *gv, int **topo);
 
 void stfi(st_acquisition *acq, st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress &stress,
-          st_model *mod, st_model_av *mod_av, st_visc_mem *visco_mem, st_seismogram *section,
+          st_model *mod, st_model_av &mod_av, st_visc_mem *visco_mem, st_seismogram *section,
           st_seismogram *section_obs, st_signals *signals, int nsrc_loc, int ntr_loc, st_pml_coeff *pml_coeff,
           st_pml_wfd *pml_wfd, st_buffer_flat *stressbuff, st_buffer_flat *velbuff, st_freq_velocity *fourier_vel,
           const float *finv, double *L2, int nf, int ntast, int lsnap, int nsnap, int ishot, int shot_id, int cdf,
@@ -315,10 +315,10 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
 void update_s_rsg(st_boundary *nb, st_velocity &vel, st_stress &stress,
                   st_visc_mem *mem, st_model *mod, float ***taus, float ***taup, float *eta);
 
-void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av *mod_av,
+void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av &mod_av,
               float ***absorb_coeff, const GlobVar *gv);
 
-void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av *mod_av,
+void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av &mod_av,
                    st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, const GlobVar *gv);
 
 void update_v_rsg(st_boundary *nb, int nt, st_velocity &vel, st_stress &stress,
@@ -400,10 +400,10 @@ void conjugate(st_gradient *grad, st_gradient *grad_prior1, st_gradient *grad_pr
                float *beta, int cdf, GlobVar *gv);
 
 double update_s_elastic(st_boundary *nb, st_velocity &vel, st_stress &stress,
-                        st_model *mod, st_model_av *mod_av, const GlobVar *gv);
+                        st_model *mod, st_model_av &mod_av, const GlobVar *gv);
 
 double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
-                             st_stress &stress, st_model *mod, st_model_av *mod_av, st_pml_coeff *pml_coeff,
+                             st_stress &stress, st_model *mod, st_model_av &mod_av, st_pml_coeff *pml_coeff,
                              st_pml_wfd *pml_wfd, const GlobVar *gv);
 
 void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, st_stress &stress,
@@ -454,23 +454,23 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
                               st_pml_wfd *pml_wfd, const GlobVar *gv);
 
 void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress &stress,
-                       st_model_av *mod_av, float ***absorb_coeff, const GlobVar *gv);
+                       st_model_av &mod_av, float ***absorb_coeff, const GlobVar *gv);
 
-void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av *mod_av,
+void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av &mod_av,
                             st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, const GlobVar *gv);
 
 void zero_wavefield_acoustic(st_velocity &vel, st_stress &stress, st_visc_mem *mem, st_pml_wfd *pml_wfd,
                              const GlobVar *gv);
 
 void timeloop(st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress &stress,
-              st_model *mod, st_model_av *mod_av, st_seismogram *section,
+              st_model *mod, st_model_av &mod_av, st_seismogram *section,
               float **srcpos_loc, int **recpos_loc, st_signals *signals, int nsrc_loc,
               float ***absorb_coeff, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd,
               st_buffer_flat *stressbuff, st_buffer_flat *velbuff, st_freq_velocity *fourier_vel,
               const float *finv, int nf, int ntast, int ntr, int lsnap, int nsnap, int pshot, int shot_id, int proptype,
               GlobVar *gv);
 
-void fsource(int nt, st_velocity &vel, st_model_av *mod_av, float **srcpos_loc,
+void fsource(int nt, st_velocity &vel, st_model_av &mod_av, float **srcpos_loc,
              st_signals *signals, int nsrc, int back, const GlobVar *gv);
 
 void time_window(float **sectiondata1, float **sectiondata2, int **recpos_loc, int ntr, int ntr_loc, int ishot,
diff --git a/src/freemem.cpp b/src/freemem.cpp
index c3faf37..e959bcd 100644
--- a/src/freemem.cpp
+++ b/src/freemem.cpp
@@ -25,7 +25,7 @@
 #include "util.hpp"
 
 void freemem(int nsrc_loc, st_acquisition *acq, st_model *mod, st_model *testmod,
-             st_model_av *mod_av, st_visc_mem *visco_mem, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd,
+             st_model_av &mod_av, st_visc_mem *visco_mem, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd,
              st_signals *signals, st_gradient *grad, st_gradient *grad_prior1, st_gradient *grad_prior2,
              st_gradient *grad_halo,
              st_hessian *hessian, st_stress &stress, st_buffer_flat *stressbuff, st_freq_velocity *fourier_vel_back,
@@ -264,9 +264,9 @@ void freemem(int nsrc_loc, st_acquisition *acq, st_model *mod, st_model *testmod
 
             free_f3tensor(testmod->taus, 0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
 
-            free_f3tensor(mod_av->tausipjp, 1, gv->NY, 1, gv->NX, 1, gv->NZ);
-            free_f3tensor(mod_av->tausjpkp, 1, gv->NY, 1, gv->NX, 1, gv->NZ);
-            free_f3tensor(mod_av->tausipkp, 1, gv->NY, 1, gv->NX, 1, gv->NZ);
+            mod_av.tausipjp.free();
+            mod_av.tausjpkp.free();
+            mod_av.tausipkp.free();
         } else {
             free_f3tensor(visco_mem->rp, 1, gv->NY, 1, gv->NX, 1, gv->NZ);
         }
@@ -284,17 +284,17 @@ void freemem(int nsrc_loc, st_acquisition *acq, st_model *mod, st_model *testmod
     free_f3tensor(testmod->pi, 0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
 
     /* averaged material parameters */
-    free_f3tensor(mod_av->rjp, 1, gv->NY, 1, gv->NX, 1, gv->NZ);
-    free_f3tensor(mod_av->rkp, 1, gv->NY, 1, gv->NX, 1, gv->NZ);
-    free_f3tensor(mod_av->rip, 1, gv->NY, 1, gv->NX, 1, gv->NZ);
+    mod_av.rjp.free();
+    mod_av.rkp.free();
+    mod_av.rip.free();
 
     if (gv->WEQ != 2) {
         free_f3tensor(mod->u, 0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
         free_f3tensor(testmod->u, 0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
 
-        free_f3tensor(mod_av->uipjp, 1, gv->NY, 1, gv->NX, 1, gv->NZ);
-        free_f3tensor(mod_av->ujpkp, 1, gv->NY, 1, gv->NX, 1, gv->NZ);
-        free_f3tensor(mod_av->uipkp, 1, gv->NY, 1, gv->NX, 1, gv->NZ);
+        mod_av.uipjp.free();
+        mod_av.ujpkp.free();
+        mod_av.uipkp.free();
     }
 
     free(velbuff->lef_to_rig);
diff --git a/src/fsource.cpp b/src/fsource.cpp
index 5a762f7..f12e2bc 100644
--- a/src/fsource.cpp
+++ b/src/fsource.cpp
@@ -23,7 +23,7 @@
 
 #include "fd.hpp"
 
-void fsource(int nt, st_velocity &vel, st_model_av *mod_av, float **srcpos_loc,
+void fsource(int nt, st_velocity &vel, st_model_av &mod_av, float **srcpos_loc,
              st_signals *signals, int nsrc, int back, const GlobVar *gv)
 {
     /* Adding body force components to corresponding particle velocities */
@@ -46,13 +46,13 @@ void fsource(int nt, st_velocity &vel, st_model_av *mod_av, float **srcpos_loc,
             float alpha_rad, beta_rad;
             switch ((int)srcpos_loc[7][l]) {
             case 2:
-                vel.vx[j, i, k] += amp * mod_av->rip[j][i][k];
+                vel.vx[j, i, k] += amp * mod_av.rip[j, i, k];
                 break;
             case 3:
-                vel.vy[j, i, k] += amp * mod_av->rkp[j][i][k]; /* single force in y, vertical direction */
+                vel.vy[j, i, k] += amp * mod_av.rkp[j, i, k]; /* single force in y, vertical direction */
                 break;
             case 4:
-                vel.vz[j, i, k] += amp * mod_av->rjp[j][i][k]; /* single force in z  */
+                vel.vz[j, i, k] += amp * mod_av.rjp[j, i, k]; /* single force in z  */
                 break;
             case 5:
                 alpha_rad = gv->ALPHA * PI / 180;              /* custom force */
diff --git a/src/ifos3d.cpp b/src/ifos3d.cpp
index 7340def..39ef982 100644
--- a/src/ifos3d.cpp
+++ b/src/ifos3d.cpp
@@ -183,7 +183,7 @@ int main(int argc, char **argv)
     }
 
     /* allocate and initialize buffers */
-    buffsize = initmem(&mod, &testmod, &mod_av, &visco_mem, &pml_coeff, &pml_wfd,
+    buffsize = initmem(&mod, &testmod, mod_av, &visco_mem, &pml_coeff, &pml_wfd,
                        &grad, &grad_prior1, &grad_prior2, &grad_halo, &hessian, stress, &stressbuff,
                        &fourier_vel_back, &fourier_vel_fw, vel, &velbuff, &gv);
 
@@ -379,7 +379,7 @@ int main(int argc, char **argv)
                 constant_boundary_acoustic(&nb, &mod, &gv);
             }
         }
-        av_mat(&mod, &mod_av, &gv);
+        av_mat(&mod, mod_av, &gv);
         L2all = 0.0;
         misfit[0] = 0.0;
 
@@ -487,7 +487,7 @@ int main(int argc, char **argv)
                     ntast = 1;
 
                 if (gv.STFI) {
-                    stfi(&acq, &nb, &nb_fix, vel, stress, &mod, &mod_av, &visco_mem, &section, &section_obs,
+                    stfi(&acq, &nb, &nb_fix, vel, stress, &mod, mod_av, &visco_mem, &section, &section_obs,
                          &signals, nsrc_loc, ntr_loc, &pml_coeff, &pml_wfd, &stressbuff, &velbuff,
                          &fourier_vel_fw, finv, &L2, nf, ntast, lsnap, nsnap, ishot, shot_id, cdf, iteration, groupnum,
                          it_group, ncplx, &gv);
@@ -497,7 +497,7 @@ int main(int argc, char **argv)
             /*****************************************************
             * Timestep loop (simulation)
             *****************************************************/
-            timeloop(&nb, &nb_fix, vel, stress, &mod, &mod_av, &section,
+            timeloop(&nb, &nb_fix, vel, stress, &mod, mod_av, &section,
                      acq.srcpos_loc, acq.recpos_loc, &signals, nsrc_loc,
                      mod.absorb_coeff, &pml_coeff, &pml_wfd, &stressbuff, &velbuff, &fourier_vel_fw,
                      finv, nf, ntast, ntr_loc, lsnap, nsnap, 0, shot_id, 1, &gv);
@@ -564,7 +564,7 @@ int main(int argc, char **argv)
                 /*****************************************************
                 *           Timestep loop (back-propagation)
                 *****************************************************/
-                timeloop(&nb, &nb_fix, vel, stress, &mod, &mod_av, &section,
+                timeloop(&nb, &nb_fix, vel, stress, &mod, mod_av, &section,
                          acq.srcpos_loc_back, acq.recpos_loc, &signals, ntr_loc,
                          mod.absorb_coeff, &pml_coeff, &pml_wfd, &stressbuff, &velbuff, &fourier_vel_back,
                          finv, nf, ntast, ntr_loc, lsnap, nsnap, 0, shot_id, 2, &gv);
@@ -744,7 +744,7 @@ int main(int argc, char **argv)
                         constant_boundary_acoustic(&nb, &testmod, &gv);
                     }
                 }
-                av_mat(&testmod, &mod_av, &gv);
+                av_mat(&testmod, mod_av, &gv);
 
                 L2 = 0.0;
 
@@ -802,7 +802,7 @@ int main(int argc, char **argv)
                         /*****************************************************
                         * Timestep loop (steplength calculation)
                         *****************************************************/
-                        timeloop(&nb, &nb_fix, vel, stress, &testmod, &mod_av, &section,
+                        timeloop(&nb, &nb_fix, vel, stress, &testmod, mod_av, &section,
                                  acq.srcpos_loc, acq.recpos_loc, &signals, nsrc_loc,
                                  mod.absorb_coeff, &pml_coeff, &pml_wfd, &stressbuff, &velbuff, &fourier_vel_fw,
                                  finv, nf, ntast, ntr_loc, lsnap, nsnap, 0, shot_id, 3, &gv);
@@ -848,7 +848,7 @@ int main(int argc, char **argv)
 
 
     /* de-allocation of memory */
-    freemem(nsrc_loc, &acq, &mod, &testmod, &mod_av,
+    freemem(nsrc_loc, &acq, &mod, &testmod, mod_av,
             &visco_mem, &pml_coeff, &pml_wfd, &signals, &grad,
             &grad_prior1, &grad_prior2, &grad_halo, &hessian, stress, &stressbuff,
             &fourier_vel_back, &fourier_vel_fw, vel, &velbuff, &gv);
diff --git a/src/initmem.cpp b/src/initmem.cpp
index 09eaa06..71f87ad 100644
--- a/src/initmem.cpp
+++ b/src/initmem.cpp
@@ -26,7 +26,7 @@
 #include "util.hpp"
 
 int initmem(st_model *mod, st_model *testmod,
-            st_model_av *mod_av, st_visc_mem *visco_mem, st_pml_coeff *pml_coeff,
+            st_model_av &mod_av, st_visc_mem *visco_mem, st_pml_coeff *pml_coeff,
             st_pml_wfd *pml_wfd, st_gradient *grad, st_gradient *grad_prior1,
             st_gradient *grad_prior2, st_gradient *grad_halo, st_hessian *hessian, st_stress &stress,
             st_buffer_flat *stressbuff, st_freq_velocity *fourier_vel_back,
@@ -396,9 +396,9 @@ int initmem(st_model *mod, st_model *testmod,
 
             mod->taus = f3tensor(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
             testmod->taus = f3tensor(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
-            mod_av->tausipjp = f3tensor(1, gv->NY, 1, gv->NX, 1, gv->NZ);
-            mod_av->tausjpkp = f3tensor(1, gv->NY, 1, gv->NX, 1, gv->NZ);
-            mod_av->tausipkp = f3tensor(1, gv->NY, 1, gv->NX, 1, gv->NZ);
+            mod_av.tausipjp.malloc(1, gv->NY, 1, gv->NX, 1, gv->NZ);
+            mod_av.tausjpkp.malloc(1, gv->NY, 1, gv->NX, 1, gv->NZ);
+            mod_av.tausipkp.malloc(1, gv->NY, 1, gv->NX, 1, gv->NZ);
         } else {
             visco_mem->rp = f3tensor(1, gv->NY, 1, gv->NX, 1, gv->NZ);
         }
@@ -421,13 +421,13 @@ int initmem(st_model *mod, st_model *testmod,
         mod->u = f3tensor(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
         testmod->u = f3tensor(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
         /* averaged material parameters */
-        mod_av->uipjp = f3tensor(1, gv->NY, 1, gv->NX, 1, gv->NZ);
-        mod_av->ujpkp = f3tensor(1, gv->NY, 1, gv->NX, 1, gv->NZ);
-        mod_av->uipkp = f3tensor(1, gv->NY, 1, gv->NX, 1, gv->NZ);
+        mod_av.uipjp.malloc(1, gv->NY, 1, gv->NX, 1, gv->NZ);
+        mod_av.ujpkp.malloc(1, gv->NY, 1, gv->NX, 1, gv->NZ);
+        mod_av.uipkp.malloc(1, gv->NY, 1, gv->NX, 1, gv->NZ);
     }
-    mod_av->rjp = f3tensor(1, gv->NY, 1, gv->NX, 1, gv->NZ);
-    mod_av->rkp = f3tensor(1, gv->NY, 1, gv->NX, 1, gv->NZ);
-    mod_av->rip = f3tensor(1, gv->NY, 1, gv->NX, 1, gv->NZ);
+    mod_av.rjp.malloc(1, gv->NY, 1, gv->NX, 1, gv->NZ);
+    mod_av.rkp.malloc(1, gv->NY, 1, gv->NX, 1, gv->NZ);
+    mod_av.rip.malloc(1, gv->NY, 1, gv->NX, 1, gv->NZ);
 
     /* memory allocation for buffer arrays in which the wavefield
      * information which is exchanged between neighbouring PEs is stored */
diff --git a/src/stfi.cpp b/src/stfi.cpp
index c7ac290..53497b3 100644
--- a/src/stfi.cpp
+++ b/src/stfi.cpp
@@ -31,7 +31,7 @@
 #include "kiss_fftr.h"
 
 void stfi(st_acquisition *acq, st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress &stress,
-          st_model *mod, st_model_av *mod_av, st_visc_mem *visco_mem, st_seismogram *section,
+          st_model *mod, st_model_av &mod_av, st_visc_mem *visco_mem, st_seismogram *section,
           st_seismogram *section_obs, st_signals *signals, int nsrc_loc, int ntr_loc, st_pml_coeff *pml_coeff,
           st_pml_wfd *pml_wfd, st_buffer_flat *stressbuff, st_buffer_flat *velbuff, st_freq_velocity *fourier_vel_fw,
           const float *finv, double *L2, int nf, int ntast, int lsnap, int nsnap, int ishot, int shot_id, int cdf,
diff --git a/src/timeloop.cpp b/src/timeloop.cpp
index 7a1e512..b9d0f79 100644
--- a/src/timeloop.cpp
+++ b/src/timeloop.cpp
@@ -24,7 +24,7 @@
 #include "logging.hpp"
 
 void timeloop(st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress &stress,
-              st_model *mod, st_model_av *mod_av, st_seismogram *section,
+              st_model *mod, st_model_av &mod_av, st_seismogram *section,
               float **srcpos_loc, int **recpos_loc, st_signals *signals, int nsrc_loc,
               float ***absorb_coeff, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd,
               st_buffer_flat *stressbuff, st_buffer_flat *velbuff, st_freq_velocity *fourier_vel,
diff --git a/src/update_s_ssg_CPML_elastic.cpp b/src/update_s_ssg_CPML_elastic.cpp
index 9848f4c..a6a9017 100644
--- a/src/update_s_ssg_CPML_elastic.cpp
+++ b/src/update_s_ssg_CPML_elastic.cpp
@@ -30,7 +30,7 @@
 #define UNUSED(x) (void)(x)
 
 double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
-                             st_stress &stress, st_model *mod, st_model_av *mod_av,
+                             st_stress &stress, st_model *mod, st_model_av &mod_av,
                              st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, const GlobVar *gv)
 {
     int h1;
@@ -147,9 +147,9 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                         vzz = vzz / pml_coeff->K_z[h1] + pml_wfd->psi_vzz[j][i][h1];
                     }
 
-                    fipjp = mod_av->uipjp[j][i][k] * gv->DT;
-                    fjpkp = mod_av->ujpkp[j][i][k] * gv->DT;
-                    fipkp = mod_av->uipkp[j][i][k] * gv->DT;
+                    fipjp = mod_av.uipjp[j, i, k] * gv->DT;
+                    fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
+                    fipkp = mod_av.uipkp[j, i, k] * gv->DT;
                     g = mod->pi[j][i][k];
                     f = 2.0f * mod->u[j][i][k];
 
@@ -269,9 +269,9 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                         vzz = vzz / pml_coeff->K_z[h1] + pml_wfd->psi_vzz[j][i][h1];
                     }
 
-                    fipjp = mod_av->uipjp[j][i][k] * gv->DT;
-                    fjpkp = mod_av->ujpkp[j][i][k] * gv->DT;
-                    fipkp = mod_av->uipkp[j][i][k] * gv->DT;
+                    fipjp = mod_av.uipjp[j, i, k] * gv->DT;
+                    fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
+                    fipkp = mod_av.uipkp[j, i, k] * gv->DT;
                     g = mod->pi[j][i][k];
                     f = 2.0f * mod->u[j][i][k];
 
@@ -364,9 +364,9 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                         vzz = vzz / pml_coeff->K_z[h1] + pml_wfd->psi_vzz[j][i][h1];
                     }
 
-                    fipjp = mod_av->uipjp[j][i][k] * gv->DT;
-                    fjpkp = mod_av->ujpkp[j][i][k] * gv->DT;
-                    fipkp = mod_av->uipkp[j][i][k] * gv->DT;
+                    fipjp = mod_av.uipjp[j, i, k] * gv->DT;
+                    fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
+                    fipkp = mod_av.uipkp[j, i, k] * gv->DT;
                     g = mod->pi[j][i][k];
                     f = 2.0f * mod->u[j][i][k];
 
@@ -460,9 +460,9 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                         vzz = vzz / pml_coeff->K_z[h1] + pml_wfd->psi_vzz[j][i][h1];
                     }
 
-                    fipjp = mod_av->uipjp[j][i][k] * gv->DT;
-                    fjpkp = mod_av->ujpkp[j][i][k] * gv->DT;
-                    fipkp = mod_av->uipkp[j][i][k] * gv->DT;
+                    fipjp = mod_av.uipjp[j, i, k] * gv->DT;
+                    fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
+                    fipkp = mod_av.uipkp[j, i, k] * gv->DT;
                     g = mod->pi[j][i][k];
                     f = 2.0f * mod->u[j][i][k];
 
@@ -529,9 +529,9 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                     pml_wfd->psi_vzz[j][i][k] = pml_coeff->b_z[k] * pml_wfd->psi_vzz[j][i][k] + pml_coeff->a_z[k] * vzz;
                     vzz = vzz / pml_coeff->K_y[k] + pml_wfd->psi_vzz[j][i][k];
 
-                    fipjp = mod_av->uipjp[j][i][k] * gv->DT;
-                    fjpkp = mod_av->ujpkp[j][i][k] * gv->DT;
-                    fipkp = mod_av->uipkp[j][i][k] * gv->DT;
+                    fipjp = mod_av.uipjp[j, i, k] * gv->DT;
+                    fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
+                    fipkp = mod_av.uipkp[j, i, k] * gv->DT;
                     g = mod->pi[j][i][k];
                     f = 2.0f * mod->u[j][i][k];
 
@@ -599,9 +599,9 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                         pml_coeff->b_z[h1] * pml_wfd->psi_vzz[j][i][h1] + pml_coeff->a_z[h1] * vzz;
                     vzz = vzz / pml_coeff->K_z[h1] + pml_wfd->psi_vzz[j][i][h1];
 
-                    fipjp = mod_av->uipjp[j][i][k] * gv->DT;
-                    fjpkp = mod_av->ujpkp[j][i][k] * gv->DT;
-                    fipkp = mod_av->uipkp[j][i][k] * gv->DT;
+                    fipjp = mod_av.uipjp[j, i, k] * gv->DT;
+                    fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
+                    fipkp = mod_av.uipkp[j, i, k] * gv->DT;
                     g = mod->pi[j][i][k];
                     f = 2.0f * mod->u[j][i][k];
 
diff --git a/src/update_s_ssg_elastic.cpp b/src/update_s_ssg_elastic.cpp
index b5c2a97..50810df 100644
--- a/src/update_s_ssg_elastic.cpp
+++ b/src/update_s_ssg_elastic.cpp
@@ -29,7 +29,7 @@
 #define UNUSED(x) (void)(x)
 
 double update_s_elastic(st_boundary *nb, st_velocity &vel,
-                        st_stress &stress, st_model *mod, st_model_av *mod_av, const GlobVar *gv)
+                        st_stress &stress, st_model *mod, st_model_av &mod_av, const GlobVar *gv)
 {
     float vxx, vxy, vxz, vyx, vyy, vyz, vzx, vzy, vzz;
     float vxyyx, vyzzy, vxzzx, vxxyyzz, vyyzz, vxxzz, vxxyy;
@@ -51,15 +51,15 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
                     vxy = (vel.vx[j + 1, i, k] - vel.vx[j, i, k]) * oody;
                     vyx = (vel.vy[j, i + 1, k] - vel.vy[j, i, k]) * oodx;
-                    stress.sxy[j, i, k] += mod_av->uipjp[j][i][k] * gv->DT * (vxy + vyx);
+                    stress.sxy[j, i, k] += mod_av.uipjp[j, i, k] * gv->DT * (vxy + vyx);
 
                     vyz = (vel.vy[j, i, k + 1] - vel.vy[j, i, k]) * oodz;
                     vzy = (vel.vz[j + 1, i, k] - vel.vz[j, i, k]) * oody;
-                    stress.syz[j, i, k] += mod_av->ujpkp[j][i][k] * gv->DT * (vyz + vzy);
+                    stress.syz[j, i, k] += mod_av.ujpkp[j, i, k] * gv->DT * (vyz + vzy);
 
                     vxz = (vel.vx[j, i, k + 1] - vel.vx[j, i, k]) * oodz;
                     vzx = (vel.vz[j, i + 1, k] - vel.vz[j, i, k]) * oodx;
-                    stress.sxz[j, i, k] += mod_av->uipkp[j][i][k] * gv->DT * (vxz + vzx);
+                    stress.sxz[j, i, k] += mod_av.uipkp[j, i, k] * gv->DT * (vxz + vzx);
 
                     vxx = (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) * oodx;
                     vyy = (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) * oody;
@@ -108,7 +108,7 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                     vyx =
                         (b1 * (vel.vy[j, i + 1, k] - vel.vy[j, i, k]) +
                          b2 * (vel.vy[j, i + 2, k] - vel.vy[j, i - 1, k])) * oodx;
-                    stress.sxy[j, i, k] += mod_av->uipjp[j][i][k] * gv->DT * (vxy + vyx);
+                    stress.sxy[j, i, k] += mod_av.uipjp[j, i, k] * gv->DT * (vxy + vyx);
 
                     vyz =
                         (b1 * (vel.vy[j, i, k + 1] - vel.vy[j, i, k]) +
@@ -116,7 +116,7 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                     vzy =
                         (b1 * (vel.vz[j + 1, i, k] - vel.vz[j, i, k]) +
                          b2 * (vel.vz[j + 2, i, k] - vel.vz[j - 1, i, k])) * oody;
-                    stress.syz[j, i, k] += mod_av->ujpkp[j][i][k] * gv->DT * (vyz + vzy);
+                    stress.syz[j, i, k] += mod_av.ujpkp[j, i, k] * gv->DT * (vyz + vzy);
 
                     vxz =
                         (b1 * (vel.vx[j, i, k + 1] - vel.vx[j, i, k]) +
@@ -124,7 +124,7 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                     vzx =
                         (b1 * (vel.vz[j, i + 1, k] - vel.vz[j, i, k]) +
                          b2 * (vel.vz[j, i + 2, k] - vel.vz[j, i - 1, k])) * oodx;
-                    stress.sxz[j, i, k] += mod_av->uipkp[j][i][k] * gv->DT * (vxz + vzx);
+                    stress.sxz[j, i, k] += mod_av.uipkp[j, i, k] * gv->DT * (vxz + vzx);
 
                     vxx =
                         (b1 * (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) +
@@ -204,9 +204,9 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                            b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2]) +
                            b3 * (vel.vz[j, i, k + 2] - vel.vz[j, i, k - 3])) * oodz;
 
-                    fipjp = mod_av->uipjp[j][i][k] * gv->DT;
-                    fjpkp = mod_av->ujpkp[j][i][k] * gv->DT;
-                    fipkp = mod_av->uipkp[j][i][k] * gv->DT;
+                    fipjp = mod_av.uipjp[j, i, k] * gv->DT;
+                    fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
+                    fipkp = mod_av.uipkp[j, i, k] * gv->DT;
                     g = mod->pi[j][i][k];
                     f = 2.0f * mod->u[j][i][k];
 
@@ -295,9 +295,9 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                            b4 * (vel.vz[j, i, k + 3] - vel.vz[j, i, k - 4])) * oodz;
 
                     /* updating components of the stress tensor, partially */
-                    fipjp = mod_av->uipjp[j][i][k] * gv->DT;
-                    fjpkp = mod_av->ujpkp[j][i][k] * gv->DT;
-                    fipkp = mod_av->uipkp[j][i][k] * gv->DT;
+                    fipjp = mod_av.uipjp[j, i, k] * gv->DT;
+                    fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
+                    fipkp = mod_av.uipkp[j, i, k] * gv->DT;
                     g = mod->pi[j][i][k];
                     f = 2.0f * mod->u[j][i][k];
 
@@ -396,9 +396,9 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                            b4 * (vel.vz[j, i, k + 3] - vel.vz[j, i, k - 4]) +
                            b5 * (vel.vz[j, i, k + 4] - vel.vz[j, i, k - 5])) * oodz;
 
-                    fipjp = mod_av->uipjp[j][i][k] * gv->DT;
-                    fjpkp = mod_av->ujpkp[j][i][k] * gv->DT;
-                    fipkp = mod_av->uipkp[j][i][k] * gv->DT;
+                    fipjp = mod_av.uipjp[j, i, k] * gv->DT;
+                    fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
+                    fipkp = mod_av.uipkp[j, i, k] * gv->DT;
                     g = mod->pi[j][i][k];
                     f = 2.0f * mod->u[j][i][k];
 
@@ -511,9 +511,9 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                            b5 * (vel.vz[j, i, k + 4] - vel.vz[j, i, k - 5]) +
                            b6 * (vel.vz[j, i, k + 5] - vel.vz[j, i, k - 6])) * oodz;
 
-                    fipjp = mod_av->uipjp[j][i][k] * gv->DT;
-                    fjpkp = mod_av->ujpkp[j][i][k] * gv->DT;
-                    fipkp = mod_av->uipkp[j][i][k] * gv->DT;
+                    fipjp = mod_av.uipjp[j, i, k] * gv->DT;
+                    fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
+                    fipkp = mod_av.uipkp[j, i, k] * gv->DT;
                     g = mod->pi[j][i][k];
                     f = 2.0f * mod->u[j][i][k];
 
diff --git a/src/update_v_ssg.cpp b/src/update_v_ssg.cpp
index 4580227..26ef017 100644
--- a/src/update_v_ssg.cpp
+++ b/src/update_v_ssg.cpp
@@ -25,7 +25,7 @@
 #include "fd.hpp"
 #include "loop_blocking.hpp"
 
-void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av *mod_av,
+void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av &mod_av,
               float ***absorb_coeff, const GlobVar *gv)
 {
     float b1, b2, b3, b4, b5, b6;
@@ -45,7 +45,7 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_mod
                     sxx_x = dx * (stress.sxx[j, i + 1, k] - stress.sxx[j, i, k]);
                     sxy_y = dy * (stress.sxy[j, i, k] - stress.sxy[j - 1, i, k]);
                     sxz_z = dz * (stress.sxz[j, i, k] - stress.sxz[j, i, k - 1]);
-                    vel.vx[j, i, k] += ((sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k]);
+                    vel.vx[j, i, k] += ((sxx_x + sxy_y + sxz_z) / mod_av.rip[j, i, k]);
                 }
             }
         }
@@ -56,7 +56,7 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_mod
                     syy_y = dy * (stress.syy[j + 1, i, k] - stress.syy[j, i, k]);
                     sxy_x = dx * (stress.sxy[j, i, k] - stress.sxy[j, i - 1, k]);
                     syz_z = dz * (stress.syz[j, i, k] - stress.syz[j, i, k - 1]);
-                    vel.vy[j, i, k] += ((syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k]);
+                    vel.vy[j, i, k] += ((syy_y + sxy_x + syz_z) / mod_av.rjp[j, i, k]);
                 }
             }
         }
@@ -67,7 +67,7 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_mod
                     szz_z = dz * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]);
                     sxz_x = dx * (stress.sxz[j, i, k] - stress.sxz[j, i - 1, k]);
                     syz_y = dy * (stress.syz[j, i, k] - stress.syz[j - 1, i, k]);
-                    vel.vz[j, i, k] += ((szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k]);
+                    vel.vz[j, i, k] += ((szz_z + sxz_x + syz_y) / mod_av.rkp[j, i, k]);
                 }
             }
         }
@@ -107,7 +107,7 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_mod
                     sxz_z =
                         dz * (b1 * (stress.sxz[j, i, k] - stress.sxz[j, i, k - 1]) +
                               b2 * (stress.sxz[j, i, k + 1] - stress.sxz[j, i, k - 2]));
-                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av.rip[j, i, k];
 
                     syy_y =
                         dy * (b1 * (stress.syy[j + 1, i, k] - stress.syy[j, i, k]) +
@@ -118,7 +118,7 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_mod
                     syz_z =
                         dz * (b1 * (stress.syz[j, i, k] - stress.syz[j, i, k - 1]) +
                               b2 * (stress.syz[j, i, k + 1] - stress.syz[j, i, k - 2]));
-                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av.rjp[j, i, k];
 
                     szz_z =
                         dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
@@ -129,7 +129,7 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_mod
                     syz_y =
                         dy * (b1 * (stress.syz[j, i, k] - stress.syz[j - 1, i, k]) +
                               b2 * (stress.syz[j + 1, i, k] - stress.syz[j - 2, i, k]));
-                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av.rkp[j, i, k];
                 }
             }
         }
@@ -159,7 +159,7 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_mod
                                   b2 * (stress.sxz[j, i, k + 1] - stress.sxz[j, i, k - 2]) +
                                   b3 * (stress.sxz[j, i, k + 2] - stress.sxz[j, i, k - 3]));
                     /* updating components of particle velocities */
-                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av.rip[j, i, k];
                     syy_y = dy * (b1 * (stress.syy[j + 1, i, k] - stress.syy[j, i, k]) +
                                   b2 * (stress.syy[j + 2, i, k] - stress.syy[j - 1, i, k]) +
                                   b3 * (stress.syy[j + 3, i, k] - stress.syy[j - 2, i, k]));
@@ -169,7 +169,7 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_mod
                     syz_z = dz * (b1 * (stress.syz[j, i, k] - stress.syz[j, i, k - 1]) +
                                   b2 * (stress.syz[j, i, k + 1] - stress.syz[j, i, k - 2]) +
                                   b3 * (stress.syz[j, i, k + 2] - stress.syz[j, i, k - 3]));
-                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av.rjp[j, i, k];
                     szz_z = dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
                                   b2 * (stress.szz[j, i, k + 2] - stress.szz[j, i, k - 1]) +
                                   b3 * (stress.szz[j, i, k + 3] - stress.szz[j, i, k - 2]));
@@ -179,7 +179,7 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_mod
                     syz_y = dy * (b1 * (stress.syz[j, i, k] - stress.syz[j - 1, i, k]) +
                                   b2 * (stress.syz[j + 1, i, k] - stress.syz[j - 2, i, k]) +
                                   b3 * (stress.syz[j + 2, i, k] - stress.syz[j - 3, i, k]));
-                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av.rkp[j, i, k];
                 }
             }
         }
@@ -212,7 +212,7 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_mod
                                   b3 * (stress.sxz[j, i, k + 2] - stress.sxz[j, i, k - 3]) +
                                   b4 * (stress.sxz[j, i, k + 3] - stress.sxz[j, i, k - 4]));
                     /* updating components of particle velocities */
-                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av.rip[j, i, k];
                     syy_y = dy * (b1 * (stress.syy[j + 1, i, k] - stress.syy[j, i, k]) +
                                   b2 * (stress.syy[j + 2, i, k] - stress.syy[j - 1, i, k]) +
                                   b3 * (stress.syy[j + 3, i, k] - stress.syy[j - 2, i, k]) +
@@ -225,7 +225,7 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_mod
                                   b2 * (stress.syz[j, i, k + 1] - stress.syz[j, i, k - 2]) +
                                   b3 * (stress.syz[j, i, k + 2] - stress.syz[j, i, k - 3]) +
                                   b4 * (stress.syz[j, i, k + 3] - stress.syz[j, i, k - 4]));
-                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av.rjp[j, i, k];
                     szz_z = dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
                                   b2 * (stress.szz[j, i, k + 2] - stress.szz[j, i, k - 1]) +
                                   b3 * (stress.szz[j, i, k + 3] - stress.szz[j, i, k - 2]) +
@@ -238,7 +238,7 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_mod
                                   b2 * (stress.syz[j + 1, i, k] - stress.syz[j - 2, i, k]) +
                                   b3 * (stress.syz[j + 2, i, k] - stress.syz[j - 3, i, k]) +
                                   b4 * (stress.syz[j + 3, i, k] - stress.syz[j - 4, i, k]));
-                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av.rkp[j, i, k];
                 }
             }
         }
@@ -276,7 +276,7 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_mod
                                   b4 * (stress.sxz[j, i, k + 3] - stress.sxz[j, i, k - 4]) +
                                   b5 * (stress.sxz[j, i, k + 4] - stress.sxz[j, i, k - 5]));
                     /* updating components of particle velocities */
-                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av.rip[j, i, k];
                     syy_y = dy * (b1 * (stress.syy[j + 1, i, k] - stress.syy[j, i, k]) +
                                   b2 * (stress.syy[j + 2, i, k] - stress.syy[j - 1, i, k]) +
                                   b3 * (stress.syy[j + 3, i, k] - stress.syy[j - 2, i, k]) +
@@ -292,7 +292,7 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_mod
                                   b3 * (stress.syz[j, i, k + 2] - stress.syz[j, i, k - 3]) +
                                   b4 * (stress.syz[j, i, k + 3] - stress.syz[j, i, k - 4]) +
                                   b5 * (stress.syz[j, i, k + 4] - stress.syz[j, i, k - 5]));
-                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av.rjp[j, i, k];
                     szz_z = dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
                                   b2 * (stress.szz[j, i, k + 2] - stress.szz[j, i, k - 1]) +
                                   b3 * (stress.szz[j, i, k + 3] - stress.szz[j, i, k - 2]) +
@@ -308,7 +308,7 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_mod
                                   b3 * (stress.syz[j + 2, i, k] - stress.syz[j - 3, i, k]) +
                                   b4 * (stress.syz[j + 3, i, k] - stress.syz[j - 4, i, k]) +
                                   b5 * (stress.syz[j + 4, i, k] - stress.syz[j - 5, i, k]));
-                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av.rkp[j, i, k];
                 }
             }
         }
@@ -353,7 +353,7 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_mod
                                   b5 * (stress.sxy[j, i, k + 4] - stress.sxy[j, i, k - 5]) +
                                   b6 * (stress.sxy[j, i, k + 5] - stress.sxy[j, i, k - 6]));
                     /* updating components of particle velocities */
-                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av.rip[j, i, k];
                     syy_y = dy * (b1 * (stress.syy[j + 1, i, k] - stress.syy[j, i, k]) +
                                   b2 * (stress.syy[j + 2, i, k] - stress.syy[j - 1, i, k]) +
                                   b3 * (stress.syy[j + 3, i, k] - stress.syy[j - 2, i, k]) +
@@ -372,7 +372,7 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_mod
                                   b4 * (stress.syz[j, i, k + 3] - stress.syz[j, i, k - 4]) +
                                   b5 * (stress.syz[j, i, k + 4] - stress.syz[j, i, k - 5]) +
                                   b6 * (stress.syz[j, i, k + 5] - stress.syz[j, i, k - 6]));
-                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av.rjp[j, i, k];
                     szz_z = dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
                                   b2 * (stress.szz[j, i, k + 2] - stress.szz[j, i, k - 1]) +
                                   b3 * (stress.szz[j, i, k + 3] - stress.szz[j, i, k - 2]) +
@@ -391,7 +391,7 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_mod
                                   b4 * (stress.syz[j + 3, i, k] - stress.syz[j - 4, i, k]) +
                                   b5 * (stress.syz[j + 4, i, k] - stress.syz[j - 5, i, k]) +
                                   b6 * (stress.syz[j + 5, i, k] - stress.syz[j - 6, i, k]));
-                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av.rkp[j, i, k];
                 }
             }
         }
diff --git a/src/update_v_ssg_CPML.cpp b/src/update_v_ssg_CPML.cpp
index 2339388..b8ba59b 100644
--- a/src/update_v_ssg_CPML.cpp
+++ b/src/update_v_ssg_CPML.cpp
@@ -30,7 +30,7 @@
 
 #define UNUSED(x) (void)(x)
 
-void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av *mod_av,
+void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av &mod_av,
                    st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, const GlobVar *gv)
 {
     float sxx_x = 0.0, sxy_y = 0.0, sxz_z = 0.0, syy_y = 0.0, sxy_x = 0.0, syz_z = 0.0;
@@ -143,9 +143,9 @@ void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress &stress, st_mode
                         szz_z = szz_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_szz_z[j][i][h1];
                     }
 
-                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
-                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
-                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av.rip[j, i, k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av.rjp[j, i, k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av.rkp[j, i, k];
                 }
             }
         }
@@ -244,9 +244,9 @@ void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress &stress, st_mode
                         szz_z = szz_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_szz_z[j][i][h1];
                     }
 
-                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
-                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
-                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av.rip[j, i, k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av.rjp[j, i, k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av.rkp[j, i, k];
                 }
             }
         }
@@ -319,9 +319,9 @@ void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress &stress, st_mode
                         szz_z = szz_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_szz_z[j][i][h1];
                     }
 
-                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
-                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
-                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av.rip[j, i, k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av.rjp[j, i, k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av.rkp[j, i, k];
                 }
             }
         }
@@ -395,9 +395,9 @@ void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress &stress, st_mode
                         szz_z = szz_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_szz_z[j][i][h1];
                     }
 
-                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
-                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
-                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av.rip[j, i, k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av.rjp[j, i, k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av.rkp[j, i, k];
                 }
             }
         }
@@ -447,9 +447,9 @@ void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress &stress, st_mode
                         pml_coeff->b_z_half[k] * pml_wfd->psi_szz_z[j][i][k] + pml_coeff->a_z_half[k] * szz_z;
                     szz_z = szz_z / pml_coeff->K_z_half[k] + pml_wfd->psi_szz_z[j][i][k];
 
-                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
-                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
-                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av.rip[j, i, k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av.rjp[j, i, k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av.rkp[j, i, k];
                 }
             }
         }
@@ -498,9 +498,9 @@ void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress &stress, st_mode
                         pml_coeff->b_z_half[h1] * pml_wfd->psi_szz_z[j][i][h1] + pml_coeff->a_z_half[h1] * szz_z;
                     szz_z = szz_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_szz_z[j][i][h1];
 
-                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av->rip[j][i][k];
-                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av->rjp[j][i][k];
-                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av.rip[j, i, k];
+                    vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av.rjp[j, i, k];
+                    vel.vz[j, i, k] += (szz_z + sxz_x + syz_y) / mod_av.rkp[j, i, k];
                 }
             }
         }
diff --git a/src/update_v_ssg_CPML_acoustic.cpp b/src/update_v_ssg_CPML_acoustic.cpp
index b364cb6..c4100e6 100644
--- a/src/update_v_ssg_CPML_acoustic.cpp
+++ b/src/update_v_ssg_CPML_acoustic.cpp
@@ -30,7 +30,7 @@
 
 #define UNUSED(x) (void)(x)
 
-void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av *mod_av,
+void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av &mod_av,
                             st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, const GlobVar *gv)
 {
     float sp_x = 0.0, sp_y = 0.0, sp_z = 0.0;
@@ -94,9 +94,9 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress
                         sp_z = sp_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_sp_z[j][i][h1];
                     }
 
-                    vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
-                    vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
-                    vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sp_x) / mod_av.rip[j, i, k];
+                    vel.vy[j, i, k] += (sp_y) / mod_av.rjp[j, i, k];
+                    vel.vz[j, i, k] += (sp_z) / mod_av.rkp[j, i, k];
                 }
             }
         }
@@ -147,9 +147,9 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress
                         sp_z = sp_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_sp_z[j][i][h1];
                     }
 
-                    vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
-                    vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
-                    vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sp_x) / mod_av.rip[j, i, k];
+                    vel.vy[j, i, k] += (sp_y) / mod_av.rjp[j, i, k];
+                    vel.vz[j, i, k] += (sp_z) / mod_av.rkp[j, i, k];
                 }
             }
         }
@@ -186,9 +186,9 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress
                         sp_z = sp_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_sp_z[j][i][h1];
                     }
 
-                    vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
-                    vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
-                    vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sp_x) / mod_av.rip[j, i, k];
+                    vel.vy[j, i, k] += (sp_y) / mod_av.rjp[j, i, k];
+                    vel.vz[j, i, k] += (sp_z) / mod_av.rkp[j, i, k];
                 }
             }
         }
@@ -226,9 +226,9 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress
                         sp_z = sp_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_sp_z[j][i][h1];
                     }
 
-                    vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
-                    vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
-                    vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sp_x) / mod_av.rip[j, i, k];
+                    vel.vy[j, i, k] += (sp_y) / mod_av.rjp[j, i, k];
+                    vel.vz[j, i, k] += (sp_z) / mod_av.rkp[j, i, k];
                 }
             }
         }
@@ -254,9 +254,9 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress
                         pml_coeff->b_z_half[k] * pml_wfd->psi_sp_z[j][i][k] + pml_coeff->a_z_half[k] * sp_z;
                     sp_z = sp_z / pml_coeff->K_z_half[k] + pml_wfd->psi_sp_z[j][i][k];
 
-                    vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
-                    vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
-                    vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sp_x) / mod_av.rip[j, i, k];
+                    vel.vy[j, i, k] += (sp_y) / mod_av.rjp[j, i, k];
+                    vel.vz[j, i, k] += (sp_z) / mod_av.rkp[j, i, k];
                 }
             }
         }
@@ -281,9 +281,9 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress
                         pml_coeff->b_z_half[h1] * pml_wfd->psi_sp_z[j][i][h1] + pml_coeff->a_z_half[h1] * sp_z;
                     sp_z = sp_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_sp_z[j][i][h1];
 
-                    vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
-                    vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
-                    vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += (sp_x) / mod_av.rip[j, i, k];
+                    vel.vy[j, i, k] += (sp_y) / mod_av.rjp[j, i, k];
+                    vel.vz[j, i, k] += (sp_z) / mod_av.rkp[j, i, k];
                 }
             }
         }
diff --git a/src/update_v_ssg_acoustic.cpp b/src/update_v_ssg_acoustic.cpp
index 78d8178..39ccb51 100644
--- a/src/update_v_ssg_acoustic.cpp
+++ b/src/update_v_ssg_acoustic.cpp
@@ -25,7 +25,7 @@
 #include "fd.hpp"
 
 void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress &stress,
-                       st_model_av *mod_av, float ***absorb_coeff, const GlobVar *gv)
+                       st_model_av &mod_av, float ***absorb_coeff, const GlobVar *gv)
 {
     float b1, b2, b3, b4, b5, b6;
     float sp_x, sp_y, sp_z;
@@ -40,11 +40,11 @@ void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress &stres
                 #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
                     float sp_x = dx * (stress.sp[j, i + 1, k] - stress.sp[j, i, k]);
-                    vel.vx[j, i, k] += sp_x / mod_av->rip[j][i][k];
+                    vel.vx[j, i, k] += sp_x / mod_av.rip[j, i, k];
                     float sp_y = dy * (stress.sp[j + 1, i, k] - stress.sp[j, i, k]);
-                    vel.vy[j, i, k] += sp_y / mod_av->rjp[j][i][k];
+                    vel.vy[j, i, k] += sp_y / mod_av.rjp[j, i, k];
                     float sp_z = dz * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]);
-                    vel.vz[j, i, k] += sp_z / mod_av->rkp[j][i][k];
+                    vel.vz[j, i, k] += sp_z / mod_av.rkp[j, i, k];
                 }
             }
         }
@@ -69,9 +69,9 @@ void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress &stres
                     float sp_z =
                         dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
                               b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]));
-                    vel.vx[j, i, k] += sp_x / mod_av->rip[j][i][k];
-                    vel.vy[j, i, k] += sp_y / mod_av->rjp[j][i][k];
-                    vel.vz[j, i, k] += sp_z / mod_av->rkp[j][i][k];
+                    vel.vx[j, i, k] += sp_x / mod_av.rip[j, i, k];
+                    vel.vy[j, i, k] += sp_y / mod_av.rjp[j, i, k];
+                    vel.vz[j, i, k] += sp_z / mod_av.rkp[j, i, k];
                 }
             }
         }
@@ -93,15 +93,15 @@ void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress &stres
                                  b2 * (stress.sp[j, i + 2, k] - stress.sp[j, i - 1, k]) +
                                  b3 * (stress.sp[j, i + 3, k] - stress.sp[j, i - 2, k]));
                     /* updating components of particle velocities */
-                    vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
+                    vel.vx[j, i, k] += (sp_x) / mod_av.rip[j, i, k];
                     sp_y = dy * (b1 * (stress.sp[j + 1, i, k] - stress.sp[j, i, k]) +
                                  b2 * (stress.sp[j + 2, i, k] - stress.sp[j - 1, i, k]) +
                                  b3 * (stress.sp[j + 3, i, k] - stress.sp[j - 2, i, k]));
-                    vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
+                    vel.vy[j, i, k] += (sp_y) / mod_av.rjp[j, i, k];
                     sp_z = dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
                                  b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]) +
                                  b3 * (stress.sp[j, i, k + 3] - stress.sp[j, i, k - 2]));
-                    vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
+                    vel.vz[j, i, k] += (sp_z) / mod_av.rkp[j, i, k];
                 }
             }
         }
@@ -126,17 +126,17 @@ void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress &stres
                                  b3 * (stress.sp[j, i + 3, k] - stress.sp[j, i - 2, k]) +
                                  b4 * (stress.sp[j, i + 4, k] - stress.sp[j, i - 3, k]));
                     /* updating components of particle velocities */
-                    vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
+                    vel.vx[j, i, k] += (sp_x) / mod_av.rip[j, i, k];
                     sp_y = dy * (b1 * (stress.sp[j + 1, i, k] - stress.sp[j, i, k]) +
                                  b2 * (stress.sp[j + 2, i, k] - stress.sp[j - 1, i, k]) +
                                  b3 * (stress.sp[j + 3, i, k] - stress.sp[j - 2, i, k]) +
                                  b4 * (stress.sp[j + 4, i, k] - stress.sp[j - 3, i, k]));
-                    vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
+                    vel.vy[j, i, k] += (sp_y) / mod_av.rjp[j, i, k];
                     sp_z = dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
                                  b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]) +
                                  b3 * (stress.sp[j, i, k + 3] - stress.sp[j, i, k - 2]) +
                                  b4 * (stress.sp[j, i, k + 4] - stress.sp[j, i, k - 3]));
-                    vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
+                    vel.vz[j, i, k] += (sp_z) / mod_av.rkp[j, i, k];
                 }
             }
         }
@@ -164,19 +164,19 @@ void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress &stres
                                  b4 * (stress.sp[j, i + 4, k] - stress.sp[j, i - 3, k]) +
                                  b5 * (stress.sp[j, i + 5, k] - stress.sp[j, i - 4, k]));
                     /* updating components of particle velocities */
-                    vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
+                    vel.vx[j, i, k] += (sp_x) / mod_av.rip[j, i, k];
                     sp_y = dy * (b1 * (stress.sp[j + 1, i, k] - stress.sp[j, i, k]) +
                                  b2 * (stress.sp[j + 2, i, k] - stress.sp[j - 1, i, k]) +
                                  b3 * (stress.sp[j + 3, i, k] - stress.sp[j - 2, i, k]) +
                                  b4 * (stress.sp[j + 4, i, k] - stress.sp[j - 3, i, k]) +
                                  b5 * (stress.sp[j + 5, i, k] - stress.sp[j - 4, i, k]));
-                    vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
+                    vel.vy[j, i, k] += (sp_y) / mod_av.rjp[j, i, k];
                     sp_z = dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
                                  b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]) +
                                  b3 * (stress.sp[j, i, k + 3] - stress.sp[j, i, k - 2]) +
                                  b4 * (stress.sp[j, i, k + 4] - stress.sp[j, i, k - 3]) +
                                  b5 * (stress.sp[j, i, k + 5] - stress.sp[j, i, k - 4]));
-                    vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
+                    vel.vz[j, i, k] += (sp_z) / mod_av.rkp[j, i, k];
                 }
             }
         }
@@ -209,21 +209,21 @@ void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress &stres
                                  b5 * (stress.sp[j, i + 5, k] - stress.sp[j, i - 4, k]) +
                                  b6 * (stress.sp[j, i + 6, k] - stress.sp[j, i - 5, k]));
                     /* updating components of particle velocities */
-                    vel.vx[j, i, k] += (sp_x) / mod_av->rip[j][i][k];
+                    vel.vx[j, i, k] += (sp_x) / mod_av.rip[j, i, k];
                     sp_y = dy * (b1 * (stress.sp[j + 1, i, k] - stress.sp[j, i, k]) +
                                  b2 * (stress.sp[j + 2, i, k] - stress.sp[j - 1, i, k]) +
                                  b3 * (stress.sp[j + 3, i, k] - stress.sp[j - 2, i, k]) +
                                  b4 * (stress.sp[j + 4, i, k] - stress.sp[j - 3, i, k]) +
                                  b5 * (stress.sp[j + 5, i, k] - stress.sp[j - 4, i, k]) +
                                  b6 * (stress.sp[j + 6, i, k] - stress.sp[j - 5, i, k]));
-                    vel.vy[j, i, k] += (sp_y) / mod_av->rjp[j][i][k];
+                    vel.vy[j, i, k] += (sp_y) / mod_av.rjp[j, i, k];
                     sp_z = dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
                                  b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]) +
                                  b3 * (stress.sp[j, i, k + 3] - stress.sp[j, i, k - 2]) +
                                  b4 * (stress.sp[j, i, k + 4] - stress.sp[j, i, k - 3]) +
                                  b5 * (stress.sp[j, i, k + 5] - stress.sp[j, i, k - 4]) +
                                  b6 * (stress.sp[j, i, k + 6] - stress.sp[j, i, k - 5]));
-                    vel.vz[j, i, k] += (sp_z) / mod_av->rkp[j][i][k];
+                    vel.vz[j, i, k] += (sp_z) / mod_av.rkp[j, i, k];
                 }
             }
         }
-- 
GitLab


From 3912412046baad5b2713ee624ddaffb9b6b5ed74 Mon Sep 17 00:00:00 2001
From: Holger Obermaier <holgerob@gmx.de>
Date: Mon, 7 Apr 2025 16:02:41 +0200
Subject: [PATCH 08/15] Use float3DTensorT in type st_pml_wfd

---
 src/fd.hpp                         |  36 ++--
 src/freemem.cpp                    |  44 ++--
 src/ifos3d.cpp                     |  24 +--
 src/initmem.cpp                    |  44 ++--
 src/stfi.cpp                       |   2 +-
 src/surface_ssg.cpp                |  50 ++---
 src/surface_ssg_elastic.cpp        |  50 ++---
 src/timeloop.cpp                   |   2 +-
 src/update_s_ssg_CPML_acoustic.cpp | 104 ++++-----
 src/update_s_ssg_CPML_elastic.cpp  | 320 ++++++++++++++--------------
 src/update_v_ssg_CPML.cpp          | 326 ++++++++++++++---------------
 src/update_v_ssg_CPML_acoustic.cpp | 110 +++++-----
 src/zero_wavefield.cpp             |  38 ++--
 src/zero_wavefield_acoustic.cpp    |  14 +-
 14 files changed, 582 insertions(+), 582 deletions(-)

diff --git a/src/fd.hpp b/src/fd.hpp
index f227dab..6b2b6ca 100644
--- a/src/fd.hpp
+++ b/src/fd.hpp
@@ -84,13 +84,13 @@ typedef struct PML_Coefficients {
     float *alpha_prime_x, *alpha_prime_x_half, *alpha_prime_y, *alpha_prime_y_half, *alpha_prime_z, *alpha_prime_z_half;
 } st_pml_coeff;
 
-typedef struct PML_Wavefield {
-    float ***psi_sp_x, ***psi_sp_y, ***psi_sp_z;
+typedef struct {
+    float3DTensorT psi_sp_x, psi_sp_y, psi_sp_z;
     //Pml Damping Wavefields for pml damping boundaries
-    float ***psi_sxx_x, ***psi_syy_y, ***psi_szz_z;
-    float ***psi_sxy_y, ***psi_sxy_x, ***psi_sxz_x, ***psi_sxz_z, ***psi_syz_y, ***psi_syz_z;
-    float ***psi_vxx, ***psi_vyy, ***psi_vzz;
-    float ***psi_vxy, ***psi_vxz, ***psi_vyx, ***psi_vyz, ***psi_vzx, ***psi_vzy;
+    float3DTensorT psi_sxx_x, psi_syy_y, psi_szz_z;
+    float3DTensorT psi_sxy_y, psi_sxy_x, psi_sxz_x, psi_sxz_z, psi_syz_y, psi_syz_z;
+    float3DTensorT psi_vxx, psi_vyy, psi_vzz;
+    float3DTensorT psi_vxy, psi_vxz, psi_vyx, psi_vyz, psi_vzx, psi_vzy;
 } st_pml_wfd;
 
 typedef struct Visco_memory {
@@ -184,7 +184,7 @@ void comm_ini_s(st_buffer *buffer, MPI_Request *req_send, MPI_Request *req_rec);
 
 void freemem(int nsrc_loc, st_acquisition *acq, st_model *mod,
              st_model *testmod, st_model_av &mod_av, st_visc_mem *visco_mem, st_pml_coeff *pml_coeff,
-             st_pml_wfd *pml_wfd, st_signals *signals,
+             st_pml_wfd &pml_wfd, st_signals *signals,
              st_gradient *grad, st_gradient *grad_prior1, st_gradient *grad_prior2, st_gradient *grad_halo,
              st_hessian *hessian,
              st_stress &stress, st_buffer_flat *stressbuff, st_freq_velocity *fourier_vel_back,
@@ -196,7 +196,7 @@ void freemem_seis(int ntr_loc, st_seismogram *section, st_seismogram *section_ob
 void globvar_change(GlobVar *gv);
 
 int initmem(st_model *mod, st_model *testmod, st_model_av &mod_av, st_visc_mem *visco_mem,
-            st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, st_gradient *grad, st_gradient *grad_prior1,
+            st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd, st_gradient *grad, st_gradient *grad_prior1,
             st_gradient *grad_prior2, st_gradient *grad_halo, st_hessian *hessian, st_stress &stress,
             st_buffer_flat *stressbuff,
             st_freq_velocity *fourier_vel_back, st_freq_velocity *fourier_vel_fw, st_velocity &vel,
@@ -290,7 +290,7 @@ void sources(FILE *fpsrc, int *nsrc, float **srcpos, GlobVar *gv, int **topo);
 void stfi(st_acquisition *acq, st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress &stress,
           st_model *mod, st_model_av &mod_av, st_visc_mem *visco_mem, st_seismogram *section,
           st_seismogram *section_obs, st_signals *signals, int nsrc_loc, int ntr_loc, st_pml_coeff *pml_coeff,
-          st_pml_wfd *pml_wfd, st_buffer_flat *stressbuff, st_buffer_flat *velbuff, st_freq_velocity *fourier_vel,
+          st_pml_wfd &pml_wfd, st_buffer_flat *stressbuff, st_buffer_flat *velbuff, st_freq_velocity *fourier_vel,
           const float *finv, double *L2, int nf, int ntast, int lsnap, int nsnap, int ishot, int shot_id, int cdf,
           int iteration, int groupnum, int it_group, int ncplx, GlobVar *gv);
 
@@ -309,7 +309,7 @@ void splitrec(int *ntr_loc, st_acquisition *acq, const GlobVar *gv);
 
 float **splitsrc(float **srcpos, int *nsrc_loc, int nsrc, int *srcswitch, GlobVar *gv);
 
-void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, st_visc_mem *mem,
+void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd, st_visc_mem *mem,
              st_stress &stress, st_velocity &vel);
 
 void update_s_rsg(st_boundary *nb, st_velocity &vel, st_stress &stress,
@@ -319,7 +319,7 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_mod
               float ***absorb_coeff, const GlobVar *gv);
 
 void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av &mod_av,
-                   st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, const GlobVar *gv);
+                   st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd, const GlobVar *gv);
 
 void update_v_rsg(st_boundary *nb, int nt, st_velocity &vel, st_stress &stress,
                   float ***rho, float **srcpos_loc, float **signals, int nsrc, float ***absorb_coeff);
@@ -366,7 +366,7 @@ void readseis(int shot_id, float **section, const st_acquisition *acq, int ntr,
 void residual(float **sectiondata, float **section, float **sectiondiff, int ntr, int ns,
               double *L2, const float *finv, int nf, const GlobVar *gv);
 
-void zero_wavefield(st_velocity &vel, st_stress &stress, st_visc_mem *mem, st_pml_wfd *pml_wfd, const GlobVar *gv);
+void zero_wavefield(st_velocity &vel, st_stress &stress, st_visc_mem *mem, st_pml_wfd &pml_wfd, const GlobVar *gv);
 
 void gradient_F(int nx, int ny, int nz, st_freq_velocity *fw, st_freq_velocity *back, st_gradient *grad,
                 st_hessian *hessian,
@@ -404,9 +404,9 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel, st_stress &stress,
 
 double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                              st_stress &stress, st_model *mod, st_model_av &mod_av, st_pml_coeff *pml_coeff,
-                             st_pml_wfd *pml_wfd, const GlobVar *gv);
+                             st_pml_wfd &pml_wfd, const GlobVar *gv);
 
-void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, st_stress &stress,
+void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd, st_stress &stress,
                      st_velocity &vel, const GlobVar *gv);
 
 void readinv(float *finv, int *nf, int *groupnum, int *itpergroup, int nfmax, GlobVar *gv);
@@ -451,21 +451,21 @@ double update_s_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress, s
 
 double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
                               st_stress &stress, st_model *mod, st_pml_coeff *pml_coeff,
-                              st_pml_wfd *pml_wfd, const GlobVar *gv);
+                              st_pml_wfd &pml_wfd, const GlobVar *gv);
 
 void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress &stress,
                        st_model_av &mod_av, float ***absorb_coeff, const GlobVar *gv);
 
 void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av &mod_av,
-                            st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, const GlobVar *gv);
+                            st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd, const GlobVar *gv);
 
-void zero_wavefield_acoustic(st_velocity &vel, st_stress &stress, st_visc_mem *mem, st_pml_wfd *pml_wfd,
+void zero_wavefield_acoustic(st_velocity &vel, st_stress &stress, st_visc_mem *mem, st_pml_wfd &pml_wfd,
                              const GlobVar *gv);
 
 void timeloop(st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress &stress,
               st_model *mod, st_model_av &mod_av, st_seismogram *section,
               float **srcpos_loc, int **recpos_loc, st_signals *signals, int nsrc_loc,
-              float ***absorb_coeff, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd,
+              float ***absorb_coeff, st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd,
               st_buffer_flat *stressbuff, st_buffer_flat *velbuff, st_freq_velocity *fourier_vel,
               const float *finv, int nf, int ntast, int ntr, int lsnap, int nsnap, int pshot, int shot_id, int proptype,
               GlobVar *gv);
diff --git a/src/freemem.cpp b/src/freemem.cpp
index e959bcd..cfa9080 100644
--- a/src/freemem.cpp
+++ b/src/freemem.cpp
@@ -25,7 +25,7 @@
 #include "util.hpp"
 
 void freemem(int nsrc_loc, st_acquisition *acq, st_model *mod, st_model *testmod,
-             st_model_av &mod_av, st_visc_mem *visco_mem, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd,
+             st_model_av &mod_av, st_visc_mem *visco_mem, st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd,
              st_signals *signals, st_gradient *grad, st_gradient *grad_prior1, st_gradient *grad_prior2,
              st_gradient *grad_halo,
              st_hessian *hessian, st_stress &stress, st_buffer_flat *stressbuff, st_freq_velocity *fourier_vel_back,
@@ -224,31 +224,31 @@ void freemem(int nsrc_loc, st_acquisition *acq, st_model *mod, st_model *testmod
         free_vector(pml_coeff->b_z_half, 1, 2 * gv->FW);
 
         if (gv->WEQ != 2) {
-            free_f3tensor(pml_wfd->psi_sxx_x, 1, gv->NY, 1, 2 * gv->FW, 1, gv->NZ);
-            free_f3tensor(pml_wfd->psi_syy_y, 1, 2 * gv->FW, 1, gv->NX, 1, gv->NZ);
-            free_f3tensor(pml_wfd->psi_szz_z, 1, gv->NY, 1, gv->NX, 1, 2 * gv->FW);
-            free_f3tensor(pml_wfd->psi_sxy_x, 1, gv->NY, 1, 2 * gv->FW, 1, gv->NZ);
-            free_f3tensor(pml_wfd->psi_sxy_y, 1, 2 * gv->FW, 1, gv->NX, 1, gv->NZ);
-            free_f3tensor(pml_wfd->psi_sxz_x, 1, gv->NY, 1, 2 * gv->FW, 1, gv->NZ);
-            free_f3tensor(pml_wfd->psi_sxz_z, 1, gv->NY, 1, gv->NX, 1, 2 * gv->FW);
-            free_f3tensor(pml_wfd->psi_syz_y, 1, 2 * gv->FW, 1, gv->NX, 1, gv->NZ);
-            free_f3tensor(pml_wfd->psi_syz_z, 1, gv->NY, 1, gv->NX, 1, 2 * gv->FW);
+            pml_wfd.psi_sxx_x.free();
+            pml_wfd.psi_syy_y.free();
+            pml_wfd.psi_szz_z.free();
+            pml_wfd.psi_sxy_x.free();
+            pml_wfd.psi_sxy_y.free();
+            pml_wfd.psi_sxz_x.free();
+            pml_wfd.psi_sxz_z.free();
+            pml_wfd.psi_syz_y.free();
+            pml_wfd.psi_syz_z.free();
 
-            free_f3tensor(pml_wfd->psi_vxy, 1, 2 * gv->FW, 1, gv->NX, 1, gv->NZ);
-            free_f3tensor(pml_wfd->psi_vyx, 1, gv->NY, 1, 2 * gv->FW, 1, gv->NZ);
-            free_f3tensor(pml_wfd->psi_vxz, 1, gv->NY, 1, gv->NX, 1, 2 * gv->FW);
-            free_f3tensor(pml_wfd->psi_vzx, 1, gv->NY, 1, 2 * gv->FW, 1, gv->NZ);
-            free_f3tensor(pml_wfd->psi_vyz, 1, gv->NY, 1, gv->NX, 1, 2 * gv->FW);
-            free_f3tensor(pml_wfd->psi_vzy, 1, 2 * gv->FW, 1, gv->NX, 1, gv->NZ);
+            pml_wfd.psi_vxy.free();
+            pml_wfd.psi_vyx.free();
+            pml_wfd.psi_vxz.free();
+            pml_wfd.psi_vzx.free();
+            pml_wfd.psi_vyz.free();
+            pml_wfd.psi_vzy.free();
         } else {
-            free_f3tensor(pml_wfd->psi_sp_x, 1, gv->NY, 1, 2 * gv->FW, 1, gv->NZ);
-            free_f3tensor(pml_wfd->psi_sp_y, 1, 2 * gv->FW, 1, gv->NX, 1, gv->NZ);
-            free_f3tensor(pml_wfd->psi_sp_z, 1, gv->NY, 1, gv->NX, 1, 2 * gv->FW);
+            pml_wfd.psi_sp_x.free();
+            pml_wfd.psi_sp_y.free();
+            pml_wfd.psi_sp_z.free();
         }
 
-        free_f3tensor(pml_wfd->psi_vxx, 1, gv->NY, 1, 2 * gv->FW, 1, gv->NZ);
-        free_f3tensor(pml_wfd->psi_vyy, 1, 2 * gv->FW, 1, gv->NX, 1, gv->NZ);
-        free_f3tensor(pml_wfd->psi_vzz, 1, gv->NY, 1, gv->NX, 1, 2 * gv->FW);
+        pml_wfd.psi_vxx.free();
+        pml_wfd.psi_vyy.free();
+        pml_wfd.psi_vzz.free();
     }
 
     if (gv->L) {
diff --git a/src/ifos3d.cpp b/src/ifos3d.cpp
index 39ef982..cfaf72a 100644
--- a/src/ifos3d.cpp
+++ b/src/ifos3d.cpp
@@ -183,7 +183,7 @@ int main(int argc, char **argv)
     }
 
     /* allocate and initialize buffers */
-    buffsize = initmem(&mod, &testmod, mod_av, &visco_mem, &pml_coeff, &pml_wfd,
+    buffsize = initmem(&mod, &testmod, mod_av, &visco_mem, &pml_coeff, pml_wfd,
                        &grad, &grad_prior1, &grad_prior2, &grad_halo, &hessian, stress, &stressbuff,
                        &fourier_vel_back, &fourier_vel_fw, vel, &velbuff, &gv);
 
@@ -471,9 +471,9 @@ int main(int argc, char **argv)
 
             /* initialize wavefield with zero */
             if (gv.WEQ != 2) {
-                zero_wavefield(vel, stress, &visco_mem, &pml_wfd, &gv);
+                zero_wavefield(vel, stress, &visco_mem, pml_wfd, &gv);
             } else {
-                zero_wavefield_acoustic(vel, stress, &visco_mem, &pml_wfd, &gv);
+                zero_wavefield_acoustic(vel, stress, &visco_mem, pml_wfd, &gv);
             }
             if (gv.METHOD)
                 zero_invers(&fourier_vel_fw, &fourier_vel_back, gv.NFMAX, &gv);
@@ -488,7 +488,7 @@ int main(int argc, char **argv)
 
                 if (gv.STFI) {
                     stfi(&acq, &nb, &nb_fix, vel, stress, &mod, mod_av, &visco_mem, &section, &section_obs,
-                         &signals, nsrc_loc, ntr_loc, &pml_coeff, &pml_wfd, &stressbuff, &velbuff,
+                         &signals, nsrc_loc, ntr_loc, &pml_coeff, pml_wfd, &stressbuff, &velbuff,
                          &fourier_vel_fw, finv, &L2, nf, ntast, lsnap, nsnap, ishot, shot_id, cdf, iteration, groupnum,
                          it_group, ncplx, &gv);
                 }
@@ -499,7 +499,7 @@ int main(int argc, char **argv)
             *****************************************************/
             timeloop(&nb, &nb_fix, vel, stress, &mod, mod_av, &section,
                      acq.srcpos_loc, acq.recpos_loc, &signals, nsrc_loc,
-                     mod.absorb_coeff, &pml_coeff, &pml_wfd, &stressbuff, &velbuff, &fourier_vel_fw,
+                     mod.absorb_coeff, &pml_coeff, pml_wfd, &stressbuff, &velbuff, &fourier_vel_fw,
                      finv, nf, ntast, ntr_loc, lsnap, nsnap, 0, shot_id, 1, &gv);
 
             time3a = MPI_Wtime();
@@ -556,9 +556,9 @@ int main(int argc, char **argv)
 
                 /* initialize wavefields */
                 if (gv.WEQ != 2) {
-                    zero_wavefield(vel, stress, &visco_mem, &pml_wfd, &gv);
+                    zero_wavefield(vel, stress, &visco_mem, pml_wfd, &gv);
                 } else {
-                    zero_wavefield_acoustic(vel, stress, &visco_mem, &pml_wfd, &gv);
+                    zero_wavefield_acoustic(vel, stress, &visco_mem, pml_wfd, &gv);
                 }
 
                 /*****************************************************
@@ -566,7 +566,7 @@ int main(int argc, char **argv)
                 *****************************************************/
                 timeloop(&nb, &nb_fix, vel, stress, &mod, mod_av, &section,
                          acq.srcpos_loc_back, acq.recpos_loc, &signals, ntr_loc,
-                         mod.absorb_coeff, &pml_coeff, &pml_wfd, &stressbuff, &velbuff, &fourier_vel_back,
+                         mod.absorb_coeff, &pml_coeff, pml_wfd, &stressbuff, &velbuff, &fourier_vel_back,
                          finv, nf, ntast, ntr_loc, lsnap, nsnap, 0, shot_id, 2, &gv);
 
                 MPI_Barrier(gv.COMM_SHOT);
@@ -794,9 +794,9 @@ int main(int argc, char **argv)
                         }
 
                         if (gv.WEQ != 2) {
-                            zero_wavefield(vel, stress, &visco_mem, &pml_wfd, &gv);
+                            zero_wavefield(vel, stress, &visco_mem, pml_wfd, &gv);
                         } else {
-                            zero_wavefield_acoustic(vel, stress, &visco_mem, &pml_wfd, &gv);
+                            zero_wavefield_acoustic(vel, stress, &visco_mem, pml_wfd, &gv);
                         }
 
                         /*****************************************************
@@ -804,7 +804,7 @@ int main(int argc, char **argv)
                         *****************************************************/
                         timeloop(&nb, &nb_fix, vel, stress, &testmod, mod_av, &section,
                                  acq.srcpos_loc, acq.recpos_loc, &signals, nsrc_loc,
-                                 mod.absorb_coeff, &pml_coeff, &pml_wfd, &stressbuff, &velbuff, &fourier_vel_fw,
+                                 mod.absorb_coeff, &pml_coeff, pml_wfd, &stressbuff, &velbuff, &fourier_vel_fw,
                                  finv, nf, ntast, ntr_loc, lsnap, nsnap, 0, shot_id, 3, &gv);
 
                         seismo_shift(&section, ntr_loc, acq.srcpos[5][ishot1], &gv);
@@ -849,7 +849,7 @@ int main(int argc, char **argv)
 
     /* de-allocation of memory */
     freemem(nsrc_loc, &acq, &mod, &testmod, mod_av,
-            &visco_mem, &pml_coeff, &pml_wfd, &signals, &grad,
+            &visco_mem, &pml_coeff, pml_wfd, &signals, &grad,
             &grad_prior1, &grad_prior2, &grad_halo, &hessian, stress, &stressbuff,
             &fourier_vel_back, &fourier_vel_fw, vel, &velbuff, &gv);
 
diff --git a/src/initmem.cpp b/src/initmem.cpp
index 71f87ad..1de6254 100644
--- a/src/initmem.cpp
+++ b/src/initmem.cpp
@@ -27,7 +27,7 @@
 
 int initmem(st_model *mod, st_model *testmod,
             st_model_av &mod_av, st_visc_mem *visco_mem, st_pml_coeff *pml_coeff,
-            st_pml_wfd *pml_wfd, st_gradient *grad, st_gradient *grad_prior1,
+            st_pml_wfd &pml_wfd, st_gradient *grad, st_gradient *grad_prior1,
             st_gradient *grad_prior2, st_gradient *grad_halo, st_hessian *hessian, st_stress &stress,
             st_buffer_flat *stressbuff, st_freq_velocity *fourier_vel_back,
             st_freq_velocity *fourier_vel_fw, st_velocity &vel, st_buffer_flat *velbuff,
@@ -359,30 +359,30 @@ int initmem(st_model *mod, st_model *testmod,
         pml_coeff->b_z_half = vector(1, 2 * gv->FW);
 
         if (gv->WEQ != 2) {
-            pml_wfd->psi_sxx_x = f3tensor(1, gv->NY, 1, 2 * gv->FW, 1, gv->NZ);
-            pml_wfd->psi_sxy_x = f3tensor(1, gv->NY, 1, 2 * gv->FW, 1, gv->NZ);
-            pml_wfd->psi_sxz_x = f3tensor(1, gv->NY, 1, 2 * gv->FW, 1, gv->NZ);
-            pml_wfd->psi_syy_y = f3tensor(1, 2 * gv->FW, 1, gv->NX, 1, gv->NZ);
-            pml_wfd->psi_sxy_y = f3tensor(1, 2 * gv->FW, 1, gv->NX, 1, gv->NZ);
-            pml_wfd->psi_syz_y = f3tensor(1, 2 * gv->FW, 1, gv->NX, 1, gv->NZ);
-            pml_wfd->psi_szz_z = f3tensor(1, gv->NY, 1, gv->NX, 1, 2 * gv->FW);
-            pml_wfd->psi_sxz_z = f3tensor(1, gv->NY, 1, gv->NX, 1, 2 * gv->FW);
-            pml_wfd->psi_syz_z = f3tensor(1, gv->NY, 1, gv->NX, 1, 2 * gv->FW);
+            pml_wfd.psi_sxx_x.malloc(1, gv->NY, 1, 2 * gv->FW, 1, gv->NZ);
+            pml_wfd.psi_sxy_x.malloc(1, gv->NY, 1, 2 * gv->FW, 1, gv->NZ);
+            pml_wfd.psi_sxz_x.malloc(1, gv->NY, 1, 2 * gv->FW, 1, gv->NZ);
+            pml_wfd.psi_syy_y.malloc(1, 2 * gv->FW, 1, gv->NX, 1, gv->NZ);
+            pml_wfd.psi_sxy_y.malloc(1, 2 * gv->FW, 1, gv->NX, 1, gv->NZ);
+            pml_wfd.psi_syz_y.malloc(1, 2 * gv->FW, 1, gv->NX, 1, gv->NZ);
+            pml_wfd.psi_szz_z.malloc(1, gv->NY, 1, gv->NX, 1, 2 * gv->FW);
+            pml_wfd.psi_sxz_z.malloc(1, gv->NY, 1, gv->NX, 1, 2 * gv->FW);
+            pml_wfd.psi_syz_z.malloc(1, gv->NY, 1, gv->NX, 1, 2 * gv->FW);
 
-            pml_wfd->psi_vxy = f3tensor(1, 2 * gv->FW, 1, gv->NX, 1, gv->NZ);
-            pml_wfd->psi_vxz = f3tensor(1, gv->NY, 1, gv->NX, 1, 2 * gv->FW);
-            pml_wfd->psi_vyx = f3tensor(1, gv->NY, 1, 2 * gv->FW, 1, gv->NZ);
-            pml_wfd->psi_vyz = f3tensor(1, gv->NY, 1, gv->NX, 1, 2 * gv->FW);
-            pml_wfd->psi_vzx = f3tensor(1, gv->NY, 1, 2 * gv->FW, 1, gv->NZ);
-            pml_wfd->psi_vzy = f3tensor(1, 2 * gv->FW, 1, gv->NX, 1, gv->NZ);
+            pml_wfd.psi_vxy.malloc(1, 2 * gv->FW, 1, gv->NX, 1, gv->NZ);
+            pml_wfd.psi_vxz.malloc(1, gv->NY, 1, gv->NX, 1, 2 * gv->FW);
+            pml_wfd.psi_vyx.malloc(1, gv->NY, 1, 2 * gv->FW, 1, gv->NZ);
+            pml_wfd.psi_vyz.malloc(1, gv->NY, 1, gv->NX, 1, 2 * gv->FW);
+            pml_wfd.psi_vzx.malloc(1, gv->NY, 1, 2 * gv->FW, 1, gv->NZ);
+            pml_wfd.psi_vzy.malloc(1, 2 * gv->FW, 1, gv->NX, 1, gv->NZ);
         } else {
-            pml_wfd->psi_sp_x = f3tensor(1, gv->NY, 1, 2 * gv->FW, 1, gv->NZ);
-            pml_wfd->psi_sp_y = f3tensor(1, 2 * gv->FW, 1, gv->NX, 1, gv->NZ);
-            pml_wfd->psi_sp_z = f3tensor(1, gv->NY, 1, gv->NX, 1, 2 * gv->FW);
+            pml_wfd.psi_sp_x.malloc(1, gv->NY, 1, 2 * gv->FW, 1, gv->NZ);
+            pml_wfd.psi_sp_y.malloc(1, 2 * gv->FW, 1, gv->NX, 1, gv->NZ);
+            pml_wfd.psi_sp_z.malloc(1, gv->NY, 1, gv->NX, 1, 2 * gv->FW);
         }
-        pml_wfd->psi_vxx = f3tensor(1, gv->NY, 1, 2 * gv->FW, 1, gv->NZ);
-        pml_wfd->psi_vyy = f3tensor(1, 2 * gv->FW, 1, gv->NX, 1, gv->NZ);
-        pml_wfd->psi_vzz = f3tensor(1, gv->NY, 1, gv->NX, 1, 2 * gv->FW);
+        pml_wfd.psi_vxx.malloc(1, gv->NY, 1, 2 * gv->FW, 1, gv->NZ);
+        pml_wfd.psi_vyy.malloc(1, 2 * gv->FW, 1, gv->NX, 1, gv->NZ);
+        pml_wfd.psi_vzz.malloc(1, gv->NY, 1, gv->NX, 1, 2 * gv->FW);
     }
 
     if (gv->L) {
diff --git a/src/stfi.cpp b/src/stfi.cpp
index 53497b3..3c6d3dc 100644
--- a/src/stfi.cpp
+++ b/src/stfi.cpp
@@ -33,7 +33,7 @@
 void stfi(st_acquisition *acq, st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress &stress,
           st_model *mod, st_model_av &mod_av, st_visc_mem *visco_mem, st_seismogram *section,
           st_seismogram *section_obs, st_signals *signals, int nsrc_loc, int ntr_loc, st_pml_coeff *pml_coeff,
-          st_pml_wfd *pml_wfd, st_buffer_flat *stressbuff, st_buffer_flat *velbuff, st_freq_velocity *fourier_vel_fw,
+          st_pml_wfd &pml_wfd, st_buffer_flat *stressbuff, st_buffer_flat *velbuff, st_freq_velocity *fourier_vel_fw,
           const float *finv, double *L2, int nf, int ntast, int lsnap, int nsnap, int ishot, int shot_id, int cdf,
           int iteration, int groupnum, int it_group, int ncplx, GlobVar *gv)
 {
diff --git a/src/surface_ssg.cpp b/src/surface_ssg.cpp
index db9cf50..249710c 100644
--- a/src/surface_ssg.cpp
+++ b/src/surface_ssg.cpp
@@ -23,7 +23,7 @@
 
 #include "fd.hpp"
 
-void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, st_visc_mem *mem,
+void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd, st_visc_mem *mem,
              st_stress &stress, st_velocity &vel)
 {
     int i, k, j, fdoh, m, h1;
@@ -87,27 +87,27 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
 
                 if (ABS_TYPE == 1) {
                     if ((POS[1] == 0) && (i <= FW)) {
-                        pml_wfd->psi_vxx[j][i][k] =
-                            pml_coeff->b_x[i] * pml_wfd->psi_vxx[j][i][k] + pml_coeff->a_x[i] * vxx;
-                        vxx = vxx / pml_coeff->K_x[i] + pml_wfd->psi_vxx[j][i][k];
+                        pml_wfd.psi_vxx[j, i, k] =
+                            pml_coeff->b_x[i] * pml_wfd.psi_vxx[j, i, k] + pml_coeff->a_x[i] * vxx;
+                        vxx = vxx / pml_coeff->K_x[i] + pml_wfd.psi_vxx[j, i, k];
                     }
                     if ((POS[1] == NPROCX - 1) && (i >= NX - FW + 1)) {
                         h1 = i - NX + 2 * FW;
 
-                        pml_wfd->psi_vxx[j][h1][k] =
-                            pml_coeff->b_x[h1] * pml_wfd->psi_vxx[j][h1][k] + pml_coeff->a_x[h1] * vxx;
-                        vxx = vxx / pml_coeff->K_x[h1] + pml_wfd->psi_vxx[j][h1][k];
+                        pml_wfd.psi_vxx[j, h1, k] =
+                            pml_coeff->b_x[h1] * pml_wfd.psi_vxx[j, h1, k] + pml_coeff->a_x[h1] * vxx;
+                        vxx = vxx / pml_coeff->K_x[h1] + pml_wfd.psi_vxx[j, h1, k];
                     }
                     if ((POS[3] == 0) && (k <= FW)) {
-                        pml_wfd->psi_vzz[j][i][k] =
-                            pml_coeff->b_z[k] * pml_wfd->psi_vzz[j][i][k] + pml_coeff->a_z[k] * vzz;
-                        vzz = vzz / pml_coeff->K_z[k] + pml_wfd->psi_vzz[j][i][k];
+                        pml_wfd.psi_vzz[j, i, k] =
+                            pml_coeff->b_z[k] * pml_wfd.psi_vzz[j, i, k] + pml_coeff->a_z[k] * vzz;
+                        vzz = vzz / pml_coeff->K_z[k] + pml_wfd.psi_vzz[j, i, k];
                     }
                     if ((POS[3] == NPROCZ - 1) && (k >= NZ - FW + 1)) {
                         h1 = (k - NZ + 2 * FW);
-                        pml_wfd->psi_vzz[j][i][h1] =
-                            pml_coeff->b_z[h1] * pml_wfd->psi_vzz[j][i][h1] + pml_coeff->a_z[h1] * vzz;
-                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd->psi_vzz[j][i][h1];
+                        pml_wfd.psi_vzz[j, i, h1] =
+                            pml_coeff->b_z[h1] * pml_wfd.psi_vzz[j, i, h1] + pml_coeff->a_z[h1] * vzz;
+                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd.psi_vzz[j, i, h1];
                     }
                 }
 
@@ -177,27 +177,27 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml
 
                 if (ABS_TYPE == 1) {
                     if ((POS[1] == 0) && (i <= FW)) {
-                        pml_wfd->psi_vxx[j][i][k] =
-                            pml_coeff->b_x[i] * pml_wfd->psi_vxx[j][i][k] + pml_coeff->a_x[i] * vxx;
-                        vxx = vxx / pml_coeff->K_x[i] + pml_wfd->psi_vxx[j][i][k];
+                        pml_wfd.psi_vxx[j, i, k] =
+                            pml_coeff->b_x[i] * pml_wfd.psi_vxx[j, i, k] + pml_coeff->a_x[i] * vxx;
+                        vxx = vxx / pml_coeff->K_x[i] + pml_wfd.psi_vxx[j, i, k];
                     }
                     if ((POS[1] == NPROCX - 1) && (i >= NX - FW + 1)) {
                         h1 = i - NX + 2 * FW;
 
-                        pml_wfd->psi_vxx[j][h1][k] =
-                            pml_coeff->b_x[h1] * pml_wfd->psi_vxx[j][h1][k] + pml_coeff->a_x[h1] * vxx;
-                        vxx = vxx / pml_coeff->K_x[h1] + pml_wfd->psi_vxx[j][h1][k];
+                        pml_wfd.psi_vxx[j, h1, k] =
+                            pml_coeff->b_x[h1] * pml_wfd.psi_vxx[j, h1, k] + pml_coeff->a_x[h1] * vxx;
+                        vxx = vxx / pml_coeff->K_x[h1] + pml_wfd.psi_vxx[j, h1, k];
                     }
                     if ((POS[3] == 0) && (k <= FW)) {
-                        pml_wfd->psi_vzz[j][i][k] =
-                            pml_coeff->b_z[k] * pml_wfd->psi_vzz[j][i][k] + pml_coeff->a_z[k] * vzz;
-                        vzz = vzz / pml_coeff->K_z[k] + pml_wfd->psi_vzz[j][i][k];
+                        pml_wfd.psi_vzz[j, i, k] =
+                            pml_coeff->b_z[k] * pml_wfd.psi_vzz[j, i, k] + pml_coeff->a_z[k] * vzz;
+                        vzz = vzz / pml_coeff->K_z[k] + pml_wfd.psi_vzz[j, i, k];
                     }
                     if ((POS[3] == NPROCZ - 1) && (k >= NZ - FW + 1)) {
                         h1 = (k - NZ + 2 * FW);
-                        pml_wfd->psi_vzz[j][i][h1] =
-                            pml_coeff->b_z[h1] * pml_wfd->psi_vzz[j][i][h1] + pml_coeff->a_z[h1] * vzz;
-                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd->psi_vzz[j][i][h1];
+                        pml_wfd.psi_vzz[j, i, h1] =
+                            pml_coeff->b_z[h1] * pml_wfd.psi_vzz[j, i, h1] + pml_coeff->a_z[h1] * vzz;
+                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd.psi_vzz[j, i, h1];
                     }
                 }
 
diff --git a/src/surface_ssg_elastic.cpp b/src/surface_ssg_elastic.cpp
index 76de5cc..2ddc2c2 100644
--- a/src/surface_ssg_elastic.cpp
+++ b/src/surface_ssg_elastic.cpp
@@ -23,7 +23,7 @@
 
 #include "fd.hpp"
 
-void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd,
+void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd,
                      st_stress &stress, st_velocity &vel, const GlobVar *gv)
 {
     int h1;
@@ -58,27 +58,27 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
 
                 if (gv->ABS_TYPE == 1) {
                     if ((gv->POS[1] == 0) && (i <= gv->FW)) {
-                        pml_wfd->psi_vxx[j][i][k] =
-                            pml_coeff->b_x[i] * pml_wfd->psi_vxx[j][i][k] + pml_coeff->a_x[i] * vxx;
-                        vxx = vxx / pml_coeff->K_x[i] + pml_wfd->psi_vxx[j][i][k];
+                        pml_wfd.psi_vxx[j, i, k] =
+                            pml_coeff->b_x[i] * pml_wfd.psi_vxx[j, i, k] + pml_coeff->a_x[i] * vxx;
+                        vxx = vxx / pml_coeff->K_x[i] + pml_wfd.psi_vxx[j, i, k];
                     }
                     if ((gv->POS[1] == gv->NPROCX - 1) && (i >= gv->NX - gv->FW + 1)) {
                         h1 = i - gv->NX + 2 * gv->FW;
 
-                        pml_wfd->psi_vxx[j][h1][k] =
-                            pml_coeff->b_x[h1] * pml_wfd->psi_vxx[j][h1][k] + pml_coeff->a_x[h1] * vxx;
-                        vxx = vxx / pml_coeff->K_x[h1] + pml_wfd->psi_vxx[j][h1][k];
+                        pml_wfd.psi_vxx[j, h1, k] =
+                            pml_coeff->b_x[h1] * pml_wfd.psi_vxx[j, h1, k] + pml_coeff->a_x[h1] * vxx;
+                        vxx = vxx / pml_coeff->K_x[h1] + pml_wfd.psi_vxx[j, h1, k];
                     }
                     if ((gv->POS[3] == 0) && (k <= gv->FW)) {
-                        pml_wfd->psi_vzz[j][i][k] =
-                            pml_coeff->b_z[k] * pml_wfd->psi_vzz[j][i][k] + pml_coeff->a_z[k] * vzz;
-                        vzz = vzz / pml_coeff->K_z[k] + pml_wfd->psi_vzz[j][i][k];
+                        pml_wfd.psi_vzz[j, i, k] =
+                            pml_coeff->b_z[k] * pml_wfd.psi_vzz[j, i, k] + pml_coeff->a_z[k] * vzz;
+                        vzz = vzz / pml_coeff->K_z[k] + pml_wfd.psi_vzz[j, i, k];
                     }
                     if ((gv->POS[3] == gv->NPROCZ - 1) && (k >= gv->NZ - gv->FW + 1)) {
                         h1 = (k - gv->NZ + 2 * gv->FW);
-                        pml_wfd->psi_vzz[j][i][h1] =
-                            pml_coeff->b_z[h1] * pml_wfd->psi_vzz[j][i][h1] + pml_coeff->a_z[h1] * vzz;
-                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd->psi_vzz[j][i][h1];
+                        pml_wfd.psi_vzz[j, i, h1] =
+                            pml_coeff->b_z[h1] * pml_wfd.psi_vzz[j, i, h1] + pml_coeff->a_z[h1] * vzz;
+                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd.psi_vzz[j, i, h1];
                     }
                 }
 
@@ -124,27 +124,27 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
 
                 if (gv->ABS_TYPE == 1) {
                     if ((gv->POS[1] == 0) && (i <= gv->FW)) {
-                        pml_wfd->psi_vxx[j][i][k] =
-                            pml_coeff->b_x[i] * pml_wfd->psi_vxx[j][i][k] + pml_coeff->a_x[i] * vxx;
-                        vxx = vxx / pml_coeff->K_x[i] + pml_wfd->psi_vxx[j][i][k];
+                        pml_wfd.psi_vxx[j, i, k] =
+                            pml_coeff->b_x[i] * pml_wfd.psi_vxx[j, i, k] + pml_coeff->a_x[i] * vxx;
+                        vxx = vxx / pml_coeff->K_x[i] + pml_wfd.psi_vxx[j, i, k];
                     }
                     if ((gv->POS[1] == gv->NPROCX - 1) && (i >= gv->NX - gv->FW + 1)) {
                         h1 = i - gv->NX + 2 * gv->FW;
 
-                        pml_wfd->psi_vxx[j][h1][k] =
-                            pml_coeff->b_x[h1] * pml_wfd->psi_vxx[j][h1][k] + pml_coeff->a_x[h1] * vxx;
-                        vxx = vxx / pml_coeff->K_x[h1] + pml_wfd->psi_vxx[j][h1][k];
+                        pml_wfd.psi_vxx[j, h1, k] =
+                            pml_coeff->b_x[h1] * pml_wfd.psi_vxx[j, h1, k] + pml_coeff->a_x[h1] * vxx;
+                        vxx = vxx / pml_coeff->K_x[h1] + pml_wfd.psi_vxx[j, h1, k];
                     }
                     if ((gv->POS[3] == 0) && (k <= gv->FW)) {
-                        pml_wfd->psi_vzz[j][i][k] =
-                            pml_coeff->b_z[k] * pml_wfd->psi_vzz[j][i][k] + pml_coeff->a_z[k] * vzz;
-                        vzz = vzz / pml_coeff->K_z[k] + pml_wfd->psi_vzz[j][i][k];
+                        pml_wfd.psi_vzz[j, i, k] =
+                            pml_coeff->b_z[k] * pml_wfd.psi_vzz[j, i, k] + pml_coeff->a_z[k] * vzz;
+                        vzz = vzz / pml_coeff->K_z[k] + pml_wfd.psi_vzz[j, i, k];
                     }
                     if ((gv->POS[3] == gv->NPROCZ - 1) && (k >= gv->NZ - gv->FW + 1)) {
                         h1 = (k - gv->NZ + 2 * gv->FW);
-                        pml_wfd->psi_vzz[j][i][h1] =
-                            pml_coeff->b_z[h1] * pml_wfd->psi_vzz[j][i][h1] + pml_coeff->a_z[h1] * vzz;
-                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd->psi_vzz[j][i][h1];
+                        pml_wfd.psi_vzz[j, i, h1] =
+                            pml_coeff->b_z[h1] * pml_wfd.psi_vzz[j, i, h1] + pml_coeff->a_z[h1] * vzz;
+                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd.psi_vzz[j, i, h1];
                     }
                 }
 
diff --git a/src/timeloop.cpp b/src/timeloop.cpp
index b9d0f79..cac7970 100644
--- a/src/timeloop.cpp
+++ b/src/timeloop.cpp
@@ -26,7 +26,7 @@
 void timeloop(st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress &stress,
               st_model *mod, st_model_av &mod_av, st_seismogram *section,
               float **srcpos_loc, int **recpos_loc, st_signals *signals, int nsrc_loc,
-              float ***absorb_coeff, st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd,
+              float ***absorb_coeff, st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd,
               st_buffer_flat *stressbuff, st_buffer_flat *velbuff, st_freq_velocity *fourier_vel,
               const float *finv, int nf, int ntast, int ntr, int lsnap, int nsnap, int pshot, int shot_id,
               int proptype, GlobVar *gv)
diff --git a/src/update_s_ssg_CPML_acoustic.cpp b/src/update_s_ssg_CPML_acoustic.cpp
index a24b82b..5e8dcc7 100644
--- a/src/update_s_ssg_CPML_acoustic.cpp
+++ b/src/update_s_ssg_CPML_acoustic.cpp
@@ -31,7 +31,7 @@
 
 double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
                               st_stress &stress, st_model *mod, st_pml_coeff *pml_coeff,
-                              st_pml_wfd *pml_wfd, const GlobVar *gv)
+                              st_pml_wfd &pml_wfd, const GlobVar *gv)
 {
     int h1;
     float vxx, vyy, vzz, vxxyyzz, g;
@@ -60,35 +60,35 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
                         (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
                          b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) / gv->DZ;
 
-                    pml_wfd->psi_vxx[j][i][k] = pml_coeff->b_x[i] * pml_wfd->psi_vxx[j][i][k] + pml_coeff->a_x[i] * vxx;
-                    vxx = vxx / pml_coeff->K_x[i] + pml_wfd->psi_vxx[j][i][k];
+                    pml_wfd.psi_vxx[j, i, k] = pml_coeff->b_x[i] * pml_wfd.psi_vxx[j, i, k] + pml_coeff->a_x[i] * vxx;
+                    vxx = vxx / pml_coeff->K_x[i] + pml_wfd.psi_vxx[j, i, k];
 
                     if ((gv->POS[2] == 0 && gv->FREE_SURF == 0) && (j <= gv->FW)) {
-                        pml_wfd->psi_vyy[j][i][k] =
-                            pml_coeff->b_y[j] * pml_wfd->psi_vyy[j][i][k] + pml_coeff->a_y[j] * vyy;
-                        vyy = vyy / pml_coeff->K_y[j] + pml_wfd->psi_vyy[j][i][k];
+                        pml_wfd.psi_vyy[j, i, k] =
+                            pml_coeff->b_y[j] * pml_wfd.psi_vyy[j, i, k] + pml_coeff->a_y[j] * vyy;
+                        vyy = vyy / pml_coeff->K_y[j] + pml_wfd.psi_vyy[j, i, k];
                     }
 
                     if ((gv->POS[2] == gv->NPROCY - 1) && (j >= nb->ny2 + 1)) {
                         h1 = (j - nb->ny2 + gv->FW);
 
-                        pml_wfd->psi_vyy[h1][i][k] =
-                            pml_coeff->b_y[h1] * pml_wfd->psi_vyy[h1][i][k] + pml_coeff->a_y[h1] * vyy;
-                        vyy = vyy / pml_coeff->K_y[h1] + pml_wfd->psi_vyy[h1][i][k];
+                        pml_wfd.psi_vyy[h1, i, k] =
+                            pml_coeff->b_y[h1] * pml_wfd.psi_vyy[h1, i, k] + pml_coeff->a_y[h1] * vyy;
+                        vyy = vyy / pml_coeff->K_y[h1] + pml_wfd.psi_vyy[h1, i, k];
                     }
 
                     if ((gv->POS[3] == 0) && (k <= gv->FW)) {
-                        pml_wfd->psi_vzz[j][i][k] =
-                            pml_coeff->b_z[k] * pml_wfd->psi_vzz[j][i][k] + pml_coeff->a_z[k] * vzz;
-                        vzz = vzz / pml_coeff->K_y[k] + pml_wfd->psi_vzz[j][i][k];
+                        pml_wfd.psi_vzz[j, i, k] =
+                            pml_coeff->b_z[k] * pml_wfd.psi_vzz[j, i, k] + pml_coeff->a_z[k] * vzz;
+                        vzz = vzz / pml_coeff->K_y[k] + pml_wfd.psi_vzz[j, i, k];
                     }
 
                     if ((gv->POS[3] == gv->NPROCZ - 1) && (k >= nb->nz2 + 1)) {
                         h1 = (k - nb->nz2 + gv->FW);
 
-                        pml_wfd->psi_vzz[j][i][h1] =
-                            pml_coeff->b_z[h1] * pml_wfd->psi_vzz[j][i][h1] + pml_coeff->a_z[h1] * vzz;
-                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd->psi_vzz[j][i][h1];
+                        pml_wfd.psi_vzz[j, i, h1] =
+                            pml_coeff->b_z[h1] * pml_wfd.psi_vzz[j, i, h1] + pml_coeff->a_z[h1] * vzz;
+                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd.psi_vzz[j, i, h1];
                     }
 
                     g = mod->pi[j][i][k];
@@ -118,36 +118,36 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
 
                     h1 = i - nb->nx2 + gv->FW;
 
-                    pml_wfd->psi_vxx[j][h1][k] =
-                        pml_coeff->b_x[h1] * pml_wfd->psi_vxx[j][h1][k] + pml_coeff->a_x[h1] * vxx;
-                    vxx = vxx / pml_coeff->K_x[h1] + pml_wfd->psi_vxx[j][h1][k];
+                    pml_wfd.psi_vxx[j, h1, k] =
+                        pml_coeff->b_x[h1] * pml_wfd.psi_vxx[j, h1, k] + pml_coeff->a_x[h1] * vxx;
+                    vxx = vxx / pml_coeff->K_x[h1] + pml_wfd.psi_vxx[j, h1, k];
 
                     if ((gv->POS[2] == 0 && gv->FREE_SURF == 0) && (j <= gv->FW)) {
-                        pml_wfd->psi_vyy[j][i][k] =
-                            pml_coeff->b_y[j] * pml_wfd->psi_vyy[j][i][k] + pml_coeff->a_y[j] * vyy;
-                        vyy = vyy / pml_coeff->K_y[j] + pml_wfd->psi_vyy[j][i][k];
+                        pml_wfd.psi_vyy[j, i, k] =
+                            pml_coeff->b_y[j] * pml_wfd.psi_vyy[j, i, k] + pml_coeff->a_y[j] * vyy;
+                        vyy = vyy / pml_coeff->K_y[j] + pml_wfd.psi_vyy[j, i, k];
                     }
 
                     if ((gv->POS[2] == gv->NPROCY - 1) && (j >= nb->ny2 + 1)) {
                         h1 = (j - nb->ny2 + gv->FW);
 
-                        pml_wfd->psi_vyy[h1][i][k] =
-                            pml_coeff->b_y[h1] * pml_wfd->psi_vyy[h1][i][k] + pml_coeff->a_y[h1] * vyy;
-                        vyy = vyy / pml_coeff->K_y[h1] + pml_wfd->psi_vyy[h1][i][k];
+                        pml_wfd.psi_vyy[h1, i, k] =
+                            pml_coeff->b_y[h1] * pml_wfd.psi_vyy[h1, i, k] + pml_coeff->a_y[h1] * vyy;
+                        vyy = vyy / pml_coeff->K_y[h1] + pml_wfd.psi_vyy[h1, i, k];
                     }
 
                     if ((gv->POS[3] == 0) && (k <= gv->FW)) {
-                        pml_wfd->psi_vzz[j][i][k] =
-                            pml_coeff->b_z[k] * pml_wfd->psi_vzz[j][i][k] + pml_coeff->a_z[k] * vzz;
-                        vzz = vzz / pml_coeff->K_y[k] + pml_wfd->psi_vzz[j][i][k];
+                        pml_wfd.psi_vzz[j, i, k] =
+                            pml_coeff->b_z[k] * pml_wfd.psi_vzz[j, i, k] + pml_coeff->a_z[k] * vzz;
+                        vzz = vzz / pml_coeff->K_y[k] + pml_wfd.psi_vzz[j, i, k];
                     }
 
                     if ((gv->POS[3] == gv->NPROCZ - 1) && (k >= nb->nz2 + 1)) {
                         h1 = (k - nb->nz2 + gv->FW);
 
-                        pml_wfd->psi_vzz[j][i][h1] =
-                            pml_coeff->b_z[h1] * pml_wfd->psi_vzz[j][i][h1] + pml_coeff->a_z[h1] * vzz;
-                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd->psi_vzz[j][i][h1];
+                        pml_wfd.psi_vzz[j, i, h1] =
+                            pml_coeff->b_z[h1] * pml_wfd.psi_vzz[j, i, h1] + pml_coeff->a_z[h1] * vzz;
+                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd.psi_vzz[j, i, h1];
                     }
 
                     g = mod->pi[j][i][k];
@@ -175,21 +175,21 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
                         (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
                          b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) / gv->DZ;
 
-                    pml_wfd->psi_vyy[j][i][k] = pml_coeff->b_y[j] * pml_wfd->psi_vyy[j][i][k] + pml_coeff->a_y[j] * vyy;
-                    vyy = vyy / pml_coeff->K_y[j] + pml_wfd->psi_vyy[j][i][k];
+                    pml_wfd.psi_vyy[j, i, k] = pml_coeff->b_y[j] * pml_wfd.psi_vyy[j, i, k] + pml_coeff->a_y[j] * vyy;
+                    vyy = vyy / pml_coeff->K_y[j] + pml_wfd.psi_vyy[j, i, k];
 
                     if ((gv->POS[3] == 0) && (k <= gv->FW)) {
-                        pml_wfd->psi_vzz[j][i][k] =
-                            pml_coeff->b_z[k] * pml_wfd->psi_vzz[j][i][k] + pml_coeff->a_z[k] * vzz;
-                        vzz = vzz / pml_coeff->K_y[k] + pml_wfd->psi_vzz[j][i][k];
+                        pml_wfd.psi_vzz[j, i, k] =
+                            pml_coeff->b_z[k] * pml_wfd.psi_vzz[j, i, k] + pml_coeff->a_z[k] * vzz;
+                        vzz = vzz / pml_coeff->K_y[k] + pml_wfd.psi_vzz[j, i, k];
                     }
 
                     if ((gv->POS[3] == gv->NPROCZ - 1) && (k >= nb->nz2 + 1)) {
                         h1 = (k - nb->nz2 + gv->FW);
 
-                        pml_wfd->psi_vzz[j][i][h1] =
-                            pml_coeff->b_z[h1] * pml_wfd->psi_vzz[j][i][h1] + pml_coeff->a_z[h1] * vzz;
-                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd->psi_vzz[j][i][h1];
+                        pml_wfd.psi_vzz[j, i, h1] =
+                            pml_coeff->b_z[h1] * pml_wfd.psi_vzz[j, i, h1] + pml_coeff->a_z[h1] * vzz;
+                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd.psi_vzz[j, i, h1];
                     }
 
                     g = mod->pi[j][i][k];
@@ -219,22 +219,22 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
 
                     h1 = (j - nb->ny2 + gv->FW);
 
-                    pml_wfd->psi_vyy[h1][i][k] =
-                        pml_coeff->b_y[h1] * pml_wfd->psi_vyy[h1][i][k] + pml_coeff->a_y[h1] * vyy;
-                    vyy = vyy / pml_coeff->K_y[h1] + pml_wfd->psi_vyy[h1][i][k];
+                    pml_wfd.psi_vyy[h1, i, k] =
+                        pml_coeff->b_y[h1] * pml_wfd.psi_vyy[h1, i, k] + pml_coeff->a_y[h1] * vyy;
+                    vyy = vyy / pml_coeff->K_y[h1] + pml_wfd.psi_vyy[h1, i, k];
 
                     if ((gv->POS[3] == 0) && (k <= gv->FW)) {
-                        pml_wfd->psi_vzz[j][i][k] =
-                            pml_coeff->b_z[k] * pml_wfd->psi_vzz[j][i][k] + pml_coeff->a_z[k] * vzz;
-                        vzz = vzz / pml_coeff->K_y[k] + pml_wfd->psi_vzz[j][i][k];
+                        pml_wfd.psi_vzz[j, i, k] =
+                            pml_coeff->b_z[k] * pml_wfd.psi_vzz[j, i, k] + pml_coeff->a_z[k] * vzz;
+                        vzz = vzz / pml_coeff->K_y[k] + pml_wfd.psi_vzz[j, i, k];
                     }
 
                     if ((gv->POS[3] == gv->NPROCZ - 1) && (k >= nb->nz2 + 1)) {
                         h1 = (k - nb->nz2 + gv->FW);
 
-                        pml_wfd->psi_vzz[j][i][h1] =
-                            pml_coeff->b_z[h1] * pml_wfd->psi_vzz[j][i][h1] + pml_coeff->a_z[h1] * vzz;
-                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd->psi_vzz[j][i][h1];
+                        pml_wfd.psi_vzz[j, i, h1] =
+                            pml_coeff->b_z[h1] * pml_wfd.psi_vzz[j, i, h1] + pml_coeff->a_z[h1] * vzz;
+                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd.psi_vzz[j, i, h1];
                     }
 
                     g = mod->pi[j][i][k];
@@ -262,8 +262,8 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
                         (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
                          b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) / gv->DZ;
 
-                    pml_wfd->psi_vzz[j][i][k] = pml_coeff->b_z[k] * pml_wfd->psi_vzz[j][i][k] + pml_coeff->a_z[k] * vzz;
-                    vzz = vzz / pml_coeff->K_y[k] + pml_wfd->psi_vzz[j][i][k];
+                    pml_wfd.psi_vzz[j, i, k] = pml_coeff->b_z[k] * pml_wfd.psi_vzz[j, i, k] + pml_coeff->a_z[k] * vzz;
+                    vzz = vzz / pml_coeff->K_y[k] + pml_wfd.psi_vzz[j, i, k];
 
                     g = mod->pi[j][i][k];
 
@@ -292,9 +292,9 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
 
                     h1 = (k - nb->nz2 + gv->FW);
 
-                    pml_wfd->psi_vzz[j][i][h1] =
-                        pml_coeff->b_z[h1] * pml_wfd->psi_vzz[j][i][h1] + pml_coeff->a_z[h1] * vzz;
-                    vzz = vzz / pml_coeff->K_z[h1] + pml_wfd->psi_vzz[j][i][h1];
+                    pml_wfd.psi_vzz[j, i, h1] =
+                        pml_coeff->b_z[h1] * pml_wfd.psi_vzz[j, i, h1] + pml_coeff->a_z[h1] * vzz;
+                    vzz = vzz / pml_coeff->K_z[h1] + pml_wfd.psi_vzz[j, i, h1];
 
                     g = mod->pi[j][i][k];
 
diff --git a/src/update_s_ssg_CPML_elastic.cpp b/src/update_s_ssg_CPML_elastic.cpp
index a6a9017..755d15e 100644
--- a/src/update_s_ssg_CPML_elastic.cpp
+++ b/src/update_s_ssg_CPML_elastic.cpp
@@ -31,7 +31,7 @@
 
 double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                              st_stress &stress, st_model *mod, st_model_av &mod_av,
-                             st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, const GlobVar *gv)
+                             st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd, const GlobVar *gv)
 {
     int h1;
     float vxx, vxy, vxz, vyx, vyy, vyz, vzx, vzy, vzz;
@@ -86,65 +86,65 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                         (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
                          b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) * oodz;
 
-                    pml_wfd->psi_vxx[j][i][k] = pml_coeff->b_x[i] * pml_wfd->psi_vxx[j][i][k] + pml_coeff->a_x[i] * vxx;
-                    vxx = vxx / pml_coeff->K_x[i] + pml_wfd->psi_vxx[j][i][k];
-                    pml_wfd->psi_vyx[j][i][k] =
-                        pml_coeff->b_x_half[i] * pml_wfd->psi_vyx[j][i][k] + pml_coeff->a_x_half[i] * vyx;
-                    vyx = vyx / pml_coeff->K_x_half[i] + pml_wfd->psi_vyx[j][i][k];
-                    pml_wfd->psi_vzx[j][i][k] =
-                        pml_coeff->b_x_half[i] * pml_wfd->psi_vzx[j][i][k] + pml_coeff->a_x_half[i] * vzx;
-                    vzx = vzx / pml_coeff->K_x_half[i] + pml_wfd->psi_vzx[j][i][k];
+                    pml_wfd.psi_vxx[j, i, k] = pml_coeff->b_x[i] * pml_wfd.psi_vxx[j, i, k] + pml_coeff->a_x[i] * vxx;
+                    vxx = vxx / pml_coeff->K_x[i] + pml_wfd.psi_vxx[j, i, k];
+                    pml_wfd.psi_vyx[j, i, k] =
+                        pml_coeff->b_x_half[i] * pml_wfd.psi_vyx[j, i, k] + pml_coeff->a_x_half[i] * vyx;
+                    vyx = vyx / pml_coeff->K_x_half[i] + pml_wfd.psi_vyx[j, i, k];
+                    pml_wfd.psi_vzx[j, i, k] =
+                        pml_coeff->b_x_half[i] * pml_wfd.psi_vzx[j, i, k] + pml_coeff->a_x_half[i] * vzx;
+                    vzx = vzx / pml_coeff->K_x_half[i] + pml_wfd.psi_vzx[j, i, k];
 
                     if ((gv->POS[2] == 0 && gv->FREE_SURF == 0) && (j <= gv->FW)) {
-                        pml_wfd->psi_vxy[j][i][k] =
-                            pml_coeff->b_y_half[j] * pml_wfd->psi_vxy[j][i][k] + pml_coeff->a_y_half[j] * vxy;
-                        vxy = vxy / pml_coeff->K_y_half[j] + pml_wfd->psi_vxy[j][i][k];
-                        pml_wfd->psi_vyy[j][i][k] =
-                            pml_coeff->b_y[j] * pml_wfd->psi_vyy[j][i][k] + pml_coeff->a_y[j] * vyy;
-                        vyy = vyy / pml_coeff->K_y[j] + pml_wfd->psi_vyy[j][i][k];
-                        pml_wfd->psi_vzy[j][i][k] =
-                            pml_coeff->b_y_half[j] * pml_wfd->psi_vzy[j][i][k] + pml_coeff->a_y_half[j] * vzy;
-                        vzy = vzy / pml_coeff->K_y_half[j] + pml_wfd->psi_vzy[j][i][k];
+                        pml_wfd.psi_vxy[j, i, k] =
+                            pml_coeff->b_y_half[j] * pml_wfd.psi_vxy[j, i, k] + pml_coeff->a_y_half[j] * vxy;
+                        vxy = vxy / pml_coeff->K_y_half[j] + pml_wfd.psi_vxy[j, i, k];
+                        pml_wfd.psi_vyy[j, i, k] =
+                            pml_coeff->b_y[j] * pml_wfd.psi_vyy[j, i, k] + pml_coeff->a_y[j] * vyy;
+                        vyy = vyy / pml_coeff->K_y[j] + pml_wfd.psi_vyy[j, i, k];
+                        pml_wfd.psi_vzy[j, i, k] =
+                            pml_coeff->b_y_half[j] * pml_wfd.psi_vzy[j, i, k] + pml_coeff->a_y_half[j] * vzy;
+                        vzy = vzy / pml_coeff->K_y_half[j] + pml_wfd.psi_vzy[j, i, k];
                     }
 
                     if ((gv->POS[2] == gv->NPROCY - 1) && (j >= nb->ny2 + 1)) {
                         h1 = (j - nb->ny2 + gv->FW);
 
-                        pml_wfd->psi_vxy[h1][i][k] =
-                            pml_coeff->b_y_half[h1] * pml_wfd->psi_vxy[h1][i][k] + pml_coeff->a_y_half[h1] * vxy;
-                        vxy = vxy / pml_coeff->K_y_half[h1] + pml_wfd->psi_vxy[h1][i][k];
-                        pml_wfd->psi_vyy[h1][i][k] =
-                            pml_coeff->b_y[h1] * pml_wfd->psi_vyy[h1][i][k] + pml_coeff->a_y[h1] * vyy;
-                        vyy = vyy / pml_coeff->K_y[h1] + pml_wfd->psi_vyy[h1][i][k];
-                        pml_wfd->psi_vzy[h1][i][k] =
-                            pml_coeff->b_y_half[h1] * pml_wfd->psi_vzy[h1][i][k] + pml_coeff->a_y_half[h1] * vzy;
-                        vzy = vzy / pml_coeff->K_y_half[h1] + pml_wfd->psi_vzy[h1][i][k];
+                        pml_wfd.psi_vxy[h1, i, k] =
+                            pml_coeff->b_y_half[h1] * pml_wfd.psi_vxy[h1, i, k] + pml_coeff->a_y_half[h1] * vxy;
+                        vxy = vxy / pml_coeff->K_y_half[h1] + pml_wfd.psi_vxy[h1, i, k];
+                        pml_wfd.psi_vyy[h1, i, k] =
+                            pml_coeff->b_y[h1] * pml_wfd.psi_vyy[h1, i, k] + pml_coeff->a_y[h1] * vyy;
+                        vyy = vyy / pml_coeff->K_y[h1] + pml_wfd.psi_vyy[h1, i, k];
+                        pml_wfd.psi_vzy[h1, i, k] =
+                            pml_coeff->b_y_half[h1] * pml_wfd.psi_vzy[h1, i, k] + pml_coeff->a_y_half[h1] * vzy;
+                        vzy = vzy / pml_coeff->K_y_half[h1] + pml_wfd.psi_vzy[h1, i, k];
                     }
 
                     if ((gv->POS[3] == 0) && (k <= gv->FW)) {
-                        pml_wfd->psi_vxz[j][i][k] =
-                            pml_coeff->b_z_half[k] * pml_wfd->psi_vxz[j][i][k] + pml_coeff->a_z_half[k] * vxz;
-                        vxz = vxz / pml_coeff->K_y_half[k] + pml_wfd->psi_vxz[j][i][k];
-                        pml_wfd->psi_vyz[j][i][k] =
-                            pml_coeff->b_z_half[k] * pml_wfd->psi_vyz[j][i][k] + pml_coeff->a_z_half[k] * vyz;
-                        vyz = vyz / pml_coeff->K_y_half[k] + pml_wfd->psi_vyz[j][i][k];
-                        pml_wfd->psi_vzz[j][i][k] =
-                            pml_coeff->b_z[k] * pml_wfd->psi_vzz[j][i][k] + pml_coeff->a_z[k] * vzz;
-                        vzz = vzz / pml_coeff->K_y[k] + pml_wfd->psi_vzz[j][i][k];
+                        pml_wfd.psi_vxz[j, i, k] =
+                            pml_coeff->b_z_half[k] * pml_wfd.psi_vxz[j, i, k] + pml_coeff->a_z_half[k] * vxz;
+                        vxz = vxz / pml_coeff->K_y_half[k] + pml_wfd.psi_vxz[j, i, k];
+                        pml_wfd.psi_vyz[j, i, k] =
+                            pml_coeff->b_z_half[k] * pml_wfd.psi_vyz[j, i, k] + pml_coeff->a_z_half[k] * vyz;
+                        vyz = vyz / pml_coeff->K_y_half[k] + pml_wfd.psi_vyz[j, i, k];
+                        pml_wfd.psi_vzz[j, i, k] =
+                            pml_coeff->b_z[k] * pml_wfd.psi_vzz[j, i, k] + pml_coeff->a_z[k] * vzz;
+                        vzz = vzz / pml_coeff->K_y[k] + pml_wfd.psi_vzz[j, i, k];
                     }
 
                     if ((gv->POS[3] == gv->NPROCZ - 1) && (k >= nb->nz2 + 1)) {
                         h1 = (k - nb->nz2 + gv->FW);
 
-                        pml_wfd->psi_vxz[j][i][h1] =
-                            pml_coeff->b_z_half[h1] * pml_wfd->psi_vxz[j][i][h1] + pml_coeff->a_z_half[h1] * vxz;
-                        vxz = vxz / pml_coeff->K_z_half[h1] + pml_wfd->psi_vxz[j][i][h1];
-                        pml_wfd->psi_vyz[j][i][h1] =
-                            pml_coeff->b_z_half[h1] * pml_wfd->psi_vyz[j][i][h1] + pml_coeff->a_z_half[h1] * vyz;
-                        vyz = vyz / pml_coeff->K_z_half[h1] + pml_wfd->psi_vyz[j][i][h1];
-                        pml_wfd->psi_vzz[j][i][h1] =
-                            pml_coeff->b_z[h1] * pml_wfd->psi_vzz[j][i][h1] + pml_coeff->a_z[h1] * vzz;
-                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd->psi_vzz[j][i][h1];
+                        pml_wfd.psi_vxz[j, i, h1] =
+                            pml_coeff->b_z_half[h1] * pml_wfd.psi_vxz[j, i, h1] + pml_coeff->a_z_half[h1] * vxz;
+                        vxz = vxz / pml_coeff->K_z_half[h1] + pml_wfd.psi_vxz[j, i, h1];
+                        pml_wfd.psi_vyz[j, i, h1] =
+                            pml_coeff->b_z_half[h1] * pml_wfd.psi_vyz[j, i, h1] + pml_coeff->a_z_half[h1] * vyz;
+                        vyz = vyz / pml_coeff->K_z_half[h1] + pml_wfd.psi_vyz[j, i, h1];
+                        pml_wfd.psi_vzz[j, i, h1] =
+                            pml_coeff->b_z[h1] * pml_wfd.psi_vzz[j, i, h1] + pml_coeff->a_z[h1] * vzz;
+                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd.psi_vzz[j, i, h1];
                     }
 
                     fipjp = mod_av.uipjp[j, i, k] * gv->DT;
@@ -207,66 +207,66 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
 
                     h1 = i - nb->nx2 + gv->FW;
 
-                    pml_wfd->psi_vxx[j][h1][k] =
-                        pml_coeff->b_x[h1] * pml_wfd->psi_vxx[j][h1][k] + pml_coeff->a_x[h1] * vxx;
-                    vxx = vxx / pml_coeff->K_x[h1] + pml_wfd->psi_vxx[j][h1][k];
-                    pml_wfd->psi_vyx[j][h1][k] =
-                        pml_coeff->b_x_half[h1] * pml_wfd->psi_vyx[j][h1][k] + pml_coeff->a_x_half[h1] * vyx;
-                    vyx = vyx / pml_coeff->K_x_half[h1] + pml_wfd->psi_vyx[j][h1][k];
-                    pml_wfd->psi_vzx[j][h1][k] =
-                        pml_coeff->b_x_half[h1] * pml_wfd->psi_vzx[j][h1][k] + pml_coeff->a_x_half[h1] * vzx;
-                    vzx = vzx / pml_coeff->K_x_half[h1] + pml_wfd->psi_vzx[j][h1][k];
+                    pml_wfd.psi_vxx[j, h1, k] =
+                        pml_coeff->b_x[h1] * pml_wfd.psi_vxx[j, h1, k] + pml_coeff->a_x[h1] * vxx;
+                    vxx = vxx / pml_coeff->K_x[h1] + pml_wfd.psi_vxx[j, h1, k];
+                    pml_wfd.psi_vyx[j, h1, k] =
+                        pml_coeff->b_x_half[h1] * pml_wfd.psi_vyx[j, h1, k] + pml_coeff->a_x_half[h1] * vyx;
+                    vyx = vyx / pml_coeff->K_x_half[h1] + pml_wfd.psi_vyx[j, h1, k];
+                    pml_wfd.psi_vzx[j, h1, k] =
+                        pml_coeff->b_x_half[h1] * pml_wfd.psi_vzx[j, h1, k] + pml_coeff->a_x_half[h1] * vzx;
+                    vzx = vzx / pml_coeff->K_x_half[h1] + pml_wfd.psi_vzx[j, h1, k];
 
                     if ((gv->POS[2] == 0 && gv->FREE_SURF == 0) && (j <= gv->FW)) {
-                        pml_wfd->psi_vxy[j][i][k] =
-                            pml_coeff->b_y_half[j] * pml_wfd->psi_vxy[j][i][k] + pml_coeff->a_y_half[j] * vxy;
-                        vxy = vxy / pml_coeff->K_y_half[j] + pml_wfd->psi_vxy[j][i][k];
-                        pml_wfd->psi_vyy[j][i][k] =
-                            pml_coeff->b_y[j] * pml_wfd->psi_vyy[j][i][k] + pml_coeff->a_y[j] * vyy;
-                        vyy = vyy / pml_coeff->K_y[j] + pml_wfd->psi_vyy[j][i][k];
-                        pml_wfd->psi_vzy[j][i][k] =
-                            pml_coeff->b_y_half[j] * pml_wfd->psi_vzy[j][i][k] + pml_coeff->a_y_half[j] * vzy;
-                        vzy = vzy / pml_coeff->K_y_half[j] + pml_wfd->psi_vzy[j][i][k];
+                        pml_wfd.psi_vxy[j, i, k] =
+                            pml_coeff->b_y_half[j] * pml_wfd.psi_vxy[j, i, k] + pml_coeff->a_y_half[j] * vxy;
+                        vxy = vxy / pml_coeff->K_y_half[j] + pml_wfd.psi_vxy[j, i, k];
+                        pml_wfd.psi_vyy[j, i, k] =
+                            pml_coeff->b_y[j] * pml_wfd.psi_vyy[j, i, k] + pml_coeff->a_y[j] * vyy;
+                        vyy = vyy / pml_coeff->K_y[j] + pml_wfd.psi_vyy[j, i, k];
+                        pml_wfd.psi_vzy[j, i, k] =
+                            pml_coeff->b_y_half[j] * pml_wfd.psi_vzy[j, i, k] + pml_coeff->a_y_half[j] * vzy;
+                        vzy = vzy / pml_coeff->K_y_half[j] + pml_wfd.psi_vzy[j, i, k];
                     }
 
                     if ((gv->POS[2] == gv->NPROCY - 1) && (j >= nb->ny2 + 1)) {
                         h1 = (j - nb->ny2 + gv->FW);
 
-                        pml_wfd->psi_vxy[h1][i][k] =
-                            pml_coeff->b_y_half[h1] * pml_wfd->psi_vxy[h1][i][k] + pml_coeff->a_y_half[h1] * vxy;
-                        vxy = vxy / pml_coeff->K_y_half[h1] + pml_wfd->psi_vxy[h1][i][k];
-                        pml_wfd->psi_vyy[h1][i][k] =
-                            pml_coeff->b_y[h1] * pml_wfd->psi_vyy[h1][i][k] + pml_coeff->a_y[h1] * vyy;
-                        vyy = vyy / pml_coeff->K_y[h1] + pml_wfd->psi_vyy[h1][i][k];
-                        pml_wfd->psi_vzy[h1][i][k] =
-                            pml_coeff->b_y_half[h1] * pml_wfd->psi_vzy[h1][i][k] + pml_coeff->a_y_half[h1] * vzy;
-                        vzy = vzy / pml_coeff->K_y_half[h1] + pml_wfd->psi_vzy[h1][i][k];
+                        pml_wfd.psi_vxy[h1, i, k] =
+                            pml_coeff->b_y_half[h1] * pml_wfd.psi_vxy[h1, i, k] + pml_coeff->a_y_half[h1] * vxy;
+                        vxy = vxy / pml_coeff->K_y_half[h1] + pml_wfd.psi_vxy[h1, i, k];
+                        pml_wfd.psi_vyy[h1, i, k] =
+                            pml_coeff->b_y[h1] * pml_wfd.psi_vyy[h1, i, k] + pml_coeff->a_y[h1] * vyy;
+                        vyy = vyy / pml_coeff->K_y[h1] + pml_wfd.psi_vyy[h1, i, k];
+                        pml_wfd.psi_vzy[h1, i, k] =
+                            pml_coeff->b_y_half[h1] * pml_wfd.psi_vzy[h1, i, k] + pml_coeff->a_y_half[h1] * vzy;
+                        vzy = vzy / pml_coeff->K_y_half[h1] + pml_wfd.psi_vzy[h1, i, k];
                     }
 
                     if ((gv->POS[3] == 0) && (k <= gv->FW)) {
-                        pml_wfd->psi_vxz[j][i][k] =
-                            pml_coeff->b_z_half[k] * pml_wfd->psi_vxz[j][i][k] + pml_coeff->a_z_half[k] * vxz;
-                        vxz = vxz / pml_coeff->K_y_half[k] + pml_wfd->psi_vxz[j][i][k];
-                        pml_wfd->psi_vyz[j][i][k] =
-                            pml_coeff->b_z_half[k] * pml_wfd->psi_vyz[j][i][k] + pml_coeff->a_z_half[k] * vyz;
-                        vyz = vyz / pml_coeff->K_y_half[k] + pml_wfd->psi_vyz[j][i][k];
-                        pml_wfd->psi_vzz[j][i][k] =
-                            pml_coeff->b_z[k] * pml_wfd->psi_vzz[j][i][k] + pml_coeff->a_z[k] * vzz;
-                        vzz = vzz / pml_coeff->K_y[k] + pml_wfd->psi_vzz[j][i][k];
+                        pml_wfd.psi_vxz[j, i, k] =
+                            pml_coeff->b_z_half[k] * pml_wfd.psi_vxz[j, i, k] + pml_coeff->a_z_half[k] * vxz;
+                        vxz = vxz / pml_coeff->K_y_half[k] + pml_wfd.psi_vxz[j, i, k];
+                        pml_wfd.psi_vyz[j, i, k] =
+                            pml_coeff->b_z_half[k] * pml_wfd.psi_vyz[j, i, k] + pml_coeff->a_z_half[k] * vyz;
+                        vyz = vyz / pml_coeff->K_y_half[k] + pml_wfd.psi_vyz[j, i, k];
+                        pml_wfd.psi_vzz[j, i, k] =
+                            pml_coeff->b_z[k] * pml_wfd.psi_vzz[j, i, k] + pml_coeff->a_z[k] * vzz;
+                        vzz = vzz / pml_coeff->K_y[k] + pml_wfd.psi_vzz[j, i, k];
                     }
 
                     if ((gv->POS[3] == gv->NPROCZ - 1) && (k >= nb->nz2 + 1)) {
                         h1 = (k - nb->nz2 + gv->FW);
 
-                        pml_wfd->psi_vxz[j][i][h1] =
-                            pml_coeff->b_z_half[h1] * pml_wfd->psi_vxz[j][i][h1] + pml_coeff->a_z_half[h1] * vxz;
-                        vxz = vxz / pml_coeff->K_z_half[h1] + pml_wfd->psi_vxz[j][i][h1];
-                        pml_wfd->psi_vyz[j][i][h1] =
-                            pml_coeff->b_z_half[h1] * pml_wfd->psi_vyz[j][i][h1] + pml_coeff->a_z_half[h1] * vyz;
-                        vyz = vyz / pml_coeff->K_z_half[h1] + pml_wfd->psi_vyz[j][i][h1];
-                        pml_wfd->psi_vzz[j][i][h1] =
-                            pml_coeff->b_z[h1] * pml_wfd->psi_vzz[j][i][h1] + pml_coeff->a_z[h1] * vzz;
-                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd->psi_vzz[j][i][h1];
+                        pml_wfd.psi_vxz[j, i, h1] =
+                            pml_coeff->b_z_half[h1] * pml_wfd.psi_vxz[j, i, h1] + pml_coeff->a_z_half[h1] * vxz;
+                        vxz = vxz / pml_coeff->K_z_half[h1] + pml_wfd.psi_vxz[j, i, h1];
+                        pml_wfd.psi_vyz[j, i, h1] =
+                            pml_coeff->b_z_half[h1] * pml_wfd.psi_vyz[j, i, h1] + pml_coeff->a_z_half[h1] * vyz;
+                        vyz = vyz / pml_coeff->K_z_half[h1] + pml_wfd.psi_vyz[j, i, h1];
+                        pml_wfd.psi_vzz[j, i, h1] =
+                            pml_coeff->b_z[h1] * pml_wfd.psi_vzz[j, i, h1] + pml_coeff->a_z[h1] * vzz;
+                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd.psi_vzz[j, i, h1];
                     }
 
                     fipjp = mod_av.uipjp[j, i, k] * gv->DT;
@@ -329,39 +329,39 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                         (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
                          b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) * oodz;
 
-                    pml_wfd->psi_vxy[j][i][k] =
-                        pml_coeff->b_y_half[j] * pml_wfd->psi_vxy[j][i][k] + pml_coeff->a_y_half[j] * vxy;
-                    vxy = vxy / pml_coeff->K_y_half[j] + pml_wfd->psi_vxy[j][i][k];
-                    pml_wfd->psi_vyy[j][i][k] = pml_coeff->b_y[j] * pml_wfd->psi_vyy[j][i][k] + pml_coeff->a_y[j] * vyy;
-                    vyy = vyy / pml_coeff->K_y[j] + pml_wfd->psi_vyy[j][i][k];
-                    pml_wfd->psi_vzy[j][i][k] =
-                        pml_coeff->b_y_half[j] * pml_wfd->psi_vzy[j][i][k] + pml_coeff->a_y_half[j] * vzy;
-                    vzy = vzy / pml_coeff->K_y_half[j] + pml_wfd->psi_vzy[j][i][k];
+                    pml_wfd.psi_vxy[j, i, k] =
+                        pml_coeff->b_y_half[j] * pml_wfd.psi_vxy[j, i, k] + pml_coeff->a_y_half[j] * vxy;
+                    vxy = vxy / pml_coeff->K_y_half[j] + pml_wfd.psi_vxy[j, i, k];
+                    pml_wfd.psi_vyy[j, i, k] = pml_coeff->b_y[j] * pml_wfd.psi_vyy[j, i, k] + pml_coeff->a_y[j] * vyy;
+                    vyy = vyy / pml_coeff->K_y[j] + pml_wfd.psi_vyy[j, i, k];
+                    pml_wfd.psi_vzy[j, i, k] =
+                        pml_coeff->b_y_half[j] * pml_wfd.psi_vzy[j, i, k] + pml_coeff->a_y_half[j] * vzy;
+                    vzy = vzy / pml_coeff->K_y_half[j] + pml_wfd.psi_vzy[j, i, k];
 
                     if ((gv->POS[3] == 0) && (k <= gv->FW)) {
-                        pml_wfd->psi_vxz[j][i][k] =
-                            pml_coeff->b_z_half[k] * pml_wfd->psi_vxz[j][i][k] + pml_coeff->a_z_half[k] * vxz;
-                        vxz = vxz / pml_coeff->K_y_half[k] + pml_wfd->psi_vxz[j][i][k];
-                        pml_wfd->psi_vyz[j][i][k] =
-                            pml_coeff->b_z_half[k] * pml_wfd->psi_vyz[j][i][k] + pml_coeff->a_z_half[k] * vyz;
-                        vyz = vyz / pml_coeff->K_y_half[k] + pml_wfd->psi_vyz[j][i][k];
-                        pml_wfd->psi_vzz[j][i][k] =
-                            pml_coeff->b_z[k] * pml_wfd->psi_vzz[j][i][k] + pml_coeff->a_z[k] * vzz;
-                        vzz = vzz / pml_coeff->K_y[k] + pml_wfd->psi_vzz[j][i][k];
+                        pml_wfd.psi_vxz[j, i, k] =
+                            pml_coeff->b_z_half[k] * pml_wfd.psi_vxz[j, i, k] + pml_coeff->a_z_half[k] * vxz;
+                        vxz = vxz / pml_coeff->K_y_half[k] + pml_wfd.psi_vxz[j, i, k];
+                        pml_wfd.psi_vyz[j, i, k] =
+                            pml_coeff->b_z_half[k] * pml_wfd.psi_vyz[j, i, k] + pml_coeff->a_z_half[k] * vyz;
+                        vyz = vyz / pml_coeff->K_y_half[k] + pml_wfd.psi_vyz[j, i, k];
+                        pml_wfd.psi_vzz[j, i, k] =
+                            pml_coeff->b_z[k] * pml_wfd.psi_vzz[j, i, k] + pml_coeff->a_z[k] * vzz;
+                        vzz = vzz / pml_coeff->K_y[k] + pml_wfd.psi_vzz[j, i, k];
                     }
 
                     if ((gv->POS[3] == gv->NPROCZ - 1) && (k >= nb->nz2 + 1)) {
                         h1 = (k - nb->nz2 + gv->FW);
 
-                        pml_wfd->psi_vxz[j][i][h1] =
-                            pml_coeff->b_z_half[h1] * pml_wfd->psi_vxz[j][i][h1] + pml_coeff->a_z_half[h1] * vxz;
-                        vxz = vxz / pml_coeff->K_z_half[h1] + pml_wfd->psi_vxz[j][i][h1];
-                        pml_wfd->psi_vyz[j][i][h1] =
-                            pml_coeff->b_z_half[h1] * pml_wfd->psi_vyz[j][i][h1] + pml_coeff->a_z_half[h1] * vyz;
-                        vyz = vyz / pml_coeff->K_z_half[h1] + pml_wfd->psi_vyz[j][i][h1];
-                        pml_wfd->psi_vzz[j][i][h1] =
-                            pml_coeff->b_z[h1] * pml_wfd->psi_vzz[j][i][h1] + pml_coeff->a_z[h1] * vzz;
-                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd->psi_vzz[j][i][h1];
+                        pml_wfd.psi_vxz[j, i, h1] =
+                            pml_coeff->b_z_half[h1] * pml_wfd.psi_vxz[j, i, h1] + pml_coeff->a_z_half[h1] * vxz;
+                        vxz = vxz / pml_coeff->K_z_half[h1] + pml_wfd.psi_vxz[j, i, h1];
+                        pml_wfd.psi_vyz[j, i, h1] =
+                            pml_coeff->b_z_half[h1] * pml_wfd.psi_vyz[j, i, h1] + pml_coeff->a_z_half[h1] * vyz;
+                        vyz = vyz / pml_coeff->K_z_half[h1] + pml_wfd.psi_vyz[j, i, h1];
+                        pml_wfd.psi_vzz[j, i, h1] =
+                            pml_coeff->b_z[h1] * pml_wfd.psi_vzz[j, i, h1] + pml_coeff->a_z[h1] * vzz;
+                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd.psi_vzz[j, i, h1];
                     }
 
                     fipjp = mod_av.uipjp[j, i, k] * gv->DT;
@@ -424,40 +424,40 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
 
                     h1 = (j - nb->ny2 + gv->FW);
 
-                    pml_wfd->psi_vxy[h1][i][k] =
-                        pml_coeff->b_y_half[h1] * pml_wfd->psi_vxy[h1][i][k] + pml_coeff->a_y_half[h1] * vxy;
-                    vxy = vxy / pml_coeff->K_y_half[h1] + pml_wfd->psi_vxy[h1][i][k];
-                    pml_wfd->psi_vyy[h1][i][k] =
-                        pml_coeff->b_y[h1] * pml_wfd->psi_vyy[h1][i][k] + pml_coeff->a_y[h1] * vyy;
-                    vyy = vyy / pml_coeff->K_y[h1] + pml_wfd->psi_vyy[h1][i][k];
-                    pml_wfd->psi_vzy[h1][i][k] =
-                        pml_coeff->b_y_half[h1] * pml_wfd->psi_vzy[h1][i][k] + pml_coeff->a_y_half[h1] * vzy;
-                    vzy = vzy / pml_coeff->K_y_half[h1] + pml_wfd->psi_vzy[h1][i][k];
+                    pml_wfd.psi_vxy[h1, i, k] =
+                        pml_coeff->b_y_half[h1] * pml_wfd.psi_vxy[h1, i, k] + pml_coeff->a_y_half[h1] * vxy;
+                    vxy = vxy / pml_coeff->K_y_half[h1] + pml_wfd.psi_vxy[h1, i, k];
+                    pml_wfd.psi_vyy[h1, i, k] =
+                        pml_coeff->b_y[h1] * pml_wfd.psi_vyy[h1, i, k] + pml_coeff->a_y[h1] * vyy;
+                    vyy = vyy / pml_coeff->K_y[h1] + pml_wfd.psi_vyy[h1, i, k];
+                    pml_wfd.psi_vzy[h1, i, k] =
+                        pml_coeff->b_y_half[h1] * pml_wfd.psi_vzy[h1, i, k] + pml_coeff->a_y_half[h1] * vzy;
+                    vzy = vzy / pml_coeff->K_y_half[h1] + pml_wfd.psi_vzy[h1, i, k];
 
                     if ((gv->POS[3] == 0) && (k <= gv->FW)) {
-                        pml_wfd->psi_vxz[j][i][k] =
-                            pml_coeff->b_z_half[k] * pml_wfd->psi_vxz[j][i][k] + pml_coeff->a_z_half[k] * vxz;
-                        vxz = vxz / pml_coeff->K_y_half[k] + pml_wfd->psi_vxz[j][i][k];
-                        pml_wfd->psi_vyz[j][i][k] =
-                            pml_coeff->b_z_half[k] * pml_wfd->psi_vyz[j][i][k] + pml_coeff->a_z_half[k] * vyz;
-                        vyz = vyz / pml_coeff->K_y_half[k] + pml_wfd->psi_vyz[j][i][k];
-                        pml_wfd->psi_vzz[j][i][k] =
-                            pml_coeff->b_z[k] * pml_wfd->psi_vzz[j][i][k] + pml_coeff->a_z[k] * vzz;
-                        vzz = vzz / pml_coeff->K_y[k] + pml_wfd->psi_vzz[j][i][k];
+                        pml_wfd.psi_vxz[j, i, k] =
+                            pml_coeff->b_z_half[k] * pml_wfd.psi_vxz[j, i, k] + pml_coeff->a_z_half[k] * vxz;
+                        vxz = vxz / pml_coeff->K_y_half[k] + pml_wfd.psi_vxz[j, i, k];
+                        pml_wfd.psi_vyz[j, i, k] =
+                            pml_coeff->b_z_half[k] * pml_wfd.psi_vyz[j, i, k] + pml_coeff->a_z_half[k] * vyz;
+                        vyz = vyz / pml_coeff->K_y_half[k] + pml_wfd.psi_vyz[j, i, k];
+                        pml_wfd.psi_vzz[j, i, k] =
+                            pml_coeff->b_z[k] * pml_wfd.psi_vzz[j, i, k] + pml_coeff->a_z[k] * vzz;
+                        vzz = vzz / pml_coeff->K_y[k] + pml_wfd.psi_vzz[j, i, k];
                     }
 
                     if ((gv->POS[3] == gv->NPROCZ - 1) && (k >= nb->nz2 + 1)) {
                         h1 = (k - nb->nz2 + gv->FW);
 
-                        pml_wfd->psi_vxz[j][i][h1] =
-                            pml_coeff->b_z_half[h1] * pml_wfd->psi_vxz[j][i][h1] + pml_coeff->a_z_half[h1] * vxz;
-                        vxz = vxz / pml_coeff->K_z_half[h1] + pml_wfd->psi_vxz[j][i][h1];
-                        pml_wfd->psi_vyz[j][i][h1] =
-                            pml_coeff->b_z_half[h1] * pml_wfd->psi_vyz[j][i][h1] + pml_coeff->a_z_half[h1] * vyz;
-                        vyz = vyz / pml_coeff->K_z_half[h1] + pml_wfd->psi_vyz[j][i][h1];
-                        pml_wfd->psi_vzz[j][i][h1] =
-                            pml_coeff->b_z[h1] * pml_wfd->psi_vzz[j][i][h1] + pml_coeff->a_z[h1] * vzz;
-                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd->psi_vzz[j][i][h1];
+                        pml_wfd.psi_vxz[j, i, h1] =
+                            pml_coeff->b_z_half[h1] * pml_wfd.psi_vxz[j, i, h1] + pml_coeff->a_z_half[h1] * vxz;
+                        vxz = vxz / pml_coeff->K_z_half[h1] + pml_wfd.psi_vxz[j, i, h1];
+                        pml_wfd.psi_vyz[j, i, h1] =
+                            pml_coeff->b_z_half[h1] * pml_wfd.psi_vyz[j, i, h1] + pml_coeff->a_z_half[h1] * vyz;
+                        vyz = vyz / pml_coeff->K_z_half[h1] + pml_wfd.psi_vyz[j, i, h1];
+                        pml_wfd.psi_vzz[j, i, h1] =
+                            pml_coeff->b_z[h1] * pml_wfd.psi_vzz[j, i, h1] + pml_coeff->a_z[h1] * vzz;
+                        vzz = vzz / pml_coeff->K_z[h1] + pml_wfd.psi_vzz[j, i, h1];
                     }
 
                     fipjp = mod_av.uipjp[j, i, k] * gv->DT;
@@ -520,14 +520,14 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                         (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
                          b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) * oodz;
 
-                    pml_wfd->psi_vxz[j][i][k] =
-                        pml_coeff->b_z_half[k] * pml_wfd->psi_vxz[j][i][k] + pml_coeff->a_z_half[k] * vxz;
-                    vxz = vxz / pml_coeff->K_y_half[k] + pml_wfd->psi_vxz[j][i][k];
-                    pml_wfd->psi_vyz[j][i][k] =
-                        pml_coeff->b_z_half[k] * pml_wfd->psi_vyz[j][i][k] + pml_coeff->a_z_half[k] * vyz;
-                    vyz = vyz / pml_coeff->K_y_half[k] + pml_wfd->psi_vyz[j][i][k];
-                    pml_wfd->psi_vzz[j][i][k] = pml_coeff->b_z[k] * pml_wfd->psi_vzz[j][i][k] + pml_coeff->a_z[k] * vzz;
-                    vzz = vzz / pml_coeff->K_y[k] + pml_wfd->psi_vzz[j][i][k];
+                    pml_wfd.psi_vxz[j, i, k] =
+                        pml_coeff->b_z_half[k] * pml_wfd.psi_vxz[j, i, k] + pml_coeff->a_z_half[k] * vxz;
+                    vxz = vxz / pml_coeff->K_y_half[k] + pml_wfd.psi_vxz[j, i, k];
+                    pml_wfd.psi_vyz[j, i, k] =
+                        pml_coeff->b_z_half[k] * pml_wfd.psi_vyz[j, i, k] + pml_coeff->a_z_half[k] * vyz;
+                    vyz = vyz / pml_coeff->K_y_half[k] + pml_wfd.psi_vyz[j, i, k];
+                    pml_wfd.psi_vzz[j, i, k] = pml_coeff->b_z[k] * pml_wfd.psi_vzz[j, i, k] + pml_coeff->a_z[k] * vzz;
+                    vzz = vzz / pml_coeff->K_y[k] + pml_wfd.psi_vzz[j, i, k];
 
                     fipjp = mod_av.uipjp[j, i, k] * gv->DT;
                     fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
@@ -589,15 +589,15 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
 
                     h1 = (k - nb->nz2 + gv->FW);
 
-                    pml_wfd->psi_vxz[j][i][h1] =
-                        pml_coeff->b_z_half[h1] * pml_wfd->psi_vxz[j][i][h1] + pml_coeff->a_z_half[h1] * vxz;
-                    vxz = vxz / pml_coeff->K_z_half[h1] + pml_wfd->psi_vxz[j][i][h1];
-                    pml_wfd->psi_vyz[j][i][h1] =
-                        pml_coeff->b_z_half[h1] * pml_wfd->psi_vyz[j][i][h1] + pml_coeff->a_z_half[h1] * vyz;
-                    vyz = vyz / pml_coeff->K_z_half[h1] + pml_wfd->psi_vyz[j][i][h1];
-                    pml_wfd->psi_vzz[j][i][h1] =
-                        pml_coeff->b_z[h1] * pml_wfd->psi_vzz[j][i][h1] + pml_coeff->a_z[h1] * vzz;
-                    vzz = vzz / pml_coeff->K_z[h1] + pml_wfd->psi_vzz[j][i][h1];
+                    pml_wfd.psi_vxz[j, i, h1] =
+                        pml_coeff->b_z_half[h1] * pml_wfd.psi_vxz[j, i, h1] + pml_coeff->a_z_half[h1] * vxz;
+                    vxz = vxz / pml_coeff->K_z_half[h1] + pml_wfd.psi_vxz[j, i, h1];
+                    pml_wfd.psi_vyz[j, i, h1] =
+                        pml_coeff->b_z_half[h1] * pml_wfd.psi_vyz[j, i, h1] + pml_coeff->a_z_half[h1] * vyz;
+                    vyz = vyz / pml_coeff->K_z_half[h1] + pml_wfd.psi_vyz[j, i, h1];
+                    pml_wfd.psi_vzz[j, i, h1] =
+                        pml_coeff->b_z[h1] * pml_wfd.psi_vzz[j, i, h1] + pml_coeff->a_z[h1] * vzz;
+                    vzz = vzz / pml_coeff->K_z[h1] + pml_wfd.psi_vzz[j, i, h1];
 
                     fipjp = mod_av.uipjp[j, i, k] * gv->DT;
                     fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
diff --git a/src/update_v_ssg_CPML.cpp b/src/update_v_ssg_CPML.cpp
index b8ba59b..37a607a 100644
--- a/src/update_v_ssg_CPML.cpp
+++ b/src/update_v_ssg_CPML.cpp
@@ -31,7 +31,7 @@
 #define UNUSED(x) (void)(x)
 
 void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av &mod_av,
-                   st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, const GlobVar *gv)
+                   st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd, const GlobVar *gv)
 {
     float sxx_x = 0.0, sxy_y = 0.0, sxz_z = 0.0, syy_y = 0.0, sxy_x = 0.0, syz_z = 0.0;
     float szz_z = 0.0, sxz_x = 0.0, syz_y = 0.0;
@@ -83,64 +83,64 @@ void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress &stress, st_mode
                     szz_z =
                         dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
                               b2 * (stress.szz[j, i, k + 2] - stress.szz[j, i, k - 1]));
-                    pml_wfd->psi_sxx_x[j][i][k] =
-                        pml_coeff->b_x_half[i] * pml_wfd->psi_sxx_x[j][i][k] + pml_coeff->a_x_half[i] * sxx_x;
-                    sxx_x = sxx_x / pml_coeff->K_x_half[i] + pml_wfd->psi_sxx_x[j][i][k];
-                    pml_wfd->psi_sxy_x[j][i][k] =
-                        pml_coeff->b_x[i] * pml_wfd->psi_sxy_x[j][i][k] + pml_coeff->a_x[i] * sxy_x;
-                    sxy_x = sxy_x / pml_coeff->K_x[i] + pml_wfd->psi_sxy_x[j][i][k];
-                    pml_wfd->psi_sxz_x[j][i][k] =
-                        pml_coeff->b_x[i] * pml_wfd->psi_sxz_x[j][i][k] + pml_coeff->a_x[i] * sxz_x;
-                    sxz_x = sxz_x / pml_coeff->K_x[i] + pml_wfd->psi_sxz_x[j][i][k];
+                    pml_wfd.psi_sxx_x[j, i, k] =
+                        pml_coeff->b_x_half[i] * pml_wfd.psi_sxx_x[j, i, k] + pml_coeff->a_x_half[i] * sxx_x;
+                    sxx_x = sxx_x / pml_coeff->K_x_half[i] + pml_wfd.psi_sxx_x[j, i, k];
+                    pml_wfd.psi_sxy_x[j, i, k] =
+                        pml_coeff->b_x[i] * pml_wfd.psi_sxy_x[j, i, k] + pml_coeff->a_x[i] * sxy_x;
+                    sxy_x = sxy_x / pml_coeff->K_x[i] + pml_wfd.psi_sxy_x[j, i, k];
+                    pml_wfd.psi_sxz_x[j, i, k] =
+                        pml_coeff->b_x[i] * pml_wfd.psi_sxz_x[j, i, k] + pml_coeff->a_x[i] * sxz_x;
+                    sxz_x = sxz_x / pml_coeff->K_x[i] + pml_wfd.psi_sxz_x[j, i, k];
 
                     if ((gv->POS[2] == 0 && gv->FREE_SURF == 0) && (j <= gv->FW)) {
-                        pml_wfd->psi_sxy_y[j][i][k] =
-                            pml_coeff->b_y[j] * pml_wfd->psi_sxy_y[j][i][k] + pml_coeff->a_y[j] * sxy_y;
-                        sxy_y = sxy_y / pml_coeff->K_y[j] + pml_wfd->psi_sxy_y[j][i][k];
-                        pml_wfd->psi_syy_y[j][i][k] =
-                            pml_coeff->b_y_half[j] * pml_wfd->psi_syy_y[j][i][k] + pml_coeff->a_y_half[j] * syy_y;
-                        syy_y = syy_y / pml_coeff->K_y_half[j] + pml_wfd->psi_syy_y[j][i][k];
-                        pml_wfd->psi_syz_y[j][i][k] =
-                            pml_coeff->b_y[j] * pml_wfd->psi_syz_y[j][i][k] + pml_coeff->a_y[j] * syz_y;
-                        syz_y = syz_y / pml_coeff->K_y[j] + pml_wfd->psi_syz_y[j][i][k];
+                        pml_wfd.psi_sxy_y[j, i, k] =
+                            pml_coeff->b_y[j] * pml_wfd.psi_sxy_y[j, i, k] + pml_coeff->a_y[j] * sxy_y;
+                        sxy_y = sxy_y / pml_coeff->K_y[j] + pml_wfd.psi_sxy_y[j, i, k];
+                        pml_wfd.psi_syy_y[j, i, k] =
+                            pml_coeff->b_y_half[j] * pml_wfd.psi_syy_y[j, i, k] + pml_coeff->a_y_half[j] * syy_y;
+                        syy_y = syy_y / pml_coeff->K_y_half[j] + pml_wfd.psi_syy_y[j, i, k];
+                        pml_wfd.psi_syz_y[j, i, k] =
+                            pml_coeff->b_y[j] * pml_wfd.psi_syz_y[j, i, k] + pml_coeff->a_y[j] * syz_y;
+                        syz_y = syz_y / pml_coeff->K_y[j] + pml_wfd.psi_syz_y[j, i, k];
                     }
 
                     if ((gv->POS[2] == gv->NPROCY - 1) && (j >= nb->ny2 + 1)) {
                         h1 = (j - nb->ny2 + gv->FW);
-                        pml_wfd->psi_sxy_y[h1][i][k] =
-                            pml_coeff->b_y[h1] * pml_wfd->psi_sxy_y[h1][i][k] + pml_coeff->a_y[h1] * sxy_y;
-                        sxy_y = sxy_y / pml_coeff->K_y[h1] + pml_wfd->psi_sxy_y[h1][i][k];
-                        pml_wfd->psi_syy_y[h1][i][k] =
-                            pml_coeff->b_y_half[h1] * pml_wfd->psi_syy_y[h1][i][k] + pml_coeff->a_y_half[h1] * syy_y;
-                        syy_y = syy_y / pml_coeff->K_y_half[h1] + pml_wfd->psi_syy_y[h1][i][k];
-                        pml_wfd->psi_syz_y[h1][i][k] =
-                            pml_coeff->b_y[h1] * pml_wfd->psi_syz_y[h1][i][k] + pml_coeff->a_y[h1] * syz_y;
-                        syz_y = syz_y / pml_coeff->K_y[h1] + pml_wfd->psi_syz_y[h1][i][k];
+                        pml_wfd.psi_sxy_y[h1, i, k] =
+                            pml_coeff->b_y[h1] * pml_wfd.psi_sxy_y[h1, i, k] + pml_coeff->a_y[h1] * sxy_y;
+                        sxy_y = sxy_y / pml_coeff->K_y[h1] + pml_wfd.psi_sxy_y[h1, i, k];
+                        pml_wfd.psi_syy_y[h1, i, k] =
+                            pml_coeff->b_y_half[h1] * pml_wfd.psi_syy_y[h1, i, k] + pml_coeff->a_y_half[h1] * syy_y;
+                        syy_y = syy_y / pml_coeff->K_y_half[h1] + pml_wfd.psi_syy_y[h1, i, k];
+                        pml_wfd.psi_syz_y[h1, i, k] =
+                            pml_coeff->b_y[h1] * pml_wfd.psi_syz_y[h1, i, k] + pml_coeff->a_y[h1] * syz_y;
+                        syz_y = syz_y / pml_coeff->K_y[h1] + pml_wfd.psi_syz_y[h1, i, k];
                     }
 
                     if ((gv->POS[3] == 0) && (k <= gv->FW)) {
-                        pml_wfd->psi_sxz_z[j][i][k] =
-                            pml_coeff->b_z[k] * pml_wfd->psi_sxz_z[j][i][k] + pml_coeff->a_z[k] * sxz_z;
-                        sxz_z = sxz_z / pml_coeff->K_z[k] + pml_wfd->psi_sxz_z[j][i][k];
-                        pml_wfd->psi_syz_z[j][i][k] =
-                            pml_coeff->b_z[k] * pml_wfd->psi_syz_z[j][i][k] + pml_coeff->a_z[k] * syz_z;
-                        syz_z = syz_z / pml_coeff->K_z[k] + pml_wfd->psi_syz_z[j][i][k];
-                        pml_wfd->psi_szz_z[j][i][k] =
-                            pml_coeff->b_z_half[k] * pml_wfd->psi_szz_z[j][i][k] + pml_coeff->a_z_half[k] * szz_z;
-                        szz_z = szz_z / pml_coeff->K_z_half[k] + pml_wfd->psi_szz_z[j][i][k];
+                        pml_wfd.psi_sxz_z[j, i, k] =
+                            pml_coeff->b_z[k] * pml_wfd.psi_sxz_z[j, i, k] + pml_coeff->a_z[k] * sxz_z;
+                        sxz_z = sxz_z / pml_coeff->K_z[k] + pml_wfd.psi_sxz_z[j, i, k];
+                        pml_wfd.psi_syz_z[j, i, k] =
+                            pml_coeff->b_z[k] * pml_wfd.psi_syz_z[j, i, k] + pml_coeff->a_z[k] * syz_z;
+                        syz_z = syz_z / pml_coeff->K_z[k] + pml_wfd.psi_syz_z[j, i, k];
+                        pml_wfd.psi_szz_z[j, i, k] =
+                            pml_coeff->b_z_half[k] * pml_wfd.psi_szz_z[j, i, k] + pml_coeff->a_z_half[k] * szz_z;
+                        szz_z = szz_z / pml_coeff->K_z_half[k] + pml_wfd.psi_szz_z[j, i, k];
                     }
 
                     if ((gv->POS[3] == gv->NPROCZ - 1) && (k >= nb->nz2 + 1)) {
                         h1 = (k - nb->nz2 + gv->FW);
-                        pml_wfd->psi_sxz_z[j][i][h1] =
-                            pml_coeff->b_z[h1] * pml_wfd->psi_sxz_z[j][i][h1] + pml_coeff->a_z[h1] * sxz_z;
-                        sxz_z = sxz_z / pml_coeff->K_z[h1] + pml_wfd->psi_sxz_z[j][i][h1];
-                        pml_wfd->psi_syz_z[j][i][h1] =
-                            pml_coeff->b_z[h1] * pml_wfd->psi_syz_z[j][i][h1] + pml_coeff->a_z[h1] * syz_z;
-                        syz_z = syz_z / pml_coeff->K_z[h1] + pml_wfd->psi_syz_z[j][i][h1];
-                        pml_wfd->psi_szz_z[j][i][h1] =
-                            pml_coeff->b_z_half[h1] * pml_wfd->psi_szz_z[j][i][h1] + pml_coeff->a_z_half[h1] * szz_z;
-                        szz_z = szz_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_szz_z[j][i][h1];
+                        pml_wfd.psi_sxz_z[j, i, h1] =
+                            pml_coeff->b_z[h1] * pml_wfd.psi_sxz_z[j, i, h1] + pml_coeff->a_z[h1] * sxz_z;
+                        sxz_z = sxz_z / pml_coeff->K_z[h1] + pml_wfd.psi_sxz_z[j, i, h1];
+                        pml_wfd.psi_syz_z[j, i, h1] =
+                            pml_coeff->b_z[h1] * pml_wfd.psi_syz_z[j, i, h1] + pml_coeff->a_z[h1] * syz_z;
+                        syz_z = syz_z / pml_coeff->K_z[h1] + pml_wfd.psi_syz_z[j, i, h1];
+                        pml_wfd.psi_szz_z[j, i, h1] =
+                            pml_coeff->b_z_half[h1] * pml_wfd.psi_szz_z[j, i, h1] + pml_coeff->a_z_half[h1] * szz_z;
+                        szz_z = szz_z / pml_coeff->K_z_half[h1] + pml_wfd.psi_szz_z[j, i, h1];
                     }
 
                     vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av.rip[j, i, k];
@@ -184,64 +184,64 @@ void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress &stress, st_mode
                         dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
                               b2 * (stress.szz[j, i, k + 2] - stress.szz[j, i, k - 1]));
                     h1 = (i - nb->nx2 + gv->FW);
-                    pml_wfd->psi_sxx_x[j][h1][k] =
-                        pml_coeff->b_x_half[h1] * pml_wfd->psi_sxx_x[j][h1][k] + pml_coeff->a_x_half[h1] * sxx_x;
-                    sxx_x = sxx_x / pml_coeff->K_x_half[h1] + pml_wfd->psi_sxx_x[j][h1][k];
-                    pml_wfd->psi_sxy_x[j][h1][k] =
-                        pml_coeff->b_x[h1] * pml_wfd->psi_sxy_x[j][h1][k] + pml_coeff->a_x[h1] * sxy_x;
-                    sxy_x = sxy_x / pml_coeff->K_x[h1] + pml_wfd->psi_sxy_x[j][h1][k];
-                    pml_wfd->psi_sxz_x[j][h1][k] =
-                        pml_coeff->b_x[h1] * pml_wfd->psi_sxz_x[j][h1][k] + pml_coeff->a_x[h1] * sxz_x;
-                    sxz_x = sxz_x / pml_coeff->K_x[h1] + pml_wfd->psi_sxz_x[j][h1][k];
+                    pml_wfd.psi_sxx_x[j, h1, k] =
+                        pml_coeff->b_x_half[h1] * pml_wfd.psi_sxx_x[j, h1, k] + pml_coeff->a_x_half[h1] * sxx_x;
+                    sxx_x = sxx_x / pml_coeff->K_x_half[h1] + pml_wfd.psi_sxx_x[j, h1, k];
+                    pml_wfd.psi_sxy_x[j, h1, k] =
+                        pml_coeff->b_x[h1] * pml_wfd.psi_sxy_x[j, h1, k] + pml_coeff->a_x[h1] * sxy_x;
+                    sxy_x = sxy_x / pml_coeff->K_x[h1] + pml_wfd.psi_sxy_x[j, h1, k];
+                    pml_wfd.psi_sxz_x[j, h1, k] =
+                        pml_coeff->b_x[h1] * pml_wfd.psi_sxz_x[j, h1, k] + pml_coeff->a_x[h1] * sxz_x;
+                    sxz_x = sxz_x / pml_coeff->K_x[h1] + pml_wfd.psi_sxz_x[j, h1, k];
 
                     if ((gv->POS[2] == 0 && gv->FREE_SURF == 0) && (j <= gv->FW)) {
-                        pml_wfd->psi_sxy_y[j][i][k] =
-                            pml_coeff->b_y[j] * pml_wfd->psi_sxy_y[j][i][k] + pml_coeff->a_y[j] * sxy_y;
-                        sxy_y = sxy_y / pml_coeff->K_y[j] + pml_wfd->psi_sxy_y[j][i][k];
-                        pml_wfd->psi_syy_y[j][i][k] =
-                            pml_coeff->b_y_half[j] * pml_wfd->psi_syy_y[j][i][k] + pml_coeff->a_y_half[j] * syy_y;
-                        syy_y = syy_y / pml_coeff->K_y_half[j] + pml_wfd->psi_syy_y[j][i][k];
-                        pml_wfd->psi_syz_y[j][i][k] =
-                            pml_coeff->b_y[j] * pml_wfd->psi_syz_y[j][i][k] + pml_coeff->a_y[j] * syz_y;
-                        syz_y = syz_y / pml_coeff->K_y[j] + pml_wfd->psi_syz_y[j][i][k];
+                        pml_wfd.psi_sxy_y[j, i, k] =
+                            pml_coeff->b_y[j] * pml_wfd.psi_sxy_y[j, i, k] + pml_coeff->a_y[j] * sxy_y;
+                        sxy_y = sxy_y / pml_coeff->K_y[j] + pml_wfd.psi_sxy_y[j, i, k];
+                        pml_wfd.psi_syy_y[j, i, k] =
+                            pml_coeff->b_y_half[j] * pml_wfd.psi_syy_y[j, i, k] + pml_coeff->a_y_half[j] * syy_y;
+                        syy_y = syy_y / pml_coeff->K_y_half[j] + pml_wfd.psi_syy_y[j, i, k];
+                        pml_wfd.psi_syz_y[j, i, k] =
+                            pml_coeff->b_y[j] * pml_wfd.psi_syz_y[j, i, k] + pml_coeff->a_y[j] * syz_y;
+                        syz_y = syz_y / pml_coeff->K_y[j] + pml_wfd.psi_syz_y[j, i, k];
                     }
 
                     if ((gv->POS[2] == gv->NPROCY - 1) && (j >= nb->ny2 + 1)) {
                         h1 = (j - nb->ny2 + gv->FW);
-                        pml_wfd->psi_sxy_y[h1][i][k] =
-                            pml_coeff->b_y[h1] * pml_wfd->psi_sxy_y[h1][i][k] + pml_coeff->a_y[h1] * sxy_y;
-                        sxy_y = sxy_y / pml_coeff->K_y[h1] + pml_wfd->psi_sxy_y[h1][i][k];
-                        pml_wfd->psi_syy_y[h1][i][k] =
-                            pml_coeff->b_y_half[h1] * pml_wfd->psi_syy_y[h1][i][k] + pml_coeff->a_y_half[h1] * syy_y;
-                        syy_y = syy_y / pml_coeff->K_y_half[h1] + pml_wfd->psi_syy_y[h1][i][k];
-                        pml_wfd->psi_syz_y[h1][i][k] =
-                            pml_coeff->b_y[h1] * pml_wfd->psi_syz_y[h1][i][k] + pml_coeff->a_y[h1] * syz_y;
-                        syz_y = syz_y / pml_coeff->K_y[h1] + pml_wfd->psi_syz_y[h1][i][k];
+                        pml_wfd.psi_sxy_y[h1, i, k] =
+                            pml_coeff->b_y[h1] * pml_wfd.psi_sxy_y[h1, i, k] + pml_coeff->a_y[h1] * sxy_y;
+                        sxy_y = sxy_y / pml_coeff->K_y[h1] + pml_wfd.psi_sxy_y[h1, i, k];
+                        pml_wfd.psi_syy_y[h1, i, k] =
+                            pml_coeff->b_y_half[h1] * pml_wfd.psi_syy_y[h1, i, k] + pml_coeff->a_y_half[h1] * syy_y;
+                        syy_y = syy_y / pml_coeff->K_y_half[h1] + pml_wfd.psi_syy_y[h1, i, k];
+                        pml_wfd.psi_syz_y[h1, i, k] =
+                            pml_coeff->b_y[h1] * pml_wfd.psi_syz_y[h1, i, k] + pml_coeff->a_y[h1] * syz_y;
+                        syz_y = syz_y / pml_coeff->K_y[h1] + pml_wfd.psi_syz_y[h1, i, k];
                     }
 
                     if ((gv->POS[3] == 0) && (k <= gv->FW)) {
-                        pml_wfd->psi_sxz_z[j][i][k] =
-                            pml_coeff->b_z[k] * pml_wfd->psi_sxz_z[j][i][k] + pml_coeff->a_z[k] * sxz_z;
-                        sxz_z = sxz_z / pml_coeff->K_z[k] + pml_wfd->psi_sxz_z[j][i][k];
-                        pml_wfd->psi_syz_z[j][i][k] =
-                            pml_coeff->b_z[k] * pml_wfd->psi_syz_z[j][i][k] + pml_coeff->a_z[k] * syz_z;
-                        syz_z = syz_z / pml_coeff->K_z[k] + pml_wfd->psi_syz_z[j][i][k];
-                        pml_wfd->psi_szz_z[j][i][k] =
-                            pml_coeff->b_z_half[k] * pml_wfd->psi_szz_z[j][i][k] + pml_coeff->a_z_half[k] * szz_z;
-                        szz_z = szz_z / pml_coeff->K_z_half[k] + pml_wfd->psi_szz_z[j][i][k];
+                        pml_wfd.psi_sxz_z[j, i, k] =
+                            pml_coeff->b_z[k] * pml_wfd.psi_sxz_z[j, i, k] + pml_coeff->a_z[k] * sxz_z;
+                        sxz_z = sxz_z / pml_coeff->K_z[k] + pml_wfd.psi_sxz_z[j, i, k];
+                        pml_wfd.psi_syz_z[j, i, k] =
+                            pml_coeff->b_z[k] * pml_wfd.psi_syz_z[j, i, k] + pml_coeff->a_z[k] * syz_z;
+                        syz_z = syz_z / pml_coeff->K_z[k] + pml_wfd.psi_syz_z[j, i, k];
+                        pml_wfd.psi_szz_z[j, i, k] =
+                            pml_coeff->b_z_half[k] * pml_wfd.psi_szz_z[j, i, k] + pml_coeff->a_z_half[k] * szz_z;
+                        szz_z = szz_z / pml_coeff->K_z_half[k] + pml_wfd.psi_szz_z[j, i, k];
                     }
 
                     if ((gv->POS[3] == gv->NPROCZ - 1) && (k >= nb->nz2 + 1)) {
                         h1 = (k - nb->nz2 + gv->FW);
-                        pml_wfd->psi_sxz_z[j][i][h1] =
-                            pml_coeff->b_z[h1] * pml_wfd->psi_sxz_z[j][i][h1] + pml_coeff->a_z[h1] * sxz_z;
-                        sxz_z = sxz_z / pml_coeff->K_z[h1] + pml_wfd->psi_sxz_z[j][i][h1];
-                        pml_wfd->psi_syz_z[j][i][h1] =
-                            pml_coeff->b_z[h1] * pml_wfd->psi_syz_z[j][i][h1] + pml_coeff->a_z[h1] * syz_z;
-                        syz_z = syz_z / pml_coeff->K_z[h1] + pml_wfd->psi_syz_z[j][i][h1];
-                        pml_wfd->psi_szz_z[j][i][h1] =
-                            pml_coeff->b_z_half[h1] * pml_wfd->psi_szz_z[j][i][h1] + pml_coeff->a_z_half[h1] * szz_z;
-                        szz_z = szz_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_szz_z[j][i][h1];
+                        pml_wfd.psi_sxz_z[j, i, h1] =
+                            pml_coeff->b_z[h1] * pml_wfd.psi_sxz_z[j, i, h1] + pml_coeff->a_z[h1] * sxz_z;
+                        sxz_z = sxz_z / pml_coeff->K_z[h1] + pml_wfd.psi_sxz_z[j, i, h1];
+                        pml_wfd.psi_syz_z[j, i, h1] =
+                            pml_coeff->b_z[h1] * pml_wfd.psi_syz_z[j, i, h1] + pml_coeff->a_z[h1] * syz_z;
+                        syz_z = syz_z / pml_coeff->K_z[h1] + pml_wfd.psi_syz_z[j, i, h1];
+                        pml_wfd.psi_szz_z[j, i, h1] =
+                            pml_coeff->b_z_half[h1] * pml_wfd.psi_szz_z[j, i, h1] + pml_coeff->a_z_half[h1] * szz_z;
+                        szz_z = szz_z / pml_coeff->K_z_half[h1] + pml_wfd.psi_szz_z[j, i, h1];
                     }
 
                     vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av.rip[j, i, k];
@@ -284,39 +284,39 @@ void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress &stress, st_mode
                     szz_z =
                         dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
                               b2 * (stress.szz[j, i, k + 2] - stress.szz[j, i, k - 1]));
-                    pml_wfd->psi_sxy_y[j][i][k] =
-                        pml_coeff->b_y[j] * pml_wfd->psi_sxy_y[j][i][k] + pml_coeff->a_y[j] * sxy_y;
-                    sxy_y = sxy_y / pml_coeff->K_y[j] + pml_wfd->psi_sxy_y[j][i][k];
-                    pml_wfd->psi_syy_y[j][i][k] =
-                        pml_coeff->b_y_half[j] * pml_wfd->psi_syy_y[j][i][k] + pml_coeff->a_y_half[j] * syy_y;
-                    syy_y = syy_y / pml_coeff->K_y_half[j] + pml_wfd->psi_syy_y[j][i][k];
-                    pml_wfd->psi_syz_y[j][i][k] =
-                        pml_coeff->b_y[j] * pml_wfd->psi_syz_y[j][i][k] + pml_coeff->a_y[j] * syz_y;
-                    syz_y = syz_y / pml_coeff->K_y[j] + pml_wfd->psi_syz_y[j][i][k];
+                    pml_wfd.psi_sxy_y[j, i, k] =
+                        pml_coeff->b_y[j] * pml_wfd.psi_sxy_y[j, i, k] + pml_coeff->a_y[j] * sxy_y;
+                    sxy_y = sxy_y / pml_coeff->K_y[j] + pml_wfd.psi_sxy_y[j, i, k];
+                    pml_wfd.psi_syy_y[j, i, k] =
+                        pml_coeff->b_y_half[j] * pml_wfd.psi_syy_y[j, i, k] + pml_coeff->a_y_half[j] * syy_y;
+                    syy_y = syy_y / pml_coeff->K_y_half[j] + pml_wfd.psi_syy_y[j, i, k];
+                    pml_wfd.psi_syz_y[j, i, k] =
+                        pml_coeff->b_y[j] * pml_wfd.psi_syz_y[j, i, k] + pml_coeff->a_y[j] * syz_y;
+                    syz_y = syz_y / pml_coeff->K_y[j] + pml_wfd.psi_syz_y[j, i, k];
 
                     if ((gv->POS[3] == 0) && (k <= gv->FW)) {
-                        pml_wfd->psi_sxz_z[j][i][k] =
-                            pml_coeff->b_z[k] * pml_wfd->psi_sxz_z[j][i][k] + pml_coeff->a_z[k] * sxz_z;
-                        sxz_z = sxz_z / pml_coeff->K_z[k] + pml_wfd->psi_sxz_z[j][i][k];
-                        pml_wfd->psi_syz_z[j][i][k] =
-                            pml_coeff->b_z[k] * pml_wfd->psi_syz_z[j][i][k] + pml_coeff->a_z[k] * syz_z;
-                        syz_z = syz_z / pml_coeff->K_z[k] + pml_wfd->psi_syz_z[j][i][k];
-                        pml_wfd->psi_szz_z[j][i][k] =
-                            pml_coeff->b_z_half[k] * pml_wfd->psi_szz_z[j][i][k] + pml_coeff->a_z_half[k] * szz_z;
-                        szz_z = szz_z / pml_coeff->K_z_half[k] + pml_wfd->psi_szz_z[j][i][k];
+                        pml_wfd.psi_sxz_z[j, i, k] =
+                            pml_coeff->b_z[k] * pml_wfd.psi_sxz_z[j, i, k] + pml_coeff->a_z[k] * sxz_z;
+                        sxz_z = sxz_z / pml_coeff->K_z[k] + pml_wfd.psi_sxz_z[j, i, k];
+                        pml_wfd.psi_syz_z[j, i, k] =
+                            pml_coeff->b_z[k] * pml_wfd.psi_syz_z[j, i, k] + pml_coeff->a_z[k] * syz_z;
+                        syz_z = syz_z / pml_coeff->K_z[k] + pml_wfd.psi_syz_z[j, i, k];
+                        pml_wfd.psi_szz_z[j, i, k] =
+                            pml_coeff->b_z_half[k] * pml_wfd.psi_szz_z[j, i, k] + pml_coeff->a_z_half[k] * szz_z;
+                        szz_z = szz_z / pml_coeff->K_z_half[k] + pml_wfd.psi_szz_z[j, i, k];
                     }
 
                     if ((gv->POS[3] == gv->NPROCZ - 1) && (k >= nb->nz2 + 1)) {
                         h1 = (k - nb->nz2 + gv->FW);
-                        pml_wfd->psi_sxz_z[j][i][h1] =
-                            pml_coeff->b_z[h1] * pml_wfd->psi_sxz_z[j][i][h1] + pml_coeff->a_z[h1] * sxz_z;
-                        sxz_z = sxz_z / pml_coeff->K_z[h1] + pml_wfd->psi_sxz_z[j][i][h1];
-                        pml_wfd->psi_syz_z[j][i][h1] =
-                            pml_coeff->b_z[h1] * pml_wfd->psi_syz_z[j][i][h1] + pml_coeff->a_z[h1] * syz_z;
-                        syz_z = syz_z / pml_coeff->K_z[h1] + pml_wfd->psi_syz_z[j][i][h1];
-                        pml_wfd->psi_szz_z[j][i][h1] =
-                            pml_coeff->b_z_half[h1] * pml_wfd->psi_szz_z[j][i][h1] + pml_coeff->a_z_half[h1] * szz_z;
-                        szz_z = szz_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_szz_z[j][i][h1];
+                        pml_wfd.psi_sxz_z[j, i, h1] =
+                            pml_coeff->b_z[h1] * pml_wfd.psi_sxz_z[j, i, h1] + pml_coeff->a_z[h1] * sxz_z;
+                        sxz_z = sxz_z / pml_coeff->K_z[h1] + pml_wfd.psi_sxz_z[j, i, h1];
+                        pml_wfd.psi_syz_z[j, i, h1] =
+                            pml_coeff->b_z[h1] * pml_wfd.psi_syz_z[j, i, h1] + pml_coeff->a_z[h1] * syz_z;
+                        syz_z = syz_z / pml_coeff->K_z[h1] + pml_wfd.psi_syz_z[j, i, h1];
+                        pml_wfd.psi_szz_z[j, i, h1] =
+                            pml_coeff->b_z_half[h1] * pml_wfd.psi_szz_z[j, i, h1] + pml_coeff->a_z_half[h1] * szz_z;
+                        szz_z = szz_z / pml_coeff->K_z_half[h1] + pml_wfd.psi_szz_z[j, i, h1];
                     }
 
                     vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av.rip[j, i, k];
@@ -360,39 +360,39 @@ void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress &stress, st_mode
                         dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
                               b2 * (stress.szz[j, i, k + 2] - stress.szz[j, i, k - 1]));
                     h1 = (j - nb->ny2 + gv->FW);
-                    pml_wfd->psi_sxy_y[h1][i][k] =
-                        pml_coeff->b_y[h1] * pml_wfd->psi_sxy_y[h1][i][k] + pml_coeff->a_y[h1] * sxy_y;
-                    sxy_y = sxy_y / pml_coeff->K_y[h1] + pml_wfd->psi_sxy_y[h1][i][k];
-                    pml_wfd->psi_syy_y[h1][i][k] =
-                        pml_coeff->b_y_half[h1] * pml_wfd->psi_syy_y[h1][i][k] + pml_coeff->a_y_half[h1] * syy_y;
-                    syy_y = syy_y / pml_coeff->K_y_half[h1] + pml_wfd->psi_syy_y[h1][i][k];
-                    pml_wfd->psi_syz_y[h1][i][k] =
-                        pml_coeff->b_y[h1] * pml_wfd->psi_syz_y[h1][i][k] + pml_coeff->a_y[h1] * syz_y;
-                    syz_y = syz_y / pml_coeff->K_y[h1] + pml_wfd->psi_syz_y[h1][i][k];
+                    pml_wfd.psi_sxy_y[h1, i, k] =
+                        pml_coeff->b_y[h1] * pml_wfd.psi_sxy_y[h1, i, k] + pml_coeff->a_y[h1] * sxy_y;
+                    sxy_y = sxy_y / pml_coeff->K_y[h1] + pml_wfd.psi_sxy_y[h1, i, k];
+                    pml_wfd.psi_syy_y[h1, i, k] =
+                        pml_coeff->b_y_half[h1] * pml_wfd.psi_syy_y[h1, i, k] + pml_coeff->a_y_half[h1] * syy_y;
+                    syy_y = syy_y / pml_coeff->K_y_half[h1] + pml_wfd.psi_syy_y[h1, i, k];
+                    pml_wfd.psi_syz_y[h1, i, k] =
+                        pml_coeff->b_y[h1] * pml_wfd.psi_syz_y[h1, i, k] + pml_coeff->a_y[h1] * syz_y;
+                    syz_y = syz_y / pml_coeff->K_y[h1] + pml_wfd.psi_syz_y[h1, i, k];
 
                     if ((gv->POS[3] == 0) && (k <= gv->FW)) {
-                        pml_wfd->psi_sxz_z[j][i][k] =
-                            pml_coeff->b_z[k] * pml_wfd->psi_sxz_z[j][i][k] + pml_coeff->a_z[k] * sxz_z;
-                        sxz_z = sxz_z / pml_coeff->K_z[k] + pml_wfd->psi_sxz_z[j][i][k];
-                        pml_wfd->psi_syz_z[j][i][k] =
-                            pml_coeff->b_z[k] * pml_wfd->psi_syz_z[j][i][k] + pml_coeff->a_z[k] * syz_z;
-                        syz_z = syz_z / pml_coeff->K_z[k] + pml_wfd->psi_syz_z[j][i][k];
-                        pml_wfd->psi_szz_z[j][i][k] =
-                            pml_coeff->b_z_half[k] * pml_wfd->psi_szz_z[j][i][k] + pml_coeff->a_z_half[k] * szz_z;
-                        szz_z = szz_z / pml_coeff->K_z_half[k] + pml_wfd->psi_szz_z[j][i][k];
+                        pml_wfd.psi_sxz_z[j, i, k] =
+                            pml_coeff->b_z[k] * pml_wfd.psi_sxz_z[j, i, k] + pml_coeff->a_z[k] * sxz_z;
+                        sxz_z = sxz_z / pml_coeff->K_z[k] + pml_wfd.psi_sxz_z[j, i, k];
+                        pml_wfd.psi_syz_z[j, i, k] =
+                            pml_coeff->b_z[k] * pml_wfd.psi_syz_z[j, i, k] + pml_coeff->a_z[k] * syz_z;
+                        syz_z = syz_z / pml_coeff->K_z[k] + pml_wfd.psi_syz_z[j, i, k];
+                        pml_wfd.psi_szz_z[j, i, k] =
+                            pml_coeff->b_z_half[k] * pml_wfd.psi_szz_z[j, i, k] + pml_coeff->a_z_half[k] * szz_z;
+                        szz_z = szz_z / pml_coeff->K_z_half[k] + pml_wfd.psi_szz_z[j, i, k];
                     }
 
                     if ((gv->POS[3] == gv->NPROCZ - 1) && (k >= nb->nz2 + 1)) {
                         h1 = (k - nb->nz2 + gv->FW);
-                        pml_wfd->psi_sxz_z[j][i][h1] =
-                            pml_coeff->b_z[h1] * pml_wfd->psi_sxz_z[j][i][h1] + pml_coeff->a_z[h1] * sxz_z;
-                        sxz_z = sxz_z / pml_coeff->K_z[h1] + pml_wfd->psi_sxz_z[j][i][h1];
-                        pml_wfd->psi_syz_z[j][i][h1] =
-                            pml_coeff->b_z[h1] * pml_wfd->psi_syz_z[j][i][h1] + pml_coeff->a_z[h1] * syz_z;
-                        syz_z = syz_z / pml_coeff->K_z[h1] + pml_wfd->psi_syz_z[j][i][h1];
-                        pml_wfd->psi_szz_z[j][i][h1] =
-                            pml_coeff->b_z_half[h1] * pml_wfd->psi_szz_z[j][i][h1] + pml_coeff->a_z_half[h1] * szz_z;
-                        szz_z = szz_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_szz_z[j][i][h1];
+                        pml_wfd.psi_sxz_z[j, i, h1] =
+                            pml_coeff->b_z[h1] * pml_wfd.psi_sxz_z[j, i, h1] + pml_coeff->a_z[h1] * sxz_z;
+                        sxz_z = sxz_z / pml_coeff->K_z[h1] + pml_wfd.psi_sxz_z[j, i, h1];
+                        pml_wfd.psi_syz_z[j, i, h1] =
+                            pml_coeff->b_z[h1] * pml_wfd.psi_syz_z[j, i, h1] + pml_coeff->a_z[h1] * syz_z;
+                        syz_z = syz_z / pml_coeff->K_z[h1] + pml_wfd.psi_syz_z[j, i, h1];
+                        pml_wfd.psi_szz_z[j, i, h1] =
+                            pml_coeff->b_z_half[h1] * pml_wfd.psi_szz_z[j, i, h1] + pml_coeff->a_z_half[h1] * szz_z;
+                        szz_z = szz_z / pml_coeff->K_z_half[h1] + pml_wfd.psi_szz_z[j, i, h1];
                     }
 
                     vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av.rip[j, i, k];
@@ -437,15 +437,15 @@ void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress &stress, st_mode
                     szz_z =
                         dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
                               b2 * (stress.szz[j, i, k + 2] - stress.szz[j, i, k - 1]));
-                    pml_wfd->psi_sxz_z[j][i][k] =
-                        pml_coeff->b_z[k] * pml_wfd->psi_sxz_z[j][i][k] + pml_coeff->a_z[k] * sxz_z;
-                    sxz_z = sxz_z / pml_coeff->K_z[k] + pml_wfd->psi_sxz_z[j][i][k];
-                    pml_wfd->psi_syz_z[j][i][k] =
-                        pml_coeff->b_z[k] * pml_wfd->psi_syz_z[j][i][k] + pml_coeff->a_z[k] * syz_z;
-                    syz_z = syz_z / pml_coeff->K_z[k] + pml_wfd->psi_syz_z[j][i][k];
-                    pml_wfd->psi_szz_z[j][i][k] =
-                        pml_coeff->b_z_half[k] * pml_wfd->psi_szz_z[j][i][k] + pml_coeff->a_z_half[k] * szz_z;
-                    szz_z = szz_z / pml_coeff->K_z_half[k] + pml_wfd->psi_szz_z[j][i][k];
+                    pml_wfd.psi_sxz_z[j, i, k] =
+                        pml_coeff->b_z[k] * pml_wfd.psi_sxz_z[j, i, k] + pml_coeff->a_z[k] * sxz_z;
+                    sxz_z = sxz_z / pml_coeff->K_z[k] + pml_wfd.psi_sxz_z[j, i, k];
+                    pml_wfd.psi_syz_z[j, i, k] =
+                        pml_coeff->b_z[k] * pml_wfd.psi_syz_z[j, i, k] + pml_coeff->a_z[k] * syz_z;
+                    syz_z = syz_z / pml_coeff->K_z[k] + pml_wfd.psi_syz_z[j, i, k];
+                    pml_wfd.psi_szz_z[j, i, k] =
+                        pml_coeff->b_z_half[k] * pml_wfd.psi_szz_z[j, i, k] + pml_coeff->a_z_half[k] * szz_z;
+                    szz_z = szz_z / pml_coeff->K_z_half[k] + pml_wfd.psi_szz_z[j, i, k];
 
                     vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av.rip[j, i, k];
                     vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av.rjp[j, i, k];
@@ -488,15 +488,15 @@ void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress &stress, st_mode
                         dz * (b1 * (stress.szz[j, i, k + 1] - stress.szz[j, i, k]) +
                               b2 * (stress.szz[j, i, k + 2] - stress.szz[j, i, k - 1]));
                     h1 = (k - nb->nz2 + gv->FW);
-                    pml_wfd->psi_sxz_z[j][i][h1] =
-                        pml_coeff->b_z[h1] * pml_wfd->psi_sxz_z[j][i][h1] + pml_coeff->a_z[h1] * sxz_z;
-                    sxz_z = sxz_z / pml_coeff->K_z[h1] + pml_wfd->psi_sxz_z[j][i][h1];
-                    pml_wfd->psi_syz_z[j][i][h1] =
-                        pml_coeff->b_z[h1] * pml_wfd->psi_syz_z[j][i][h1] + pml_coeff->a_z[h1] * syz_z;
-                    syz_z = syz_z / pml_coeff->K_z[h1] + pml_wfd->psi_syz_z[j][i][h1];
-                    pml_wfd->psi_szz_z[j][i][h1] =
-                        pml_coeff->b_z_half[h1] * pml_wfd->psi_szz_z[j][i][h1] + pml_coeff->a_z_half[h1] * szz_z;
-                    szz_z = szz_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_szz_z[j][i][h1];
+                    pml_wfd.psi_sxz_z[j, i, h1] =
+                        pml_coeff->b_z[h1] * pml_wfd.psi_sxz_z[j, i, h1] + pml_coeff->a_z[h1] * sxz_z;
+                    sxz_z = sxz_z / pml_coeff->K_z[h1] + pml_wfd.psi_sxz_z[j, i, h1];
+                    pml_wfd.psi_syz_z[j, i, h1] =
+                        pml_coeff->b_z[h1] * pml_wfd.psi_syz_z[j, i, h1] + pml_coeff->a_z[h1] * syz_z;
+                    syz_z = syz_z / pml_coeff->K_z[h1] + pml_wfd.psi_syz_z[j, i, h1];
+                    pml_wfd.psi_szz_z[j, i, h1] =
+                        pml_coeff->b_z_half[h1] * pml_wfd.psi_szz_z[j, i, h1] + pml_coeff->a_z_half[h1] * szz_z;
+                    szz_z = szz_z / pml_coeff->K_z_half[h1] + pml_wfd.psi_szz_z[j, i, h1];
 
                     vel.vx[j, i, k] += (sxx_x + sxy_y + sxz_z) / mod_av.rip[j, i, k];
                     vel.vy[j, i, k] += (syy_y + sxy_x + syz_z) / mod_av.rjp[j, i, k];
diff --git a/src/update_v_ssg_CPML_acoustic.cpp b/src/update_v_ssg_CPML_acoustic.cpp
index c4100e6..e8e0b3e 100644
--- a/src/update_v_ssg_CPML_acoustic.cpp
+++ b/src/update_v_ssg_CPML_acoustic.cpp
@@ -31,7 +31,7 @@
 #define UNUSED(x) (void)(x)
 
 void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av &mod_av,
-                            st_pml_coeff *pml_coeff, st_pml_wfd *pml_wfd, const GlobVar *gv)
+                            st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd, const GlobVar *gv)
 {
     float sp_x = 0.0, sp_y = 0.0, sp_z = 0.0;
     int h1;
@@ -64,34 +64,34 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress
                     sp_z =
                         dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
                               b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]));
-                    pml_wfd->psi_sp_x[j][i][k] =
-                        pml_coeff->b_x_half[i] * pml_wfd->psi_sp_x[j][i][k] + pml_coeff->a_x_half[i] * sp_x;
-                    sp_x = sp_x / pml_coeff->K_x_half[i] + pml_wfd->psi_sp_x[j][i][k];
+                    pml_wfd.psi_sp_x[j, i, k] =
+                        pml_coeff->b_x_half[i] * pml_wfd.psi_sp_x[j, i, k] + pml_coeff->a_x_half[i] * sp_x;
+                    sp_x = sp_x / pml_coeff->K_x_half[i] + pml_wfd.psi_sp_x[j, i, k];
 
                     if ((gv->POS[2] == 0 && gv->FREE_SURF == 0) && (j <= gv->FW)) {
-                        pml_wfd->psi_sp_y[j][i][k] =
-                            pml_coeff->b_y_half[j] * pml_wfd->psi_sp_y[j][i][k] + pml_coeff->a_y_half[j] * sp_y;
-                        sp_y = sp_y / pml_coeff->K_y_half[j] + pml_wfd->psi_sp_y[j][i][k];
+                        pml_wfd.psi_sp_y[j, i, k] =
+                            pml_coeff->b_y_half[j] * pml_wfd.psi_sp_y[j, i, k] + pml_coeff->a_y_half[j] * sp_y;
+                        sp_y = sp_y / pml_coeff->K_y_half[j] + pml_wfd.psi_sp_y[j, i, k];
                     }
 
                     if ((gv->POS[2] == gv->NPROCY - 1) && (j >= nb->ny2 + 1)) {
                         h1 = (j - nb->ny2 + gv->FW);
-                        pml_wfd->psi_sp_y[h1][i][k] =
-                            pml_coeff->b_y_half[h1] * pml_wfd->psi_sp_y[h1][i][k] + pml_coeff->a_y_half[h1] * sp_y;
-                        sp_y = sp_y / pml_coeff->K_y_half[h1] + pml_wfd->psi_sp_y[h1][i][k];
+                        pml_wfd.psi_sp_y[h1, i, k] =
+                            pml_coeff->b_y_half[h1] * pml_wfd.psi_sp_y[h1, i, k] + pml_coeff->a_y_half[h1] * sp_y;
+                        sp_y = sp_y / pml_coeff->K_y_half[h1] + pml_wfd.psi_sp_y[h1, i, k];
                     }
 
                     if ((gv->POS[3] == 0) && (k <= gv->FW)) {
-                        pml_wfd->psi_sp_z[j][i][k] =
-                            pml_coeff->b_z_half[k] * pml_wfd->psi_sp_z[j][i][k] + pml_coeff->a_z_half[k] * sp_z;
-                        sp_z = sp_z / pml_coeff->K_z_half[k] + pml_wfd->psi_sp_z[j][i][k];
+                        pml_wfd.psi_sp_z[j, i, k] =
+                            pml_coeff->b_z_half[k] * pml_wfd.psi_sp_z[j, i, k] + pml_coeff->a_z_half[k] * sp_z;
+                        sp_z = sp_z / pml_coeff->K_z_half[k] + pml_wfd.psi_sp_z[j, i, k];
                     }
 
                     if ((gv->POS[3] == gv->NPROCZ - 1) && (k >= nb->nz2 + 1)) {
                         h1 = (k - nb->nz2 + gv->FW);
-                        pml_wfd->psi_sp_z[j][i][h1] =
-                            pml_coeff->b_z_half[h1] * pml_wfd->psi_sp_z[j][i][h1] + pml_coeff->a_z_half[h1] * sp_z;
-                        sp_z = sp_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_sp_z[j][i][h1];
+                        pml_wfd.psi_sp_z[j, i, h1] =
+                            pml_coeff->b_z_half[h1] * pml_wfd.psi_sp_z[j, i, h1] + pml_coeff->a_z_half[h1] * sp_z;
+                        sp_z = sp_z / pml_coeff->K_z_half[h1] + pml_wfd.psi_sp_z[j, i, h1];
                     }
 
                     vel.vx[j, i, k] += (sp_x) / mod_av.rip[j, i, k];
@@ -117,34 +117,34 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress
                         dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
                               b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]));
                     h1 = (i - nb->nx2 + gv->FW);
-                    pml_wfd->psi_sp_x[j][h1][k] =
-                        pml_coeff->b_x_half[h1] * pml_wfd->psi_sp_x[j][h1][k] + pml_coeff->a_x_half[h1] * sp_x;
-                    sp_x = sp_x / pml_coeff->K_x_half[h1] + pml_wfd->psi_sp_x[j][h1][k];
+                    pml_wfd.psi_sp_x[j, h1, k] =
+                        pml_coeff->b_x_half[h1] * pml_wfd.psi_sp_x[j, h1, k] + pml_coeff->a_x_half[h1] * sp_x;
+                    sp_x = sp_x / pml_coeff->K_x_half[h1] + pml_wfd.psi_sp_x[j, h1, k];
 
                     if ((gv->POS[2] == 0 && gv->FREE_SURF == 0) && (j <= gv->FW)) {
-                        pml_wfd->psi_sp_y[j][i][k] =
-                            pml_coeff->b_y_half[j] * pml_wfd->psi_sp_y[j][i][k] + pml_coeff->a_y_half[j] * sp_y;
-                        sp_y = sp_y / pml_coeff->K_y_half[j] + pml_wfd->psi_sp_y[j][i][k];
+                        pml_wfd.psi_sp_y[j, i, k] =
+                            pml_coeff->b_y_half[j] * pml_wfd.psi_sp_y[j, i, k] + pml_coeff->a_y_half[j] * sp_y;
+                        sp_y = sp_y / pml_coeff->K_y_half[j] + pml_wfd.psi_sp_y[j, i, k];
                     }
 
                     if ((gv->POS[2] == gv->NPROCY - 1) && (j >= nb->ny2 + 1)) {
                         h1 = (j - nb->ny2 + gv->FW);
-                        pml_wfd->psi_sp_y[h1][i][k] =
-                            pml_coeff->b_y_half[h1] * pml_wfd->psi_sp_y[h1][i][k] + pml_coeff->a_y_half[h1] * sp_y;
-                        sp_y = sp_y / pml_coeff->K_y_half[h1] + pml_wfd->psi_sp_y[h1][i][k];
+                        pml_wfd.psi_sp_y[h1, i, k] =
+                            pml_coeff->b_y_half[h1] * pml_wfd.psi_sp_y[h1, i, k] + pml_coeff->a_y_half[h1] * sp_y;
+                        sp_y = sp_y / pml_coeff->K_y_half[h1] + pml_wfd.psi_sp_y[h1, i, k];
                     }
 
                     if ((gv->POS[3] == 0) && (k <= gv->FW)) {
-                        pml_wfd->psi_sp_z[j][i][k] =
-                            pml_coeff->b_z_half[k] * pml_wfd->psi_sp_z[j][i][k] + pml_coeff->a_z_half[k] * sp_z;
-                        sp_z = sp_z / pml_coeff->K_z_half[k] + pml_wfd->psi_sp_z[j][i][k];
+                        pml_wfd.psi_sp_z[j, i, k] =
+                            pml_coeff->b_z_half[k] * pml_wfd.psi_sp_z[j, i, k] + pml_coeff->a_z_half[k] * sp_z;
+                        sp_z = sp_z / pml_coeff->K_z_half[k] + pml_wfd.psi_sp_z[j, i, k];
                     }
 
                     if ((gv->POS[3] == gv->NPROCZ - 1) && (k >= nb->nz2 + 1)) {
                         h1 = (k - nb->nz2 + gv->FW);
-                        pml_wfd->psi_sp_z[j][i][h1] =
-                            pml_coeff->b_z_half[h1] * pml_wfd->psi_sp_z[j][i][h1] + pml_coeff->a_z_half[h1] * sp_z;
-                        sp_z = sp_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_sp_z[j][i][h1];
+                        pml_wfd.psi_sp_z[j, i, h1] =
+                            pml_coeff->b_z_half[h1] * pml_wfd.psi_sp_z[j, i, h1] + pml_coeff->a_z_half[h1] * sp_z;
+                        sp_z = sp_z / pml_coeff->K_z_half[h1] + pml_wfd.psi_sp_z[j, i, h1];
                     }
 
                     vel.vx[j, i, k] += (sp_x) / mod_av.rip[j, i, k];
@@ -169,21 +169,21 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress
                     sp_z =
                         dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
                               b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]));
-                    pml_wfd->psi_sp_y[j][i][k] =
-                        pml_coeff->b_y_half[j] * pml_wfd->psi_sp_y[j][i][k] + pml_coeff->a_y_half[j] * sp_y;
-                    sp_y = sp_y / pml_coeff->K_y_half[j] + pml_wfd->psi_sp_y[j][i][k];
+                    pml_wfd.psi_sp_y[j, i, k] =
+                        pml_coeff->b_y_half[j] * pml_wfd.psi_sp_y[j, i, k] + pml_coeff->a_y_half[j] * sp_y;
+                    sp_y = sp_y / pml_coeff->K_y_half[j] + pml_wfd.psi_sp_y[j, i, k];
 
                     if ((gv->POS[3] == 0) && (k <= gv->FW)) {
-                        pml_wfd->psi_sp_z[j][i][k] =
-                            pml_coeff->b_z_half[k] * pml_wfd->psi_sp_z[j][i][k] + pml_coeff->a_z_half[k] * sp_z;
-                        sp_z = sp_z / pml_coeff->K_z_half[k] + pml_wfd->psi_sp_z[j][i][k];
+                        pml_wfd.psi_sp_z[j, i, k] =
+                            pml_coeff->b_z_half[k] * pml_wfd.psi_sp_z[j, i, k] + pml_coeff->a_z_half[k] * sp_z;
+                        sp_z = sp_z / pml_coeff->K_z_half[k] + pml_wfd.psi_sp_z[j, i, k];
                     }
 
                     if ((gv->POS[3] == gv->NPROCZ - 1) && (k >= nb->nz2 + 1)) {
                         h1 = (k - nb->nz2 + gv->FW);
-                        pml_wfd->psi_sp_z[j][i][h1] =
-                            pml_coeff->b_z_half[h1] * pml_wfd->psi_sp_z[j][i][h1] + pml_coeff->a_z_half[h1] * sp_z;
-                        sp_z = sp_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_sp_z[j][i][h1];
+                        pml_wfd.psi_sp_z[j, i, h1] =
+                            pml_coeff->b_z_half[h1] * pml_wfd.psi_sp_z[j, i, h1] + pml_coeff->a_z_half[h1] * sp_z;
+                        sp_z = sp_z / pml_coeff->K_z_half[h1] + pml_wfd.psi_sp_z[j, i, h1];
                     }
 
                     vel.vx[j, i, k] += (sp_x) / mod_av.rip[j, i, k];
@@ -209,21 +209,21 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress
                         dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
                               b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]));
                     h1 = (j - nb->ny2 + gv->FW);
-                    pml_wfd->psi_sp_y[h1][i][k] =
-                        pml_coeff->b_y_half[h1] * pml_wfd->psi_sp_y[h1][i][k] + pml_coeff->a_y_half[h1] * sp_y;
-                    sp_y = sp_y / pml_coeff->K_y_half[h1] + pml_wfd->psi_sp_y[h1][i][k];
+                    pml_wfd.psi_sp_y[h1, i, k] =
+                        pml_coeff->b_y_half[h1] * pml_wfd.psi_sp_y[h1, i, k] + pml_coeff->a_y_half[h1] * sp_y;
+                    sp_y = sp_y / pml_coeff->K_y_half[h1] + pml_wfd.psi_sp_y[h1, i, k];
 
                     if ((gv->POS[3] == 0) && (k <= gv->FW)) {
-                        pml_wfd->psi_sp_z[j][i][k] =
-                            pml_coeff->b_z_half[k] * pml_wfd->psi_sp_z[j][i][k] + pml_coeff->a_z_half[k] * sp_z;
-                        sp_z = sp_z / pml_coeff->K_z_half[k] + pml_wfd->psi_sp_z[j][i][k];
+                        pml_wfd.psi_sp_z[j, i, k] =
+                            pml_coeff->b_z_half[k] * pml_wfd.psi_sp_z[j, i, k] + pml_coeff->a_z_half[k] * sp_z;
+                        sp_z = sp_z / pml_coeff->K_z_half[k] + pml_wfd.psi_sp_z[j, i, k];
                     }
 
                     if ((gv->POS[3] == gv->NPROCZ - 1) && (k >= nb->nz2 + 1)) {
                         h1 = (k - nb->nz2 + gv->FW);
-                        pml_wfd->psi_sp_z[j][i][h1] =
-                            pml_coeff->b_z_half[h1] * pml_wfd->psi_sp_z[j][i][h1] + pml_coeff->a_z_half[h1] * sp_z;
-                        sp_z = sp_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_sp_z[j][i][h1];
+                        pml_wfd.psi_sp_z[j, i, h1] =
+                            pml_coeff->b_z_half[h1] * pml_wfd.psi_sp_z[j, i, h1] + pml_coeff->a_z_half[h1] * sp_z;
+                        sp_z = sp_z / pml_coeff->K_z_half[h1] + pml_wfd.psi_sp_z[j, i, h1];
                     }
 
                     vel.vx[j, i, k] += (sp_x) / mod_av.rip[j, i, k];
@@ -250,9 +250,9 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress
                     sp_z =
                         dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
                               b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]));
-                    pml_wfd->psi_sp_z[j][i][k] =
-                        pml_coeff->b_z_half[k] * pml_wfd->psi_sp_z[j][i][k] + pml_coeff->a_z_half[k] * sp_z;
-                    sp_z = sp_z / pml_coeff->K_z_half[k] + pml_wfd->psi_sp_z[j][i][k];
+                    pml_wfd.psi_sp_z[j, i, k] =
+                        pml_coeff->b_z_half[k] * pml_wfd.psi_sp_z[j, i, k] + pml_coeff->a_z_half[k] * sp_z;
+                    sp_z = sp_z / pml_coeff->K_z_half[k] + pml_wfd.psi_sp_z[j, i, k];
 
                     vel.vx[j, i, k] += (sp_x) / mod_av.rip[j, i, k];
                     vel.vy[j, i, k] += (sp_y) / mod_av.rjp[j, i, k];
@@ -277,9 +277,9 @@ void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress
                         dz * (b1 * (stress.sp[j, i, k + 1] - stress.sp[j, i, k]) +
                               b2 * (stress.sp[j, i, k + 2] - stress.sp[j, i, k - 1]));
                     h1 = (k - nb->nz2 + gv->FW);
-                    pml_wfd->psi_sp_z[j][i][h1] =
-                        pml_coeff->b_z_half[h1] * pml_wfd->psi_sp_z[j][i][h1] + pml_coeff->a_z_half[h1] * sp_z;
-                    sp_z = sp_z / pml_coeff->K_z_half[h1] + pml_wfd->psi_sp_z[j][i][h1];
+                    pml_wfd.psi_sp_z[j, i, h1] =
+                        pml_coeff->b_z_half[h1] * pml_wfd.psi_sp_z[j, i, h1] + pml_coeff->a_z_half[h1] * sp_z;
+                    sp_z = sp_z / pml_coeff->K_z_half[h1] + pml_wfd.psi_sp_z[j, i, h1];
 
                     vel.vx[j, i, k] += (sp_x) / mod_av.rip[j, i, k];
                     vel.vy[j, i, k] += (sp_y) / mod_av.rjp[j, i, k];
diff --git a/src/zero_wavefield.cpp b/src/zero_wavefield.cpp
index a68b013..e3d0ad6 100644
--- a/src/zero_wavefield.cpp
+++ b/src/zero_wavefield.cpp
@@ -22,7 +22,7 @@
  * -------------------------------------------------------------------------*/
 
 #include "fd.hpp"
-void zero_wavefield(st_velocity &vel, st_stress &stress, st_visc_mem *mem, st_pml_wfd *pml_wfd, const GlobVar *gv)
+void zero_wavefield(st_velocity &vel, st_stress &stress, st_visc_mem *mem, st_pml_wfd &pml_wfd, const GlobVar *gv)
 {
     int l = 1;
 
@@ -94,12 +94,12 @@ void zero_wavefield(st_velocity &vel, st_stress &stress, st_visc_mem *mem, st_pm
             for (int i = 1; i <= gv->NX; i++) {
                 #pragma omp simd
                 for (int k = 1; k <= 2 * gv->FW; k++) {
-                    pml_wfd->psi_sxz_z[j][i][k] = 0.0f;
-                    pml_wfd->psi_syz_z[j][i][k] = 0.0f;
-                    pml_wfd->psi_szz_z[j][i][k] = 0.0f;
-                    pml_wfd->psi_vxz[j][i][k] = 0.0f;
-                    pml_wfd->psi_vyz[j][i][k] = 0.0f;
-                    pml_wfd->psi_vzz[j][i][k] = 0.0f;
+                    pml_wfd.psi_sxz_z[j, i, k] = 0.0f;
+                    pml_wfd.psi_syz_z[j, i, k] = 0.0f;
+                    pml_wfd.psi_szz_z[j, i, k] = 0.0f;
+                    pml_wfd.psi_vxz[j, i, k] = 0.0f;
+                    pml_wfd.psi_vyz[j, i, k] = 0.0f;
+                    pml_wfd.psi_vzz[j, i, k] = 0.0f;
                 }
             }
         }
@@ -108,12 +108,12 @@ void zero_wavefield(st_velocity &vel, st_stress &stress, st_visc_mem *mem, st_pm
             for (int i = 1; i <= 2 * gv->FW; i++) {
                 #pragma omp simd
                 for (int k = 1; k <= gv->NZ; k++) {
-                    pml_wfd->psi_sxx_x[j][i][k] = 0.0f;
-                    pml_wfd->psi_sxy_x[j][i][k] = 0.0f;
-                    pml_wfd->psi_sxz_x[j][i][k] = 0.0f;
-                    pml_wfd->psi_vxx[j][i][k] = 0.0f;
-                    pml_wfd->psi_vyx[j][i][k] = 0.0f;
-                    pml_wfd->psi_vzx[j][i][k] = 0.0f;
+                    pml_wfd.psi_sxx_x[j, i, k] = 0.0f;
+                    pml_wfd.psi_sxy_x[j, i, k] = 0.0f;
+                    pml_wfd.psi_sxz_x[j, i, k] = 0.0f;
+                    pml_wfd.psi_vxx[j, i, k] = 0.0f;
+                    pml_wfd.psi_vyx[j, i, k] = 0.0f;
+                    pml_wfd.psi_vzx[j, i, k] = 0.0f;
                 }
             }
         }
@@ -122,12 +122,12 @@ void zero_wavefield(st_velocity &vel, st_stress &stress, st_visc_mem *mem, st_pm
             for (int i = 1; i <= gv->NX; i++) {
                 #pragma omp simd
                 for (int k = 1; k <= gv->NZ; k++) {
-                    pml_wfd->psi_sxy_y[j][i][k] = 0.0f;
-                    pml_wfd->psi_syy_y[j][i][k] = 0.0f;
-                    pml_wfd->psi_syz_y[j][i][k] = 0.0f;
-                    pml_wfd->psi_vxy[j][i][k] = 0.0f;
-                    pml_wfd->psi_vyy[j][i][k] = 0.0f;
-                    pml_wfd->psi_vzy[j][i][k] = 0.0f;
+                    pml_wfd.psi_sxy_y[j, i, k] = 0.0f;
+                    pml_wfd.psi_syy_y[j, i, k] = 0.0f;
+                    pml_wfd.psi_syz_y[j, i, k] = 0.0f;
+                    pml_wfd.psi_vxy[j, i, k] = 0.0f;
+                    pml_wfd.psi_vyy[j, i, k] = 0.0f;
+                    pml_wfd.psi_vzy[j, i, k] = 0.0f;
                 }
             }
         }
diff --git a/src/zero_wavefield_acoustic.cpp b/src/zero_wavefield_acoustic.cpp
index 4334d3d..e9c7002 100644
--- a/src/zero_wavefield_acoustic.cpp
+++ b/src/zero_wavefield_acoustic.cpp
@@ -23,7 +23,7 @@
 
 #include "fd.hpp"
 void zero_wavefield_acoustic(st_velocity &vel, st_stress &stress, st_visc_mem *mem,
-                             st_pml_wfd *pml_wfd, const GlobVar *gv)
+                             st_pml_wfd &pml_wfd, const GlobVar *gv)
 {
     int l = 1;
 
@@ -85,8 +85,8 @@ void zero_wavefield_acoustic(st_velocity &vel, st_stress &stress, st_visc_mem *m
             for (int i = 1; i <= gv->NX; i++) {
                 #pragma omp simd
                 for (int k = 1; k <= 2 * gv->FW; k++) {
-                    pml_wfd->psi_sp_z[j][i][k] = 0.0f;
-                    pml_wfd->psi_vzz[j][i][k] = 0.0f;
+                    pml_wfd.psi_sp_z[j, i, k] = 0.0f;
+                    pml_wfd.psi_vzz[j, i, k] = 0.0f;
                 }
             }
         }
@@ -95,8 +95,8 @@ void zero_wavefield_acoustic(st_velocity &vel, st_stress &stress, st_visc_mem *m
             for (int i = 1; i <= 2 * gv->FW; i++) {
                 #pragma omp simd
                 for (int k = 1; k <= gv->NZ; k++) {
-                    pml_wfd->psi_sp_x[j][i][k] = 0.0f;
-                    pml_wfd->psi_vxx[j][i][k] = 0.0f;
+                    pml_wfd.psi_sp_x[j, i, k] = 0.0f;
+                    pml_wfd.psi_vxx[j, i, k] = 0.0f;
                 }
             }
         }
@@ -105,8 +105,8 @@ void zero_wavefield_acoustic(st_velocity &vel, st_stress &stress, st_visc_mem *m
             for (int i = 1; i <= gv->NX; i++) {
                 #pragma omp simd
                 for (int k = 1; k <= gv->NZ; k++) {
-                    pml_wfd->psi_sp_y[j][i][k] = 0.0f;
-                    pml_wfd->psi_vyy[j][i][k] = 0.0f;
+                    pml_wfd.psi_sp_y[j, i, k] = 0.0f;
+                    pml_wfd.psi_vyy[j, i, k] = 0.0f;
                 }
             }
         }
-- 
GitLab


From 48ccc2f8945c75727aeaad41bbd7b1999755f654 Mon Sep 17 00:00:00 2001
From: Holger Obermaier <holger.obermaier@kit.edu>
Date: Tue, 8 Apr 2025 15:09:34 +0200
Subject: [PATCH 09/15] Use float3DTensorT in type st_model

---
 genmod/hh.cpp                      |  24 ++--
 genmod/hh_3DSchach.cpp             |  14 +-
 genmod/hh_toy_ac_start.cpp         |  10 +-
 genmod/hh_toy_ac_true.cpp          |  34 ++---
 genmod/hh_toy_start.cpp            |  14 +-
 genmod/hh_toy_true.cpp             |  54 ++++----
 genmod/rheinstetten_elastic.cpp    |  14 +-
 src/absorb.cpp                     |  16 +--
 src/av_mat.cpp                     |  32 ++---
 src/checkfd_ssg.cpp                |  30 ++--
 src/constant_boundary.cpp          | 213 +++++++++++++----------------
 src/constant_boundary_acoustic.cpp | 116 ++++++++--------
 src/cpmodel.cpp                    |  26 ++--
 src/fd.hpp                         |  83 +++++------
 src/float3DTensorT.hpp             |  12 ++
 src/freemem.cpp                    |  26 ++--
 src/gradient_F.cpp                 |  22 ++-
 src/gradient_F_acoustic.cpp        |  14 +-
 src/ifos3d.cpp                     |  56 ++++----
 src/initmem.cpp                    |  26 ++--
 src/matcopy.cpp                    | 122 ++++++++---------
 src/matcopy_acoustic.cpp           |  74 +++++-----
 src/model2_5D.cpp                  |  22 +--
 src/modelupdate.cpp                |  42 +++---
 src/modelupdate_acoustic.cpp       |  32 ++---
 src/outmod.cpp                     |  14 +-
 src/readmod.cpp                    |  14 +-
 src/seismo_ssg.cpp                 |  10 +-
 src/snap_ssg.cpp                   |  28 ++--
 src/stfi.cpp                       |   4 +-
 src/surface_ssg.cpp                |  62 ++++-----
 src/surface_ssg_elastic.cpp        |  26 ++--
 src/timeloop.cpp                   |   4 +-
 src/update_s_ssg_CPML_acoustic.cpp |  14 +-
 src/update_s_ssg_CPML_elastic.cpp  |  26 ++--
 src/update_s_ssg_acoustic.cpp      |  14 +-
 src/update_s_ssg_elastic.cpp       |  30 ++--
 src/update_v_ssg.cpp               |  20 +--
 src/update_v_ssg_acoustic.cpp      |  10 +-
 39 files changed, 697 insertions(+), 707 deletions(-)

diff --git a/genmod/hh.cpp b/genmod/hh.cpp
index b729a90..8c294d1 100644
--- a/genmod/hh.cpp
+++ b/genmod/hh.cpp
@@ -24,7 +24,7 @@
 #include "fd.hpp"
 #include "util.hpp"
 
-void model(st_model *mod, GlobVar *gv)
+void model(st_model &mod, GlobVar *gv)
 {
     /* local variables */
     float muv, piv, ws;
@@ -47,7 +47,7 @@ void model(st_model *mod, GlobVar *gv)
         pts = vector(1, gv->L);
         for (l = 1; l <= gv->L; l++) {
             pts[l] = 1.0 / (2.0 * PI * gv->FL[l]);
-            mod->eta[l] = gv->DT / pts[l];
+            mod.eta[l] = gv->DT / pts[l];
         }
         ts = gv->TAU;
         tp = gv->TAU;
@@ -77,12 +77,12 @@ void model(st_model *mod, GlobVar *gv)
                     jj = j - gv->POS[2] * gv->NY;
                     kk = k - gv->POS[3] * gv->NZ;
                     if (gv->L) {
-                        mod->taus[jj][ii][kk] = ts;
-                        mod->taup[jj][ii][kk] = tp;
+                        mod.taus[jj, ii, kk] = ts;
+                        mod.taup[jj, ii, kk] = tp;
                     }
-                    mod->u[jj][ii][kk] = muv;
-                    mod->rho[jj][ii][kk] = Rho;
-                    mod->pi[jj][ii][kk] = piv;
+                    mod.u[jj, ii, kk] = muv;
+                    mod.rho[jj, ii, kk] = Rho;
+                    mod.pi[jj, ii, kk] = piv;
                 }
             }
         }
@@ -111,12 +111,12 @@ void model(st_model *mod, GlobVar *gv)
                     jj = j - gv->POS[2] * gv->NY;
                     kk = k - gv->POS[3] * gv->NZ;
                     if (gv->L) {
-                        mod->taus[jj][ii][kk] = ts;
-                        mod->taup[jj][ii][kk] = tp;
+                        mod.taus[jj, ii, kk] = ts;
+                        mod.taup[jj, ii, kk] = tp;
                     }
-                    mod->u[jj][ii][kk] = muv;
-                    mod->rho[jj][ii][kk] = Rho;
-                    mod->pi[jj][ii][kk] = piv;
+                    mod.u[jj, ii, kk] = muv;
+                    mod.rho[jj, ii, kk] = Rho;
+                    mod.pi[jj, ii, kk] = piv;
                 }
             }
         }
diff --git a/genmod/hh_3DSchach.cpp b/genmod/hh_3DSchach.cpp
index ff7288a..c82ab1c 100644
--- a/genmod/hh_3DSchach.cpp
+++ b/genmod/hh_3DSchach.cpp
@@ -6,7 +6,7 @@
 #include "fd.hpp"
 #include "util.hpp"
 
-void model(st_model *mod, GlobVar *gv)
+void model(st_model &mod, GlobVar *gv)
 {
     /* local variables */
     float muv, piv, ws;
@@ -29,7 +29,7 @@ void model(st_model *mod, GlobVar *gv)
         pts = vector(1, gv->L);
         for (l = 1; l <= gv->L; l++) {
             pts[l] = 1.0 / (2.0 * PI * gv->FL[l]);
-            mod->eta[l] = gv->DT / pts[l];
+            mod.eta[l] = gv->DT / pts[l];
         }
         ts = gv->TAU;
         tp = gv->TAU;
@@ -68,13 +68,13 @@ void model(st_model *mod, GlobVar *gv)
                                 jj = j - gv->POS[2] * gv->NY;
                                 kk = k - gv->POS[3] * gv->NZ;
                                 if (gv->L) {
-                                    mod->taus[jj][ii][kk] = ts;
-                                    mod->taup[jj][ii][kk] = tp;
+                                    mod.taus[jj, ii, kk] = ts;
+                                    mod.taup[jj, ii, kk] = tp;
                                 }
 
-                                mod->u[jj][ii][kk] = muv;
-                                mod->rho[jj][ii][kk] = Rho;
-                                mod->pi[jj][ii][kk] = piv;
+                                mod.u[jj, ii, kk] = muv;
+                                mod.rho[jj, ii, kk] = Rho;
+                                mod.pi[jj, ii, kk] = piv;
                             }
                         }
                     }
diff --git a/genmod/hh_toy_ac_start.cpp b/genmod/hh_toy_ac_start.cpp
index 425e149..8419106 100644
--- a/genmod/hh_toy_ac_start.cpp
+++ b/genmod/hh_toy_ac_start.cpp
@@ -6,7 +6,7 @@
 #include "fd.hpp"
 #include "util.hpp"
 
-void model(st_model *mod, GlobVar *gv)
+void model(st_model &mod, GlobVar *gv)
 {
     /* local variables */
     float piv, ws;
@@ -29,7 +29,7 @@ void model(st_model *mod, GlobVar *gv)
 
         for (l = 1; l <= gv->L; l++) {
             pts[l] = 1.0 / (2.0 * PI * gv->FL[l]);
-            mod->eta[l] = gv->DT / pts[l];
+            mod.eta[l] = gv->DT / pts[l];
         }
 
         tp = gv->TAU;
@@ -58,11 +58,11 @@ void model(st_model *mod, GlobVar *gv)
                     kk = k - gv->POS[3] * gv->NZ;
 
                     if (gv->L) {
-                        mod->taup[jj][ii][kk] = tp;
+                        mod.taup[jj, ii, kk] = tp;
                     }
 
-                    mod->rho[jj][ii][kk] = Rho;
-                    mod->pi[jj][ii][kk] = piv;
+                    mod.rho[jj, ii, kk] = Rho;
+                    mod.pi[jj, ii, kk] = piv;
                 }
             }
         }
diff --git a/genmod/hh_toy_ac_true.cpp b/genmod/hh_toy_ac_true.cpp
index 7ba1762..e2fe560 100644
--- a/genmod/hh_toy_ac_true.cpp
+++ b/genmod/hh_toy_ac_true.cpp
@@ -6,7 +6,7 @@
 #include "fd.hpp"
 #include "util.hpp"
 
-void model(st_model *mod, GlobVar *gv)
+void model(st_model &mod, GlobVar *gv)
 {
     /* local variables */
     float piv, ws;
@@ -30,7 +30,7 @@ void model(st_model *mod, GlobVar *gv)
 
         for (l = 1; l <= gv->L; l++) {
             pts[l] = 1.0 / (2.0 * PI * gv->FL[l]);
-            mod->eta[l] = gv->DT / pts[l];
+            mod.eta[l] = gv->DT / pts[l];
         }
 
         tp = gv->TAU;
@@ -59,11 +59,11 @@ void model(st_model *mod, GlobVar *gv)
                     kk = k - gv->POS[3] * gv->NZ;
 
                     if (gv->L) {
-                        mod->taup[jj][ii][kk] = tp;
+                        mod.taup[jj, ii, kk] = tp;
                     }
 
-                    mod->rho[jj][ii][kk] = Rho;
-                    mod->pi[jj][ii][kk] = piv;
+                    mod.rho[jj, ii, kk] = Rho;
+                    mod.pi[jj, ii, kk] = piv;
                 }
             }
         }
@@ -89,11 +89,11 @@ void model(st_model *mod, GlobVar *gv)
                         kk = k - gv->POS[3] * gv->NZ;
 
                         if (gv->L) {
-                            mod->taup[jj][ii][kk] = tp;
+                            mod.taup[jj, ii, kk] = tp;
                         }
 
-                        mod->rho[jj][ii][kk] = Rho;
-                        mod->pi[jj][ii][kk] = piv;
+                        mod.rho[jj, ii, kk] = Rho;
+                        mod.pi[jj, ii, kk] = piv;
                     }
                 }
             }
@@ -118,11 +118,11 @@ void model(st_model *mod, GlobVar *gv)
                         kk = k - gv->POS[3] * gv->NZ;
 
                         if (gv->L) {
-                            mod->taup[jj][ii][kk] = tp;
+                            mod.taup[jj, ii, kk] = tp;
                         }
 
-                        mod->rho[jj][ii][kk] = Rho;
-                        mod->pi[jj][ii][kk] = piv;
+                        mod.rho[jj, ii, kk] = Rho;
+                        mod.pi[jj, ii, kk] = piv;
                     }
                 }
             }
@@ -147,11 +147,11 @@ void model(st_model *mod, GlobVar *gv)
                         kk = k - gv->POS[3] * gv->NZ;
 
                         if (gv->L) {
-                            mod->taup[jj][ii][kk] = tp;
+                            mod.taup[jj, ii, kk] = tp;
                         }
 
-                        mod->rho[jj][ii][kk] = Rho;
-                        mod->pi[jj][ii][kk] = piv;
+                        mod.rho[jj, ii, kk] = Rho;
+                        mod.pi[jj, ii, kk] = piv;
                     }
                 }
             }
@@ -176,11 +176,11 @@ void model(st_model *mod, GlobVar *gv)
                         kk = k - gv->POS[3] * gv->NZ;
 
                         if (gv->L) {
-                            mod->taup[jj][ii][kk] = tp;
+                            mod.taup[jj, ii, kk] = tp;
                         }
 
-                        mod->rho[jj][ii][kk] = Rho;
-                        mod->pi[jj][ii][kk] = piv;
+                        mod.rho[jj, ii, kk] = Rho;
+                        mod.pi[jj, ii, kk] = piv;
                     }
                 }
             }
diff --git a/genmod/hh_toy_start.cpp b/genmod/hh_toy_start.cpp
index 29be6dc..faef39a 100644
--- a/genmod/hh_toy_start.cpp
+++ b/genmod/hh_toy_start.cpp
@@ -6,7 +6,7 @@
 #include "fd.hpp"
 #include "util.hpp"
 
-void model(st_model *mod, GlobVar *gv)
+void model(st_model &mod, GlobVar *gv)
 {
     /* local variables */
     float muv, piv, ws;
@@ -30,7 +30,7 @@ void model(st_model *mod, GlobVar *gv)
 
         for (l = 1; l <= gv->L; l++) {
             pts[l] = 1.0 / (2.0 * PI * gv->FL[l]);
-            mod->eta[l] = gv->DT / pts[l];
+            mod.eta[l] = gv->DT / pts[l];
         }
 
         ts = gv->TAU;
@@ -63,13 +63,13 @@ void model(st_model *mod, GlobVar *gv)
                     kk = k - gv->POS[3] * gv->NZ;
 
                     if (gv->L) {
-                        mod->taus[jj][ii][kk] = ts;
-                        mod->taup[jj][ii][kk] = tp;
+                        mod.taus[jj, ii, kk] = ts;
+                        mod.taup[jj, ii, kk] = tp;
                     }
 
-                    mod->u[jj][ii][kk] = muv;
-                    mod->rho[jj][ii][kk] = Rho;
-                    mod->pi[jj][ii][kk] = piv;
+                    mod.u[jj, ii, kk] = muv;
+                    mod.rho[jj, ii, kk] = Rho;
+                    mod.pi[jj, ii, kk] = piv;
                 }
             }
         }
diff --git a/genmod/hh_toy_true.cpp b/genmod/hh_toy_true.cpp
index 0c900c4..1d51b9e 100644
--- a/genmod/hh_toy_true.cpp
+++ b/genmod/hh_toy_true.cpp
@@ -6,7 +6,7 @@
 #include "fd.hpp"
 #include "util.hpp"
 
-void model(st_model *mod, GlobVar *gv)
+void model(st_model &mod, GlobVar *gv)
 {
     /* local variables */
     float muv, piv, ws;
@@ -31,7 +31,7 @@ void model(st_model *mod, GlobVar *gv)
 
         for (l = 1; l <= gv->L; l++) {
             pts[l] = 1.0 / (2.0 * PI * gv->FL[l]);
-            mod->eta[l] = gv->DT / pts[l];
+            mod.eta[l] = gv->DT / pts[l];
         }
 
         ts = gv->TAU;
@@ -64,13 +64,13 @@ void model(st_model *mod, GlobVar *gv)
                     kk = k - gv->POS[3] * gv->NZ;
 
                     if (gv->L) {
-                        mod->taus[jj][ii][kk] = ts;
-                        mod->taup[jj][ii][kk] = tp;
+                        mod.taus[jj, ii, kk] = ts;
+                        mod.taup[jj, ii, kk] = tp;
                     }
 
-                    mod->u[jj][ii][kk] = muv;
-                    mod->rho[jj][ii][kk] = Rho;
-                    mod->pi[jj][ii][kk] = piv;
+                    mod.u[jj, ii, kk] = muv;
+                    mod.rho[jj, ii, kk] = Rho;
+                    mod.pi[jj, ii, kk] = piv;
                 }
             }
         }
@@ -99,13 +99,13 @@ void model(st_model *mod, GlobVar *gv)
                         kk = k - gv->POS[3] * gv->NZ;
 
                         if (gv->L) {
-                            mod->taus[jj][ii][kk] = ts;
-                            mod->taup[jj][ii][kk] = tp;
+                            mod.taus[jj, ii, kk] = ts;
+                            mod.taup[jj, ii, kk] = tp;
                         }
 
-                        mod->u[jj][ii][kk] = muv;
-                        mod->rho[jj][ii][kk] = Rho;
-                        mod->pi[jj][ii][kk] = piv;
+                        mod.u[jj, ii, kk] = muv;
+                        mod.rho[jj, ii, kk] = Rho;
+                        mod.pi[jj, ii, kk] = piv;
                     }
                 }
             }
@@ -133,13 +133,13 @@ void model(st_model *mod, GlobVar *gv)
                         kk = k - gv->POS[3] * gv->NZ;
 
                         if (gv->L) {
-                            mod->taus[jj][ii][kk] = ts;
-                            mod->taup[jj][ii][kk] = tp;
+                            mod.taus[jj, ii, kk] = ts;
+                            mod.taup[jj, ii, kk] = tp;
                         }
 
-                        mod->u[jj][ii][kk] = muv;
-                        mod->rho[jj][ii][kk] = Rho;
-                        mod->pi[jj][ii][kk] = piv;
+                        mod.u[jj, ii, kk] = muv;
+                        mod.rho[jj, ii, kk] = Rho;
+                        mod.pi[jj, ii, kk] = piv;
                     }
                 }
             }
@@ -167,13 +167,13 @@ void model(st_model *mod, GlobVar *gv)
                         kk = k - gv->POS[3] * gv->NZ;
 
                         if (gv->L) {
-                            mod->taus[jj][ii][kk] = ts;
-                            mod->taup[jj][ii][kk] = tp;
+                            mod.taus[jj, ii, kk] = ts;
+                            mod.taup[jj, ii, kk] = tp;
                         }
 
-                        mod->u[jj][ii][kk] = muv;
-                        mod->rho[jj][ii][kk] = Rho;
-                        mod->pi[jj][ii][kk] = piv;
+                        mod.u[jj, ii, kk] = muv;
+                        mod.rho[jj, ii, kk] = Rho;
+                        mod.pi[jj, ii, kk] = piv;
                     }
                 }
             }
@@ -201,13 +201,13 @@ void model(st_model *mod, GlobVar *gv)
                         kk = k - gv->POS[3] * gv->NZ;
 
                         if (gv->L) {
-                            mod->taus[jj][ii][kk] = ts;
-                            mod->taup[jj][ii][kk] = tp;
+                            mod.taus[jj, ii, kk] = ts;
+                            mod.taup[jj, ii, kk] = tp;
                         }
 
-                        mod->u[jj][ii][kk] = muv;
-                        mod->rho[jj][ii][kk] = Rho;
-                        mod->pi[jj][ii][kk] = piv;
+                        mod.u[jj, ii, kk] = muv;
+                        mod.rho[jj, ii, kk] = Rho;
+                        mod.pi[jj, ii, kk] = piv;
                     }
                 }
             }
diff --git a/genmod/rheinstetten_elastic.cpp b/genmod/rheinstetten_elastic.cpp
index dfc6375..ef22754 100644
--- a/genmod/rheinstetten_elastic.cpp
+++ b/genmod/rheinstetten_elastic.cpp
@@ -7,7 +7,7 @@
 #include "fd.hpp"
 #include "util.hpp"
 
-void model(st_model *mod, GlobVar *gv)
+void model(st_model &mod, GlobVar *gv)
 {
     /* local variables */
     float muv, piv, vp, vs, rhov;
@@ -92,9 +92,9 @@ void model(st_model *mod, GlobVar *gv)
                             jj = j - gv->POS[2] * gv->NY;
                             kk = k - gv->POS[3] * gv->NZ;
 
-                            mod->u[jj][ii][kk] = muv;
-                            mod->rho[jj][ii][kk] = rhov;
-                            mod->pi[jj][ii][kk] = piv;
+                            mod.u[jj, ii, kk] = muv;
+                            mod.rho[jj, ii, kk] = rhov;
+                            mod.pi[jj, ii, kk] = piv;
                         }
                     }
                 }
@@ -119,9 +119,9 @@ void model(st_model *mod, GlobVar *gv)
                     jj = j - gv->POS[2] * gv->NY;
                     kk = k - gv->POS[3] * gv->NZ;
 
-                    mod->u[jj][ii][kk] = muv;
-                    mod->rho[jj][ii][kk] = rhov;
-                    mod->pi[jj][ii][kk] = piv;
+                    mod.u[jj, ii, kk] = muv;
+                    mod.rho[jj, ii, kk] = rhov;
+                    mod.pi[jj, ii, kk] = piv;
                 }
             }
         }
diff --git a/src/absorb.cpp b/src/absorb.cpp
index fda56bb..40cd3ed 100644
--- a/src/absorb.cpp
+++ b/src/absorb.cpp
@@ -34,7 +34,7 @@
 #include "util.hpp"
 #include "logging.hpp"
 
-void absorb(float ***absorb_coeff, GlobVar *gv)
+void absorb(float3DTensorT &absorb_coeff, GlobVar *gv)
 {
     int ifw, xb, yb, zb, xe, ye, ze;
     float amp, a, *coeff;
@@ -71,7 +71,7 @@ void absorb(float ***absorb_coeff, GlobVar *gv)
     for (int k = 1; k <= gv->NZ; k++)
         for (int j = 1; j <= gv->NY; j++)
             for (int i = 1; i <= gv->NX; i++)
-                absorb_coeff[j][i][k] = 1.0;
+                absorb_coeff[j, i, k] = 1.0;
 
     /* compute coefficients for left and right grid boundaries (x-direction) */
     if ((!gv->BOUNDARY) && (gv->POS[1] == 0)) {
@@ -90,7 +90,7 @@ void absorb(float ***absorb_coeff, GlobVar *gv)
                 ye = gv->NY - i + 1;
             for (int k = zb; k <= ze; k++)
                 for (int j = yb; j <= ye; j++)
-                    absorb_coeff[j][i][k] = coeff[i];
+                    absorb_coeff[j, i, k] = coeff[i];
         }
     }
 
@@ -111,7 +111,7 @@ void absorb(float ***absorb_coeff, GlobVar *gv)
                 ye = gv->NY - i + 1;
             for (int k = zb; k <= ze; k++)
                 for (int j = yb; j <= ye; j++)
-                    absorb_coeff[j][ii][k] = coeff[i];
+                    absorb_coeff[j, ii, k] = coeff[i];
         }
     }
 
@@ -133,7 +133,7 @@ void absorb(float ***absorb_coeff, GlobVar *gv)
                 ye = gv->NY - k + 1;
             for (int i = xb; i <= xe; i++)
                 for (int j = yb; j <= ye; j++)
-                    absorb_coeff[j][i][k] = coeff[k];
+                    absorb_coeff[j, i, k] = coeff[k];
         }
     }
 
@@ -154,7 +154,7 @@ void absorb(float ***absorb_coeff, GlobVar *gv)
                 ye = gv->NY - k + 1;
             for (int i = xb; i <= xe; i++)
                 for (int j = yb; j <= ye; j++)
-                    absorb_coeff[j][i][kk] = coeff[k];
+                    absorb_coeff[j, i, kk] = coeff[k];
         }
     }
 
@@ -176,7 +176,7 @@ void absorb(float ***absorb_coeff, GlobVar *gv)
                 ze = gv->NZ - j + 1;
             for (int i = xb; i <= xe; i++)
                 for (int k = zb; k <= ze; k++)
-                    absorb_coeff[j][i][k] = coeff[j];
+                    absorb_coeff[j, i, k] = coeff[j];
         }
     }
 
@@ -197,7 +197,7 @@ void absorb(float ***absorb_coeff, GlobVar *gv)
                 ze = gv->NZ - j + 1;
             for (int i = xb; i <= xe; i++)
                 for (int k = zb; k <= ze; k++)
-                    absorb_coeff[jj][i][k] = coeff[j];
+                    absorb_coeff[jj, i, k] = coeff[j];
         }
     }
 
diff --git a/src/av_mat.cpp b/src/av_mat.cpp
index 0e94aed..82937db 100644
--- a/src/av_mat.cpp
+++ b/src/av_mat.cpp
@@ -25,15 +25,15 @@
 
 #include "fd.hpp"
 
-void av_mat(st_model *mod, st_model_av &mod_av, const GlobVar *gv)
+void av_mat(st_model &mod, st_model_av &mod_av, const GlobVar *gv)
 {
     for (int j = 1; j <= gv->NY; j++) {
         for (int i = 1; i <= gv->NX; i++) {
             #pragma omp simd
             for (int k = 1; k <= gv->NZ; k++) {
-                mod_av.rjp[j, i, k] = 0.5f * (mod->rho[j][i][k] + mod->rho[j + 1][i][k]);
-                mod_av.rkp[j, i, k] = 0.5f * (mod->rho[j][i][k] + mod->rho[j][i][k + 1]);
-                mod_av.rip[j, i, k] = 0.5f * (mod->rho[j][i][k] + mod->rho[j][i + 1][k]);
+                mod_av.rjp[j, i, k] = 0.5f * (mod.rho[j, i, k] + mod.rho[j + 1, i, k]);
+                mod_av.rkp[j, i, k] = 0.5f * (mod.rho[j, i, k] + mod.rho[j, i, k + 1]);
+                mod_av.rip[j, i, k] = 0.5f * (mod.rho[j, i, k] + mod.rho[j, i + 1, k]);
             }
         }
     }
@@ -44,28 +44,28 @@ void av_mat(st_model *mod, st_model_av &mod_av, const GlobVar *gv)
                     /* harmonic averaging of shear modulus */
                     mod_av.uipjp[j, i, k] =
                         4.0f /
-                        ((1.0f / mod->u[j][i][k]) + (1.0f / mod->u[j][i + 1][k]) + (1.0f / mod->u[j + 1][i + 1][k]) +
-                         (1.0f / mod->u[j + 1][i][k]));
+                        ((1.0f / mod.u[j, i, k]) + (1.0f / mod.u[j, i + 1, k]) + (1.0f / mod.u[j + 1, i + 1, k]) +
+                         (1.0f / mod.u[j + 1, i, k]));
                     mod_av.ujpkp[j, i, k] =
                         4.0f /
-                        ((1.0f / mod->u[j][i][k]) + (1.0f / mod->u[j][i][k + 1]) + (1.0f / mod->u[j + 1][i][k + 1]) +
-                         (1.0f / mod->u[j + 1][i][k]));
+                        ((1.0f / mod.u[j, i, k]) + (1.0f / mod.u[j, i, k + 1]) + (1.0f / mod.u[j + 1, i, k + 1]) +
+                         (1.0f / mod.u[j + 1, i, k]));
                     mod_av.uipkp[j, i, k] =
                         4.0f /
-                        ((1.0f / mod->u[j][i][k]) + (1.0f / mod->u[j][i][k + 1]) + (1.0f / mod->u[j][i + 1][k + 1]) +
-                         (1.0f / mod->u[j][i + 1][k]));
+                        ((1.0f / mod.u[j, i, k]) + (1.0f / mod.u[j, i, k + 1]) + (1.0f / mod.u[j, i + 1, k + 1]) +
+                         (1.0f / mod.u[j, i + 1, k]));
 
                     /* arithmetic averaging of TAU for S-waves and density */
                     if (gv->L) {
                         mod_av.tausipjp[j, i, k] =
-                            0.25f * (mod->taus[j][i][k] + mod->taus[j][i + 1][k] + mod->taus[j + 1][i + 1][k] +
-                                     mod->taus[j + 1][i][k]);
+                            0.25f * (mod.taus[j, i, k] + mod.taus[j, i + 1, k] + mod.taus[j + 1, i + 1, k] +
+                                     mod.taus[j + 1, i, k]);
                         mod_av.tausjpkp[j, i, k] =
-                            0.25f * (mod->taus[j][i][k] + mod->taus[j + 1][i][k] + mod->taus[j + 1][i][k + 1] +
-                                     mod->taus[j][i][k + 1]);
+                            0.25f * (mod.taus[j, i, k] + mod.taus[j + 1, i, k] + mod.taus[j + 1, i, k + 1] +
+                                     mod.taus[j, i, k + 1]);
                         mod_av.tausipkp[j, i, k] =
-                            0.25f * (mod->taus[j][i][k] + mod->taus[j][i + 1][k] + mod->taus[j][i + 1][k + 1] +
-                                     mod->taus[j][i][k + 1]);
+                            0.25f * (mod.taus[j, i, k] + mod.taus[j, i + 1, k] + mod.taus[j, i + 1, k + 1] +
+                                     mod.taus[j, i, k + 1]);
                     }
                 }
             }
diff --git a/src/checkfd_ssg.cpp b/src/checkfd_ssg.cpp
index 3043dca..8b36069 100644
--- a/src/checkfd_ssg.cpp
+++ b/src/checkfd_ssg.cpp
@@ -34,7 +34,7 @@
 #include "fd.hpp"
 #include "logging.hpp"
 
-void checkfd(st_model *mod, st_acquisition *acq, GlobVar *gv)
+void checkfd(st_model &mod, st_acquisition *acq, GlobVar *gv)
 {
     float c = 0.0, cmax_p = 0.0, cmin_p = 1e9, cmax_s = 0.0, cmin_s = 1e9, fmax;
     float dhmax, dhmin;
@@ -56,13 +56,13 @@ void checkfd(st_model *mod, st_acquisition *acq, GlobVar *gv)
         for (int k = 1 + nfw; k <= (nz - nfw); k++) {
             for (int i = 1 + nfw; i <= (nx - nfw); i++) {
                 for (int j = ny1; j <= (ny - nfw); j++) {
-                    if (mod->rho[j][i][k] == 0.0)
+                    if (mod.rho[j, i, k] == 0.0)
                         log_warn("rho=0 detected by MYID=%d at i=%d,j=%d,k=%d\n", gv->MYID, i, j, k);
                     else {
                         if (gv->L) {
-                            c = sqrt(mod->u[j][i][k] * (1.0 + gv->L * mod->taus[j][i][k]) / mod->rho[j][i][k]);
+                            c = sqrt(mod.u[j, i, k] * (1.0 + gv->L * mod.taus[j, i, k]) / mod.rho[j, i, k]);
                         } else
-                            c = sqrt(mod->u[j][i][k] / mod->rho[j][i][k]);
+                            c = sqrt(mod.u[j, i, k] / mod.rho[j, i, k]);
                     }
                     if (cmax_s < c)
                         cmax_s = c;
@@ -70,13 +70,13 @@ void checkfd(st_model *mod, st_acquisition *acq, GlobVar *gv)
                      * frequency of the source */
                     sum = 0.0;
                     for (int l = 1; l <= gv->L; l++) {
-                        ts = gv->DT / mod->eta[l];
-                        sum = sum + ((w * w * mod->taus[j][i][k] * ts * ts) / (1.0 + w * w * ts * ts));
+                        ts = gv->DT / mod.eta[l];
+                        sum = sum + ((w * w * mod.taus[j, i, k] * ts * ts) / (1.0 + w * w * ts * ts));
                     }
-                    if (mod->rho[j][i][k] == 0.0)
+                    if (mod.rho[j, i, k] == 0.0)
                         log_warn("rho=0 detected by MYID=%d at i=%d,j=%d,k=%d\n", gv->MYID, i, j, k);
                     else
-                        c = sqrt(mod->u[j][i][k] * (1.0 + sum) / mod->rho[j][i][k]);
+                        c = sqrt(mod.u[j, i, k] * (1.0 + sum) / mod.rho[j, i, k]);
                     if ((c > cwater) && (cmin_s > c))
                         cmin_s = c;
                 }
@@ -89,13 +89,13 @@ void checkfd(st_model *mod, st_acquisition *acq, GlobVar *gv)
     for (int k = 1 + nfw; k <= (nz - nfw); k++) {
         for (int i = 1 + nfw; i <= (nx - nfw); i++) {
             for (int j = ny1; j <= (ny - nfw); j++) {
-                if (mod->rho[j][i][k] == 0.0)
+                if (mod.rho[j, i, k] == 0.0)
                     log_warn("rho=0 detected by MYID=%d at i=%d,j=%d,k=%d\n", gv->MYID, i, j, k);
                 else {
                     if (gv->L)
-                        c = sqrt(mod->pi[j][i][k] * (1.0 + gv->L * mod->taup[j][i][k]) / mod->rho[j][i][k]);
+                        c = sqrt(mod.pi[j, i, k] * (1.0 + gv->L * mod.taup[j, i, k]) / mod.rho[j, i, k]);
                     else
-                        c = sqrt(mod->pi[j][i][k] / mod->rho[j][i][k]);
+                        c = sqrt(mod.pi[j, i, k] / mod.rho[j, i, k]);
                 }
                 if (cmax_p < c)
                     cmax_p = c;
@@ -103,13 +103,13 @@ void checkfd(st_model *mod, st_acquisition *acq, GlobVar *gv)
                  * frequency of the source */
                 sum = 0.0;
                 for (int l = 1; l <= gv->L; l++) {
-                    ts = gv->DT / mod->eta[l];
-                    sum = sum + ((w * w * mod->taup[j][i][k] * ts * ts) / (1.0 + w * w * ts * ts));
+                    ts = gv->DT / mod.eta[l];
+                    sum = sum + ((w * w * mod.taup[j, i, k] * ts * ts) / (1.0 + w * w * ts * ts));
                 }
-                if (mod->rho[j][i][k] == 0.0)
+                if (mod.rho[j, i, k] == 0.0)
                     log_warn("rho=0 detected by MYID=%d at i=%d,j=%d,k=%d\n", gv->MYID, i, j, k);
                 else
-                    c = sqrt(mod->pi[j][i][k] * (1.0 + sum) / mod->rho[j][i][k]);
+                    c = sqrt(mod.pi[j, i, k] * (1.0 + sum) / mod.rho[j, i, k]);
                 if (cmin_p > c)
                     cmin_p = c;
             }
diff --git a/src/constant_boundary.cpp b/src/constant_boundary.cpp
index 6095c01..0ebe82d 100644
--- a/src/constant_boundary.cpp
+++ b/src/constant_boundary.cpp
@@ -23,7 +23,7 @@
 
 #include "fd.hpp"
 
-void constant_boundary(const st_boundary *nb, st_model *mod, const GlobVar *gv)
+void constant_boundary(const st_boundary *nb, st_model &mod, const GlobVar *gv)
 {
     int dist = 4;
     int dum1 = 1;
@@ -34,9 +34,9 @@ void constant_boundary(const st_boundary *nb, st_model *mod, const GlobVar *gv)
             dum1 = 2;
             for (int i = 1; i <= gv->FW + dist; i++) {
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    mod->u[1][i][k] = mod->u[1][gv->FW + 1 + dist][k];
-                    mod->pi[1][i][k] = mod->pi[1][gv->FW + 1 + dist][k];
-                    mod->rho[1][i][k] = mod->rho[1][gv->FW + 1 + dist][k];
+                    mod.u[1, i, k] = mod.u[1, gv->FW + 1 + dist, k];
+                    mod.pi[1, i, k] = mod.pi[1, gv->FW + 1 + dist, k];
+                    mod.rho[1, i, k] = mod.rho[1, gv->FW + 1 + dist, k];
                 }
             }
         }
@@ -44,38 +44,31 @@ void constant_boundary(const st_boundary *nb, st_model *mod, const GlobVar *gv)
             dum2 = gv->NY - 1;
             for (int i = 1; i <= gv->FW + dist; i++) {
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    mod->u[gv->NY][i][k] = mod->u[gv->NY][gv->FW + 1 + dist][k];
-                    mod->pi[gv->NY][i][k] = mod->pi[gv->NY][gv->FW + 1 + dist][k];
-                    mod->rho[gv->NY][i][k] = mod->rho[gv->NY][gv->FW + 1 + dist][k];
+                    mod.u[gv->NY, i, k] = mod.u[gv->NY, gv->FW + 1 + dist, k];
+                    mod.pi[gv->NY, i, k] = mod.pi[gv->NY, gv->FW + 1 + dist, k];
+                    mod.rho[gv->NY, i, k] = mod.rho[gv->NY, gv->FW + 1 + dist, k];
                 }
             }
         }
         for (int j = dum1; j <= dum2; j++) {
             for (int i = 1; i <= gv->FW + dist; i++) {
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    mod->u[j][i][k] =
-                        (3.0 * mod->u[j][gv->FW + 1 + dist][k] + mod->u[j - 1][gv->FW + 1 + dist][k] +
-                         mod->u[j + 1][gv->FW + 1 + dist][k] + mod->u[j][gv->FW + 1 + dist][k - 1] +
-                         mod->u[j][gv->FW + 1 +
-                                   dist][k +
-                                         1] +
-                         mod->u[j][gv->FW + 2 + dist][k]) / 8.0f;
-                    mod->pi[j][i][k] =
-                        (3.0 * mod->pi[j][gv->FW + 1 + dist][k] + mod->pi[j - 1][gv->FW + 1 + dist][k] +
-                         mod->pi[j + 1][gv->FW + 1 + dist][k] + mod->pi[j][gv->FW + 1 + dist][k - 1] +
-                         mod->pi[j][gv->FW + 1 +
-                                    dist][
-                             k + 1] +
-                         mod->pi[j][gv->FW + 2 + dist][k]) / 8.0f;
-                    mod->rho[j][i][k] =
-                        (3.0 * mod->rho[j][gv->FW + 1 + dist][k] + mod->rho[j - 1][gv->FW + 1 + dist][k] +
-                         mod->rho[j + 1][gv->FW + 1 + dist][k] + mod->rho[j][gv->FW + 1 + dist][k - 1] +
-                         mod->rho[j][gv->FW + 1 +
-                                     dist]
-                         [k +
-                          1]
+                    mod.u[j, i, k] =
+                        (3.0 * mod.u[j, gv->FW + 1 + dist, k] + mod.u[j - 1, gv->FW + 1 + dist, k] +
+                         mod.u[j + 1, gv->FW + 1 + dist, k] + mod.u[j, gv->FW + 1 + dist, k - 1] +
+                         mod.u[j, gv->FW + 1 + dist, k + 1] +
+                         mod.u[j, gv->FW + 2 + dist, k]) / 8.0f;
+                    mod.pi[j, i, k] =
+                        (3.0 * mod.pi[j, gv->FW + 1 + dist, k] + mod.pi[j - 1, gv->FW + 1 + dist, k] +
+                         mod.pi[j + 1, gv->FW + 1 + dist, k] + mod.pi[j, gv->FW + 1 + dist, k - 1] +
+                         mod.pi[j, gv->FW + 1 + dist, k + 1] +
+                         mod.pi[j, gv->FW + 2 + dist, k]) / 8.0f;
+                    mod.rho[j, i, k] =
+                        (3.0 * mod.rho[j, gv->FW + 1 + dist, k] + mod.rho[j - 1, gv->FW + 1 + dist, k] +
+                         mod.rho[j + 1, gv->FW + 1 + dist, k] + mod.rho[j, gv->FW + 1 + dist, k - 1] +
+                         mod.rho[j, gv->FW + 1 + dist, k + 1]
                          +
-                         mod->rho[j][gv->FW + 2 + dist][k]) / 8.0f;
+                         mod.rho[j, gv->FW + 2 + dist, k]) / 8.0f;
                 }
             }
         }
@@ -86,9 +79,9 @@ void constant_boundary(const st_boundary *nb, st_model *mod, const GlobVar *gv)
             dum1 = 2;
             for (int i = nb->nx2 + 1 - dist; i <= nb->nx2 + gv->FW; i++) {
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    mod->u[1][i][k] = mod->u[1][nb->nx2 - dist][k];
-                    mod->pi[1][i][k] = mod->pi[1][nb->nx2 - dist][k];
-                    mod->rho[1][i][k] = mod->rho[1][nb->nx2 - dist][k];
+                    mod.u[1, i, k] = mod.u[1, nb->nx2 - dist, k];
+                    mod.pi[1, i, k] = mod.pi[1, nb->nx2 - dist, k];
+                    mod.rho[1, i, k] = mod.rho[1, nb->nx2 - dist, k];
                 }
             }
         }
@@ -96,33 +89,32 @@ void constant_boundary(const st_boundary *nb, st_model *mod, const GlobVar *gv)
             dum2 = gv->NY - 1;
             for (int i = nb->nx2 + 1 - dist; i <= nb->nx2 + gv->FW; i++) {
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    mod->u[gv->NY][i][k] = mod->u[gv->NY][nb->nx2 - dist][k];
-                    mod->pi[gv->NY][i][k] = mod->pi[gv->NY][nb->nx2 - dist][k];
-                    mod->rho[gv->NY][i][k] = mod->rho[gv->NY][nb->nx2 - dist][k];
+                    mod.u[gv->NY, i, k] = mod.u[gv->NY, nb->nx2 - dist, k];
+                    mod.pi[gv->NY, i, k] = mod.pi[gv->NY, nb->nx2 - dist, k];
+                    mod.rho[gv->NY, i, k] = mod.rho[gv->NY, nb->nx2 - dist, k];
                 }
             }
         }
         for (int j = dum1; j <= dum2; j++) {
             for (int i = nb->nx2 + 1 - dist; i <= nb->nx2 + gv->FW; i++) {
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    mod->u[j][i][k] =
-                        (3.0 * mod->u[j][nb->nx2 - dist][k] + mod->u[j - 1][nb->nx2 - dist][k] +
-                         mod->u[j + 1][nb->nx2 - dist][k] +
-                         mod->u[j][nb->nx2 - dist][k - 1] + mod->u[j][nb->nx2 - dist][k + 1] + mod->u[j][nb->nx2 - 1 -
-                                                                                                         dist][k]) /
+                    mod.u[j, i, k] =
+                        (3.0 * mod.u[j, nb->nx2 - dist, k] + mod.u[j - 1, nb->nx2 - dist, k] +
+                         mod.u[j + 1, nb->nx2 - dist, k] +
+                         mod.u[j, nb->nx2 - dist, k - 1] + mod.u[j, nb->nx2 - dist,
+                                                                 k + 1] + mod.u[j, nb->nx2 - 1 - dist, k]) /
                         8.0f;
-                    mod->pi[j][i][k] =
-                        (3.0 * mod->pi[j][nb->nx2 - dist][k] + mod->pi[j - 1][nb->nx2 - dist][k] +
-                         mod->pi[j + 1][nb->nx2 - dist][k] + mod->pi[j][nb->nx2 - dist][k - 1] +
-                         mod->pi[j][nb->nx2 - dist][k + 1] +
-                         mod->pi[j][nb->nx2 - 1 - dist][k]) / 8.0f;
-                    mod->rho[j][i][k] =
-                        (3.0 * mod->rho[j][nb->nx2 - dist][k] + mod->rho[j - 1][nb->nx2 - dist][k] +
-                         mod->rho[j + 1][nb->nx2 - dist][k] + mod->rho[j][nb->nx2 - dist][k - 1] +
-                         mod->rho[j][nb->nx2 - dist][k +
-                                                     1]
+                    mod.pi[j, i, k] =
+                        (3.0 * mod.pi[j, nb->nx2 - dist, k] + mod.pi[j - 1, nb->nx2 - dist, k] +
+                         mod.pi[j + 1, nb->nx2 - dist, k] + mod.pi[j, nb->nx2 - dist, k - 1] +
+                         mod.pi[j, nb->nx2 - dist, k + 1] +
+                         mod.pi[j, nb->nx2 - 1 - dist, k]) / 8.0f;
+                    mod.rho[j, i, k] =
+                        (3.0 * mod.rho[j, nb->nx2 - dist, k] + mod.rho[j - 1, nb->nx2 - dist, k] +
+                         mod.rho[j + 1, nb->nx2 - dist, k] + mod.rho[j, nb->nx2 - dist, k - 1] +
+                         mod.rho[j, nb->nx2 - dist, k + 1]
                          +
-                         mod->rho[j][nb->nx2 - 1 - dist][k]) / 8.0f;
+                         mod.rho[j, nb->nx2 - 1 - dist, k]) / 8.0f;
                 }
             }
         }
@@ -133,9 +125,9 @@ void constant_boundary(const st_boundary *nb, st_model *mod, const GlobVar *gv)
             dum1 = 2;
             for (int i = 1; i <= gv->NX; i++) {
                 for (int k = 1; k <= gv->FW + dist; k++) {
-                    mod->u[1][i][k] = mod->u[1][i][gv->FW + 1 + dist];
-                    mod->pi[1][i][k] = mod->pi[1][i][gv->FW + 1 + dist];
-                    mod->rho[1][i][k] = mod->rho[1][i][gv->FW + 1 + dist];
+                    mod.u[1, i, k] = mod.u[1, i, gv->FW + 1 + dist];
+                    mod.pi[1, i, k] = mod.pi[1, i, gv->FW + 1 + dist];
+                    mod.rho[1, i, k] = mod.rho[1, i, gv->FW + 1 + dist];
                 }
             }
         }
@@ -143,9 +135,9 @@ void constant_boundary(const st_boundary *nb, st_model *mod, const GlobVar *gv)
             dum2 = gv->NY - 1;
             for (int i = 1; i <= gv->NX; i++) {
                 for (int k = 1; k <= gv->FW + dist; k++) {
-                    mod->u[gv->NY][i][k] = mod->u[gv->NY][i][gv->FW + 1 + dist];
-                    mod->pi[gv->NY][i][k] = mod->pi[gv->NY][i][gv->FW + 1 + dist];
-                    mod->rho[gv->NY][i][k] = mod->rho[gv->NY][i][gv->FW + 1 + dist];
+                    mod.u[gv->NY, i, k] = mod.u[gv->NY, i, gv->FW + 1 + dist];
+                    mod.pi[gv->NY, i, k] = mod.pi[gv->NY, i, gv->FW + 1 + dist];
+                    mod.rho[gv->NY, i, k] = mod.rho[gv->NY, i, gv->FW + 1 + dist];
                 }
             }
         }
@@ -153,9 +145,9 @@ void constant_boundary(const st_boundary *nb, st_model *mod, const GlobVar *gv)
             for (int j = dum1; j <= dum2; j++) {
                 for (int i = 1; i <= gv->FW + dist; i++) {
                     for (int k = 1; k <= gv->FW + dist; k++) {
-                        mod->u[j][i][k] = mod->u[j][i][gv->FW + 1 + dist];
-                        mod->pi[j][i][k] = mod->pi[j][i][gv->FW + 1 + dist];
-                        mod->rho[j][i][k] = mod->rho[j][i][gv->FW + 1 + dist];
+                        mod.u[j, i, k] = mod.u[j, i, gv->FW + 1 + dist];
+                        mod.pi[j, i, k] = mod.pi[j, i, gv->FW + 1 + dist];
+                        mod.rho[j, i, k] = mod.rho[j, i, gv->FW + 1 + dist];
                     }
                 }
             }
@@ -164,9 +156,9 @@ void constant_boundary(const st_boundary *nb, st_model *mod, const GlobVar *gv)
             for (int j = dum1; j <= dum2; j++) {
                 for (int i = nb->nx2 + 1 - dist; i <= nb->nx2 + gv->FW; i++) {
                     for (int k = 1; k <= gv->FW + dist; k++) {
-                        mod->u[j][i][k] = mod->u[j][i][gv->FW + 1 + dist];
-                        mod->pi[j][i][k] = mod->pi[j][i][gv->FW + 1 + dist];
-                        mod->rho[j][i][k] = mod->rho[j][i][gv->FW + 1 + dist];
+                        mod.u[j, i, k] = mod.u[j, i, gv->FW + 1 + dist];
+                        mod.pi[j, i, k] = mod.pi[j, i, gv->FW + 1 + dist];
+                        mod.rho[j, i, k] = mod.rho[j, i, gv->FW + 1 + dist];
                     }
                 }
             }
@@ -174,30 +166,22 @@ void constant_boundary(const st_boundary *nb, st_model *mod, const GlobVar *gv)
         for (int j = dum1; j <= dum2; j++) {
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 for (int k = 1; k <= gv->FW + dist; k++) {
-                    mod->u[j][i][k] =
-                        (3.0 * mod->u[j][i][gv->FW + 1 + dist] + mod->u[j - 1][i][gv->FW + 1 + dist] +
-                         mod->u[j + 1][i][gv->FW + 1 + dist] + mod->u[j][i - 1][gv->FW + 1 + dist] +
-                         mod->u[j][i + 1][gv->FW + 1 +
-                                          dist]
+                    mod.u[j, i, k] =
+                        (3.0 * mod.u[j, i, gv->FW + 1 + dist] + mod.u[j - 1, i, gv->FW + 1 + dist] +
+                         mod.u[j + 1, i, gv->FW + 1 + dist] + mod.u[j, i - 1, gv->FW + 1 + dist] +
+                         mod.u[j, i + 1, gv->FW + 1 + dist]
                          +
-                         mod->u[j][i][gv->FW + 2 + dist]) / 8.0f;
-                    mod->pi[j][i][k] =
-                        (3.0 * mod->pi[j][i][gv->FW + 1 + dist] + mod->pi[j - 1][i][gv->FW + 1 + dist] +
-                         mod->pi[j + 1][i][gv->FW + 1 + dist] + mod->pi[j][i - 1][gv->FW + 1 + dist] +
-                         mod->pi[j][i + 1][gv->FW +
-                                           1
-                                           +
-                                           dist]
-                         +
-                         mod->pi[j][i][gv->FW + 2 + dist]) / 8.0f;
-                    mod->rho[j][i][k] =
-                        (3.0 * mod->rho[j][i][gv->FW + 1 + dist] + mod->rho[j - 1][i][gv->FW + 1 + dist] +
-                         mod->rho[j + 1][i][gv->FW + 1 + dist] + mod->rho[j][i - 1][gv->FW + 1 + dist] +
-                         mod->rho[j][i + 1][gv->FW +
-                                            1
-                                            +
-                                            dist]
-                         + mod->rho[j][i][gv->FW + 2 + dist]) / 8.0f;
+                         mod.u[j, i, gv->FW + 2 + dist]) / 8.0f;
+                    mod.pi[j, i, k] =
+                        (3.0 * mod.pi[j, i, gv->FW + 1 + dist] + mod.pi[j - 1, i, gv->FW + 1 + dist] +
+                         mod.pi[j + 1, i, gv->FW + 1 + dist] + mod.pi[j, i - 1, gv->FW + 1 + dist] +
+                         mod.pi[j, i + 1, gv->FW + 1 + dist] +
+                         mod.pi[j, i, gv->FW + 2 + dist]) / 8.0f;
+                    mod.rho[j, i, k] =
+                        (3.0 * mod.rho[j, i, gv->FW + 1 + dist] + mod.rho[j - 1, i, gv->FW + 1 + dist] +
+                         mod.rho[j + 1, i, gv->FW + 1 + dist] + mod.rho[j, i - 1, gv->FW + 1 + dist] +
+                         mod.rho[j, i + 1, gv->FW + 1 + dist]
+                         + mod.rho[j, i, gv->FW + 2 + dist]) / 8.0f;
                 }
             }
         }
@@ -208,9 +192,9 @@ void constant_boundary(const st_boundary *nb, st_model *mod, const GlobVar *gv)
             dum1 = 2;
             for (int i = 1; i <= gv->NX; i++) {
                 for (int k = nb->nz2 + 1 - dist; k <= nb->nz2 + gv->FW; k++) {
-                    mod->u[1][i][k] = mod->u[1][i][nb->nz2 - dist];
-                    mod->pi[1][i][k] = mod->pi[1][i][nb->nz2 - dist];
-                    mod->rho[1][i][k] = mod->rho[1][i][nb->nz2 - dist];
+                    mod.u[1, i, k] = mod.u[1, i, nb->nz2 - dist];
+                    mod.pi[1, i, k] = mod.pi[1, i, nb->nz2 - dist];
+                    mod.rho[1, i, k] = mod.rho[1, i, nb->nz2 - dist];
                 }
             }
         }
@@ -218,9 +202,9 @@ void constant_boundary(const st_boundary *nb, st_model *mod, const GlobVar *gv)
             dum2 = gv->NY - 1;
             for (int i = 1; i <= gv->NX; i++) {
                 for (int k = nb->nz2 + 1 - dist; k <= nb->nz2 + gv->FW; k++) {
-                    mod->u[gv->NY][i][k] = mod->u[gv->NY][i][nb->nz2 - dist];
-                    mod->pi[gv->NY][i][k] = mod->pi[gv->NY][i][nb->nz2 - dist];
-                    mod->rho[gv->NY][i][k] = mod->rho[gv->NY][i][nb->nz2 - dist];
+                    mod.u[gv->NY, i, k] = mod.u[gv->NY, i, nb->nz2 - dist];
+                    mod.pi[gv->NY, i, k] = mod.pi[gv->NY, i, nb->nz2 - dist];
+                    mod.rho[gv->NY, i, k] = mod.rho[gv->NY, i, nb->nz2 - dist];
                 }
             }
         }
@@ -228,9 +212,9 @@ void constant_boundary(const st_boundary *nb, st_model *mod, const GlobVar *gv)
             for (int j = dum1; j <= dum2; j++) {
                 for (int i = 1; i <= gv->FW + dist; i++) {
                     for (int k = nb->nz2 + 1 - dist; k <= nb->nz2 + gv->FW; k++) {
-                        mod->u[j][i][k] = mod->u[j][i][nb->nz2 - dist];
-                        mod->pi[j][i][k] = mod->pi[j][i][nb->nz2 - dist];
-                        mod->rho[j][i][k] = mod->rho[j][i][nb->nz2 - dist];
+                        mod.u[j, i, k] = mod.u[j, i, nb->nz2 - dist];
+                        mod.pi[j, i, k] = mod.pi[j, i, nb->nz2 - dist];
+                        mod.rho[j, i, k] = mod.rho[j, i, nb->nz2 - dist];
                     }
                 }
             }
@@ -239,9 +223,9 @@ void constant_boundary(const st_boundary *nb, st_model *mod, const GlobVar *gv)
             for (int j = dum1; j <= dum2; j++) {
                 for (int i = nb->nx2 + 1 - dist; i <= nb->nx2 + gv->FW; i++) {
                     for (int k = nb->nz2 + 1 - dist; k <= nb->nz2 + gv->FW; k++) {
-                        mod->u[j][i][k] = mod->u[j][i][nb->nz2 - dist];
-                        mod->pi[j][i][k] = mod->pi[j][i][nb->nz2 - dist];
-                        mod->rho[j][i][k] = mod->rho[j][i][nb->nz2 - dist];
+                        mod.u[j, i, k] = mod.u[j, i, nb->nz2 - dist];
+                        mod.pi[j, i, k] = mod.pi[j, i, nb->nz2 - dist];
+                        mod.rho[j, i, k] = mod.rho[j, i, nb->nz2 - dist];
                     }
                 }
             }
@@ -249,25 +233,22 @@ void constant_boundary(const st_boundary *nb, st_model *mod, const GlobVar *gv)
         for (int j = dum1; j <= dum2; j++) {
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 for (int k = nb->nz2 + 1 - dist; k <= nb->nz2 + gv->FW; k++) {
-                    mod->u[j][i][k] =
-                        (3.0 * mod->u[j][i][nb->nz2 - dist] + mod->u[j - 1][i][nb->nz2 - dist] +
-                         mod->u[j + 1][i][nb->nz2 - dist] +
-                         mod->u[j][i - 1][nb->nz2 - dist] + mod->u[j][i + 1][nb->nz2 - dist] +
-                         mod->u[j][i][nb->nz2 - 1 -
-                                      dist]) /
+                    mod.u[j, i, k] =
+                        (3.0 * mod.u[j, i, nb->nz2 - dist] + mod.u[j - 1, i, nb->nz2 - dist] +
+                         mod.u[j + 1, i, nb->nz2 - dist] +
+                         mod.u[j, i - 1, nb->nz2 - dist] + mod.u[j, i + 1, nb->nz2 - dist] +
+                         mod.u[j, i, nb->nz2 - 1 - dist]) /
                         8.0f;
-                    mod->pi[j][i][k] =
-                        (3.0 * mod->pi[j][i][nb->nz2 - dist] + mod->pi[j - 1][i][nb->nz2 - dist] +
-                         mod->pi[j + 1][i][nb->nz2 - dist] + mod->pi[j][i - 1][nb->nz2 - dist] +
-                         mod->pi[j][i + 1][nb->nz2 - dist] +
-                         mod->pi[j][i][nb->nz2 - dist - 1]) / 8.0f;
-                    mod->rho[j][i][k] =
-                        (3.0 * mod->rho[j][i][nb->nz2 - dist] + mod->rho[j - 1][i][nb->nz2 - dist] +
-                         mod->rho[j + 1][i][nb->nz2 - dist] + mod->rho[j][i - 1][nb->nz2 - dist] +
-                         mod->rho[j][i + 1][nb->nz2 -
-                                            dist]
-                         +
-                         mod->rho[j][i][nb->nz2 - dist - 1]) / 8.0f;
+                    mod.pi[j, i, k] =
+                        (3.0 * mod.pi[j, i, nb->nz2 - dist] + mod.pi[j - 1, i, nb->nz2 - dist] +
+                         mod.pi[j + 1, i, nb->nz2 - dist] + mod.pi[j, i - 1, nb->nz2 - dist] +
+                         mod.pi[j, i + 1, nb->nz2 - dist] +
+                         mod.pi[j, i, nb->nz2 - dist - 1]) / 8.0f;
+                    mod.rho[j, i, k] =
+                        (3.0 * mod.rho[j, i, nb->nz2 - dist] + mod.rho[j - 1, i, nb->nz2 - dist] +
+                         mod.rho[j + 1, i, nb->nz2 - dist] + mod.rho[j, i - 1, nb->nz2 - dist] +
+                         mod.rho[j, i + 1, nb->nz2 - dist] +
+                         mod.rho[j, i, nb->nz2 - dist - 1]) / 8.0f;
                 }
             }
         }
diff --git a/src/constant_boundary_acoustic.cpp b/src/constant_boundary_acoustic.cpp
index f8221df..63f2f5e 100644
--- a/src/constant_boundary_acoustic.cpp
+++ b/src/constant_boundary_acoustic.cpp
@@ -23,7 +23,7 @@
 
 #include "fd.hpp"
 
-void constant_boundary_acoustic(const st_boundary *nb, st_model *mod, const GlobVar *gv)
+void constant_boundary_acoustic(const st_boundary *nb, st_model &mod, const GlobVar *gv)
 {
     int dum1, dum2;
     int dist = 4;
@@ -36,8 +36,8 @@ void constant_boundary_acoustic(const st_boundary *nb, st_model *mod, const Glob
             dum1 = 2;
             for (int i = 1; i <= gv->FW + dist; i++) {
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    mod->pi[1][i][k] = mod->pi[1][gv->FW + 1 + dist][k];
-                    mod->rho[1][i][k] = mod->rho[1][gv->FW + 1 + dist][k];
+                    mod.pi[1, i, k] = mod.pi[1, gv->FW + 1 + dist, k];
+                    mod.rho[1, i, k] = mod.rho[1, gv->FW + 1 + dist, k];
                 }
             }
         }
@@ -45,22 +45,22 @@ void constant_boundary_acoustic(const st_boundary *nb, st_model *mod, const Glob
             dum2 = gv->NY - 1;
             for (int i = 1; i <= gv->FW + dist; i++) {
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    mod->pi[gv->NY][i][k] = mod->pi[gv->NY][gv->FW + 1 + dist][k];
-                    mod->rho[gv->NY][i][k] = mod->rho[gv->NY][gv->FW + 1 + dist][k];
+                    mod.pi[gv->NY, i, k] = mod.pi[gv->NY, gv->FW + 1 + dist, k];
+                    mod.rho[gv->NY, i, k] = mod.rho[gv->NY, gv->FW + 1 + dist, k];
                 }
             }
         }
         for (int j = dum1; j <= dum2; j++) {
             for (int i = 1; i <= gv->FW + dist; i++) {
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    mod->pi[j][i][k] =
-                        (3.0 * mod->pi[j][gv->FW + 1 + dist][k] + mod->pi[j - 1][gv->FW + 1 + dist][k] +
-                         mod->pi[j + 1][gv->FW + 1 + dist][k] + mod->pi[j][gv->FW + 1 + dist][k - 1] +
-                         mod->pi[j][gv->FW + 1 + dist][k + 1] + mod->pi[j][gv->FW + 2 + dist][k]) / 8.0f;
-                    mod->rho[j][i][k] =
-                        (3.0 * mod->rho[j][gv->FW + 1 + dist][k] + mod->rho[j - 1][gv->FW + 1 + dist][k] +
-                         mod->rho[j + 1][gv->FW + 1 + dist][k] + mod->rho[j][gv->FW + 1 + dist][k - 1] +
-                         mod->rho[j][gv->FW + 1 + dist][k + 1] + mod->rho[j][gv->FW + 2 + dist][k]) / 8.0f;
+                    mod.pi[j, i, k] =
+                        (3.0 * mod.pi[j, gv->FW + 1 + dist, k] + mod.pi[j - 1, gv->FW + 1 + dist, k] +
+                         mod.pi[j + 1, gv->FW + 1 + dist, k] + mod.pi[j, gv->FW + 1 + dist, k - 1] +
+                         mod.pi[j, gv->FW + 1 + dist, k + 1] + mod.pi[j, gv->FW + 2 + dist, k]) / 8.0f;
+                    mod.rho[j, i, k] =
+                        (3.0 * mod.rho[j, gv->FW + 1 + dist, k] + mod.rho[j - 1, gv->FW + 1 + dist, k] +
+                         mod.rho[j + 1, gv->FW + 1 + dist, k] + mod.rho[j, gv->FW + 1 + dist, k - 1] +
+                         mod.rho[j, gv->FW + 1 + dist, k + 1] + mod.rho[j, gv->FW + 2 + dist, k]) / 8.0f;
                 }
             }
         }
@@ -71,8 +71,8 @@ void constant_boundary_acoustic(const st_boundary *nb, st_model *mod, const Glob
             dum1 = 2;
             for (int i = nb->nx2 + 1 - dist; i <= nb->nx2 + gv->FW; i++) {
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    mod->pi[1][i][k] = mod->pi[1][nb->nx2 - dist][k];
-                    mod->rho[1][i][k] = mod->rho[1][nb->nx2 - dist][k];
+                    mod.pi[1, i, k] = mod.pi[1, nb->nx2 - dist, k];
+                    mod.rho[1, i, k] = mod.rho[1, nb->nx2 - dist, k];
                 }
             }
         }
@@ -80,23 +80,23 @@ void constant_boundary_acoustic(const st_boundary *nb, st_model *mod, const Glob
             dum2 = gv->NY - 1;
             for (int i = nb->nx2 + 1 - dist; i <= nb->nx2 + gv->FW; i++) {
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    mod->pi[gv->NY][i][k] = mod->pi[gv->NY][nb->nx2 - dist][k];
-                    mod->rho[gv->NY][i][k] = mod->rho[gv->NY][nb->nx2 - dist][k];
+                    mod.pi[gv->NY, i, k] = mod.pi[gv->NY, nb->nx2 - dist, k];
+                    mod.rho[gv->NY, i, k] = mod.rho[gv->NY, nb->nx2 - dist, k];
                 }
             }
         }
         for (int j = dum1; j <= dum2; j++) {
             for (int i = nb->nx2 + 1 - dist; i <= nb->nx2 + gv->FW; i++) {
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    mod->pi[j][i][k] =
-                        (3.0 * mod->pi[j][nb->nx2 - dist][k] + mod->pi[j - 1][nb->nx2 - dist][k] +
-                         mod->pi[j + 1][nb->nx2 - dist][k] + mod->pi[j][nb->nx2 - dist][k - 1] +
-                         mod->pi[j][nb->nx2 - dist][k + 1] +
-                         mod->pi[j][nb->nx2 - 1 - dist][k]) / 8.0f;
-                    mod->rho[j][i][k] =
-                        (3.0 * mod->rho[j][nb->nx2 - dist][k] + mod->rho[j - 1][nb->nx2 - dist][k] +
-                         mod->rho[j + 1][nb->nx2 - dist][k] + mod->rho[j][nb->nx2 - dist][k - 1] +
-                         mod->rho[j][nb->nx2 - dist][k + 1] + mod->rho[j][nb->nx2 - 1 - dist][k]) / 8.0f;
+                    mod.pi[j, i, k] =
+                        (3.0 * mod.pi[j, nb->nx2 - dist, k] + mod.pi[j - 1, nb->nx2 - dist, k] +
+                         mod.pi[j + 1, nb->nx2 - dist, k] + mod.pi[j, nb->nx2 - dist, k - 1] +
+                         mod.pi[j, nb->nx2 - dist, k + 1] +
+                         mod.pi[j, nb->nx2 - 1 - dist, k]) / 8.0f;
+                    mod.rho[j, i, k] =
+                        (3.0 * mod.rho[j, nb->nx2 - dist, k] + mod.rho[j - 1, nb->nx2 - dist, k] +
+                         mod.rho[j + 1, nb->nx2 - dist, k] + mod.rho[j, nb->nx2 - dist, k - 1] +
+                         mod.rho[j, nb->nx2 - dist, k + 1] + mod.rho[j, nb->nx2 - 1 - dist, k]) / 8.0f;
                 }
             }
         }
@@ -107,8 +107,8 @@ void constant_boundary_acoustic(const st_boundary *nb, st_model *mod, const Glob
             dum1 = 2;
             for (int i = 1; i <= gv->NX; i++) {
                 for (int k = 1; k <= gv->FW + dist; k++) {
-                    mod->pi[1][i][k] = mod->pi[1][i][gv->FW + 1 + dist];
-                    mod->rho[1][i][k] = mod->rho[1][i][gv->FW + 1 + dist];
+                    mod.pi[1, i, k] = mod.pi[1, i, gv->FW + 1 + dist];
+                    mod.rho[1, i, k] = mod.rho[1, i, gv->FW + 1 + dist];
                 }
             }
         }
@@ -116,8 +116,8 @@ void constant_boundary_acoustic(const st_boundary *nb, st_model *mod, const Glob
             dum2 = gv->NY - 1;
             for (int i = 1; i <= gv->NX; i++) {
                 for (int k = 1; k <= gv->FW + dist; k++) {
-                    mod->pi[gv->NY][i][k] = mod->pi[gv->NY][i][gv->FW + 1 + dist];
-                    mod->rho[gv->NY][i][k] = mod->rho[gv->NY][i][gv->FW + 1 + dist];
+                    mod.pi[gv->NY, i, k] = mod.pi[gv->NY, i, gv->FW + 1 + dist];
+                    mod.rho[gv->NY, i, k] = mod.rho[gv->NY, i, gv->FW + 1 + dist];
                 }
             }
         }
@@ -125,8 +125,8 @@ void constant_boundary_acoustic(const st_boundary *nb, st_model *mod, const Glob
             for (int j = dum1; j <= dum2; j++) {
                 for (int i = 1; i <= gv->FW + dist; i++) {
                     for (int k = 1; k <= gv->FW + dist; k++) {
-                        mod->pi[j][i][k] = mod->pi[j][i][gv->FW + 1 + dist];
-                        mod->rho[j][i][k] = mod->rho[j][i][gv->FW + 1 + dist];
+                        mod.pi[j, i, k] = mod.pi[j, i, gv->FW + 1 + dist];
+                        mod.rho[j, i, k] = mod.rho[j, i, gv->FW + 1 + dist];
                     }
                 }
             }
@@ -135,8 +135,8 @@ void constant_boundary_acoustic(const st_boundary *nb, st_model *mod, const Glob
             for (int j = dum1; j <= dum2; j++) {
                 for (int i = nb->nx2 + 1 - dist; i <= nb->nx2 + gv->FW; i++) {
                     for (int k = 1; k <= gv->FW + dist; k++) {
-                        mod->pi[j][i][k] = mod->pi[j][i][gv->FW + 1 + dist];
-                        mod->rho[j][i][k] = mod->rho[j][i][gv->FW + 1 + dist];
+                        mod.pi[j, i, k] = mod.pi[j, i, gv->FW + 1 + dist];
+                        mod.rho[j, i, k] = mod.rho[j, i, gv->FW + 1 + dist];
                     }
                 }
             }
@@ -144,14 +144,14 @@ void constant_boundary_acoustic(const st_boundary *nb, st_model *mod, const Glob
         for (int j = dum1; j <= dum2; j++) {
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 for (int k = 1; k <= gv->FW + dist; k++) {
-                    mod->pi[j][i][k] =
-                        (3.0 * mod->pi[j][i][gv->FW + 1 + dist] + mod->pi[j - 1][i][gv->FW + 1 + dist] +
-                         mod->pi[j + 1][i][gv->FW + 1 + dist] + mod->pi[j][i - 1][gv->FW + 1 + dist] +
-                         mod->pi[j][i + 1][gv->FW + 1 + dist] + mod->pi[j][i][gv->FW + 2 + dist]) / 8.0f;
-                    mod->rho[j][i][k] =
-                        (3.0 * mod->rho[j][i][gv->FW + 1 + dist] + mod->rho[j - 1][i][gv->FW + 1 + dist] +
-                         mod->rho[j + 1][i][gv->FW + 1 + dist] + mod->rho[j][i - 1][gv->FW + 1 + dist] +
-                         mod->rho[j][i + 1][gv->FW + 1 + dist] + mod->rho[j][i][gv->FW + 2 + dist]) / 8.0f;
+                    mod.pi[j, i, k] =
+                        (3.0 * mod.pi[j, i, gv->FW + 1 + dist] + mod.pi[j - 1, i, gv->FW + 1 + dist] +
+                         mod.pi[j + 1, i, gv->FW + 1 + dist] + mod.pi[j, i - 1, gv->FW + 1 + dist] +
+                         mod.pi[j, i + 1, gv->FW + 1 + dist] + mod.pi[j, i, gv->FW + 2 + dist]) / 8.0f;
+                    mod.rho[j, i, k] =
+                        (3.0 * mod.rho[j, i, gv->FW + 1 + dist] + mod.rho[j - 1, i, gv->FW + 1 + dist] +
+                         mod.rho[j + 1, i, gv->FW + 1 + dist] + mod.rho[j, i - 1, gv->FW + 1 + dist] +
+                         mod.rho[j, i + 1, gv->FW + 1 + dist] + mod.rho[j, i, gv->FW + 2 + dist]) / 8.0f;
                 }
             }
         }
@@ -162,8 +162,8 @@ void constant_boundary_acoustic(const st_boundary *nb, st_model *mod, const Glob
             dum1 = 2;
             for (int i = 1; i <= gv->NX; i++) {
                 for (int k = nb->nz2 + 1 - dist; k <= nb->nz2 + gv->FW; k++) {
-                    mod->pi[1][i][k] = mod->pi[1][i][nb->nz2 - dist];
-                    mod->rho[1][i][k] = mod->rho[1][i][nb->nz2 - dist];
+                    mod.pi[1, i, k] = mod.pi[1, i, nb->nz2 - dist];
+                    mod.rho[1, i, k] = mod.rho[1, i, nb->nz2 - dist];
                 }
             }
         }
@@ -171,8 +171,8 @@ void constant_boundary_acoustic(const st_boundary *nb, st_model *mod, const Glob
             dum2 = gv->NY - 1;
             for (int i = 1; i <= gv->NX; i++) {
                 for (int k = nb->nz2 + 1 - dist; k <= nb->nz2 + gv->FW; k++) {
-                    mod->pi[gv->NY][i][k] = mod->pi[gv->NY][i][nb->nz2 - dist];
-                    mod->rho[gv->NY][i][k] = mod->rho[gv->NY][i][nb->nz2 - dist];
+                    mod.pi[gv->NY, i, k] = mod.pi[gv->NY, i, nb->nz2 - dist];
+                    mod.rho[gv->NY, i, k] = mod.rho[gv->NY, i, nb->nz2 - dist];
                 }
             }
         }
@@ -180,8 +180,8 @@ void constant_boundary_acoustic(const st_boundary *nb, st_model *mod, const Glob
             for (int j = dum1; j <= dum2; j++) {
                 for (int i = 1; i <= gv->FW + dist; i++) {
                     for (int k = nb->nz2 + 1 - dist; k <= nb->nz2 + gv->FW; k++) {
-                        mod->pi[j][i][k] = mod->pi[j][i][nb->nz2 - dist];
-                        mod->rho[j][i][k] = mod->rho[j][i][nb->nz2 - dist];
+                        mod.pi[j, i, k] = mod.pi[j, i, nb->nz2 - dist];
+                        mod.rho[j, i, k] = mod.rho[j, i, nb->nz2 - dist];
                     }
                 }
             }
@@ -190,8 +190,8 @@ void constant_boundary_acoustic(const st_boundary *nb, st_model *mod, const Glob
             for (int j = dum1; j <= dum2; j++) {
                 for (int i = nb->nx2 + 1 - dist; i <= nb->nx2 + gv->FW; i++) {
                     for (int k = nb->nz2 + 1 - dist; k <= nb->nz2 + gv->FW; k++) {
-                        mod->pi[j][i][k] = mod->pi[j][i][nb->nz2 - dist];
-                        mod->rho[j][i][k] = mod->rho[j][i][nb->nz2 - dist];
+                        mod.pi[j, i, k] = mod.pi[j, i, nb->nz2 - dist];
+                        mod.rho[j, i, k] = mod.rho[j, i, nb->nz2 - dist];
                     }
                 }
             }
@@ -199,14 +199,14 @@ void constant_boundary_acoustic(const st_boundary *nb, st_model *mod, const Glob
         for (int j = dum1; j <= dum2; j++) {
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 for (int k = nb->nz2 + 1 - dist; k <= nb->nz2 + gv->FW; k++) {
-                    mod->pi[j][i][k] =
-                        (3.0 * mod->pi[j][i][nb->nz2 - dist] + mod->pi[j - 1][i][nb->nz2 - dist] +
-                         mod->pi[j + 1][i][nb->nz2 - dist] + mod->pi[j][i - 1][nb->nz2 - dist] +
-                         mod->pi[j][i + 1][nb->nz2 - dist] + mod->pi[j][i][nb->nz2 - dist - 1]) / 8.0f;
-                    mod->rho[j][i][k] =
-                        (3.0 * mod->rho[j][i][nb->nz2 - dist] + mod->rho[j - 1][i][nb->nz2 - dist] +
-                         mod->rho[j + 1][i][nb->nz2 - dist] + mod->rho[j][i - 1][nb->nz2 - dist] +
-                         mod->rho[j][i + 1][nb->nz2 - dist] + mod->rho[j][i][nb->nz2 - dist - 1]) / 8.0f;
+                    mod.pi[j, i, k] =
+                        (3.0 * mod.pi[j, i, nb->nz2 - dist] + mod.pi[j - 1, i, nb->nz2 - dist] +
+                         mod.pi[j + 1, i, nb->nz2 - dist] + mod.pi[j, i - 1, nb->nz2 - dist] +
+                         mod.pi[j, i + 1, nb->nz2 - dist] + mod.pi[j, i, nb->nz2 - dist - 1]) / 8.0f;
+                    mod.rho[j, i, k] =
+                        (3.0 * mod.rho[j, i, nb->nz2 - dist] + mod.rho[j - 1, i, nb->nz2 - dist] +
+                         mod.rho[j + 1, i, nb->nz2 - dist] + mod.rho[j, i - 1, nb->nz2 - dist] +
+                         mod.rho[j, i + 1, nb->nz2 - dist] + mod.rho[j, i, nb->nz2 - dist - 1]) / 8.0f;
                 }
             }
         }
diff --git a/src/cpmodel.cpp b/src/cpmodel.cpp
index 3087111..49370c4 100644
--- a/src/cpmodel.cpp
+++ b/src/cpmodel.cpp
@@ -24,20 +24,20 @@
 
 #include "fd.hpp"
 
-void cpmodel(st_model *mod, st_model *testmod, const GlobVar *gv)
+void cpmodel(st_model &mod, st_model &testmod, const GlobVar *gv)
 {
     for (int j = 1; j <= gv->NY; j++) {
         for (int i = 1; i <= gv->NX; i++) {
             for (int k = 1; k <= gv->NZ; k++) {
-                testmod->rho[j][i][k] = 0.0;
-                testmod->rho[j][i][k] = mod->rho[j][i][k];
+                testmod.rho[j, i, k] = 0.0;
+                testmod.rho[j, i, k] = mod.rho[j, i, k];
 
-                testmod->pi[j][i][k] = 0.0;
-                testmod->pi[j][i][k] = mod->pi[j][i][k];
+                testmod.pi[j, i, k] = 0.0;
+                testmod.pi[j, i, k] = mod.pi[j, i, k];
 
                 if (gv->L) {
-                    testmod->taup[j][i][k] = 0.0;
-                    testmod->taup[j][i][k] = mod->taup[j][i][k];
+                    testmod.taup[j, i, k] = 0.0;
+                    testmod.taup[j, i, k] = mod.taup[j, i, k];
                 }
             }
         }
@@ -46,12 +46,12 @@ void cpmodel(st_model *mod, st_model *testmod, const GlobVar *gv)
         for (int j = 1; j <= gv->NY; j++) {
             for (int i = 1; i <= gv->NX; i++) {
                 for (int k = 1; k <= gv->NZ; k++) {
-                    testmod->u[j][i][k] = 0.0;
-                    testmod->u[j][i][k] = mod->u[j][i][k];
+                    testmod.u[j, i, k] = 0.0;
+                    testmod.u[j, i, k] = mod.u[j, i, k];
 
                     if (gv->L) {
-                        testmod->taus[j][i][k] = 0.0;
-                        testmod->taus[j][i][k] = mod->taus[j][i][k];
+                        testmod.taus[j, i, k] = 0.0;
+                        testmod.taus[j, i, k] = mod.taus[j, i, k];
                     }
                 }
             }
@@ -60,8 +60,8 @@ void cpmodel(st_model *mod, st_model *testmod, const GlobVar *gv)
 
     if (gv->L) {
         for (int l = 1; l <= gv->L; l++) {
-            testmod->eta[l] = 0.0;
-            testmod->eta[l] = mod->eta[l];
+            testmod.eta[l] = 0.0;
+            testmod.eta[l] = mod.eta[l];
         }
     }
 }
diff --git a/src/fd.hpp b/src/fd.hpp
index 6b2b6ca..efa255b 100644
--- a/src/fd.hpp
+++ b/src/fd.hpp
@@ -39,10 +39,11 @@
 #include "float3DTensorT.hpp"
 
 typedef struct {
-    float ***rho, ***pi, ***u;
+    float3DTensorT rho, pi, u;
     /* Variables for viscoelastic modeling */
-    float ***taus, ***taup, *eta;
-    float ***absorb_coeff;
+    float3DTensorT taus, taup;
+    float *eta;
+    float3DTensorT absorb_coeff;
 } st_model;
 
 typedef struct {
@@ -156,13 +157,13 @@ typedef struct Acquisition {
 
 /* declaration of functions */
 
-void absorb(float ***absorb_coeff, GlobVar *gv);
+void absorb(float3DTensorT &absorb_coeff, GlobVar *gv);
 
 void absorb_PML(float ***absorb_coeffx, float ***absorb_coeffy, float ***absorb_coeffz);
 
 void CPML_coeff(st_pml_coeff *pml_coeff, const GlobVar *gv);
 
-void av_mat(st_model *mod, st_model_av &mod_av, const GlobVar *gv);
+void av_mat(st_model &mod, st_model_av &mod_av, const GlobVar *gv);
 
 void calc_res(int ishot, int shot_id, st_seismogram *section, st_seismogram *section_obs, st_signals *signals,
               int ntr_loc, const float *finv, int nf, double *L2, int res_switch, int groupnum,
@@ -170,9 +171,9 @@ void calc_res(int ishot, int shot_id, st_seismogram *section, st_seismogram *sec
 
 void catseis(float **data, float **fulldata, const int *recswitch, int ntr_glob, int ns, const GlobVar *gv);
 
-void checkfd(st_model *mod, st_acquisition *acq, GlobVar *gv);
+void checkfd(st_model &mod, st_acquisition *acq, GlobVar *gv);
 
-void checkfd_rsg(FILE *fp, st_model *mod);
+void checkfd_rsg(FILE *fp, st_model &mod);
 
 void check_recfile(const st_acquisition *acq, const GlobVar *gv);
 
@@ -182,8 +183,8 @@ void comm_ini(st_buffer *buffer, MPI_Request *req_send, MPI_Request *req_rec);
 
 void comm_ini_s(st_buffer *buffer, MPI_Request *req_send, MPI_Request *req_rec);
 
-void freemem(int nsrc_loc, st_acquisition *acq, st_model *mod,
-             st_model *testmod, st_model_av &mod_av, st_visc_mem *visco_mem, st_pml_coeff *pml_coeff,
+void freemem(int nsrc_loc, st_acquisition *acq, st_model &mod,
+             st_model &testmod, st_model_av &mod_av, st_visc_mem *visco_mem, st_pml_coeff *pml_coeff,
              st_pml_wfd &pml_wfd, st_signals *signals,
              st_gradient *grad, st_gradient *grad_prior1, st_gradient *grad_prior2, st_gradient *grad_halo,
              st_hessian *hessian,
@@ -195,7 +196,7 @@ void freemem_seis(int ntr_loc, st_seismogram *section, st_seismogram *section_ob
 
 void globvar_change(GlobVar *gv);
 
-int initmem(st_model *mod, st_model *testmod, st_model_av &mod_av, st_visc_mem *visco_mem,
+int initmem(st_model &mod, st_model &testmod, st_model_av &mod_av, st_visc_mem *visco_mem,
             st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd, st_gradient *grad, st_gradient *grad_prior1,
             st_gradient *grad_prior2, st_gradient *grad_halo, st_hessian *hessian, st_stress &stress,
             st_buffer_flat *stressbuff,
@@ -206,15 +207,15 @@ void initproc(GlobVar *gv);
 
 void initseis(int *ntr_loc, st_seismogram *section, st_seismogram *section_obs, st_signals *signals, GlobVar *gv);
 
-void matcopy(st_model *mod, GlobVar *gv);
+void matcopy(st_model &mod, GlobVar *gv);
 
 void merge(int nsnap, int type, const GlobVar *gv);
 
 void mergemod(const char *modfile, int format, GlobVar *gv);
 
-void readmod(st_model *mod, GlobVar *gv);
+void readmod(st_model &mod, GlobVar *gv);
 
-void model(st_model *mod, GlobVar *gv);
+void model(st_model &mod, GlobVar *gv);
 
 float normalize_trace(float **section, int i, int ns, const GlobVar *gv);
 
@@ -270,17 +271,17 @@ void savesig(float **signals, st_acquisition *acq, int nsrc_loc, int ishot, int
 int **scan_topo(GlobVar *gv);
 
 void seismo(int lsamp, int ntr, int **recpos, st_seismogram *section, st_velocity &vel, st_stress &stress,
-            st_model *mod, const GlobVar *gv);
+            st_model &mod, const GlobVar *gv);
 
 void seismo_rsg(int lsamp, int ntr, int **recpos, float **sectionvx, float **sectionvy,
                 float **sectionvz, float **sectiondiv, float **sectioncurl, float **sectionp,
-                st_velocity &vel, st_stress &stress, st_model *mod);
+                st_velocity &vel, st_stress &stress, st_model &mod);
 
-void snap(int nt, int nsnap, st_velocity &vel, st_stress &stress, const st_model *mod,
+void snap(int nt, int nsnap, st_velocity &vel, st_stress &stress, const st_model &mod,
           const st_boundary *nb, GlobVar *gv);
 
 void snap_rsg(FILE *fp, int nt, int nsnap, int format, int type,
-              st_velocity &vel, st_stress &stress, st_model *mod,
+              st_velocity &vel, st_stress &stress, st_model &mod,
               int idx, int idy, int idz, int nx1, int ny1, int nz1, int nx2, int ny2, int nz2);
 
 void snapmerge(int nsnap, GlobVar *gv);
@@ -288,7 +289,7 @@ void snapmerge(int nsnap, GlobVar *gv);
 void sources(FILE *fpsrc, int *nsrc, float **srcpos, GlobVar *gv, int **topo);
 
 void stfi(st_acquisition *acq, st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress &stress,
-          st_model *mod, st_model_av &mod_av, st_visc_mem *visco_mem, st_seismogram *section,
+          st_model &mod, st_model_av &mod_av, st_visc_mem *visco_mem, st_seismogram *section,
           st_seismogram *section_obs, st_signals *signals, int nsrc_loc, int ntr_loc, st_pml_coeff *pml_coeff,
           st_pml_wfd &pml_wfd, st_buffer_flat *stressbuff, st_buffer_flat *velbuff, st_freq_velocity *fourier_vel,
           const float *finv, double *L2, int nf, int ntast, int lsnap, int nsnap, int ishot, int shot_id, int cdf,
@@ -309,20 +310,20 @@ void splitrec(int *ntr_loc, st_acquisition *acq, const GlobVar *gv);
 
 float **splitsrc(float **srcpos, int *nsrc_loc, int nsrc, int *srcswitch, GlobVar *gv);
 
-void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd, st_visc_mem *mem,
+void surface(int ndepth, st_model &mod, st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd, st_visc_mem *mem,
              st_stress &stress, st_velocity &vel);
 
 void update_s_rsg(st_boundary *nb, st_velocity &vel, st_stress &stress,
-                  st_visc_mem *mem, st_model *mod, float ***taus, float ***taup, float *eta);
+                  st_visc_mem *mem, st_model &mod, float ***taus, float ***taup, float *eta);
 
 void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av &mod_av,
-              float ***absorb_coeff, const GlobVar *gv);
+    float3DTensorT &absorb_coeff, const GlobVar *gv);
 
 void update_v_CPML(st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av &mod_av,
                    st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd, const GlobVar *gv);
 
 void update_v_rsg(st_boundary *nb, int nt, st_velocity &vel, st_stress &stress,
-                  float ***rho, float **srcpos_loc, float **signals, int nsrc, float ***absorb_coeff);
+                  float ***rho, float **srcpos_loc, float **signals, int nsrc, float3DTensorT &absorb_coeff);
 
 void wavelet(float **srcpos_loc, int nsrc, int sourceshape, float **signals, float **sig_raw, float freq,
              const GlobVar *gv);
@@ -370,13 +371,13 @@ void zero_wavefield(st_velocity &vel, st_stress &stress, st_visc_mem *mem, st_pm
 
 void gradient_F(int nx, int ny, int nz, st_freq_velocity *fw, st_freq_velocity *back, st_gradient *grad,
                 st_hessian *hessian,
-                st_model *mod, const float *finv, int nf, const GlobVar *gv);
+                st_model &mod, const float *finv, int nf, const GlobVar *gv);
 
 void gradient_smoothing(st_gradient *grad, const GlobVar *gv);
 
 void readgrad(st_gradient *grad, st_gradient *grad_halo, float finv, int iteration, int **topo, int gtop, GlobVar *gv);
 
-void modelupdate(st_gradient *grad, st_model *mod, float step, int it_group, GlobVar *gv);
+void modelupdate(st_gradient *grad, st_model &mod, float step, int it_group, GlobVar *gv);
 
 void zero_invers(st_freq_velocity *fourier_fw, st_freq_velocity *fourier_back, int nfmax, const GlobVar *gv);
 
@@ -386,7 +387,7 @@ void outgrad(st_gradient *grad, float finv, int iteration, const char *outfile,
 
 void outhess(st_hessian *hessian, float finv, int iteration, const char *outfile, GlobVar *gv);
 
-void outmod(const st_model *mod, int iteration, GlobVar *gv);
+void outmod(const st_model &mod, int iteration, GlobVar *gv);
 
 void steplength(int iteration, double *L2, float *step, int it_group, GlobVar *gv);
 
@@ -394,19 +395,19 @@ void zero_grad(st_gradient *grad, const GlobVar *gv);
 
 void zero_hess(st_hessian *hessian, const GlobVar *gv);
 
-void cpmodel(st_model *mod, st_model *testmod, const GlobVar *gv);
+void cpmodel(st_model &mod, st_model &testmod, const GlobVar *gv);
 
 void conjugate(st_gradient *grad, st_gradient *grad_prior1, st_gradient *grad_prior2,
                float *beta, int cdf, GlobVar *gv);
 
 double update_s_elastic(st_boundary *nb, st_velocity &vel, st_stress &stress,
-                        st_model *mod, st_model_av &mod_av, const GlobVar *gv);
+                        st_model &mod, st_model_av &mod_av, const GlobVar *gv);
 
 double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
-                             st_stress &stress, st_model *mod, st_model_av &mod_av, st_pml_coeff *pml_coeff,
+                             st_stress &stress, st_model &mod, st_model_av &mod_av, st_pml_coeff *pml_coeff,
                              st_pml_wfd &pml_wfd, const GlobVar *gv);
 
-void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd, st_stress &stress,
+void surface_elastic(int ndepth, st_model &mod, st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd, st_stress &stress,
                      st_velocity &vel, const GlobVar *gv);
 
 void readinv(float *finv, int *nf, int *groupnum, int *itpergroup, int nfmax, GlobVar *gv);
@@ -417,9 +418,9 @@ void discfourier(const st_boundary *nb, int nt, st_velocity &vel,
 
 void filt_seis(float **data, int ntr, int ns, float finv, const GlobVar *gv);
 
-void model_gauss(st_model *mod);
+void model_gauss(st_model &mod);
 
-void model2_5(st_model *mod);
+void model2_5(st_model &mod);
 
 void hess_apply(const st_boundary *nb, st_gradient *grad, st_hessian *hessian, const GlobVar *gv);
 
@@ -429,32 +430,32 @@ void lbfgs(st_gradient *grad, int iteration, GlobVar *gv);
 
 void lbfgs_savegrad(st_gradient *grad, const GlobVar *gv);
 
-void constant_boundary(const st_boundary *nb, st_model *mod, const GlobVar *gv);
+void constant_boundary(const st_boundary *nb, st_model &mod, const GlobVar *gv);
 
-void constant_boundary_acoustic(const st_boundary *nb, st_model *mod, const GlobVar *gv);
+void constant_boundary_acoustic(const st_boundary *nb, st_model &mod, const GlobVar *gv);
 
 double exchange_s_acoustic(st_stress &stress, st_buffer_flat *buffer, GlobVar *gv);
 
 void gradient_F_acoustic(int nx, int ny, int nz, st_freq_velocity *fw, st_freq_velocity *back, st_gradient *grad,
                          st_hessian *hessian,
-                         st_model *mod, const float *finv, int nf, const GlobVar *gv);
+                         st_model &mod, const float *finv, int nf, const GlobVar *gv);
 
-void matcopy_acoustic(st_model *mod, GlobVar *gv);
+void matcopy_acoustic(st_model &mod, GlobVar *gv);
 
-void modelupdate_acoustic(st_gradient *grad, st_model *mod, float step, int it_group, GlobVar *gv);
+void modelupdate_acoustic(st_gradient *grad, st_model &mod, float step, int it_group, GlobVar *gv);
 
 void precon_grad_acoustic(int ishot, st_gradient *grad, st_acquisition *acq, GlobVar *gv);
 
 void surface_acoustic(int ndepth, st_stress &stress, const GlobVar *gv);
 
-double update_s_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress, st_model *mod, const GlobVar *gv);
+double update_s_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress, st_model &mod, const GlobVar *gv);
 
 double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
-                              st_stress &stress, st_model *mod, st_pml_coeff *pml_coeff,
+                              st_stress &stress, st_model &mod, st_pml_coeff *pml_coeff,
                               st_pml_wfd &pml_wfd, const GlobVar *gv);
 
 void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress &stress,
-                       st_model_av &mod_av, float ***absorb_coeff, const GlobVar *gv);
+                       st_model_av &mod_av, float3DTensorT &absorb_coeff, const GlobVar *gv);
 
 void update_v_CPML_acoustic(st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av &mod_av,
                             st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd, const GlobVar *gv);
@@ -463,9 +464,9 @@ void zero_wavefield_acoustic(st_velocity &vel, st_stress &stress, st_visc_mem *m
                              const GlobVar *gv);
 
 void timeloop(st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress &stress,
-              st_model *mod, st_model_av &mod_av, st_seismogram *section,
+              st_model &mod, st_model_av &mod_av, st_seismogram *section,
               float **srcpos_loc, int **recpos_loc, st_signals *signals, int nsrc_loc,
-              float ***absorb_coeff, st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd,
+              float3DTensorT &absorb_coeff, st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd,
               st_buffer_flat *stressbuff, st_buffer_flat *velbuff, st_freq_velocity *fourier_vel,
               const float *finv, int nf, int ntast, int ntr, int lsnap, int nsnap, int pshot, int shot_id, int proptype,
               GlobVar *gv);
diff --git a/src/float3DTensorT.hpp b/src/float3DTensorT.hpp
index d4ac128..7e96f5f 100644
--- a/src/float3DTensorT.hpp
+++ b/src/float3DTensorT.hpp
@@ -27,6 +27,7 @@ public:
     void free();
 
     constexpr float &operator[](const int &i, const int &j, const int &k) noexcept;
+    constexpr const float &operator[](const int &i, const int &j, const int &k) const noexcept;
 
     constexpr int lb_i() noexcept;
     constexpr int ub_i() noexcept;
@@ -53,4 +54,15 @@ constexpr float &float3DTensorT::operator[](const int &i, const int &j, const in
     return data[index];
 }
 
+// https://en.cppreference.com/w/cpp/language/operators#Array_subscript_operator
+constexpr const float &float3DTensorT::operator[](const int &i, const int &j, const int &k) const noexcept
+{
+    assert(_lb_i <= i and i <= _ub_i);
+    assert(_lb_j <= j and j <= _ub_j);
+    assert(_lb_k <= k and k <= _ub_k);
+    const size_t index = i * _stride_i + j * _stride_j + k - offset;
+    assert(index < _size);
+    return data[index];
+}
+
 #endif
diff --git a/src/freemem.cpp b/src/freemem.cpp
index cfa9080..23f96df 100644
--- a/src/freemem.cpp
+++ b/src/freemem.cpp
@@ -24,7 +24,7 @@
 #include "fd.hpp"
 #include "util.hpp"
 
-void freemem(int nsrc_loc, st_acquisition *acq, st_model *mod, st_model *testmod,
+void freemem(int nsrc_loc, st_acquisition *acq, st_model &mod, st_model &testmod,
              st_model_av &mod_av, st_visc_mem *visco_mem, st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd,
              st_signals *signals, st_gradient *grad, st_gradient *grad_prior1, st_gradient *grad_prior2,
              st_gradient *grad_halo,
@@ -260,9 +260,9 @@ void freemem(int nsrc_loc, st_acquisition *acq, st_model *mod, st_model *testmod
             free_f3tensor(visco_mem->ryz, 1, gv->NY, 1, gv->NX, 1, gv->NZ);
             free_f3tensor(visco_mem->rxz, 1, gv->NY, 1, gv->NX, 1, gv->NZ);
 
-            free_f3tensor(mod->taus, 0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
+            mod.taus.free();
 
-            free_f3tensor(testmod->taus, 0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
+            testmod.taus.free();
 
             mod_av.tausipjp.free();
             mod_av.tausjpkp.free();
@@ -270,18 +270,18 @@ void freemem(int nsrc_loc, st_acquisition *acq, st_model *mod, st_model *testmod
         } else {
             free_f3tensor(visco_mem->rp, 1, gv->NY, 1, gv->NX, 1, gv->NZ);
         }
-        free_f3tensor(mod->taup, 0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
+        mod.taup.free();
 
-        free_f3tensor(testmod->taup, 0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
+        testmod.taup.free();
 
-        free_vector(mod->eta, 1, gv->L);
+        free_vector(mod.eta, 1, gv->L);
     }
 
-    free_f3tensor(mod->rho, 0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
-    free_f3tensor(mod->pi, 0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
-    free_f3tensor(mod->absorb_coeff, 1, gv->NY, 1, gv->NX, 1, gv->NZ);
-    free_f3tensor(testmod->rho, 0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
-    free_f3tensor(testmod->pi, 0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
+    mod.rho.free();
+    mod.pi.free();
+    mod.absorb_coeff.free();
+    testmod.rho.free();
+    testmod.pi.free();
 
     /* averaged material parameters */
     mod_av.rjp.free();
@@ -289,8 +289,8 @@ void freemem(int nsrc_loc, st_acquisition *acq, st_model *mod, st_model *testmod
     mod_av.rip.free();
 
     if (gv->WEQ != 2) {
-        free_f3tensor(mod->u, 0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
-        free_f3tensor(testmod->u, 0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
+        mod.u.free();
+        testmod.u.free();
 
         mod_av.uipjp.free();
         mod_av.ujpkp.free();
diff --git a/src/gradient_F.cpp b/src/gradient_F.cpp
index 1bc81d0..e8775a8 100644
--- a/src/gradient_F.cpp
+++ b/src/gradient_F.cpp
@@ -28,7 +28,7 @@
 
 void gradient_F(int nx, int ny, int nz, st_freq_velocity *fw, st_freq_velocity *back, st_gradient *grad,
                 st_hessian *hessian,
-                st_model *mod, const float *finv, int nf, const GlobVar *gv)
+                st_model &mod, const float *finv, int nf, const GlobVar *gv)
 {
     float fvxx, fvxy, fvxz, fvyx, fvyy, fvyz, fvzx, fvzy, fvzz;
     float bvxx, bvxy, bvxz, bvyx, bvyy, bvyz, bvzx, bvzy, bvzz;
@@ -194,16 +194,14 @@ void gradient_F(int nx, int ny, int nz, st_freq_velocity *fw, st_freq_velocity *
                     /*parametrisation vp, vs, rho */
                     grad->vp[j + gv->SMOOTH_LENGTH_DY][i + gv->SMOOTH_LENGTH_DX][k +
                                                                                  gv->SMOOTH_LENGTH_DZ] +=
-                        sqrt(mod->rho[j][i][k] * mod->pi[j][i][k]) * 2 * gradlam;                                                                                        /*gradient vp */
+                        sqrt(mod.rho[j, i, k] * mod.pi[j, i, k]) * 2 * gradlam;                                                                                        /*gradient vp */
                     grad->vs[j + gv->SMOOTH_LENGTH_DY][i + gv->SMOOTH_LENGTH_DX][k + gv->SMOOTH_LENGTH_DZ] += -4 *
                                                                                                               sqrt(
-                        mod->rho[j][i][k] * mod->u[j][i][k]) * gradlam + 2 * sqrt(mod->rho[j][i][k] * mod->u[j][i][k]) *
+                        mod.rho[j, i, k] * mod.u[j, i, k]) * gradlam + 2 * sqrt(mod.rho[j, i, k] * mod.u[j, i, k]) *
                                                                                                               gradmu;                                                                                                            /*gradient vs */
                     grad->rho[j + gv->SMOOTH_LENGTH_DY][i + gv->SMOOTH_LENGTH_DX][k + gv->SMOOTH_LENGTH_DZ] += gradrho +
-                                                                                                               mod->u[j]
-                                                                                                               [i][k] /
-                                                                                                               mod->rho[
-                        j][i][k] * gradmu + (mod->pi[j][i][k] - 2 * mod->u[j][i][k]) / mod->rho[j][i][k] * gradlam;                                                                                                                              /*gradient rho */
+                                                                                                               mod.u[j, i, k] /
+                                                                                                               mod.rho[j, i, k] * gradmu + (mod.pi[j, i, k] - 2 * mod.u[j, i, k]) / mod.rho[j, i, k] * gradlam;                                                                                                                                                                                                                              /*gradient rho */
 
 
                     if (gv->HESS && !gv->READ_HESS) {
@@ -227,11 +225,11 @@ void gradient_F(int nx, int ny, int nz, st_freq_velocity *fw, st_freq_velocity *
                              fw->Fvy_im[l][j][i][k] * fw->Fvy_im[l][j][i][k] +
                              fw->Fvz_im[l][j][i][k] * fw->Fvz_im[l][j][i][k]);
 
-                        hessian->vp[j][i][k] += sqrt(mod->rho[j][i][k] * mod->pi[j][i][k]) * 2 * relam;                /*gradient vp */
-                        hessian->vs[j][i][k] += -4 * sqrt(mod->rho[j][i][k] * mod->u[j][i][k]) * relam + 2 *
-                                                sqrt(mod->rho[j][i][k] * mod->u[j][i][k]) * remu;                      /*gradient vs */
-                        hessian->rho[j][i][k] += rerho + mod->u[j][i][k] / mod->rho[j][i][k] * remu +
-                                                 (mod->pi[j][i][k] - 2 * mod->u[j][i][k]) / mod->rho[j][i][k] * relam; /*gradient rho */
+                        hessian->vp[j][i][k] += sqrt(mod.rho[j, i, k] * mod.pi[j, i, k]) * 2 * relam;               /*gradient vp */
+                        hessian->vs[j][i][k] += -4 * sqrt(mod.rho[j, i, k] * mod.u[j, i, k]) * relam + 2 *
+                                                sqrt(mod.rho[j, i, k] * mod.u[j, i, k]) * remu;                     /*gradient vs */
+                        hessian->rho[j][i][k] += rerho + mod.u[j, i, k] / mod.rho[j, i, k] * remu +
+                                                 (mod.pi[j, i, k] - 2 * mod.u[j, i, k]) / mod.rho[j, i, k] * relam; /*gradient rho */
                     }
                 }
             }
diff --git a/src/gradient_F_acoustic.cpp b/src/gradient_F_acoustic.cpp
index 3c44f1b..a8e93a3 100644
--- a/src/gradient_F_acoustic.cpp
+++ b/src/gradient_F_acoustic.cpp
@@ -28,7 +28,7 @@
 
 void gradient_F_acoustic(int nx, int ny, int nz, st_freq_velocity *fw, st_freq_velocity *back, st_gradient *grad,
                          st_hessian *hessian,
-                         st_model *mod, const float *finv, int nf, const GlobVar *gv)
+                         st_model &mod, const float *finv, int nf, const GlobVar *gv)
 {
     float fvxx, fvyy, fvzz, bvxx, bvyy, bvzz;
     float fivxx, fivyy, fivzz, bivxx, bivyy, bivzz;
@@ -107,12 +107,10 @@ void gradient_F_acoustic(int nx, int ny, int nz, st_freq_velocity *fw, st_freq_v
                     /* parametrisation vp, rho */
                     grad->vp[j + gv->SMOOTH_LENGTH_DY][i + gv->SMOOTH_LENGTH_DX][k +
                                                                                  gv->SMOOTH_LENGTH_DZ] +=
-                        sqrt(mod->rho[j][i][k] * mod->pi[j][i][k]) * 2 * gradlam;                                                                                         /*gradient vp */
+                        sqrt(mod.rho[j, i, k] * mod.pi[j, i, k]) * 2 * gradlam;                                                                                         /*gradient vp */
                     grad->rho[j + gv->SMOOTH_LENGTH_DY][i + gv->SMOOTH_LENGTH_DX][k + gv->SMOOTH_LENGTH_DZ] += gradrho +
-                                                                                                               mod->pi[j]
-                                                                                                               [i][k] /
-                                                                                                               mod->rho[
-                        j][i][k] * gradlam;                                                                                                                               /*gradient rho */
+                                                                                                               mod.pi[j, i, k] /
+                                                                                                               mod.rho[j, i, k] * gradlam;                                                                                                                               /*gradient rho */
 
                     if (gv->HESS && !gv->READ_HESS) {
                         rerho =
@@ -127,8 +125,8 @@ void gradient_F_acoustic(int nx, int ny, int nz, st_freq_velocity *fw, st_freq_v
                                 (fivxx + fivyy + fivzz);
                         relam = relam * fdummy;
 
-                        hessian->vp[j][i][k] += sqrt(mod->rho[j][i][k] * mod->pi[j][i][k]) * 2 * relam;
-                        hessian->rho[j][i][k] += rerho + (mod->pi[j][i][k]) / mod->rho[j][i][k] * relam;
+                        hessian->vp[j][i][k] += sqrt(mod.rho[j, i, k] * mod.pi[j, i, k]) * 2 * relam;
+                        hessian->rho[j][i][k] += rerho + (mod.pi[j, i, k]) / mod.rho[j, i, k] * relam;
                     }
                 }
             }
diff --git a/src/ifos3d.cpp b/src/ifos3d.cpp
index cfaf72a..ed9ceeb 100644
--- a/src/ifos3d.cpp
+++ b/src/ifos3d.cpp
@@ -183,7 +183,7 @@ int main(int argc, char **argv)
     }
 
     /* allocate and initialize buffers */
-    buffsize = initmem(&mod, &testmod, mod_av, &visco_mem, &pml_coeff, pml_wfd,
+    buffsize = initmem(mod, testmod, mod_av, &visco_mem, &pml_coeff, pml_wfd,
                        &grad, &grad_prior1, &grad_prior2, &grad_halo, &hessian, stress, &stressbuff,
                        &fourier_vel_back, &fourier_vel_fw, vel, &velbuff, &gv);
 
@@ -204,13 +204,13 @@ int main(int argc, char **argv)
     /* create model grids */
     log_infoc(0, "------------------------- Model creation / output -----------\n");
     if (gv.READMOD) {
-        readmod(&mod, &gv);     // read model
+        readmod(mod, &gv);     // read model
     } else {
-        model(&mod, &gv);       // create model
+        model(mod, &gv);       // create model
     }
 
     if (gv.COLOR == 0 && gv.ITMIN == 1) {
-        outmod(&mod, 0, &gv);
+        outmod(mod, 0, &gv);
     }
 
     /* reading source positions from SOURCE_FILE */
@@ -332,7 +332,7 @@ int main(int argc, char **argv)
     MPI_Barrier(MPI_COMM_WORLD);
 
     /* check if the FD run will be stable and free of numerical dispersion */
-    checkfd(&mod, &acq, &gv);
+    checkfd(mod, &acq, &gv);
 
     st_boundary nb_fix = { .nx1 = 1, .nx2 = gv.NX, .ny1 = 1, .ny2 = gv.NY, .nz1 = 1, .nz2 = gv.NZ };
     nb = nb_fix;
@@ -368,18 +368,18 @@ int main(int argc, char **argv)
             zero_invers(&fourier_vel_fw, &fourier_vel_back, gv.NFMAX, &gv);
         }
         if (gv.WEQ != 2) {
-            matcopy(&mod, &gv);
+            matcopy(mod, &gv);
         } else {
-            matcopy_acoustic(&mod, &gv);
+            matcopy_acoustic(mod, &gv);
         }
         if (gv.FREE_SURF) {
             if (gv.WEQ != 2) {
-                constant_boundary(&nb, &mod, &gv);
+                constant_boundary(&nb, mod, &gv);
             } else {
-                constant_boundary_acoustic(&nb, &mod, &gv);
+                constant_boundary_acoustic(&nb, mod, &gv);
             }
         }
-        av_mat(&mod, mod_av, &gv);
+        av_mat(mod, mod_av, &gv);
         L2all = 0.0;
         misfit[0] = 0.0;
 
@@ -487,7 +487,7 @@ int main(int argc, char **argv)
                     ntast = 1;
 
                 if (gv.STFI) {
-                    stfi(&acq, &nb, &nb_fix, vel, stress, &mod, mod_av, &visco_mem, &section, &section_obs,
+                    stfi(&acq, &nb, &nb_fix, vel, stress, mod, mod_av, &visco_mem, &section, &section_obs,
                          &signals, nsrc_loc, ntr_loc, &pml_coeff, pml_wfd, &stressbuff, &velbuff,
                          &fourier_vel_fw, finv, &L2, nf, ntast, lsnap, nsnap, ishot, shot_id, cdf, iteration, groupnum,
                          it_group, ncplx, &gv);
@@ -497,7 +497,7 @@ int main(int argc, char **argv)
             /*****************************************************
             * Timestep loop (simulation)
             *****************************************************/
-            timeloop(&nb, &nb_fix, vel, stress, &mod, mod_av, &section,
+            timeloop(&nb, &nb_fix, vel, stress, mod, mod_av, &section,
                      acq.srcpos_loc, acq.recpos_loc, &signals, nsrc_loc,
                      mod.absorb_coeff, &pml_coeff, pml_wfd, &stressbuff, &velbuff, &fourier_vel_fw,
                      finv, nf, ntast, ntr_loc, lsnap, nsnap, 0, shot_id, 1, &gv);
@@ -564,7 +564,7 @@ int main(int argc, char **argv)
                 /*****************************************************
                 *           Timestep loop (back-propagation)
                 *****************************************************/
-                timeloop(&nb, &nb_fix, vel, stress, &mod, mod_av, &section,
+                timeloop(&nb, &nb_fix, vel, stress, mod, mod_av, &section,
                          acq.srcpos_loc_back, acq.recpos_loc, &signals, ntr_loc,
                          mod.absorb_coeff, &pml_coeff, pml_wfd, &stressbuff, &velbuff, &fourier_vel_back,
                          finv, nf, ntast, ntr_loc, lsnap, nsnap, 0, shot_id, 2, &gv);
@@ -579,10 +579,10 @@ int main(int argc, char **argv)
                 MPI_Barrier(gv.COMM_SHOT);
 
                 if (gv.WEQ != 2) {
-                    gradient_F(gv.NX, gv.NY, gv.NZ, &fourier_vel_fw, &fourier_vel_back, &grad, &hessian, &mod, finv, nf,
+                    gradient_F(gv.NX, gv.NY, gv.NZ, &fourier_vel_fw, &fourier_vel_back, &grad, &hessian, mod, finv, nf,
                                &gv);
                 } else {
-                    gradient_F_acoustic(gv.NX, gv.NY, gv.NZ, &fourier_vel_fw, &fourier_vel_back, &grad, &hessian, &mod,
+                    gradient_F_acoustic(gv.NX, gv.NY, gv.NZ, &fourier_vel_fw, &fourier_vel_back, &grad, &hessian, mod,
                                         finv, nf, &gv);
                 }
 
@@ -729,22 +729,22 @@ int main(int argc, char **argv)
                     log_info("%d. test steplength: step[%d]=%.2e\n", steptest, steptest, step[steptest]);
                 }
 
-                cpmodel(&mod, &testmod, &gv);
+                cpmodel(mod, testmod, &gv);
                 if (gv.WEQ != 2) {
-                    modelupdate(&grad, &testmod, step[steptest], it_group, &gv);
-                    matcopy(&testmod, &gv);
+                    modelupdate(&grad, testmod, step[steptest], it_group, &gv);
+                    matcopy(testmod, &gv);
                 } else {
-                    modelupdate_acoustic(&grad, &testmod, step[steptest], it_group, &gv);
-                    matcopy_acoustic(&testmod, &gv);
+                    modelupdate_acoustic(&grad, testmod, step[steptest], it_group, &gv);
+                    matcopy_acoustic(testmod, &gv);
                 }
                 if (gv.FREE_SURF) {
                     if (gv.WEQ != 2) {
-                        constant_boundary(&nb, &testmod, &gv);
+                        constant_boundary(&nb, testmod, &gv);
                     } else {
-                        constant_boundary_acoustic(&nb, &testmod, &gv);
+                        constant_boundary_acoustic(&nb, testmod, &gv);
                     }
                 }
-                av_mat(&testmod, mod_av, &gv);
+                av_mat(testmod, mod_av, &gv);
 
                 L2 = 0.0;
 
@@ -802,7 +802,7 @@ int main(int argc, char **argv)
                         /*****************************************************
                         * Timestep loop (steplength calculation)
                         *****************************************************/
-                        timeloop(&nb, &nb_fix, vel, stress, &testmod, mod_av, &section,
+                        timeloop(&nb, &nb_fix, vel, stress, testmod, mod_av, &section,
                                  acq.srcpos_loc, acq.recpos_loc, &signals, nsrc_loc,
                                  mod.absorb_coeff, &pml_coeff, pml_wfd, &stressbuff, &velbuff, &fourier_vel_fw,
                                  finv, nf, ntast, ntr_loc, lsnap, nsnap, 0, shot_id, 3, &gv);
@@ -830,12 +830,12 @@ int main(int argc, char **argv)
             }
 
             if (gv.WEQ != 2) {
-                modelupdate(&grad, &mod, step[3], it_group, &gv);
+                modelupdate(&grad, mod, step[3], it_group, &gv);
             } else {
-                modelupdate_acoustic(&grad, &mod, step[3], it_group, &gv);
+                modelupdate_acoustic(&grad, mod, step[3], it_group, &gv);
             }
             if (gv.COLOR == 0) {
-                outmod(&mod, iteration, &gv);
+                outmod(mod, iteration, &gv);
             }
         }
         /* fwi loop */
@@ -848,7 +848,7 @@ int main(int argc, char **argv)
 
 
     /* de-allocation of memory */
-    freemem(nsrc_loc, &acq, &mod, &testmod, mod_av,
+    freemem(nsrc_loc, &acq, mod, testmod, mod_av,
             &visco_mem, &pml_coeff, pml_wfd, &signals, &grad,
             &grad_prior1, &grad_prior2, &grad_halo, &hessian, stress, &stressbuff,
             &fourier_vel_back, &fourier_vel_fw, vel, &velbuff, &gv);
diff --git a/src/initmem.cpp b/src/initmem.cpp
index 1de6254..54a548f 100644
--- a/src/initmem.cpp
+++ b/src/initmem.cpp
@@ -25,7 +25,7 @@
 #include "logging.hpp"
 #include "util.hpp"
 
-int initmem(st_model *mod, st_model *testmod,
+int initmem(st_model &mod, st_model &testmod,
             st_model_av &mod_av, st_visc_mem *visco_mem, st_pml_coeff *pml_coeff,
             st_pml_wfd &pml_wfd, st_gradient *grad, st_gradient *grad_prior1,
             st_gradient *grad_prior2, st_gradient *grad_halo, st_hessian *hessian, st_stress &stress,
@@ -394,32 +394,32 @@ int initmem(st_model *mod, st_model *testmod,
             visco_mem->ryy = f3tensor(1, gv->NY, 1, gv->NX, 1, gv->NZ);
             visco_mem->rzz = f3tensor(1, gv->NY, 1, gv->NX, 1, gv->NZ);
 
-            mod->taus = f3tensor(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
-            testmod->taus = f3tensor(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
+            mod.taus.malloc(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
+            testmod.taus.malloc(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
             mod_av.tausipjp.malloc(1, gv->NY, 1, gv->NX, 1, gv->NZ);
             mod_av.tausjpkp.malloc(1, gv->NY, 1, gv->NX, 1, gv->NZ);
             mod_av.tausipkp.malloc(1, gv->NY, 1, gv->NX, 1, gv->NZ);
         } else {
             visco_mem->rp = f3tensor(1, gv->NY, 1, gv->NX, 1, gv->NZ);
         }
-        mod->taup = f3tensor(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
+        mod.taup.malloc(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
 
         // testmodel dummy (currently no viscoelastic gradients)
-        testmod->taup = f3tensor(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
+        testmod.taup.malloc(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
 
-        mod->eta = vector(1, gv->L);
+        mod.eta = vector(1, gv->L);
     }
 
     /* visco_memory allocation for static (model) arrays */
-    mod->rho = f3tensor(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
-    mod->pi = f3tensor(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
-    mod->absorb_coeff = f3tensor(1, gv->NY, 1, gv->NX, 1, gv->NZ);
-    testmod->rho = f3tensor(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
-    testmod->pi = f3tensor(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
+    mod.rho.malloc(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
+    mod.pi.malloc(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
+    mod.absorb_coeff.malloc(1, gv->NY, 1, gv->NX, 1, gv->NZ);
+    testmod.rho.malloc(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
+    testmod.pi.malloc(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
 
     if (gv->WEQ != 2) {
-        mod->u = f3tensor(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
-        testmod->u = f3tensor(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
+        mod.u.malloc(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
+        testmod.u.malloc(0, gv->NY + 1, 0, gv->NX + 1, 0, gv->NZ + 1);
         /* averaged material parameters */
         mod_av.uipjp.malloc(1, gv->NY, 1, gv->NX, 1, gv->NZ);
         mod_av.ujpkp.malloc(1, gv->NY, 1, gv->NX, 1, gv->NZ);
diff --git a/src/matcopy.cpp b/src/matcopy.cpp
index e5f9434..e4c2339 100644
--- a/src/matcopy.cpp
+++ b/src/matcopy.cpp
@@ -29,7 +29,7 @@
 #include "fd.hpp"
 #include "util.hpp"
 
-void matcopy(st_model *mod, GlobVar *gv)
+void matcopy(st_model &mod, GlobVar *gv)
 {
     MPI_Status status;
     //double time1=0.0, time2=0.0;
@@ -56,13 +56,13 @@ void matcopy(st_model *mod, GlobVar *gv)
     for (i = 0; i <= gv->NX + 1; i++) {
         for (k = 0; k <= gv->NZ + 1; k++) {
             /* storage of top of local volume into buffer */
-            buffertop_to_bot[i][k][1] = mod->rho[1][i][k];
-            buffertop_to_bot[i][k][2] = mod->pi[1][i][k];
-            buffertop_to_bot[i][k][3] = mod->u[1][i][k];
+            buffertop_to_bot[i][k][1] = mod.rho[1, i, k];
+            buffertop_to_bot[i][k][2] = mod.pi[1, i, k];
+            buffertop_to_bot[i][k][3] = mod.u[1, i, k];
 
             if (gv->L) {
-                buffertop_to_bot[i][k][4] = mod->taus[1][i][k];
-                buffertop_to_bot[i][k][5] = mod->taup[1][i][k];
+                buffertop_to_bot[i][k][4] = mod.taus[1, i, k];
+                buffertop_to_bot[i][k][5] = mod.taup[1, i, k];
             }
         }
     }
@@ -70,13 +70,13 @@ void matcopy(st_model *mod, GlobVar *gv)
     for (i = 0; i <= gv->NX + 1; i++) {
         for (k = 0; k <= gv->NZ + 1; k++) {
             /* storage of bottom of local volume into buffer */
-            bufferbot_to_top[i][k][1] = mod->rho[gv->NY][i][k];
-            bufferbot_to_top[i][k][2] = mod->pi[gv->NY][i][k];
-            bufferbot_to_top[i][k][3] = mod->u[gv->NY][i][k];
+            bufferbot_to_top[i][k][1] = mod.rho[gv->NY, i, k];
+            bufferbot_to_top[i][k][2] = mod.pi[gv->NY, i, k];
+            bufferbot_to_top[i][k][3] = mod.u[gv->NY, i, k];
 
             if (gv->L) {
-                bufferbot_to_top[i][k][4] = mod->taus[gv->NY][i][k];
-                bufferbot_to_top[i][k][5] = mod->taup[gv->NY][i][k];
+                bufferbot_to_top[i][k][4] = mod.taus[gv->NY, i, k];
+                bufferbot_to_top[i][k][5] = mod.taup[gv->NY, i, k];
             }
         }
     }
@@ -94,24 +94,24 @@ void matcopy(st_model *mod, GlobVar *gv)
 
     for (i = 0; i <= gv->NX + 1; i++) {
         for (k = 0; k <= gv->NZ + 1; k++) {
-            mod->rho[gv->NY + 1][i][k] = buffertop_to_bot[i][k][1];
-            mod->pi[gv->NY + 1][i][k] = buffertop_to_bot[i][k][2];
-            mod->u[gv->NY + 1][i][k] = buffertop_to_bot[i][k][3];
+            mod.rho[gv->NY + 1, i, k] = buffertop_to_bot[i][k][1];
+            mod.pi[gv->NY + 1, i, k] = buffertop_to_bot[i][k][2];
+            mod.u[gv->NY + 1, i, k] = buffertop_to_bot[i][k][3];
             if (gv->L) {
-                mod->taus[gv->NY + 1][i][k] = buffertop_to_bot[i][k][4];
-                mod->taup[gv->NY + 1][i][k] = buffertop_to_bot[i][k][5];
+                mod.taus[gv->NY + 1, i, k] = buffertop_to_bot[i][k][4];
+                mod.taup[gv->NY + 1, i, k] = buffertop_to_bot[i][k][5];
             }
         }
     }
 
     for (i = 0; i <= gv->NX + 1; i++) {
         for (k = 0; k <= gv->NZ + 1; k++) {
-            mod->rho[0][i][k] = bufferbot_to_top[i][k][1];
-            mod->pi[0][i][k] = bufferbot_to_top[i][k][2];
-            mod->u[0][i][k] = bufferbot_to_top[i][k][3];
+            mod.rho[0, i, k] = bufferbot_to_top[i][k][1];
+            mod.pi[0, i, k] = bufferbot_to_top[i][k][2];
+            mod.u[0, i, k] = bufferbot_to_top[i][k][3];
             if (gv->L) {
-                mod->taus[0][i][k] = bufferbot_to_top[i][k][4];
-                mod->taup[0][i][k] = bufferbot_to_top[i][k][5];
+                mod.taus[0, i, k] = bufferbot_to_top[i][k][4];
+                mod.taup[0, i, k] = bufferbot_to_top[i][k][5];
             }
         }
     }
@@ -121,12 +121,12 @@ void matcopy(st_model *mod, GlobVar *gv)
     for (j = 0; j <= gv->NY + 1; j++) {
         for (k = 0; k <= gv->NZ + 1; k++) {
             /* storage of left edge of local volume into buffer */
-            bufferlef_to_rig[j][k][1] = mod->rho[j][1][k];
-            bufferlef_to_rig[j][k][2] = mod->pi[j][1][k];
-            bufferlef_to_rig[j][k][3] = mod->u[j][1][k];
+            bufferlef_to_rig[j][k][1] = mod.rho[j, 1, k];
+            bufferlef_to_rig[j][k][2] = mod.pi[j, 1, k];
+            bufferlef_to_rig[j][k][3] = mod.u[j, 1, k];
             if (gv->L) {
-                bufferlef_to_rig[j][k][4] = mod->taus[j][1][k];
-                bufferlef_to_rig[j][k][5] = mod->taup[j][1][k];
+                bufferlef_to_rig[j][k][4] = mod.taus[j, 1, k];
+                bufferlef_to_rig[j][k][5] = mod.taup[j, 1, k];
             }
         }
     }
@@ -134,12 +134,12 @@ void matcopy(st_model *mod, GlobVar *gv)
     for (j = 0; j <= gv->NY + 1; j++) {
         for (k = 0; k <= gv->NZ + 1; k++) {
             /* storage of right edge of local volume into buffer */
-            bufferrig_to_lef[j][k][1] = mod->rho[j][gv->NX][k];
-            bufferrig_to_lef[j][k][2] = mod->pi[j][gv->NX][k];
-            bufferrig_to_lef[j][k][3] = mod->u[j][gv->NX][k];
+            bufferrig_to_lef[j][k][1] = mod.rho[j, gv->NX, k];
+            bufferrig_to_lef[j][k][2] = mod.pi[j, gv->NX, k];
+            bufferrig_to_lef[j][k][3] = mod.u[j, gv->NX, k];
             if (gv->L) {
-                bufferrig_to_lef[j][k][4] = mod->taus[j][gv->NX][k];
-                bufferrig_to_lef[j][k][5] = mod->taup[j][gv->NX][k];
+                bufferrig_to_lef[j][k][4] = mod.taus[j, gv->NX, k];
+                bufferrig_to_lef[j][k][5] = mod.taup[j, gv->NX, k];
             }
         }
     }
@@ -157,24 +157,24 @@ void matcopy(st_model *mod, GlobVar *gv)
 
     for (j = 0; j <= gv->NY + 1; j++) {
         for (k = 0; k <= gv->NZ + 1; k++) {
-            mod->rho[j][gv->NX + 1][k] = bufferlef_to_rig[j][k][1];
-            mod->pi[j][gv->NX + 1][k] = bufferlef_to_rig[j][k][2];
-            mod->u[j][gv->NX + 1][k] = bufferlef_to_rig[j][k][3];
+            mod.rho[j, gv->NX + 1, k] = bufferlef_to_rig[j][k][1];
+            mod.pi[j, gv->NX + 1, k] = bufferlef_to_rig[j][k][2];
+            mod.u[j, gv->NX + 1, k] = bufferlef_to_rig[j][k][3];
             if (gv->L) {
-                mod->taus[j][gv->NX + 1][k] = bufferlef_to_rig[j][k][4];
-                mod->taup[j][gv->NX + 1][k] = bufferlef_to_rig[j][k][5];
+                mod.taus[j, gv->NX + 1, k] = bufferlef_to_rig[j][k][4];
+                mod.taup[j, gv->NX + 1, k] = bufferlef_to_rig[j][k][5];
             }
         }
     }
 
     for (j = 0; j <= gv->NY + 1; j++) {
         for (k = 0; k <= gv->NZ + 1; k++) {
-            mod->rho[j][0][k] = bufferrig_to_lef[j][k][1];
-            mod->pi[j][0][k] = bufferrig_to_lef[j][k][2];
-            mod->u[j][0][k] = bufferrig_to_lef[j][k][3];
+            mod.rho[j, 0, k] = bufferrig_to_lef[j][k][1];
+            mod.pi[j, 0, k] = bufferrig_to_lef[j][k][2];
+            mod.u[j, 0, k] = bufferrig_to_lef[j][k][3];
             if (gv->L) {
-                mod->taus[j][0][k] = bufferrig_to_lef[j][k][4];
-                mod->taup[j][0][k] = bufferrig_to_lef[j][k][5];
+                mod.taus[j, 0, k] = bufferrig_to_lef[j][k][4];
+                mod.taup[j, 0, k] = bufferrig_to_lef[j][k][5];
             }
         }
     }
@@ -184,12 +184,12 @@ void matcopy(st_model *mod, GlobVar *gv)
     for (i = 0; i <= gv->NX + 1; i++) {
         for (j = 0; j <= gv->NY + 1; j++) {
             /* storage of front side of local volume into buffer */
-            bufferfro_to_bac[j][i][1] = mod->rho[j][i][1];
-            bufferfro_to_bac[j][i][2] = mod->pi[j][i][1];
-            bufferfro_to_bac[j][i][3] = mod->u[j][i][1];
+            bufferfro_to_bac[j][i][1] = mod.rho[j, i, 1];
+            bufferfro_to_bac[j][i][2] = mod.pi[j, i, 1];
+            bufferfro_to_bac[j][i][3] = mod.u[j, i, 1];
             if (gv->L) {
-                bufferfro_to_bac[j][i][4] = mod->taus[j][i][1];
-                bufferfro_to_bac[j][i][5] = mod->taup[j][i][1];
+                bufferfro_to_bac[j][i][4] = mod.taus[j, i, 1];
+                bufferfro_to_bac[j][i][5] = mod.taup[j, i, 1];
             }
         }
     }
@@ -197,12 +197,12 @@ void matcopy(st_model *mod, GlobVar *gv)
     for (i = 0; i <= gv->NX + 1; i++) {
         for (j = 0; j <= gv->NY + 1; j++) {
             /* storage of back side of local volume into buffer */
-            bufferbac_to_fro[j][i][1] = mod->rho[j][i][gv->NZ];
-            bufferbac_to_fro[j][i][2] = mod->pi[j][i][gv->NZ];
-            bufferbac_to_fro[j][i][3] = mod->u[j][i][gv->NZ];
+            bufferbac_to_fro[j][i][1] = mod.rho[j, i, gv->NZ];
+            bufferbac_to_fro[j][i][2] = mod.pi[j, i, gv->NZ];
+            bufferbac_to_fro[j][i][3] = mod.u[j, i, gv->NZ];
             if (gv->L) {
-                bufferbac_to_fro[j][i][4] = mod->taus[j][i][gv->NZ];
-                bufferbac_to_fro[j][i][5] = mod->taup[j][i][gv->NZ];
+                bufferbac_to_fro[j][i][4] = mod.taus[j, i, gv->NZ];
+                bufferbac_to_fro[j][i][5] = mod.taup[j, i, gv->NZ];
             }
         }
     }
@@ -220,24 +220,24 @@ void matcopy(st_model *mod, GlobVar *gv)
 
     for (i = 0; i <= gv->NX + 1; i++) {
         for (j = 0; j <= gv->NY + 1; j++) {
-            mod->rho[j][i][gv->NZ + 1] = bufferfro_to_bac[j][i][1];
-            mod->pi[j][i][gv->NZ + 1] = bufferfro_to_bac[j][i][2];
-            mod->u[j][i][gv->NZ + 1] = bufferfro_to_bac[j][i][3];
+            mod.rho[j, i, gv->NZ + 1] = bufferfro_to_bac[j][i][1];
+            mod.pi[j, i, gv->NZ + 1] = bufferfro_to_bac[j][i][2];
+            mod.u[j, i, gv->NZ + 1] = bufferfro_to_bac[j][i][3];
             if (gv->L) {
-                mod->taus[j][i][gv->NZ + 1] = bufferfro_to_bac[j][i][4];
-                mod->taup[j][i][gv->NZ + 1] = bufferfro_to_bac[j][i][5];
+                mod.taus[j, i, gv->NZ + 1] = bufferfro_to_bac[j][i][4];
+                mod.taup[j, i, gv->NZ + 1] = bufferfro_to_bac[j][i][5];
             }
         }
     }
 
     for (i = 0; i <= gv->NX + 1; i++) {
         for (j = 0; j <= gv->NY + 1; j++) {
-            mod->rho[j][i][0] = bufferbac_to_fro[j][i][1];
-            mod->pi[j][i][0] = bufferbac_to_fro[j][i][2];
-            mod->u[j][i][0] = bufferbac_to_fro[j][i][3];
+            mod.rho[j, i, 0] = bufferbac_to_fro[j][i][1];
+            mod.pi[j, i, 0] = bufferbac_to_fro[j][i][2];
+            mod.u[j, i, 0] = bufferbac_to_fro[j][i][3];
             if (gv->L) {
-                mod->taus[j][i][0] = bufferbac_to_fro[j][i][4];
-                mod->taup[j][i][0] = bufferbac_to_fro[j][i][5];
+                mod.taus[j, i, 0] = bufferbac_to_fro[j][i][4];
+                mod.taup[j, i, 0] = bufferbac_to_fro[j][i][5];
             }
         }
     }
diff --git a/src/matcopy_acoustic.cpp b/src/matcopy_acoustic.cpp
index 8ccc40d..7dc2832 100644
--- a/src/matcopy_acoustic.cpp
+++ b/src/matcopy_acoustic.cpp
@@ -29,7 +29,7 @@
 #include "fd.hpp"
 #include "util.hpp"
 
-void matcopy_acoustic(st_model *mod, GlobVar *gv)
+void matcopy_acoustic(st_model &mod, GlobVar *gv)
 {
     MPI_Status status;
     //double time1=0.0, time2=0.0;
@@ -56,11 +56,11 @@ void matcopy_acoustic(st_model *mod, GlobVar *gv)
     for (i = 0; i <= gv->NX + 1; i++) {
         for (k = 0; k <= gv->NZ + 1; k++) {
             /* storage of top of local volume into buffer */
-            buffertop_to_bot[i][k][1] = mod->rho[1][i][k];
-            buffertop_to_bot[i][k][2] = mod->pi[1][i][k];
+            buffertop_to_bot[i][k][1] = mod.rho[1, i, k];
+            buffertop_to_bot[i][k][2] = mod.pi[1, i, k];
 
             if (gv->L) {
-                buffertop_to_bot[i][k][3] = mod->taup[1][i][k];
+                buffertop_to_bot[i][k][3] = mod.taup[1, i, k];
             }
         }
     }
@@ -68,11 +68,11 @@ void matcopy_acoustic(st_model *mod, GlobVar *gv)
     for (i = 0; i <= gv->NX + 1; i++) {
         for (k = 0; k <= gv->NZ + 1; k++) {
             /* storage of bottom of local volume into buffer */
-            bufferbot_to_top[i][k][1] = mod->rho[gv->NY][i][k];
-            bufferbot_to_top[i][k][2] = mod->pi[gv->NY][i][k];
+            bufferbot_to_top[i][k][1] = mod.rho[gv->NY, i, k];
+            bufferbot_to_top[i][k][2] = mod.pi[gv->NY, i, k];
 
             if (gv->L) {
-                bufferbot_to_top[i][k][3] = mod->taup[gv->NY][i][k];
+                bufferbot_to_top[i][k][3] = mod.taup[gv->NY, i, k];
             }
         }
     }
@@ -90,20 +90,20 @@ void matcopy_acoustic(st_model *mod, GlobVar *gv)
 
     for (i = 0; i <= gv->NX + 1; i++) {
         for (k = 0; k <= gv->NZ + 1; k++) {
-            mod->rho[gv->NY + 1][i][k] = buffertop_to_bot[i][k][1];
-            mod->pi[gv->NY + 1][i][k] = buffertop_to_bot[i][k][2];
+            mod.rho[gv->NY + 1, i, k] = buffertop_to_bot[i][k][1];
+            mod.pi[gv->NY + 1, i, k] = buffertop_to_bot[i][k][2];
             if (gv->L) {
-                mod->taup[gv->NY + 1][i][k] = buffertop_to_bot[i][k][3];
+                mod.taup[gv->NY + 1, i, k] = buffertop_to_bot[i][k][3];
             }
         }
     }
 
     for (i = 0; i <= gv->NX + 1; i++) {
         for (k = 0; k <= gv->NZ + 1; k++) {
-            mod->rho[0][i][k] = bufferbot_to_top[i][k][1];
-            mod->pi[0][i][k] = bufferbot_to_top[i][k][2];
+            mod.rho[0, i, k] = bufferbot_to_top[i][k][1];
+            mod.pi[0, i, k] = bufferbot_to_top[i][k][2];
             if (gv->L) {
-                mod->taup[0][i][k] = bufferbot_to_top[i][k][3];
+                mod.taup[0, i, k] = bufferbot_to_top[i][k][3];
             }
         }
     }
@@ -113,10 +113,10 @@ void matcopy_acoustic(st_model *mod, GlobVar *gv)
     for (j = 0; j <= gv->NY + 1; j++) {
         for (k = 0; k <= gv->NZ + 1; k++) {
             /* storage of left edge of local volume into buffer */
-            bufferlef_to_rig[j][k][1] = mod->rho[j][1][k];
-            bufferlef_to_rig[j][k][2] = mod->pi[j][1][k];
+            bufferlef_to_rig[j][k][1] = mod.rho[j, 1, k];
+            bufferlef_to_rig[j][k][2] = mod.pi[j, 1, k];
             if (gv->L) {
-                bufferlef_to_rig[j][k][3] = mod->taup[j][1][k];
+                bufferlef_to_rig[j][k][3] = mod.taup[j, 1, k];
             }
         }
     }
@@ -124,10 +124,10 @@ void matcopy_acoustic(st_model *mod, GlobVar *gv)
     for (j = 0; j <= gv->NY + 1; j++) {
         for (k = 0; k <= gv->NZ + 1; k++) {
             /* storage of right edge of local volume into buffer */
-            bufferrig_to_lef[j][k][1] = mod->rho[j][gv->NX][k];
-            bufferrig_to_lef[j][k][2] = mod->pi[j][gv->NX][k];
+            bufferrig_to_lef[j][k][1] = mod.rho[j, gv->NX, k];
+            bufferrig_to_lef[j][k][2] = mod.pi[j, gv->NX, k];
             if (gv->L) {
-                bufferrig_to_lef[j][k][3] = mod->taup[j][gv->NX][k];
+                bufferrig_to_lef[j][k][3] = mod.taup[j, gv->NX, k];
             }
         }
     }
@@ -145,20 +145,20 @@ void matcopy_acoustic(st_model *mod, GlobVar *gv)
 
     for (j = 0; j <= gv->NY + 1; j++) {
         for (k = 0; k <= gv->NZ + 1; k++) {
-            mod->rho[j][gv->NX + 1][k] = bufferlef_to_rig[j][k][1];
-            mod->pi[j][gv->NX + 1][k] = bufferlef_to_rig[j][k][2];
+            mod.rho[j, gv->NX + 1, k] = bufferlef_to_rig[j][k][1];
+            mod.pi[j, gv->NX + 1, k] = bufferlef_to_rig[j][k][2];
             if (gv->L) {
-                mod->taup[j][gv->NX + 1][k] = bufferlef_to_rig[j][k][3];
+                mod.taup[j, gv->NX + 1, k] = bufferlef_to_rig[j][k][3];
             }
         }
     }
 
     for (j = 0; j <= gv->NY + 1; j++) {
         for (k = 0; k <= gv->NZ + 1; k++) {
-            mod->rho[j][0][k] = bufferrig_to_lef[j][k][1];
-            mod->pi[j][0][k] = bufferrig_to_lef[j][k][2];
+            mod.rho[j, 0, k] = bufferrig_to_lef[j][k][1];
+            mod.pi[j, 0, k] = bufferrig_to_lef[j][k][2];
             if (gv->L) {
-                mod->taup[j][0][k] = bufferrig_to_lef[j][k][3];
+                mod.taup[j, 0, k] = bufferrig_to_lef[j][k][3];
             }
         }
     }
@@ -168,10 +168,10 @@ void matcopy_acoustic(st_model *mod, GlobVar *gv)
     for (i = 0; i <= gv->NX + 1; i++) {
         for (j = 0; j <= gv->NY + 1; j++) {
             /* storage of front side of local volume into buffer */
-            bufferfro_to_bac[j][i][1] = mod->rho[j][i][1];
-            bufferfro_to_bac[j][i][2] = mod->pi[j][i][1];
+            bufferfro_to_bac[j][i][1] = mod.rho[j, i, 1];
+            bufferfro_to_bac[j][i][2] = mod.pi[j, i, 1];
             if (gv->L) {
-                bufferfro_to_bac[j][i][3] = mod->taup[j][i][1];
+                bufferfro_to_bac[j][i][3] = mod.taup[j, i, 1];
             }
         }
     }
@@ -179,10 +179,10 @@ void matcopy_acoustic(st_model *mod, GlobVar *gv)
     for (i = 0; i <= gv->NX + 1; i++) {
         for (j = 0; j <= gv->NY + 1; j++) {
             /* storage of back side of local volume into buffer */
-            bufferbac_to_fro[j][i][1] = mod->rho[j][i][gv->NZ];
-            bufferbac_to_fro[j][i][2] = mod->pi[j][i][gv->NZ];
+            bufferbac_to_fro[j][i][1] = mod.rho[j, i, gv->NZ];
+            bufferbac_to_fro[j][i][2] = mod.pi[j, i, gv->NZ];
             if (gv->L) {
-                bufferbac_to_fro[j][i][3] = mod->taup[j][i][gv->NZ];
+                bufferbac_to_fro[j][i][3] = mod.taup[j, i, gv->NZ];
             }
         }
     }
@@ -200,20 +200,20 @@ void matcopy_acoustic(st_model *mod, GlobVar *gv)
 
     for (i = 0; i <= gv->NX + 1; i++) {
         for (j = 0; j <= gv->NY + 1; j++) {
-            mod->rho[j][i][gv->NZ + 1] = bufferfro_to_bac[j][i][1];
-            mod->pi[j][i][gv->NZ + 1] = bufferfro_to_bac[j][i][2];
+            mod.rho[j, i, gv->NZ + 1] = bufferfro_to_bac[j][i][1];
+            mod.pi[j, i, gv->NZ + 1] = bufferfro_to_bac[j][i][2];
             if (gv->L) {
-                mod->taup[j][i][gv->NZ + 1] = bufferfro_to_bac[j][i][3];
+                mod.taup[j, i, gv->NZ + 1] = bufferfro_to_bac[j][i][3];
             }
         }
     }
 
     for (i = 0; i <= gv->NX + 1; i++) {
         for (j = 0; j <= gv->NY + 1; j++) {
-            mod->rho[j][i][0] = bufferbac_to_fro[j][i][1];
-            mod->pi[j][i][0] = bufferbac_to_fro[j][i][2];
+            mod.rho[j, i, 0] = bufferbac_to_fro[j][i][1];
+            mod.pi[j, i, 0] = bufferbac_to_fro[j][i][2];
             if (gv->L) {
-                mod->taup[j][i][0] = bufferbac_to_fro[j][i][3];
+                mod.taup[j, i, 0] = bufferbac_to_fro[j][i][3];
             }
         }
     }
diff --git a/src/model2_5D.cpp b/src/model2_5D.cpp
index 68dfb57..ba069b2 100644
--- a/src/model2_5D.cpp
+++ b/src/model2_5D.cpp
@@ -25,7 +25,7 @@
 
 #include "fd.hpp"
 
-void model2_5(st_model *mod)
+void model2_5(st_model &mod)
 {
     /*--------------------------------------------------------------------------*/
     /* extern variables */
@@ -40,21 +40,21 @@ void model2_5(st_model *mod)
     for (j = 1; j <= NYG; j++) {
         for (i = 1; i <= NXG; i++) {
             if (L) {
-                ts = mod->taus[j][i][100];
-                tp = mod->taup[j][i][100];
+                ts = mod.taus[j, i, 100];
+                tp = mod.taup[j, i, 100];
             }
-            muv = mod->u[j][i][100];
-            Rho = mod->rho[j][i][100];
-            piv = mod->pi[j][i][100];
+            muv = mod.u[j, i, 100];
+            Rho = mod.rho[j, i, 100];
+            piv = mod.pi[j, i, 100];
             for (k = 1; k <= NZG; k++) {
                 if (L) {
-                    mod->taus[j][i][k] = ts;
-                    mod->taup[j][i][k] = tp;
+                    mod.taus[j, i, k] = ts;
+                    mod.taup[j, i, k] = tp;
                 }
 
-                mod->u[j][i][k] = muv;
-                mod->rho[j][i][k] = Rho;
-                mod->pi[j][i][k] = piv;
+                mod.u[j, i, k] = muv;
+                mod.rho[j, i, k] = Rho;
+                mod.pi[j, i, k] = piv;
             }
         }
     }
diff --git a/src/modelupdate.cpp b/src/modelupdate.cpp
index 0b4e867..2c22807 100644
--- a/src/modelupdate.cpp
+++ b/src/modelupdate.cpp
@@ -25,7 +25,7 @@
 #include "fd.hpp"
 #include "logging.hpp"
 
-void modelupdate(st_gradient *grad, st_model *mod, float step, int it_group, GlobVar *gv)
+void modelupdate(st_gradient *grad, st_model &mod, float step, int it_group, GlobVar *gv)
 {
     int j, i, k, l, l1;
     float vpnew, vsnew, rhonew, vpstart, vsstart;
@@ -66,15 +66,15 @@ void modelupdate(st_gradient *grad, st_model *mod, float step, int it_group, Glo
             for (k = 1; k <= gv->NZ; k++) {
                 vp = 0.0;
                 vs = 0.0;
-                vp = sqrt(mod->pi[j][i][k] / mod->rho[j][i][k]);
-                vs = sqrt(mod->u[j][i][k] / mod->rho[j][i][k]);
+                vp = sqrt(mod.pi[j, i, k] / mod.rho[j, i, k]);
+                vs = sqrt(mod.u[j, i, k] / mod.rho[j, i, k]);
 
                 if (vp > max[0])
                     max[0] = vp;
                 if (vs > max[1])
                     max[1] = vs;
-                if (mod->rho[j][i][k] > max[2])
-                    max[2] = mod->rho[j][i][k];
+                if (mod.rho[j, i, k] > max[2])
+                    max[2] = mod.rho[j, i, k];
             }
         }
     }
@@ -157,8 +157,8 @@ void modelupdate(st_gradient *grad, st_model *mod, float step, int it_group, Glo
             for (k = 1; k <= gv->NZ; k++) {
                 /*update model */
                 vpnew = 0.0;
-                vpstart = sqrt(mod->pi[j][i][k] / mod->rho[j][i][k]);
-                /*vpnew=sqrt(mod->pi[j][i][k]/mod->rho[j][i][k])+max[0]*step*gradconvp[j][i][k]; */
+                vpstart = sqrt(mod.pi[j, i, k] / mod.rho[j, i, k]);
+                /*vpnew=sqrt(mod.pi[j, i, k]/mod.rho[j, i, k])+max[0]*step*gradconvp[j][i][k]; */
                 vpnew = vpstart + step * scale1 *
                         grad->vp[j + gv->SMOOTH_LENGTH_DY][i + gv->SMOOTH_LENGTH_DX][k + gv->SMOOTH_LENGTH_DZ] *
                         gv->VP0;
@@ -182,8 +182,8 @@ void modelupdate(st_gradient *grad, st_model *mod, float step, int it_group, Glo
                 }
 
                 vsnew = 0.0;
-                vsstart = sqrt(mod->u[j][i][k] / mod->rho[j][i][k]);
-                /*vsnew=sqrt(mod->u[j][i][k]/mod->rho[j][i][k])+max[1]*step*gradconvs[j][i][k]; */
+                vsstart = sqrt(mod.u[j, i, k] / mod.rho[j, i, k]);
+                /*vsnew=sqrt(mod.u[j, i, k]/mod.rho[j, i, k])+max[1]*step*gradconvs[j][i][k]; */
                 vsnew = vsstart + step * scale2 *
                         grad->vs[j + gv->SMOOTH_LENGTH_DY][i + gv->SMOOTH_LENGTH_DX][k + gv->SMOOTH_LENGTH_DZ] *
                         gv->VS0;
@@ -207,24 +207,24 @@ void modelupdate(st_gradient *grad, st_model *mod, float step, int it_group, Glo
                 }
 
                 rhonew = 0.0;
-                rhonew = mod->rho[j][i][k] + scale3 * step *
+                rhonew = mod.rho[j, i, k] + scale3 * step *
                          grad->rho[j + gv->SMOOTH_LENGTH_DY][i + gv->SMOOTH_LENGTH_DX][k + gv->SMOOTH_LENGTH_DZ] *
                          gv->RHO0;
                 if (gv->RHOMIN > 0 && rhonew < gv->RHOMIN) {
-                    if (gv->RHOMIN <= mod->rho[j][i][k]) {
+                    if (gv->RHOMIN <= mod.rho[j, i, k]) {
                         rhonew = gv->RHOMIN;
                     } else {
-                        if (rhonew <= mod->rho[j][i][k]) {
-                            rhonew = mod->rho[j][i][k];
+                        if (rhonew <= mod.rho[j, i, k]) {
+                            rhonew = mod.rho[j, i, k];
                         }
                     }
                 }
                 if (gv->RHOMAX > 0 && rhonew > gv->RHOMAX) {
-                    if (gv->RHOMAX >= mod->rho[j][i][k]) {
+                    if (gv->RHOMAX >= mod.rho[j, i, k]) {
                         rhonew = gv->RHOMAX;
                     } else {
-                        if (rhonew >= mod->rho[j][i][k]) {
-                            rhonew = mod->rho[j][i][k];
+                        if (rhonew >= mod.rho[j, i, k]) {
+                            rhonew = mod.rho[j, i, k];
                         }
                     }
                 }
@@ -233,15 +233,15 @@ void modelupdate(st_gradient *grad, st_model *mod, float step, int it_group, Glo
                     /*save normalised model differences for gv->LBFGS */
                     l++;
                     l1++;
-                    grad->bfgsmod[w][l] = (vpnew - sqrt(mod->pi[j][i][k] / mod->rho[j][i][k])) / gv->VP0;
+                    grad->bfgsmod[w][l] = (vpnew - sqrt(mod.pi[j, i, k] / mod.rho[j, i, k])) / gv->VP0;
                     if (gv->NUMPAR > 1) {
-                        grad->bfgsmod[w][l1] = (vsnew - sqrt(mod->u[j][i][k] / mod->rho[j][i][k])) / gv->VS0;
+                        grad->bfgsmod[w][l1] = (vsnew - sqrt(mod.u[j, i, k] / mod.rho[j, i, k])) / gv->VS0;
                     }
                 }
 
-                mod->u[j][i][k] = rhonew * vsnew * vsnew;
-                mod->pi[j][i][k] = rhonew * vpnew * vpnew;
-                mod->rho[j][i][k] = rhonew;
+                mod.u[j, i, k] = rhonew * vsnew * vsnew;
+                mod.pi[j, i, k] = rhonew * vpnew * vpnew;
+                mod.rho[j, i, k] = rhonew;
             }
         }
     }
diff --git a/src/modelupdate_acoustic.cpp b/src/modelupdate_acoustic.cpp
index 37108ca..9d5a43d 100644
--- a/src/modelupdate_acoustic.cpp
+++ b/src/modelupdate_acoustic.cpp
@@ -25,7 +25,7 @@
 #include "fd.hpp"
 #include "logging.hpp"
 
-void modelupdate_acoustic(st_gradient *grad, st_model *mod, float step, int it_group, GlobVar *gv)
+void modelupdate_acoustic(st_gradient *grad, st_model &mod, float step, int it_group, GlobVar *gv)
 {
     int j, i, k, l; // l1;
     float vpnew, rhonew, vpstart;
@@ -57,12 +57,12 @@ void modelupdate_acoustic(st_gradient *grad, st_model *mod, float step, int it_g
         for (i = 1; i <= gv->NX; i++) {
             for (k = 1; k <= gv->NZ; k++) {
                 vp = 0.0;
-                vp = sqrt(mod->pi[j][i][k] / mod->rho[j][i][k]);
+                vp = sqrt(mod.pi[j, i, k] / mod.rho[j, i, k]);
 
                 if (vp > max[0])
                     max[0] = vp;
-                if (mod->rho[j][i][k] > max[1])
-                    max[1] = mod->rho[j][i][k];
+                if (mod.rho[j, i, k] > max[1])
+                    max[1] = mod.rho[j, i, k];
             }
         }
     }
@@ -129,8 +129,8 @@ void modelupdate_acoustic(st_gradient *grad, st_model *mod, float step, int it_g
             for (k = 1; k <= gv->NZ; k++) {
                 /*update model */
                 vpnew = 0.0;
-                vpstart = sqrt(mod->pi[j][i][k] / mod->rho[j][i][k]);
-                /*vpnew=sqrt(mod->pi[j][i][k]/mod->rho[j][i][k])+max[0]*step*gradconvp[j][i][k]; */
+                vpstart = sqrt(mod.pi[j, i, k] / mod.rho[j, i, k]);
+                /*vpnew=sqrt(mod.pi[j, i, k]/mod.rho[j, i, k])+max[0]*step*gradconvp[j][i][k]; */
                 vpnew = vpstart + step * scale1 *
                         grad->vp[j + gv->SMOOTH_LENGTH_DY][i + gv->SMOOTH_LENGTH_DX][k + gv->SMOOTH_LENGTH_DZ] *
                         gv->VP0;
@@ -154,24 +154,24 @@ void modelupdate_acoustic(st_gradient *grad, st_model *mod, float step, int it_g
                 }
 
                 rhonew = 0.0;
-                rhonew = mod->rho[j][i][k] + scale3 * step *
+                rhonew = mod.rho[j, i, k] + scale3 * step *
                          grad->rho[j + gv->SMOOTH_LENGTH_DY][i + gv->SMOOTH_LENGTH_DX][k + gv->SMOOTH_LENGTH_DZ] *
                          gv->RHO0;
                 if (gv->RHOMIN > 0 && rhonew < gv->RHOMIN) {
-                    if (gv->RHOMIN <= mod->rho[j][i][k]) {
+                    if (gv->RHOMIN <= mod.rho[j, i, k]) {
                         rhonew = gv->RHOMIN;
                     } else {
-                        if (rhonew <= mod->rho[j][i][k]) {
-                            rhonew = mod->rho[j][i][k];
+                        if (rhonew <= mod.rho[j, i, k]) {
+                            rhonew = mod.rho[j, i, k];
                         }
                     }
                 }
                 if (gv->RHOMAX > 0 && rhonew > gv->RHOMAX) {
-                    if (gv->RHOMAX >= mod->rho[j][i][k]) {
+                    if (gv->RHOMAX >= mod.rho[j, i, k]) {
                         rhonew = gv->RHOMAX;
                     } else {
-                        if (rhonew >= mod->rho[j][i][k]) {
-                            rhonew = mod->rho[j][i][k];
+                        if (rhonew >= mod.rho[j, i, k]) {
+                            rhonew = mod.rho[j, i, k];
                         }
                     }
                 }
@@ -180,11 +180,11 @@ void modelupdate_acoustic(st_gradient *grad, st_model *mod, float step, int it_g
                     /*save normalised model differences for gv->LBFGS */
                     l++;
                     // l1++;
-                    grad->bfgsmod[w][l] = (vpnew - sqrt(mod->pi[j][i][k] / mod->rho[j][i][k])) / gv->VP0;
+                    grad->bfgsmod[w][l] = (vpnew - sqrt(mod.pi[j, i, k] / mod.rho[j, i, k])) / gv->VP0;
                 }
 
-                mod->pi[j][i][k] = rhonew * vpnew * vpnew;
-                mod->rho[j][i][k] = rhonew;
+                mod.pi[j, i, k] = rhonew * vpnew * vpnew;
+                mod.rho[j, i, k] = rhonew;
             }
         }
     }
diff --git a/src/outmod.cpp b/src/outmod.cpp
index 4984e3d..cbe48d2 100644
--- a/src/outmod.cpp
+++ b/src/outmod.cpp
@@ -24,7 +24,7 @@
 
 #include "fd.hpp"
 
-void outmod(const st_model *mod, int iteration, GlobVar *gv)
+void outmod(const st_model &mod, int iteration, GlobVar *gv)
 {
     FILE *fpmod1, *fpmod2, *fpmod3;
 
@@ -47,9 +47,9 @@ void outmod(const st_model *mod, int iteration, GlobVar *gv)
         for (k = 1; k <= gv->NZ; k++) {
             for (i = 1; i <= gv->NX; i++) {
                 for (j = 1; j <= gv->NY; j++) {
-                    vp = sqrt(mod->pi[j][i][k] / mod->rho[j][i][k]);
+                    vp = sqrt(mod.pi[j, i, k] / mod.rho[j, i, k]);
                     fwrite(&vp, sizeof(float), 1, fpmod1);
-                    fwrite(&mod->rho[j][i][k], sizeof(float), 1, fpmod3);
+                    fwrite(&mod.rho[j, i, k], sizeof(float), 1, fpmod3);
                 }
             }
         }
@@ -63,7 +63,7 @@ void outmod(const st_model *mod, int iteration, GlobVar *gv)
             for (k = 1; k <= gv->NZ; k++) {
                 for (i = 1; i <= gv->NX; i++) {
                     for (j = 1; j <= gv->NY; j++) {
-                        vs = sqrt(mod->u[j][i][k] / mod->rho[j][i][k]);
+                        vs = sqrt(mod.u[j, i, k] / mod.rho[j, i, k]);
                         fwrite(&vs, sizeof(float), 1, fpmod2);
                     }
                 }
@@ -99,7 +99,7 @@ void outmod(const st_model *mod, int iteration, GlobVar *gv)
             for (k = 1; k <= gv->NZ; k++) {
                 for (i = 1; i <= gv->NX; i++) {
                     for (j = 1; j <= gv->NY; j++) {
-                        vp = sqrt(mod->pi[j][i][k] / mod->rho[j][i][k]);
+                        vp = sqrt(mod.pi[j, i, k] / mod.rho[j, i, k]);
                         fwrite(&vp, sizeof(float), 1, fpmod1);
                     }
                 }
@@ -125,7 +125,7 @@ void outmod(const st_model *mod, int iteration, GlobVar *gv)
             for (k = 1; k <= gv->NZ; k++) {
                 for (i = 1; i <= gv->NX; i++) {
                     for (j = 1; j <= gv->NY; j++) {
-                        vs = sqrt(mod->u[j][i][k] / mod->rho[j][i][k]);
+                        vs = sqrt(mod.u[j, i, k] / mod.rho[j, i, k]);
                         fwrite(&vs, sizeof(float), 1, fpmod2);
                     }
                 }
@@ -151,7 +151,7 @@ void outmod(const st_model *mod, int iteration, GlobVar *gv)
             for (k = 1; k <= gv->NZ; k++) {
                 for (i = 1; i <= gv->NX; i++) {
                     for (j = 1; j <= gv->NY; j++) {
-                        fwrite(&mod->rho[j][i][k], sizeof(float), 1, fpmod3);
+                        fwrite(&mod.rho[j, i, k], sizeof(float), 1, fpmod3);
                     }
                 }
             }
diff --git a/src/readmod.cpp b/src/readmod.cpp
index 6e84b17..880c4df 100644
--- a/src/readmod.cpp
+++ b/src/readmod.cpp
@@ -25,7 +25,7 @@
 #include "util.hpp"
 #include "logging.hpp"
 
-void readmod(st_model *mod, GlobVar *gv)
+void readmod(st_model &mod, GlobVar *gv)
 {
     float rhov, vp, vs = 0.0;
     float *pts = NULL, tp = 0.0, ts = 0.0, sumpi = 0.0, sumu = 0.0, ws;
@@ -43,7 +43,7 @@ void readmod(st_model *mod, GlobVar *gv)
         pts = vector(1, gv->L);
         for (int l = 1; l <= gv->L; l++) {
             pts[l] = 1.0f / (2.0f * PI * gv->FL[l]);
-            mod->eta[l] = gv->DT / pts[l];
+            mod.eta[l] = gv->DT / pts[l];
         }
 
         tp = gv->TAU;
@@ -180,15 +180,15 @@ void readmod(st_model *mod, GlobVar *gv)
                     ii = i - gv->POS[1] * gv->NX;
                     jj = j - gv->POS[2] * gv->NY;
                     kk = k - gv->POS[3] * gv->NZ;
-                    mod->rho[jj][ii][kk] = rhov;
-                    mod->pi[jj][ii][kk] = vp * vp * rhov / (1.0 + sumpi);
+                    mod.rho[jj, ii, kk] = rhov;
+                    mod.pi[jj, ii, kk] = vp * vp * rhov / (1.0 + sumpi);
                     if (gv->WEQ != 2) {
-                        mod->u[jj][ii][kk] = vs * vs * rhov / (1.0 + sumu);
+                        mod.u[jj, ii, kk] = vs * vs * rhov / (1.0 + sumu);
                     }
                     if (gv->L) {
-                        mod->taup[jj][ii][kk] = tp;
+                        mod.taup[jj, ii, kk] = tp;
                         if (gv->WEQ != 2) {
-                            mod->taus[jj][ii][kk] = ts;
+                            mod.taus[jj, ii, kk] = ts;
                         }
                     }
                 }
diff --git a/src/seismo_ssg.cpp b/src/seismo_ssg.cpp
index 81d3cdc..88602a5 100644
--- a/src/seismo_ssg.cpp
+++ b/src/seismo_ssg.cpp
@@ -25,7 +25,7 @@
 #include "fd.hpp"
 
 void seismo(int nt, int ntr, int **recpos, st_seismogram *section,
-            st_velocity &vel, st_stress &stress, st_model *mod, const GlobVar *gv)
+            st_velocity &vel, st_stress &stress, st_model &mod, const GlobVar *gv)
 {
     int i, j, k, itr;
     float amp, dh24x, dh24y, dh24z, vyx, vxy, vxx, vyy, vzx, vyz, vxz, vzy, vzz;
@@ -87,7 +87,7 @@ void seismo(int nt, int ntr, int **recpos, st_seismogram *section,
                 vzx = (vel.vz[j, i + 1, k] - vel.vz[j, i, k]) * (dh24x);
                 vzy = (vel.vz[j + 1, i, k] - vel.vz[j, i, k]) * (dh24y);
 
-                amp = mod->u[j][i][k] * ((vyz - vzy) * fabs(vyz - vzy) +
+                amp = mod.u[j, i, k] * ((vyz - vzy) * fabs(vyz - vzy) +
                                          (vzx - vxz) * fabs(vzx - vxz) + (vxy - vyx) * fabs(vxy - vyx));
                 section->curl[itr][nt] = fsign(amp) * sqrt(fabs(amp));
             }
@@ -100,7 +100,7 @@ void seismo(int nt, int ntr, int **recpos, st_seismogram *section,
             vyy = (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) * (dh24y);
             vzz = (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) * (dh24z);
 
-            section->div[itr][nt] = (vxx + vyy + vzz) * sqrt(mod->pi[j][i][k]);
+            section->div[itr][nt] = (vxx + vyy + vzz) * sqrt(mod.pi[j, i, k]);
 
             break;
         case 4:
@@ -142,7 +142,7 @@ void seismo(int nt, int ntr, int **recpos, st_seismogram *section,
                 vzx = (vel.vz[j, i + 1, k] - vel.vz[j, i, k]) * (dh24x);
                 vzy = (vel.vz[j + 1, i, k] - vel.vz[j, i, k]) * (dh24y);
 
-                amp = mod->u[j][i][k] * ((vyz - vzy) * fabs(vyz - vzy) +
+                amp = mod.u[j, i, k] * ((vyz - vzy) * fabs(vyz - vzy) +
                                          (vzx - vxz) * fabs(vzx - vxz) + (vxy - vyx) * fabs(vxy - vyx));
                 section->curl[itr][nt] = fsign(amp) * sqrt(fabs(amp));
             }
@@ -155,7 +155,7 @@ void seismo(int nt, int ntr, int **recpos, st_seismogram *section,
             vyy = (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) * (dh24y);
             vzz = (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) * (dh24z);
 
-            section->div[itr][nt] = (vxx + vyy + vzz) * sqrt(mod->pi[j][i][k]);
+            section->div[itr][nt] = (vxx + vyy + vzz) * sqrt(mod.pi[j, i, k]);
             break;
         }
     }
diff --git a/src/snap_ssg.cpp b/src/snap_ssg.cpp
index c17fd3e..a447f00 100644
--- a/src/snap_ssg.cpp
+++ b/src/snap_ssg.cpp
@@ -24,7 +24,7 @@
 #include "fd.hpp"
 #include "logging.hpp"
 
-void snap(int nt, int nsnap, st_velocity &vel, st_stress &stress, const st_model *mod,
+void snap(int nt, int nsnap, st_velocity &vel, st_stress &stress, const st_model &mod,
           const st_boundary *nb, GlobVar *gv)
 {
     /*
@@ -164,30 +164,30 @@ void snap(int nt, int nsnap, st_velocity &vel, st_stress &stress, const st_model
                         switch (gv->SNAP_PLANE) {
                         case 1:    /* energy without sign */
                             /* sqrt(Es) with Es = u*amp*amp (second amp removed due to missing sqrt in amp */
-                            a = sqrt((mod->u[j][i][k]) * amp);
+                            a = sqrt((mod.u[j, i, k]) * amp);
                             break;
                         case 2:    /* energy with sign true for x-y-plane */
                             /*sign(rot(v)x * sqrt(Es) with Es = u*amp*amp (second amp removed due to missing sqrt in amp */
-                            a = fsign((vxy - vyx)) * sqrt((mod->u[j][i][k]) * amp);
+                            a = fsign((vxy - vyx)) * sqrt((mod.u[j, i, k]) * amp);
                             break;
                         case 3:    /* energy with sign true for x-z-plane */
                             /*sign(rot(v)r * sqrt(Es) with Es = u*amp*amp (second amp removed due to missing sqrt in amp */
-                            a = fsign((vxz - vzx)) * sqrt((mod->u[j][i][k]) * amp);
+                            a = fsign((vxz - vzx)) * sqrt((mod.u[j, i, k]) * amp);
                             break;
                         case 4:    /* energy with sign true for y-z-plane */
                             /*sign(rot(v)t * sqrt(Es) with Es = u*amp*amp (second amp removed due to missing sqrt in amp */
-                            a = fsign((vzy - vyz)) * sqrt((mod->u[j][i][k]) * amp);
+                            a = fsign((vzy - vyz)) * sqrt((mod.u[j, i, k]) * amp);
                             break;
                         case 5:    /*custom force *//*not yet working properly */
                             /*sign(rot(v)t * sqrt(Es) with Es = u*amp*amp (second amp removed due to missing sqrt in amp */
-                            a = fsign((vxz - vzx)) * sqrt((mod->u[j][i][k]) * amp);
+                            a = fsign((vxz - vzx)) * sqrt((mod.u[j, i, k]) * amp);
                             break;
                         }
 
                         /*sign(rot(v)t * sqrt(Es) with Es = u*amp*amp (second amp removed due to missing sqrt in amp */
-                        /*a=fsign((vxz-vzx))*sqrt((mod->u[j][i][k])*amp);
+                        /*a=fsign((vxz-vzx))*sqrt((mod.u[j, i, k])*amp);
                          *
-                         * amp=mod->u[j][i][k]*((vyz-vzy)*fabs(vyz-vzy)+
+                         * amp=mod.u[j, i, k]*((vyz-vzy)*fabs(vyz-vzy)+
                          * (vzx-vxz)*fabs(vzx-vxz)+(vxy-vyx)*fabs(vxy-vyx));
                          * a=fsign(amp)*sqrt(fabs(amp)); */
 
@@ -214,26 +214,26 @@ void snap(int nt, int nsnap, st_velocity &vel, st_stress &stress, const st_model
                     switch (gv->SNAP_PLANE) {
                     case 1:        /* energy without sign */
                         /* Ep with Ep=pi*amp*amp */
-                        a = sqrt((mod->pi[j][i][k]) * amp * amp);
+                        a = sqrt((mod.pi[j, i, k]) * amp * amp);
                         break;
                     case 2:        /* single force in x */
                         /*sign of div(v) * Ep with Ep=pi*amp*amp */
-                        a = fsign(amp) * sqrt((mod->pi[j][i][k]) * amp * amp);
+                        a = fsign(amp) * sqrt((mod.pi[j, i, k]) * amp * amp);
                         break;
                     case 3:        /* single force in y */
                         /*sign of div(v) * Ep with Ep=pi*amp*amp */
-                        a = fsign(amp) * sqrt((mod->pi[j][i][k]) * amp * amp);
+                        a = fsign(amp) * sqrt((mod.pi[j, i, k]) * amp * amp);
                         break;
                     case 4:        /* single force in z */
                         /*sign of div(v) * Ep with Ep=pi*amp*amp */
-                        a = fsign(amp) * sqrt((mod->pi[j][i][k]) * amp * amp);
+                        a = fsign(amp) * sqrt((mod.pi[j, i, k]) * amp * amp);
                         break;
                     }
 
                     /*sign of div(v) * Ep with Ep=pi*amp*amp */
-                    /*a=fsign(amp)*sqrt((mod->pi[j][i][k])*amp*amp);
+                    /*a=fsign(amp)*sqrt((mod.pi[j, i, k])*amp*amp);
                      *
-                     * a=(vxx+vyy+vzz)*sqrt(mod->pi[j][i][k]); */
+                     * a=(vxx+vyy+vzz)*sqrt(mod.pi[j, i, k]); */
 
                     writedsk(fpx2, a, gv->SNAP_FORMAT);
                 }
diff --git a/src/stfi.cpp b/src/stfi.cpp
index 3c6d3dc..9989d38 100644
--- a/src/stfi.cpp
+++ b/src/stfi.cpp
@@ -31,7 +31,7 @@
 #include "kiss_fftr.h"
 
 void stfi(st_acquisition *acq, st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress &stress,
-          st_model *mod, st_model_av &mod_av, st_visc_mem *visco_mem, st_seismogram *section,
+          st_model &mod, st_model_av &mod_av, st_visc_mem *visco_mem, st_seismogram *section,
           st_seismogram *section_obs, st_signals *signals, int nsrc_loc, int ntr_loc, st_pml_coeff *pml_coeff,
           st_pml_wfd &pml_wfd, st_buffer_flat *stressbuff, st_buffer_flat *velbuff, st_freq_velocity *fourier_vel_fw,
           const float *finv, double *L2, int nf, int ntast, int lsnap, int nsnap, int ishot, int shot_id, int cdf,
@@ -49,7 +49,7 @@ void stfi(st_acquisition *acq, st_boundary *nb, const st_boundary *nb_fix, st_ve
         * Timestep loop (simulation for STFI)
         *****************************************************/
         timeloop(nb, nb_fix, vel, stress, mod, mod_av, section, acq->srcpos_loc, acq->recpos_loc,
-                 signals, nsrc_loc, mod->absorb_coeff, pml_coeff, pml_wfd, stressbuff, velbuff,
+                 signals, nsrc_loc, mod.absorb_coeff, pml_coeff, pml_wfd, stressbuff, velbuff,
                  fourier_vel_fw, finv, nf, ntast, ntr_loc, lsnap, nsnap, 0, shot_id, 4, gv);
 
         /* STFI: Calculate filter */
diff --git a/src/surface_ssg.cpp b/src/surface_ssg.cpp
index 249710c..482053c 100644
--- a/src/surface_ssg.cpp
+++ b/src/surface_ssg.cpp
@@ -23,7 +23,7 @@
 
 #include "fd.hpp"
 
-void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd, st_visc_mem *mem,
+void surface(int ndepth, st_model &mod, st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd, st_visc_mem *mem,
              st_stress &stress, st_velocity &vel)
 {
     int i, k, j, fdoh, m, h1;
@@ -112,16 +112,16 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd &pml
                 }
 
                 /* partially updating sxx and szz in the same way */
-                f = mod->u[j][i][k] * 2.0f * (1.0f + L * mod->taus[j][i][k]);
-                g = mod->pi[j][i][k] * (1.0f + L * mod->taup[j][i][k]);
+                f = mod.u[j, i, k] * 2.0f * (1.0f + L * mod.taus[j, i, k]);
+                g = mod.pi[j, i, k] * (1.0f + L * mod.taup[j, i, k]);
                 h = -(DT * (g - f) * (g - f) * (vxx + vzz) / g) - (DT * (g - f) * vyy);
                 stress.sxx[j, i, k] += h - (dthalbe * mem->rxx[j][i][k]);
                 stress.szz[j, i, k] += h - (dthalbe * mem->rzz[j][i][k]);
 
                 /* updating the memory-variable rxx, rzz at the free surface */
-                b = mod->eta[1] / (1.0 + (mod->eta[1] * 0.5));
-                d = 2.0f * mod->u[j][i][k] * mod->taus[j][i][k];
-                e = mod->pi[j][i][k] * mod->taup[j][i][k];
+                b = mod.eta[1] / (1.0 + (mod.eta[1] * 0.5));
+                d = 2.0f * mod.u[j, i, k] * mod.taus[j, i, k];
+                e = mod.pi[j, i, k] * mod.taup[j, i, k];
                 h = b * (((d - e) * ((f / g) - 1.0) * (vxx + vzz)) - ((d - e) * vyy));
                 mem->rxx[j][i][k] += h;
                 mem->rzz[j][i][k] += h;
@@ -202,16 +202,16 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd &pml
                 }
 
                 /* partially updating sxx and szz in the same way */
-                f = mod->u[j][i][k] * 2.0f * (1.0f + L * mod->taus[j][i][k]);
-                g = mod->pi[j][i][k] * (1.0f + L * mod->taup[j][i][k]);
+                f = mod.u[j, i, k] * 2.0f * (1.0f + L * mod.taus[j, i, k]);
+                g = mod.pi[j, i, k] * (1.0f + L * mod.taup[j, i, k]);
                 h = -(DT * (g - f) * (g - f) * (vxx + vzz) / g) - (DT * (g - f) * vyy);
                 stress.sxx[j, i, k] += h - (dthalbe * mem->rxx[j][i][k]);
                 stress.szz[j, i, k] += h - (dthalbe * mem->rzz[j][i][k]);
 
                 /* updating the memory-variable rxx, rzz at the free surface */
-                b = mod->eta[1] / (1.0 + (mod->eta[1] * 0.5));
-                d = 2.0f * mod->u[j][i][k] * mod->taus[j][i][k];
-                e = mod->pi[j][i][k] * mod->taup[j][i][k];
+                b = mod.eta[1] / (1.0 + (mod.eta[1] * 0.5));
+                d = 2.0f * mod.u[j, i, k] * mod.taus[j, i, k];
+                e = mod.pi[j, i, k] * mod.taup[j, i, k];
                 h = b * (((d - e) * ((f / g) - 1.0) * (vxx + vzz)) - ((d - e) * vyy));
                 mem->rxx[j][i][k] += h;
                 mem->rzz[j][i][k] += h;
@@ -269,16 +269,16 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd &pml
                        b3 * (vel.vz[j, i, k + 2] - vel.vz[j, i, k - 3])) / DZ;
 
                 /* partially updating sxx and szz in the same way */
-                f = mod->u[j][i][k] * 2.0f * (1.0f + L * mod->taus[j][i][k]);
-                g = mod->pi[j][i][k] * (1.0 + L * mod->taup[j][i][k]);
+                f = mod.u[j, i, k] * 2.0f * (1.0f + L * mod.taus[j, i, k]);
+                g = mod.pi[j, i, k] * (1.0 + L * mod.taup[j, i, k]);
                 h = -(DT * (g - f) * (g - f) * (vxx + vzz) / g) - (DT * (g - f) * vyy);
                 stress.sxx[j, i, k] += h - (dthalbe * mem->rxx[j][i][k]);
                 stress.szz[j, i, k] += h - (dthalbe * mem->rzz[j][i][k]);
 
                 /* updating the memory-variable rxx, rzz at the free surface */
-                b = mod->eta[1] / (1.0 + (mod->eta[1] * 0.5));
-                d = 2.0f * mod->u[j][i][k] * mod->taus[j][i][k];
-                e = mod->pi[j][i][k] * mod->taup[j][i][k];
+                b = mod.eta[1] / (1.0 + (mod.eta[1] * 0.5));
+                d = 2.0f * mod.u[j, i, k] * mod.taus[j, i, k];
+                e = mod.pi[j, i, k] * mod.taup[j, i, k];
                 h = b * (((d - e) * ((f / g) - 1.0) * (vxx + vzz)) - ((d - e) * vyy));
                 mem->rxx[j][i][k] += h;
                 mem->rzz[j][i][k] += h;
@@ -342,16 +342,16 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd &pml
                        b4 * (vel.vz[j, i, k + 3] - vel.vz[j, i, k - 4])) / DZ;
 
                 /* partially updating sxx and szz in the same way */
-                f = mod->u[j][i][k] * 2.0f * (1.0f + L * mod->taus[j][i][k]);
-                g = mod->pi[j][i][k] * (1.0f + L * mod->taup[j][i][k]);
+                f = mod.u[j, i, k] * 2.0f * (1.0f + L * mod.taus[j, i, k]);
+                g = mod.pi[j, i, k] * (1.0f + L * mod.taup[j, i, k]);
                 h = -(DT * (g - f) * (g - f) * (vxx + vzz) / g) - (DT * (g - f) * vyy);
                 stress.sxx[j, i, k] += h - (dthalbe * mem->rxx[j][i][k]);
                 stress.szz[j, i, k] += h - (dthalbe * mem->rzz[j][i][k]);
 
                 /* updating the memory-variable rxx, rzz at the free surface */
-                b = mod->eta[1] / (1.0 + (mod->eta[1] * 0.5));
-                d = 2.0f * mod->u[j][i][k] * mod->taus[j][i][k];
-                e = mod->pi[j][i][k] * mod->taup[j][i][k];
+                b = mod.eta[1] / (1.0 + (mod.eta[1] * 0.5));
+                d = 2.0f * mod.u[j, i, k] * mod.taus[j, i, k];
+                e = mod.pi[j, i, k] * mod.taup[j, i, k];
                 h = b * (((d - e) * ((f / g) - 1.0) * (vxx + vzz)) - ((d - e) * vyy));
                 mem->rxx[j][i][k] += h;
                 mem->rzz[j][i][k] += h;
@@ -420,16 +420,16 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd &pml
                        b5 * (vel.vz[j, i, k + 4] - vel.vz[j, i, k - 5])) / DZ;
 
                 /* partially updating sxx and szz in the same way */
-                f = mod->u[j][i][k] * 2.0f * (1.0f + L * mod->taus[j][i][k]);
-                g = mod->pi[j][i][k] * (1.0f + L * mod->taup[j][i][k]);
+                f = mod.u[j, i, k] * 2.0f * (1.0f + L * mod.taus[j, i, k]);
+                g = mod.pi[j, i, k] * (1.0f + L * mod.taup[j, i, k]);
                 h = -(DT * (g - f) * (g - f) * (vxx + vzz) / g) - (DT * (g - f) * vyy);
                 stress.sxx[j, i, k] += h - (dthalbe * mem->rxx[j][i][k]);
                 stress.szz[j, i, k] += h - (dthalbe * mem->rzz[j][i][k]);
 
                 /* updating the memory-variable rxx, rzz at the free surface */
-                b = mod->eta[1] / (1.0 + (mod->eta[1] * 0.5));
-                d = 2.0f * mod->u[j][i][k] * mod->taus[j][i][k];
-                e = mod->pi[j][i][k] * mod->taup[j][i][k];
+                b = mod.eta[1] / (1.0 + (mod.eta[1] * 0.5));
+                d = 2.0f * mod.u[j, i, k] * mod.taus[j, i, k];
+                e = mod.pi[j, i, k] * mod.taup[j, i, k];
                 h = b * (((d - e) * ((f / g) - 1.0f) * (vxx + vzz)) - ((d - e) * vyy));
                 mem->rxx[j][i][k] += h;
                 mem->rzz[j][i][k] += h;
@@ -505,16 +505,16 @@ void surface(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd &pml
                        b6 * (vel.vz[j, i, k + 5] - vel.vz[j, i, k - 6])) / DZ;
 
                 /* partially updating sxx and szz in the same way */
-                f = mod->u[j][i][k] * 2.0f * (1.0f + L * mod->taus[j][i][k]);
-                g = mod->pi[j][i][k] * (1.0f + L * mod->taup[j][i][k]);
+                f = mod.u[j, i, k] * 2.0f * (1.0f + L * mod.taus[j, i, k]);
+                g = mod.pi[j, i, k] * (1.0f + L * mod.taup[j, i, k]);
                 h = -(DT * (g - f) * (g - f) * (vxx + vzz) / g) - (DT * (g - f) * vyy);
                 stress.sxx[j, i, k] += h - (dthalbe * mem->rxx[j][i][k]);
                 stress.szz[j, i, k] += h - (dthalbe * mem->rzz[j][i][k]);
 
                 /* updating the memory-variable rxx, rzz at the free surface */
-                b = mod->eta[1] / (1.0 + (mod->eta[1] * 0.5));
-                d = 2.0f * mod->u[j][i][k] * mod->taus[j][i][k];
-                e = mod->pi[j][i][k] * mod->taup[j][i][k];
+                b = mod.eta[1] / (1.0 + (mod.eta[1] * 0.5));
+                d = 2.0f * mod.u[j, i, k] * mod.taus[j, i, k];
+                e = mod.pi[j, i, k] * mod.taup[j, i, k];
                 h = b * (((d - e) * ((f / g) - 1.0) * (vxx + vzz)) - ((d - e) * vyy));
                 mem->rxx[j][i][k] += h;
                 mem->rzz[j][i][k] += h;
diff --git a/src/surface_ssg_elastic.cpp b/src/surface_ssg_elastic.cpp
index 2ddc2c2..52343f4 100644
--- a/src/surface_ssg_elastic.cpp
+++ b/src/surface_ssg_elastic.cpp
@@ -23,7 +23,7 @@
 
 #include "fd.hpp"
 
-void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd,
+void surface_elastic(int ndepth, st_model &mod, st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd,
                      st_stress &stress, st_velocity &vel, const GlobVar *gv)
 {
     int h1;
@@ -82,8 +82,8 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
                     }
                 }
 
-                f = mod->u[j][i][k] * 2.0;
-                g = mod->pi[j][i][k];
+                f = mod.u[j, i, k] * 2.0;
+                g = mod.pi[j, i, k];
                 h = -(gv->DT * (g - f) * (g - f) * (vxx + vzz) / g) - (gv->DT * (g - f) * vyy);
                 stress.sxx[j, i, k] += h;
                 stress.szz[j, i, k] += h;
@@ -148,8 +148,8 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
                     }
                 }
 
-                f = mod->u[j][i][k] * 2.0;
-                g = mod->pi[j][i][k];
+                f = mod.u[j, i, k] * 2.0;
+                g = mod.pi[j, i, k];
                 h = -(gv->DT * (g - f) * (g - f) * (vxx + vzz) / g) - (gv->DT * (g - f) * vyy);
                 stress.sxx[j, i, k] += h;
                 stress.szz[j, i, k] += h;
@@ -192,8 +192,8 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
                        b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2]) +
                        b3 * (vel.vz[j, i, k + 2] - vel.vz[j, i, k - 3])) * oodz;
 
-                f = mod->u[j][i][k] * 2.0;
-                g = mod->pi[j][i][k];
+                f = mod.u[j, i, k] * 2.0;
+                g = mod.pi[j, i, k];
                 h = -(gv->DT * (g - f) * (g - f) * (vxx + vzz) / g) - (gv->DT * (g - f) * vyy);
                 stress.sxx[j, i, k] += h;
                 stress.szz[j, i, k] += h;
@@ -242,8 +242,8 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
                        b3 * (vel.vz[j, i, k + 2] - vel.vz[j, i, k - 3]) +
                        b4 * (vel.vz[j, i, k + 3] - vel.vz[j, i, k - 4])) * oodz;
 
-                f = mod->u[j][i][k] * 2.0;
-                g = mod->pi[j][i][k];
+                f = mod.u[j, i, k] * 2.0;
+                g = mod.pi[j, i, k];
                 h = -(gv->DT * (g - f) * (g - f) * (vxx + vzz) / g) - (gv->DT * (g - f) * vyy);
                 stress.sxx[j, i, k] += h;
                 stress.szz[j, i, k] += h;
@@ -297,8 +297,8 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
                        b4 * (vel.vz[j, i, k + 3] - vel.vz[j, i, k - 4]) +
                        b5 * (vel.vz[j, i, k + 4] - vel.vz[j, i, k - 5])) * oodz;
 
-                f = mod->u[j][i][k] * 2.0;
-                g = mod->pi[j][i][k];
+                f = mod.u[j, i, k] * 2.0;
+                g = mod.pi[j, i, k];
                 h = -(gv->DT * (g - f) * (g - f) * (vxx + vzz) / g) - (gv->DT * (g - f) * vyy);
                 stress.sxx[j, i, k] += h;
                 stress.szz[j, i, k] += h;
@@ -359,8 +359,8 @@ void surface_elastic(int ndepth, st_model *mod, st_pml_coeff *pml_coeff, st_pml_
                        b5 * (vel.vz[j, i, k + 4] - vel.vz[j, i, k - 5]) +
                        b6 * (vel.vz[j, i, k + 5] - vel.vz[j, i, k - 6])) * oodz;
 
-                f = mod->u[j][i][k] * 2.0;
-                g = mod->pi[j][i][k];
+                f = mod.u[j, i, k] * 2.0;
+                g = mod.pi[j, i, k];
                 h = -(gv->DT * (g - f) * (g - f) * (vxx + vzz) / g) - (gv->DT * (g - f) * vyy);
                 stress.sxx[j, i, k] += h;
                 stress.szz[j, i, k] += h;
diff --git a/src/timeloop.cpp b/src/timeloop.cpp
index cac7970..037823a 100644
--- a/src/timeloop.cpp
+++ b/src/timeloop.cpp
@@ -24,9 +24,9 @@
 #include "logging.hpp"
 
 void timeloop(st_boundary *nb, const st_boundary *nb_fix, st_velocity &vel, st_stress &stress,
-              st_model *mod, st_model_av &mod_av, st_seismogram *section,
+              st_model &mod, st_model_av &mod_av, st_seismogram *section,
               float **srcpos_loc, int **recpos_loc, st_signals *signals, int nsrc_loc,
-              float ***absorb_coeff, st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd,
+              float3DTensorT &absorb_coeff, st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd,
               st_buffer_flat *stressbuff, st_buffer_flat *velbuff, st_freq_velocity *fourier_vel,
               const float *finv, int nf, int ntast, int ntr, int lsnap, int nsnap, int pshot, int shot_id,
               int proptype, GlobVar *gv)
diff --git a/src/update_s_ssg_CPML_acoustic.cpp b/src/update_s_ssg_CPML_acoustic.cpp
index 5e8dcc7..e7be7fc 100644
--- a/src/update_s_ssg_CPML_acoustic.cpp
+++ b/src/update_s_ssg_CPML_acoustic.cpp
@@ -30,7 +30,7 @@
 #define UNUSED(x) (void)(x)
 
 double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
-                              st_stress &stress, st_model *mod, st_pml_coeff *pml_coeff,
+                              st_stress &stress, st_model &mod, st_pml_coeff *pml_coeff,
                               st_pml_wfd &pml_wfd, const GlobVar *gv)
 {
     int h1;
@@ -91,7 +91,7 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
                         vzz = vzz / pml_coeff->K_z[h1] + pml_wfd.psi_vzz[j, i, h1];
                     }
 
-                    g = mod->pi[j][i][k];
+                    g = mod.pi[j, i, k];
 
                     vxxyyzz = vxx + vyy + vzz;
 
@@ -150,7 +150,7 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
                         vzz = vzz / pml_coeff->K_z[h1] + pml_wfd.psi_vzz[j, i, h1];
                     }
 
-                    g = mod->pi[j][i][k];
+                    g = mod.pi[j, i, k];
 
                     vxxyyzz = vxx + vyy + vzz;
 
@@ -192,7 +192,7 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
                         vzz = vzz / pml_coeff->K_z[h1] + pml_wfd.psi_vzz[j, i, h1];
                     }
 
-                    g = mod->pi[j][i][k];
+                    g = mod.pi[j, i, k];
 
                     vxxyyzz = vxx + vyy + vzz;
 
@@ -237,7 +237,7 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
                         vzz = vzz / pml_coeff->K_z[h1] + pml_wfd.psi_vzz[j, i, h1];
                     }
 
-                    g = mod->pi[j][i][k];
+                    g = mod.pi[j, i, k];
 
                     vxxyyzz = vxx + vyy + vzz;
 
@@ -265,7 +265,7 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
                     pml_wfd.psi_vzz[j, i, k] = pml_coeff->b_z[k] * pml_wfd.psi_vzz[j, i, k] + pml_coeff->a_z[k] * vzz;
                     vzz = vzz / pml_coeff->K_y[k] + pml_wfd.psi_vzz[j, i, k];
 
-                    g = mod->pi[j][i][k];
+                    g = mod.pi[j, i, k];
 
                     vxxyyzz = vxx + vyy + vzz;
 
@@ -296,7 +296,7 @@ double update_s_CPML_acoustic(st_boundary *nb, st_velocity &vel,
                         pml_coeff->b_z[h1] * pml_wfd.psi_vzz[j, i, h1] + pml_coeff->a_z[h1] * vzz;
                     vzz = vzz / pml_coeff->K_z[h1] + pml_wfd.psi_vzz[j, i, h1];
 
-                    g = mod->pi[j][i][k];
+                    g = mod.pi[j, i, k];
 
                     vxxyyzz = vxx + vyy + vzz;
 
diff --git a/src/update_s_ssg_CPML_elastic.cpp b/src/update_s_ssg_CPML_elastic.cpp
index 755d15e..5dc7ed8 100644
--- a/src/update_s_ssg_CPML_elastic.cpp
+++ b/src/update_s_ssg_CPML_elastic.cpp
@@ -30,7 +30,7 @@
 #define UNUSED(x) (void)(x)
 
 double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
-                             st_stress &stress, st_model *mod, st_model_av &mod_av,
+                             st_stress &stress, st_model &mod, st_model_av &mod_av,
                              st_pml_coeff *pml_coeff, st_pml_wfd &pml_wfd, const GlobVar *gv)
 {
     int h1;
@@ -150,8 +150,8 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                     fipjp = mod_av.uipjp[j, i, k] * gv->DT;
                     fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
                     fipkp = mod_av.uipkp[j, i, k] * gv->DT;
-                    g = mod->pi[j][i][k];
-                    f = 2.0f * mod->u[j][i][k];
+                    g = mod.pi[j, i, k];
+                    f = 2.0f * mod.u[j, i, k];
 
                     vxyyx = vxy + vyx;
                     vyzzy = vyz + vzy;
@@ -272,8 +272,8 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                     fipjp = mod_av.uipjp[j, i, k] * gv->DT;
                     fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
                     fipkp = mod_av.uipkp[j, i, k] * gv->DT;
-                    g = mod->pi[j][i][k];
-                    f = 2.0f * mod->u[j][i][k];
+                    g = mod.pi[j, i, k];
+                    f = 2.0f * mod.u[j, i, k];
 
                     vxyyx = vxy + vyx;
                     vyzzy = vyz + vzy;
@@ -367,8 +367,8 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                     fipjp = mod_av.uipjp[j, i, k] * gv->DT;
                     fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
                     fipkp = mod_av.uipkp[j, i, k] * gv->DT;
-                    g = mod->pi[j][i][k];
-                    f = 2.0f * mod->u[j][i][k];
+                    g = mod.pi[j, i, k];
+                    f = 2.0f * mod.u[j, i, k];
 
                     vxyyx = vxy + vyx;
                     vyzzy = vyz + vzy;
@@ -463,8 +463,8 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                     fipjp = mod_av.uipjp[j, i, k] * gv->DT;
                     fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
                     fipkp = mod_av.uipkp[j, i, k] * gv->DT;
-                    g = mod->pi[j][i][k];
-                    f = 2.0f * mod->u[j][i][k];
+                    g = mod.pi[j, i, k];
+                    f = 2.0f * mod.u[j, i, k];
 
                     vxyyx = vxy + vyx;
                     vyzzy = vyz + vzy;
@@ -532,8 +532,8 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                     fipjp = mod_av.uipjp[j, i, k] * gv->DT;
                     fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
                     fipkp = mod_av.uipkp[j, i, k] * gv->DT;
-                    g = mod->pi[j][i][k];
-                    f = 2.0f * mod->u[j][i][k];
+                    g = mod.pi[j, i, k];
+                    f = 2.0f * mod.u[j, i, k];
 
                     vxyyx = vxy + vyx;
                     vyzzy = vyz + vzy;
@@ -602,8 +602,8 @@ double update_s_CPML_elastic(st_boundary *nb, st_velocity &vel,
                     fipjp = mod_av.uipjp[j, i, k] * gv->DT;
                     fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
                     fipkp = mod_av.uipkp[j, i, k] * gv->DT;
-                    g = mod->pi[j][i][k];
-                    f = 2.0f * mod->u[j][i][k];
+                    g = mod.pi[j, i, k];
+                    f = 2.0f * mod.u[j, i, k];
 
                     vxyyx = vxy + vyx;
                     vyzzy = vyz + vzy;
diff --git a/src/update_s_ssg_acoustic.cpp b/src/update_s_ssg_acoustic.cpp
index f91375d..cba7bac 100644
--- a/src/update_s_ssg_acoustic.cpp
+++ b/src/update_s_ssg_acoustic.cpp
@@ -28,7 +28,7 @@
 #define UNUSED(x) (void)(x)
 
 double update_s_acoustic(st_boundary *nb, st_velocity &vel,
-                         st_stress &stress, st_model *mod, const GlobVar *gv)
+                         st_stress &stress, st_model &mod, const GlobVar *gv)
 {
     float vxx, vyy, vzz;
     float vxxyyzz;
@@ -49,7 +49,7 @@ double update_s_acoustic(st_boundary *nb, st_velocity &vel,
                     float vxx = (vel.vx[j, i, k] - vel.vx[j, i - 1, k]) * oodx;
                     float vyy = (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) * oody;
                     float vzz = (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) * oodz;
-                    stress.sp[j, i, k] += gv->DT * mod->pi[j][i][k] * (vxx + vyy + vzz);
+                    stress.sp[j, i, k] += gv->DT * mod.pi[j, i, k] * (vxx + vyy + vzz);
                 }
             }
         }
@@ -76,7 +76,7 @@ double update_s_acoustic(st_boundary *nb, st_velocity &vel,
                     float vzz =
                         (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
                          b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) * oodz;
-                    stress.sp[j, i, k] += gv->DT * mod->pi[j][i][k] * (vxx + vyy + vzz);
+                    stress.sp[j, i, k] += gv->DT * mod.pi[j, i, k] * (vxx + vyy + vzz);
                 }
             }
         }
@@ -112,7 +112,7 @@ double update_s_acoustic(st_boundary *nb, st_velocity &vel,
                            b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2]) +
                            b3 * (vel.vz[j, i, k + 2] - vel.vz[j, i, k - 3])) * oodz;
 
-                    g = mod->pi[j][i][k];
+                    g = mod.pi[j, i, k];
 
                     vxxyyzz = vxx + vyy + vzz;
 
@@ -158,7 +158,7 @@ double update_s_acoustic(st_boundary *nb, st_velocity &vel,
                            b4 * (vel.vz[j, i, k + 3] - vel.vz[j, i, k - 4])) * oodz;
 
                     /* updating components of the stress tensor, partially */
-                    g = mod->pi[j][i][k];
+                    g = mod.pi[j, i, k];
 
                     vxxyyzz = vxx + vyy + vzz;
 
@@ -208,7 +208,7 @@ double update_s_acoustic(st_boundary *nb, st_velocity &vel,
                            b4 * (vel.vz[j, i, k + 3] - vel.vz[j, i, k - 4]) +
                            b5 * (vel.vz[j, i, k + 4] - vel.vz[j, i, k - 5])) * oodz;
 
-                    g = mod->pi[j][i][k];
+                    g = mod.pi[j, i, k];
 
                     vxxyyzz = vxx + vyy + vzz;
 
@@ -266,7 +266,7 @@ double update_s_acoustic(st_boundary *nb, st_velocity &vel,
                            b5 * (vel.vz[j, i, k + 4] - vel.vz[j, i, k - 5]) +
                            b6 * (vel.vz[j, i, k + 5] - vel.vz[j, i, k - 6])) * oodz;
 
-                    g = mod->pi[j][i][k];
+                    g = mod.pi[j, i, k];
 
                     vxxyyzz = vxx + vyy + vzz;
 
diff --git a/src/update_s_ssg_elastic.cpp b/src/update_s_ssg_elastic.cpp
index 50810df..5b0ab21 100644
--- a/src/update_s_ssg_elastic.cpp
+++ b/src/update_s_ssg_elastic.cpp
@@ -29,7 +29,7 @@
 #define UNUSED(x) (void)(x)
 
 double update_s_elastic(st_boundary *nb, st_velocity &vel,
-                        st_stress &stress, st_model *mod, st_model_av &mod_av, const GlobVar *gv)
+                        st_stress &stress, st_model &mod, st_model_av &mod_av, const GlobVar *gv)
 {
     float vxx, vxy, vxz, vyx, vyy, vyz, vzx, vzy, vzz;
     float vxyyx, vyzzy, vxzzx, vxxyyzz, vyyzz, vxxzz, vxxyy;
@@ -65,13 +65,13 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                     vyy = (vel.vy[j, i, k] - vel.vy[j - 1, i, k]) * oody;
                     vzz = (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) * oodz;
                     stress.sxx[j, i, k] += gv->DT *
-                                           (mod->pi[j][i][k] * (vxx + vyy + vzz) - 2.0f * mod->u[j][i][k] *
+                                           (mod.pi[j, i, k] * (vxx + vyy + vzz) - 2.0f * mod.u[j, i, k] *
                                             (vyy + vzz));
                     stress.syy[j, i, k] += gv->DT *
-                                           (mod->pi[j][i][k] * (vxx + vyy + vzz) - 2.0f * mod->u[j][i][k] *
+                                           (mod.pi[j, i, k] * (vxx + vyy + vzz) - 2.0f * mod.u[j, i, k] *
                                             (vxx + vzz));
                     stress.szz[j, i, k] += gv->DT *
-                                           (mod->pi[j][i][k] * (vxx + vyy + vzz) - 2.0f * mod->u[j][i][k] *
+                                           (mod.pi[j, i, k] * (vxx + vyy + vzz) - 2.0f * mod.u[j, i, k] *
                                             (vxx + vyy));
                 }
             }
@@ -136,13 +136,13 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                         (b1 * (vel.vz[j, i, k] - vel.vz[j, i, k - 1]) +
                          b2 * (vel.vz[j, i, k + 1] - vel.vz[j, i, k - 2])) * oodz;
                     stress.sxx[j, i, k] += gv->DT *
-                                           (mod->pi[j][i][k] * (vxx + vyy + vzz) - 2.0f * mod->u[j][i][k] *
+                                           (mod.pi[j, i, k] * (vxx + vyy + vzz) - 2.0f * mod.u[j, i, k] *
                                             (vyy + vzz));
                     stress.syy[j, i, k] += gv->DT *
-                                           (mod->pi[j][i][k] * (vxx + vyy + vzz) - 2.0f * mod->u[j][i][k] *
+                                           (mod.pi[j, i, k] * (vxx + vyy + vzz) - 2.0f * mod.u[j, i, k] *
                                             (vxx + vzz));
                     stress.szz[j, i, k] += gv->DT *
-                                           (mod->pi[j][i][k] * (vxx + vyy + vzz) - 2.0f * mod->u[j][i][k] *
+                                           (mod.pi[j, i, k] * (vxx + vyy + vzz) - 2.0f * mod.u[j, i, k] *
                                             (vxx + vyy));
                 }
             }
@@ -207,8 +207,8 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                     fipjp = mod_av.uipjp[j, i, k] * gv->DT;
                     fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
                     fipkp = mod_av.uipkp[j, i, k] * gv->DT;
-                    g = mod->pi[j][i][k];
-                    f = 2.0f * mod->u[j][i][k];
+                    g = mod.pi[j, i, k];
+                    f = 2.0f * mod.u[j, i, k];
 
                     vxyyx = vxy + vyx;
                     vyzzy = vyz + vzy;
@@ -298,8 +298,8 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                     fipjp = mod_av.uipjp[j, i, k] * gv->DT;
                     fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
                     fipkp = mod_av.uipkp[j, i, k] * gv->DT;
-                    g = mod->pi[j][i][k];
-                    f = 2.0f * mod->u[j][i][k];
+                    g = mod.pi[j, i, k];
+                    f = 2.0f * mod.u[j, i, k];
 
                     vxyyx = vxy + vyx;
                     vyzzy = vyz + vzy;
@@ -399,8 +399,8 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                     fipjp = mod_av.uipjp[j, i, k] * gv->DT;
                     fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
                     fipkp = mod_av.uipkp[j, i, k] * gv->DT;
-                    g = mod->pi[j][i][k];
-                    f = 2.0f * mod->u[j][i][k];
+                    g = mod.pi[j, i, k];
+                    f = 2.0f * mod.u[j, i, k];
 
                     vxyyx = vxy + vyx;
                     vyzzy = vyz + vzy;
@@ -514,8 +514,8 @@ double update_s_elastic(st_boundary *nb, st_velocity &vel,
                     fipjp = mod_av.uipjp[j, i, k] * gv->DT;
                     fjpkp = mod_av.ujpkp[j, i, k] * gv->DT;
                     fipkp = mod_av.uipkp[j, i, k] * gv->DT;
-                    g = mod->pi[j][i][k];
-                    f = 2.0f * mod->u[j][i][k];
+                    g = mod.pi[j, i, k];
+                    f = 2.0f * mod.u[j, i, k];
 
                     vxyyx = vxy + vyx;
                     vyzzy = vyz + vzy;
diff --git a/src/update_v_ssg.cpp b/src/update_v_ssg.cpp
index 26ef017..b5037a1 100644
--- a/src/update_v_ssg.cpp
+++ b/src/update_v_ssg.cpp
@@ -26,7 +26,7 @@
 #include "loop_blocking.hpp"
 
 void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_model_av &mod_av,
-              float ***absorb_coeff, const GlobVar *gv)
+    float3DTensorT &absorb_coeff, const GlobVar *gv)
 {
     float b1, b2, b3, b4, b5, b6;
     float sxx_x, sxy_y, sxz_z, syy_y, sxy_x, syz_z;
@@ -404,15 +404,15 @@ void update_v(const st_boundary *nb, st_velocity &vel, st_stress &stress, st_mod
         for (int j = nb->ny1; j <= nb->ny2; j++) {
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    vel.vx[j, i, k] *= absorb_coeff[j][i][k];
-                    vel.vy[j, i, k] *= absorb_coeff[j][i][k];
-                    vel.vz[j, i, k] *= absorb_coeff[j][i][k];
-                    stress.sxy[j, i, k] *= absorb_coeff[j][i][k];
-                    stress.syz[j, i, k] *= absorb_coeff[j][i][k];
-                    stress.sxz[j, i, k] *= absorb_coeff[j][i][k];
-                    stress.sxx[j, i, k] *= absorb_coeff[j][i][k];
-                    stress.syy[j, i, k] *= absorb_coeff[j][i][k];
-                    stress.szz[j, i, k] *= absorb_coeff[j][i][k];
+                    vel.vx[j, i, k] *= absorb_coeff[j, i, k];
+                    vel.vy[j, i, k] *= absorb_coeff[j, i, k];
+                    vel.vz[j, i, k] *= absorb_coeff[j, i, k];
+                    stress.sxy[j, i, k] *= absorb_coeff[j, i, k];
+                    stress.syz[j, i, k] *= absorb_coeff[j, i, k];
+                    stress.sxz[j, i, k] *= absorb_coeff[j, i, k];
+                    stress.sxx[j, i, k] *= absorb_coeff[j, i, k];
+                    stress.syy[j, i, k] *= absorb_coeff[j, i, k];
+                    stress.szz[j, i, k] *= absorb_coeff[j, i, k];
                 }
             }
         }
diff --git a/src/update_v_ssg_acoustic.cpp b/src/update_v_ssg_acoustic.cpp
index 39ccb51..1162052 100644
--- a/src/update_v_ssg_acoustic.cpp
+++ b/src/update_v_ssg_acoustic.cpp
@@ -25,7 +25,7 @@
 #include "fd.hpp"
 
 void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress &stress,
-                       st_model_av &mod_av, float ***absorb_coeff, const GlobVar *gv)
+                       st_model_av &mod_av, float3DTensorT &absorb_coeff, const GlobVar *gv)
 {
     float b1, b2, b3, b4, b5, b6;
     float sp_x, sp_y, sp_z;
@@ -237,10 +237,10 @@ void update_v_acoustic(const st_boundary *nb, st_velocity &vel, st_stress &stres
             for (int i = nb->nx1; i <= nb->nx2; i++) {
                 #pragma omp simd
                 for (int k = nb->nz1; k <= nb->nz2; k++) {
-                    vel.vx[j, i, k] *= absorb_coeff[j][i][k];
-                    vel.vy[j, i, k] *= absorb_coeff[j][i][k];
-                    vel.vz[j, i, k] *= absorb_coeff[j][i][k];
-                    stress.sp[j, i, k] *= absorb_coeff[j][i][k];
+                    vel.vx[j, i, k] *= absorb_coeff[j, i, k];
+                    vel.vy[j, i, k] *= absorb_coeff[j, i, k];
+                    vel.vz[j, i, k] *= absorb_coeff[j, i, k];
+                    stress.sp[j, i, k] *= absorb_coeff[j, i, k];
                 }
             }
         }
-- 
GitLab


From fa8d102d6257cea66333391ebd41b85f56ea510c Mon Sep 17 00:00:00 2001
From: Holger Obermaier <holgerob@gmx.de>
Date: Thu, 10 Apr 2025 20:36:37 +0200
Subject: [PATCH 10/15] float3DTensorT implementation based on mdspan

---
 src/float3DTensorT.cpp |  86 ++++++++++++++--------
 src/float3DTensorT.hpp | 163 +++++++++++++++++++++++++++++++++++++++++
 src/scan_topo.cpp      |   1 -
 3 files changed, 217 insertions(+), 33 deletions(-)

diff --git a/src/float3DTensorT.cpp b/src/float3DTensorT.cpp
index 2f8d59b..8b1510c 100644
--- a/src/float3DTensorT.cpp
+++ b/src/float3DTensorT.cpp
@@ -4,6 +4,7 @@
 #include <cstdlib>
 #include <iostream>
 
+#ifdef FLOAT3D_TENSOR_USE_ARRAY
 void float3DTensorT::init()
 {
     _lb_i = 0;
@@ -83,52 +84,73 @@ void float3DTensorT::free()
     std::free(data);
     float3DTensorT::init();
 }
+#endif
 
-constexpr int float3DTensorT::lb_i() noexcept
-{
-    return _lb_i;
-}
-
-constexpr int float3DTensorT::ub_i() noexcept
+#ifdef FLOAT3D_TENSOR_USE_MDSPAN
+void float3DTensorT::init()
 {
-    return _ub_i;
-}
+    _lb_i = 0;
+    _ub_i = 0;
+    _lb_j = 0;
+    _ub_j = 0;
+    _lb_k = 0;
+    _ub_k = 0;
 
-constexpr int float3DTensorT::lb_j() noexcept
-{
-    return _lb_j;
+    ms = std::mdspan<float, std::dextents<size_t, 3>>{};
 }
 
-constexpr int float3DTensorT::ub_j() noexcept
+float3DTensorT::float3DTensorT()
 {
-    return _ub_j;
-}
+    float3DTensorT::init();
+};
 
-constexpr int float3DTensorT::lb_k() noexcept
-{
-    return _lb_k;
-}
-constexpr int float3DTensorT::ub_k() noexcept
+float3DTensorT::float3DTensorT(
+    const int &lb_i, const int &ub_i,
+    const int &lb_j, const int &ub_j,
+    const int &lb_k, const int &ub_k)
 {
-    return _ub_k;
-}
+    float3DTensorT::malloc(lb_i, ub_i, lb_j, ub_j, lb_k, ub_k);
+};
 
-constexpr size_t float3DTensorT::dim_i() noexcept
+float3DTensorT::~float3DTensorT()
 {
-    return _dim_i;
+    assert(ms.size() == 0);
 }
 
-constexpr size_t float3DTensorT::dim_j() noexcept
+void float3DTensorT::malloc(
+    const int &lb_i, const int &ub_i,
+    const int &lb_j, const int &ub_j,
+    const int &lb_k, const int &ub_k)
 {
-    return _dim_j;
-}
+    assert(lb_i <= ub_i);
+    _lb_i = lb_i;
+    _ub_i = ub_i;
+    assert(lb_j <= ub_j);
+    _lb_j = lb_j;
+    _ub_j = ub_j;
+    assert(lb_k <= ub_k);
+    _lb_k = lb_k;
+    _ub_k = ub_k;
 
-constexpr size_t float3DTensorT::dim_k() noexcept
-{
-    return _dim_k;
-}
+    const size_t dim_i = ub_i - lb_i + 1;
+    const size_t dim_j = ub_j - lb_j + 1;
+    const size_t dim_k = ub_k - lb_k + 1;
+    const size_t size = dim_i * dim_j * dim_k;
+    float *data = (float *)std::malloc(size * sizeof(float));
+    if (data == NULL) {
+        std::cerr << "Failed to allocate memory" << std::endl;
+        exit(EXIT_FAILURE);
+    }
+    #pragma omp simd
+    for (size_t i = 0; i < size; i++) {
+        data[i] = 0.0f;
+    }
+    ms = std::mdspan(data, dim_i, dim_j, dim_k);
+};
 
-constexpr size_t float3DTensorT::size() noexcept
+void float3DTensorT::free()
 {
-    return _size;
+    std::free(ms.data_handle());
+    float3DTensorT::init();
 }
+#endif
\ No newline at end of file
diff --git a/src/float3DTensorT.hpp b/src/float3DTensorT.hpp
index 7e96f5f..b8544b4 100644
--- a/src/float3DTensorT.hpp
+++ b/src/float3DTensorT.hpp
@@ -4,6 +4,11 @@
 #include <cassert>
 #include <cstddef>
 
+#if !defined(FLOAT3D_TENSOR_USE_ARRAY) && !defined(FLOAT3D_TENSOR_USE_MDSPAN)
+    #define FLOAT3D_TENSOR_USE_ARRAY
+#endif
+
+#ifdef FLOAT3D_TENSOR_USE_ARRAY
 struct float3DTensorT {
 private:
     int    _lb_i, _ub_i,
@@ -65,4 +70,162 @@ constexpr const float &float3DTensorT::operator[](const int &i, const int &j, co
     return data[index];
 }
 
+constexpr int float3DTensorT::lb_i() noexcept
+{
+    return _lb_i;
+}
+
+constexpr int float3DTensorT::ub_i() noexcept
+{
+    return _ub_i;
+}
+
+constexpr int float3DTensorT::lb_j() noexcept
+{
+    return _lb_j;
+}
+
+constexpr int float3DTensorT::ub_j() noexcept
+{
+    return _ub_j;
+}
+
+constexpr int float3DTensorT::lb_k() noexcept
+{
+    return _lb_k;
+}
+constexpr int float3DTensorT::ub_k() noexcept
+{
+    return _ub_k;
+}
+
+constexpr size_t float3DTensorT::dim_i() noexcept
+{
+    return _dim_i;
+}
+
+constexpr size_t float3DTensorT::dim_j() noexcept
+{
+    return _dim_j;
+}
+
+constexpr size_t float3DTensorT::dim_k() noexcept
+{
+    return _dim_k;
+}
+
+constexpr size_t float3DTensorT::size() noexcept
+{
+    return _size;
+}
+#endif
+
+#ifdef FLOAT3D_TENSOR_USE_MDSPAN
+#include <mdspan>
+
+struct float3DTensorT {
+private:
+    int    _lb_i, _ub_i,
+           _lb_j, _ub_j,
+           _lb_k, _ub_k;
+    std::mdspan<float, std::dextents<size_t, 3>> ms;
+    void init();
+
+public:
+    float3DTensorT();
+    float3DTensorT(const int &lb_i, const int &ub_i,
+                   const int &lb_j, const int &ub_j,
+                   const int &lb_k, const int &ub_k);
+
+    ~float3DTensorT();
+    void malloc(const int &lb_i, const int &ub_i,
+                const int &lb_j, const int &ub_j,
+                const int &lb_k, const int &ub_k);
+    void free();
+
+    constexpr float &operator[](const int &i, const int &j, const int &k) noexcept;
+    constexpr const float &operator[](const int &i, const int &j, const int &k) const noexcept;
+
+    constexpr int lb_i() noexcept;
+    constexpr int ub_i() noexcept;
+    constexpr int lb_j() noexcept;
+    constexpr int ub_j() noexcept;
+    constexpr int lb_k() noexcept;
+    constexpr int ub_k() noexcept;
+
+    constexpr size_t dim_i() noexcept;
+    constexpr size_t dim_j() noexcept;
+    constexpr size_t dim_k() noexcept;
+
+    constexpr size_t size() noexcept;
+};
+
+// https://en.cppreference.com/w/cpp/language/operators#Array_subscript_operator
+constexpr float &float3DTensorT::operator[](const int &i, const int &j, const int &k) noexcept
+{
+    assert(_lb_i <= i and i <= _ub_i);
+    assert(_lb_j <= j and j <= _ub_j);
+    assert(_lb_k <= k and k <= _ub_k);
+    return ms[i - _lb_i, j - _lb_j, k - _lb_k];
+}
+
+// https://en.cppreference.com/w/cpp/language/operators#Array_subscript_operator
+constexpr const float &float3DTensorT::operator[](const int &i, const int &j, const int &k) const noexcept
+{
+    assert(_lb_i <= i and i <= _ub_i);
+    assert(_lb_j <= j and j <= _ub_j);
+    assert(_lb_k <= k and k <= _ub_k);
+    return ms[i - _lb_i, j - _lb_j, k - _lb_k];
+}
+
+constexpr int float3DTensorT::lb_i() noexcept
+{
+    return _lb_i;
+}
+
+constexpr int float3DTensorT::ub_i() noexcept
+{
+    return _ub_i;
+}
+
+constexpr int float3DTensorT::lb_j() noexcept
+{
+    return _lb_j;
+}
+
+constexpr int float3DTensorT::ub_j() noexcept
+{
+    return _ub_j;
+}
+
+constexpr int float3DTensorT::lb_k() noexcept
+{
+    return _lb_k;
+}
+constexpr int float3DTensorT::ub_k() noexcept
+{
+    return _ub_k;
+}
+
+constexpr size_t float3DTensorT::dim_i() noexcept
+{
+    return ms.extent(0);
+}
+
+constexpr size_t float3DTensorT::dim_j() noexcept
+{
+    return ms.extent(1);
+}
+
+constexpr size_t float3DTensorT::dim_k() noexcept
+{
+    return ms.extent(2);
+}
+
+constexpr size_t float3DTensorT::size() noexcept
+{
+    return ms.size();
+}
 #endif
+
+#endif
\ No newline at end of file
diff --git a/src/scan_topo.cpp b/src/scan_topo.cpp
index 2aa7ca4..9391490 100644
--- a/src/scan_topo.cpp
+++ b/src/scan_topo.cpp
@@ -28,7 +28,6 @@
 #include "util.hpp"
 #include <unistd.h>
 #include <cstdbool>
-#include <cfloat>
 
 int **scan_topo(GlobVar *gv)
 {
-- 
GitLab


From 904d1248fb0f75c914acb90596c95af418c867cb Mon Sep 17 00:00:00 2001
From: Holger Obermaier <holgerob@gmx.de>
Date: Mon, 14 Apr 2025 14:22:51 +0200
Subject: [PATCH 11/15] Align memory allocation to 64 bytes

---
 src/float3DTensorT.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/float3DTensorT.cpp b/src/float3DTensorT.cpp
index 8b1510c..98dd6d5 100644
--- a/src/float3DTensorT.cpp
+++ b/src/float3DTensorT.cpp
@@ -3,6 +3,7 @@
 #include <cstddef>
 #include <cstdlib>
 #include <iostream>
+#include <memory> // assume_aligned
 
 #ifdef FLOAT3D_TENSOR_USE_ARRAY
 void float3DTensorT::init()
@@ -64,7 +65,7 @@ void float3DTensorT::malloc(
     _dim_j = ub_j - lb_j + 1;
     _dim_k = ub_k - lb_k + 1;
     _size = _dim_i * _dim_j * _dim_k;
-    data = (float *)std::malloc(_size * sizeof(float));
+    data = std::assume_aligned<64>((float *) aligned_alloc(64, _size * sizeof(float)));
     if (data == NULL) {
         std::cerr << "Failed to allocate memory" << std::endl;
         exit(EXIT_FAILURE);
@@ -75,8 +76,8 @@ void float3DTensorT::malloc(
     }
     _stride_i = _dim_j * _dim_k;
     _stride_j = _dim_k;
-    _stride_k = 0;
-    offset = lb_i * _stride_i + lb_j * _stride_j + lb_k;
+    _stride_k = 1;
+    offset = lb_i * _stride_i + lb_j * _stride_j + lb_k * _stride_k;
 };
 
 void float3DTensorT::free()
-- 
GitLab


From dd7b60c560bc7d22c5f3189b2d8e9d503acf20a0 Mon Sep 17 00:00:00 2001
From: Holger Obermaier <holgerob@gmx.de>
Date: Mon, 14 Apr 2025 15:08:21 +0200
Subject: [PATCH 12/15] Check if feature std::assume_aligned is available

---
 src/float3DTensorT.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/float3DTensorT.cpp b/src/float3DTensorT.cpp
index 98dd6d5..1f1af4f 100644
--- a/src/float3DTensorT.cpp
+++ b/src/float3DTensorT.cpp
@@ -65,7 +65,11 @@ void float3DTensorT::malloc(
     _dim_j = ub_j - lb_j + 1;
     _dim_k = ub_k - lb_k + 1;
     _size = _dim_i * _dim_j * _dim_k;
+    #if __cpp_lib_assume_aligned
     data = std::assume_aligned<64>((float *) aligned_alloc(64, _size * sizeof(float)));
+    #else
+    data = (float *) aligned_alloc(64, _size * sizeof(float));
+    #endif
     if (data == NULL) {
         std::cerr << "Failed to allocate memory" << std::endl;
         exit(EXIT_FAILURE);
-- 
GitLab


From 6a8f9e596ef3f8f80ba1ab760ef1322563c1f8eb Mon Sep 17 00:00:00 2001
From: Holger Obermaier <holgerob@gmx.de>
Date: Tue, 15 Apr 2025 13:21:02 +0200
Subject: [PATCH 13/15] Do aligned memory allocation in mdspan implementation
 of float3DTensorT

---
 src/float3DTensorT.cpp | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/src/float3DTensorT.cpp b/src/float3DTensorT.cpp
index 1f1af4f..7d818d3 100644
--- a/src/float3DTensorT.cpp
+++ b/src/float3DTensorT.cpp
@@ -65,15 +65,16 @@ void float3DTensorT::malloc(
     _dim_j = ub_j - lb_j + 1;
     _dim_k = ub_k - lb_k + 1;
     _size = _dim_i * _dim_j * _dim_k;
-    #if __cpp_lib_assume_aligned
-    data = std::assume_aligned<64>((float *) aligned_alloc(64, _size * sizeof(float)));
-    #else
     data = (float *) aligned_alloc(64, _size * sizeof(float));
-    #endif
     if (data == NULL) {
         std::cerr << "Failed to allocate memory" << std::endl;
         exit(EXIT_FAILURE);
     }
+    #if __cpp_lib_assume_aligned
+    data = std::assume_aligned<64>(data);
+    #else
+        #warning "std::assume_aligned not supported"
+    #endif
     #pragma omp simd
     for (size_t i = 0; i < _size; i++) {
         data[i] = 0.0f;
@@ -141,11 +142,16 @@ void float3DTensorT::malloc(
     const size_t dim_j = ub_j - lb_j + 1;
     const size_t dim_k = ub_k - lb_k + 1;
     const size_t size = dim_i * dim_j * dim_k;
-    float *data = (float *)std::malloc(size * sizeof(float));
+    float *data = (float *) aligned_alloc(64, size * sizeof(float));
     if (data == NULL) {
         std::cerr << "Failed to allocate memory" << std::endl;
         exit(EXIT_FAILURE);
     }
+    #if __cpp_lib_assume_aligned
+    data = std::assume_aligned<64>(data);
+    #else
+        #warning "std::assume_aligned not supported"
+    #endif
     #pragma omp simd
     for (size_t i = 0; i < size; i++) {
         data[i] = 0.0f;
-- 
GitLab


From 1edb2450c2b6ec529686bd931ad67d7fecd7857c Mon Sep 17 00:00:00 2001
From: Holger Obermaier <holgerob@gmx.de>
Date: Tue, 15 Apr 2025 13:59:44 +0200
Subject: [PATCH 14/15] Link with c++ compiler

---
 build/Makefile | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/build/Makefile b/build/Makefile
index 6176be7..897e579 100644
--- a/build/Makefile
+++ b/build/Makefile
@@ -346,6 +346,7 @@ help:
 	@echo "   CXX: $(CXX)"
 	@echo "   CPPFLAGS: $(CPPFLAGS) [$(EXTRA_CPPFLAGS)]"
 	@echo "   CFLAGS: $(CFLAGS)"
+	@echo "   CXXFLAGS: $(CXXFLAGS)"
 	@echo "   LD: $(LD)"
 	@echo "   LDFLAGS: $(LDFLAGS) [$(EXTRA_LDFLAGS)]"
 	@echo 
@@ -445,7 +446,7 @@ quiet_cmd_compile_cxx = \e[32m[CC]\e[0m    $@
       cmd_compile_cxx = $(CXX) -o$@ $(CDEPEND) $(CXXFLAGS.$@) $(CPPFLAGS) -I$(SRCTREE) $(CXXFLAGS) -c $<
 
 quiet_cmd_link = \e[94m[LD]\e[0m    $@
-      cmd_link = $(LD) $(CFLAGS) -o$@ $^ $(LDFLAGS.$@) $(LDFLAGS)
+      cmd_link = $(LD) $(CXXFLAGS) -o$@ $^ $(LDFLAGS.$@) $(LDFLAGS)
 
 quiet_cmd_ar = \e[32m[AR]\e[0m    $@
       cmd_ar = $(AR) $(ARFLAGS) $@ $^ && ranlib $@
-- 
GitLab


From c5c6fcaa21a8199d75e2ac517b85cd3b85c399bf Mon Sep 17 00:00:00 2001
From: Holger Obermaier <holgerob@gmx.de>
Date: Wed, 16 Apr 2025 19:49:26 +0200
Subject: [PATCH 15/15] Make float3DTensorT interface more mdspan-like

---
 src/float3DTensorT.cpp |  97 +++++++-------
 src/float3DTensorT.hpp | 298 ++++++++++++++++-------------------------
 2 files changed, 164 insertions(+), 231 deletions(-)

diff --git a/src/float3DTensorT.cpp b/src/float3DTensorT.cpp
index 7d818d3..3d797cd 100644
--- a/src/float3DTensorT.cpp
+++ b/src/float3DTensorT.cpp
@@ -8,21 +8,14 @@
 #ifdef FLOAT3D_TENSOR_USE_ARRAY
 void float3DTensorT::init()
 {
-    _lb_i = 0;
-    _ub_i = 0;
-    _lb_j = 0;
-    _ub_j = 0;
-    _lb_k = 0;
-    _ub_k = 0;
-
-    _dim_i = 0;
-    _dim_j = 0;
-    _dim_k = 0;
-    _size = 0;
+    for (int i = 0; i < rank(); i++) {
+        _lb[i] = 0;
+        _ub[i] = 0;
+        _extent[i] = 0;
+        _stride[i] = 0;
+    }
 
-    _stride_i = 0;
-    _stride_j = 0;
-    _stride_k = 0;
+    _size = 0;
     offset = 0;
 
     data = NULL;
@@ -30,7 +23,7 @@ void float3DTensorT::init()
 
 float3DTensorT::float3DTensorT()
 {
-    float3DTensorT::init();
+    init();
 };
 
 float3DTensorT::float3DTensorT(
@@ -38,7 +31,7 @@ float3DTensorT::float3DTensorT(
     const int &lb_j, const int &ub_j,
     const int &lb_k, const int &ub_k)
 {
-    float3DTensorT::malloc(lb_i, ub_i, lb_j, ub_j, lb_k, ub_k);
+    malloc(lb_i, ub_i, lb_j, ub_j, lb_k, ub_k);
 };
 
 float3DTensorT::~float3DTensorT()
@@ -52,20 +45,20 @@ void float3DTensorT::malloc(
     const int &lb_k, const int &ub_k)
 {
     assert(lb_i <= ub_i);
-    _lb_i = lb_i;
-    _ub_i = ub_i;
+    _lb[0] = lb_i;
+    _ub[0] = ub_i;
     assert(lb_j <= ub_j);
-    _lb_j = lb_j;
-    _ub_j = ub_j;
+    _lb[1] = lb_j;
+    _ub[1] = ub_j;
     assert(lb_k <= ub_k);
-    _lb_k = lb_k;
-    _ub_k = ub_k;
-
-    _dim_i = ub_i - lb_i + 1;
-    _dim_j = ub_j - lb_j + 1;
-    _dim_k = ub_k - lb_k + 1;
-    _size = _dim_i * _dim_j * _dim_k;
-    data = (float *) aligned_alloc(64, _size * sizeof(float));
+    _lb[2] = lb_k;
+    _ub[2] = ub_k;
+
+    _extent[0] = ub_i - lb_i + 1;
+    _extent[1] = ub_j - lb_j + 1;
+    _extent[2] = ub_k - lb_k + 1;
+    _size = _extent[0] * _extent[1] * _extent[2];
+    data = (float *)aligned_alloc(64, _size * sizeof(float));
     if (data == NULL) {
         std::cerr << "Failed to allocate memory" << std::endl;
         exit(EXIT_FAILURE);
@@ -79,35 +72,35 @@ void float3DTensorT::malloc(
     for (size_t i = 0; i < _size; i++) {
         data[i] = 0.0f;
     }
-    _stride_i = _dim_j * _dim_k;
-    _stride_j = _dim_k;
-    _stride_k = 1;
-    offset = lb_i * _stride_i + lb_j * _stride_j + lb_k * _stride_k;
+    _stride[0] = _extent[1] * _extent[2];
+    _stride[1] = _extent[2];
+    _stride[2] = 1;
+    offset = lb_i * _stride[0] + lb_j * _stride[1] + lb_k * _stride[2];
 };
 
 void float3DTensorT::free()
 {
     std::free(data);
-    float3DTensorT::init();
+    init();
 }
 #endif
 
 #ifdef FLOAT3D_TENSOR_USE_MDSPAN
 void float3DTensorT::init()
 {
-    _lb_i = 0;
-    _ub_i = 0;
-    _lb_j = 0;
-    _ub_j = 0;
-    _lb_k = 0;
-    _ub_k = 0;
-
-    ms = std::mdspan<float, std::dextents<size_t, 3>>{};
+    _lb[0] = 0;
+    _ub[0] = 0;
+    _lb[1] = 0;
+    _ub[1] = 0;
+    _lb[2] = 0;
+    _ub[2] = 0;
+
+    ms = std::mdspan<float, std::dextents<size_t, 3> >{};
 }
 
 float3DTensorT::float3DTensorT()
 {
-    float3DTensorT::init();
+    init();
 };
 
 float3DTensorT::float3DTensorT(
@@ -115,7 +108,7 @@ float3DTensorT::float3DTensorT(
     const int &lb_j, const int &ub_j,
     const int &lb_k, const int &ub_k)
 {
-    float3DTensorT::malloc(lb_i, ub_i, lb_j, ub_j, lb_k, ub_k);
+    malloc(lb_i, ub_i, lb_j, ub_j, lb_k, ub_k);
 };
 
 float3DTensorT::~float3DTensorT()
@@ -129,20 +122,20 @@ void float3DTensorT::malloc(
     const int &lb_k, const int &ub_k)
 {
     assert(lb_i <= ub_i);
-    _lb_i = lb_i;
-    _ub_i = ub_i;
+    _lb[0] = lb_i;
+    _ub[0] = ub_i;
     assert(lb_j <= ub_j);
-    _lb_j = lb_j;
-    _ub_j = ub_j;
+    _lb[1] = lb_j;
+    _ub[1] = ub_j;
     assert(lb_k <= ub_k);
-    _lb_k = lb_k;
-    _ub_k = ub_k;
+    _lb[2] = lb_k;
+    _ub[2] = ub_k;
 
     const size_t dim_i = ub_i - lb_i + 1;
     const size_t dim_j = ub_j - lb_j + 1;
     const size_t dim_k = ub_k - lb_k + 1;
     const size_t size = dim_i * dim_j * dim_k;
-    float *data = (float *) aligned_alloc(64, size * sizeof(float));
+    float *data = (float *)aligned_alloc(64, size * sizeof(float));
     if (data == NULL) {
         std::cerr << "Failed to allocate memory" << std::endl;
         exit(EXIT_FAILURE);
@@ -162,6 +155,6 @@ void float3DTensorT::malloc(
 void float3DTensorT::free()
 {
     std::free(ms.data_handle());
-    float3DTensorT::init();
+    init();
 }
-#endif
\ No newline at end of file
+#endif
diff --git a/src/float3DTensorT.hpp b/src/float3DTensorT.hpp
index b8544b4..028f1e5 100644
--- a/src/float3DTensorT.hpp
+++ b/src/float3DTensorT.hpp
@@ -11,11 +11,8 @@
 #ifdef FLOAT3D_TENSOR_USE_ARRAY
 struct float3DTensorT {
 private:
-    int    _lb_i, _ub_i,
-           _lb_j, _ub_j,
-           _lb_k, _ub_k;
-    size_t _dim_i, _dim_j, _dim_k, _size,
-           _stride_i, _stride_j, _stride_k, offset;
+    int    _lb[3], _ub[3];
+    size_t _extent[3], _stride[3], _size, offset;
     float *data;
     void init();
 
@@ -31,104 +28,75 @@ public:
                 const int &lb_k, const int &ub_k);
     void free();
 
-    constexpr float &operator[](const int &i, const int &j, const int &k) noexcept;
-    constexpr const float &operator[](const int &i, const int &j, const int &k) const noexcept;
-
-    constexpr int lb_i() noexcept;
-    constexpr int ub_i() noexcept;
-    constexpr int lb_j() noexcept;
-    constexpr int ub_j() noexcept;
-    constexpr int lb_k() noexcept;
-    constexpr int ub_k() noexcept;
-
-    constexpr size_t dim_i() noexcept;
-    constexpr size_t dim_j() noexcept;
-    constexpr size_t dim_k() noexcept;
-
-    constexpr size_t size() noexcept;
+    // https://en.cppreference.com/w/cpp/language/operators#Array_subscript_operator
+    constexpr float &operator[](const int &i, const int &j, const int &k) noexcept
+    {
+        assert(_lb[0] <= i and i <= _ub[0]);
+        assert(_lb[1] <= j and j <= _ub[1]);
+        assert(_lb[2] <= k and k <= _ub[2]);
+        const size_t index = i * _stride[0] + j * _stride[1] + k - offset;
+        assert(index < _size);
+        return data[index];
+    }
+
+    // https://en.cppreference.com/w/cpp/language/operators#Array_subscript_operator
+    constexpr const float &operator[](const int &i, const int &j, const int &k) const noexcept
+    {
+        assert(_lb[0] <= i and i <= _ub[0]);
+        assert(_lb[1] <= j and j <= _ub[1]);
+        assert(_lb[2] <= k and k <= _ub[2]);
+        const size_t index = i * _stride[0] + j * _stride[1] + k - offset;
+        assert(index < _size);
+        return data[index];
+    }
+
+    constexpr int rank() noexcept
+    {
+        return 3;
+    };
+
+    // lower bound for extend in i-th dimension
+    constexpr int lower_bound(const int i) noexcept
+    {
+        assert(0 <= i and i < rank());
+        return _lb[i];
+    };
+
+    // upper bound for extend in i-th dimension
+    constexpr int uper_bound(const int i) noexcept
+    {
+        assert(0 <= i and i < rank());
+        return _ub[i];
+    };
+
+    // size of extend in i-th dimension
+    constexpr size_t extent(const int i) noexcept
+    {
+        assert(0 <= i and i < rank());
+        return _extent[i];
+    };
+
+    // size of stride in i-th dimension
+    constexpr size_t stride(const int i) noexcept
+    {
+        assert(0 <= i and i < rank());
+        return _stride[i];
+    };
+
+    constexpr size_t size() noexcept
+    {
+        return _size;
+    }
 };
-
-// https://en.cppreference.com/w/cpp/language/operators#Array_subscript_operator
-constexpr float &float3DTensorT::operator[](const int &i, const int &j, const int &k) noexcept
-{
-    assert(_lb_i <= i and i <= _ub_i);
-    assert(_lb_j <= j and j <= _ub_j);
-    assert(_lb_k <= k and k <= _ub_k);
-    const size_t index = i * _stride_i + j * _stride_j + k - offset;
-    assert(index < _size);
-    return data[index];
-}
-
-// https://en.cppreference.com/w/cpp/language/operators#Array_subscript_operator
-constexpr const float &float3DTensorT::operator[](const int &i, const int &j, const int &k) const noexcept
-{
-    assert(_lb_i <= i and i <= _ub_i);
-    assert(_lb_j <= j and j <= _ub_j);
-    assert(_lb_k <= k and k <= _ub_k);
-    const size_t index = i * _stride_i + j * _stride_j + k - offset;
-    assert(index < _size);
-    return data[index];
-}
-
-constexpr int float3DTensorT::lb_i() noexcept
-{
-    return _lb_i;
-}
-
-constexpr int float3DTensorT::ub_i() noexcept
-{
-    return _ub_i;
-}
-
-constexpr int float3DTensorT::lb_j() noexcept
-{
-    return _lb_j;
-}
-
-constexpr int float3DTensorT::ub_j() noexcept
-{
-    return _ub_j;
-}
-
-constexpr int float3DTensorT::lb_k() noexcept
-{
-    return _lb_k;
-}
-constexpr int float3DTensorT::ub_k() noexcept
-{
-    return _ub_k;
-}
-
-constexpr size_t float3DTensorT::dim_i() noexcept
-{
-    return _dim_i;
-}
-
-constexpr size_t float3DTensorT::dim_j() noexcept
-{
-    return _dim_j;
-}
-
-constexpr size_t float3DTensorT::dim_k() noexcept
-{
-    return _dim_k;
-}
-
-constexpr size_t float3DTensorT::size() noexcept
-{
-    return _size;
-}
 #endif
 
 #ifdef FLOAT3D_TENSOR_USE_MDSPAN
-#include <mdspan>
+    #include <mdspan>
 
 struct float3DTensorT {
 private:
-    int    _lb_i, _ub_i,
-           _lb_j, _ub_j,
-           _lb_k, _ub_k;
-    std::mdspan<float, std::dextents<size_t, 3>> ms;
+    int                                           _lb[3], _ub[3];
+    std::mdspan<float, std::dextents<size_t, 3> > ms;
     void init();
 
 public:
@@ -143,89 +111,61 @@ public:
                 const int &lb_k, const int &ub_k);
     void free();
 
-    constexpr float &operator[](const int &i, const int &j, const int &k) noexcept;
-    constexpr const float &operator[](const int &i, const int &j, const int &k) const noexcept;
-
-    constexpr int lb_i() noexcept;
-    constexpr int ub_i() noexcept;
-    constexpr int lb_j() noexcept;
-    constexpr int ub_j() noexcept;
-    constexpr int lb_k() noexcept;
-    constexpr int ub_k() noexcept;
-
-    constexpr size_t dim_i() noexcept;
-    constexpr size_t dim_j() noexcept;
-    constexpr size_t dim_k() noexcept;
-
-    constexpr size_t size() noexcept;
+    // https://en.cppreference.com/w/cpp/language/operators#Array_subscript_operator
+    constexpr float &operator[](const int &i, const int &j, const int &k) noexcept
+    {
+        assert(_lb[0] <= i and i <= _ub[0]);
+        assert(_lb[1] <= j and j <= _ub[1]);
+        assert(_lb[2] <= k and k <= _ub[2]);
+        return ms[i - _lb[0], j - _lb[1], k - _lb[2]];
+    }
+
+    // https://en.cppreference.com/w/cpp/language/operators#Array_subscript_operator
+    constexpr const float &operator[](const int &i, const int &j, const int &k) const noexcept
+    {
+        assert(_lb[0] <= i and i <= _ub[0]);
+        assert(_lb[1] <= j and j <= _ub[1]);
+        assert(_lb[2] <= k and k <= _ub[2]);
+        return ms[i - _lb[0], j - _lb[1], k - _lb[2]];
+    }
+    constexpr int rank() noexcept
+    {
+        return ms.rank();
+    };
+
+    // lower bound for extend in i-th dimension
+    constexpr int lower_bound(const int i) noexcept
+    {
+        assert(0 <= i and i < rank());
+        return _lb[i];
+    };
+
+    // upper bound for extend in i-th dimension
+    constexpr int uper_bound(const int i) noexcept
+    {
+        assert(0 <= i and i < rank());
+        return _ub[i];
+    };
+
+    // size of extend in i-th dimension
+    constexpr int extent(const int i) noexcept
+    {
+        assert(0 <= i and i < rank());
+        return ms.extent(i);
+    }
+
+    // size of stride in i-th dimension
+    constexpr size_t stride(const int i) noexcept
+    {
+        assert(0 <= i and i < rank());
+        return ms.stride(i);
+    };
+
+    constexpr size_t size() noexcept
+    {
+        return ms.size();
+    };
 };
-
-// https://en.cppreference.com/w/cpp/language/operators#Array_subscript_operator
-constexpr float &float3DTensorT::operator[](const int &i, const int &j, const int &k) noexcept
-{
-    assert(_lb_i <= i and i <= _ub_i);
-    assert(_lb_j <= j and j <= _ub_j);
-    assert(_lb_k <= k and k <= _ub_k);
-    return ms[i - _lb_i, j - _lb_j, k - _lb_k];
-}
-
-// https://en.cppreference.com/w/cpp/language/operators#Array_subscript_operator
-constexpr const float &float3DTensorT::operator[](const int &i, const int &j, const int &k) const noexcept
-{
-    assert(_lb_i <= i and i <= _ub_i);
-    assert(_lb_j <= j and j <= _ub_j);
-    assert(_lb_k <= k and k <= _ub_k);
-    return ms[i - _lb_i, j - _lb_j, k - _lb_k];
-}
-
-constexpr int float3DTensorT::lb_i() noexcept
-{
-    return _lb_i;
-}
-
-constexpr int float3DTensorT::ub_i() noexcept
-{
-    return _ub_i;
-}
-
-constexpr int float3DTensorT::lb_j() noexcept
-{
-    return _lb_j;
-}
-
-constexpr int float3DTensorT::ub_j() noexcept
-{
-    return _ub_j;
-}
-
-constexpr int float3DTensorT::lb_k() noexcept
-{
-    return _lb_k;
-}
-constexpr int float3DTensorT::ub_k() noexcept
-{
-    return _ub_k;
-}
-
-constexpr size_t float3DTensorT::dim_i() noexcept
-{
-    return ms.extent(0);
-}
-
-constexpr size_t float3DTensorT::dim_j() noexcept
-{
-    return ms.extent(1);
-}
-
-constexpr size_t float3DTensorT::dim_k() noexcept
-{
-    return ms.extent(2);
-}
-
-constexpr size_t float3DTensorT::size() noexcept
-{
-    return ms.size();
-}
 #endif
 
-#endif
\ No newline at end of file
+#endif
-- 
GitLab