Garchupiter / Kraken-Optical-Simulator

Python - Exact ray tracing library
GNU General Public License v3.0
66 stars 15 forks source link

extra_data Add precise Fresnel data? #12

Open xacGOOD opened 5 months ago

xacGOOD commented 5 months ago

I'm trying to do a ray simulation of a Fresnel lens using KeakenOS, using the EXTRA_DATA feature, but the ray tracing results don't meet expectations. Here's the code:

`#!/usr/bin/env python3

-- coding: utf-8 --

"""Examp Extra Shape Radial Sine""" import math

import matplotlib import pkg_resources required = {'KrakenOS'} installed = {pkg.key for pkg in pkg_resources.working_set} missing = required - installed

if missing: print("No instalado") import sys sys.path.append("../..")

import KrakenOS as Kos import numpy as np import matplotlib.pyplot as plt matplotlib.use('TkAgg')

__

P_Obj = Kos.surf() P_Obj.Rc = 0.0 P_Obj.Thickness = 10 P_Obj.Glass = "AIR" P_Obj.Diameter = 30.0 P_Obj.Drawing = 0

__

data = [] # just use to export Kraken surf data def fresnel(x,y,data): dis = np.sqrt(x2+y2) z = np.interp(x=dis,xp=data[...,0],fp=data[...,1]) global data data += np.array((dis,z)).T.tolist() # append to data return z

fresnel_data= np.loadtxt('R1064_F1800_超大菲涅尔.txt',delimiter=',') # fresnel profile data L1a = Kos.surf() L1a.Rc = 0.0 L1a.Thickness = 5.0 L1a.Glass = "PMMA" L1a.Diameter = 2128 fresnel_ES = [fresnel,fresnel_data] L1a.ExtraData = fresnel_ES

__

L1c = Kos.surf() L1c.Rc = 0.0 L1c.Thickness = 1800 # 本片的厚度,也是后面一片的起点距离 L1c.Glass = "AIR" L1c.Diameter = 2128

__

P_Ima = Kos.surf() P_Ima.Rc = 0.0 P_Ima.Thickness = 0.0 P_Ima.Glass = "AIR" P_Ima.Diameter = 200.0 P_Ima.Name = "Image plane"

__

A = [P_Obj, L1a, L1c,P_Ima] Config_1 = Kos.Setup()

__

Lens = Kos.system(A, Config_1) Rays = Kos.raykeeper(Lens)

__

Wav = 0.45 # 波长??? y = fresnel_data[...,0] y_diff = np.diff(y)/2 y[:-1] += y_diff

index = np.arange(0,y.shape[0],100) y = y[index] print(y)

for i in y: p_s = [0.0,i,0.0] d_cos = [0.0,0.0,1.0] Lens.Trace(p_s,d_cos,0.55) Rays.push()

__

data = np.unique(np.array(data),axis=0) # unique and sort np.savetxt('rz.txt',data_,fmt='%.8f',delimiter=',') # save for verify

Kos.display3d(Lens, Rays, 2) Kos.display2d(Lens, Rays, 0)

`The 2D display results are as follows:

image

The original design of the lens is as follows: image

The results of using Lighttools simulation are as follows: image

How can I use KrakenOS to accurately ray trace Extra_data custom outlines?

xacGOOD commented 5 months ago

R1064_F1800_超大菲涅尔.zip fresnel profile data is here, type is rar

xacGOOD commented 5 months ago

image

By comparing the extracted ray and the exported profile, the refractive index of the material at the inverted incidence is 1.55, which does not conform to the design. The refractive index of the material at the exit is 1.4936, which is in line with the design value, so what went wrong?

xacGOOD commented 5 months ago

Here's the latest test code: `

!/usr/bin/env python3

-- coding: utf-8 --

"""Examp Extra Shape Radial Sine""" import math

import matplotlib import pkg_resources required = {'KrakenOS'} installed = {pkg.key for pkg in pkg_resources.working_set} missing = required - installed

if missing: print("No instalado") import sys sys.path.append("../..")

import KrakenOS as Kos import numpy as np import matplotlib.pyplot as plt matplotlib.use('TkAgg')

__

P_Obj = Kos.surf() P_Obj.Rc = 0.0 P_Obj.Thickness = 10.0 P_Obj.Glass = "AIR" P_Obj.Diameter = 2128.0 P_Obj.Drawing = 0

__

data = [] # just use to export Kraken surf data def fresnel(x,y,data): dis = np.sqrt(x2+y2) z = np.interp(x=dis,xp=data[...,0],fp=data[...,1]) global data data += np.array((dis,z)).T.tolist() # append to data return z

