Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Increase max number of ions per compartment #3055

Merged
merged 10 commits into from
Sep 20, 2024
44 changes: 25 additions & 19 deletions src/nrnoc/eion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
#include <array>
#include <string>

#include <memory>
#include <bitset>
#include <vector>

#undef hoc_retpushx

extern double chkarg(int, double low, double high);
Expand Down Expand Up @@ -64,7 +68,7 @@ double nrn_ion_charge(Symbol* sym) {

void ion_register(void) {
/* hoc level registration of ion name. Return -1 if name already
in use and not an ion; and the mechanism subtype otherwise.
in use and not an ion; and the mechanism subtype otherwise.
*/
char* name;
Symbol* s;
Expand Down Expand Up @@ -401,38 +405,39 @@ The argument `i` specifies which concentration is being written to. It's 0 for
exterior; and 1 for interior.
*/
void nrn_check_conc_write(Prop* p_ok, Prop* pion, int i) {
static long *chk_conc_, *ion_bit_, size_;
const int max_length = 10000; // parametrize?
wthun marked this conversation as resolved.
Show resolved Hide resolved
static long size_;

static std::vector<std::bitset<max_length>> chk_conc_, ion_bit_;
wthun marked this conversation as resolved.
Show resolved Hide resolved

Prop* p;
int flag, j, k;
if (i == 1) {
flag = 0200;
} else {
flag = 0400;
}
/* an embarassing hack */
/* up to 32 possible ions */
/* continuously compute a bitmap that allows determination
of which models WRITE which ion concentrations */

/* Create a vector holding std::bitset to track which ions
are being written to the membrane */
if (n_memb_func > size_) {
if (!chk_conc_) {
chk_conc_ = (long*) ecalloc(2 * n_memb_func, sizeof(long));
ion_bit_ = (long*) ecalloc(n_memb_func, sizeof(long));
} else {
chk_conc_ = (long*) erealloc(chk_conc_, 2 * n_memb_func * sizeof(long));
ion_bit_ = (long*) erealloc(ion_bit_, n_memb_func * sizeof(long));
for (j = size_; j < n_memb_func; ++j) {
chk_conc_[2 * j] = 0;
chk_conc_[2 * j + 1] = 0;
ion_bit_[j] = 0;
}

chk_conc_.resize(2 * n_memb_func);
ion_bit_.resize(n_memb_func);

for (j = size_; j < n_memb_func; ++j) {
chk_conc_[2 * j].reset();
chk_conc_[2 * j + 1].reset();
ion_bit_[j].reset();
}

size_ = n_memb_func;
}
for (k = 0, j = 0; j < n_memb_func; ++j) {
if (nrn_is_ion(j)) {
ion_bit_[j] = (1 << k);
++k;
assert(k < sizeof(long) * 8);
assert(k < max_length);
wthun marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand All @@ -443,7 +448,8 @@ void nrn_check_conc_write(Prop* p_ok, Prop* pion, int i) {
if (p == p_ok) {
continue;
}
if (chk_conc_[2 * p->_type + i] & ion_bit_[pion->_type]) {
auto rst = chk_conc_[2 * p->_type + i] & ion_bit_[pion->_type];
if (rst.count() > 0) {
wthun marked this conversation as resolved.
Show resolved Hide resolved
char buf[300];
Sprintf(buf,
"%.*s%c is being written at the same location by %s and %s",
Expand Down
Loading