Example #1
0
 def indices(self, r=None):
     """return the indices corresponding to this species in the given region
     
     if r is None, then returns all species indices"""
     # TODO: beware, may really want self._indices3d or self._indices1d
     initializer._do_init()
     return self._indices1d(r) + self._indices3d(r)
Example #2
0
 def indices(self, r=None):
     """return the indices corresponding to this species in the given region
     
     if r is None, then returns all species indices"""
     # TODO: beware, may really want self._indices3d or self._indices1d
     initializer._do_init()
     return self._indices1d(r) + self._indices3d(r)
Example #3
0
def _ode_count(offset):
    global last_structure_change_cnt
    global _rxd_offset
    initializer._do_init()
    _rxd_offset = offset
    if _diffusion_matrix is None or last_structure_change_cnt != _structure_change_count.value: _setup_matrices()
    last_structure_change_cnt = _structure_change_count.value
    return len(_nonzero_volume_indices)
Example #4
0
 def nodes(self):
     """A NodeList of all the nodes corresponding to the species.
     
     This can then be further restricted using the callable property of NodeList objects."""
     initializer._do_init()
     
     # The first part here is for the 1D -- which doesn't keep live node objects -- the second part is for 3D
     return nodelist.NodeList(list(itertools.chain.from_iterable([s.nodes for s in self._secs])) + self._nodes)
Example #5
0
def _fixed_step_solve(raw_dt):
    initializer._do_init()
    global pinverse, _fixed_step_count
    global _last_m, _last_dt, _last_preconditioner

    if species._species_count == 0:
        return

    # allow for skipping certain fixed steps
    # warning: this risks numerical errors!
    fixed_step_factor = options.fixed_step_factor
    _fixed_step_count += 1
    if _fixed_step_count % fixed_step_factor: return
    dt = fixed_step_factor * raw_dt

    # TODO: this probably shouldn't be here
    if _diffusion_matrix is None and _euler_matrix is None: _setup_matrices()

    states = _node_get_states()[:]

    b = _rxd_reaction(states) - _diffusion_matrix * states

    if not species._has_3d:
        # use Hines solver since 1D only
        states[:] += _reaction_matrix_solve(
            dt, states, _diffusion_matrix_solve(dt, dt * b))

        # clear the zero-volume "nodes"
        states[_zero_volume_indices] = 0

        # TODO: refactor so this isn't in section1d... probably belongs in node
        _section1d_transfer_to_legacy()

        _last_preconditioner = None
    else:
        # TODO: this looks to be semi-implicit method because it doesn't take into account the reaction contribution to the Jacobian; do we care?
        # the actual advance via implicit euler
        n = len(states)
        if _last_dt != dt or _last_preconditioner is None:
            _last_m = eye_minus_dt_J(n, dt)
            _last_preconditioner = _LinearOperator(
                (n, n),
                _spilu(csc_matrix(_last_m)).solve)
            _last_dt = dt
        # removed diagonal preconditioner since tests showed no improvement in convergence
        result, info = _scipy_sparse_linalg_bicgstab(_last_m,
                                                     dt * b,
                                                     M=_last_preconditioner)
        assert (info == 0)
        states[:] += result

        # clear the zero-volume "nodes"
        states[_zero_volume_indices] = 0

        for sr in _species_get_all_species().values():
            s = sr()
            if s is not None: s._transfer_to_legacy()
Example #6
0
def _ode_count(offset):
    global last_structure_change_cnt
    global _rxd_offset
    initializer._do_init()
    _rxd_offset = offset
    if _diffusion_matrix is None or last_structure_change_cnt != _structure_change_count.value:
        _setup_matrices()
    last_structure_change_cnt = _structure_change_count.value
    return len(_nonzero_volume_indices)
Example #7
0
    def nodes(self):
        """A NodeList of all the nodes corresponding to the species.
        
        This can then be further restricted using the callable property of NodeList objects."""
        initializer._do_init()

        # The first part here is for the 1D -- which doesn't keep live node objects -- the second part is for 3D
        return nodelist.NodeList(
            list(itertools.chain.from_iterable([s.nodes
                                                for s in self._secs])) +
            self._nodes)
