0% found this document useful (0 votes)
56 views25 pages

CS 294-73 Software Engineering For Scientific Computing Lecture 8: Unstructured Grids and Sparse Matrices

This document summarizes a lecture on unstructured grids and sparse matrices for scientific computing. It discusses vector calculus concepts like gradient, divergence and Laplacian operators. It then covers the weak form of Poisson's equation and its finite element discretization. This leads to assembling the sparse matrix and computing the right-hand side. Iterative methods like point Jacobi iteration are presented for solving the resulting linear system. Representing the sparse matrix efficiently using compressed sparse row format is also summarized.

Uploaded by

Edmund Zin
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
56 views25 pages

CS 294-73 Software Engineering For Scientific Computing Lecture 8: Unstructured Grids and Sparse Matrices

This document summarizes a lecture on unstructured grids and sparse matrices for scientific computing. It discusses vector calculus concepts like gradient, divergence and Laplacian operators. It then covers the weak form of Poisson's equation and its finite element discretization. This leads to assembling the sparse matrix and computing the right-hand side. Iterative methods like point Jacobi iteration are presented for solving the resulting linear system. Representing the sparse matrix efficiently using compressed sparse row format is also summarized.

Uploaded by

Edmund Zin
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 25

CS 294-73 


Software Engineering for


Scientific Computing


Lecture 8: Unstructured grids
and sparse matrices



Back to Poisson’s equation.

09/19/2017 CS294-73 Lecture 8 2


Some Vector Calculus
@ @
Gradient operator: r = ,
@x @y
@Fx @Fy
Divergence operator: r · (Fx , Fy ) = +
@x @y
@2 @2
Laplacian: = r · (r ) = +
@x2 @y 2

•  Green’s theorem (aka integration by parts)


Z Z Z
(x)(r · (r ))(x)dx = r · r dx + (x)(r )(x)dS
@⌦
⌦ ⌦
•  If ⌘ 0 on @⌦ , then
Z Z
(x)(r · (r ))(x)dx = r · r dx

09/19/2017 CS294-73 Lecture 8 3


Weak Form of Poisson’s Equation

We want to solve Poisson’s equation (note the sign convention)


=f on ⌦
=0 on @⌦

We want find a weak solution, i.e.
Z Z
( )(x) (x)dx = f (x) (x)dx on ⌦
⌦ ⌦

For all continuous piecewise smooth test functions


. (x) with = 0 on @⌦

Applying Green’s Theorem, this is the same as

09/19/2017 CS294-73 Lecture 8 4


Finite element discretization

Step 1: we discretize our domain as


a union of triangles.

Step 2: We replace by ,a
finite-dimensional space of test
functions. For this exercise, we will
Interior Nodes = NI
use linear combinations of
continuous, piecewise linear Elements e = 0, . . . E 1
functions, indexed by interior
nodes nodes, linear on each
triangle containing the node. A
basis for this space is given
by { hn (x) : n .2 NI }.
Step 3: We also approximate the
solution as a linear combination of
the the elements in .
h
n (xn0 ) = nn0 , n0 2 N
09/19/2017 CS294-73 Lecture 8 5
Weak form -> matrix equation.

We apply the weak form of the equations to the finite-dimensional


subspace

09/19/2017 CS294-73 Lecture 8 6


Elements

Two issues:
•  Computing L.
•  Quadrature for computing b.

09/19/2017 CS294-73 Lecture 8 7


Matrix Assembly

Pseudocode: Interior Nodes =NI , Elements e = 0, . . . E 1

•  L is a matrix with mostly zero entries. But it is nice: symmetric,


positive-definite, M-matrix.
•  is a constant vector, easily computed.
•  We’re building a matrix dimensioned by nodes by iterating over
elements and building it up incrementally.

09/19/2017 CS294-73 Lecture 8 8


Getting the right-hand side

Quadrature for b: midpoint rule on each element.

More element magic.


09/19/2017 CS294-73 Lecture 8 9
Point Jacobi Iteration

Motivation: to solve La = b, we compute it as a steady-state


solution to an ODE.

If all of the eigenvalues of L are positive, then

Point Jacobi: use forward Euler to solve ODE.

Stop when the residual has been reduced by a suitable amount.

