4# A pype template for Nektar simulation
7# ---------------------------
9# protocol A pacing protocol
10# ---------------------------
12# This file is derived from Myokit.
16import myokit.lib.guess as guess
17import myokit.lib.hh as hh
21model.reserve_unique_names(*nektar.keywords)
22model.create_unique_names()
24# Find transmembrane potential
25vm = guess.membrane_potential(model)
27# Set Vm to first index by swapping if necessary
28indices = {var.qname(): var.indice() for var in model.states()}
29if indices[vm.qname()] != 0:
30 for var, i in indices.items():
32 indices[var] = vm.indice()
33 indices[vm.qname()] = 0
36# Find any gating variables for Rush-Larsen integration
38concentration_vars = []
41for var in model.states():
44 ret = hh.get_inf_and_tau(var, vm)
47 inf_vars[ret[0]] = indices[var.qname()]
48 tau_vars[ret[1]] = len(gate_vars)-1
50 concentration_vars.append(var)
54 # if a gate var the outarray is updated with the steady-state
55 if isinstance(var, myokit.Derivative) and var not in gate_vars:
56 return 'outarray[' + str(indices[var.var().qname()]) + '][i]'
57 elif isinstance(var, myokit.Name):
60 return 'inarray[' + str(indices[var.qname()]) + '][i]'
61 elif var.is_constant():
62 return 'AC_' + var.uname()
64 return 'm_gates_tau[' + str(tau_vars[var]) + '][i]'
66 return 'outarray[' + str(inf_vars[var]) + '][i]'
68 return 'AV_' + var.uname()
70# Create expression writer
71w = nektar.NektarExpressionWriter()
78equations = model.solvable_order()
81model_name = name if name is not None else model.name();
121#include <CardiacEPSolver/CellModels/<?= model_name ?>.h>
126std::string <?= model_name ?>::className
129 <?= model_name ?>::create,
134 print(
'// Register cell model variants')
135 print('
std::
string ' + model_name + '::lookupIds[' + str(len(variants)) + '] = {
')
136 for variant in variants.keys():
138 print(2*tab + '"' + variant + '",
' + model_name + '::e
' + variant + '),
')
141 print(
'std::string ' + model_name +
'::def =')
142 print(tab + 'LibUtilities::SessionReader::RegisterDefaultSolverInfo(')
143 print(2*tab + '"CellModelVariant", "' + list(variants.keys())[0] + '");')
148<?= model_name ?>::<?= model_name ?>(
151 : CellModel(pSession, pField)
155 print(tab +
'model_variant = pSession->GetSolverInfoAsEnum<')
156 print(3*tab + model_name + '::Variants>("CellModelVariant");')
158 m_nvar = <?= model.count_states() ?>;
163 print(tab + 'm_gates.push_back(' + str(indices[var.qname()]) + ');
167for var in concentration_vars:
168 print(tab + 'm_concentrations.push_back(' + str(indices[var.qname()]) + ');
174for label, eqs in equations.items():
175 if eqs.has_equations(
const=True):
176 print(tab +
'/* ' + label +
' */')
177 for eq in eqs.equations(const=True):
178 # check if included as a variant and will be handled after
180 variant_dict[eq.lhs.var().qname()] = eq.lhs.var()
182 print(tab +
w.eq(eq) +
'; // ' + str(eq.lhs.var().unit()))
186 print(tab + 'switch (model_variant) {
')
187 for variant_name, constant_dict in variants.items():
188 print(2*tab + 'case e
' + variant_name + ':
')
189 for name, value in constant_dict.items():
190 print(3*tab + v(variant_dict[name]) + ' =
' + str(value) + ';
')
191 print(3*tab + 'break;
')
195<?= model_name ?>::~<?= model_name ?>()
200void <?= model_name ?>::v_Update(
201 const Array<OneD, const Array<OneD, NekDouble> > &inarray,
202 Array<OneD, Array<OneD, NekDouble> > &outarray,
203 [[maybe_unused]] const NekDouble time)
205 ASSERTL0(inarray.data() != outarray.data(),
206 "Must have different arrays for input and output.");
208 /* State variable ordering
210for var in model.states():
211 print(tab + v(var) + ' ' + var.qname())
214 for (unsigned int i = 0; i < m_nq; ++i)
217for label, eqs in equations.items():
218 if eqs.has_equations(const=False):
220 for eq in eqs.equations(const=False):
222 if var in model.bindings():
223 print(2*tab + v(var) + ' =
' + model.binding(var) + ';
')
224 elif var in gate_vars:
225 # don't want to fill derivatives of Rush-Larsen gating variables
228 print(2*tab +
w.eq(eq) +
';')
233void <?= model_name ?>::v_GenerateSummary(
SummaryList& s)
238void <?= model_name ?>::v_SetInitialConditions()
242 print(tab +
'switch (model_variant) {')
243 for variant_name, variant_inits in initial_states.items():
244 print(2*tab + 'case e' + variant_name + ':')
245 for eq in variant_inits:
246 print(3*tab + '
Vmath::Fill(m_nq, (
NekDouble)' + str(eq.rhs) + ', m_cellSol[' + str(indices[eq.lhs.var().qname()]) + '], 1);')
247 print(3*tab + 'break;')
250 for eq in model.inits():
251 print(tab + '
Vmath::Fill(m_nq, (
NekDouble)' + str(eq.rhs) + ', m_cellSol[' + str(indices[eq.lhs.var().qname()]) + '], 1);')
255std::
string <?= model_name ?>::v_GetCellVarName(
size_t idx)
258print(tab +
'switch (idx) {')
259for var in model.states():
260 print(2*tab + 'case ' + str(var.index()) + ':')
261 print(3*tab + 'return "' + var.name() + '";')
262print(2*tab + 'default:')
263print(3*tab + 'return "unknown";')
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
static std::string RegisterEnumValue(std::string pEnum, std::string pString, int pEnumValue)
Registers an enumeration value.
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
std::vector< std::pair< std::string, std::string > > SummaryList
void AddSummaryItem(SummaryList &l, const std::string &name, const std::string &value)
Adds a summary item to the summary info list.
std::vector< double > w(NPUPPER)
CellModelFactory & GetCellModelFactory()