rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
praktikum_poisson_model.m
1 function model = praktikum_poisson_model(params);
2 %function model = praktikum_poisson_model(params)
3 %
4 % small example of a model, i.e. a structure describing the data
5 % functions and geometry information of a general elliptic equation consisting
6 % of diffusion, convection, reaction equation:
7 %
8 % - div ( a(x) grad u(x)) + div (b(x) u(x)) + c(x) u(x) = f(x) on Omega
9 % u(x)) = g_D(x) on Gamma_D
10 % a(x) grad u(x)) = g_N(x) on Gamma_N
11 %
12 % Here, we denote the functions as
13 % u: solution (if known, useful for validation purpose)
14 % f: source
15 % a: diffusivity
16 % b: velocity
17 % c: reaction
18 % g_D: Dirichlet boundary values
19 % g_N: Neumann boundary values
20 %
21 % Each function allows the evaluation in many points
22 % simultaneuously by
23 %
24 % model.source(glob)
25 % or model.source(glob,params)
26 %
27 % where glob is a n times 2 matrix of row-wise points. The result
28 % is a n times 1 vector of resulting values of f.
29 %
30 % additionally, the model has a function, which determines, whether
31 % a point lies on a Dirichlet or Neumann boundary:
32 %
33 % model.boundary_type(glob)
34 % 0 no boundary (inner edge or point)
35 % -1 indicates Dirichlet-boundary
36 % -2 indicates Neumann-boundary
37 %
38 % The data functions given in this model are the simple poisson
39 % equation with Gamma_D = boundary(Omega), Gamma_N = {}
40 %
41 % -div (grad u) = f
42 % u = 0 on Gamma_D
43 %
44 % with exact solution u(x) = x_1(1-x_1)x_2(1-x_2),
45 % i.e. f(x) = 2 (x_1 + x_2 - x_1^2 - x_2^2)
46 %
47 % params is an optional parameter, perhaps useful later
48 
49 % B. Haasdonk 23.11.2010
50 
51 model = [];
52 
53 if nargin<1
54  params = [];
55 end;
56 
57 % check if user wants to have pure dirichlet boundary:
58 if ~isfield(params,'all_dirichlet_boundary')
59  params.all_dirichlet_boundary = 1;
60 end;
61 
62 % solution is known for debugging and error analysis
63 model.solution = @(glob,params) ...
64  glob(:,1).*(1-glob(:,1)).*glob(:,2).*(1-glob(:,2));
65 ds = 1e-5;
66 model.solution_gradient = @(glob,params) ...
67  [(model.solution(glob+repmat([ds/2,0],size(glob,1),1))-...
68  model.solution(glob-repmat([ds/2,0],size(glob,1),1)))/ds,...
69  (model.solution(glob+repmat([0,ds/2],size(glob,1),1))-...
70  model.solution(glob-repmat([0,ds/2],size(glob,1),1)))/ds];
71 
72 % params is an optional parameter, perhaps useful later
73 model.source = @(glob,params) ...
74  2 * (glob(:,1)+ glob(:,2)- glob(:,1).^2 - glob(:,2).^2);
75 model.reaction = @(glob,params) zeros(size(glob,1),1);
76 model.velocity = @(glob,params) zeros(size(glob,1),1);
77 model.diffusivity = @(glob,params) ones(size(glob,1),1);
78 model.diffusivity_gradient = @(glob,params) zeros(size(glob,1),2);
79 
80 model.reaction = @(glob,params) zeros(size(glob,1),1);
81 
82 % Dirichlet everywhere or mixed, see functions below.
83 model.boundary_type = @mixed_boundary_type;
84 if params.all_dirichlet_boundary
85  model.boundary_type = @all_dirichlet_boundary_type;
86 end;
87 model.dirichlet_values = @(glob,params) zeros(size(glob,1),1);
88 model.normals = @my_normals;
89 model.neumann_values = @(glob,params) ...
90  model.diffusivity(glob).*...
91  sum(model.solution_gradient(glob).*model.normals(glob),2);
92 
93 % all edges of unit square are dirichlet, other inner
94 function res = all_dirichlet_boundary_type(glob,params)
95 res = zeros(size(glob,1),1);
96 i = find(glob(:,1)<=1e-10);
97 i = [i, find(glob(:,1)>=1-1e-10)];
98 i = [i, find(glob(:,2)<=1e-10)];
99 i = [i, find(glob(:,2)>=1-1e-10)];
100 res(i) = -1;
101 
102 function res = mixed_boundary_type(glob,params)
103 res = zeros(size(glob,1),1);
104 i = find(glob(:,1)<=1e-10);
105 res(i) = -1;
106 i = find(glob(:,1)>=1-1e-10);
107 res(i) = -1;
108 i = find(glob(:,2)<=1e-10);
109 res(i) = -1;
110 i = find(glob(:,2)>=1-1e-10);
111 res(i) = -2;
112 
113 function res = my_normals(glob,params);
114 res = zeros(size(glob,1),2); % each row one normal
115 i = find(glob(:,1)>1-1e-10);
116 res(i,1)= 1.0;
117 i = find(glob(:,1)<-1+1e-10);
118 res(i,1)= -1.0;
119 i = find(glob(:,2)>1-1e-10);
120 res(i,2)= 1.0;
121 i = find(glob(:,2)<-1+1e-10);
122 res(i,2)= -1.0;
123 % remove diagonal normals
124 i = find (sum(abs(res),2)>1.5);
125 res(i,1)= 0;
function Udirichlet = dirichlet_values(model, X, Y)
UDIRICHLET = DIRICHLET_VALUES([X],[Y], MODEL) Examples dirichlet_values([0,1,2],[1,1,1],struct(name_dirichlet_values, homogeneous, ... c_dir, 1)) dirichlet_values([0:0.1:1],[0],struct(name_dirichlet_values, xstripes, ... c_dir, [0 1 2], ... dir_borders, [0.3 0.6])) dirichlet_values([0:0.1:1],[0],struct(name_dirichlet_values, box, ... c_dir, 1, ... dir_box_xrange, [0.3 0.6], ... dir_box_yrange, [-0.1 0.1]))