Beispiel #1
0
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
Beispiel #2
0
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
import scipy.integrate
import matplotlib.pyplot as plt
import analytic_pol_rad_trans
plt.ion()
from radtrans_integrate import radtrans_integrate
rhoarr = np.zeros((300, 3))
jarr = np.tile(np.array([1., 0., 0., 0.]), 300).reshape(300, 4)
a = np.array([10., 4., 1., 7.])
a2 = np.array([5., 3., 2., 1.])
a2arr = np.tile(a2, 150).reshape(150, 4)
aarr = np.tile(a, 150).reshape(150, 4)
aarr = np.append(a2arr / 3., 3. * aarr, axis=0)
Karr = (np.append(aarr, rhoarr, axis=1))
x = np.cumsum(np.zeros(300) + 1e-2)
tau = np.append(0., scipy.integrate.cumtrapz(Karr[:, 0], x))
radtrans_integrate.init_radtrans_integrate_data(0, 4, 300, 300, 10., 0.1, 1e-8,
                                                1e-6, 1e-2)
radtrans_integrate.integrate(x[::-1], jarr[:, :], Karr[:, :], tau, 4)
isteplsoda = radtrans_integrate.intensity.copy()
istep, Qstep, Pstep, imstep, deltastep, dxstep, QQstep, PPstep, immstep, itstep = analytic_pol_rad_trans.delo_intensity(
    dx=(np.zeros(300 - 1) + 1e-2),
    a=aarr,
    I0=np.array([0., 0., 0., 0.]),
    rho=rhoarr,
    j=jarr,
    thin=1e-2)
jmean = 1.
jsinarr = jmean + 0.5 * np.sin(
    2. * np.arccos(-1.) * np.transpose(np.tile(x, 4).reshape(4, 300)) / 0.6)
amean = np.array([1., 0.3, 0.6, 0.2])
asinarr = np.tile(amean, 300).reshape(300, 4)
asinarr = asinarr + 0.5 * np.sin(
Beispiel #4
0
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
Beispiel #5
0
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
import scipy.integrate
import matplotlib.pyplot as plt
import analytic_pol_rad_trans
plt.ion()
from radtrans_integrate import radtrans_integrate
rhoarr = np.zeros((300,3))
jarr = np.tile(np.array([1.,0.,0.,0.]),300).reshape(300,4)
a = np.array([10.,4.,1.,7.])
a2 = np.array([5.,3.,2.,1.])
a2arr = np.tile(a2,150).reshape(150,4)
aarr = np.tile(a,150).reshape(150,4)
aarr = np.append(a2arr/3.,3.*aarr,axis=0)
Karr = (np.append(aarr,rhoarr,axis=1))
x = np.cumsum(np.zeros(300)+1e-2)
tau = np.append(0.,scipy.integrate.cumtrapz(Karr[:,0],x))
radtrans_integrate.init_radtrans_integrate_data(0,4,300,300,10.,0.1,1e-8,1e-6,1e-2)
radtrans_integrate.integrate(x[::-1],jarr[:,:],Karr[:,:],tau,4)
isteplsoda = radtrans_integrate.intensity.copy()
istep,Qstep,Pstep,imstep,deltastep,dxstep,QQstep,PPstep,immstep,itstep = analytic_pol_rad_trans.delo_intensity(dx=(np.zeros(300-1)+1e-2),a=aarr,I0=np.array([0.,0.,0.,0.]),rho=rhoarr,j=jarr,thin=1e-2)
jmean = 1.
jsinarr = jmean + 0.5*np.sin(2.*np.arccos(-1.)*np.transpose(np.tile(x,4).reshape(4,300))/0.6)
amean = np.array([1.,0.3,0.6,0.2])
asinarr = np.tile(amean,300).reshape(300,4)
asinarr = asinarr + 0.5*np.sin(2.*np.arccos(-1.)*np.transpose(np.tile(x,4).reshape(4,300))/0.6)
rhomean = np.array([-0.4,0.4,0.1])
rhosinarr = np.tile(rhomean,300).reshape(300,3)
rhosinarr = rhosinarr + 0.2*np.sin(2.*np.arccos(-1.)*np.transpose(np.tile(x,3).reshape(3,300))/0.75)
apos = np.array([0.5,1.2,2.6,1.4])
apeak = amean.copy()*3.
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.)
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