1 classdef BcInfo < handle
2 %classdef BcInfo < handle
3 % Class
for boundary condition information. Allows more flexible usage.
5 % One can specify boundary parts via model.bnd_rect_corner1 and
6 % model.bnd_rect_corner2. For boundary integrals one has to group the
7 % rectangles with numbers < -1 in model.bnd_rect_index. For each of
8 % these rectangles an integral kernel and coefficient functions can be
9 % given in model. Then, model.matrix_boundary_int_kernel{i} or
10 % model.rhs_boundary_int_kernel{i} is used on the boundary with index
11 % -(i+1). If a term is zero, there should be an empty cell entry.
13 % Boundaries not assigned in
this way are used
for Dirichlet conditions
14 % by
default. It is also possible to define Dirichlet constraints
for
15 % chosen dimensions of the field variable in model.bnd_dimrange_index.
16 % Then the rectangles have to be given explicitly (after the rectangles
17 %
for the integral terms).
19 % The
Fem assembly requires a field named bc_info in model_data, which
20 % is an
object of
this class.
32 dirichlet_dof_vector_components;
37 function bi =
BcInfo(model, grid, df_info)
38 %bi =
BcInfo(model, grid, df_info)
39 % Constructor preparing all necessary boundary condition
40 % information
for the
Fem assembly.
45 bi.nbint_parts = -min(min(grid.NBI)) - 1;
46 bi.elinds = cell(bi.nbint_parts, 1);
47 bi.edgeinds = cell(bi.nbint_parts, 1);
49 for i = 1:bi.nbint_parts
51 ind = find(grid.NBI == -(i+1));
52 [bi.elinds{i}, bi.edgeinds{i}] = ind2sub(size(grid.NBI), ind);
55 bi.has_dirichlet_values = model.has_dirichlet_values;
56 bi.dirichlet_gids = [];
57 bi.dirichlet_dof_vector_components = {};
59 if bi.has_dirichlet_values
61 % find dirichlet indices
62 if (isfield(model,
'bnd_rect_index') && ...
63 size(model.bnd_rect_corner1, 2) > length(model.bnd_rect_index)) ...
64 || (~isfield(model,
'bnd_rect_index') && ...
65 isfield(model,
'bnd_dimrange_index'))
67 bnd_ind = find(grid.NBI <= 0);
68 SX = grid.ECX(bnd_ind);
69 SY = grid.ECY(bnd_ind);
71 % field bnd_dimrange_index of model is required
72 for i = 1:length(model.bnd_dimrange_index)
74 dimrange_index = model.bnd_dimrange_index{i};
75 dir_corner_index = length(model.bnd_rect_index) + i;
76 dof_ids_local = cat(2, df_info.dof_ids_local{dimrange_index});
78 inds = (SX > model.bnd_rect_corner1(1, dir_corner_index)) & ...
79 (SX < model.bnd_rect_corner2(1, dir_corner_index)) & ...
80 (SY > model.bnd_rect_corner1(2, dir_corner_index)) & ...
81 (SY < model.bnd_rect_corner2(2, dir_corner_index));
83 bnd_inds_tmp = bnd_ind(inds);
84 [elids, edgeids] = ind2sub(size(grid.NBI), bnd_inds_tmp);
88 elids_tmp = elids(edgeids == j);
89 lids = find(df_info.dofs_edges_llcoord(:, j) > -1);
90 lids = intersect(lids, dof_ids_local);
92 if ~isempty(lids) && ~isempty(elids_tmp)
94 gids = get_global_dof_index(df_info, elids_tmp, lids);
95 bi.dirichlet_gids = union(bi.dirichlet_gids, gids(:));
101 if isfield(model, 'bnd_dimrange_index')
103 dof_ids_local = cat(2, df_info.dof_ids_local{model.bnd_dimrange_index{1}});
107 for j = 1:grid.nneigh
109 elids = find(grid.NBI(:, j) == -1);
110 lids = find(df_info.dofs_edges_llcoord(:, j) > -1);
111 if isfield(model,
'bnd_dimrange_index')
112 lids = intersect(lids, dof_ids_local);
114 if ~isempty(lids) && ~isempty(elids)
116 gids = get_global_dof_index(df_info, elids, lids);
117 bi.dirichlet_gids = union(bi.dirichlet_gids, gids(:));
122 old_decomp_mode = model.decomp_mode;
123 model.decomp_mode = 1;
124 bi.dirichlet_dof_vector_components = ...
125 Fem.Assembly.dirichlet_dof_vector(model, df_info, bi);
126 model.decomp_mode = old_decomp_mode;
128 end %has_dirichlet_values
Class for boundary condition information. Allows more flexible usage.