Mercurial > repos > public > sbplib
comparison +scheme/bcSetup.m @ 781:69ab0e69f972 feature/interpolation
Merge with feature/grids
author | Jonatan Werpers <jonatan@werpers.com> |
---|---|
date | Tue, 24 Jul 2018 20:14:29 -0700 |
parents | 0776fa4754ff |
children | c02b6d03c77c |
comparison
equal
deleted
inserted
replaced
751:005a8d071da3 | 781:69ab0e69f972 |
---|---|
1 % function [closure, S] = bcSetup(diffOp, bc) | |
2 % Takes a diffOp and a cell array of boundary condition definitions. | |
3 % Each bc is a struct with the fields | |
4 % * type -- Type of boundary condition | |
5 % * boundary -- Boundary identifier | |
6 % * data -- A function_handle for a function which provides boundary data.(see below) | |
7 % Also takes S_sign which modifies the sign of S, [-1,1] | |
8 % Returns a closure matrix and a forcing function S. | |
9 % | |
10 % The boundary data function can either be a function of time or a function of time and space coordinates. | |
11 % In the case where it only depends on time it should return the data as grid function for the boundary. | |
12 % In the case where it also takes space coordinates the number of space coordinates should match the number of dimensions of the problem domain. | |
13 % For example in the 2D case: f(t,x,y). | |
14 function [closure, S] = bcSetup(diffOp, bc, S_sign) | |
15 default_arg('S_sign', 1); | |
16 assertType(bc, 'cell'); | |
17 assert(S_sign == 1 || S_sign == -1, 'S_sign must be either 1 or -1'); | |
18 | |
19 | |
20 % Setup storage arrays | |
21 closure = spzeros(size(diffOp)); | |
22 gridDataPenalties = {}; | |
23 gridDataFunctions = {}; | |
24 symbolicDataPenalties = {}; | |
25 symbolicDataFunctions = {}; | |
26 symbolicDataCoords = {}; | |
27 | |
28 % Collect closures, penalties and data | |
29 for i = 1:length(bc) | |
30 assertType(bc{i}, 'struct'); | |
31 [localClosure, penalty] = diffOp.boundary_condition(bc{i}.boundary, bc{i}.type); | |
32 closure = closure + localClosure; | |
33 | |
34 if ~isfield(bc{i},'data') || isempty(bc{i}.data) | |
35 % Skip to next loop if there is no data | |
36 continue | |
37 end | |
38 assertType(bc{i}.data, 'function_handle'); | |
39 | |
40 % Find dimension | |
41 dim = size(diffOp.grid.getBoundary(bc{i}.boundary), 2); | |
42 | |
43 if nargin(bc{i}.data) == 1 | |
44 % Grid data | |
45 boundarySize = [size(diffOp.grid.getBoundary(bc{i}.boundary),1),1]; | |
46 assertSize(bc{i}.data(0), boundarySize); % Eval for t = 0 and make sure the function returns a grid vector of the correct size. | |
47 gridDataPenalties{end+1} = penalty; | |
48 gridDataFunctions{end+1} = bc{i}.data; | |
49 elseif nargin(bc{i}.data) == 1+dim | |
50 % Symbolic data | |
51 coord = diffOp.grid.getBoundary(bc{i}.boundary); | |
52 symbolicDataPenalties{end+1} = penalty; | |
53 symbolicDataFunctions{end+1} = bc{i}.data; | |
54 symbolicDataCoords{end+1} = num2cell(coord ,1); | |
55 else | |
56 error('sbplib:scheme:bcSetup:DataWrongNumberOfArguments', 'bc{%d}.data has the wrong number of input arguments. Must be either only time or time and space.', i); | |
57 end | |
58 end | |
59 | |
60 % Setup penalty function | |
61 O = spzeros(size(diffOp),1); | |
62 function v = S_fun(t) | |
63 v = O; | |
64 for i = 1:length(gridDataFunctions) | |
65 v = v + gridDataPenalties{i}*gridDataFunctions{i}(t); | |
66 end | |
67 | |
68 for i = 1:length(symbolicDataFunctions) | |
69 v = v + symbolicDataPenalties{i}*symbolicDataFunctions{i}(t, symbolicDataCoords{i}{:}); | |
70 end | |
71 | |
72 v = S_sign * v; | |
73 end | |
74 S = @S_fun; | |
75 end |