fresnel_data= np.loadtxt('R1064_F1800_超大菲涅尔.txt',delimiter=',') # fresnel profile data L1a = Kos.surf() L1a.Rc = 0.0 L1a.Thickness = 5.0 L1a.Glass = "PMMA" L1a.Diameter = 2128.0 fresnel_ES = [fresnel,fresnel_data] L1a.ExtraData = fresnel_ES L1a.Name = 'zone side'

__

L1c = Kos.surf() L1c.Rc = 0.0 L1c.Thickness = 1800 # 本片的厚度,也是后面一片的起点距离 L1c.Glass = "AIR" L1c.Diameter = 2128.0 L1c.Name = 'plan side'

__

P_Ima = Kos.surf() P_Ima.Rc = 0.0 P_Ima.Thickness = 0.0 P_Ima.Glass = "AIR" P_Ima.Diameter = 200.0 P_Ima.Name = "Image plane"

__

A = [P_Obj, L1a, L1c,P_Ima] Config_1 = Kos.Setup()

__

Lens = Kos.system(A, Config_1) Rays = Kos.raykeeper(Lens)

Wav = 0.55 # 波长??? y = np.arange(1063,1064,0.002) np.savetxt('y.txt',y,delimiter=',')

__

for i in y: p_s = [0.0,i,0.0] d_cos = [0.0,0.0,1.0] Lens.Trace(p_s,d_cos,0.55) Rays.push()

__

print(Rays.XYZ[100]) # here is verify ray , ri shoot in material is 1.550, out from material to air is 1.4936, why?

data = np.unique(np.array(data),axis=0) # unique and sort np.savetxt('rz.txt',data_,fmt='%.8f',delimiter=',') # save for verify

Kos.display3d(Lens, Rays, 2) Kos.display2d(Lens, Rays, 0)

`

How can I customize the refractive index of a material?

xacGOOD commented 5 months ago

Here's the latest test code: `

!/usr/bin/env python3

-- coding: utf-8 --

"""Examp Extra Shape Radial Sine""" import math

import matplotlib import pkg_resources required = {'KrakenOS'} installed = {pkg.key for pkg in pkg_resources.working_set} missing = required - installed

if missing: print("No instalado") import sys sys.path.append("../..")

import KrakenOS as Kos import numpy as np import matplotlib.pyplot as plt matplotlib.use('TkAgg')

__

P_Obj = Kos.surf() P_Obj.Rc = 0.0 P_Obj.Thickness = 10.0 P_Obj.Glass = "AIR" P_Obj.Diameter = 2128.0 P_Obj.Drawing = 0

__

data = [] # just use to export Kraken surf data def fresnel(x,y,data): dis = np.sqrt(x2+y2) z = np.interp(x=dis,xp=data[...,0],fp=data[...,1]) global data data += np.array((dis,z)).T.tolist() # append to data return z

fresnel_data= np.loadtxt('R1064_F1800_超大菲涅尔.txt',delimiter=',') # fresnel profile data L1a = Kos.surf() L1a.Rc = 0.0 L1a.Thickness = 5.0 L1a.Glass = "PMMA" L1a.Diameter = 2128.0 fresnel_ES = [fresnel,fresnel_data] L1a.ExtraData = fresnel_ES L1a.Name = 'zone side'

__

L1c = Kos.surf() L1c.Rc = 0.0 L1c.Thickness = 1800 # 本片的厚度,也是后面一片的起点距离 L1c.Glass = "AIR" L1c.Diameter = 2128.0 L1c.Name = 'plan side'

__

P_Ima = Kos.surf() P_Ima.Rc = 0.0 P_Ima.Thickness = 0.0 P_Ima.Glass = "AIR" P_Ima.Diameter = 200.0 P_Ima.Name = "Image plane"

__

A = [P_Obj, L1a, L1c,P_Ima] Config_1 = Kos.Setup()

__

Lens = Kos.system(A, Config_1) Rays = Kos.raykeeper(Lens)

Wav = 0.55 # 波长??? y = np.arange(1063,1064,0.002) np.savetxt('y.txt',y,delimiter=',')

__

for i in y: p_s = [0.0,i,0.0] d_cos = [0.0,0.0,1.0] Lens.Trace(p_s,d_cos,0.55) Rays.push()

__

print(Rays.XYZ[100]) # here is verify ray , ri shoot in material is 1.550, out from material to air is 1.4936, why?

data = np.unique(np.array(data),axis=0) # unique and sort np.savetxt('rz.txt',data_,fmt='%.8f',delimiter=',') # save for verify