09/19/2017 CS294-73 Lecture 8 10


Matrix Properties

Our matrix has the following properties:


•  Symmetric, positive-definite:
•  Positive along diagonal.
•  Rows sum to a non-negative number:
•  For triangles sufficiently close to equilateral, the nonzero off-diagonal
elements are non-negative, i.e. .

09/19/2017 CS294-73 Lecture 8 11


Choosing a Relaxation Parameter
This leads to the following choice for our relaxation parameter.

If your grid is strongly-varying, may want to use a local relaxation


parameter (you will not be doing this in the present assignment).

09/19/2017 CS294-73 Lecture 8 12


Sparse Matrices.

•  Compact basis function space results in a linear operator (Matrix)


that has mostly zero entries.

Typical non-zero
entries in A matrix
from a finite element
problem

09/19/2017 CS294-73 Lecture 8 13


RectMDArray can hold this matrix, but wasteful

•  Wasteful in several ways


-  You waste memory storing the number 0 in a lot of places
-  You was floating point instructions performing multiplication with 0
-  You waste processor bandwidth to memory
-  You waste hits in your cache

09/19/2017 CS294-73 Lecture 8 14


Sparse Matrix representation using vectors

⎛1.5 0 0 0 0 0 0 0 ⎞
⎜ ⎟
⎜ 0 2.3 0 1.4 0 0 0 0 ⎟
⎜ 0 0 3.7 0 0 0 0 0 ⎟
⎜ ⎟
⎜ 0 − 1.6 0 2.3 9.9 0 0 0 ⎟
A=⎜
⎜ 0 0 0 0 5.8 0 0 0 ⎟⎟
⎜ 0 0 0 0 0 7.4 0 0 ⎟
⎜ ⎟
⎜ 0 0 1.9 0 0 0 4.9 0 ⎟
⎜ 0 0 0 0 0 0 0 3.6 ⎟⎠

We represent a sparse matrix


as two vectors of vectors:
vector<vector<double> >
to hold the matrix elements,
vector<vector<int> >

to hold the column indices.

Compressed-sparse-row (CSR) representation.


09/19/2017 CS294-73 Lecture 8 15
SparseMatrix Class
class SparseMatrix
{
public:
/// set up an M rows and N columns sparse matrix
SparseMatrix(int a_M, int a_N);
/// Matrix Vector multiply. a_v.size()==a_N, returns vector of size a_M
vector<double> operator*(const vector<double>& a_v) const;
///accessor functions for get and set operations of matrix elements
double& operator[](const array<int,2>&);
private: If necessary, sparse matrix automatically adds
int m_m, m_n; a new matrix element when you reference that
float m_zero; location, and initializes it to zero.
vector<vector<double> > m_data; For each non-zero entry in ‘A’ we keep one float,
vector<vector<int> > m_colIndex; and one int indicating which column it is in
};

Part of your homework 2 will be to implement this class, with a few more functions

09/19/2017 CS294-73 Lecture 8 16


Setup for Homework 2

•  Build an operator corresponding to a triangular element


discretization of the Poisson equation.
•  Use an iterative solver to solve the equation.
•  What we will provide:
-  Triangular grids, stored in files.
-  Classes for reading those files, and storing and manipulating
computing geometric information.
-  A class for writing out the solution in a form that can be viewed
by VisIt.
•  You will write:
-  A class FEPoissonOperator that generates and stores the
sparse matrix, and applies the operator to the right-hand side.
-  The SparseMatrix class.
-  An implementation of point Jacobi iteration to solve the resulting
linear system.
We will discuss the details of these in the next few slides.
09/19/2017 CS294-73 Lecture 8 17
Node , Element, and FEGrid
class Node
{
public:
Node();
Node(array<double,DIM> a_position,
const int& a_interiorNodeID,
const bool& a_isInterior);
/// Constant access to node Location in space.
const array<double,DIM>& getPosition() const;
const int& getInteriorNodeID() const;
const bool& isInterior() const;
private:
array<double,DIM> m_position; Three different integer ID’s for nodes:
bool m_isInterior; •  Where they are in the vector of all nodes
int m_interiorNodeID; making up the triangular grid;
}; •  Where they are in the vector making up the
interior nodes;
•  Where they are in the vector making up the
nodes on an element (localNodeNumber)

