Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions example/test_problem/ELBDM/Soliton/Input__TestProb
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ Soliton_CoreRadiusAll 1.0e1 # core radius for ALL solitons (in code uni
Soliton_EmptyRegion 0.0 # soliton-free region [0.0]
# -> solitons only reside in [Soliton_EmptyRegion : BOX_SIZE-Soliton_EmptyRegion]
# -> useful only when Soliton_RSeed >= 0
Soliton_InitMode 1 # soliton initialization mode (1=table of the density profile, 2=analytical function of the density profile) [1]
Soliton_DensProf_Filename SolitonDensityProfile_Lambda0.0 # filename of the input soliton density profile
1 change: 1 addition & 0 deletions example/test_problem/ELBDM/Soliton/README
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ Note:
Soliton_N > 1: soliton merger
--> Set Soliton_RSeed >= 0
Set Soliton_EmptyRegion > 0.0 (e.g., 1.0e2)
2. Input density profile tables should use $| \psi |^2$ units. The code automatically converts this to mass density.
180 changes: 116 additions & 64 deletions src/TestProblem/ELBDM/Soliton/Init_TestProb_ELBDM_Soliton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ static double Soliton_CoreRadiusAll; // core radius for all
// (<=0.0 --> hard coding each soliton)
static double Soliton_EmptyRegion; // soliton-free region from the boundary
// (useful only when Soliton_RSeed>=0)
static int Soliton_InitMode; // soliton initialization mode (1=table of the density profile, 2=analytical function of the density profile)
static char Soliton_DensProf_Filename[MAX_STRING]; // filename of the reference soliton density profile

static int Soliton_DensProf_NBin; // number of radial bins of the soliton density profile
Expand All @@ -20,7 +21,7 @@ static double (*Soliton_Center)[3] = NULL; // center coordinates o
static double *Soliton_ScaleL = NULL; // L/D: length/density scale factors of each soliton
// (defined as the ratio between the core radii/peak
// density of the target and reference soliton profiles)
static double *Soliton_ScaleD = NULL;
static double *Soliton_ScaleD = NULL; // ( for Soliton_InitMode==1 only)
// =======================================================================================

