Advertisement
Guest User

Biot Savart in Julia

a guest
Feb 24th, 2025
337
0
71 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Julia 4.95 KB | Science | 0 0
  1. using LinearAlgebra
  2. using Interpolations
  3. using StatsBase
  4. using NPZ
  5.  
  6. function createXZGrid(bbox, meshsize)
  7.     x1, z1, x2, z2 = bbox
  8.     xgrid, zgrid = meshgrid(range(x1, x2, length=meshsize), range(z1, z2, length=meshsize))
  9.  
  10.     zeroes = zeros(size(xgrid))
  11.  
  12.     # create the individual position vectors
  13.     vecs = cat(reshape(xgrid, :, 1), reshape(zeroes, :, 1), reshape(zgrid, :, 1), dims=2)
  14.     vecs = reshape(vecs, size(xgrid)..., 3)
  15.     return xgrid, zgrid, vecs
  16. end
  17.  
  18. function meshgrid(x, y)
  19.     X = [i for j in y, i in x]
  20.     Y = [j for j in y, i in x]
  21.     return X, Y
  22. end
  23.  
  24. function wireIntegrate(meshgrid::Array{Float64,3}, l::Matrix{Float64})
  25.  
  26.  
  27.     dl = diff(l, dims=1)
  28.  
  29.     vectorIntegral = zeros(Float32, size(meshgrid))
  30.     integrand = zeros(Float32, size(meshgrid))
  31.  
  32.     for (lv, dlv) in zip(eachrow(l[1:end-1,:]), eachrow(dl))
  33.         rp = meshgrid .- reshape(lv, 1, 1, :)
  34.  
  35.         norms = norm.(eachslice(rp, dims=(1,2)))
  36.         norms = reshape(norms, size(rp)[1:end-1])
  37.  
  38.         for i=1:size(meshgrid)[1], j=1:size(meshgrid)[2]
  39.             integrand[i,j,:] = cross(dlv, rp[i,j,:]) / norms[i,j]^3
  40.         end
  41.  
  42.         integrand = replace(integrand, NaN => 0.0)
  43.  
  44.         vectorIntegral += integrand
  45.     end
  46.  
  47.     return vectorIntegral
  48. end
  49.  
  50. function cutoffPercentile(magnitudes::Matrix{Float64}, cutoff::Real)
  51.     mags = copy(magnitudes)
  52.  
  53.     q = quantile(vec(mags), cutoff / 100) # cutoff must be between 0 and 1.
  54.  
  55.     mags[mags .> q] .= q
  56.  
  57.     return mags
  58. end
  59.  
  60. function createCanvasViaRotation(numCells::Int, newShape::Int, bField::Array{Float64, 3})
  61.     # We create a 3D canvas of size newShape x newShape x newShape by rotating the 2D canvas x-z through 360 degrees and interpolate the values that don't fall on the grid.
  62.    
  63.     #  Create a 3D canvas of size newShape x newShape x newShape
  64.     cellCanvas   = zeros(Float64, newShape, newShape, newShape, 3)
  65.  
  66.     for ii in 1:numCells
  67.         for jj in 1:numCells
  68.             for kk in 1:numCells
  69.                 d = sqrt((ii - 1)^2 + (jj - 1)^2) # Adjust for 1-based indexing
  70.                 if Int(floor(d)) >= numCells
  71.                     break
  72.                 end
  73.                 if d == floor(d)
  74.                     # The bField is a vertical slice through the 3D field.  The ii,jj
  75.                     # indices are the x and y indices of the 2D canvas.  The kk index
  76.                     # is the z index of the vertical slice of the 3D field.
  77.                     cellCanvas[ii, jj, kk,:] = bField[kk, Int(floor(d)) + 1, :] # Adjust for 1-based indexing
  78.                 else
  79.                     xp = [jj - 1, jj] # Adjust for 1-based indexing
  80.                     if d < size(bField, 2) - 1
  81.                         yps0 = [bField[kk, Int(floor(d)) + 1:Int(floor(d)) + 2, i] for i in 1:3] # Adjust for 1-based indexing
  82.                    
  83.                         interpVector  = [LinearInterpolation([floor(d), floor(d) + 1], vs) for vs in yps0]
  84.                         cellCanvas[ii, jj, kk,:] = map.(interpVector, repeat([d], 3))
  85.                     end
  86.                 end
  87.             end
  88.         end
  89.     end
  90.  
  91.     return cellCanvas
  92. end
  93.  
  94. meshsize = 800  # The size of the mesh grid
  95. I = 1 # 1 amp of current flowing through coil
  96. mu0 = 4 *pi*10^(-7)  # magnetic permeability constant
  97. radius = 1  # radius of coil in meters
  98. # bounding box of visual area in meters
  99. bbox = (0,0, 10, 10)  # bounding box of visual area in meters
  100. xgrid, zgrid, vecs = createXZGrid(bbox, meshsize)
  101. println(size(vecs))
  102.  
  103. rIdx = Int(meshsize/(bbox[3]-bbox[1]))
  104.  
  105. angnum = 360 # The number of evenly spaced angle values around a circumference of length 2*pi*R or part thereof
  106. radius = 1.0 # Example radius
  107.  
  108. stop_value = pi/2
  109. step_size = stop_value / angnum
  110.  
  111. angles = 0:step_size:(stop_value - step_size) # Calculate step size and create range
  112.  
  113. coss = cos.(angles)
  114. sins = sin.(angles)
  115. zz = zeros(size(angles))
  116.  
  117. l = hcat(coss, sins, zz) * radius
  118.  
  119. println(size(l))
  120.  
  121.  
  122.  
  123. @time vectorIntegral = wireIntegrate(vecs, l)
  124.  
  125. println("vectorIntegral = ", size(vectorIntegral))
  126.  
  127. doubleShape = Tuple(2 * s for s in size(vectorIntegral)[1:end-1])
  128. doubleShape = (doubleShape..., size(vectorIntegral)[end])
  129.  
  130.  
  131. cellsCanvas = zeros(Float64, doubleShape)
  132. println(size(cellsCanvas))
  133.  
  134. cellsCanvas[meshsize+1:2*meshsize, meshsize+1:2*meshsize,:] += vectorIntegral
  135. cellsCanvas[meshsize:-1:1, meshsize+1:2*meshsize,:] += vectorIntegral
  136. cellsCanvas[meshsize:-1:1, meshsize:-1:1,:] += vectorIntegral
  137. cellsCanvas[meshsize+1:2*meshsize, meshsize:-1:1,:] += vectorIntegral
  138.  
  139.  
  140.  
  141.  
  142.  
  143. # Take the norm of the vector field
  144. magnitudes = dropdims(mapslices(norm, cellsCanvas, dims=3); dims=3)
  145. cutoff = 95.0
  146.  
  147. result = cutoffPercentile(magnitudes, cutoff)
  148.  
  149.  
  150.  
  151. # Example usage:
  152.  
  153. bField = vectorIntegral # rand(numCells, numCells, 3)
  154. newShape = size(bField,1)
  155. numCells = newShape
  156. @time result = createCanvasViaRotation(numCells, newShape, bField)
  157.  
  158. println(size(result))
  159.  
  160. npzwrite("cellCanvas-jl-$numCells.npy", result)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement