Advertisement
Guest User

util_functions.py

a guest
Feb 26th, 2025
59
0
163 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.65 KB | None | 0 0
  1. import numpy as np
  2.  
  3. def createXYGrid(bbox, meshsize):
  4.     x1, y1, x2, y2 = bbox
  5.     xgrid, ygrid =np.meshgrid(np.linspace(x1, x2 ,meshsize), np.linspace(y1,y2,meshsize))
  6.    
  7.     zeroes = np.zeros(xgrid.shape)
  8.    
  9.     # create the individual position vectors
  10.     vecs = np.stack((xgrid.flatten(), ygrid.flatten(), zeroes.flatten()), axis=-1).reshape(xgrid.shape + (3,))
  11.     return xgrid, ygrid,vecs
  12.  
  13. def createXZGrid(bbox, meshsize):
  14.     x1, z1, x2, z2 = bbox
  15.     xgrid, zgrid =np.meshgrid(np.linspace(x1, x2 ,meshsize), np.linspace(z1,z2,meshsize))
  16.    
  17.     zeroes = np.zeros(xgrid.shape)
  18.    
  19.     # create the individual position vectors
  20.     vecs = np.stack((xgrid.flatten(), zeroes.flatten(), zgrid.flatten()), axis=-1).reshape(xgrid.shape + (3,))
  21.     return xgrid, zgrid, vecs
  22.  
  23. def createXYZGrid(bbox, meshsize):
  24.     x1, y1, z1, x2, y2, z2 = bbox
  25.     xgrid, ygrid, zgrid =np.meshgrid(np.linspace(x1, x2 ,meshsize), np.linspace(y1,y2,meshsize), np.linspace(z1,z2,meshsize))
  26.    
  27.    
  28.     # create the individual position vectors
  29.     vecs = np.stack((xgrid.flatten(), ygrid.flatten(), zgrid.flatten()), axis=-1).reshape(xgrid.shape + (3,))
  30.     return xgrid, ygrid, zgrid, vecs
  31.  
  32.  
  33. def wireIntegrate(meshgrid, l, closed=True):
  34.  
  35.     def process(meshgrid, vectorIntegral, l, dl):
  36.         for lv, dlv in zip(l, dl):
  37.        
  38.             rp = meshgrid - lv
  39.        
  40.            
  41.            
  42.             # We want to make all the vectors unit vectors to have a magnitude of 1 but numpy doesn't seem to like how I am trying to do it
  43.             # so I am duplicating the norm entries 3 times to make the matrices the same size.
  44.             #
  45.             # Because a nxn matrix is not broadcastable via a nxnx3 matrix make the smaller into a nxnx3 matrix by repeating
  46.             # it's entries 3 times
  47.  
  48.             # Note we use the ellipsis notation here (below) to make this code generic enough to handle 2D or 3D grids.
  49.             norms = np.repeat(np.linalg.norm(rp, axis=-1)[...,np.newaxis], 3, axis=-1)
  50.            
  51.             # Now compute the Biot Savart cross product term
  52.             integrand = np.nan_to_num(np.cross(dlv, rp) /norms**3)
  53.            
  54.             # Add the dl magnetic contribution to the sum of all vector dl contributions
  55.             vectorIntegral += integrand
  56.  
  57.    
  58.     # create an array of the vector dl from l
  59.    
  60.     if type(l) == np.ndarray:
  61.         dl = np.diff(l, n=1, axis=0)
  62.         if closed:
  63.             dl = np.append(dl, [l[0] - l[-1]], axis=0)
  64.         # The result of the integral summation goes to integrand_vecum as a 2D array of 3-vectors.
  65.         vectorIntegral = np.zeros_like(meshgrid, dtype=np.float32)    
  66.         # Now sum up the magnetic field contributions along all the wire lengths dl
  67.        
  68.         # The numpy way of doing this without looping but it tends to cause the kernel to die
  69.         #lvdlv = np.stack((l, dl), axis=1)
  70.    
  71.         #rp = meshgrid[:,:,np.newaxis] - lvdlv[:,0,:]
  72.         #norms = np.linalg.norm(rp, axis=-1)
  73.         #cross = I*np.nan_to_num(np.cross(lvdlv[:,1,:], rp) / norms[... , np.newaxis] ** 3)
  74.         #vectorIntegral = cross.sum(axis=2)
  75.    
  76.         process(meshgrid, vectorIntegral, l, dl)
  77.     elif type(l) == tuple or type(l) == list:
  78.        
  79.         vectorIntegral = np.zeros_like(meshgrid, dtype=np.float32)    
  80.         for l1 in l:
  81.             #print (l1.shape)
  82.             dl = np.diff(l1, n=1, axis=0)
  83.             if closed:
  84.                 dl = np.append(dl, [l1[0] - l1[-1]], axis=0)
  85.             process(meshgrid, vectorIntegral, l1, dl)
  86.     return vectorIntegral
  87.    
  88. def cutoffPercentile(magnitudes, cutoff):
  89.     mags = np.copy(magnitudes)
  90.     # Now this is the only tricky bit.  Because the magnetic values close or in the wire tend to blow up I am chopping those
  91.     # values out and setting them to a maximum value.  This is because B = μ0 I / 2R causes a pole right on top of the wire.  If I don't do
  92.     # this then the visualisation is swamped by the contrast by the extreme high values and the linear scale I am using to match values to grayscale colours.
  93.    
  94.     q = (np.percentile(mags, cutoff))
  95.     mags[mags > q] = q
  96.     #print("percentile ===", cutoff, " value = ", q)
  97.     return mags
  98.    
  99. def toGreyScale(magnitudes):
  100.    
  101.     mags = magnitudes
  102.     # Find the minimum and maximum values in our magnitudes.  Of course the maximum value will be our cutoff value.
  103.     minv = np.amin(mags[~np.isnan(mags)])
  104.     maxv = np.amax(mags[~np.isnan(mags)])
  105.    
  106.     print(minv, maxv)
  107.     # Produce our array of greyscale values
  108.     #print ("arrint")
  109.     arrint = (((mags - minv)/(maxv - minv)*255).astype(int))
  110.     #print(arrint)
  111.     return arrint
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement