1 function model = praktikum_ellipt_model(params);
2 %
function model = praktikum_ellipt_model(params);
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:
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
12 % Here, we denote the functions as
13 % u: solution (if known, useful for validation purpose)
18 % g_D: Dirichlet boundary values
19 % g_N: Neumann boundary values
21 % Each function allows the evaluation in many points
25 % or model.source(glob,params)
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.
30 % additionally, the model has a function, which determines, whether
31 % a point lies on a Dirichlet or Neumann boundary:
33 % model.boundary_type(glob)
34 % 0 no boundary (inner edge or point)
35 % -1 indicates Dirichlet-boundary
36 % -2 indicates Neumann-boundary
38 % The data functions given in this model are given on the exercise sheet
39 % Omega = [-1,1]^2 \ [0,1]^2
40 % with Gamma_D = ecke oben rechts, Gamma_N = rand vom ursprünglichen 4eck
42 % -div ( a div(u)) = f
44 % (a div(u))*n = g_N on Gamma_N
46 % with exact solution u(x) = ||x||^(alpha),
48 % params is an optional parameter, perhaps useful later
50 % B. Haasdonk 23.11.2010
56 % check if user wants to have pure dirichlet boundary:
57 if ~isfield(params,'all_dirichlet_boundary')
58 params.all_dirichlet_boundary = 1;
67 %for i=(3*n+1):(3*n+m)
70 %for i=(3*n+m+1):(3*n+2*m)
73 %for i=(3*n+2*m+1):(3*n+3*m)
76 %for i=(3*n+3*m+1):(3*n+4*m)
79 %for i=(3*n+4*m+1):(3*n+5*m)
88 % params is an optional parameter, perhaps useful later
89 model.source = @(glob,params) ...
90 -alpha*sqrt(glob(:,1).^2+glob(:,2).^2).^(alpha-2).*(3*glob(:,1)+4)-alpha*(alpha-2)*(glob(:,1)+2).*sqrt(glob(:,1).^2+glob(:,2).^2).^(alpha-3);
91 model.reaction = @(glob,params) zeros(size(glob,1),1);
92 model.velocity = @(glob,params) zeros(size(glob,1),1);
93 model.diffusivity = @(glob,params) glob(:,1)+2;
94 %model.diffusivity_gradient = @(glob,params) [1,0];
96 % Dirichlet everywhere, see function below.
97 if params.all_dirichlet_boundary
98 model.boundary_type = @all_dirichlet_boundary_type;
100 model.boundary_type = @mixed_boundary_type;
102 model.
dirichlet_values = @(glob,params) sqrt(glob(:,1).^2+glob(:,2).^2).^alpha;
103 model.normals = @my_normals;
104 model.neumann_values = @(glob,params) alpha*sqrt(glob(:,1).^2+glob(:,2).^2).^(alpha-2).*(glob(:,1)+2).*sum(glob.*model.normals(glob),2);
107 model.solution = @(glob,params) ...
108 sqrt(glob(:,1).^2+glob(:,2).^2).^alpha;
110 % all edges of unit square are dirichlet, other inner
111 function res = all_dirichlet_boundary_type(glob,params)
112 res = zeros(size(glob,1),1);
113 i = find(glob(:,1)<-1+1e-10);
115 i = find(glob(:,1)>1-1e-10);
117 i = find(glob(:,2)>1-1e-10);
119 i = find(glob(:,2)<-1+1e-10);
121 i = find((glob(:,1)>0-1e-10) & (glob(:,2)>1e-10));
123 i = find((glob(:,1)>1e-10) & (glob(:,2)>-1e-10));
126 function res = mixed_boundary_type(glob,params)
127 res = zeros(size(glob,1),1);
128 i = find(glob(:,1)<-1+1e-10);
130 i = find(glob(:,1)>1-1e-10);
132 i = find(glob(:,2)>1-1e-10);
134 i = find(glob(:,2)<-1+1e-10);
136 i = find((glob(:,1)>0-1e-10) & (glob(:,2)>1e-10));
138 i = find((glob(:,1)>1e-10) & (glob(:,2)>-1e-10));
141 function res = my_normals(glob,params);
142 res = zeros(size(glob,1),2); % each row one normal
143 i = find((glob(:,1)>0-1e-10) & (glob(:,2)>1e-10));
145 i = find((glob(:,1)>1e-10) & (glob(:,2)>-1e-10));
147 i = find(glob(:,1)<-1+1e-10);
149 i = find(glob(:,1)>1-1e-10);
151 i = find(glob(:,2)>1-1e-10);
153 i = find(glob(:,2)<-1+1e-10);
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]))