Esempio n. 1
0
 def AssembleNonLinearTerms(self):
     print("Assembling Non-Linear terms...")
     starttime = ti.time()
     i = 0
     w = self.w
     phi = self.phi
     dxphi = self.dxphi
     dyphi = self.dyphi
     A = syp.MutableDenseNDimArray(zeros((self.N, self.N)))
     B = syp.MutableDenseNDimArray(zeros((self.N, self.N)))
     while i < self.N:
         weight_func = w[i]
         for j in range(self.N):
             phi1 = phi[j]
             for k in range(self.N):
                 A[i, j] += self.a_sym[k] * integrate(
                     weight_func * phi1 * dxphi[k] * self.orthW, self.wx,
                     self.x_int, self.wy, self.y_int)
                 B[i, j] += self.a_sym[k] * integrate(
                     weight_func * phi1 * dyphi[k] * self.orthW, self.wx,
                     self.x_int, self.wy, self.y_int)
         i += 1
     print("Done")
     print("that took:",
           ti.time() - starttime, "s")
     return syp.lambdify([self.a_sym], A), syp.lambdify([self.a_sym], B)
 def AssembleNonLinearTerms(self):
     print("Assembling Non-Linear terms...")
     starttime = ti.time()
     i = 0
     w = array(self.w)
     phi = array(self.phi)
     dxphi = array(self.dxphi)
     dyphi = array(self.dyphi)
     A = syp.MutableDenseNDimArray(zeros((self.N, self.N)))
     B = syp.MutableDenseNDimArray(zeros((self.N, self.N)))
     while i < self.N:
         weight_func = w[i]
         for j in range(self.N):
             for k in range(self.N):
                 A[i, j] += self.a_sym[k] * integrate(
                     weight_func * dyphi[j] * dxphi[k] * self.orthW, wx,
                     x_int, wy, y_int)
                 B[i, j] += self.a_sym[k] * integrate(
                     weight_func * dxphi[j] * dyphi[k] * self.orthW, wx,
                     x_int, wy, y_int)
     #while i < self.N:
     #	weight_func = w[i];
     #	for j in range(self.N):
     #		A[i, j] = integrate(weight_func*syp.diff(self.phi[j], xi)*comm1, wx, x_int, wy, y_int);
     #		B[i, j] = integrate(weight_func*syp.diff(self.phi[j], yi)*comm2, wx, x_int, wy, y_int);
         i += 1
     print("Done")
     print("that took:",
           ti.time() - starttime, "s")
     return syp.lambdify([self.a_sym], A * c), syp.lambdify([self.a_sym],
                                                            B * c)
Esempio n. 3
0
 def Error_test_Momentum(self, mu):
     t_sym = syp.symbols("t_sym")
     fakeSolnx = syp.exp(-t_sym) * self.phi[0]
     fakeSolny = syp.exp(-t_sym) * self.phi[0]
     fx = syp.lambdify([self.x, self.y, t_sym], fakeSolnx, "numpy")
     fy = syp.lambdify([self.x, self.y, t_sym], fakeSolny, "numpy")
     SourceTermx = syp.diff(fakeSolnx, t_sym) + fakeSolnx * syp.diff(
         fakeSolnx, self.x) + fakeSolny * syp.diff(
             fakeSolnx,
             self.y) - mu * (syp.diff(syp.diff(fakeSolnx, self.x), self.x) +
                             syp.diff(syp.diff(fakeSolnx, self.y), self.y))
     SourceTermy = syp.diff(fakeSolny, t_sym) + fakeSolnx * syp.diff(
         fakeSolny, self.x) + fakeSolny * syp.diff(
             fakeSolny,
             self.y) - mu * (syp.diff(syp.diff(fakeSolny, self.x), self.x) +
                             syp.diff(syp.diff(fakeSolny, self.y), self.y))
     source_x = syp.MutableDenseNDimArray(zeros((1, self.N))[0])
     source_y = syp.MutableDenseNDimArray(zeros((1, self.N))[0])
     self.a_error[0, 0] = 1.0
     self.b_error[0, 0] = 1.0
     for i in range(self.N):
         source_x[i] = integrate(SourceTermx * self.phi[i] * self.orthW,
                                 self.wx, self.x_int, self.wy, self.y_int)
         source_y[i] = integrate(SourceTermy * self.phi[i] * self.orthW,
                                 self.wx, self.x_int, self.wy, self.y_int)
     return fx, fy, syp.lambdify([t_sym], source_x), syp.lambdify([t_sym],
                                                                  source_y)
