Beispiel #1
0
def _ode_solve(dt, t, b, y):
    initializer.assert_initialized()
    if _diffusion_matrix is None: _setup_matrices()
    lo = _rxd_offset
    hi = lo + len(_nonzero_volume_indices)
    n = len(_node_get_states())
    # TODO: this will need changed when can have both 1D and 3D
    if species._has_3d:
        if species._has_1d:
            raise Exception(
                'development issue: cvode currently does not support hybrid simulations (fix by shifting for zero volume indices)'
            )
        # NOTE: only working on the rxd part
        rxd_b = b[lo:hi]
        # TODO: make sure can handle both 1D and 3D
        m = eye_minus_dt_J(n, dt)
        # removed diagonal preconditioner since tests showed no improvement in convergence
        result, info = _scipy_sparse_linalg_bicgstab(m, dt * rxd_b)
        assert (info == 0)
        b[lo:hi] = _react_matrix_solver(result)
    else:
        # 1D only; use Hines solver
        full_b = numpy.zeros(n)
        full_b[_nonzero_volume_indices] = b[lo:hi]
        b[lo:hi] = _react_matrix_solver(_diffusion_matrix_solve(
            dt, full_b))[_nonzero_volume_indices]
Beispiel #2
0
def _ode_fun(t, y, ydot):
    initializer.assert_initialized()
    lo = _rxd_offset
    hi = lo + len(_nonzero_volume_indices)
    if lo == hi: return
    states = _node_get_states()
    states[_nonzero_volume_indices] = y[lo : hi]

    # need to fill in the zero volume states with the correct concentration
    # this assumes that states at the zero volume indices is zero (although that
    # assumption could be easily removed)
    #matrix = _scipy_sparse_dok_matrix((len(_zero_volume_indices), len(states)))
    """
    for i, row in enumerate(_zero_volume_indices):
        d = _diffusion_matrix[row, row]
        if d:
            nzj = _diffusion_matrix[row].nonzero()[1]
            print 'nzj:', nzj
            for j in nzj:
                matrix[i, j] = -_diffusion_matrix[row, j] / d
    states[_zero_volume_indices] = matrix * states
    """
    if len(_zero_volume_indices):
        states[_zero_volume_indices] = _mat_for_zero_volume_nodes * states
    """
    for i in _zero_volume_indices:
        v = _diffusion_matrix[i] * states
        d = _diffusion_matrix[i, i]
        if d:
            states[i] = -v / d
    """
    # TODO: make this so that the section1d parts use cptrs (can't do this directly for 3D because sum, but could maybe move that into the C)
    # the old way: _section1d_transfer_to_legacy()
    for sr in _species_get_all_species().values():
        s = sr()
        if s is not None: s._transfer_to_legacy()

    
    if ydot is not None:
        # diffusion_matrix = - jacobian    
        ydot[lo : hi] = (_rxd_reaction(states) - _diffusion_matrix * states)[_nonzero_volume_indices]
        
    states[_zero_volume_indices] = 0
Beispiel #3
0
def _ode_fun(t, y, ydot):
    initializer.assert_initialized()
    lo = _rxd_offset
    hi = lo + len(_nonzero_volume_indices)
    if lo == hi: return
    states = _node_get_states()
    states[_nonzero_volume_indices] = y[lo:hi]

    # need to fill in the zero volume states with the correct concentration
    # this assumes that states at the zero volume indices is zero (although that
    # assumption could be easily removed)
    #matrix = _scipy_sparse_dok_matrix((len(_zero_volume_indices), len(states)))
    """
    for i, row in enumerate(_zero_volume_indices):
        d = _diffusion_matrix[row, row]
        if d:
            nzj = _diffusion_matrix[row].nonzero()[1]
            print 'nzj:', nzj
            for j in nzj:
                matrix[i, j] = -_diffusion_matrix[row, j] / d
    states[_zero_volume_indices] = matrix * states
    """
    if len(_zero_volume_indices):
        states[_zero_volume_indices] = _mat_for_zero_volume_nodes * states
    """
    for i in _zero_volume_indices:
        v = _diffusion_matrix[i] * states
        d = _diffusion_matrix[i, i]
        if d:
            states[i] = -v / d
    """
    # TODO: make this so that the section1d parts use cptrs (can't do this directly for 3D because sum, but could maybe move that into the C)
    # the old way: _section1d_transfer_to_legacy()
    for sr in _species_get_all_species().values():
        s = sr()
        if s is not None: s._transfer_to_legacy()

    if ydot is not None:
        # diffusion_matrix = - jacobian
        ydot[lo:hi] = (_rxd_reaction(states) -
                       _diffusion_matrix * states)[_nonzero_volume_indices]

    states[_zero_volume_indices] = 0
Beispiel #4
0
def _ode_solve(dt, t, b, y):
    initializer.assert_initialized()
    if _diffusion_matrix is None: _setup_matrices()
    lo = _rxd_offset
    hi = lo + len(_nonzero_volume_indices)
    n = len(_node_get_states())
    # TODO: this will need changed when can have both 1D and 3D
    if species._has_3d:
        if species._has_1d:
            raise Exception('development issue: cvode currently does not support hybrid simulations (fix by shifting for zero volume indices)')
        # NOTE: only working on the rxd part
        rxd_b = b[lo : hi]
        # TODO: make sure can handle both 1D and 3D
        m = _scipy_sparse_eye(n, n) - dt * _euler_matrix
        # removed diagonal preconditioner since tests showed no improvement in convergence
        result, info = _scipy_sparse_linalg_bicgstab(m, dt * rxd_b)
        assert(info == 0)
        b[lo : hi] = _react_matrix_solver(result)
    else:
        # 1D only; use Hines solver
        full_b = numpy.zeros(n)
        full_b[_nonzero_volume_indices] = b[lo : hi]
        b[lo : hi] = _react_matrix_solver(_diffusion_matrix_solve(dt, full_b))[_nonzero_volume_indices]