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
3 changes: 2 additions & 1 deletion .github/scripts/preflight.sh
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ run_probe() {
# reasons -- no input file, no restart data, a missing module -- and none of them
# say anything about the node. Treating any non-zero status as a fault here would
# exclude every healthy node in the cluster. 132 is 128+4, a child killed by
# SIGILL; bash reports signals that way, and mpirun/srun forward it.
# SIGILL; bash reports signals that way, and mpirun/srun forward it. Some
# launchers do not pass 132 on, so the "Illegal instruction" text is matched too.
isa_probe() {
isa_bin=$(newest_for_device pre_process)
[ -n "$isa_bin" ] || return 0
Expand Down
2 changes: 1 addition & 1 deletion .github/scripts/submit-slurm-job.sh
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ while :; do
# 34183404644 exactly this way. sacct knows the node whether or not the
# .out exists, so identification no longer depends on the marker.
if [ -z "$faulted_node" ]; then
faulted_node=$(sacct -j "$job_id" -X -n -o NodeList 2>/dev/null | head -n1 | tr -d ' ')
faulted_node=$(sacct -j "$job_id" -X -n -o NodeList 2>/dev/null | head -n1 | tr -d ' ' || true)
case "$faulted_node" in ""|None*|*[,\[]*) faulted_node="" ;; esac
fi
if [ "$node_attempt" -lt "$MFC_MAX_NODE_RESUBMITS" ]; then
Expand Down
5 changes: 3 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ if (CMAKE_Fortran_COMPILER_ID STREQUAL "Cray")
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/toolchain/cmake/cce")
endif()

if (CMAKE_Fortran_COMPILER_ID STREQUAL "LLVMFlang")
if (CMAKE_Fortran_COMPILER_ID STREQUAL "LLVMFlang" AND MFC_OpenMP)
# Otherwise the GPU targets are never up to date and every build redoes the
# whole-image device LTO link -- ~20 minutes on Frontier, paid on each mfc.sh
# invocation even when nothing changed. CMake asks the linker for its
Expand All @@ -133,7 +133,8 @@ if (CMAKE_Fortran_COMPILER_ID STREQUAL "LLVMFlang")
# Directory scope, not a target property: LINK_DEPENDS_USE_LINKER exists only as
# a variable, and set_target_properties would silently create a custom property
# that does nothing. Setting it inside MFC_SETUP_TARGET would be function-scoped
# and equally silent.
# and equally silent. MFC_OpenMP is the amdflang offload build; CPU builds keep
# the linker's dependency tracking.
set(CMAKE_LINK_DEPENDS_USE_LINKER OFF)
endif()

Expand Down
2 changes: 1 addition & 1 deletion docs/documentation/case.md
Original file line number Diff line number Diff line change
Expand Up @@ -1405,7 +1405,7 @@ The entries labeled "Characteristic." are characteristic boundary conditions bas

This boundary condition can be used for subsonic inflow (`bc_[x,y,z]%[beg,end]` = -7) and subsonic outflow (`bc_[x,y,z]%[beg,end]` = -8) characteristic boundary conditions. These are based on \cite Pirozzoli13. This enables to provide inflow and outflow conditions outside the computational domain.

`bc_[x,y,z]%%vel_in_ramp` starts the inflow smoothly instead of holding it constant, which is what a jet or a tunnel accelerating from rest requires: the start-up is the event of interest, not a transient to be discarded. The inflow velocity is scaled by \f$f(t) = f_0 + (1 - f_0)\left[1 + \tanh\left(6 (t - t_0)/\tau - 3\right)\right]/2\f$, with \f$\tau\f$ = `vel_in_ramp`, \f$t_0\f$ = `vel_in_t0` and \f$f_0\f$ = `vel_in_frac0`, so it leaves \f$f_0\f$ of the final velocity at \f$t_0\f$ and is within half a percent of it at \f$t_0 + \tau\f$. A boundary with `vel_in_ramp = 0` is held constant, as before. The ramp acts on a GRCBC inflow (`grcbc_in`) or on the ghost-cell velocity of a Dirichlet (-17) boundary or boundary patch normal to that direction, such as a nozzle set into a wall.
`bc_[x,y,z]%%vel_in_ramp` starts the inflow smoothly instead of holding it constant, which is what a jet or a tunnel accelerating from rest requires: the start-up is the event of interest, not a transient to be discarded. The inflow velocity is scaled by \f$f(t) = f_0 + (1 - f_0)\left[1 + \tanh\left(6 (t - t_0)/\tau - 3\right)\right]/2\f$, with \f$\tau\f$ = `vel_in_ramp`, \f$t_0\f$ = `vel_in_t0` and \f$f_0\f$ = `vel_in_frac0`, so it leaves \f$\approx f_0\f$ of the final velocity at \f$t_0\f$ and is within half a percent of it at \f$t_0 + \tau\f$. A boundary with `vel_in_ramp = 0` is held constant, as before. The ramp acts on a GRCBC inflow (`grcbc_in`) or on the ghost-cell velocity of a Dirichlet (-17) boundary or boundary patch normal to that direction, such as a nozzle set into a wall.

### Patch types {#patch-types}

Expand Down
80 changes: 40 additions & 40 deletions docs/index.html

Large diffs are not rendered by default.

5 changes: 1 addition & 4 deletions examples/2D_ibm_thin_plate_force/case.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,11 @@
t_end = t0 + t_p + 4.0
x0, x1, y0, y1 = -2.0, 5.0, -2.5, 2.5

# L4 added after the first three failed to converge: refining 2 -> 4 -> 8 cells across the thickness moved
# NCELL=16 added after 2, 4 and 8 failed to converge: refining 2 -> 4 -> 8 cells across the thickness moved
# the peak lift 6.41 -> 4.68 -> 4.46 against a reference of 7.00, i.e. away from it and then stalling.
# Two under-resolved answers landing near each other is not convergence. If a few cells across a thin
# body is simply too few for the immersed boundary, 16 should move back toward the reference; if the
# finite thickness is genuinely the difference, it should stay near 4.5.
LEVELS = {"L1": 0.0125, "L2": 0.00625, "L3": 0.003125, "L4": 0.0015625}


NCELL = int(os.environ.get("NCELL", 4))
dx = THICK / NCELL
m, n = int((x1 - x0) / dx) - 1, int((y1 - y0) / dx) - 1
Expand Down
7 changes: 5 additions & 2 deletions examples/3D_ibm_neighborhood_radius/case.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,10 @@
if os.environ.get("SUMMARY"):
bound = 0.5 * math.sqrt(c**2 + SPAN**2 + THICK**2)
print(f"plate half-extent (s_get_ib_bound, geometry 9): {bound:.4f}")
print(f"rank extents at 64 ranks (16 x 2 x 2): x {(x1 - x0) / 16:.3f}, " f"y {(y1 - y0) / 2:.3f}, z {(z1 - z0) / 2:.3f}")
print(f"hops needed across the thinnest rank: ceil(1.1 * {bound:.4f} / {(x1 - x0) / 16:.3f}) = " f"{max(1, math.ceil(1.1 * bound / ((x1 - x0) / 16)))}")
# Ranks per direction, as MFC's topology search picks them for 400 x 50 x 50 at 64 ranks; set TOPOLOGY otherwise.
topo = [int(t) for t in os.environ.get("TOPOLOGY", "16,2,2").split(",")]
ext = [(hi - lo) / t for (lo, hi), t in zip(((x0, x1), (y0, y1), (z0, z1)), topo)]
print(f"rank extents at {topo[0] * topo[1] * topo[2]} ranks ({' x '.join(map(str, topo))}): x {ext[0]:.3f}, y {ext[1]:.3f}, z {ext[2]:.3f}")
print(f"hops needed across the thinnest rank: ceil(1.1 * {bound:.4f} / {min(ext):.3f}) = {max(1, math.ceil(1.1 * bound / min(ext)))}")
else:
print(json.dumps(case, indent=4))
4 changes: 2 additions & 2 deletions src/common/m_derived_types.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ module m_derived_types
real(wp), dimension(num_fluids_max) :: alpha_rho_in, alpha_in
logical :: grcbc_in, grcbc_out, grcbc_vel_out
!> Smooth start-up of a GRCBC inflow: the inflow velocity is scaled by f(t) = vel_in_frac0 + (1 - vel_in_frac0) (1 + tanh(6
!! (t - t0)/tau - 3))/2, so it leaves vel_in_frac0 of its final value at t0 and reaches it after vel_in_ramp. Inactive when
!! the ramp duration is zero.
!! (t - t0)/tau - 3))/2, so f(t0) ~ vel_in_frac0 and f(t0 + tau) ~ 1 (within 0.25%). Inactive when the ramp duration is
!! zero.
real(wp) :: vel_in_ramp, vel_in_t0, vel_in_frac0
logical :: isothermal_in, isothermal_out
real(wp) :: Twall_in, Twall_out
Expand Down
10 changes: 5 additions & 5 deletions src/simulation/m_start_up.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -650,12 +650,12 @@ contains
end if