Example #8
0
def _currents(rhs):
    initializer._do_init()
    # setup membrane fluxes from our stuff
    # TODO: cache the memb_cur_ptrs, memb_cur_charges, memb_net_charges, memb_cur_mapped
    #       because won't change very often
    global _rxd_induced_currents

    # need this; think it's because of initialization of mod files
    if _curr_indices is None: return

    # TODO: change so that this is only called when there are in fact currents
    _rxd_induced_currents = _numpy_zeros(len(_curr_indices))
    rxd_memb_flux = []
    memb_cur_ptrs = []
    memb_cur_charges = []
    memb_net_charges = []
    memb_cur_mapped = []
    for rptr in _all_reactions:
        r = rptr()
        if r and r._membrane_flux:
            # NOTE: memb_flux contains any scaling we need
            new_fluxes = r._get_memb_flux(_node_get_states())
            rxd_memb_flux += list(new_fluxes)
            memb_cur_ptrs += r._cur_ptrs
            memb_cur_mapped += r._cur_mapped
            memb_cur_charges += [r._cur_charges] * len(new_fluxes)
            memb_net_charges += [r._net_charges] * len(new_fluxes)

    # TODO: is this in any way dimension dependent?

    if rxd_memb_flux:
        # TODO: remove the asserts when this is verified to work
        assert (len(rxd_memb_flux) == len(_cur_node_indices))
        assert (len(rxd_memb_flux) == len(memb_cur_ptrs))
        assert (len(rxd_memb_flux) == len(memb_cur_charges))
        assert (len(rxd_memb_flux) == len(memb_net_charges))
        for flux, cur_ptrs, cur_charges, net_charge, i, cur_maps in zip(
                rxd_memb_flux, memb_cur_ptrs, memb_cur_charges,
                memb_net_charges, _cur_node_indices, memb_cur_mapped):
            rhs[i] -= net_charge * flux
            #print net_charge * flux
            #import sys
            #sys.exit()
            # TODO: remove this assert when more thoroughly tested
            assert (len(cur_ptrs) == len(cur_maps))
            for ptr, charge, cur_map_i in zip(cur_ptrs, cur_charges, cur_maps):
                # this has the opposite sign of the above because positive
                # currents lower the membrane potential
                cur = charge * flux
                ptr[0] += cur
                for sign, c in zip([-1, 1], cur_maps):
                    if c is not None:
                        _rxd_induced_currents[c] += sign * cur
Example #9
0
def _currents(rhs):
    initializer._do_init()
    # setup membrane fluxes from our stuff
    # TODO: cache the memb_cur_ptrs, memb_cur_charges, memb_net_charges, memb_cur_mapped
    #       because won't change very often
    global _rxd_induced_currents

    # need this; think it's because of initialization of mod files
    if _curr_indices is None: return

    # TODO: change so that this is only called when there are in fact currents
    _rxd_induced_currents = _numpy_zeros(len(_curr_indices))
    rxd_memb_flux = []
    memb_cur_ptrs = []
    memb_cur_charges = []
    memb_net_charges = []
    memb_cur_mapped = []
    for rptr in _all_reactions:
        r = rptr()
        if r and r._membrane_flux:
            # NOTE: memb_flux contains any scaling we need
            new_fluxes = r._get_memb_flux(_node_get_states())
            rxd_memb_flux += list(new_fluxes)
            memb_cur_ptrs += r._cur_ptrs
            memb_cur_mapped += r._cur_mapped
            memb_cur_charges += [r._cur_charges] * len(new_fluxes)
            memb_net_charges += [r._net_charges] * len(new_fluxes)

    # TODO: is this in any way dimension dependent?

    if rxd_memb_flux:
        # TODO: remove the asserts when this is verified to work
        assert(len(rxd_memb_flux) == len(_cur_node_indices))
        assert(len(rxd_memb_flux) == len(memb_cur_ptrs))
        assert(len(rxd_memb_flux) == len(memb_cur_charges))
        assert(len(rxd_memb_flux) == len(memb_net_charges))
        for flux, cur_ptrs, cur_charges, net_charge, i, cur_maps in zip(rxd_memb_flux, memb_cur_ptrs, memb_cur_charges, memb_net_charges, _cur_node_indices, memb_cur_mapped):
            rhs[i] -= net_charge * flux
            #print net_charge * flux
            #import sys
            #sys.exit()
            # TODO: remove this assert when more thoroughly tested
            assert(len(cur_ptrs) == len(cur_maps))
            for ptr, charge, cur_map_i in zip(cur_ptrs, cur_charges, cur_maps):
                # this has the opposite sign of the above because positive
                # currents lower the membrane potential
                cur = charge * flux
                ptr[0] += cur
                for sign, c in zip([-1, 1], cur_maps):
                    if c is not None:
                        _rxd_induced_currents[c] += sign * cur