Esempio n. 4
0
 def init_chr(self):
     """ Christoffel symbols of the metric. The first index is the upper index. """
     self.inv = self.tensor.inv() # Metric inverse
     chr = sp.MutableDenseNDimArray(np.zeros((self.dim,)*3)) # Initializing symbols
     dg = sp.MutableDenseNDimArray(np.zeros((self.dim,)*3)) # derivative of metric w.r.t. variables
     for mu in range(self.dim):
         dg[:,:,mu] = sp.diff(self.tensor, self.variables[mu])
     for nu in range(self.dim):
         chr[:,:,nu] = 1/2*( self.inv*dg[:,:,nu] + self.inv*dg[:,nu,:] - self.inv*(sp.Matrix(dg[:,nu,:]).transpose()))
     self.chr = sp.simplify(chr) # store christoffel symbols in object
Esempio n. 5
0
 def init_riemann(self):
     """ Riemann tensor of the metric, which is a 4-index tensor. """
     riemann = sp.MutableDenseNDimArray(np.zeros((self.dim,)*4)) # Inizializing 4-index tensor
     dchr = sp.MutableDenseNDimArray(np.zeros((self.dim,)*4)) # Derivative of Christoffel symbols
     if isinstance(self.chr, type(None)):
         self.init_chr() # Initialize Christoffel symbols (if not already done)
     for mu in range(self.dim):
         dchr[:,:,:,mu] = sp.diff(self.chr, self.variables[mu])
     for sigma in range(self.dim):
         for rho in range(self.dim):
             riemann[rho,sigma,:,:] = dchr[rho,:,sigma,:].transpose() - dchr[rho,:,sigma,:] \
                     + sp.tensorcontraction(sp.tensorproduct(self.chr[rho,:,:], self.chr[:,:,sigma]),(1,2)) \
                     - (sp.tensorcontraction(sp.tensorproduct(self.chr[rho,:,:], self.chr[:,:,sigma]),(1,2))).transpose()
     self.riemann = sp.simplify(riemann)
Esempio n. 6
0
        def as_array(self):
            dim = len(self.stencil[0])
            assert (dim == 2 or dim
                    == 3), "Only 2D or 3D matrix representations are available"
            max_offset = max(
                max(abs(e) for e in direction) for direction in self.stencil)
            shape_list = []
            for i in range(dim):
                shape_list.append(2 * max_offset + 1)

            number_of_elements = np.prod(shape_list)
            shape = tuple(shape_list)
            result = sp.MutableDenseNDimArray([0] * number_of_elements, shape)

            if dim == 2:
                for direction, weight in zip(self.stencil, self.weights):
                    result[max_offset - direction[1],
                           max_offset + direction[0]] = weight
            if dim == 3:
                for direction, weight in zip(self.stencil, self.weights):
                    result[max_offset - direction[1],
                           max_offset + direction[0],
                           max_offset + direction[2]] = weight

            return result
Esempio n. 7
0
    def __computeDDG(self):
        """ 
		G is a list of lenght (m) 
		this function calculates the double gradient of G 
		As we have (n) variables (X), the double gradient of G is: 
		[DDG]_{ijk} = d2(G_i)/d(X_j)d(X_k) 
		"""
        if self.G is None:
            self.DDG = None
            self._DDG0 = np.zeros((0, self.n, self.n))
            self.isDDGconst = True
        else:
            self.DDG = np.zeros((self.m, self.n, self.n))
            self.DDG = sp.MutableDenseNDimArray(self.DDG)
            for i, g in enumerate(self.G):
                for j, xj in enumerate(self.X):
                    for k, xk in enumerate(self.X):
                        self.DDG[i, j, k] = sp.diff(g, xj, xk)
            self.DDG = sp.Array(self.DDG)

            self.isDDGconst = isMatrixConstant(self.DDG, self.X)
            if not self.isDDGconst:
                self._DDG0 = None
            else:
                self._DDG0 = np.array(self.DDG, dtype="float32")
