How to I make a part float with this water system. (also need help understanding code)

So, I made a post earlier asking how I would make a part float on water terrain. most of the people said just make a water system and whilst going through my old games I found a water system that I clearly did not make, and I think I got it from an open-source dev forum post, but I couldn’t seem to find it.

I do want to make one thing clear: I suck at math; I have no idea how this works. I have spent the past few hours trying to get this to work, but with no prevail. I would like someone to explain to me how this works as well.

here is the code:

local Settings = self._settings
	local Direction = Settings.Direction
	for _,v in pairs(self._bones) do
		local WorldPos = v.WorldPosition
		print(WorldPos)
		
		if Direction == EmptyVector2 then
			-- Use Perlin Noise
			local Noise = self._noise[v]
			local NoiseX = Noise and self._noise[v].X
			local NoiseZ = Noise and self._noise[v].Z
			local NoiseModifier = 5 -- If you want more of a consistent direction, change this number to something bigger
			
			if not Noise then
				self._noise[v] = {}
				-- Uses perlin noise to generate smooth transitions between random directions in the waves
				NoiseX = math_noise(WorldPos.X/NoiseModifier,WorldPos.Z/NoiseModifier,1)
				NoiseZ = math_noise(WorldPos.X/NoiseModifier,WorldPos.Z/NoiseModifier,0)
				
				self._noise[v].X = NoiseX
				self._noise[v].Z = NoiseZ
			end
			
			Direction = Vector2.new(NoiseX,NoiseZ)
		else
			Direction = GetDirection(Settings,WorldPos)
		end
		
		v.Transform = newCFrame(Gerstner(WorldPos,Settings.WaveLength,Direction,Settings.Steepness,Settings.Gravity,self._time))
	end
	for _, V: Part in pairs(workspace.Floats:GetChildren()) do
		local WorldPos = V.Position
		V.CFrame = newCFrame(Gerstner(WorldPos,Settings.WaveLength,Direction,Settings.Steepness,Settings.Gravity,self._time))
-- this returns NAN
	end

here is the Gerstner function:

local function Gerstner(Position: Vector3,Wavelength: number,Direction: Vector2,Steepness: number,Gravity: number,Time: number)
	local k = (2 * math.pi) / Wavelength
	local a = Steepness/k
	local d = Direction.Unit
	local c = math.sqrt(Gravity / k)
	local f = k * d:Dot(Vector2.new(Position.X,Position.Z)) - c * Time
	local cosF = math.cos(f)

	--Displacement Vectors
	local dX = (d.X * (a * cosF))
	local dY = a * math.sin(f)
	local dZ = ( d.Y * (a * cosF))
	return Vector3.new(dX,dY,dZ)
end