Peano
Loading...
Searching...
No Matches
BoundaryConditions.cpp
Go to the documentation of this file.
2
4#include "peano4/utils/Loop.h"
5
6#include "tarch/logging/Log.h"
8
11
12#include <iomanip>
13
14
16 std::function< void(
17 const double* __restrict__ Qinside,
18 double * __restrict__ Qoutside,
21 double t,
22 double dt,
23 int normal
24 ) > boundaryCondition,
27 double t,
28 double dt,
29 int numberOfGridCellsPerPatchPerAxis,
30 int overlap,
31 int unknownsPlusAuxiliaryVariables,
32 int faceNumber,
33 double* __restrict__ Q
34) {
35 static tarch::logging::Log _log( "exahype2::fd" );
36 logTraceInWith4Arguments( "applyBoundaryConditions(...)", faceCentre, patchSize, numberOfGridCellsPerPatchPerAxis, faceNumber);
37
39 faceNumber,
40 numberOfGridCellsPerPatchPerAxis,
41 overlap,
42 unknownsPlusAuxiliaryVariables,
43 0
44 );
45
46 tarch::la::Vector<Dimensions,double> volumeH = exahype2::fd::getGridCellSize(patchSize, numberOfGridCellsPerPatchPerAxis);
47 tarch::la::Vector<Dimensions,double> faceOffset = faceCentre - 0.5 * patchSize;
48 faceOffset(faceNumber%Dimensions) += 0.5 * patchSize(faceNumber%Dimensions);
49
50 dfore(volume,numberOfGridCellsPerPatchPerAxis,faceNumber % Dimensions,0) {
51 tarch::la::Vector<Dimensions,int> insideGridCell = volume;
52 tarch::la::Vector<Dimensions,int> outsideGridCell = volume;
53 tarch::la::Vector<Dimensions,double> x = faceOffset + tarch::la::multiplyComponents( tarch::la::convertScalar<double>(volume)+tarch::la::Vector<Dimensions,double>(0.5), volumeH);
54
55 x(faceNumber%Dimensions) -= 0.5 * volumeH(faceNumber%Dimensions);
56
57 for (int layer=0; layer<overlap; layer++) {
58 if (faceNumber<Dimensions) {
59 insideGridCell(faceNumber % Dimensions) = overlap-layer;
60 outsideGridCell(faceNumber % Dimensions) = overlap-1-layer;
61 }
62 else {
63 insideGridCell(faceNumber % Dimensions) = layer+overlap-1;
64 outsideGridCell(faceNumber % Dimensions) = layer+overlap;
65 }
66
68 "applyBoundaryConditions(...)",
69 faceCentre << " x " << faceNumber << ": " <<
70 insideGridCell << "->" << outsideGridCell << " (" << enumerator(insideGridCell,0) << "->" << enumerator(outsideGridCell,0) << "): " <<
71 *(Q + enumerator(insideGridCell,0))
72 );
73
74 boundaryCondition(
75 Q + enumerator(insideGridCell,0),
76 Q + enumerator(outsideGridCell,0),
77 x, volumeH, t, dt, faceNumber
78 );
79 }
80 }
81
82 logTraceOut( "applyBoundaryConditions(...)" );
83}
84
85
87 std::function< double(
88 const double* __restrict__ Q,
91 double t,
92 double dt,
93 int normal
94 ) > maxEigenvalue,
95 std::function< void(
96 double* __restrict__ Q,
99 ) > farFieldSolution,
100 const tarch::la::Vector<Dimensions,double>& faceCentre,
102 double t,
103 double dt,
104 int numberOfGridCellsPerPatchPerAxis,
105 int overlap,
106 int numberOfUnknowns,
107 int numberOfAuxiliaryVariables,
108 int faceNumber,
109 const tarch::la::Vector<Dimensions,double>& systemOrigin,
110 double* __restrict__ Qold,
111 double* __restrict__ Qnew,
112 double CheckpointTimeStamp
113) {
114 static tarch::logging::Log _log( "exahype2::fd" );
115 logTraceInWith4Arguments( "applySommerfeldConditions(...)", faceCentre, patchSize, numberOfGridCellsPerPatchPerAxis, faceNumber);
116 std::cout<<std::setprecision(8);
117
119 faceNumber,
120 numberOfGridCellsPerPatchPerAxis,
121 overlap,
122 numberOfUnknowns+numberOfAuxiliaryVariables,
123 0
124 );
125
126 double* QInf = tarch::allocateMemory<double>( numberOfUnknowns+numberOfAuxiliaryVariables, tarch::MemoryLocation::Heap );
127
128 tarch::la::Vector<Dimensions,double> volumeH = exahype2::fd::getGridCellSize(patchSize, numberOfGridCellsPerPatchPerAxis);
129 tarch::la::Vector<Dimensions,double> faceOffset = faceCentre - 0.5 * patchSize;
130 faceOffset(faceNumber%Dimensions) += 0.5 * patchSize(faceNumber%Dimensions);
131 //std::cout<<"face offseet: "<<faceOffset<<std::endl;
132
133 dfore(volume,numberOfGridCellsPerPatchPerAxis,faceNumber % Dimensions,0) {
134 tarch::la::Vector<Dimensions,int> insideGridCell = volume;
135 tarch::la::Vector<Dimensions,int> outsideGridCell = volume;
136 tarch::la::Vector<Dimensions,double> x = faceOffset + tarch::la::multiplyComponents( tarch::la::convertScalar<double>(volume)+tarch::la::Vector<Dimensions,double>(0.5), volumeH);
137
139 //if (faceNumber<Dimensions) {
140 // xOnLayer(faceNumber%Dimensions) -= volumeH(faceNumber%Dimensions);
141 //}
142 //std::cout<<"xonlayer: "<<xOnLayer<<std::endl;
143
144 for (int layer=0; layer<overlap; layer++) {
145 if (faceNumber<Dimensions) {
146 insideGridCell(faceNumber % Dimensions) = overlap-layer;
147 outsideGridCell(faceNumber % Dimensions) = overlap-1-layer;
148 //std::cout<<"x: "<<x<<std::endl;
149 //std::cout<<"shift: "<< -layer * volumeH(faceNumber%Dimensions)<<std::endl;
150 xOnLayer(faceNumber%Dimensions) = x(faceNumber%Dimensions) - layer * volumeH(faceNumber%Dimensions); //for each layer the x is different
151 xOnLayer(faceNumber%Dimensions) -= volumeH(faceNumber%Dimensions); //due to shortcut above we need to remove another layer to make coordinate correct
152 //std::cout<<"xOnlayer: "<<xOnLayer<<std::endl;
153 }
154 else {
155 insideGridCell(faceNumber % Dimensions) = layer+overlap-1;
156 outsideGridCell(faceNumber % Dimensions) = layer+overlap;
157 //std::cout<<"x: "<<x<<std::endl;
158 //std::cout<<"shift: "<< +layer * volumeH(faceNumber%Dimensions)<<std::endl;
159 xOnLayer(faceNumber%Dimensions) = x(faceNumber%Dimensions) + layer * volumeH(faceNumber%Dimensions); //for each layer the x is different
160 //std::cout<<"xOnlayer: "<<xOnLayer<<std::endl;
161 }
162 //std::cout<<"xOnlayer: "<<xOnLayer<<std::endl;
163
164 if (tarch::la::equals(t,0.0)){ //for the initial timestep, we need to fill the outside volume for old data as well.
165 for(int i=0; i<numberOfUnknowns+numberOfAuxiliaryVariables; i++) {
166 (Qold + enumerator(outsideGridCell,0))[i]=(Qold+enumerator(insideGridCell,0))[i];
167 }
168 }
169
170 if (tarch::la::equals(t,CheckpointTimeStamp,1e-8)){ //for the initial timestep, we need to fill the outside volume for old data as well.
171 for(int i=0; i<numberOfUnknowns+numberOfAuxiliaryVariables; i++) {
172 (Qold + enumerator(outsideGridCell,0))[i]=(Qold+enumerator(insideGridCell,0))[i];
173 }
174 }
175
176 const double rOnLayer=tarch::la::norm2(xOnLayer-systemOrigin);
177 const double waveSpeed=maxEigenvalue( Qold + enumerator(outsideGridCell,0), faceCentre, volumeH, t, dt, faceNumber % Dimensions);
178 //std::cout<<"rOnlayer: "<<rOnLayer<<" waveSpeed: "<<waveSpeed<<std::endl;
179
180 logDebug(
181 "applySommerfeldConditions(...)",
182 faceCentre << " x " << faceNumber << ": " <<
183 insideGridCell << "->" << outsideGridCell << " (" << enumerator(insideGridCell,0) << "->" << enumerator(outsideGridCell,0) << "): " <<
184 *(Qnew + enumerator(insideGridCell,0))
185 );
186
187 farFieldSolution(
188 QInf,
189 xOnLayer,
190 volumeH
191 );
192
193 //do something here, we have Qold, Qnew, waveSpeed, xOnLayer, rOnLayer, dt, volumeH, Qinf
194 //we try the first approach first to see if it is already sufficient.
195 double dtInverse=1/dt;
196 double spaceFactor=waveSpeed*rOnLayer/volumeH(faceNumber%Dimensions)/xOnLayer(faceNumber%Dimensions);
197 //std::cout<<"dtInverse: "<<dtInverse<<" spaceFactor: "<<spaceFactor<<std::endl;
198
199 //logInfo("text","factor "<< spaceFactor <<" waveSpeed "<<waveSpeed<<" rOnLayer "<<rOnLayer<<" volumeH "<<volumeH(faceNumber%Dimensions)
200 // <<" xOnLayer "<<xOnLayer(faceNumber%Dimensions));
201
202 for(int i=0; i<numberOfUnknowns; i++) {
203 double numerator=-(waveSpeed/rOnLayer)*((Qold + enumerator(outsideGridCell,0))[i]+(Qold+enumerator(insideGridCell,0))[i]-2*QInf[i])
204 +(+dtInverse-spaceFactor)*(Qold + enumerator(outsideGridCell,0))[i]
205 +(-dtInverse+spaceFactor)*(Qnew + enumerator( insideGridCell,0))[i]
206 +(+dtInverse+spaceFactor)*(Qold + enumerator( insideGridCell,0))[i];
207 //logInfo("numerator","numerator "<<numerator );
208 (Qnew + enumerator(outsideGridCell,0))[i]=numerator/(dtInverse+spaceFactor);
209 }
210 for(int i=numberOfUnknowns; i<numberOfUnknowns+numberOfAuxiliaryVariables; i++) {
211 (Qnew + enumerator(outsideGridCell,0))[i]=(Qold+enumerator(insideGridCell,0))[i];
212 } //in principle we do not need to assign auxiliary variables, but I do this here for safety
213
214 }
215 }
216
218
219 logTraceOut( "applySommerfeldConditions(...)" );
220}
221
222
224 std::function< double(
225 const double* __restrict__ Q,
226 const tarch::la::Vector<Dimensions,double>& faceCentre,
228 double t,
229 double dt,
230 int normal
231 ) > maxEigenvalue,
232 const tarch::la::Vector<Dimensions,double>& faceCentre,
234 double t,
235 double dt,
236 int numberOfGridCellsPerPatchPerAxis,
237 int overlap,
238 int numberOfUnknowns,
239 int numberOfAuxiliaryVariables,
240 int faceNumber,
241 const tarch::la::Vector<Dimensions,double>& systemOrigin,
242 double* __restrict__ Qold,
243 double* __restrict__ Qnew,
244 double CheckpointTimeStamp
245) {
247 maxEigenvalue,
248 [&] (
249 double* __restrict__ Q,
250 const tarch::la::Vector<Dimensions,double>& faceCentre,
252 ) -> void {
253 for (int i=0; i<numberOfUnknowns+numberOfAuxiliaryVariables; i++) {
254 Q[i] = 0.0;
255 }
256 },
257 faceCentre,
258 patchSize,
259 t,
260 dt,
261 numberOfGridCellsPerPatchPerAxis,
262 overlap,
263 numberOfUnknowns,
264 numberOfAuxiliaryVariables,
265 faceNumber,
266 systemOrigin,
267 Qold,
268 Qnew,
269 CheckpointTimeStamp
270 );
271}
272
273
#define logDebug(methodName, logMacroMessageStream)
Definition Log.h:50
#define logTraceOut(methodName)
Definition Log.h:379
#define logTraceInWith4Arguments(methodName, argument0, argument1, argument2, argument3)
Definition Log.h:373
#define dfore(counter, max, dim, value)
This is an exclusive d-dimensional for loop.
Definition Loop.h:942
Log Device.
Definition Log.h:516
tarch::logging::Log _log("exahype2::fv")
void applyBoundaryConditions(std::function< void(const double *__restrict__ Qinside, double *__restrict__ Qoutside, const tarch::la::Vector< Dimensions, double > &faceCentre, const tarch::la::Vector< Dimensions, double > &volumeH, double t, double dt, int normal) > boundaryCondition, const tarch::la::Vector< Dimensions, double > &faceCentre, const tarch::la::Vector< Dimensions, double > &patchSize, double t, double dt, int numberOfGridCellsPerPatchPerAxis, int overlap, int unknownsPlusAuxiliaryVariables, int faceNumber, double *__restrict__ Q)
Apply (generic) boundary conditions.
static tarch::la::Vector< 2, double > getGridCellSize(const tarch::la::Vector< 2, double > &h, int numberOfGridCellsPerPatchPerAxis)
Definition PatchUtils.h:22
void applySommerfeldConditions(std::function< double(const double *__restrict__ Q, const tarch::la::Vector< Dimensions, double > &faceCentre, const tarch::la::Vector< Dimensions, double > &gridCellH, double t, double dt, int normal) > maxEigenvalue, std::function< void(double *__restrict__ Q, const tarch::la::Vector< Dimensions, double > &faceCentre, const tarch::la::Vector< Dimensions, double > &gridCellH) > farFieldSolution, const tarch::la::Vector< Dimensions, double > &faceCentre, const tarch::la::Vector< Dimensions, double > &patchSize, double t, double dt, int numberOfGridCellsPerPatchPerAxis, int overlap, int numberOfUnknowns, int numberOfAuxiliaryVariables, int faceNumber, const tarch::la::Vector< Dimensions, double > &systemOrigin, double *__restrict__ Qold, double *__restrict__ Qnew, double CheckpointTimeStamp)
bool equals(const Matrix< Rows, Cols, Scalar > &lhs, const Matrix< Rows, Cols, Scalar > &rhs, const Scalar &tolerance=NUMERICAL_ZERO_DIFFERENCE)
Compares to matrices on equality by means of a numerical accuracy.
Matrix< Rows, Cols, Scalar > multiplyComponents(const Matrix< Rows, X, Scalar > &lhs, const Matrix< X, Cols, Scalar > &rhs)
Scalar norm2(const Vector< Size, Scalar > &vector)
Computes the 2-norm of the vector, i.e.
void freeMemory(void *data, MemoryLocation location, int device=accelerator::Device::HostDevice)
Free memory.
@ Heap
Create data on the heap of the local device.
Simple vector class.
Definition Vector.h:134