def _rebuild_operators(self):

        dof = self.mesh.dof(include_bc=True)

        # a more readable reference
        oc = self.operator_components

        built = oc.get('_numpy_components_built', False)

        # build the static components
        if not built:
            # build laplacian
            oc.L = build_derivative_matrix(self.mesh, 2,
                                           self.spatial_accuracy_order)

            # build sigmax
            sx = build_sigma(self.mesh, self.mesh.x)
            oc.minus_sigmax = make_diag_mtx(-sx)

            # build sigmaz
            sz = build_sigma(self.mesh, self.mesh.z)
            oc.minus_sigmaz = make_diag_mtx(-sz)

            # build Dx
            oc.Dx = build_derivative_matrix(self.mesh,
                                            1,
                                            self.spatial_accuracy_order,
                                            dimension='x')

            # build Dz
            oc.Dz = build_derivative_matrix(self.mesh,
                                            1,
                                            self.spatial_accuracy_order,
                                            dimension='z')

            # build other useful things
            oc.I = spsp.eye(dof, dof)
            oc.empty = spsp.csr_matrix((dof, dof))

            # useful intermediates
            oc.sigma_xz = make_diag_mtx(sx * sz)
            oc.minus_sigma_xPz = oc.minus_sigmax + oc.minus_sigmaz
            oc.sigma_zMx_Dx = make_diag_mtx(sz - sx) * oc.Dx
            oc.sigma_xMz_Dz = make_diag_mtx(sx - sz) * oc.Dz

            oc._numpy_components_built = True

        C = self.model_parameters.C
        oc.m_inv = make_diag_mtx((C**2).reshape(-1, ))

        self.A = spsp.bmat(
            [[oc.empty, oc.I, oc.empty, oc.empty],
             [
                 oc.m_inv * oc.L - oc.sigma_xz, oc.minus_sigma_xPz,
                 oc.m_inv * oc.Dx, oc.m_inv * oc.Dz
             ], [oc.sigma_zMx_Dx, oc.empty, oc.minus_sigmax, oc.empty],
             [oc.sigma_xMz_Dz, oc.empty, oc.empty, oc.minus_sigmaz]])
    def _rebuild_operators(self):

        dof = self.mesh.dof(include_bc=True)

        # a more readable reference
        oc = self.operator_components

        built = oc.get('_numpy_components_built', False)

        # build the static components
        if not built:
            # build laplacian
            oc.L = build_derivative_matrix(self.mesh,
                                           2,
                                           self.spatial_accuracy_order)

            # build sigmax
            sx = build_sigma(self.mesh, self.mesh.x)
            oc.minus_sigmax = make_diag_mtx(-sx)

            # build sigmaz
            sz = build_sigma(self.mesh, self.mesh.z)
            oc.minus_sigmaz = make_diag_mtx(-sz)

            # build Dx
            oc.Dx = build_derivative_matrix(self.mesh,
                                            1,
                                            self.spatial_accuracy_order,
                                            dimension='x')

            # build Dz
            oc.Dz = build_derivative_matrix(self.mesh,
                                            1,
                                            self.spatial_accuracy_order,
                                            dimension='z')

            # build other useful things
            oc.I     = spsp.eye(dof, dof)
            oc.empty = spsp.csr_matrix((dof, dof))

            # useful intermediates
            oc.sigma_xz = make_diag_mtx(sx*sz)
            oc.minus_sigma_xPz = oc.minus_sigmax + oc.minus_sigmaz
            oc.sigma_zMx_Dx = make_diag_mtx(sz-sx)*oc.Dx
            oc.sigma_xMz_Dz = make_diag_mtx(sx-sz)*oc.Dz

            oc._numpy_components_built = True

        C = self.model_parameters.C
        oc.m_inv = make_diag_mtx((C**2).reshape(-1,))

        self.A = spsp.bmat([[oc.empty,                  oc.I,               oc.empty,        oc.empty        ],
                            [oc.m_inv*oc.L-oc.sigma_xz, oc.minus_sigma_xPz, oc.m_inv*oc.Dx,  oc.m_inv*oc.Dz  ],
                            [oc.sigma_zMx_Dx,           oc.empty,           oc.minus_sigmax, oc.empty        ],
                            [oc.sigma_xMz_Dz,           oc.empty,           oc.empty,        oc.minus_sigmaz ]])
Example #3
0
    def _rebuild_operators(self):

        oc = self.operator_components

        built = oc.get('_base_components_built', False)

        # build the static components
        if not built:
            oc.sx = build_sigma(self.mesh, self.mesh.x)
            oc.sz = build_sigma(self.mesh, self.mesh.z)

            oc.sxPsz = oc.sx + oc.sz
            oc.sxsz = oc.sx * oc.sz

            oc._base_components_built = True
    def _rebuild_operators(self):

        oc = self.operator_components

        built = oc.get('_base_components_built', False)

        # build the static components
        if not built:
            oc.sx = build_sigma(self.mesh, self.mesh.x)
            oc.sz = build_sigma(self.mesh, self.mesh.z)

            oc.sxPsz = oc.sx + oc.sz
            oc.sxsz = oc.sx * oc.sz

            oc._base_components_built = True
    def _rebuild_operators(self):

        ConstantDensityAcousticTimeScalar_1D._rebuild_operators(self)

        dof = self.mesh.dof(include_bc=True)

        oc = self.operator_components

        built = oc.get('_numpy_components_built', False)

        # build the static components
        if not built:
            # build laplacian
            oc.L = build_derivative_matrix(self.mesh,
                                           2,
                                           self.spatial_accuracy_order)

            # build sigmaz
            sz = build_sigma(self.mesh, self.mesh.z)
            oc.sigmaz = make_diag_mtx(sz)

            # build Dz
            oc.Dz = build_derivative_matrix(self.mesh,
                                            1,
                                            self.spatial_accuracy_order,
                                            dimension='z')

            # build other useful things
            oc.I = spsp.eye(dof, dof)
            oc.empty = spsp.csr_matrix((dof, dof))

            # Stiffness matrix K doesn't change
            oc.K = spsp.bmat([[          -oc.L,    -oc.Dz],
                              [oc.sigmaz*oc.Dz, oc.sigmaz]])

            oc._numpy_components_built = True

        C = self.model_parameters.C
        oc.m = make_diag_mtx((C**-2).reshape(-1,))

        C = spsp.bmat([[oc.sigmaz*oc.m, None],
                       [          None, oc.I]]) / self.dt

        M = spsp.bmat([[oc.m,     None],
                       [None, oc.empty]]) / self.dt**2

        Stilde_inv = M+C
        Stilde_inv.data = 1./Stilde_inv.data

        self.A_k   = Stilde_inv*(2*M - oc.K + C)
        self.A_km1 = -1*Stilde_inv*(M)
        self.A_f   = Stilde_inv
    def _rebuild_operators(self):

        ConstantDensityAcousticTimeScalar_1D._rebuild_operators(self)

        dof = self.mesh.dof(include_bc=True)

        oc = self.operator_components

        built = oc.get('_numpy_components_built', False)

        # build the static components
        if not built:
            # build laplacian
            oc.L = build_derivative_matrix(self.mesh,
                                           2,
                                           self.spatial_accuracy_order)

            # build sigmaz
            sz = build_sigma(self.mesh, self.mesh.z)
            oc.sigmaz = make_diag_mtx(sz)

            # build Dz
            oc.Dz = build_derivative_matrix(self.mesh,
                                            1,
                                            self.spatial_accuracy_order,
                                            dimension='z')

            # build other useful things
            oc.I = spsp.eye(dof, dof)
            oc.empty = spsp.csr_matrix((dof, dof))

            # Stiffness matrix K doesn't change
            oc.K = spsp.bmat([[-oc.L,    -oc.Dz],
                              [oc.sigmaz*oc.Dz, oc.sigmaz]])

            oc._numpy_components_built = True

        C = self.model_parameters.C
        oc.m = make_diag_mtx((C**-2).reshape(-1,))

        C = spsp.bmat([[oc.sigmaz*oc.m, None],
                       [None, oc.I]]) / self.dt

        M = spsp.bmat([[oc.m,     None],
                       [None, oc.empty]]) / self.dt**2

        Stilde_inv = M+C
        Stilde_inv.data = 1./Stilde_inv.data

        self.A_k = Stilde_inv*(2*M - oc.K + C)
        self.A_km1 = -1*Stilde_inv*(M)
        self.A_f = Stilde_inv
