Exemple #1
0
def test_annulus():
    """
    Tests annulus function vs explicit annulus formula up to L=5. Full annulus.
    """
    qcyl = qlm.annulus(5, 1, 1, 2, 3, 0, np.pi)
    qcyl2 = qlmA.annulus(5, 1/(5*np.pi), 1, 2, 3, 0, np.pi)
    assert (abs(qcyl-qcyl2) < 30*np.finfo(float).eps).all()
Exemple #2
0
def test_cylinder2():
    """
    Tests recursive cylinder function vs annulus formula up to L=10. That is
    the annulus formula should be consistent with the recursive cylinder
    calculation.
    """
    qcyl = qlm.cylinder(10, 1, 1, 1)
    qcyl2 = qlm.annulus(10, 1, 1, 0, 1, 0, np.pi)
    assert (abs(qcyl-qcyl2) < 10*np.finfo(float).eps).all()
Exemple #3
0
 def __init__(self, N, lmax, inner, mass, H, Ri, Ro, phic, phih):
     Shape.__init__(self, N, lmax, inner)
     self.mass = mass
     if self.inner:
         self.qlm = qlm.annulus(lmax, mass, H, Ri, Ro, phic, phih)
     else:
         dens = mass/(2*phih*(Ro**2 - Ri**2)*H)
         self.qlm = bqlm.annulus(lmax, dens, H/2, Ri, Ro, phic, phih)
         self.qlm += bqlm.annulus(lmax, dens, -H/2, Ri, Ro, phic, phih)
     self.pointmass = gshp.wedge(mass, Ri, Ro, H, phih, N, N)
     self.pointmass = glb.rotate_point_array(self.pointmass, phic,
                                             [0, 0, 1])
Exemple #4
0
def test_annulus2():
    """
    Tests annulus function vs explicit annulus formula up to L=5. Partial.
    """
    qcyl = qlm.annulus(5, 1, 1, 2, 3, np.pi/3, np.pi/8)
    rho = 8/(np.pi*(3**2-2**2))
    qcyl2 = qlmA.annulus(5, rho, 1, 2, 3, np.pi/3, np.pi/8)
    assert (abs(qcyl-qcyl2) < 90*np.finfo(float).eps).all()
    qcyl3 = qlmN.cyl_mom(5, rho, np.pi/8, 2, 3, -.5, .5)
    qcyl3 = rot.rotate_qlm(qcyl3, np.pi/3, 0, 0)
    assert (abs(qcyl-qcyl2) < 90*np.finfo(float).eps).all()
    # Test explicit formula for L<5 (we'll do L=3)
    qcyl2 = qlmA.annulus(3, rho, 1, 2, 3, np.pi/3, np.pi/8)
    assert (np.shape(qcyl2) == (4, 7))
