have scatering matrix deduced
This commit is contained in:
parent
ce95d74274
commit
6c73ed6341
|
@ -62,10 +62,26 @@ class IsotopeClass:
|
|||
return [1, 'H']
|
||||
if ASym == "d" :
|
||||
return [2, 'H']
|
||||
if ASym == "t" :
|
||||
return [3, 'H']
|
||||
if ASym == "h" :
|
||||
return [3, 'He']
|
||||
if ASym == "a" :
|
||||
return [4, 'He']
|
||||
match = re.match(r'(\d+)(\D+)', ASym)
|
||||
return [int(match.group(1)), match.group(2) ]
|
||||
|
||||
def GetAZ(self, ASym : str):
|
||||
if ASym == "p" :
|
||||
return [1, 1]
|
||||
if ASym == "d" :
|
||||
return [2, 1]
|
||||
if ASym == "t" :
|
||||
return [3, 1]
|
||||
if ASym == "h" :
|
||||
return [3, 2]
|
||||
if ASym == "a" :
|
||||
return [3, 2]
|
||||
[A, sym] = self.BreakDownName(ASym)
|
||||
try:
|
||||
dudu = self.data[(self.data['symbol']==sym) & (self.data['A']==A)]
|
||||
|
@ -119,6 +135,13 @@ class IsotopeClass:
|
|||
return dudu['jp'].iloc[0]
|
||||
except:
|
||||
return "unknown"
|
||||
|
||||
def GetJpi(self, A : int, Z : int):
|
||||
try:
|
||||
dudu = self.data[(self.data['z']==Z) & (self.data['A']==A)]
|
||||
return dudu['jp'].iloc[0]
|
||||
except:
|
||||
return "unknown"
|
||||
|
||||
def GetHalfLife(self, ASym : str) -> float:
|
||||
[A, sym] = self.BreakDownName(ASym)
|
||||
|
|
|
@ -1,9 +1,80 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from boundState import BoundState
|
||||
|
||||
boundState = BoundState(16, 8, 1, 0, 0, 2, 2.5, -4.14)
|
||||
boundState.SetPotential(1.10, 0.65, -6, 1.25, 0.65)
|
||||
boundState.FindPotentialDepth(-70, -60, 0.5)
|
||||
# boundState.PrintWF()
|
||||
boundState.PlotBoundState()
|
||||
|
||||
from solveSE import WoodsSaxonPot, CoulombPotential, SpinOrbit_Pot, WS_SurfacePot, SolvingSE
|
||||
from mpmath import coulombf, coulombg
|
||||
|
||||
import numpy as np
|
||||
from scipy.special import gamma
|
||||
|
||||
# boundState = BoundState(16, 8, 1, 0, 1, 0, 0.5, -4.14)
|
||||
# boundState.SetPotential(1.10, 0.65, -6, 1.25, 0.65, 1.25)
|
||||
# boundState.FindPotentialDepth(-75, -60, 0.1)
|
||||
# # boundState.PrintWF()
|
||||
# boundState.PlotBoundState()
|
||||
|
||||
def SevenPointsSlope(data, n):
|
||||
return (-data[n + 3] + 9 * data[n + 2] - 45 * data[n + 1] + 45 * data[n - 1] - 9 * data[n - 2] + data[n - 3]) / 60
|
||||
|
||||
def FivePointsSlope(data, n):
|
||||
return ( data[n + 2] - 8 * data[n + 1] + 8 * data[n - 1] - data[n - 2] ) / 12
|
||||
|
||||
|
||||
dw = SolvingSE("60Ni", "p", 30)
|
||||
dw.SetRange(0, 0.1, 300)
|
||||
dw.SetLJ(0, 0.5)
|
||||
dw.dsolu0 = 1
|
||||
dw.CalCMConstants()
|
||||
dw.PrintInput()
|
||||
|
||||
dw.ClearPotential()
|
||||
dw.AddPotential(WoodsSaxonPot(-47.937-2.853j, 1.20, 0.669), False)
|
||||
dw.AddPotential(WS_SurfacePot(-6.878j, 1.28, 0.550), False)
|
||||
dw.AddPotential(SpinOrbit_Pot(-5.250 + 0.162j, 1.02, 0.590), False)
|
||||
dw.AddPotential(CoulombPotential(1.258), False)
|
||||
|
||||
rpos = dw.rpos
|
||||
solU = dw.SolveByRK4()
|
||||
|
||||
solU /= dw.maxSolU
|
||||
|
||||
# for r, u in zip(rpos, solU):
|
||||
# print(f"{r:.3f} {np.real(u):.6f} {np.imag(u):.6f}")
|
||||
|
||||
def CoulombPhaseShift(L, eta):
|
||||
return np.angle(gamma(L+1+1j*eta))
|
||||
|
||||
sigma = CoulombPhaseShift(dw.L, dw.eta)
|
||||
# find pahse shift by using the asymptotic behavior of the wave function
|
||||
r1 = rpos[-2]
|
||||
f1 = float(coulombf(dw.L, dw.eta, dw.k*r1))
|
||||
g1 = float(coulombg(dw.L, dw.eta, dw.k*r1))
|
||||
u1 = solU[-2]
|
||||
|
||||
r2 = rpos[-1]
|
||||
f2 = float(coulombf(dw.L, dw.eta, dw.k*r2))
|
||||
g2 = float(coulombg(dw.L, dw.eta, dw.k*r2))
|
||||
u2 = solU[-1]
|
||||
|
||||
det = f2*g1 - f1*g2
|
||||
A = (f2*u1 - u2*f1) / det
|
||||
B = (u2*g1 - g2*u1) / det
|
||||
|
||||
print(f"A = {np.real(A):.6f} + {np.imag(A):.6f} I")
|
||||
print(f"B = {np.real(B):.6f} + {np.imag(B):.6f} I")
|
||||
|
||||
ScatMatrix = (B + A * 1j)/(B - A * 1j)
|
||||
print(f"Scat Matrix = {np.real(ScatMatrix):.6f} + {np.imag(ScatMatrix):.6f} I")
|
||||
|
||||
solU = np.array(solU, dtype=np.complex128)
|
||||
solU *= np.exp(1j * sigma)/(B-A*1j)
|
||||
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
plt.plot(rpos, np.real(solU), label="Real")
|
||||
plt.plot(rpos, np.imag(solU), label="Imaginary")
|
||||
plt.legend()
|
||||
plt.show(block=False)
|
||||
|
||||
input("Press Enter to continue...")
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from solveSE import WSPotential, CoulombPotential, SpinOrbitPotential, SolvingSE
|
||||
from solveSE import WoodsSaxonPot, CoulombPotential, SpinOrbit_Pot, SolvingSE
|
||||
|
||||
from scipy.optimize import curve_fit
|
||||
from scipy.interpolate import interp1d
|
||||
|
@ -12,22 +12,14 @@ import mpmath
|
|||
|
||||
mpmath.mp.dps = 15 # Decimal places of precision
|
||||
|
||||
def SevenPointsSlope(data, n):
|
||||
return (-data[n + 3] + 9 * data[n + 2] - 45 * data[n + 1] + 45 * data[n - 1] - 9 * data[n - 2] + data[n - 3]) / 60
|
||||
|
||||
|
||||
class BoundState(SolvingSE):
|
||||
def __init__(self, A, ZA, a, Za, node, L, J, BE):
|
||||
super().__init__(A, ZA, a, Za, BE)
|
||||
self.Ecm = BE
|
||||
self.BE = BE
|
||||
|
||||
self.CalCMConstants( True)
|
||||
self.SetRange(0, 0.1, 300) # default range
|
||||
self.PrintInput()
|
||||
|
||||
self.node = node # number of nodes of the wave function r > 0
|
||||
self.SetLJ(L, J)
|
||||
|
||||
self.PrintInput()
|
||||
self.node = node # number of nodes of the wave function r > 0
|
||||
self.FoundBounfState = False
|
||||
|
||||
def SetPotential(self, r0, a0, Vso, rso, aso, rc = 0.0):
|
||||
|
@ -38,8 +30,8 @@ class BoundState(SolvingSE):
|
|||
self.aso = aso
|
||||
self.rc = rc
|
||||
self.ClearPotential()
|
||||
self.AddPotential(WSPotential(-60, r0, a0), False) # not use mass number of a
|
||||
self.AddPotential(SpinOrbitPotential(Vso, rso, aso), False) # not use mass number of a
|
||||
self.AddPotential(WoodsSaxonPot(-60, r0, a0), False) # not use mass number of a
|
||||
self.AddPotential(SpinOrbit_Pot(Vso, rso, aso), False) # not use mass number of a
|
||||
if rc > 0 and self.Z_a > 0:
|
||||
self.AddPotential(CoulombPotential(rc), False) # not use mass number of a
|
||||
|
||||
|
@ -50,8 +42,8 @@ class BoundState(SolvingSE):
|
|||
maxLastSolU = 0
|
||||
for V0 in V0List:
|
||||
self.ClearPotential()
|
||||
self.AddPotential(WSPotential(V0, self.r0, self.a0), False)
|
||||
self.AddPotential(SpinOrbitPotential(self.Vso, self.rso, self.aso), False) # not use mass number of a
|
||||
self.AddPotential(WoodsSaxonPot(V0, self.r0, self.a0), False)
|
||||
self.AddPotential(SpinOrbit_Pot(self.Vso, self.rso, self.aso), False) # not use mass number of a
|
||||
if self.rc > 0 and self.Z_a > 0:
|
||||
self.AddPotential(CoulombPotential(self.rc), False)
|
||||
wf = self.SolveByRK4()
|
||||
|
@ -62,16 +54,16 @@ class BoundState(SolvingSE):
|
|||
maxLastSolU = lastSolU[-1]
|
||||
|
||||
if minLastSolU >= 0 or maxLastSolU <= 0:
|
||||
print("No bound state found in the range")
|
||||
print("min Last SolU = ", minLastSolU)
|
||||
print("max Last SolU = ", maxLastSolU)
|
||||
plt.plot(V0List, lastSolU, marker="x")
|
||||
plt.grid()
|
||||
plt.xlabel('V0 (MeV)')
|
||||
plt.show(block=False)
|
||||
input("Press Enter to exit.")
|
||||
print("No bound state found in the range")
|
||||
print("min Last SolU = ", minLastSolU)
|
||||
print("max Last SolU = ", maxLastSolU)
|
||||
plt.plot(V0List, lastSolU, marker="x")
|
||||
plt.grid()
|
||||
plt.xlabel('V0 (MeV)')
|
||||
plt.show(block=False)
|
||||
input("Press Enter to exit.")
|
||||
|
||||
return
|
||||
return
|
||||
|
||||
f = interp1d(lastSolU, V0List, kind='cubic')
|
||||
self.V_BS = f(0)
|
||||
|
@ -79,8 +71,8 @@ class BoundState(SolvingSE):
|
|||
|
||||
# recaluclate the wave function for V_BS
|
||||
self.ClearPotential()
|
||||
self.AddPotential(WSPotential(self.V_BS, self.r0, self.a0), False)
|
||||
self.AddPotential(SpinOrbitPotential(self.Vso, self.rso, self.aso), False) # not use mass number of a
|
||||
self.AddPotential(WoodsSaxonPot(self.V_BS, self.r0, self.a0), False)
|
||||
self.AddPotential(SpinOrbit_Pot(self.Vso, self.rso, self.aso), False) # not use mass number of a
|
||||
if self.rc > 0 and self.Z_a > 0:
|
||||
self.AddPotential(CoulombPotential(self.rc), False)
|
||||
|
||||
|
@ -109,7 +101,7 @@ class BoundState(SolvingSE):
|
|||
self.wf[1:] = self.SolU[1:] / self.rpos[1:]
|
||||
self.wf[0] = self.SolU[0] # Handle the first element separately if needed
|
||||
|
||||
#extrapolate wf from 0.2, 0.1 to 0.0
|
||||
#extrapolate wf with quadrotic from 0.2, 0.1 to 0.0
|
||||
def func(x, a, b, c):
|
||||
return a * x**2 + b * x + c
|
||||
popt, pcov = curve_fit(func, self.rpos[1:6], self.wf[1:6])
|
||||
|
@ -117,18 +109,15 @@ class BoundState(SolvingSE):
|
|||
|
||||
if isPathWhittaker:
|
||||
# patch the long range function to Whittaker function
|
||||
kappa = np.sqrt(2*self.mu*np.abs(self.BE))/self.hbarc
|
||||
charge = self.Z
|
||||
self.eta = kappa * charge * self.ee / 2 / self.BE
|
||||
|
||||
R = min(self.r0 * (pow(self.A_A, 1/3) + pow(self.A_a, 1/3)) + 5 * self.a0, max(self.rpos))
|
||||
rIndex = self.NearestPosIndex(R)
|
||||
print(f"replacing wave function with Whittaker after R : {R:5.1f}, index : {rIndex}")
|
||||
if rIndex < len(self.rpos):
|
||||
R = self.rpos[rIndex]
|
||||
W_values = [float(whitw(-1j*self.eta, self.L + 0.5, 2*kappa * r))/(kappa * r) for r in self.rpos]
|
||||
W_values = [np.real(whitw(-1j*self.eta, self.L + 0.5, 2*self.k * r))/(self.k * r) for r in self.rpos[1:]]
|
||||
W_values.insert(0, 0)
|
||||
|
||||
self.ANC = self.wf[rIndex] / W_values[rIndex]
|
||||
self.ANC = float(self.wf[rIndex] / W_values[rIndex])
|
||||
print(f"ANC : {self.ANC:10.6e}")
|
||||
self.wf[rIndex:] = self.ANC * np.array(W_values[rIndex:])
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import math
|
||||
import numpy as np
|
||||
|
||||
import re
|
||||
import sys, os
|
||||
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), '../Cleopatra'))
|
||||
|
@ -29,7 +29,7 @@ class CoulombPotential:
|
|||
else:
|
||||
return (self.Charge * self.ee) / (2 * self.Rc) * (3 - (x / self.Rc)**2)
|
||||
|
||||
class WSPotential:
|
||||
class WoodsSaxonPot:
|
||||
def __init__(self, V0, r0, a0) :
|
||||
self.V0 = V0
|
||||
self.r0 = r0
|
||||
|
@ -45,7 +45,7 @@ class WSPotential:
|
|||
def output(self, x):
|
||||
return self.V0/(1 + math.exp((x-self.R0)/self.a0))
|
||||
|
||||
class SpinOrbitPotential:
|
||||
class SpinOrbit_Pot:
|
||||
def __init__(self, VSO, rSO, aSO) :
|
||||
# the LS factor is put in the SolvingSE Class
|
||||
self.VSO = VSO
|
||||
|
@ -65,7 +65,7 @@ class SpinOrbitPotential:
|
|||
else :
|
||||
return 4*1e+19
|
||||
|
||||
class WSSurface:
|
||||
class WS_SurfacePot:
|
||||
def __init__(self, V0, r0, a0):
|
||||
self.V0 = V0
|
||||
self.r0 = r0
|
||||
|
@ -80,7 +80,7 @@ class WSSurface:
|
|||
|
||||
def output(self, x):
|
||||
exponent = (x - self.R0) / self.a0
|
||||
return self.V0 * math.exp(exponent) / (1 + math.exp(exponent))**2
|
||||
return 4* self.V0 * math.exp(exponent) / (1 + math.exp(exponent))**2
|
||||
|
||||
#========================================
|
||||
class SolvingSE:
|
||||
|
@ -109,52 +109,78 @@ class SolvingSE:
|
|||
potential_List = []
|
||||
|
||||
def PrintInput(self):
|
||||
print(f" A : ({self.A_A:3d}, {self.Z_A:3d})")
|
||||
print(f" a : ({self.A_a:3d}, {self.Z_a:3d})")
|
||||
print(f" Elab : {self.Energy : 10.3f} MeV")
|
||||
print(f" mu : {self.mu: 10.3f} MeV/c2")
|
||||
# print(f" Ecm : {self.Ecm: 10.3f} MeV")
|
||||
# print(f" k : {self.k: 10.3f} MeV/c")
|
||||
# print(f" eta : {self.eta: 10.3f}")
|
||||
# print(f" L : {self.L}, maxL : {self.maxL}")
|
||||
print(f" A : ({self.A_A:3d}, {self.Z_A:3d}), spin : {self.spin_A},")
|
||||
print(f" a : ({self.A_a:3d}, {self.Z_a:3d}), spin : {self.spin_a},")
|
||||
print(f" Elab : {self.Energy : 10.5f} MeV")
|
||||
print(f" mu : {self.mu: 10.5f} MeV/c2")
|
||||
print(f" Ecm : {self.Ecm: 10.5f} MeV")
|
||||
print(f" k : {self.k: 10.5f} MeV/c")
|
||||
print(f" eta : {self.eta: 10.5f}")
|
||||
print(f" L : {self.L}, maxL : {self.maxL}")
|
||||
print(f" dr : {self.dr} fm, nStep : {self.nStep}")
|
||||
print(f"rStart : {self.rStart} fm, rMax : {self.nStep * self.dr} fm")
|
||||
print(f"spin-A : {self.sA}, spin-a : {self.sa} ")
|
||||
|
||||
def __init__(self, A_or_SymA = None, ZA_or_Syma = None \
|
||||
, a_or_ELabPerA = None, Za_or_none = None, ELabPerA_or_none = None):
|
||||
if Za_or_none is None :
|
||||
self.ConstructUsingSymbol(A_or_SymA, ZA_or_Syma, a_or_ELabPerA)
|
||||
else:
|
||||
self.ConstructUsingAZ(A_or_SymA, ZA_or_Syma, a_or_ELabPerA, Za_or_none, ELabPerA_or_none)
|
||||
|
||||
def __init__(self, A, ZA, a, Za, Energy):
|
||||
haha = IsotopeClass()
|
||||
self.mass_A = haha.GetMassFromAZ(self.A_A, self.Z_A)
|
||||
self.mass_a = haha.GetMassFromAZ(self.A_a, self.Z_a)
|
||||
self.spin_A = float(eval(re.sub(r'[+-]', '', haha.GetJpi(self.A_A, self.Z_A))))
|
||||
self.spin_a = float(eval(re.sub(r'[+-]', '', haha.GetJpi(self.A_a, self.Z_a))))
|
||||
self.S = self.spin_a
|
||||
|
||||
self.mu = (self.mass_A * self.mass_a)/(self.mass_A + self.mass_a)
|
||||
self.Ecm = 0.0
|
||||
|
||||
def ConstructUsingAZ(self, A, ZA, a, Za, ELabPerA):
|
||||
print(f"ConstructUsingAZ : {A}, {ZA}, {a}, {Za}, {ELabPerA}")
|
||||
self.A_A = A
|
||||
self.A_a = a
|
||||
self.Z_A = ZA
|
||||
self.Z_a = Za
|
||||
self.Z = ZA * Za
|
||||
|
||||
self.sA = 0
|
||||
self.sa = 0
|
||||
self.L = 0
|
||||
self.S = 0
|
||||
self.J = 0
|
||||
self.Energy = ELabPerA
|
||||
|
||||
def ConstructUsingSymbol(self, Sym_A, Sym_a, ELabPerA):
|
||||
print(f"ConstructUsingSymbol : {Sym_A}, {Sym_a}, {ELabPerA}")
|
||||
self.L = 0
|
||||
self.S = 0
|
||||
self.J = 0
|
||||
|
||||
haha = IsotopeClass()
|
||||
self.mass_A = haha.GetMassFromAZ(self.A_A, self.Z_A)
|
||||
self.mass_a = haha.GetMassFromAZ(self.A_a, self.Z_a)
|
||||
self.A_A, self.Z_A = haha.GetAZ(Sym_A)
|
||||
self.A_a, self.Z_a = haha.GetAZ(Sym_a)
|
||||
self.Z = self.Z_A * self.Z_a
|
||||
self.Energy = ELabPerA
|
||||
|
||||
#self.mu = (A * a)/(A + a) * self.amu
|
||||
self.mu = (self.mass_A * self.mass_a)/(self.mass_A + self.mass_a)
|
||||
|
||||
self.Energy = Energy
|
||||
# self.E_tot = math.sqrt(math.pow((a+A)*self.amu,2) + 2 * A * self.amu * eng_Lab)
|
||||
# self.Ecm = self.E_tot - (a + A) * self.amu
|
||||
# self.k = math.sqrt(self.mu * 2 * abs(self.Ecm)) / self.hbarc
|
||||
# self.eta = self.Z * self.ee * math.sqrt( self.mu/2/self.Ecm ) / self.hbarc
|
||||
def CalCMConstants(self, useELabAsEcm = False):
|
||||
if useELabAsEcm:
|
||||
self.E_tot = self.Energy # total energy in CM
|
||||
self.Ecm = self.Energy # KE in cm
|
||||
else:
|
||||
self.E_tot = math.sqrt(math.pow((self.mass_a+self.mass_A),2) + 2 * self.mass_A * self.Energy)
|
||||
self.Ecm = self.E_tot - (self.mass_a + self.mass_A)
|
||||
|
||||
self.k = math.sqrt(self.mu * 2 * abs(self.Ecm)) / self.hbarc
|
||||
if self.Z == 0 :
|
||||
self.eta = 0
|
||||
else:
|
||||
self.eta = self.Z * self.ee * self.k /2 /self.Ecm
|
||||
self.maxL = int(self.k * (1.4 * (self.A_A**(1/3) + self.A_a**(1/3)) + 5))
|
||||
|
||||
# self.maxL = int(self.k * (1.4 * (self.A**(1/3) + self.a**(1/3)) + 3))
|
||||
|
||||
def SetSpin(self, sA, sa):
|
||||
self.sA = sA
|
||||
self.sa = sa
|
||||
self.S = self.sa
|
||||
# def SetA_ExSpin(self, ExA, sA ):
|
||||
# self.ExA = ExA
|
||||
# self.spin_A = sA
|
||||
|
||||
def SetLJ(self, L, J):
|
||||
self.L = L
|
||||
|
@ -234,7 +260,7 @@ class SolvingSE:
|
|||
self.SolU.append(y + dy)
|
||||
dSolU.append(z + dz)
|
||||
|
||||
if abs(self.SolU[-1]) > self.maxSolU:
|
||||
if np.real(self.SolU[-1]) > self.maxSolU:
|
||||
self.maxSolU = abs(self.SolU[-1])
|
||||
|
||||
return self.SolU
|
||||
|
|
Loading…
Reference in New Issue
Block a user