rbmatlab 0.10.01
|
00001 classdef feminfo < handle 00002 % structure representing the fem-space information shared by all 00003 % fem-functions. Implemneted as handle class, in order to be linked 00004 % into df-classes. 00005 00006 % B. Haasdonk 13.1.2011 00007 00008 % adapted to new assembly 00009 00010 % I. Maier 24.03.2011 00011 00012 properties 00013 % polynomial degree 00014 pdeg; 00015 00016 % dimension of ranges space 00017 dimrange; 00018 00019 % index vector of global DOFs 00020 global_dof_index; 00021 00022 % number of DOFs 00023 ndofs; 00024 00025 % number of DOFs per grid element 00026 ndofs_per_element; 00027 00028 % object of type .gridbase 00029 grid; 00030 00031 % number of lagrange node indices 00032 nlagrange_nodes; 00033 00034 % the lagrange points on nodes 00035 lagrange_nodes; 00036 00037 % the lagrange points on edges 00038 lagrange_edges; 00039 00040 % determinant of reference mapping 00041 detDF; 00042 00043 % global IDs of dirichlet DOFs 00044 dirichlet_gids; 00045 00046 % element IDs of Robin DOFs 00047 robin_elind; 00048 00049 % edge IDs of Robin DOFs 00050 robin_edgeind; 00051 00052 % element IDs of Neumann DOFs 00053 neumann_elind; 00054 00055 % edge IDs of Neumann DOFs 00056 neumann_edgeind; 00057 00058 % weight matrix for `L^2` inner product 00059 l2_inner_product_matrix; 00060 00061 % weight matrix for `H^1_0` inner product 00062 h10_inner_product_matrix; 00063 00064 % weight matrix for regularized `H^1_0` inner product 00065 regularized_h10_inner_product_matrix; 00066 end 00067 00068 methods 00069 00070 function df_info = feminfo (model,grid) 00071 %function feminfo(model,grid) 00072 % required fields of model: 00073 % pdeg: polynomial degree 00074 df_info.pdeg = model.pdeg; 00075 df_info.dimrange = model.dimrange; 00076 df_info.ndofs = fem_ndofs(model,grid); 00077 df_info.ndofs_per_element = fem_ndofs_per_element(model); 00078 df_info.global_dof_index = fem_global_dof_index(model,grid); 00079 df_info.grid = grid; 00080 00081 df_info.lagrange_nodes = lagrange_nodes_lcoord(model.pdeg); 00082 df_info.nlagrange_nodes = size(df_info.lagrange_nodes,1); 00083 df_info.lagrange_edges = lagrange_nodes_edges(model.pdeg); 00084 df_info.detDF = grid.A(:)*2; % determinant of reference mapping per element; 00085 df_info.dirichlet_gids = []; 00086 00087 % l2_inner_product and h10_inner product for now only for 00088 % scalar functions. Extend later. 00089 % make sure, that the folliwing is called with empty 00090 % dirichlet nodes, as fem_matrix_volume_component_assembly does 00091 % dirichlet treatment!!! 00092 % reaction term == 1 then reaction matrix is l2matrix 00093 if df_info.dimrange == 1 00094 warning('off', 'Matlab:StructOnObject'); 00095 descr = struct(model); 00096 warning('on', 'Matlab:StructOnObject'); 00097 descr.reaction = @(grid,eindices,loc,params) ones(size(eindices,1),1); 00098 descr.qdeg = 2*df_info.pdeg; 00099 df_info.l2_inner_product_matrix = ... 00100 fem_matrix_volume_part_assembly(@fem_matrix_reac_integral_kernel,descr,df_info); 00101 % H10_inner_product_matrix: identity diffusion 00102 descr.diffusivity_tensor = @(grid,eindices,loc,params) ... 00103 [ones(size(eindices,1),1), zeros(size(eindices,1),1), ... 00104 zeros(size(eindices,1),1), ones(size(eindices,1),1)]; 00105 df_info.h10_inner_product_matrix = ... 00106 fem_matrix_volume_part_assembly(@fem_matrix_diff_integral_kernel,descr,df_info); 00107 end; 00108 00109 % find dirichlet indices as preparation 00110 is_dirichlet_gid = zeros(df_info.ndofs,1); 00111 % dirichlet-treatment: insert unit-vector row into A in dirichlet 00112 % rows. Little loop over local lagrange node index 00113 % this is repeated in r assembly as these will be kept separated 00114 for i=1:df_info.nlagrange_nodes 00115 % search all elements, in which the i-th Lagrange node is 00116 % dirichlet point 00117 eids = find(df_info.lagrange_edges(i,:)==1); 00118 if ~isempty(eids) 00119 for e = eids; % possibly one point belongs to 2 edges!! 00120 elids = find(grid.NBI(:,e)==-1); 00121 gids = df_info.global_dof_index(elids,i); 00122 is_dirichlet_gid(gids) = 1; 00123 end; 00124 end; 00125 end 00126 df_info.dirichlet_gids = find(is_dirichlet_gid); 00127 00128 % find robin boundary elements and edge numbers 00129 ind = find(grid.NBI==-3); 00130 [df_info.robin_elind,df_info.robin_edgeind] = ind2sub(size(grid.NBI),ind); 00131 00132 % find neumann boundary elements and edge numbers 00133 ind = find(grid.NBI==-2); 00134 [df_info.neumann_elind,df_info.neumann_edgeind] = ind2sub(size(grid.NBI),ind); 00135 % regularized_h10_inner_product_matrix: make unit rows in 00136 % dirichlet indices: 00137 00138 if df_info.dimrange == 1 00139 reg_mat = df_info.h10_inner_product_matrix; 00140 if ~isempty(df_info.dirichlet_gids) 00141 reg_mat(df_info.dirichlet_gids,:) = 0; 00142 A_dirichlet = sparse(df_info.dirichlet_gids,... 00143 df_info.dirichlet_gids, ... 00144 ones(size(df_info.dirichlet_gids)),... 00145 df_info.ndofs,df_info.ndofs); 00146 reg_mat = reg_mat + A_dirichlet; 00147 end; 00148 df_info.regularized_h10_inner_product_matrix = reg_mat; 00149 end; 00150 00151 end 00152 00153 end 00154 00155 end 00156 00157