程序控

IPPP (Institute of Penniless Peasent-Programmer) Fellow

博客园 :: 首页 :: :: :: 新随笔 :: 联系 :: :: 管理 ::
 77 随笔 :: 0 文章 :: 439 评论 :: 0 引用

公告

Time limit: 3.000 seconds

Problem问题

In engineering sciences, partial differential equations play an important and central role. For example, the temperature of a metal plate can be expressed as a partial differential equation if the temperature on the boundaries is known. This is called a boundary value problem.

Usually, it is not easy to solve these problems. Analytical solutions exist only in very special cases. But there are some more or less "good" numerical ways to solve boundary value problems.

We now will look at one method which works with finite difference approximations for the derivatives of a function. For this approach, we do not look at an analytical function u(x) but we are only interested in the values of u at a finite set of discrete points xi : ui=u(xi). The distance between two adjacent points, xi and xi+1, is constant: h=xi+1–xi(cf. figure 1).

Figure 1: u(x) at some discrete points xi

The finite difference approximation of a first derivative of the function u(x) is

•     (1)

The second derivative is approximated by

•     (2)

This approximation works with 2-dimensional functions u(x,y) as well. For simplicity we only work on square problems, i.e. (x, y) is element of [0, 1]×[0, 1]. Again, the area of the function is discretized in a similar way: xi+1–xi=yi+1–yi=h=1/n, for some integer n≥2. We only look at the values of u(x,y) at the discrete points Pk=(xi, yi):ui,j=u(Pk). With this discretization, we have a function ui,j as shown in figure 2:

Figure 2: Function ui,j in the discretization area

On the boundary, u(xi, yi) is given by 4 known functions:

• u(xi, 0) = b1(xi)
• u(xi, 1) = b2(xi)
• u(0, yj) = b3(yj)
• u(1, yj) = b4(yj)    (3)

The points Pk cover the inner points of the discretization area, i.e. the area without the boundary. They are numbered from left to right and from top to bottom like English text.

What we now want to do is to solve the poisson-equation in the area [0, 1]×[0, 1]:

•     (4)

with the above boundary conditions. f(x,y) is a given 2-dimensional function. With equation (2) and the above discretization, the poisson-equation can be approximated at
f(x,y)是一个给定的二元函数。根据方程式(2)和上面的离散化，泊松方程可以逼近为：

•     (5)

where fi,j is the function f(x,y), evaluated at the discrete points (xi, yj).

Formula (5) can be written in a more readable form, depending on the position of the discrete points:

•    (6a)

A similar equation, which we will use as an example below, is:

•     (6b)

We call the 3×3 matrix on the left hand side v and the 3×3 matrix on the right hand side g.

Now, equation (6b) can be formulated in every point of the discrete area of figure 2:

•     (7)

and (7) is a linear equation system for the values of u(x,y) at the points P1, P2, P3 and P4.
(7)式是一个u(x,y)在P1、P2、P3和P4点处值的线性方程组。

By rearranging and adding the terms on each line, the linear equation system can be formulated as:

• az = b    (8)

where a is a 4×4 matrix and b is a vector with 4 elements. Vector z represents the unknown values of u(x,y) at the points P1, P2, P3 and P4.

You are to write a program that creates the linear equation system (7) in the form (8) for any two matrices v and g (6). As input, the two matrices v and g and the functions b1, b2, b3, b4, and f are given. Also, a parameter n is given as the number of discretization intervals. Thus, h=1/n. As the result, your program should calculate the matrix a and the vector b. For this more general case, there are (n-1)2 inner points and a and b must be sized accordingly.

Input输入

The input file consists of m tests. The number m is given in the first line of the file. The first line of each test contains the number n which gives the number of discretizations intervals as defined above. You may assume that 2≤n≤30. Then the 3×3 matrices v and g follow. The following four lines contain the functions b1, b2, b3 and b4, each given as a vector of order n+1, containing the values for 0, h, 2h, ..., 1. Finally, the function f is given as a n+1 by n+1 matrix. Like the vectors before, it contains the values for x,y=0, h, 2h, ..., 1. Each row contains from left to right the function values for increasing x values while each column contains from top to bottom the function values for decreasing y values.

A vector occupies one line. Its values are given in ascending order, separated by a space. A n by n matrix occupies n lines. Its rows are given in ascending order as vectors, which occupy one line each. All values found in the input file are integer values.

Output输出

For each test found in the input file, your program should output the matrices a and b. Matrix a is a (n–1)2×(n–1)2 matrix (the discretization area (cf. figure 2) contains (n–1)2 inner points, which are unknown). The vector b is of order (n–1)2. They should be output in the same format as the vectors and matrices in the input file. Your output should only contain integer values. Note that the expression 1/h2 yields an integer number and that all other calculations can also be done using integer numbers.

1
3
1 0 2
0 -4 0
3 0 4
0 5 0
6 0 7
0 8 0
3 4 5 6
0 1 2 3
3 2 1 0
6 5 4 3
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4

Sample Output输出示例

-36 0 0 36
0 -36 27 0
0 18 -36 0
9 0 0 -36
-35 -188 -189 -315

Solution解析

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
//主函数
int main(void) {
int m, n, v[3][3], g[3][3], b[4][31], f[31][31], *a = new int[841 * 841];
for (cin >> m; --m >= 0; ) {
cin >> n;
int r[841] = {0}, nSize = (n - 1) * (n - 1), h2 = n * n;
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; cin >> v[i][j++]);
}
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; cin >> g[i][j++]);
}
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < n + 1; cin >> b[i][j++]);
}
for (int i = 0; i < n + 1; ++i) {
for (int j = 0; j < n + 1; cin >> f[i][j++]);
}
for (int i = 1; i < n; ++i) {
for (int j = 1; j < n; ++j) {
int id = (i - 1) * (n - 1) + j - 1;
for (int s = 0; s < 3; ++s) {
for (int t = 0; t < 3; ++t) {
int as = i + s - 1, at = j + t - 1;
r[id] += f[as][at] * g[s][t];
if (as == 0) {
r[id] -= b[1][at] * v[s][t] * h2;
}
else if (at == 0) {
r[id] -= b[2][n - as] * v[s][t] * h2;
}
else if (as == n) {
r[id] -= b[0][at] * v[s][t] * h2;
}
else if (at == n) {
r[id] -= b[3][n - as] * v[s][t] * h2;
}
else {
int aid = (as - 1) * (n - 1) + at - 1;
a[id * nSize + aid] = v[s][t] * h2;
}
}
}
}
}
for (int i = 0; i < nSize; ++i) {
for (int j = 0; j < nSize - 1; ++j) {
cout << a[i * nSize + j] << ' ';
}
cout << a[i * nSize + nSize - 1] << endl;
}
for (int i = 0; i < nSize - 1; ++i) {
cout << r[i] << ' ';
}
cout << r[nSize - 1] << endl;
}
delete[] a;
return 0;
}

posted on 2010-08-23 20:49 Devymex 阅读(...) 评论(...) 编辑 收藏