# Julia GPU FSI: Updating p0, v0, a0, t0 Each Step Without Non-isbits (Core.Box) Error

**URL:** https://discourse.julialang.org/t/julia-gpu-fsi-updating-p0-v0-a0-t0-each-step-without-non-isbits-core-box-error/132090
**Category:** General Usage
**Tags:** question
**Created:** [September 4, 2025, 7:05am UTC](https://discourse.julialang.org/t/julia-gpu-fsi-updating-p0-v0-a0-t0-each-step-without-non-isbits-core-box-error/132090 "2025-09-04T07:05:42Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![Mr.Fool](https://avatars.discourse-cdn.com/v4/letter/m/f14d63/32.png) [@Mr.Fool](https://discourse.julialang.org/u/Mr.Fool)
#### Post date: [September 4, 2025, 7:05am UTC](https://discourse.julialang.org/t/julia-gpu-fsi-updating-p0-v0-a0-t0-each-step-without-non-isbits-core-box-error/132090/1 "2025-09-04T07:05:42Z")

</div>

using WaterLily  
using Plots; gr()  
using StaticArrays  
using BenchmarkTools  
using CSV, DataFrames  
using Printf  
using CUDA

function TwoCylWIV(Ur,mem=Array)

```
Re = 150; U = 1
p = 6; L = 2^p
nl = 12L; ml = 8L

# signed distance function to circle
radius = L/2
diameter = 2*radius

# fsi parameters
rho = 1.0 # density of fluid
mₐ = π*radius^2*rho # displacement mass
m = 2*mₐ # structural mass
fn = U/Ur/diameter # natural frequency Ur = U/(fn*D)
k = 4*π^2*m*fn^2 # spring constant

#first cylinder
centerFix = SA[2L,ml/2-1];
circleFix = AutoBody((x,t)->√sum(abs2, x .- centerFix) - radius)

#second cylinder
center = SA[6L,ml/2-1];
# initial condition FSI
p0=radius/3; v0=0; a0=0; t0=0
# motion function uses global var to adjust
posx(t) = p0 + (t-t0)*v0
# motion definition
map(x,t) = x - SA[0, posx(t)]
# make a body
circle = AutoBody((x,t)->√sum(abs2, x .- center) - radius,map)

@show circle
bodies = AutoBody[]
push!(bodies, circleFix)
push!(bodies, circle)
# combine into one body
bodyCir = circleFix+circle
# @show bodyCir
#bodyCir = Bodies(bodies, repeat([identity], length(bodies)-1))

# generate sim
sim = Simulation((nl,ml), (U,0), diameter; ν=U*diameter/Re, body=bodyCir, mem=CuArray)

# get start time
duration=160; step=0.1; t₀=round(sim_time(sim))
t_series = Float64[]
p_series = Float64[]
cl_series = Float64[]
cd_series = Float64[]

@gif for tᵢ in range(t₀,t₀+duration;step)
    # update until time tᵢ in the background
    t = sum(sim.flow.Δt[1:end-1])
    while t < tᵢ*sim.L/sim.U
        # measure body
        measure!(sim,t)
        # update flow
        mom_step!(sim.flow,sim.pois)

        # pressure force
        forcePre = -WaterLily.pressure_force(sim.flow, sim.body)
        forceVis = -WaterLily.viscous_force(sim.flow, sim.body)
        force = forcePre + forceVis

        # compute motion and acceleration 1DOF
        Δt = sim.flow.Δt[end]
        accel = (force[2]- k*p0)/m
        p0 += Δt*(v0+Δt*accel/2.)
        v0 += Δt*accel
        a0 = accel

        # update time, sets the pos/v0 correctly
        t0 = t; t += Δt

        push!(t_series, t0)
        push!(p_series, p0/diameter)
        push!(cd_series, force[1]./(0.5sim.L*sim.U^2))
        push!(cl_series, force[2]./(0.5sim.L*sim.U^2))
    end
    # print time step
    @inside sim.flow.σ[I] = WaterLily.curl(3,I,sim.flow.u)*sim.L/sim.U
    flood(sim.flow.σ; shift=(-0.5,-0.5),clims=(-5,5))
    body_plot!(sim); plot!(title="tU/L $tᵢ")

    # print time step
    println("tU/L=",round(tᵢ,digits=4),", Δt=",round(sim.flow.Δt[end],digits=3))

    println("tU/L=",round(tᵢ,digits=4),", Δt=",round(sim.flow.Δt[end],digits=3),", AyD=",round(p0 / diameter,digits=3))

end

# Primary y-axis: displacement vs time
p = plot(t_series, p_series,
label = "Displacement",
xlabel = "Time",
ylabel = "Displacement",
legend = :topleft,
lw = 2)

display(p)
filename = @sprintf("output/01wiv_plot_Ur%.1f.png", Ur) |> x -> replace(x, "." => "_")
filename = filename |> x -> replace(x, "_png" => ".png")
savefig(p, filename)

df = DataFrame(
time = t_series,
displacement = p_series,
lift = cl_series,
drag = cd_series)
filename = @sprintf("output/01wiv_data_Ur%.1f.csv", Ur) |> x -> replace(x, "." => "_")
filename = filename |> x -> replace(x, "_csv" => ".csv")
CSV.write(filename, df)

#return t_series, p_series, cl_series, cd_series

```

end

elapsed = @elapsed TwoCylWIV(2)  
println(“Elapsed time: $(elapsed) seconds”)

The above is my code. I need to update `p0`, `v0`, `a0`, and `t0` at every time step, and define the body’s motion based on these variables. However, when using GPU computation, these variables appear as `Core.Box` types rather than `isbits` types. How should I modify my code to enable GPU computation? I look forward to your response.
