Professional Documents
Culture Documents
Three
Variational Methods
Using H0, H1, and H2 Type
Objects
In functional analysis, H0 (= L2 = W0,2), H1 (=W1,2), and H2 (= W2,2) are Sobolev spaces. They are also Hilbert spaces that has the inner product defined. For the users of VectorSpace C++ Library, it is sufficient to know
H0, H1, and H2 type objects are integrable objects (among them H1 and H2 type objects are also differentiable
objects). The applications such as those in variational methods can be easily implemented with H0, H1, and H2
type objects. C++ programs using VectorSpace C++ Library in this chapter are projects contained in project
workspace file Hn.dsw under directory vs\ex\Hn.
3.1.1 Quadrature
Numerical integration is also known as quadrature, which means the process of finding a square equal in area
to a given area. The trapezoidal rule and the Simpsons rule are the most fundalmental ones that are introduced in
calculus1. For a one dimensional function f(x), the trapezoidal rule and Simpsons rule evaluate the areas of the
1. For example, p. 602-609, in T.M. Apostol, 1969, Calculus, 2nd eds., vol. 2, Blaisdell Publishing Company, Waltham,
Mass.
Chapter
Simpsons rule
f(x)
quadratic interpolation
linear interpolation
x0 h = x1 - x0
f(x)
x1
x0
x1
x2
x f ( x )dx
Trapezoidal rule:
Simpsons rule:
1
1
= h --- f ( x 0 ) + --- f ( x 1 ) + O ( h 3 f)
2
2
1
4
1
f ( x )dx = h --- f ( x 0 ) + --- f ( x 1 ) + --- f ( x 2 ) + O ( h 5 f ( 4 ) )
3
3
3
0
x2
Eq. 31
where O( ) indicates order of errors as a function of size h and derivatives of f(x). The two methods are illustrated in Figure 31 . Formula without the necessity of evaluating the function at the end-points (open-type
formula) exists; e.g.,
x5
x f ( x )dx
0
55
5
5
55
= h ------ f ( x 1 ) + ------ f ( x 2 ) + ------ f ( x 3 ) + ------ f ( x 4 ) + O ( h 5 f ( 4 ) )
24
24
24
24
Eq. 32
We notice that f(x0) and f(x5) are not in Eq. 32. So, if a singularity of f(x) presents at any such end-points it can
be avoided. Repeatedly using the trapezoidal rule or Simpsons rule of Eq. 31 in many smaller segments yields
the extended-type formula
Extended trapezoidal rule:
( x N x 0 ) 3 f
1
1
-----------------------------
--f
(
x
)dx
h
f
(
x
)
+
f
(
x
)
+
f
(
x
)
+
+
f
(
x
)
+
f
(
x
)
O
=
+
1
2
N1
x 0
(N + 1)2
2 0
2 N
xN
1
4
2
4
2
1
1
4
f ( x )dx = h --- f ( x 0 ) + --- f ( x 1 ) + --- f ( x 2 ) + --- f ( x 3 ) + + --- f ( x N 2 ) + --- f ( x N 1 ) + --- f ( x N ) + O --------------------4-
(N + 1)
3
3
3
3
3
3
3
Eq. 33
166
H0 Type Objects
The above formula are all expressible as
N
hci f ( xi )
Eq. 34
i=0
where ci is an array of coefficients in Eq. 31, Eq. 32, and Eq. 33. They all use equally spaced intervals (h = x i+1
- xi), and f(xi) are evaluated at positions xi = x0 + i h. For example, an integration problem
2
( x 2 2x + 1 ) dx
Eq. 35
using extended Simpsons rule can be written in C++ with VectorSpace C++ Library as (see project:
extended_simpson)
// QUADRATURE: EXTENDED SIMPSONS RULE
const int N = 11;
// number of integration segments
double c[N] = {1.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, // ci
2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0,
2.0/3.0, 4.0/3.0, 1.0/3.0},
X[2] = {1.0, 2.0},
// starting and end points
h = (X[1]-X[0])/N;
// size of one segment
Quadrature qp(c, X[0], X[1], N);
// domain [a, b], 11 integration points
// THE INTEGRATION
2
H0 x(qp);
( x 2 2x + 1 ) dx = 1/3
C0 area = (x.pow(2) - 2 * x + 1) | J(h);
// 1
cout << area << endl;
// 0.333334
The class Quadrature takes arguments of (1) array of coefficients, (2) starting and end points, and (3) number
of integration points. VectorSpace C++ Library uses integration operator H0::operator | (const J&), where
another new class J, the Jacobian, may take the size of an integration segment as its arguments. The reason of
using class J is to be compatible with more complicated integration domain and will become more evident
later. For now, in view of Eq. 34, we define referential coordinate (with domain [0, 1]) for every integration
segment. Hence, the length of each referential integration segment is || = 1. The actual integration segement
domain [xi, xi+1] is mapped with a linear coordinate transformation rule x = x() = (1-) xi + xi+1. The Jacobain
for the segement is J = dx/d = (xi+1-xi) / || = h, the length of the segment per se. For various quadrature rules
discussed in the above only the values of the coefficient array need to be defined differently.
Higher order approximation can be obtained, in general, with greater number of function evaluations, which,
unfortunately, increases the computational cost. The significant computational improvement can be achieved if
we can reduce the number of function evaluations while maintain higher order approximation. The idea of Gaussian quadrature is to choose not only the values of ci but also the locations for the function evaluation (i.e., the
integration point coordinates). Therefore, we have two times the degree of freedom to improve the order of
approximation. For example, we seek a two-point integration rule to exactly integrate a general cubic polynominal. Let
Workbook of Applications in VectorSpace C++ Library
167
Chapter
Eq. 36
where i are the coefficients for the cubic function f(). First we normalize the integration domain to [-1, 1], and
assume that the integration points are spaced symmetrically and weighted equally. Therefore, W 0 = W1 and 0 =
-1. Integration of Eq. 36 at the interval of [-1, 1] gives
f ( ) d = 2 0 + 2--- 2
3
Eq. 37
The two-point Gaussian quadrature wieghting coefficients Wi at integration points i gives (with i = 0, 1)
Eq. 38
Eq. 39
For arbitary values of 0 and 2 Eq. 39 must always hold. Therefore, we obtain weightings W0 = W1 = 1, and
integration point coordinates 0 = - 1 = -1 / 3 . Tabulated values of Wi and i with more integration points can
be found in Stroud and Secrest1. Gaussian integration can be applied to integral domains other than the normalized interval [-1, 1]. For example, for an actual integration domain of [1, 2], we can define a linear interpolation
function f(x) = f(), with the natural coordinate (Gaussian integration domain in [-1, 1]), as
1
1
f() = --- (1-) f(x0) + --- (1+) f(x1)
2
Eq. 310
where we can check f(1) = f(x0) and f(1) = f(x1). We can also define a similar linear coordinate transformation
1
1
x() = --- (1-) x0 + --- (1+) x1
2
Eq. 311
We note that the forms of the interpolation function and the coordinate transformation do not have to be the same
as they are in this example. Again, we can check at the starting point x(1) = x0, and at the end point x(1) = x1.
Then, without loss of generality for a multi-dimensional case, we write
f ( x ) dx
f ( x )det x
------ d = f ( x )J d
Wi f ( xi )Ji
i=0
1. A.H. Stroud and D. Secrest, 1966, Gaussian quadrature formulas, Prentice-Hall, Englewood Cliffs, N.J.
168
Eq. 312
H0 Type Objects
where is the integration domain, and is the normalized integration domain. Define J = x/ as the Jacobian matrix, and J = det J =det ( x/ ) is the Jacobian. In an one-dimensional case, if the coordinate transformation rule x() is chosen to be linear such as Eq. 310, Ji = dx/d = (x1-x0)/2 equal the same constant.
Comparing Eq. 312 with Eq. 34, we find that (1) the constant Ji is in place of segment size h, (2) the
wieghting coefficients Wi is in place of the coefficients ci and (3) the integration point coordinates in Eq. 312 is
now taking from tabulated numbers instead of simply computed from a equally spaced formula of xi = x0 + i h.
The integration problem in Eq. 35,
1( x 1 ) 2 dx
2
using Gauss quadrature, can be re-written in C++ with VectorSpace C++ Library as (project:
linear_coordinate_transformation)
double X[2] = {1.0, 2.0};
Quadrature qp(1, 2);
H0 z(qp),
x = (1-z) /2*X[0] + (1+z)/2 * X[1];
J omega((X[1]-X[0])/2);
C0 area = (x-1).pow(2) | omega;
cout << area << endl;
The Gaussian quadrature is the default integration method in VectorSpace C++ Library, because of its higher
order approximation. Database for both the weighting coefficients and integration points of the Gaussian quadrature are hidden from end-users. The users, however, need to input number of dimensions and number of integration points in the constructor of class Quadrature. In the present example, since the coordinate transformation is
linear the Jacobian is constant everywhere along the integral line; i.e., J = (x1-x0)/2, where 2 is the length of the
integration domain, since the natural coordinate is defined in the interval of [-1, 1]. The result of the integration is 0.333334. A quadratic coordinate tranformation case is presented later. We note that the restriction of constant values for the Jacobian can be relaxed when we introduce H1 type later.
We have seen various integration methods, and we have inferred the basic elements in object-oriented modeling of an integrable class. Now we are ready to deduce the data abstraction for constructing classes in H0 type.
H0 type objects are generalization of C0 type objects with integration capability. As in C0 type objects, H0 type
objects are subdivided into primary objects and utility objects. The primary objects include Integrable_Scalar,
Integrable_Vector, and Integrable_Matrix. These objects deserve detailed description. For the utility objects,
Integrable_Subvector and Integrable_Submatrix, it is suffice to say that they are mostly comformable to their C0
counterparts.
3.1.2 Integrable_Scalar
An Integrable_Scalar, H0::H0(const Quadrature&), contains a reference to a Quadrature class instance,
and a pointer array of C0 *u. The dual abstraction, discussed on page 97, is also used to model the high-level
169
Chapter
mathematics and to encapsulate the details of low-level memory management. The pointer array of C0, u, is
referring to double *v.
Integrable_Scalar Object
x
C0* of Scalaru
TABLE 3.1 Dual abstraction of an Integrable_Scalar.
Physical Memory
double*v
Constructors
Two examples of using variable dedicated constructor for H0 type Integrable_Scalar have been shown on
page 167 and page 169 for Simpsons rule and Gaussian quadrature, respectively. We show a few more non-trivial examples, in the followings. Consider a diffusion problem, e.g., heat conduction or chemical diffusion, in the
form of a differential equation1
2
d u
--------2 = f ( x ) , with 0 < x < 1, u ( 0 ) = , u ( 1 ) =
dx
Eq. 313
where f(x) is the source term. The solution to Eq. 313 can be expressed in integral form as
1
u( x) =
g ( x, )f ( )d + ( 1 x ) + x
Eq. 314
where g(x, ) is Greens function. The physical interpretation of the Greens function is that g(x, ) is the temperature (or concentration) sampling at x when a unit concentrated point source is located at . Therefore, g(x, )
satisfies Eq. 313; i.e., with g(x, ) in place of u(x) in the differential equation. We also require, at the location x
= , g(x, ) to be continuous. And the net flux of the infinitesimal control line segment at x = equals to the
source intensity; i.e., g(+, ) - g(-, ) = -1, which is also known as the jump condition. From the above conditions, the Greens function can be solved as
x ( 1 ), 0 < x <
g ( x, ) =
( 1 x ), < x < 1
Eq. 315
u ( x ) = ( 1 x ) f ( )d+ x ( 1 )f ( )d + ( 1 x ) + x
0
1. p. 42 in I. Stakgold, 1979, Greens function and boundary value problems, John Wiley & Sons, New York.
170
Eq. 316
H0 Type Objects
where at interval [0, x] of the integration domain < x, so the second line of Eq. 315 is applicable, and at the
interval [x, 1] of the integration domain, x < , the first line of Eq. 315 is applicable .
For a specific case with source distribution as f(x) = sin (x), and homogeneous boundary conditions = =
0, we can compute ten point values of the solution u(x) at interval of h = 0.1. Program Listing 31 implemented
the solution using Eq. 316. The analytical solution corresponding to this source distribution is u = - (1/ 2)
sin(x), which is used to compare with the computed result of the integral equation. They only differs after the
sixth digit after the decimal point ( see TABLE 3.2.)
#include include/vs.h
int main() {
double const PI = 3.141592654;
double const alpha = 0.0; double const beta = 0.0;
double x = 0.0,
w[11] = {1.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0,
4.0/3.0, 1.0/3.0};
for(int i = 0; i < 11; i++) {
Quadrature q1(w, 0.0, x, 11), q2(w, x, 1.0, 11);
H0 z1(q1), z2(q2),
f_1 = sin(PI*z1), f_2 = sin(PI*z2);
C0 integ_1, integ_2;
if(i !=0) integ_1 &= (1-x)*( (z1*f_1) | J(x/10.0); else integ_1 &= C0(0.0);
if(i !=10) integ_2 &= x*( ((1-z2)*f_2) | J((1-x)/10.0); else integ_2 &= C0(0.0);
double u = (double)(integ_1+integ_2) + (1-x)*alpha+x*beta;
cout << u( << x << ): << u << endl;
if(i != 10) x += 0.1;
}
return 0;
}
==0
extended Simpsons rule
f(x) = sin x
x
( 1 x ) f ( )d + x ( 1 )f ( )d
- (1/ 2) sin(x)
Program Listing 31
0.0
0.000000
0.000000
0.1
0.031310
0.031311
0.2
0.059555
0.059555
0.3
0.081971
0.081970
0.4
0.096362
0.096361
0.5
0.101321
0.101320
0.6
0.096362
0.096361
0.7
0.081971
0.081970
0.8
0.059555
0.059555
171
Chapter
- (1/ 2) sin(x)
Program Listing 31
0.9
0.031310
0.031311
1.0
0.000000
0.000000
Eq. 317
g ( x, )f ( )d
Eq. 318
The Greens function should satisfy Eq. 317 and should be continuous at x = . The jump condition is
k()[g(+,)-g(-, )] = -1. These conditions lead to the Greens function for this problem as
g ( x, ) =
- dy,
--------k(y)
0<x<
Eq. 319
- dy,
--------k(y)
<x<1
Substituting Eq. 319 into Eq. 318, with the case of k(x) = (1+x), and f(x) = x, gives
u(x) =
ln ( 1 + )f ( )d + ln ( 1 + x ) f ( )d
0
Eq. 320
Eq. 321
Program Listing 32 implements Eq. 320, which are codes from the Program Listing 31 with only very slight
modifications. The results of Program Listing 32 are listed in TABLE 3.2. for comparison with the analytical
solution. Only last three points in the interval of [0.8, 1.0] has 1.e-6 in error. We emphasize that Eq. 316 and Eq.
320 are much more complicated than that of the corresponding analytical solutions. However, analytical solutions are only possible when the given f(x) and k(x) happen to give an analytical solvable differential equations,
while the Greens function method is quite general for less restricted forms of f(x) and k(x). This concludes the
example for the Integrable_Scalar object of H0 type.
172
H0 Type Objects
#include include/vs.h
int main() {
double x = 0.0,
w[11] = {1.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0,
4.0/3.0, 1.0/3.0};
for(int i = 0; i < 11; i++) {
Quadrature q1(w, 0.0, x, 11), q2(w, x, 1.0, 11);
H0 z1(q1), z2(q2);
C0 integ_1, integ_2;
if(i !=0) integ_1 &= ( (z1*log(1+z1)) | J(x/10.0); else integ_1 &= C0(0.0);
if(i !=10) integ_2 &= log(1+x)*( z2 | J((1-x)/10.0); else integ_2 &= C0(0.0);
double u = (double)(integ_1+integ_2) ;
cout << u( << x << ): << u << endl;
if(i != 10) x += 0.1;
}
return 0;
}
ln ( 1 + )f ( )d + ln ( 1 + x ) f ( )d
0
Listing 32 Solving diffusion problem with k(x) = 1+x and f(x) = x using integral expression (traget:
green_diffusion_variable_conductivity).
-x2/4 +x/2
Program Listing 32
0.0
0.000000
0.000000
0.1
0.047500
0.047500
0.2
0.090000
0.090000
0.3
0.127500
0.127500
0.4
0.160000
0.160000
0.5
0.187500
0.187500
0.6
0.210000
0.210000
0.7
0.227500
0.227500
0.8
0.240000
0.240001
0.9
0.247500
0.247501
1.0
0.250000
0.250001
173
Chapter
The constant strings used for the virtual constructors (for example, using macro definition H0 x =
INTEGRABLE_SCALAR(const char*, ...)) and the autonomous virtual constructor (for example, using H0 x
= H0(const char*, ...)) are shown in the following box.
priority
by reference
H0&
H0 type Integrable_Scalar object
1
H0*
a pointer to H0 type Integrable_Scalar object
2
double*, const Quadrature&, int, int
3
double pointer, Quadrature, m_row_size, m_col_size
by value
const Quadrature&
const H0&
const H0*
Quadrature
H0 type Integrable_Scalar object
pointer to H0 type Integrable_Scalar object
4
5
6
The second operator invoked, operator +(const C0&, const H0&) is a binary operator which is declared a
friend function (operator) to H0 class. These operators, needed for the promotion operation, are not listed in the
box for simplicity.
174
H0 Type Objects
operator or function
remark
symbolic operators
H0& operator &= ( )
H0& operator = ( )
H0 operator & ( ) const
H0 operator && () const
H0 operator | ( ) const
H0 operator || () const
assignment by reference
assignment by value
column concatenation
one-by-one column concatenation
row concatenation
one-by-one row concatenation
arithmatic operators
H0 operator + ( ) const
H0 operator - ( ) const
H0 operator + (const H0&) const
H0 operator - (const H0&) const
H0 operator * (const H0&) const
H0 operator / (const H0&) const
H0& operator += (const H0&)
H0& operator -= (const H0&)
H0& operator *= (const H0&)
H0& operator /= (const H0&)
positive
negative
addition
subtraction
multiplication
multiplication
replacement addition
replacement subtraction
replacement multiplication
replacement division
unary
unary
logic operators
int operator == (const H0&) const
int operator != (const H0&) const
int operator >= (const H0&) const
int operator <= (const H0&) const
int operator > (const H0&) const
int operator < (const H0&) const
equal
not equal
greater or equal
less or equal
greater
less
TRUE == 1
FALSE == 0
functions
H0 pow(int) const
H0 sqrt(const C0&) const
H0 exp(const C0&) const
H0 log(const C0&) const
H0 sin(const C0&) const
H0 cos(const C0&) const
power
square root
exponent
log
sin
cos
Partial listing of H0 type Integrable_Scalar class arithmetic operators, logic operators and functions.
175
Chapter
3.1.3 Integrable_Vector
Constructors
A dedicated constructor of an Integrable_Vector, H0::H0(int, double*, const Quadrature&), contains a reference to a Quadrature instance, and a pointer array of C0 *u. The dual abstraction is used. The pointer array
of C0, u, is referring to a double *v.
Integrable_Vector Object
x
C0* of Vectoru
TABLE 3.4. Dual abstraction of an Integrable_Vector.
Physical Memory
double*v
//
// 1-dimension, 2-points Gaussian
// natural coordinates
// Integrable_Vector object of H0 type
// N0 = (-1)/2
// N1= 1-2
// N2 = (+1)/2
// y = Nifi
// H0::operator | (const J&)
// 1/3
Eq. 322
We mentioned in previous section on the subject of Integrable_Scalar that since we have not yet introduced H1
type objects, we need a linear coordinate transformation to have constant values of the Jacobian throughout the
integration domain. We can make Eq. 322 consistent with a linear coordinate transformation rule by enforcing
x1 = (x0+x2)/2
i.e., x1 has to be the middle point of the segment. Substituting this relation into Eq. 322 to eliminate x1 yields
1
1
x() = --- (1-) x0 + --- (1+) x2
2
176
H0 Type Objects
f(x2) = 3
f(x3) = 2
f(x1) = 2
f(x0) = 1
x2 = (1,1)
x3 = (0,1)
x1 = (1,0)
x0 = (0,0)
Figure 32 Integration of a plane surface with a square integration domain.
which is exactly the linear coordinate transformation rule of Eq. 311. Therefore, we have J = (2-1)/2 = 0.5 as
used in the above example.
We show an example of a 2-D problem using Gaussian quadrature. Again, without H1 type objects for differentiation operation, we restrict the integration domain to be a square or a rhombic region in order to have constant Jacobian everywhere. In this example, a set of bilinear interpolation functions are used
1
1
1
1
f(, ) = --- (1)(1) f(x0) + --- (1+)(1) f(x1) + --- (1+)(1+) f(x2) + --- (1)(1+) f(x3)
4
Eq. 323
Assuming a plane as shown in , f(x0) = 1, f(x1) = 2, f(x2) = 2, and f(x3) = 3, where x0 = (0, 0), x1 = (1, 0),x2 = (1,
1), and x3 = (0, 1). The constant Jacobian of the problem is J = 1/4, where the area of the referential domain
1 1 and 1 1 , is 4. (in project: integration_2d).
double f[4] = {1.0, 2.0, 2.0, 3.0};
// f(xi)
Quadrature qp(2, 4);
// 2-D, and 2x2 (= 4) integration points
H0 z(2, (double*)0, qp), zai, eta;
// natural coordinates
zai &= z[0], eta &= z[1];
// alias of elements in the Integrable_Vector
C0 volume = ((1-zai)*(1-eta)/4 *f[0]
// f ( , ) d
+ (1+zai)*(1-eta)/4*f[1]
+(1+zai)*(1+eta)/4*f[2]
+(1-zai)*(1+eta)/4*f[3]) | J(0.25);
cout << volume << endl;
// 2.0
177
Chapter
The constant strings used for the virtual constructors (for example, using macro definition in H0 x =
INTEGRABLE_VECTOR(const char*, ...)) and the autonomous virtual constructor (for example, using H0 x
= H0(const char*, ...)) are shown in the following box.
virtual constructor string
by reference
H0&
H0*
int, double*, const Quadrature&,
int, int
by value
int, const Quadrature&
const H0*
int, H0&, int, const Quadrature
priority
H0 type Integrable_Vector
a pointer to H0 type Integrable_Vector
length, double* != 0, Quadrature
m_row_size, m_col_size
length, Quadrature
H0*
length, H0, starting index, Quadrature
(the only one for reference Integrable_Vector)
178
H0 Type Objects
operator or function
VectorSpace C++
remark
symbolic operators
H0& operator &= ( )
H0& operator = ( )
H0& operator [] (int)
H0 operator & ( ) const
H0 operator && () const
H0 operator | ( ) const
H0 operator || ( ) const
assignment by reference
assignment by value
selector
column concatenation
one-by-one column concatenation
row concatenation
one-by-one row concatenation
arithmetic operators
H0 operator ~ ( ) const
H0 operator + ( ) const
H0 operator - ( ) const
H0 operator + (const H0&) const
H0 operator - (const H0&) const
H0 operator * (const H0&) const
H0 operator %(const H0&) const
H0 operator / (const H0&) const
H0& operator += (const H0&)
H0& operator -= (const H0&)
H0& operator *= (const H0&)
H0& operator /= (const H0&)
logic operators
int operator == (const H0&) const
int operator != (const H0&) const
int operator >= (const H0&) const
int operator <= (const H0&) const
int operator > (const H0&) const
int operator < (const H0&) const
equal
not equal
greater or equal
less or equal
greater
less
return scalar
return matrix
return matrix
TRUE == 1
FALSE == 0
functions
int length() const
double norm(int = 2) const
double norm(const char*) const
H0 pow(int) const
H0 sqrt(const H0&) const
H0 exp(const H0&) const
H0 log(const H0&) const
H0 sin(const H0&) const
H0 cos(const H0&) const
179
Chapter
3.1.4 Integrable_Matrix
Constructors
A dedicated constructor of an Integrable_Matrix, H0::H0(int, int, double*, const Quadrature&), contains a
reference to a Quadrature instance, and a pointer array of C0 *u (pointer to C0 type Matrix object). The dual
abstraction is also used. The pointer array of C0, u, is referring to a double *v.
Integrable_Matrix Object
x
C0* of Matrixu
TABLE 3.5. Dual abstraction of an Integrable_Matrix.
Physical Memory
double*v
A simple example of an Integrable_Matrix is the consistent mass matrix; e.g., M in Eq. 3217 on
page 258, generated from the tensor product operation (using % in VectorSpace C++ Library ) of two
Integrable_Vector objects of H0 type. Integrable_Matrix is often encountered in variational calculus to be introduced later in this Chapter.
The constant strings used for the virtual constructors (for example, using macro definition in H0 x =
INTEGRABLE_MATRIX(const char*, ...)) and the autonomous virtual constructor (for example, using H0 x
= H0(const char*, ...)) are shown in the following box.
priority
H0 type Matrix
a pointer to H0 type Matrix
row-length, column-length, double* != 0,
memory-row-length, memory-column-length
180
10
11
12
13
14
H0 Type Objects
operator or function
remark
functions
H0 pow(int) const
H0 sqrt(const H0&) const
H0 exp(const H0&) const
H0 log(const H0&) const
H0 sin(const H0&) const
H0 cos(const H0&) const
rank of a Matrix
identity Matrix
condition number of a Matrix
inverse of a Matrix
determinant of a Matrix
Partial listing of H0 type Integrable_Matrix class arithmetic operators, logic operators and functions.
181
Chapter
symbolic operators
H0& operator &= ( )
H0& operator = ( )
H0& operator [ ] (int)
H0& operator( )(int)
H0& operator ( )(int, int)
H0 operator & ( ) const
H0 operator && () const
H0 operator | ( ) const
H0 operator || ( ) const
assignment by reference
assignment by value
row selector
column selector
element selector
column concatenation
one-by-one column concatenation
row concatenation
one-by-one row concatenation
arithmetic operators
H0 operator + ( ) const
H0 operator - ( ) const
H0 operator + (const C0&) const
H0 operator - (const C0&) const
H0 operator * (const C0&) const
H0 operator / (const C0&) const
H0& operator += (const C0&)
H0& operator -= (const C0&)
H0& operator *= (const C0&)
H0& operator /= (const C0&)
transpose
matrix decomposition
logic operators
int operator == (const H0&) const
int operator != (const H0&) const
int operator >= (const H0&) const
int operator <= (const H0&) const
int operator > (const H0&) const
int operator < (const H0&) const
equal
not equal
greater or equal
less or equal
greater
less
functions
int row_length() const
int col_length() const
H0 norm(in) const
H0 norm(const char*) const
Partial listing of H0 type Integrable_Matrix class arithmetic operators, logic operators and functions.
182
remark
TRUE == 1
FALSE == 0
We can consider H1 and H2 types as natural extensions of C1 and C2 types. That is the high-level data
abstraction in the dual abstraction of H1 and H2 type object is a pointer array to C1 and C2 type objects (i.e.,
C1*, or C2*), and the length of the pointer array equals the number of quadrature points. The low-level data
abstraction is pointers to double (double*) to represent the memory space of the base point, tangent, and tangent
of tangent, in which the values of all quadrature points are connected together in a continuous memory space for
efficient memory management. A cross-relation of the dual abstraction is shown in Figure 33. The high-level
entities, in this case, three conceptually separate C1 type objects have their sub-entities (base points and tangents), share the continuous memory spaces.
mathematical abstraction
C1( tangent bundle)*u
base
point
C1 *u;
tangent
quadrature
point # 2
quadrature
point # 3
double * v
double* dv
quadrature
point # 1
quadrature
u[0] point # 1
quadrature
point # 2
quadrature
u[1] point # 2
u[2] quadrature
point # 3
quadrature
point # 3
(assume spatial dimension = 3)
3.2.1
Integrable_Tangent_Bundle / Integrable_Vector_of_Tangent_Bundle
Integrable_Tangent_Bundle and Integrable_Vector_of_Tangent_Bundle are two H1 type objects that are the
integrable extension of Tangent_Bundle and Vector_of_Tangent_Bundle objects of C1 type.
Constructors
The dedicated constructors for an Integrable_Tangent_Bundle are
183
Chapter
by reference
H1&
H1 type Matrix
H1*
a pointer to H1 type Matrix
double*, double*, Quadrature
v, dv,
double*, double*, int, Quadraturev, dv, spatial dimension,
by value
Quadrature,
int, Quadrature
memory-row-length, memory-column-length
const double&, const double&, v, dv, (for spatial dimension = 1 only)
const Quadrature&
const double*, const double*,
v, dv,
int, Quadrature&
spatial dimension
const H0&, const H0&
base point, tangent
const H0*, const H0*
base point, tangent
const H1&
Integrable_Tangent_Bundle
const H1*
Integrable_Tangent_Bundle*
Strings in H1 virtual constructor for H1 type Integrable_Tangent_Bundle class.
184
priority
1
2
7
8
3
4
5
6
9
10
11
12
by reference
H1&
H1*
int, int, double*, double*,
Quadrature, int, int
by value
int, int, Quadrature,
const H0&, const H0&
const H0*, const H0*
int, const H1*
const H1&
const H1*
priority
H1 type Matrix
13
15
1-D Integration: We seek the integration of the example shown on page 176. That is
x2
x3
( x 1 ) 2 dx = x x 2 + ----3-
x0
x2
Eq. 324
x0
x
f ( x ) dx f ( x ) ------ d = f ( x )J d W i f ( x i )J i
i=0
On page 176 we restrict ourselves to have equal-spaced points of x0, x1, and x2, in order to have a constant Jacobian throughout the integration domain. Now Jacobian of the coordinate tranformation rule in this case is an
Integrable_Scalar of H0 type
dx ( )
J = -------------d
Eq. 325
This numerical integration problem can be coded with VectorSpace C++ Library as (project: integration_1d)
double x[3] = {1.0, 1.5, 3.0};
Quadrature qp(1,3);
185
Chapter
// Integrable_Tangent_Bundle
( x 1 ) 2 dx
//
// 2.66667,
2
= 2 --3
Now the restriction of requring the three nodes to be equally spaced is lifted. The Jacobian is simply J(d(X)) as
in the above program.
Line Integration in 2-D: Consider an example of line integration on a two-dimensional space. We first look at
the arc length method in calculus. We seek the length of a circle in the first quadrant (see the right-hand-side of
Figure 34)
x2 + y 2 = 1
The value of the ordinate y can be considered as a function of x as
f( x) y =
1 x2
Eq. 326
The arc length, s, of a function f(x) is (see the middle of Figure 34)
s ( x i ) 2 + f ( x i + 1 ) f ( x i ) 2
Eq. 327
by applying pythagorean law. For differentiable function f(x) at the limit of x 0 we have the arc-length
method formula
s =
1 + f ( x )2 dx
Eq. 328
y = f(x)
y
arc length = s
r
x 2 + y 2 = r2
f(xi+1)-f(xi)
x
x
Figure 34 Use arcs to approximate the length of a curve.
186
1
1
y() = --- (-1) y0 + (1-2) y1 + --- (+1) y2
2
Eq. 329
where is the parameter for the coordinate transformation of x and y coordinates. An infinitesimal length of the
curve dr can be obtained as (see Figure 35)
2
dr =
dx + dy d
d
d
Eq. 330
dx + dy
d
d
= dr
d
J
2
Eq. 331
That is the Euclidean norm of Jacobian of the coordinate transformation rule. Therefore, we have
Eq. 332
dr = J 2 d
This integration formula is simply written consistent with the coordinate transformation method.
Program Listing 33 implements the arc length method with Eq. 326 and Eq. 328, and the coordinate transformation method with Eq. 329 and Eq. 330. The program computes the line integration using arc length
method, if the macro definition __ARC_LENGTH is defined at the compile time. Otherwise, the default
dr
r
dy
y
r
dx
x
187
Chapter
1
N0() = --- (-1), N1()= (1-2)
2
1
N2()= --- (+1)
2
1 +f ( x )2 dx
dr =
dx + dy d = J d
2
d
d
Listing 33 Line integration using the arc length method or the coordinate transformation method (project:
line_integration_2d).
188
Number
of Nodes
Arc Length
Coordinate
Transformation
1.57077
1.56245
1.57079
1.57020
1.57079
1.57068
1.57079
1.57076
V =
z ( )dx
x
A =
z 2
z 2
1 + -------- + -------- dx
x 0
x 1
x1
x0
Figure 36 Spherical (polar) coordinates and formula for computing the volume and
surface area of one-eighth of a sphere with unit radius.
Workbook of Applications in VectorSpace C++ Library
189
Chapter
x()
6
0
4
1
Figure 37 Coordinate transformation rule x(, ) of a 9-node Lagrangian element.
Eq. 333
Eq. 334
Then, (2) modify four corner nodes due to the presence of the center node
N0 -= N8/4, N1 -= N8/4, N2 -= N8/4, N3 -= N8/4,
Eq. 335
Step 3: For each of the four edge nodes (i = 4, 5, 6, 7), do the following. If the edge node is present,
(1) add the edge node according to the corresponding interpolation function
N4(, ) = (1-2)(1-) - N8/2, N5(, ) = (1-2)(1+) - N8/2
N6(, ) = (1-2)(1+) - N8/2, N7(, ) = (1-2)(1-) - N8/2
Eq. 336
Then, (2) modify the four corner nodes according to the presence of the four edge nodes
N0 -= (N4+N7)/2, N1 -= (N4+N5)/2, N2 -= (N5+N6)/2, N3 -= (N6+N7)/2,
190
Eq. 337
6
2
1
5
1
2
4
1
0
Figure 38 Finite element discretization of a quarter of a circle.
The order of the node number (left-hand-side of Figure 37) and the interpolation functions defined in the above
are both accepted standard in finite element method. A quarter of a circle is taken as a whole element or subdivided into three quadrilateral elements as in Figure 38.
The coordinate tranformation rule for a nodal point x = (x0, x1) is now
x ( , ) = N x
Eq. 338
where the components of vector N are the shape functions defined in Eq. 333 to Eq. 337, and x = (x0, x1) are
nodal coordinates. The interpolation function for the z-coordinates of a point on the surface of a sphere can be
expressed similarly as
z ( , ) = N z
Eq. 339
where z is the height of the spherical surface above a node. For geometrical entities that are simple enough, as in
this case with the unit sphere, their algebraic expression can be found in analytical geometry. Instead of Eq. 339,
the height of the unit sphere can be written as
z ( , ) =
1 ( x0 ) 2 ( x 1 ) 2
Eq. 340
z ( )dx
Eq. 341
where is a vector = {, }T. Either, the isoparametric interpolation of Eq. 339 or analytical expression of Eq.
340 can be used in Eq. 341. A three dimensional surface area of a two dimensional integration domain has its
formula as a multiple dimensional generalization to that of the arc length method shown in Eq. 328.
surface area =
z 2
z 2
1 + -------- + -------- dx
x 0
x 1
Eq. 342
191
Chapter
where
z
-------x 0
dz
dz dx 1
------
= ------ ------
dx
d d
z
-------x 1
Eq. 343
The Program Listing 35 defines the element geometry as shown in Figure 38. The Program Listing 35 is
the C++ main() porgram implements integration formula for computing volume and surface area using Eq. 339
or Eq. 339. The macro definition __THREE_ELEMENTS, if defined, the program discretizes one-quarter of
a circular domain into three nine-nodes quadrilateral elements, otherwise, only one element is used. The macro
definition __ANALYTICAL_GEOMETRY, if defined, Eq. 340 is used in place of Eq. 339. The macro definition __SURFACE_AREA, if defined, compute the surface area instead of the volume. (Program Listing 35
and Program Listing 35 are in project: volume_and_surface_area)
The results of this computation are shown in TABLE 3.7. Three elements discretization does improve the
accuracy of the integration as compared to that of the one element discretization.
Volume
Surface Area
1 Element
3.99991
12.3264
3 Elements
4.17283
12.5465
Analytical
4.18879
12.5664
192
frist element
second element
third element
Listing 34 Element discretization of two dimensional integration domain for a sphere with unit radius.
control points use linear of quadratic interpolation functions to map a referential domain to a physical domain
(see Figure 37). The second and third argument -node-no and -node-no indicate the number of nodes
generated in each direction. The fourth argument control-node-no has values of 4 to 9. The following controlnode-flag uses either TRUE (=1) or FALSE (=0) to indicate if a node is to be used as a control node. The
pointer to double array is the nodal coordinates of the control nodes. This is followed by two integers to indicate
the first node number and the first element number to be generated. For example (see also Figure 39),
193
Chapter
1
2
3
4
5
6
7
8
9
4 to 9 nodes algorithm
Step 1: four corner nodes
Step 2: center nodes and modification
to four corner nodes
Step 3: four edge nodes and modifcation
to other nodes
coordinate transformation
x ( , ) = N x
1: Surface Area
interpolation z ( , ) = N z
area =
z 2
z 2
1 + -------- + -------- dx
x 0
x 1
2: Volume
z ( , ) =
1 ( x 0 ) 2 ( x1 ) 2
interpolation z ( , ) = N z
volume =
z ( )dx
x
Listing 35 Two dimensional integration domain for volume and surface area of a sphere with unit radius.
194
6
2
2
5
0
4
3
2
3
2
0
0
1
Figure 39 Use of block() function to generate elements and nodes
automatically. The control nodes are shwon as open squares.
The function sphere() is to generate Catesian coordinates on a circular domain (on x0-x1 plane, see Figure 36)
given the latitude and colatitude of a unit sphere. This generates a 9-nodes Lagrangian element with four corner nodes as control nodes (see element number 0 in Figure 39). The other two 9-nodes Lagrangian elements
labeled as element number 1 and element number 2 and can be constructed as .
1
2
3
4
5
6
7
8
9
10
11
The control nodes ordering is the same as that shown in Figure 37. For the element number 1, the total number
of control nodes is 6, and the node number 4 is skipped by setting control_node_flag[4] = FALSE;. For the
element number 2, the total number of control nodes is 7, and both node number 4 and 5 are skipped by
setting control_node_flag[4] = control_node_flag[5] = FALSE;. In the main() program, the discretized domain
is declared as
Omega_h oh;
the geometrical information of nodes and elements can be accessed as
195
Chapter
Program Listing 36 is the program to generate three 9-nodes Lagragian elements. The geometrical information
on the nodes and elements are coded in the segment for the constructor of the discretized global domain
Omega_h::Omega_h(). The actual instance of the discretized global domain is declared inside the main() program. The project block_volume_integral can be used to generate either 9-nodes Lagragian elements or 4nodes quadrilateral elements. The 9 nodes Lagragian elements are generated when the macro definition
__LAGRANGAIN_9_NODES is defined at the compile time. 2, 4, and 8 subdivision for each side of the
block can be defined using macro definition __TWO_SEGMENTS and __FOUR_SEGMENTS for the first
two kinds of subdivision. The nodes and elements for these options are shown in Figure 310. The results of
refined computation are shown in TABLE 3.8.
12 elements
3 elements
48 elements
12 elements
192 elements
4-nodes Quadrilateral
48 elements
196
x- and y- coordinates
x ( , ) = N x
Volume
z ( , ) =
1 ( x0 ) 2 ( x1 )2
interpolation z ( , ) = N z
volume = z ( )dx
x
Listing 36 Volume integration using block() function to generate nodes and elements automatically.
197
Chapter
No. of Elements
4-nodes Quadrilateral
9-nodes Lagragian
4.19694
12
4.17459
4.19144
4.18803
4.18958
48
4.18092
Constructors
The dedicated constructors for a Integrable_Tangent_Bundle are
H2::H2(const Quadrature&)
H2::H2(double* v, const Quadrature&)
H2::H2(double* v, int spatial_dimension, const Quadrature&)
The dedicated constructors for a Integrable_Vector_of_Tangent_of_Tangent_Bundle is
H2::H2(int vector_size, double* v, const Quadrature&)
For the dedicated constructor, the size of vector is equal to the number of spatial dimension.
The constant strings used for the virtual constructors and autonomous virtual constructor are listed in the
following two boxes. The macro defintions use for the virtual constructors of the
Integrable_Tangent_of_Tangent_Bundle and Integrable_Vector_of_Tangent_of_Tangent_Bundle are
H2 x = INTEGRABLE_TANGENT_OF_TANGENT_BUNDLE(const char*, ...);
H2 x = INTEGRABLE_VECTOR_OF_TANGENT_OF_TANGENT_BUNDLE(const char*, ...);
respectively. H2 x = H2(const char*, ...) is used for autonomous virtual constructors. There are not much different in the use of H2 type objects compared to that of the H1 type objects, The major difference is that the H2
type objects allow twice differentiable operation needed in some applications. In the next section on the variational methods, a lot of examples with H2 type are shown.
198
priority
H2 type Matrix
a pointer to H2 type Matrix
v, dv, ddv
1
2
7
v, dv, ddv,
spatial dimension
memory-row-length, memory-column-length
v, dv, (for spatial dimension = 1 only)
ddv
v, dv,
ddv, spatial dimension
base point, tangent,
tangent of tangent
base point, tangent,
tangent of tangent
Integrable_Tangent_of_Tangent_Bundle
Integrable_Tangent_of_Tangent_Bundle*
Strings in H2 virtual constructor for Integrable_Tangent _of_Tangent_Bundle object.
3
4
5
6
9
10
11
12
priority
by reference
H2&
H2 type Matrix
H2*
a pointer to H2 type Matrix
int, int, double*, double*, double*,vector size, spatial dimension, v, dv, ddv
14
Quadrature, int, int
quadrature, memory row size, and column size
by value
int, int, Quadrature,
vector size, spatial dimension
13
const H0&, const H0&,
base point , tangent
const H0&
tangent of tangent
const H0*, const H0*,
base point, tangent
const H0*
tangent of tangent
int, const H2*
vector size, Integrable_Tangent_of_Tangent_Bundle* 15
const H2&
Integrable_Vector_of_Tangent_of_Tangent_Bundle
const H2*
Integrable_Vector_of_Tangent_of_Tangent_Bundle*
Strings in H2 virtual constructor for Integrable_Vector_of_Tangent_of_Tangent_Bundle object.
199
Chapter
Eq. 344
Eq. 345
where (u, f) is a linear functional and a(u, u) is a bilinear functional with a(u, u) (u, Au). For u0, a solution
corresponding to the minimum value of J; i.e., J(u0) J(u). We define u = u0 + , where is a small real number and is called the variation. The variation of J denoted as J can be defined with the directional derivatives
as
d
J(u)= ------ J ( u 0 + )
d
= 0
Eq. 346
Set J(u) = 0 for the minimization of J. Considering Eq. 346 equals zero is always true for the arbitary small
real number , the term in bracket must equal zero for u0 to give a stationary value of J. So, we have
d 1
2
------ --- a ( u 0, u 0 ) + a ( , u 0 ) + ----- a ( , ) ( u 0, f ) ( , f )
2
d 2
=0
= a ( , u 0 ) ( , f ) = 0
Eq. 347
That is,
a(, u0) = (, f)
Eq. 348
which is just the Eq. 344 multiplies by the variation . So it is equivalent to the Eq. 344. Therefore, the solution of the differential equation (strong form) of Eq. 344, is the solution of the minimization problem of Eq.
345, and is also the solution of the variational formulation (weak form) of Eq. 348.
Re-defining v = u0 + , and u = u0 in Eq. 348, we have (v, Au) = (v, f), And, the adjoint homogeneous
equation A*v = 0, therefore, (A*v, u) = (0, u).
(v, Au) - (A*v, u) = (v, f) - (0, u) = (v, f)
Eq. 349
The left-hand-side of Eq. 349 is (Au, v) - (u, A*v) = 0 for self-adjoint operator A. So, we have
(v, f) = 0
Eq. 350
Eq. 350 is the solvability condition. From linear algebra, orthogonal complement of the range space of A is the
null space of its adjoint A*, usually denoted as R(A) = N(A*). Since f R(A) and v N(A*), this leads directly
to the orthogonal relation (v, f) = 0.
200
Variational Methods
3.3.1 Rayleigh-Ritz Method
For the Rayleigh-Ritz method we write the approximation of the variational formulation in Eq. 348 as
a(vN, uN) = (vN, f)
Eq. 351
u N = vN =
ci i
Eq. 352
i=0
The approximation basis functions i should give finite energy with respect to the bilinear form a(. , .), such that
derivatives corresponding to the operator A is integrable. Substituting Eq. 352 into Eq. 351 gives a system of
simultaneous equations
N1
ci
a ( i, j ) cj
= c i ( f, i ), where i = 0, 1, , N 1
Eq. 353
j=0
coefficients ci are present in both sides of the equation, so it can be dropped. Eq. 353 can be re-written in matrix
form as
Mc=b
Eq. 354
where Mij = a(i, j), and bi = (i, f). The solution vector c of Eq. 354 is the vector consists of coefficients ci in
Eq. 352. If i are chosen to be orthogonal basis functions, M is diagonal; i.e., Mij = 0 for i j.
d u
dx
Eq. 355
with different kinds of boundary conditions for each of the two problems:
1. Dirichlet boundary conditionsu(0) = u(1) = 0
2. Mixed boundary conditionsu(0) = 0, and u(1) = 0
1. p. 265-270 in J.N. Reddy, 1986, Applied functional analysis and variational methods in engineering, McGraw-Hill, Inc.
201
Chapter
Dirichlet Boundary Conditions: For the first one with the Dirichlet boundary conditions u(0) = u(1) = 0 the
exact solution is
1
uexact(x) = -----2 ( cos x + 2x 1 )
Eq. 356
d uN
vN d x2 + vN cos x dx =
0
dv N du N
du N
d x d x + v N cos x dx + v N d x
0
=
0
dv N du N
+ v N cos x dx = 0
dx
d x
Eq. 357
We have applied the integration by part on the term with the second order derivative and requring homogeneous
conditions, vN(0) = vN(1) = 0, on the boundary integral term
du N
vN
dx
= 0
Eq. 358
Therefore, we choose i in Eq. 352 as the set of orthogonal functions {sin [(i+1)x] | 0 i N 1 }. Notice
that this set of functions satisfies the requirement of vN(0) = vN(1) =0. Since the set is orthogonal, all off-diagonals of M matrix are zeros. We only consider the diagonal elements of M as
1
diag(M)i = a(i, i) =
d i d i
dx , and bi = i cos x
dx
dx
Eq. 359
The solution of the coefficient vector is simply ci = bi / diag(M)i , component by component without having to
solve a system of simultaneous equation. The Program Listing 37 implements the Eq. 359. After the ci are
solved for, the solution of the Dirichlet boundary value problem is obtained by plug in ci in Eq. 352.
In Figure 311, the exact solution in Eq. 356 is compared to the solution constructed using ci computed from
Program Listing 37. The approximated vairiational solution, in the form of Eq. 352 uN = cii, with N = 2 to N =
16 (even numbers only) are ploted in the left-hand-side. Only the case with N=2 has clear differences from the
exact solution, other solutions (N= 4-16) converge rapidly towards the exact solution. Figure 312 shows the
alternative approach discussed in page 170 with an integral equation using Green function as kernel for solution.
The results are computed by Program Listing 37, which is almost with a simple modification that f(x) = cos
x instead of f(x) = sin(x).
202
Variational Methods
#include "include\vs.h"
#define PI 3.141592654
int main() {
const int n = 16;
double w[35] = {1.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0,
4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0,
4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0,
4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 1.0/3.0};
Quadrature qp(w, 0.0, 1.0, 35);
H1 x(qp),
phi = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE("int, int, Quadrature", n, 1, qp);
for(int i = 0; i < n; i++) phi[i] = sin(((double)i+1.0)*PI*x);
H0 d_phi_2(n, (double*)0, qp);
for(int i = 0; i < n; i++) d_phi_2[i] = d(phi[i]).pow(2);
C0 M = d_phi_2 | J(1.0/34.0);
C0 b = ( ((H0)phi) * cos(PI*((H0)x)) ) | J(1.0/34.0);
C0 c(n, (double*)0);
for(int i = 0; i < n; i++) c[i] = b[i] / M[i];
for(int i = 0; i < n; i++) cout << c[i] << ", "; cout << endl;
return 0;
}
i = sin[(i+1)x], i = 0, N-1
1
diag(M)i = a(i, i) =
bi = i cos x
ci = bi / diag(M)i
d i d i
dx
dx
dx
0
Listing 37 Dirichlet boundary condition u(0) = u(1) = 0, for the differential equation - u = f (project:
dirichlet).
Exact = (cos x + 2x -1) /2
uN = cii , i = 0, ( = 216)
0.02
0.01
-0.01
-0.02
0.02
0.01
0.20.40.60.8 1
-0.01
-0.02
=2
0.20.40.60.8 1
Figure 311 The left-hand-side is the exact solution, and the right-hand-side is the solution
with N=2 to N = 16 Rayleigh-Ritz method.
Mixed Boundary Conditions: For the Mixed boundary conditions u(0) = u(1) = 0, the exact solution is
1
uexact(x) = -----2 ( cos x 1 )
Eq. 360
With this different set of boundary conditions the Eq. 357 to Eq. 359 still hold. However, i = {sin(ix) |
0 i N 1 } now is not complete with respect to x = 1, where u(1) = 0 always. We can add a new algebraic
function 0 = x (the simplest one) to fix this situation. That is the new set of becomes {x, sin(x), sin(2x),
sin(3x), ... }. Therefore, the Program Listing 37 only needs the slightest modification. The Program Listing 38
is a modified version for the mixed boundary conditions problem. Aternatively, since the solution of ci in Program Listing 37 is working out component by component for this problem (since we select a orthogonal set of
i), we can just compute one additional term c0 with 0 = x and add to the solution of the problem 1. Figure 313
Workbook of Applications in VectorSpace C++ Library
203
Chapter
0.01
0.2
0.4
0.6
0.8
-0.01
-0.02
Figure 312 Point-values are solution of integral equation using Green function computed by Program
Listing 31 with a simple modification that f(x) = cos x.
shows that the solution up to N= 2 is already a good enough approximation to the exact solution for this
problem.
#include "include\vs.h"
#define PI 3.141592654
int main() {
const int n = 16;
double w[35] = {1.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0,
4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0,
4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0,
4.0/3.0, 2.0/3.0, 4.0/3.0, 2.0/3.0, 4.0/3.0, 1.0/3.0};
Quadrature qp(w, 0.0, 1.0, 35);
H1 x(qp),
phi = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE("int, int, Quadrature", n, 1, qp);
phi[0] = x;
for(int i = 1; i < n; i++) phi[i] = sin(((double)i+1)*PI*x);
H0 d_phi_2(n, (double*)0, qp);
for(int i = 0; i < n; i++) d_phi_2[i] = d(phi[i]).pow(2);
C0 M = d_phi_2 | J(1.0/34.0);
C0 b = ( ((H0)phi) * cos(PI*((H0)x)) ) | J(1.0/34.0);
C0 c(n, (double*)0);
for(int i = 0; i < n; i++) c[i] = b[i] / M[i];
for(int i = 0; i < n; i++) cout << c[i] << ", "; cout << endl;
return 0;
}
0 = x, i = sin[ix], i = 1, N-1
Listing 38 Mixed boundary condition u(0) = u(1) = 0, for the differential equation - u = f (project: mixed).
Dirichlet Boundary Conditions Revisited: We can use polynominals instead of trigonometric functions as the
basis functions, such as
i = x(i+1) (1-x).
Eq. 361
Notice that this choice of i satisfies the Dirichlet boundary conditions u(0) = u(1) = 0. However the is are not
orthogonal with each other and therefore Mij will not be a diagonal matrix. The solution of a system of simultaneous equations is required. We choose 0 i 3 ; i.e., N=4. Hence the highest order polynomial is fifth-order.
One modification to the Program Listing 37 is that we use Bodes integration rule which is a fifth-order approximation. The weights for the Bodes rule is
204
Variational Methods
0.20.40.60.8 1
0.20.40.60.8 1
-0.05
-0.1
-0.15
-0.2
-0.05
-0.1
-0.15
-0.2
uN = cii , i = 0, ( = 216)
Figure 313 Exact solution (cos x -1) /2 comparing to solutions of N= 2-16 Rayleigh-Ritz method.
64 24 64 14
14 24 64 28 64 24 64 28
------, ------ , ------, ------, ------ , ------, ------, ------, , ------, ------, ------, -----45 45 45 45
45 45 45 45 45 45 45 45
Redefine i simply as phi[0] = x*(1-x); for(int i = 1; i < 4; i++) phi[i] = phi[i-1]*x; Program Listing 39 implements the polynomial approximation. Figure 314 shows the solutions of the polynomial approximations which
is almost the same as the eact solution visually.
#include "include\vs.h"
#define PI 3.141592654
int main() {
double w[17] = {14.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0, 28.0/45.0,
64.0/45.0, 24.0/45.0, 64.0/45.0, 28.0/45.0,
64.0/45.0, 24.0/45.0, 64.0/45.0, 28.0/45.0,
64.0/45.0, 24.0/45.0, 64.0/45.0, 14.0/45.0};
Quadrature qp(w, 0.0, 1.0, 17);
H1 x(qp),
phi = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE("int, int, Quadrature", 4, 1, qp);
phi[0] = x*(1-x); for(int i = 1; i < n; i++) phi[i] = phi[i-1]*x;
C0 M = ( d(phi)*(~d(phi)) ) | J(1.0/16.0);
C0 b = ( ((H0)phi) * cos(PI*((H0)x)) ) | J(1.0/16.0);
C0 c = b / M;
for(int i = 0; i < 4; i++) cout << c[i] << ", ";
return 0;
}
Mij = a(i, j) =
bi = i cos x
ci = bi /Mij
d i d j
dx
dx
dx
0
Listing 39 Polynomial basis i = x(i+1) (1-x), i = 0, N-1 for the Dirichlet boundary condition u(0) = u(1) = 0,
for the differential equation - u = f (project: polynomial).
1. p.188-190, and p. 351-353 in J.M.Gere, and S.P. Timoshenko, 1984, Mechanics of materials, 2nd ed., Wadsworth, Inc.,
Belmont, California.
205
Chapter
0.02
0.01
0.2
0.4
0.6
0.8
-0.01
-0.02
Figure 314 Solution of Dirichlet boundary problem using polynomial basis functions.
the beam as w (see Figure 315). From balance of force, the transverse loading (f) is equal to the derivative of
shear force (V) as
dV/dx =- f
Eq. 362
and the shear force is equal to the derivative of bending moment (M) as
dM/dx =- V
Eq. 363
Therefore,
2
dM
= f
dx2
Eq. 364
The curvature (d2w/dx2) of the beam is related to the bending moment and the flexure rigidity of the beam as
w
f(x)
x
M
L
Figure 315 Transverse deflection of a beam.
206
Variational Methods
2
dw
M
= --------2EI
dx2
Eq. 365
where EI is the flexural rigidity. Substituting M in Eq. 365 into Eq. 364 gives
2
2
d d w
EI
= f, where 0 < x < L
d x d x2
Eq. 366
w( 0 ) =
dw
dw
d d w
( 0 ) = 0, EI 2 ( L ) = M, V ( L ) =
EI
(L) = 0
dx
d
x d x2
dx
Eq. 367
Eq. 368
2
d d u
EI
= f, where 0 < x < L
dx dx2
Eq. 369
1. From examples in p. 156-158, and p. 275-280 in J.N. Reddy, 1986, Applied functional analysis and variational methods
in engineering, McGraw-Hill, Inc.
207
Chapter
u(0) =
du
d d u
du
( 0 ) = EI 2 ( L ) =
EI
(L) = 0
d
x dx2
dx
dx
Eq. 370
J(u) =
EI d u
------
fu dx
2 d x2
Eq. 371
J ( u ) =
2
d u
d v d u
d
EI
( u ) 2 uf dx = EI 2 2 vf dx = 0
2
d
x
dx
dx dx
Eq. 372
The second identity is obtained from applying integration by parts twice and considering that all boundary conditions are homogeneous. Dropping , for which is arbitary, we can define an approximated system of equations
with left-hand-side and right-hand-side as
L
a(vN, uN) =
d v N d u N
EI 2 2 dx , and (vN, f) =
dx dx
[ vN
f ] dx
Eq. 373
respectively. The approximation basis functions are taken as i = {x i+2}, i = 0,1, ..., N-1. Program Listing 310
implements Eq. 373, with N= 2, 3. The case with N= 3 actually produces the coefficients of the exact solution
in Eq. 368. Figure 316 shows N=2 is almost identical to the exact solution visually.
0.6
0.5
0.4
0.4
0.6
0.8
Figure 316 Irreducible formulation for transeverse deflection of a beam with N=2, 3.
2. Lagrange Multiplier Formulation: We refer to Chapter 2, Eq. 211 in page 118 for an introduction on the
Lagrangian functional in the Lagrange multiplier method for the constrained optimization problem. We now
define the constraint equation as the variable of the negative slope
=
208
dw
dx
Eq. 374
Variational Methods
#include "include\vs.h"
int main() {
double L_ = 1.0, E_ = 1.0, I_ = 1.0, f_ = 1.0, M_ = 1.0;
for(int N = 2; N < 4; N++) {
double w[17] = {14.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0, 28.0/45.0,
64.0/45.0, 24.0/45.0, 64.0/45.0, 28.0/45.0,
64.0/45.0, 24.0/45.0, 64.0/45.0, 28.0/45.0,
64.0/45.0, 24.0/45.0, 64.0/45.0, 14.0/45.0};
Quadrature qp(w, 0.0, L_, 17);
H2 x((double*)0, qp),
phi = INTEGRABLE_VECTOR_OF_TANGENT_OF_TANGENT_BUNDLE(
"int, int, Quadrature", N/*vector size*/, 1/*spatial dim.*/, qp);
for(int i = 0; i < N; i++) phi[i] = x.pow(i+2);
H0 d2_phi = INTEGRABLE_VECTOR("int, Quadrature", N, qp);
for(int i = 0; i < N; i++) d2_phi[i] = dd(phi)(i)[0][0];
C0 M = ( E_* I_* (d2_phi%d2_phi) ) | J(L_/16.0);
C0 b = ( ( ((H0)phi) * f_ ) | J(L_/16.0) )+ M_bc;
C0 c = b / M;
for(int i = 0; i < N; i++) cout << c[i] << endl;
}
return 0;
}
Mij =
d i d j
EI 2 2 dx
dx dx
bi =
[ i
f ] dx
ci = bi /Mij
N = 2: ci={0.20833,-0.0833333}T,
N = 3: ci={0.25, -0.166667, 0.041667}T
Listing 310 Transverse deflection of a beam using irreducible formulation. i = x(i+2) , i = 0, N-1 (project:
irreducible_formulation).
Substituting Eq. 374 into Eq. 371 and considering the boundary term yields
L
J ( , w ) =
EI d 2
----- fw dx + ( M )
2 dx
Eq. 375
L
Using the Lagrangian multiplier with the constraint equation (Eq. 374), we can define the Lagrangian functional l(, w, ) as
L
l ( , w, ) =
EI d 2
dw
----- f w + + dx + ( M )
2 dx
dx
Eq. 376
L
subject to boundary condition that (0) = w(0) = 0. The Euler-Lagrange equations can be obtained by setting
l(, w, ) = 0 as
209
Chapter
l ( , w, ) =
d d
EI ---------+ ( ) dx + ( M )
dx d x
0
L
- w
---------dx
dw
+
L
f dx +
0
L
+ d x dx
dw
Eq. 377
=0
The Lagrange multiplier in this case has physical interpretation of the shear force.
2
d d w
=
EI
dx d x2
Eq. 378
Therefore, the exact solution for and can be obtained by differentiating the exact solution for w(x) in Eq.
368 as
f
fL 2 ------- ( 2M + fL 2 )
- 3
x + ------- ( x ) = -----------------------------2EI x 6EI x ,
2EI
= f(L x )
Eq. 379
The approximation basis functions for each approximated variable are taken as
N wN N = c i i c iw iw c i i
d i d j
- ---------- dx
EI
--------dx dx
i j dx
c j
0
L
i j dx
djw
i ---------- dx
dx
( i M )
L
d iw
- dx c jw =
--------dx j
iw f dx
c j
Eq. 380
Therefore, the matrix and vectors in Eq. 380 can be labeled to be comformed with M c = b (Eq. 354). We
first consider a one-parameter approximation with
210
Variational Methods
0 0w 0 = x x 1
Eq. 381
Eq. 382
Eq. 380 with Eq. 381 or Eq. 382 offers a first non-trivial matrix formulation in this workbook and it deserves
us to look into the various ways, that VectorSpace C++ Library supports, to implment these equations. Program
Listing 311 implements the one-parameter approixmation.
#include "include\vs.h"
int main() {
double L_ = 1.0, E_ = 1.0, I_ = 1.0, f_ = 1.0, M_ = 1.0, weight[2] = {0.5, 0.5};
Quadrature qp(weight, 0.0, L_, 2);
H1 x(qp), psi = x, w = x;
double lambda = 1.0;
H0 m = INTEGRABLE_MATRIX("int, int, Quadrature", 3, 3, qp);
m[0][0] = (E_*I_)*d(psi)*d(psi);
m[0][2] = m[2][0] = ((H0)psi)*lambda;
m[1][2] = m[2][1] = d(w)*lambda;
m[0][1] = m[1][0] = m[1][1] = m[2][2] = 0.0;
C0 M = m | J(L_),
b(3, (double*)0);
b[0] = -L_*M_; b[1] = ( ((H0)w)*f_ ) | J(L_); b[2] = 0.0;
C0 c = b / M;
for(int i = 0; i < 3; i++) cout << c[i] << ", "; cout << endl;
return 0;
}
M00=
d 0 d 0
EI ---------- ---------- dx
dx dx
0
L
M02 =M20 =
0 0 dx
M12 =M21 =
L d w
0
--------- dx
dx 0
0
b=
ML 0w fdx 0
Listing 311 On-parameter approximation in Lagrange multiplier method for beam bending problem
(project: lagrange_multiplier).
For one-parameter approximation matrix M is only 3 3, which is not too complicated. It can be accessed
with plain C or Fortran semantics using the selector []. Two alternative approaches are available in VectorSpace C++ Library. First we can build M just as it is written in matrix form using concatenation operator | and
& such as
C0 M = ( ( (E_*I_*(d(psi)*d(psi)))| null
| (((H0)psi)*lambda) )&
( null
| null
| (d(w)*lambda)
)&
( (((H0)psi)*lambda)
| (d(w)*lambda) | null
) ) | J(L_),
b = ( C0(-L_*M_) &
( (((H0)w)*f_) | J(L_) ) &
C0(0.0) );
211
Chapter
The expression is to mimic directly the image of the right-hand-side matrix and the left-hand-side vector of Eq.
380. Or, we can use basis expression closer to linear algebra as
C0 e(3),
M = ( (E_*I_*(d(psi)*d(psi)))
0.0
(((H0)psi)*lambda)
0.0*(e[1]%e[0])+ 0.0
(d(w)*lambda)
(((H0)psi)*lambda)
(d(w)*lambda)
0.0
) | J(L_),
b = (-L_*M_)
((((H0)w)*f_) | J(L_))
0.0
*(e[0]%e[0])+
*(e[0]%e[1])+
*(e[0]%e[2])+
*(e[1]%e[1])+
*(e[1]%e[2])+
*(e[2]%e[0])+
*(e[2]%e[1])+
*(e[2]%e[2])
*e[0] +
*e[1] +
*e[2];
M=
0 ( e 0 e 1 ) + 0 0 dx ( e 0 e 2 ) +
0
L
d iw
dx
0 ( e 1 e 1 ) + ---------- j dx ( e 1 e 2 ) +
0 ( e1 e0 ) +
0
L
0 0 dx ( e 2 e0 ) +
0
d 0w
0 ---------- dx ( e 2
dx
e1 ) +
0 ( e2 e2 )
and,
L
b=
( 0 M )
e 0 + 0w f dx e 1 + 0 e 2
0
The results of one-parameter approximation are shown in Figure 317. There is room for improvements obviously.
Program Listing 312 implements the two-parameter approximation.
-0.2
-0.4
-0.6
-0.8
-1
-1.2
exact
0.6
0.5
0.4
0.3
0.2
0.1
exact
0.8
0.6
0.4
exact
0.2 0.4 0.6 0.8
0.2
1
Variational Methods
T
= w , = x x2 , w = x x2 , = 1 x
T
Eq. 383
For more than one-parameter approximation, the complexities for the formulation increase dramatically. Submatrix/Subvector become an important tool to deal with the complexities. We used in Program Listing 312, the reference Integrable_Matrix mi j, where i, j = 0, 1, 2. Each mi j is a matrix of size 2x2.
#include "include\vs.h"
int main() {
double L_ = 1.0, E_ = 1.0, I_ = 1.0, f_ = 1.0, M_ = 1.0, weight[3] = {1.0/3.0, 4.0/3.0, 1.0/3.0};
Quadrature qp(weight, 0.0, L_, 3);
H1 x(qp),
psi = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE("int, int, Quadrature", 2, 1, qp),
w
= INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE("int, int, Quadrature", 2, 1, qp),
lambda=INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE("int, int, Quadrature",2,1,qp);
psi[0] = x; psi[1] = x.pow(2);
w[0] = x; w[1]
= x.pow(2);
lambda[0] = 1.0; lambda[1] = x;
H0 m(6, 6, (double*)0, qp),
m00(2, 2, m, 0, 0, qp), m01(2, 2, m, 0, 2, qp), m02 (2, 2, m, 0, 4, qp),
m10(2, 2, m, 2, 0, qp), m11(2, 2, m, 2, 2, qp), m12(2, 2, m, 2, 4, qp),
m20(2, 2, m, 4, 0, qp), m21(2, 2, m, 4, 2, qp), m22(2, 2, m, 4, 4, qp);
m00 = (E_*I_)*d(psi)*(~d(psi)); m01 = 0.0;
m02 = ((H0)psi)%((H0)lambda);
m10 = 0.0;
m11 = 0.0;
m12 = d(w)(0)%((H0)lambda);
m20 = ((H0)lambda)%((H0)psi); m21 = ((H0)lambda)%d(w)(0); m22 = 0.0;
C0 M = m | J(L_/2);
H0 f(6, (double*)0, qp), f0(2, f, 0, qp), f1(2, f, 2, qp), f2(2, f, 4, qp);
f1 = (((H0)w)*f_); f0 = f2 = 0.0;
C0 b = f | J(L_/2);
b[0] = -M_*L_;b[1] = -M_*pow(L_, 2);
C0 c = b / M;
for(int i = 0; i < 6; i++) cout << c[i] << ", "; cout << endl;
return 0;
}
M00=
d d
EI --------- --------- dx
dx
dx
0
L
ML
02
= dx
dx ,
M20
0
L
d w
-dx
M12= ---------- dx , M21= --------dx
dx
0
b=
( M ( L ) ) w fdx 0
Listing 312 Two-parameters approximation in Lagrange multiplier method for beam bending problem
(project: lagrange_multiplier).
Three alternative implementions of the two-parameter approximation in VectorSpace C++ Library are possible. First, concatenation operators can be used to patch smaller matrices and vectors into a larger one, such as
H0 null = INTEGRABLE_MATRIX("int, int, Quadrature", 2, 2, qp); null = 0.0;
C0 M =(( (E_*I_*(d(psi)*(~d(psi)))) |
null
| (((H0)psi)%((H0)lambda)) )&
(
null
|
null
| (d(w)(0)%((H0)lambda)) )&
( (((H0)lambda)%((H0)psi)) | (((H0)lambda)%d(w)(0)) |
null
)
) | J(L_/2);
C0 M_delta_psi(2, (double*)0), zero(2, (double*)0);
M_delta_psi[0] = -M_*L_; M_delta_psi[1] = -M_*L_*L_; zero = 0.0;
C0 b = ( M_delta_psi & ( (((H0)w)*f_) | J(L_/2)) & zero);
213
Chapter
This code is hardly different from the one-parameter version, although each term is now an Integrable_Matrix
instead of an Integrable_Scalar. Secondly, the two-parameter approximation for the linear algebra version can be
written as
C0 e(2), E(3),
M =+( ((E_*I_)*(d(psi)*(~d(psi)))) *((e%e)*(E[0]%E[0]))+
0.0
*((e%e)*(E[0]%E[1]))+
(((H0)psi)%((H0)lambda)) *((e%e)*(E[0]%E[2]))+
0.0
*((e%e)*(E[1]%E[0]))+
0.0
*((e%e)*(E[1]%E[1]))+
(d(w)(0)%((H0)lambda))
*((e%e)*(E[1]%E[2]))+
(((H0)lambda)%((H0)psi))
*((e%e)*(E[2]%E[0]))+
(((H00)lambda)%d(w)(0))
*((e%e)*(E[2]%E[1]))+
0.0
*((e%e)*(E[2]%E[2]))
) | J(L_/2);
C0 M_delta_psi(2, (double*)0); M_delta_psi[0] = -M_*L_; M_delta_psi[1] = -M_*L_*L_;
C0 b = +( M_delta_psi
*(e*E[0]) +
( (((H0)w)*f_) | J(L_/2) )
*(e*E[1]) +
0.0
*(e*E[2]) );
The expressions for using Integrable_Submatrix or Integrable_Subvector in two-parameter case are very close to
those of the one-parameter approximation case. The fact that they are now matrix of size 2x2 and vector of size
2x1 instead of a scalar component (comparing to one-parameter case discussed on page 212) is handled by projecting these matrices and vectors to ((e%e)*(E[i]%E[j])) or (e*E[i]) ) according to basis expression introduced in Section 1.1.6. We call your attention to the last operations in the construction of both M and b.
They use unary + operator. This is the primary casting which down casts Subvectors and Submatrices into
Vectors and Matrices, respectively.
Basis expression generates Integrable_Subvector and Integrable_Submatrix. Third, a complementary expression using the objects of Integrable_Subvector and Integrable_Submatrix directly is
H0 m(6, 6, (double*)0, qp),
ms(2, 2, m);
ms(0,0) = E_*I_*(d(psi)*(~d(psi))); ms(0,1) = 0.0;
ms(0,2) = ((H0)psi)%((H0)lambda);
ms(1,0) = 0.0;
ms(1,1) = 0.0;
ms(1,2) = d(w)(0)%((H0)lambda);
ms(2,0) = ((H0)lambda)%((H0)psi); ms(2,1) = ((H0)lambda)%d(w)(0); ms(2,2) = 0.0;
H0 f(6, (double*)0, qp), fs(2, f);
fs(1) = (((H0)w)*f_); fs(0) = fs(2) = 0.0;
C0 M = m | J(L_/2),
b = f | J(L_/2);
b[0] = -M_*L_; b[1] = -M_*pow(L_, 2);
The results of two-parameter approximation are shown in Figure 318. Compared with Figure 317 the approximations for and w are almost equal to the exact solution, and the approximation for is identical to the exact
solution.
214
Variational Methods
0.6
-0.2 0.20.40.60.8 1 0.5
0.4
-0.4
0.3
-0.6
0.2
-0.8 exact ~~ approx.
0.1
-1
1
0.8
0.6
0.4
0.2
exact ~
~ approx.
0.20.40.60.8 1
exact = approx.
0.20.40.60.8 1
Figure 318 Two-parameter approximation using Lagrange multiplier formulation for the beam
bending problem.
3. Penalty Function Formulation: We refer to Chapter 2, Eq. 261 on page 153 for the basics of the penalty
method. Taking J(, w) in Eq. 375 with a quadratic penalty term, we have
L
J p ( , w ) =
dw 2
+ --- + dx
2
dx
EI d 2
----- fw dx + ( M )
2 dx
Eq. 384
- ------- wf dx + ( M )
EI --------
dx dx
dw
dw
+ + ----------- + ------- dx = 0
dx
dx
d d
Eq. 385
Using approximation basis functions as in the Rayleigh-Ritz method this equation can be written in matrix form
as
L
d i d j
d jw
EI -------- dx ----------------
+
dx dx i j
i dx- dx
0
L
d iw
---------- j dx
dx
0
L
d iw d jw
---------- ---------- dx
dx dx
M i
c j
=
c jw
iw fdx
Eq. 386
215
Chapter
Eq. 387
Program Listing 313 implements the penalty function formulation as in Eq. 386 and approximation basis
functions as in Eq. 387.
#include "include\vs.h"
int main() {
double L_ = 1.0, E_ = 1.0, I_ = 1.0, f_ = 1.0, M_ = 1.0,
rho = 1.0, weight[3] = {1.0/3.0, 4.0/3.0, 1.0/3.0};
Quadrature qp(weight, 0.0, L_, 3);
C0 c, delta_c, c_cache(3, (double*)0);
do {
H1 x(qp), psi = x,
w = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE("int, int, Quadrature",
2, 1, qp);
w[0] = x; w[1] = x.pow(2);
H0 m = INTEGRABLE_MATRIX("int, int, Quadrature", 3, 3, qp);
m[0][0] = E_*I_*d(psi)*d(psi)+rho*((H0)psi)*((H0)psi);
m[0][1] = m[1][0] = rho*((H0)psi)*d(w[0]);
m[0][2] = m[2][0] = rho*((H0)psi)*d(w[1]);
m[1][1] = rho*d(w[0])*d(w[0]); m[1][2] = rho*d(w[0])*d(w[1]);
m[2][1] = rho*d(w[1])*d(w[0]); m[2][2] = rho*d(w[1])*d(w[1]);
C0 M = m | J(L_/2.0);
C0b(3, (double*)0);
b[0] = -M_*L_; b[1] = (((H0)w[0])*f_) | J(L_/2.0); b[2] = (((H0)w[1])*f_) | J(L_/2.0);
c &= b / M;
delta_c &= c_cache - c;
c_cache = c;
rho *= 5.0;
} while((double)norm(delta_c) > 1.e-6);
cout << c << endl;
return 0;
}
= x, and w = x x
L
M00=
2 T
d 0 d 0
EI ---------- ---------- dx
dx dx
0
L
w
w
0 d 1 dx ,
[M01, M02] = 0 d
--------- ---------0
M 10
M 20
dx
dx
d w
-------- dx
0 dx
=
d 1w
0 --------
dx
M11 M 12
M21 M 22
b=
d w d w
= ---------- ---------- dx
dx
dx
0
w w
( M 0 ( L ) ) 0 1 fdx
Listing 313 Penalty function formulation for beam bending problem (project: penalty_function).
Notice that the penalty functional Jp can be written in quadratic form Jp(c) = cTMc-cT b where M is a symmetrical positive definitive. Jp = 0 gives Mc = b. Therefore, the solution is c = b / M. Alternatively, we consider that Newtons method for the minimization of Jp(x) should be achieved in just one iteration for a quadratic
functional
c = - Jp,c / Jp,c c = b / M
Eq. 388
Applied Newtons formula gives the same result. Therefore, Eq. 386 can be used to replace the inner loop of the
Newtons iteration in Program Listing 220 for the penalty method in Chapter 2.
216
Variational Methods
The results of the penalty function formulation are shown in Figure 319. Both the and w approximation
are significantly different from the exact solution, considering the exact solution for y is spanned by [x, x2, x3] (in
Eq. 379), and the exact solution for w is spanned by [x2, x3, x4] (in Eq. 368).
exact
0.6
0.5
0.4
0.3
0.2
0.1
exact
4. Mixed Formulation: The irreducible formulation is based on a fourth-order differential equation (Eq. 366),
which is obtained from substituting M in Eq. 365 into Eq. 364. The mixed formulation is based on the two separated equations, Eq. 364 and Eq. 365, directly. That is
2
M
dM
dw
= ---------, and
= f
2EI
dx2
d x2
Eq. 389
These equations are subject to the boundary conditions of w(0) = 0, and M(L) = M. The Lagrangian functional
corresponding to the above equations is
L
J M ( w, M ) =
M2
dw dM + ------- d x d x 2EI- + fw dx
Eq. 390
- -------- + wf dx
---------
dx dx
0
L
dw dM
( M )M
= 0
- ------- + ------------------ dx
---------dx dx
EI
dM dw
= 0
Eq. 391
217
Chapter
Using Eq. 365, the exact solution for the bending moment M can be obtained by differentiating Eq. 368 as
Mexact(x) = (f/2) (x-L)2 +M
The approximated solutions for w and M, which satisfies the boundary condtions w(0) = 0 and M(L) = M, are
taken as
w c 0w x + c 1w x 2, and M M + c 0M ( L x ) + c 1M ( L x ) 2
Substituting w and M in Eq. 391, we can write Eq. 391 in matrix form as
L
d w d M
- ---------- dx
--------dx
dx
cw
d w
dx
- ---------- dx -------------------- --------dx
dx
EI
0
0
L
d M
w fdx
cM
Eq. 392
MM
------------ dx
EI
where w = [x, x2], and M = [(L-x), (L-x)2]. The second term in the right-hand-side vector has the bending
moment boundary condition M(L) = M, which is shifted to the right-hand-side of Eq. 392 from the second term
in the second equation of the left-hand-side of Eq. 391. Program Listing 314 implements Eq. 392. The results
of the mixed formulation are shown in Figure 320.
#include "include\vs.h"
int main() {
double L_ = 1.0, E_ = 1.0, I_ = 1.0, f_ = 1.0, M_ = 1.0,
weight[5] = {14.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0, 14.0/45.0};
Quadrature qp(weight, 0.0, L_, 5.0);
H1 x(qp),
w = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE("int, int, Quadrature", 2, 1, qp),
M = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE("int, int, Quadrature", 2, 1, qp);
w[0] = x;
w[1] = x.pow(2);
M[0] = x-L_; M[1] = (x-L_).pow(2);
C0 e(2), E(2),
m =+( 0.0
*((e%e)*(E[0]%E[0])) +
(d(w)*(~d(M)))
*((e%e)*(E[0]%E[1]))+
(d(M)*(~d(w)))
*((e%e)*(E[1]%E[0])) +
( ((H0)M)*(~((H0)M))/(E_*I_) )*((e%e)*(E[1]%E[1])) ) | J(L_/4),
b = +( ( (-(H0)w)*f_ )
*(e*E[0])+
( (-(H0)M)*(M_/(E_*I_)) )
*(e*E[1]) ) | J(L_/4);
c = b / m;
cout << c << endl;
return 0;
}
M01 =
d w
d M
d M
d w
- ---------- dx
--------dx
dx
0
L
M10 =
- ---------- dx
--------dx
dx
0
L
M11 =
dx
--------------------EI
M
w fdx
b=
0
L M
M
------------ dx
EI
0
Listing 314 Mixed formulation for beam bending problem (project: mixed_formulation).
218
Variational Methods
0.6
0.5
0.4
0.3
0.2
0.1
1.5
1.4
1.3
1.2
1.1
exact ~~ approx.
exact = approx.
Figure 320 Approximated transeverse deflection w and bending moment M using mixed
formulation for the beam bending problem.
Green Function Solution: We now re-visit the solution by integral equation using Green function to solve the
same fourth-order differential equation and boundary conditions posed in Eq. 365 and Eq. 366. For simplicity
we set all material constant as 1 and this simplifies the problem to have a Green function that satisfies
4
dg
= ( x ), 0 < x, < 1 ;g ( 0, ) = g( 0, ) = g( 1, ) = 0, g( 1, ) = 1
dx4
Eq. 393
where ( . ) is the Dirac delta function. The jump condition of the shear force (V) due to the concentrated load at
is
V(+)-V(-) = -1
That results in the jump condition
solving the Green function is
g( + , ) g( , ) = 1
1.
dg
= 0, 0 < x < , < x < 1
dx4
2. ( 0, ) = g( 0, ) = g( 1, ) = 0, g( 1, ) = 1
3. g, g, g continuous at x = ; g( + , ) g( , ) = 1
219
Chapter
From conditions 1. and 2. we can determine that the Green function is of the form
For x < , g1= Ax2 + B x3 (from g4 = 0 and g ( 0, ) = g( 0, ) = 0 )
For x > , g2 =a + b (1-x) + c (1-x)2 (from g4 = 0 and g( 1, ) = 0 )
We can determine c = 1/2 by using g( 1, ) = 1 . Applying the jump condition g( + , ) g( , ) = 1 on x
= we have
g1= Ax2 - (1/6) x3 , and g2 =a + b (1-x) + (1/2)(1-x)2
That is B = -1/6. Consequently, the continuity of g at gives A = (1+)/2, and the continuity of g gives b = - 1
2/2. Then, the continuity of g gives a = 1/2 +(1/2) 2 (1/6) 3. Therefore,
g1= ((1+)/2) x2 - (1/6) x3; for x <
g2 = (1/2 +(1/2) 2 (1/6) 3) - (1+2/2) (1-x) + (1/2) (1-x)2; for x >
Eq. 394
Program Listing 315 implements the Green function defined in Eq. 394, the transverse loading f(x) is taken as
a constant 1.0. The results of eleven-points values are shown in Figure 321 for compared with the exact solution.
#include "include/vs.h"
int main() {
double x = 0.0,
wt[17] = {14.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0, 28.0/45.0 64.0/45.0, 24.0/45.0,
64.0/45.0, 28.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0, 28.0/45.0, 64.0/45.0,
24.0/45.0, 64.0/45.0, 14.0/45.0};
for(int i = 0; i < 11; i++) {
Quadrature q1(wt, 0.0, x, 17), q2(wt, x, 1.0, 17);
double c = 1.0/2.0, B = -1.0/6.0;
H0 z1(q1), z2(q2);
H0 A = (1.0 + z2) / 2.0,
a = 1.0/2.0+1.0/2.0*z1.pow(2)-1.0/6.0*z1.pow(3),
b = -1.0 - 1.0/2.0*z1.pow(2),
integrand1 = a + b*(1.0-x)+ c*pow((1.0-x), 2),
integrand2 = A*pow(x, 2) + B*pow(x, 3);
C0 integal_1, integal_2;
if(i != 0) integal_1 &= integrand1 | J(x / 16.0); else integal_1 &= C0(0.0);
if(i != 10) integal_2 &= integrand2 | J((1.0-x) / 16.0); else integal_2 &= C0(0.0);
double w = (double) (integal_1 + integal_2);
cout << "w(" << x << "): " << w << endl;
if(i != 10) x += 0.1;
}
return 0;
}
f(x) = 1, a constant
c = 1/2, B = - 1/6
A = (1+)/2
a = 1/2 +(1/2)2 (1/6)3
b = - 1 2/2
g2 =a + b (1-x) + c (1-x)2 (where <x)
g1= Ax2 + B x3 (where >x)
x
w(x) =
g2 d +
0
g 1 d
Listing 315 Integral equation solution using Green function for beam bending problem (project:
green_function).
220
Variational Methods
0.6
0.5
0.4
0.3
0.2
0.1
0.2
0.4
0.6
0.8
Figure 321 Point-values are integral equation solution using the Green function compared
with the curve of the exact solution.
221
Chapter
Poisson Equation
The two sub-sections on second-order differential equation and the fourth-order differential equation discussed above are ordinary differential equations with only one dimension. We now deal with the Poisson equation which is a partial differetial equation with dimensions greater than one.
Consider the Poisson equation defined in an unit square region with homogenous essential or natural boundary conditions
2 u = f
Eq. 395
Denote the square region as and its boundary as . Multiply the left-hand-side with the variation v and integrate over the square region .
v 2 udV =
[ ( vu ) v u ]dV
v udV vu nds
v udV
Eq. 396
The first identity uses the integration by parts and the second identity uses divergence theorem of Gauss, where
n is the surface unit normal vector. For homogeneous boundary conditions the boundary integral term vanishes.
We investigate three sets of boundary conditions
1. Dirichlet boundary conditions: u = 0 on all sides,
2. Neumann boundary conditions: u n = 0 on all sides,
3. Mixed boundary conditions: u = 0 on x0 = 1 and x1 = 1; u n = 0 on x0 = 0 and x1 = 0.
The matrix form for the Eq. 396 in this particular 2-D settings can be re-written as
11
Mij
i j i j
= -------- -------- + -------- -------- dx 0 dx 1, b i =
x 0 x 0 x 1 x 1
00
11
i fdx 0 dx1
Eq. 397
00
Eq. 398
Program Listing 316 implements Eq. 397 with basis functions in Eq. 398, where N = 3 and f = 1. Notice that
the 2-D integration are obtained by forming a 2-D array of weightings. The Jacobian of this problem is constant
throughout the whole integration domain. Figure 322 shows the results obtained from Program Listing 316.
222
Variational Methods
#include "include\vs.h"
#define PI 3.141597
int main() {
double f_0 = 1.0, weight[5][5],
bode[5] = {14.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0, 14.0/45.0};
for(int i = 0; i < 5; i++)
for(int j = 0; j < 5; j++) weight[i][j] = bode[i] * bode[j];
Quadrature qp(weight[0], 0.0, 1.0, 5, 0.0, 1.0, 5);
J d_a(pow( (1.0/4.0), 2.0));
H1 x(2, (double*)0, qp), phi = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE(
"int, int, Quadrature",9, 2, qp);
for(int m = 0; m < 3; m++)
for(int n = 0; n < 3; n++) phi[m*3+n] = sin((m+1.0)*PI*x[0])*sin((n+1.0)*PI*x[1]);
H0 M_diag(9, (double*)0, qp);
for(int i = 0; i < 9; i++)
M_diag[i] = d(phi[i]).pow(2);
C0 M = M_diag | d_a,
b = ( ((H0)phi) * f_0 ) | d_a,
c(9, (double*)0);
for(int i = 0; i < 9; i++) c[i] = b[i] / M[i];
cout << c << endl;
return 0;
}
2-D weightings
2-D Jacobian
i = mn = sin(mx0) sin(nx1)
m, n = 0, 2, ..., N-1, and i = m N + n
11
M ii =
i i
i i
00
11
bi =
i fdx0 dx1
00
Listing 316 The Poisson equation with the Dirichlet boundary conditions (project: poisson_dirichlet).
0.06
6
1
0.04
04
0.8
0.02
02
0.6
0
0
0.2
0.4
0.4
0.2
0.6
0.8
10
Figure 322 Solution of Poisson equation with homogeneous Dirichlet boundary conditions.
Eq. 399
For this Neumann boundary condition to be solvable, f can not be a non-zero constant. On physical ground if we
consider the Poisson equation to be for the heat conduction problem, the homogeneous Neumann boundary conditions mean that the square region is to be insulated from its surroundings. The temperature in the region will
Workbook of Applications in VectorSpace C++ Library
223
Chapter
increase with time, since the internal source f is added to the region. For a steady state solution to be possible
with totally insulated condition, we conclude that the N(A*) of the Laplace operator consists of constant functions (with the homogeneous Neuman boundary conditions.) Therefore, the solvability condition, from Eq. 350,
requires the orthogonal relation which has the internal source to equal the internal sink; i.e.,
f dV
Eq. 3100
= 0
In this case, we choose f = cos x which satisfies Eq. 3100. For the computation we only need to replace the
definition for i (N = 2) and the source term f = cos x.
Mixed Boundary Conditions : We choose approximation basis functions to be algebraic polynomials of the
form
i = (1-x02+i) (1-x12+i); i = 0, 1, 2, ..., N-1
Eq. 3101
We choose N = 2 and f = 1. The results of the Neumann boundary conditions and the mixed boundary conditions
are shown in Figure 323.
Mixed boundary conditions, with f = 1.0
Neumann boundary conditions, with f = cos x
0.3
3
0.1
1
0.05
5
0
-0.05
05
-0.1
.1
0
1
0.8
0.8
0.1
.1
0.6
0.2
0.2
2
0.4
0.6
0
0
0.2
0.4
0.4
0.4
0.2
0.6
0.2
0.6
0.8
0.8
10
10
Figure 323 Solutions of the Poisson equation with the Neumann and mixed boundary conditions.
Green Function Method : The Green function for Eq. 395 with the Dirichlet boundary condtions is1
g ( x, y ;, ) =
y ))}
Eq. 3102
n=1
1. Problem 9.3.9 in p. 147 of G.F. Carrier, and C.E. Pearson, 1988, Partial Differential Equations: Theory and technique
2nd eds., Academic Press Inc., San Diego, CA.
224
Variational Methods
Program Listing 317 (project: green_poisson) is the code for Poisson equations with the Dirichlet boundary
conditions using the Green function (Eq. 3102). The computation approximates the infinite series only up to n =
8. The results of this approximation are shown in Figure 324.
#include "include\vs.h"
#define PI 3.141597
H0 cosh(const H0& a) { return (exp(a)+exp(-a))/2.0; }
int main() {
const double f_0 = -1.0,
bode[17] = {14.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0, 28.0/45.0, 64.0/45.0, 24.0/45.0,
64.0/45.0, 28.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0, 28.0/45.0, 64.0/45.0, 24.0/45.0,
64.0/45.0, 14.0/45.0}, weight[17][17];
for(int i = 0; i < 17; i++)
for(int j = 0; j < 17; j++) weight[i][j] = bode[i] * bode[j];
Quadrature qp(weight[0], 0.0, 1.0, 17, 0.0, 1.0, 17);
J d_a(pow( (1.0/16.0), 2.0));
double x0, x1;
H0 z(2, (double*)0, qp), integrand(qp), zai, eta; zai &= z[0]; eta &= z[1];
for(int i = 0; i < 11; i++) {
for(int j = 0; j < 11; j++) {
x0 = 0.1 * j; x1 = 0.1 * i;
integrand = 0.0;
for(int n = 1; n <= 8; n++) {
integrand += (f_0/(n*PI*sinh(n*PI))*sin(n*PI*x0)*sin(n*PI*zai)*
(cosh(n*PI*(1.0-x1-eta))-cosh(n*PI*(1.0-sqrt((x1-eta)*(x1-eta))))));
}
C0 integal = integrand | d_a;
cout << "u(" << x0 << ", " << x1 << ") = " << ((double)integal) << ", ";
}
cout << endl;
}
return 0;
}
2-D weightings
2-D Jacobian
g ( x, y ;, ) =
sin ( n ) sin ( nx )
--------------------------------------------n sinh ( n )
n=1
{ cosh ( n ( 1 ( y + ) ) ) cosh ( n ( 1 y ) ) }
Listing 317 The Green function method on the Poisson equation with the Dirichlet boundary conditions.
0.06
6
1.0
1.
0.04
04
0.02
02
0
0.0
-1
0.5
0.5
1 -1
Figure 324 Eight-term (n=8) Green function method for the Poisson equation with the Dirichlet
boundary conditions.
1.0
1
0 0.0
225
Chapter
Eq. 3103
where is set to the essential boundary conditions of u, and i is homogenous on the boundaries. Define the
residual RN of the approximated solution as
Eq. 3104
R N = Au N f
The residual can be distributed in an over-all manner through-out the whole domain, and then set the integrated
value to be zero, such as
( w, R N ) =
wRN d
= 0
Eq. 3105
where w is the weighting function. Different ways of defining the weighting function lead to different types of
approximation methods. The general class of methods in the form of Eq. 3105 is known as the weighted-residual methods.
Point-Collocation Method
The weighting function of the point-collocation method can be expressed using the Dirac delta function that
is
w = (x-)
Eq. 3106
( x )f ( x ) dx
= f( )
Eq. 3107
Therefore, substituting Eq. 3106 into Eq. 3105 gives RN() = 0. What we have to do is simply pick a number of
collocation points i , evaluate their corresponding residuals, and obtain a system of equations by setting these
residual equations to zero.
Considering the example1
2
du
+ u + x = 0,
dx2
0<x<1
Eq. 3108
1. p. 14 and on in C.A. Brebbia, J.C.F. Telles, and L.C. Wrobel, 1984, Boundary element techniques: Theory and applications in engineering, Springer-Verlag, Berlin, Germany.
226
Variational Methods
subject to boundary conditions u(0) = u(1) = 0. The exact solution to this problem is
sin ( x )
u exact = --------------- x
sin ( 1 )
Eq. 3109
Two term approixmation basis functions which satisfy this homogenous boundary condition can be taken from
Eq. 361 in page 204,
0 = x (1-x), and 1 = x2 (1-x)
That is u2 = c0 0 + c1 1. Two collocation points are necessary for solving the two unkown coefficients, and they
are taken at 0 = 1/4 and 1 = 3/4. These two points generate two residual equations in matrix form as
d2 1 ( 0 )
d 2 0 ( 0 )
---------------------- + 0 ( 0 ) --------------------- + 1 ( 0 )
c0
0
dx 2
dx 2
=
2
2
c1
1
d 1 ( 1 )
d 0 ( 1 )
--------------------- + 0 ( 1 ) --------------------- + 1 ( 1 )
2
2
dx
dx
Eq. 3110
We can also write Eq. 3110 as M c = - b. This two-point collocation problem is simple enough to be solved by
hand, or you can code it with VectorSpace C++ Library, which has the advantage that it can be extended to higher
number of basis functions and collocation points, and the matrix solution procedure becomes inevitable (see
project: point_collocation)
double x[2] = {0.25, 0.75};
// 0 = 1/4, 1 = 3/4
C0 M(2, 2, (double*)0), b(2, x);
for(int i = 0; i < 2; i++) {
C2 z(x[i]),
phi = VECTOR_OF_TANGENT_OF_TANGENT_BUNDLE(int, int, 2, 1);
phi[0] = z*(1-z); phi[1] = z.pow(2)*(1-z);
// 0 = x (1-x), 1 = x2 (1-x)
M[i] = (+dd(phi))(0)+((C0)phi);
// d2/dx2 +
}
C0 c = -b / M;
cout << c << endl;
// c = {0.189841, 0.172043}T
For a Vector_of_Tangent_of_Tangent_Bundle object with spatial dimension = 1, we need a forced degeneration
operation for its Hessain, (+dd(phi))(0). The first operation has the primary casting operator + casting a
Nominal_Submatrix to a Matrix, and then a column selector ( ) makes this Matrix into a Vector. The approximated two-point-collocation solution is u2 = 0.189841 x (1-x) + 0.172043 x2 (1-x). This result is plotted against
the exact solution uexact = sin(x)/sin(1) -x in Figure 325. There are no significant differences among the two
from the left-hand-side of Figure 325.
227
Chapter
Solution - Exact
0.07
0.06
0.2
0.05
0.04
-0.0002
0.03
-0.0004
0.4
0.6
0.8
0.02
-0.0006
0.01
0.2
0.4
0.6
0.8
-0.0008
Figure 325 Two-points collocation solution and error comparing to the exact solution.
We can investigate further on the relationships of the point-collocation method and the finite difference
method. Considering the domain (cell) has three equally spaced points xi-1, xi, and xi+1, the approximating
function u correspoinding to these three points are given as ui-1, ui, and ui+1. The value of u in between two consequtive points can be interpolated with a set of quadratic interpolation functions as
u = ui-1 1 + ui 2 + ui+1 3
Eq. 3111
Eq. 3112
where
Considering the cell length = 2h for the three equally spaced points, we have a constant Jacobian for the coordinate transformation rule through-out the whole cell as d/dx = 1/h. With a point-collocation on = 0, the first
derivative of u with respect to x is
du/ dx = (du/ d) (d/dx) = [(-1/2)ui-1 + 2ui + (+1/2)ui+1] 1--h
=0
1
= ------ (ui+1-ui-1)
2h
Eq. 3113
Notice that the point-collocation is taken at = 0. Eq. 3113 is the central difference formula. We can check that
point-collocation at = -1/2 and = 1/2 will yield the backward difference and the forward difference formula,
respectively. The second derivative of u can be derived accordingly as
1
h
Eq. 3114
This finite difference formula for the second derivative is independent of ; i.e., the position of collocation point.
228
Variational Methods
Subdomain-Collocation Method
The weighting function for the subdomain-collocation method is taken as a step function defined, for example, as
1, 1 < x < 2
w =
0, 1 < x < 1 or 2 < x < 1
Eq. 3115
where x, 1, and 2 can be all defined in the interval of (-1, 1). For a function f(x), we have
2
wf ( x )dx
f ( x )dx
Eq. 3116
That is the domain of integration is now restricted to the subdomain bounded by [1, 2]. Substituting the weighting function of Eq. 3115 in the weighted-residual statement of Eq. 3105 gives
2
RN ( x )dx
Eq. 3117
= 0
The subdomain-collocation method evaluates a number of subdomains bounded by different sets of [1, 2] in
Eq. 3117, for solving the coefficient vector c.
Considering the same example in the point-collocation case with the same basis functions and two subdomains 1 = (-1, 0), and 2 = (0, 1), we then have
d2 0
----------- + 0 dx
dx 2
d 2 1
- + 1 dx
---------dx 2
c0
1
d2 0
----------- + 0 dx
dx 2
c1
d 2 1
----------- + 1 dx
2
dx
xdx
=
Eq. 3118
xdx
2
The code which implements Eq. 3118 with VectorSpace C++ Library is (project: subdomain_collocation)
double x[2][2] = {{-1.0, 0.0}, {0.0, 1.0}},
// 1 =(-1,0), 2 = (0, 1)
w[5] = {14.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0, 14.0/45.0}; // Bodes integration rule
C0 M(2, 2, (double*)0), b(2, (double*)0);
for(int i = 0; i < 2; i++) {
Quadrature qp(w, x[i][0], x[i][1], 5);
// Quadrautre in subdomain i
J d_l((x[i][1]-x[i][0])/4.0);
Workbook of Applications in VectorSpace C++ Library
229
Chapter
// c = {0.181818, 0.181818}T
The coefficient vector is not substantially different from that of the point-collocation case. The results are shown
in Figure 326.
Error
0.07
0.00025
0.06
0.2
0.05
0.4
0.6
0.8
-0.00025
0.04
-0.0005
0.03
-0.00075
-0.001
0.02
-0.00125
0.01
-0.0015
0.2
0.4
0.6
0.8
Figure 326 Solution of subdomain collocation and error compared with the exact
solution.
We note that the first derivative of u with respect to x collocated in the interval of (-1/2, 1/2) is
1
--2
1
--2
du
d x dx
1
--2
d d x dx
du
1 1
1
= --- --- ( 1 )u i 1 + ( 1 ) ( 1 + )u i + --- ( 1 + )u i + 1
h 2
2
1
--2
1
--2
1
--2
1
= ------ (ui+1-ui-1) Eq. 3119
2h
This gives the central difference formula. Similarly, subdomains [-1, 0] and [0, -1] give backward difference and
forward difference formula, respectively.
Method of Moment
In statistics, the idea of using moments to descirbe a distribution is taken from mechanics. The expectation of
a distribution can be considered as the center of the gravity. The variance is the second power of distances of the
data with respect to this center of gravity. Skewness and kurtosis are defined as the third and fourth power of
the distances, respectively.
For the weighted-residual method, we can choose the weighting function in Eq. 3105 to be the various
power of coordinate variable x, such as
230
Variational Methods
wi = xi, i = 0, 1, 2, ....
Eq. 3120
That is the residuals (or errors) are distributed through-out the domain with various moments of x. We notice that
the weighting function for the weighted residual method in general is not necessarily required to satisfy the
homogeneous boundary conditions.
Consider the example in the point-collocation and subdomain collocation with the approximation basis function 0 = x (1-x), and 1 = x2 (1-x). We use first two weighting moments w 0 = 1 and w1 = x. This gives
d2
----------0- + dx
dx 2 0
d2
----------1- + dx
dx 2 1
c0
d2
----------0- + dx
x
dx 2 0
c
d2
----------1- + dx 1
x
dx 2 1
xdx
=
Eq. 3121
x 2 dx
The code which implements Eq. 3121 with VectorSpace C++ Library is (project: method_of_moment)
double w[5] = {14.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0, 14.0/45.0}; // Bodes integration rule
C0 M(2, 2, (double*)0), b(2, (double*)0);
Quadrature qp(w, 0.0, 1.0, 5);
J d_l(1.0/4.0);
for(int i = 0; i < 2; i++) {
H2 x(qp),
phi = INTEGRABLE_VECTOR_OF_TANGENT_OF_TANGENT_BUNDLE(
int, int, Quadrature, 2, 1, qp);
phi[0] = x*(1-x); phi[1] = x.pow(2)*(1-x);
// 0 = x (1-x), 1 = x2 (1-x)
M[i] = (((H0)x).pow(i)*(+dd(phi))(0)+((H0)phi)) | d_l; // d2/dx2 +
b[i] = - ((H0)x).pow(i+1) | d_l;
}
C0 c = b / M;
cout << c << endl;
// c = {0.166667, 0.212121}T
The results of this implementation are shown in Figure 327.
Error
0.07
0.001
0.06
0.05
0.2
0.04
0.03
0.4
0.6
0.8
-0.001
0.02
-0.002
0.01
0.2
0.4
0.6
0.8
231
Chapter
Eq. 3122
Consider the same example we solved starting from the point-collocation method in the above. We have
d2 j
- + j dx
i --------
dx 2
c j = i xdx
Eq. 3123
For two term approximation (i = 0, 1), the matrix form can be written as
d2 0
d 2 1
- + 0 dx 0 ----------- + 1 dx
0 ---------
dx 2
dx 2
d2
0
1 --------- dx 2
+ 0 dx
d2
1
1 --------- dx 2
+ 1 dx
c0
c1
0 xdx
=
Eq. 3124
1 xdx
The code implements Eq. 3124 with VectorSpace C++ Library as (project: galerkin_method)
double w[5] = {14.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0, 14.0/45.0}; // Bodes integration rule
C0 M(2, 2, (double*)0), b(2, (double*)0);
Quadrature qp(w, 0.0, 1.0, 5);
J d_l(1.0/4.0);
for(int i = 0; i < 2; i++) {
H2 x(qp),
phi = INTEGRABLE_VECTOR_OF_TANGENT_OF_TANGENT_BUNDLE(
int, int, Quadrature, 2, 1, qp);
phi[0] = x*(1-x); phi[1] = x.pow(2)*(1-x);
// 0 = x (1-x), 1 = x2 (1-x)
M[i] = (((H0)phi)[i]*(+dd(phi))(0)+((H0)phi)) | d_l;
// d2/dx2 +
b[i] = - (((H0)phi)[i]*((H0)x)) | d_l;
}
C0 c = b / M;
cout << c << endl;
// c = {0.166667, 0.212121}T
The results of the above implementation are shown in Figure 327. Notice that although we choose the weighting functions equal to the approximation basis functions; i.e., wi = i , the left-hand-side matrix M is still not
symmetrical. This is because the operator A(u) = (d2 u/ dx2 + u) is not self-adjoint. .
232
Variational Methods
0.08
0.14
Error
0.12
0.06
0.1
0.08
0.04
0.06
0.02
0.04
0.02
0.2
0.2
0.4
0.6
0.8
0.4
0.6
0.8
Eq. 3125
= ( i, A j )
Eq. 3126
where a( . , . ) is a bilinear form which is symmetrical. Therefore, A is self-adjoint ( Eq. 3126), and the resultant
weak formulation with the Galerkin weighting is symmetrical (Eq. 3125). In the case of the self-adjoint operator, the Galerkin method with wi = i is also known as the Bubnov-Galerkin method. When wi i , it is known
as the Petrov-Galerkin method
A second example is the eigenvalue problem of a circular membrance of radius a given by1
2u = u
Eq. 3127
with homogeneous essential boundary conditions. This axisymmetric problem can be reduced to a 1-D problem
in polar coordinate r as
1d
du
--- r
= u
r d r d r
Eq. 3128
The approximation basis functions which satisfy the homogeneous boundary conditions are
r
i = cos ( 2 i + 1 ) ------, i = 0, 1, 2, , N 1
2a
Eq. 3129
1. p. 292 in J.N. Reddy, 1986, Applied functional analysis and variational methods in engineering, McGraw-Hill, Inc.
233
Chapter
1 d dj
i --r- d r r d r ( 2rdr )cj =
0
i j ( 2rdr )cj
Eq. 3130
Therefore,
2
a d
a
d j
j r
rdr c
c
dr
=
i 2
idr
i j j
dr j
0
Eq. 3131
Eq. 3132
We solve Eq. 3131 for N = 2 and a = 1. First, we notice that the off-diagonals of A is analytically identical since
the Laplace operator is self-adjoint. However, numerically, the off-diagonals of A can be slightly different due to
errors from numerical integration. We can either ignore such differences or symmetrize A numerically by defining As = (A+AT)/2. Now we can solve the generalized eigenvalue problem by using the inverse of B as
B -1Asx = x
Eq. 3133
However, (B -1As) will not be symmetrical. We can not use a symmetrical eigenvalue solver for this problem.
Therefore, we first use Cholesky decomposition for the symmetrical matrix B = LLT. The symmetry of the lefthand-side can now be preserved by pre-multipling L -1 and post-multipling (L-1)T on Eq. 3132 to give
(L -1) As ((L-1)T) x = x
Eq. 3134
Program Listing 318 implements the Galerkin method with Laplace operator in Eq. 3131, and using Eq. 3134
to solve the symmetric eigenvalue problem.
The results are shown in Figure 329. The surface graphs represent the modes from eigenvectors as a function of vi j j, where vi is the i-th eigenvector. The frequencies i are computed from eigenvalues i as
i =
234
Variational Methods
#include "include\vs.h"
#define PI 3.141592654
int main() {
double a_= 1.0,
weight[25] = {14.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0, 28.0/45.0, 64.0/45.0, 24.0/45.0,
64.0/45.0, 28.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0, 28.0/45.0, 64.0/45.0,
24.0/45.0, 64.0/45.0, 28.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0, 28.0/45.0,
64.0/45.0, 24.0/45.0, 64.0/45.0, 14.0/45.0};
Quadrature qp(weight, 0.0, a_, 25);
J d_r(a_/24.0);
H2 r((double*)0, qp),
phi = INTEGRABLE_VECTOR_OF_TANGENT_OF_TANGENT_BUNDLE(
"int, int, Quadrature", 3, 1, qp);
phi[0] = cos((PI/2.0/a_)*r); phi[1] = cos((3.0*PI/2.0/a_)*r); phi[2] = cos(5.0*PI/2.0/a_*r);
H0 d2_phi = INTEGRABLE_VECTOR("int, Quadrature", 3, qp);
for(int i = 0; i < 3; i++) d2_phi[i] = dd(phi)(i)[0][0];
C0 A = -( ( d(phi)(0)%((H0)phi) + d2_phi%((H0)phi)*((H0)r) ) | d_r ),
B = ( ((H0)phi)%((H0)phi) * ((H0)r) ) | d_r;
C0 L = MATRIX("int, int", 3, 3);
Cholesky Ch(B);
for(int i = 0; i < 3; i++)
for(int j = 0; j < 3; j++)
if(i >= j) L[i][j] = Ch.rep_ptr()[0][i*(1+i)/2+j];
else L[i][j] = 0.0;
C0 L_inv = L.inverse(),
C = L_inv*((A+~A)/2.0*(~L_inv)),
lambda = Eigen(C).Eigenvalues(),
v = Eigen(C).Eigenvectors();
cout << lambda << endl;
cout << v << endl;
return 0;
}
radius a = 1
extended Bodes integration rule
r
i = cos ( 2 i + 1 ) ------, i = 0, 1, 2
2a
2
d j
d j
A= i r i 2 dr
d
r
dr
0
a
B=
i j rdr
0
Cholesky decomposition
Lower triangular matrix
(L -1) As ((L-1)T) x = x
= {5.78529, 30.4889, 75.0492}T
v0 ={0.999174, 0.398374, -0.008019}T
v1 ={0.0396508,-0.998966,-0.022225}T
v2={0.00889577,-0.0218887,0.99972}T
Listing 318 Galerkin method for the eigenvalue problem of a circular membrance (project:
circular_membrance).
0 =2.40526
1 = 5.52168
2 = 8.66309
2
1
0.5
-1
-2
-1
0.5
-1
-2
-1
-0.5
-0.5
1 -1
0
-0.5
0
0.5
0.5
0.5
1
0.5
-1
-2
-1
-0.5
-0.5
-0.5
1
0
1 -1
1 -1
Figure 329 Three frequency and mode pairs of the circular membrance eigenvalue problem.
235
Chapter
du
du 2
u 2 + = 1,
d x
dx
Eq. 3135
1 + x2
Eq. 3136
This problem can be transformed to one that has homogeneous boundary conditions by setting u = v+ 2 such
that
2
(v + 2)
d v dv 2
+
= 1,
d x 2 d x
v' ( 0 ) = 0, v ( 1 ) = 0
Eq. 3137
This is equivalent to
dv
d
(v + 2)
dx
dx
= 1,
v' ( 0 ) = 0, v ( 1 ) = 0
Eq. 3138
dv N
d
( vN + 2)
1
dx
dx
Eq. 3139
The weighted residuals method with Galerkin weightings, wN = ci i , and approximation basis functions, vN = cj
j , gives
1
dv N
d
I ( c ) = c i i R ( v N ) dx = c i i
( vN + 2)
1 dx = 0
dx
dx
Eq. 3140
where ci are arbitary constants and will eventually be dropped from Eq. 3140, and cj is the only unknown vector
of the non-linear problem. Integrating by part on the first term gives the weak formulation
1
I ( c ) = ci ( vN + 2 )
d i dv N
i dx = 0
dx dx
Eq. 3141
1. p. 294 in J.N. Reddy, 1986, Applied functional analysis and variational methods in engineering, McGraw-Hill, Inc.
236
Variational Methods
I ( c jk + 1 ) = I ( c jk + cjk ) I ( cjk ) +
I
c
c jk = 0
Eq. 3142
cjk
where cjk+1 = cjk + cjk. The approximation in this equation is the Taylor expansion to the first-order derivatives.
That is the increment of the solution cjk can be solved by
c jk =
I
c
I ( c jk ) = [ IT ] 1 I ( c jk )
Eq. 3143
d i dv N d j
+
( v + 2 ) dx
dx jdx
dx N
Eq. 3144
ci
= ci
0
Program Listing 319 implements the three-parameters approximation of the weak formulation I(c) (Eq. 3141)
and its tangent IT (Eq. 3144), then, uses the iterative alogrithm (Eq. 3143; i.e., Newtons method) to solve for
the increment of the Ritz coefficients c. The preprocessing macro __PETROV_GALERKIN, if defined at
compile time, the corresponding code segment implements the Petrov-Galerkin method with the approximation
basis functions for weighting as
2i + 1
i = cos -------------- , i = 0, 1, 2
2
Eq. 3145
u = wN + 2 = c0 ( 1 x ) + c 1 ( 1 x ) + c2 ( 1 x 3 ) + 2
Eq. 3146
The results of the computation are shown in Figure 330. The data speak for themselve without the need for any
elaboration.
237
Chapter
#include "include\vs.h"
#define EPSILON 1.e-12
int main() {
double weight[13] = {14.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0, 28.0/45.0, 64.0/45.0,
24.0/45.0, 64.0/45.0, 28.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0,
14.0/45.0};
Quadrature qp(weight, 0.0, 1.0, 13);
J d_l(1.0/12.0);
H1 x(qp),
phi = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE(
"int, int, Quadrature", 3, 1, qp);
phi[0] = 1.0-x; phi[1] = 1.0-x.pow(2); phi[2] = 1.0-x.pow(3);
#if defined(__PETROV_GALERKIN)
#define PI 3.141592654
H1 psi = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE(
"int, int, Quadrature", 3, 1, qp);
psi[0] = cos(PI/2.0*x); psi[1] = cos(3.0*PI/2.0*x); psi[2] = cos(5.0*PI/2.0*x);
#else
H1 psi;
psi &= phi;
#endif
C0 c(3,(double*)0), delta_c(3,(double*)0);
do {
H1 v = c * phi;
C0 I = ( d(psi)(0) * ( ((H0)v)+sqrt(2.0) ) * d(v)[0] + ((H0)psi) ) | d_l,
I_t = ( d(psi)(0) % (((H0)phi) * d(v)[0] + d(phi)(0) * ( ((H0)v)+sqrt(2.0) ) ) ) | d_l;
delta_c = - I / I_t;
c += delta_c;
cout << c << ", " << norm(delta_c) << endl;
} while((double)norm(delta_c ) > EPSILON);
cout << c << endl;
return 0;
}
i = (1-xi+1), i = 0, 1, 2
Petrov-Galerkin method
(2 i + 1)
i = cos ---------------------- , i = 0, 1, 2
2
Bubnov-Galerkin method
i = i
1
I=
0
1
IT=
( vN + 2 )
d i dv N
i dx
dx dx
d i dv N dj
+
( v + 2 ) dx
dx jdx
dx N
c = - I / IT , and ck+1 = ck + ck
Bubnov: c = {0.00539687, -0.547092,
0.127479}T, Petrov: c = {0.00884522, 0.554076, 0.131396}T .
Listing 319 Galerkin method for a non-linear differential equation (project: nonlinear_galerkin).
1.4
u exact ( x ) =
1 + x2
0.0006
1.3
0.0004
1.2
0.0002
Petrov-Galerkin
Bubnov-Galerkin
Errors
1.1
0.2
0.2
0.4
0.6
0.8
0.4
0.6
-0.0002
238
0.8
Variational Methods
Least Squares Method
The basic idea of the least squares method is introduced in Eq. 126 of Chapter 1 on page 35. The minimization of the squares of the residual norm is
R N 22
R N
= 0
------------------ = 2 RN, ---------
c
c
Eq. 3147
The factor 2 can be dropped since the equation equals zero. Comparing Eq. 3147 with the weighted-residual
statement ( R N, w ) = 0 it shows that the least squares method is a special case of the weighted-residual method
with the weighting function w as
R N
w = ---------c
Eq. 3148
c
c
ci
RN R N
2 RN
Eq. 3149
RN = ( vN + 2 )
d vN
dx2
dv N 2
1
+
dx
Eq. 3150
dv
R N
d dv N
d
---------- = N +
(v + 2) + 2
dxdx
c
d x2
dx2 N
Eq. 3151
2 RN
d d
d d
------------- =
+
+2
dx dx
c 2
dx2 dx2
Eq. 3152
Program Listing 320 implements Eq. 3149 to Eq. 3152, with three-parameter approximation. Considering that
the exact solution of the problem is an even function we assume the approximation basis functions are 0 = (1x2), 1 = (1-x4), and 2 = (1-x6). This set of approximation basis functions are as accurate as if we had used sixparameter approximation with continuous power of algebraic functions. The errors of this computation are
shown in Figure 331. Before we proceed any further, we notice that the combination of the concept of subdomain collocation method and weak formulation with Galerkin method provides the foundations of the finite element method which we will discuss in details in Chapter 4 and Chapter 5.
Workbook of Applications in VectorSpace C++ Library
239
Chapter
#include "include\vs.h"
#define EPSILON 1.e-12
int main() {
double weight[13] = {14.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0, 28.0/45.0, 64.0/45.0,
24.0/45.0, 64.0/45.0, 28.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0,
14.0/45.0};
Quadrature qp(weight, 0.0, 1.0, 13);
J d_l(1.0/12.0);
H2 x((double*)0, qp),
phi = INTEGRABLE_VECTOR_OF_TANGENT_OF_TANGENT_BUNDLE(
"int, int, Quadrature", 3, 1, qp);
phi[0] = 1.0-x.pow(2); phi[1] = 1.0-x.pow(4); phi[2] = 1.0-x.pow(6);
H0 d2_phi = INTEGRABLE_VECTOR("int, Quadrature", 3, qp);
for(int i = 0; i < 3; i++) d2_phi[i] = dd(phi)(i)[0][0];
C0 c(3, (double*)0), delta_c(3, (double*)0);
do {
H2 w = c * phi;
H0 R = d(w)[0].pow(2)+(((H0)w)+sqrt(2.0))*dd(w)[0][0]-1.0,
dR = 2.0*d(phi)(0)*d(w)[0]+((H0)phi)*dd(w)[0][0]+d2_phi*(((H0)w)+sqrt(2.0)),
ddR = 2.0*(d(phi)(0)%d(phi)(0))+((H0)phi)%d2_phi+d2_phi%((H0)phi);
C0 I = ( dR*R ) | d_l,
I_t = ( dR%dR+ddR*R ) | d_l;
delta_c = -I /I_t;
c += delta_c;
cout << c << ", " << norm(delta_c) << endl;
} while((double)norm(delta_c ) > EPSILON);
cout << c << endl;
return 0;
}
RN = ( vN + 2 )
2
R
c
N
I = R N, ----------
2R
N
N
N
IT= ----------, ---------- + R N, ------------c c
c 2
c = - I / IT , and ck+1 = ck + ck
c= {-0.491866, 0.0970614, -0.018541}T
0.0006
Error
0.0004
0.0002
0.6
0.8
240
2 RN
d d
d d
------------- =
+
+2
dx dx
c 2
dx2 dx2
0.0008
0.4
dx2
dv N 2
1
+
dx
d vN d
R N
d dv N
---------- =
+ 2 ( vN + 2 ) + 2
2
c
dxdx
dx
dx
Listing 320 Least squares method for a non-linear differential equation (project:
nonlinear_least_squares).
0.2
d vN
Variational Methods
3.3.3 Boundary Solution Methods
Consider the residual of the Poisson equation as in Eq. 395; i.e., R N = 2 u + f , in the context of the
weighted-residual statement,
( R N, w ) =
RN w d
( 2 u + f )w d
= 0
Eq. 3153
If we integrate by part once, and apply Greens theorem to transform the volume integral to the surface integral
as
u w + f w d
( n u )w d
Eq. 3154
when the approximation basis functions for u and w are the same the first term in the left-hand-side of Eq. 3154
is equivalent to the corresponding term in the Bubnov-Galerkin method for a self-adjoint operator (weak formulation) discussed in Eq. 3125. When the right-hand-side of Eq. 3154 is included in the variational statment, Eq.
3154 is also equivalent to the corresponding term in the Rayleigh-Ritz method in Eq. 353. Taking Eq. 3154
and integrating by parts once more, and applying Greens theorem to transform volume integral to surface integral,again, we have
( ( 2 w )u + fw ) d
( n w )u d ( n u )w d
Eq. 3155
An alternative view to the weighted-residual derivation from Eq. 3153 is possible. By setting f = - 2 u , we identify, directly, Eq. 3154 as Greens first identity, and Eq. 3155 as Greens second identity.1
Trefftz Method
In Trefftz method, both u and w in Eq. 3155 are taken as harmonic functions. By definition, harmonic founctions satisfy the Laplace operator
2 u = 2w = 0
Eq. 3156
( n w )u d
( n u )w d
Eq. 3157
1. p. 450 in L.E. Malvern, 1969, Introduction to the mechanics of a continuous medium, Prentice-Hall, Englewood Cliffs,
N.J.
2. p. 38 in C.A. Brebbia, J.C.F. Telles, and L.C. Wrobel, 1984, Boundary element Techniques: Theory and applications in
engineering, Springer-Verlag, Berlin, Germany.
241
Chapter
Eq. 3158
u = --- (x2+y2) + v
Eq. 3159
v
v
----x
dy =
x=1
v
----x
0
dy
Eq. 3160
x=1
i
- i
-----
x
0
dy c =
x=1
- v
dy
-----x
x=1
Eq. 3161
M =
i
- i
-----
x
0
dy,
and b =
x=1
- v
dy
-----x x = 1
Eq. 3162
Due to the symmetry of the problem with respect to x and y, only H0, H2 and H4 out of the list of algebraic harmonic functions will be taken. In view of the problem at hand, H0 = 1.0 can not be in i, because the x-derivatives in the matrix M and vector b are both zero. We can remedy this by taking only
1 = H2 = (x4 - 6x2y2 + y4) and 2 = H4 = (x8 - 28 x6y2 + 70 x4y4 -28 x2y6 + y8)
242
Eq. 3163
Variational Methods
v = c1 1 + c2 2 with u = -v + v + c0 where v = (x2+y2) f /4. Without the solution for a constant term, the boundary integral equation is indetermined up to the constant value c0. After we obtain c1 and c2, c0 can be computed
by requiring
1
u dy
( v + c1 1 + c2 2 + c0 ) x = 1 dy
= 0 =
Eq. 3164
c0 = ( v + c1 1 + c 2 2 )
x=1
Eq. 3165
dy
Program Listing 321 implements Eq. 3162 with basis functions Eq. 3163 and integrating constant c0 computed from Eq. 3165. Alternatively we can use transcendental harmonic functions symmetrized with respect to x
and y as
1 = cos(x/2) cosh(y/2) + cos(y/2) cosh(x/2), and
2 = cos(3x/2) cosh(3y/2) + cos(3y/2) cosh(3x/2)
The macro definition __TRANSCENDENTAL, if defined at compile time, turns on the corresponding code
segments.
The first quadrant solution of this problem is shown in Figure 332, which is directly comparable to the solution of the same problem shown in the right-hand side of Figure 323. Transcendental harmonic functions give
almost identical results.
0.3
3
1
0.2
2
0.8
0.1
.1
0
0
0.6
0.2
0.4
0.4
0.2
0.6
0.8
10
Figure 332 The first quadrant solution of the Poisson equation using the Trefftz method.
243
Chapter
x evaluated at 1
v = f (x2+y2) /4
1, and 2
1
M =
- i
dy
-----
x
x=1
0
b =
- v
dy
-----x x = 1
0
c0 = ( v + c1 1 + c2 2 )
algebraic: c0 = 0.29469
c= {-0.0453175, 0.0013438}T
transcendental: c0 = 0.496296
c= {-0.10095, 0.00014436}T
Listing 321 Solution of Poisson equation with Trefftz method (project: trefftz_method).
244
x=1
dy
Variational Methods
Boundary Element Method
If we consider the Poisson equation and set f = - 2 u , Eq. 3155 becomes the Greens second identity
( ( 2 w )u ( 2 u ) w ) d
( n w )ud ( n u )w d
Eq. 3166
In the case of heat conduction, we use temperature T in place of u; therefore, we have the heat flow q =
n u = u n , the weighting function w is taken as the fundamental solution (Greens function) T* in the
boundary element method, which satisfies
( x, )
2 T ( x, ) = -------------------k
Eq. 3167
where (x, ) is the Dirac delta function with x as the sampling point, as the point source location, and k is the
conductivity. In two-dimensional case, the solution is
1
T ( x, ) = ---------- ln ( r )
2k
Eq. 3168
Eq. 3169
For simplicity, we deal with problems without internal heat source; i.e., f = 0. When f 0 , domain integral is
required. From programming point of view, the advantage of the boundary element method begins to make concession to the finite element method. Substituting Eq. 3168 and Eq. 3169 into Eq. 3166, we have
( x, )
-------------------- T d ( 0 )T d =
k
n q
- T d ( n q )T d
-------------k
Eq. 3170
( n q )T d ( n q )T d
Eq. 3171
where c = 1 if is inside , c = 0 if is outside , and c = 1/2 if is on a smooth boundary . The boundary integral equation for the boundary element method is obtained by discretizing the boundary to boundary elements
as
Workbook of Applications in VectorSpace C++ Library
245
Chapter
( n q ) e T ( x, ) d T e ( n q ( x, )) d
e
Eq. 3172
where T and q can be either a variable or a specified boundary condition. For the matrix form representation of
Eq. 3172, we reserve T and q as the unknown and T and q as corresponding boundary conditions, and denote
G ij =
T ( x, i ) d,
and H ij =
( n q ( x, i ) ) d,
ij
with H ij = H ij -----2
Eq. 3173
H ij G ij
Tj
qj
Eq. 3174
= H ij Tj + G ij q j
This can be re-written as A x = b. Two singular integrations in Eq. 3174 occur, when the source location is
right on the element under consideration; i.e., all diagonal terms on the left-hand-side. For an element with constant shape function, it can be proved that 1
H ii =
(n q ) d = 0,
and G ii =
2
ln --- + 1
h
T d= --------2k
Eq. 3175
where h is the size of the constant element with one variable node on the middle of the element. After the variables T and q are solved from Eq. 3174. The interior temperature at any location can be recovered using Eq.
3172, by setting c = 1. The interior heat flux can also be recovered by applying Fouriers law of conduction and
Eq. 3172 (c = 1). We have a response gradient boundary integral equation as
T ( x, )
(n q ( x, ))
T ( )
q ( ) = k -------------- = k ( n q ) e ----------------------- d T e ------------------------------------- d
Eq. 3176
where
( xi i )
( x i i )
1
r
T ( x, )
r
----------------------- = ---------- r 1 ------- = ------------------, sin ce ------- = ----------------------2k i
i
r
i
2kr 2
Eq. 3177
and
1. p. 69 in C.A. Brebbia, J.C.F. Telles, and L.C. Wrobel, 1984, Boundary element Techniques: Theory and applications in
engineering, Springer-Verlag, Berlin, Germany.
246
Variational Methods
1
( n q ( x, ) )
r
------------------------------------- = --------------- r 2 ( n e i ) 2r 3 ----- ( ( x ) n )
i
2kr 2
2 ( xi i ) ( ( x ) n )
1
-
= --------------2- n i + ----------------------------------------------------2kr
r2
Eq. 3178
We consider a trivial example which solution is self-evident for checking our implementation of this method.
We investigate conduction of heat on a squre region -1 < x < 1, and -1 < y < 1. The upper and lower boundaries
are insulated from its sorrounding by setting qy = 0, the left boundary has T = 0, and the right boundary has T =
100. Because of the steady state condition 2 T = 0 , the gradient on the x direction is constant. This leads to a
linear temperature distribution and constant heat flux on x direction. On y direction, temperature distribution is
uniform and heat flux is zero. Program Listing 322 to Program Listing 326 implement Eq. 3174 to solve for
the variables T and q on the boundaries, then, use Eq. 3172 and Eq. 3176 to recover the interior temperature
and heat flux. We discritize each side of the square region into eight equal length constant elements. Program
Listing 322 is the main() program of the boundary element method.
#include "include\vs.h"
static const double PI = 3.141592654;
static C0 A(32, 32, (double*)0);
static C0 f(32, (double*)0);
static C0 H(32, 16, A, 0, 0);
static C0 mG(32, 16, A, 0, 16);
double w[9] = {14.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0, 28.0/45.0,
64.0/45.0, 24.0/45.0, 64.0/45.0, 14.0/45.0},
x[8][2] = {{-1.0, -0.75}, {-0.75, -0.5}, {-0.5, -0.25}, {-0.25, -0.0}, {0.0, 0.25}, {0.25, 0.5},
{0.5, 0.75}, {0.75, 1.0}},
y[8][2] = {{-1.0, -0.75}, {-0.75, -0.5}, {-0.5, -0.25}, {-0.25, -0.0}, {0.0, 0.25}, {0.25, 0.5},
{0.5, 0.75}, {0.75, 1.0}},
zai[8] = {-0.875, -0.625, -0.375, -0.125, 0.125, 0.375, 0.625, 0.875},
eta[8] = {-0.875, -0.625, -0.375, -0.125, 0.125, 0.375, 0.625, 0.875};
void LHS_0_15();
void LHS_16_31();
void RHS();
void T_recovery(const C0&, const C0&, const C0&);
void q_recovery(const C0&, const C0&, const C0&, const C0&);
int main() {
LHS_0_15();
LHS_16_31();
RHS();
C0 Y = f / A,
T_gamma(16, Y, 0), q_gamma(16, Y, 16),
T(8, 8, (double*)0), q_x(8, 8, (double*)0), q_y(8, 8, (double*)0);
cout << T_gamma << endl;
cout << q_gamma << endl;
T_recovery(T_gamma, q_gamma, T);
cout << T << endl;
q_recovery(T_gamma, q_gamma, q_x, q_y);
cout << q_x << endl;
cout << q_y << endl;
return 0;
}
row 0-15 of A
row 16-31 of A
b
Solve boundary integral equations
Listing 322 The main program of the boundary element method (project: boundary_element_method).
247
Chapter
void LHS_0_15() {
for(int i = 0; i < 16; i++) H[i][i] = -1.0/2.0;
for(int i = 0; i < 8; i++) {
for(int j = 0; j < 8; j++) {
Quadrature qp(w, x[j][0], x[j][1], 9);
J d_l(0.25/8.0);
H0 X(qp),
R_pow_2 = 4+(X-zai[i]).pow(2);
H[i][j+8] = H[i+8][j] = 1.0/(PI*R_pow_2) | d_l;
}
}
for(int i = 0; i < 8; i++) {
for(int j = 0; j < 8; j++) {
Quadrature qp(w, y[j][0], y[j][1], 9);
J d_l(0.25/8.0);
H0 Y(qp),
R0 = sqrt(pow(1.0-zai[i], 2)+(Y-1).pow(2)),
R1 = sqrt(pow(1.0+zai[i], 2)+(Y-1).pow(2)),
R2 = sqrt(pow(1.0-zai[i], 2)+(Y+1).pow(2)),
R3 = sqrt(pow(1.0+zai[i], 2)+(Y+1).pow(2));
mG[i][j] = 1.0/(2.0*PI)*log(R0) | d_l;
mG[i][j+8] = 1.0/(2.0*PI)*log(R1) | d_l;
mG[i+8][j] = 1.0/(2.0*PI)*log(R2) | d_l; mG[i+8][j+8] = 1.0/(2.0*PI)*log(R3) | d_l;
}
}
}
H ij =
- d
------r 2
ln ( r )
- d
----------2k
G ij =
H ij =
(n q ( x, i )) d
( x 1 1 )
d
--------------------2r 2
- d
---------2r 2
- d
------r 2
Eq. 3179
The -Gij terms in the first 16 rows of matrix A corresponding to the 8 upper boundary elements and 8 lower
boundary elements are simply
G ij = T ( x, i ) d =
j
248
ln ( r ( x, i ) )
d
--------------------------2k
Eq. 3180
Variational Methods
void LHS_16_31() {
double mG_diag = 0.125 / PI * (log(0.125)-1.0);
for(int i = 0; i < 16; i++) mG[i+16][i] = mG_diag;
for(int i = 0; i < 8; i++) {
for(int j = 0; j < 8; j++) {
Quadrature qp(w, y[j][0], y[j][1], 9);
J d_l(0.25/8.0);
H0 Y(qp);
if(i != j) {
if(i<j) mG[i+16][j] = mG[i+24][j+8] = 1.0/(2.0*PI) * log(Y-eta[i]) | d_l;
else mG[i+16][j] = mG[i+24][j+8] = 1.0/(2.0*PI) * log(eta[i]-Y) | d_l;
}
}
}
for(int i = 0; i < 8; i++)
for(int j = 0; j < 8; j++) {
Quadrature qp(w, y[j][0], y[j][1], 9);
J d_l(0.25/8.0);
H0 Y(qp),
R = sqrt(4+(Y-eta[i]).pow(2));
mG[i+16][j+8] = mG[i+24][j] = 1.0/(2.0*PI) * log(R) | d_l;
}
for(int i = 0; i < 8; i++)
for(int j = 0; j < 8; j++) {
Quadrature qp(w, x[j][0], x[j][1], 9);
J d_l(0.25/8.0);
H0 X(qp),
R0_2 = pow(1-eta[i], 2) +(X-1).pow(2),
R1_2 = pow(1+eta[i], 2) +(X-1).pow(2),
R2_2 = pow(1-eta[i], 2) +(X+1).pow(2),
R3_2 = pow(1+eta[i], 2) +(X+1).pow(2);
H[i+16][j] = (1.0-eta[i])/(2.0*PI*R0_2) | d_l;
H[i+16][j+8] = (1.0+eta[i])/(2.0*PI*R1_2) | d_l;
H[i+24][j] = (1.0-eta[i])/(2.0*PI*R2_2) | d_l;
H[i+24][j+8] = (1.0+eta[i])/(2.0*PI*R3_2) | d_l;
}
}
h
2
G ii = ---------- ln --- + 1
2k h
G ij =
ln ( r )
- d
----------2k
H ij =
( n e 1 ) ( x1 1 )
- d
---------------------------------------2r 2
Eq. 3181
Otherwise, -Gij use the definition in Eq. 3180. For the terms of Hij
H ij =
( n q ( x , i ) ) d
( n e 1 ) ( x1 1 )
- d
---------------------------------------2r 2
Eq. 3182
249
Chapter
void RHS() {
for(int i = 0; i < 8; i++) {
for(int j = 0; j < 8; j++) {
Quadrature qp(w, y[j][0], y[j][1], 9);
J d_l(0.25/8.0);
H0 Y(qp),
R0_2 = pow(1-zai[i], 2)+(Y-1).pow(2),
R1_2 = pow(1-zai[i], 2)+(Y+1).pow(2);
f[i] += (-100.0*(1-zai[i]))/(2.0*PI*R0_2) | d_l;
f[i+8] += (-100.0*(1-zai[i]))/(2.0*PI*R1_2) | d_l;
}
}
for(int i = 16; i < 24; i++) f[i] = 100.0 / 2.0;
for(int i = 24; i < 32; i++) {
for(int j = 0; j < 8; j++) {
Quadrature qp(w, y[j][0], y[j][1], 9);
J d_l(0.25/8.0);
H0 Y(qp), R_pow_2 = 4+(Y-eta[i-24]).pow(2);
f[i] += - 100.0 / (PI*R_pow_2) | d_l;
}
}
}
100 ( 1 0 )
- d
b i = --------- -----------------2
r2
j
bi = 100/2
100 1
b i = --------- ---2- d
r
j
- d = --------- ------------------ d
b i = H ij T j = 100 ( n q ( x, i ) ) d = 100 ---------------------------------------2
2
2r
r2
j
Eq. 3183
For source position on left boundary elements, singular integrals occur. Therefore, bi = -c Tj, where c = -1/2;
i.e., bi = 100/2 = 50, for i = 16~23. For source position on right boundary elements (i = 24~31), we have
( n e0 ) ( x0 0 )
100 1
- d = --------- ---- d
b i = H ij T j = 100 (n q ( x, i )) d = 100 --------------------------------------- r2
2r 2
j
Eq. 3184
Program Listing 326 for interior temperature and interior heat flux recovery is a straight forward implementation of Eq. 3172 and Eq. 3176.
The results of this simple problem are trivial. It is suffice to say that close to boundaries the accuracy deteriorates fast, since we have a lot of ln(r), 1/r, 1/r 2 ... etc. in the equations. This phenomenon is known as hypersingularity of the boundary integral equation. These complex functions are very chanlleging for numerical
integration. Special integration rules for these functions are common practice in boundary element method.
250
Variational Methods
void T_recovery(const C0& T_gamma, const C0& q_gamma, const C0& T) {
for(int i = 0; i < 8; i++)
for(int j = 0; j < 8; j++) {
for(int k = 0; k < 8; k++) {
Quadrature qpx(w, x[k][0], x[k][1], 9);
J d_l(0.25/8.0);
H0 X(qpx),
R0_2 = pow((1-eta[i]), 2) + (X-zai[j]).pow(2),
R1_2 = pow((1+eta[i]), 2) + (X-zai[j]).pow(2);
T[i][j] += T_gamma[k] /(2.0*PI)*(1-eta[i])/R0_2 | d_l;
T[i][j] += T_gamma[k+8] /(2.0*PI)*(1+eta[i])/R1_2 | d_l;
Quadrature qpy(w, y[k][0], y[k][1], 9);
H0 Y(qpy),
R2_2 = pow((1-zai[j]), 2) + (Y-eta[i]).pow(2),
R3_2 = pow((zai[j]+1), 2) + (Y-eta[i]).pow(2);
T[i][j] += 100.0 / (2.0*PI)*(1-zai[j])/R2_2 | d_l;
T[i][j] += q_gamma[k] / (2.0*PI)*log(sqrt(R2_2)) | d_l;
T[i][j] += q_gamma[k+8] / (2.0*PI)*log(sqrt(R3_2)) | d_l;
}
}
}
void q_recovery(const C0& T_gamma, const C0& q_gamma,
const C0& q_x, const C0& q_y) {
double nx, ny;
nx = 1.0;
for(int i = 0; i < 8; i++)
for(int j = 0; j < 8; j++) {
for(int k = 0; k < 8; k++) {
Quadrature qpx(w, x[k][0], x[k][1], 9);
J d_l(0.25/8.0);
H0 X(qpx),
R0_2 = pow((1-eta[i]), 2) + (X-zai[j]).pow(2),
R1_2 = pow((1+eta[i]), 2) + (X-zai[j]).pow(2);
ny = 1.0;
q_x[i][j] -= (ny*T_gamma[k] /(2.0*PI*R0_2)*(2.0*(X-zai[j])*(1-eta[i])/R0_2)) | d_l;
q_y[i][j] -= (ny*T_gamma[k] /(2.0*PI*R0_2)*
(2.0*(1-eta[i])*(1-eta[i])/R0_2-1.0)) | d_l;
ny = -1.0;
q_x[i][j] -= (ny*T_gamma[k+8] /(2.0*PI*R1_2)*
(2.0*(X-zai[j])*(-1-eta[i])/R1_2)) | d_l;
q_y[i][j] -= (ny*T_gamma[k+8] /(2.0*PI*R1_2)*
(2.0*(-1-eta[i])*(-1-eta[i])/R1_2-1.0)) | d_l;
Quadrature qpy(w, y[k][0], y[k][1], 9);
H0 Y(qpy),
R2_2 = pow((1-zai[j]), 2) + (Y-eta[i]).pow(2),
R3_2 = pow((zai[j]+1), 2) + (Y-eta[i]).pow(2);
q_x[i][j] -= (nx*100.0 / (2.0*PI*R2_2)*(2.0*(1-zai[j])*(1-zai[j])/R2_2 - 1.0)) | d_l;
q_y[i][j] -= (nx*100.0 / (2.0*PI*R2_2)*(2.0*(Y-eta[i])*(1-zai[j])/R2_2 )) | d_l;
q_x[i][j] += (q_gamma[k] / (2.0*PI*R2_2)*(1-zai[j])) | d_l;
q_y[i][j] += (q_gamma[k] / (2.0*PI*R2_2)*(Y-eta[i])) | d_l;
q_x[i][j] += (q_gamma[k+8] / (2.0*PI*R3_2)*(-1-zai[j])) | d_l;
q_y[i][j] += (q_gamma[k+8] / (2.0*PI*R3_2)*(Y-eta[i])) | d_l;
}
}
}
T() =
( n q ) e T ( x, ) d
e
T e ( n q ( x, ) ) d
e
where
1
q = ----------2- [ ( x 0 0 )e 0 + ( x 1 1 )e 1 ]
2r
1
T ( x, )= ---------- ln ( r )
2k
T ( x, )
q ( ) = k ( n q ) e ----------------------- d
( n q ( x, ) )
+ k T e ------------------------------------- d
where
T ( x, ) ( x i i )
----------------------- = ------------------ i
2kr 2
and
(n q ( x, ))
------------------------------------- =
i
2 ( xi i ) ( ( x ) n )
1
--------------- n i + -----------------------------------------------------
2
2kr
r2
251
Chapter
Eq. 3185
where C is the heat capacitiy matrix, K is the conductivity matrix, and f is heat source vector. The variable a is
the temperature and a is the time derivative of temperature. Structural dynamics (a hyperbolic equation) is of
the form
Ma + Ka + f = 0
Eq. 3186
where M is the consistent mass matrix, K is the stiffness matrix, and f is the force vector. The variable a is the
displacement and the second time derivative of the displacement, a gives the acceleration.
Parabolic Equation
Considering a time interval tn to tn+1, and t = tn+1 - tn. At this time interval, (= t - tn) can be normalized by
t as a referential coordinate = / t, with 0 < < 1. The variable a at time tn and tn+1 is denoted as an and an+1,
respectively. A linear interpolation function, the trapezoidal rule for time integration, is used to approximate a in
the time interval tn to tn+1 as1
a a ( ) = ( 1 )a n + a n + 1 = a n + ( a n + 1 a n ) = a n + ----- ( a n + 1 a n )
t
Eq. 3187
Now, the residual of Eq. 3185 is distributed through-out the time domain (tn, tn+1) by a weighted-residual statement similar to Eq. 3105 as
t
WR d
0
W ( Ca ( ) + Ka ( ) + f ) d
= 0
Eq. 3188
A parameter is defined as
= W d
t W d
Eq. 3189
1. We follow Chapter 10 in Zienkiewicz and Taylor, 1991, The finite element method, 4th eds. vol. 2, McGraw-Hill Book
Company, UK.
252
Variational Methods
( an + 1 a n )
d
C ( a ( ) ) + K [ a n + ( a n + 1 a n ) ] + [ f n + ( f n + 1 f n ) ] = 0, where a ( ) = a ( ) = ----------------------------t
d
Eq. 3190
Note that similar interpolation of force vector f is taken as that for the variable a. Re-arranging in order to solve
for the unknown an+1, we have
( C + tK )a n + 1 = ( C t ( 1 )K )a n f
Eq. 3191
f = f + ( f
n
n + 1 fn )
Eq. 3192
where
Eq. 3191 is a time recurrence formula with which the solutions of consequtive time steps can be calculated.
From the results of Eq. 3113 and Eq. 3114, we have, in the context of the point-collocation method, the values
of = 0, 1, 0.5 corresponding to the backward difference, forward difference, and central difference, respectively.
Consider an initial value problem1
u 2 u
----- -------- = 0, 0 < x < 1
t x 2
Eq. 3193
u
u ( 0, t ) = 0, ------ ( 1, t ) = 0, and u ( x, 0 ) = 1
x
Eq. 3194
u exact ( x, t ) = 2
n=0
e n t sin n x
( 2n + 1 )
-----------------------------, n = -----------------------n
2
2
Eq. 3195
Making (1) a weighted-residual statement, and (2) integration by part on the spatial derivative term of Eq. 3193,
we have the weak form with Bubnov-Galerkin weighting v w = u as
1
v 2 v
0 = v ----- --------2 dx =
t x
0
v v v
v
+ ------ ------ dx v ------
v ---- x
t x x
0
=
0
v v
+ ------ ------ dx
v ----t x x
Eq. 3196
1. p. 323-324 in J.N. Reddy, 1986, Applied functional analysis and variational methods in engineering, McGraw-Hill, Inc.
253
Chapter
This is the equation of the form of Eq. 3185; i.e., Ca + Ka + f = 0 , where f = 0. Two term approximation for v is
v(x, t) = c0(t) 0(x) + c1(t) 1(x)
Eq. 3197
where we take 0(x) = x, and 1(x) = x2. Now the matrices in Eq. 3185 can be identified as
1
0
1
0
1
0
1
0
1
0 0
- --------- dx --------0- --------1- dx
------- x x
x x
0 0 dx 0 1 dx
C =
, and K =
1 0
Eq. 3198
1 1
1 0 dx 1 1 dx
v [ v ( x, 0 ) 1 ] dx
= 0 =
[ ( c ( 0 ) ) ] dx
Eq. 3199
or in matrix form,
1
0 0 dx 0 1 dx
0
1
0
1
1 0 dx 1 1 dx
0
0 dx
c0 ( 0 )
=
c1 ( 0 )
0
1
Eq. 3200
1 dx
0
Therefore, the results are c0(0) = 4 and c1(0) = -10/3. This serves as the initial condition in place of Eq. 3200 for
the basis function approximation in Eq. 3197. Although Eq. 3200 is simple enough to be solved by hand, we
can easily implement Eq. 3200 with VectorSpace C++ Library.
Program Listing 327 first implements the approximated initial condition with Eq. 3200, and then, uses the
definitions of C and K in Eq. 3198 to solve for the time recurrence formula provided by Eq. 3191. In this
implementation, the time step t = 0.05, and = 0.5 is used for the central difference method. Note that for the
initial condition approximation the highest order polynomial is the fifth-order. We use Bodes integration rule for
the accuracy of the initial condition approximation. For the time recurrence formula the highest order polynomial for integration is only up to second order, so Simpsons rule will be sufficient.
The results of the computation are shown in Figure 333. A large error occurs at time zero, since the initial
condition is only approximated through Eq. 3199.
254
Variational Methods
#include "include\vs.h"
int main() {
C0 c_t_n(2, (double*)0), c_t_n1(2, (double*)0);
{
double weight[5] = {14.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0, 14.0/45.0};
Quadrature qp(weight, 0.0, 1.0, 5);
J d_l(1.0/4.0);
H1 x(qp),
phi = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE(
"int, int, Quadrature", 2, 1, qp);
phi[0] = x; phi[1] = x.pow(2);
C0 C = (((H0)phi)%((H0)phi))|d_l,
b = ((H0)phi)|d_l;
c_t_n = b / C;
}
double weight[3] = {1.0/3.0, 4.0/3.0, 1.0/3.0};
Quadrature qp(weight, 0.0, 1.0, 3);
J d_l(1.0/2.0);
H1 x(qp),
phi = INTEGRABLE_VECTOR_OF_TANGENT_BUNDLE(
"int, int, Quadrature", 2, 1, qp);
phi[0] = x; phi[1] = x.pow(2);
C0 C = (((H0)phi)%((H0)phi))|d_l,
K = (d(phi)(0)%d(phi)(0))|d_l;
double theta_ = 0.5, dt_ = 0.05;
C0 LHS = C + theta_ * dt_ * K,
RHS = C - (1.0 - theta_) * dt_ * K;
C0 d_LHS = !LHS;
for(int i = 0; i < 30; i++) {
c_t_n1 = d_LHS*(RHS*c_t_n);
double iptr;
if(modf( ((double)(i+1))/2.0, &iptr)==0) cout << c_t_n1 << endl;
c_t_n = c_t_n1;
}
return 0;
}
0 0 dx 0 1 dx
0
1
0
1
1 0 dx 1 1 dx
0
0 dx
c0 ( 0 )
c1 ( 0 )
0
1
1 dx
0
C =
dx
0
1
K =
- ------ dx
----x x
0
( C + tK )a n + 1=( C t ( 1 )K )a n
Hyperbolic Equation
We consider a more general second order differential equation (hyperbolic-parabolic equation) such as
Ma + Ca + Ka + f = 0
Eq. 3201
where M is the mass matrix, C is the viscous damping, K is the stiffness, and f is the forcing terms. In structural
dynamics, a is the displacement, a is the velocity, and a is the acceleration. When C = 0, Eq. 3201 reduces to
the hyperbolic case. For Eq. 3201, we use a time recurrence formula in which given a n, a n , and an at time tn,
we seek solutions of a n + 1, a n + 1, and an + 1 at time tn+1. Similar to Eq. 3187, we use a linear interpolation function with a natural coordinate = / t, where 0 < < 1, to approximate the acceleration as
255
Chapter
0.8
x = 1.0
0.8
t=0.2
0.6
t=0.4
0.6
x = 1.0
0.4
0.4
t=0.6
t=0.8
t=1.0
t=1.2
t=1.4
0.2
x = 0.5
0.2
0.4
0.6
0.8
0.2
x = 0.5
0.2
0.4
0.6
0.8
1.2
1.4
t
x
Figure 333 The left-hand-side is the exact solution computed from Eq. 3195. The results of
numerical solution on x = 0.5 and 1.0 are shown.
a a ( ) = ( 1 )an + an + 1 = an + ( an + 1 an ) = an + ----- ( an + 1 an )
t
Eq. 3202
For the displacement a and the velocity a , we can approximate them with Taylor series approximation to the
second order of t for an+1 as
t 2
a n + 1 a n + ta n + -------- [ ( 1 2 )an + 2an + 1 ]
2
Eq. 3203
Eq. 3204
The two parameters and are choosen independently. Notice that Eq. 3204 is an expression only up to the
first order of t. Therefore, we restrict our choice of = 1/2 to keep the order of accuracy up to O(t2). Two
choices of are popular. For the so-called constant average acceleration = 2 = 1/2, the weighting functions
W() for acceleration terms in Eq. 3203 and Eq. 3204 are the same. In the context of point-collocation the
value 1/2 corresponds to central difference method. This value is also equivalent to collocation with a constant
weighting function throught out the time interval tn to tn+1; i.e., W() = 1, such that from the definition in Eq.
3189, we get
t
= 2 = W d
256
2
t W d = ----- ( t )
2
t
0
1
= --2
Eq. 3205
Variational Methods
Similarly, for the so-called linear acceleration, = 1/2 is to keep the second order accuracy, but now set = 1/6.
That is we use W() = 1 for Eq. 3204, while we take a linear weighting function W() = (1) = (1 / t) for
Eq. 3203, so
t
2 = W d
2
2 3
t W d = ----- ----- -----
2 3 2
1
0
1
= --3
Eq. 3206
Now, we work out the formula for the Newmark method for the hyperbolic-parablic equation. From Eq.
3203, we have
1
t 2
an + 1 = --------- a n + 1 a n ta n -------- ( 1 2 )an
2
t
Eq. 3207
t
2
Eq. 3208
Since a n, a n , and an at time tn are all given values, the three unknowns a n + 1, a n + 1, and an + 1 at time tn+1 can be
substituted into Eq. 3201 as
Man + 1 + Ca n + 1 + Ka n + 1 + fn + 1 = 0
Eq. 3209
where a n + 1 , and an + 1 are expressed in Eq. 3207 and Eq. 3208, and the only unknown is a n + 1 in Eq. 3209.
Re-arranging Eq. 3209, we have1
Kan + 1 = Rn + 1
Eq. 3210
K = K + a 0 M + a 1 C, and R n + 1 = f n + 1 + ( a 0 a n + a 2 a n + a 3 an )M + ( a 1 a n + a 4 a n + a 5 an )C
Eq. 3211
where,
a n + 1 is solved from Eq. 3210, then, a n + 1 , and an + 1 are calculated from re-arranged Eq. 3207 and Eq. 3208
as
an + 1 = a 0 ( a n + 1 a n ) a 2 a n a 3 an
a
= a + a a + a a
n+1
6 n
7 n+1
Eq. 3212
The so-called Newmark coefficients ai in Eq. 3211 and Eq. 3212 are
1. p. 323 in K Bathe, and E.L. Wilson, 1976, Numerical method in finite element analysis, Prentice-Hall, New Jersey.
257
Chapter
1
1
t
1
a 0 = -----------2, a 1 = ---------, a 2 = ---------, a 3 = ------ 1, a 4 = --- 1, a 5 = ----- --- 2 , a 6 = t ( 1 ), a 7 = t
t
t
2
2
Eq. 3213
Eq. 3214
Eq. 3215
Eq. 3216
1 = 1-cos(4x)
for w2 = c0(t) 0(x) + c1(t) 1(x), with C = 0 and f = 0 in Eq. 3201, M and K can be identified as
1
M =
( ) dx, and K =
0
d d
d x2 d x2 dx
Eq. 3217
The coefficients for the initial condition in Eq. 3216 is approximated by weighted-residual method
1
W [ w2 ( x, 0 ) sin ( x ) + x ( 1 x ) ] dx
= 0
Eq. 3218
With Bubnov-Galerkin weighting W(x, t) = w2(x, t) = c0(t) 0(x) + c1(t) 1(x) , Eq. 3218 becomes
1
( ) dx
0
c(0) =
[ sin ( x ) x ( 1 x ) ] dx
Eq. 3219
258
Variational Methods
#include "include\vs.h"
#define PI 3.141592654
int main()
{
double weight[33] = {14.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0, 28.0/45.0, 64.0/45.0,
24.0/45.0, 64.0/45.0, 28.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0,
28.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0, 28.0/45.0, 64.0/45.0,
24.0/45.0, 64.0/45.0, 28.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0,
28.0/45.0, 64.0/45.0, 24.0/45.0, 64.0/45.0, 28.0/45.0, 64.0/45.0,
24.0/45.0, 64.0/45.0, 14.0/45.0};
Quadrature qp(weight, 0.0, 1.0, 33);
J d_l(1.0/32.0);
H2 x((double*)0, qp),
phi = INTEGRABLE_VECTOR_OF_TANGENT_OF_TANGENT_BUNDLE(
"int, int, Quadrature", 2, 1, qp);
phi[0] = 1.0-cos(2.0*PI*x); phi[1] = 1.0-cos(4.0*PI*x);
H0 d2_phi = INTEGRABLE_VECTOR("int, Quadrature", 2, qp);
for(int i = 0; i < 2; i++) d2_phi[i] = dd(phi)(i)[0][0];
C0 mass = (((H0)phi)%((H0)phi))|d_l,
stiff = (d2_phi%d2_phi)|d_l;
double gamma_ = 0.5, beta_ = 0.25, dt_ = 0.01, a[8];
C0 c_old(2, (double*)0), c_new(2, (double*)0), dc_old(2, (double*)0),
dc_new(2, (double*)0), ddc_old(2, (double*)0), ddc_new(2, (double*)0);
a[0] = 1.0/(beta_*pow(dt_,2)); a[1] = gamma_/(beta_*dt_); a[2] = 1.0/(beta_*dt_);
a[3] = 1.0/(2.0*beta_)-1.0; a[4] = gamma_/beta_-1.0; a[5] = dt_/2.0*(gamma_/beta_-2.0);
a[6] = dt_*(1.0-gamma_);
a[7] = gamma_*dt_;
H0 w_0 = sin(PI*((H0)x))-PI*((H0)x)*(1.0-((H0)x));
c_old = ( ( ((H0)phi)*w_0 )|d_l ) / ( ( ((H0)phi)%((H0)phi) )|d_l );
C0 LHS = stiff + a[0]*mass,
d_LHS = !LHS;
for(int i = 0; i < 28; i++) {
C0 RHS = mass * (a[0]*c_old + a[2] * dc_old + a[3] * ddc_old);
c_new = d_LHS*RHS;
double iptr;
if(modf( ((double)(i+1))/2.0, &iptr)==0) cout << "t= " << ((i+1)*dt_) << ", u(0.5) = " <<
(c_new[0]*(1.0-cos(PI))+c_new[1]*(1.0-cos(2.0*PI))) << endl;
ddc_new = a[0]*(c_new - c_old)-a[2]*dc_old-a[3]*ddc_old;
dc_new = dc_old + a[6]*ddc_old + a[7]*ddc_new;
c_old = c_new; dc_old = dc_new; ddc_old = ddc_new;
}
return 0;
}
( ) dx
M =
0
1
d d
K = 2 2 dx
dx
dx
0
K = K + a0 M
R n + 1 = ( a 0 a n + a 2 a n + a 3 an )M
an + 1 = a 0 ( a n + 1 a n ) a 2 a n a 3 an
a
= a + a a + a a
n+1
6 n
7 n+1
update ( . )n = ( . )n+1
Listing 328 Hyperbolic equation using Newmark method with constant average acceleration (project:
hyperbolic_equation).
259
Chapter
0.2
t=0.28
t=0.26
0.2
t=0.04
t=0.24
0.1
0.1
t=0.08
t=0.22
w
w
0.2
-0.1
0.4
0.6
t=0.08
t=0.10
0.8
0.2
-0.1
t=0.14
Figure 334
260
0.6
t=0.20
t=0.18
t=0.12
-0.2
0.4
-0.2
t=0.16
0.8