static void BC( real Array[], const int ArraySize[], real fluid[], const int NVar_Flu,
Expand Down Expand Up @@ -124,6 +125,7 @@ void LoadInputTestProb( const LoadParaMode_t load_mode, ReadPara_t *ReadPara, HD
LOAD_PARA( load_mode, "Soliton_RSeed", &Soliton_RSeed, 0, NoMin_int, NoMax_int );
LOAD_PARA( load_mode, "Soliton_CoreRadiusAll", &Soliton_CoreRadiusAll, NoDef_double, NoMin_double, NoMax_double );
LOAD_PARA( load_mode, "Soliton_EmptyRegion", &Soliton_EmptyRegion, 0.0, NoMin_double, NoMax_double );
LOAD_PARA( load_mode, "Soliton_InitMode", &Soliton_InitMode, 1, 1, 2 );
LOAD_PARA( load_mode, "Soliton_DensProf_Filename", Soliton_DensProf_Filename, NoDef_str, Useless_str, Useless_str );

} // FUNCITON : LoadInputTestProb
Expand Down Expand Up @@ -171,13 +173,21 @@ void SetParameter()
if ( Soliton_CoreRadiusAll == NoDef_double )
Aux_Error( ERROR_INFO, "Runtime parameter \"Soliton_CoreRadiusAll\" is not set !!\n" );

if ( !OPT__UNIT && Soliton_InitMode == 2 )
Aux_Error( ERROR_INFO, "OPT__UNIT must be enabled for Soliton_InitMode == 2 !!\n" );

// (2) set the problem-specific derived parameters
// (2-1) allocate memory
Soliton_CoreRadius = new double [Soliton_N];
Soliton_Center = new double [Soliton_N][3];
Soliton_ScaleL = new double [Soliton_N];
Soliton_ScaleD = new double [Soliton_N];
if ( Soliton_InitMode == 1 )
{
Soliton_ScaleL = new double [Soliton_N];
Soliton_ScaleD = new double [Soliton_N];
}
else if ( Soliton_InitMode == 2 ) {}
else
Aux_Error( ERROR_INFO, "unsupported Soliton_InitMode (%d) !!\n", Soliton_InitMode );

// (2-2) soliton core radii
if ( Soliton_CoreRadiusAll > 0.0 )
Expand Down Expand Up @@ -231,41 +241,47 @@ void SetParameter()
// (3) load the reference soliton density profile and evaluate the scale factors
if ( OPT__INIT != INIT_BY_RESTART )
{
// load the reference profile
const bool RowMajor_No = false; // load data into the column-major order
const bool AllocMem_Yes = true; // allocate memory for Soliton_DensProf
const int NCol = 2; // total number of columns to load
const int Col[NCol] = {0, 1}; // target columns: (radius, density)
if ( Soliton_InitMode == 1 )
{
// load the reference profile
const bool RowMajor_No = false; // load data into the column-major order
const bool AllocMem_Yes = true; // allocate memory for Soliton_DensProf
const int NCol = 2; // total number of columns to load
const int Col[NCol] = {0, 1}; // target columns: (radius, density)

Soliton_DensProf_NBin = Aux_LoadTable( Soliton_DensProf, Soliton_DensProf_Filename, NCol, Col, RowMajor_No, AllocMem_Yes );
Soliton_DensProf_NBin = Aux_LoadTable( Soliton_DensProf, Soliton_DensProf_Filename, NCol, Col, RowMajor_No, AllocMem_Yes );


// get the core radius of the reference profile
const double *RadiusRef = Soliton_DensProf + 0*Soliton_DensProf_NBin;
const double *DensRef = Soliton_DensProf + 1*Soliton_DensProf_NBin;
const double DensCore = 0.5*DensRef[0]; // define core radius as the half-density radius
// get the core radius of the reference profile
const double *RadiusRef = Soliton_DensProf + 0*Soliton_DensProf_NBin;
const double *DensRef = Soliton_DensProf + 1*Soliton_DensProf_NBin;
const double DensCore = 0.5*DensRef[0]; // define core radius as the half-density radius

double CoreRadiusRef = NULL_REAL;
double CoreRadiusRef = NULL_REAL;

for (int b=1; b<Soliton_DensProf_NBin-1; b++)
{
if ( DensRef[b] >= DensCore && DensRef[b+1] <= DensCore )
for (int b=1; b<Soliton_DensProf_NBin-1; b++)
{
CoreRadiusRef = 0.5*( RadiusRef[b] + RadiusRef[b+1] );
break;
if ( DensRef[b] >= DensCore && DensRef[b+1] <= DensCore )
{
CoreRadiusRef = RadiusRef[b] + (DensCore - DensRef[b])*(RadiusRef[b+1]-RadiusRef[b])/(DensRef[b+1]-DensRef[b]);
break;
}
}
}

if ( CoreRadiusRef == NULL_REAL )
Aux_Error( ERROR_INFO, "cannot determine the reference core radius !!\n" );
if ( CoreRadiusRef == NULL_REAL )
Aux_Error( ERROR_INFO, "cannot determine the reference core radius !!\n" );


// evaluate the scale factors of each soliton
for (int t=0; t<Soliton_N; t++)
{
Soliton_ScaleL[t] = Soliton_CoreRadius[t] / CoreRadiusRef;
Soliton_ScaleD[t] = 1.0 / ( 4.0*M_PI*NEWTON_G*SQR(ELBDM_ETA)*POW4(Soliton_ScaleL[t]) );
}
// evaluate the scale factors of each soliton
for (int t=0; t<Soliton_N; t++)
{
Soliton_ScaleL[t] = Soliton_CoreRadius[t] / CoreRadiusRef;
Soliton_ScaleD[t] = 1.0 / ( 4.0*M_PI*NEWTON_G*SQR(ELBDM_ETA)*POW4(Soliton_ScaleL[t]) );
}
} // if ( Soliton_InitMode == 1 )
else if ( Soliton_InitMode == 2 ) {}
else
Aux_Error( ERROR_INFO, "unsupported Soliton_InitMode (%d) !!\n", Soliton_InitMode );
} // if ( OPT__INIT != INIT_BY_RESTART )


Expand Down Expand Up @@ -293,16 +309,34 @@ void SetParameter()
Aux_Message( stdout, " total number of solitons = %d\n", Soliton_N );
Aux_Message( stdout, " random seed for setting the center coord. = %d\n", Soliton_RSeed );
Aux_Message( stdout, " size of the soliton-free zone = %13.7e\n", Soliton_EmptyRegion );
Aux_Message( stdout, " density profile filename = %s\n", Soliton_DensProf_Filename );
Aux_Message( stdout, " number of bins of the density profile = %d\n", Soliton_DensProf_NBin );
if (Soliton_InitMode==1)
{
Aux_Message( stdout, " density profile filename = %s\n", Soliton_DensProf_Filename );
Aux_Message( stdout, " number of bins of the density profile = %d\n", Soliton_DensProf_NBin );
}
Aux_Message( stdout, "\n" );
Aux_Message( stdout, " Soliton info:\n" );
Aux_Message( stdout, " %7s %13s %13s %13s %13s %13s %13s\n",
"ID", "CoreRadius", "ScaleL", "ScaleD", "Center_X", "Center_Y", "Center_Z" );
for (int t=0; t<Soliton_N; t++)
Aux_Message( stdout, " %7d %13.6e %13.6e %13.6e %13.6e %13.6e %13.6e\n",
t, Soliton_CoreRadius[t], Soliton_ScaleL[t], Soliton_ScaleD[t],
Soliton_Center[t][0], Soliton_Center[t][1], Soliton_Center[t][2] );
if ( Soliton_InitMode == 1 )
{
Aux_Message( stdout, " (InitMode = 1 --> use the table of the density profile)\n" );
Aux_Message( stdout, " %7s %13s %13s %13s %13s %13s %13s\n",
"ID", "CoreRadius", "ScaleL", "ScaleD", "Center_X", "Center_Y", "Center_Z" );
for (int t=0; t<Soliton_N; t++)
Aux_Message( stdout, " %7d %13.6e %13.6e %13.6e %13.6e %13.6e %13.6e\n",
t, Soliton_CoreRadius[t], Soliton_ScaleL[t], Soliton_ScaleD[t],
Soliton_Center[t][0], Soliton_Center[t][1], Soliton_Center[t][2] );
} // if ( Soliton_InitMode == 1 )
else if ( Soliton_InitMode == 2 )
{
Aux_Message( stdout, " (InitMode = 2 --> use the analytical function of the density profile)\n" );
Aux_Message( stdout, " %7s %13s %13s %13s %13s\n", "ID", "CoreRadius", "Center_X", "Center_Y", "Center_Z" );
for (int t=0; t<Soliton_N; t++)
Aux_Message( stdout, " %7d %13.6e %13.6e %13.6e %13.6e\n",
t, Soliton_CoreRadius[t],
Soliton_Center[t][0], Soliton_Center[t][1], Soliton_Center[t][2] );
} // if ( Soliton_InitMode == 2 )
else
Aux_Error( ERROR_INFO, "unsupported Soliton_InitMode (%d) !!\n", Soliton_InitMode );
Aux_Message( stdout, "======================================================================================\n" );
}