Example #10
0
def _fixed_step_solve(raw_dt):
    initializer._do_init()
    global pinverse, _fixed_step_count
    global _last_m, _last_dt, _last_preconditioner

    if species._species_count == 0:
        return

    # allow for skipping certain fixed steps
    # warning: this risks numerical errors!
    fixed_step_factor = options.fixed_step_factor
    _fixed_step_count += 1
    if _fixed_step_count % fixed_step_factor: return
    dt = fixed_step_factor * raw_dt
    
    # TODO: this probably shouldn't be here
    if _diffusion_matrix is None and _euler_matrix is None: _setup_matrices()

    states = _node_get_states()[:]

    b = _rxd_reaction(states) - _diffusion_matrix * states
    

    if not species._has_3d:
        # use Hines solver since 1D only
        states[:] += _reaction_matrix_solve(dt, states, _diffusion_matrix_solve(dt, dt * b))

        # clear the zero-volume "nodes"
        states[_zero_volume_indices] = 0

        # TODO: refactor so this isn't in section1d... probably belongs in node
        _section1d_transfer_to_legacy()
        
        _last_preconditioner = None
    else:
        # TODO: this looks to be semi-implicit method because it doesn't take into account the reaction contribution to the Jacobian; do we care?
        # the actual advance via implicit euler
        n = len(states)
        if _last_dt != dt or _last_preconditioner is None:
            _last_m = _scipy_sparse_eye(n, n) - dt * _euler_matrix
            _last_preconditioner = _LinearOperator((n, n), _spilu(csc_matrix(_last_m)).solve)
            _last_dt = dt
        # removed diagonal preconditioner since tests showed no improvement in convergence
        result, info = _scipy_sparse_linalg_bicgstab(_last_m, dt * b, M=_last_preconditioner)
        assert(info == 0)
        states[:] += result

        for sr in _species_get_all_species().values():
            s = sr()
            if s is not None: s._transfer_to_legacy()
Example #11
0
def _init():
    initializer._do_init()
    
    # TODO: check about the 0<x<1 problem alluded to in the documentation
    h.define_shape()
    
    if species._has_1d:
        section1d._purge_cptrs()
    
    for sr in _species_get_all_species().values():
        s = sr()
        if s is not None:
            # TODO: are there issues with hybrid or 3D here? (I don't think so, but here's a bookmark just in case)
            s._register_cptrs()
            s._finitialize()
    _setup_matrices()
Example #12
0
def _init():
    initializer._do_init()

    # TODO: check about the 0<x<1 problem alluded to in the documentation
    h.define_shape()

    if species._has_1d:
        section1d._purge_cptrs()

    for sr in _species_get_all_species().values():
        s = sr()
        if s is not None:
            # TODO: are there issues with hybrid or 3D here? (I don't think so, but here's a bookmark just in case)
            s._register_cptrs()
            s._finitialize()
    _setup_matrices()
Example #13
0
    def nodes(self):
        """A NodeList of the Node objects containing concentration data for the given Species and Region.

        The code

            node_list = ca[cyt].nodes

        is more efficient than the otherwise equivalent

            node_list = ca.nodes(cyt)

        because the former only creates the Node objects belonging to the restriction ca[cyt] whereas the second option
        constructs all Node objects belonging to the Species ca and then culls the list to only include those also
        belonging to the Region cyt.
        """
        initializer._do_init()
        return nodelist.NodeList(itertools.chain.from_iterable([s.nodes for s in self._species()._secs if s._region == self._region()]))
Example #14
0
    def nodes(self):
        """A NodeList of the Node objects containing concentration data for the given Species and Region.

        The code

            node_list = ca[cyt].nodes

        is more efficient than the otherwise equivalent

            node_list = ca.nodes(cyt)

        because the former only creates the Node objects belonging to the restriction ca[cyt] whereas the second option
        constructs all Node objects belonging to the Species ca and then culls the list to only include those also
        belonging to the Region cyt.
        """
        initializer._do_init()
        return nodelist.NodeList(
            itertools.chain.from_iterable([
                s.nodes for s in self._species()._secs
                if s._region == self._region()
            ]))
Example #15
0
def _setup():
    initializer._do_init()
    # TODO: this is when I should resetup matrices (structure changed event)
    global _last_dt, _external_solver_initialized
    _last_dt = None
    _external_solver_initialized = False
Example #16
0
def _setup():
    initializer._do_init()
    # TODO: this is when I should resetup matrices (structure changed event)
    global _last_dt, _external_solver_initialized
    _last_dt = None
    _external_solver_initialized = False