Peano
Loading...
Searching...
No Matches
CCZ4.cpp
Go to the documentation of this file.
1#include "CCZ4.h"
2#include "exahype2/RefinementControl.h"
3#include <algorithm>
4
5#include "Constants.h"
6
7#include <limits>
8
9#include <stdio.h>
10#include <string.h>
11#include "tarch/NonCriticalAssertions.h"
12
13#ifdef IncludeTwoPunctures
15#endif
16
17tarch::logging::Log applications::exahype2::ccz4::CCZ4::_log( "applications::exahype2::ccz4::CCZ4" );
18
19#ifdef IncludeTwoPunctures
20//pre-process, solve the puncture equations
22 //first we set the parameter. TODO:find a way to read parameter from python script
23 //int swi=0;//0--single black hole, 2--BBH hoc, 2--BBH rotation, 3--GW150914
24 //bbhtype=0 head on, 1-b=3, 2-b=2
25
26 if (CCZ4swi==0){
27 tp->par_b=1.0;
28 tp->center_offset[0]=-1.0; tp->center_offset[1]=0.0; tp->center_offset[2]=0.0;
29 tp->target_M_plus=1.0;//adm mass
30 tp->par_P_plus[0]=0.0; tp->par_P_plus[1]=0.0; tp->par_P_plus[2]=0.0;//linear momentum
31 tp->par_S_plus[0]=0.0; tp->par_S_plus[1]=0.0; tp->par_S_plus[2]=0.0;//spin
32 tp->target_M_minus=0.0;//adm mass
33 tp->par_P_minus[0]=0.0; tp->par_P_minus[1]=0.0; tp->par_P_minus[2]=0.0;//linear momentum
34 tp->par_S_minus[0]=0.0; tp->par_S_minus[1]=0.0; tp->par_S_minus[2]=0.0; //spin
35 tp->grid_setup_method="evaluation"; //evaluation or Taylor expansion
36 tp->TP_epsilon=1e-6;}
37
38 if (CCZ4swi==4){
39 tp->par_b=1.0;
40 tp->center_offset[0]=-3.0; tp->center_offset[1]=-2.0; tp->center_offset[2]=0.0;
41 tp->target_M_plus=1.0;//adm mass
42 tp->par_P_plus[0]=0.1; tp->par_P_plus[1]=0.1; tp->par_P_plus[2]=0.0;//linear momentum
43 tp->par_S_plus[0]=0.0; tp->par_S_plus[1]=0.0; tp->par_S_plus[2]=0.0;//spin
44 tp->target_M_minus=0.0;//adm mass
45 tp->par_P_minus[0]=0.0; tp->par_P_minus[1]=0.0; tp->par_P_minus[2]=0.0;//linear momentum
46 tp->par_S_minus[0]=0.0; tp->par_S_minus[1]=0.0; tp->par_S_minus[2]=0.0; //spin
47 tp->grid_setup_method="evaluation"; //evaluation or Taylor expansion
48 tp->TP_epsilon=1e-6;}
49
50 if (CCZ4swi==2 and CCZ4BBHType==0){
51 tp->par_b=2.0;
52 tp->center_offset[0]=0.0; tp->center_offset[1]=0.0; tp->center_offset[2]=0.0;
53 tp->target_M_plus=0.5;//adm mass
54 tp->par_P_plus[0]=0.0; tp->par_P_plus[1]=0.0; tp->par_P_plus[2]=0.0;//linear momentum
55 tp->par_S_plus[0]=0.0; tp->par_S_plus[1]=0.0; tp->par_S_plus[2]=0.0;//spin
56 tp->target_M_minus=0.5;//adm mass
57 tp->par_P_minus[0]=0.0; tp->par_P_minus[1]=0.0; tp->par_P_minus[2]=0.0;//linear momentum
58 tp->par_S_minus[0]=0.0; tp->par_S_minus[1]=0.0; tp->par_S_minus[2]=0.0; //spin
59 tp->grid_setup_method="evaluation"; //evaluation or Taylor expansion
60 tp->TP_epsilon=1e-6;}
61
62 //following data reference: https://journals.aps.org/prd/pdf/10.1103/PhysRevD.69.024006
63 if (CCZ4swi==2 and CCZ4BBHType==1){
64 tp->par_b=5.0;
65 tp->center_offset[0]=0.0; tp->center_offset[1]=0.0; tp->center_offset[2]=0.0;
66 tp->give_bare_mass=true;//use puncture mass instead of adm mass
67 tp->par_m_plus=0.48595; tp->par_m_minus=0.48595;
68 //tp->target_M_plus=999;//adm mass
69 tp->par_P_plus[0]=0.0; tp->par_P_plus[1]=0.095433; tp->par_P_plus[2]=0.0;//linear momentum
70 tp->par_S_plus[0]=0.0; tp->par_S_plus[1]=0.0; tp->par_S_plus[2]=0.0;//spin
71 //tp->target_M_minus=999;//adm mass
72 tp->par_P_minus[0]=0.0; tp->par_P_minus[1]=-0.095433; tp->par_P_minus[2]=0.0;//linear momentum
73 tp->par_S_minus[0]=0.0; tp->par_S_minus[1]=0.0; tp->par_S_minus[2]=0.0; //spin
74 tp->grid_setup_method="evaluation"; //evaluation or Taylor expansion
75 tp->TP_epsilon=1e-6;}
76
77 if (CCZ4swi==2 and CCZ4BBHType==2){
78 tp->par_b=2.0;
79 tp->center_offset[0]=0.0; tp->center_offset[1]=0.0; tp->center_offset[2]=0.0;
80 tp->give_bare_mass=true;//use puncture mass instead of adm mass
81 tp->par_m_plus=0.46477; tp->par_m_minus=0.46477;
82 //tp->target_M_plus=999;//adm mass
83 tp->par_P_plus[0]=0.0; tp->par_P_plus[1]=0.19243; tp->par_P_plus[2]=0.0;//linear momentum
84 tp->par_S_plus[0]=0.0; tp->par_S_plus[1]=0.0; tp->par_S_plus[2]=0.0;//spin
85 //tp->target_M_minus=999;//adm mass
86 tp->par_P_minus[0]=0.0; tp->par_P_minus[1]=-0.19243; tp->par_P_minus[2]=0.0;//linear momentum
87 tp->par_S_minus[0]=0.0; tp->par_S_minus[1]=0.0; tp->par_S_minus[2]=0.0; //spin
88 tp->grid_setup_method="evaluation"; //evaluation or Taylor expansion
89 tp->TP_epsilon=1e-6;}
90
91 if (CCZ4swi==3){
92 double D=10.0, q=36.0/29.0, chip=0.31, chim=-0.46, M=1.0;
93 double Pr=-0.00084541526517121, Pphi=0.09530152296974252;
94 double mp=M*q/(1+q), mm=M*1/(1+q);
95 tp->par_b=5.0;
96 tp->center_offset[0]=D*mm-D/2; tp->center_offset[1]=0.0; tp->center_offset[2]=0.0;
97 tp->target_M_plus=mp;//adm mass
98 tp->par_P_plus[0]=Pr; tp->par_P_plus[1]=Pphi; tp->par_P_plus[2]=0.0;//linear momentum
99 tp->par_S_plus[0]=0.0; tp->par_S_plus[1]=0.0; tp->par_S_plus[2]=chip*mp*mp;//spin
100 tp->target_M_minus=1/(1+q);//adm mass
101 tp->par_P_minus[0]=-Pr; tp->par_P_minus[1]=-Pphi; tp->par_P_minus[2]=0.0;//linear momentum
102 tp->par_S_minus[0]=0.0; tp->par_S_minus[1]=0.0; tp->par_S_minus[2]=chim*mm*mm; //spin
103 tp->grid_setup_method="evaluation"; //evaluation or Taylor expansion
104 tp->TP_epsilon=1e-6;}
105 tp->PrintParameters();
106
107 //then solve the equation
108 tp->Run();
109}
110#endif
111
113 if ( Scenario==0 || Scenario==1 ) {
114 const char* name = "GaugeWave";//nothing to do here for now
115 int length = strlen(name);
116 //initparameters_(&length, name);
117 }
118 #ifdef IncludeTwoPunctures
119 if ( Scenario==2 ) {
120 prepare(_tp);//we solve the puncture equation here.
121 //exit(0);
122 }
123 #endif
124 else {
125 //std::cerr << "initial scenario " << Scenario << " is not supported" << std::endl << std::endl << std::endl;
126 }
127}
128
130 double * NOALIAS Q,
131 const tarch::la::Vector<DIMENSIONS,double>& volumeX,
132 const tarch::la::Vector<DIMENSIONS,double>& volumeH,
133 bool gridIsConstructed
134) {
135 logTraceInWith3Arguments( "initialCondition(...)", volumeX, volumeH, gridIsConstructed );
136
137 if ( Scenario==0 ) {
139 }
140 else if ( Scenario==3 ) {
142 }
143 else if ( Scenario==1 ) {
145 }
146 else if ( Scenario==4 ) {
148 }
149 #ifdef IncludeTwoPunctures
150 else if ( Scenario==2 ) {
151
152 // We use the bool to trigger the hgh res interpolation once the grid is constructed
153 applications::exahype2::ccz4::ApplyTwoPunctures(Q, volumeX, 0, _tp, not gridIsConstructed); //we interpolate for real IC here.
154 }
155 #endif
156 else {
157 logError( "initialCondition(...)", "initial scenario " << Scenario << " is not supported" );
158 }
159
160 for (int i=0; i<NumberOfUnknowns; i++) {
161 assertion2( std::isfinite(Q[i]), volumeX, i );
162 }
163
164 for (int i=NumberOfUnknowns; i<NumberOfUnknowns+NumberOfAuxiliaryVariables; i++) {
165 Q[i] = 0.0;
166 }
167
168
169/*
170 else {
171 enforceCCZ4constraints(Q);
172 }
173*/
174 logTraceOut( "initialCondition(...)" );
175}
176
177
179 const double * NOALIAS Q, // Q[59+0]
180 const tarch::la::Vector<DIMENSIONS,double>& volumeX,
181 const tarch::la::Vector<DIMENSIONS,double>& volumeH,
182 double t,
183 double dt,
184 double * NOALIAS S // S[59
185) {
186 logTraceInWith4Arguments( "sourceTerm(...)", volumeX, volumeH, t, dt );
187 for(int i=0; i<NumberOfUnknowns; i++){
188 assertion3( std::isfinite(Q[i]), i, volumeX, t );
189 }
190 // for (int i=NumberOfUnknowns; i<NumberOfUnknowns+NumberOfAuxiliaryVariables; i++) {
191 // S[i] = 0.0;
192 //}
193 applications::exahype2::ccz4::CCZ4::sourceTerm(Q, volumeX, volumeH, t, dt, S, Offloadable::Yes);
194 /*
195 if (CCZ4smoothing>0){// then we apply simple laplacian smoothing
196 constexpr int NumberOfRefinementLayers = 3;
197 double Radius[NumberOfRefinementLayers] = {5.0*1.8, 3.0*1.8, 1.5*1.8};
198 double radius=volumeX(0)*volumeX(0)+volumeX(1)*volumeX(1)+volumeX(2)*volumeX(2); radius=pow(radius,0.5);
199 ::exahype2::CellAccess access(
200 Q, // make it initially point to input
201 1, // halo size, which you know as user
202 NumberOfUnknowns, // defined in superclass
203 NumberOfAuxiliaryVariables // defined in superclass
204 NumberOfDoFsPerAxisInCell, // defined in superclass
205 );
206 double laplacian=0.0;
207 for (int unknown=0; unknown<NumberOfUnknowns; unknown++) {
208 laplacian = -6.0 * access.centre(unknown)
209 + 1.0 * access.left(0,unknown)+ 1.0 * access.right(0,unknown)
210 + 1.0 * access.left(1,unknown)+ 1.0 * access.right(1,unknown)
211 + 1.0 * access.left(2,unknown)+ 1.0 * access.right(2,unknown);
212 laplacian /= volumeH(0);
213 laplacian /= volumeH(0);
214 double coef=CCZ4smoothing*(std::exp(-5.0*std::abs(radius-Radius[0])) + std::exp(-5.0*std::abs(radius-Radius[1])) + std::exp(-5.0*std::abs(radius-Radius[2])) )/3.0;
215 coef=CCZ4smoothing;
216 S[unknown]+=coef*laplacian;
217 }
218 }*/
219
220 for(int i=0; i<NumberOfUnknowns; i++){
221 nonCriticalAssertion3( std::isfinite(S[i]), i, volumeX, t );
222 }
223 logTraceOut( "sourceTerm(...)" );
224}
225
226
228 const double * NOALIAS Qinside, // Qinside[59+0]
229 double * NOALIAS Qoutside, // Qoutside[59+0]
230 const tarch::la::Vector<DIMENSIONS,double>& faceCentre,
231 const tarch::la::Vector<DIMENSIONS,double>& volumeH,
232 double t,
233 int normal
234) {
235 logTraceInWith4Arguments( "boundaryConditions(...)", faceCentre, volumeH, t, normal );
236 for(int i=0; i<NumberOfUnknowns+NumberOfAuxiliaryVariables; i++) {
237 assertion4( Qinside[i]==Qinside[i], faceCentre, t, normal, i );
238 Qoutside[i]=Qinside[i];
239 }
240 logTraceOut( "boundaryConditions(...)" );
241}
242
243
245 const double * NOALIAS Q, // Q[59+0],
246 const tarch::la::Vector<DIMENSIONS,double>& faceCentre,
247 const tarch::la::Vector<DIMENSIONS,double>& volumeH,
248 double t,
249 double dt,
250 int normal
251)
252{
253 return maxEigenvalue(Q, faceCentre, volumeH, t, dt, normal, Offloadable::Yes);
254}
255
256
258 const double * NOALIAS Q, // Q[59+0],
259 const double * NOALIAS deltaQ, // [59+0]
260 const tarch::la::Vector<DIMENSIONS,double>& faceCentre,
261 const tarch::la::Vector<DIMENSIONS,double>& volumeH,
262 double t,
263 double dt,
264 int normal,
265 double * NOALIAS BgradQ // BgradQ[59]
266) {
267 logTraceInWith4Arguments( "nonconservativeProduct(...)", faceCentre, volumeH, t, normal );
268 assertion( normal>=0 );
269 assertion( normal<DIMENSIONS );
270 nonconservativeProduct(Q, deltaQ, faceCentre, volumeH, t, dt, normal, BgradQ, Offloadable::Yes);
271
272 for (int i=0; i<NumberOfUnknowns; i++) {
273 nonCriticalAssertion4( std::isfinite(BgradQ[i]), i, faceCentre, t, normal );
274 }
275 logTraceOut( "nonconservativeProduct(...)" );
276}
277
279 const double * NOALIAS Q, // Q[59+0],
280 const double * NOALIAS deltaQ, // [59+0]
281 const tarch::la::Vector<DIMENSIONS,double>& faceCentre,
282 const tarch::la::Vector<DIMENSIONS,double>& volumeH,
283 double t,
284 double dt,
285 int normal,
286 double * NOALIAS BgradQ, // BgradQ[59]
287 Offloadable
288)
289{
290 double gradQSerialised[NumberOfUnknowns*3];
291 for (int i=0; i<NumberOfUnknowns; i++) {
292 gradQSerialised[i+0*NumberOfUnknowns] = 0.0;
293 gradQSerialised[i+1*NumberOfUnknowns] = 0.0;
294 gradQSerialised[i+2*NumberOfUnknowns] = 0.0;
295
296 gradQSerialised[i+normal*NumberOfUnknowns] = deltaQ[i];
297 }
298 //for (int i=NumberOfUnknowns; i<NumberOfUnknowns+NumberOfAuxiliaryVariables; i++) {
299 // BgradQ[i] = 0.0;
300 //}
301 ncp(BgradQ, Q, gradQSerialised, normal, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4mu, CCZ4SO);
302}
303
305 const double * NOALIAS Q,
306 const tarch::la::Vector<DIMENSIONS,double>& volumeCentre,
307 const tarch::la::Vector<DIMENSIONS,double>& volumeH,
308 double t
309) {
310 ::exahype2::RefinementCommand result = ::exahype2::RefinementCommand::Keep;
311
312 const double radius = tarch::la::norm2( volumeCentre );
313 //
314 // see documentation in header file
315 //
316 if (CCZ4ReSwi==1) { //radius based
317 if (radius<0.1) {
318 result=::exahype2::RefinementCommand::Refine;
319 }
320 }
321 if (CCZ4ReSwi==2) { //
322 if (tarch::la::equals(t,0.0)){ //static AMR, for bbh, type==1
323 constexpr int NumberOfRefinementLayers = 2;
324// current "standard" refinement pattern
325 double Radius[NumberOfRefinementLayers] = {8, 6};
326 double MaxH[NumberOfRefinementLayers] = {0.15,0.04};
327 result = ::exahype2::RefinementCommand::Keep;
328 for (int i=0; i<NumberOfRefinementLayers; i++) {
329 if (radius<Radius[i] and tarch::la::max(volumeH)>MaxH[i]) {
330 result=::exahype2::RefinementCommand::Refine;
331 }
332 }
333 }
334 }
335 if (CCZ4ReSwi==3) { //not used
336 tarch::la::Vector<DIMENSIONS,double> leftBH = {-4.241, 0.0, 0.0};
337 tarch::la::Vector<DIMENSIONS,double> rightBH = { 4.241, 0.0, 0.0};
338
339 const double radius1 = tarch::la::norm2( volumeCentre - leftBH );
340 const double radius2 = tarch::la::norm2( volumeCentre - rightBH );
341
342 if (tarch::la::equals(t,0.0)){ //as we use a quantity calculated in postpocessing, we need to provide criterion at the first timestep
343 if ( ((radius1<5) or (radius2<5)) and (volumeH(0)>1.0)) { result=::exahype2::RefinementCommand::Refine; }
344 else if ((radius1<2.5) or (radius2<2.5)) { result=::exahype2::RefinementCommand::Refine; }
345 else {result = ::exahype2::RefinementCommand::Keep;}
346 } else {
347 if ((Q[65]>0.1) and (volumeH(0)>1.0)) { result=::exahype2::RefinementCommand::Refine; }
348 else if (Q[65]>0.2) { result=::exahype2::RefinementCommand::Refine; }
349 else {result = ::exahype2::RefinementCommand::Keep;}
350 }
351 }
352 if (CCZ4ReSwi==5){
353 if (tarch::la::equals(t,0.0)){ //static AMR, for bbh, type==0, 2
354 constexpr int NumberOfRefinementLayers = 2;
355 double Radius[NumberOfRefinementLayers] = {4, 3};
356 double MaxH[NumberOfRefinementLayers] = {0.17,0.06};
357
358 result = ::exahype2::RefinementCommand::Keep;
359 for (int i=0; i<NumberOfRefinementLayers; i++) {
360 if (radius<Radius[i] and tarch::la::max(volumeH)>MaxH[i]) {
361 result=::exahype2::RefinementCommand::Refine;
362 }
363 }
364 }
365 }
366 if (CCZ4ReSwi==6){
367 if (tarch::la::equals(t,0.0)){ //static AMR, for bbh, type==0, 2
368 constexpr int NumberOfRefinementLayers = 2;
369 double Radius[NumberOfRefinementLayers] = {4, 3};
370 double MaxH[NumberOfRefinementLayers] = {0.15,0.04};
371
372 result = ::exahype2::RefinementCommand::Keep;
373 for (int i=0; i<NumberOfRefinementLayers; i++) {
374 if (radius<Radius[i] and tarch::la::max(volumeH)>MaxH[i]) {
375 result=::exahype2::RefinementCommand::Refine;
376 }
377 }
378 }
379 }
380 if (CCZ4ReSwi==8){
381 if (tarch::la::equals(t,0.0)){ //static AMR, for bbh, type==0, 2
382 constexpr int NumberOfRefinementLayers = 2;
383 double Radius[NumberOfRefinementLayers] = {4, 3};
384 double MaxH[NumberOfRefinementLayers] = {0.1,0.035};
385
386 result = ::exahype2::RefinementCommand::Keep;
387 for (int i=0; i<NumberOfRefinementLayers; i++) {
388 if (radius<Radius[i] and tarch::la::max(volumeH)>MaxH[i]) {
389 result=::exahype2::RefinementCommand::Refine;
390 }
391 }
392 }
393 }
394 if (CCZ4ReSwi==7){
395 if (tarch::la::equals(t,0.0)){ //static AMR, for sbh
396 constexpr int NumberOfRefinementLayers = 2;
397 double Radius[NumberOfRefinementLayers] = {3.0, 1.5};
398 double MaxH[NumberOfRefinementLayers] = {0.15,0.04};
399 result = ::exahype2::RefinementCommand::Keep;
400 for (int i=0; i<NumberOfRefinementLayers; i++) {
401 if (radius<Radius[i] and tarch::la::max(volumeH)>MaxH[i]) {
402 result=::exahype2::RefinementCommand::Refine;
403 }
404 }
405 }
406 }
407 return result;
408}
409
TP::TwoPunctures * _tp
Definition CCZ4.cpp:16
::exahype2::RefinementCommand refinementCriterion(const double *NOALIAS Q, const tarch::la::Vector< DIMENSIONS, double > &volumeCentre, const tarch::la::Vector< DIMENSIONS, double > &volumeH, double t) override
Refinement criterion.
Definition CCZ4.cpp:304
virtual void boundaryConditions(const double *NOALIAS Qinside, double *NOALIAS Qoutside, const tarch::la::Vector< DIMENSIONS, double > &faceCentre, const tarch::la::Vector< DIMENSIONS, double > &volumeH, double t, int normal) override
Definition CCZ4.cpp:227
void prepare(TP::TwoPunctures *tp)
Definition CCZ4.cpp:21
static tarch::logging::Log _log
Definition CCZ4.h:32
void sourceTerm(const double *NOALIAS Q, const tarch::la::Vector< DIMENSIONS, double > &volumeCentre, const tarch::la::Vector< DIMENSIONS, double > &volumeH, double t, double dt, double *NOALIAS S) override
Definition CCZ4.cpp:178
virtual void nonconservativeProduct(const double *NOALIAS Q, const double *NOALIAS deltaQ, const tarch::la::Vector< DIMENSIONS, double > &faceCentre, const tarch::la::Vector< DIMENSIONS, double > &volumeH, double t, double dt, int normal, double *NOALIAS BgradQ) override
Definition CCZ4.cpp:257
virtual double maxEigenvalue(const double *NOALIAS Q, const tarch::la::Vector< DIMENSIONS, double > &faceCentre, const tarch::la::Vector< DIMENSIONS, double > &volumeH, double t, double dt, int normal) override
Determine max eigenvalue over Jacobian in a given point with solution values (states) Q.
Definition CCZ4.cpp:244
void initialCondition(double *NOALIAS Q, const tarch::la::Vector< DIMENSIONS, double > &volumeCentre, const tarch::la::Vector< DIMENSIONS, double > &volumeH, bool gridIsConstructed) override
Definition CCZ4.cpp:129
void diagonal_gaugeWave(double *NOALIAS Q, const tarch::la::Vector< DIMENSIONS, double > &x, double t)
static void ncp(double *BgradQ, const double *const Q, const double *const gradQSerialised, const int normal, const int CCZ4LapseType, const double CCZ4ds, const double CCZ4c, const double CCZ4e, const double CCZ4f, const double CCZ4bs, const double CCZ4sk, const double CCZ4xi, const double CCZ4mu, const double CCZ4SO)
void linearWave(double *NOALIAS Q, const tarch::la::Vector< DIMENSIONS, double > &X, double t)
void ApplyTwoPunctures(double *NOALIAS Q, const tarch::la::Vector< DIMENSIONS, double > &X, double t, TP::TwoPunctures *tp, bool low_res)
void flat(double *NOALIAS Q, const tarch::la::Vector< DIMENSIONS, double > &X, double t)
static double maxEigenvalue(const double *const Q, int normal, const double CCZ4e, const double CCZ4ds, const double CCZ4GLMc, const double CCZ4GLMd)
void gaugeWave(double *NOALIAS Q, const tarch::la::Vector< DIMENSIONS, double > &x, double t)
double par_S_plus[3]
std::string grid_setup_method
double par_P_plus[3]
double par_S_minus[3]
double center_offset[3]
double target_M_minus
double par_P_minus[3]