Esempio n. 8
0
 def init_ricci(self):
     """ Ricci tensor of the metric, which is a (dim x dim) tensor. """
     self.ricci = sp.MutableDenseNDimArray(np.zeros((self.dim,)*2))
     if isinstance(self.riemann, type(None)):
         self.init_riemann() # Initialize Riemann tensor (if not already done)
     for mu in range(self.dim):
         self.ricci += self.riemann[mu,:,mu,:] # Contracting first (upper) and third (lower) indices
     self.ricci = sp.Matrix(sp.simplify(self.ricci))
Esempio n. 9
0
 def __init__(self, basis_funcs, basis_funcs_p, weighting_funcs, x, y,
              int_vals, tn):
     self.phi = basis_funcs
     self.phi_p = basis_funcs_p
     self.w = weighting_funcs
     self.wx, self.x_int, self.wy, self.y_int = int_vals
     self.x = x
     self.y = y
     self.orthW = 1 / (syp.sqrt(1 - x**2) * syp.sqrt(1 - y**2))
     self.N = len(basis_funcs)
     # Number of basis functions
     self.a_sym = syp.symbols("a_sym0:%d" % self.N)
     self.b_sym = syp.symbols("b_sym0:%d" % self.N)
     self.UV = syp.lambdify([self.a_sym, self.x, self.y],
                            array(self.phi).dot(self.a_sym), 'numpy')
     P = array(self.phi_p).dot(self.a_sym)
     self.P = syp.lambdify([self.a_sym, self.x, self.y], P, 'numpy')
     self.a = zeros((self.N, tn))
     # Weights for u
     self.b = zeros((self.N, tn))
     # Weights for v
     self.a_error = zeros((self.N, tn))
     # Weights for u_error
     self.b_error = zeros((self.N, tn))
     # Weights for v_error
     self.p_error = zeros((self.N, tn))
     # Weights for p_error
     self.p = zeros((self.N, tn))
     # Weights for p
     self.p_error = zeros((self.N, tn))
     # Weights for p_error
     self.S_m = syp.MutableDenseNDimArray(zeros((1, self.N))[0])
     # Source Term for pressure
     self.S_mf = 0
     # Source Term function for pressure
     self.dxphi = [] * len(self.phi)
     # Derivatives of basis functions
     self.dxphi_p = [] * len(self.phi)
     self.dyphi = [] * len(self.phi)
     self.dyphi_p = [] * len(self.phi)
     print("Computing derivatives of basis functions")
     for i in range(len(self.phi)):
         self.dxphi.append(syp.diff(self.phi[i], x))
         self.dxphi_p.append(syp.diff(self.phi_p[i], x))
         self.dyphi.append(syp.diff(self.phi[i], y))
         self.dyphi_p.append(syp.diff(self.phi_p[i], y))
     print("Done")
     self.vorticity = syp.lambdify([self.a_sym, self.b_sym, self.x, self.y],
                                   array(self.dyphi).dot(self.a_sym) -
                                   array(self.dxphi).dot(self.b_sym),
                                   'numpy')
     self.grad_v = syp.lambdify([self.a_sym, self.b_sym, self.x, self.y],
                                array(self.dxphi).dot(self.a_sym) +
                                array(self.dyphi).dot(self.b_sym), "numpy")
Esempio n. 10
0
 def Error_test_Pressure(self):
     t_sym = syp.symbols("t_sym")
     fakeSoln = syp.exp(-t_sym) * self.phi_p[0]
     fP = syp.lambdify([self.x, self.y, t_sym], fakeSoln, "numpy")
     SourceTerm = syp.diff(fakeSoln, t_sym)
     source = syp.MutableDenseNDimArray(zeros((1, self.N))[0])
     self.p_error[0, 0] = 1
     for i in range(self.N):
         source[i] = integrate(SourceTerm * self.phi_p[i] * self.orthW,
                               self.wx, self.x_int, self.wy, self.y_int)
     return fP, syp.lambdify([t_sym], source, "numpy")