Example #7
0
    def _rebuild_operators(self):

        dof = self.mesh.dof(include_bc=True)

        oc = self.operator_components

        built = oc.get('_numpy_components_built', False)

        oc.I = spsp.eye(dof, dof)

        # build the static components
        if not built:
            # build laplacian
            oc.L = build_derivative_matrix(self.mesh,
                                           2,
                                           self.spatial_accuracy_order,
                                           use_shifted_differences=self.spatial_shifted_differences)

            # build sigmaz
            sz = build_sigma(self.mesh, self.mesh.z)
            oc.sigmaz = make_diag_mtx(sz)

            # build Dz
            oc.Dz = build_derivative_matrix(self.mesh,
                                            1,
                                            self.spatial_accuracy_order,
                                            dimension='z',
                                            use_shifted_differences=self.spatial_shifted_differences)

            # build other useful things
            oc.empty = spsp.csr_matrix((dof, dof))

            # Stiffness matrix K doesn't change
            self.K = spsp.bmat([[-oc.L,    -oc.Dz],
                                [oc.sigmaz*oc.Dz, oc.sigmaz]])

            oc._numpy_components_built = True

        C = self.model_parameters.C
        oc.m = make_diag_mtx((C**-2).reshape(-1,))

        self.C = spsp.bmat([[oc.sigmaz*oc.m, None],
                            [None,           oc.I]])

        self.M = spsp.bmat([[oc.m,     None],
                            [None, oc.empty]])

        self.dM = oc.I
        self.dC = oc.sigmaz
        self.dK = 0
    def _rebuild_operators(self):

        dof = self.mesh.dof(include_bc=True)

        oc = self.operator_components

        built = oc.get('_numpy_components_built', False)

        # build the static components
        if not built:
            # build laplacian
            oc.L = build_derivative_matrix(self.mesh,
                                           2,
                                           self.spatial_accuracy_order)

            # build sigmaz (stored as -1*sigmaz)
            sz = build_sigma(self.mesh, self.mesh.z)
            oc.minus_sigmaz = make_diag_mtx(-sz)

            # build Dz
            oc.Dz = build_derivative_matrix(self.mesh,
                                            1,
                                            self.spatial_accuracy_order,
                                            dimension='z')

            # build other useful things
            oc.I     = spsp.eye(dof, dof)
            oc.empty = spsp.csr_matrix((dof, dof))

            oc._numpy_components_built = True

        C = self.model_parameters.C
        oc.m_inv = make_diag_mtx((C**2).reshape(-1,))

        self.A = spsp.bmat([[oc.empty,              oc.I,            oc.empty       ],
                            [oc.m_inv*oc.L,         oc.minus_sigmaz, oc.m_inv*oc.Dz ],
                            [oc.minus_sigmaz*oc.Dz, oc.empty,        oc.minus_sigmaz]])
    def _rebuild_operators(self):

        dof = self.mesh.dof(include_bc=True)

        oc = self.operator_components

        built = oc.get('_numpy_components_built', False)

        # build the static components
        if not built:
            # build laplacian
            oc.L = build_derivative_matrix(self.mesh,
                                           2,
                                           self.spatial_accuracy_order)

            # build sigmaz (stored as -1*sigmaz)
            sz = build_sigma(self.mesh, self.mesh.z)
            oc.minus_sigmaz = make_diag_mtx(-sz)

            # build Dz
            oc.Dz = build_derivative_matrix(self.mesh,
                                            1,
                                            self.spatial_accuracy_order,
                                            dimension='z')

            # build other useful things
            oc.I     = spsp.eye(dof, dof)
            oc.empty = spsp.csr_matrix((dof, dof))

            oc._numpy_components_built = True

        C = self.model_parameters.C
        oc.m_inv = make_diag_mtx((C**2).reshape(-1,))

        self.A = spsp.bmat([[oc.empty,              oc.I,            oc.empty       ],
                            [oc.m_inv*oc.L,         oc.minus_sigmaz, oc.m_inv*oc.Dz ],
                            [oc.minus_sigmaz*oc.Dz, oc.empty,        oc.minus_sigmaz]])
    def _rebuild_operators(self):
        if self.mesh.x.lbc.type == 'pml' and self.compact:
          # build intermediates for compact operator 
          dof = self.mesh.dof(include_bc=True)
          oc = self.operator_components
          built = oc.get('_numpy_components_built', False)
          oc.M = make_diag_mtx(self.model_parameters.C.squeeze()**-2)
          # build the static components
          if not built:          
            # build Dxx
            oc.Dxx = build_derivative_matrix(self.mesh,
                                                  2,
                                                  self.spatial_accuracy_order,
                                                  dimension='x',
                                                  use_shifted_differences=self.spatial_shifted_differences)
            # build Dzz
            oc.Dzz = build_derivative_matrix(self.mesh,
                                                  2,
                                                  self.spatial_accuracy_order,
                                                  dimension='z',
                                                  use_shifted_differences=self.spatial_shifted_differences)
            # build Dyy
            oc.Dyy = build_derivative_matrix(self.mesh,
                                                  2,
                                                  self.spatial_accuracy_order,
                                                  dimension='y',
                                                  use_shifted_differences=self.spatial_shifted_differences)
            # build Dx
            oc.Dx = build_derivative_matrix(self.mesh,
                                                  1,
                                                  self.spatial_accuracy_order,
                                                  dimension='x',
                                                  use_shifted_differences=self.spatial_shifted_differences)
            
            # build Dz
            oc.Dz = build_derivative_matrix(self.mesh,
                                                  1,
                                                  self.spatial_accuracy_order,
                                                  dimension='z',
                                                  use_shifted_differences=self.spatial_shifted_differences)
            # build Dz
            oc.Dy = build_derivative_matrix(self.mesh,
                                                  1,
                                                  self.spatial_accuracy_order,
                                                  dimension='y',
                                                  use_shifted_differences=self.spatial_shifted_differences)
                                                  
            # build sigma
            oc.sx, oc.sy, oc.sz, oc.sxp, oc.syp, oc.szp = self._sigma_PML(self.mesh)

            oc._numpy_components_built = True

        else :
          # build intermediates for operator with auxiliary fields
          dof = self.mesh.dof(include_bc=True)

          oc = self.operator_components

          built = oc.get('_numpy_components_built', False)

          # build the static components
          if not built:
              # build laplacian
              oc.L = build_derivative_matrix(self.mesh,
                                             2,
                                             self.spatial_accuracy_order,
                                             use_shifted_differences=self.spatial_shifted_differences)

              # build sigmax
              sx = build_sigma(self.mesh, self.mesh.x)
              oc.sigmax = make_diag_mtx(sx)

              # build sigmay
              sy = build_sigma(self.mesh, self.mesh.y)
              oc.sigmay = make_diag_mtx(sy)

              # build sigmaz
              sz = build_sigma(self.mesh, self.mesh.z)
              oc.sigmaz = make_diag_mtx(sz)

              # build Dx
              oc.minus_Dx = build_derivative_matrix(self.mesh,
                                                    1,
                                                    self.spatial_accuracy_order,
                                                    dimension='x',
                                                    use_shifted_differences=self.spatial_shifted_differences)
              oc.minus_Dx.data *= -1

              # build Dy
              oc.minus_Dy = build_derivative_matrix(self.mesh,
                                                    1,
                                                    self.spatial_accuracy_order,
                                                    dimension='y',
                                                    use_shifted_differences=self.spatial_shifted_differences)
              oc.minus_Dy.data *= -1

              # build Dz
              oc.minus_Dz = build_derivative_matrix(self.mesh,
                                                    1,
                                                    self.spatial_accuracy_order,
                                                    dimension='z',
                                                    use_shifted_differences=self.spatial_shifted_differences)
              oc.minus_Dz.data *= -1

              # build other useful things
              oc.I = spsp.eye(dof, dof)
              oc.minus_I = -1*oc.I
              oc.empty = spsp.csr_matrix((dof, dof))

              # useful intermediates
              oc.sigma_sum_pair_prod  = make_diag_mtx(sx*sy + sx*sz + sy*sz)
              oc.sigma_sum            = make_diag_mtx(sx+sy+sz)
              oc.sigma_prod           = make_diag_mtx(sx*sy*sz)
              oc.minus_sigma_yPzMx_Dx = make_diag_mtx(sy+sz-sx)*oc.minus_Dx
              oc.minus_sigma_xPzMy_Dy = make_diag_mtx(sx+sz-sy)*oc.minus_Dy
              oc.minus_sigma_xPyMz_Dz = make_diag_mtx(sx+sy-sz)*oc.minus_Dz

              oc.minus_sigma_yz_Dx    = make_diag_mtx(sy*sz)*oc.minus_Dx
              oc.minus_sigma_zx_Dy    = make_diag_mtx(sz*sx)*oc.minus_Dy
              oc.minus_sigma_xy_Dz    = make_diag_mtx(sx*sy)*oc.minus_Dz

              oc._numpy_components_built = True

          C = self.model_parameters.C
          oc.m = make_diag_mtx((C**-2).reshape(-1,))

          self.K = spsp.bmat([[oc.m*oc.sigma_sum_pair_prod-oc.L, oc.m*oc.sigma_prod,   oc.minus_Dx, oc.minus_Dy, oc.minus_Dz ],
                              [oc.minus_I,                       oc.empty,             oc.empty,    oc.empty,    oc.empty    ],
                              [oc.minus_sigma_yPzMx_Dx,          oc.minus_sigma_yz_Dx, oc.sigmax,   oc.empty,    oc.empty    ],
                              [oc.minus_sigma_xPzMy_Dy,          oc.minus_sigma_zx_Dy, oc.empty,    oc.sigmay,   oc.empty    ],
                              [oc.minus_sigma_xPyMz_Dz,          oc.minus_sigma_xy_Dz, oc.empty,    oc.empty,    oc.sigmaz   ]])

          self.C = spsp.bmat([[oc.m*oc.sigma_sum, oc.empty, oc.empty, oc.empty, oc.empty],
                              [oc.empty,          oc.I,     oc.empty, oc.empty, oc.empty],
                              [oc.empty,          oc.empty, oc.I,     oc.empty, oc.empty],
                             [oc.empty,          oc.empty, oc.empty, oc.I,     oc.empty],
                             [oc.empty,          oc.empty, oc.empty, oc.empty, oc.I    ]]) / self.dt

          self.M = spsp.bmat([[    oc.m, oc.empty, oc.empty, oc.empty, oc.empty],
                             [oc.empty, oc.empty, oc.empty, oc.empty, oc.empty],
                              [oc.empty, oc.empty, oc.empty, oc.empty, oc.empty],
                             [oc.empty, oc.empty, oc.empty, oc.empty, oc.empty],
                             [oc.empty, oc.empty, oc.empty, oc.empty, oc.empty]])
    def _rebuild_operators(self):

        dof = self.mesh.dof(include_bc=True)

        oc = self.operator_components

        built = oc.get('_numpy_components_built', False)

        # build the static components
        if not built:
            # build laplacian
            oc.L = build_derivative_matrix(self.mesh,
                                           2,
                                           self.spatial_accuracy_order,
                                           use_shifted_differences=self.spatial_shifted_differences)

            # build sigmax
            sx = build_sigma(self.mesh, self.mesh.x)
            oc.sigmax = make_diag_mtx(sx)

            # build sigmay
            sy = build_sigma(self.mesh, self.mesh.y)
            oc.sigmay = make_diag_mtx(sy)

            # build sigmaz
            sz = build_sigma(self.mesh, self.mesh.z)
            oc.sigmaz = make_diag_mtx(sz)

            # build Dx
            oc.minus_Dx = build_derivative_matrix(self.mesh,
                                                  1,
                                                  self.spatial_accuracy_order,
                                                  dimension='x',
                                                  use_shifted_differences=self.spatial_shifted_differences)
            oc.minus_Dx.data *= -1

            # build Dy
            oc.minus_Dy = build_derivative_matrix(self.mesh,
                                                  1,
                                                  self.spatial_accuracy_order,
                                                  dimension='y',
                                                  use_shifted_differences=self.spatial_shifted_differences)
            oc.minus_Dy.data *= -1

            # build Dz
            oc.minus_Dz = build_derivative_matrix(self.mesh,
                                                  1,
                                                  self.spatial_accuracy_order,
                                                  dimension='z',
                                                  use_shifted_differences=self.spatial_shifted_differences)
            oc.minus_Dz.data *= -1

            # build other useful things
            oc.I = spsp.eye(dof, dof)
            oc.minus_I = -1*oc.I
            oc.empty = spsp.csr_matrix((dof, dof))

            # useful intermediates
            oc.sigma_sum_pair_prod  = make_diag_mtx(sx*sy + sx*sz + sy*sz)
            oc.sigma_sum            = make_diag_mtx(sx+sy+sz)
            oc.sigma_prod           = make_diag_mtx(sx*sy*sz)
            oc.minus_sigma_yPzMx_Dx = make_diag_mtx(sy+sz-sx)*oc.minus_Dx
            oc.minus_sigma_xPzMy_Dy = make_diag_mtx(sx+sz-sy)*oc.minus_Dy
            oc.minus_sigma_xPyMz_Dz = make_diag_mtx(sx+sy-sz)*oc.minus_Dz

            oc.minus_sigma_yz_Dx    = make_diag_mtx(sy*sz)*oc.minus_Dx
            oc.minus_sigma_zx_Dy    = make_diag_mtx(sz*sx)*oc.minus_Dy
            oc.minus_sigma_xy_Dz    = make_diag_mtx(sx*sy)*oc.minus_Dz

            oc._numpy_components_built = True

        C = self.model_parameters.C
        oc.m = make_diag_mtx((C**-2).reshape(-1,))

        self.K = spsp.bmat([[oc.m*oc.sigma_sum_pair_prod-oc.L, oc.m*oc.sigma_prod,   oc.minus_Dx, oc.minus_Dy, oc.minus_Dz ],
                            [oc.minus_I,                       oc.empty,             oc.empty,    oc.empty,    oc.empty    ],
                            [oc.minus_sigma_yPzMx_Dx,          oc.minus_sigma_yz_Dx, oc.sigmax,   oc.empty,    oc.empty    ],
                            [oc.minus_sigma_xPzMy_Dy,          oc.minus_sigma_zx_Dy, oc.empty,    oc.sigmay,   oc.empty    ],
                            [oc.minus_sigma_xPyMz_Dz,          oc.minus_sigma_xy_Dz, oc.empty,    oc.empty,    oc.sigmaz   ]])

        self.C = spsp.bmat([[oc.m*oc.sigma_sum, oc.empty, oc.empty, oc.empty, oc.empty],
                            [oc.empty,          oc.I,     oc.empty, oc.empty, oc.empty],
                            [oc.empty,          oc.empty, oc.I,     oc.empty, oc.empty],
                           [oc.empty,          oc.empty, oc.empty, oc.I,     oc.empty],
                           [oc.empty,          oc.empty, oc.empty, oc.empty, oc.I    ]]) / self.dt

        self.M = spsp.bmat([[    oc.m, oc.empty, oc.empty, oc.empty, oc.empty],
                           [oc.empty, oc.empty, oc.empty, oc.empty, oc.empty],
                            [oc.empty, oc.empty, oc.empty, oc.empty, oc.empty],
                           [oc.empty, oc.empty, oc.empty, oc.empty, oc.empty],
                           [oc.empty, oc.empty, oc.empty, oc.empty, oc.empty]])
    def _rebuild_operators(self):

        ConstantDensityAcousticTimeScalar_2D._rebuild_operators(self)

        dof = self.mesh.dof(include_bc=True)

        oc = self.operator_components

        built = oc.get('_numpy_components_built', False)

        # build the static components
        if not built:
            # build laplacian
            oc.L = build_derivative_matrix(self.mesh,
                                           2,
                                           self.spatial_accuracy_order)

            # build sigmax
            sx = build_sigma(self.mesh, self.mesh.x)
            oc.sigmax = make_diag_mtx(sx)

            # build sigmaz
            sz = build_sigma(self.mesh, self.mesh.z)
            oc.sigmaz = make_diag_mtx(sz)

            # build Dx
            oc.minus_Dx = build_derivative_matrix(self.mesh,
                                                  1,
                                                  self.spatial_accuracy_order,
                                                  dimension='x')
            oc.minus_Dx.data *= -1

            # build Dz
            oc.minus_Dz = build_derivative_matrix(self.mesh,
                                                  1,
                                                  self.spatial_accuracy_order,
                                                  dimension='z')
            oc.minus_Dz.data *= -1

            # build other useful things
            oc.I = spsp.eye(dof, dof)
            oc.empty = spsp.csr_matrix((dof, dof))

            # useful intermediates
            oc.sigma_xz = make_diag_mtx(sx*sz)
            oc.sigma_xPz = oc.sigmax + oc.sigmaz

            oc.minus_sigma_zMx_Dx = make_diag_mtx((sz-sx))*oc.minus_Dx
            oc.minus_sigma_xMz_Dz = make_diag_mtx((sx-sz))*oc.minus_Dz

            oc._numpy_components_built = True

        C = self.model_parameters.C
        oc.m = make_diag_mtx((C**-2).reshape(-1,))

        K = spsp.bmat([[oc.m*oc.sigma_xz-oc.L, oc.minus_Dx, oc.minus_Dz],
                       [oc.minus_sigma_zMx_Dx, oc.sigmax,   oc.empty],
                       [oc.minus_sigma_xMz_Dz, oc.empty,    oc.sigmaz]])

        C = spsp.bmat([[oc.m*oc.sigma_xPz, oc.empty, oc.empty],
                       [oc.empty,          oc.I,     oc.empty],
                       [oc.empty,          oc.empty, oc.I]]) / self.dt

        M = spsp.bmat([[oc.m, oc.empty, oc.empty],
                       [oc.empty, oc.empty, oc.empty],
                       [oc.empty, oc.empty, oc.empty]]) / self.dt**2

        Stilde_inv = M+C
        Stilde_inv.data = 1./Stilde_inv.data

        self.A_k = Stilde_inv*(2*M - K + C)
        self.A_km1 = -1*Stilde_inv*(M)
        self.A_f = Stilde_inv
    def _rebuild_operators(self):

        dof = self.mesh.dof(include_bc=True)

        oc = self.operator_components

        built = oc.get('_numpy_components_built', False)

        # build the static components
        if not built:
            # build laplacian
            oc.L = build_derivative_matrix(self.mesh,
                                           2,
                                           self.spatial_accuracy_order,
                                           use_shifted_differences=self.spatial_shifted_differences)

            # build sigmax
            sx = build_sigma(self.mesh, self.mesh.x)
            oc.sigmax = make_diag_mtx(sx)

            # build sigmaz
            sz = build_sigma(self.mesh, self.mesh.z)
            oc.sigmaz = make_diag_mtx(sz)

            # build Dx
            oc.minus_Dx = build_derivative_matrix(self.mesh,
                                                  1,
                                                  self.spatial_accuracy_order,
                                                  dimension='x',
                                                  use_shifted_differences=self.spatial_shifted_differences)
            oc.minus_Dx.data *= -1

            # build Dz
            oc.minus_Dz = build_derivative_matrix(self.mesh,
                                                  1,
                                                  self.spatial_accuracy_order,
                                                  dimension='z',
                                                  use_shifted_differences=self.spatial_shifted_differences)
            oc.minus_Dz.data *= -1

            # build other useful things
            oc.I = spsp.eye(dof, dof)
            oc.empty = spsp.csr_matrix((dof, dof))

            # useful intermediates
            oc.sigma_xz  = make_diag_mtx(sx*sz)
            oc.sigma_xPz = oc.sigmax + oc.sigmaz

            oc.minus_sigma_zMx_Dx = make_diag_mtx((sz-sx))*oc.minus_Dx
            oc.minus_sigma_xMz_Dz = make_diag_mtx((sx-sz))*oc.minus_Dz

            oc._numpy_components_built = True

        C = self.model_parameters.C
        oc.m = make_diag_mtx((C**-2).reshape(-1,))

        self.K = spsp.bmat([[oc.m*oc.sigma_xz-oc.L, oc.minus_Dx, oc.minus_Dz ],
                            [oc.minus_sigma_zMx_Dx, oc.sigmax,   oc.empty    ],
                            [oc.minus_sigma_xMz_Dz, oc.empty,    oc.sigmaz   ]])

        self.C = spsp.bmat([[oc.m*oc.sigma_xPz, oc.empty, oc.empty],
                            [oc.empty,          oc.I,     oc.empty],
                            [oc.empty,          oc.empty, oc.I    ]])

        self.M = spsp.bmat([[    oc.m, oc.empty, oc.empty],
                            [oc.empty, oc.empty, oc.empty],
                            [oc.empty, oc.empty, oc.empty]])
    def _rebuild_operators(self):

        ConstantDensityAcousticTimeScalar_3D._rebuild_operators(self)

        dof = self.mesh.dof(include_bc=True)

        oc = self.operator_components

        built = oc.get("_numpy_components_built", False)

        # build the static components
        if not built:
            # build laplacian
            oc.L = build_derivative_matrix(self.mesh, 2, self.spatial_accuracy_order)

            # build sigmax
            sx = build_sigma(self.mesh, self.mesh.x)
            oc.sigmax = make_diag_mtx(sx)

            # build sigmay
            sy = build_sigma(self.mesh, self.mesh.y)
            oc.sigmay = make_diag_mtx(sy)

            # build sigmaz
            sz = build_sigma(self.mesh, self.mesh.z)
            oc.sigmaz = make_diag_mtx(sz)

            # build Dx
            oc.minus_Dx = build_derivative_matrix(self.mesh, 1, self.spatial_accuracy_order, dimension="x")
            oc.minus_Dx.data *= -1

            # build Dy
            oc.minus_Dy = build_derivative_matrix(self.mesh, 1, self.spatial_accuracy_order, dimension="y")
            oc.minus_Dy.data *= -1

            # build Dz
            oc.minus_Dz = build_derivative_matrix(self.mesh, 1, self.spatial_accuracy_order, dimension="z")
            oc.minus_Dz.data *= -1

            # build other useful things
            oc.I = spsp.eye(dof, dof)
            oc.minus_I = -1 * oc.I
            oc.empty = spsp.csr_matrix((dof, dof))

            # useful intermediates
            oc.sigma_sum_pair_prod = make_diag_mtx(sx * sy + sx * sz + sy * sz)
            oc.sigma_sum = make_diag_mtx(sx + sy + sz)
            oc.sigma_prod = make_diag_mtx(sx * sy * sz)
            oc.minus_sigma_yPzMx_Dx = make_diag_mtx(sy + sz - sx) * oc.minus_Dx
            oc.minus_sigma_xPzMy_Dy = make_diag_mtx(sx + sz - sy) * oc.minus_Dy
            oc.minus_sigma_xPyMz_Dz = make_diag_mtx(sx + sy - sz) * oc.minus_Dz

            oc.minus_sigma_yz_Dx = make_diag_mtx(sy * sz) * oc.minus_Dx
            oc.minus_sigma_zx_Dy = make_diag_mtx(sz * sx) * oc.minus_Dy
            oc.minus_sigma_xy_Dz = make_diag_mtx(sx * sy) * oc.minus_Dz

            oc._numpy_components_built = True

        C = self.model_parameters.C
        oc.m = make_diag_mtx((C ** -2).reshape(-1))

        K = spsp.bmat(
            [
                [oc.m * oc.sigma_sum_pair_prod - oc.L, oc.m * oc.sigma_prod, oc.minus_Dx, oc.minus_Dy, oc.minus_Dz],
                [oc.minus_I, oc.empty, oc.empty, oc.empty, oc.empty],
                [oc.minus_sigma_yPzMx_Dx, oc.minus_sigma_yz_Dx, oc.sigmax, oc.empty, oc.empty],
                [oc.minus_sigma_xPzMy_Dy, oc.minus_sigma_zx_Dy, oc.empty, oc.sigmay, oc.empty],
                [oc.minus_sigma_xPyMz_Dz, oc.minus_sigma_xy_Dz, oc.empty, oc.empty, oc.sigmaz],
            ]
        )

        C = (
            spsp.bmat(
                [
                    [oc.m * oc.sigma_sum, oc.empty, oc.empty, oc.empty, oc.empty],
                    [oc.empty, oc.I, oc.empty, oc.empty, oc.empty],
                    [oc.empty, oc.empty, oc.I, oc.empty, oc.empty],
                    [oc.empty, oc.empty, oc.empty, oc.I, oc.empty],
                    [oc.empty, oc.empty, oc.empty, oc.empty, oc.I],
                ]
            )
            / self.dt
        )

        M = (
            spsp.bmat(
                [
                    [oc.m, oc.empty, oc.empty, oc.empty, oc.empty],
                    [oc.empty, oc.empty, oc.empty, oc.empty, oc.empty],
                    [oc.empty, oc.empty, oc.empty, oc.empty, oc.empty],
                    [oc.empty, oc.empty, oc.empty, oc.empty, oc.empty],
                    [oc.empty, oc.empty, oc.empty, oc.empty, oc.empty],
                ]
            )
            / self.dt ** 2
        )

        Stilde_inv = M + C
        Stilde_inv.data = 1.0 / Stilde_inv.data

        self.A_k = Stilde_inv * (2 * M - K + C)
        self.A_km1 = -1 * Stilde_inv * (M)
        self.A_f = Stilde_inv
    def _rebuild_operators(self):
    
            VariableDensityAcousticTimeScalar_2D._rebuild_operators(self)
    
            dof = self.mesh.dof(include_bc=True)
    
            oc = self.operator_components
    
            built = oc.get('_numpy_components_built', False)
    
            # build the static components
            if not built:
                # build sigmax
                sx = build_sigma(self.mesh, self.mesh.x)
                oc.sigmax = make_diag_mtx(sx)
    
                # build sigmaz
                sz = build_sigma(self.mesh, self.mesh.z)
                oc.sigmaz = make_diag_mtx(sz)
    
                # build Dx
                oc.Dx = build_derivative_matrix(self.mesh,
                                                        1,
                                                        self.spatial_accuracy_order,
                                                        dimension='x')
                oc.minus_Dx = copy.deepcopy(oc.Dx)      #more storage, but less computations
                oc.minus_Dx.data *= -1                  
    
                # build Dz
                oc.Dz = build_derivative_matrix(self.mesh,
                                                        1,
                                                        self.spatial_accuracy_order,
                                                        dimension='z')
                oc.minus_Dz = copy.deepcopy(oc.Dz)      #more storage, but less computations
                oc.minus_Dz.data *= -1                                  

    
                # build other useful things
                oc.I = spsp.eye(dof, dof)
                oc.empty = spsp.csr_matrix((dof, dof))
    
                # useful intermediates
                oc.sigma_xz  = make_diag_mtx(sx*sz)
                oc.sigma_xPz = oc.sigmax + oc.sigmaz
    
                oc.minus_sigma_zMx_Dx = make_diag_mtx((sz-sx))*oc.minus_Dx
                oc.minus_sigma_xMz_Dz = make_diag_mtx((sx-sz))*oc.minus_Dz
    
                oc._numpy_components_built = True

            kappa = self.model_parameters.kappa
            rho = self.model_parameters.rho
    
            oc.m1 = make_diag_mtx((kappa**-1).reshape(-1,))
            oc.m2 = make_diag_mtx((rho**-1).reshape(-1,))

            oc.L = build_derivative_matrix_VDA(self.mesh,
                                               2,
                                               self.spatial_accuracy_order,
                                               alpha = rho**-1
                                               )
            
    
            # oc.L is a heterogenous laplacian operator. It computes div(m2 grad), where m2 = 1/rho. 
            # Ian's implementation used the regular Dx operators in the PML even though the heterogeneous Laplacian with staggered derivative operators is used in the physical domain.
            # I (Bram) did not change this or investigate if this causes some problems but am noting it here for completeness. 
            
            K = spsp.bmat([[oc.m1*oc.sigma_xz-oc.L, oc.minus_Dx*oc.m2, oc.minus_Dz*oc.m2 ],
                           [oc.minus_sigma_zMx_Dx, oc.sigmax,   oc.empty    ],
                           [oc.minus_sigma_xMz_Dz, oc.empty,    oc.sigmaz   ]])
    
            C = spsp.bmat([[oc.m1*oc.sigma_xPz, oc.empty, oc.empty],
                           [oc.empty,          oc.I,     oc.empty],
                           [oc.empty,          oc.empty, oc.I    ]]) / self.dt
    
            M = spsp.bmat([[    oc.m1, oc.empty, oc.empty],
                           [oc.empty, oc.empty, oc.empty],
                           [oc.empty, oc.empty, oc.empty]]) / self.dt**2
    
            Stilde_inv = M+C
            Stilde_inv.data = 1./Stilde_inv.data
    
            self.A_k   = Stilde_inv*(2*M - K + C)
            self.A_km1 = -1*Stilde_inv*(M)
            self.A_f   = Stilde_inv
    def _rebuild_operators(self):
        if self.mesh.x.lbc.type == 'pml' and self.compact:
            # build intermediates for the compact operator
            dof = self.mesh.dof(include_bc=True)

            oc = self.operator_components

            built = oc.get('_numpy_components_built', False)
            oc.M = make_diag_mtx(self.model_parameters.C.squeeze()**-2)
            oc.I = spsp.eye(dof, dof)
            # build the static components
            if not built:
                # build Dxx
                oc.Dxx = build_derivative_matrix(
                    self.mesh,
                    2,
                    self.spatial_accuracy_order,
                    dimension='x',
                    use_shifted_differences=self.spatial_shifted_differences)
                # build Dzz
                oc.Dzz = build_derivative_matrix(
                    self.mesh,
                    2,
                    self.spatial_accuracy_order,
                    dimension='z',
                    use_shifted_differences=self.spatial_shifted_differences)
                # build Dx
                oc.Dx = build_derivative_matrix(
                    self.mesh,
                    1,
                    self.spatial_accuracy_order,
                    dimension='x',
                    use_shifted_differences=self.spatial_shifted_differences)

                # build Dz
                oc.Dz = build_derivative_matrix(
                    self.mesh,
                    1,
                    self.spatial_accuracy_order,
                    dimension='z',
                    use_shifted_differences=self.spatial_shifted_differences)

                # build sigma
                oc.sx, oc.sz, oc.sxp, oc.szp = self._sigma_PML(self.mesh)

                oc._numpy_components_built = True

            self.dK = 0
            self.dC = 0
            self.dM = oc.I
        else:
            # build intermediates for operator with auxiliary fields
            dof = self.mesh.dof(include_bc=True)

            oc = self.operator_components
            oc.I = spsp.eye(dof, dof)

            built = oc.get('_numpy_components_built', False)

            # build the static components
            if not built:
                # build laplacian
                oc.L = build_derivative_matrix(
                    self.mesh,
                    2,
                    self.spatial_accuracy_order,
                    use_shifted_differences=self.spatial_shifted_differences)

                # build sigmax
                sx = build_sigma(self.mesh, self.mesh.x)
                oc.sigmax = make_diag_mtx(sx)

                # build sigmaz
                sz = build_sigma(self.mesh, self.mesh.z)
                oc.sigmaz = make_diag_mtx(sz)

                # build Dx
                oc.minus_Dx = build_derivative_matrix(
                    self.mesh,
                    1,
                    self.spatial_accuracy_order,
                    dimension='x',
                    use_shifted_differences=self.spatial_shifted_differences)
                oc.minus_Dx.data *= -1

                # build Dz
                oc.minus_Dz = build_derivative_matrix(
                    self.mesh,
                    1,
                    self.spatial_accuracy_order,
                    dimension='z',
                    use_shifted_differences=self.spatial_shifted_differences)
                oc.minus_Dz.data *= -1

                # build other useful things
                oc.I = spsp.eye(dof, dof)
                oc.empty = spsp.csr_matrix((dof, dof))

                # useful intermediates
                oc.sigma_xz = make_diag_mtx(sx * sz)
                oc.sigma_xPz = oc.sigmax + oc.sigmaz

                oc.minus_sigma_zMx_Dx = make_diag_mtx((sz - sx)) * oc.minus_Dx
                oc.minus_sigma_xMz_Dz = make_diag_mtx((sx - sz)) * oc.minus_Dz

                oc._numpy_components_built = True

            C = self.model_parameters.C
            oc.m = make_diag_mtx((C**-2).reshape(-1, ))

            self.K = spsp.bmat(
                [[oc.m * oc.sigma_xz - oc.L, oc.minus_Dx, oc.minus_Dz],
                 [oc.minus_sigma_zMx_Dx, oc.sigmax, oc.empty],
                 [oc.minus_sigma_xMz_Dz, oc.empty, oc.sigmaz]])

            self.C = spsp.bmat([[oc.m * oc.sigma_xPz, oc.empty, oc.empty],
                                [oc.empty, oc.I, oc.empty],
                                [oc.empty, oc.empty, oc.I]])

            self.M = spsp.bmat([[oc.m, oc.empty, oc.empty],
                                [oc.empty, oc.empty, oc.empty],
                                [oc.empty, oc.empty, oc.empty]])

            self.dK = oc.sigma_xz
            self.dC = oc.sigma_xPz
            self.dM = oc.I
    def _rebuild_operators(self):
        if self.mesh.x.lbc.type == 'pml' and self.compact:
            # build intermediates for the compact operator
            raise ValidationFunctionError(
                " This solver is in construction and is not yet complete. For variable density and compact PML."
            )
            dof = self.mesh.dof(include_bc=True)

            oc = self.operator_components

            built = oc.get('_numpy_components_built', False)
            oc.M = make_diag_mtx(self.model_parameters.C.squeeze()**-2)
            # build the static components
            if not built:
                # build Dxx
                oc.Dxx = build_derivative_matrix(
                    self.mesh,
                    2,
                    self.spatial_accuracy_order,
                    dimension='x',
                    use_shifted_differences=self.spatial_shifted_differences)
                # build Dzz
                oc.Dzz = build_derivative_matrix(
                    self.mesh,
                    2,
                    self.spatial_accuracy_order,
                    dimension='z',
                    use_shifted_differences=self.spatial_shifted_differences)
                # build Dx
                oc.Dx = build_derivative_matrix(
                    self.mesh,
                    1,
                    self.spatial_accuracy_order,
                    dimension='x',
                    use_shifted_differences=self.spatial_shifted_differences)

                # build Dz
                oc.Dz = build_derivative_matrix(
                    self.mesh,
                    1,
                    self.spatial_accuracy_order,
                    dimension='z',
                    use_shifted_differences=self.spatial_shifted_differences)

                # build sigma
                oc.sx, oc.sz, oc.sxp, oc.szp = self._sigma_PML(self.mesh)

                oc._numpy_components_built = True
        else:
            # build intermediates for operator with auxiliary fields
            dof = self.mesh.dof(include_bc=True)

            oc = self.operator_components

            built = oc.get('_numpy_components_built', False)

            # build the static components
            if not built:
                # build sigmax
                sx = build_sigma(self.mesh, self.mesh.x)
                oc.sigmax = make_diag_mtx(sx)

                # build sigmaz
                sz = build_sigma(self.mesh, self.mesh.z)
                oc.sigmaz = make_diag_mtx(sz)

                # build Dx
                oc.minus_Dx = build_derivative_matrix(
                    self.mesh,
                    1,
                    self.spatial_accuracy_order,
                    dimension='x',
                    use_shifted_differences=self.spatial_shifted_differences)
                oc.minus_Dx.data *= -1

                # build Dz
                oc.minus_Dz = build_derivative_matrix(
                    self.mesh,
                    1,
                    self.spatial_accuracy_order,
                    dimension='z',
                    use_shifted_differences=self.spatial_shifted_differences)
                oc.minus_Dz.data *= -1

                # build other useful things
                oc.I = spsp.eye(dof, dof)
                oc.empty = spsp.csr_matrix((dof, dof))

                # useful intermediates
                oc.sigma_xz = make_diag_mtx(sx * sz)
                oc.sigma_xPz = oc.sigmax + oc.sigmaz

                oc.minus_sigma_zMx_Dx = make_diag_mtx((sz - sx)) * oc.minus_Dx
                oc.minus_sigma_xMz_Dz = make_diag_mtx((sx - sz)) * oc.minus_Dz

                oc._numpy_components_built = True

        kappa = self.model_parameters.kappa
        rho = self.model_parameters.rho
        oc.m1 = make_diag_mtx((kappa**-1).reshape(-1, ))
        oc.m2 = make_diag_mtx((rho**-1).reshape(-1, ))
        # build heterogenous laplacian
        sh = self.mesh.shape(include_bc=True, as_grid=True)
        deltas = [self.mesh.x.delta, self.mesh.z.delta]
        oc.L = build_derivative_matrix_VDA(self.mesh,
                                           2,
                                           self.spatial_accuracy_order,
                                           alpha=rho**-1)

        # oc.L is a heterogenous laplacian operator. It computes div(m2 grad), where m2 = 1/rho.
        # Currently the creation of oc.L is slow. This is because we have implemented a cenetered heterogenous laplacian.
        # To speed up computation, we could compute a div(m2 grad) operator that is not centered by simply multiplying
        # a divergence operator by oc.m2 by a gradient operator.

        self.K = spsp.bmat([[
            oc.m1 * oc.sigma_xz - oc.L, oc.minus_Dx * oc.m2,
            oc.minus_Dz * oc.m2
        ], [oc.minus_sigma_zMx_Dx, oc.sigmax, oc.empty],
                            [oc.minus_sigma_xMz_Dz, oc.empty, oc.sigmaz]])

        self.C = spsp.bmat([[oc.m1 * oc.sigma_xPz, oc.empty, oc.empty],
                            [oc.empty, oc.I, oc.empty],
                            [oc.empty, oc.empty, oc.I]])

        self.M = spsp.bmat([[oc.m1, oc.empty, oc.empty],
                            [oc.empty, oc.empty, oc.empty],
                            [oc.empty, oc.empty, oc.empty]])
    def _rebuild_operators(self):

        VariableDensityAcousticTimeScalar_2D._rebuild_operators(self)

        dof = self.mesh.dof(include_bc=True)

        oc = self.operator_components

        built = oc.get('_numpy_components_built', False)

        # build the static components
        if not built:
            # build sigmax
            sx = build_sigma(self.mesh, self.mesh.x)
            oc.sigmax = make_diag_mtx(sx)

            # build sigmaz
            sz = build_sigma(self.mesh, self.mesh.z)
            oc.sigmaz = make_diag_mtx(sz)

            # build Dx
            oc.minus_Dx = build_derivative_matrix(self.mesh,
                                                  1,
                                                  self.spatial_accuracy_order,
                                                  dimension='x')
            oc.minus_Dx.data *= -1

            # build Dz
            oc.minus_Dz = build_derivative_matrix(self.mesh,
                                                  1,
                                                  self.spatial_accuracy_order,
                                                  dimension='z')
            oc.minus_Dz.data *= -1

            # build other useful things
            oc.I = spsp.eye(dof, dof)
            oc.empty = spsp.csr_matrix((dof, dof))

            # useful intermediates
            oc.sigma_xz  = make_diag_mtx(sx*sz)
            oc.sigma_xPz = oc.sigmax + oc.sigmaz

            oc.minus_sigma_zMx_Dx = make_diag_mtx((sz-sx))*oc.minus_Dx
            oc.minus_sigma_xMz_Dz = make_diag_mtx((sx-sz))*oc.minus_Dz

            oc._numpy_components_built = True

        kappa = self.model_parameters.kappa
        rho = self.model_parameters.rho

        oc.m1 = make_diag_mtx((kappa**-1).reshape(-1,))
        oc.m2 = make_diag_mtx((rho**-1).reshape(-1,))
        
        # build heterogenous laplacian
        sh = self.mesh.shape(include_bc=True,as_grid=True)
        deltas = [self.mesh.x.delta,self.mesh.z.delta]
        oc.L = build_heterogenous_laplacian(sh,rho**-1,deltas)

        # oc.L is a heterogenous laplacian operator. It computes div(m2 grad), where m2 = 1/rho. 
        # Currently the creation of oc.L is slow. This is because we have implemented a cenetered heterogenous laplacian.
        # To speed up computation, we could compute a div(m2 grad) operator that is not centered by simply multiplying
        # a divergence operator by oc.m2 by a gradient operator.

        K = spsp.bmat([[oc.m1*oc.sigma_xz-oc.L, oc.minus_Dx*oc.m2, oc.minus_Dz*oc.m2 ],
                       [oc.minus_sigma_zMx_Dx, oc.sigmax,   oc.empty    ],
                       [oc.minus_sigma_xMz_Dz, oc.empty,    oc.sigmaz   ]])

        C = spsp.bmat([[oc.m1*oc.sigma_xPz, oc.empty, oc.empty],
                       [oc.empty,          oc.I,     oc.empty],
                       [oc.empty,          oc.empty, oc.I    ]]) / self.dt

        M = spsp.bmat([[    oc.m1, oc.empty, oc.empty],
                       [oc.empty, oc.empty, oc.empty],
                       [oc.empty, oc.empty, oc.empty]]) / self.dt**2

        Stilde_inv = M+C
        Stilde_inv.data = 1./Stilde_inv.data

        self.A_k   = Stilde_inv*(2*M - K + C)
        self.A_km1 = -1*Stilde_inv*(M)
        self.A_f   = Stilde_inv
    def _rebuild_operators(self):
        if self.mesh.x.lbc.type == 'pml' and self.compact:
            # build intermediates for the compact operator
            dof = self.mesh.dof(include_bc=True)

            oc = self.operator_components

            built = oc.get('_numpy_components_built', False)
            oc.M = make_diag_mtx(self.model_parameters.C.squeeze()**-2)
            oc.I = spsp.eye(dof, dof)
            # build the static components
            if not built:
                # build Dxx
                oc.Dxx = build_derivative_matrix(self.mesh,
                                                 2,
                                                 self.spatial_accuracy_order,
                                                 dimension='x',
                                                 use_shifted_differences=self.spatial_shifted_differences)
                # build Dzz
                oc.Dzz = build_derivative_matrix(self.mesh,
                                                 2,
                                                 self.spatial_accuracy_order,
                                                 dimension='z',
                                                 use_shifted_differences=self.spatial_shifted_differences)
                # build Dx
                oc.Dx = build_derivative_matrix(self.mesh,
                                                1,
                                                self.spatial_accuracy_order,
                                                dimension='x',
                                                use_shifted_differences=self.spatial_shifted_differences)

                # build Dz
                oc.Dz = build_derivative_matrix(self.mesh,
                                                1,
                                                self.spatial_accuracy_order,
                                                dimension='z',
                                                use_shifted_differences=self.spatial_shifted_differences)

                # build sigma
                oc.sx, oc.sz, oc.sxp, oc.szp = self._sigma_PML(self.mesh)

                oc._numpy_components_built = True

            self.dK = 0
            self.dC = 0
            self.dM = oc.I
        else:
            # build intermediates for operator with auxiliary fields
            dof = self.mesh.dof(include_bc=True)

            oc = self.operator_components
            oc.I = spsp.eye(dof, dof)

            built = oc.get('_numpy_components_built', False)

            # build the static components
            if not built:
                # build laplacian
                oc.L = build_derivative_matrix(self.mesh,
                                               2,
                                               self.spatial_accuracy_order,
                                               use_shifted_differences=self.spatial_shifted_differences)

                # build sigmax
                sx = build_sigma(self.mesh, self.mesh.x)
                oc.sigmax = make_diag_mtx(sx)

                # build sigmaz
                sz = build_sigma(self.mesh, self.mesh.z)
                oc.sigmaz = make_diag_mtx(sz)

                # build Dx
                oc.minus_Dx = build_derivative_matrix(self.mesh,
                                                      1,
                                                      self.spatial_accuracy_order,
                                                      dimension='x',
                                                      use_shifted_differences=self.spatial_shifted_differences)
                oc.minus_Dx.data *= -1

                # build Dz
                oc.minus_Dz = build_derivative_matrix(self.mesh,
                                                      1,
                                                      self.spatial_accuracy_order,
                                                      dimension='z',
                                                      use_shifted_differences=self.spatial_shifted_differences)
                oc.minus_Dz.data *= -1

                # build other useful things
                oc.I = spsp.eye(dof, dof)
                oc.empty = spsp.csr_matrix((dof, dof))

                # useful intermediates
                oc.sigma_xz = make_diag_mtx(sx*sz)
                oc.sigma_xPz = oc.sigmax + oc.sigmaz

                oc.minus_sigma_zMx_Dx = make_diag_mtx((sz-sx))*oc.minus_Dx
                oc.minus_sigma_xMz_Dz = make_diag_mtx((sx-sz))*oc.minus_Dz

                oc._numpy_components_built = True

            C = self.model_parameters.C
            oc.m = make_diag_mtx((C**-2).reshape(-1,))

            self.K = spsp.bmat([[oc.m*oc.sigma_xz-oc.L, oc.minus_Dx, oc.minus_Dz],
                                [oc.minus_sigma_zMx_Dx, oc.sigmax,   oc.empty],
                                [oc.minus_sigma_xMz_Dz, oc.empty,    oc.sigmaz]])

            self.C = spsp.bmat([[oc.m*oc.sigma_xPz, oc.empty, oc.empty],
                                [oc.empty,          oc.I,     oc.empty],
                                [oc.empty,          oc.empty, oc.I]])

            self.M = spsp.bmat([[oc.m,     oc.empty, oc.empty],
                                [oc.empty, oc.empty, oc.empty],
                                [oc.empty, oc.empty, oc.empty]])

            self.dK = oc.sigma_xz
            self.dC = oc.sigma_xPz
            self.dM = oc.I
