rbmatlab 0.10.01
|
00001 function model = poisson_model(params); 00002 %function model = poisson_model(params) 00003 % 00004 % small example of a model, i.e. a structure describing the data 00005 % functions and geometry information of a general elliptic equation consisting 00006 % of diffusion, convection, reaction equation: 00007 % 00008 % - div ( a(x) grad u(x)) + div (b(x) u(x)) + c(x) u(x) = f(x) on Omega 00009 % u(x)) = g_D(x) on Gamma_D 00010 % a(x) (grad u(x)) n) = g_N(x) on Gamma_N 00011 % alpha(x) u(x) + beta(x) a(x) (grad u(x)) n) = g_R(x) on Gamma_R 00012 % 00013 % s = l(u) linear output functional 00014 % 00015 % Here, we denote the functions as 00016 % u: scalar 'solution' (if known, for validation purpose) 00017 % f: scalar 'source' 00018 % a: tensor valued 'diffusivity_tensor' 00019 % b: vector valued 'velocity' 00020 % c: scalar 'reaction' 00021 % g_D: scalar 'dirichlet_values' 00022 % g_N: scalar 'neumann_values' 00023 % g_R: scalar 'robin_values' 00024 % alpha: scalar 'robin_alpha' 00025 % beta: scalar 'robin_beta' 00026 % 00027 % Each function allows the evaluation in many points 00028 % simultaneuously by 00029 % 00030 % model.source(glob) 00031 % or model.source(glob,params) 00032 % 00033 % where glob is a n times 2 matrix of row-wise points. The result 00034 % is a n times 1 vector of resulting values of f. 00035 % 00036 % model.diffusivity_tensor(glob) 00037 % or model.diffusivity_tensor(glob,params) 00038 % 00039 % where glob is a n times 2 matrix of row-wise points. The result 00040 % is a n times 4 matrix of resulting values of diffusivity, where 00041 % the values of a are sorted in matlab-order as [a_11, a_21, a_12, a_22]; 00042 % 00043 % additionally, the model has a function, which determines, whether 00044 % a point lies on a Dirichlet, Neumann or Robin boundary: 00045 % 00046 % model.boundary_type(glob) 00047 % 0 no boundary (inner edge or point) 00048 % -1 indicates Dirichlet-boundary 00049 % -2 indicates Neumann-boundary 00050 % -3 indicates Robin-boundary 00051 % 00052 % Additionally, the normals in a boundary point can be requested by 00053 % 00054 % model.normals(glob) 00055 % Here, glob are assumed to be boundary points lying ON THE 00056 % INTERIOR of an edge, such that the outer unit normal is well-defined. 00057 % 00058 % The latter 2 methods boundary_type() and normals() need not be 00059 % implemented for grid-based methods, as the normals simply can be 00060 % obtained by the grid. The methods are only required, if using 00061 % meshless methods with data functions that use normals. 00062 % 00063 % The output functional must be specified 00064 % s = model.output_functional(model, model_data, u) 00065 % where u is a dof vector of the discrete solution. model_data is 00066 % assumed to contain the grid 00067 % 00068 % possible fields of params: 00069 % numintervals: the unit square is divided into numintervals 00070 % intervals per side. default is 10; 00071 % 00072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00073 % 00074 % The data functions given in this model are the simple poisson 00075 % equation with Gamma_D = boundary(Omega), Gamma_N = {}, Gamma_R = {} 00076 % 00077 % -div (grad u) = f 00078 % u = 0 on Gamma_D 00079 % 00080 % with exact solution u(x) = 16 x_1(1-x_1)x_2(1-x_2), 00081 % i.e. f(x) = 32 (x_1 + x_2 - x_1^2 - x_2^2) 00082 00083 % B. Haasdonk 23.11.2010 00084 00085 if nargin == 0 00086 params = []; 00087 end; 00088 00089 if ~isfield(params,'numintervals') 00090 params.numintervals = 10; % 2 x 2 grid! with 8 triangles 00091 end; 00092 00093 if ~isfield(params,'pdeg') 00094 params.pdeg = 2; % 2 x 2 grid! with 8 triangles 00095 end; 00096 00097 if ~isfield(params,'qdeg') 00098 params.qdeg = 2; % 2 x 2 grid! with 8 triangles 00099 end; 00100 00101 model = []; 00102 model.rb_problem_type = 'lin_elliptic'; 00103 00104 %%%%%%% data function specification: 00105 00106 % if any of the following flags is set, the corresponding function 00107 % pointers must be provided below. 00108 00109 model.has_reaction = 1; 00110 %model.has_reaction = 0; 00111 model.has_source = 1; 00112 model.has_reaction = 1; 00113 %model.has_reaction = 0; 00114 model.has_advection = 1; 00115 %model.has_advection = 0; 00116 model.has_diffusivity = 1; 00117 model.has_output_functional = 1; 00118 model.has_dirichlet_values = 1; 00119 model.has_neumann_values = 1; 00120 %model.has_neumann_values = 0; 00121 %model.has_robin_values = 1; 00122 model.has_robin_values = 1; 00123 00124 % solution is known: 00125 model.solution = @(glob,params) ... 00126 16 * glob(:,1).*(1-glob(:,1)).*glob(:,2).*(1-glob(:,2)); 00127 % for debugging: f = 1; u = -1/4 (x^2+y^2) 00128 %model.solution = @(glob,params) ... 00129 % -0.25 * (glob(:,1).^2+glob(:,2).^2); 00130 00131 % params is an optional parameter, perhaps useful later 00132 model.source = @(glob,params) ... 00133 32 * (glob(:,1)+ glob(:,2)- glob(:,1).^2 - glob(:,2).^2); 00134 % for debugging: f = 1; u = -0.25* (x^2+y^2) 00135 %model.source = @(glob,params) ... 00136 % ones(size(glob,1),1); 00137 00138 model.reaction = @(glob,params) zeros(size(glob,1),1); 00139 model.velocity = @(glob,params) zeros(size(glob,1),2); 00140 model.diffusivity_tensor = @(glob,params) ... 00141 [ones(size(glob,1),1),... 00142 zeros(size(glob,1),1),... 00143 zeros(size(glob,1),1),... 00144 ones(size(glob,1),1)]; 00145 %model.diffusivity_gradient = @(glob,params) zeros(size(glob,1),2); 00146 model.reaction = @(glob,params) zeros(size(glob,1),1); 00147 00148 % Dirichlet everywhere, see function below. 00149 %model.dirichlet_values = @(glob,params) zeros(size(glob,1),1); 00150 model.dirichlet_values = @(glob,params) ... 00151 params.solution(glob,params); 00152 model.neumann_values = @(glob,params) zeros(size(glob,1),1); 00153 model.robin_values = @(glob,params) zeros(size(glob,1),1); 00154 model.robin_alpha = @(glob,params) zeros(size(glob,1),1); 00155 model.robin_beta = @(glob,params) zeros(size(glob,1),1); 00156 00157 % output functional, e.g. average over unit-square: 00158 model.output_functional = @output_functional_volume_integral; 00159 model.output_function = @output_function_box_mean; 00160 model.sbox_xmin = 0; 00161 model.sbox_ymin = 0; 00162 model.sbox_xmax = 1; 00163 model.sbox_ymax = 1; 00164 model.output_integral_qdeg = 0; % midpoint integration 00165 % later, e.g. for thermal block: 00166 %model.output_functional = @output_functional_boundary_integral; 00167 %model.output_function = @output_function_dirichlet_indicator; 00168 00169 %%%%%%% geometry specification and discretization: 00170 00171 model.gridtype = 'triagrid'; 00172 model.xnumintervals = params.numintervals; 00173 model.ynumintervals = params.numintervals; 00174 model.xrange = [0,1]; 00175 model.yrange = [0,1]; 00176 00177 % numerics settings: 00178 model.pdeg = params.pdeg; % degree of polynomial functions 00179 model.qdeg = params.qdeg; % quadrature degree 00180 model.dimrange = 1; % scalar solution 00181 00182 % The following 2 methods boundary_type() and normals() need not be 00183 % implemented for grid-based methods, as the normals simply can be 00184 % obtained by the grid. The methods are only required, if using 00185 % meshless methods with data functions that use normals. 00186 model.boundary_type = @my_boundary_type; 00187 model.normals = @my_normals; 00188 00189 %%%%%%% auxiliary functions: 00190 00191 % all edges of unit square are dirichlet, other inner 00192 % note this function is not used by grid-based methods 00193 function res = my_boundary_type(glob,params) 00194 res = zeros(size(glob,1),1); 00195 i = find(glob(:,1)<=1e-10); 00196 i = [i, find(glob(:,1)>=1-1e-10)]; 00197 i = [i, find(glob(:,2)<=1e-10)]; 00198 i = [i, find(glob(:,2)>=1-1e-10)]; 00199 res(i) = -1; 00200 00201 function res = my_normals(glob,params); 00202 res = zeros(size(glob,1),2); % each row one normal 00203 i = find(glob(:,1)>1-1e-10); 00204 res(i,1)= 1.0; 00205 i = find(glob(:,1)<-1+1e-10); 00206 res(i,1)= -1.0; 00207 i = find(glob(:,2)>1-1e-10); 00208 res(i,2)= 1.0; 00209 i = find(glob(:,2)<-1+1e-10); 00210 res(i,2)= -1.0; 00211 % remove diagonal normals 00212 i = find (sum(abs(res),2)>1.5); 00213 res(i,1)= 0; 00214 00215 00216