Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/example3/example3_withaxisymm.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@
" \"final_t\": 1,\n",
" \"initial_dt\": 0.01,\n",
" \"time_precision\": 6,\n",
" \"attempt_timestep_restart_on_divergence\": True\n",
" # \"attempt_timestep_restart_on_divergence\": True\n",
" }\n",
")\n",
"config_cur.flags.update({\"axisymmetric_model\": True})"
Expand Down Expand Up @@ -627,7 +627,7 @@
" \"final_t\": 1,\n",
" \"initial_dt\": 0.01,\n",
" \"time_precision\": 6,\n",
" \"attempt_timestep_restart_on_divergence\": True,\n",
" # \"attempt_timestep_restart_on_divergence\": True,\n",
" }\n",
" )\n",
" config_cur.flags.update({\"axisymmetric_model\": True})\n",
Expand Down
9 changes: 6 additions & 3 deletions smart/mesh_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -1438,16 +1438,19 @@ def load_mesh(
if extra_keys is None:
extra_keys = []

if not pathlib.Path(filename).is_file():
if isinstance(filename, str):
filename = pathlib.Path(filename)

if not filename.is_file():
raise FileNotFoundError(f"File {filename} does not exists")

if mesh is None:
mesh = d.Mesh(comm)

with d.HDF5File(comm, pathlib.Path(filename).with_suffix(".h5").as_posix(), "r") as hdf5:
with d.HDF5File(comm, filename.with_suffix(".h5").as_posix(), "r") as hdf5:
hdf5.read(mesh, "/mesh", False)

dim = mesh.geometric_dimension()
dim = mesh.topology().dim() # geometric_dimension()
mf_cell = d.MeshFunction("size_t", mesh, dim)
mf_facet = d.MeshFunction("size_t", mesh, dim - 1)
subdomains = []
Expand Down
12 changes: 11 additions & 1 deletion smart/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,12 @@ def _init_2_1_reactions_to_symbolic_strings(self):
raise ValueError(
"Reaction %s does not seem to have an associated equation" % reaction.name
)
if reaction.eqn_f_str == "":
reaction.eqn_str = f"-{reaction.eqn_r_str}"
elif reaction.eqn_r_str == "":
reaction.eqn_str = f"{reaction.eqn_f_str}"
else:
reaction.eqn_str = f"{reaction.eqn_f_str}-{reaction.eqn_r_str}"

def _init_2_2_check_reaction_validity(self):
"""Confirms that all reactions have parameters/species defined"""
Expand Down Expand Up @@ -986,7 +992,11 @@ def _init_4_7_set_initial_conditions(self):
# restrict to specified subdomain
u_cur = self.cc[species.compartment_name].u[ukey]
u_new = create_restriction(u_cur, species.subdomain_data, species.subdomain_val)
u_cur.assign(u_new)
values = u_cur.vector().get_local()
values_new = u_new.vector().get_local()
values[species.dof_map] = values_new[species.dof_map]
u_cur.vector().set_local(values)
u_cur.vector().apply("insert")

def _init_5_1_reactions_to_fluxes(self):
"""Convert reactions to flux objects"""
Expand Down
100 changes: 53 additions & 47 deletions smart/model_assembly.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,8 @@ def print_to_latex(
self,
properties_to_print=None,
max_col_width=None,
sig_figs=2,
return_df=True,
sig_figs=3,
return_df=False,
):
"""
Print object properties in latex format.
Expand All @@ -242,7 +242,33 @@ def print_to_latex(

for row in range(df.shape[0]):
for col in range(df.shape[1]):
if isinstance(df.iat[row, col], str):
if df.columns[col] == "eqn_str":
cur_str = df.iat[row, col]
cur_str = "$" + cur_str + "$"
cur_str = cur_str.replace("**", "^")
idx = 0
while idx < len(cur_str):
if cur_str[idx] == "_":
cur_str = cur_str[0 : idx + 1] + "{" + cur_str[idx + 1 :]
isMath = False
testIdx = idx + 2
while not isMath:
if not (cur_str[testIdx].isalnum() or cur_str[testIdx] == "_"):
if cur_str[testIdx] == "*":
cur_str = cur_str[0:testIdx] + "} " + cur_str[testIdx + 1 :]
else:
cur_str = cur_str[0:testIdx] + "}" + cur_str[testIdx:]
isMath = True
else:
testIdx += 1
idx = testIdx + 2
elif cur_str[idx] == "*":
cur_str = cur_str[0:idx] + " " + cur_str[idx + 1 :]
idx += 1
else:
idx += 1
df.iloc[row, col] = cur_str
elif isinstance(df.iat[row, col], str):
cur_str = df.iat[row, col]
if "_" in cur_str:
df.iloc[row, col] = cur_str.replace("_", "\_")
Expand All @@ -259,23 +285,23 @@ def print_to_latex(
new_list[i] = "`"
cur_str = "".join(new_list)
df.iloc[row, col] = cur_str
for col in df.columns:
# Convert quantity objects to unit
if isinstance(df[col].iloc[0], pint.Quantity):
# if tablefmt=='latex':
df[col] = df[col].apply(lambda x: f"${x:0.{sig_figs}e~Lx}$")

if col == "idx":
df = df.drop("idx", axis=1)
# Convert quantity objects to unit
elif isinstance(df.iat[row, col], pint.Quantity):
x = df.iat[row, col]
if isinstance(x.magnitude, str):
df.iloc[row, col] = f"{x:s~P}"
else:
df.iloc[row, col] = f"${x:0.{sig_figs}e~Lx}$"

for col in df.columns:
if "_" in col:
df = df.rename(columns={col: col.replace("_", "\_")})

if return_df:
return df
else:
with pandas.option_context("max_colwidth", 1000):
logger.info(df.to_latex(escape=False, longtable=True, index=False))
logger.info(df.to_latex(escape=False, longtable=True, index=True))

def get_pandas_dataframe_formatted(
self,
Expand Down Expand Up @@ -326,11 +352,14 @@ def print(
)

# # Change certain df entries to best format for printing
for col in df.columns:
# Convert quantity objects to unit
if isinstance(df[col].iloc[0], pint.Quantity):
# if tablefmt=='latex':
df[col] = df[col].apply(lambda x: f"{x:0.{sig_figs}e~P}")
for row in range(df.shape[0]):
for col in range(df.shape[1]):
if isinstance(df.iat[row, col], pint.Quantity):
x = df.iat[row, col]
if isinstance(x.magnitude, str):
df.iloc[row, col] = f"{x:s~P}"
else:
df.iloc[row, col] = f"{x:0.{sig_figs}e~P}"

# print to file
if filename is None:
Expand Down Expand Up @@ -447,7 +476,7 @@ def __init__(self):

self.properties_to_print = [
"_quantity",
"is_time_dependent",
# "is_time_dependent",
"sym_expr",
"notes",
"group",
Expand Down Expand Up @@ -760,8 +789,7 @@ def __init__(self):
self.properties_to_print = [
"compartment_name",
"_Diffusion",
"initial_condition",
"concentration_units",
"_Initial_Concentration",
]

def print(
Expand All @@ -774,33 +802,9 @@ def print(
for s in self:
s.D_quantity
s.latex_name
s.initial_condition_quantity
super().print(tablefmt, self.properties_to_print, filename, max_col_width)

def print_to_latex(
self,
properties_to_print=None,
max_col_width=None,
sig_figs=2,
return_df=False,
):
properties_to_print = ["_latex_name"]
properties_to_print.extend(self.properties_to_print)
df = super().print_to_latex(properties_to_print, max_col_width, sig_figs, return_df=True)
# fix dof_index
for col in df.columns:
if col == "dof_index":
df[col] = df[col].astype(int)
# fix name
# get the column of df that contains the name
# this can be more robust
# df.columns

if return_df:
return df
else:
with pandas.option_context("max_colwidth", 1000):
logger.info(df.to_latex(escape=False, longtable=True, index=False))


@dataclass
class Species(ObjectInstance):
Expand Down Expand Up @@ -841,7 +845,6 @@ class Species(ObjectInstance):
def to_dict(self):
"Convert to a dict that can be used to recreate the object."
keys_to_keep = [
"name",
"initial_condition",
"concentration_units",
"D",
Expand Down Expand Up @@ -1139,7 +1142,7 @@ class ReactionContainer(ObjectContainer):
def __init__(self):
super().__init__(Reaction)

self.properties_to_print = ["lhs", "rhs", "eqn_f_str", "eqn_r_str"]
self.properties_to_print = ["lhs", "rhs", "eqn_str", "topology"]

def print(
self,
Expand Down Expand Up @@ -1217,6 +1220,8 @@ class Reaction(ObjectInstance):
track_value: bool = False
eqn_f_str: str = ""
eqn_r_str: str = ""
eqn_str: str = ""
topology: str = ""
group: str = ""
axisymm: bool = False
has_subdomain: bool = False
Expand All @@ -1235,6 +1240,7 @@ def to_dict(self):
"track_value",
"eqn_f_str",
"eqn_r_str",
"eqn_str",
"group",
"axisymm",
]
Expand Down