Example #20
0
    def _rebuild_operators(self):

        dof = self.mesh.dof(include_bc=True)

        oc = self.operator_components

        built = oc.get('_numpy_components_built', False)

        # build the static components
        if not built:
            # build sigmax
            sx = build_sigma(self.mesh, self.mesh.x)
            oc.sigmax = make_diag_mtx(sx)

            # build sigmaz
            sz = build_sigma(self.mesh, self.mesh.z)
            oc.sigmaz = make_diag_mtx(sz)

            # build Dx
            oc.minus_Dx = build_derivative_matrix(self.mesh,
                                                  1,
                                                  self.spatial_accuracy_order,
                                                  dimension='x',
                                                  use_shifted_differences=self.spatial_shifted_differences)
            oc.minus_Dx.data *= -1

            # build Dz
            oc.minus_Dz = build_derivative_matrix(self.mesh,
                                                  1,
                                                  self.spatial_accuracy_order,
                                                  dimension='z',
                                                  use_shifted_differences=self.spatial_shifted_differences)
            oc.minus_Dz.data *= -1

            # build other useful things
            oc.I = spsp.eye(dof, dof)
            oc.empty = spsp.csr_matrix((dof, dof))

            # useful intermediates
            oc.sigma_xz  = make_diag_mtx(sx*sz)
            oc.sigma_xPz = oc.sigmax + oc.sigmaz

            oc.minus_sigma_zMx_Dx = make_diag_mtx((sz-sx))*oc.minus_Dx
            oc.minus_sigma_xMz_Dz = make_diag_mtx((sx-sz))*oc.minus_Dz

            oc._numpy_components_built = True

        kappa = self.model_parameters.kappa
        rho = self.model_parameters.rho
        oc.m1 = make_diag_mtx((kappa**-1).reshape(-1,))
        oc.m2 = make_diag_mtx((rho**-1).reshape(-1,))
        # build heterogenous laplacian
        sh = self.mesh.shape(include_bc=True,as_grid=True)
        deltas = [self.mesh.x.delta,self.mesh.z.delta]
        oc.L = build_heterogenous_laplacian(sh,rho**-1,deltas)

        # oc.L is a heterogenous laplacian operator. It computes div(m2 grad), where m2 = 1/rho. 
        # Currently the creation of oc.L is slow. This is because we have implemented a cenetered heterogenous laplacian.
        # To speed up computation, we could compute a div(m2 grad) operator that is not centered by simply multiplying
        # a divergence operator by oc.m2 by a gradient operator.

        self.K = spsp.bmat([[oc.m1*oc.sigma_xz-oc.L, oc.minus_Dx*oc.m2, oc.minus_Dz*oc.m2 ],
                            [oc.minus_sigma_zMx_Dx, oc.sigmax,   oc.empty    ],
                            [oc.minus_sigma_xMz_Dz, oc.empty,    oc.sigmaz   ]])

        self.C = spsp.bmat([[oc.m1*oc.sigma_xPz, oc.empty, oc.empty],
                            [oc.empty,          oc.I,     oc.empty],
                            [oc.empty,          oc.empty, oc.I    ]])

        self.M = spsp.bmat([[    oc.m1, oc.empty, oc.empty],
                            [oc.empty, oc.empty, oc.empty],
                            [oc.empty, oc.empty, oc.empty]])
    def _rebuild_operators(self):

        VariableDensityAcousticTimeScalar_2D._rebuild_operators(self)

        dof = self.mesh.dof(include_bc=True)

        oc = self.operator_components

        built = oc.get('_numpy_components_built', False)

        # build the static components
        if not built:
            # build sigmax
            sx = build_sigma(self.mesh, self.mesh.x)
            oc.sigmax = make_diag_mtx(sx)

            # build sigmaz
            sz = build_sigma(self.mesh, self.mesh.z)
            oc.sigmaz = make_diag_mtx(sz)

            # build Dx
            oc.Dx = build_derivative_matrix(self.mesh,
                                            1,
                                            self.spatial_accuracy_order,
                                            dimension='x')
            oc.minus_Dx = copy.deepcopy(
                oc.Dx)  #more storage, but less computations
            oc.minus_Dx.data *= -1

            # build Dz
            oc.Dz = build_derivative_matrix(self.mesh,
                                            1,
                                            self.spatial_accuracy_order,
                                            dimension='z')
            oc.minus_Dz = copy.deepcopy(
                oc.Dz)  #more storage, but less computations
            oc.minus_Dz.data *= -1

            # build other useful things
            oc.I = spsp.eye(dof, dof)
            oc.empty = spsp.csr_matrix((dof, dof))

            # useful intermediates
            oc.sigma_xz = make_diag_mtx(sx * sz)
            oc.sigma_xPz = oc.sigmax + oc.sigmaz

            oc.minus_sigma_zMx_Dx = make_diag_mtx((sz - sx)) * oc.minus_Dx
            oc.minus_sigma_xMz_Dz = make_diag_mtx((sx - sz)) * oc.minus_Dz

            oc._numpy_components_built = True

        kappa = self.model_parameters.kappa
        rho = self.model_parameters.rho

        oc.m1 = make_diag_mtx((kappa**-1).reshape(-1, ))
        oc.m2 = make_diag_mtx((rho**-1).reshape(-1, ))

        oc.L = build_derivative_matrix_VDA(self.mesh,
                                           2,
                                           self.spatial_accuracy_order,
                                           alpha=rho**-1)

        # oc.L is a heterogenous laplacian operator. It computes div(m2 grad), where m2 = 1/rho.
        # Ian's implementation used the regular Dx operators in the PML even though the heterogeneous Laplacian with staggered derivative operators is used in the physical domain.
        # I (Bram) did not change this or investigate if this causes some problems but am noting it here for completeness.

        K = spsp.bmat([[
            oc.m1 * oc.sigma_xz - oc.L, oc.minus_Dx * oc.m2,
            oc.minus_Dz * oc.m2
        ], [oc.minus_sigma_zMx_Dx, oc.sigmax, oc.empty],
                       [oc.minus_sigma_xMz_Dz, oc.empty, oc.sigmaz]])

        C = spsp.bmat([[oc.m1 * oc.sigma_xPz, oc.empty, oc.empty],
                       [oc.empty, oc.I, oc.empty], [oc.empty, oc.empty, oc.I]
                       ]) / self.dt

        M = spsp.bmat([[oc.m1, oc.empty, oc.empty],
                       [oc.empty, oc.empty, oc.empty],
                       [oc.empty, oc.empty, oc.empty]]) / self.dt**2

        Stilde_inv = M + C
        Stilde_inv.data = 1. / Stilde_inv.data

        self.A_k = Stilde_inv * (2 * M - K + C)
        self.A_km1 = -1 * Stilde_inv * (M)
        self.A_f = Stilde_inv