def exterior_derivative(f, basis):
    r"""

    :param f:
    :param basis:
    :return:
    """

    df = None

    # Handle the (0)-grade case
    if isinstance(f, sympy.Expr):
        n = len(basis)
        df = [0] * len(basis)
        for ii in range(n):
            df[ii] = sympy.diff(f, basis[ii])
        df = sympy.MutableDenseNDimArray(df)

    # Handle the (1+)-grade cases
    if isinstance(f, sympy.Array) or isinstance(f, sympy.Matrix) or isinstance(
            f, sympy.MutableDenseNDimArray):
        n = (len(basis), ) + f.shape
        df = sympy.MutableDenseNDimArray(sympy.zeros(*n))
        if len(n) == 2:
            for ii in range(df.shape[0]):
                for jj in range(df.shape[1]):
                    if ii == jj:
                        df[ii, jj] = 0

                    if ii < jj:
                        df[ii, jj] += sympy.diff(f[jj], basis[ii])
                        df[ii, jj] += -sympy.diff(f[ii], basis[jj])
                        df[jj, ii] += -sympy.diff(f[jj], basis[ii])
                        df[jj, ii] += sympy.diff(f[ii], basis[jj])

        # TODO Check if this is valid statement
        if len(n) > 2:
            raise NotImplementedError('Grade greater than 2 not implemeted')

    return df
def pb(f, g, prob):
    r"""

    :param f:
    :param g:
    :param prob:
    :return:
    """
    if f is None and g is not None:
        omega = prob.omega.tomatrix()
        h = sympy.MutableDenseNDimArray([0] * omega.shape[0])
        for i, states_i in enumerate(prob.states + prob.costates):
            for j, states_j in enumerate(prob.states + prob.costates):
                h[(i, )] += omega[i, j] * total_derivative(
                    g.expr, states_j.sym)

        return h
    raise NotImplementedError
def make_standard_symplectic_form(states, costates):
    r"""
    Makes the standard symplectic form.

    :param states: A list of state variables, :math:`x`.
    :param costates: A list of co-state variables, :math:`\lambda`.
    :return: :math:`\omega`, the standard symplectic form
    """
    if len(states) != len(costates):
        raise ValueError('Number of states and costates must be equal.')

    n = len(states)
    omega = sympy.zeros(2 * n, 2 * n)
    omega = sympy.MutableDenseNDimArray(omega)
    for ii in range(2 * n):
        for jj in range(2 * n):
            if jj - ii == n:
                omega[ii, jj] = 1
            if ii - jj == n:
                omega[ii, jj] = -1

    return omega
 def __init__(self, basis_funcs, weighting_funcs, x, y):
     self.phi = basis_funcs
     self.w = weighting_funcs
     self.N = len(basis_funcs)
     # Number of basis functions
     self.a_sym = syp.symbols("a_sym0:%d" % self.N)
     self.a = zeros((self.N, tn))
     # Weights for w
     self.b = zeros((self.N, tn))
     # Weights for psi
     self.S_m = syp.MutableDenseNDimArray(zeros((1, self.N)))
     # Source Term for Stream Function
     self.S_mf = 0
     # Source Term function for Stream Function
     self.dxphi = [] * len(self.phi)
     # Derivatives of basis functions
     self.dyphi = [] * len(self.phi)
     self.orthW = 1 / (syp.sqrt(1 - x**2) * syp.sqrt(1 - y**2))
     print("Computing derivatives of basis functions")
     for i in range(len(self.phi)):
         self.dxphi.append(syp.diff(self.phi[i], x))
         self.dyphi.append(syp.diff(self.phi[i], y))
     print("Done")
