rbmatlab 0.10.01
discfunc/fem/feminfo.m
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 
All Classes Namespaces Files Functions Variables