Example #22
0
    def _rebuild_operators(self):

        ConstantDensityAcousticTimeScalar_2D._rebuild_operators(self)

        dof = self.mesh.dof(include_bc=True)

        oc = self.operator_components

        built = oc.get('_numpy_components_built', False)

        # build the static components
        if not built:
            # build laplacian
            oc.L = build_derivative_matrix(self.mesh, 2,
                                           self.spatial_accuracy_order)

            # build sigmax
            sx = build_sigma(self.mesh, self.mesh.x)
            oc.sigmax = make_diag_mtx(sx)

            # build sigmaz
            sz = build_sigma(self.mesh, self.mesh.z)
            oc.sigmaz = make_diag_mtx(sz)

            # build Dx
            oc.minus_Dx = build_derivative_matrix(self.mesh,
                                                  1,
                                                  self.spatial_accuracy_order,
                                                  dimension='x')
            oc.minus_Dx.data *= -1

            # build Dz
            oc.minus_Dz = build_derivative_matrix(self.mesh,
                                                  1,
                                                  self.spatial_accuracy_order,
                                                  dimension='z')
            oc.minus_Dz.data *= -1

            # build other useful things
            oc.I = spsp.eye(dof, dof)
            oc.empty = spsp.csr_matrix((dof, dof))

            # useful intermediates
            oc.sigma_xz = make_diag_mtx(sx * sz)
            oc.sigma_xPz = oc.sigmax + oc.sigmaz

            oc.minus_sigma_zMx_Dx = make_diag_mtx((sz - sx)) * oc.minus_Dx
            oc.minus_sigma_xMz_Dz = make_diag_mtx((sx - sz)) * oc.minus_Dz

            oc._numpy_components_built = True

        C = self.model_parameters.C
        oc.m = make_diag_mtx((C**-2).reshape(-1, ))

        K = spsp.bmat([[oc.m * oc.sigma_xz - oc.L, oc.minus_Dx, oc.minus_Dz],
                       [oc.minus_sigma_zMx_Dx, oc.sigmax, oc.empty],
                       [oc.minus_sigma_xMz_Dz, oc.empty, oc.sigmaz]])

        C = spsp.bmat([[oc.m * oc.sigma_xPz, oc.empty, oc.empty],
                       [oc.empty, oc.I, oc.empty], [oc.empty, oc.empty, oc.I]
                       ]) / self.dt

        M = spsp.bmat([[oc.m, oc.empty, oc.empty],
                       [oc.empty, oc.empty, oc.empty],
                       [oc.empty, oc.empty, oc.empty]]) / self.dt**2

        Stilde_inv = M + C
        Stilde_inv.data = 1. / Stilde_inv.data

        self.A_k = Stilde_inv * (2 * M - K + C)
        self.A_km1 = -1 * Stilde_inv * (M)
        self.A_f = Stilde_inv
    def _rebuild_operators(self):
        if self.mesh.x.lbc.type == 'pml' and self.compact:
          # build intermediates for the compact operator
          raise ValidationFunctionError(" This solver is in construction and is not yet complete. For variable density and compact PML.")
          dof = self.mesh.dof(include_bc=True)

          oc = self.operator_components

          built = oc.get('_numpy_components_built', False)
          oc.M = make_diag_mtx(self.model_parameters.C.squeeze()**-2)
          # build the static components
          if not built:          
            # build Dxx
            oc.Dxx = build_derivative_matrix(self.mesh,
                                                  2,
                                                  self.spatial_accuracy_order,
                                                  dimension='x',
                                                  use_shifted_differences=self.spatial_shifted_differences)
            # build Dzz
            oc.Dzz = build_derivative_matrix(self.mesh,
                                                  2,
                                                  self.spatial_accuracy_order,
                                                  dimension='z',
                                                  use_shifted_differences=self.spatial_shifted_differences)
            # build Dx
            oc.Dx = build_derivative_matrix(self.mesh,
                                                  1,
                                                  self.spatial_accuracy_order,
                                                  dimension='x',
                                                  use_shifted_differences=self.spatial_shifted_differences)
            
            # build Dz
            oc.Dz = build_derivative_matrix(self.mesh,
                                                  1,
                                                  self.spatial_accuracy_order,
                                                  dimension='z',
                                                  use_shifted_differences=self.spatial_shifted_differences)
                                                  
            # build sigma
            oc.sx, oc.sz, oc.sxp, oc.szp = self._sigma_PML(self.mesh)

            oc._numpy_components_built = True
        else:
          # build intermediates for operator with auxiliary fields
          dof = self.mesh.dof(include_bc=True)

          oc = self.operator_components

          built = oc.get('_numpy_components_built', False)

          # build the static components
          if not built:
            # build sigmax
            sx = build_sigma(self.mesh, self.mesh.x)
            oc.sigmax = make_diag_mtx(sx)

            # build sigmaz
            sz = build_sigma(self.mesh, self.mesh.z)
            oc.sigmaz = make_diag_mtx(sz)

            # build Dx
            oc.minus_Dx = build_derivative_matrix(self.mesh,
                                                  1,
                                                  self.spatial_accuracy_order,
                                                  dimension='x',
                                                  use_shifted_differences=self.spatial_shifted_differences)
            oc.minus_Dx.data *= -1

            # build Dz
            oc.minus_Dz = build_derivative_matrix(self.mesh,
                                                  1,
                                                  self.spatial_accuracy_order,
                                                  dimension='z',
                                                  use_shifted_differences=self.spatial_shifted_differences)
            oc.minus_Dz.data *= -1

            # build other useful things
            oc.I = spsp.eye(dof, dof)
            oc.empty = spsp.csr_matrix((dof, dof))

            # useful intermediates
            oc.sigma_xz  = make_diag_mtx(sx*sz)
            oc.sigma_xPz = oc.sigmax + oc.sigmaz

            oc.minus_sigma_zMx_Dx = make_diag_mtx((sz-sx))*oc.minus_Dx
            oc.minus_sigma_xMz_Dz = make_diag_mtx((sx-sz))*oc.minus_Dz

            oc._numpy_components_built = True

        kappa = self.model_parameters.kappa
        rho = self.model_parameters.rho
        oc.m1 = make_diag_mtx((kappa**-1).reshape(-1,))
        oc.m2 = make_diag_mtx((rho**-1).reshape(-1,))
        # build heterogenous laplacian
        sh = self.mesh.shape(include_bc=True,as_grid=True)
        deltas = [self.mesh.x.delta,self.mesh.z.delta]
        oc.L = build_heterogenous_laplacian(sh,rho**-1,deltas)

        # oc.L is a heterogenous laplacian operator. It computes div(m2 grad), where m2 = 1/rho. 
        # Currently the creation of oc.L is slow. This is because we have implemented a cenetered heterogenous laplacian.
        # To speed up computation, we could compute a div(m2 grad) operator that is not centered by simply multiplying
        # a divergence operator by oc.m2 by a gradient operator.

        self.K = spsp.bmat([[oc.m1*oc.sigma_xz-oc.L, oc.minus_Dx*oc.m2, oc.minus_Dz*oc.m2 ],
                            [oc.minus_sigma_zMx_Dx, oc.sigmax,   oc.empty    ],
                            [oc.minus_sigma_xMz_Dz, oc.empty,    oc.sigmaz   ]])

        self.C = spsp.bmat([[oc.m1*oc.sigma_xPz, oc.empty, oc.empty],
                            [oc.empty,          oc.I,     oc.empty],
                            [oc.empty,          oc.empty, oc.I    ]])

        self.M = spsp.bmat([[    oc.m1, oc.empty, oc.empty],
                            [oc.empty, oc.empty, oc.empty],
                            [oc.empty, oc.empty, oc.empty]])