! Advance time after RK so source terms see current-step time. With a fixed dt, use the same t_step*dt a restart
! starts from (p_main): a running sum drifts from it (1290 ulps by step 27000), so a restarted run would see the
! prescribed IB kinematics, inflow ramps and forcing at slightly different times than the run it continues
! starts from (p_main): a running sum drifts from it, so a restarted run would see the prescribed IB kinematics,
! inflow ramps and forcing at slightly different times than the run it continues
if (cfl_dt) then
mytime = mytime + dt
else
mytime = (t_step + 1)*dt
mytime = real(t_step + 1, wp)*dt
end if

if (relax) call s_infinite_relaxation_k(q_cons_ts(1)%vf)
Expand Down Expand Up @@ -704,7 +704,7 @@ contains
open (1, file='time_data.dat', position='append', status='old')
else
open (1, file='time_data.dat', status='new')
! time_final is the fastest single RK stage (one RHS evaluation), not a whole step; see s_tvd_rk
! time_final: max over ranks of each rank's fastest RK stage (one RHS evaluation), not a whole step; see s_tvd_rk
write (1, '(A10, A15, A15)') "Ranks", "s/rhs", "ns/gp/eq/rhs"
end if

Expand All @@ -717,7 +717,7 @@ contains
open (1, file='io_time_data.dat', position='append', status='old')
else
open (1, file='io_time_data.dat', status='new')
! io_time_final is the mean time of one s_save_data call
! io_time_final is the max over ranks of each rank's mean s_save_data time
write (1, '(A10, A15)') "Ranks", "s/save"
end if

