def run(x,jarr,aarr,rhoarr,sphstokes=-1,atol=1e-8,rtol=1e-6,max_tau=10): if sphstokes==-1: method=0 else: method=3 radtrans_integrate.init_radtrans_integrate_data(method,4,len(x),len(x),max_tau,0.1,atol,rtol,1e-2,100000) Karr = (np.append(aarr,rhoarr,axis=1)) tau = np.append(0.,scipy.integrate.cumtrapz(Karr[:,0],x)) radtrans_integrate.integrate(x[::-1],jarr[:,:],Karr[:,:],tau,4) i = radtrans_integrate.intensity.copy() radtrans_integrate.del_radtrans_integrate_data() return i
def run(x,jarr,aarr,rhoarr,sphstokes=-1,atol=1e-8,rtol=1e-6): if sphstokes==-1: method=0 else: method=3 radtrans_integrate.init_radtrans_integrate_data(method,4,len(x),len(x),10.,0.1,atol,rtol,1e-2,100000) Karr = (np.append(aarr,rhoarr,axis=1)) tau = np.append(0.,scipy.integrate.cumtrapz(Karr[:,0],x)) radtrans_integrate.integrate(x[::-1],jarr[:,:],Karr[:,:],tau,4) i = radtrans_integrate.intensity.copy() radtrans_integrate.del_radtrans_integrate_data() return i
j=jarr) isin, Qsin, Psin, imsin, deltasin, dxsin, QQsin, PPsin, immsin, itsin = analytic_pol_rad_trans.delo_intensity( dx=(np.zeros(300 - 1) + 1e-2), a=asinarr, I0=np.array([0., 0., 0., 0.]), rho=rhosinarr, j=jsinarr, thin=1e-2) Karr = np.append(agarr, rhogarr, axis=1) tau = np.append(0., scipy.integrate.cumtrapz(Karr[:, 0], x)) radtrans_integrate.integrate(x[::-1], jarr[:, :], Karr[:, :], tau, 4) iglsoda = radtrans_integrate.intensity.copy() Karr = np.append(asinarr, rhosinarr, axis=1) tau = np.append(0., scipy.integrate.cumtrapz(Karr[:, 0], x)) radtrans_integrate.integrate(x[::-1], jsinarr[:, :], Karr[:, :], tau, 4) isinlsoda = radtrans_integrate.intensity.copy() radtrans_integrate.del_radtrans_integrate_data() radtrans_integrate.init_radtrans_integrate_data(1, 4, 300, 300, 10., 0.1, 1e-8, 1e-6, 1e-2) radtrans_integrate.integrate(x[::-1], jsinarr[:, :], Karr[:, :], tau, 4) isindelo = radtrans_integrate.intensity.copy() Karr = np.append(agarr, rhogarr, axis=1) tau = np.append(0., scipy.integrate.cumtrapz(Karr[:, 0], x)) radtrans_integrate.integrate(x[::-1], jarr[:, :], Karr[:, :], tau, 4) igdelo = radtrans_integrate.intensity.copy() Karr = (np.append(aarr, rhoarr, axis=1)) tau = np.append(0., scipy.integrate.cumtrapz(Karr[:, 0], x)) radtrans_integrate.integrate(x[::-1], jarr[:, :], Karr[:, :], tau, 4) istepdelo = radtrans_integrate.intensity.copy() radtrans_integrate.del_radtrans_integrate_data()
def integrate_ray_lsoda(x, j, K, atol=1e-8, rtol=1e-6, max_step_size=None, frac_max_step_size=1e-3, max_steps=100000): """Use `grtrans <https://github.com/jadexter/grtrans>`_ to integrate one ray using its LSODA method. **Call signature** *x* 1D array, shape (n,). Path length along ray, starting from zero, in cm. *j* Array, shape (n, 4). Emission coefficients: ``j_{IQUV}``, in that order. *K* Array, shape (n, 7). Absorption coefficients and Faraday mixing coefficients: ``alpha_{IQUV}, rho_{QUV}``. *atol* Some kind of tolerance parameter. *rtol* Some kind of tolerance parameter. *max_step_size* The maximum absolute step size. Overrides *frac_max_step_size*. *frac_max_step_size* If *max_step_size* is not specified, the maximum step size passed to the integrator is ``x.max()`` multiplied by this parameter. Experience shows that (for LSODA at least) this parameter must be pretty small to get good convergence! *max_steps* The maximum number of steps to take. Return value Array of shape (4, m): Stokes intensities IQUV along parts of the ray with non-zero total emissivities; m <= n. """ n = x.size if max_step_size is None: max_step_size = frac_max_step_size * x.max() # the LSODA method clips its input arrays based on "tau" and zero emission # coefficients. It's hard for us to find out how it clipped, though, so we # reproduce its logic. LSODA doesn't use "tau" for anything besides this # clipping, so we pass it all zeros. if np.all(j[:, 0] == 0.): return np.zeros((4, n)) i0 = 0 i1 = n - 1 while j[i0, 0] == 0.: i0 += 1 while j[i1, 0] == 0.: i1 -= 1 n = i1 + 1 - i0 x = x[i0:i1 + 1] j = j[i0:i1 + 1] K = K[i0:i1 + 1] # OK we can go. radtrans_integrate.init_radtrans_integrate_data( METHOD_LSODA_YES_LINEAR_STOKES, # method selector 4, # number of equations n, # number of input data points n, # number of output data points 10., # maximum optical depth; defused here (see comment above) max_step_size, # maximum absolute step size atol, # absolute tolerance rtol, # relative tolerance 1e-2, # "thin" parameter for DELO method ... to be researched max_steps, # maximum number of steps ) try: tau = np.zeros(n) radtrans_integrate.integrate(x[::-1], j, K, tau, 4) i = radtrans_integrate.intensity.copy() finally: # If we exit without calling this, the next init call causes an abort radtrans_integrate.del_radtrans_integrate_data() return i
def integrate_ray_formal(x, j, K): """Use `grtrans <https://github.com/jadexter/grtrans>`_ to integrate one ray using its "formal" (matricant / O-matrix) method. **Call signature** *x* 1D array, shape (n,). Path length along ray, starting from zero, in cm. *j* Array, shape (n, 4). Emission coefficients: ``j_{IQUV}``, in that order. *K* Array, shape (n, 7). Absorption coefficients and Faraday mixing coefficients: ``alpha_{IQUV}, rho_{QUV}``. Return value Array of shape (4, m): Stokes intensities ``IQUV`` along parts of the ray with non-zero total emissivities; m <= n. """ # A correct version of the fully-specified absorption matrix is in Leung+ # 2011 (10.1088/0004-637X/737/1/21). From looking at the function # `radtrans_jac_form` of grtrans' `radtrans_integrate.f90` file, one can # see that the K vector is indeed packed in the way described above. from radtrans_integrate import radtrans_integrate n = x.size # The formal method doesn't do the same kind of clipping as LSODA *inside* # grtrans, but here we do the same clipping for consistency, and since it # is genuinely true that the clipped samples are superfluous. if np.all(j[:, 0] == 0.): return np.zeros((4, n)) i0 = 0 i1 = n - 1 while j[i0, 0] == 0.: i0 += 1 while j[i1, 0] == 0.: i1 -= 1 n = i1 + 1 - i0 x = x[i0:i1 + 1] j = j[i0:i1 + 1] K = K[i0:i1 + 1] # OK we can go. radtrans_integrate.init_radtrans_integrate_data( METHOD_FORMAL, # method selector 4, # number of equations n, # number of input data points n, # number of output data points 10., # maximum optical depth; not used by "formal" 1., # maximum absolute step size; not used by "formal" 0.1, # absolute tolerance; not used by "formal" 0.1, # relative tolerance; not used by "formal" 1e-2, # "thin" parameter for DELO method; not used by "formal" 1, # maximum number of steps; not used by "formal" ) try: tau = x # not used by "formal" radtrans_integrate.integrate(x[::-1], j[::-1], K[::-1], tau[::-1], 4) i = radtrans_integrate.intensity.copy() finally: # If we exit without calling this, the next init call causes an abort radtrans_integrate.del_radtrans_integrate_data() return i
awidth = 0.1 agarr = np.tile(apeak,300).reshape(300,4)*np.exp(-(np.transpose(np.tile(x,4).reshape(4,300))-np.tile(apos,300).reshape(300,4))**2./2./awidth**2.) rhopeak = rhomean.copy()*3. rhopos = np.array([0.9,2.2,2.5]) rhowidth = 0.07 rhogarr = np.tile(rhopeak,300).reshape(300,3)*np.exp(-(np.transpose(np.tile(x,3).reshape(3,300))-np.tile(rhopos,300).reshape(300,3))**2./2./rhowidth**2.) ig,Qg,Pg,img,deltag,dxg,QQg,PPg,immg,itg = analytic_pol_rad_trans.delo_intensity(dx=(np.zeros(300-1)+1e-2),a=agarr,I0=np.array([0.,0.,0.,0.]),rho=rhogarr,j=jarr) isin,Qsin,Psin,imsin,deltasin,dxsin,QQsin,PPsin,immsin,itsin = analytic_pol_rad_trans.delo_intensity(dx=(np.zeros(300-1)+1e-2),a=asinarr,I0=np.array([0.,0.,0.,0.]),rho=rhosinarr,j=jsinarr,thin=1e-2) Karr = np.append(agarr,rhogarr,axis=1) tau = np.append(0.,scipy.integrate.cumtrapz(Karr[:,0],x)) radtrans_integrate.integrate(x[::-1],jarr[:,:],Karr[:,:],tau,4) iglsoda = radtrans_integrate.intensity.copy() Karr = np.append(asinarr,rhosinarr,axis=1) tau = np.append(0.,scipy.integrate.cumtrapz(Karr[:,0],x)) radtrans_integrate.integrate(x[::-1],jsinarr[:,:],Karr[:,:],tau,4) isinlsoda = radtrans_integrate.intensity.copy() radtrans_integrate.del_radtrans_integrate_data() radtrans_integrate.init_radtrans_integrate_data(1,4,300,300,10.,0.1,1e-8,1e-6,1e-2) radtrans_integrate.integrate(x[::-1],jsinarr[:,:],Karr[:,:],tau,4) isindelo = radtrans_integrate.intensity.copy() Karr = np.append(agarr,rhogarr,axis=1) tau = np.append(0.,scipy.integrate.cumtrapz(Karr[:,0],x)) radtrans_integrate.integrate(x[::-1],jarr[:,:],Karr[:,:],tau,4) igdelo = radtrans_integrate.intensity.copy() Karr = (np.append(aarr,rhoarr,axis=1)) tau = np.append(0.,scipy.integrate.cumtrapz(Karr[:,0],x)) radtrans_integrate.integrate(x[::-1],jarr[:,:],Karr[:,:],tau,4) istepdelo = radtrans_integrate.intensity.copy() radtrans_integrate.del_radtrans_integrate_data()
def run(abs=1, far=1, bfar=1, save=0): # do strong FR test with emission and compare to analytic solution for LSODA, DELO, FORMAL methods x = np.cumsum(np.zeros(3000) + 1e-2) - 1e-2 rhoarr = np.zeros((3000, 3)) rhoarr[:, 2] = 10. #; rhoarr[:,1]=-4. jarr = np.tile(np.array([1., 0.7, 0., 0.]), 3000).reshape(3000, 4) #a = np.array([10.,4.,1.,7.]) #a2 = np.array([5.,3.,2.,1.]) #a2arr = np.tilbe(a2,150).reshape(150,4) aarr = np.zeros((3000, 4)) #aarr = np.append(a2arr/3.,3.*aarr,axis=0) Karr = (np.append(aarr, rhoarr, axis=1)) tau = np.append(0., scipy.integrate.cumtrapz(Karr[:, 0], x)) radtrans_integrate.init_radtrans_integrate_data(0, 4, 3000, 3000, 10., 0.1, 1e-8, 1e-6, 1e-2) radtrans_integrate.integrate(x[::-1], jarr[:, :], Karr[:, :], tau, 4) ilb = radtrans_integrate.intensity.copy() radtrans_integrate.del_radtrans_integrate_data() radtrans_integrate.init_radtrans_integrate_data(1, 4, 3000, 3000, 10., 0.1, 1e-8, 1e-6, 1e-2) radtrans_integrate.integrate(x[::-1], jarr[:, :], Karr[:, :], tau, 4) idb = radtrans_integrate.intensity.copy() radtrans_integrate.del_radtrans_integrate_data() radtrans_integrate.init_radtrans_integrate_data(2, 4, 3000, 3000, 10., 0.1, 1e-8, 1e-6, 1e-2) radtrans_integrate.integrate(x[::-1], jarr[:, :], Karr[:, :], tau, 4) ifb = radtrans_integrate.intensity.copy() radtrans_integrate.del_radtrans_integrate_data() # analytic solution ii = jarr[:, 0] * x iu = jarr[:, 1] / rhoarr[:, 2] * (1. - np.cos(x * rhoarr[:, 2])) iq = jarr[:, 1] / rhoarr[:, 2] * np.sin(x * rhoarr[:, 2]) print np.shape(iu), np.shape(jarr), np.shape(ifb) print 'max error faraday basic lsoda: ', np.max( np.abs(ii - ilb[0, :])), np.max(np.abs(iq - ilb[1, :])), np.max( np.abs(iu - ilb[2, :])) print 'max error faraday basic formal: ', np.max( np.abs(ii - ifb[0, :])), np.max(np.abs(iq - ifb[1, :])), np.max( np.abs(iu - ifb[2, :])) print 'max error faraday basic delo: ', np.max( np.abs(ii - idb[0, :])), np.max(np.abs(iq - idb[1, :])), np.max( np.abs(iu - idb[2, :])) # now with both Faraday rotation and conversion rhoarr[:, 0] = -4. rhoarr[:, 2] = 10. aarr[:, :] = 0. jarr[:, :] = 0. jarr[:, 0] = 1e-8 jarr[:, 1] = 0.1 jarr[:, 3] = 0.1 jarr[:, 2] = 0.1 Karr = (np.append(aarr, rhoarr, axis=1)) radtrans_integrate.init_radtrans_integrate_data(0, 4, 3000, 3000, 10., 0.1, 1e-8, 1e-6, 1e-2) radtrans_integrate.integrate(x[::-1], jarr[:, :], Karr[:, :], tau, 4) ilf = radtrans_integrate.intensity.copy() radtrans_integrate.del_radtrans_integrate_data() radtrans_integrate.init_radtrans_integrate_data(1, 4, 3000, 3000, 10., 0.1, 1e-8, 1e-6, 1e-2) radtrans_integrate.integrate(x[::-1], jarr[:, :], Karr[:, :], tau, 4) idf = radtrans_integrate.intensity.copy() radtrans_integrate.del_radtrans_integrate_data() radtrans_integrate.init_radtrans_integrate_data(2, 4, 3000, 3000, 10., 0.1, 1e-8, 1e-6, 1e-2) radtrans_integrate.integrate(x[::-1], jarr[:, :], Karr[:, :], tau, 4) iff = radtrans_integrate.intensity.copy() radtrans_integrate.del_radtrans_integrate_data() # analytic solution ii = jarr[:, 0] * x iq, iu, iv = analytic_radtrans_faraday(jarr[:, 1], jarr[:, 2], jarr[:, 3], rhoarr[:, 0], rhoarr[:, 2], x) print np.shape(iu), np.shape(jarr), np.shape(iff) print 'max error faraday lsoda: ', np.max(np.abs(ii - ilf[0, :])), np.max( np.abs(iq - ilf[1, :])), np.max(np.abs(iu - ilf[2, :])), np.max( np.abs(iv - ilf[3, :])) print 'max error faraday formal: ', np.max(np.abs(ii - iff[0, :])), np.max( np.abs(iq - iff[1, :])), np.max(np.abs(iu - iff[2, :])), np.max( np.abs(iv - iff[3, :])) print 'max error faraday delo: ', np.max(np.abs(ii - idf[0, :])), np.max( np.abs(iq - idf[1, :])), np.max(np.abs(iu - idf[2, :])), np.max( np.abs(iv - idf[3, :])) # with rhou as well rhoarr[:, 0] = -4. rhoarr[:, 2] = 100. rhoarr[:, 1] = 7. rhoarr *= 1000. aarr[:, :] = 0. jarr[:, :] = 0. jarr[:, 0] = 1e-8 jarr[:, 1] = 0.1 jarr[:, 3] = 0.1 jarr[:, 2] = 0.1 Karr = (np.append(aarr, rhoarr, axis=1)) radtrans_integrate.init_radtrans_integrate_data(0, 4, 3000, 3000, 10., 0.1, 1e-8, 1e-6, 1e-2) radtrans_integrate.integrate(x[::-1], jarr[:, :], Karr[:, :], tau, 4) ilf2 = radtrans_integrate.intensity.copy() radtrans_integrate.del_radtrans_integrate_data() radtrans_integrate.init_radtrans_integrate_data(1, 4, 3000, 3000, 10., 0.1, 1e-8, 1e-6, 1e-2) radtrans_integrate.integrate(x[::-1], jarr[:, :], Karr[:, :], tau, 4) idf2 = radtrans_integrate.intensity.copy() radtrans_integrate.del_radtrans_integrate_data() radtrans_integrate.init_radtrans_integrate_data(2, 4, 3000, 3000, 10., 0.1, 1e-8, 1e-6, 1e-2) radtrans_integrate.integrate(x[::-1], jarr[:, :], Karr[:, :], tau, 4) iff2 = radtrans_integrate.intensity.copy() radtrans_integrate.del_radtrans_integrate_data() # analytic solution ii = jarr[:, 0] * x iq, iu, iv = analytic_radtrans_faraday_full(jarr[:, 1], jarr[:, 2], jarr[:, 3], rhoarr[:, 0], rhoarr[:, 1], rhoarr[:, 2], x) print np.shape(iu), np.shape(jarr), np.shape(iff2) print 'max error faraday full lsoda: ', np.max( np.abs(ii - ilf2[0, :])), np.max(np.abs(iq - ilf2[1, :])), np.max( np.abs(iu - ilf2[2, :])), np.max(np.abs(iv - ilf2[3, :])) print 'max error faraday full formal: ', np.max( np.abs(ii - iff2[0, :])), np.max(np.abs(iq - iff2[1, :])), np.max( np.abs(iu - iff2[2, :])), np.max(np.abs(iv - iff2[3, :])) print 'max error faraday full delo: ', np.max( np.abs(ii - idf2[0, :])), np.max(np.abs(iq - idf2[1, :])), np.max( np.abs(iu - idf2[2, :])), np.max(np.abs(iv - idf2[3, :])) # now do strong absorption test with emission the same way aarr[:, 0] = 5. aarr[:, 1] = 4. jarr[:, :] = 0. jarr[:, 0] = 1. jarr[:, 1] = 0.8 rhoarr[:, :] = 0. Karr = (np.append(aarr, rhoarr, axis=1)) tau = np.append(0., scipy.integrate.cumtrapz(Karr[:, 0], x)) radtrans_integrate.init_radtrans_integrate_data(0, 4, 3000, 3000, 2000., 0.1, 1e-8, 1e-6, 1e-2) radtrans_integrate.integrate(x[::-1], jarr[:, :], Karr[:, :], tau, 4) ila = radtrans_integrate.intensity.copy() radtrans_integrate.del_radtrans_integrate_data() radtrans_integrate.init_radtrans_integrate_data(1, 4, 3000, 3000, 10., 0.1, 1e-8, 1e-6, 1e-2) radtrans_integrate.integrate(x[::-1], jarr[:, :], Karr[:, :], tau, 4) ida = radtrans_integrate.intensity.copy() radtrans_integrate.del_radtrans_integrate_data() radtrans_integrate.init_radtrans_integrate_data(2, 4, 3000, 3000, 10., 0.1, 1e-8, 1e-6, 1e-2) radtrans_integrate.integrate(x[::-1], jarr[:, :], Karr[:, :], tau, 4) ifa = radtrans_integrate.intensity.copy() radtrans_integrate.del_radtrans_integrate_data() # analytic solution ii, iqq = analytic_radtrans_absorption(jarr[:, 0], jarr[:, 1], aarr[:, 0], aarr[:, 1], x) #iu = jarr[:,1]/rhoarr[:,2]*(1.-np.cos(x*rhoarr[:,2])) #iq = jarr[:,1]/rhoarr[:,2]*np.sin(x*rhoarr[:,2]) print np.shape(iu), np.shape(jarr), np.shape(ifa) print 'max error absorption lsoda: ', np.max( np.abs(ii - ila[0, :])), np.max(np.abs(iqq - ila[1, :])) print 'max error absorption formal: ', np.max( np.abs(ii - ifa[0, :])), np.max(np.abs(iqq - ifa[1, :])) print 'max error absorption delo: ', np.max( np.abs(ii - ida[0, :])), np.max(np.abs(iqq - ida[1, :])) if save == 1: analytic = np.array([iq, iu, iv, ii, iqq, x]) num = np.append( np.append(np.append(np.append(np.append(ilf, idf), iff), ila), ida), ifa) np.savetxt('unit_tests_integration_output_analytic.txt', analytic) np.savetxt('unit_tests_integration_output_num.txt', num) return ilb, idb, ifb, ilf, idf, iff, ila, ida, ifa, ilf2, idf2, iff2, iq, iu, iv