PrincetonUniversity/athena

Problem with boundary functions in 1D hydro shock tube

c-white opened this issue · 2 comments

The following simple test segfaults:

python configure.py --prob=shock_tube --coord=cartesian -debug
make clean
make
cd bin
./athena -i ../inputs/hydro/athinput.sod

Using a debugger, it seems the problem is in BoundaryValues::ReceiveAndSetFluidBoundary(), line 423 of bvals.cpp, when dir is inner_x2. The function pointer is bad. This is due to the conditionals if (pmb->block_size.nx2 > 1) and if (pmb->block_size.nx3 > 1) (lines 124 and 186) of the BoundaryValues constructor being skipped in 1D problems, so the x2 and x3 boundary functions are never set.

Removing these conditionals does not solve the problem. Things first go wrong when bvals.cpp:423 is forced to actually call PeriodicInnerX2() rather than a dead pointer. If the j dimension is singleton, then js and je will be 0, and line 90 of periodic_fluid.cpp will write out of the array bounds (causing hard-to-diagnose errors where, for example, the Coordinates object's pmy_block pointer will be nulled).

Looking back at older versions of the code, the equivalent of bvals.cpp:423 used to be protected by an extra conditional. Perhaps this line should be changed to

{
  if ((dir == inner_x1 or dir == outer_x1)
      or ((dir == inner_x2 or dir == outer_x2) and pmb->block_size.nx2 > 1)
      or ((dir == inner_x3 or dir == outer_x3) and pmb->block_size.nx2 > 1))
    FluidBoundary_[dir](pmb,dst);
}

Sorry, this is my fault. The boundary routine is being largely modified during implementation of MeshBlocks and MPI. This had been already fixed in my version but I have not committed it yet. I will commit as soon as possible once I confirm MPI is working correctly.

After implementing the fix I suggested in my local copy, a new error shows up. This might be a sign of a separate bug, so I'll record it here.

python configure.py --prob shock_tube --coord cartesian -debug
make clean
make
cd bin
./athena -i ../inputs/hydro/athinput.sod

results in

### FATAL ERROR in function [ParameterInput::GetReal]
Parameter name 'problem_id' not found in block 'job'

Some debug results:

gdb athena
(gdb) b parameter_input.cpp:ParameterInput::GetString
(gdb) run -i ../inputs/hydro/athinput.sod
(gdb) c
(gdb) b InputBlock::GetPtrToLine
(gdb) c
(gdb) n
(gdb) p name.c_str()
$1 = 0x100204318 "problem_id"
(gdb) p name.length()
$2 = 10
(gdb) p pl->param_name.c_str()
$3 = 0x100200de8 "problem_id"
(gdb) p pl->param_name.length()
$4 = 4607182418800017408

It seems that when searching for a line with "problem_id" it finds the line, but the C++ std::string is corrupted with a bad length. Note that std::string::compare() will not return a match if this parameter is not the same, even if the underlying C character arrays are the same up to a terminating \0.