Expand Down
4 changes: 2 additions & 2 deletions src/simulation/m_time_steppers.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -876,8 +876,8 @@ contains
if (time_stepper == time_stepper_rk3 .and. s == 2) t_stage = mytime + 0.5_wp*dt
else
! The same t_step*dt form a restart evaluates the kinematics at, so a restart sees bitwise the same body
t_stage = (t_step + 1)*dt
if (time_stepper == time_stepper_rk3 .and. s == 2) t_stage = (t_step + 0.5_wp)*dt
t_stage = real(t_step + 1, wp)*dt
if (time_stepper == time_stepper_rk3 .and. s == 2) t_stage = (real(t_step, wp) + 0.5_wp)*dt
end if

$:GPU_PARALLEL_LOOP(private='[i, gbl_id]', copyin='[s, t_stage]')
Expand Down
10 changes: 5 additions & 5 deletions toolchain/mfc/case_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -1073,7 +1073,7 @@ def _eos_coefficient_args(self, i, family):
args = []
for suffix in family.coefficients_args:
value = self.get(f"fluid_pp({i})%{family.prefix}_{suffix}")
args.append((value or 0.0) if suffix in optional else value)
args.append(0.0 if value is None and suffix in optional else value)
return args

def _check_initial_states_inside_eos(self, num_fluids):
Expand Down Expand Up @@ -1960,10 +1960,10 @@ def check_grcbc(self):
# dir_idx, which is (2,1,3) for a y inflow and (3,1,2) for z -- so requiring only
# component 1 would leave the normal velocity of a y or z inflow unchecked.
num_dims = 3 if (self.get("p", 0) or 0) > 0 else (2 if (self.get("n", 0) or 0) > 0 else 1)
missing = [n for n in (f"bc_{dir}%pres_in",) if self.get(n) is None]
missing += [f"bc_{dir}%vel_in({d})" for d in range(1, num_dims + 1) if self.get(f"bc_{dir}%vel_in({d})") is None]
missing += [f"bc_{dir}%alpha_rho_in({i})" for i in range(1, num_fluids + 1) if self.get(f"bc_{dir}%alpha_rho_in({i})") is None]
missing += [f"bc_{dir}%alpha_in({i})" for i in range(1, num_fluids + 1) if self.get(f"bc_{dir}%alpha_in({i})") is None]
required = [f"bc_{dir}%pres_in"]
required += [f"bc_{dir}%vel_in({d})" for d in range(1, num_dims + 1)]
required += [f"bc_{dir}%{name}({i})" for name in ("alpha_rho_in", "alpha_in") for i in range(1, num_fluids + 1)]
missing = [name for name in required if self.get(name) is None]
self.prohibit(len(missing) > 0, f"Subsonic Inflow (grcbc_in) needs the full inflow state; missing {', '.join(missing)}")
if grcbc_out:
# Check if EITHER beg OR end is set to -8
Expand Down
16 changes: 13 additions & 3 deletions toolchain/mfc/test_thermochem.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,24 @@
FPE_TRAP: ["-ffpe-trap=invalid,zero,overflow"],
},
# CCE enables OpenACC by default; turn it off unless asked for, as cmake/MFCTargets.cmake does.
"Cray": {"base": ["-eZ"], None: ["-hnoacc"], "acc": ["-hacc"], "mp": ["-hnoacc", "-fopenmp"], FPE_TRAP: ["-Ktrap=divz,inv,ovf"]},
"Cray": {
"base": ["-eZ"],
None: ["-hnoacc"],
"acc": ["-hacc"],
"mp": ["-hnoacc", "-fopenmp"],
FPE_TRAP: ["-Ktrap=divz,inv,ovf"],
},
}


@functools.cache
def fortran_compiler():
"""The compiler MFC's build would use ($FC, else ftn or gfortran on PATH) and its family, or None."""
names = [os.environ["FC"]] if os.environ.get("FC") else ["ftn", "gfortran"]
return _probe_compiler(os.environ.get("FC") or None)


@functools.cache # keyed on $FC, so a changed $FC is probed afresh
def _probe_compiler(fc):
names = [fc] if fc else ["ftn", "gfortran"]
for name in names:
path = shutil.which(name)
if path is None:
Expand Down