Mercurial > repos > public > sbplib
comparison +scheme/bcSetup.m @ 749:1de60c4d462d feature/grids
Allow gird functions as data in bcSetup
author | Jonatan Werpers <jonatan@werpers.com> |
---|---|
date | Mon, 04 Jun 2018 17:47:32 +0200 |
parents | 87436a107d8a |
children | 2645188489f6 0776fa4754ff |
comparison
equal
deleted
inserted
replaced
748:ec0a594bea9f | 749:1de60c4d462d |
---|---|
1 % function [closure, S] = bcSetup(diffOp, bc) | 1 % function [closure, S] = bcSetup(diffOp, bc) |
2 % Takes a diffOp and a cell array of boundary condition definitions. | 2 % Takes a diffOp and a cell array of boundary condition definitions. |
3 % Each bc is a struct with the fields | 3 % Each bc is a struct with the fields |
4 % * type -- Type of boundary condition | 4 % * type -- Type of boundary condition |
5 % * boundary -- Boundary identifier | 5 % * boundary -- Boundary identifier |
6 % * data -- A function_handle with time and space coordinates as a parameters, for example f(t,x,y) for a 2D problem | 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] | 7 % Also takes S_sign which modifies the sign of S, [-1,1] |
8 % Returns a closure matrix and a forcing function S | 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). | |
9 function [closure, S] = bcSetup(diffOp, bc, S_sign) | 14 function [closure, S] = bcSetup(diffOp, bc, S_sign) |
10 default_arg('S_sign', 1); | 15 default_arg('S_sign', 1); |
11 assertType(bc, 'cell'); | 16 assertType(bc, 'cell'); |
12 assert(S_sign == 1 || S_sign == -1, 'S_sign must be either 1 or -1'); | 17 assert(S_sign == 1 || S_sign == -1, 'S_sign must be either 1 or -1'); |
13 | 18 |
14 | 19 |
20 % Setup storage arrays | |
15 closure = spzeros(size(diffOp)); | 21 closure = spzeros(size(diffOp)); |
16 penalties = {}; | 22 gridDataPenalties = {}; |
17 dataFunctions = {}; | 23 gridDataFunctions = {}; |
18 dataParams = {}; | 24 symbolicDataPenalties = {}; |
25 symbolicDataFunctions = {}; | |
26 symbolicDataCoords = {}; | |
19 | 27 |
28 % Collect closures, penalties and data | |
20 for i = 1:length(bc) | 29 for i = 1:length(bc) |
21 assertType(bc{i}, 'struct'); | 30 assertType(bc{i}, 'struct'); |
22 [localClosure, penalty] = diffOp.boundary_condition(bc{i}.boundary, bc{i}.type); | 31 [localClosure, penalty] = diffOp.boundary_condition(bc{i}.boundary, bc{i}.type); |
23 closure = closure + localClosure; | 32 closure = closure + localClosure; |
24 | 33 |
25 if ~isfield(bc{i},'data') || isempty(bc{i}.data) | 34 if ~isfield(bc{i},'data') || isempty(bc{i}.data) |
35 % Skip to next loop if there is no data | |
26 continue | 36 continue |
27 end | 37 end |
28 assertType(bc{i}.data, 'function_handle'); | 38 assertType(bc{i}.data, 'function_handle'); |
29 | 39 |
30 coord = diffOp.grid.getBoundary(bc{i}.boundary); | 40 % Find dimension |
31 assertNumberOfArguments(bc{i}.data, 1+size(coord,2)); | 41 dim = size(diffOp.grid.getBoundary(bc{i}.boundary), 2); |
32 | 42 |
33 penalties{end+1} = penalty; | 43 if nargin(bc{i}.data) == 1 |
34 dataFunctions{end+1} = bc{i}.data; | 44 % Grid data |
35 dataParams{end+1} = num2cell(coord ,1); | 45 boundarySize = [size(diffOp.grid.getBoundary(bc{i}.boundary),1),1]; |
46 assert_size(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 | |
36 end | 58 end |
37 | 59 |
60 % Setup penalty function | |
38 O = spzeros(size(diffOp),1); | 61 O = spzeros(size(diffOp),1); |
39 function v = S_fun(t) | 62 function v = S_fun(t) |
40 v = O; | 63 v = O; |
41 for i = 1:length(dataFunctions) | 64 for i = 1:length(gridDataFunctions) |
42 v = v + penalties{i}*dataFunctions{i}(t, dataParams{i}{:}); | 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}{:}); | |
43 end | 70 end |
44 | 71 |
45 v = S_sign * v; | 72 v = S_sign * v; |
46 end | 73 end |
47 S = @S_fun; | 74 S = @S_fun; |