Esempio n. 15
0
    def Source(self):
        t_sym = syp.symbols("t_sym")
        a = 0.0001
        SourceTermx = (syp.exp(-t_sym**2 / a**2) + syp.exp(
            -(t_sym - 0.3)**2 / a**2) + syp.exp(-(t_sym - 0.6)**2 / a**2)) * (
                2 * self.phi[0] + 6.7 * self.phi[1] - 3.5 * self.phi[2] +
                1.4 * self.phi[3])
        source_x = syp.MutableDenseNDimArray(zeros((1, self.N))[0])
        for i in range(self.N):
            source_x[i] = integrate(SourceTermx * self.phi[i] * self.orthW,
                                    self.wx, self.x_int, self.wy, self.y_int)
        return syp.lambdify([t_sym], source_x, "numpy")

    #def SourceTerm(self, t):
    #	u = self.UV(self.a[:, t], x_mesh, y_mesh);
    #	v = self.UV(self.b[:, t], x_mesh, y_mesh);
    #	b = zeros_like(u);
    #	b[1: -1, 1: -1] = (rho*(1/dt*((u[1: -1, 2:] - u[1: -1, 0: -2])/(2*dx) + (v[2:, 1: -1] - v[0: -2, 1: -1])/(2*dy)) - ((u[1: -1, 2:] - u[1: -1, 0: -2])/(2*dx))**2 -
    #						2*((u[2:, 1: -1] - u[0: -2, 1: -1])/(2*dy)*(v[1: -1, 2:] - v[1: -1, 0: -2])/(2*dx)) - ((v[2:, 1: -1] - v[0: -2, 1: -1])/(2*dy))**2));
    #	return b;

    #def Pressure_Update(p, t, iter_max = 50):
    #	iter = 1;
    #	b = self.SourceTerm(t);
    #	while iter <= iter_max:
    #		pn = p.copy();
    #		p[1: -1, 1: -1] = (((pn[1: -1, 2:] + pn[1: -1, 0: -2])*dy**2 + (pn[2:, 1: -1] + pn[0: -2, 1: -1])*dx**2)/(2*(dx**2 + dy**2)) -
    #						dx**2*dy**2/(2*(dx**2 + dy**2))*b[1: -1, 1: -1]);

    #		# Wall BC
    #		p[:, -1] = p[:, -2];				# @ x = 1
    #		p[0, :] = p[1, :];					# @ y = -1
    #		p[:, 0] = p[:, 1];					# @ x = -1
    #		p[-1, :] = p[-2, :];				# @ y = 1
    #		iter += 1
    #	return p;
Esempio n. 16
0
#gdown = sym.diag(1/(1+u[0]**2+u[1]**2),1/(1+u[0]**2+u[1]**2))
#gdown = sym.diag(1/(1+u[0]**2+u[1]**2)**2,1/(1+u[0]**2+u[1]**2)**2)
#gdown = sym.Matrix([[1/(u[0]**2+u[1]**2+1), 1/(u[0]**2+u[1]**2+1)/2],[1/(u[0]**2+u[1]**2+1)/2, 1/(u[0]**2+u[1]**2+1)]])

gup = gdown**-1

detg = gdown.det()


def connection_down(i, j, k):
    return (sym.diff(gdown[i, j], u[k]) + sym.diff(gdown[i, k], u[j]) -
            sym.diff(gdown[j, k], u[i])) / 2


##allocate space to save connections
gam_down = sym.MutableDenseNDimArray(range(dim**3), shape=(dim, dim, dim))
gam_up = sym.MutableDenseNDimArray(range(dim**3), shape=(dim, dim, dim))

#compute connection \Gamma_{ijk}
for i in range(dim):
    for j in range(dim):
        for k in range(j + 1):
            gam_down[i, j, k] = connection_down(i, j, k)
            if (j != k):
                gam_down[i, k, j] = gam_down[i, j, k]