Expand Down Expand Up @@ -333,43 +367,61 @@ void SetParameter()
void SetGridIC( real fluid[], const double x, const double y, const double z, const double Time,
const int lv, double AuxArray[] )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@boxianliu The format of this comment looks a bit strange and too long. You may consider:

  • Using the Add a suggestion button to highlight the differences.
  • Previewing your comment with the Preview button before submitting.

{
double r_tar, r_ref, dens_ref, dens;

const double *Table_Radius = Soliton_DensProf + 0*Soliton_DensProf_NBin; // radius
const double *Table_Density = Soliton_DensProf + 1*Soliton_DensProf_NBin; // density

double r_tar, r_ref, dens_ref;


// initialize density as zero since there may be multiple solitons
// initialize density as zero since there may be multiple solitons
fluid[DENS] = 0.0;

// loop over all solitons to get the total density
for (int t=0; t<Soliton_N; t++)
if ( Soliton_InitMode == 1 )
{
r_tar = sqrt( SQR(x-Soliton_Center[t][0]) + SQR(y-Soliton_Center[t][1]) + SQR(z-Soliton_Center[t][2]) );
const double *Table_Radius = Soliton_DensProf + 0*Soliton_DensProf_NBin; // radius
const double *Table_Density = Soliton_DensProf + 1*Soliton_DensProf_NBin; // density

// rescale radius (target radius --> reference radius)
r_ref = r_tar / Soliton_ScaleL[t];
// loop over all solitons to get the total density
for (int t=0; t<Soliton_N; t++)
{
r_tar = sqrt( SQR(x-Soliton_Center[t][0]) + SQR(y-Soliton_Center[t][1]) + SQR(z-Soliton_Center[t][2]) );

// linear interpolation
dens_ref = Mis_InterpolateFromTable( Soliton_DensProf_NBin, Table_Radius, Table_Density, r_ref );
// rescale radius (target radius --> reference radius)
r_ref = r_tar / Soliton_ScaleL[t];

if ( dens_ref == NULL_REAL )
{
if ( r_ref < Table_Radius[0] )
dens_ref = Table_Density[0];
// linear interpolation
dens_ref = Mis_InterpolateFromTable( Soliton_DensProf_NBin, Table_Radius, Table_Density, r_ref );

else if ( r_ref >= Table_Radius[Soliton_DensProf_NBin-1] )
dens_ref = Table_Density[Soliton_DensProf_NBin-1];
if ( dens_ref == NULL_REAL )
{
if ( r_ref < Table_Radius[0] )
dens_ref = Table_Density[0];

else
Aux_Error( ERROR_INFO, "interpolation failed at radius %13.7e (min/max radius = %13.7e/%13.7e) !!\n",
r_ref, Table_Radius[0], Table_Radius[Soliton_DensProf_NBin-1] );
}
else if ( r_ref >= Table_Radius[Soliton_DensProf_NBin-1] )
dens_ref = Table_Density[Soliton_DensProf_NBin-1];

// rescale density (reference density --> target density) and add to the fluid array
fluid[DENS] += dens_ref*Soliton_ScaleD[t];
} // for (int t=0; t<Soliton_N; t++)
else
Aux_Error( ERROR_INFO, "interpolation failed at radius %13.7e (min/max radius = %13.7e/%13.7e) !!\n",
r_ref, Table_Radius[0], Table_Radius[Soliton_DensProf_NBin-1] );
}

// rescale density (reference density --> target density) and add to the fluid array
fluid[DENS] += dens_ref*Soliton_ScaleD[t];
} // for (int t=0; t<Soliton_N; t++)
} // if ( Soliton_InitMode == 1 )
else if ( Soliton_InitMode == 2 )
{
const double m22 = ELBDM_MASS*UNIT_M/(Const_eV/SQR(Const_c))/1.0e-22;

// loop over all solitons to get the total density
for (int t=0; t<Soliton_N; t++)
{
r_tar = sqrt( SQR(x-Soliton_Center[t][0]) + SQR(y-Soliton_Center[t][1]) + SQR(z-Soliton_Center[t][2]) );

const double rc_kpc = Soliton_CoreRadius[t]*UNIT_L/Const_kpc;
dens = 1.945/SQR(m22*10)/POW4(rc_kpc) / POW(1 + (POW(2.0,1.0/8.0)-1.0)*SQR(r_tar/Soliton_CoreRadius[t]), 8); // in unit of Msun/pc^3
dens = dens* Const_Msun/CUBE(Const_pc) / UNIT_D ; // code unit
fluid[DENS] += dens;
} // for (int t=0; t<Soliton_N; t++)
} // if ( Soliton_InitMode == 2 )
else
Aux_Error( ERROR_INFO, "unsupported Soliton_InitMode (%d) !!\n", Soliton_InitMode );


# if ( ELBDM_SCHEME == ELBDM_HYBRID )
Expand Down Expand Up @@ -411,7 +463,7 @@ void End_Soliton()

//-------------------------------------------------------------------------------------------------------
// Function : BC
// Description : Set the extenral boundary condition
// Description : Set the external boundary condition
//
// Note : 1. Linked to the function pointer "BC_User_Ptr"
//
Expand Down