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 ]])
    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 #5
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):

        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:
            nx = self.mesh.x.n
            nz = self.mesh.z.n

            #We actually don't need to correct the operators for the boundary nodes. But it will make the final matrix a little more sparse and therefore faster. Also, it makes is more clear that something needs to happen to the boundary. Any failure to do so can easily be seen by eye.
            self.left_boundary_nodes = np.arange(
                0, nz)  #includes left corner dirichlet nodes
            self.right_boundary_nodes = np.arange(
                (nx - 1) * nz, nx * nz)  #uncludes right corner dirichlet nodes
            self.top_boundary_nodes = np.arange(
                nz, (nx - 1) * nz,
                nx)  #does not include corner dirichlet nodes
            self.bot_boundary_nodes = np.arange(
                2 * nz - 1, nx * nz - 1,
                nx)  #does not include corner dirichlet nodes
            self.all_boundary_nodes = np.concatenate([
                self.left_boundary_nodes, self.right_boundary_nodes,
                self.top_boundary_nodes, self.bot_boundary_nodes
            ])

            # build laplacian
            oc.L = build_derivative_matrix(self.mesh, 2,
                                           self.spatial_accuracy_order)

            #Set the rows corresponding to the boundary nodes in oc.L to zero (could be any junk value). This is not necessary, but will indicate that I will have to correct the boundary values at the end of the time increment.
            oc.L = self._zero_mat_rows(oc.L, self.all_boundary_nodes)

            # 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  #just wavespeed. Don't confuse with the matrix C that used to be here for a while
        oc.m = make_diag_mtx((C**-2).reshape(-1, ))

        K = -oc.L

        M = oc.m / self.dt**2
        M_bc_zero = self._zero_mat_rows(
            M, self.all_boundary_nodes
        )  #put boundary values to zero, not really necessary because boundary values will be overwritten anyway. But easier to see that something must happen when the algorithm will default them to zero so you know you need to correct them.
        Stilde_inv = M
        Stilde_inv.data = 1. / Stilde_inv.data

        self.A_k = Stilde_inv * (2 * M_bc_zero - K)
        self.A_km1 = -1 * Stilde_inv * (M_bc_zero)
        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)

            # 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):

        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):
        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 #14
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):
        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]])
    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):
    
            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):

        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 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):
        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]])
Example #21
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
            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