Exemple #5
0
def read_mpc(LMax, filename, filepath='C:\\mpc\\'):
    """
    Attempts to open .mpc files in the same manner as MULTIN by having a
    'working register' and a 'total register'. That is, there are two sets of
    moments stored in memory. One is the sum of all the previous moments
    (total) and the other is the current shape (working) being manipulated. The
    working shape can be rotated, translated, and added to total sequentially
    many times. This function does not allow the use of 'recall', 'store',
    'rescale', or 'save' statements currently. Takes an optional filepath which
    is assumed to be the standard filepath for MULTIN, 'C:\\mpc\\'.

    Inputs
    ------
    LMax : int
        Highest degree inner multipole moments to compute
    filename : str
        Name of .mpc file (with or without extension)
    filepath : str, optional
        Directory containing .mpc file, assumed 'C:\\mpc\\' in MULTIN

    Returns
    -------
    qlmTot : ndarray, complex
        Complex (LMax+1)x(2LMax + 1) array of inner multipole coefficients
    """
    if not filename.endswith('.mpc'):
        filename += '.mpc'
    with open(filepath + filename) as f:
        lines = f.readlines()
    title = lines[0]
    print(title)
    # We don't actually use n integration in this
    nsteps = 25
    # Assume units are centimeters unless told otherwise
    fac = 1e-2
    nlines = len(lines[1:])
    qlmTot = np.zeros([LMax + 1, 2 * LMax + 1], dtype='complex')
    qlmWrk = np.zeros([LMax + 1, 2 * LMax + 1], dtype='complex')
    k = 0
    while k < nlines:
        line = lines[1 + k]
        # Get rid of stuff after a comment
        line = line.split('%')[0]
        if 'create' in line:
            print(line)
            shape = line.split('create')[1].split()[0]
            if shape == 'cylinder':
                line2 = [float(val) for val in lines[2 + k].split(',')]
                Ri, Ro, H, phi0, phi1 = line2
                Ri, Ro, H = Ri * fac, Ro * fac, H * fac
                phic = (phi1 + phi0) * np.pi / 180 / 2
                phih = (phi1 - phi0) * np.pi / 180 / 2
                dens = float(lines[3 + k].split(',')[0]) * 1000
                mass = dens * phih * H * (Ro**2 - Ri**2)
                print(dens, line2)
                qlmWrk = qlm.annulus(LMax, mass, H, Ri, Ro, phic, phih)
                pos = np.array(lines[4 + k].split(','), dtype=float) * fac
                k += 3
                if (pos == 0).all() and ('add' in lines[2 + k]):
                    k += 1
                    print('added ', shape)
                    qlmTot += qlmWrk
                else:
                    print('translated ', shape)
                    qlmWrk = trs.translate_qlm(qlmWrk, pos)
            elif shape == 'sphere':
                line2 = [float(val) * fac for val in lines[2 + k].split(',')]
                r = line2[0]
                dens = float(lines[3 + k].split(',')[0]) * 1000
                mass = dens * 4 / 3 * np.pi * r**3
                qlmWrk = qlm.sphere(LMax, mass, r)
                pos = np.array(lines[4 + k].split(','), dtype=float) * fac
                k += 3
                if (pos == 0).all() and ('add' in lines[2 + k]):
                    k += 1
                    print('added ', shape)
                    qlmTot += qlmWrk
                else:
                    print('translated ', shape)
                    qlmWrk = trs.translate_qlm(qlmWrk, pos)
            elif shape == 'cone':
                line2 = [float(val) * fac for val in lines[2 + k].split(',')]
                LR, UR, H = line2
                dens = float(lines[3 + k].split(',')[0]) * 1000
                mass = dens * np.pi * H * LR**2 / 3
                print(LR, UR, H, dens, mass)
                qlmWrk = qlm.cone(LMax, mass, H, LR, 0, np.pi)
                pos = np.array(lines[4 + k].split(','), dtype=float) * fac
                k += 3
                if (pos == 0).all() and ('add' in lines[2 + k]):
                    k += 1
                    print('added ', shape)
                    qlmTot += qlmWrk
                else:
                    print('translated ', shape)
                    qlmWrk = trs.translate_qlm(qlmWrk, pos)
            elif shape == 'triangle':
                line2 = [float(val) * fac for val in lines[2 + k].split(',')]
                d, y1, y2, t = line2
                dens = float(lines[3 + k].split(',')[0]) * 1000
                mass = dens * t * d * abs(y2 - y1) / 2
                qlmWrk = qlm.tri_prism(LMax, mass, t, d, y1, y2)
                pos = np.array(lines[4 + k].split(','), dtype=float) * fac
                k += 3
                if (pos == 0).all() and ('add' in lines[2 + k]):
                    k += 1
                    print('added ', shape)
                    qlmTot += qlmWrk
                else:
                    print('translated ', shape)
                    qlmWrk = trs.translate_qlm(qlmWrk, pos)
            elif shape == 'trapezoid':
                line2 = [float(val) * fac for val in lines[2 + k].split(',')]
                w1, w2, h, t = line2
                if w2 < w1:
                    w3, w4 = w2, w1
                    flip = True
                else:
                    w3, w4 = w1, w2
                    flip = False
                dens = float(lines[3 + k].split(',')[0]) * 1000
                y1, y2 = w3 / 2, w4 / 2
                hs = w3 * h / (w4 - w3)
                hb = h + hs
                massTrib = dens * t * w4 * hb / 2
                massTris = dens * t * w3 * hs / 2
                print(hs, hb, w3, w4)
                qlmWrk = qlm.tri_iso_prism(LMax, massTrib, t, w4, hb, 0)
                qlmWrk -= qlm.tri_iso_prism(LMax, massTris, t, w3, hs, 0)
                qlmWrk = trs.translate_qlm(qlmWrk, [-hs, 0, 0])
                if flip:
                    qlmWrk = trs.translate_qlm(qlmWrk, [-(hb - hs), 0, 0])
                    qlmWrk = rot.rotate_qlm(qlmWrk, 0, 0, np.pi)
                pos = np.array(lines[4 + k].split(','), dtype=float) * fac
                k += 3
                if (pos == 0).all() and ('add' in lines[2 + k]):
                    k += 1
                    print('added ', shape)
                    qlmTot += qlmWrk
                else:
                    print('translated ', shape)
                    qlmWrk = trs.translate_qlm(qlmWrk, pos)
            elif shape == 'partcylinder':
                line2 = [float(val) * fac for val in lines[2 + k].split(',')]
                r, d, h = line2
                dens = float(lines[3 + k].split(',')[0]) * 1000
                phih = np.arccos(d / r)
                massCyl = dens * h * phih * r**2
                massTri = dens * h * d * r * np.sin(phih)
                qlmWrk = qlm.annulus(LMax, massCyl, h, 0, r, 0, phih)
                qlmWrk -= qlm.tri_iso_prism2(LMax, massTri, h, r, 0, phih)
                pos = np.array(lines[4 + k].split(','), dtype=float) * fac
                k += 3
                if (pos == 0).all() and ('add' in lines[2 + k]):
                    k += 1
                    print('added ', shape)
                    qlmTot += qlmWrk
                else:
                    print('translated ', shape)
                    qlmWrk = trs.translate_qlm(qlmWrk, pos)
            elif shape == 'tetrahedron':
                line2 = [float(val) * fac for val in lines[2 + k].split(',')]
                x, y, z = line2
                dens = float(lines[3 + k].split(',')[0]) * 1000
                mass = dens * x * y * z / 6
                qlmWrk = qlm.tetrahedron(LMax, mass, x, y, z)
                pos = np.array(lines[4 + k].split(','), dtype=float) * fac
                k += 3
                if (pos == 0).all() and ('add' in lines[2 + k]):
                    k += 1
                    print('added ', shape)
                    qlmTot += qlmWrk
                else:
                    print('translated ', shape)
                    qlmWrk = trs.translate_qlm(qlmWrk, pos)
            elif shape == 'platehole':
                line2 = [float(val) for val in lines[2 + k].split(',')]
                r, t, theta = line2
                t, r = t * fac, r * fac
                theta *= np.pi / 180
                dens = float(lines[3 + k].split(',')[0]) * 1000
                qlmWrk = qlmA.platehole(LMax, dens, t, r, theta)
                # qlmWrk = qlmN.platehole(LMax, dens, t, r, theta)
                # qlmWrk = rot.rotate_qlm(qlmWrk, 0, theta, 0)
                pos = np.array(lines[4 + k].split(','), dtype=float) * fac
                k += 3
                if (pos == 0).all() and ('add' in lines[2 + k]):
                    k += 1
                    print('added ', shape)
                    qlmTot += qlmWrk
                else:
                    print('translated ', shape)
                    qlmWrk = trs.translate_qlm(qlmWrk, pos)
            elif shape == 'cylhole':
                line2 = [float(val) * fac for val in lines[2 + k].split(',')]
                r, R = line2
                dens = float(lines[3 + k].split(',')[0]) * 1000
                qlmWrk = qlmN.steinmetz(LMax, dens, r, R)
                qlmWrk = rot.rotate_qlm(qlmWrk, np.pi / 2, 0, 0)
                pos = np.array(lines[4 + k].split(','), dtype=float) * fac
                k += 3
                if (pos == 0).all() and ('add' in lines[2 + k]):
                    k += 1
                    print('added ', shape)
                    qlmTot += qlmWrk
                else:
                    print('translated ', shape)
                    qlmWrk = trs.translate_qlm(qlmWrk, pos)
            elif shape == 'pyramid':
                line2 = [float(val) * fac for val in lines[2 + k].split(',')]
                x, y, z = line2
                dens = float(lines[3 + k].split(',')[0]) * 1000
                mass = dens * x * y * z / 3
                qlmWrk = qlm.pyramid(LMax, mass, x / 2, y / 2, z)
                pos = np.array(lines[4 + k].split(','), dtype=float) * fac
                k += 3
                if (pos == 0).all() and ('add' in lines[2 + k]):
                    k += 1
                    print('added ', shape)
                    qlmTot += qlmWrk
                else:
                    print('translated ', shape)
                    qlmWrk = trs.translate_qlm(qlmWrk, pos)
            elif shape == 'rectangle':
                line2 = [float(val) * fac for val in lines[2 + k].split(',')]
                x, y, z = line2
                dens = float(lines[3 + k].split(',')[0]) * 1000
                mass = dens * x * y * z
                qlmWrk = qlm.rect_prism(LMax, mass, z, x, y, 0)
                pos = np.array(lines[4 + k].split(','), dtype=float) * fac
                k += 3
                if (pos == 0).all() and ('add' in lines[2 + k]):
                    k += 1
                    print('added ', shape)
                    qlmTot += qlmWrk
                else:
                    print('translated ', shape)
                    qlmWrk = trs.translate_qlm(qlmWrk, pos)
            else:
                print(shape, ' does not have a known set of moments')
                for n in range(nlines - k):
                    line2 = lines[1 + k + 1]
                    if ('create' not in line2) and ('end' not in line2):
                        k += 1
                    else:
                        break
        elif 'rotate' in line:
            dphi = np.array(line.split('rotate')[1].split(','), dtype=float)
            # Convert to radians
            dphi *= np.pi / 180
            print('rotated ', shape)
            qlmWrk = rot.rotate_qlm(qlmWrk, dphi[0], dphi[1], dphi[2])
        elif 'translate' in line:
            print('translated ', shape)
            dr = np.array(line.split('translate')[1].split(','), dtype=float)
            dr *= fac
            qlmWrk = trs.translate_qlm(qlmWrk, dr)
        elif 'add' in line:
            print('added ', shape)
            qlmTot += qlmWrk
        elif 'cmin' in line:
            print('parameters in centimeters')
            fac = 1e-2
        elif 'inchin' in line:
            print('parameters in inches')
            fac = 25.4e-3
        elif 'nsteps' in line:
            nsteps = line.split()[-1]
        elif 'load' in line:
            fname = line.split('load ')[1]
            fname = fname.strip()
            print(fname)
            qlmLoad = read_gsq(fname, filepath.replace('mpc', 'mom'))
            if np.shape(qlmLoad) != np.shape(qlmWrk):
                raise TypeError('Loaded part ' + fname + ' has wrong LMax')
            qlmWrk = qlmLoad
            shape = fname
        elif 'zeroqlm' in line:
            qlmTot *= 0
        elif 'gettotal' in line:
            qlmWrk = np.copy(qlmTot)
            shape = 'Total'
        elif 'puttotal' in line:
            qlmTot = np.copy(qlmWrk)
            shape = 'Working'
        elif 'end' in line:
            print('end')
            break
        k += 1
    return qlmTot
