rbmatlab  1.16.09
 All Classes Namespaces Files Functions Variables Modules Pages
poisson_model.m
1 function model = poisson_model(params);
2 %function model = 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)) n) = g_N(x) on Gamma_N
11 % alpha(x) u(x) + beta(x) a(x) (grad u(x)) n) = g_R(x) on Gamma_R
12 %
13 % s = l(u) linear output functional
14 %
15 % Here, we denote the functions as
16 % u: scalar 'solution' (if known, for validation purpose)
17 % f: scalar 'source'
18 % a: tensor valued 'diffusivity_tensor'
19 % b: vector valued 'velocity'
20 % c: scalar 'reaction'
21 % g_D: scalar 'dirichlet_values'
22 % g_N: scalar 'neumann_values'
23 % g_R: scalar 'robin_values'
24 % alpha: scalar 'robin_alpha'
25 % beta: scalar 'robin_beta'
26 %
27 % Each function allows the evaluation in many points
28 % simultaneuously by
29 %
30 % model.source(glob)
31 % or model.source(glob,params)
32 %
33 % where glob is a n times 2 matrix of row-wise points. The result
34 % is a n times 1 vector of resulting values of f.
35 %
36 % model.diffusivity_tensor(glob)
37 % or model.diffusivity_tensor(glob,params)
38 %
39 % where glob is a n times 2 matrix of row-wise points. The result
40 % is a n times 4 matrix of resulting values of diffusivity, where
41 % the values of a are sorted in matlab-order as [a_11, a_21, a_12, a_22];
42 %
43 % additionally, the model has a function, which determines, whether
44 % a point lies on a Dirichlet, Neumann or Robin boundary:
45 %
46 % model.boundary_type(glob)
47 % 0 no boundary (inner edge or point)
48 % -1 indicates Dirichlet-boundary
49 % -2 indicates Neumann-boundary
50 % -3 indicates Robin-boundary
51 %
52 % Additionally, the normals in a boundary point can be requested by
53 %
54 % model.normals(glob)
55 % Here, glob are assumed to be boundary points lying ON THE
56 % INTERIOR of an edge, such that the outer unit normal is well-defined.
57 %
58 % The latter 2 methods boundary_type() and normals() need not be
59 % implemented for grid-based methods, as the normals simply can be
60 % obtained by the grid. The methods are only required, if using
61 % meshless methods with data functions that use normals.
62 %
63 % The output functional must be specified
64 % s = model.output_functional(model, model_data, u)
65 % where u is a dof vector of the discrete solution. model_data is
66 % assumed to contain the grid
67 %
68 % possible fields of params:
69 % numintervals: the unit square is divided into numintervals
70 % intervals per side. default is 10;
71 %
72 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73 %
74 % The data functions given in this model are the simple poisson
75 % equation with Gamma_D = boundary(Omega), Gamma_N = {}, Gamma_R = {}
76 %
77 % -div (grad u) = f
78 % u = 0 on Gamma_D
79 %
80 % with exact solution u(x) = 16 x_1(1-x_1)x_2(1-x_2),
81 % i.e. f(x) = 32 (x_1 + x_2 - x_1^2 - x_2^2)
82 
83 % B. Haasdonk 23.11.2010
84 
85 if nargin == 0
86  params = [];
87 end;
88 
89 if ~isfield(params,'numintervals')
90  params.numintervals = 10; % 2 x 2 grid! with 8 triangles
91 end;
92 
93 if ~isfield(params,'pdeg')
94  params.pdeg = 2; %quadratic elements
95 end;
96 
97 if ~isfield(params,'qdeg')
98  params.qdeg = 4; % 2 x 2 grid! with 8 triangles
99 end;
100 
101 model = lin_stat_model_default;
102 %%%%%%% data function specification:
103 
104 % if any of the following flags is set, the corresponding function
105 % pointers must be provided below.
106 
107 model.has_reaction = 1;
108 %model.has_reaction = 0;
109 model.has_source = 1;
110 model.has_reaction = 1;
111 %model.has_reaction = 0;
112 model.has_advection = 1;
113 %model.has_advection = 0;
114 model.has_diffusivity = 1;
115 model.has_output_functional = 1;
116 model.has_dirichlet_values = 1;
117 model.has_neumann_values = 1;
118 %model.has_neumann_values = 0;
119 %model.has_robin_values = 1;
120 model.has_robin_values = 1;
121 
122 % solution is known:
123 % for debugging: f = 1; u = -1/4 (x^2+y^2)
124 % model.solution = @(glob,params) ...
125 % -0.25 * (glob(:,1).^2+glob(:,2).^2);
126 % params is an optional parameter, perhaps useful later
127 model.source = @(glob,params) ...
128  32 * (glob(:,1)+ glob(:,2)- glob(:,1).^2 - glob(:,2).^2);
129  model.solution = @(glob,params) ...
130  16 * glob(:,1).*(1-glob(:,1)) .* ...
131  glob(:,2).*(1-glob(:,2));
132 
133 %u_exact = @(glob,params) sin(2*pi*glob(:,1)).*sin(2*pi*glob(:,2));
134 %model.solution = u_exact;
135 %% f = -laplace u_exact
136 %model.source = @(glob,params) 8*pi*pi*u_exact(glob,params);
137 
138 % for debugging: f = 1; u = -0.25* (x^2+y^2)
139 %model.source = @(glob,params) ...
140 % ones(size(glob,1),1);
141 
142 model.reaction = @(glob,params) zeros(size(glob,1),1);
143 model.velocity = @(glob,params) zeros(size(glob,1),2);
144 model.diffusivity_tensor = @(glob,params) ...
145  [ones(size(glob,1),1),...
146  zeros(size(glob,1),1),...
147  zeros(size(glob,1),1),...
148  ones(size(glob,1),1)];
149 %model.diffusivity_gradient = @(glob,params) zeros(size(glob,1),2);
150 model.reaction = @(glob,params) zeros(size(glob,1),1);
151 
152 % Dirichlet everywhere, see function below.
153 %model.dirichlet_values = @(glob,params) zeros(size(glob,1),1);
154 model.dirichlet_values = @(glob,params) ...
155  params.solution(glob,params);
156 model.neumann_values = @(glob,params) zeros(size(glob,1),1);
157 model.robin_values = @(glob,params) zeros(size(glob,1),1);
158 model.robin_alpha = @(glob,params) zeros(size(glob,1),1);
159 model.robin_beta = @(glob,params) zeros(size(glob,1),1);
160 
161 % output functional, e.g. average over unit-square:
162 model.output_functional = @output_functional_volume_integral;
163 model.output_function = @output_function_box_mean;
164 model.sbox_xmin = 0;
165 model.sbox_ymin = 0;
166 model.sbox_xmax = 1;
167 model.sbox_ymax = 1;
168 model.output_integral_qdeg = 0; % midpoint integration
169 % later, e.g. for thermal block:
170 %model.output_functional = @output_functional_boundary_integral;
171 %model.output_function = @output_function_dirichlet_indicator;
172 
173 %%%%%%% geometry specification and discretization:
174 
175 model.gridtype = 'triagrid';
176 model.xnumintervals = params.numintervals;
177 model.ynumintervals = params.numintervals;
178 model.xrange = [0,1];
179 model.yrange = [0,1];
180 
181 % numerics settings:
182 model.pdeg = params.pdeg; % degree of polynomial functions
183 model.qdeg = params.qdeg; % quadrature degree
184 model.dimrange = 1; % scalar solution
185 
186 % The following 2 methods boundary_type() and normals() need not be
187 % implemented for grid-based methods, as the normals simply can be
188 % obtained by the grid. The methods are only required, if using
189 % meshless methods with data functions that use normals.
190 model.boundary_type = @my_boundary_type;
191 model.normals = @my_normals;
192 
193 % generate local function evaluations
194 model = elliptic_discrete_model(model);
195 
196 %%%%%%% auxiliary functions:
197 
198 % all edges of unit square are dirichlet, other inner
199 % note this function is not used by grid-based methods
200 function res = my_boundary_type(glob,params)
201 res = zeros(size(glob,1),1);
202 i = find(glob(:,1)<=1e-10);
203 i = [i, find(glob(:,1)>=1-1e-10)];
204 i = [i, find(glob(:,2)<=1e-10)];
205 i = [i, find(glob(:,2)>=1-1e-10)];
206 res(i) = -1;
207 
208 function res = my_normals(glob,params);
209 res = zeros(size(glob,1),2); % each row one normal
210 i = find(glob(:,1)>1-1e-10);
211 res(i,1)= 1.0;
212 i = find(glob(:,1)<-1+1e-10);
213 res(i,1)= -1.0;
214 i = find(glob(:,2)>1-1e-10);
215 res(i,2)= 1.0;
216 i = find(glob(:,2)<-1+1e-10);
217 res(i,2)= -1.0;
218 % remove diagonal normals
219 i = find (sum(abs(res),2)>1.5);
220 res(i,1)= 0;
221 
222 
223 
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]))
function local_model = elliptic_discrete_model(model)
function creating a model with local functions out of a model with global functions. See detailed description for explanation.