fn solve_pressure(&mut self, delta_t: f64, tolerance: f64, max_iterations: usize) {
        let delta_x_squared = self.grid_cell_size * self.grid_cell_size;
        let scale = delta_t / (self.density * delta_x_squared);

        let mut max_delta = 0.0_f64;

        for _ in 0..max_iterations {
            max_delta = 0.0;
            for i in 0..self.w {
                for j in 0..self.h {
                    let mut diagonal = 0.0;
                    let mut off_diagonal = 0.0;

                    // In this function, we are essentially solving an equation
                    // `Ap = b`, where `p` contains the unknown pressure at each
                    // grid cell location.
                    //
                    // First, we assemble the coefficients for the row of `A`
                    // corresponding to cell (i, j). Note that because each cell
                    // has at most 4 neighbors, `A` will be extremely sparse.
                    //
                    // The entry corresponding to p(i, j) will have a coefficient
                    // of the form:
                    //
                    //          [Δt / (ρ * Δx * Δx)] * n
                    //
                    // where `n` is the number of neighboring cells that contain
                    // either fluid or air. This entry would appear along the
                    // diagonal of the matrix `A`, which is why we accumulate
                    // this value in a variable named `diag`.
                    //
                    // Entries corresponding to the cells neighboring cell (i, j)
                    // will have coefficients of the form:
                    //
                    //          -[Δt / (ρ * Δx * Δx)]
                    //
                    // For now, we assume that all solid boundaries are stationary.

                    // Check if this cell is on the left, vertical edge.
                    if i > 0 {
                        diagonal += scale;
                        off_diagonal -= scale * self.p.get(i - 1, j);
                    }
                    // Check if this cell is on the bottom, horizontal edge.
                    if j > 0 {
                        diagonal += scale;
                        off_diagonal -= scale * self.p.get(i, j - 1);
                    }
                    // Check if this cell is on the right, vertical edge.
                    if i < (self.w - 1) {
                        diagonal += scale;
                        off_diagonal -= scale * self.p.get(i + 1, j);
                    }
                    // Check if this cell is on the top, horizontal edge.
                    if j < (self.h - 1) {
                        diagonal += scale;
                        off_diagonal -= scale * self.p.get(i, j + 1);
                    }

                    let p_next = (self.rhs.get(i, j) - off_diagonal) / diagonal;

                    // Can we exit the solver?
                    let abs_diff = (self.p.get(i, j) - p_next).abs();
                    max_delta = max_delta.max(abs_diff);

                    // Update the pressure at cell (i, j).
                    *self.p.get_mut(i, j) = p_next;
                }
            }

            // If none of the values drastically changed, we exit
            // the outer loop.
            if max_delta < tolerance {
                break;
            }
        }
    }
/// Project using the Gauss-Seidel method, which is an iterative
/// approach to solving systems of linear equations.
Project using the Gauss-Seidel method, which is an iterative
approach to solving systems of linear equations.
Project using the Gauss - Seidel method which is an iterative approach to solving systems of linear equations .
fn solve_pressure(&mut self, delta_t: f64, tolerance: f64, max_iterations: usize) {
        let delta_x_squared = self.grid_cell_size * self.grid_cell_size;
        let scale = delta_t / (self.density * delta_x_squared);
        let mut max_delta = 0.0_f64;
        for _ in 0..max_iterations {
            max_delta = 0.0;
            for i in 0..self.w {
                for j in 0..self.h {
                    let mut diagonal = 0.0;
                    let mut off_diagonal = 0.0;
                    // In this function, we are essentially solving an equation
                    // `Ap = b`, where `p` contains the unknown pressure at each
                    // grid cell location.
                    //
                    // First, we assemble the coefficients for the row of `A`
                    // corresponding to cell (i, j). Note that because each cell
                    // has at most 4 neighbors, `A` will be extremely sparse.
                    //
                    // The entry corresponding to p(i, j) will have a coefficient
                    // of the form:
                    //
                    //          [Δt / (ρ * Δx * Δx)] * n
                    //
                    // where `n` is the number of neighboring cells that contain
                    // either fluid or air. This entry would appear along the
                    // diagonal of the matrix `A`, which is why we accumulate
                    // this value in a variable named `diag`.
                    //
                    // Entries corresponding to the cells neighboring cell (i, j)
                    // will have coefficients of the form:
                    //
                    //          -[Δt / (ρ * Δx * Δx)]
                    //
                    // For now, we assume that all solid boundaries are stationary.
                    // Check if this cell is on the left, vertical edge.
                    if i > 0 {
                        diagonal += scale;
                        off_diagonal -= scale * self.p.get(i - 1, j);
                    }
                    // Check if this cell is on the bottom, horizontal edge.
                    if j > 0 {
                        diagonal += scale;
                        off_diagonal -= scale * self.p.get(i, j - 1);
                    }
                    // Check if this cell is on the right, vertical edge.
                    if i < (self.w - 1) {
                        diagonal += scale;
                        off_diagonal -= scale * self.p.get(i + 1, j);
                    }
                    // Check if this cell is on the top, horizontal edge.
                    if j < (self.h - 1) {
                        diagonal += scale;
                        off_diagonal -= scale * self.p.get(i, j + 1);
                    }
                    let p_next = (self.rhs.get(i, j) - off_diagonal) / diagonal;
                    // Can we exit the solver?
                    let abs_diff = (self.p.get(i, j) - p_next).abs();
                    max_delta = max_delta.max(abs_diff);
                    // Update the pressure at cell (i, j).
                    *self.p.get_mut(i, j) = p_next;
                }
            }
            // If none of the values drastically changed, we exit
            // the outer loop.
            if max_delta < tolerance {
                break;
            }
        }
    }
