comparison +scheme/bcSetup.m @ 869:d356f1a22d4f bcSetupExperiment

Start organizing the code
author Jonatan Werpers <jonatan@werpers.com>
date Fri, 07 Sep 2018 09:19:03 +0200
parents 57760d7088ad
children fb91d12093f8
comparison
equal deleted inserted replaced
868:57760d7088ad 869:d356f1a22d4f
14 function [closure, S] = bcSetup(diffOp, bcs, S_sign) 14 function [closure, S] = bcSetup(diffOp, bcs, S_sign)
15 default_arg('S_sign', 1); 15 default_arg('S_sign', 1);
16 assertType(bcs, 'cell'); 16 assertType(bcs, 'cell');
17 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');
18 18
19 verifyBcFormat(bcs, diffOp); 19 [closure, penalties] = bcClosureSetup(diffOp, bcs);
20 20 S = bcForcingSetup(diffOp, penalties, bcs, S_sign);
21 % Setup storage arrays
22 closure = spzeros(size(diffOp));
23 gridData = {};
24 symbolicData = {};
25
26 % Collect closures, penalties and data
27 for i = 1:length(bcs)
28 [localClosure, penalty] = diffOp.boundary_condition(bcs{i}.boundary, bcs{i}.type);
29 closure = closure + localClosure;
30
31 [ok, isSym, data] = parseData(bcs{i}, penalty, diffOp.grid);
32
33 if ~ok
34 % There was no data
35 continue
36 end
37
38 if isSym
39 symbolicData{end+1} = data;
40 else
41 gridData{end+1} = data;
42 end
43 end
44
45 % Setup penalty function
46 O = spzeros(size(diffOp),1);
47 function v = S_fun(t)
48 v = O;
49 for i = 1:length(gridData)
50 v = v + gridData{i}.penalty*gridData{i}.func(t);
51 end
52
53 for i = 1:length(symbolicData)
54 v = v + symbolicData{i}.penalty*symbolicData{i}.func(t, symbolicData{i}.coords{:});
55 end
56
57 v = S_sign * v;
58 end
59 S = @S_fun;
60 end 21 end
61 22
23 %%% NOTES
62 % Borde man använda eval on här?? 24 % Borde man använda eval on här??
63 % Borde man dela upp bcSetup i bcSetupSymbolic(name?) och bcSetupGridData 25 % Borde man dela upp bcSetup i bcSetupSymbolic(name?) och bcSetupGridData
64 % och sen skriva en wrapper som sorterar och wrappar de två andra?? 26 % och sen skriva en wrapper som sorterar och wrappar de två andra??
65 27
66 % Borde man ha en separat funktion för closure penalty generering 28 % Borde man ha en separat funktion för closure penalty generering
67 % och en separat för att bygga ihop penaltyn med data? 29 % och en separat för att bygga ihop penaltyn med data?
68 30
69 % Erbjuda en separat function for att validera en bc specifikation? 31 % Erbjuda en separat function for att validera en bc specifikation?
70 % alltid kräva alla fields? 32 % alltid kräva alla fields?
71 % literal struct improvement? 33 % literal struct improvement?
72
73 function verifyBcFormat(bcs, diffOp)
74 for i = 1:length(bcs)
75 assertType(bcs{i}, 'struct');
76 assertStructFields(bcs{i}, {'type', 'boundary'});
77
78 if ~isfield(bcs{i}, 'data') || isempty(bcs{i}.data)
79 continue
80 end
81
82 if ~isa(bcs{i}.data, 'function_handle')
83 error('bcs{%d}.data should be a function of time or a function of time and space',i);
84 end
85
86 b = diffOp.grid.getBoundary(bcs{i}.boundary);
87
88 dim = size(b,2);
89
90 if nargin(bcs{i}.data) == 1
91 % Grid data (only function of time)
92 assertSize(bcs{i}.data(0), 1, size(b));
93 elseif nargin(bcs{i}.data) ~= 1+dim
94 error('sbplib:scheme:bcSetup:DataWrongNumberOfArguments', 'bcs{%d}.data has the wrong number of input arguments. Must be either only time or time and space.', i);
95 end
96 end
97 end
98
99 function [ok, isSym, dataStruct] = parseData(bc, penalty, grid)
100 if ~isfield(bc,'data') || isempty(bc.data)
101 ok = false;
102 return
103 end
104 ok = true;
105
106 nArg = nargin(bc.data);
107
108 if nArg > 1
109 % Symbolic data
110 isSym = true;
111 coord = grid.getBoundary(bc.boundary);
112 dataStruct.penalty = penalty;
113 dataStruct.func = bc.data;
114 dataStruct.coords = num2cell(coord, 1);
115 else
116 % Grid data
117 isSym = false;
118 dataStruct.penalty = penalty;
119 dataStruct.func = bcs{i}.data;
120 end
121 end