Kos.display3d(Lens, Rays, 2) Kos.display2d(Lens, Rays, 0)

`

How can I customize the refractive index of a material?

Garchupiter commented 4 months ago

Hi,

I got a bit confused with the series of questions. I understand that in the end, your only question is how to add the refractive index. I am not familiar with the glass catalog you are using for MMA, but you can add the refractive index directly. For example, L1a.Glass = "PMMA”.

For some reason, I can't run your code because my Python kernel crashes.

Best regards,
Joel H. V.

El 2 jun 2024, a las 7:06 a.m., xacGOOD @.***> escribió:

Here's the latest test code: `

!/usr/bin/env python3

-- coding: utf-8 --

"""Examp Extra Shape Radial Sine""" import math

import matplotlib import pkg_resources required = {'KrakenOS'} installed = {pkg.key for pkg in pkg_resources.working_set} missing = required - installed

if missing: print("No instalado") import sys sys.path.append("../..")

import KrakenOS as Kos import numpy as np import matplotlib.pyplot as plt matplotlib.use('TkAgg')

__#

P_Obj = Kos.surf() P_Obj.Rc = 0.0 P_Obj.Thickness = 10.0 P_Obj.Glass = "AIR" P_Obj.Diameter = 2128.0 P_Obj.Drawing = 0

__#

data = [] # just use to export Kraken surf data def fresnel(x,y,data): dis = np.sqrt(x2+y2) z = np.interp(x=dis,xp=data[...,0],fp=data[...,1]) global data data += np.array((dis,z)).T.tolist() # append to data return z

fresnel_data= np.loadtxt('R1064_F1800_超大菲涅尔.txt',delimiter=',') # fresnel profile data L1a = Kos.surf() L1a.Rc = 0.0 L1a.Thickness = 5.0 L1a.Glass = "PMMA" L1a.Diameter = 2128.0 fresnel_ES = [fresnel,fresnel_data] L1a.ExtraData = fresnel_ES L1a.Name = 'zone side'

__#

L1c = Kos.surf() L1c.Rc = 0.0 L1c.Thickness = 1800 # 本片的厚度,也是后面一片的起点距离 L1c.Glass = "AIR" L1c.Diameter = 2128.0 L1c.Name = 'plan side'

__#

P_Ima = Kos.surf() P_Ima.Rc = 0.0 P_Ima.Thickness = 0.0 P_Ima.Glass = "AIR" P_Ima.Diameter = 200.0 P_Ima.Name = "Image plane"

__#

A = [P_Obj, L1a, L1c,P_Ima] Config_1 = Kos.Setup()

__#

Lens = Kos.system(A, Config_1) Rays = Kos.raykeeper(Lens)

Wav = 0.55 # 波长??? y = np.arange(1063,1064,0.002) np.savetxt('y.txt',y,delimiter=',')

__#

for i in y: p_s = [0.0,i,0.0] d_cos = [0.0,0.0,1.0] Lens.Trace(p_s,d_cos,0.55) Rays.push()

__#

print(Rays.XYZ[100]) # here is verify ray , ri shoot in material is 1.550, out from material to air is 1.4936, why?

data = np.unique(np.array(data),axis=0) # unique and sort np.savetxt('rz.txt',data_,fmt='%.8f',delimiter=',') # save for verify

Kos.display3d(Lens, Rays, 2) Kos.display2d(Lens, Rays, 0)