Exemple #6
0
beta = np.pi / 8
dens = 2800  # kg/m^3, 7075 T6 aluminum
mc = dens * 2 * beta * (orc**2 - irc**2) * hc
r3 = .10478
r2 = .06033
mtm = 39.658
htm = .20  # 20cm thickness
rtm = .35 / 2  # 35cm diam
d = 1.32  # m
phi = 0.241  # radian
dx = d * np.cos(phi)
dy = d * np.sin(phi)
LMax = 10

# Create some rotating test-masses
arc = qlm.annulus(LMax, mc / 2, hc, irc, orc, 0, beta)
arc2 = rot.rotate_qlm(arc, np.pi, 0, 0)
arctot = arc + arc2

# create a test-mirror
tm = qlm.cylinder(LMax, mtm, htm, rtm)
tm = rot.rotate_qlm(tm, np.pi / 2, np.pi / 2, -np.pi / 2)
tm = trs.translate_q2Q(tm, [dx, dy, 0])

# Figure out the force at different rotor angles
nAng = 120
forces = np.zeros([nAng, 3], dtype='complex')
nlm, nc, ns = mplb.torque_lm(LMax, arctot, tm)
dphi = 2 * np.pi / nAng
# Now rotate the cylindrical test-masses through various angles and calculate
# the forces