fn solve_pressure ( & mut self , delta_t : f64 , tolerance : f64 , max_iterations : usize ) { let delta_x_squared = self . grid_cell_size * self . grid_cell_size ; let scale = delta_t / ( self . density * delta_x_squared ) ; let mut max_delta = 0.0_f64 ; for _ in 0 .. max_iterations { max_delta = 0.0 ; for i in 0 .. self . w { for j in 0 .. self . h { let mut diagonal = 0.0 ; let mut off_diagonal = 0.0 ; // In this function, we are essentially solving an equation // `Ap = b`, where `p` contains the unknown pressure at each // grid cell location. // // First, we assemble the coefficients for the row of `A` // corresponding to cell (i, j). Note that because each cell // has at most 4 neighbors, `A` will be extremely sparse. // // The entry corresponding to p(i, j) will have a coefficient // of the form: // //          [Δt / (ρ * Δx * Δx)] * n // // where `n` is the number of neighboring cells that contain // either fluid or air. This entry would appear along the // diagonal of the matrix `A`, which is why we accumulate // this value in a variable named `diag`. // // Entries corresponding to the cells neighboring cell (i, j) // will have coefficients of the form: // //          -[Δt / (ρ * Δx * Δx)] // // For now, we assume that all solid boundaries are stationary. // Check if this cell is on the left, vertical edge. if i > 0 { diagonal += scale ; off_diagonal -= scale * self . p . get ( i - 1 , j ) ; } // Check if this cell is on the bottom, horizontal edge. if j > 0 { diagonal += scale ; off_diagonal -= scale * self . p . get ( i , j - 1 ) ; } // Check if this cell is on the right, vertical edge. if i < ( self . w - 1 ) { diagonal += scale ; off_diagonal -= scale * self . p . get ( i + 1 , j ) ; } // Check if this cell is on the top, horizontal edge. if j < ( self . h - 1 ) { diagonal += scale ; off_diagonal -= scale * self . p . get ( i , j + 1 ) ; } let p_next = ( self . rhs . get ( i , j ) - off_diagonal ) / diagonal ; // Can we exit the solver? let abs_diff = ( self . p . get ( i , j ) - p_next ) . abs ( ) ; max_delta = max_delta . max ( abs_diff ) ; // Update the pressure at cell (i, j). * self . p . get_mut ( i , j ) = p_next ; } } // If none of the values drastically changed, we exit // the outer loop. if max_delta < tolerance { break ; } } }
Project using the Gauss-Seidel method, which is an iterative
approach to solving systems of linear equations.
Project using the Gauss - Seidel method which is an iterative approach to solving systems of linear equations .
&mut self
delta_t
f64
tolerance
f64
max_iterations
usize
&mut self
delta_t
f64
tolerance
f64
max_iterations
usize