09/19/2017 CS294-73 Lecture 8 18


Node , Element, and FEGrid

#define VERTICES 3
class Element
{
0
public:
Element();
/// Constructor. iElt
Element(array<int,VERTICES>& a_tr); 2
/// Destructor.
1
~Element(); Local node numbers
/// local indexing to get nodeNumber. for element iElt.
const int& operator[](const int& a_localNodeNumber) const;
private:
array<int,VERTICES> m_vertices;
};

09/19/2017 CS294-73 Lecture 8 19


Node , Element, and FEGrid

class FEGrid We’re implementing this one (along with Node and Element)for
{ you – you just have to use them correctly.
public:
FEGrid();
/// Constructor by reading from file.
FEGrid(char* a_nodeFileName,char* a_elementFileName);
///Destructor.
~FEGrid(); Read in the file names from argv.
/// Get number of elements, nodes, interior nodes.
int getNumElts() const;
int getNumNodes() const;
int getNumInteriorNodes() const;

09/19/2017 CS294-73 Lecture 8 20


Node , Element, and FEGrid

... Element-centered calculus.


/// Compute gradient of basis function at node
/// a_localNodeNumber = 0,..,VERTICES-1, on element
a_eltNumber.
array<double,DIM> gradient(const int& a_eltNumber,
const int& a_localNodeNumber) const;
/// Compute centroid of element.
array<double,DIM> centroid(const int& a_eltNumber) const;
/// Compute area of element.
float elementArea(const int& a_eltNumber) const;
/// Compute value of basis function.
float elementValue(const array<double,DIM>& a_xVal,
const array<double,DIM>& a_gradient,
const int& a_eltNumber,
const int& a_localNodeNumber) const;

09/19/2017 CS294-73 Lecture 8 21


Node , Element, and FEGrid

...
/// get reference to node on an element.
const Node& getNode(const int& a_eltNumber,
const int& a_localNodeNumber) const;

private:
vector<Node > m_nodes;
vector<Element > m_elements;
int m_numInteriorNodes;
Notice what we don’t have: neither an
};
explicit mapping that gives all of the
elements touching a given node, nor
one that maps interiorNodes into
nodes. The first one we don’t need,
and the second is encoded implicitly in
Node.

09/19/2017 CS294-73 Lecture 8 22


FEPoissonOperator

class FEPoissonOperator
{
public:
FEPoissonOperator();
FEPoissonOperator(const FEGrid& a_grid);
void applyOperator(vector<float> & a_LOfPhi, const
vector<double> & a_phi) const;
void makeRHS(vector<double> & a_rhsAtNodes, const
vector<float> & a_rhsAtCentroids) const;
const FEGrid& getFEGrid() const;
const SparseMatrix& getSparseMatrix() const;
~FEPoissonOperator();
private:
SparseMatrix m_matrix; Note that a_phi is defined
only on the interior nodes, as is
FEGrid m_grid;
a_LOfPhi, a_rhsAtNodes .
};

09/19/2017 CS294-73 Lecture 8 23


Building the Sparse Matrix ( FEPoisson::FEPoisson( ... )

•  Our sparse matrix has dimensions


(getNumInteriorNodes())
•  To compute the inner product on each element,
you need gradient, elementArea.
•  Fill in incrementally, by incrementing
matrix elements corresponding to pairs of
interior nodes in each element, then iterating
over elements
(getNode(...),Node::InteriorNodeID()
).

Sparse matrix automatically


adds new matrix element when
you index that location, and
09/19/2017 CS294-73 Lecture 8 initializes it to zero.
Building the Right-hand Side (makeRHS)

•  Our right-hand side is an -


dimensional vector
(getNumInteriorNodes()),
while our input f a vector of values
evaluated at the centroids of
elements (getNumElements(),
centroid(...) ).
•  Fill in b incrementally, by iterating
over elements , then computing
interior nodes in each element
(getNode(...),
Node::InteriorNodeID()).
•  Use elementValue(...),
elementArea(...) to compute
contribution from each node in an
element.

09/19/2017 CS294-73 Lecture 8 25

You might also like