def connection_up(i, j, k):
    gam = 0
    for l in range(dim):
        gam += gam_down[l, j, k] * gup[l, i]
    def transformation(self, prob: Problem) -> Problem:
        if not is_symplectic(prob.omega):
            logging.warning('BVP is not symplectic. Skipping reduction.')
            return prob

        constant_of_motion = prob.constants_of_motion[self.com_index]

        state_syms = extract_syms(prob.states)
        costates_syms = extract_syms(prob.costates)
        parameter_syms = extract_syms(prob.parameters)
        constant_syms = extract_syms(prob.constants)

        fn_p = prob.lambdify(
            [state_syms, costates_syms, parameter_syms, constant_syms],
            constant_of_motion.expr)

        states_and_costates = prob.states + prob.costates

        atoms = constant_of_motion.expr.atoms()
        atoms2 = set()
        for atom in atoms:
            if isinstance(atom, sympy.Symbol) and (atom not in {
                    item.sym
                    for item in prob.parameters + prob.constants
            }):
                atoms2.add(atom)

        atoms = atoms2

        solve_for_p = sympy.solve(constant_of_motion.expr -
                                  constant_of_motion.sym,
                                  atoms,
                                  dict=True,
                                  simplify=False)

        if len(solve_for_p) > 1:
            raise ValueError

        parameter_index, symmetry, replace_p = 0, 0, None
        for parameter in solve_for_p[0].keys():
            symmetry, symmetry_unit = noether(prob, constant_of_motion)
            replace_p = parameter
            for idx, state in enumerate(states_and_costates):
                if state.sym == parameter:
                    parameter_index = idx
                    prob.parameters.append(
                        NamedDimensionalStruct(constant_of_motion.name,
                                               constant_of_motion.units))

        symmetry_index = parameter_index - len(prob.states)

        # Derive the quad
        # Evaluate int(pdq) = int(PdQ)
        n = len(prob.quads)
        symmetry_symbol = sympy.Symbol('_q_{}'.format(n))
        _lhs = constant_of_motion.expr / constant_of_motion.sym * symmetry
        lhs = 0
        for idx, state in enumerate(states_and_costates):
            lhs += sympy.integrate(_lhs[idx], state.sym)

        lhs, _ = recursive_sub(lhs, solve_for_p[0])

        state_syms = extract_syms(prob.states)
        costates_syms = extract_syms(prob.costates)
        parameter_syms = extract_syms(prob.parameters)
        constant_syms = extract_syms(prob.constants)

        # the_p = [constant_of_motion.sym]
        fn_q = prob.lambdify(
            [state_syms, costates_syms, parameter_syms, constant_syms], lhs)

        replace_q = states_and_costates[symmetry_index].sym
        solve_for_q = sympy.solve(lhs - symmetry_symbol,
                                  replace_q,
                                  dict=True,
                                  simplify=False)

        # Evaluate X_H(pi(., c)), pi = O^sharp
        omega = prob.omega.tomatrix()
        rvec = sympy.Matrix(([0] * len(states_and_costates)))
        for ii, state_1 in enumerate(states_and_costates):
            for jj, state_2 in enumerate(states_and_costates):
                rvec[ii] += omega[ii, jj] * sympy.diff(constant_of_motion.expr,
                                                       state_2.sym)

        symmetry_eom = sym_zero
        for idx, state in enumerate(states_and_costates):
            symmetry_eom += state.eom * rvec[idx]

        # TODO: Figure out how to find units of the quads. This is only works in some specialized cases.
        symmetry_unit = states_and_costates[symmetry_index].units

        prob.quads.append(
            DynamicStruct(str(symmetry_symbol),
                          symmetry_eom,
                          symmetry_unit,
                          local_compiler=prob.local_compiler))

        for idx, state in enumerate(states_and_costates):
            state.eom, _ = recursive_sub(state.eom, solve_for_p[0])
            state.eom, _ = recursive_sub(state.eom, solve_for_q[0])

        for idx, bc in enumerate(prob.constraints['initial'] +
                                 prob.constraints['terminal']):
            bc.expr, _ = recursive_sub(bc.expr, solve_for_p[0])
            bc.expr, _ = recursive_sub(bc.expr, solve_for_q[0])

        for idx, law in enumerate(prob.control_law):
            for jj, symbol in enumerate(law.keys()):
                prob.control_law[idx][symbol], _ = recursive_sub(
                    prob.sympify(law[symbol]), solve_for_p[0])
                # prob.control_law[idx][symbol] = law[symbol]
                prob.control_law[idx][symbol], _ = recursive_sub(
                    prob.sympify(law[symbol]), solve_for_q[0])
                # prob.control_law[idx][symbol] = law[symbol]

        for idx, com in enumerate(prob.constants_of_motion):
            if idx != self.com_index:
                com.expr, _ = recursive_sub(com.expr, solve_for_p[0])
                com.expr, _ = recursive_sub(com.expr, solve_for_q[0])

        remove_parameter = states_and_costates[parameter_index]
        remove_symmetry = states_and_costates[symmetry_index]

        remove_parameter_dict = {'location': None, 'index': None}
        if remove_parameter in prob.states:
            remove_parameter_dict = {
                'location': 'states',
                'index': prob.states.index(remove_parameter)
            }
            prob.states.remove(remove_parameter)
        if remove_parameter in prob.costates:
            remove_parameter_dict = {
                'location': 'costates',
                'index': prob.costates.index(remove_parameter)
            }
            prob.costates.remove(remove_parameter)

        remove_symmetry_dict = {'location': None, 'index': None}
        if remove_symmetry in prob.states:
            remove_symmetry_dict = {
                'location': 'states',
                'index': prob.states.index(remove_symmetry)
            }
            prob.states.remove(remove_symmetry)
        if remove_symmetry in prob.costates:
            remove_symmetry_dict = {
                'location': 'costates',
                'index': prob.costates.index(remove_symmetry)
            }
            prob.costates.remove(remove_symmetry)

        omega = prob.omega.tomatrix()
        if parameter_index > symmetry_index:
            omega.row_del(parameter_index)
            omega.col_del(parameter_index)
            omega.row_del(symmetry_index)
            omega.col_del(symmetry_index)
        else:
            omega.row_del(symmetry_index)
            omega.col_del(symmetry_index)
            omega.row_del(parameter_index)
            omega.col_del(parameter_index)

        prob.omega = sympy.MutableDenseNDimArray(omega)

        del prob.constants_of_motion[self.com_index]

        state_syms = extract_syms(prob.states)
        costates_syms = extract_syms(prob.costates)
        parameter_syms = extract_syms(prob.parameters)
        constant_syms = extract_syms(prob.constants)
        quad_syms = extract_syms(prob.quads)

        fn_q_inv = prob.lambdify([
            state_syms, costates_syms, quad_syms, parameter_syms, constant_syms
        ], solve_for_q[0][replace_q])
        fn_p_inv = prob.lambdify(
            [state_syms, costates_syms, parameter_syms, constant_syms],
            solve_for_p[0][replace_p])

        prob.sol_map_chain.append(
            MF(remove_parameter_dict, remove_symmetry_dict, fn_p, fn_q,
               fn_p_inv, fn_q_inv))

        return prob
