def get_profile(R): M = params.recipe['mass'] g = params.G * M / pow(R, 2.0) P = params.recipe['P_surf'] T = None phase = phases.get_phase(0, None, P, params.recipe['T_surf']) rho = phase['rho_0'] q_surf = params.recipe['q_surf_est'] layersbelow_mass = params.recipe['mass'] radius = R solution = [None] * 2 for layer_number in xrange(0, params.recipe['layers']): x = np.linspace(0, radius, params.layerpoints) layersbelow_mass = layersbelow_mass - params.recipe['layer_masses'][layer_number] define_mass_event(layersbelow_mass) layer_solution = odelay(structure_equations, [rho, g, M, P], x, events=[mass_event], args=(phase, radius, False)) # if(T is None): # uncomment this when you have T solved for and indent the next line # If this is our first iteration we don't have an initial temperature profile yet # create a constant profile of temperature T_surf. # This means phase relations won't go insane in subsequent steps T = np.zeros_like(layer_solution[0]) + params.recipe['T_surf'] solution[layer_number] = get_layer_properties(layer_solution, T, q_surf, layer_number, radius) if (layer_number < params.recipe['layers'] - 1): phase = phases.get_phase(layer_number + 1, None, P, 300) radius = solution[layer_number]['bottom_r'] P = solution[layer_number]['bottom_P'] rho = phases.vinet_density(P, phase) g = solution[layer_number]['bottom_g'] M = solution[layer_number]['bottom_m'] # Interp all my fields for use in the temperature ODE solution = interp_solution(solution) # Toss to the temperature solver return solution
def ForceForwardToNextEvent(initialstate, eventType): # take a small step forward (0.1 time units) so that the integration is sure to move forward from the current state shorttimespan = np.linspace(0.0, 0.1, 10) computeOneStep = integrate.odeint(nonlinearDerivativesFunction, initialstate, shorttimespan) # this is the new initial state (last vector from short propagation above) initialstate = computeOneStep[9] # step to the next event (given maximum time constraint) t, statesOverTime, EventTime, EventState, EventIndex = odelay(nonlinearDerivativesFunction, initialstate, timespan, events=[eventType, stop_maxTime]) EventTime = EventTime + 0.1; return EventTime, EventState
def test_odelay_event(): X, Y, XE, YE, IE = odelay(ode, y0, xspan, events=[event], args=(k, )) assert feq(XE[0], 0.3)
isterminal = False return value, isterminal, direction def maxima(y, x): '''Approaching a maximum, dydx is positive and going to zero. our event function is decreasing''' value = ode(y, x) direction = -1 isterminal = False return value, isterminal, direction xspan = np.linspace(0.0, 20.0, 100) y0 = 0 X, Y, XE, YE, IE = odelay(ode, y0, xspan, events=[minima, maxima]) print(IE) import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt plt.plot(X, Y) # blue is maximum, red is minimum colors = 'rb' for xe, ye, ie in zip(XE, YE, IE): plt.plot([xe], [ye], 'o', color=colors[ie]) # plt.show()
from pycse import odelay import numpy as np import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt def ode(y, x, k): return -k * y def event(y, x): value = y - 0.3 isterminal = True direction = 0 return value, isterminal, direction xspan = np.linspace(0, 3) y0 = 1 for k in [2, 3, 4]: X, Y, XE, YE, IE = odelay(ode, y0, xspan, events=[event], args=(k, )) plt.plot(X, Y) # plt.show()
from pycse import odelay import numpy as np import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt def ode(y, x, k): return -k * y def event(y, x): value = y - 0.3 isterminal = True direction = 0 return value, isterminal, direction xspan = np.linspace(0, 3) y0 = 1 for k in [2, 3, 4]: X, Y, XE, YE, IE = odelay(ode, y0, xspan, events=[event], args=(k,)) plt.plot(X, Y) # plt.show()
print(np.sum(y[0:-2] * y[1:-1] < 0)) # method two used ODE function to solve the derivative of initial functions from pycse import odelay # define functions def fprime(f, x): return 3.0 * x**2 + 12.0 * x - 4.0 def event(f, x): value = f # we want f =0 isterminal = False direction = 0 return value, isterminal, direction xspan = np.linspace(-8, 4) f0 = -120 X, F, TE, YE, IE = odelay(fprime, f0, xspan, events=[event]) for te, ye in zip(TE, YE): print('root round at x ={0:1.3f},f={1:1.3f}'.format(te, float(ye))) print('ODE done')
def test_odelay_minmax(): xspan = np.linspace(0.0, 20.0, 100) y0 = 0 X, Y, XE, YE, IE = odelay(ode, y0, xspan, events=[minima, maxima]) assert (IE == [0, 1, 0, 1, 0, 1, 0]).all()
def test_odelay_minmax(): X, Y, XE, YE, IE = odelay(ode, y0, xspan, events=[minima, maxima]) assert (IE == [0, 1, 0, 1, 0, 1, 0]).all()
import matplotlib.pyplot as plt Ca0 = 3.0 # mol / L v0 = 10.0 # L / min k = 0.23 # 1 / min Fa_Exit = 0.3 * v0 def ode(Fa, V): Ca = Fa / v0 return -k * Ca def event1(Fa, V): isterminal = False direction = 0 value = Fa - Fa_Exit return value, isterminal, direction Vspan = np.linspace(0, 200) # L V, F, TE, YE, IE = odelay(ode, Ca0 * v0, Vspan, events=[event1]) print('Solution is at {0} L'.format(V[-1])) matplotlib.use('Agg') plt.plot(V, F)
direction = 1 isterminal = False return value, isterminal, direction def maxima(y, x): '''Approaching a maximum, dydx is positive and going to zero. our event function is decreasing''' value = ode(y, x) direction = -1 isterminal = False return value, isterminal, direction xspan = np.linspace(0.0, 20.0, 100) y0 = 0 X, Y, XE, YE, IE = odelay(ode, y0, xspan, events=[minima, maxima]) print(IE) import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt plt.plot(X, Y) # blue is maximum, red is minimum colors = 'rb' for xe, ye, ie in zip(XE, YE, IE): plt.plot([xe], [ye], 'o', color=colors[ie]) # plt.show()
y1, y2 = Y value = y2 - (-1.0) isterminal = True direction = 0 return value, isterminal, direction def event2(Y, x): dy1dx, dy2dx = ode(Y,x) value = dy1dx - 0.0 isterminal = False direction = -1 # derivative is decreasing towards a maximum return value, isterminal, direction Y0 = [2.0, 1.0] xspan = np.linspace(0, 5) X, Y, XE, YE, IE = odelay(ode, Y0, xspan, events=[event1, event2]) plt.plot(X, Y) for ie,xe,ye in zip(IE, XE, YE): if ie == 1: #this is the second event y1,y2 = ye plt.plot(xe, y1, 'ro') plt.legend(['$y_1$', '$y_2$'], loc='best') #plt.savefig('images/odelay-mult-eq.png') plt.show() # <headingcell level=3> # Example from pycse 2
def test_odelay_event(): X, Y, XE, YE, IE = odelay(ode, y0, xspan, events=[event], args=(k,)) assert feq(XE[0], 0.3)
# create a perturbed initial state #initialstate2 = np.zeros(len(initialstate_H)) #initialstate2[0:3] = initialstate_H[0:3] #initialstate2[3:6] = [x * 1.001 for x in initialstate_H[3:6]] #print initialstate2 # <headingcell level=3> # Define functions: ForceForwardToNextEvent, ForceForwardNEvents, FuncToSolve, Haloize # <codecell> ''' from the pysce source code at https://github.com/jkitchin/pycse/blob/2c9ff7fe81b0dfb34b3edf87356817312910b799/pycse/PYCSE.py#L78 odelay(func, y0, xspan, events, fsolve_args=None, **kwargs): ode wrapper with events func is callable, with signature func(Y, x) y0 are the initial conditions xspan is what you want to integrate over events is a list of callable functions with signature event(Y, x). These functions return zero when an event has happened. [value, isterminal, direction] = event(Y, x) value is the value of the event function. When value = 0, an event is triggered isterminal = True if the integration is to terminate at a zero of this event function, otherwise, False. direction = 0 if all zeros are to be located (the default), +1