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]
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
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
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]