Esempio n. 18
0
crR13Uc = smarr.MutableDenseNDimArray([crR13Uc_x, crR13Uc_y, crR13Uc_z])
crR02Uc = smarr.MutableDenseNDimArray([crR02Uc_x, crR02Uc_y, crR02Uc_z])
crR02R13 = smarr.MutableDenseNDimArray([crR02R13_x, crR02R13_y, crR02R13_z])
for cc in range(3):
    Der = Der.subs(eq_crR02Uc[cc], crR02Uc[cc])
    Der = Der.subs(eq_crR13Uc[cc], crR13Uc[cc])
    Der = Der.subs(eq_crR02R13[cc], crR02R13[cc])
norm_crR02R13 = sm.symbols('norm_crR02R13', real=True)
cub_crR02R13 = sm.symbols('cub_crR02R13', real=True)
Der = Der.subs(sm.sqrt(crR02R13_x**2 + crR02R13_y**2 + crR02R13_z**2),
               norm_crR02R13)
Der = Der.subs(norm_crR02R13**3, cub_crR02R13)

# other products
eq_Acr = linfunc.cross_product(crR02R13, R13)
Acr_x, Acr_y, Acr_z = sm.symbols('Acr_x Acr_y Acr_z', real=True)
Acr = sm.MutableDenseNDimArray([Acr_x, Acr_y, Acr_z])
for cc in range(3):
    Der = Der.subs(eq_Acr[cc], Acr[cc])

eq_Bcr = linfunc.cross_product(crR02R13, R02)
Bcr_x, Bcr_y, Bcr_z = sm.symbols('Bcr_x Bcr_y Bcr_z', real=True)
Bcr = sm.MutableDenseNDimArray([Bcr_x, Bcr_y, Bcr_z])
for cc in range(3):
    Der = Der.subs(eq_Bcr[cc], Bcr[cc])

eq_Cdot = linfunc.scalar_product(crR02R13, Uc)
Cdot = sm.symbols('Cdot', real=True)
Der = Der.subs(eq_Cdot, Cdot)
Esempio n. 19
0
def MatrixSymbolicFunction2(name, n, m):
    M = np.zeros((n, n), dtype="object")
    for i in range(n):
        for j in range(m):
            M[i, j] = sp.Function(f"{name}{i}{j}")
    return sp.MutableDenseNDimArray(M)
Esempio n. 20
0
def MatrixSymbolicFunction1(name, n):
    M = np.zeros(n, dtype="object")
    for i in range(n):
        M[i] = sp.Function(f"{name}{i}")
    return sp.MutableDenseNDimArray(M)