`

How can I customize the refractive index of a material?

— Reply to this email directly, view it on GitHub https://github.com/Garchupiter/Kraken-Optical-Simulator/issues/12#issuecomment-2143867705, or unsubscribe https://github.com/notifications/unsubscribe-auth/AED73RS4HQWG3LBUXOQRFSDZFMRHDAVCNFSM6AAAAABIVAWNG2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNBTHA3DONZQGU. You are receiving this because you are subscribed to this thread.

Dr. Joel Herrera Vázquez Observatorio Astronómico Nacional Instituto de Astronomía de la UNAM (Sede Ensenada B.C.)

Tel. (646) 1 74 45 80 Ext.426

xacGOOD commented 3 months ago

Hi, I got a bit confused with the series of questions. I understand that in the end, your only question is how to add the refractive index. I am not familiar with the glass catalog you are using for MMA, but you can add the refractive index directly. For example, L1a.Glass = "PMMA”. For some reason, I can't run your code because my Python kernel crashes. Best regards, Joel H. V. El 2 jun 2024, a las 7:06 a.m., xacGOOD @.***> escribió: Here's the latest test code: #!/usr/bin/env python3 -- coding: utf-8 -- """Examp Extra Shape Radial Sine""" import math import matplotlib import pkg_resources required = {'KrakenOS'} installed = {pkg.key for pkg in pkg_resources.working_set} missing = required - installed if missing: print("No instalado") import sys sys.path.append("../..") import KrakenOS as Kos import numpy as np import matplotlib.pyplot as plt matplotlib.use('TkAgg') ______________________________________# P_Obj = Kos.surf() P_Obj.Rc = 0.0 P_Obj.Thickness = 10.0 P_Obj.Glass = "AIR" P_Obj.Diameter = 2128.0 P_Obj.Drawing = 0 ______________________________________# data_ = [] # just use to export Kraken surf data def fresnel(x,y,data): dis = np.sqrt(x2+y2) z = np.interp(x=dis,xp=data[...,0],fp=data[...,1]) global data_ data_ += np.array((dis,z)).T.tolist() # append to data_ return z fresnel_data= np.loadtxt('R1064_F1800_超大菲涅尔.txt',delimiter=',') # fresnel profile data L1a = Kos.surf() L1a.Rc = 0.0 L1a.Thickness = 5.0 L1a.Glass = "PMMA" L1a.Diameter = 2128.0 fresnel_ES = [fresnel,fresnel_data] L1a.ExtraData = fresnel_ES L1a.Name = 'zone side' ______________________________________# L1c = Kos.surf() L1c.Rc = 0.0 L1c.Thickness = 1800 # 本片的厚度,也是后面一片的起点距离 L1c.Glass = "AIR" L1c.Diameter = 2128.0 L1c.Name = 'plan side' ______________________________________# P_Ima = Kos.surf() P_Ima.Rc = 0.0 P_Ima.Thickness = 0.0 P_Ima.Glass = "AIR" P_Ima.Diameter = 200.0 P_Ima.Name = "Image plane" ______________________________________# A = [P_Obj, L1a, L1c,P_Ima] Config_1 = Kos.Setup() ______________________________________# Lens = Kos.system(A, Config_1) Rays = Kos.raykeeper(Lens) Wav = 0.55 # 波长??? y = np.arange(1063,1064,0.002) np.savetxt('y.txt',y,delimiter=',') ______________________________________# for i in y: p_s = [0.0,i,0.0] d_cos = [0.0,0.0,1.0] Lens.Trace(p_s,d_cos,0.55) Rays.push() ______________________________________# print(Rays.XYZ[100]) # here is verify ray , ri shoot in material is 1.550, out from material to air is 1.4936, why? data_ = np.unique(np.array(data_),axis=0) # unique and sort np.savetxt('rz.txt',data_,fmt='%.8f',delimiter=',') # save for verify Kos.display3d(Lens, Rays, 2) Kos.display2d(Lens, Rays, 0) How can I customize the refractive index of a material? — Reply to this email directly, view it on GitHub <#12 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AED73RS4HQWG3LBUXOQRFSDZFMRHDAVCNFSM6AAAAABIVAWNG2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNBTHA3DONZQGU. You are receiving this because you are subscribed to this thread. Dr. Joel Herrera Vázquez Observatorio Astronómico Nacional Instituto de Astronomía de la UNAM (Sede Ensenada B.C.) Tel. (646) 1 74 45 80 Ext.426

dear Dr. Joel Herrera Vázquez,

Thank you for your reply, it's true that my problem description is not clear enough.

There were two questions I asked last time: First question: How do I use a custom profile? I currently need to import a Rotary Fresnel lens into KrakenOS for ray tracing. However, the results of ray tracing are inconsistent with Lighttools. I noticed that the light was wrong at the edge of the Fresnel tooth. I don't know why this issue is happening. (Maybe I'm using the custom outline in the wrong way? But the profile I extracted from KrakenOS is consistent with the lens design file. This is puzzling and I intend to try again with the Fresnel.stp file. ) The second question: how to customize the refractive index of the material, there are already many materials in KrakenOS, you can use the method of L1a.Glass = "PMMA" to specify, KrakenOS will automatically calculate the appropriate refractive index of the material according to the wavelength. But if I only know the refractive index of the material now, I don't know the name of the material, or the material is not in the KrakenOS library, how do I specify the refractive index of this material? Looking forward to your answers, thank you.

Best regards KrankenOS Learners: Anchun Xia

xacGOOD commented 3 months ago

dear Dr. Joel Herrera Vázquez,

I just found out that KrakenOS doesn't support STP files, so I'll still have to use L1a.ExtraData to add the shape of the Fresnel lens. Here's the code:

def fresnel(x,y,data):
    dis = np.sqrt(x**2+y**2)
    z = np.interp(x=dis,xp=data[...,0],fp=data[...,1])
    return z

fresnel_data= np.loadtxt('fresnel_Data.txt',delimiter=',') # Focused Fresnel lens tooth plane data
L1a = Kos.surf()
L1a.Thickness = 75.0
L1a.Glass = "PMMA"
L1a.Diameter = 2128.0
fresnel_ES = [fresnel,fresnel_data]
L1a.ExtraData = fresnel_ES
L1a.Name = 'zone side'

I'm following the Fresnel lens data I added above, but with ray tracing, I can't focus accurately, can you take the time to check what I'm doing wrong?

Best regards KrankenOS Learners: Anchun Xia

clacker commented 3 months ago

Hello Anchun,

You can enter a model refractive index using

L1a.Glass = 1.4936

I tried this using your points with the following code and it looks OK. I don't know why the image doesn't form at 1800 but is at 1790 instead. I assume it has to do with a difference in refractive index used to make your model?

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Examp ExtraShape Fresnel Lens"""

import pkg_resources
""" Looking for if KrakenOS is installed, if not, it assumes that
an folder downloaded from github is run"""

required = {'KrakenOS'}
installed = {pkg.key for pkg in pkg_resources.working_set}
missing = required - installed

if missing:
    print("Not installed")
    import sys
    sys.path.append("../..")

import KrakenOS as Kos
import numpy as np
import matplotlib.pyplot as plt

# ______________________________________#

P_Obj = Kos.surf()
P_Obj.Rc = 0.0
P_Obj.Thickness = 150
P_Obj.Glass = "AIR"
P_Obj.Diameter = 50.0

# ______________________________________#

surface_data = np.loadtxt('R1064.txt', delimiter=',')

def fresnel(x, y , E):
    radialX = np.sqrt(x*x + y*y)
    z = np.interp(radialX, surface_data[..., 0], surface_data[..., 1])
    return z

L1a = Kos.surf()
L1a.Rc = 0.0
L1a.Thickness = 5.0
L1a.Glass = "PMMA"
L1a.Diameter = 2128.0
coef = [] #just a dummy value
L1a.ExtraData = [fresnel, coef]
L1a.Res = 1
L1a.Name = 'zone side'
L1a.Nm_Pos = (-500,200)

# ______________________________________#

L1b = Kos.surf()
L1b.Thickness = 1790
L1b.Glass = "AIR"
L1b.Diameter = 2128.0
L1b.Name = 'flat side'
L1b.Nm_Pos = (500,200)

# ______________________________________#

P_Ima = Kos.surf()
P_Ima.Rc = 0.0
P_Ima.Thickness = 0.0
P_Ima.Glass = "AIR"
P_Ima.Diameter = 100.0
P_Ima.Name = "Image plane"

# ______________________________________#

A = [P_Obj, L1a, L1b, P_Ima]
Config_1 = Kos.Setup()

# ______________________________________#

Lens = Kos.system(A, Config_1)
Rays = Kos.raykeeper(Lens)

# ______________________________________#

Wav = 0.526
for i in range(-100, 100 + 1):
    pSource = [0.0, i*10+.25, 0.0]
    dCos = [0.0, 0.0, 1.0]
    Lens.Trace(pSource, dCos, Wav)
    Rays.push()

# ______________________________________#

Kos.display3d(Lens, Rays, 0)
Kos.display2d(Lens, Rays, 0)

Figure_1

xacGOOD commented 3 months ago

Hello Anchun,

You can enter a model refractive index using

L1a.Glass = 1.4936

I tried this using your points with the following code and it looks OK. I don't know why the image doesn't form at 1800 but is at 1790 instead. I assume it has to do with a difference in refractive index used to make your model?

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Examp ExtraShape Fresnel Lens"""

import pkg_resources
""" Looking for if KrakenOS is installed, if not, it assumes that
an folder downloaded from github is run"""

required = {'KrakenOS'}
installed = {pkg.key for pkg in pkg_resources.working_set}
missing = required - installed

if missing:
    print("Not installed")
    import sys
    sys.path.append("../..")

import KrakenOS as Kos
import numpy as np
import matplotlib.pyplot as plt

# ______________________________________#

P_Obj = Kos.surf()
P_Obj.Rc = 0.0
P_Obj.Thickness = 150
P_Obj.Glass = "AIR"
P_Obj.Diameter = 50.0

# ______________________________________#

surface_data = np.loadtxt('R1064.txt', delimiter=',')

def fresnel(x, y , E):
    radialX = np.sqrt(x*x + y*y)
    z = np.interp(radialX, surface_data[..., 0], surface_data[..., 1])
    return z

L1a = Kos.surf()
L1a.Rc = 0.0
L1a.Thickness = 5.0
L1a.Glass = "PMMA"
L1a.Diameter = 2128.0
coef = [] #just a dummy value
L1a.ExtraData = [fresnel, coef]
L1a.Res = 1
L1a.Name = 'zone side'
L1a.Nm_Pos = (-500,200)

# ______________________________________#

L1b = Kos.surf()
L1b.Thickness = 1790
L1b.Glass = "AIR"
L1b.Diameter = 2128.0
L1b.Name = 'flat side'
L1b.Nm_Pos = (500,200)

# ______________________________________#

P_Ima = Kos.surf()
P_Ima.Rc = 0.0
P_Ima.Thickness = 0.0
P_Ima.Glass = "AIR"
P_Ima.Diameter = 100.0
P_Ima.Name = "Image plane"

# ______________________________________#

A = [P_Obj, L1a, L1b, P_Ima]
Config_1 = Kos.Setup()

# ______________________________________#

Lens = Kos.system(A, Config_1)
Rays = Kos.raykeeper(Lens)

# ______________________________________#

Wav = 0.526
for i in range(-100, 100 + 1):
    pSource = [0.0, i*10+.25, 0.0]
    dCos = [0.0, 0.0, 1.0]
    Lens.Trace(pSource, dCos, Wav)
    Rays.push()

# ______________________________________#

Kos.display3d(Lens, Rays, 0)
Kos.display2d(Lens, Rays, 0)

Figure_1

Dear clacker,

Thank you very much for your answers. I took a closer look at your code and found that the problem with the light simulation is mainly the following code:

Wav = 0.526
for i in np.arange(-1000, 1001,0.5):
    # pSource = [0.0, i*10+.25, 0.0]
    pSource = [0.0, i, 0.0]
    dCos = [0.0, 0.0, 1.0]
    Lens.Trace(pSource, dCos, Wav)
    Rays.push()

If the Y axis of the trace is set to a different position, the entire ray tracing will not work, and as shown in the code above, ray tracing will fail. Does pSource[x,y,z] have a special format? (I think this is the starting point coordinate of the ray)

We look forward to hearing from you again.

Best regards KrankenOS Learners: Anchun Xia

xacGOOD commented 3 months ago

Dear @clacker ,

I did a different Lens.Trace again, using your code. Only the Lens.Trace part was changed, the code is as follows:

Wav = 0.526
for i in np.arange(-1000, 0,0.5):
    # pSource = [0.0, i+.25, 0.0]
    pSource = [0.0, i+0.1, 0.0]
    dCos = [0.0, 0.0, 1.0]
    Lens.Trace(pSource, dCos, Wav)
    Rays.push()

for i in np.arange(0, 1001,0.5):
    # pSource = [0.0, i+.25, 0.0]
    pSource = [0.0, i, 0.0]
    dCos = [0.0, 0.0, 1.0]
    Lens.Trace(pSource, dCos, Wav)
    Rays.push()

As a result, the ray tracing Y-axis -1000 to 0 is normal, and 0 to 1001 is not. It seems that the Lens.Trace part needs special attention, I noticed that each value of your Y axis is offset by 0.25, why do you need to offset this value?

If I want to add more rays, say every 0.001mm in the Y axis, I'll do it with the following code, but it's clear that ray tracing will mess up.

for i in np.arange(-1000, 1001,0.001): # Depending on the computer performance, you can also simulate a part, for example: np.arange(998, 999,0.001)
    pSource = [0.0, i, 0.0]
    dCos = [0.0, 0.0, 1.0]
    Lens.Trace(pSource, dCos, Wav)
    Rays.push()

Roundup: How do you accurately simulate any quantity, any position, any density of light?

Looking forward to your help!

Best regards KrankenOS Learners: Anchun Xia

屏幕截图 2024-08-02 232540

Garchupiter commented 3 months ago

Hello Anchun, apologies, I haven't had much time to focus on KrakenOS, but your problem is very interesting, so I took some time to review it.

I would like to know how you determined the refractive indices shown in this image:

image

I am using the same profile you use and the PMMA material, so the refractive index is calculated automatically for each wavelength using the dispersion parameters for that material. In the same way as clacker, I obtain the following figure:

image

I obtain the refractive indices from the ray container through Rays.N0. In the following console image, you can see an array of the refractive indices. Many of the rays passed through indices [1., 1.4935809, 1.], while other rays did not reach the image plane, showing [1., 1.4935809].

image

Many rays do not reach the image plane due to the diameter being assigned to this last surface.

It is important to analyze the lens profile. I see that it is impossible for it to focus light on a fine point. I am not familiar with Lighttools, but I understand that it is selecting rays in such a way that only the regions of the profile that form a point image are used. To visualize the profile, I use this code.

import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import interp1d

# Load data from the file
file_path = 'R1064_F1800_超大菲涅尔 (1).txt'
data = np.loadtxt(file_path, delimiter=',')

# Extract data columns
x = data[:, 0]
y = data[:, 1]

# Define new x points for interpolation
x_new = np.linspace(x.min(), x.max(), num=len(x))

interp_func = interp1d(x, y, kind='linear', fill_value='extrapolate')

# Perform interpolation
y_interp = interp_func(x_new)

# Create the plot
plt.figure(figsize=(8, 8))
plt.plot(x, y, 'o', label='Original Data')
plt.plot(x_new, y_interp, '-', label='Interpolation')

# Set the axes to have the same scale
plt.axis('equal')

# Add labels, title, and legend
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Plot of Data and Interpolation with Equal Scale on Both Axes')
plt.legend()

# Show the plot
plt.grid(True)
plt.show()

Zooming in on an extreme region shows that the interpolated curve has slopes in different directions:

354825621-dd3a79e5-76a0-4ade-a4c2-170cb3dff16b

Even at the upper edges, there are slopes in different directions:

354825637-f6379d90-80a2-4f5a-9813-37913350aa40

Another thing I want to mention is that KrakenOS uses the function with which the shape of the surface is defined to generate the visualization. This is done in low definition to perform it quickly, so if you zoom in on the image in KrakenOS, the details of the Fresnel profile are not shown. The detailed shape profile is used for ray tracing.

KrakenOS does not support STP; it only supports STL, which is very simple. It only defines planes in space using triangles, and a complex surface is tessellated using these triangles, each having its own individual normal.

I believe the main error is that you are assuming that the Fresnel lens profile focuses light on a perfectly defined particular position. Besides the profile details I mentioned earlier, you are probably using a slightly different wavelength than the one used to design the lens profile.

A tip to improve the speed of ray tracing is to create the interpolation as an object (interp_func = interp1d(r, z, kind='linear', fill_value='extrapolate') ) and pass it as a parameter to the profile function. This way, the interpolation does not have to be performed for each ray trace. You can see this in the following code based on what Steven Vogel shared. Additionally, I am generating rays randomly, minimizing the recurrence of rays in the area where the rays are refracted divergently.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Examp ExtraShape Fresnel Lens"""

import pkg_resources
""" Looking for if KrakenOS is installed, if not, it assumes that
an folder downloaded from github is run"""

required = {'KrakenOS'}
installed = {pkg.key for pkg in pkg_resources.working_set}
missing = required - installed

if missing:
    print("Not installed")
    import sys
    sys.path.append("../..")

import KrakenOS as Kos
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d

# ______________________________________#

P_Obj = Kos.surf()
P_Obj.Rc = 0.0
P_Obj.Thickness = 150
P_Obj.Glass = "AIR"
P_Obj.Diameter = 50.0

# ______________________________________#

surface_data = np.loadtxt('R1064_F1800_超大菲涅尔 (1).txt', delimiter=',')
r = surface_data[:, 0]
z = surface_data[:, 1]
interp_func = interp1d(r, z, kind='linear', fill_value='extrapolate')

def fresnel(x, y , E):
    r = np.sqrt(x*x + y*y)
    return E(r)

L1a = Kos.surf()
L1a.Rc = 0.0
L1a.Thickness = 5.0
L1a.Glass = "PMMA"
L1a.Diameter = 2128.0
L1a.ExtraData = [fresnel, interp_func]
L1a.Res = 1
L1a.Name = 'zone side'
L1a.Nm_Pos = (-500,200)

# ______________________________________#

L1b = Kos.surf()
L1b.Thickness = 1790
L1b.Glass = "AIR"
L1b.Diameter = 2128.0
L1b.Name = 'flat side'
L1b.Nm_Pos = (500,200)

# ______________________________________#

P_Ima = Kos.surf()
P_Ima.Rc = 0.0
P_Ima.Thickness = 0.0
P_Ima.Glass = "AIR"
P_Ima.Diameter = 100.0
P_Ima.Name = "Image plane"

# ______________________________________#

A = [P_Obj, L1a, L1b, P_Ima]
Config_1 = Kos.Setup()

# ______________________________________#

Lens = Kos.system(A, Config_1)
Rays = Kos.raykeeper(Lens)

# ______________________________________#

SemiDiameter = np.max(r)

I = np.random.uniform(low = -SemiDiameter, high = SemiDiameter, size=50)

Wav = 0.55
for i in I:
    pSource = [0.0, i, 0.0]
    dCos = [0.0, 0.0, 1.0]
    Lens.Trace(pSource, dCos, Wav)
    Rays.push()

# ______________________________________#

Kos.display3d(Lens, Rays, 0)
Kos.display2d(Lens, Rays, 0)

If you vary the diameter of the image plane, for example, to 2000mm, you will see that there is a lot of dispersion everywhere.

image

image

Best regards, Joel H. V.

clacker commented 3 months ago

@xacGOOD Achun,

You asked:

I noticed that each value of your Y axis is offset by 0.25, why do you need to offset this value?

Because I saw the same thing that Joel H. V. saw: your tooth shape has both a draft on the raising edge (so it can be pulled from the mold) and a radius at the root of the tooth. I used the 0.25 (half of the tooth width) to make sure I was always hitting the working side of the tooth. I plotted the last few teeth with this code:

import numpy as np
import matplotlib.pyplot as plt

sd = np.loadtxt('R1064.txt', delimiter=',')

xrange, yrange = sd.shape

toothWidth = 0.5    # in mm
totalWidth = 1064   # in mm
pointsPerTooth = round(xrange/(totalWidth/toothWidth))
xmin = xrange-3*pointsPerTooth
xmax = xrange

print(pointsPerTooth, xmin, xmax)

x = sd[xmin:xmax, 0]
y = sd[xmin:xmax, 1]

plt.plot(x,y)
plt.show()

Figure_1

@Garchupiter

That trick with the interpolation object is a very neat.

xacGOOD commented 3 months ago

dear @Garchupiter , dear @clacker ,

Through the answers of the two of them, it was found that my ray tracing did not look normal because the light I was using happened to be in the invalid position of the Fresnel lens. This was my gross negligence. @Garchupiter Q: How is the simulated refractive index obtained: 335869959-925a8317-1def-406b-a514-03a1d94d1c93

This refractive index is verified in AutoCAD by measuring the angle of incidence and exit based on the path of the rays and the contour of the Fresnel surface. The profile data used is obtained with the following code:

data_ = [] # just use to export Kraken surf data
    def fresnel(x,y,data):
    dis = np.sqrt(x2+y2)
    z = np.interp(x=dis,xp=data[...,0],fp=data[...,1])
    global data_
    data_ += np.array((dis,z)). T.tolist() # append to data_
    return z
    # Omit the rest of the code
    data_ = np.unique(np.array(data_),axis=0) # unique and sort
    np.savetxt('rz.txt',data_,fmt='%.8f',delimiter=',') # save for verify

The above saved rz.txt as the contour of the Fresnel lens, and then using the Rays.XYZ to get the ray coordinates, and then importing it into AutoCAD to measure the angle to calculate the refractive index, may there be a problem rz.txt the saved Fresnel profile data? However, in AutoCAD, it was found to be consistent with the original outline.

I'm going to continue to look into the next two pieces of code and the KrakenOS case to check for problems with my own code.

Thank you very much@Garchupiter Take the time to answer my questions, two gentlemen: in this case, the Fresnel lens added by L1a.ExtraData has a lot of tiny facets, which are shapes used for optical design, As you mentioned: """ Another thing I want to mention is that KrakenOS uses the function with which the shape of the surface is defined to generate the visualization. This is done in low definition to perform it quickly, so if you zoom in on the image in KrakenOS, the details of the Fresnel profile are not shown. The detailed shape profile is used for ray tracing. """ How does KrakenOS extract accurate facets from L1a.ExtraData? I think the only entry point to get the data is: L1a.ExtraData = [fresnel, interp_func] step, how do I know the extraction accuracy here?

Best regards KrankenOS Learners: Anchun Xia

Garchupiter commented 3 months ago

Hi @clacker and @xacGOOD

I just found a little error in the precision of the derivative calculation that particularly affects the user-defined surfaces with sharp features. I will update the library in a few days to provide better control of user-defined surfaces.

Best regards, Joel H. V.

xacGOOD commented 3 months ago

Dear @Garchupiter ,

Received, very much looking forward to your update.

Best regards KrankenOS Learners: Anchun Xia