LoAdSG
StencilMC.h
1//
2// Created by to35jepo on 9/19/24.
3//
4
5#ifndef RUN_STENCILMC_H
6#define RUN_STENCILMC_H
7
8
9#include <random>
10#include "Stencil.h"
11
12
13template <typename F>
14class StencilMC: public StencilTemplate{
15
16public:
17
18 StencilMC(AdaptiveSparseGrid& grid_, const F &varCoeff_, int c_) : StencilTemplate(grid_), varCoeff(varCoeff_), c(c_){
19 dofs=grid.getDOFS();
20 gen =std::mt19937(rd());
21 };
22
23
24 int c=1;
25
26
27 inline double integration(CellDimension& cell, CellIndexDirection& dirP, CellIndexDirection& dirQ){
28 FunctionClass functionClass(cell,dirP,dirQ);
29 double value = 1.0;
30
31 int numberMC = 1;
32 int l=0;
33
34 for(int d=0; d<DimensionSparseGrid;d++){
35 l+=cell.getDepth(d)-1;
36
37 }
38
39
40 int vol_cell= POW2(unsigned (l));
41
42
43 if(vol_cell>dofs) numberMC=1;
44 else numberMC= dofs/vol_cell;
45
46 numberMC*=c;
47
48
49
50
51
52
53
54 double sum=0.0;
55
56
57 for(int j=0; j<numberMC;j++){
58 double x[DimensionSparseGrid];
59 for(int d=0;d<DimensionSparseGrid;d++){
60 x[d]=std::uniform_real_distribution<>(cell.getLeftBoundary(d),cell.getRightBoundary(d))(gen);
61 }
62 double vC = varCoeff(x)*functionClass.evaluation(x);
63
64 sum+=vC;
65 }
66 value = (1.0/vol_cell)*(sum/double(numberMC));
67
68 return value;
69
70
71
72 }
73 class FunctionClass{
74
75
76 public:
77 FunctionClass (CellDimension& cell_, CellIndexDirection& dirP_, CellIndexDirection &dirQ_): cell(cell_),dirP(dirP_),dirQ(dirQ_){
78
79 for(int i=0; i<DimensionSparseGrid; i++){
80 double h = cell.getRightBoundary(i)-cell.getLeftBoundary(i);
81
82 meshwidth[i]=h;
83
84 }
85
86 }
87 double evaluation(double* x){
88
89
90
91
92
93
94 double value = 1.0;
95
96 for(int i = 0; i < DimensionSparseGrid; ++i )
97 {
98
99 // === Muliply by the first base function ===
100 if(dirP.getDirection(i)==Left){
101 // p(x) = (x-b)/(a-b)=(b-x)/h
102 value *= (cell.getRightBoundary(i)-x[i]) / (meshwidth[i]);
103
104 }else{
105 // p(x) = (x-a)/(b-a)
106 value *= (x[i] - cell.getLeftBoundary(i)) / (meshwidth[i]);
107 }
108
109 // === Muliply by the second base function ===
110 if(dirQ.getDirection(i)==Left){
111 // p(x) = (x-b)/(a-b)=(b-x)/h
112 value *= (cell.getRightBoundary(i)-x[i]) / (meshwidth[i]);
113
114
115 }else{
116 // p(x) = (x-a)/(b-a)
117 value *= (x[i] - cell.getLeftBoundary(i)) / (meshwidth[i]);
118 }
119
120
121 }
122
123
124
125
126
127 return value;
128 };
129
130
131
132
133
134
135 private:
136
137 double meshwidth[DimensionSparseGrid];
138 CellDimension cell;
139 CellIndexDirection dirP;
140 CellIndexDirection dirQ;
141
142
143 };
144 F varCoeff;
145 int dofs;
146 std::random_device rd;
147 std::uniform_real_distribution<> dist[DimensionSparseGrid];
148 std::mt19937 gen;
149};
150
151
152template <typename F>
153class RHS_MC: public StencilTemplate{
154
155public:
156
157 RHS_MC(AdaptiveSparseGrid& grid_, const F &varCoeff_, int c_) : StencilTemplate(grid_), varCoeff(varCoeff_), c(c_){
158 dofs=grid.getDOFS();
159 gen =std::mt19937(rd());
160 };
161
162
163 int c=1;
164
165
166 inline double integration(CellDimension& cell, CellIndexDirection& dirP, CellIndexDirection& dirQ){
167 FunctionClass functionClass(cell,dirP,dirQ);
168 double value = 1.0;
169
170 int numberMC = 1;
171 int l=0;
172
173 for(int d=0; d<DimensionSparseGrid;d++){
174 l+=cell.getDepth(d)-1;
175
176 }
177
178
179 int vol_cell= POW2(unsigned (l));
180
181
182 if(vol_cell>dofs) numberMC=1;
183 else numberMC= dofs/vol_cell;
184
185 numberMC*=c;
186
187
188
189
190
191
192
193 double sum=0.0;
194
195
196 for(int j=0; j<numberMC;j++){
197 double x[DimensionSparseGrid];
198 for(int d=0;d<DimensionSparseGrid;d++){
199 x[d]=std::uniform_real_distribution<>(cell.getLeftBoundary(d),cell.getRightBoundary(d))(gen);
200 }
201 double vC = varCoeff(x)*functionClass.evaluation(x);
202
203 sum+=vC;
204 }
205 value = (1.0/vol_cell)*(sum/double(numberMC));
206
207 return value;
208
209
210
211 }
212 class FunctionClass{
213
214
215 public:
216 FunctionClass (CellDimension& cell_, CellIndexDirection& dirP_, CellIndexDirection &dirQ_): cell(cell_),dirP(dirP_),dirQ(dirQ_){
217
218 for(int i=0; i<DimensionSparseGrid; i++){
219 double h = cell.getRightBoundary(i)-cell.getLeftBoundary(i);
220
221 meshwidth[i]=h;
222
223 }
224
225 }
226 double evaluation(double* x){
227
228 double value = 1.0;
229
230 for(int i = 0; i < DimensionSparseGrid; ++i )
231 {
232
233 // === Muliply by the first base function ===
234 if(dirP.getDirection(i)==Left){
235 // p(x) = (x-b)/(a-b)=(b-x)/h
236 value *= (cell.getRightBoundary(i)-x[i]) / (meshwidth[i]);
237
238 }else{
239 // p(x) = (x-a)/(b-a)
240 value *= (x[i] - cell.getLeftBoundary(i)) / (meshwidth[i]);
241 }
242
243 // === Muliply by the second base function ===
244 if(dirQ.getDirection(i)==Left){
245 // p(x) = (x-b)/(a-b)=(b-x)/h
246 value *= (cell.getRightBoundary(i)-x[i]) / (meshwidth[i]);
247
248
249 }else{
250 // p(x) = (x-a)/(b-a)
251 value *= (x[i] - cell.getLeftBoundary(i)) / (meshwidth[i]);
252 }
253
254
255 }
256
257
258
259
260
261 return value;
262 };
263
264
265
266
267
268
269 private:
270
271 double meshwidth[DimensionSparseGrid];
272 CellDimension cell;
273 CellIndexDirection dirP;
274 CellIndexDirection dirQ;
275
276
277 };
278 F varCoeff;
279 int dofs;
280 std::random_device rd;
281 std::uniform_real_distribution<> dist[DimensionSparseGrid];
282 std::mt19937 gen;
283};
284
285
286#endif //RUN_STENCILMC_H
Definition sparseGrid.h:277