From a424849c8f53b80ef6777aaea7218ba863a12e31 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Fri, 11 Feb 2022 12:27:05 +0100 Subject: [PATCH 01/45] Fix docstring warnings DeprecationWarning: invalid escape sequence \s --- python/amici/ode_export.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/amici/ode_export.py b/python/amici/ode_export.py index 48594f55c2..3aa93e617e 100644 --- a/python/amici/ode_export.py +++ b/python/amici/ode_export.py @@ -1222,7 +1222,7 @@ def add_conservation_law(self, total_abundance: sp.Symbol, state_expr: sp.Expr, abundance_expr: sp.Expr) -> None: - """ + r""" Adds a new conservation law to the model. A conservation law is defined by the conserved quantity :math:`T = \sum_i(a_i * x_i)`, where :math:`a_i` are coefficients and :math:`x_i` are different state From 86105592fa1ceec63e33ed47c765a830e52804f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Fr=C3=B6hlich?= Date: Fri, 11 Feb 2022 17:03:47 -0500 Subject: [PATCH 02/45] add support for pysb local functions (#1666) * add support for local functions * fixup * fix tags --- .gitignore | 1 + python/amici/pysb_import.py | 15 ++++++++++++++- python/tests/test_pysb.py | 8 +------- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index cd75359839..4dd0ab662a 100644 --- a/.gitignore +++ b/.gitignore @@ -136,6 +136,7 @@ tests/test/* */tests/fricker_2010_apoptosis_amici/* */tests/explicit_amici/* */tests/fixed_initial_amici/* +*/tests/localfunc_amici/* tests/cpp/writeResults.h5 tests/cpp/writeResults.h5.bak tests/sbml-test-suite/* diff --git a/python/amici/pysb_import.py b/python/amici/pysb_import.py index 0d38391e94..85e0948fb7 100644 --- a/python/amici/pysb_import.py +++ b/python/amici/pysb_import.py @@ -325,7 +325,20 @@ def _process_pysb_expressions( # they are ordered according to their dependency and we can # evaluate them sequentially without reordering. Important to make # sure that observables are processed first though. - for expr in pysb_model.expressions: + + # we use _constant and _dynamic functions to get access to derived + # expressions that are otherwise only accessible as private attribute + for expr in pysb_model.expressions_constant(include_derived=True)\ + | pysb_model.expressions_dynamic(include_derived=True): + if any( + isinstance(symbol, pysb.Tag) + for symbol in expr.expand_expr().free_symbols + ): + # we only need explicit instantiations of expressions with tags, + # which are defined in the derived expressions. The abstract + # expressions are not needed and lead to compilation errors so + # we skip them. + continue _add_expression(expr, expr.name, expr.expr, pysb_model, ode_model, observables, sigmas, noise_distributions) diff --git a/python/tests/test_pysb.py b/python/tests/test_pysb.py index e5559f8c9c..de86865e22 100644 --- a/python/tests/test_pysb.py +++ b/python/tests/test_pysb.py @@ -93,7 +93,7 @@ def test_compare_to_sbml_import(pysb_example_presimulation_module, 'bngwiki_enzymatic_cycle_mm', 'bngwiki_simple', 'earm_1_0', 'earm_1_3', 'move_connected', 'michment', 'kinase_cascade', 'hello_pysb', 'fricker_2010_apoptosis', 'explicit', - 'fixed_initial', + 'fixed_initial', 'localfunc' ] custom_models = [ 'bngwiki_egfr_simple_deletemolecules', @@ -109,12 +109,6 @@ def test_compare_to_pysb_simulation(example): with amici.add_path(os.path.dirname(pysb.examples.__file__)): with amici.add_path(os.path.join(os.path.dirname(__file__), '..', 'tests', 'pysb_test_models')): - - if example == 'earm_1_3' \ - and platform.sys.version_info[0] == 3 \ - and platform.sys.version_info[1] < 7: - return - # load example pysb.SelfExporter.cleanup() # reset pysb pysb.SelfExporter.do_export = True From 9212bbdaf5712727ff284cc475f16d2a983f9bf2 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Thu, 17 Feb 2022 10:08:37 +0100 Subject: [PATCH 03/45] SBML import: conservation laws for non-constant species (#1669) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extends identification conservation laws during SBML import to non-constant species based on the algorithm proposed in [1]. Parameterized stoichiometric coefficients are not supported. Neither are models with events/Heaviside/piecewise or RateRules. Conservation laws for non-constant species are completely ignored in this case. **Experimental feature**: Enable by setting environment variable `AMICI_EXPERIMENTAL_SBML_NONCONST_CLS` to any value. [1] De Martino A, De Martino D, Mulet R, Pagnani A (2014) Identifying All Moiety Conservation Laws in Genome-Scale Metabolic Networks. PLoS ONE 9(7): e100750. https://doi.org/10.1371/journal.pone.0100750 Co-authored-by: Stephan Grein Co-authored-by: Fabian Fröhlich --- .gitignore | 2 +- documentation/python_modules.rst | 1 + python/amici/conserved_moieties.py | 864 +++++++++++++++++++++++ python/amici/import_utils.py | 33 +- python/amici/sbml_import.py | 198 +++++- python/amici/setup.template.py | 2 + python/sdist/amici/conserved_moieties.py | 1 + python/tests/test_conserved_moieties.py | 284 ++++++++ 8 files changed, 1348 insertions(+), 37 deletions(-) create mode 100644 python/amici/conserved_moieties.py create mode 120000 python/sdist/amici/conserved_moieties.py create mode 100644 python/tests/test_conserved_moieties.py diff --git a/.gitignore b/.gitignore index 4dd0ab662a..6b0a18901b 100644 --- a/.gitignore +++ b/.gitignore @@ -192,6 +192,6 @@ tests/performance/CS_Signalling_ERBB_RAS_AKT/ tests/performance/CS_Signalling_ERBB_RAS_AKT_petab/* coverage_SBMLSuite.xml Benchmark-Models-PEtab/ - +/test_bmc/ CS_Signalling_ERBB_RAS_AKT/ diff --git a/documentation/python_modules.rst b/documentation/python_modules.rst index b493fb7ff7..013261fb9d 100644 --- a/documentation/python_modules.rst +++ b/documentation/python_modules.rst @@ -21,3 +21,4 @@ AMICI Python API amici.logging amici.gradient_check amici.parameter_mapping + amici.conserved_moieties diff --git a/python/amici/conserved_moieties.py b/python/amici/conserved_moieties.py new file mode 100644 index 0000000000..e5cdad8f8f --- /dev/null +++ b/python/amici/conserved_moieties.py @@ -0,0 +1,864 @@ +import logging +import math +import random +import sys +from typing import List, MutableSequence, Sequence, Tuple, Union + +from .logging import get_logger + +logger = get_logger(__name__, logging.ERROR) + +# increase recursion limit for recursive quicksort +sys.setrecursionlimit(3000) + +_MIN = 1e-9 +_MAX = 1e9 + + +def compute_moiety_conservation_laws( + stoichiometric_list: Sequence[float], + num_species: int, + num_reactions: int, + max_num_monte_carlo: int = 20, + rng_seed: Union[None, bool, int] = False +) -> Tuple[List[List[int]], List[List[float]]]: + """Compute moiety conservation laws. + + According to the algorithm proposed by De Martino et al. (2014) + https://doi.org/10.1371/journal.pone.0100750 + + :param stoichiometric_list: + the stoichiometric matrix as a list (species x reactions, + column-major ordering) + :param num_species: + total number of species in the reaction network + :param num_reactions: + total number of reactions in the reaction network + :param max_num_monte_carlo: + maximum number of MonteCarlo steps before changing to relaxation + :param rng_seed: + Seed for the random number generator. If `False`, the RNG will not be + re-initialized. Other values will be passed to :func:`random.seed`. + :returns: + Integer MCLs as list of lists of indices of involved species and + list of lists of corresponding coefficients. + """ + # compute semi-positive conservation laws + (kernel_dim, engaged_species, int_kernel_dim, conserved_moieties, + cls_species_idxs, cls_coefficients) = _kernel( + stoichiometric_list, num_species, num_reactions) + # if the number of integer MCLs equals total MCLS no MC relaxation + done = (int_kernel_dim == kernel_dim) + + if not done: + # construct interaction matrix + J, J2, fields = _fill(stoichiometric_list, engaged_species, + num_species) + + # seed random number generator + if rng_seed is not False: + random.seed(rng_seed) + + timer = 0 + # maximum number of montecarlo search before starting relaxation + while not done: + yes, int_kernel_dim, conserved_moieties = _monte_carlo( + engaged_species, J, J2, fields, conserved_moieties, + int_kernel_dim, cls_species_idxs, cls_coefficients, + num_species, max_iter=max_num_monte_carlo + ) + # if the number of integer MCLs equals total MCLS then MC done + done = (int_kernel_dim == kernel_dim) + timer = 0 if yes else timer + 1 + + if timer == max_num_monte_carlo: + done = _relax(stoichiometric_list, conserved_moieties, + num_reactions, num_species) + timer = 0 + _reduce(int_kernel_dim, cls_species_idxs, cls_coefficients, num_species) + + return cls_species_idxs[:int_kernel_dim], cls_coefficients[:int_kernel_dim] + + +def _qsort( + k: int, + km: int, + order: MutableSequence[int], + pivots: Sequence[int] +) -> None: + """Quicksort + + Recursive implementation of the quicksort algorithm + + :param k: + number of elements to sort + :param km: + current center element + :param order: + ordering of the elements + :param pivots: + corresponding pivot elements from scaled partial pivoting strategy + """ + # TODO: Rewrite into an iterative algorithm with pivoting strategy + + if k - km < 1: + # nothing to sort + return + + pivot = km + int((k - km) / 2) + l = 0 + p = k - km - 1 + new_order = [0] * (k - km) + for i in range(km, k): + if i != pivot: + if pivots[order[i]] < pivots[order[pivot]]: + new_order[l] = order[i] + l += 1 + else: + new_order[p] = order[i] + p -= 1 + new_order[p] = order[pivot] + order[km:k] = new_order + + # calculate center, then recursive calls on left and right intervals + centre = p + km + _qsort(k, centre + 1, order, pivots) + _qsort(centre, km, order, pivots) + + +def _kernel( + stoichiometric_list: Sequence[float], + num_species: int, + num_reactions: int +) -> Tuple[float, List[int], int, List[int], + List[List[int]], List[List[float]]]: + """ + Kernel (left nullspace of :math:`S`) calculation by Gaussian elimination + + To compute the left nullspace of the stoichiometric matrix :math:`S`, + a Gaussian elimination method with partial scaled pivoting is used to deal + effectively with a possibly ill-conditioned stoichiometric matrix + :math:`S`. + + Note that this is the Python reimplementation of the algorithm proposed by + `De Martino et al. (2014) `_ + and thus a direct adaption of the original implementation in C++. + + :param stoichiometric_list: + the stoichiometric matrix as a list (species x reactions, + col-major ordering) + :param num_species: + total number of species in the reaction network + :param num_reactions: + total number of reactions in the reaction network + :returns: + kernel dimension, MCLs, integer kernel dimension, integer MCLs and + indices to species and reactions in the preceding order as a tuple + """ + matrix: List[List[int]] = [[] for _ in range(num_species)] + matrix2: List[List[float]] = [[] for _ in range(num_species)] + i_reaction = 0 + i_species = 0 + for val in stoichiometric_list: + if val != 0: + matrix[i_species].append(i_reaction) + matrix2[i_species].append(val) + i_species += 1 + if i_species == num_species: + i_species = 0 + i_reaction += 1 + for i in range(num_species): + matrix[i].append(num_reactions + i) + matrix2[i].append(1) + + order: List[int] = list(range(num_species)) + pivots = [matrix[i][0] if len(matrix[i]) else _MAX + for i in range(num_species)] + + done = False + while not done: + _qsort(num_species, 0, order, pivots) + for j in range(num_species - 1): + if pivots[order[j + 1]] == pivots[order[j]] != _MAX: + min1 = _MAX + if len(matrix[order[j]]) > 1: + for i in range(len(matrix[order[j]])): + min1 = min(min1, abs(matrix2[order[j]][0] + / matrix2[order[j]][i])) + + min2 = _MAX + if len(matrix[order[j + 1]]) > 1: + for i in range(len(matrix[order[j + 1]])): + min2 = min(min2, abs(matrix2[order[j + 1]][0] + / matrix2[order[j + 1]][i])) + + if min2 > min1: + # swap + k2 = order[j + 1] + order[j + 1] = order[j] + order[j] = k2 + done = True + + for j in range(num_species - 1): + if pivots[order[j + 1]] == pivots[order[j]] != _MAX: + k1 = order[j + 1] + k2 = order[j] + column: List[float] = [0] * (num_species + num_reactions) + g = matrix2[k2][0] / matrix2[k1][0] + for i in range(1, len(matrix[k1])): + column[matrix[k1][i]] = matrix2[k1][i] * g + + for i in range(1, len(matrix[k2])): + column[matrix[k2][i]] -= matrix2[k2][i] + + matrix[k1] = [] + matrix2[k1] = [] + for col_idx, col_val in enumerate(column): + if abs(col_val) > _MIN: + matrix[k1].append(col_idx) + matrix2[k1].append(col_val) + + done = False + if len(matrix[order[j + 1]]): + pivots[order[j + 1]] = matrix[order[j + 1]][0] + else: + pivots[order[j + 1]] = _MAX + + RSolutions = [[] for _ in range(num_species)] + RSolutions2 = [[] for _ in range(num_species)] + kernel_dim = 0 + + for i in range(num_species): + done = all(matrix[i][j] >= num_reactions + for j in range(len(matrix[i]))) + if done and len(matrix[i]): + for j in range(len(matrix[i])): + RSolutions[kernel_dim].append(matrix[i][j] - num_reactions) + RSolutions2[kernel_dim].append(matrix2[i][j]) + kernel_dim += 1 + del matrix, matrix2 + + matched = [] + int_matched = [] + cls_species_idxs = [[] for _ in range(num_species)] + cls_coefficients = [[] for _ in range(num_species)] + + i2 = 0 + for i in range(kernel_dim): + ok2 = True + for j in range(len(RSolutions[i])): + if RSolutions2[i][j] * RSolutions2[i][0] < 0: + ok2 = False + if not matched or all( + cur_matched != RSolutions[i][j] for cur_matched in + matched + ): + matched.append(RSolutions[i][j]) + if ok2 and len(RSolutions[i]): + min_value = _MAX + for j in range(len(RSolutions[i])): + cls_species_idxs[i2].append(RSolutions[i][j]) + cls_coefficients[i2].append(abs(RSolutions2[i][j])) + min_value = min(min_value, abs(RSolutions2[i][j])) + if not int_matched or all( + cur_int_matched != cls_species_idxs[i2][j] + for cur_int_matched in int_matched + ): + int_matched.append(cls_species_idxs[i2][j]) + for j in range(len(cls_species_idxs[i2])): + cls_coefficients[i2][j] /= min_value + i2 += 1 + int_kernel_dim = i2 + + assert int_kernel_dim <= kernel_dim + assert len(cls_species_idxs) == len(cls_coefficients), \ + "Inconsistent number of conserved quantities in coefficients and " \ + "species" + return (kernel_dim, matched, int_kernel_dim, int_matched, cls_species_idxs, + cls_coefficients) + + +def _fill( + stoichiometric_list: Sequence[float], + matched: Sequence[int], + num_species: int +) -> Tuple[List[List[int]], List[List[int]], List[int]]: + """Construct interaction matrix + + Construct the interaction matrix out of the given stoichiometric matrix + :math:`S`. + + :param stoichiometric_list: + the stoichiometric matrix given as a flat list + :param matched: + found and independent moiety conservation laws (MCL) + :param num_species: + number of rows in :math:`S` + :returns: + interactions of metabolites and reactions, and matrix of interaction + """ + dim = len(matched) + + # for each entry in the stoichiometric matrix save interaction + i_reaction = 0 + i_species = 0 + matrix = [[] for _ in range(dim)] + matrix2 = [[] for _ in range(dim)] + for val in stoichiometric_list: + if val != 0: + take = dim + for matched_idx, matched_val in enumerate(matched): + if i_species == matched_val: + take = matched_idx + if take < dim: + matrix[take].append(i_reaction) + matrix2[take].append(val) + i_species += 1 + if i_species == num_species: + i_species = 0 + i_reaction += 1 + + J = [[] for _ in range(num_species)] + J2 = [[] for _ in range(num_species)] + fields = [0] * num_species + for i in range(dim): + for j in range(i, dim): + interactions = 0 + for po in range(len(matrix[i])): + for pu in range(len(matrix[j])): + if matrix[i][po] == matrix[j][pu]: + interactions += matrix2[i][po] * matrix2[j][pu] + if j == i: + fields[i] = interactions + elif abs(interactions) > _MIN: + J[i].append(j) + J2[i].append(interactions) + J[j].append(i) + J2[j].append(interactions) + return J, J2, fields + + +def _is_linearly_dependent( + vector: Sequence[float], + int_kernel_dim: int, + cls_species_idxs: Sequence[Sequence[int]], + cls_coefficients: Sequence[Sequence[float]], + matched: Sequence[int], + num_species: int +) -> bool: + """Check for linear dependence between MCLs + + Check if the solutions found with Monte Carlo are linearly independent + with respect to the previous found solution for all MCLs involved + + :param vector: + found basis + :param int_kernel_dim: + number of integer conservative laws + :param cls_species_idxs: + NSolutions contains the species involved in the MCL + :param cls_coefficients: + NSolutions2 contains the corresponding coefficients in the MCL + :param matched: + actual found MCLs + :param num_species: + number of rows in :math:`S` + :returns: + boolean indicating linear dependence (true) or not (false) + """ + K = int_kernel_dim + 1 + matrix: List[List[int]] = [[] for _ in range(K)] + matrix2: List[List[float]] = [[] for _ in range(K)] + # Populate matrices with species ids and coefficients for CLs + for i in range(K - 1): + for j in range(len(cls_species_idxs[i])): + matrix[i].append(cls_species_idxs[i][j]) + matrix2[i].append(cls_coefficients[i][j]) + + order2 = list(range(len(matched))) + pivots2 = matched[:] + _qsort(len(matched), 0, order2, pivots2) + + # ensure positivity + for i in range(len(matched)): + if vector[order2[i]] > _MIN: + matrix[K - 1].append(matched[order2[i]]) + matrix2[K - 1].append(vector[order2[i]]) + + order = list(range(K)) + pivots = [matrix[i][0] if len(matrix[i]) else _MAX for i in range(K)] + + # check for linear independence of the solution + ok = False + while not ok: + _qsort(K, 0, order, pivots) + for j in range(K - 1): + if pivots[order[j + 1]] == pivots[order[j]] != _MAX: + min1 = _MAX + if len(matrix[order[j]]) > 1: + for i in range(len(matrix[order[j]])): + min1 = min(min1, abs(matrix2[order[j]][0] + / matrix2[order[j]][i])) + min2 = _MAX + if len(matrix[order[j + 1]]) > 1: + for i in range(len(matrix[order[j + 1]])): + min2 = min(min2, abs(matrix2[order[j + 1]][0] + / matrix2[order[j + 1]][i])) + if min2 > min1: + # swap + k2 = order[j + 1] + order[j + 1] = order[j] + order[j] = k2 + ok = True + for j in range(K - 1): + if pivots[order[j + 1]] == pivots[order[j]] != _MAX: + k1 = order[j + 1] + k2 = order[j] + column: List[float] = [0] * num_species + g = matrix2[k2][0] / matrix2[k1][0] + for i in range(1, len(matrix[k1])): + column[matrix[k1][i]] = matrix2[k1][i] * g + for i in range(1, len(matrix[k2])): + column[matrix[k2][i]] -= matrix2[k2][i] + + matrix[k1] = [] + matrix2[k1] = [] + for i in range(num_species): + if abs(column[i]) > _MIN: + matrix[k1].append(i) + matrix2[k1].append(column[i]) + ok = False + pivots[k1] = matrix[k1][0] if len(matrix[k1]) else _MAX + K1 = sum(len(matrix[i]) > 0 for i in range(K)) + return K == K1 + + +def _monte_carlo( + matched: Sequence[int], + J: Sequence[Sequence[int]], + J2: Sequence[Sequence[float]], + fields: Sequence[float], + int_matched: MutableSequence[int], + int_kernel_dim: int, + cls_species_idxs: MutableSequence[MutableSequence[int]], + cls_coefficients: MutableSequence[MutableSequence[float]], + num_species: int, + initial_temperature: float = 1, + cool_rate: float = 1e-3, + max_iter: int = 10 +) -> Tuple[bool, int, Sequence[int]]: + """MonteCarlo simulated annealing for finding integer MCLs + + Finding integer solutions for the MCLs by Monte Carlo, see step (b) in + the De Martino (2014) paper and Eqs. 11-13 in the publication + + :param matched: + number of found MCLs + :param J: + index of metabolites involved in a MCL + :param J2: + coefficients of metabolites involved in a MCL + :param fields: + actual number of metabolites involved in a MCL + :param int_matched: + actual matched MCLs + :param int_kernel_dim: + number of MCLs found in :math:`S` + :param cls_species_idxs: + Modified in-place. + :param cls_coefficients: + Modified in-place. + :param initial_temperature: + initial temperature + :param cool_rate: + cooling rate of simulated annealing + :param max_iter: + maximum number of MonteCarlo steps before changing to relaxation + :returns: + status of MC iteration, number of integer MCLs, number of MCLs, + metabolites and reaction indices, MCLs and integer MCLs as a tuple + + status indicates if the currently found moiety by the Monte Carlo + process is linearly dependent (False) or linearly independent (True) + in case of linear dependence, the current Monte Carlo cycle can be + considered otherwise the algorithm retries Monte Carlo up to max_iter + """ + dim = len(matched) + num = [int(2 * random.uniform(0, 1)) if len(J[i]) else 0 + for i in range(dim)] + numtot = sum(num) + + def compute_h(): + H = 0 + for i in range(dim): + H += fields[i] * num[i] ** 2 + for j in range(len(J[i])): + H += J2[i][j] * num[i] * num[J[i][j]] + return H + + H = compute_h() + + count = 0 + howmany = 0 + T1 = initial_temperature + e = math.exp(-1 / T1) + while True: + en = int(random.uniform(0, 1) * dim) + while not len(J[en]): + en = int(random.uniform(0, 1) * dim) + + p = -1 if num[en] > 0 and random.uniform(0, 1) < 0.5 else 1 + delta = fields[en] * num[en] + for i in range(len(J[en])): + delta += J2[en][i] * num[J[en][i]] + delta = 2 * p * delta + fields[en] + + if delta < 0 or random.uniform(0, 1) < math.pow(e, delta): + num[en] += p + numtot += p + H += delta + + count += 1 + if count % dim == 0: + T1 -= cool_rate + if T1 <= 0: + T1 = cool_rate + e = math.exp(-1 / T1) + + if count == dim // cool_rate: + count = 0 + T1 = initial_temperature + e = math.exp(-1 / T1) + en = int(random.uniform(0, 1) * dim) + while not len(J[en]): + en = int(random.uniform(0, 1) * dim) + num = [0] * dim + num[en] = 1 + numtot = 1 + + H = compute_h() + howmany += 1 + + if (H < _MIN and numtot > 0) or (howmany == 10 * max_iter): + break + + if howmany >= 10 * max_iter: + return False, int_kernel_dim, int_matched + + # founds MCLS? need to check for linear independence + if len(int_matched) and not _is_linearly_dependent( + num, int_kernel_dim, cls_species_idxs, + cls_coefficients, matched, num_species): + logger.debug( + "Found a moiety but it is linearly dependent... next.") + return False, int_kernel_dim, int_matched + + # reduce by MC procedure + order2 = list(range(len(matched))) + pivots2 = matched[:] + _qsort(len(matched), 0, order2, pivots2) + for i in range(len(matched)): + if num[order2[i]] > 0: + cls_species_idxs[int_kernel_dim].append(matched[order2[i]]) + cls_coefficients[int_kernel_dim].append(num[order2[i]]) + int_kernel_dim += 1 + _reduce(int_kernel_dim, cls_species_idxs, cls_coefficients, num_species) + min_value = 1000 + for i in range(len(cls_species_idxs[int_kernel_dim - 1])): + if not len(int_matched) \ + or all(cur_int_matched + != cls_species_idxs[int_kernel_dim - 1][i] + for cur_int_matched in int_matched): + int_matched.append(cls_species_idxs[int_kernel_dim - 1][i]) + + min_value = min(min_value, cls_coefficients[int_kernel_dim - 1][i]) + for i in range(len(cls_species_idxs[int_kernel_dim - 1])): + cls_coefficients[int_kernel_dim - 1][i] /= min_value + + logger.debug( + f"Found linearly independent moiety, now there are " + f"{int_kernel_dim} engaging {len(int_matched)} species") + + return True, int_kernel_dim, int_matched + + +def _relax( + stoichiometric_list: Sequence[float], + int_matched: Sequence[int], + num_reactions: int, + num_species: int, + relaxation_max: float = 1e6, + relaxation_step: float = 1.9 +) -> bool: + """Relaxation scheme for Monte Carlo final solution + + Checking for completeness using Motzkin's theorem. See Step (c) in + De Martino (2014) and the Eqs. 14-16 in the corresponding publication + + :param stoichiometric_list: + stoichiometric matrix :math:`S` as a flat list (column-major ordering) + :param int_matched: + number of matched integer CLs + :param num_reactions: + number of reactions in reaction network + :param num_species: + number of species in reaction network + :param relaxation_max: + maximum relaxation step + :param relaxation_step: + relaxation step width + :returns: + boolean indicating if relaxation has succeeded (``True``) or not + (``False``) + """ + K = len(int_matched) + matrix: List[List[int]] = [[] for _ in range(K)] + matrix2: List[List[float]] = [[] for _ in range(K)] + i_reaction = 0 + i_species = 0 + for val in stoichiometric_list: + if val != 0: + take = K + if K > 0: + for i in range(K): + if i_species == int_matched[i]: + take = i + if take < K: + matrix[take].append(i_reaction) + matrix2[take].append(val) + i_species += 1 + if i_species == num_species: + i_species = 0 + i_reaction += 1 + + # reducing the stoichiometric matrix of conserved moieties to row echelon + # form by Gaussian elimination + order = list(range(K)) + pivots = [matrix[i][0] if len(matrix[i]) else _MAX for i in range(K)] + done = False + while not done: + _qsort(K, 0, order, pivots) + for j in range(K - 1): + if pivots[order[j + 1]] == pivots[order[j]] != _MAX: + min1 = _MAX + if len(matrix[order[j]]) > 1: + for i in range(len(matrix[order[j]])): + min1 = min(min1, abs(matrix2[order[j]][0] + / matrix2[order[j]][i])) + min2 = _MAX + if len(matrix[order[j + 1]]) > 1: + for i in range(len(matrix[order[j + 1]])): + min2 = min(min2, abs(matrix2[order[j + 1]][0] + / matrix2[order[j + 1]][i])) + if min2 > min1: + # swap + k2 = order[j + 1] + order[j + 1] = order[j] + order[j] = k2 + done = True + for j in range(K - 1): + if pivots[order[j + 1]] == pivots[order[j]] != _MAX: + k1 = order[j + 1] + k2 = order[j] + column: List[float] = [0] * num_reactions + g = matrix2[k2][0] / matrix2[k1][0] + for i in range(1, len(matrix[k1])): + column[matrix[k1][i]] = matrix2[k1][i] * g + for i in range(1, len(matrix[k2])): + column[matrix[k2][i]] -= matrix2[k2][i] + + matrix[k1] = [] + matrix2[k1] = [] + for col_idx, col_val in enumerate(column): + if abs(col_val) > _MIN: + matrix[k1].append(col_idx) + matrix2[k1].append(col_val) + done = False + if len(matrix[order[j + 1]]): + pivots[order[j + 1]] = matrix[order[j + 1]][0] + else: + pivots[order[j + 1]] = _MAX + + # normalize + for matrix2_i in matrix2: + if len(matrix2_i): + norm = matrix2_i[0] + for j in range(len(matrix2_i)): + matrix2_i[j] /= norm + + for k1 in reversed(range(K - 1)): + k = order[k1] + if len(matrix[k]) <= 1: + continue + + i = 0 + while i < len(matrix[k]): + for i_species in range(k1 + 1, K): + j = order[i_species] + if not len(matrix[j]) or matrix[j][0] != matrix[k][i]: + continue + + row_k: List[float] = [0] * num_reactions + for a in range(len(matrix[k])): + row_k[matrix[k][a]] = matrix2[k][a] + for a in range(len(matrix[j])): + row_k[matrix[j][a]] -= matrix2[j][a] * matrix2[k][i] + # filter + matrix[k] = [row_idx for row_idx, row_val in enumerate(row_k) + if row_val != 0] + matrix2[k] = [row_val for row_val in row_k if row_val != 0] + i += 1 + + indip = [K + 1] * num_reactions + for i in range(K): + if len(matrix[i]): + indip[matrix[i][0]] = i + M1 = 0 + for i in range(num_reactions): + if indip[i] == K + 1: + indip[i] = K + M1 + M1 += 1 + + matrixAus = [[] for _ in range(M1)] + matrixAus2 = [[] for _ in range(M1)] + i_reaction = 0 + for i in range(num_reactions): + if indip[i] >= K: + matrixAus[i_reaction].append(i) + matrixAus2[i_reaction].append(1) + i_reaction += 1 + else: + t = indip[i] + if len(matrix[t]) > 1: + for k in range(1, len(matrix[t])): + idx = indip[matrix[t][k]] - K + matrixAus[idx].append(i) + matrixAus2[idx].append(-matrix2[t][k]) + del matrix + + N1 = num_species - K + matrix_aus = [[] for _ in range(N1)] + matrix_aus2 = [[] for _ in range(N1)] + k1 = 0 + i_reaction = 0 + i_species = 0 + for val in stoichiometric_list: + take = 1 + for i in range(len(int_matched)): + if i_species == int_matched[i]: + take -= 1 + if val != 0 and take == 1: + matrix_aus[k1].append(i_reaction) + matrix_aus2[k1].append(val) + i_species += 1 + k1 += take + if i_species == num_species: + i_species = 0 + k1 = 0 + i_reaction += 1 + + matrixb = [[] for _ in range(N1)] + matrixb2 = [[] for _ in range(N1)] + for i in range(M1): + for j in range(N1): + if len(matrix_aus[j]) * len(matrixAus[i]): + prod = 0 + for ib in range(len(matrixAus[i])): + for jb in range(len(matrix_aus[j])): + if matrixAus[i][ib] == matrix_aus[j][jb]: + prod += matrixAus2[i][ib] * matrix_aus2[j][jb] + if abs(prod) > _MIN: + matrixb[j].append(i) + matrixb2[j].append(prod) + del matrixAus, matrixAus2, matrix_aus, matrix_aus2 + + var = [_MIN] * M1 + time = 0 + cmin_idx = 0 + while True: + cmin = 1000 + for j in range(N1): + constr = 0 + if len(matrixb[j]): + for i in range(len(matrixb[j])): + constr += matrixb2[j][i] * var[matrixb[j][i]] + if constr < cmin: + cmin_idx = j + cmin = constr + if cmin >= 0: + # constraints satisfied + break + + # Motzkin relaxation + alpha = -relaxation_step * cmin + fact = sum(val ** 2 for val in matrixb2[cmin_idx]) + alpha /= fact + alpha = max(1e-9 * _MIN, alpha) + for j in range(len(matrixb[cmin_idx])): + var[matrixb[cmin_idx][j]] += alpha * matrixb2[cmin_idx][j] + + time += 1 + if time >= relaxation_max: + # timeout + break + + return done + + +def _reduce( + int_kernel_dim: int, + cls_species_idxs: MutableSequence[MutableSequence[int]], + cls_coefficients: MutableSequence[MutableSequence[float]], + num_species: int +) -> None: + """Reducing the solution which has been found by the Monte Carlo process + + In case of superpositions of independent MCLs one can reduce by + iteratively subtracting the other independent MCLs, taking care + to maintain then non-negativity constraint, see Eq. 13 in De Martino (2014) + + :param int_kernel_dim: + number of found MCLs + :param cls_species_idxs: + Species indices involved in each of the conservation laws. + Modified in-place. + :param cls_coefficients: + Coefficients for each of the species involved in each of the + conservation laws. Modified in-place. + :param num_species: + number of species / rows in :math:`S` + """ + K = int_kernel_dim + order = list(range(K)) + pivots = [-len(cls_species_idxs[i]) for i in range(K)] + + done = False + while not done: + _qsort(K, 0, order, pivots) + done = True + for i in range(K - 1): + k1 = order[i] + for j in range(i + 1, K): + k2 = order[j] + column: List[float] = [0] * num_species + for species_idx, coefficient \ + in zip(cls_species_idxs[k1], cls_coefficients[k1]): + column[species_idx] = coefficient + ok1 = True + for species_idx, coefficient \ + in zip(cls_species_idxs[k2], cls_coefficients[k2]): + column[species_idx] -= coefficient + if column[species_idx] < -_MIN: + ok1 = False + break + if not ok1: + continue + + done = False + cls_species_idxs[k1] = [] + cls_coefficients[k1] = [] + for col_idx, col_val in enumerate(column): + if abs(col_val) > _MIN: + cls_species_idxs[k1].append(col_idx) + cls_coefficients[k1].append(col_val) + pivots[k1] = -len(cls_species_idxs[k1]) diff --git a/python/amici/import_utils.py b/python/amici/import_utils.py index 054b820467..9be9d44f3a 100644 --- a/python/amici/import_utils.py +++ b/python/amici/import_utils.py @@ -1,20 +1,39 @@ """Miscellaneous functions related to model import, independent of any specific model format""" - -from typing import ( - Dict, Union, Optional, Callable, Sequence, Tuple, Iterable, Any -) -import sympy as sp import enum import itertools as itt +import sys +from typing import (Any, Callable, Dict, Iterable, Optional, Sequence, Tuple, + Union) -from toposort import toposort -from sympy.logic.boolalg import BooleanAtom +import sympy as sp from sympy.functions.elementary.piecewise import ExprCondPair +from sympy.logic.boolalg import BooleanAtom +from toposort import toposort SymbolDef = Dict[sp.Symbol, Union[Dict[str, sp.Expr], sp.Expr]] +# Monkey-patch toposort CircularDependencyError to handle non-sortable objects, +# such as sympy objects +class CircularDependencyError(ValueError): + def __init__(self, data): + # Sort the data just to make the output consistent, for use in + # error messages. That's convenient for doctests. + s = "Circular dependencies exist among these items: {{{}}}".format( + ", ".join( + "{!r}:{!r}".format(key, value) for key, value in sorted( + {str(k): v for k, v in data.items()}.items()) + ) + ) + super(CircularDependencyError, self).__init__(s) + self.data = data + + +setattr(sys.modules["toposort"], "CircularDependencyError", + CircularDependencyError) + + class ObservableTransformation(str, enum.Enum): """ Different modes of observable transformation. diff --git a/python/amici/sbml_import.py b/python/amici/sbml_import.py index b86e822beb..2d11fb77e6 100644 --- a/python/amici/sbml_import.py +++ b/python/amici/sbml_import.py @@ -4,33 +4,33 @@ This module provides all necessary functionality to import a model specified in the `Systems Biology Markup Language (SBML) `_. """ - - -import sympy as sp -import libsbml as sbml -import re -import math +import copy import itertools as itt -import warnings import logging -import copy -from typing import ( - Dict, List, Callable, Any, Iterable, Union, Optional, -) +import math +import os +import re +import warnings +from typing import (Any, Callable, Dict, Iterable, List, Optional, Union) -from .import_utils import ( - smart_subs, smart_subs_dict, toposort_symbols, - _get_str_symbol_identifiers, noise_distribution_to_cost_function, - noise_distribution_to_observable_transformation, _parse_special_functions, - _check_unsupported_functions, -) +import libsbml as sbml +import sympy as sp + +from . import has_clibs +from .conserved_moieties import compute_moiety_conservation_laws +from .constants import SymbolId +from .import_utils import (_check_unsupported_functions, + _get_str_symbol_identifiers, + _parse_special_functions, + noise_distribution_to_cost_function, + noise_distribution_to_observable_transformation, + smart_subs, smart_subs_dict, toposort_symbols, + CircularDependencyError) +from .logging import get_logger, log_execution_time, set_log_level from .ode_export import ( ODEExporter, ODEModel, generate_measurement_symbol, symbol_with_assumptions ) -from .constants import SymbolId -from .logging import get_logger, log_execution_time, set_log_level -from . import has_clibs class SBMLException(Exception): @@ -282,8 +282,12 @@ def sbml2amici(self, if set to ``True``, conservation laws are automatically computed and applied such that the state-jacobian of the ODE right-hand-side has full rank. This option should be set to - ``True`` when using the newton algorithm to compute steadystate + ``True`` when using the Newton algorithm to compute steadystate sensitivities. + Conservation laws for constant species are enabled by default. + Support for conservation laws for non-constant species is + experimental and may be enabled by setting an environment variable + ``AMICI_EXPERIMENTAL_SBML_NONCONST_CLS`` to any value. :param simplify: see :attr:`ODEModel._simplify` @@ -347,7 +351,8 @@ def sbml2amici(self, sbml.L3P_PARSE_LOG_AS_LN ) self._process_sbml(constant_parameters) - if self.symbols.get(SymbolId.EVENT, False): + if self.symbols.get(SymbolId.EVENT, False) \ + or any(e.has(sp.Heaviside) for e in self.flux_vector): if compute_conservation_laws: logger.warning( 'Conservation laws are currently not supported for models ' @@ -1385,21 +1390,24 @@ def process_conservation_laws(self, ode_model) -> None: :param ode_model: ODEModel object with basic definitions - - :returns volume_updates_solver: - List (according to reduced stoichiometry) with updates for the - stoichiometric matrix accounting for compartment volumes """ conservation_laws = [] - # So far, only conservation laws for constant species are supported + # Create conservation laws for constant species species_solver = _add_conservation_for_constant_species( ode_model, conservation_laws ) + # Non-constant species processed here + if "AMICI_EXPERIMENTAL_SBML_NONCONST_CLS" in os.environ \ + or "GITHUB_ACTIONS" in os.environ: + species_solver = list(set( + self._add_conservation_for_non_constant_species( + ode_model, conservation_laws)) & set(species_solver)) # Check, whether species_solver is empty now. As currently, AMICI - # cannot handle ODEs without species, CLs must switched in this case - if len(species_solver) == 0: + # cannot handle ODEs without species, CLs must be switched off in this + # case + if not len(species_solver): conservation_laws = [] species_solver = list(range(ode_model.num_states_rdata())) @@ -1411,6 +1419,138 @@ def process_conservation_laws(self, ode_model) -> None: for cl in conservation_laws: ode_model.add_conservation_law(**cl) + def _add_conservation_for_non_constant_species( + self, + ode_model: ODEModel, + conservation_laws: List[ConservationLaw] + ) -> List[int]: + """Add non-constant species to conservation laws + + :param ode_model: + ODEModel object with basic definitions + :param conservation_laws: + List of already known conservation laws + :returns: + List of species indices which later remain in the ODE solver + """ + # indices of retained species + species_solver = list(range(ode_model.num_states_rdata())) + + try: + stoichiometric_list = [ + float(entry) for entry in self.stoichiometric_matrix.T.flat() + ] + except TypeError: + # https://github.com/AMICI-dev/AMICI/issues/1673 + warnings.warn("Conservation laws for non-constant species in " + "combination with parameterized stoichiometric " + "coefficients are not currently supported " + "and will be turned off.") + return species_solver + + if any(rule.getTypeCode() == sbml.SBML_RATE_RULE + for rule in self.sbml.getListOfRules()): + # see SBML semantic test suite, case 33 for an example + warnings.warn("Conservation laws for non-constant species in " + "models with RateRules are not currently supported " + "and will be turned off.") + return species_solver + + cls_state_idxs, cls_coefficients = compute_moiety_conservation_laws( + stoichiometric_list, *self.stoichiometric_matrix.shape, + rng_seed=32) + + # previously removed constant species + eliminated_state_ids = {cl['state'] for cl in conservation_laws} + + # iterate over list of conservation laws, create symbolic expressions, + # and mark replaced species for removal from stoichiometric matrix + species_to_be_removed = set() + # keep new conservation laws separate until we know everything worked + new_conservation_laws = [] + for state_idxs, coefficients in zip(cls_state_idxs, cls_coefficients): + assert len(state_idxs) == len(coefficients) + + state_ids = [ode_model._states[i_state].get_id() + for i_state in state_idxs] + + # choose a state that is not already subject to removal + try: + target_state_cl_idx = next(filter( + lambda x: state_ids[x] not in eliminated_state_ids, + range(len(state_idxs))) + ) + except StopIteration: + # all engaged states have already been eliminated + continue + + target_state_model_idx = state_idxs[target_state_cl_idx] + target_state_id = state_ids[target_state_cl_idx] + eliminated_state_ids.add(target_state_id) + + compartment_sizes = [ + self.compartments[ + self.symbols[SymbolId.SPECIES][state_id]['compartment']] + if not self.symbols[SymbolId.SPECIES][state_id]['amount'] + else sp.Integer(1) + for state_id in state_ids + ] + if any(x.free_symbols for x in compartment_sizes): + # https://github.com/AMICI-dev/AMICI/issues/1673 + # see SBML semantic test suite, case 783 for an example + warnings.warn( + "Conservation laws for non-constant species in " + "compartments with parameter-dependent size are not " + "currently supported and will be turned off.") + return species_solver + + total_abundance = symbol_with_assumptions(f'tcl_{target_state_id}') + target_compartment = compartment_sizes[target_state_cl_idx] + target_state_coeff = coefficients[target_state_cl_idx] + + # \sum coeff * state * volume + abundance_expr = sp.Add(*[ + state_id * coeff * compartment + for state_id, coeff, compartment + in zip(state_ids, coefficients, compartment_sizes) + ]) + + new_conservation_laws.append({ + 'state': target_state_id, + 'total_abundance': total_abundance, + 'state_expr': + (total_abundance - (abundance_expr + - target_state_id * target_compartment + * target_state_coeff)) + / target_state_coeff / target_compartment, + 'abundance_expr': abundance_expr + }) + species_to_be_removed.add(target_state_model_idx) + + # replace eliminated states by their state expressions, taking care of + # any (non-cyclic) dependencies + state_exprs = { + cl['state']: cl['state_expr'] + for cl in itt.chain(conservation_laws, new_conservation_laws) + } + try: + sorted_state_exprs = toposort_symbols(state_exprs) + except CircularDependencyError as e: + # see SBML semantic test suite, case 18 for an example + warnings.warn("Circular dependency detected in conservation laws. " + "Skipping conservation laws for non-constant " + f"species. Error was: {e}.") + return species_solver + + for cl in new_conservation_laws: + cl['state_expr'] = smart_subs_dict(cl['state_expr'], + sorted_state_exprs) + + conservation_laws.extend(new_conservation_laws) + + # list of species that are not determined by conservation laws + return [ix for ix in species_solver if ix not in species_to_be_removed] + def _replace_compartments_with_volumes(self): """ Replaces compartment symbols in expressions with their respective diff --git a/python/amici/setup.template.py b/python/amici/setup.template.py index 990b5ea232..688b29f400 100644 --- a/python/amici/setup.template.py +++ b/python/amici/setup.template.py @@ -34,6 +34,8 @@ def build_extension(self, ext): self.compiler.compile = compile_parallel.__get__( self.compiler, setuptools._distutils.ccompiler.CCompiler) + print(f"Building model extension in {os.getcwd()}") + build_ext.build_extension(self, ext) def find_swig(self) -> str: diff --git a/python/sdist/amici/conserved_moieties.py b/python/sdist/amici/conserved_moieties.py new file mode 120000 index 0000000000..8e96336ae0 --- /dev/null +++ b/python/sdist/amici/conserved_moieties.py @@ -0,0 +1 @@ +../../amici/conserved_moieties.py \ No newline at end of file diff --git a/python/tests/test_conserved_moieties.py b/python/tests/test_conserved_moieties.py new file mode 100644 index 0000000000..77edbbd983 --- /dev/null +++ b/python/tests/test_conserved_moieties.py @@ -0,0 +1,284 @@ +"""Tests for conservation laws / conserved moieties""" +import os +from time import perf_counter + +import numpy as np +import pytest +import sympy as sp + +from amici.conserved_moieties import (_fill, _kernel, + compute_moiety_conservation_laws) +from amici.logging import get_logger, log_execution_time + +logger = get_logger(__name__) + +# reference data for `engaged_species` after kernel() +demartino2014_kernel_engaged_species = [ + 179, 181, 185, 186, 187, 190, 191, 194, 195, 197, 198, 200, 208, 209, 210, + 211, 214, 215, 218, 219, 221, 222, 224, 277, 292, 340, 422, 467, 468, 490, + 491, 598, 613, 966, 968, 1074, 1171, 1221, 1223, 1234, 1266, 1478, 1479, + 1480, 1481, 1496, 1497, 1498, 1501, 1526, 1527, 1528, 1529, 394, 1066, 398, + 465, 466, 594, 671, 429, 990, 652, 655, 662, 663, 664, 665, 666, 667, 668, + 669, 759, 760, 920, 921, 569, 1491, 1055, 1546, 276, 1333, 1421, 1429, + 1430, 1438, 1551, 1428, 1439, 1552, 1513, 1553, 1520, 1523, 1530, 1531, + 384, 1536, 440, 1537, 447, 1538, 456, 1539, 582, 1540, 876, 1541, 885, + 1542, 911, 1543, 978, 1544, 1010, 1545, 1070, 1547, 761, 1127, 1548, 1324, + 1549, 1370, 1550, 1554, 1560, 1555, 1580, 1556, 1644 +] + + +@pytest.fixture(scope="session") +def data_demartino2014(): + """Get tests from DeMartino2014 Suppl. Material""" + import urllib.request + import io + import gzip + + # stoichiometric matrix + response = urllib.request.urlopen( + r'https://chimera.roma1.infn.it/SYSBIO/test-ecoli.dat.gz', + timeout=10 + ) + data = gzip.GzipFile(fileobj=io.BytesIO(response.read())) + S = [int(item) for sl in + [entry.decode('ascii').strip().split('\t') + for entry in data.readlines()] for item in sl] + + # metabolite / row names + response = urllib.request.urlopen( + r'https://chimera.roma1.infn.it/SYSBIO/test-ecoli-met.txt', + timeout=10 + ) + row_names = [entry.decode('ascii').strip() + for entry in io.BytesIO(response.read())] + + return S, row_names + + +def output( + int_kernel_dim, kernel_dim, int_matched, species_indices, + species_coefficients, row_names, verbose=False +): + """Print status""" + print(f"There are {int_kernel_dim} linearly independent conserved " + f"moieties, engaging {len(int_matched)} metabolites.") + if int_kernel_dim == kernel_dim: + print("They generate all the conservation laws") + else: + print(f"They don't generate all the conservation laws, " + f"{kernel_dim - int_kernel_dim} of them are not reducible to " + "moieties") + # print all conservation laws + if verbose: + for i, coefficients, engaged_species_idxs \ + in enumerate(zip(species_coefficients, species_indices)): + print(f"Moiety number {i + 1} engages {len(engaged_species_idxs)} " + "metabolites:") + for species_idx, coefficient \ + in zip(engaged_species_idxs, coefficients): + print(f"\t{row_names[species_idx]}\t{coefficient}") + + +def test_kernel_demartino2014(data_demartino2014, quiet=True): + """Invoke test case and benchmarking for De Martino's published results + for E. coli network. Kernel-only.""" + stoichiometric_list, row_names = data_demartino2014 + num_species = 1668 + num_reactions = 2381 + assert len(stoichiometric_list) == num_species * num_reactions, \ + "Unexpected dimension of stoichiometric matrix" + + # Expected number of metabolites per conservation law found after kernel() + expected_num_species = \ + [53] + [2] * 11 + [6] + [3] * 2 + [2] * 15 + [3] + [2] * 5 + + (kernel_dim, engaged_species, int_kernel_dim, conserved_moieties, + cls_species_idxs, cls_coefficients) = _kernel( + stoichiometric_list, num_species, num_reactions) + + if not quiet: + output(int_kernel_dim, kernel_dim, engaged_species, cls_species_idxs, + cls_coefficients, row_names) + + # There are 38 conservation laws, engaging 131 metabolites + # 36 are integers (conserved moieties), engaging 128 metabolites (from C++) + assert kernel_dim == 38, "Not all conservation laws found" + assert int_kernel_dim == 36, "Not all conserved moiety laws found" + assert engaged_species == demartino2014_kernel_engaged_species, \ + "Wrong engaged metabolites reported" + assert len(conserved_moieties) == 128, \ + "Wrong number of conserved moieties reported" + + # Assert that each conserved moiety has the correct number of metabolites + for i in range(int_kernel_dim - 2): + assert (len(cls_species_idxs[i]) == expected_num_species[i]), \ + f"Moiety #{i + 1} failed for test case (De Martino et al.)" + + +def test_fill_demartino2014(data_demartino2014): + """Test creation of interaction matrix""" + stoichiometric_list, row_names = data_demartino2014 + num_species = 1668 + J, J2, fields = _fill(stoichiometric_list, + demartino2014_kernel_engaged_species, num_species) + ref_for_J = [ + [25, 27], [12, 42], [13, 43], [14, 44], [15, 41], [16, 45], + [17, 47], [18, 48], [19, 23, 49], [20, 50], [21, 51], [22, 52], + [1, 23, 30, 35], [2, 23, 29, 35], [3, 23, 35, 46], + [4, 23, 33, 35], [5, 23, 31, 35], [6, 23, 35, 37], + [7, 23, 28, 35], [8, 23, 32, 35], [9, 23, 34, 35], + [10, 23, 35, 40], [11, 23, 35, 36], + [8, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 46], [23, 25], + [0, 23, 24, 35], [23], [0, 28], [18, 23, 27, 35], + [13, 23, 35, 42], [12, 23, 35, 47], [16, 23, 35, 47], + [19, 23, 35, 45], [15, 23, 35, 44], [20, 23, 35, 48], + [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 25, 28, 29, + 30, 31, 32, 33, 34, 36, 37, 40, 46], [22, 23, 35, 49], + [17, 23, 35, 50], [23, 51], [23, 41], [21, 23, 35, 52], + [4, 39], [1, 29], [2, 46], [3, 33], [5, 32], [14, 23, 35, 43], + [6, 30, 31], [7, 34], [8, 36], [9, 37], [10, 38], [11, 40], + [54], [53], [58, 80], [57, 59, 82], [56], [55, 59, 80], + [56, 58, 82], [61], [60], [63], [62], [65], [64], [67, 68, 69], + [66, 68, 69], [66, 67, 69, 70, 71, 94, 95], + [66, 67, 68, 70, 71, 94, 95], [68, 69, 71], [68, 69, 70], [73], + [72], [75], [74], [77], [76], [79], [78], [55, 58, 81], [80], + [56, 59], [84], [83, 85, 87], [84, 86, 87], [85], [84, 85], + [89], [88], [91], [90], [93], [92], [68, 69, 95], [68, 69, 94], + [97], [96], [99], [98], [101], [100], [103], [102], [105], + [104], [107], [106], [109], [108], [111], [110], [113], [112], + [115], [114], [117], [116], [119], [118, 120], [119], [122], + [121], [124], [123], [126], [125], [128], [127], [130], [129] + ] + ref_for_J2 = [ + [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], [-1, -1], + [-1, -1], [-1, -1], [-1, -2, -1], [-1, -1], [-1, -1], + [-1, -1], [-1, 1, -1, -1], [-1, 1, -1, -1], [-1, 1, -1, -1], + [-1, 1, -1, -1], [-1, 1, -1, -1], [-1, 1, -1, -1], + [-1, 1, -1, -1], [-1, 1, -1, -1], [-1, 1, -1, -1], + [-1, 1, -1, -1], [-1, 1, -1, -1], + [-2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -2, 1, -1, -1, -1, -1, + -3, -6, -6, -1, -13, -7, -3, -3, -3, -5, -5], [-2, -1], + [-1, 1, -1, -2], [-1], [-1, -2], [-1, -1, -2, 1], + [-1, -1, 1, -2], [-1, -1, 1, -1], [-1, -3, 1, -2], + [-1, -6, 1, -2], [-1, -6, 1, -2], [-1, -1, 1, -2], + [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -13, -2, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1], [-1, -7, 1, -2], [-1, -3, 1, -2], + [-3, -2], [-3, -2], [-1, -5, 1, -2], [-1, -2], [-1, -2], + [-1, -2], [-1, -2], [-1, -2], [-1, -5, 1, -2], [-1, -1, -2], + [-1, -2], [-1, -2], [-1, -2], [-1, -2], [-1, -2], [-2], [-2], + [1, -1], [-2, -1, -1], [-2], [1, -1, -1], [-1, -1, 1], [-1], + [-1], [-2], [-2], [-2], [-2], [-2, -1, 1], [-2, 1, -1], + [-1, 1, -3, -1, 1, -1, 1], [1, -1, -3, 1, -1, 1, -1], + [-1, 1, -2], [1, -1, -2], [-5], [-5], [-6], [-6], [-2], [-2], + [-1], [-1], [-1, -1, -1], [-1], [-1, 1], [-1], [-1, 1, -1], + [1, -1, -1], [-1], [-1, -1], [-1], [-1], [-1], [-1], [-2], + [-2], [-1, 1, -10], [1, -1, -10], [-1], [-1], [-1], [-1], + [-1], [-1], [-1], [-1], [-1], [-1], [-1], [-1], [-2], [-2], + [-1], [-1], [-1], [-1], [-1], [-1], [-1], [-1], [-1], + [-1, -1], [-1], [-1], [-1], [-1], [-1], [-1], [-1], [-1], + [-1], [-1], [-1] + ] + ref_for_fields = [ + 2, 2, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 51, 3, 3, 1, 3, 3, 3, 2, 5, 8, 8, 3, 15, 9, 5, + 5, 5, 7, 3, 3, 3, 3, 3, 7, 4, 3, 3, 3, 3, 3, 2, 2, 1, 3, + 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 2, 2, 5, 5, 6, 6, + 2, 2, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 10, + 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + ] + # compare J from Python with reference from C++ + for i in range(len(ref_for_J)): + assert J[i] == ref_for_J[i], \ + f"J_{i} ({J[i]}) does not match J_{i}_ref ({ref_for_J[i]})" + assert not any(J[len(ref_for_J):]) + + # compare J2 from Python with reference from C++ + for i in range(len(ref_for_J2)): + assert J2[i] == ref_for_J2[i], \ + f"J_{i} ({J2[i]}) does not match J_{i}_ref ({ref_for_J2[i]})" + assert not any(J2[len(ref_for_J2):]) + + # compare fields from Python with reference from C++ + for i in range(len(ref_for_fields)): + assert fields[i] == ref_for_fields[i], \ + f"J_{i} ({fields[i]}) does not match J_{i}_ref ({ref_for_fields[i]})" + assert not any(fields[len(ref_for_fields):]) + + +def test_compute_moiety_conservation_laws_demartino2014( + data_demartino2014, quiet=False +): + """Invoke test case and benchmarking for De Martino's published results + for E. coli network""" + stoichiometric_list, row_names = data_demartino2014 + num_species = 1668 + num_reactions = 2381 + assert len(stoichiometric_list) == num_species * num_reactions, \ + "Unexpected dimension of stoichiometric matrix" + + start = perf_counter() + cls_state_idxs, cls_coefficients = compute_moiety_conservation_laws( + stoichiometric_list, + num_species=num_species, + num_reactions=num_reactions + ) + runtime = perf_counter() - start + if not quiet: + print(f"Execution time: {runtime} [s]") + + assert len(cls_state_idxs) == len(cls_coefficients) == 38 + return runtime + + +@log_execution_time("Detecting moiety conservation laws", logger) +def test_cl_detect_execution_time(data_demartino2014): + """Test execution time stays within a certain predefined bound. + As the algorithm is non-deterministic, allow for some retries. + Only one has to succeed.""" + max_tries = 5 + # <5s on modern hardware, but leave some slack + max_time_seconds = 30 if "GITHUB_ACTIONS" in os.environ else 10 + + runtime = np.Inf + + for _ in range(max_tries): + runtime = test_compute_moiety_conservation_laws_demartino2014( + data_demartino2014, quiet=True) + if runtime < max_time_seconds: + break + assert runtime < max_time_seconds, "Took too long" + + +def test_compute_moiety_conservation_laws_simple(): + """Test a simple example, ensure the conservation laws are identified + reliably. Requires the Monte Carlo to identify all.""" + stoichiometric_matrix = sp.Matrix([ + [-1.0, 1.0], + [-1.0, 1.0], + [1.0, -1.0], + [1.0, -1.0]] + ) + stoichiometric_list = [ + float(entry) for entry in stoichiometric_matrix.T.flat() + ] + + num_tries = 1000 + found_all_n_times = 0 + for _ in range(num_tries): + cls_state_idxs, cls_coefficients = compute_moiety_conservation_laws( + stoichiometric_list, *stoichiometric_matrix.shape) + + assert cls_state_idxs in ([[0, 3], [1, 2], [1, 3]], + [[0, 3], [1, 2], [0, 2]], + # should happen rarely + [[0, 3], [1, 2]]) + assert cls_coefficients in ([[1.0, 1.0], [1.0, 1.0], [1.0, 1.0]], + [[1.0, 1.0], [1.0, 1.0]]) + + num_cls_found = len(cls_state_idxs) + if num_cls_found == 3: + found_all_n_times += 1 + # sometimes we don't find all conservation laws, but this should be rare + assert found_all_n_times / num_tries >= 0.995 From e1eaba89d4b28739f34ef66eede811a71155cce7 Mon Sep 17 00:00:00 2001 From: Dilan Pathirana <59329744+dilpath@users.noreply.github.com> Date: Sat, 19 Feb 2022 15:11:55 +0100 Subject: [PATCH 04/45] Memoization of simplify in ODE model (#1672) * can decrease import time for models with events * may cause issues for PySB models (see PR) * disabled by default for all format imports (SBML and PySB) Co-authored-by: Daniel Weindl --- python/amici/ode_export.py | 36 +++++++++++++++++++++++++++++++++++- python/amici/pysb_import.py | 23 ++++++++++++++++++++++- python/amici/sbml_import.py | 10 +++++++++- 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/python/amici/ode_export.py b/python/amici/ode_export.py index 3aa93e617e..4978b86a5c 100644 --- a/python/amici/ode_export.py +++ b/python/amici/ode_export.py @@ -959,7 +959,8 @@ class ODEModel: """ def __init__(self, verbose: Optional[Union[bool, int]] = False, - simplify: Optional[Callable] = sp.powsimp): + simplify: Optional[Callable] = sp.powsimp, + cache_simplify: bool = False): """ Create a new ODEModel instance. @@ -969,6 +970,10 @@ def __init__(self, verbose: Optional[Union[bool, int]] = False, :param simplify: see :meth:`ODEModel._simplify` + + :param cache_simplify: + Whether to cache calls to the simplify method. Can e.g. decrease + import times for models with events. """ self._states: List[State] = [] self._observables: List[Observable] = [] @@ -1037,6 +1042,35 @@ def __init__(self, verbose: Optional[Union[bool, int]] = False, self._lock_total_derivative: List[str] = list() self._simplify: Callable = simplify + if cache_simplify and simplify is not None: + def cached_simplify( + expr: sp.Expr, + _simplified: Dict[str, sp.Expr] = {}, + _simplify: Callable = simplify, + ) -> sp.Expr: + """Speed up expression simplification with caching. + + NB: This can decrease model import times for models that have + many repeated expressions during C++ file generation. + For example, this can be useful for models with events. + However, for other models, this may increase model import + times. + + :param expr: + The SymPy expression. + :param _simplified: + The cache. + :param _simplify: + The simplification method. + + :return: + The simplified expression. + """ + expr_str = repr(expr) + if expr_str not in _simplified: + _simplified[expr_str] = _simplify(expr) + return _simplified[expr_str] + self._simplify = cached_simplify self._x0_fixedParameters_idx: Union[None, Sequence[int]] self._w_recursion_depth: int = 0 self._has_quadratic_nllh: bool = True diff --git a/python/amici/pysb_import.py b/python/amici/pysb_import.py index 85e0948fb7..bc7c15da0c 100644 --- a/python/amici/pysb_import.py +++ b/python/amici/pysb_import.py @@ -49,6 +49,9 @@ def pysb2amici( compute_conservation_laws: bool = True, compile: bool = True, simplify: Callable = lambda x: sp.powsimp(x, deep=True), + # Do not enable by default without testing. + # See https://github.com/AMICI-dev/AMICI/pull/1672 + cache_simplify: bool = False, generate_sensitivity_code: bool = True, ): r""" @@ -115,6 +118,11 @@ def pysb2amici( :param simplify: see :attr:`amici.ODEModel._simplify` + :param cache_simplify: + see :func:`amici.ODEModel.__init__` + Note that there are possible issues with PySB models: + https://github.com/AMICI-dev/AMICI/pull/1672 + :param generate_sensitivity_code: if set to ``False``, code for sensitivity computation will not be generated @@ -134,6 +142,7 @@ def pysb2amici( noise_distributions=noise_distributions, compute_conservation_laws=compute_conservation_laws, simplify=simplify, + cache_simplify=cache_simplify, verbose=verbose, ) exporter = ODEExporter( @@ -160,6 +169,9 @@ def ode_model_from_pysb_importer( noise_distributions: Optional[Dict[str, Union[str, Callable]]] = None, compute_conservation_laws: bool = True, simplify: Callable = sp.powsimp, + # Do not enable by default without testing. + # See https://github.com/AMICI-dev/AMICI/pull/1672 + cache_simplify: bool = False, verbose: Union[int, bool] = False, ) -> ODEModel: """ @@ -188,6 +200,11 @@ def ode_model_from_pysb_importer( :param simplify: see :attr:`amici.ODEModel._simplify` + :param cache_simplify: + see :func:`amici.ODEModel.__init__` + Note that there are possible issues with PySB models: + https://github.com/AMICI-dev/AMICI/pull/1672 + :param verbose: verbosity level for logging, True/False default to :attr:`logging.DEBUG`/:attr:`logging.ERROR` @@ -195,7 +212,11 @@ def ode_model_from_pysb_importer( New ODEModel instance according to pysbModel """ - ode = ODEModel(verbose=verbose, simplify=simplify) + ode = ODEModel( + verbose=verbose, + simplify=simplify, + cache_simplify=cache_simplify, + ) if constant_parameters is None: constant_parameters = [] diff --git a/python/amici/sbml_import.py b/python/amici/sbml_import.py index 2d11fb77e6..49090d6475 100644 --- a/python/amici/sbml_import.py +++ b/python/amici/sbml_import.py @@ -218,6 +218,7 @@ def sbml2amici(self, compile: bool = True, compute_conservation_laws: bool = True, simplify: Callable = lambda x: sp.powsimp(x, deep=True), + cache_simplify: bool = False, log_as_log10: bool = True, generate_sensitivity_code: bool = True, **kwargs) -> None: @@ -292,6 +293,9 @@ def sbml2amici(self, :param simplify: see :attr:`ODEModel._simplify` + :param cache_simplify: + see :func:`amici.ODEModel.__init__` + :param log_as_log10: If ``True``, log in the SBML model will be parsed as ``log10`` (default), if ``False``, log will be parsed as natural logarithm @@ -366,7 +370,11 @@ def sbml2amici(self, self._clean_reserved_symbols() self._process_time() - ode_model = ODEModel(verbose=verbose, simplify=simplify) + ode_model = ODEModel( + verbose=verbose, + simplify=simplify, + cache_simplify=cache_simplify, + ) ode_model.import_from_sbml_importer( self, compute_cls=compute_conservation_laws) exporter = ODEExporter( From 952c3f31327ead456ba4e85bc55a7207b543bcd3 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Sat, 19 Feb 2022 19:26:32 +0100 Subject: [PATCH 05/45] Cleanup tests/testSBMLSuite.py (#1676) --- tests/testSBMLSuite.py | 50 ++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/tests/testSBMLSuite.py b/tests/testSBMLSuite.py index 9a4c9f648d..b54bb032ba 100755 --- a/tests/testSBMLSuite.py +++ b/tests/testSBMLSuite.py @@ -14,18 +14,18 @@ """ import copy -import importlib import os import re import shutil import sys -from typing import Tuple, Set +from typing import Set, Tuple -import amici import libsbml as sbml import numpy as np import pandas as pd import pytest + +import amici from amici.constants import SymbolId # directory with sbml semantic test cases @@ -35,10 +35,7 @@ @pytest.fixture(scope="session") def result_path(): - # ensure directory for test results is empty - upload_result_path = os.path.join(os.path.dirname(__file__), - 'amici-semantic-results') - return upload_result_path + return os.path.join(os.path.dirname(__file__), 'amici-semantic-results') @pytest.fixture(scope="function", autouse=True) @@ -55,7 +52,6 @@ def sbml_test_dir(): def test_sbml_testsuite_case(test_number, result_path): - test_id = format_test_id(test_number) model_dir = None try: @@ -63,7 +59,7 @@ def test_sbml_testsuite_case(test_number, result_path): # parse expected results results_file = os.path.join(current_test_path, - test_id + '-results.csv') + f'{test_id}-results.csv') results = pd.read_csv(results_file, delimiter=',') results.rename(columns={c: c.replace(' ', '') for c in results.columns}, @@ -99,8 +95,10 @@ def test_sbml_testsuite_case(test_number, result_path): shutil.rmtree(model_dir, ignore_errors=True) -def verify_results(settings, rdata, expected, wrapper, - model, atol, rtol): +def verify_results( + settings, rdata, expected, wrapper, + model, atol, rtol +): """Verify test results""" amount_species, variables = get_amount_and_variables(settings) @@ -167,7 +165,7 @@ def amounts_to_concentrations( This allows for the reuse of the concentrations_to_amounts method... """ for species in amount_species: - if not species == '': + if species != '': simulated.loc[:, species] = 1 / simulated.loc[:, species] concentrations_to_amounts([species], wrapper, simulated, requested_concentrations) @@ -200,15 +198,18 @@ def concentrations_to_amounts( continue simulated.loc[:, species] *= simulated.loc[ - :, comp if comp in simulated.columns else 'amici_' + comp + :, comp if comp in simulated.columns else f'amici_{comp}' ] -def write_result_file(simulated: pd.DataFrame, - test_id: str, result_path: str): +def write_result_file( + simulated: pd.DataFrame, + test_id: str, + result_path: str +): """ Create test result file for upload to - http://sbml.org/Facilities/Database/Submission/Create + http://raterule.caltech.edu/Facilities/Database Requires csv file with test ID in name and content of [time, Species, ...] """ @@ -263,7 +264,7 @@ def compile_model(path, test_id, model_dir): if not os.path.exists(model_dir): os.makedirs(model_dir) - model_name = 'SBMLTest' + test_id + model_name = f'SBMLTest{test_id}' wrapper.sbml2amici(model_name, output_dir=model_dir, generate_sensitivity_code=False) @@ -279,26 +280,26 @@ def compile_model(path, test_id, model_dir): def find_model_file(current_test_path: str, test_id: str): """Find model file for the given test (guess filename extension)""" - sbml_file = os.path.join(current_test_path, test_id + '-sbml-l3v2.xml') + sbml_file = os.path.join(current_test_path, f'{test_id}-sbml-l3v2.xml') # fallback l3v1 if not os.path.isfile(sbml_file): - sbml_file = os.path.join(current_test_path, test_id + '-sbml-l3v1.xml') + sbml_file = os.path.join(current_test_path, f'{test_id}-sbml-l3v1.xml') # fallback l2v5 if not os.path.isfile(sbml_file): - sbml_file = os.path.join(current_test_path, test_id + '-sbml-l2v5.xml') + sbml_file = os.path.join(current_test_path, f'{test_id}-sbml-l2v5.xml') return sbml_file def read_settings_file(current_test_path: str, test_id: str): """Read settings for the given test""" - settings_file = os.path.join(current_test_path, test_id + '-settings.txt') + settings_file = os.path.join(current_test_path, f'{test_id}-settings.txt') settings = {} with open(settings_file) as f: for line in f: - if not line == '\n': + if line != '\n': (key, val) = line.split(':') settings[key] = val return settings @@ -306,9 +307,7 @@ def read_settings_file(current_test_path: str, test_id: str): def format_test_id(test_id) -> str: """Format numeric to 0-padded string""" - test_str = str(test_id) - test_str = '0'*(5-len(test_str)) + test_str - return test_str + return f"{test_id:0>5}" def get_tags_for_test(test_id) -> Tuple[Set[str], Set[str]]: @@ -317,7 +316,6 @@ def get_tags_for_test(test_id) -> Tuple[Set[str], Set[str]]: Returns: Tuple of set of strings for componentTags and testTags """ - current_test_path = os.path.join(TEST_PATH, test_id) info_file = os.path.join(current_test_path, f'{test_id}-model.m') with open(info_file) as f: From fc4f3c75e31f9cd2e04ee43ece1200a33d98bbd7 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Sat, 19 Feb 2022 19:28:15 +0100 Subject: [PATCH 06/45] Allow using states eliminated by conservation laws to be used in root functions (#1677) Closes #1674 --- include/amici/abstract_model.h | 7 ++++-- include/amici/model_ode.h | 4 +++- matlab/@amifun/getArgs.m | 10 ++++++--- models/model_calvetti/model_calvetti.h | 8 +++---- models/model_dirac/model_dirac.h | 22 +++++++++---------- models/model_dirac/model_dirac_deltasx.cpp | 2 +- models/model_dirac/model_dirac_root.cpp | 2 +- models/model_dirac/model_dirac_stau.cpp | 2 +- models/model_events/model_events.h | 22 +++++++++---------- models/model_events/model_events_deltasx.cpp | 2 +- models/model_events/model_events_root.cpp | 2 +- models/model_events/model_events_stau.cpp | 2 +- .../model_jakstat_adjoint.h | 10 ++++----- .../model_jakstat_adjoint_o2.h | 10 ++++----- .../model_nested_events/model_nested_events.h | 22 +++++++++---------- .../model_nested_events_deltasx.cpp | 2 +- .../model_nested_events_root.cpp | 2 +- .../model_nested_events_stau.cpp | 2 +- models/model_neuron/model_neuron.h | 22 +++++++++---------- models/model_neuron/model_neuron_deltasx.cpp | 2 +- models/model_neuron/model_neuron_root.cpp | 2 +- models/model_neuron/model_neuron_stau.cpp | 2 +- models/model_neuron_o2/model_neuron_o2.h | 22 +++++++++---------- .../model_neuron_o2_deltasx.cpp | 2 +- .../model_neuron_o2/model_neuron_o2_root.cpp | 2 +- .../model_neuron_o2/model_neuron_o2_stau.cpp | 2 +- models/model_robertson/model_robertson.h | 8 +++---- models/model_steadystate/model_steadystate.h | 10 ++++----- python/amici/ode_export.py | 11 ++++++---- python/amici/sbml_import.py | 3 +-- src/abstract_model.cpp | 4 +++- src/model.cpp | 17 +++++++------- src/model_ode.cpp | 5 +++-- 33 files changed, 131 insertions(+), 116 deletions(-) diff --git a/include/amici/abstract_model.h b/include/amici/abstract_model.h index dc11b13e9f..06fbb9a12c 100644 --- a/include/amici/abstract_model.h +++ b/include/amici/abstract_model.h @@ -282,13 +282,14 @@ class AbstractModel { * @param p parameter vector * @param k constant vector * @param h Heaviside vector + * @param tcl total abundances for conservation laws * @param sx current state sensitivity * @param ip sensitivity index * @param ie event index */ virtual void fstau(realtype *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, - const realtype *sx, int ip, int ie); + const realtype *tcl, const realtype *sx, int ip, int ie); /** * @brief Model-specific implementation of fy @@ -487,13 +488,15 @@ class AbstractModel { * @param xdot_old previous model right hand side * @param sx state sensitivity * @param stau event-time sensitivity + * @param tcl total abundances for conservation laws */ virtual void fdeltasx(realtype *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, int ip, int ie, const realtype *xdot, const realtype *xdot_old, - const realtype *sx, const realtype *stau); + const realtype *sx, const realtype *stau, + const realtype *tcl); /** * @brief Model-specific implementation of fdeltaxB diff --git a/include/amici/model_ode.h b/include/amici/model_ode.h index 4a11ab4101..a7c701a90c 100644 --- a/include/amici/model_ode.h +++ b/include/amici/model_ode.h @@ -317,9 +317,11 @@ class Model_ODE : public Model { * @param p parameter vector * @param k constants vector * @param h Heaviside vector + * @param tcl total abundances for conservation laws **/ virtual void froot(realtype *root, realtype t, const realtype *x, - const realtype *p, const realtype *k, const realtype *h); + const realtype *p, const realtype *k, const realtype *h, + const realtype *tcl); /** * @brief Model specific implementation for fxdot diff --git a/matlab/@amifun/getArgs.m b/matlab/@amifun/getArgs.m index 65499d43ae..a8e3b69c9c 100644 --- a/matlab/@amifun/getArgs.m +++ b/matlab/@amifun/getArgs.m @@ -42,7 +42,11 @@ case 'sx0' this.argstr = '(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip)'; case 'root' - this.argstr = ['(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h' dx ')']; + if(strcmp(model.wtype,'iw')) + this.argstr = ['(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h' dx ')']; + else + this.argstr = ['(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl' dx ')']; + end case 'y' this.argstr = '(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w)'; case 'z' @@ -72,7 +76,7 @@ case 'deltaqB' this.argstr = '(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB)'; case 'deltasx' - this.argstr = '(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau)'; + this.argstr = '(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl)'; case 'dxdotdp' this.argstr = ['(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip' dx ', const realtype *w, const realtype *dwdp)']; case 'sigma_y' @@ -84,7 +88,7 @@ case 'dsigma_zdp' this.argstr = '(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip)'; case 'stau' - this.argstr = '(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie)'; + this.argstr = '(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie)'; case 'Jy' this.argstr = '(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my)'; case 'dJydy' diff --git a/models/model_calvetti/model_calvetti.h b/models/model_calvetti/model_calvetti.h index 27fad45d3e..52675c57ac 100644 --- a/models/model_calvetti/model_calvetti.h +++ b/models/model_calvetti/model_calvetti.h @@ -1,6 +1,6 @@ #ifndef _amici_model_calvetti_h #define _amici_model_calvetti_h -/* Generated by amiwrap (R2017b) dc99fa1bcb04914008ba8ed39157513d443c3f43 */ +/* Generated by amiwrap (R2017b) 9212bbdaf5712727ff284cc475f16d2a983f9bf2 */ #include #include #include "amici/defines.h" @@ -67,7 +67,7 @@ class Model_model_calvetti : public amici::Model_DAE { amici::Model* clone() const override { return new Model_model_calvetti(*this); }; - std::string getAmiciCommit() const override { return "dc99fa1bcb04914008ba8ed39157513d443c3f43"; }; + std::string getAmiciCommit() const override { return "9212bbdaf5712727ff284cc475f16d2a983f9bf2"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype cj, const realtype *dx, const realtype *w, const realtype *dwdx) override { JSparse_model_calvetti(JSparse, t, x, p, k, h, cj, dx, w, dwdx); @@ -110,7 +110,7 @@ class Model_model_calvetti : public amici::Model_DAE { void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) override { } void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { @@ -171,7 +171,7 @@ class Model_model_calvetti : public amici::Model_DAE { void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) override { } void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { diff --git a/models/model_dirac/model_dirac.h b/models/model_dirac/model_dirac.h index 481522b282..03639ddef6 100644 --- a/models/model_dirac/model_dirac.h +++ b/models/model_dirac/model_dirac.h @@ -1,6 +1,6 @@ #ifndef _amici_model_dirac_h #define _amici_model_dirac_h -/* Generated by amiwrap (R2017b) dc99fa1bcb04914008ba8ed39157513d443c3f43 */ +/* Generated by amiwrap (R2017b) 9212bbdaf5712727ff284cc475f16d2a983f9bf2 */ #include #include #include "amici/defines.h" @@ -18,13 +18,13 @@ extern void JSparse_model_dirac(SUNMatrixContent_Sparse JSparse, const realtype extern void Jy_model_dirac(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); extern void dJydsigma_model_dirac(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); extern void dJydy_model_dirac(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); -extern void deltasx_model_dirac(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau); +extern void deltasx_model_dirac(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl); extern void deltax_model_dirac(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old); extern void dxdotdp_model_dirac(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydx_model_dirac(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); -extern void root_model_dirac(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); +extern void root_model_dirac(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); extern void sigmay_model_dirac(double *sigmay, const realtype t, const realtype *p, const realtype *k); -extern void stau_model_dirac(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie); +extern void stau_model_dirac(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie); extern void xdot_model_dirac(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w); extern void y_model_dirac(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w); @@ -67,7 +67,7 @@ class Model_model_dirac : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_dirac(*this); }; - std::string getAmiciCommit() const override { return "dc99fa1bcb04914008ba8ed39157513d443c3f43"; }; + std::string getAmiciCommit() const override { return "9212bbdaf5712727ff284cc475f16d2a983f9bf2"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_dirac(JSparse, t, x, p, k, h, w, dwdx); @@ -106,8 +106,8 @@ class Model_model_dirac : public amici::Model_ODE { void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { - deltasx_model_dirac(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau); + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) override { + deltasx_model_dirac(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau, tcl); } void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { @@ -152,8 +152,8 @@ class Model_model_dirac : public amici::Model_ODE { void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { - root_model_dirac(root, t, x, p, k, h); + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { + root_model_dirac(root, t, x, p, k, h, tcl); } void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { @@ -169,8 +169,8 @@ class Model_model_dirac : public amici::Model_ODE { void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { - stau_model_dirac(stau, t, x, p, k, h, sx, ip, ie); + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) override { + stau_model_dirac(stau, t, x, p, k, h, tcl, sx, ip, ie); } void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { diff --git a/models/model_dirac/model_dirac_deltasx.cpp b/models/model_dirac/model_dirac_deltasx.cpp index 12b79f9371..ebb0be64cb 100644 --- a/models/model_dirac/model_dirac_deltasx.cpp +++ b/models/model_dirac/model_dirac_deltasx.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_dirac{ -void deltasx_model_dirac(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) { +void deltasx_model_dirac(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) { switch (ip) { case 0: { switch(ie) { diff --git a/models/model_dirac/model_dirac_root.cpp b/models/model_dirac/model_dirac_root.cpp index a54473970a..ce1c5f4364 100644 --- a/models/model_dirac/model_dirac_root.cpp +++ b/models/model_dirac/model_dirac_root.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_dirac{ -void root_model_dirac(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) { +void root_model_dirac(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) { root[0] = -t+p[1]; root[1] = t-p[1]; } diff --git a/models/model_dirac/model_dirac_stau.cpp b/models/model_dirac/model_dirac_stau.cpp index 24fb6db818..67c725fcea 100644 --- a/models/model_dirac/model_dirac_stau.cpp +++ b/models/model_dirac/model_dirac_stau.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_dirac{ -void stau_model_dirac(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) { +void stau_model_dirac(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) { switch (ip) { case 1: { switch(ie) { diff --git a/models/model_events/model_events.h b/models/model_events/model_events.h index 56e90327e4..2dc99f9399 100644 --- a/models/model_events/model_events.h +++ b/models/model_events/model_events.h @@ -1,6 +1,6 @@ #ifndef _amici_model_events_h #define _amici_model_events_h -/* Generated by amiwrap (R2017b) dc99fa1bcb04914008ba8ed39157513d443c3f43 */ +/* Generated by amiwrap (R2017b) 9212bbdaf5712727ff284cc475f16d2a983f9bf2 */ #include #include #include "amici/defines.h" @@ -24,18 +24,18 @@ extern void dJydsigma_model_events(double *dJydsigma, const int iy, const realty extern void dJydy_model_events(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); extern void dJzdsigma_model_events(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz); extern void dJzdz_model_events(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz); -extern void deltasx_model_events(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau); +extern void deltasx_model_events(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl); extern void drzdx_model_events(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); extern void dxdotdp_model_events(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydp_model_events(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydx_model_events(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); extern void dzdx_model_events(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); -extern void root_model_events(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); +extern void root_model_events(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); extern void rz_model_events(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); extern void sigmay_model_events(double *sigmay, const realtype t, const realtype *p, const realtype *k); extern void sigmaz_model_events(double *sigmaz, const realtype t, const realtype *p, const realtype *k); extern void srz_model_events(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip); -extern void stau_model_events(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie); +extern void stau_model_events(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie); extern void sz_model_events(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip); extern void x0_model_events(realtype *x0, const realtype t, const realtype *p, const realtype *k); extern void xdot_model_events(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w); @@ -81,7 +81,7 @@ class Model_model_events : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_events(*this); }; - std::string getAmiciCommit() const override { return "dc99fa1bcb04914008ba8ed39157513d443c3f43"; }; + std::string getAmiciCommit() const override { return "9212bbdaf5712727ff284cc475f16d2a983f9bf2"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_events(JSparse, t, x, p, k, h, w, dwdx); @@ -126,8 +126,8 @@ class Model_model_events : public amici::Model_ODE { void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { - deltasx_model_events(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau); + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) override { + deltasx_model_events(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau, tcl); } void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { @@ -174,8 +174,8 @@ class Model_model_events : public amici::Model_ODE { dzdx_model_events(dzdx, ie, t, x, p, k, h); } - void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { - root_model_events(root, t, x, p, k, h); + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { + root_model_events(root, t, x, p, k, h, tcl); } void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { @@ -194,8 +194,8 @@ class Model_model_events : public amici::Model_ODE { srz_model_events(srz, ie, t, x, p, k, h, sx, ip); } - void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { - stau_model_events(stau, t, x, p, k, h, sx, ip, ie); + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) override { + stau_model_events(stau, t, x, p, k, h, tcl, sx, ip, ie); } void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { diff --git a/models/model_events/model_events_deltasx.cpp b/models/model_events/model_events_deltasx.cpp index 62516b1ab3..9dacb2ee54 100644 --- a/models/model_events/model_events_deltasx.cpp +++ b/models/model_events/model_events_deltasx.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_events{ -void deltasx_model_events(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) { +void deltasx_model_events(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) { switch (ip) { case 0: { switch(ie) { diff --git a/models/model_events/model_events_root.cpp b/models/model_events/model_events_root.cpp index 4da74dc79a..9207a8a25f 100644 --- a/models/model_events/model_events_root.cpp +++ b/models/model_events/model_events_root.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_events{ -void root_model_events(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) { +void root_model_events(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) { root[0] = x[1]-x[2]; root[1] = x[0]-x[2]; root[2] = -t+4.0; diff --git a/models/model_events/model_events_stau.cpp b/models/model_events/model_events_stau.cpp index 9649efab4c..6a192189e1 100644 --- a/models/model_events/model_events_stau.cpp +++ b/models/model_events/model_events_stau.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_events{ -void stau_model_events(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) { +void stau_model_events(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) { switch (ip) { case 0: { switch(ie) { diff --git a/models/model_jakstat_adjoint/model_jakstat_adjoint.h b/models/model_jakstat_adjoint/model_jakstat_adjoint.h index 418acbf2f5..69bd1eadc2 100644 --- a/models/model_jakstat_adjoint/model_jakstat_adjoint.h +++ b/models/model_jakstat_adjoint/model_jakstat_adjoint.h @@ -1,6 +1,6 @@ #ifndef _amici_model_jakstat_adjoint_h #define _amici_model_jakstat_adjoint_h -/* Generated by amiwrap (R2017b) dc99fa1bcb04914008ba8ed39157513d443c3f43 */ +/* Generated by amiwrap (R2017b) 9212bbdaf5712727ff284cc475f16d2a983f9bf2 */ #include #include #include "amici/defines.h" @@ -70,7 +70,7 @@ class Model_model_jakstat_adjoint : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_jakstat_adjoint(*this); }; - std::string getAmiciCommit() const override { return "dc99fa1bcb04914008ba8ed39157513d443c3f43"; }; + std::string getAmiciCommit() const override { return "9212bbdaf5712727ff284cc475f16d2a983f9bf2"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_jakstat_adjoint(JSparse, t, x, p, k, h, w, dwdx); @@ -109,7 +109,7 @@ class Model_model_jakstat_adjoint : public amici::Model_ODE { void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) override { } void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { @@ -157,7 +157,7 @@ class Model_model_jakstat_adjoint : public amici::Model_ODE { void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { } void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { @@ -173,7 +173,7 @@ class Model_model_jakstat_adjoint : public amici::Model_ODE { void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) override { } void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { diff --git a/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h b/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h index 33a5beb306..142c8ae8c6 100644 --- a/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h +++ b/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h @@ -1,6 +1,6 @@ #ifndef _amici_model_jakstat_adjoint_o2_h #define _amici_model_jakstat_adjoint_o2_h -/* Generated by amiwrap (R2017b) dc99fa1bcb04914008ba8ed39157513d443c3f43 */ +/* Generated by amiwrap (R2017b) 9212bbdaf5712727ff284cc475f16d2a983f9bf2 */ #include #include #include "amici/defines.h" @@ -70,7 +70,7 @@ class Model_model_jakstat_adjoint_o2 : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_jakstat_adjoint_o2(*this); }; - std::string getAmiciCommit() const override { return "dc99fa1bcb04914008ba8ed39157513d443c3f43"; }; + std::string getAmiciCommit() const override { return "9212bbdaf5712727ff284cc475f16d2a983f9bf2"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_jakstat_adjoint_o2(JSparse, t, x, p, k, h, w, dwdx); @@ -109,7 +109,7 @@ class Model_model_jakstat_adjoint_o2 : public amici::Model_ODE { void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) override { } void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { @@ -157,7 +157,7 @@ class Model_model_jakstat_adjoint_o2 : public amici::Model_ODE { void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { } void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { @@ -173,7 +173,7 @@ class Model_model_jakstat_adjoint_o2 : public amici::Model_ODE { void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) override { } void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { diff --git a/models/model_nested_events/model_nested_events.h b/models/model_nested_events/model_nested_events.h index 8f85951440..fcf703b914 100644 --- a/models/model_nested_events/model_nested_events.h +++ b/models/model_nested_events/model_nested_events.h @@ -1,6 +1,6 @@ #ifndef _amici_model_nested_events_h #define _amici_model_nested_events_h -/* Generated by amiwrap (R2017b) dc99fa1bcb04914008ba8ed39157513d443c3f43 */ +/* Generated by amiwrap (R2017b) 9212bbdaf5712727ff284cc475f16d2a983f9bf2 */ #include #include #include "amici/defines.h" @@ -19,13 +19,13 @@ extern void Jy_model_nested_events(double *nllh, const int iy, const realtype *p extern void dJydsigma_model_nested_events(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); extern void dJydy_model_nested_events(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); extern void deltaqB_model_nested_events(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB); -extern void deltasx_model_nested_events(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau); +extern void deltasx_model_nested_events(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl); extern void deltax_model_nested_events(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old); extern void dxdotdp_model_nested_events(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydx_model_nested_events(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); -extern void root_model_nested_events(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); +extern void root_model_nested_events(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); extern void sigmay_model_nested_events(double *sigmay, const realtype t, const realtype *p, const realtype *k); -extern void stau_model_nested_events(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie); +extern void stau_model_nested_events(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie); extern void sx0_model_nested_events(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip); extern void x0_model_nested_events(realtype *x0, const realtype t, const realtype *p, const realtype *k); extern void xdot_model_nested_events(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w); @@ -70,7 +70,7 @@ class Model_model_nested_events : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_nested_events(*this); }; - std::string getAmiciCommit() const override { return "dc99fa1bcb04914008ba8ed39157513d443c3f43"; }; + std::string getAmiciCommit() const override { return "9212bbdaf5712727ff284cc475f16d2a983f9bf2"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_nested_events(JSparse, t, x, p, k, h, w, dwdx); @@ -110,8 +110,8 @@ class Model_model_nested_events : public amici::Model_ODE { deltaqB_model_nested_events(deltaqB, t, x, p, k, h, ip, ie, xdot, xdot_old, xB); } - void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { - deltasx_model_nested_events(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau); + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) override { + deltasx_model_nested_events(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau, tcl); } void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { @@ -156,8 +156,8 @@ class Model_model_nested_events : public amici::Model_ODE { void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { - root_model_nested_events(root, t, x, p, k, h); + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { + root_model_nested_events(root, t, x, p, k, h, tcl); } void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { @@ -173,8 +173,8 @@ class Model_model_nested_events : public amici::Model_ODE { void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { - stau_model_nested_events(stau, t, x, p, k, h, sx, ip, ie); + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) override { + stau_model_nested_events(stau, t, x, p, k, h, tcl, sx, ip, ie); } void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { diff --git a/models/model_nested_events/model_nested_events_deltasx.cpp b/models/model_nested_events/model_nested_events_deltasx.cpp index d464477b44..15b55bb525 100644 --- a/models/model_nested_events/model_nested_events_deltasx.cpp +++ b/models/model_nested_events/model_nested_events_deltasx.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_nested_events{ -void deltasx_model_nested_events(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) { +void deltasx_model_nested_events(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) { switch (ip) { case 0: { switch(ie) { diff --git a/models/model_nested_events/model_nested_events_root.cpp b/models/model_nested_events/model_nested_events_root.cpp index c18683f8ec..0cf33d2d57 100644 --- a/models/model_nested_events/model_nested_events_root.cpp +++ b/models/model_nested_events/model_nested_events_root.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_nested_events{ -void root_model_nested_events(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) { +void root_model_nested_events(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) { root[0] = -x[0]+1.0; root[1] = x[0]-1.0; root[2] = t-p[2]; diff --git a/models/model_nested_events/model_nested_events_stau.cpp b/models/model_nested_events/model_nested_events_stau.cpp index c97800dea3..bfaad2f012 100644 --- a/models/model_nested_events/model_nested_events_stau.cpp +++ b/models/model_nested_events/model_nested_events_stau.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_nested_events{ -void stau_model_nested_events(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) { +void stau_model_nested_events(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) { switch (ip) { case 0: { switch(ie) { diff --git a/models/model_neuron/model_neuron.h b/models/model_neuron/model_neuron.h index bd12dd9b5d..aacdef0da6 100644 --- a/models/model_neuron/model_neuron.h +++ b/models/model_neuron/model_neuron.h @@ -1,6 +1,6 @@ #ifndef _amici_model_neuron_h #define _amici_model_neuron_h -/* Generated by amiwrap (R2017b) dc99fa1bcb04914008ba8ed39157513d443c3f43 */ +/* Generated by amiwrap (R2017b) 9212bbdaf5712727ff284cc475f16d2a983f9bf2 */ #include #include #include "amici/defines.h" @@ -25,19 +25,19 @@ extern void dJydy_model_neuron(double *dJydy, const int iy, const realtype *p, c extern void dJzdsigma_model_neuron(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz); extern void dJzdz_model_neuron(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz); extern void deltaqB_model_neuron(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB); -extern void deltasx_model_neuron(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau); +extern void deltasx_model_neuron(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl); extern void deltax_model_neuron(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old); extern void deltaxB_model_neuron(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB); extern void drzdx_model_neuron(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); extern void dxdotdp_model_neuron(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydx_model_neuron(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); extern void dzdx_model_neuron(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); -extern void root_model_neuron(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); +extern void root_model_neuron(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); extern void rz_model_neuron(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); extern void sigmay_model_neuron(double *sigmay, const realtype t, const realtype *p, const realtype *k); extern void sigmaz_model_neuron(double *sigmaz, const realtype t, const realtype *p, const realtype *k); extern void srz_model_neuron(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip); -extern void stau_model_neuron(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie); +extern void stau_model_neuron(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie); extern void sx0_model_neuron(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip); extern void sz_model_neuron(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip); extern void x0_model_neuron(realtype *x0, const realtype t, const realtype *p, const realtype *k); @@ -84,7 +84,7 @@ class Model_model_neuron : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_neuron(*this); }; - std::string getAmiciCommit() const override { return "dc99fa1bcb04914008ba8ed39157513d443c3f43"; }; + std::string getAmiciCommit() const override { return "9212bbdaf5712727ff284cc475f16d2a983f9bf2"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_neuron(JSparse, t, x, p, k, h, w, dwdx); @@ -130,8 +130,8 @@ class Model_model_neuron : public amici::Model_ODE { deltaqB_model_neuron(deltaqB, t, x, p, k, h, ip, ie, xdot, xdot_old, xB); } - void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { - deltasx_model_neuron(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau); + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) override { + deltasx_model_neuron(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau, tcl); } void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { @@ -179,8 +179,8 @@ class Model_model_neuron : public amici::Model_ODE { dzdx_model_neuron(dzdx, ie, t, x, p, k, h); } - void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { - root_model_neuron(root, t, x, p, k, h); + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { + root_model_neuron(root, t, x, p, k, h, tcl); } void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { @@ -199,8 +199,8 @@ class Model_model_neuron : public amici::Model_ODE { srz_model_neuron(srz, ie, t, x, p, k, h, sx, ip); } - void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { - stau_model_neuron(stau, t, x, p, k, h, sx, ip, ie); + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) override { + stau_model_neuron(stau, t, x, p, k, h, tcl, sx, ip, ie); } void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { diff --git a/models/model_neuron/model_neuron_deltasx.cpp b/models/model_neuron/model_neuron_deltasx.cpp index 35dc79a782..29bd503840 100644 --- a/models/model_neuron/model_neuron_deltasx.cpp +++ b/models/model_neuron/model_neuron_deltasx.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_neuron{ -void deltasx_model_neuron(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) { +void deltasx_model_neuron(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) { switch (ip) { case 0: { switch(ie) { diff --git a/models/model_neuron/model_neuron_root.cpp b/models/model_neuron/model_neuron_root.cpp index 516bc91304..6a68f67719 100644 --- a/models/model_neuron/model_neuron_root.cpp +++ b/models/model_neuron/model_neuron_root.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_neuron{ -void root_model_neuron(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) { +void root_model_neuron(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) { root[0] = x[0]-3.0E1; } diff --git a/models/model_neuron/model_neuron_stau.cpp b/models/model_neuron/model_neuron_stau.cpp index 66b3518578..d77cfb5bdc 100644 --- a/models/model_neuron/model_neuron_stau.cpp +++ b/models/model_neuron/model_neuron_stau.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_neuron{ -void stau_model_neuron(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) { +void stau_model_neuron(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) { switch (ip) { case 0: { switch(ie) { diff --git a/models/model_neuron_o2/model_neuron_o2.h b/models/model_neuron_o2/model_neuron_o2.h index d1d2fc1734..8fb9ce900e 100644 --- a/models/model_neuron_o2/model_neuron_o2.h +++ b/models/model_neuron_o2/model_neuron_o2.h @@ -1,6 +1,6 @@ #ifndef _amici_model_neuron_o2_h #define _amici_model_neuron_o2_h -/* Generated by amiwrap (R2017b) dc99fa1bcb04914008ba8ed39157513d443c3f43 */ +/* Generated by amiwrap (R2017b) 9212bbdaf5712727ff284cc475f16d2a983f9bf2 */ #include #include #include "amici/defines.h" @@ -25,7 +25,7 @@ extern void dJydy_model_neuron_o2(double *dJydy, const int iy, const realtype *p extern void dJzdsigma_model_neuron_o2(double *dJzdsigma, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz); extern void dJzdz_model_neuron_o2(double *dJzdz, const int iz, const realtype *p, const realtype *k, const double *z, const double *sigmaz, const double *mz); extern void deltaqB_model_neuron_o2(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB); -extern void deltasx_model_neuron_o2(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau); +extern void deltasx_model_neuron_o2(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl); extern void deltax_model_neuron_o2(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old); extern void deltaxB_model_neuron_o2(double *deltaxB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB); extern void drzdx_model_neuron_o2(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); @@ -33,12 +33,12 @@ extern void dwdx_model_neuron_o2(realtype *dwdx, const realtype t, const realtyp extern void dxdotdp_model_neuron_o2(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydx_model_neuron_o2(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); extern void dzdx_model_neuron_o2(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); -extern void root_model_neuron_o2(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); +extern void root_model_neuron_o2(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); extern void rz_model_neuron_o2(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); extern void sigmay_model_neuron_o2(double *sigmay, const realtype t, const realtype *p, const realtype *k); extern void sigmaz_model_neuron_o2(double *sigmaz, const realtype t, const realtype *p, const realtype *k); extern void srz_model_neuron_o2(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip); -extern void stau_model_neuron_o2(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie); +extern void stau_model_neuron_o2(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie); extern void sx0_model_neuron_o2(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip); extern void sz_model_neuron_o2(double *sz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip); extern void w_model_neuron_o2(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); @@ -86,7 +86,7 @@ class Model_model_neuron_o2 : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_neuron_o2(*this); }; - std::string getAmiciCommit() const override { return "dc99fa1bcb04914008ba8ed39157513d443c3f43"; }; + std::string getAmiciCommit() const override { return "9212bbdaf5712727ff284cc475f16d2a983f9bf2"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_neuron_o2(JSparse, t, x, p, k, h, w, dwdx); @@ -132,8 +132,8 @@ class Model_model_neuron_o2 : public amici::Model_ODE { deltaqB_model_neuron_o2(deltaqB, t, x, p, k, h, ip, ie, xdot, xdot_old, xB); } - void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { - deltasx_model_neuron_o2(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau); + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) override { + deltasx_model_neuron_o2(deltasx, t, x, p, k, h, w, ip, ie, xdot, xdot_old, sx, stau, tcl); } void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { @@ -182,8 +182,8 @@ class Model_model_neuron_o2 : public amici::Model_ODE { dzdx_model_neuron_o2(dzdx, ie, t, x, p, k, h); } - void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { - root_model_neuron_o2(root, t, x, p, k, h); + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { + root_model_neuron_o2(root, t, x, p, k, h, tcl); } void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { @@ -202,8 +202,8 @@ class Model_model_neuron_o2 : public amici::Model_ODE { srz_model_neuron_o2(srz, ie, t, x, p, k, h, sx, ip); } - void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { - stau_model_neuron_o2(stau, t, x, p, k, h, sx, ip, ie); + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) override { + stau_model_neuron_o2(stau, t, x, p, k, h, tcl, sx, ip, ie); } void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { diff --git a/models/model_neuron_o2/model_neuron_o2_deltasx.cpp b/models/model_neuron_o2/model_neuron_o2_deltasx.cpp index 621cb92ed4..10c0d6a052 100644 --- a/models/model_neuron_o2/model_neuron_o2_deltasx.cpp +++ b/models/model_neuron_o2/model_neuron_o2_deltasx.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_neuron_o2{ -void deltasx_model_neuron_o2(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) { +void deltasx_model_neuron_o2(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) { switch (ip) { case 0: { switch(ie) { diff --git a/models/model_neuron_o2/model_neuron_o2_root.cpp b/models/model_neuron_o2/model_neuron_o2_root.cpp index 852a2806b6..7fba331de0 100644 --- a/models/model_neuron_o2/model_neuron_o2_root.cpp +++ b/models/model_neuron_o2/model_neuron_o2_root.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_neuron_o2{ -void root_model_neuron_o2(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) { +void root_model_neuron_o2(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) { root[0] = x[0]-3.0E1; } diff --git a/models/model_neuron_o2/model_neuron_o2_stau.cpp b/models/model_neuron_o2/model_neuron_o2_stau.cpp index 70a8cf3a58..c639781b90 100644 --- a/models/model_neuron_o2/model_neuron_o2_stau.cpp +++ b/models/model_neuron_o2/model_neuron_o2_stau.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_neuron_o2{ -void stau_model_neuron_o2(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) { +void stau_model_neuron_o2(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) { switch (ip) { case 0: { switch(ie) { diff --git a/models/model_robertson/model_robertson.h b/models/model_robertson/model_robertson.h index a83d68d8d7..041e793d0a 100644 --- a/models/model_robertson/model_robertson.h +++ b/models/model_robertson/model_robertson.h @@ -1,6 +1,6 @@ #ifndef _amici_model_robertson_h #define _amici_model_robertson_h -/* Generated by amiwrap (R2017b) dc99fa1bcb04914008ba8ed39157513d443c3f43 */ +/* Generated by amiwrap (R2017b) 9212bbdaf5712727ff284cc475f16d2a983f9bf2 */ #include #include #include "amici/defines.h" @@ -68,7 +68,7 @@ class Model_model_robertson : public amici::Model_DAE { amici::Model* clone() const override { return new Model_model_robertson(*this); }; - std::string getAmiciCommit() const override { return "dc99fa1bcb04914008ba8ed39157513d443c3f43"; }; + std::string getAmiciCommit() const override { return "9212bbdaf5712727ff284cc475f16d2a983f9bf2"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype cj, const realtype *dx, const realtype *w, const realtype *dwdx) override { JSparse_model_robertson(JSparse, t, x, p, k, h, cj, dx, w, dwdx); @@ -111,7 +111,7 @@ class Model_model_robertson : public amici::Model_DAE { void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) override { } void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { @@ -173,7 +173,7 @@ class Model_model_robertson : public amici::Model_DAE { void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) override { } void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { diff --git a/models/model_steadystate/model_steadystate.h b/models/model_steadystate/model_steadystate.h index 0da7d77631..f955d97c84 100644 --- a/models/model_steadystate/model_steadystate.h +++ b/models/model_steadystate/model_steadystate.h @@ -1,6 +1,6 @@ #ifndef _amici_model_steadystate_h #define _amici_model_steadystate_h -/* Generated by amiwrap (R2017b) dc99fa1bcb04914008ba8ed39157513d443c3f43 */ +/* Generated by amiwrap (R2017b) 9212bbdaf5712727ff284cc475f16d2a983f9bf2 */ #include #include #include "amici/defines.h" @@ -67,7 +67,7 @@ class Model_model_steadystate : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_steadystate(*this); }; - std::string getAmiciCommit() const override { return "dc99fa1bcb04914008ba8ed39157513d443c3f43"; }; + std::string getAmiciCommit() const override { return "9212bbdaf5712727ff284cc475f16d2a983f9bf2"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_steadystate(JSparse, t, x, p, k, h, w, dwdx); @@ -106,7 +106,7 @@ class Model_model_steadystate : public amici::Model_ODE { void fdeltaqB(double *deltaqB, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *xB) override { } - void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau) override { + void fdeltasx(double *deltasx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const int ip, const int ie, const realtype *xdot, const realtype *xdot_old, const realtype *sx, const realtype *stau, const realtype *tcl) override { } void fdeltax(double *deltax, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ie, const realtype *xdot, const realtype *xdot_old) override { @@ -152,7 +152,7 @@ class Model_model_steadystate : public amici::Model_ODE { void fdzdx(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { + void froot(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl) override { } void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { @@ -168,7 +168,7 @@ class Model_model_steadystate : public amici::Model_ODE { void fsrz(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip) override { } - void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip, const int ie) override { + void fstau(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie) override { } void fsx0(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip) override { diff --git a/python/amici/ode_export.py b/python/amici/ode_export.py index 4978b86a5c..786c7110cd 100644 --- a/python/amici/ode_export.py +++ b/python/amici/ode_export.py @@ -111,7 +111,8 @@ class _FunctionInfo: 'root': _FunctionInfo( 'realtype *root, const realtype t, const realtype *x, ' - 'const realtype *p, const realtype *k, const realtype *h' + 'const realtype *p, const realtype *k, const realtype *h, ' + 'const realtype *tcl' ), 'dwdp': _FunctionInfo( @@ -181,7 +182,8 @@ class _FunctionInfo: _FunctionInfo( 'realtype *stau, const realtype t, const realtype *x, ' 'const realtype *p, const realtype *k, const realtype *h, ' - 'const realtype *sx, const int ip, const int ie', + 'const realtype *sx, const int ip, const int ie, ' + 'const realtype *tcl', generate_body=False ), 'drootdt': @@ -196,7 +198,8 @@ class _FunctionInfo: _FunctionInfo( 'realtype *stau, const realtype t, const realtype *x, ' 'const realtype *p, const realtype *k, const realtype *h, ' - 'const realtype *sx, const int ip, const int ie' + 'const realtype *tcl, const realtype *sx, const int ip, ' + 'const int ie' ), 'deltax': _FunctionInfo( @@ -216,7 +219,7 @@ class _FunctionInfo: 'const realtype *p, const realtype *k, const realtype *h, ' 'const realtype *w, const int ip, const int ie, ' 'const realtype *xdot, const realtype *xdot_old, ' - 'const realtype *sx, const realtype *stau' + 'const realtype *sx, const realtype *stau, const realtype *tcl' ), 'w': _FunctionInfo( diff --git a/python/amici/sbml_import.py b/python/amici/sbml_import.py index 49090d6475..c7a337845b 100644 --- a/python/amici/sbml_import.py +++ b/python/amici/sbml_import.py @@ -355,8 +355,7 @@ def sbml2amici(self, sbml.L3P_PARSE_LOG_AS_LN ) self._process_sbml(constant_parameters) - if self.symbols.get(SymbolId.EVENT, False) \ - or any(e.has(sp.Heaviside) for e in self.flux_vector): + if self.symbols.get(SymbolId.EVENT, False): if compute_conservation_laws: logger.warning( 'Conservation laws are currently not supported for models ' diff --git a/src/abstract_model.cpp b/src/abstract_model.cpp index f866eb7dbe..ede420f131 100644 --- a/src/abstract_model.cpp +++ b/src/abstract_model.cpp @@ -79,6 +79,7 @@ AbstractModel::fstau(realtype* /*stau*/, const realtype* /*p*/, const realtype* /*k*/, const realtype* /*h*/, + const realtype* /*tcl*/, const realtype* /*sx*/, const int /*ip*/, const int /*ie*/) @@ -280,7 +281,8 @@ AbstractModel::fdeltasx(realtype* /*deltasx*/, const realtype* /*xdot*/, const realtype* /*xdot_old*/, const realtype* /*sx*/, - const realtype* /*stau*/) + const realtype* /*stau*/, + const realtype* /*tcl*/) { throw AmiException("Requested functionality is not supported as %s is " "not implemented for this model!", diff --git a/src/model.cpp b/src/model.cpp index 2e1a557992..b3912ae267 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -1076,7 +1076,7 @@ void Model::getEventTimeSensitivity(std::vector &stau, for (int ip = 0; ip < nplist(); ip++) { fstau(&stau.at(ip), t, computeX_pos(x), state_.unscaledParameters.data(), state_.fixedParameters.data(), - state_.h.data(), sx.data(ip), + state_.h.data(), state_.total_cl.data(), sx.data(ip), plist(ip), ie); } } @@ -1084,9 +1084,9 @@ void Model::getEventTimeSensitivity(std::vector &stau, void Model::addStateEventUpdate(AmiVector &x, const int ie, const realtype t, const AmiVector &xdot, const AmiVector &xdot_old) { - + derived_state_.deltax_.assign(nx_solver, 0.0); - + std::copy_n(computeX_pos(x), nx_solver, x.data()); // compute update @@ -1120,7 +1120,8 @@ void Model::addStateSensitivityEventUpdate(AmiVectorArray &sx, const int ie, state_.unscaledParameters.data(), state_.fixedParameters.data(), state_.h.data(), derived_state_.w_.data(), plist(ip), ie, - xdot.data(), xdot_old.data(), sx.data(ip), &stau.at(ip)); + xdot.data(), xdot_old.data(), sx.data(ip), &stau.at(ip), + state_.total_cl.data()); if (always_check_finite_) { app->checkFinite(derived_state_.deltasx_, "deltasx"); @@ -1225,7 +1226,7 @@ void Model::fx0(AmiVector &x) { void Model::fx0_fixedParameters(AmiVector &x) { if (!getReinitializeFixedParameterInitialStates()) return; - + /* we transform to the unreduced states x_rdata and then apply x0_fixedparameters to (i) enable updates to states that were removed from conservation laws and (ii) be able to correctly compute total abundances @@ -1347,7 +1348,7 @@ void Model::initializeVectors() { void Model::fy(const realtype t, const AmiVector &x) { if (!ny) return; - + auto x_pos = computeX_pos(x); derived_state_.y_.assign(ny, 0.0); @@ -1365,7 +1366,7 @@ void Model::fy(const realtype t, const AmiVector &x) { void Model::fdydp(const realtype t, const AmiVector &x) { if (!ny) return; - + auto x_pos = computeX_pos(x); derived_state_.dydp_.assign(ny * nplist(), 0.0); @@ -1394,7 +1395,7 @@ void Model::fdydp(const realtype t, const AmiVector &x) { void Model::fdydx(const realtype t, const AmiVector &x) { if (!ny) return; - + auto x_pos = computeX_pos(x); derived_state_.dydx_.assign(ny * nx_solver, 0.0); diff --git a/src/model_ode.cpp b/src/model_ode.cpp index bd6e465e71..02905ef2c0 100644 --- a/src/model_ode.cpp +++ b/src/model_ode.cpp @@ -83,7 +83,7 @@ void Model_ODE::froot(realtype t, const_N_Vector x, gsl::span root) { std::fill(root.begin(), root.end(), 0.0); froot(root.data(), t, N_VGetArrayPointerConst(x_pos), state_.unscaledParameters.data(), state_.fixedParameters.data(), - state_.h.data()); + state_.h.data(), state_.total_cl.data()); } void Model_ODE::fxdot(const realtype t, const AmiVector &x, @@ -204,7 +204,8 @@ void Model_ODE::fJSparse_rowvals(SUNMatrixWrapper &/*JSparse*/) { void Model_ODE::froot(realtype * /*root*/, const realtype /*t*/, const realtype * /*x*/, const realtype * /*p*/, - const realtype * /*k*/, const realtype * /*h*/) { + const realtype * /*k*/, const realtype * /*h*/, + const realtype */*tcl*/) { throw AmiException("Requested functionality is not supported as %s is not " "implemented for this model!", __func__); // not implemented From 5e750654c76c5f574d1bb4a0803bf17f9ef549ef Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Mon, 21 Feb 2022 22:42:46 +0100 Subject: [PATCH 07/45] Model import: Get rid of multiplications with 1.0 (#1681) Reduces code bloat, improves readability Closes #1671 --- python/amici/ode_export.py | 9 ++++++--- python/amici/sbml_import.py | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/python/amici/ode_export.py b/python/amici/ode_export.py index 786c7110cd..35ac4d053d 100644 --- a/python/amici/ode_export.py +++ b/python/amici/ode_export.py @@ -961,9 +961,12 @@ class ODEModel: Code printer to generate C++ code """ - def __init__(self, verbose: Optional[Union[bool, int]] = False, - simplify: Optional[Callable] = sp.powsimp, - cache_simplify: bool = False): + def __init__( + self, verbose: Optional[Union[bool, int]] = False, + simplify: Optional[Callable] + = lambda x: sp.powsimp(x, deep=True).subs(1.0, 1), + cache_simplify: bool = False + ): """ Create a new ODEModel instance. diff --git a/python/amici/sbml_import.py b/python/amici/sbml_import.py index c7a337845b..a0cc3b9b9a 100644 --- a/python/amici/sbml_import.py +++ b/python/amici/sbml_import.py @@ -217,7 +217,8 @@ def sbml2amici(self, allow_reinit_fixpar_initcond: bool = True, compile: bool = True, compute_conservation_laws: bool = True, - simplify: Callable = lambda x: sp.powsimp(x, deep=True), + simplify: Callable = lambda x: + sp.powsimp(x, deep=True).subs(1.0, 1), cache_simplify: bool = False, log_as_log10: bool = True, generate_sensitivity_code: bool = True, From a99b4590337ff45c88aea65b8fb61904af14baa5 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Mon, 21 Feb 2022 22:43:39 +0100 Subject: [PATCH 08/45] Doc: Update reference list (#1680) --- documentation/amici_refs.bib | 26 ++++++++++++++++++++++++++ documentation/references.md | 8 +++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/documentation/amici_refs.bib b/documentation/amici_refs.bib index 6a0b18243f..9eaf4c9db7 100644 --- a/documentation/amici_refs.bib +++ b/documentation/amici_refs.bib @@ -999,6 +999,32 @@ @Article{AdlungSta2021 url = {https://www.sciencedirect.com/science/article/pii/S2211124721009372}, } +@article {Sundqvist2022.02.15.480629, + author = {Sundqvist, Nicolas and Sten, Sebastian and Engstr{\"o}m, Maria and Cedersund, Gunnar}, + title = {Mechanistic model for human brain metabolism and the neurovascular coupling.}, + elocation-id = {2022.02.15.480629}, + year = {2022}, + doi = {10.1101/2022.02.15.480629}, + publisher = {Cold Spring Harbor Laboratory}, + abstract = {The neurovascular coupling (NVC) connects cerebral activity, blood flow, and metabolism. This interconnection is used in for instance functional imaging, which analyses the blood-oxygen-dependent (BOLD) signal. The mechanisms underlying the NVC are complex, which warrants a model-based analysis of data. We have previously developed a mechanistically detailed model for the NVC, and others have proposed detailed models for cerebral metabolism. However, existing metabolic models are still not fully utilizing available magnetic resonance spectroscopy (MRS) data and are not connected to detailed models for NVC. Therefore, we herein present a new model that integrates mechanistic modelling of both MRS and BOLD data. The metabolic model covers central metabolism, and can describe time-series data for glucose, lactate, aspartate, and glutamine, measured after visual stimuli. Statistical tests confirm that the model can describe both estimation data and predict independent validation data, not used for model training. The interconnected NVC model can simultaneously describe BOLD data and can be used to predict expected metabolic responses in experiments where metabolism has not been measured. This model is a step towards a useful and mechanistically detailed model for cerebral blood flow and metabolism, with potential applications in both basic research and clinical applications.Competing Interest StatementThe authors have declared no competing interest.}, + URL = {https://www.biorxiv.org/content/early/2022/02/19/2022.02.15.480629}, + eprint = {https://www.biorxiv.org/content/early/2022/02/19/2022.02.15.480629.full.pdf}, + journal = {bioRxiv} +} + +@article {Froehlich2022.02.17.480899, + author = {Fr{\"o}hlich, Fabian and Gerosa, Luca and Muhlich, Jeremy and Sorger, Peter K.}, + title = {Mechanistic model of MAPK signaling reveals how allostery and rewiring contribute to drug resistance}, + elocation-id = {2022.02.17.480899}, + year = {2022}, + doi = {10.1101/2022.02.17.480899}, + publisher = {Cold Spring Harbor Laboratory}, + abstract = {BRAFV600E is prototypical of oncogenic mutations that can be targeted therapeutically and treatment of BRAF-mutant melanomas with RAF and MEK inhibitors results in rapid tumor regression. However, drug-induced rewiring causes BRAFV600E melanoma cells to rapidly acquire a drug-adapted state. In patients this is thought to promote acquisition or selection for resistance mutations and disease recurrence. In this paper we use an energy-based implementation of ordinary differential equations in combination with proteomic, transcriptomic and imaging data from melanoma cells, to model the precise mechanisms responsible for adaptive rewiring. We demonstrate the presence of two parallel MAPK (RAF-MEK-ERK kinase) reaction channels in BRAFV600E melanoma cells that are differentially sensitive to RAF and MEK inhibitors. This arises from differences in protein oligomerization and allosteric regulation induced by oncogenic mutations and drug binding. As a result, the RAS-regulated MAPK channel can be active under conditions in which the BRAFV600E-driven channel is fully inhibited. Causal tracing demonstrates that this provides a sufficient quantitative explanation for initial and acquired responses to multiple different RAF and MEK inhibitors individually and in combination.HighlightsA thermodynamic framework enables structure-based description of allosteric interactions in the EGFR and MAPK pathwaysCausal decomposition of efficacy of targeted drugs elucidates rewiring of MAPK channelsModel-based extrapolation from type I{\textonehalf} RAF inhibitors to type II RAF inhibitorsA unified mechanistic explanation for adaptive and genetic resistance across BRAF-cancersCompeting Interest StatementPKS is a member of the SAB or Board of Directors of Glencoe Software, Applied Biomath, and RareCyte Inc. and has equity in these companies; PKS is also a member of the SAB of NanoString and a consultant for Montai Health and Merck. LG is currently an employee of Genentech. PKS and LG declare that none of these relationships are directly or indirectly related to the content of this manuscript.}, + URL = {https://www.biorxiv.org/content/early/2022/02/18/2022.02.17.480899}, + eprint = {https://www.biorxiv.org/content/early/2022/02/18/2022.02.17.480899.full.pdf}, + journal = {bioRxiv} +} + @Comment{jabref-meta: databaseType:bibtex;} @Comment{jabref-meta: grouping: diff --git a/documentation/references.md b/documentation/references.md index 7c559496c0..e21c044115 100644 --- a/documentation/references.md +++ b/documentation/references.md @@ -1,17 +1,23 @@ # References -List of publications using AMICI. Total number is 64. +List of publications using AMICI. Total number is 66. If you applied AMICI in your work and your publication is missing, please let us know via a new Github issue.

2022

+
+

Fröhlich, Fabian, Luca Gerosa, Jeremy Muhlich, and Peter K. Sorger. 2022. “Mechanistic Model of Mapk Signaling Reveals How Allostery and Rewiring Contribute to Drug Resistance.” bioRxiv. https://doi.org/10.1101/2022.02.17.480899.

+

Schmucker, Robin, Gabriele Farina, James Faeder, Fabian Fröhlich, Ali Sinan Saglam, and Tuomas Sandholm. 2022. “Combination Treatment Optimization Using a Pan-Cancer Pathway Model.” PLOS Computational Biology 17 (12): 1–22. https://doi.org/10.1371/journal.pcbi.1009689.

Stapor, Paul, Leonard Schmiester, Christoph Wierling, Simon Merkt, Dilan Pathirana, Bodo M. H. Lange, Daniel Weindl, and Jan Hasenauer. 2022. “Mini-batch optimization enables training of ODE models on large-scale datasets.” Nature Communications 13 (1): 34. https://doi.org/10.1038/s41467-021-27374-6.

+
+

Sundqvist, Nicolas, Sebastian Sten, Maria Engström, and Gunnar Cedersund. 2022. “Mechanistic Model for Human Brain Metabolism and the Neurovascular Coupling.” bioRxiv. https://doi.org/10.1101/2022.02.15.480629.

+

2021

From 92a4e8bb4445de3a090ec7a79fd80ba33d36c460 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Wed, 23 Feb 2022 20:31:20 +0100 Subject: [PATCH 09/45] Support for parameter-dependent conservation laws (#1678) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds support for parameter-dependent conservation laws. This allows applying conservation laws to models comprising species in different compartments where model states correspond to concentrations. Closes #1673 Co-authored-by: Fabian Fröhlich --- include/amici/abstract_model.h | 20 +++++++- include/amici/model.h | 34 ++++++++++--- python/amici/ode_export.py | 82 +++++++++++++++++++++++++------- python/amici/sbml_import.py | 11 ++--- src/abstract_model.cpp | 11 +++++ src/model.cpp | 84 ++++++++++++++++++++++++--------- src/model_header.ODE_template.h | 6 +++ src/rdata.cpp | 6 +-- tests/testSBMLSuite.py | 25 ++++++++-- 9 files changed, 218 insertions(+), 61 deletions(-) diff --git a/include/amici/abstract_model.h b/include/amici/abstract_model.h index 06fbb9a12c..4ddacdb26b 100644 --- a/include/amici/abstract_model.h +++ b/include/amici/abstract_model.h @@ -306,7 +306,7 @@ class AbstractModel { const realtype *w); /** - * @brief Model-specific implementation of fdydp + * @brief Model-specific implementation of fdydp (MATLAB-only) * @param dydp partial derivative of observables y w.r.t. model parameters p * @param t current time * @param x current state @@ -321,6 +321,24 @@ class AbstractModel { const realtype *p, const realtype *k, const realtype *h, int ip, const realtype *w, const realtype *dwdp); + /** + * @brief Model-specific implementation of fdydp (Python) + * @param dydp partial derivative of observables y w.r.t. model parameters p + * @param t current time + * @param x current state + * @param p parameter vector + * @param k constant vector + * @param h Heaviside vector + * @param ip parameter index w.r.t. which the derivative is requested + * @param w repeating elements vector + * @param tcl total abundances for conservation laws + * @param dtcldp Sensitivities of total abundances for conservation laws + */ + virtual void fdydp(realtype *dydp, const realtype t, const realtype *x, + const realtype *p, const realtype *k, const realtype *h, + int ip, const realtype *w, const realtype *tcl, + const realtype *dtcldp); + /** * @brief Model-specific implementation of fdydx * @param dydx partial derivative of observables y w.r.t. model states x diff --git a/include/amici/model.h b/include/amici/model.h index 7de98177e8..b9e8fb7b8a 100644 --- a/include/amici/model.h +++ b/include/amici/model.h @@ -1265,8 +1265,11 @@ class Model : public AbstractModel, public ModelDimensions { * conservation laws expanded (stored in `amici::ReturnData`). * @param sx_solver State variables sensitivities with conservation laws * applied (solver returns this) + * @param x_solver State variables with conservation laws + * applied (solver returns this) */ - void fsx_rdata(AmiVectorArray &sx_rdata, const AmiVectorArray &sx_solver); + void fsx_rdata(AmiVectorArray &sx_rdata, const AmiVectorArray &sx_solver, + const AmiVector &x_solver); /** * @brief Set indices of states to be reinitialized based on provided @@ -1644,9 +1647,12 @@ class Model : public AbstractModel, public ModelDimensions { * @param x_rdata State variables with conservation laws expanded * @param x_solver State variables with conservation laws applied * @param tcl Total abundances for conservation laws + * @param p parameter vector + * @param k constant vector */ virtual void fx_rdata(realtype *x_rdata, const realtype *x_solver, - const realtype *tcl); + const realtype *tcl, const realtype *p, + const realtype *k); /** * @brief Compute fsx_solver. @@ -1658,10 +1664,17 @@ class Model : public AbstractModel, public ModelDimensions { * @param sx_solver State sensitivity variables with conservation laws * applied * @param stcl Sensitivities of total abundances for conservation laws + * @param p parameter vector + * @param k constant vector + * @param x_solver State variables with conservation laws applied + * @param tcl Total abundances for conservation laws * @param ip Sensitivity index */ virtual void fsx_rdata(realtype *sx_rdata, const realtype *sx_solver, - const realtype *stcl, int ip); + const realtype *stcl, const realtype *p, + const realtype *k, const realtype *x_solver, + const realtype *tcl, + const int ip); /** * @brief Compute fx_solver. @@ -1692,8 +1705,11 @@ class Model : public AbstractModel, public ModelDimensions { * * @param total_cl Total abundances of conservation laws * @param x_rdata State variables with conservation laws expanded + * @param p parameter vector + * @param k constant vector */ - virtual void ftotal_cl(realtype *total_cl, const realtype *x_rdata); + virtual void ftotal_cl(realtype *total_cl, const realtype *x_rdata, + const realtype *p, const realtype *k); /** * @brief Compute fstotal_cl @@ -1705,9 +1721,15 @@ class Model : public AbstractModel, public ModelDimensions { * @param sx_rdata State sensitivity variables with conservation laws * expanded * @param ip Sensitivity index + * @param x_rdata State variables with conservation laws expanded + * @param p parameter vector + * @param k constant vector + * @param tcl Total abundances for conservation laws */ virtual void fstotal_cl(realtype *stotal_cl, const realtype *sx_rdata, - int ip); + const int ip, const realtype *x_rdata, + const realtype *p, const realtype *k, + const realtype *tcl); /** * @brief Compute non-negative state vector. @@ -1723,7 +1745,7 @@ class Model : public AbstractModel, public ModelDimensions { * stateIsNonNegative */ const_N_Vector computeX_pos(const_N_Vector x); - + /** * @brief Compute non-negative state vector. * diff --git a/python/amici/ode_export.py b/python/amici/ode_export.py index 35ac4d053d..630d46220b 100644 --- a/python/amici/ode_export.py +++ b/python/amici/ode_export.py @@ -166,7 +166,8 @@ class _FunctionInfo: _FunctionInfo( 'realtype *dydp, const realtype t, const realtype *x, ' 'const realtype *p, const realtype *k, const realtype *h, ' - 'const int ip, const realtype *w, const realtype *dtcldp', + 'const int ip, const realtype *w, const realtype *tcl, ' + 'const realtype *dtcldp', ), 'dsigmaydp': _FunctionInfo( @@ -241,7 +242,7 @@ class _FunctionInfo: ), 'sx0': _FunctionInfo( - 'realtype *sx0, const realtype t,const realtype *x, ' + 'realtype *sx0, const realtype t, const realtype *x, ' 'const realtype *p, const realtype *k, const int ip', ), 'sx0_fixedParameters': @@ -267,11 +268,26 @@ class _FunctionInfo: ), 'x_rdata': _FunctionInfo( - 'realtype *x_rdata, const realtype *x, const realtype *tcl' + 'realtype *x_rdata, const realtype *x, const realtype *tcl, ' + 'const realtype *p, const realtype *k' + ), + 'sx_rdata': + _FunctionInfo( + 'realtype *sx_rdata, const realtype *sx_solver, ' + 'const realtype *stotal_cl, const realtype *p, const realtype *k, ' + 'const realtype *x, const realtype *tcl, const int ip' ), 'total_cl': - _FunctionInfo('realtype *total_cl, const realtype *x_rdata'), - + _FunctionInfo( + 'realtype *total_cl, const realtype *x_rdata, ' + 'const realtype *p, const realtype *k' + ), + 'stotal_cl': + _FunctionInfo( + 'realtype *stotal_cl, const realtype *sx_rdata, const int ip, ' + 'const realtype *x_rdata, const realtype *p, const realtype *k, ' + 'const realtype *tcl' + ), 'x_solver': _FunctionInfo('realtype *x_solver, const realtype *x_rdata') } @@ -1032,19 +1048,13 @@ def __init__( } self._total_derivative_prototypes: \ Dict[str, Dict[str, Union[str, List[str]]]] = { - 'sx_rdata': { - 'eq': 'x_rdata', - 'chainvars': ['x'], - 'var': 'p', - 'dxdz_name': 'sx', - }, 'sroot': { 'eq': 'root', 'chainvars': ['x'], 'var': 'p', 'dxdz_name': 'sx', - } - } + }, + } self._lock_total_derivative: List[str] = list() self._simplify: Callable = simplify @@ -1603,6 +1613,12 @@ def _generate_symbol(self, name: str, *, from_sbml: bool = False) -> None: if state._conservation_law is None ]) return + elif name == 'sx_rdata': + self._syms[name] = sp.Matrix([ + f'sx_rdata_{i}' + for i in range(len(self._states)) + ]) + return elif name == 'dtcldp': # check, whether the CL consists of only one state. Then, # sensitivities drop out, otherwise generate symbols @@ -1854,9 +1870,41 @@ def _compute_equation(self, name: str) -> None: sp.zeros(self.num_cons_law(), self.num_states_solver()) elif name == 'dtcldp': - # force symbols - self._eqs[name] = self.sym(name) + self._derivative('total_cl', 'p', name=name) + + elif name == 'stotal_cl': + # stotal_cl = dtotal_cl/dp + dtotal_cl/dx_rdata * sx_rdata + # shape: ncl x np + self._eqs[name] = self.eq('dtcldp') + dtotal_cldx_rdata = smart_jacobian(self.eq('total_cl'), + self.sym('x_rdata')) + tmp = smart_multiply(dtotal_cldx_rdata, self.sym('sx_rdata')) + for ip in range(self._eqs[name].shape[1]): + self._eqs[name][:, ip] += tmp + elif name == 'sx_rdata': + if self.num_cons_law(): + # sx_rdata = dx_rdata/dx_solver * sx_solver + # + dx_rdata/d_tcl * stcl + dxrdata/dp + # shape: nx_rdata, 1 + dx_rdata_dx_solver = smart_jacobian(self.eq('x_rdata'), + self.sym('x')) + sym_sx_solver = self.sym('sx_solver') + dx_rdata_dp = smart_jacobian(self.eq('x_rdata'), + self.sym('p')) + self._eqs[name] = dx_rdata_dp + tmp = smart_multiply(dx_rdata_dx_solver, sym_sx_solver) + for ip in range(self._eqs[name].shape[1]): + self._eqs[name][:, ip] += tmp + sym_stotal_cl = self.sym('stotal_cl') + dx_rdata_dtotal_cl = smart_jacobian(self.eq('x_rdata'), + self.sym('tcl')) + tmp = smart_multiply(dx_rdata_dtotal_cl, sym_stotal_cl) + for ip in range(self._eqs[name].shape[1]): + self._eqs[name][:, ip] += tmp + else: + # if there are no conservation laws, this is simply sx_solver + self._eqs[name] = self.sym('sx_solver') elif name == 'dxdotdx_explicit': # force symbols self._derivative('xdot', 'x', name=name) @@ -3072,7 +3120,8 @@ def _get_function_body( outer_cases[ie] = copy.copy(inner_lines) lines.extend(get_switch_statement('ie', outer_cases, 1)) - elif function in sensi_functions: + elif function in sensi_functions \ + and equations.shape[1] == self.model.num_par(): cases = { ipar: self.model._code_printer._get_sym_lines_array( equations[:, ipar], function, 0) @@ -3080,7 +3129,6 @@ def _get_function_body( if not smart_is_zero_matrix(equations[:, ipar]) } lines.extend(get_switch_statement('ip', cases, 1)) - elif function in multiobs_functions: if function == 'dJydy': cases = { diff --git a/python/amici/sbml_import.py b/python/amici/sbml_import.py index a0cc3b9b9a..8b5aed3779 100644 --- a/python/amici/sbml_import.py +++ b/python/amici/sbml_import.py @@ -1503,14 +1503,9 @@ def _add_conservation_for_non_constant_species( else sp.Integer(1) for state_id in state_ids ] - if any(x.free_symbols for x in compartment_sizes): - # https://github.com/AMICI-dev/AMICI/issues/1673 - # see SBML semantic test suite, case 783 for an example - warnings.warn( - "Conservation laws for non-constant species in " - "compartments with parameter-dependent size are not " - "currently supported and will be turned off.") - return species_solver + # prevent sympy from evaluating float operations in abundance + # expression below + coefficients = list(map(sp.Rational, coefficients)) total_abundance = symbol_with_assumptions(f'tcl_{target_state_id}') target_compartment = compartment_sizes[target_state_cl_idx] diff --git a/src/abstract_model.cpp b/src/abstract_model.cpp index ede420f131..486239e103 100644 --- a/src/abstract_model.cpp +++ b/src/abstract_model.cpp @@ -119,6 +119,17 @@ AbstractModel::fdydp(realtype* /*dydp*/, __func__); } +void AbstractModel::fdydp(realtype */*dydp*/, const realtype /*t*/, + const realtype */*x*/, const realtype */*p*/, + const realtype */*k*/, const realtype */*h*/, + int /*ip*/, const realtype */*w*/, + const realtype */*tcl*/, const realtype */*dtcldp*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + void AbstractModel::fdydx(realtype* /*dydx*/, const realtype /*t*/, diff --git a/src/model.cpp b/src/model.cpp index b3912ae267..b2dc5fc008 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -234,7 +234,9 @@ void Model::initializeStates(AmiVector &x) { fx0(x); } else { std::vector x0_solver(nx_solver, 0.0); - ftotal_cl(state_.total_cl.data(), x0data_.data()); + ftotal_cl(state_.total_cl.data(), x0data_.data(), + state_.unscaledParameters.data(), + state_.fixedParameters.data()); fx_solver(x0_solver.data(), x0data_.data()); std::copy(x0_solver.cbegin(), x0_solver.cend(), x.data()); } @@ -250,7 +252,11 @@ void Model::initializeStateSensitivities(AmiVectorArray &sx, for (int ip = 0; ip < nplist(); ip++) { if (ncl() > 0) stcl = &state_.stotal_cl.at(plist(ip) * ncl()); - fstotal_cl(stcl, &sx0data_.at(ip * nx_rdata), plist(ip)); + fstotal_cl(stcl, &sx0data_.at(ip * nx_rdata), plist(ip), + derived_state_.x_rdata_.data(), + state_.unscaledParameters.data(), + state_.fixedParameters.data(), + state_.total_cl.data()); fsx_solver(sx0_solver_slice.data(), &sx0data_.at(ip * nx_rdata)); for (int ix = 0; ix < nx_solver; ix++) { sx.at(ix, ip) = sx0_solver_slice.at(ix); @@ -1215,7 +1221,9 @@ void Model::fx0(AmiVector &x) { state_.unscaledParameters.data(), state_.fixedParameters.data()); fx_solver(x.data(), derived_state_.x_rdata_.data()); - ftotal_cl(state_.total_cl.data(), derived_state_.x_rdata_.data()); + ftotal_cl(state_.total_cl.data(), derived_state_.x_rdata_.data(), + state_.unscaledParameters.data(), + state_.fixedParameters.data()); if (always_check_finite_) { checkFinite(derived_state_.x_rdata_, "x0 x_rdata"); @@ -1232,7 +1240,8 @@ void Model::fx0_fixedParameters(AmiVector &x) { conservation laws and (ii) be able to correctly compute total abundances after updating the state variables */ fx_rdata(derived_state_.x_rdata_.data(), computeX_pos(x), - state_.total_cl.data()); + state_.total_cl.data(), state_.unscaledParameters.data(), + state_.fixedParameters.data()); fx0_fixedParameters(derived_state_.x_rdata_.data(), simulation_parameters_.tstart_, state_.unscaledParameters.data(), @@ -1241,7 +1250,9 @@ void Model::fx0_fixedParameters(AmiVector &x) { ); fx_solver(x.data(), derived_state_.x_rdata_.data()); /* update total abundances */ - ftotal_cl(state_.total_cl.data(), derived_state_.x_rdata_.data()); + ftotal_cl(state_.total_cl.data(), derived_state_.x_rdata_.data(), + state_.unscaledParameters.data(), + state_.fixedParameters.data()); } void Model::fsx0(AmiVectorArray &sx, const AmiVector &x) { @@ -1256,7 +1267,11 @@ void Model::fsx0(AmiVectorArray &sx, const AmiVector &x) { computeX_pos(x), state_.unscaledParameters.data(), state_.fixedParameters.data(), plist(ip)); fsx_solver(sx.data(ip), derived_state_.sx_rdata_.data()); - fstotal_cl(stcl, derived_state_.sx_rdata_.data(), plist(ip)); + fstotal_cl(stcl, derived_state_.sx_rdata_.data(), plist(ip), + derived_state_.x_rdata_.data(), + state_.unscaledParameters.data(), + state_.fixedParameters.data(), + state_.total_cl.data()); } } @@ -1267,7 +1282,11 @@ void Model::fsx0_fixedParameters(AmiVectorArray &sx, const AmiVector &x) { for (int ip = 0; ip < nplist(); ip++) { if (ncl() > 0) stcl = &state_.stotal_cl.at(plist(ip) * ncl()); - fsx_rdata(derived_state_.sx_rdata_.data(), sx.data(ip), stcl, plist(ip)); + fsx_rdata(derived_state_.sx_rdata_.data(), sx.data(ip), stcl, + state_.unscaledParameters.data(), + state_.fixedParameters.data(), + x.data(), state_.total_cl.data(), + plist(ip)); fsx0_fixedParameters(derived_state_.sx_rdata_.data(), simulation_parameters_.tstart_, computeX_pos(x), @@ -1276,24 +1295,33 @@ void Model::fsx0_fixedParameters(AmiVectorArray &sx, const AmiVector &x) { plist(ip), simulation_parameters_.reinitialization_state_idxs_sim); fsx_solver(sx.data(ip), derived_state_.sx_rdata_.data()); - fstotal_cl(stcl, derived_state_.sx_rdata_.data(), plist(ip)); + fstotal_cl(stcl, derived_state_.sx_rdata_.data(), plist(ip), + derived_state_.x_rdata_.data(), + state_.unscaledParameters.data(), + state_.fixedParameters.data(), + state_.total_cl.data()); } } void Model::fsdx0() {} void Model::fx_rdata(AmiVector &x_rdata, const AmiVector &x) { - fx_rdata(x_rdata.data(), computeX_pos(x), state_.total_cl.data()); + fx_rdata(x_rdata.data(), computeX_pos(x), state_.total_cl.data(), + state_.unscaledParameters.data(), state_.fixedParameters.data()); if (always_check_finite_) checkFinite(x_rdata.getVector(), "x_rdata"); } -void Model::fsx_rdata(AmiVectorArray &sx_rdata, const AmiVectorArray &sx) { +void Model::fsx_rdata(AmiVectorArray &sx_rdata, const AmiVectorArray &sx, + AmiVector const& x_solver) { realtype *stcl = nullptr; for (int ip = 0; ip < nplist(); ip++) { if (ncl() > 0) stcl = &state_.stotal_cl.at(plist(ip) * ncl()); - fsx_rdata(sx_rdata.data(ip), sx.data(ip), stcl, ip); + fsx_rdata(sx_rdata.data(ip), sx.data(ip), stcl, + state_.unscaledParameters.data(), + state_.fixedParameters.data(), x_solver.data(), + state_.total_cl.data(), plist(ip)); } } @@ -1379,7 +1407,8 @@ void Model::fdydp(const realtype t, const AmiVector &x) { fdydp(&derived_state_.dydp_.at(ip * ny), t, x_pos, state_.unscaledParameters.data(), state_.fixedParameters.data(), state_.h.data(), plist(ip), - derived_state_.w_.data(), state_.stotal_cl.data()); + derived_state_.w_.data(), state_.total_cl.data(), + state_.stotal_cl.data()); } else { fdydp(&derived_state_.dydp_.at(ip * ny), t, x_pos, state_.unscaledParameters.data(), @@ -2068,7 +2097,8 @@ void Model::fdwdw(const realtype t, const realtype *x) { } void Model::fx_rdata(realtype *x_rdata, const realtype *x_solver, - const realtype * /*tcl*/) { + const realtype * /*tcl*/, const realtype */*p*/, + const realtype */*k*/) { if (nx_solver != nx_rdata) throw AmiException( "A model that has differing nx_solver and nx_rdata needs " @@ -2077,8 +2107,15 @@ void Model::fx_rdata(realtype *x_rdata, const realtype *x_solver, } void Model::fsx_rdata(realtype *sx_rdata, const realtype *sx_solver, - const realtype *stcl, const int /*ip*/) { - fx_rdata(sx_rdata, sx_solver, stcl); + const realtype */*stcl*/, const realtype */*p*/, + const realtype */*k*/, const realtype * /*x_solver*/, + const realtype */*tcl*/, + const int /*ip*/) { + if (nx_solver != nx_rdata) + throw AmiException( + "A model that has differing nx_solver and nx_rdata needs " + "to implement its own fx_rdata"); + std::copy_n(sx_solver, nx_solver, sx_rdata); } void Model::fx_solver(realtype *x_solver, const realtype *x_rdata) { @@ -2096,19 +2133,22 @@ void Model::fsx_solver(realtype *sx_solver, const realtype *sx_rdata) { fx_solver(sx_solver, sx_rdata); } -void Model::ftotal_cl(realtype * /*total_cl*/, const realtype * /*x_rdata*/) { +void Model::ftotal_cl(realtype * /*total_cl*/, const realtype * /*x_rdata*/, + const realtype */*p*/, const realtype */*k*/) { if (nx_solver != nx_rdata) throw AmiException( "A model that has differing nx_solver and nx_rdata needs " "to implement its own ftotal_cl"); } -void Model::fstotal_cl(realtype *stotal_cl, const realtype *sx_rdata, - const int /*ip*/) { - /* for the moment we do not need an implementation of fstotal_cl as - * we can simply reuse ftotal_cl and replace states by their - * sensitivities */ - ftotal_cl(stotal_cl, sx_rdata); +void Model::fstotal_cl(realtype */*stotal_cl*/, const realtype */*sx_rdata*/, + const int /*ip*/, const realtype */*x_rdata*/, + const realtype */*p*/, const realtype */*k*/, + const realtype */*tcl*/) { + if (nx_solver != nx_rdata) + throw AmiException( + "A model that has differing nx_solver and nx_rdata needs " + "to implement its own ftotal_cl"); } const_N_Vector Model::computeX_pos(const_N_Vector x) { diff --git a/src/model_header.ODE_template.h b/src/model_header.ODE_template.h index 96bfcbad50..bcf3c8feff 100644 --- a/src/model_header.ODE_template.h +++ b/src/model_header.ODE_template.h @@ -69,6 +69,8 @@ TPL_DELTASX_DEF TPL_X_RDATA_DEF TPL_X_SOLVER_DEF TPL_TOTAL_CL_DEF +TPL_STOTAL_CL_DEF +TPL_SX_RDATA_DEF /** * @brief AMICI-generated model subclass. @@ -464,6 +466,10 @@ class Model_TPL_MODELNAME : public amici::Model_ODE { TPL_TOTAL_CL_IMPL + TPL_STOTAL_CL_IMPL + + TPL_SX_RDATA_IMPL + std::string getName() const override { return "TPL_MODELNAME"; } diff --git a/src/rdata.cpp b/src/rdata.cpp index d0fe49067b..3eab8f5c13 100644 --- a/src/rdata.cpp +++ b/src/rdata.cpp @@ -193,7 +193,7 @@ void ReturnData::processPreEquilibration(SteadystateProblem const &preeq, writeSlice(x_rdata_, x_ss); } if (!sx_ss.empty() && sensi >= SensitivityOrder::first) { - model.fsx_rdata(sx_rdata_, sx_solver_); + model.fsx_rdata(sx_rdata_, sx_solver_, x_solver_); for (int ip = 0; ip < nplist; ip++) writeSlice(sx_rdata_[ip], slice(sx_ss, ip, nx)); } @@ -254,7 +254,7 @@ void ReturnData::processForwardProblem(ForwardProblem const &fwd, Model &model, } if (!sx0.empty()) { - model.fsx_rdata(sx_rdata_, sx_solver_); + model.fsx_rdata(sx_rdata_, sx_solver_, x_solver_); for (int ip = 0; ip < nplist; ip++) writeSlice(sx_rdata_[ip], slice(sx0, ip, nx)); } @@ -318,7 +318,7 @@ void ReturnData::getDataOutput(int it, Model &model, ExpData const *edata) { void ReturnData::getDataSensisFSA(int it, Model &model, ExpData const *edata) { if (!sx.empty()) { - model.fsx_rdata(sx_rdata_, sx_solver_); + model.fsx_rdata(sx_rdata_, sx_solver_, x_solver_); for (int ip = 0; ip < nplist; ip++) { writeSlice(sx_rdata_[ip], slice(sx, it * nplist + ip, nx)); diff --git a/tests/testSBMLSuite.py b/tests/testSBMLSuite.py index b54bb032ba..187637a15f 100755 --- a/tests/testSBMLSuite.py +++ b/tests/testSBMLSuite.py @@ -27,6 +27,7 @@ import amici from amici.constants import SymbolId +from amici.gradient_check import check_derivatives # directory with sbml semantic test cases TEST_PATH = os.path.join(os.path.dirname(__file__), 'sbml-test-suite', 'cases', @@ -54,6 +55,14 @@ def sbml_test_dir(): def test_sbml_testsuite_case(test_number, result_path): test_id = format_test_id(test_number) model_dir = None + + # test cases for which sensitivities are to be checked + # key: case ID; value: epsilon for finite differences + sensitivity_check_cases = { + # parameter-dependent conservation laws + '00783': 1.5e-2, + } + try: current_test_path = os.path.join(TEST_PATH, test_id) @@ -68,8 +77,9 @@ def test_sbml_testsuite_case(test_number, result_path): # setup model model_dir = os.path.join(os.path.dirname(__file__), 'SBMLTestModels', test_id) - model, solver, wrapper = compile_model(current_test_path, test_id, - model_dir) + model, solver, wrapper = compile_model( + current_test_path, test_id, model_dir, + generate_sensitivity_code=test_id in sensitivity_check_cases) settings = read_settings_file(current_test_path, test_id) atol, rtol = apply_settings(settings, solver, model) @@ -88,6 +98,12 @@ def test_sbml_testsuite_case(test_number, result_path): # record results write_result_file(simulated, test_id, result_path) + # check sensitivities for selected models + if epsilon := sensitivity_check_cases.get(test_id): + solver.setSensitivityOrder(amici.SensitivityOrder.first) + solver.setSensitivityMethod(amici.SensitivityMethod.forward) + check_derivatives(model, solver, epsilon=epsilon) + except amici.sbml_import.SBMLException as err: pytest.skip(str(err)) finally: @@ -255,7 +271,8 @@ def apply_settings(settings, solver, model): return atol, rtol -def compile_model(path, test_id, model_dir): +def compile_model(path, test_id, model_dir, + generate_sensitivity_code: bool = False): """Import the given test model to AMICI""" sbml_file = find_model_file(path, test_id) @@ -266,7 +283,7 @@ def compile_model(path, test_id, model_dir): model_name = f'SBMLTest{test_id}' wrapper.sbml2amici(model_name, output_dir=model_dir, - generate_sensitivity_code=False) + generate_sensitivity_code=generate_sensitivity_code) # settings model_module = amici.import_model_module(model_name, model_dir) From 905b4e3c98ab78f2588aa4a099e1ba854ea32f69 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Fri, 25 Feb 2022 09:24:34 +0100 Subject: [PATCH 10/45] Fix output for conservation laws (#1684) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix output * use logging * fix typehints Co-authored-by: Fabian Fröhlich --- python/amici/conserved_moieties.py | 48 +++++++++++++++++++++++-- python/amici/sbml_import.py | 4 ++- python/tests/test_conserved_moieties.py | 27 ++------------ 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/python/amici/conserved_moieties.py b/python/amici/conserved_moieties.py index e5cdad8f8f..6cdc8b9857 100644 --- a/python/amici/conserved_moieties.py +++ b/python/amici/conserved_moieties.py @@ -2,7 +2,7 @@ import math import random import sys -from typing import List, MutableSequence, Sequence, Tuple, Union +from typing import List, MutableSequence, Sequence, Tuple, Union, Optional from .logging import get_logger @@ -20,7 +20,8 @@ def compute_moiety_conservation_laws( num_species: int, num_reactions: int, max_num_monte_carlo: int = 20, - rng_seed: Union[None, bool, int] = False + rng_seed: Union[None, bool, int] = False, + species_names: Optional[Sequence[str]] = None, ) -> Tuple[List[List[int]], List[List[float]]]: """Compute moiety conservation laws. @@ -39,6 +40,8 @@ def compute_moiety_conservation_laws( :param rng_seed: Seed for the random number generator. If `False`, the RNG will not be re-initialized. Other values will be passed to :func:`random.seed`. + :param species_names: + Species names. Optional and only used for logging. :returns: Integer MCLs as list of lists of indices of involved species and list of lists of corresponding coefficients. @@ -76,10 +79,49 @@ def compute_moiety_conservation_laws( num_reactions, num_species) timer = 0 _reduce(int_kernel_dim, cls_species_idxs, cls_coefficients, num_species) + _output(int_kernel_dim, kernel_dim, engaged_species, cls_species_idxs, + cls_coefficients, species_names, verbose=True) return cls_species_idxs[:int_kernel_dim], cls_coefficients[:int_kernel_dim] +def _output( + int_kernel_dim: int, + kernel_dim: int, + int_matched: List[int], + species_indices: List[List[int]], + species_coefficients: List[List[float]], + species_names: Optional[Sequence[str]] = None, + verbose: bool = False, + log_level: int = logging.DEBUG +): + """Log infos on identified conservation laws""" + def log(*args, **kwargs): + logger.log(log_level, *args, **kwargs) + + log(f"There are {int_kernel_dim} linearly independent conserved " + f"moieties, engaging {len(int_matched)} state variables.") + if int_kernel_dim == kernel_dim: + log("They generate all the conservation laws") + else: + log(f"They don't generate all the conservation laws, " + f"{kernel_dim - int_kernel_dim} of them are not reducible to " + "moieties") + # print all conserved quantities + if verbose: + for i, (coefficients, engaged_species_idxs) \ + in enumerate(zip(species_coefficients, species_indices)): + if not engaged_species_idxs: + continue + log(f"Moiety number {i + 1} engages {len(engaged_species_idxs)} " + "species:") + for species_idx, coefficient \ + in zip(engaged_species_idxs, coefficients): + name = species_names[species_idx] if species_names \ + else species_idx + log(f"\t{name}\t{coefficient}") + + def _qsort( k: int, km: int, @@ -130,7 +172,7 @@ def _kernel( stoichiometric_list: Sequence[float], num_species: int, num_reactions: int -) -> Tuple[float, List[int], int, List[int], +) -> Tuple[int, List[int], int, List[int], List[List[int]], List[List[float]]]: """ Kernel (left nullspace of :math:`S`) calculation by Gaussian elimination diff --git a/python/amici/sbml_import.py b/python/amici/sbml_import.py index 8b5aed3779..597e3763e5 100644 --- a/python/amici/sbml_import.py +++ b/python/amici/sbml_import.py @@ -1466,7 +1466,9 @@ def _add_conservation_for_non_constant_species( cls_state_idxs, cls_coefficients = compute_moiety_conservation_laws( stoichiometric_list, *self.stoichiometric_matrix.shape, - rng_seed=32) + rng_seed=32, + species_names=[str(x.get_id()) for x in ode_model._states] + ) # previously removed constant species eliminated_state_ids = {cl['state'] for cl in conservation_laws} diff --git a/python/tests/test_conserved_moieties.py b/python/tests/test_conserved_moieties.py index 77edbbd983..9a7b2c811a 100644 --- a/python/tests/test_conserved_moieties.py +++ b/python/tests/test_conserved_moieties.py @@ -7,7 +7,8 @@ import sympy as sp from amici.conserved_moieties import (_fill, _kernel, - compute_moiety_conservation_laws) + compute_moiety_conservation_laws, + _output as output) from amici.logging import get_logger, log_execution_time logger = get_logger(__name__) @@ -55,30 +56,6 @@ def data_demartino2014(): return S, row_names -def output( - int_kernel_dim, kernel_dim, int_matched, species_indices, - species_coefficients, row_names, verbose=False -): - """Print status""" - print(f"There are {int_kernel_dim} linearly independent conserved " - f"moieties, engaging {len(int_matched)} metabolites.") - if int_kernel_dim == kernel_dim: - print("They generate all the conservation laws") - else: - print(f"They don't generate all the conservation laws, " - f"{kernel_dim - int_kernel_dim} of them are not reducible to " - "moieties") - # print all conservation laws - if verbose: - for i, coefficients, engaged_species_idxs \ - in enumerate(zip(species_coefficients, species_indices)): - print(f"Moiety number {i + 1} engages {len(engaged_species_idxs)} " - "metabolites:") - for species_idx, coefficient \ - in zip(engaged_species_idxs, coefficients): - print(f"\t{row_names[species_idx]}\t{coefficient}") - - def test_kernel_demartino2014(data_demartino2014, quiet=True): """Invoke test case and benchmarking for De Martino's published results for E. coli network. Kernel-only.""" From 2b3a9b18c5b736d022a6eccc10d3e41528746c46 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Fri, 25 Feb 2022 11:44:24 +0100 Subject: [PATCH 11/45] Sparsify conserved quantities to avoid circular dependencies (#1683) Sparsify conserved quantities to avoid circular dependencies. Bring conservation law matrix to reduced row echelon form, eliminate pivot species. Closes #1682 --- python/amici/sbml_import.py | 90 ++++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 42 deletions(-) diff --git a/python/amici/sbml_import.py b/python/amici/sbml_import.py index 597e3763e5..5f564d907e 100644 --- a/python/amici/sbml_import.py +++ b/python/amici/sbml_import.py @@ -1449,7 +1449,9 @@ def _add_conservation_for_non_constant_species( float(entry) for entry in self.stoichiometric_matrix.T.flat() ] except TypeError: - # https://github.com/AMICI-dev/AMICI/issues/1673 + # Due to the numerical algorithm currently used to identify + # conserved quantities, we can't have symbols in the + # stoichiometric matrix warnings.warn("Conservation laws for non-constant species in " "combination with parameterized stoichiometric " "coefficients are not currently supported " @@ -1470,48 +1472,53 @@ def _add_conservation_for_non_constant_species( species_names=[str(x.get_id()) for x in ode_model._states] ) + # Sparsify conserved quantities + # ``compute_moiety_conservation_laws`` identifies conserved quantities + # with positive coefficients. The resulting system is, therefore, + # often non-sparse. This leads to circular dependencies in the + # state expressions of eliminated states. The identified conserved + # quantities are linearly independent. We can construct `A` as in + # `A * x0 = total_cl` and bring it to reduced row echelon form. The + # pivot species are the ones to be eliminated. The resulting state + # expressions are sparse and void of any circular dependencies. + A = sp.zeros(len(cls_coefficients), len(ode_model._states)) + for i_cl, (cl, coefficients) in enumerate(zip(cls_state_idxs, + cls_coefficients)): + for i, c in zip(cl, coefficients): + A[i_cl, i] = sp.Rational(c) + rref, pivots = A.rref() + species_to_be_removed = set(pivots) + + # keep new conservations laws separate until we know everything worked + new_conservation_laws = [] # previously removed constant species eliminated_state_ids = {cl['state'] for cl in conservation_laws} - # iterate over list of conservation laws, create symbolic expressions, - # and mark replaced species for removal from stoichiometric matrix - species_to_be_removed = set() - # keep new conservation laws separate until we know everything worked - new_conservation_laws = [] - for state_idxs, coefficients in zip(cls_state_idxs, cls_coefficients): - assert len(state_idxs) == len(coefficients) - - state_ids = [ode_model._states[i_state].get_id() - for i_state in state_idxs] + all_state_ids = [x.get_id() for x in ode_model._states] + all_compartment_sizes = [ + self.compartments[ + self.symbols[SymbolId.SPECIES][state_id]['compartment']] + if not self.symbols[SymbolId.SPECIES][state_id]['amount'] + else sp.Integer(1) + for state_id in all_state_ids + ] - # choose a state that is not already subject to removal - try: - target_state_cl_idx = next(filter( - lambda x: state_ids[x] not in eliminated_state_ids, - range(len(state_idxs))) - ) - except StopIteration: - # all engaged states have already been eliminated + # iterate over list of conservation laws, create symbolic expressions, + for i_cl, target_state_model_idx in enumerate(pivots): + if all_state_ids[target_state_model_idx] in eliminated_state_ids: + # constants state, already eliminated continue - - target_state_model_idx = state_idxs[target_state_cl_idx] - target_state_id = state_ids[target_state_cl_idx] - eliminated_state_ids.add(target_state_id) - - compartment_sizes = [ - self.compartments[ - self.symbols[SymbolId.SPECIES][state_id]['compartment']] - if not self.symbols[SymbolId.SPECIES][state_id]['amount'] - else sp.Integer(1) - for state_id in state_ids - ] - # prevent sympy from evaluating float operations in abundance - # expression below - coefficients = list(map(sp.Rational, coefficients)) - + # collect values for species engaged in the current CL + state_idxs = [i for i, coeff in enumerate(rref[i_cl, :]) + if coeff] + coefficients = [coeff for coeff in rref[i_cl, :] if coeff] + state_ids = [all_state_ids[i_state] for i_state in state_idxs] + compartment_sizes = [all_compartment_sizes[i] for i in state_idxs] + + target_state_id = all_state_ids[target_state_model_idx] + target_compartment = all_compartment_sizes[target_state_model_idx] + target_state_coeff = coefficients[0] total_abundance = symbol_with_assumptions(f'tcl_{target_state_id}') - target_compartment = compartment_sizes[target_state_cl_idx] - target_state_coeff = coefficients[target_state_cl_idx] # \sum coeff * state * volume abundance_expr = sp.Add(*[ @@ -1541,11 +1548,10 @@ def _add_conservation_for_non_constant_species( try: sorted_state_exprs = toposort_symbols(state_exprs) except CircularDependencyError as e: - # see SBML semantic test suite, case 18 for an example - warnings.warn("Circular dependency detected in conservation laws. " - "Skipping conservation laws for non-constant " - f"species. Error was: {e}.") - return species_solver + raise AssertionError( + "Circular dependency detected in conservation laws. " + "This should not have happened." + ) from e for cl in new_conservation_laws: cl['state_expr'] = smart_subs_dict(cl['state_expr'], From 7273c347f95c91134cb2bbc974f66042146b30ef Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Mon, 28 Feb 2022 18:46:05 +0100 Subject: [PATCH 12/45] Improve logging of computation time for some derivatives (#1686) Improve logging of computation time for some derivatives by using `ODEModel.eq()` --- python/amici/ode_export.py | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/python/amici/ode_export.py b/python/amici/ode_export.py index 630d46220b..dd3e9d893a 100644 --- a/python/amici/ode_export.py +++ b/python/amici/ode_export.py @@ -1876,35 +1876,45 @@ def _compute_equation(self, name: str) -> None: # stotal_cl = dtotal_cl/dp + dtotal_cl/dx_rdata * sx_rdata # shape: ncl x np self._eqs[name] = self.eq('dtcldp') - dtotal_cldx_rdata = smart_jacobian(self.eq('total_cl'), - self.sym('x_rdata')) + dtotal_cldx_rdata = self.eq('dtotal_cldx_rdata') tmp = smart_multiply(dtotal_cldx_rdata, self.sym('sx_rdata')) for ip in range(self._eqs[name].shape[1]): self._eqs[name][:, ip] += tmp + + elif name == 'dx_rdatadx_solver': + self._eqs[name] = smart_jacobian(self.eq('x_rdata'), + self.sym('x')) + + elif name == 'dx_rdatadp': + self._eqs[name] = smart_jacobian(self.eq('x_rdata'), + self.sym('p')) + + elif name == 'dx_rdatadtcl': + self._eqs[name] = smart_jacobian(self.eq('x_rdata'), + self.sym('tcl')) + elif name == 'sx_rdata': if self.num_cons_law(): # sx_rdata = dx_rdata/dx_solver * sx_solver # + dx_rdata/d_tcl * stcl + dxrdata/dp # shape: nx_rdata, 1 - dx_rdata_dx_solver = smart_jacobian(self.eq('x_rdata'), - self.sym('x')) + dx_rdata_dx_solver = self.eq('dx_rdatadx_solver') sym_sx_solver = self.sym('sx_solver') - dx_rdata_dp = smart_jacobian(self.eq('x_rdata'), - self.sym('p')) + dx_rdata_dp = self.eq('dx_rdatadp') self._eqs[name] = dx_rdata_dp tmp = smart_multiply(dx_rdata_dx_solver, sym_sx_solver) for ip in range(self._eqs[name].shape[1]): self._eqs[name][:, ip] += tmp sym_stotal_cl = self.sym('stotal_cl') - dx_rdata_dtotal_cl = smart_jacobian(self.eq('x_rdata'), - self.sym('tcl')) + dx_rdata_dtotal_cl = self.eq('dx_rdatadtcl') tmp = smart_multiply(dx_rdata_dtotal_cl, sym_stotal_cl) for ip in range(self._eqs[name].shape[1]): self._eqs[name][:, ip] += tmp else: # if there are no conservation laws, this is simply sx_solver self._eqs[name] = self.sym('sx_solver') + elif name == 'dxdotdx_explicit': # force symbols self._derivative('xdot', 'x', name=name) From a366a63404e3ea94339ce36f01a72619052504cc Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Mon, 28 Feb 2022 18:46:36 +0100 Subject: [PATCH 13/45] Add `--no-sensitivities` to `amici_import_petab` (#1688) ... to enable model import without generating sensitivity code from the command line --- python/amici/petab_import.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/python/amici/petab_import.py b/python/amici/petab_import.py index 4f8ad93c9e..0446570a14 100644 --- a/python/amici/petab_import.py +++ b/python/amici/petab_import.py @@ -691,7 +691,7 @@ def show_model_info(sbml_model: 'libsbml.Model'): logger.info(f'Reactions: {len(sbml_model.getListOfReactions())}') -def parse_cli_args(): +def _parse_cli_args(): """ Parse command line arguments @@ -714,6 +714,9 @@ def parse_cli_args(): action='store_true', help='Flatten measurement specific overrides of ' 'observable and noise parameters') + parser.add_argument('--no-sensitivities', dest='generate_sensitivity_code', + default=False, action='store_false', + help='Skip generation of sensitivity code') # Call with set of files parser.add_argument('-s', '--sbml', dest='sbml_file_name', @@ -750,7 +753,7 @@ def main(): Command line interface to import a model in the PEtab (https://github.com/PEtab-dev/PEtab/) format into AMICI. """ - args = parse_cli_args() + args = _parse_cli_args() if args.yaml_file_name: pp = petab.Problem.from_yaml(args.yaml_file_name) @@ -775,6 +778,7 @@ def main(): measurement_table=pp.measurement_df, model_output_dir=args.model_output_dir, compile=args.compile, + generate_sensitivity_code=args.generate_sensitivity_code, verbose=args.verbose) From e8e46ac8ec0c895549703eace15f2135fdb1747b Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Mon, 28 Feb 2022 21:48:44 +0100 Subject: [PATCH 14/45] Fix IndexError conserved_moieties._reduce (#1685) Fixes `IndexError` occurring under rare circumstances: ``` File "/venv/src/amici/python/sdist/amici/conserved_moieties.py", line 698, in _relax if not len(matrix[j]) or matrix[j][0] != matrix[k][i]: IndexError: list index out of range ``` * .. --- python/amici/conserved_moieties.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/python/amici/conserved_moieties.py b/python/amici/conserved_moieties.py index 6cdc8b9857..28fe3f9e77 100644 --- a/python/amici/conserved_moieties.py +++ b/python/amici/conserved_moieties.py @@ -740,6 +740,8 @@ def _relax( if not len(matrix[j]) or matrix[j][0] != matrix[k][i]: continue + # subtract rows + # matrix2[k] = matrix2[k] - matrix2[j] * matrix2[k][i] row_k: List[float] = [0] * num_reactions for a in range(len(matrix[k])): row_k[matrix[k][a]] = matrix2[k][a] @@ -749,6 +751,9 @@ def _relax( matrix[k] = [row_idx for row_idx, row_val in enumerate(row_k) if row_val != 0] matrix2[k] = [row_val for row_val in row_k if row_val != 0] + + if len(matrix[k]) <= i: + break i += 1 indip = [K + 1] * num_reactions From 3c6bd41e3fbf0e9eceb047d780106f0bf5327609 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Tue, 1 Mar 2022 10:40:47 +0100 Subject: [PATCH 15/45] SBML import: Raise in case of nested observables (#1690) Closes #1689 --- python/amici/sbml_import.py | 14 ++++++++++++++ python/tests/test_sbml_import.py | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/python/amici/sbml_import.py b/python/amici/sbml_import.py index 5f564d907e..c4f713d11c 100644 --- a/python/amici/sbml_import.py +++ b/python/amici/sbml_import.py @@ -1229,6 +1229,20 @@ def _process_observables( } for iobs, (obs, definition) in enumerate(observables.items()) } + # check for nesting of observables (unsupported) + # performing string-based check, because lhs symbols are `real`, + # whereas rhs symbols are not. + observable_syms = { + str(obs) for obs in self.symbols[SymbolId.OBSERVABLE].keys() + } + for obs in self.symbols[SymbolId.OBSERVABLE].values(): + if any(str(sym) in observable_syms + for sym in obs['value'].free_symbols): + raise ValueError( + "Nested observables are not supported, " + f"but observable `{obs['name']} = {obs['value']}` " + "references another observable." + ) elif observables is None: self._generate_default_observables() diff --git a/python/tests/test_sbml_import.py b/python/tests/test_sbml_import.py index ea624e51eb..3385a2cdcb 100644 --- a/python/tests/test_sbml_import.py +++ b/python/tests/test_sbml_import.py @@ -54,6 +54,25 @@ def test_sbml2amici_no_observables(simple_sbml_model): assert hasattr(module_module, 'getModel') +def test_sbml2amici_nested_observables_fail(simple_sbml_model): + """Test model generation works for model without observables""" + sbml_doc, sbml_model = simple_sbml_model + sbml_importer = SbmlImporter(sbml_source=sbml_model, + from_file=False) + + with TemporaryDirectory() as tmpdir: + with pytest.raises(ValueError, match="(?i)nested"): + sbml_importer.sbml2amici( + model_name="test", + output_dir=tmpdir, + observables={'outer': {'formula': 'inner'}, + 'inner': {'formula': 'S1'}}, + compute_conservation_laws=False, + generate_sensitivity_code=False, + compile=False, + ) + + def test_nosensi(simple_sbml_model): sbml_doc, sbml_model = simple_sbml_model sbml_importer = SbmlImporter(sbml_source=sbml_model, From 7168f56488c2d0441dc3b5e711418d6dfa64b2ad Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Fri, 4 Mar 2022 15:22:33 +0100 Subject: [PATCH 16/45] Add support for observable-dependent sigmas (#1692) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Standard deviations may now depend on observables. Side-effects: * `ssigmay` will not be available anymore with adjoint sensitivity analysis. * Observable IDs shadowing other model entities are no longer allowed Closes #609 Co-authored-by: Fabian Fröhlich --- documentation/INSTALL.md | 1 - ...steadystate_scaled_without_observables.xml | 1 + include/amici/abstract_model.h | 23 ++- include/amici/model.h | 11 ++ include/amici/model_state.h | 7 +- matlab/@amifun/getArgs.m | 4 +- models/model_calvetti/model_calvetti.h | 12 +- .../model_calvetti/model_calvetti_sigmay.cpp | 2 +- models/model_dirac/model_dirac.h | 12 +- models/model_dirac/model_dirac_sigmay.cpp | 2 +- models/model_events/model_events.h | 12 +- models/model_events/model_events_sigmay.cpp | 2 +- .../model_jakstat_adjoint.h | 16 +- .../model_jakstat_adjoint_dsigmaydp.cpp | 2 +- .../model_jakstat_adjoint_sigmay.cpp | 2 +- .../model_jakstat_adjoint_o2.h | 16 +- .../model_jakstat_adjoint_o2_dsigmaydp.cpp | 2 +- .../model_jakstat_adjoint_o2_sigmay.cpp | 2 +- .../model_nested_events/model_nested_events.h | 12 +- .../model_nested_events_sigmay.cpp | 2 +- models/model_neuron/model_neuron.h | 12 +- models/model_neuron/model_neuron_sigmay.cpp | 2 +- models/model_neuron_o2/model_neuron_o2.h | 12 +- .../model_neuron_o2_sigmay.cpp | 2 +- models/model_robertson/model_robertson.h | 12 +- .../model_robertson_sigmay.cpp | 2 +- models/model_steadystate/model_steadystate.h | 12 +- .../model_steadystate_sigmay.cpp | 2 +- python/amici/ode_export.py | 9 +- python/amici/sbml_import.py | 12 +- .../ExampleSteadystate.ipynb | 6 +- ...steadystate_scaled_without_observables.xml | 153 ++++++++++++++++++ python/tests/test_sbml_import.py | 55 +++++++ src/abstract_model.cpp | 17 +- src/model.cpp | 84 +++++++++- src/model_header.ODE_template.h | 3 + src/rdata.cpp | 14 +- src/returndata_matlab.cpp | 2 +- tests/cpp/expectedResults.h5 | Bin 4198368 -> 4198368 bytes 39 files changed, 448 insertions(+), 106 deletions(-) delete mode 120000 documentation/INSTALL.md create mode 120000 documentation/model_steadystate_scaled_without_observables.xml create mode 100644 python/examples/example_steadystate/model_steadystate_scaled_without_observables.xml diff --git a/documentation/INSTALL.md b/documentation/INSTALL.md deleted file mode 120000 index 71db8b4934..0000000000 --- a/documentation/INSTALL.md +++ /dev/null @@ -1 +0,0 @@ -../INSTALL.md \ No newline at end of file diff --git a/documentation/model_steadystate_scaled_without_observables.xml b/documentation/model_steadystate_scaled_without_observables.xml new file mode 120000 index 0000000000..be8991d93e --- /dev/null +++ b/documentation/model_steadystate_scaled_without_observables.xml @@ -0,0 +1 @@ +../python/examples/example_steadystate/model_steadystate_scaled_without_observables.xml \ No newline at end of file diff --git a/include/amici/abstract_model.h b/include/amici/abstract_model.h index 4ddacdb26b..d333fab1d0 100644 --- a/include/amici/abstract_model.h +++ b/include/amici/abstract_model.h @@ -561,20 +561,37 @@ class AbstractModel { * @param t current time * @param p parameter vector * @param k constant vector + * @param y model output at timepoint t */ virtual void fsigmay(realtype *sigmay, const realtype t, const realtype *p, - const realtype *k); + const realtype *k, const realtype *y); /** - * @brief Model-specific implementation of fsigmay + * @brief Model-specific implementation of fdsigmaydp * @param dsigmaydp partial derivative of standard deviation of measurements * @param t current time * @param p parameter vector * @param k constant vector + * @param y model output at timepoint t * @param ip sensitivity index */ virtual void fdsigmaydp(realtype *dsigmaydp, const realtype t, - const realtype *p, const realtype *k, int ip); + const realtype *p, const realtype *k, + const realtype *y, int ip); + /** + * @brief Model-specific implementation of fsigmay + * @param dsigmaydy partial derivative of standard deviation of measurements + * w.r.t. model outputs + * @param t current time + * @param p parameter vector + * @param k constant vector + * @param y model output at timepoint t + * @param ip sensitivity index + */ + virtual void fdsigmaydy(realtype *dsigmaydy, const realtype t, + const realtype *p, const realtype *k, + const realtype *y, int ip); + /** * @brief Model-specific implementation of fsigmaz diff --git a/include/amici/model.h b/include/amici/model.h index b9e8fb7b8a..18e5928be3 100644 --- a/include/amici/model.h +++ b/include/amici/model.h @@ -115,6 +115,7 @@ class Model : public AbstractModel, public ModelDimensions { using AbstractModel::fdrzdp; using AbstractModel::fdrzdx; using AbstractModel::fdsigmaydp; + using AbstractModel::fdsigmaydy; using AbstractModel::fdsigmazdp; using AbstractModel::fdwdp; using AbstractModel::fdwdp_colptrs; @@ -851,11 +852,13 @@ class Model : public AbstractModel, public ModelDimensions { * Total derivative (can be used with both adjoint and forward sensitivity). * * @param ssigmay Buffer (shape `ny` x `nplist`, row-major) + * @param sy Sensitivity of time-resolved observables for current timepoint * @param it Timepoint index * @param edata Pointer to experimental data instance (optional, pass * `nullptr` to ignore) */ void getObservableSigmaSensitivity(gsl::span ssigmay, + gsl::span sy, const int it, const ExpData *edata); /** @@ -1396,6 +1399,14 @@ class Model : public AbstractModel, public ModelDimensions { */ void fdsigmaydp(int it, const ExpData *edata); + /** + * @brief Compute partial derivative of standard deviation of measurements + * w.r.t. model outputs. + * @param it Timepoint index + * @param edata pointer to `amici::ExpData` data instance holding sigma values + */ + void fdsigmaydy(int it, const ExpData *edata); + /** * @brief Compute negative log-likelihood of measurements \f$ y \f$. * diff --git a/include/amici/model_state.h b/include/amici/model_state.h index 578835283a..60b91f2ea9 100644 --- a/include/amici/model_state.h +++ b/include/amici/model_state.h @@ -228,11 +228,16 @@ struct ModelStateDerived { /** data standard deviation for current timepoint (dimension: ny) */ std::vector sigmay_; - /** temporary storage for parameter derivative of data standard deviation, + /** temporary storage for parameter derivative of data standard deviation, * (dimension: ny x nplist, row-major) */ std::vector dsigmaydp_; + /** temporary storage for observable derivative of data standard deviation, + * (dimension: ny x ny, row-major) + */ + std::vector dsigmaydy_; + /** temporary storage for event-resolved observable (dimension: nz) */ std::vector z_; diff --git a/matlab/@amifun/getArgs.m b/matlab/@amifun/getArgs.m index a8e3b69c9c..e59c10173c 100644 --- a/matlab/@amifun/getArgs.m +++ b/matlab/@amifun/getArgs.m @@ -80,9 +80,9 @@ case 'dxdotdp' this.argstr = ['(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip' dx ', const realtype *w, const realtype *dwdp)']; case 'sigma_y' - this.argstr = '(double *sigmay, const realtype t, const realtype *p, const realtype *k)'; + this.argstr = '(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y)'; case 'dsigma_ydp' - this.argstr = '(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip)'; + this.argstr = '(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip)'; case 'sigma_z' this.argstr = '(double *sigmaz, const realtype t, const realtype *p, const realtype *k)'; case 'dsigma_zdp' diff --git a/models/model_calvetti/model_calvetti.h b/models/model_calvetti/model_calvetti.h index 52675c57ac..41fe28a957 100644 --- a/models/model_calvetti/model_calvetti.h +++ b/models/model_calvetti/model_calvetti.h @@ -1,6 +1,6 @@ #ifndef _amici_model_calvetti_h #define _amici_model_calvetti_h -/* Generated by amiwrap (R2017b) 9212bbdaf5712727ff284cc475f16d2a983f9bf2 */ +/* Generated by amiwrap (R2017b) e8e46ac8ec0c895549703eace15f2135fdb1747b */ #include #include #include "amici/defines.h" @@ -22,7 +22,7 @@ extern void dJydy_model_calvetti(double *dJydy, const int iy, const realtype *p, extern void dwdx_model_calvetti(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl); extern void dydx_model_calvetti(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); extern void root_model_calvetti(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *dx); -extern void sigmay_model_calvetti(double *sigmay, const realtype t, const realtype *p, const realtype *k); +extern void sigmay_model_calvetti(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y); extern void w_model_calvetti(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); extern void x0_model_calvetti(realtype *x0, const realtype t, const realtype *p, const realtype *k); extern void xdot_model_calvetti(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *dx, const realtype *w); @@ -67,7 +67,7 @@ class Model_model_calvetti : public amici::Model_DAE { amici::Model* clone() const override { return new Model_model_calvetti(*this); }; - std::string getAmiciCommit() const override { return "9212bbdaf5712727ff284cc475f16d2a983f9bf2"; }; + std::string getAmiciCommit() const override { return "e8e46ac8ec0c895549703eace15f2135fdb1747b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype cj, const realtype *dx, const realtype *w, const realtype *dwdx) override { JSparse_model_calvetti(JSparse, t, x, p, k, h, cj, dx, w, dwdx); @@ -125,7 +125,7 @@ class Model_model_calvetti : public amici::Model_DAE { void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) override { } void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { @@ -161,8 +161,8 @@ class Model_model_calvetti : public amici::Model_DAE { void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { - sigmay_model_calvetti(sigmay, t, p, k); + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) override { + sigmay_model_calvetti(sigmay, t, p, k, y); } void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { diff --git a/models/model_calvetti/model_calvetti_sigmay.cpp b/models/model_calvetti/model_calvetti_sigmay.cpp index a970a9b280..690d1a01a9 100644 --- a/models/model_calvetti/model_calvetti_sigmay.cpp +++ b/models/model_calvetti/model_calvetti_sigmay.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_calvetti{ -void sigmay_model_calvetti(double *sigmay, const realtype t, const realtype *p, const realtype *k) { +void sigmay_model_calvetti(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) { sigmay[0] = 1.0; sigmay[1] = 1.0; sigmay[2] = 1.0; diff --git a/models/model_dirac/model_dirac.h b/models/model_dirac/model_dirac.h index 03639ddef6..a379b3ea24 100644 --- a/models/model_dirac/model_dirac.h +++ b/models/model_dirac/model_dirac.h @@ -1,6 +1,6 @@ #ifndef _amici_model_dirac_h #define _amici_model_dirac_h -/* Generated by amiwrap (R2017b) 9212bbdaf5712727ff284cc475f16d2a983f9bf2 */ +/* Generated by amiwrap (R2017b) e8e46ac8ec0c895549703eace15f2135fdb1747b */ #include #include #include "amici/defines.h" @@ -23,7 +23,7 @@ extern void deltax_model_dirac(double *deltax, const realtype t, const realtype extern void dxdotdp_model_dirac(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydx_model_dirac(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); extern void root_model_dirac(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); -extern void sigmay_model_dirac(double *sigmay, const realtype t, const realtype *p, const realtype *k); +extern void sigmay_model_dirac(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y); extern void stau_model_dirac(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie); extern void xdot_model_dirac(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w); extern void y_model_dirac(double *y, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w); @@ -67,7 +67,7 @@ class Model_model_dirac : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_dirac(*this); }; - std::string getAmiciCommit() const override { return "9212bbdaf5712727ff284cc475f16d2a983f9bf2"; }; + std::string getAmiciCommit() const override { return "e8e46ac8ec0c895549703eace15f2135fdb1747b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_dirac(JSparse, t, x, p, k, h, w, dwdx); @@ -123,7 +123,7 @@ class Model_model_dirac : public amici::Model_ODE { void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) override { } void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { @@ -159,8 +159,8 @@ class Model_model_dirac : public amici::Model_ODE { void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { - sigmay_model_dirac(sigmay, t, p, k); + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) override { + sigmay_model_dirac(sigmay, t, p, k, y); } void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { diff --git a/models/model_dirac/model_dirac_sigmay.cpp b/models/model_dirac/model_dirac_sigmay.cpp index 97538bff2a..9b5782f79f 100644 --- a/models/model_dirac/model_dirac_sigmay.cpp +++ b/models/model_dirac/model_dirac_sigmay.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_dirac{ -void sigmay_model_dirac(double *sigmay, const realtype t, const realtype *p, const realtype *k) { +void sigmay_model_dirac(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) { sigmay[0] = 1.0; } diff --git a/models/model_events/model_events.h b/models/model_events/model_events.h index 2dc99f9399..c83b1dbe62 100644 --- a/models/model_events/model_events.h +++ b/models/model_events/model_events.h @@ -1,6 +1,6 @@ #ifndef _amici_model_events_h #define _amici_model_events_h -/* Generated by amiwrap (R2017b) 9212bbdaf5712727ff284cc475f16d2a983f9bf2 */ +/* Generated by amiwrap (R2017b) e8e46ac8ec0c895549703eace15f2135fdb1747b */ #include #include #include "amici/defines.h" @@ -32,7 +32,7 @@ extern void dydx_model_events(double *dydx, const realtype t, const realtype *x, extern void dzdx_model_events(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); extern void root_model_events(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); extern void rz_model_events(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); -extern void sigmay_model_events(double *sigmay, const realtype t, const realtype *p, const realtype *k); +extern void sigmay_model_events(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y); extern void sigmaz_model_events(double *sigmaz, const realtype t, const realtype *p, const realtype *k); extern void srz_model_events(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip); extern void stau_model_events(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie); @@ -81,7 +81,7 @@ class Model_model_events : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_events(*this); }; - std::string getAmiciCommit() const override { return "9212bbdaf5712727ff284cc475f16d2a983f9bf2"; }; + std::string getAmiciCommit() const override { return "e8e46ac8ec0c895549703eace15f2135fdb1747b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_events(JSparse, t, x, p, k, h, w, dwdx); @@ -143,7 +143,7 @@ class Model_model_events : public amici::Model_ODE { drzdx_model_events(drzdx, ie, t, x, p, k, h); } - void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) override { } void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { @@ -182,8 +182,8 @@ class Model_model_events : public amici::Model_ODE { rz_model_events(rz, ie, t, x, p, k, h); } - void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { - sigmay_model_events(sigmay, t, p, k); + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) override { + sigmay_model_events(sigmay, t, p, k, y); } void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { diff --git a/models/model_events/model_events_sigmay.cpp b/models/model_events/model_events_sigmay.cpp index 42fac3dfbf..87bd4ffb30 100644 --- a/models/model_events/model_events_sigmay.cpp +++ b/models/model_events/model_events_sigmay.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_events{ -void sigmay_model_events(double *sigmay, const realtype t, const realtype *p, const realtype *k) { +void sigmay_model_events(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) { sigmay[0] = 1.0; } diff --git a/models/model_jakstat_adjoint/model_jakstat_adjoint.h b/models/model_jakstat_adjoint/model_jakstat_adjoint.h index 69bd1eadc2..5ec0de560d 100644 --- a/models/model_jakstat_adjoint/model_jakstat_adjoint.h +++ b/models/model_jakstat_adjoint/model_jakstat_adjoint.h @@ -1,6 +1,6 @@ #ifndef _amici_model_jakstat_adjoint_h #define _amici_model_jakstat_adjoint_h -/* Generated by amiwrap (R2017b) 9212bbdaf5712727ff284cc475f16d2a983f9bf2 */ +/* Generated by amiwrap (R2017b) e8e46ac8ec0c895549703eace15f2135fdb1747b */ #include #include #include "amici/defines.h" @@ -18,13 +18,13 @@ extern void JSparse_model_jakstat_adjoint(SUNMatrixContent_Sparse JSparse, const extern void Jy_model_jakstat_adjoint(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); extern void dJydsigma_model_jakstat_adjoint(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); extern void dJydy_model_jakstat_adjoint(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); -extern void dsigmaydp_model_jakstat_adjoint(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip); +extern void dsigmaydp_model_jakstat_adjoint(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip); extern void dwdp_model_jakstat_adjoint(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl); extern void dwdx_model_jakstat_adjoint(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl); extern void dxdotdp_model_jakstat_adjoint(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydp_model_jakstat_adjoint(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydx_model_jakstat_adjoint(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); -extern void sigmay_model_jakstat_adjoint(double *sigmay, const realtype t, const realtype *p, const realtype *k); +extern void sigmay_model_jakstat_adjoint(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y); extern void sx0_model_jakstat_adjoint(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip); extern void w_model_jakstat_adjoint(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); extern void x0_model_jakstat_adjoint(realtype *x0, const realtype t, const realtype *p, const realtype *k); @@ -70,7 +70,7 @@ class Model_model_jakstat_adjoint : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_jakstat_adjoint(*this); }; - std::string getAmiciCommit() const override { return "9212bbdaf5712727ff284cc475f16d2a983f9bf2"; }; + std::string getAmiciCommit() const override { return "e8e46ac8ec0c895549703eace15f2135fdb1747b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_jakstat_adjoint(JSparse, t, x, p, k, h, w, dwdx); @@ -124,8 +124,8 @@ class Model_model_jakstat_adjoint : public amici::Model_ODE { void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { - dsigmaydp_model_jakstat_adjoint(dsigmaydp, t, p, k, ip); + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) override { + dsigmaydp_model_jakstat_adjoint(dsigmaydp, t, p, k, y, ip); } void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { @@ -163,8 +163,8 @@ class Model_model_jakstat_adjoint : public amici::Model_ODE { void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { - sigmay_model_jakstat_adjoint(sigmay, t, p, k); + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) override { + sigmay_model_jakstat_adjoint(sigmay, t, p, k, y); } void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { diff --git a/models/model_jakstat_adjoint/model_jakstat_adjoint_dsigmaydp.cpp b/models/model_jakstat_adjoint/model_jakstat_adjoint_dsigmaydp.cpp index 38045122ba..7313fb731b 100644 --- a/models/model_jakstat_adjoint/model_jakstat_adjoint_dsigmaydp.cpp +++ b/models/model_jakstat_adjoint/model_jakstat_adjoint_dsigmaydp.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_jakstat_adjoint{ -void dsigmaydp_model_jakstat_adjoint(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) { +void dsigmaydp_model_jakstat_adjoint(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) { switch (ip) { case 14: { dsigmaydp[0] = 1.0; diff --git a/models/model_jakstat_adjoint/model_jakstat_adjoint_sigmay.cpp b/models/model_jakstat_adjoint/model_jakstat_adjoint_sigmay.cpp index 18172dff23..99dd28dff6 100644 --- a/models/model_jakstat_adjoint/model_jakstat_adjoint_sigmay.cpp +++ b/models/model_jakstat_adjoint/model_jakstat_adjoint_sigmay.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_jakstat_adjoint{ -void sigmay_model_jakstat_adjoint(double *sigmay, const realtype t, const realtype *p, const realtype *k) { +void sigmay_model_jakstat_adjoint(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) { sigmay[0] = p[14]; sigmay[1] = p[15]; sigmay[2] = p[16]; diff --git a/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h b/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h index 142c8ae8c6..d8a0167aad 100644 --- a/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h +++ b/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h @@ -1,6 +1,6 @@ #ifndef _amici_model_jakstat_adjoint_o2_h #define _amici_model_jakstat_adjoint_o2_h -/* Generated by amiwrap (R2017b) 9212bbdaf5712727ff284cc475f16d2a983f9bf2 */ +/* Generated by amiwrap (R2017b) e8e46ac8ec0c895549703eace15f2135fdb1747b */ #include #include #include "amici/defines.h" @@ -18,13 +18,13 @@ extern void JSparse_model_jakstat_adjoint_o2(SUNMatrixContent_Sparse JSparse, co extern void Jy_model_jakstat_adjoint_o2(double *nllh, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); extern void dJydsigma_model_jakstat_adjoint_o2(double *dJydsigma, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); extern void dJydy_model_jakstat_adjoint_o2(double *dJydy, const int iy, const realtype *p, const realtype *k, const double *y, const double *sigmay, const double *my); -extern void dsigmaydp_model_jakstat_adjoint_o2(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip); +extern void dsigmaydp_model_jakstat_adjoint_o2(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip); extern void dwdp_model_jakstat_adjoint_o2(realtype *dwdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl, const realtype *stcl); extern void dwdx_model_jakstat_adjoint_o2(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl); extern void dxdotdp_model_jakstat_adjoint_o2(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydp_model_jakstat_adjoint_o2(double *dydp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydx_model_jakstat_adjoint_o2(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); -extern void sigmay_model_jakstat_adjoint_o2(double *sigmay, const realtype t, const realtype *p, const realtype *k); +extern void sigmay_model_jakstat_adjoint_o2(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y); extern void sx0_model_jakstat_adjoint_o2(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip); extern void w_model_jakstat_adjoint_o2(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); extern void x0_model_jakstat_adjoint_o2(realtype *x0, const realtype t, const realtype *p, const realtype *k); @@ -70,7 +70,7 @@ class Model_model_jakstat_adjoint_o2 : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_jakstat_adjoint_o2(*this); }; - std::string getAmiciCommit() const override { return "9212bbdaf5712727ff284cc475f16d2a983f9bf2"; }; + std::string getAmiciCommit() const override { return "e8e46ac8ec0c895549703eace15f2135fdb1747b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_jakstat_adjoint_o2(JSparse, t, x, p, k, h, w, dwdx); @@ -124,8 +124,8 @@ class Model_model_jakstat_adjoint_o2 : public amici::Model_ODE { void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { - dsigmaydp_model_jakstat_adjoint_o2(dsigmaydp, t, p, k, ip); + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) override { + dsigmaydp_model_jakstat_adjoint_o2(dsigmaydp, t, p, k, y, ip); } void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { @@ -163,8 +163,8 @@ class Model_model_jakstat_adjoint_o2 : public amici::Model_ODE { void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { - sigmay_model_jakstat_adjoint_o2(sigmay, t, p, k); + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) override { + sigmay_model_jakstat_adjoint_o2(sigmay, t, p, k, y); } void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { diff --git a/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2_dsigmaydp.cpp b/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2_dsigmaydp.cpp index 7ebea670ba..ac9cb8730d 100644 --- a/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2_dsigmaydp.cpp +++ b/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2_dsigmaydp.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_jakstat_adjoint_o2{ -void dsigmaydp_model_jakstat_adjoint_o2(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) { +void dsigmaydp_model_jakstat_adjoint_o2(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) { switch (ip) { case 14: { dsigmaydp[0] = 1.0; diff --git a/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2_sigmay.cpp b/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2_sigmay.cpp index 26120455ae..6b162c6f03 100644 --- a/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2_sigmay.cpp +++ b/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2_sigmay.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_jakstat_adjoint_o2{ -void sigmay_model_jakstat_adjoint_o2(double *sigmay, const realtype t, const realtype *p, const realtype *k) { +void sigmay_model_jakstat_adjoint_o2(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) { sigmay[0] = p[14]; sigmay[1] = p[15]; sigmay[2] = p[16]; diff --git a/models/model_nested_events/model_nested_events.h b/models/model_nested_events/model_nested_events.h index fcf703b914..bcc1969455 100644 --- a/models/model_nested_events/model_nested_events.h +++ b/models/model_nested_events/model_nested_events.h @@ -1,6 +1,6 @@ #ifndef _amici_model_nested_events_h #define _amici_model_nested_events_h -/* Generated by amiwrap (R2017b) 9212bbdaf5712727ff284cc475f16d2a983f9bf2 */ +/* Generated by amiwrap (R2017b) e8e46ac8ec0c895549703eace15f2135fdb1747b */ #include #include #include "amici/defines.h" @@ -24,7 +24,7 @@ extern void deltax_model_nested_events(double *deltax, const realtype t, const r extern void dxdotdp_model_nested_events(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydx_model_nested_events(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); extern void root_model_nested_events(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); -extern void sigmay_model_nested_events(double *sigmay, const realtype t, const realtype *p, const realtype *k); +extern void sigmay_model_nested_events(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y); extern void stau_model_nested_events(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie); extern void sx0_model_nested_events(realtype *sx0, const realtype t,const realtype *x0, const realtype *p, const realtype *k, const int ip); extern void x0_model_nested_events(realtype *x0, const realtype t, const realtype *p, const realtype *k); @@ -70,7 +70,7 @@ class Model_model_nested_events : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_nested_events(*this); }; - std::string getAmiciCommit() const override { return "9212bbdaf5712727ff284cc475f16d2a983f9bf2"; }; + std::string getAmiciCommit() const override { return "e8e46ac8ec0c895549703eace15f2135fdb1747b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_nested_events(JSparse, t, x, p, k, h, w, dwdx); @@ -127,7 +127,7 @@ class Model_model_nested_events : public amici::Model_ODE { void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) override { } void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { @@ -163,8 +163,8 @@ class Model_model_nested_events : public amici::Model_ODE { void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { - sigmay_model_nested_events(sigmay, t, p, k); + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) override { + sigmay_model_nested_events(sigmay, t, p, k, y); } void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { diff --git a/models/model_nested_events/model_nested_events_sigmay.cpp b/models/model_nested_events/model_nested_events_sigmay.cpp index 4852d83e1f..0f928ca69a 100644 --- a/models/model_nested_events/model_nested_events_sigmay.cpp +++ b/models/model_nested_events/model_nested_events_sigmay.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_nested_events{ -void sigmay_model_nested_events(double *sigmay, const realtype t, const realtype *p, const realtype *k) { +void sigmay_model_nested_events(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) { sigmay[0] = 1.0; } diff --git a/models/model_neuron/model_neuron.h b/models/model_neuron/model_neuron.h index aacdef0da6..d32f24c4fd 100644 --- a/models/model_neuron/model_neuron.h +++ b/models/model_neuron/model_neuron.h @@ -1,6 +1,6 @@ #ifndef _amici_model_neuron_h #define _amici_model_neuron_h -/* Generated by amiwrap (R2017b) 9212bbdaf5712727ff284cc475f16d2a983f9bf2 */ +/* Generated by amiwrap (R2017b) e8e46ac8ec0c895549703eace15f2135fdb1747b */ #include #include #include "amici/defines.h" @@ -34,7 +34,7 @@ extern void dydx_model_neuron(double *dydx, const realtype t, const realtype *x, extern void dzdx_model_neuron(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); extern void root_model_neuron(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); extern void rz_model_neuron(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); -extern void sigmay_model_neuron(double *sigmay, const realtype t, const realtype *p, const realtype *k); +extern void sigmay_model_neuron(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y); extern void sigmaz_model_neuron(double *sigmaz, const realtype t, const realtype *p, const realtype *k); extern void srz_model_neuron(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip); extern void stau_model_neuron(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie); @@ -84,7 +84,7 @@ class Model_model_neuron : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_neuron(*this); }; - std::string getAmiciCommit() const override { return "9212bbdaf5712727ff284cc475f16d2a983f9bf2"; }; + std::string getAmiciCommit() const override { return "e8e46ac8ec0c895549703eace15f2135fdb1747b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_neuron(JSparse, t, x, p, k, h, w, dwdx); @@ -149,7 +149,7 @@ class Model_model_neuron : public amici::Model_ODE { drzdx_model_neuron(drzdx, ie, t, x, p, k, h); } - void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) override { } void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { @@ -187,8 +187,8 @@ class Model_model_neuron : public amici::Model_ODE { rz_model_neuron(rz, ie, t, x, p, k, h); } - void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { - sigmay_model_neuron(sigmay, t, p, k); + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) override { + sigmay_model_neuron(sigmay, t, p, k, y); } void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { diff --git a/models/model_neuron/model_neuron_sigmay.cpp b/models/model_neuron/model_neuron_sigmay.cpp index 092c626156..8bc0d292f8 100644 --- a/models/model_neuron/model_neuron_sigmay.cpp +++ b/models/model_neuron/model_neuron_sigmay.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_neuron{ -void sigmay_model_neuron(double *sigmay, const realtype t, const realtype *p, const realtype *k) { +void sigmay_model_neuron(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) { sigmay[0] = 1.0; } diff --git a/models/model_neuron_o2/model_neuron_o2.h b/models/model_neuron_o2/model_neuron_o2.h index 8fb9ce900e..c3879526c3 100644 --- a/models/model_neuron_o2/model_neuron_o2.h +++ b/models/model_neuron_o2/model_neuron_o2.h @@ -1,6 +1,6 @@ #ifndef _amici_model_neuron_o2_h #define _amici_model_neuron_o2_h -/* Generated by amiwrap (R2017b) 9212bbdaf5712727ff284cc475f16d2a983f9bf2 */ +/* Generated by amiwrap (R2017b) e8e46ac8ec0c895549703eace15f2135fdb1747b */ #include #include #include "amici/defines.h" @@ -35,7 +35,7 @@ extern void dydx_model_neuron_o2(double *dydx, const realtype t, const realtype extern void dzdx_model_neuron_o2(double *dzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); extern void root_model_neuron_o2(realtype *root, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); extern void rz_model_neuron_o2(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h); -extern void sigmay_model_neuron_o2(double *sigmay, const realtype t, const realtype *p, const realtype *k); +extern void sigmay_model_neuron_o2(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y); extern void sigmaz_model_neuron_o2(double *sigmaz, const realtype t, const realtype *p, const realtype *k); extern void srz_model_neuron_o2(double *srz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *sx, const int ip); extern void stau_model_neuron_o2(double *stau, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl, const realtype *sx, const int ip, const int ie); @@ -86,7 +86,7 @@ class Model_model_neuron_o2 : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_neuron_o2(*this); }; - std::string getAmiciCommit() const override { return "9212bbdaf5712727ff284cc475f16d2a983f9bf2"; }; + std::string getAmiciCommit() const override { return "e8e46ac8ec0c895549703eace15f2135fdb1747b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_neuron_o2(JSparse, t, x, p, k, h, w, dwdx); @@ -151,7 +151,7 @@ class Model_model_neuron_o2 : public amici::Model_ODE { drzdx_model_neuron_o2(drzdx, ie, t, x, p, k, h); } - void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) override { } void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { @@ -190,8 +190,8 @@ class Model_model_neuron_o2 : public amici::Model_ODE { rz_model_neuron_o2(rz, ie, t, x, p, k, h); } - void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { - sigmay_model_neuron_o2(sigmay, t, p, k); + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) override { + sigmay_model_neuron_o2(sigmay, t, p, k, y); } void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { diff --git a/models/model_neuron_o2/model_neuron_o2_sigmay.cpp b/models/model_neuron_o2/model_neuron_o2_sigmay.cpp index 5938f5e08f..3e5743cb70 100644 --- a/models/model_neuron_o2/model_neuron_o2_sigmay.cpp +++ b/models/model_neuron_o2/model_neuron_o2_sigmay.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_neuron_o2{ -void sigmay_model_neuron_o2(double *sigmay, const realtype t, const realtype *p, const realtype *k) { +void sigmay_model_neuron_o2(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) { sigmay[0] = 1.0; } diff --git a/models/model_robertson/model_robertson.h b/models/model_robertson/model_robertson.h index 041e793d0a..7e0756ffef 100644 --- a/models/model_robertson/model_robertson.h +++ b/models/model_robertson/model_robertson.h @@ -1,6 +1,6 @@ #ifndef _amici_model_robertson_h #define _amici_model_robertson_h -/* Generated by amiwrap (R2017b) 9212bbdaf5712727ff284cc475f16d2a983f9bf2 */ +/* Generated by amiwrap (R2017b) e8e46ac8ec0c895549703eace15f2135fdb1747b */ #include #include #include "amici/defines.h" @@ -23,7 +23,7 @@ extern void dwdp_model_robertson(realtype *dwdp, const realtype t, const realtyp extern void dwdx_model_robertson(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl); extern void dxdotdp_model_robertson(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *dx, const realtype *w, const realtype *dwdp); extern void dydx_model_robertson(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); -extern void sigmay_model_robertson(double *sigmay, const realtype t, const realtype *p, const realtype *k); +extern void sigmay_model_robertson(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y); extern void w_model_robertson(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); extern void x0_model_robertson(realtype *x0, const realtype t, const realtype *p, const realtype *k); extern void xdot_model_robertson(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *dx, const realtype *w); @@ -68,7 +68,7 @@ class Model_model_robertson : public amici::Model_DAE { amici::Model* clone() const override { return new Model_model_robertson(*this); }; - std::string getAmiciCommit() const override { return "9212bbdaf5712727ff284cc475f16d2a983f9bf2"; }; + std::string getAmiciCommit() const override { return "e8e46ac8ec0c895549703eace15f2135fdb1747b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype cj, const realtype *dx, const realtype *w, const realtype *dwdx) override { JSparse_model_robertson(JSparse, t, x, p, k, h, cj, dx, w, dwdx); @@ -126,7 +126,7 @@ class Model_model_robertson : public amici::Model_DAE { void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) override { } void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { @@ -163,8 +163,8 @@ class Model_model_robertson : public amici::Model_DAE { void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { - sigmay_model_robertson(sigmay, t, p, k); + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) override { + sigmay_model_robertson(sigmay, t, p, k, y); } void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { diff --git a/models/model_robertson/model_robertson_sigmay.cpp b/models/model_robertson/model_robertson_sigmay.cpp index 6e57e3c50f..9e1e5e019c 100644 --- a/models/model_robertson/model_robertson_sigmay.cpp +++ b/models/model_robertson/model_robertson_sigmay.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_robertson{ -void sigmay_model_robertson(double *sigmay, const realtype t, const realtype *p, const realtype *k) { +void sigmay_model_robertson(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) { sigmay[0] = 1.0; sigmay[1] = 1.0; sigmay[2] = 1.0; diff --git a/models/model_steadystate/model_steadystate.h b/models/model_steadystate/model_steadystate.h index f955d97c84..dfbddbd850 100644 --- a/models/model_steadystate/model_steadystate.h +++ b/models/model_steadystate/model_steadystate.h @@ -1,6 +1,6 @@ #ifndef _amici_model_steadystate_h #define _amici_model_steadystate_h -/* Generated by amiwrap (R2017b) 9212bbdaf5712727ff284cc475f16d2a983f9bf2 */ +/* Generated by amiwrap (R2017b) e8e46ac8ec0c895549703eace15f2135fdb1747b */ #include #include #include "amici/defines.h" @@ -22,7 +22,7 @@ extern void dwdp_model_steadystate(realtype *dwdp, const realtype t, const realt extern void dwdx_model_steadystate(realtype *dwdx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *tcl); extern void dxdotdp_model_steadystate(realtype *dxdotdp, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const int ip, const realtype *w, const realtype *dwdp); extern void dydx_model_steadystate(double *dydx, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx); -extern void sigmay_model_steadystate(double *sigmay, const realtype t, const realtype *p, const realtype *k); +extern void sigmay_model_steadystate(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y); extern void w_model_steadystate(realtype *w, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *tcl); extern void x0_model_steadystate(realtype *x0, const realtype t, const realtype *p, const realtype *k); extern void xdot_model_steadystate(realtype *xdot, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w); @@ -67,7 +67,7 @@ class Model_model_steadystate : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_steadystate(*this); }; - std::string getAmiciCommit() const override { return "9212bbdaf5712727ff284cc475f16d2a983f9bf2"; }; + std::string getAmiciCommit() const override { return "e8e46ac8ec0c895549703eace15f2135fdb1747b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_steadystate(JSparse, t, x, p, k, h, w, dwdx); @@ -121,7 +121,7 @@ class Model_model_steadystate : public amici::Model_ODE { void fdrzdx(double *drzdx, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const int ip) override { + void fdsigmaydp(double *dsigmaydp, const realtype t, const realtype *p, const realtype *k, const realtype *y, const int ip) override { } void fdsigmazdp(double *dsigmazdp, const realtype t, const realtype *p, const realtype *k, const int ip) override { @@ -158,8 +158,8 @@ class Model_model_steadystate : public amici::Model_ODE { void frz(double *rz, const int ie, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h) override { } - void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k) override { - sigmay_model_steadystate(sigmay, t, p, k); + void fsigmay(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) override { + sigmay_model_steadystate(sigmay, t, p, k, y); } void fsigmaz(double *sigmaz, const realtype t, const realtype *p, const realtype *k) override { diff --git a/models/model_steadystate/model_steadystate_sigmay.cpp b/models/model_steadystate/model_steadystate_sigmay.cpp index 8e9ebc4417..d895acd6ca 100644 --- a/models/model_steadystate/model_steadystate_sigmay.cpp +++ b/models/model_steadystate/model_steadystate_sigmay.cpp @@ -10,7 +10,7 @@ namespace amici { namespace model_model_steadystate{ -void sigmay_model_steadystate(double *sigmay, const realtype t, const realtype *p, const realtype *k) { +void sigmay_model_steadystate(double *sigmay, const realtype t, const realtype *p, const realtype *k, const realtype *y) { sigmay[0] = 1.0; sigmay[1] = 1.0; sigmay[2] = 1.0; diff --git a/python/amici/ode_export.py b/python/amici/ode_export.py index dd3e9d893a..863c9c9be3 100644 --- a/python/amici/ode_export.py +++ b/python/amici/ode_export.py @@ -169,15 +169,20 @@ class _FunctionInfo: 'const int ip, const realtype *w, const realtype *tcl, ' 'const realtype *dtcldp', ), + 'dsigmaydy': + _FunctionInfo( + 'realtype *dsigmaydy, const realtype t, const realtype *p, ' + 'const realtype *k, const realtype *y, const int ip', + ), 'dsigmaydp': _FunctionInfo( 'realtype *dsigmaydp, const realtype t, const realtype *p, ' - 'const realtype *k, const int ip', + 'const realtype *k, const realtype *y, const int ip', ), 'sigmay': _FunctionInfo( 'realtype *sigmay, const realtype t, const realtype *p, ' - 'const realtype *k', + 'const realtype *k, const realtype *y', ), 'sroot': _FunctionInfo( diff --git a/python/amici/sbml_import.py b/python/amici/sbml_import.py index c4f713d11c..45d8444d0f 100644 --- a/python/amici/sbml_import.py +++ b/python/amici/sbml_import.py @@ -1214,6 +1214,10 @@ def _process_observables( # add user-provided observables or make all species, and compartments # with assignment rules, observable if observables: + # gather local symbols before parsing observable and sigma formulas + for obs in observables.keys(): + self.add_local_symbol(obs, symbol_with_assumptions(obs)) + self.symbols[SymbolId.OBSERVABLE] = { symbol_with_assumptions(obs): { 'name': definition.get('name', f'y{iobs}'), @@ -1230,13 +1234,9 @@ def _process_observables( for iobs, (obs, definition) in enumerate(observables.items()) } # check for nesting of observables (unsupported) - # performing string-based check, because lhs symbols are `real`, - # whereas rhs symbols are not. - observable_syms = { - str(obs) for obs in self.symbols[SymbolId.OBSERVABLE].keys() - } + observable_syms = set(self.symbols[SymbolId.OBSERVABLE].keys()) for obs in self.symbols[SymbolId.OBSERVABLE].values(): - if any(str(sym) in observable_syms + if any(sym in observable_syms for sym in obs['value'].free_symbols): raise ValueError( "Nested observables are not supported, " diff --git a/python/examples/example_steadystate/ExampleSteadystate.ipynb b/python/examples/example_steadystate/ExampleSteadystate.ipynb index d1acfe687d..52f014dba8 100644 --- a/python/examples/example_steadystate/ExampleSteadystate.ipynb +++ b/python/examples/example_steadystate/ExampleSteadystate.ipynb @@ -16,7 +16,7 @@ "outputs": [], "source": [ "# SBML model we want to import\n", - "sbml_file = 'model_steadystate_scaled.xml'\n", + "sbml_file = 'model_steadystate_scaled_without_observables.xml'\n", "# Name of the model that will also be the name of the python module\n", "model_name = 'model_steadystate_scaled'\n", "# Directory to which the generated model code is written\n", @@ -133,7 +133,7 @@ "\n", "Specifying observables is beyond the scope of SBML. Here we define them manually.\n", "\n", - "If you are looking for a more scalable way for defining observables, then checkout [PEtab](https://github.com/PEtab-dev/PEtab). Another possibility is using SBML's [`AssignmentRule`s](http://sbml.org/Software/libSBML/5.13.0/docs//python-api/classlibsbml_1_1_rule.html) to specify model outputs within the SBML file." + "If you are looking for a more scalable way for defining observables, then checkout [PEtab](https://github.com/PEtab-dev/PEtab). Another possibility is using SBML's [`AssignmentRule`s](https://sbml.org/software/libsbml/5.18.0/docs/formatted/python-api/classlibsbml_1_1_assignment_rule.html) to specify model outputs within the SBML file." ] }, { @@ -1937,7 +1937,7 @@ ], "source": [ "# look at the States in rdata as DataFrame\n", - "amici.getSimulationStatesAsDataFrame(model, [edata], [rdata])" + "amici.getSimulationStatesAsDataFrame(model, [edata], [rdata])\n" ] } ], diff --git a/python/examples/example_steadystate/model_steadystate_scaled_without_observables.xml b/python/examples/example_steadystate/model_steadystate_scaled_without_observables.xml new file mode 100644 index 0000000000..62c673e513 --- /dev/null +++ b/python/examples/example_steadystate/model_steadystate_scaled_without_observables.xml @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + p1 + + + x1 + 2 + + + + + + + + + + + + + + + + + + p2 + x1 + x2 + + + + + + + + + + + + + + + + p3 + x2 + + + + + + + + + + + + + + + + + p4 + x3 + + + + + + + + + + + + + k0 + x3 + + + + + + + + + + + p5 + + + + + + + diff --git a/python/tests/test_sbml_import.py b/python/tests/test_sbml_import.py index 3385a2cdcb..4637e149ad 100644 --- a/python/tests/test_sbml_import.py +++ b/python/tests/test_sbml_import.py @@ -97,6 +97,61 @@ def test_nosensi(simple_sbml_model): assert rdata.status == amici.AMICI_ERROR +@pytest.fixture +def observable_dependent_error_model(simple_sbml_model): + sbml_doc, sbml_model = simple_sbml_model + # add parameter and rate rule + sbml_model.getSpecies("S1").setInitialConcentration(1.0) + sbml_model.getParameter("p1").setValue(0.2) + rr = sbml_model.createRateRule() + rr.setVariable("S1") + rr.setMath(libsbml.parseL3Formula("p1")) + relative_sigma = sbml_model.createParameter() + relative_sigma.setId('relative_sigma') + relative_sigma.setValue(0.05) + + sbml_importer = SbmlImporter(sbml_source=sbml_model, + from_file=False) + + with TemporaryDirectory() as tmpdir: + sbml_importer.sbml2amici( + model_name="test", + output_dir=tmpdir, + observables={'observable_s1': {'formula': 'S1'}, + 'observable_s1_scaled': {'formula': '0.5 * S1'}}, + sigmas={'observable_s1': '0.1 + relative_sigma * observable_s1', + 'observable_s1_scaled': '0.02 * observable_s1_scaled'}, + ) + yield amici.import_model_module(module_name='test', + module_path=tmpdir) + + +def test_sbml2amici_observable_dependent_error(observable_dependent_error_model): + """Check gradients for model with observable-dependent error""" + model_module = observable_dependent_error_model + model = model_module.getModel() + model.setTimepoints(np.linspace(0, 60, 61)) + solver = model.getSolver() + + # generate artificial data + rdata = amici.runAmiciSimulation(model, solver) + assert np.allclose(rdata.sigmay[:, 0], 0.1 + 0.05 * rdata.y[:, 0]) + assert np.allclose(rdata.sigmay[:, 1], 0.02 * rdata.y[:, 1]) + edata = amici.ExpData(rdata, 1.0, 0.0) + edata.setObservedDataStdDev(np.nan) + + # check sensitivities + solver.setSensitivityOrder(amici.SensitivityOrder.first) + # FSA + solver.setSensitivityMethod(amici.SensitivityMethod.forward) + rdata = amici.runAmiciSimulation(model, solver, edata) + assert np.any(rdata.ssigmay != 0.0) + check_derivatives(model, solver, edata) + # ASA + solver.setSensitivityMethod(amici.SensitivityMethod.adjoint) + check_derivatives(model, solver, edata) + + @pytest.fixture def model_steadystate_module(): sbml_file = os.path.join(os.path.dirname(__file__), '..', diff --git a/src/abstract_model.cpp b/src/abstract_model.cpp index 486239e103..859b9d8424 100644 --- a/src/abstract_model.cpp +++ b/src/abstract_model.cpp @@ -339,7 +339,8 @@ void AbstractModel::fsigmay(realtype* /*sigmay*/, const realtype /*t*/, const realtype* /*p*/, - const realtype* /*k*/) + const realtype* /*k*/, + const realtype */*y*/) { throw AmiException("Requested functionality is not supported as %s is " "not implemented for this model!", @@ -351,6 +352,7 @@ AbstractModel::fdsigmaydp(realtype* /*dsigmaydp*/, const realtype /*t*/, const realtype* /*p*/, const realtype* /*k*/, + const realtype */*y*/, const int /*ip*/) { throw AmiException("Requested functionality is not supported as %s is " @@ -358,6 +360,19 @@ AbstractModel::fdsigmaydp(realtype* /*dsigmaydp*/, __func__); } +void +AbstractModel::fdsigmaydy(realtype */*dsigmaydy*/, + const realtype /*t*/, + const realtype */*p*/, + const realtype */*k*/, + const realtype */*y*/, + int /*ip*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + void AbstractModel::fsigmaz(realtype* /*sigmaz*/, const realtype /*t*/, diff --git a/src/model.cpp b/src/model.cpp index b2dc5fc008..2bb2dd6fbb 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -849,9 +849,29 @@ void Model::getObservableSigma(gsl::span sigmay, const int it, } void Model::getObservableSigmaSensitivity(gsl::span ssigmay, + gsl::span sy, const int it, const ExpData *edata) { fdsigmaydp(it, edata); writeSlice(derived_state_.dsigmaydp_, ssigmay); + + if(pythonGenerated) { + // ssigmay = dsigmaydy*(dydx_solver*sx+dydp)+dsigmaydp + // = dsigmaydy*sy+dsigmaydp + + fdsigmaydy(it, edata); + + // compute ssigmay = 1.0 * dsigmaydp + 1.0 * dsigmaydy * sy + // dsigmaydp C[ny,nplist] += dsigmaydy A[ny,ny] * sy B[ny,nplist] + // M N M K K N + // ldc lda ldb + amici_dgemm(BLASLayout::colMajor, BLASTranspose::noTrans, + BLASTranspose::noTrans, ny, nplist(), ny, 1.0, + derived_state_.dsigmaydy_.data(), ny, + sy.data(), ny, 1.0, ssigmay.data(), ny); + } + + if (always_check_finite_) + checkFinite(ssigmay, "ssigmay"); } void Model::addObservableObjective(realtype &Jy, const int it, @@ -1447,8 +1467,11 @@ void Model::fsigmay(const int it, const ExpData *edata) { derived_state_.sigmay_.assign(ny, 0.0); - fsigmay(derived_state_.sigmay_.data(), getTimepoint(it), state_.unscaledParameters.data(), - state_.fixedParameters.data()); + fsigmay(derived_state_.sigmay_.data(), + getTimepoint(it), + state_.unscaledParameters.data(), + state_.fixedParameters.data(), + derived_state_.y_.data()); if (edata) { auto sigmay_edata = edata->getObservedDataStdDevPtr(it); @@ -1481,6 +1504,7 @@ void Model::fdsigmaydp(const int it, const ExpData *edata) { fdsigmaydp(&derived_state_.dsigmaydp_.at(ip * ny), getTimepoint(it), state_.unscaledParameters.data(), state_.fixedParameters.data(), + derived_state_.y_.data(), plist(ip)); // sigmas in edata override model-sigma -> for those sigmas, set dsigmaydp @@ -1500,6 +1524,38 @@ void Model::fdsigmaydp(const int it, const ExpData *edata) { } } +void Model::fdsigmaydy(const int it, const ExpData *edata) { + if (!ny) + return; + + derived_state_.dsigmaydy_.assign(ny * nplist(), 0.0); + + for (int ip = 0; ip < nplist(); ip++) + // get dsigmaydy slice (ny) for current timepoint and parameter + fdsigmaydy(&derived_state_.dsigmaydy_.at(ip * ny), getTimepoint(it), + state_.unscaledParameters.data(), + state_.fixedParameters.data(), + derived_state_.y_.data(), + plist(ip)); + + // sigmas in edata override model-sigma -> for those sigmas, set dsigmaydy + // to zero + if (edata) { + for (int iy = 0; iy < nytrue; iy++) { + if (!edata->isSetObservedDataStdDev(it, iy)) + continue; + for (int ip = 0; ip < nplist(); ip++) { + derived_state_.dsigmaydy_.at(ip * ny + iy) = 0.0; + } + } + } + + if (always_check_finite_) { + app->checkFinite(derived_state_.dsigmaydy_, "dsigmaydy"); + } +} + + void Model::fdJydy(const int it, const AmiVector &x, const ExpData &edata) { if (!ny) return; @@ -1508,6 +1564,10 @@ void Model::fdJydy(const int it, const AmiVector &x, const ExpData &edata) { fsigmay(it, &edata); if (pythonGenerated) { + fdJydsigma(it, x, edata); + fdsigmaydy(it, &edata); + SUNMatrixWrapper tmp_dense(nJ, ny); + for (int iyt = 0; iyt < nytrue; iyt++) { if (!derived_state_.dJydy_.at(iyt).capacity()) continue; @@ -1524,6 +1584,25 @@ void Model::fdJydy(const int it, const AmiVector &x, const ExpData &edata) { derived_state_.sigmay_.data(), edata.getObservedDataPtr(it)); + // dJydy += dJydsigma * dsigmaydy + // C(nJ,ny) A(nJ,ny) * B(ny,ny) + // sparse dense dense + tmp_dense.zero(); + amici_dgemm(BLASLayout::colMajor, BLASTranspose::noTrans, + BLASTranspose::noTrans, nJ, ny, ny, 1.0, + &derived_state_.dJydsigma_.at(iyt * nJ * ny), nJ, + derived_state_.dsigmaydy_.data(), ny, 1.0, + tmp_dense.data(), nJ); + + auto tmp_sparse = SUNMatrixWrapper(tmp_dense, 0.0, CSC_MAT); + auto ret = SUNMatScaleAdd(1.0, derived_state_.dJydy_.at(iyt).get(), + tmp_sparse.get()); + if(ret != SUNMAT_SUCCESS) { + throw AmiException("SUNMatScaleAdd failed with status %d in %s", + ret, __func__); + } + derived_state_.dJydy_.at(iyt).refresh(); + if (always_check_finite_) { app->checkFinite( gsl::make_span(derived_state_.dJydy_.at(iyt).get()), @@ -1577,7 +1656,6 @@ void Model::fdJydp(const int it, const AmiVector &x, const ExpData &edata) { // dJydy nJ, nytrue x ny // dydp nplist * ny // dJydp nplist x nJ - // dJydsigma if (!ny) return; diff --git a/src/model_header.ODE_template.h b/src/model_header.ODE_template.h index bcf3c8feff..c253d79efc 100644 --- a/src/model_header.ODE_template.h +++ b/src/model_header.ODE_template.h @@ -56,6 +56,7 @@ TPL_DYDX_DEF TPL_DYDP_DEF TPL_SIGMAY_DEF TPL_DSIGMAYDP_DEF +TPL_DSIGMAYDY_DEF TPL_W_DEF TPL_X0_DEF TPL_X0_FIXEDPARAMETERS_DEF @@ -293,6 +294,8 @@ class Model_TPL_MODELNAME : public amici::Model_ODE { TPL_DSIGMAYDP_IMPL + TPL_DSIGMAYDY_IMPL + /** * @brief model specific implementation of fsigmaz * @param dsigmazdp partial derivative of standard deviation of event diff --git a/src/rdata.cpp b/src/rdata.cpp index 3eab8f5c13..00b08e7353 100644 --- a/src/rdata.cpp +++ b/src/rdata.cpp @@ -142,7 +142,6 @@ void ReturnData::initializeFullReporting(bool quadratic_llh) { srz.resize(nmaxevent * nz * nplist, 0.0); } - ssigmay.resize(nt * ny * nplist, 0.0); ssigmaz.resize(nmaxevent * nz * nplist, 0.0); if (sensi >= SensitivityOrder::second && sensi_meth == SensitivityMethod::forward) @@ -303,16 +302,17 @@ void ReturnData::getDataOutput(int it, Model &model, ExpData const *edata) { if (sensi >= SensitivityOrder::first && nplist > 0) { - if (!ssigmay.empty()) - model.getObservableSigmaSensitivity(slice(ssigmay, it, nplist * ny), - it, edata); - if (sensi_meth == SensitivityMethod::forward) { getDataSensisFSA(it, model, edata); } else if (edata && !sllh.empty()) { model.addPartialObservableObjectiveSensitivity( sllh, s2llh, it, x_solver_, *edata); } + + if (!ssigmay.empty()) + model.getObservableSigmaSensitivity(slice(ssigmay, it, nplist * ny), + slice(sy, it, nplist * ny), + it, edata); } } @@ -866,7 +866,7 @@ void ReturnData::fsres(const int it, Model &model, const ExpData &edata) { std::vector sigmay_it(ny, 0.0); model.getObservableSigma(sigmay_it, it, &edata); std::vector ssigmay_it(ny * nplist, 0.0); - model.getObservableSigmaSensitivity(ssigmay_it, it, &edata); + model.getObservableSigmaSensitivity(ssigmay_it, sy_it, it, &edata); auto observedData = edata.getObservedDataPtr(it); for (int iy = 0; iy < nytrue; ++iy) { @@ -904,7 +904,7 @@ void ReturnData::fFIM(int it, Model &model, const ExpData &edata) { std::vector sigmay_it(ny, 0.0); model.getObservableSigma(sigmay_it, it, &edata); std::vector ssigmay_it(ny * nplist, 0.0); - model.getObservableSigmaSensitivity(ssigmay_it, it, &edata); + model.getObservableSigmaSensitivity(ssigmay_it, sy_it, it, &edata); /* * https://www.wolframalpha.com/input/?i=d%2Fdu+d%2Fdv+log%28s%28u%2Cv%29%29+%2B+0.5+*+%28r%28u%2Cv%29%2Fs%28u%2Cv%29%29%5E2 diff --git a/src/returndata_matlab.cpp b/src/returndata_matlab.cpp index 0a1d79961a..739d23cfaf 100644 --- a/src/returndata_matlab.cpp +++ b/src/returndata_matlab.cpp @@ -82,7 +82,7 @@ mxArray *initMatlabReturnFields(ReturnData const *rdata) { } } - if (rdata->ny > 0) { + if (!rdata->ssigmay.empty()) { writeMatlabField3(matlabSolutionStruct, "ssigmay", rdata->ssigmay, rdata->nt, rdata->nplist, rdata->ny, perm2); } if ((rdata->nz > 0) & (rdata->ne > 0)) { diff --git a/tests/cpp/expectedResults.h5 b/tests/cpp/expectedResults.h5 index 3525c1b4b1f29ba0c7eef5de599bb5e865918c73..a24be851566e794a6dffd0f0564bed2660e06996 100644 GIT binary patch delta 377 zcmXZVIZnes6o6qRU>k!mge74O#y}Ew%)W(mT!4ZO$O$MCB#K0GVaaVGiYeo{0YXUQ zGPj_0gSY__9lsI9r;*-2PcP~D*#v%&39`XJF!-+BH8PsGZ)j3m$nCEj%SyJ?WY*XZ7E4?22v4v6C7{fSnn7|~aFpWG4n87UOFpmW+qKG9p yScZ!gtYQr%l#$+C#|AdBg>CF$7kluqj{_Xy2*)_VDb8??3tXa#E9J+vhudGk{-PxS delta 424 zcmXZWJ5R!J6vp9D?Y|T%)*E;OD=Hu=g5q6d^9wk*DSQG3FkyhCCMCEM6FWjT9W^Fp zbz^pM?PB~E#vjDt$r;Xj-W;!MN*+whXGzwWHU2K&RDHs}t;&wAe+vJY-jX}7(WjbR zcY8JY@{Q$BLO6EmH=s&c!Or&bLDlXgMdi_pt8OkOzOP6{8l*-QgVrdfXB5@`Xo!k! zgbHfA+!SuPsocfMesz`q?8A#PtTdCFYTx&iVWq!qI0}YSMF2t9aI{#M)1s^K%yU|m z2HNNuSF5+pzJ>{eFbN$~n8pldF^4cBn8yMZv4mwr5yJ`$tRjvztYZTSB$2`<(%8Z_ hc96j?vdCc%`^e(}hd9D9PH>7doTGpX*X$Qd*MH^Ht?d8+ From 398d5b7eb14367b4f5219a7d10a7e90bd81b4316 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Mon, 7 Mar 2022 22:31:31 +0100 Subject: [PATCH 17/45] Sympy 1.10 compatibility (#1694) sympify now automatically parses min/max, thereby escaping our argument conversion for float. Fixed here by moving the conversion from import to code generation. Also fixes sphinx autodoc typehint issue due to circular import error with TYPE_CHECKING=True in sympy1.10 --- documentation/conf.py | 3 ++- python/amici/cxxcodeprinter.py | 23 ++++++++++++++++++++--- python/amici/import_utils.py | 5 ----- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/documentation/conf.py b/documentation/conf.py index 99dfa29b85..f9dbc3fb94 100644 --- a/documentation/conf.py +++ b/documentation/conf.py @@ -20,8 +20,9 @@ # need to import before setting typing.TYPE_CHECKING=True, fails otherwise import pandas as pd +import sympy as sp -exhale_multiproject_monkeypatch, pd # to avoid removal of unused import +exhale_multiproject_monkeypatch, pd, sp # to avoid removal of unused import # BEGIN Monkeypatch exhale from exhale.deploy import _generate_doxygen as exhale_generate_doxygen diff --git a/python/amici/cxxcodeprinter.py b/python/amici/cxxcodeprinter.py index 5411010270..005d0299be 100644 --- a/python/amici/cxxcodeprinter.py +++ b/python/amici/cxxcodeprinter.py @@ -20,9 +20,26 @@ def doprint(self, expr: sp.Expr, assign_to: Optional[str] = None) -> str: return code except TypeError as e: raise ValueError( - f'Encountered unsupported function in expression "{expr}": ' - f'{e}!' - ) + f'Encountered unsupported function in expression "{expr}"' + ) from e + + def _print_min_max(self, expr, cpp_fun: str, sympy_fun): + # C++ doesn't like mixing int and double for arguments for min/max, + # therefore, we just always convert to float + arg0 = sp.Float(expr.args[0]) if expr.args[0].is_number \ + else expr.args[0] + if len(expr.args) == 1: + return self._print(arg0) + return "%s%s(%s, %s)" % (self._ns, cpp_fun, self._print(arg0), + self._print(sympy_fun(*expr.args[1:]))) + + def _print_Min(self, expr): + from sympy.functions.elementary.miscellaneous import Min + return self._print_min_max(expr, "min", Min) + + def _print_Max(self, expr): + from sympy.functions.elementary.miscellaneous import Max + return self._print_min_max(expr, "max", Max) def _get_sym_lines_array( self, diff --git a/python/amici/import_utils.py b/python/amici/import_utils.py index 9be9d44f3a..c5510a3306 100644 --- a/python/amici/import_utils.py +++ b/python/amici/import_utils.py @@ -351,11 +351,6 @@ def _parse_special_functions(sym: sp.Expr, toplevel: bool = True) -> sp.Expr: } if sym.__class__.__name__ in fun_mappings: - # c++ doesnt like mixing int and double for arguments of those - # functions - if sym.__class__.__name__ in ['min', 'max']: - args = tuple(sp.Float(arg) if arg.is_number else arg - for arg in args) return fun_mappings[sym.__class__.__name__](*args) elif sym.__class__.__name__ == 'piecewise' \ From 3ad735ad7111c71f9483730cb71d402709a1c364 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Wed, 9 Mar 2022 13:49:59 +0100 Subject: [PATCH 18/45] Remove unnecessary sundials files (#1695) * Remove unnecessary sundials files * .. --- .../sundials/cmake/SundialsSetupCuda.cmake | 106 - .../sundials/cmake/SundialsSetupFortran.cmake | 339 --- .../sundials/cmake/SundialsSetupHIP.cmake | 56 - ThirdParty/sundials/cmake/tpl/FindHYPRE.cmake | 91 - ThirdParty/sundials/cmake/tpl/FindMAGMA.cmake | 111 - ThirdParty/sundials/cmake/tpl/FindPETSC.cmake | 777 ----- .../sundials/cmake/tpl/FindTrilinos.cmake | 45 - .../sundials/cmake/tpl/FindXBRAID.cmake | 196 -- .../sundials/cmake/tpl/SundialsHypre.cmake | 113 - .../sundials/cmake/tpl/SundialsMAGMA.cmake | 109 - .../sundials/cmake/tpl/SundialsMPI.cmake | 89 - .../sundials/cmake/tpl/SundialsPETSC.cmake | 91 - .../sundials/cmake/tpl/SundialsRAJA.cmake | 87 - .../sundials/cmake/tpl/SundialsTrilinos.cmake | 140 - .../sundials/cmake/tpl/SundialsXBRAID.cmake | 129 - .../sunlinsol/sunlinsol_cusolversp_batchqr.h | 111 - .../include/sunmatrix/sunmatrix_cusparse.h | 134 - ThirdParty/sundials/src/kinsol/CMakeLists.txt | 81 - ThirdParty/sundials/src/kinsol/LICENSE | 29 - ThirdParty/sundials/src/kinsol/NOTICE | 21 - ThirdParty/sundials/src/kinsol/README.md | 69 - ThirdParty/sundials/src/kinsol/kinsol.c | 2702 ----------------- .../sundials/src/kinsol/kinsol_bbdpre.c | 582 ---- .../sundials/src/kinsol/kinsol_bbdpre_impl.h | 82 - .../sundials/src/kinsol/kinsol_direct.c | 55 - ThirdParty/sundials/src/kinsol/kinsol_impl.h | 489 --- ThirdParty/sundials/src/kinsol/kinsol_io.c | 1073 ------- ThirdParty/sundials/src/kinsol/kinsol_ls.c | 1365 --------- .../sundials/src/kinsol/kinsol_ls_impl.h | 185 -- ThirdParty/sundials/src/kinsol/kinsol_spils.c | 73 - .../fixedpoint/fmod/CMakeLists.txt | 31 - .../fmod/fsunnonlinsol_fixedpoint_mod.c | 443 --- .../fmod/fsunnonlinsol_fixedpoint_mod.f90 | 473 --- .../sunnonlinsol/newton/fmod/CMakeLists.txt | 31 - .../newton/fmod/fsunnonlinsol_newton_mod.c | 453 --- .../newton/fmod/fsunnonlinsol_newton_mod.f90 | 491 --- 36 files changed, 11452 deletions(-) delete mode 100644 ThirdParty/sundials/cmake/SundialsSetupCuda.cmake delete mode 100644 ThirdParty/sundials/cmake/SundialsSetupFortran.cmake delete mode 100644 ThirdParty/sundials/cmake/SundialsSetupHIP.cmake delete mode 100644 ThirdParty/sundials/cmake/tpl/FindHYPRE.cmake delete mode 100644 ThirdParty/sundials/cmake/tpl/FindMAGMA.cmake delete mode 100644 ThirdParty/sundials/cmake/tpl/FindPETSC.cmake delete mode 100644 ThirdParty/sundials/cmake/tpl/FindTrilinos.cmake delete mode 100644 ThirdParty/sundials/cmake/tpl/FindXBRAID.cmake delete mode 100644 ThirdParty/sundials/cmake/tpl/SundialsHypre.cmake delete mode 100644 ThirdParty/sundials/cmake/tpl/SundialsMAGMA.cmake delete mode 100644 ThirdParty/sundials/cmake/tpl/SundialsMPI.cmake delete mode 100644 ThirdParty/sundials/cmake/tpl/SundialsPETSC.cmake delete mode 100644 ThirdParty/sundials/cmake/tpl/SundialsRAJA.cmake delete mode 100644 ThirdParty/sundials/cmake/tpl/SundialsTrilinos.cmake delete mode 100644 ThirdParty/sundials/cmake/tpl/SundialsXBRAID.cmake delete mode 100644 ThirdParty/sundials/include/sunlinsol/sunlinsol_cusolversp_batchqr.h delete mode 100644 ThirdParty/sundials/include/sunmatrix/sunmatrix_cusparse.h delete mode 100644 ThirdParty/sundials/src/kinsol/CMakeLists.txt delete mode 100644 ThirdParty/sundials/src/kinsol/LICENSE delete mode 100644 ThirdParty/sundials/src/kinsol/NOTICE delete mode 100644 ThirdParty/sundials/src/kinsol/README.md delete mode 100644 ThirdParty/sundials/src/kinsol/kinsol.c delete mode 100644 ThirdParty/sundials/src/kinsol/kinsol_bbdpre.c delete mode 100644 ThirdParty/sundials/src/kinsol/kinsol_bbdpre_impl.h delete mode 100644 ThirdParty/sundials/src/kinsol/kinsol_direct.c delete mode 100644 ThirdParty/sundials/src/kinsol/kinsol_impl.h delete mode 100644 ThirdParty/sundials/src/kinsol/kinsol_io.c delete mode 100644 ThirdParty/sundials/src/kinsol/kinsol_ls.c delete mode 100644 ThirdParty/sundials/src/kinsol/kinsol_ls_impl.h delete mode 100644 ThirdParty/sundials/src/kinsol/kinsol_spils.c delete mode 100644 ThirdParty/sundials/src/sunnonlinsol/fixedpoint/fmod/CMakeLists.txt delete mode 100644 ThirdParty/sundials/src/sunnonlinsol/fixedpoint/fmod/fsunnonlinsol_fixedpoint_mod.c delete mode 100644 ThirdParty/sundials/src/sunnonlinsol/fixedpoint/fmod/fsunnonlinsol_fixedpoint_mod.f90 delete mode 100644 ThirdParty/sundials/src/sunnonlinsol/newton/fmod/CMakeLists.txt delete mode 100644 ThirdParty/sundials/src/sunnonlinsol/newton/fmod/fsunnonlinsol_newton_mod.c delete mode 100644 ThirdParty/sundials/src/sunnonlinsol/newton/fmod/fsunnonlinsol_newton_mod.f90 diff --git a/ThirdParty/sundials/cmake/SundialsSetupCuda.cmake b/ThirdParty/sundials/cmake/SundialsSetupCuda.cmake deleted file mode 100644 index f7c04df036..0000000000 --- a/ThirdParty/sundials/cmake/SundialsSetupCuda.cmake +++ /dev/null @@ -1,106 +0,0 @@ -# --------------------------------------------------------------- -# Programmer(s): Cody J. Balos @ LLNL -# --------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# --------------------------------------------------------------- -# Setup the CUDA languge and CUDA libraries. -# --------------------------------------------------------------- - -# =============================================================== -# Configure options needed prior to enabling the CUDA language -# =============================================================== - -if(NOT CMAKE_CUDA_HOST_COMPILER) - # If a user did not provide the host compiler, then we - # assume that they want to use the CXX compiler that was set. - set(CMAKE_CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER} CACHE FILEPATH "NVCC host compiler") -endif() - -# =============================================================== -# Configure the CUDA flags -# =============================================================== - -set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} --expt-extended-lambda") - -if(${CMAKE_VERSION} VERSION_LESS "3.18.0") - if(CMAKE_CUDA_ARCHITECTURES) - foreach(arch ${CMAKE_CUDA_ARCHITECTURES}) - # Remove real/virtual specifiers - string(REGEX MATCH "[0-9]+" arch_name "${arch}") - string(APPEND _nvcc_arch_flags " -gencode=arch=compute_${arch_name},code=sm_${arch_name}") - endforeach() - - set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} ${_nvcc_arch_flags}") - endif() -endif() - -if( (CMAKE_CXX_COMPILER_ID MATCHES GNU) - OR (CMAKE_CXX_COMPILER_ID MATCHES Clang) - AND (CMAKE_SYSTEM_PROCESSOR MATCHES ppc64le) ) - include(CheckCXXCompilerFlag) - check_cxx_compiler_flag(-mno-float128 _hasflag) - if(_hasflag) - set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler=-mno-float128") - endif() -endif() - -# Need c++11 for the CUDA compiler check. -set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -std=c++11") - -# =============================================================== -# Enable CUDA lang and find the CUDA libraries. -# =============================================================== - -enable_language(CUDA) -set(CUDA_FOUND TRUE) - -# Need this as long as CUDA libraries like cuSOLVER are not available -# through some other way. -find_package(CUDA REQUIRED) - -# Hide legacy FindCUDA variables -get_cmake_property(_variables VARIABLES) -foreach(_var ${_variables}) - if("${_var}" MATCHES "^CUDA_[A-z]+_LIBRARY") - # do nothing - elseif("${_var}" MATCHES "^CUDA_.*") - mark_as_advanced(${_var}) - endif() -endforeach() - -# Make the CUDA_rt_LIBRARY advanced like the other CUDA_*_LIBRARY variables -mark_as_advanced(FORCE CUDA_rt_LIBRARY) - -# Show CUDA flags -mark_as_advanced(CLEAR CMAKE_CUDA_FLAGS) - -# We need c++11 for the CUDA compiler check, but if we don't remove it, -# then we will get a redefinition error. CMAKE_CUDA_STANDARD ends up -# setting the proper version. -if(CMAKE_CUDA_FLAGS) - STRING(REPLACE "-std=c++11" " " CMAKE_CUDA_FLAGS ${CMAKE_CUDA_FLAGS}) -endif() -set(CMAKE_CUDA_STANDARD ${CMAKE_CXX_STANDARD}) - -# =============================================================== -# Print out information about CUDA. -# =============================================================== - -message(STATUS "CUDA Version: ${CUDA_VERSION_STRING}") -message(STATUS "CUDA Architectures: ${CMAKE_CUDA_ARCHITECTURES}") -message(STATUS "CUDA Compiler: ${CMAKE_CUDA_COMPILER}") -message(STATUS "CUDA Host Compiler: ${CMAKE_CUDA_HOST_COMPILER}") -message(STATUS "CUDA Include Path: ${CUDA_INCLUDE_DIRS}") -message(STATUS "CUDA Libraries: ${CUDA_LIBRARIES}") -message(STATUS "CUDA Compile Flags: ${CMAKE_CUDA_FLAGS}") -message(STATUS "CUDA Link Flags: ${CMAKE_CUDA_LINK_FLAGS}") -message(STATUS "CUDA Link Executable: ${CMAKE_CUDA_LINK_EXECUTABLE}") -message(STATUS "CUDA Separable Compilation: ${CMAKE_CUDA_SEPARABLE_COMPILATION}") diff --git a/ThirdParty/sundials/cmake/SundialsSetupFortran.cmake b/ThirdParty/sundials/cmake/SundialsSetupFortran.cmake deleted file mode 100644 index 06f388a831..0000000000 --- a/ThirdParty/sundials/cmake/SundialsSetupFortran.cmake +++ /dev/null @@ -1,339 +0,0 @@ -# --------------------------------------------------------------- -# Programmer(s): Radu Serban, David Gardner, Cody J. Balos @ LLNL -# --------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# --------------------------------------------------------------- -# Module which enables Fortran and tests for support of necessary -# compiler features for the current SUNDIALS configuration. -# Will define the variables: -# Fortran_FOUND - TRUE if a Fortran compiler is found -# F77_FOUND - equivalent to Fortran_FOUND -# F90_FOUND - TRUE if the Fortran compiler supports Fortran 90 -# F2003_FOUND - TRUE if the Fortran compiler supports the -# Fortran 2003 standard -# --------------------------------------------------------------- - -# If the Fortran compiler flags are set using environemnt variables (i.e., -# CMAKE_Fortran_FLAGS is not set), then check if both FFLAGS and FCFLAGS are -# set. If both are set and not the same then a fatal error occurs. -# -# NOTE: This check must occur before 'enable_language(Fortran)' as it will use -# the value of FFLAGS to set CMAKE_Fortran_FLAGS -set(ENV_FFLAGS "$ENV{FFLAGS}") -set(ENV_FCFLAGS "$ENV{FCFLAGS}") - -# check if environment variables are used and CMAKE_Fortran_FLAGS is not -if ((NOT "${ENV_FFLAGS}" STREQUAL "") AND (NOT "${ENV_FCFLAGS}" STREQUAL "") - AND ("${CMAKE_Fortran_FLAGS}" STREQUAL "")) - - # check if environment variables are equal - if (NOT "${ENV_FFLAGS}" STREQUAL "${ENV_FCFLAGS}") - print_error("FFLAGS='${ENV_FFLAGS}' and FCFLAGS='${ENV_FCFLAGS}' are both set but are not equal.") - endif() -endif() - -# ----------------------------------------------------------------------------- -# Enable Fortran -# ----------------------------------------------------------------------------- -enable_language(Fortran) -set(Fortran_FOUND TRUE) -set(F77_FOUND TRUE) - -# ----------------------------------------------------------------------------- -# Check if Fortran 90 is supported -# ----------------------------------------------------------------------------- -if(CMAKE_Fortran_COMPILER_SUPPORTS_F90) - set(F90_FOUND TRUE) -else() - set(F90_FOUND FALSE) - print_warning("Fortran compiler does not support F90" "F90 support will not be provided") -endif() - -# ----------------------------------------------------------------------------- -# Check if Fortran 2003 is supported -# ----------------------------------------------------------------------------- -if(BUILD_FORTRAN_MODULE_INTERFACE) - if(NOT F2003_FOUND) - message(STATUS "Checking whether ${CMAKE_Fortran_COMPILER} supports F2003") - - set(F2003Test_DIR ${PROJECT_BINARY_DIR}/F2003Test_DIR) - file(MAKE_DIRECTORY ${F2003Test_DIR}) - - # Create a CMakeLists.txt file - file(WRITE ${F2003Test_DIR}/CMakeLists.txt - "CMAKE_MINIMUM_REQUIRED(VERSION 3.1.3)\n" - "PROJECT(ftest Fortran)\n" - "SET(CMAKE_VERBOSE_MAKEFILE ON)\n" - "SET(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\")\n" - "SET(CMAKE_Fortran_COMPILER \"${CMAKE_Fortran_COMPILER}\")\n" - "SET(CMAKE_Fortran_FLAGS \"${CMAKE_Fortran_FLAGS}\")\n" - "SET(CMAKE_Fortran_FLAGS_RELEASE \"${CMAKE_Fortran_FLAGS_RELEASE}\")\n" - "SET(CMAKE_Fortran_FLAGS_DEBUG \"${CMAKE_Fortran_FLAGS_DEBUG}\")\n" - "SET(CMAKE_Fortran_FLAGS_RELWITHDEBUGINFO \"${CMAKE_Fortran_FLAGS_RELWITHDEBUGINFO}\")\n" - "SET(CMAKE_Fortran_FLAGS_MINSIZE \"${CMAKE_Fortran_FLAGS_MINSIZE}\")\n" - "ADD_EXECUTABLE(ftest ftest.f90)\n") - - # Create a Fortran source file which tries to use iso_c_binding - file(WRITE ${F2003Test_DIR}/ftest.f90 - "program main\n" - "use, intrinsic :: iso_c_binding\n" - "end program main\n") - - # Attempt compile the executable - try_compile(FTEST_OK ${F2003Test_DIR} ${F2003Test_DIR} - ftest OUTPUT_VARIABLE COMPILE_OUTPUT) - - # To ensure we do not use stuff from the previous attempts, - # we must remove the CMakeFiles directory. - file(REMOVE_RECURSE ${F2003Test_DIR}/CMakeFiles) - - if(FTEST_OK) - message(STATUS "Checking whether ${CMAKE_Fortran_COMPILER} supports F2003 -- yes") - set(F2003_FOUND TRUE CACHE BOOL "${CMAKE_Fortran_COMPILER} supports F2003" FORCE) - else() - message(STATUS "Checking whether ${CMAKE_Fortran_COMPILER} supports F2003 -- no") - message(STATUS "Check output:") - message("${COMPILE_OUTPUT}") - print_error("BUILD_FORTRAN_MODULE_INTERFACE is set to ON, but the CMAKE_Fortran_COMPILER does not support F2003") - endif() - else() - message(STATUS "Skipped F2003 tests, assuming ${CMAKE_Fortran_COMPILER} supports the f2003 standard. To rerun the F2003 tests, set F2003_FOUND to FALSE.") - endif() -endif() - -# Ensure that F90 compiler is found if F90 examples are enabled -if (EXAMPLES_ENABLE_F90 AND (NOT F90_FOUND)) - print_error("Compiler with F90 support not found" "Disabling F90 Examples") - set(DOCSTR "Build SUNDIALS F90 examples") - force_variable(EXAMPLES_ENABLE_F90 BOOL "${DOCSTR}" OFF) -endif() - -# Put all F2003 modules into one build directory -set(CMAKE_Fortran_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/fortran") - -# --------------------------------------------------------------- -# Determining the name-mangling scheme if needed -# --------------------------------------------------------------- -# In general, names of symbols with and without underscore may be mangled -# differently (e.g. g77 mangles mysub to mysub_ and my_sub to my_sub__), -# we have to consider both cases. -# -# Method: -# 1) create a library from a Fortran source file which defines a function "mysub" -# 2) attempt to link with this library a C source file which calls the "mysub" -# function using various possible schemes (6 different schemes, corresponding -# to all combinations lower/upper case and none/one/two underscores). -# 3) define the name-mangling scheme based on the test that was successful. -# -# On exit, if we were able to infer the scheme, the variables -# CMAKE_Fortran_SCHEME_NO_UNDERSCORES and CMAKE_Fortran_SCHEME_WITH_UNDERSCORES -# contain the mangled names for "mysub" and "my_sub", respectively. -# --------------------------------------------------------------- -if(NEED_FORTRAN_NAME_MANGLING) - - set(CMAKE_Fortran_SCHEME_NO_UNDERSCORES "") - set(CMAKE_Fortran_SCHEME_WITH_UNDERSCORES "") - - # Create the FortranTest directory - set(FortranTest_DIR ${PROJECT_BINARY_DIR}/FortranTest) - file(MAKE_DIRECTORY ${FortranTest_DIR}) - - # Create a CMakeLists.txt file which will generate the "flib" library - # and an executable "ftest" - file(WRITE ${FortranTest_DIR}/CMakeLists.txt - "CMAKE_MINIMUM_REQUIRED(VERSION 3.0.2)\n" - "PROJECT(ftest Fortran)\n" - "SET(CMAKE_VERBOSE_MAKEFILE ON)\n" - "SET(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\")\n" - "SET(CMAKE_Fortran_COMPILER \"${CMAKE_Fortran_COMPILER}\")\n" - "SET(CMAKE_Fortran_FLAGS \"${CMAKE_Fortran_FLAGS}\")\n" - "SET(CMAKE_Fortran_FLAGS_RELEASE \"${CMAKE_Fortran_FLAGS_RELEASE}\")\n" - "SET(CMAKE_Fortran_FLAGS_DEBUG \"${CMAKE_Fortran_FLAGS_DEBUG}\")\n" - "SET(CMAKE_Fortran_FLAGS_RELWITHDEBUGINFO \"${CMAKE_Fortran_FLAGS_RELWITHDEBUGINFO}\")\n" - "SET(CMAKE_Fortran_FLAGS_MINSIZE \"${CMAKE_Fortran_FLAGS_MINSIZE}\")\n" - "ADD_LIBRARY(flib flib.f)\n" - "ADD_EXECUTABLE(ftest ftest.f)\n" - "TARGET_LINK_LIBRARIES(ftest flib)\n") - - # Create the Fortran source flib.f which defines two subroutines, "mysub" and "my_sub" - file(WRITE ${FortranTest_DIR}/flib.f - " SUBROUTINE mysub\n" - " RETURN\n" - " END\n" - " SUBROUTINE my_sub\n" - " RETURN\n" - " END\n") - - # Create the Fortran source ftest.f which calls "mysub" and "my_sub" - file(WRITE ${FortranTest_DIR}/ftest.f - " PROGRAM ftest\n" - " CALL mysub()\n" - " CALL my_sub()\n" - " END\n") - - # Use TRY_COMPILE to make the targets "flib" and "ftest" - try_compile(FTEST_OK ${FortranTest_DIR} ${FortranTest_DIR} - ftest OUTPUT_VARIABLE MY_OUTPUT) - - # To ensure we do not use stuff from the previous attempts, - # we must remove the CMakeFiles directory. - file(REMOVE_RECURSE ${FortranTest_DIR}/CMakeFiles) - - # Proceed based on test results - if(FTEST_OK) - - # Infer Fortran name-mangling scheme for symbols WITHOUT underscores. - # Overwrite CMakeLists.txt with one which will generate the "ctest1" executable - file(WRITE ${FortranTest_DIR}/CMakeLists.txt - "CMAKE_MINIMUM_REQUIRED(VERSION 3.0.2)\n" - "PROJECT(ctest1 C)\n" - "SET(CMAKE_VERBOSE_MAKEFILE ON)\n" - "SET(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\")\n" - "SET(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n" - "SET(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS}\")\n" - "SET(CMAKE_C_FLAGS_RELEASE \"${CMAKE_C_FLAGS_RELEASE}\")\n" - "SET(CMAKE_C_FLAGS_DEBUG \"${CMAKE_C_FLAGS_DEBUG}\")\n" - "SET(CMAKE_C_FLAGS_RELWITHDEBUGINFO \"${CMAKE_C_FLAGS_RELWITHDEBUGINFO}\")\n" - "SET(CMAKE_C_FLAGS_MINSIZE \"${CMAKE_C_FLAGS_MINSIZE}\")\n" - "ADD_EXECUTABLE(ctest1 ctest1.c)\n" - "FIND_LIBRARY(FLIB flib \"${FortranTest_DIR}\")\n" - "TARGET_LINK_LIBRARIES(ctest1 \${FLIB})\n") - - # Define the list "options" of all possible schemes that we want to consider - # Get its length and initialize the counter "iopt" to zero - set(options mysub mysub_ mysub__ MYSUB MYSUB_ MYSUB__) - list(LENGTH options imax) - set(iopt 0) - - # We will attempt to sucessfully generate the "ctest1" executable as long as - # there still are entries in the "options" list - while(${iopt} LESS ${imax}) - # Get the current list entry (current scheme) - list(GET options ${iopt} opt) - # Generate C source which calls the "mysub" function using the current scheme - file(WRITE ${FortranTest_DIR}/ctest1.c - "extern void ${opt}();\n" - "int main(){${opt}();return(0);}\n") - # Use TRY_COMPILE to make the "ctest1" executable from the current C source - # and linking to the previously created "flib" library. - try_compile(CTEST_OK ${FortranTest_DIR} ${FortranTest_DIR} - ctest1 OUTPUT_VARIABLE MY_OUTPUT) - # Write output compiling the test code - file(WRITE ${FortranTest_DIR}/ctest1_${opt}.out "${MY_OUTPUT}") - # To ensure we do not use stuff from the previous attempts, - # we must remove the CMakeFiles directory. - file(REMOVE_RECURSE ${FortranTest_DIR}/CMakeFiles) - # Test if we successfully created the "ctest" executable. - # If yes, save the current scheme, and set the counter "iopt" to "imax" - # so that we exit the while loop. - # Otherwise, increment the counter "iopt" and go back in the while loop. - if(CTEST_OK) - set(CMAKE_Fortran_SCHEME_NO_UNDERSCORES ${opt}) - set(iopt ${imax}) - else(CTEST_OK) - math(EXPR iopt ${iopt}+1) - endif() - endwhile(${iopt} LESS ${imax}) - - # Infer Fortran name-mangling scheme for symbols WITH underscores. - # Practically a duplicate of the previous steps. - file(WRITE ${FortranTest_DIR}/CMakeLists.txt - "CMAKE_MINIMUM_REQUIRED(VERSION 3.0.2)\n" - "PROJECT(ctest2 C)\n" - "SET(CMAKE_VERBOSE_MAKEFILE ON)\n" - "SET(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\")\n" - "SET(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\")\n" - "SET(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS}\")\n" - "SET(CMAKE_C_FLAGS_RELEASE \"${CMAKE_C_FLAGS_RELEASE}\")\n" - "SET(CMAKE_C_FLAGS_DEBUG \"${CMAKE_C_FLAGS_DEBUG}\")\n" - "SET(CMAKE_C_FLAGS_RELWITHDEBUGINFO \"${CMAKE_C_FLAGS_RELWITHDEBUGINFO}\")\n" - "SET(CMAKE_C_FLAGS_MINSIZE \"${CMAKE_C_FLAGS_MINSIZE}\")\n" - "ADD_EXECUTABLE(ctest2 ctest2.c)\n" - "FIND_LIBRARY(FLIB flib ${FortranTest_DIR})\n" - "TARGET_LINK_LIBRARIES(ctest2 \${FLIB})\n") - - set(options my_sub my_sub_ my_sub__ MY_SUB MY_SUB_ MY_SUB__) - list(LENGTH options imax) - set(iopt 0) - while(${iopt} LESS ${imax}) - list(GET options ${iopt} opt) - file(WRITE ${FortranTest_DIR}/ctest2.c - "extern void ${opt}();\n" - "int main(){${opt}();return(0);}\n") - try_compile(CTEST_OK ${FortranTest_DIR} ${FortranTest_DIR} - ctest2 OUTPUT_VARIABLE MY_OUTPUT) - file(WRITE ${FortranTest_DIR}/ctest2_${opt}.out "${MY_OUTPUT}") - file(REMOVE_RECURSE ${FortranTest_DIR}/CMakeFiles) - if(CTEST_OK) - set(CMAKE_Fortran_SCHEME_WITH_UNDERSCORES ${opt}) - set(iopt ${imax}) - else(CTEST_OK) - math(EXPR iopt ${iopt}+1) - endif() - endwhile(${iopt} LESS ${imax}) - - # If a name-mangling scheme was found set the C preprocessor macros to use - # that scheme. Otherwise default to lower case with one underscore. - if(CMAKE_Fortran_SCHEME_NO_UNDERSCORES AND CMAKE_Fortran_SCHEME_WITH_UNDERSCORES) - message(STATUS "Determining Fortran name-mangling scheme... OK") - else() - message(STATUS "Determining Fortran name-mangling scheme... DEFAULT") - set(CMAKE_Fortran_SCHEME_NO_UNDERSCORES "mysub_") - set(CMAKE_Fortran_SCHEME_WITH_UNDERSCORES "my_sub_") - endif() - - # Symbols NO underscores - if(${CMAKE_Fortran_SCHEME_NO_UNDERSCORES} MATCHES "mysub") - set(F77_MANGLE_MACRO1 "#define SUNDIALS_F77_FUNC(name,NAME) name") - endif() - if(${CMAKE_Fortran_SCHEME_NO_UNDERSCORES} MATCHES "mysub_") - set(F77_MANGLE_MACRO1 "#define SUNDIALS_F77_FUNC(name,NAME) name ## _") - endif() - if(${CMAKE_Fortran_SCHEME_NO_UNDERSCORES} MATCHES "mysub__") - set(F77_MANGLE_MACRO1 "#define SUNDIALS_F77_FUNC(name,NAME) name ## __") - endif() - if(${CMAKE_Fortran_SCHEME_NO_UNDERSCORES} MATCHES "MYSUB") - set(F77_MANGLE_MACRO1 "#define SUNDIALS_F77_FUNC(name,NAME) NAME") - endif() - if(${CMAKE_Fortran_SCHEME_NO_UNDERSCORES} MATCHES "MYSUB_") - set(F77_MANGLE_MACRO1 "#define SUNDIALS_F77_FUNC(name,NAME) NAME ## _") - endif() - if(${CMAKE_Fortran_SCHEME_NO_UNDERSCORES} MATCHES "MYSUB__") - set(F77_MANGLE_MACRO1 "#define SUNDIALS_F77_FUNC(name,NAME) NAME ## __") - endif() - - # Symbols WITH underscores - if(${CMAKE_Fortran_SCHEME_WITH_UNDERSCORES} MATCHES "my_sub") - set(F77_MANGLE_MACRO2 "#define SUNDIALS_F77_FUNC_(name,NAME) name") - endif() - if(${CMAKE_Fortran_SCHEME_WITH_UNDERSCORES} MATCHES "my_sub_") - set(F77_MANGLE_MACRO2 "#define SUNDIALS_F77_FUNC_(name,NAME) name ## _") - endif() - if(${CMAKE_Fortran_SCHEME_WITH_UNDERSCORES} MATCHES "my_sub__") - set(F77_MANGLE_MACRO2 "#define SUNDIALS_F77_FUNC_(name,NAME) name ## __") - endif() - if(${CMAKE_Fortran_SCHEME_WITH_UNDERSCORES} MATCHES "MY_SUB") - set(F77_MANGLE_MACRO2 "#define SUNDIALS_F77_FUNC_(name,NAME) NAME") - endif() - if(${CMAKE_Fortran_SCHEME_WITH_UNDERSCORES} MATCHES "MY_SUB_") - set(F77_MANGLE_MACRO2 "#define SUNDIALS_F77_FUNC_(name,NAME) NAME ## _") - endif() - if(${CMAKE_Fortran_SCHEME_WITH_UNDERSCORES} MATCHES "MY_SUB__") - set(F77_MANGLE_MACRO2 "#define SUNDIALS_F77_FUNC_(name,NAME) NAME ## __") - endif() - - # name-mangling scheme has been set - set(NEED_FORTRAN_NAME_MANGLING FALSE) - else(FTEST_OK) - message(STATUS "Determining Fortran name-mangling scheme... FAILED") - endif() - -endif() \ No newline at end of file diff --git a/ThirdParty/sundials/cmake/SundialsSetupHIP.cmake b/ThirdParty/sundials/cmake/SundialsSetupHIP.cmake deleted file mode 100644 index f120080377..0000000000 --- a/ThirdParty/sundials/cmake/SundialsSetupHIP.cmake +++ /dev/null @@ -1,56 +0,0 @@ -# --------------------------------------------------------------- -# Programmer(s): Cody J. Balos @ LLNL -# --------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# --------------------------------------------------------------- -# Setup the HIP language and libraries. -# --------------------------------------------------------------- - -if(NOT DEFINED ROCM_PATH) - if(NOT DEFINED ENV{ROCM_PATH}) - set(ROCM_PATH "/opt/rocm/" CACHE PATH "Path to which ROCm has been installed") - else() - set(ROCM_PATH "$ENV{ROCM_PATH}" CACHE PATH "Path to which ROCm has been installed") - endif() -endif() - -if(NOT DEFINED HIP_PATH) - if(NOT DEFINED ENV{HIP_PATH}) - set(HIP_PATH "/opt/rocm/hip" CACHE PATH "Path to which HIP has been installed") - else() - set(HIP_PATH "$ENV{HIP_PATH}" CACHE PATH "Path to which HIP has been installed") - endif() -endif() - -if(NOT DEFINED HIP_PLATFORM) - if(NOT DEFINED ENV{HIP_PLATFORM}) - set(HIP_PLATFORM "hcc" CACHE STRING "HIP platform (hcc, nvcc)") - else() - set(HIP_PLATFORM "$ENV{HIP_PLATFORM}" CACHE STRING "HIP platform (hcc, nvcc)") - endif() -endif() - -# Set CMAKE_PREFIX_PATH as the hip-config.cmake has some find_package calls -# which don't have the proper path set (not sure if this is a bug or -# intentional), so without this they will fail even if we provide the PATH -# option to find_package(HIP). -set(CMAKE_PREFIX_PATH "${ROCM_PATH};${HIP_PATH}") -find_package(HIP REQUIRED) - -if("${HIP_COMPILER}" STREQUAL "hcc") - print_error("Deprecated HCC compiler is not supported" "Please update ROCm") -endif() - -message(STATUS "HIP version: ${HIP_VERSION}") -message(STATUS "HIP platform: ${HIP_PLATFORM}") -message(STATUS "HIP compiler: ${HIP_COMPILER}") -message(STATUS "HIP linker: ${CMAKE_CXX_LINK_EXECUTABLE}") -message(STATUS "AMD targets: ${AMDGPU_TARGETS}") diff --git a/ThirdParty/sundials/cmake/tpl/FindHYPRE.cmake b/ThirdParty/sundials/cmake/tpl/FindHYPRE.cmake deleted file mode 100644 index 168b8da621..0000000000 --- a/ThirdParty/sundials/cmake/tpl/FindHYPRE.cmake +++ /dev/null @@ -1,91 +0,0 @@ -# --------------------------------------------------------------- -# Programmer(s): Eddy Banks, Slaven Peles, Cody J. Balos, and -# Jean Sexton @ LLNL -# --------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# --------------------------------------------------------------- -# HYPRE find module that creates an imported target for HYPRE. -# The target is SUNDIALS::HYPRE. -# -# The variable HYPRE_LIBRARY_DIR can be used to control -# where the module looks for the library. -# -# The variable HYPRE_INCLUDE_DIR can be used to set the -# include path for the library. -# -# This module also defines variables, but it is best to use -# the defined target to ensure includes and compile/link -# options are correctly passed to consumers. -# -# HYPRE_FOUND - system has HYPRE library -# HYPRE_LIBRARY - the HYPRE library -# HYPRE_INCLUDE_DIR - the HYPRE include path -# HYPRE_LIBRARIES - all of the libraries needed for HYPRE -# --------------------------------------------------------------- - -### Find include dir -find_path(temp_HYPRE_INCLUDE_DIR hypre.h ${HYPRE_INCLUDE_DIR}) -if (temp_HYPRE_INCLUDE_DIR) - set(HYPRE_INCLUDE_DIR ${temp_HYPRE_INCLUDE_DIR}) -endif() -unset(temp_HYPRE_INCLUDE_DIR CACHE) - -if (HYPRE_LIBRARY) - # We have (or were given) HYPRE_LIBRARY - get path to use for any related libs - get_filename_component(HYPRE_LIBRARY_DIR ${HYPRE_LIBRARY} PATH) - - # force CACHE update to show user DIR that will be used - set(HYPRE_LIBRARY_DIR ${HYPRE_LIBRARY_DIR} CACHE PATH "" FORCE) -else () - # find library with user provided directory path - set(HYPRE_LIBRARY_NAMES hypre HYPRE) - find_library(HYPRE_LIBRARY - NAMES ${HYPRE_LIBRARY_NAMES} - PATHS ${HYPRE_LIBRARY_DIR} NO_DEFAULT_PATH - ) -endif () -mark_as_advanced(HYPRE_LIBRARY) - -list(FIND HYPRE_LIBRARIES ${HYPRE_LIBRARY} _idx) -if (_idx EQUAL -1) - set(HYPRE_LIBRARIES "${HYPRE_LIBRARY};${HYPRE_LIBRARIES}" CACHE STRING "" FORCE) -endif () - -# set a more informative error message in case the library was not found -set(HYPRE_NOT_FOUND_MESSAGE "\ -************************************************************************\n\ -ERROR: Could not find HYPRE. Please check the variables:\n\ - HYPRE_INCLUDE_DIR and HYPRE_LIBRARY_DIR\n\ -************************************************************************") - -# set package variables including HYPRE_FOUND -find_package_handle_standard_args(HYPRE - REQUIRED_VARS - HYPRE_LIBRARY - HYPRE_LIBRARIES - HYPRE_INCLUDE_DIR - FAIL_MESSAGE - "${HYPRE_NOT_FOUND_MESSAGE}" - ) - -# Create target for HYPRE -if(HYPRE_FOUND) - - if(NOT TARGET SUNDIALS::HYPRE) - add_library(SUNDIALS::HYPRE UNKNOWN IMPORTED) - endif() - - set_target_properties(SUNDIALS::HYPRE PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${HYPRE_INCLUDE_DIR}" - INTERFACE_LINK_LIBRARIES "${HYPRE_LIBRARIES}" - IMPORTED_LOCATION "${HYPRE_LIBRARY}") - -endif() diff --git a/ThirdParty/sundials/cmake/tpl/FindMAGMA.cmake b/ThirdParty/sundials/cmake/tpl/FindMAGMA.cmake deleted file mode 100644 index c621b88204..0000000000 --- a/ThirdParty/sundials/cmake/tpl/FindMAGMA.cmake +++ /dev/null @@ -1,111 +0,0 @@ -# ----------------------------------------------------------------------------- -# Programmer(s): Cody J. Balos @ LLNL -# ----------------------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# ----------------------------------------------------------------------------- -# Find module that locates the MAGMA linear algebra library. -# ----------------------------------------------------------------------------- - -# find the MAGMA include path -find_path(MAGMA_INCLUDE_DIR magma_v2.h - NAMES magma_v2.h - HINTS ${MAGMA_DIR} $ENV{MAGMA_DIR} - PATH_SUFFIXES include - NO_DEFAULT_PATH - DOC "Directory with MAGMA header" -) - -# find the main MAGMA library -find_library(MAGMA_LIBRARY - NAMES magma - HINTS ${MAGMA_DIR} $ENV{MAGMA_DIR} - PATH_SUFFIXES lib lib64 - NO_DEFAULT_PATH - DOC "The MAGMA library.") - -# Find the optional sparse component -if("SPARSE" IN_LIST MAGMA_FIND_COMPONENTS) - set(_sparse_required MAGMA_SPARSE_LIBRARY) - find_library(MAGMA_SPARSE_LIBRARY - NAMES magma_sparse - HINTS ${MAGMA_DIR} $ENV{MAGMA_DIR} - PATH_SUFFIXES lib lib64 - NO_DEFAULT_PATH - DOC "The MAGMA sparse library.") -else() - set(_sparse_required ) -endif() - -# Determine MAGMA version and libraries it depends on -if(MAGMA_LIBRARY AND MAGMA_INCLUDE_DIR) - get_filename_component(libdir ${MAGMA_LIBRARY} DIRECTORY) - find_file(MAGMA_PKG_CONFIG_PATH magma.pc PATHS "${libdir}/pkgconfig") - - if(MAGMA_PKG_CONFIG_PATH) - file(STRINGS ${MAGMA_PKG_CONFIG_PATH} _version_string REGEX "Version: [0-9].[0-9].[0-9]") - string(REGEX MATCHALL "[0-9]" _version_full "${_version_string}") - - list(GET _version_full 0 _version_major) - list(GET _version_full 1 _version_minor) - list(GET _version_full 2 _version_patch) - - set(MAGMA_VERSION "${_version_major}.${_version_minor}.${_version_patch}") - - file(STRINGS ${MAGMA_PKG_CONFIG_PATH} _libraries_string REGEX "Libs:.*") - string(REPLACE " " ";" _libraries_list ${_libraries_string}) - list(SUBLIST _libraries_list 1 -1 _libraries_list) # remove 'Libs:' part - - set(_interface_libraires ) - foreach(lib ${_libraries_list}) - if(NOT (lib STREQUAL "-lmagma" OR lib STREQUAL "-lmagma_sparse" OR lib STREQUAL "-L\${libdir}" OR lib STREQUAL "") ) - string(REPLACE "-l" "" lib ${lib}) - list(APPEND _interface_libraires ${lib}) - endif() - endforeach() - endif() -endif() - -set(MAGMA_LIBRARIES "${MAGMA_LIBRARY};${_interface_libraires}") - -find_package_handle_standard_args(MAGMA - REQUIRED_VARS - MAGMA_LIBRARY - MAGMA_LIBRARIES - MAGMA_INCLUDE_DIR - ${_sparse_required} - VERSION_VAR - MAGMA_VERSION - ) - -# Create target for MAGMA -if(MAGMA_FOUND) - - if(NOT TARGET SUNDIALS::MAGMA) - add_library(SUNDIALS::MAGMA UNKNOWN IMPORTED) - endif() - - set_target_properties(SUNDIALS::MAGMA PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${MAGMA_INCLUDE_DIR}" - INTERFACE_LINK_LIBRARIES "${_interface_libraires}" - IMPORTED_LOCATION "${MAGMA_LIBRARY}") - - if(MAGMA_SPARSE_LIBRARY) - if(NOT TARGET SUNDIALS::MAGMA_SPARSE) - add_library(SUNDIALS::MAGMA_SPARSE UNKNOWN IMPORTED) - endif() - - set_target_properties(SUNDIALS::MAGMA_SPARSE PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${MAGMA_INCLUDE_DIR}" - INTERFACE_LINK_LIBRARIES "${MAGMA_LIBRARY};${_interface_libraires}" - IMPORTED_LOCATION "${MAGMA_SPARSE_LIBRARY}") - endif() - -endif() diff --git a/ThirdParty/sundials/cmake/tpl/FindPETSC.cmake b/ThirdParty/sundials/cmake/tpl/FindPETSC.cmake deleted file mode 100644 index 1ef09d53dc..0000000000 --- a/ThirdParty/sundials/cmake/tpl/FindPETSC.cmake +++ /dev/null @@ -1,777 +0,0 @@ -# ------------------------------------------------------------------------------ -# Programmer(s): Cody J. Balos and David J. Gardner @ LLNL -# ------------------------------------------------------------------------------ -# Based on the FindPETSC module by Jed Brown. -# ------------------------------------------------------------------------------ -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# ------------------------------------------------------------------------------ -# Copyright Jed Brown -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# ------------------------------------------------------------------------------ -# Try to find PETSC. This has three usage modes. -# -# The first usage mode is to find PETSC by introspection. -# This case is triggered when PETSC_DIR is not set by the user. -# Setting the variables below change the behavior of the search in this mode: -# PETSC_DIR - directory in which PETSC resides -# PETSC_ARCH - build architecture -# PETSC_CURRENT - (advanced) redo the find stage and executable tests -# PETSC_WORKS - (advanced) set to ON to ignore the output of the -# executable tests (not recommended) -# -# The second usage mode is to find PETSC based on the user-provided -# PETSC_DIR, and optionally PETSC_ARCH, variables. This case is triggered -# when just PETSC_DIR, and optionally PETSC_ARCH, are set by the user. -# Setting the variables below change the behavior of the search in this mode: -# PETSC_DIR - directory in which PETSC resides -# PETSC_ARCH - build architecture -# PETSC_CURRENT - (advanced) redo the find stage and executable tests -# PETSC_WORKS - (advanced) set to ON to ignore the output of the -# executable tests (not recommended) -# -# The third usage mode is to 'find' PETSC based on the user-provided list -# of include directories and libraries. This mode will only use the includes -# and libraries provided in the PETSC_INCLUDES and PETSC_LIBRARIES variable. -# This case is triggered when PETSC_INCLUDES, and PETSC_LIBRARIES are set. -# Setting the variables below change the behavior of the search in this mode: -# PETSC_LIBRARIES - (advanced) link these to use PETSC -# PETSC_INCLUDES - (advanced) the PETSC include directories -# PETSC_CURRENT - (advanced) redo the executable tests -# PETSC_WORKS - (advanced) set to ON to ignore the output of the -# executable tests (not recommended) -# -# Note that setting PETSC_LIBRARIES and PETSC_INCLUDES takes precedence over -# setting PETSC_DIR. -# -# Once done this will define the targets: -# -# SUNDIALS::PETSC_ALL - a CMake target for all of PETSc -# SUNDIALS::PETSC_SYS - a CMake target for the main PETSc library -# SUNDIALS::PETSC_VEC - a CMake target for the PETSc vector library -# SUNDIALS::PETSC_MAT - a CMake target for the PETSc matrix library -# SUNDIALS::PETSC_DM - a CMake target for the PETSc DM library -# SUNDIALS::PETSC_KSP - a CMake target for the PETSc KSP library -# SUNDIALS::PETSC_SNES - a CMake target for the PETSc SNES library -# SUNDIALS::PETSC_TS - a CMake target for the PETSc TS library -# -# It will also define the following, potentially useful, variables: -# -# PETSC_COMPILER - (advanced) Compiler used by PETSC, helpful to find a compatible MPI -# PETSC_DEFINITIONS - (advanced) Compiler switches for using PETSC -# PETSC_MPIEXEC - (advanced) Executable for running MPI programs -# PETSC_INDEX_SIZE - (internal) the size of indices in PETSC -# PETSC_PRECISION - (internal) the real type precision in PETSC -# PETSC_VERSION - (internal) Version string (MAJOR.MINOR.SUBMINOR) -# -# Usage: -# find_package(PETSC COMPONENTS CXX) - required if build --with-clanguage=C++ --with-c-support=0 -# find_package(PETSC COMPONENTS C) - standard behavior of checking build using a C compiler -# find_package(PETSC) - same as above -# -# Redistribution and use is allowed according to the terms of the BSD license. -# ------------------------------------------------------------------------------ - -# ------------------------------------------------------------------------------ -# helper macros and functions -# ------------------------------------------------------------------------------ - -function (PETSC_GET_VERSION) - if (EXISTS "${PETSC_INCLUDE_DIR}/petscversion.h") - file (STRINGS "${PETSC_INCLUDE_DIR}/petscversion.h" vstrings REGEX "#define PETSC_VERSION_(RELEASE|MAJOR|MINOR|SUBMINOR|PATCH) ") - foreach (line ${vstrings}) - string (REGEX REPLACE " +" ";" fields ${line}) # break line into three fields (the first is always "#define") - list (GET fields 1 var) - list (GET fields 2 val) - set (${var} ${val} PARENT_SCOPE) - set (${var} ${val}) # Also in local scope so we have access below - endforeach () - if (PETSC_VERSION_RELEASE) - if ($(PETSC_VERSION_PATCH) GREATER 0) - set (PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}p${PETSC_VERSION_PATCH}" CACHE INTERNAL "PETSC version" FORCE) - else () - set (PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}" CACHE INTERNAL "PETSC version" FORCE) - endif () - else () - # make dev version compare higher than any patch level of a released version - set (PETSC_VERSION "${PETSC_VERSION_MAJOR}.${PETSC_VERSION_MINOR}.${PETSC_VERSION_SUBMINOR}.99" CACHE INTERNAL "PETSC version" FORCE) - endif () - else () - message (SEND_ERROR "${PETSC_INCLUDE_DIR}/petscversion.h does not exist") - endif () -endfunction () - -macro (PETSC_GET_VARIABLE name var) - if (NOT DEFINED MAKE_EXECUTABLE) - # need to find the make executable the first time this macro is used - find_program (MAKE_EXECUTABLE NAMES make gmake) - if (MAKE_EXECUTABLE MATCHES "NOTFOUND") - message(SEND_ERROR "MAKE_EXECUTABLE could not be found (looked for `make` and `gmake`)") - endif () - endif () - set (${var} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) - execute_process (COMMAND ${MAKE_EXECUTABLE} --no-print-directory -f ${petsc_config_makefile} show VARIABLE=${name} - OUTPUT_VARIABLE ${var} - RESULT_VARIABLE petsc_return) -endmacro (PETSC_GET_VARIABLE) - -macro (PETSC_TEST_RUNS includes libraries runs) - if (PETSC_VERSION VERSION_GREATER 3.1) - set (_PETSC_TSDestroy "TSDestroy(&ts)") - else () - set (_PETSC_TSDestroy "TSDestroy(ts)") - endif () - - set (_PETSC_TEST_SOURCE " -static const char help[] = \"PETSC test program.\"; -#include -int main(int argc,char *argv[]) { - PetscErrorCode ierr; - TS ts; - - ierr = PetscInitialize(&argc,&argv,0,help);CHKERRQ(ierr); - ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); - ierr = TSSetFromOptions(ts);CHKERRQ(ierr); - ierr = ${_PETSC_TSDestroy};CHKERRQ(ierr); - ierr = PetscFinalize();CHKERRQ(ierr); - return 0; -} -") - - multipass_source_runs ("${includes}" "${libraries}" "${_PETSC_TEST_SOURCE}" ${runs} "${PETSC_LANGUAGE_BINDINGS}") - - if (${${runs}}) - set (PETSC_EXECUTABLE_RUNS "YES" CACHE INTERNAL - "The system can successfully run a PETSC executable" FORCE) - else() - set (PETSC_EXECUTABLE_RUNS "NO" CACHE INTERNAL - "The system can NOT successfully run a PETSC executable" FORCE) - endif () -endmacro (PETSC_TEST_RUNS) - -macro (PETSC_FIND_LIBRARY suffix name) - # Clear any stale value, if we got here, we need to find it again - set (PETSC_LIBRARY_${suffix} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) - - if (WIN32) - set (libname lib${name}) # windows expects "libfoo", linux expects "foo" - else (WIN32) - set (libname ${name}) - endif (WIN32) - - find_library (PETSC_LIBRARY_${suffix} NAMES ${libname} HINTS ${petsc_lib_dir} NO_DEFAULT_PATH) - set (PETSC_LIBRARIES_${suffix} "${PETSC_LIBRARY_${suffix}}" CACHE INTERNAL "PETSC ${suffix} libraries" FORCE) - mark_as_advanced(PETSC_LIBRARY_${suffix}) -endmacro (PETSC_FIND_LIBRARY suffix name) - -macro (PETSC_FIND_LIBRARY_IN_LIST suffix names liblist) - # Clear any stale value, if we got here, we need to find it again - set (PETSC_LIBRARY_${suffix} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) - - foreach (name ${names}) - if (WIN32) - set (libname lib${name}) # windows expects "libfoo", linux expects "foo" - else (WIN32) - set (libname ${name}) - endif (WIN32) - foreach (lib ${${liblist}}) - if ("${lib}" MATCHES "${libname}[.].*") - set (PETSC_LIBRARY_${suffix} ${lib} CACHE INTERNAL "" FORCE) - list (REMOVE_ITEM ${liblist} ${lib}) - break () - endif () - endforeach () - endforeach () - set (PETSC_LIBRARIES_${suffix} "${PETSC_LIBRARY_${suffix}}" CACHE INTERNAL "PETSC ${suffix} libraries" FORCE) - mark_as_advanced(PETSC_LIBRARY_${suffix}) - -endmacro (PETSC_FIND_LIBRARY_IN_LIST suffix names liblist) - -macro (PETSC_JOIN libs deps) - list (APPEND PETSC_LIBRARIES_${libs} ${PETSC_LIBRARIES_${deps}}) - # since list APPEND creates a new local variable in the current scope we need - # to set the cache variable value to propagate the changes upwards - set (PETSC_LIBRARIES_${libs} ${PETSC_LIBRARIES_${libs}} CACHE INTERNAL "PETSC ${libs} libraries" FORCE) -endmacro (PETSC_JOIN libs deps) - -# ------------------------------------------------------------------------------ -# FindPETSC -# ------------------------------------------------------------------------------ - -set (PETSC_VALID_COMPONENTS C CXX) - -if (NOT PETSC_FIND_COMPONENTS) - - get_property (_enabled_langs GLOBAL PROPERTY ENABLED_LANGUAGES) - list(FIND _enabled_langs "C" _c_index) - if (${_c_index} GREATER -1) - set (PETSC_LANGUAGE_BINDINGS "C") - else () - set (PETSC_LANGUAGE_BINDINGS "CXX") - endif () - -else() - - # Right now, this is designed for compatability with the --with-clanguage option, so - # only allow one item in the components list. - list(LENGTH ${PETSC_FIND_COMPONENTS} components_length) - if(${components_length} GREATER 1) - message(FATAL_ERROR "Only one component for PETSC is allowed to be specified") - endif() - # This is a stub for allowing multiple components should that time ever come. Perhaps - # to also test Fortran bindings? - foreach(component ${PETSC_FIND_COMPONENTS}) - list(FIND PETSC_VALID_COMPONENTS ${component} component_location) - if(${component_location} EQUAL -1) - message(FATAL_ERROR "\"${component}\" is not a valid PETSC component.") - else() - list(APPEND PETSC_LANGUAGE_BINDINGS ${component}) - endif() - endforeach() - -endif() - -# Set which state variables to check to determine if the PETSC configuration is -# current and clear the other state variables -if (PETSC_INCLUDES OR PETSC_LIBRARIES) - - if (PETSC_INCLUDES AND PETSC_LIBRARIES) - - set (PETSC_STATES "LIBRARIES;INCLUDES" CACHE INTERNAL "" FORCE) - set (PETSC_DIR "" CACHE PATH "Path to the root of a PETSc installation" FORCE) - set (PETSC_ARCH "" CACHE STRING "PETSc architecture" FORCE) - - else () - - string (CONCAT msg - "Both PETSC_INCLUDES and PETSC_LIBRARIES must be provided:\n" - " PETSC_INCLUDES=${PETSC_INCLUDES}\n" - " PETSC_LIBRARIES=${PETSC_LIBRARIES}") - message (FATAL_ERROR ${msg}) - - endif () - -else () - - set (PETSC_STATES "DIR;ARCH" CACHE INTERNAL "" FORCE) - set (PETSC_INCLUDES "" CACHE STRING "Semi-colon separated list of PETSc include directories" FORCE) - set (PETSC_LIBRARIES "" CACHE STRING "Semi-colon separated list of PETSc link libraries" FORCE) - -endif () - -# Keep track of FindPETSC state so that we do not do the complete -# set of tests and variable lookups every time cmake is run. -include (FindPackageMultipass) -set (petsc_slaves LIBRARIES_SYS LIBRARIES_VEC LIBRARIES_MAT LIBRARIES_DM LIBRARIES_KSP LIBRARIES_SNES LIBRARIES_TS) -set (petsc_deps LIBRARY_DIR INCLUDE_DIR LIBRARIES_ INCLUDES_ COMPILER MPIEXEC EXECUTABLE_RUNS ${petsc_slaves}) -find_package_multipass (PETSC petsc_config_current STATES ${PETSC_STATES} DEPENDENTS ${petsc_deps}) - -# This runs anytime the current configuration is not current. -# This happens either when a user sets PETSC_CURRENT=FALSE, -# or when one of the dependents given to find_package_multipass changes. -if (NOT petsc_config_current) - - if (PETSC_INCLUDES AND PETSC_LIBRARIES) - - message (STATUS "Finding PETSC using PETSC_INCLUDES and PETSC_LIBRARIES") - - # extract path from PETSC_INCLUDES - foreach (_include_dir ${PETSC_INCLUDES}) - if (EXISTS "${_include_dir}/petsc.h") - set (PETSC_INCLUDE_DIR "${_include_dir}" CACHE INTERNAL "Internal PETSc include directory" FORCE) - break () - endif () - endforeach () - - # check if the include directory was found - if (NOT PETSC_INCLUDE_DIR) - string (CONCAT msg - "Could not determine PETSc include directory from PETSC_INCLUDES:\n" - " PETSC_INCLUDES=${PETSC_INCLUDES}\n") - message (FATAL_ERROR ${msg}) - endif() - - # extract path from PETSC_LIBRARIES - foreach (_library_path ${PETSC_LIBRARIES}) - get_filename_component (_library_name "${_library_path}" NAME) - if (_library_name MATCHES "petsc") - get_filename_component (_library_dir "${_library_path}" DIRECTORY) - set (PETSC_LIBRARY_DIR "${_library_dir}" CACHE INTERNAL "Internal PETSc library directory" FORCE) - break () - endif () - endforeach () - - # check if the library directory was found - if (NOT PETSC_LIBRARY_DIR) - string (CONCAT msg - "Could not DETERMINE PETSc library directory from PETSC_LIBRARIES:\n" - " PETSC_LIBRARIES=${PETSC_LIBRARIES}") - message (FATAL_ERROR ${msg}) - endif() - - # set internal PETSC_DIR and PETSC_ARCH variables - set (PETSC_DIR_ "${PETSC_LIBRARY_DIR}/.." CACHE INTERNAL "Internal PETSC_DIR" FORCE) - set (PETSC_ARCH_ "" CACHE INTERNAL "Internal PETSC_ARCH" FORCE) - - else() - - message (STATUS "Finding PETSC using PETSC_DIR") - - # find PETSC_DIR - if (NOT PETSC_DIR) - - message (STATUS "Looking for PETSc in common install locations") - - # Debian uses versioned paths e.g /usr/lib/petscdir/3.5/ - file (GLOB DEB_PATHS "/usr/lib/petscdir/*") - - find_path (PETSC_DIR include/petsc.h - HINTS ENV PETSC_DIR - PATHS - /usr/lib/petsc - # Debian paths - ${DEB_PATHS} - # Arch Linux path - /opt/petsc/linux-c-opt - # MacPorts path - /opt/local/lib/petsc - $ENV{HOME}/petsc - DOC "PETSC Directory") - - # check if PETSC_DIR was set/found - if (NOT PETSC_DIR) - - string (CONCAT msg - "Could not locate PETSc install directory please set:\n" - " - PETSC_DIR and (optionally) PETSC_ARCH\n" - "or used the advanced options\n" - " - PETSC_INCLUDES and PETSC_LIBRARIES.") - message (FATAL_ERROR ${msg}) - - endif () - - endif() - - # find PETSC_ARCH - if (NOT PETSC_ARCH) - - set (_petsc_arches - $ENV{PETSC_ARCH} # If set, use environment variable first - linux-gnu-c-debug linux-gnu-c-opt # Debian defaults - x86_64-unknown-linux-gnu i386-unknown-linux-gnu) - set (PETSCCONF "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) - foreach (arch ${_petsc_arches}) - find_path (PETSCCONF petscconf.h - HINTS ${PETSC_DIR} - PATH_SUFFIXES ${arch}/include bmake/${arch} - NO_DEFAULT_PATH) - if (PETSCCONF) - set (PETSC_ARCH "${arch}" CACHE STRING "PETSC build architecture" FORCE) - break () - endif () - endforeach () - set (PETSCCONF "NOTFOUND" CACHE INTERNAL "Scratch variable" FORCE) - - endif () - - if (PETSC_ARCH) - set (PETSC_INCLUDE_DIR "${PETSC_DIR}/${PETSC_ARCH}/include" CACHE INTERNAL "Internal PETSc include directory" FORCE) - set (PETSC_LIBRARY_DIR "${PETSC_DIR}/${PETSC_ARCH}/lib" CACHE INTERNAL "Internal PETSc library directory" FORCE) - else () - set (PETSC_INCLUDE_DIR "${PETSC_DIR}/include" CACHE INTERNAL "Internal PETSc include directory" FORCE) - set (PETSC_LIBRARY_DIR "${PETSC_DIR}/lib" CACHE INTERNAL "Internal PETSc library directory" FORCE) - endif () - - # set internal PETSC_DIR and PETSC_ARCH variables - set (PETSC_DIR_ "${PETSC_DIR}" CACHE INTERNAL "Internal PETS_DIR" FORCE) - set (PETSC_ARCH_ "${PETSC_ARCH}" CACHE INTERNAL "Internal PETS_ARCH" FORCE) - - endif () - - # Resolve the conf/rules and conf/variables files. - # The location of these files has changed with different PETSc versions, - # so look in a few different locations for them. - if (EXISTS "${PETSC_LIBRARY_DIR}/petsc/conf/petscvariables") # > 3.5 - set (petsc_conf_rules "${PETSC_LIBRARY_DIR}/petsc/conf/rules") - set (petsc_conf_variables "${PETSC_LIBRARY_DIR}/petsc/conf/variables") - elseif (EXISTS "${PETSC_INCLUDE_DIR}/petscconf.h") # > 2.3.3 - set (petsc_conf_rules "${PETSC_DIR_}/conf/rules") - set (petsc_conf_variables "${PETSC_DIR_}/conf/variables") - elseif (EXISTS "${PETSC_DIR_}/bmake/${PETSC_ARCH_}/petscconf.h") # <= 2.3.3 - set (petsc_conf_rules "${PETSC_DIR_}/bmake/common/rules") - set (petsc_conf_variables "${PETSC_DIR_}/bmake/common/variables") - elseif (PETSC_LIBRARIES AND PETSC_INCLUDES) - message (FATAL_ERROR "PETSC_LIBRARIES=${PETSC_LIBRARIES} and PETSC_INCLUDES=${PETSC_INCLUDES} do not specify a valid PETSC installation") - else () - message (FATAL_ERROR "PETSC_DIR=${PETSC_DIR} and PETSC_ARCH=${PETSC_ARCH} do not specify a valid PETSC installation") - endif () - - # ---------------------------------------------------------------------------- - # Probe the PETSc installation for information about how it was configured. - # ---------------------------------------------------------------------------- - - # Get the PETSc version - petsc_get_version() - - # Put variables into environment since they are needed to get - # configuration (petscvariables) in the PETSC makefile - set (ENV{PETSC_DIR} "${PETSC_DIR_}") - set (ENV{PETSC_ARCH} "${PETSC_ARCH_}") - - # A temporary makefile to probe the PETSC configuration - set (petsc_config_makefile "${PROJECT_BINARY_DIR}/Makefile.petsc") - file (WRITE "${petsc_config_makefile}" -"## This file was autogenerated by FindPETSC.cmake -# PETSC_DIR = ${PETSC_DIR_} -# PETSC_ARCH = ${PETSC_ARCH_} -include ${petsc_conf_rules} -include ${petsc_conf_variables} -show : -\t-@echo -n \${\${VARIABLE}} -") - - # Extract information about the PETSC configuration - petsc_get_variable (PETSC_LIB_DIR petsc_lib_dir) - petsc_get_variable (PETSC_EXTERNAL_LIB_BASIC petsc_libs_external) - petsc_get_variable (PETSC_CCPPFLAGS petsc_cpp_line) - petsc_get_variable (PETSC_INCLUDE petsc_include) - petsc_get_variable (PCC petsc_cc) - petsc_get_variable (PCC_FLAGS petsc_cc_flags) - petsc_get_variable (MPIEXEC petsc_mpiexec) - petsc_get_variable (PETSC_INDEX_SIZE petsc_index_size) - petsc_get_variable (PETSC_PRECISION petsc_precision) - - # We are done with the temporary Makefile, calling PETSC_GET_VARIABLE after this point is invalid! - file (REMOVE ${petsc_config_makefile}) - - # ---------------------------------------------------------------------------- - # Determine what libraries and includes are needed. - # ---------------------------------------------------------------------------- - - if (PETSC_INCLUDES AND PETSC_LIBRARIES) - - # If the user manually set PETSC_INCUDES and PETSC_LIBRARIES, we work off of - # what they provided. - - # Make a copy of the user-provided library list to modify as libraries are - # found and extracted - set (PETSC_LIBRARIES_REMAINING ${PETSC_LIBRARIES}) - - # Look for petscvec first, if it doesn't exist, we must be using single-library - petsc_find_library_in_list (VEC petscvec PETSC_LIBRARIES_REMAINING) - - if (PETSC_LIBRARY_VEC) - - # libpetscsys is called libpetsc prior to 3.1 (when single-library was introduced) - petsc_find_library_in_list (SYS "petscsys;petsc" PETSC_LIBRARIES_REMAINING) - petsc_find_library_in_list (MAT petscmat PETSC_LIBRARIES_REMAINING) - petsc_find_library_in_list (DM petscdm PETSC_LIBRARIES_REMAINING) - petsc_find_library_in_list (KSP petscksp PETSC_LIBRARIES_REMAINING) - petsc_find_library_in_list (SNES petscsnes PETSC_LIBRARIES_REMAINING) - petsc_find_library_in_list (TS petscts PETSC_LIBRARIES_REMAINING) - petsc_join (SYS REMAINING) - petsc_join (VEC SYS) - petsc_join (MAT VEC) - petsc_join (DM MAT) - petsc_join (KSP DM) - petsc_join (SNES KSP) - petsc_join (TS SNES) - - set (PETSC_LIBRARY_ALL ${PETSC_LIBRARY_TS} CACHE INTERNAL "All PETSC libraries" FORCE) - set (PETSC_LIBRARIES_ALL ${PETSC_LIBRARIES_TS} CACHE INTERNAL "All PETSC libraries" FORCE) - - message (STATUS "Recognized PETSC install with separate libraries for each package") - - else () - - # There is no libpetscvec - set (PETSC_LIBRARY_VEC "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) - - petsc_find_library_in_list (SINGLE petsc PETSC_LIBRARIES_REMAINING) - # Debian 9/Ubuntu 16.04 uses _real and _complex extensions when using libraries in /usr/lib/petsc. - if (NOT PETSC_LIBRARY_SINGLE) - petsc_find_library_in_list (SINGLE petsc_real PETSC_LIBRARIES_REMAINING) - endif() - if (NOT PETSC_LIBRARY_SINGLE) - petsc_find_library_in_list (SINGLE petsc_complex PETSC_LIBRARIES_REMAINING) - endif() - - foreach (pkg SYS VEC MAT DM KSP SNES TS ALL) - set (PETSC_LIBRARIES_${pkg} "${PETSC_LIBRARY_SINGLE}" CACHE INTERNAL "PETSC ${pkg} libraries" FORCE) - endforeach () - - message (STATUS "Recognized PETSC install with single library for all packages") - - endif () - - # At this point PETSC_LIBRARIES_REMAINING should only contain external - # libraries needed by PETSc. These may (e.g., static build) or may not - # (e.g., shared build) be needed to compile but are added to the package - # libraries regardless. - foreach (pkg SYS VEC MAT DM KSP SNES TS ALL) - list (APPEND PETSC_LIBRARIES_${pkg} ${PETSC_LIBRARIES_REMAINING}) - # since list APPEND creates a new local variable in the current scope we need - # to set the cache variable value to propagate the changes upwards - set (PETSC_LIBRARIES_${pkg} ${PETSC_LIBRARIES_${pkg}} CACHE INTERNAL "PETSC ${pkg} libraries" FORCE) - endforeach () - - # Try to run a simple executable - petsc_test_runs ("${PETSC_INCLUDES}" "${PETSC_LIBRARIES_TS}" petsc_works_userprovided) - if (petsc_works_userprovided) - message (STATUS "PETSC works with the includes and libraries given.") - else () - message (STATUS "PETSC could not be used, maybe the install is broken.") - endif () - - # set include and library variables needed to create targets below - set (petsc_includes_needed ${PETSC_INCLUDES}) - set (petsc_libraries_needed ${PETSC_LIBRARIES}) - - else () - - include (ResolveCompilerPaths) - # Extract include paths and libraries from compile command line - resolve_includes (petsc_includes_all "${petsc_cpp_line}") - - # On windows we need to make sure we're linking against the right - # runtime library - if (WIN32) - if (petsc_cc_flags MATCHES "-MT") - - set (using_md False) - foreach(flag_var - CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE - CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO - CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE - CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) - if(${flag_var} MATCHES "/MD") - set (using_md True) - endif(${flag_var} MATCHES "/MD") - endforeach(flag_var) - if(${using_md} MATCHES "True") - string(CONCAT msg "PETSC was built with /MT, but /MD is currently set.\n" - "See http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F") - message(WARNING ${msg}) - endif(${using_md} MATCHES "True") - - endif (petsc_cc_flags MATCHES "-MT") - endif (WIN32) - - include (CorrectWindowsPaths) - convert_cygwin_path(petsc_lib_dir) - - # Look for petscvec first, if it doesn't exist, we must be using single-library - petsc_find_library (VEC petscvec) - if (PETSC_LIBRARY_VEC) - - petsc_find_library (SYS "petscsys;petsc") # libpetscsys is called libpetsc prior to 3.1 (when single-library was introduced) - petsc_find_library (MAT petscmat) - petsc_find_library (DM petscdm) - petsc_find_library (KSP petscksp) - petsc_find_library (SNES petscsnes) - petsc_find_library (TS petscts) - petsc_join (VEC SYS) - petsc_join (MAT VEC) - petsc_join (DM MAT) - petsc_join (KSP DM) - petsc_join (SNES KSP) - petsc_join (TS SNES) - - set (PETSC_LIBRARY_ALL ${PETSC_LIBRARY_TS} CACHE INTERNAL "All PETSC libraries" FORCE) - set (PETSC_LIBRARIES_ALL ${PETSC_LIBRARIES_TS} CACHE INTERNAL "All PETSC libraries" FORCE) - - message (STATUS "Recognized PETSC install with separate libraries for each package") - - else () - - # There is no libpetscvec - set (PETSC_LIBRARY_VEC "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) - - petsc_find_library (SINGLE petsc) - # Debian 9/Ubuntu 16.04 uses _real and _complex extensions when using libraries in /usr/lib/petsc. - if (NOT PETSC_LIBRARY_SINGLE) - petsc_find_library (SINGLE petsc_real) - endif() - if (NOT PETSC_LIBRARY_SINGLE) - petsc_find_library (SINGLE petsc_complex) - endif() - - foreach (pkg SYS VEC MAT DM KSP SNES TS ALL) - set (PETSC_LIBRARIES_${pkg} "${PETSC_LIBRARY_SINGLE}" CACHE INTERNAL "PETSC ${pkg} libraries" FORCE) - endforeach () - - message (STATUS "Recognized PETSC install with single library for all packages") - - endif () - - # determine the include and library variables needed to create targets below - - find_path (PETSC_INCLUDE_CONF petscconf.h HINTS "${PETSC_INCLUDE_DIR}" "${PETSC_DIR_}/bmake/${PETSC_ARCH_}" NO_DEFAULT_PATH) - mark_as_advanced (PETSC_INCLUDE_CONF) - - set (petsc_includes_minimal ${PETSC_INCLUDE_CONF} ${PETSC_INCLUDE_DIR}) - - petsc_test_runs ("${petsc_includes_minimal}" "${PETSC_LIBRARIES_TS}" petsc_works_minimal) - if (petsc_works_minimal) - - message (STATUS "Minimal PETSC includes and libraries work. This probably means we are building with shared libs.") - set (petsc_includes_needed "${petsc_includes_minimal}") - - else (petsc_works_minimal) # Minimal includes fail, see if just adding full includes fixes it - - petsc_test_runs ("${petsc_includes_all}" "${PETSC_LIBRARIES_TS}" petsc_works_allincludes) - if (petsc_works_allincludes) # It does, we just need all the includes - - string (CONCAT msg "PETSC requires extra include paths, but links correctly with only interface libraries.\n" - "This is an unexpected configuration (but it seems to work fine).") - message (STATUS ${msg}) - set (petsc_includes_needed ${petsc_includes_all}) - - else (petsc_works_allincludes) # We are going to need to link the external libs explicitly - - resolve_libraries (petsc_libraries_external "${petsc_libs_external}") - foreach (pkg SYS VEC MAT DM KSP SNES TS ALL) - list (APPEND PETSC_LIBRARIES_${pkg} ${petsc_libraries_external}) - # since list APPEND creates a new local variable in the current scope we need - # to set the cache variable value to propagate the changes upwards - set (PETSC_LIBRARIES_${pkg} ${PETSC_LIBRARIES_${pkg}} CACHE INTERNAL "PETSC ${pkg} libraries" FORCE) - endforeach (pkg) - - petsc_test_runs ("${petsc_includes_minimal}" "${PETSC_LIBRARIES_TS}" petsc_works_alllibraries) - if (petsc_works_alllibraries) - - string (CONCAT msg "PETSC only need minimal includes, but requires explicit linking to all dependencies.\n" - "This is expected when PETSC is built with static libraries.") - message(STATUS ${msg}) - set (petsc_includes_needed ${petsc_includes_minimal}) - - else (petsc_works_alllibraries) - - # It looks like we really need everything, should have listened to Matt - set (petsc_includes_needed ${petsc_includes_all}) - petsc_test_runs ("${petsc_includes_all}" "${PETSC_LIBRARIES_TS}" petsc_works_all) - if (petsc_works_all) # We fail anyways - string (CONCAT msg "PETSC requires extra include paths and explicit linking to all dependencies.\n" - "This probably means you have static libraries and something unexpected in PETSC headers.") - message (STATUS ${msg}) - else (petsc_works_all) # We fail anyways - message (STATUS "PETSC could not be used, maybe the install is broken.") - endif (petsc_works_all) - - endif (petsc_works_alllibraries) - - endif (petsc_works_allincludes) - - endif (petsc_works_minimal) - - set (petsc_libraries_needed ${PETSC_LIBRARIES_ALL}) - - endif () - - # ---------------------------------------------------------------------------- - # Now we set all of the variables needed to build targets. - # ---------------------------------------------------------------------------- - - # If PETSC_WORKS is set override the executable test results. This variable - # can be manually set to ON to force CMake to accept a given PETSC - # configuration, but this will almost always result in a broken build. - if (PETSC_WORKS) - message (STATUS "Overwriting PETSc test results with PETSC_WORKS = ${PETSC_WORKS}") - set (PETSC_EXECUTABLE_RUNS ${PETSC_WORKS} CACHE INTERNAL "Overwritten by PETSC_WORKS" FORCE) - endif () - - # We do an out-of-source build so __FILE__ will be an absolute path, hence __INSDIR__ is superfluous - if (${PETSC_VERSION} VERSION_LESS 3.1) - set (PETSC_DEFINITIONS "-D__SDIR__=\"\"" CACHE STRING "PETSC definitions" FORCE) - else () - set (PETSC_DEFINITIONS "-D__INSDIR__=\"\"" CACHE STRING "PETSC definitions" FORCE) - endif () - - # Sometimes this can be used to assist FindMPI.cmake - set (PETSC_COMPILER ${petsc_cc} CACHE FILEPATH "PETSC compiler" FORCE) - set (PETSC_MPIEXEC ${petsc_mpiexec} CACHE FILEPATH "Executable for running PETSC MPI programs" FORCE) - - # Internal variables needed for configuring targets - set (PETSC_INDEX_SIZE ${petsc_index_size} CACHE INTERNAL "PETSC index size" FORCE) - set (PETSC_PRECISION ${petsc_precision} CACHE INTERNAL "PETSC real type precision" FORCE) - set (PETSC_INCLUDES_ ${petsc_includes_needed} CACHE INTERNAL "PETSC include paths to be used" FORCE) - set (PETSC_LIBRARIES_ ${petsc_libraries_needed} CACHE INTERNAL "PETSC libraries to be used" FORCE) - - # Note that we have forced values for all these choices. If you - # change these, you are telling the system to trust you that they - # work. It is likely that you will end up with a broken build. - mark_as_advanced (PETSC_CURRENT PETSC_COMPILER PETSC_DEFINITIONS PETSC_MPIEXEC PETSC_EXECUTABLE_RUNS) - -endif () - -include (FindPackageHandleStandardArgs) -find_package_handle_standard_args (PETSC - REQUIRED_VARS PETSC_EXECUTABLE_RUNS - VERSION_VAR PETSC_VERSION - FAIL_MESSAGE "PETSC could not be found.") - -# Create targets -if (PETSC_FOUND) - if (PETSC_LIBRARY_SINGLE) - foreach (suffix SYS VEC MAT DM KSP SNES TS ALL) - if (NOT TARGET SUNDIALS::PETSC_${suffix}) - add_library (SUNDIALS::PETSC_${suffix} UNKNOWN IMPORTED) - # add properties one-by-one for easier debugging - set_target_properties (SUNDIALS::PETSC_${suffix} PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${PETSC_INCLUDES_}") - set_target_properties (SUNDIALS::PETSC_${suffix} PROPERTIES - INTERFACE_LINK_LIBRARIES "${PETSC_LIBRARIES_}") - set_target_properties (SUNDIALS::PETSC_${suffix} PROPERTIES - INTERFACE_COMPILE_OPTIONS ${PETSC_DEFINITIONS}) - set_target_properties (SUNDIALS::PETSC_${suffix} PROPERTIES - IMPORTED_LOCATION ${PETSC_LIBRARY_SINGLE}) - endif () - endforeach () - else () - foreach (suffix SYS VEC MAT DM KSP SNES TS ALL) - if (PETSC_LIBRARY_${suffix} AND (NOT TARGET SUNDIALS::PETSC_${suffix})) - add_library (SUNDIALS::PETSC_${suffix} UNKNOWN IMPORTED) - # add properties one-by-one for easier debugging - set_target_properties (SUNDIALS::PETSC_${suffix} PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${PETSC_INCLUDES_}") - set_target_properties (SUNDIALS::PETSC_${suffix} PROPERTIES - INTERFACE_LINK_LIBRARIES "${PETSC_LIBRARIES_${suffix}}") - set_target_properties (SUNDIALS::PETSC_${suffix} PROPERTIES - INTERFACE_COMPILE_OPTIONS ${PETSC_DEFINITIONS}) - set_target_properties (SUNDIALS::PETSC_${suffix} PROPERTIES - IMPORTED_LOCATION ${PETSC_LIBRARY_${suffix}}) - endif () - endforeach () - endif () -endif (PETSC_FOUND) diff --git a/ThirdParty/sundials/cmake/tpl/FindTrilinos.cmake b/ThirdParty/sundials/cmake/tpl/FindTrilinos.cmake deleted file mode 100644 index eb78f834e3..0000000000 --- a/ThirdParty/sundials/cmake/tpl/FindTrilinos.cmake +++ /dev/null @@ -1,45 +0,0 @@ -# ----------------------------------------------------------------------------- -# Programmer(s): Slaven Peles and Cody J. Balos @ LLNL -# ----------------------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# ----------------------------------------------------------------------------- -# Find module for Trilinos that uses the TrilinosConfig.cmake that is installed -# with Trilinos. The module will also create a SUNDIALS::TRILINOS target. -# ----------------------------------------------------------------------------- - -# First try and find Trilinos using Trilinos_DIR only. -find_package(Trilinos - NAMES Trilinos TRILINOS - PATHS - ${Trilinos_DIR}/lib/cmake/Trilinos - ${Trilinos_DIR} - NO_DEFAULT_PATH - QUIET) - -# set package variables including Trilinos_FOUND -find_package_handle_standard_args(Trilinos - REQUIRED_VARS - Trilinos_LIBRARIES # defined in TrilinosConfig.cmake - Trilinos_INCLUDE_DIRS # defined in TrilinosConfig.cmake - ) - -# Create Trilinos target -if(Trilinos_FOUND) - - if(NOT TARGET SUNDIALS::TRILINOS) - add_library(SUNDIALS::TRILINOS IMPORTED INTERFACE) - endif() - - set_target_properties(SUNDIALS::TRILINOS PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${Trilinos_INCLUDE_DIRS}" - INTERFACE_LINK_LIBRARIES "${Trilinos_LIBRARIES}") - -endif() diff --git a/ThirdParty/sundials/cmake/tpl/FindXBRAID.cmake b/ThirdParty/sundials/cmake/tpl/FindXBRAID.cmake deleted file mode 100644 index 6b2d8b0521..0000000000 --- a/ThirdParty/sundials/cmake/tpl/FindXBRAID.cmake +++ /dev/null @@ -1,196 +0,0 @@ -# ------------------------------------------------------------------------------ -# Programmer(s): David J. Gardner @ LLNL -# ------------------------------------------------------------------------------ -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# ------------------------------------------------------------------------------ -# XBRAID find module that creates an imported target for XBRAID. -# The target is SUNDIALS::XBRAID. -# -# The variable XBRAID_DIR can be used to control where the module -# looks for the library. -# -# XBRAID_LIBRARIES - (advanced) the libraries to link against -# XBRAID_INCLUDES - (advanced) the directories to include -# -# This module also defines variables, but it is best to use -# the defined target to ensure includes and compile/link -# options are correctly passed to consumers. -# -# XBRAID_FOUND - system has the XBRAID library -# ------------------------------------------------------------------------------ - -# Check if we are locating XBraid using the root install directory or a list of -# include directories and link libraries -if (XBRAID_INCLUDES OR XBRAID_LIBRARIES) - - if (XBRAID_INCLUDES AND XBRAID_LIBRARIES) - - set(XBRAID_DIR "" CACHE PATH "Path to the root of XBraid installation" FORCE) - - else () - - string(CONCAT msg - "Both XBRAID_INCLUDES and XBRAID_LIBRARIES must be provided:\n" - " XBRAID_INCLUDES=${XBRAID_INCLUDES}\n" - " XBRAID_LIBRARIES=${XBRAID_LIBRARIES}") - message(FATAL_ERROR ${msg}) - - endif () - -else () - - set(XBRAID_INCLUDES "" CACHE STRING "Semi-colon separated list of XBraid include directories" FORCE) - set(XBRAID_LIBRARIES "" CACHE STRING "Semi-colon separated list of XBraid link libraries" FORCE) - -endif () - -# unset cache values for multiple passes -unset(XBRAID_INCLUDE_DIR CACHE) -unset(XBRAID_LIBRARY CACHE) - -unset(XBRAID_INCS CACHE) -unset(XBRAID_LIBS CACHE) - -if (XBRAID_INCLUDES AND XBRAID_LIBRARIES) - - message(STATUS "Finding XBraid using XBRAID_INCLUDES and XBRAID_LIBRARIES") - - # extract path from XBRAID_INCLUDES - foreach (include_dir ${XBRAID_INCLUDES}) - if (EXISTS "${include_dir}/braid.h") - set(XBRAID_INCLUDE_DIR "${include_dir}" CACHE "XBraid include directory") - break() - endif () - endforeach () - - # check if the include directory was found - if (NOT XBRAID_INCLUDE_DIR) - string(CONCAT msg - "Could not determine XBraid include directory from XBRAID_INCLUDES:\n" - " XBRAID_INCLUDES=${XBRAID_INCLUDES}\n") - message(FATAL_ERROR ${msg}) - endif () - - # extract library from XBRAID_LIBRARIES - foreach (library_path ${XBRAID_LIBRARIES}) - get_filename_component(library_name "${library_path}" NAME) - if (library_name MATCHES "braid") - set(XBRAID_LIBRARY "${library_path}" CACHE "XBraid library") - break() - endif () - endforeach () - - # check if the library directory was found - if (NOT XBRAID_LIBRARY) - string(CONCAT msg - "Could not determine XBraid library from XBRAID_LIBRARIES:\n" - " XBRAID_LIBRARIES=${XBRAID_LIBRARIES}") - message(FATAL_ERROR ${msg}) - endif () - -else () - - message(STATUS "Finding XBraid using XBRAID_DIR") - - # find XBRAID_DIR - if (NOT XBRAID_DIR) - - message(STATUS "Looking for XBraid in common install locations") - find_path(XBRAID_DIR include/braid.h braid/braid.h) - - endif () - - # check if XBRAID_DIR was set/found - if (NOT XBRAID_DIR) - - string(CONCAT msg - "Could not locate XBraid install directory please set:\n" - " - XBRAID_DIR\n" - "or used the advanced options\n" - " - XBRAID_INCLUDES and XBRAID_LIBRARIES.") - message(FATAL_ERROR ${msg}) - - endif () - - # Find the include dir - find_path(XBRAID_INCLUDE_DIR braid.h - PATHS - ${XBRAID_DIR} - PATH_SUFFIXES - include braid - DOC - "XBraid include directory" - NO_DEFAULT_PATH) - - # check if the include directory was found - if (NOT XBRAID_INCLUDE_DIR) - string(CONCAT msg - "Could not determine XBraid include directory from XBRAID_DIR:\n" - " XBRAID_DIR=${XBRAID_DIR}\n") - message(FATAL_ERROR ${msg}) - endif () - - # Find the library - find_library(XBRAID_LIBRARY braid - PATHS - ${XBRAID_DIR} - PATH_SUFFIXES - lib braid - DOC - "XBraid library" - NO_DEFAULT_PATH) - - # check if the library was found - if (NOT XBRAID_LIBRARY) - string(CONCAT msg - "Could not determine XBraid library from XBRAID_DIR:\n" - " XBRAID_DIR=${XBRAID_DIR}\n") - message(FATAL_ERROR ${msg}) - endif () - -endif () - -# set package variables including XBRAID_FOUND -find_package_handle_standard_args(XBRAID - REQUIRED_VARS - XBRAID_INCLUDE_DIR - XBRAID_LIBRARY - ) - -# XBraid target -if (XBRAID_FOUND) - - # create target if necessary - if (NOT TARGET SUNDIALS::XBRAID) - add_library(SUNDIALS::XBRAID UNKNOWN IMPORTED) - endif () - - # update target properties (for multiple passes) - set_target_properties(SUNDIALS::XBRAID PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${XBRAID_INCLUDE_DIR}" - INTERFACE_LINK_LIBRARIES "${XBRAID_LIBRARIES}" - IMPORTED_LOCATION "${XBRAID_LIBRARY}") - - # set variables for output message, compile tests, and - # CMake/Makefile templates - if (XBRAID_INCLUDES AND XBRAID_LIBRARIES) - set(XBRAID_INCS "${XBRAID_INCLUDES}" CACHE INTERNAL - "Internal XBraid includes") - set(XBRAID_LIBS "${XBRAID_LIBRARIES}" CACHE INTERNAL - "Internal XBraid libraries") - else () - set(XBRAID_INCS "${XBRAID_INCLUDE_DIR}" CACHE INTERNAL - "Internal XBraid includes") - set(XBRAID_LIBS "${XBRAID_LIBRARY}" CACHE INTERNAL - "Internal XBraid libraries") - endif () - -endif () diff --git a/ThirdParty/sundials/cmake/tpl/SundialsHypre.cmake b/ThirdParty/sundials/cmake/tpl/SundialsHypre.cmake deleted file mode 100644 index b2fb7af2d0..0000000000 --- a/ThirdParty/sundials/cmake/tpl/SundialsHypre.cmake +++ /dev/null @@ -1,113 +0,0 @@ -# ----------------------------------------------------------------------------- -# Programmer(s): Cody J. Balos @ LLNL -# ----------------------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# ----------------------------------------------------------------------------- -# Module to find and setup HYPRE correctly. -# Created from the SundialsTPL.cmake template. -# All SUNDIALS modules that find and setup a TPL must: -# -# 1. Check to make sure the SUNDIALS configuration and the TPL is compatible. -# 2. Find the TPL. -# 3. Check if the TPL works with SUNDIALS, UNLESS the override option -# TPL_WORKS is TRUE - in this case the tests should not be performed and it -# should be assumed that the TPL works with SUNDIALS. -# ----------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# Section 1: Include guard -# ----------------------------------------------------------------------------- - -if(NOT DEFINED SUNDIALS_HYPRE_INCLUDED) - set(SUNDIALS_HYPRE_INCLUDED) -else() - return() -endif() - -# ----------------------------------------------------------------------------- -# Section 2: Check to make sure options are compatible -# ----------------------------------------------------------------------------- - -# Using hypre requres building with MPI enabled -if(ENABLE_HYPRE AND NOT ENABLE_MPI) - print_error("MPI is required for hypre support. Set ENABLE_MPI to ON.") -endif() - -# ----------------------------------------------------------------------------- -# Section 3: Find the TPL -# ----------------------------------------------------------------------------- - -find_package(HYPRE REQUIRED) - -message(STATUS "HYPRE_LIBRARIES: ${HYPRE_LIBRARIES}") -message(STATUS "HYPRE_INCLUDE_DIR: ${HYPRE_INCLUDE_DIR}") - -# ----------------------------------------------------------------------------- -# Section 4: Test the TPL -# ----------------------------------------------------------------------------- - -if(HYPRE_FOUND AND (NOT HYPRE_WORKS)) - # Do any checks which don't require compilation first. - - # Create the HYPRE_TEST directory - set(HYPRE_TEST_DIR ${PROJECT_BINARY_DIR}/HYPRE_TEST) - file(MAKE_DIRECTORY ${HYPRE_TEST_DIR}) - - # Create a CMakeLists.txt file - file(WRITE ${HYPRE_TEST_DIR}/CMakeLists.txt - "CMAKE_MINIMUM_REQUIRED(VERSION 3.0.2)\n" - "PROJECT(ltest C)\n" - "SET(CMAKE_VERBOSE_MAKEFILE ON)\n" - "SET(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\")\n" - "SET(CMAKE_C_COMPILER ${MPI_C_COMPILER})\n" - "SET(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS}\")\n" - "SET(CMAKE_C_FLAGS_RELEASE \"${CMAKE_C_FLAGS_RELEASE}\")\n" - "SET(CMAKE_C_FLAGS_DEBUG \"${CMAKE_C_FLAGS_DEBUG}\")\n" - "SET(CMAKE_C_FLAGS_RELWITHDEBUGINFO \"${CMAKE_C_FLAGS_RELWITHDEBUGINFO}\")\n" - "SET(CMAKE_C_FLAGS_MINSIZE \"${CMAKE_C_FLAGS_MINSIZE}\")\n" - "SET(CMAKE_EXE_LINKER_FLAGS \"${LINK_MATH_LIB}\")\n" - "INCLUDE_DIRECTORIES(${HYPRE_INCLUDE_DIR})\n" - "ADD_EXECUTABLE(ltest ltest.c)\n" - "TARGET_LINK_LIBRARIES(ltest ${HYPRE_LIBRARIES})\n") - - file(WRITE ${HYPRE_TEST_DIR}/ltest.c - "\#include \"HYPRE_parcsr_ls.h\"\n" - "int main(){\n" - "HYPRE_ParVector par_b;\n" - "HYPRE_IJVector b;\n" - "par_b = 0;\n" - "b = 0;\n" - "if (par_b != 0 || b != 0) return(1);\n" - "else return(0);\n" - "}\n") - - # To ensure we do not use stuff from the previous attempts, - # we must remove the CMakeFiles directory. - file(REMOVE_RECURSE ${HYPRE_TEST_DIR}/CMakeFiles) - - # Attempt to build and link the "ltest" executable - try_compile(COMPILE_OK ${HYPRE_TEST_DIR} ${HYPRE_TEST_DIR} ltest - OUTPUT_VARIABLE COMPILE_OUTPUT) - - # Process test result - if(COMPILE_OK) - message(STATUS "Checking if HYPRE works... OK") - set(HYPRE_WORKS TRUE CACHE BOOL "HYPRE works with SUNDIALS as configured" FORCE) - else() - message(STATUS "Checking if HYPRE works... FAILED") - message(STATUS "Check output: ") - message("${COMPILE_OUTPUT}") - print_error("SUNDIALS interface to HYPRE is not functional.") - endif() - -elseif(HYPRE_FOUND AND HYPRE_WORKS) - message(STATUS "Skipped HYPRE tests, assuming HYPRE works with SUNDIALS. Set HYPRE_WORKS=FALSE to (re)run compatibility test.") -endif() diff --git a/ThirdParty/sundials/cmake/tpl/SundialsMAGMA.cmake b/ThirdParty/sundials/cmake/tpl/SundialsMAGMA.cmake deleted file mode 100644 index 671fac1aaf..0000000000 --- a/ThirdParty/sundials/cmake/tpl/SundialsMAGMA.cmake +++ /dev/null @@ -1,109 +0,0 @@ -# ----------------------------------------------------------------------------- -# Programmer(s): Cody J. Balos @ LLNL -# ----------------------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# ----------------------------------------------------------------------------- -# Module to find and setup MAGMA correctly. -# Created from the SundialsTPL.cmake template. -# All SUNDIALS modules that find and setup a TPL must: -# -# 1. Check to make sure the SUNDIALS configuration and the TPL is compatible. -# 2. Find the TPL. -# 3. Check if the TPL works with SUNDIALS, UNLESS the override option -# TPL_WORKS is TRUE - in this case the tests should not be performed and it -# should be assumed that the TPL works with SUNDIALS. -# ----------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# Section 1: Include guard -# ----------------------------------------------------------------------------- - -if(NOT DEFINED SUNDIALS_MAGMA_INCLUDED) - set(SUNDIALS_MAGMA_INCLUDED) -else() - return() -endif() - -# ----------------------------------------------------------------------------- -# Section 2: Check to make sure options are compatible -# ----------------------------------------------------------------------------- - -if(SUNDIALS_PRECISION MATCHES "extended") - print_error("SUNDIALS MAGMA interface is not compatible with extended precision") -endif() - -# ----------------------------------------------------------------------------- -# Section 3: Find the TPL -# ----------------------------------------------------------------------------- - -find_package(MAGMA REQUIRED) - -message(STATUS "MAGMA_VERSION: ${MAGMA_VERSION}") -message(STATUS "MAGMA_LIBRARIES: ${MAGMA_LIBRARIES}") -message(STATUS "MAGMA_INCLUDE_DIR: ${MAGMA_INCLUDE_DIR}") - -# ----------------------------------------------------------------------------- -# Section 4: Test the TPL -# ----------------------------------------------------------------------------- - -if(SUNDIALS_MAGMA_BACKENDS MATCHES "CUDA" AND NOT ENABLE_CUDA) - print_error("SUNDIALS_MAGMA_BACKENDS includes CUDA but CUDA is not enabled. Set ENABLE_CUDA=ON or change the backend.") -endif() -if(SUNDIALS_MAGMA_BACKENDS MATCHES "HIP" AND NOT ENABLE_HIP) - print_error("SUNDIALS_MAGMA_BACKENDS includes HIP but HIP is not enabled. Set ENABLE_HIP=ON or change the backend.") -endif() - -if(MAGMA_FOUND AND (NOT MAGMA_WORKS)) - # Create the MAGMA_TEST directory - set(MAGMA_TEST_DIR ${PROJECT_BINARY_DIR}/CMakeFiles/MAGMA_TEST) - file(MAKE_DIRECTORY ${MAGMA_TEST_DIR}) - - if(SUNDIALS_MAGMA_BACKENDS MATCHES "HIP") - set(lang CXX) - set(ext cxx) - set(define_have "\#define HAVE_HIP") - set(lib hip::host) - elseif(SUNDIALS_MAGMA_BACKENDS MATCHES "CUDA") - set(lang CUDA) - set(ext cu) - set(define_have "\#define HAVE_CUBLAS") - set(lib ) - endif() - - file(WRITE ${MAGMA_TEST_DIR}/ltest.${ext} - "${define_have}\n" - "\#include \"magma_v2.h\"\n" - "int main(){\n" - "magma_int_t a=0;\n" - "return(a);\n" - "}\n") - - try_compile(COMPILE_OK ${MAGMA_TEST_DIR} ${MAGMA_TEST_DIR}/ltest.${ext} - CMAKE_FLAGS - "-DINCLUDE_DIRECTORIES=${MAGMA_INCLUDE_DIR}" - LINK_LIBRARIES ${MAGMA_LIBRARIES} ${lib} - OUTPUT_VARIABLE COMPILE_OUTPUT - ${lang}_STANDARD ${CMAKE_${lang}_STANDARD} - ) - - # Process test result - if(COMPILE_OK) - message(STATUS "Checking if MAGMA works... OK") - set(MAGMA_WORKS TRUE CACHE BOOL "MAGMA works with SUNDIALS as configured" FORCE) - else() - message(STATUS "Checking if MAGMA works... FAILED") - message(STATUS "Check output: ") - message("${COMPILE_OUTPUT}") - print_error("SUNDIALS interface to MAGMA is not functional.") - endif() -elseif(MAGMA_FOUND AND MAGMA_WORKS) - message(STATUS "Skipped MAGMA tests, assuming MAGMA works with SUNDIALS.") -endif() diff --git a/ThirdParty/sundials/cmake/tpl/SundialsMPI.cmake b/ThirdParty/sundials/cmake/tpl/SundialsMPI.cmake deleted file mode 100644 index ad5d721c04..0000000000 --- a/ThirdParty/sundials/cmake/tpl/SundialsMPI.cmake +++ /dev/null @@ -1,89 +0,0 @@ -# --------------------------------------------------------------------------- -# Programmer(s): David J. Gardner @ LLNL -# --------------------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# --------------------------------------------------------------------------- -# Setup MPI for SUNDIALS CMake-based configuration. -# --------------------------------------------------------------------------- -# Prior to CMake 3.10 the CMake FindMPI module considers: -# 1. Inspect MPI wrappers (MPI__COMPILER) -# 2. Try guesses -# 3. Try the compiler (CMAKE__COMPILER) -# -# Starting with CMake 3.10 the CMake FindMPI module considers: -# 1. Try the compiler (CMAKE__COMPILER) -# 2. Inspect MPI wrappers (MPI__COMPILER) -# 3. Try guesses -# --------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# Section 1: Include guard -# ----------------------------------------------------------------------------- - -if(NOT DEFINED SUNDIALS_MPI_INCLUDED) - set(SUNDIALS_MPI_INCLUDED) -else() - return() -endif() - -# --------------------------------------------------------------------------- -# If MPI__COMPILER is set, FindMPI will try to set the below variables -# for the given compiler wrapper. If MPI__COMPILER is unset FindMPI -# will attempt to locate an installed MPI library and set the below -# variables. -# -# MPI__FOUND TRUE if FindMPI found MPI flags for -# MPI__COMPILER MPI Compiler wrapper for -# MPI__COMPILE_FLAGS Compilation flags for MPI programs -# MPI__INCLUDE_PATH Include path(s) for MPI header -# MPI__LINK_FLAGS Linking flags for MPI programs -# MPI__LIBRARIES All libraries to link MPI programs against -# -# MPIEXEC_EXECUTABLE Executable for running MPI programs -# MPIEXEC_NUMPROC_FLAG Flag to pass to MPIEXEC_EXECUTABLE before -# giving it the number of processors to run on -# MPIEXEC_PREFLAGS Flags to pass to MPIEXEC_EXECUTABLE directly -# before the executable to run. -# MPIEXEC_POSTFLAGS Flags to pass to MPIEXEC_EXECUTABLE after -# other flags -# --------------------------------------------------------------------------- - -mark_as_advanced(MPI_EXTRA_LIBRARY) -mark_as_advanced(MPI_LIBRARY) - -foreach(lang ${_SUNDIALS_ENABLED_LANGS}) - mark_as_advanced(CLEAR MPI_${lang}_COMPILER) - mark_as_advanced(MPI_${lang}_LIBRARIES) - mark_as_advanced(MPI_${lang}_COMPILE_FLAGS) - mark_as_advanced(MPI_${lang}_INCLUDE_PATH) - mark_as_advanced(MPI_${lang}_LIBRARIES) - mark_as_advanced(MPI_${lang}_LINK_FLAGS) -endforeach() - -find_package(MPI 2.0.0 REQUIRED) - -# --------------------------------------------------------------------------- -# Configure the presentation of MPI options in the GUI. -# --------------------------------------------------------------------------- - -mark_as_advanced(CLEAR MPIEXEC_EXECUTABLE) - -mark_as_advanced(MPI_EXTRA_LIBRARY) -mark_as_advanced(MPI_LIBRARY) - -foreach(lang ${_SUNDIALS_ENABLED_LANGS}) - mark_as_advanced(CLEAR MPI_${lang}_COMPILER) - mark_as_advanced(MPI_${lang}_LIBRARIES) - mark_as_advanced(MPI_${lang}_COMPILE_FLAGS) - mark_as_advanced(MPI_${lang}_INCLUDE_PATH) - mark_as_advanced(MPI_${lang}_LIBRARIES) - mark_as_advanced(MPI_${lang}_LINK_FLAGS) -endforeach() diff --git a/ThirdParty/sundials/cmake/tpl/SundialsPETSC.cmake b/ThirdParty/sundials/cmake/tpl/SundialsPETSC.cmake deleted file mode 100644 index 822c763fd4..0000000000 --- a/ThirdParty/sundials/cmake/tpl/SundialsPETSC.cmake +++ /dev/null @@ -1,91 +0,0 @@ -# ----------------------------------------------------------------------------- -# Programmer(s): Cody J. Balos @ LLNL -# ----------------------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# ----------------------------------------------------------------------------- -# Module to find and setup PETSC correctly. -# Created from the SundialsTPL.cmake template. -# All SUNDIALS modules that find and setup a TPL must: -# -# 1. Check to make sure the SUNDIALS configuration and the TPL is compatible. -# 2. Find the TPL. -# 3. Check if the TPL works with SUNDIALS, UNLESS the override option -# TPL_WORKS is TRUE - in this case the tests should not be performed and it -# should be assumed that the TPL works with SUNDIALS. -# ----------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# Section 1: Include guard -# ----------------------------------------------------------------------------- - -if(NOT DEFINED SUNDIALS_PETSC_INCLUDED) - set(SUNDIALS_PETSC_INCLUDED) -else() - return() -endif() - -# ----------------------------------------------------------------------------- -# Section 2: Check to make sure options are compatible -# ----------------------------------------------------------------------------- - -# Using PETSc requires building with MPI enabled -if(ENABLE_PETSC AND NOT ENABLE_MPI) - print_error("MPI is required for PETSc support. Set ENABLE_MPI to ON.") -endif() - -if(SUNDIALS_PRECISION MATCHES "EXTENDED") - print_error("SUNDIALS is not compatible with PETSc when using ${SUNDIALS_PRECISION} precision") -endif() - -# ----------------------------------------------------------------------------- -# Section 3: Find the TPL -# ----------------------------------------------------------------------------- - -find_package(PETSC REQUIRED) - -message(STATUS "PETSC_DIR: ${PETSC_DIR}") -message(STATUS "PETSC_LIBRARIES: ${PETSC_LIBRARIES_}") -message(STATUS "PETSC_INCLUDES: ${PETSC_INCLUDES_}") -message(STATUS "PETSC_INDEX_SIZE: ${PETSC_INDEX_SIZE}") -message(STATUS "PETSC_PRECISION: ${PETSC_PRECISION}\n") - -# ----------------------------------------------------------------------------- -# Section 4: Test the TPL -# ----------------------------------------------------------------------------- - -if(PETSC_FOUND AND (NOT PETSC_WORKS)) - # No need for any compile tests because the FindPETSC module - # does compile tests already. - - if(NOT ("${SUNDIALS_INDEX_SIZE}" MATCHES "${PETSC_INDEX_SIZE}")) - string(CONCAT _err_msg_string - "PETSc not functional due to index size mismatch:\n" - "SUNDIALS_INDEX_SIZE=${SUNDIALS_INDEX_SIZE}, " - "but PETSc was built with ${PETSC_INDEX_SIZE}-bit indices\n" - "PETSC_DIR: ${PETSC_DIR}\n") - print_error("${_err_msg_string}") - endif() - - string(TOUPPER "${PETSC_PRECISION}" _petsc_precision) - string(TOUPPER "${SUNDIALS_PRECISION}" _sundials_precision) - if(NOT ("${_sundials_precision}" MATCHES "${_petsc_precision}")) - string(CONCAT _err_msg_string - "PETSc not functional due to real type precision mismatch:\n" - "SUNDIALS_PRECISION=${_sundials_precision}, " - "but PETSc was built with ${_petsc_precision} precision\n" - "PETSC_DIR: ${PETSC_DIR}\n") - print_error("${_err_msg_string}") - endif() - - set(PETSC_WORKS TRUE CACHE BOOL "PETSC works with SUNDIALS as configured" FORCE) -elseif(PETSC_FOUND AND PETSC_WORKS) - message(STATUS "Skipped PETSC tests, assuming PETSC works with SUNDIALS. Set PETSC_WORKS=FALSE to (re)run compatibility test.") -endif() diff --git a/ThirdParty/sundials/cmake/tpl/SundialsRAJA.cmake b/ThirdParty/sundials/cmake/tpl/SundialsRAJA.cmake deleted file mode 100644 index 4a7a0ab411..0000000000 --- a/ThirdParty/sundials/cmake/tpl/SundialsRAJA.cmake +++ /dev/null @@ -1,87 +0,0 @@ -# ----------------------------------------------------------------------------- -# Programmer(s): Cody J. Balos @ LLNL -# ----------------------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# ----------------------------------------------------------------------------- -# Module to find and setup RAJA correctly. -# Created from the SundialsTPL.cmake template. -# All SUNDIALS modules that find and setup a TPL must: -# -# 1. Check to make sure the SUNDIALS configuration and the TPL is compatible. -# 2. Find the TPL. -# 3. Check if the TPL works with SUNDIALS, UNLESS the override option -# TPL_WORKS is TRUE - in this case the tests should not be performed and it -# should be assumed that the TPL works with SUNDIALS. -# ----------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# Section 1: Include guard -# ----------------------------------------------------------------------------- - -if(NOT DEFINED SUNDIALS_RAJA_INCLUDED) - set(SUNDIALS_RAJA_INCLUDED) -else() - return() -endif() - -# ----------------------------------------------------------------------------- -# Section 2: Check to make sure options are compatible -# ----------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# Section 3: Find the TPL -# ----------------------------------------------------------------------------- - -# find the library configuration file -find_file(RAJA_CONFIGHPP_PATH config.hpp - HINTS "${RAJA_DIR}" - PATH_SUFFIXES include include/RAJA - NO_DEFAULT_PATH) -mark_as_advanced(FORCE RAJA_CONFIGHPP_PATH) - -# Look for CMake configuration file in RAJA installation -find_package(RAJA CONFIG - PATHS "${RAJA_DIR}" "${RAJA_DIR}/share/raja/cmake" - NO_DEFAULT_PATH - REQUIRED) - -# determine the backends -foreach(_backend CUDA HIP OPENMP TARGET_OPENMP) - file(STRINGS "${RAJA_CONFIGHPP_PATH}" _raja_has_backend REGEX "^#define RAJA_ENABLE_${_backend}\$") - if(_raja_has_backend) - set(RAJA_BACKENDS "${_backend};${RAJA_BACKENDS}") - endif() -endforeach() - -message(STATUS "RAJA Version: ${RAJA_VERSION_MAJOR}.${RAJA_VERSION_MINOR}.${RAJA_VERSION_PATCHLEVEL}") -message(STATUS "RAJA Backends: ${RAJA_BACKENDS}") - -# ----------------------------------------------------------------------------- -# Section 4: Test the TPL -# ----------------------------------------------------------------------------- - -if((SUNDIALS_RAJA_BACKENDS MATCHES "CUDA") AND - (NOT RAJA_BACKENDS MATCHES "CUDA")) - print_error("Requested that SUNDIALS uses the CUDA RAJA backend, but RAJA was not built with the CUDA backend.") -endif() - -if((SUNDIALS_RAJA_BACKENDS MATCHES "HIP") AND - (NOT RAJA_BACKENDS MATCHES "HIP")) - print_error("Requested that SUNDIALS uses the HIP RAJA backend, but RAJA was not built with the HIP backend.") -endif() - -if(NOT ENABLE_OPENMP AND RAJA_BACKENDS MATCHES "OPENMP") - print_error("RAJA was built with OpenMP, but OpenMP is not enabled. Set ENABLE_OPENMP to ON.") -endif() - -if(NOT ENABLE_OPENMP_DEVICE AND RAJA_BACKENDS MATCHES "TARGET_OPENMP") - print_error("RAJA was built with OpenMP device offloading, but OpenMP with device offloading is not enabled. Set ENABLE_OPENMP_DEVICE to ON.") -endif() diff --git a/ThirdParty/sundials/cmake/tpl/SundialsTrilinos.cmake b/ThirdParty/sundials/cmake/tpl/SundialsTrilinos.cmake deleted file mode 100644 index e995b0fec8..0000000000 --- a/ThirdParty/sundials/cmake/tpl/SundialsTrilinos.cmake +++ /dev/null @@ -1,140 +0,0 @@ -# ----------------------------------------------------------------------------- -# Programmer(s): Cody J. Balos @ LLNL -# ----------------------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# ----------------------------------------------------------------------------- -# Module to find and setup Trilinos correctly. -# Created from the SundialsTPL.cmake template. -# All SUNDIALS modules that find and setup a TPL must: -# -# 1. Check to make sure the SUNDIALS configuration and the TPL is compatible. -# 2. Find the TPL. -# 3. Check if the TPL works with SUNDIALS, UNLESS the override option -# TPL_WORKS is TRUE - in this case the tests should not be performed and it -# should be assumed that the TPL works with SUNDIALS. -# ----------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# Section 1: Include guard -# ----------------------------------------------------------------------------- - -if(NOT DEFINED SUNDIALS_TRILINOS_INCLUDED) - set(SUNDIALS_TRILINOS_INCLUDED) -else() - return() -endif() - -# ----------------------------------------------------------------------------- -# Section 2: Check to make sure options are compatible -# ----------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# Section 3: Find the TPL -# ----------------------------------------------------------------------------- - -# Find Trilinos -find_package(Trilinos REQUIRED) - -# Check if Trilinos was built with MPI -if(";${Trilinos_TPL_LIST};" MATCHES ";MPI;") - set(Trilinos_MPI TRUE) -else() - set(Trilinos_MPI FALSE) -endif() - -# For XSDK compatibility, only use the user/spack provided compiler and flags to build -# SUNDIALS modules that use Trilinos. If we are not in XSDK mode, we can use the imported -# Trilinos compiler and flags by default, but allow the user to change it through CMake -# the Trilinos_INTERFACE_* options. - -if(USE_XSDK_DEFAULTS) - if(Trilinos_MPI AND MPI_CXX_FOUND) - force_variable(Trilinos_INTERFACE_CXX_COMPILER STRING "C++ compiler for Trilinos interface" "${MPI_CXX_COMPILER}") - set(Trilinos_INTERFACE_MPI_CXX_FOUND ${Trilinos_MPI} CACHE INTERNAL "Is Trilinos interface C++ compiler MPI") - else() - force_variable(Trilinos_INTERFACE_CXX_COMPILER STRING "C compiler for Trilinos interface" "${CMAKE_CXX_COMPILER}") - set(Trilinos_INTERFACE_MPI_CXX_FOUND FALSE CACHE INTERNAL "Is Trilinos interface C++ compiler MPI") - endif() - if(Trilinos_MPI AND MPI_C_FOUND) - force_variable(Trilinos_INTERFACE_C_COMPILER STRING "C compiler for Trilinos interface" "${MPI_C_COMPILER}") - set(Trilinos_INTERFACE_MPI_C_FOUND ${Trilinos_MPI} CACHE INTERNAL "Is Trilinos interface C compiler MPI") - else() - force_variable(Trilinos_INTERFACE_C_COMPILER STRING "C compiler for Trilinos interface" "${CMAKE_C_COMPILER}") - set(Trilinos_INTERFACE_MPI_C_FOUND FALSE CACHE INTERNAL "Is Trilinos interface C compiler MPI") - endif() - force_variable(Trilinos_INTERFACE_CXX_COMPILER_FLAGS STRING "C++ compiler flags specific to Trilinos interface" "") - force_variable(Trilinos_INTERFACE_C_COMPILER_FLAGS STRING "C compiler flags specific to Trilinos interface" "") - force_variable(Trilinos_INTERFACE_MPIEXEC STRING "MPI executable for Trilinos interface" "${MPIEXEC_EXECUTABLE}") -else() - force_variable(Trilinos_INTERFACE_CXX_COMPILER STRING "C++ compiler for Trilinos interface" "${Trilinos_CXX_COMPILER}") - force_variable(Trilinos_INTERFACE_C_COMPILER STRING "C compiler for Trilinos interface" "${Trilinos_C_COMPILER}") - force_variable(Trilinos_INTERFACE_CXX_COMPILER_FLAGS STRING "C++ compiler flags for Trilinos interface" "${Trilinos_CXX_COMPILER_FLAGS}") - force_variable(Trilinos_INTERFACE_C_COMPILER_FLAGS STRING "C compiler flags for Trilinos interface" "${Trilinos_C_COMPILER_FLAGS}") - force_variable(Trilinos_INTERFACE_MPIEXEC STRING "MPI executable for Trilinos interface" "${Trilinos_MPI_EXEC}") - set(Trilinos_INTERFACE_MPI_CXX_FOUND ${Trilinos_MPI} CACHE INTERNAL "Is Trilinos interface C++ compiler MPI") - set(Trilinos_INTERFACE_MPI_C_FOUND ${Trilinos_MPI} CACHE INTERNAL "Is Trilinos interface C compiler MPI") -endif() - -message(STATUS "Trilinos_MPI: ${Trilinos_MPI}") -message(STATUS "Trilinos_LIBRARIES: ${Trilinos_LIBRARIES}") -message(STATUS "Trilinos_INCLUDE_DIRS: ${Trilinos_INCLUDE_DIRS}") - -# ----------------------------------------------------------------------------- -# Section 4: Test the TPL -# ----------------------------------------------------------------------------- - -if(Trilinos_FOUND AND (NOT Trilinos_WORKS)) - # Do any checks which don't require compilation first. - - # Create the Trilinos_TEST directory - set(Trilinos_TEST_DIR ${PROJECT_BINARY_DIR}/Trilinos_TEST) - file(MAKE_DIRECTORY ${Trilinos_TEST_DIR}) - - # Create a CMakeLists.txt file - file(WRITE ${Trilinos_TEST_DIR}/CMakeLists.txt - "CMAKE_MINIMUM_REQUIRED(VERSION 3.1.3)\n" - "PROJECT(ltest CXX)\n" - "SET(CMAKE_VERBOSE_MAKEFILE ON)\n" - "SET(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\")\n" - "SET(CMAKE_CXX_COMPILER \"${Trilinos_INTERFACE_CXX_COMPILER}\")\n" - "SET(CMAKE_CXX_FLAGS \"${Trilinos_INTERFACE_CXX_COMPILER_FLAGS}\")\n" - "SET(Trilinos_DIR \"${Trilinos_DIR}\")\n" - "INCLUDE(FindPackageHandleStandardArgs)\n" - "INCLUDE(${PROJECT_SOURCE_DIR}/cmake/tpl/FindTrilinos.cmake)\n" - "ADD_EXECUTABLE(ltest ltest.cpp)\n" - "TARGET_LINK_LIBRARIES(ltest SUNDIALS::TRILINOS)\n") - - # Create a C++ source file which calls a Trilinos function - file(WRITE ${Trilinos_TEST_DIR}/ltest.cpp - "#include \n" - "int main(){\n" - "std::cout << Tpetra::version() << std::endl;\n" - "return(0);\n" - "}\n") - - # Attempt to build and link the "ltest" executable - try_compile(COMPILE_OK ${Trilinos_TEST_DIR} ${Trilinos_TEST_DIR} ltest - OUTPUT_VARIABLE COMPILE_OUTPUT) - - # Process test result - if(COMPILE_OK) - message(STATUS "Checking if Trilinos works with SUNDIALS... OK") - set(Trilinos_WORKS TRUE CACHE BOOL "Trilinos works with SUNDIALS as configured" FORCE) - else() - message(STATUS "Checking if Trilinos works with SUNDIALS... FAILED") - message(STATUS "Check output: ") - message("${COMPILE_OUTPUT}") - print_error("SUNDIALS interface to Trilinos is not functional.") - endif() - -elseif(Trilinos_FOUND AND Trilinos_WORKS) - message(STATUS "Skipped Trilinos tests, assuming Trilinos works with SUNDIALS. Set Trilinos_WORKS=FALSE to (re)run compatibility test.") -endif() diff --git a/ThirdParty/sundials/cmake/tpl/SundialsXBRAID.cmake b/ThirdParty/sundials/cmake/tpl/SundialsXBRAID.cmake deleted file mode 100644 index 91b99669f2..0000000000 --- a/ThirdParty/sundials/cmake/tpl/SundialsXBRAID.cmake +++ /dev/null @@ -1,129 +0,0 @@ -# ----------------------------------------------------------------------------- -# Programmer(s): David J. Gardner @ LLNL -# ----------------------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# ----------------------------------------------------------------------------- -# Module to find and setup correctly. -# Created from the SundialsTPL.cmake template. -# All SUNDIALS modules that find and setup a TPL must: -# -# 1. Check to make sure the SUNDIALS configuration and the TPL is compatible. -# 2. Find the TPL. -# 3. Check if the TPL works with SUNDIALS, UNLESS the override option -# TPL_WORKS is TRUE - in this case the tests should not be performed and it -# should be assumed that the TPL works with SUNDIALS. -# ----------------------------------------------------------------------------- - -# ----------------------------------------------------------------------------- -# Section 1: Include guard -# ----------------------------------------------------------------------------- - -if(NOT DEFINED SUNDIALS_XBRAID_INCLUDED) - set(SUNDIALS_XBRAID_INCLUDED) -else() - return() -endif() - -# ----------------------------------------------------------------------------- -# Section 2: Check to make sure options are compatible -# ----------------------------------------------------------------------------- - -# Using XBRAID requires building with MPI enabled -if(NOT ENABLE_MPI) - message(FATAL_ERROR - "MPI is required for XBraid support. Set ENABLE_MPI to ON.") -endif() - -# XBraid does not support single or extended precision -if(SUNDIALS_PRECISION MATCHES "SINGLE" OR SUNDIALS_PRECISION MATCHES "EXTENDED") - message(FATAL_ERROR - "XBraid is not compatible with ${SUNDIALS_PRECISION} precision") -endif() - -# XBraid does not support 64-bit index sizes -if(SUNDIALS_INDEX_SIZE MATCHES "64") - message(FATAL_ERROR - "XBraid is not compatible with ${SUNDIALS_INDEX_SIZE}-bit indices") -endif() - -# ----------------------------------------------------------------------------- -# Section 3: Find the TPL -# ----------------------------------------------------------------------------- - -find_package(XBRAID REQUIRED) - -message(STATUS "XBRAID_LIBRARIES: ${XBRAID_LIBS}") -message(STATUS "XBRAID_INCLUDES: ${XBRAID_INCS}") - -# ----------------------------------------------------------------------------- -# Section 4: Test the TPL -# ----------------------------------------------------------------------------- - -# Add works variable - -if(XBRAID_FOUND AND (NOT XBRAID_WORKS)) - - # Create the XBRAID_TEST directory - set(XBRAID_TEST_DIR ${PROJECT_BINARY_DIR}/XBRAID_TEST) - file(MAKE_DIRECTORY ${XBRAID_TEST_DIR}) - - # Create a CMakeLists.txt file - file(WRITE ${XBRAID_TEST_DIR}/CMakeLists.txt - "cmake_minimum_required(VERSION ${CMAKE_VERSION})\n" - "project(ltest C)\n" - "set(CMAKE_VERBOSE_MAKEFILE ON)\n" - "set(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\")\n" - "set(CMAKE_C_COMPILER ${MPI_C_COMPILER})\n" - "set(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS}\")\n" - "set(CMAKE_C_FLAGS_RELEASE \"${CMAKE_C_FLAGS_RELEASE}\")\n" - "set(CMAKE_C_FLAGS_DEBUG \"${CMAKE_C_FLAGS_DEBUG}\")\n" - "set(CMAKE_C_FLAGS_RELWITHDEBUGINFO \"${CMAKE_C_FLAGS_RELWITHDEBUGINFO}\")\n" - "set(CMAKE_C_FLAGS_MINSIZE \"${CMAKE_C_FLAGS_MINSIZE}\")\n" - "add_executable(ltest ltest.c)\n" - "target_include_directories(ltest PRIVATE \"${XBRAID_INCS}\")\n" - "target_link_libraries(ltest \"${XBRAID_LIBS}\")\n" - "target_link_libraries(ltest m)\n") - - # Create a C source file - file(WRITE ${XBRAID_TEST_DIR}/ltest.c - "\#include \n" - "\#include \"braid.h\"\n" - "int main(){\n" - "braid_Int rand;\n" - "rand = braid_Rand();\n" - "if (rand < 0) return 1;\n" - "return 0;\n" - "}\n") - - # To ensure we do not use stuff from the previous attempts, - # we must remove the CMakeFiles directory. - file(REMOVE_RECURSE ${XBRAID_TEST_DIR}/CMakeFiles) - - # Attempt to build and link the "ltest" executable - try_compile(COMPILE_OK ${XBRAID_TEST_DIR} ${XBRAID_TEST_DIR} ltest - OUTPUT_VARIABLE COMPILE_OUTPUT) - - # Process test result - if(COMPILE_OK) - message(STATUS "Checking if XBRAID works... OK") - set(XBRAID_WORKS TRUE CACHE BOOL "XBRAID works as configured" FORCE) - else() - message(STATUS "Checking if XBRAID works... FAILED") - message(STATUS "Check output: ") - message("${COMPILE_OUTPUT}") - message(FATAL_ERROR "XBRAID compile test failed.") - endif() - - message(STATUS "XBRAID tests passed") - -else() - message(STATUS "Skipped XBRAID tests, assuming XBRAID works with SUNDIALS.") -endif() diff --git a/ThirdParty/sundials/include/sunlinsol/sunlinsol_cusolversp_batchqr.h b/ThirdParty/sundials/include/sunlinsol/sunlinsol_cusolversp_batchqr.h deleted file mode 100644 index b4729f1944..0000000000 --- a/ThirdParty/sundials/include/sunlinsol/sunlinsol_cusolversp_batchqr.h +++ /dev/null @@ -1,111 +0,0 @@ -/* ---------------------------------------------------------------------------- - * Programmer(s): Cody J. Balos @ LLNL - * ---------------------------------------------------------------------------- - * Based on work by Donald Wilcox @ LBNL - * ---------------------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - * ---------------------------------------------------------------------------- - * Header file for cuSolverSp batched QR SUNLinearSolver interface. - * ----------------------------------------------------------------------------*/ - -#ifndef _SUNLINSOL_CUSOLVERSP_H -#define _SUNLINSOL_CUSOLVERSP_H - -#include -#include - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * ---------------------------------------------------------------------------- - * PART I: cuSolverSp implementation of SUNLinearSolver - * ---------------------------------------------------------------------------- - */ - -struct _SUNLinearSolverContent_cuSolverSp_batchQR { - int last_flag; /* last return flag */ - booleantype first_factorize; /* is this the first factorization? */ - size_t internal_size; /* size of cusolver internal buffer for Q and R */ - size_t workspace_size; /* size of cusolver memory block for num. factorization */ - cusolverSpHandle_t cusolver_handle; /* cuSolverSp context */ - csrqrInfo_t info; /* opaque cusolver data structure */ - void* workspace; /* memory block used by cusolver */ - const char* desc; /* description of this linear solver */ -}; - -typedef struct _SUNLinearSolverContent_cuSolverSp_batchQR *SUNLinearSolverContent_cuSolverSp_batchQR; - - -/* - * ---------------------------------------------------------------------------- - * PART II: Functions exported by sunlinsol_sludist - * ---------------------------------------------------------------------------- - */ - -SUNDIALS_EXPORT SUNLinearSolver SUNLinSol_cuSolverSp_batchQR(N_Vector y, SUNMatrix A, - cusolverSpHandle_t cusol_handle); - - -/* - * ---------------------------------------------------------------------------- - * cuSolverSp implementations of SUNLinearSolver operations - * ---------------------------------------------------------------------------- - */ - -SUNDIALS_EXPORT SUNLinearSolver_Type SUNLinSolGetType_cuSolverSp_batchQR(SUNLinearSolver S); - -SUNDIALS_EXPORT SUNLinearSolver_ID SUNLinSolGetID_cuSolverSp_batchQR(SUNLinearSolver S); - -SUNDIALS_EXPORT int SUNLinSolInitialize_cuSolverSp_batchQR(SUNLinearSolver S); - -SUNDIALS_EXPORT int SUNLinSolSetup_cuSolverSp_batchQR(SUNLinearSolver S, - SUNMatrix A); - -SUNDIALS_EXPORT int SUNLinSolSolve_cuSolverSp_batchQR(SUNLinearSolver S, - SUNMatrix A, - N_Vector x, - N_Vector b, - realtype tol); - -SUNDIALS_EXPORT sunindextype SUNLinSolLastFlag_cuSolverSp_batchQR(SUNLinearSolver S); - -SUNDIALS_EXPORT int SUNLinSolFree_cuSolverSp_batchQR(SUNLinearSolver S); - - -/* - * ---------------------------------------------------------------------------- - * Additional get and set functions. - * ---------------------------------------------------------------------------- - */ - -SUNDIALS_EXPORT void SUNLinSol_cuSolverSp_batchQR_GetDescription(SUNLinearSolver S, - char** desc); - -SUNDIALS_EXPORT void SUNLinSol_cuSolverSp_batchQR_SetDescription(SUNLinearSolver S, - const char* desc); - -SUNDIALS_EXPORT void SUNLinSol_cuSolverSp_batchQR_GetDeviceSpace(SUNLinearSolver S, - size_t* cuSolverInternal, - size_t* cuSolverWorkspace); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ThirdParty/sundials/include/sunmatrix/sunmatrix_cusparse.h b/ThirdParty/sundials/include/sunmatrix/sunmatrix_cusparse.h deleted file mode 100644 index 458413826e..0000000000 --- a/ThirdParty/sundials/include/sunmatrix/sunmatrix_cusparse.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * ----------------------------------------------------------------- - * Programmer(s): Cody J. Balos @ LLNL - * ----------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - * ----------------------------------------------------------------- - * This is the header file is for the cuSPARSE implementation of the - * SUNMATRIX module. - * ----------------------------------------------------------------- - */ - -#ifndef _SUNMATRIX_CUSPARSE_H -#define _SUNMATRIX_CUSPARSE_H - -#include - -#include -#include - -#include -#include -#include - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -/* ------------------------------------------ - * Implementation of SUNMATRIX_CUSPARSE - * ------------------------------------------ */ - -/* storage formats */ -#define SUNMAT_CUSPARSE_CSR 0 -#define SUNMAT_CUSPARSE_BCSR 1 - -struct _SUNMatrix_Content_cuSparse { - int M; - int N; - int NNZ; - int nblocks; - int blockrows; - int blockcols; - int blocknnz; - int sparse_type; - booleantype own_matd; - booleantype own_exec; - booleantype fixed_pattern; - booleantype matvec_issetup; - SUNMemory colind; - SUNMemory rowptrs; - SUNMemory data; - SUNMemoryHelper mem_helper; - cusparseMatDescr_t mat_descr; -#if CUDART_VERSION >= 11000 - SUNMemory dBufferMem; - size_t bufferSize; - cusparseDnVecDescr_t vecX, vecY; - cusparseSpMatDescr_t spmat_descr; -#endif - cusparseHandle_t cusp_handle; - SUNCudaExecPolicy* exec_policy; -}; - -typedef struct _SUNMatrix_Content_cuSparse *SUNMatrix_Content_cuSparse; - -/* ------------------------------------------------------------------ - * Constructors. - * ------------------------------------------------------------------ */ - -SUNDIALS_EXPORT SUNMatrix SUNMatrix_cuSparse_NewCSR(int M, int N, int NNZ, cusparseHandle_t cusp); -SUNDIALS_EXPORT SUNMatrix SUNMatrix_cuSparse_MakeCSR(cusparseMatDescr_t mat_descr, int M, int N, int NNZ, - int *rowptrs , int *colind , realtype *data, - cusparseHandle_t cusp); - -/* Creates a CSR block-diagonal matrix where each block shares the same sparsity structure. - Reduces memory usage by only storing the row pointers and column indices for one block. */ -SUNDIALS_EXPORT SUNMatrix SUNMatrix_cuSparse_NewBlockCSR(int nblocks, int blockrows, int blockcols, - int blocknnz, cusparseHandle_t cusp); - - -/* ------------------------------------------------------------------ - * Implementation specific routines. - * ------------------------------------------------------------------ */ - -SUNDIALS_EXPORT int SUNMatrix_cuSparse_SparseType(SUNMatrix A); -SUNDIALS_EXPORT int SUNMatrix_cuSparse_Rows(SUNMatrix A); -SUNDIALS_EXPORT int SUNMatrix_cuSparse_Columns(SUNMatrix A); -SUNDIALS_EXPORT int SUNMatrix_cuSparse_NNZ(SUNMatrix A); -SUNDIALS_EXPORT int* SUNMatrix_cuSparse_IndexPointers(SUNMatrix A); -SUNDIALS_EXPORT int* SUNMatrix_cuSparse_IndexValues(SUNMatrix A); -SUNDIALS_EXPORT realtype* SUNMatrix_cuSparse_Data(SUNMatrix A); - -SUNDIALS_EXPORT int SUNMatrix_cuSparse_SetFixedPattern(SUNMatrix A, booleantype yesno); -SUNDIALS_EXPORT int SUNMatrix_cuSparse_SetKernelExecPolicy(SUNMatrix A, SUNCudaExecPolicy* exec_policy); -SUNDIALS_EXPORT int SUNMatrix_cuSparse_NumBlocks(SUNMatrix A); -SUNDIALS_EXPORT int SUNMatrix_cuSparse_BlockRows(SUNMatrix A); -SUNDIALS_EXPORT int SUNMatrix_cuSparse_BlockColumns(SUNMatrix A); -SUNDIALS_EXPORT int SUNMatrix_cuSparse_BlockNNZ(SUNMatrix A); -SUNDIALS_EXPORT realtype* SUNMatrix_cuSparse_BlockData(SUNMatrix A, int blockidx); -SUNDIALS_EXPORT cusparseMatDescr_t SUNMatrix_cuSparse_MatDescr(SUNMatrix A); -SUNDIALS_EXPORT int SUNMatrix_cuSparse_CopyToDevice(SUNMatrix device, realtype* h_data, - int* h_idxptrs, int* h_idxvals); -SUNDIALS_EXPORT int SUNMatrix_cuSparse_CopyFromDevice(SUNMatrix device, realtype* h_data, - int* h_idxptrs, int* h_idxvals); - - -/* ------------------------------------------------------------------ - * SUNMatrix API routines. - * ------------------------------------------------------------------ */ - -SUNDIALS_EXPORT SUNMatrix_ID SUNMatGetID_cuSparse(SUNMatrix A); -SUNDIALS_EXPORT SUNMatrix SUNMatClone_cuSparse(SUNMatrix A); -SUNDIALS_EXPORT void SUNMatDestroy_cuSparse(SUNMatrix A); -SUNDIALS_EXPORT int SUNMatZero_cuSparse(SUNMatrix A); -SUNDIALS_EXPORT int SUNMatCopy_cuSparse(SUNMatrix A, SUNMatrix B); -SUNDIALS_EXPORT int SUNMatScaleAdd_cuSparse(realtype c, SUNMatrix A, SUNMatrix B); -SUNDIALS_EXPORT int SUNMatScaleAddI_cuSparse(realtype c, SUNMatrix A); -SUNDIALS_EXPORT int SUNMatMatvecSetup_cuSparse(SUNMatrix A); -SUNDIALS_EXPORT int SUNMatMatvec_cuSparse(SUNMatrix A, N_Vector x, N_Vector y); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ThirdParty/sundials/src/kinsol/CMakeLists.txt b/ThirdParty/sundials/src/kinsol/CMakeLists.txt deleted file mode 100644 index e6bb1a9079..0000000000 --- a/ThirdParty/sundials/src/kinsol/CMakeLists.txt +++ /dev/null @@ -1,81 +0,0 @@ -# --------------------------------------------------------------- -# Programmer(s): Daniel R. Reynolds @ SMU -# Radu Serban, Cody J. Balos @ LLNL -# --------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# --------------------------------------------------------------- -# CMakeLists.txt file for the KINSOL library -# --------------------------------------------------------------- - -install(CODE "MESSAGE(\"\nInstall KINSOL\n\")") - -# Add variable kinsol_SOURCES with the sources for the KINSOL library -set(kinsol_SOURCES - kinsol.c - kinsol_bbdpre.c - kinsol_direct.c - kinsol_io.c - kinsol_ls.c - kinsol_spils.c - ) - -# Add variable kinsol_HEADERS with the exported KINSOL header files -set(kinsol_HEADERS - kinsol.h - kinsol_bbdpre.h - kinsol_direct.h - kinsol_ls.h - kinsol_spils.h - ) - -# Add prefix with complete path to the KINSOL header files -add_prefix(${SUNDIALS_SOURCE_DIR}/include/kinsol/ kinsol_HEADERS) - -# Create the library -sundials_add_library(sundials_kinsol - SOURCES - ${kinsol_SOURCES} - HEADERS - ${kinsol_HEADERS} - INCLUDE_SUBDIR - kinsol - OBJECT_LIBRARIES - sundials_generic_obj - sundials_nvecserial_obj - sundials_sunmatrixband_obj - sundials_sunmatrixdense_obj - sundials_sunmatrixsparse_obj - sundials_sunlinsolband_obj - sundials_sunlinsoldense_obj - sundials_sunlinsolspbcgs_obj - sundials_sunlinsolspfgmr_obj - sundials_sunlinsolspgmr_obj - sundials_sunlinsolsptfqmr_obj - sundials_sunlinsolpcg_obj - OUTPUT_NAME - sundials_kinsol - VERSION - ${kinsollib_VERSION} - SOVERSION - ${kinsollib_SOVERSION} -) - -# Finished KINSOL -message(STATUS "Added KINSOL module") - -# Add F2003 module if the interface is enabled -if(BUILD_FORTRAN_MODULE_INTERFACE) - add_subdirectory(fmod) -endif() - -if(BUILD_FORTRAN77_INTERFACE) - add_subdirectory(fcmix) -endif() diff --git a/ThirdParty/sundials/src/kinsol/LICENSE b/ThirdParty/sundials/src/kinsol/LICENSE deleted file mode 100644 index 4ba2c48483..0000000000 --- a/ThirdParty/sundials/src/kinsol/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -BSD 3-Clause License - -Copyright (c) 2002-2021, Lawrence Livermore National Security and Southern Methodist University. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ThirdParty/sundials/src/kinsol/NOTICE b/ThirdParty/sundials/src/kinsol/NOTICE deleted file mode 100644 index 329b142ee6..0000000000 --- a/ThirdParty/sundials/src/kinsol/NOTICE +++ /dev/null @@ -1,21 +0,0 @@ -This work was produced under the auspices of the U.S. Department of -Energy by Lawrence Livermore National Laboratory under Contract -DE-AC52-07NA27344. - -This work was prepared as an account of work sponsored by an agency of -the United States Government. Neither the United States Government nor -Lawrence Livermore National Security, LLC, nor any of their employees -makes any warranty, expressed or implied, or assumes any legal liability -or responsibility for the accuracy, completeness, or usefulness of any -information, apparatus, product, or process disclosed, or represents that -its use would not infringe privately owned rights. - -Reference herein to any specific commercial product, process, or service -by trade name, trademark, manufacturer, or otherwise does not necessarily -constitute or imply its endorsement, recommendation, or favoring by the -United States Government or Lawrence Livermore National Security, LLC. - -The views and opinions of authors expressed herein do not necessarily -state or reflect those of the United States Government or Lawrence -Livermore National Security, LLC, and shall not be used for advertising -or product endorsement purposes. \ No newline at end of file diff --git a/ThirdParty/sundials/src/kinsol/README.md b/ThirdParty/sundials/src/kinsol/README.md deleted file mode 100644 index 2f73f75ff8..0000000000 --- a/ThirdParty/sundials/src/kinsol/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# KINSOL -### Version 5.7.0 (Jan 2021) - -**Alan C. Hindmarsh, Radu Serban, Cody J. Balos, David J. Gardner, - and Carol S. Woodward, Center for Applied Scientific Computing, LLNL** - -**Daniel R. Reynolds, Department of Mathematics, Southern Methodist University** - - -KINSOL is a package for the solution for nonlinear algebraic systems -``` -F(u) = 0. -``` -Nonlinear solver methods available include Newton-Krylov, Picard, and -fixed-point. Both Picard and fixed point can be accelerated with Anderson -acceleration. - -KINSOL is part of the SUNDIALS Suite of Nonlinear and Differential/Algebraic -equation Solvers which consists of ARKode, CVODE, CVODES, IDA, IDAS and KINSOL. -It is written in ANSI standard C, but is based on the previous Fortran package -NKSOL, written by Peter Brown and Youcef Saad. KINSOL can be used in a variety -of computing environments including serial, shared memory, distributed memory, -and accelerator-based (e.g., GPU) systems. This flexibility is obtained from a -modular design that leverages the shared vector, matrix, and linear solver APIs -used across SUNDIALS packages. - -For use with Fortran applications, a set of Fortran/C interface routines, called -FKINSOL, is also supplied. These are written in C, but assume that the user -calling program and all user-supplied routines are in Fortran. - -## Documentation - -See the [KINSOL User Guide](/doc/kinsol/kin_guide.pdf) and -[KINSOL Examples](/doc/kinsol/kin_examples.pdf) document for more information -about IDA usage and the provided example programs respectively. - -## Installation - -For installation instructions see the [INSTALL_GUIDE](/INSTALL_GUIDE.pdf) -or the "Installation Procedure" chapter in the KINSOL User Guide. - -## Release History - -Information on recent changes to KINSOL can be found in the "Introduction" -chapter of the KINSOL User Guide and a complete release history is available in -the "SUNDIALS Release History" appendix of the KINSOL User Guide. - -## References - -* A. C. Hindmarsh, R. Serban, C. J. Balos, D. J. Gardner, - D. R. Reynolds and C. S. Woodward, - "User Documentation for KINSOL v5.7.0," LLNL technical report - UCRL-SM-208116, Jan 2021. - -* A. M. Collier and R. Serban, "Example Programs for KINSOL v5.7.0," - LLNL technical report UCRL-SM-208114, Jan 2021. - -* A. C. Hindmarsh, P. N. Brown, K. E. Grant, S. L. Lee, R. Serban, - D. E. Shumaker, and C. S. Woodward, "SUNDIALS, Suite of Nonlinear and - Differential/Algebraic Equation Solvers," ACM Trans. Math. Softw., - 31(3), pp. 363-396, 2005. - -* Peter N. Brown and Youcef Saad, "Hybrid Krylov Methods for - Nonlinear Systems of Equations," SIAM J. Sci. Stat. Comput., - Vol 11, no 3, pp. 450-481, May 1990. - -* A. G. Taylor and A. C. Hindmarsh, "User Documentation for KINSOL, - A Nonlinear Solver for Sequential and Parallel Computers," LLNL - technical report UCRL-ID-131185, July 1998. diff --git a/ThirdParty/sundials/src/kinsol/kinsol.c b/ThirdParty/sundials/src/kinsol/kinsol.c deleted file mode 100644 index 5d6e994232..0000000000 --- a/ThirdParty/sundials/src/kinsol/kinsol.c +++ /dev/null @@ -1,2702 +0,0 @@ -/* - * ----------------------------------------------------------------- - * Programmer(s): Allan Taylor, Alan Hindmarsh, Radu Serban, Carol Woodward, - * John Loffeld, and Aaron Collier @ LLNL - * ----------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - * ----------------------------------------------------------------- - * This is the implementation file for the main KINSol solver. - * It is independent of the KINSol linear solver in use. - * ----------------------------------------------------------------- - * - * EXPORTED FUNCTIONS - * ------------------ - * Creation and allocation functions - * KINCreate - * KINInit - * Main solver function - * KINSol - * Deallocation function - * KINFree - * - * PRIVATE FUNCTIONS - * ----------------- - * KINCheckNvector - * Memory allocation/deallocation - * KINAllocVectors - * KINFreeVectors - * Initial setup - * KINSolInit - * Step functions - * KINLinSolDrv - * KINFullNewton - * KINLineSearch - * KINConstraint - * KINFP - * KINPicardAA - * Stopping tests - * KINStop - * KINForcingTerm - * Norm functions - * KINScFNorm - * KINScSNorm - * KINSOL Verbose output functions - * KINPrintInfo - * KINInfoHandler - * KINSOL Error Handling functions - * KINProcessError - * KINErrHandler - * ----------------------------------------------------------------- - */ - -/* - * ================================================================= - * IMPORTED HEADER FILES - * ================================================================= - */ - -#include -#include -#include -#include - -#include - -#include "kinsol_impl.h" -#include - -/* - * ================================================================= - * KINSOL PRIVATE CONSTANTS - * ================================================================= - */ - -#define HALF RCONST(0.5) -#define ZERO RCONST(0.0) -#define ONE RCONST(1.0) -#define ONEPT5 RCONST(1.5) -#define TWO RCONST(2.0) -#define THREE RCONST(3.0) -#define FIVE RCONST(5.0) -#define TWELVE RCONST(12.0) -#define POINT1 RCONST(0.1) -#define POINT01 RCONST(0.01) -#define POINT99 RCONST(0.99) -#define THOUSAND RCONST(1000.0) -#define ONETHIRD RCONST(0.3333333333333333) -#define TWOTHIRDS RCONST(0.6666666666666667) -#define POINT9 RCONST(0.9) -#define POINT0001 RCONST(0.0001) - -/* - * ================================================================= - * KINSOL ROUTINE-SPECIFIC CONSTANTS - * ================================================================= - */ - -/* - * Control constants for lower-level functions used by KINSol - * ---------------------------------------------------------- - * - * KINStop return value requesting more iterations - * RETRY_ITERATION - * CONTINUE_ITERATIONS - * - * KINFullNewton, KINLineSearch, KINFP, and KINPicardAA return values: - * KIN_SUCCESS - * KIN_SYSFUNC_FAIL - * STEP_TOO_SMALL - * - * KINConstraint return values: - * KIN_SUCCESS - * CONSTR_VIOLATED - */ - -#define RETRY_ITERATION -998 -#define CONTINUE_ITERATIONS -999 -#define STEP_TOO_SMALL -997 -#define CONSTR_VIOLATED -996 - -/* - * Algorithmic constants - * --------------------- - * - * MAX_RECVR max. no. of attempts to correct a recoverable func error - */ - -#define MAX_RECVR 5 - -/* - * Keys for KINPrintInfo - * --------------------- - */ - -#define PRNT_RETVAL 1 -#define PRNT_NNI 2 -#define PRNT_TOL 3 -#define PRNT_FMAX 4 -#define PRNT_PNORM 5 -#define PRNT_PNORM1 6 -#define PRNT_FNORM 7 -#define PRNT_LAM 8 -#define PRNT_ALPHA 9 -#define PRNT_BETA 10 -#define PRNT_ALPHABETA 11 -#define PRNT_ADJ 12 - -/* - * ================================================================= - * PRIVATE FUNCTION PROTOTYPES - * ================================================================= - */ - -static booleantype KINCheckNvector(N_Vector tmpl); -static booleantype KINAllocVectors(KINMem kin_mem, N_Vector tmpl); -static int KINSolInit(KINMem kin_mem); -static int KINConstraint(KINMem kin_mem ); -static void KINForcingTerm(KINMem kin_mem, realtype fnormp); -static void KINFreeVectors(KINMem kin_mem); - -static int KINFullNewton(KINMem kin_mem, realtype *fnormp, - realtype *f1normp, booleantype *maxStepTaken); -static int KINLineSearch(KINMem kin_mem, realtype *fnormp, - realtype *f1normp, booleantype *maxStepTaken); -static int KINPicardAA(KINMem kin_mem, long int *iter, realtype *R, - realtype *gamma, realtype *fmax); -static int KINFP(KINMem kin_mem); - -static int KINLinSolDrv(KINMem kinmem); -static int KINPicardFcnEval(KINMem kin_mem, N_Vector gval, N_Vector uval, - N_Vector fval1); -static realtype KINScFNorm(KINMem kin_mem, N_Vector v, N_Vector scale); -static realtype KINScSNorm(KINMem kin_mem, N_Vector v, N_Vector u); -static int KINStop(KINMem kin_mem, booleantype maxStepTaken, - int sflag); -static int AndersonAcc(KINMem kin_mem, N_Vector gval, N_Vector fv, N_Vector x, - N_Vector x_old, long int iter, realtype *R, realtype *gamma); - -/* - * ================================================================= - * EXPORTED FUNCTIONS IMPLEMENTATION - * ================================================================= - */ - -/* - * ----------------------------------------------------------------- - * Creation and allocation functions - * ----------------------------------------------------------------- - */ - -/* - * Function : KINCreate - * - * KINCreate creates an internal memory block for a problem to - * be solved by KINSOL. If successful, KINCreate returns a pointer - * to the problem memory. This pointer should be passed to - * KINInit. If an initialization error occurs, KINCreate prints - * an error message to standard error and returns NULL. - */ - -void *KINCreate(void) -{ - KINMem kin_mem; - realtype uround; - - kin_mem = NULL; - kin_mem = (KINMem) malloc(sizeof(struct KINMemRec)); - if (kin_mem == NULL) { - KINProcessError(kin_mem, 0, "KINSOL", "KINCreate", MSG_MEM_FAIL); - return(NULL); - } - - /* Zero out kin_mem */ - memset(kin_mem, 0, sizeof(struct KINMemRec)); - - /* set uround (unit roundoff) */ - - kin_mem->kin_uround = uround = UNIT_ROUNDOFF; - - /* set default values for solver optional inputs */ - - kin_mem->kin_func = NULL; - kin_mem->kin_user_data = NULL; - kin_mem->kin_uu = NULL; - kin_mem->kin_unew = NULL; - kin_mem->kin_fval = NULL; - kin_mem->kin_gval = NULL; - kin_mem->kin_uscale = NULL; - kin_mem->kin_fscale = NULL; - kin_mem->kin_pp = NULL; - kin_mem->kin_constraints = NULL; - kin_mem->kin_vtemp1 = NULL; - kin_mem->kin_vtemp2 = NULL; - kin_mem->kin_fold_aa = NULL; - kin_mem->kin_gold_aa = NULL; - kin_mem->kin_df_aa = NULL; - kin_mem->kin_dg_aa = NULL; - kin_mem->kin_q_aa = NULL; - kin_mem->kin_gamma_aa = NULL; - kin_mem->kin_R_aa = NULL; - kin_mem->kin_ipt_map = NULL; - kin_mem->kin_cv = NULL; - kin_mem->kin_Xv = NULL; - kin_mem->kin_lmem = NULL; - kin_mem->kin_m_aa = 0; - kin_mem->kin_aamem_aa = 0; - kin_mem->kin_setstop_aa = 0; - kin_mem->kin_beta_aa = ONE; - kin_mem->kin_damping_aa = SUNFALSE; - kin_mem->kin_constraintsSet = SUNFALSE; - kin_mem->kin_ehfun = KINErrHandler; - kin_mem->kin_eh_data = kin_mem; - kin_mem->kin_errfp = stderr; - kin_mem->kin_ihfun = KINInfoHandler; - kin_mem->kin_ih_data = kin_mem; - kin_mem->kin_infofp = stdout; - kin_mem->kin_printfl = PRINTFL_DEFAULT; - kin_mem->kin_mxiter = MXITER_DEFAULT; - kin_mem->kin_noInitSetup = SUNFALSE; - kin_mem->kin_msbset = MSBSET_DEFAULT; - kin_mem->kin_noResMon = SUNFALSE; - kin_mem->kin_msbset_sub = MSBSET_SUB_DEFAULT; - kin_mem->kin_update_fnorm_sub = SUNFALSE; - kin_mem->kin_mxnbcf = MXNBCF_DEFAULT; - kin_mem->kin_sthrsh = TWO; - kin_mem->kin_noMinEps = SUNFALSE; - kin_mem->kin_mxnstepin = ZERO; - kin_mem->kin_sqrt_relfunc = SUNRsqrt(uround); - kin_mem->kin_scsteptol = SUNRpowerR(uround,TWOTHIRDS); - kin_mem->kin_fnormtol = SUNRpowerR(uround,ONETHIRD); - kin_mem->kin_etaflag = KIN_ETACHOICE1; - kin_mem->kin_eta = POINT1; /* default for KIN_ETACONSTANT */ - kin_mem->kin_eta_alpha = TWO; /* default for KIN_ETACHOICE2 */ - kin_mem->kin_eta_gamma = POINT9; /* default for KIN_ETACHOICE2 */ - kin_mem->kin_MallocDone = SUNFALSE; - kin_mem->kin_eval_omega = SUNTRUE; - kin_mem->kin_omega = ZERO; /* default to using min/max */ - kin_mem->kin_omega_min = OMEGA_MIN; - kin_mem->kin_omega_max = OMEGA_MAX; - - /* initialize lrw and liw */ - - kin_mem->kin_lrw = 17; - kin_mem->kin_liw = 22; - - /* NOTE: needed since KINInit could be called after KINSetConstraints */ - - kin_mem->kin_lrw1 = 0; - kin_mem->kin_liw1 = 0; - - return((void *) kin_mem); -} - -/* - * Function : KINInit - * - * KINInit allocates memory for a problem or execution of KINSol. - * If memory is successfully allocated, KIN_SUCCESS is returned. - * Otherwise, an error message is printed and an error flag - * returned. - */ - -int KINInit(void *kinmem, KINSysFn func, N_Vector tmpl) -{ - sunindextype liw1, lrw1; - KINMem kin_mem; - booleantype allocOK, nvectorOK; - - /* check kinmem */ - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINInit", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - kin_mem = (KINMem) kinmem; - - if (func == NULL) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINInit", MSG_FUNC_NULL); - return(KIN_ILL_INPUT); - } - - /* check if all required vector operations are implemented */ - - nvectorOK = KINCheckNvector(tmpl); - if (!nvectorOK) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINInit", MSG_BAD_NVECTOR); - return(KIN_ILL_INPUT); - } - - /* set space requirements for one N_Vector */ - - if (tmpl->ops->nvspace != NULL) { - N_VSpace(tmpl, &lrw1, &liw1); - kin_mem->kin_lrw1 = lrw1; - kin_mem->kin_liw1 = liw1; - } - else { - kin_mem->kin_lrw1 = 0; - kin_mem->kin_liw1 = 0; - } - - /* allocate necessary vectors */ - - allocOK = KINAllocVectors(kin_mem, tmpl); - if (!allocOK) { - KINProcessError(kin_mem, KIN_MEM_FAIL, "KINSOL", "KINInit", MSG_MEM_FAIL); - free(kin_mem); kin_mem = NULL; - return(KIN_MEM_FAIL); - } - - /* copy the input parameter into KINSol state */ - - kin_mem->kin_func = func; - - /* set the linear solver addresses to NULL */ - - kin_mem->kin_linit = NULL; - kin_mem->kin_lsetup = NULL; - kin_mem->kin_lsolve = NULL; - kin_mem->kin_lfree = NULL; - kin_mem->kin_lmem = NULL; - - /* problem memory has been successfully allocated */ - - kin_mem->kin_MallocDone = SUNTRUE; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Main solver function - * ----------------------------------------------------------------- - */ - -/* - * Function : KINSol - * - * KINSol (main KINSOL driver routine) manages the computational - * process of computing an approximate solution of the nonlinear - * system F(uu) = 0. The KINSol routine calls the following - * subroutines: - * - * KINSolInit checks if initial guess satisfies user-supplied - * constraints and initializes linear solver - * - * KINLinSolDrv interfaces with linear solver to find a - * solution of the system J(uu)*x = b (calculate - * Newton step) - * - * KINFullNewton/KINLineSearch implement the global strategy - * - * KINForcingTerm computes the forcing term (eta) - * - * KINStop determines if an approximate solution has been found - */ - -int KINSol(void *kinmem, N_Vector u, int strategy_in, - N_Vector u_scale, N_Vector f_scale) -{ - realtype fnormp, f1normp, epsmin, fmax=ZERO; - KINMem kin_mem; - int ret, sflag; - booleantype maxStepTaken; - - /* intialize to avoid compiler warning messages */ - - maxStepTaken = SUNFALSE; - f1normp = fnormp = -ONE; - - /* initialize epsmin to avoid compiler warning message */ - - epsmin = ZERO; - - /* check for kinmem non-NULL */ - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSol", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - kin_mem = (KINMem) kinmem; - - if(kin_mem->kin_MallocDone == SUNFALSE) { - KINProcessError(NULL, KIN_NO_MALLOC, "KINSOL", "KINSol", MSG_NO_MALLOC); - return(KIN_NO_MALLOC); - } - - /* load input arguments */ - - kin_mem->kin_uu = u; - kin_mem->kin_uscale = u_scale; - kin_mem->kin_fscale = f_scale; - kin_mem->kin_globalstrategy = strategy_in; - - /* CSW: - Call fixed point solver if requested. Note that this should probably - be forked off to a FPSOL solver instead of kinsol in the future. */ - if ( kin_mem->kin_globalstrategy == KIN_FP ) { - if (kin_mem->kin_uu == NULL) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSol", MSG_UU_NULL); - return(KIN_ILL_INPUT); - } - - if (kin_mem->kin_constraintsSet != SUNFALSE) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSol", MSG_CONSTRAINTS_NOTOK); - return(KIN_ILL_INPUT); - } - - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_TOL, "KINSOL", "KINSol", INFO_TOL, kin_mem->kin_scsteptol, kin_mem->kin_fnormtol); - - kin_mem->kin_nfe = kin_mem->kin_nnilset = kin_mem->kin_nnilset_sub = kin_mem->kin_nni = kin_mem->kin_nbcf = kin_mem->kin_nbktrk = 0; - ret = KINFP(kin_mem); - - switch(ret) { - case KIN_SYSFUNC_FAIL: - KINProcessError(kin_mem, KIN_SYSFUNC_FAIL, "KINSOL", "KINSol", MSG_SYSFUNC_FAILED); - break; - case KIN_MAXITER_REACHED: - KINProcessError(kin_mem, KIN_MAXITER_REACHED, "KINSOL", "KINSol", MSG_MAXITER_REACHED); - break; - } - - return(ret); - } - - /* initialize solver */ - ret = KINSolInit(kin_mem); - if (ret != KIN_SUCCESS) return(ret); - - kin_mem->kin_ncscmx = 0; - - /* Note: The following logic allows the choice of whether or not - to force a call to the linear solver setup upon a given call to - KINSol */ - - if (kin_mem->kin_noInitSetup) kin_mem->kin_sthrsh = ONE; - else kin_mem->kin_sthrsh = TWO; - - /* if eps is to be bounded from below, set the bound */ - - if (kin_mem->kin_inexact_ls && !(kin_mem->kin_noMinEps)) - epsmin = POINT01 * kin_mem->kin_fnormtol; - - - /* if omega is zero at this point, make sure it will be evaluated - at each iteration based on the provided min/max bounds and the - current function norm. */ - if (kin_mem->kin_omega == ZERO) kin_mem->kin_eval_omega = SUNTRUE; - else kin_mem->kin_eval_omega = SUNFALSE; - - - /* CSW: - Call fixed point solver for Picard method if requested. - Note that this should probably be forked off to a part of an - FPSOL solver instead of kinsol in the future. */ - if ( kin_mem->kin_globalstrategy == KIN_PICARD ) { - - if (kin_mem->kin_gval == NULL) { - kin_mem->kin_gval = N_VClone(kin_mem->kin_unew); - if (kin_mem->kin_gval == NULL) { - KINProcessError(kin_mem, KIN_MEM_FAIL, "KINSOL", "KINSol", MSG_MEM_FAIL); - return(KIN_MEM_FAIL); - } - kin_mem->kin_liw += kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_lrw1; - } - ret = KINPicardAA(kin_mem, &(kin_mem->kin_nni), kin_mem->kin_R_aa, kin_mem->kin_gamma_aa, &fmax); - - return(ret); - } - - - for(;;){ - - kin_mem->kin_retry_nni = SUNFALSE; - - kin_mem->kin_nni++; - - /* calculate the epsilon (stopping criteria for iterative linear solver) - for this iteration based on eta from the routine KINForcingTerm */ - - if (kin_mem->kin_inexact_ls) { - kin_mem->kin_eps = (kin_mem->kin_eta + kin_mem->kin_uround) * kin_mem->kin_fnorm; - if(!(kin_mem->kin_noMinEps)) kin_mem->kin_eps = SUNMAX(epsmin, kin_mem->kin_eps); - } - - repeat_nni: - - /* call the appropriate routine to calculate an acceptable step pp */ - - sflag = 0; - - if (kin_mem->kin_globalstrategy == KIN_NONE) { - - /* Full Newton Step*/ - - /* call KINLinSolDrv to calculate the (approximate) Newton step, pp */ - ret = KINLinSolDrv(kin_mem); - if (ret != KIN_SUCCESS) break; - - sflag = KINFullNewton(kin_mem, &fnormp, &f1normp, &maxStepTaken); - - /* if sysfunc failed unrecoverably, stop */ - if ((sflag == KIN_SYSFUNC_FAIL) || (sflag == KIN_REPTD_SYSFUNC_ERR)) { - ret = sflag; - break; - } - - } else if (kin_mem->kin_globalstrategy == KIN_LINESEARCH) { - - /* Line Search */ - - /* call KINLinSolDrv to calculate the (approximate) Newton step, pp */ - ret = KINLinSolDrv(kin_mem); - if (ret != KIN_SUCCESS) break; - - sflag = KINLineSearch(kin_mem, &fnormp, &f1normp, &maxStepTaken); - - /* if sysfunc failed unrecoverably, stop */ - if ((sflag == KIN_SYSFUNC_FAIL) || (sflag == KIN_REPTD_SYSFUNC_ERR)) { - ret = sflag; - break; - } - - /* if too many beta condition failures, then stop iteration */ - if (kin_mem->kin_nbcf > kin_mem->kin_mxnbcf) { - ret = KIN_LINESEARCH_BCFAIL; - break; - } - - } - - if ( (kin_mem->kin_globalstrategy != KIN_PICARD) && - (kin_mem->kin_globalstrategy != KIN_FP) ) { - - /* evaluate eta by calling the forcing term routine */ - if (kin_mem->kin_callForcingTerm) KINForcingTerm(kin_mem, fnormp); - - kin_mem->kin_fnorm = fnormp; - - /* call KINStop to check if tolerances where met by this iteration */ - ret = KINStop(kin_mem, maxStepTaken, sflag); - - if (ret == RETRY_ITERATION) { - kin_mem->kin_retry_nni = SUNTRUE; - goto repeat_nni; - } - } - - /* update uu after the iteration */ - N_VScale(ONE, kin_mem->kin_unew, kin_mem->kin_uu); - - kin_mem->kin_f1norm = f1normp; - - /* print the current nni, fnorm, and nfe values if printfl > 0 */ - - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_NNI, "KINSOL", "KINSol", INFO_NNI, kin_mem->kin_nni, kin_mem->kin_nfe, kin_mem->kin_fnorm); - - if (ret != CONTINUE_ITERATIONS) break; - - fflush(kin_mem->kin_errfp); - - } /* end of loop; return */ - - - - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_RETVAL, "KINSOL", "KINSol", INFO_RETVAL, ret); - - switch(ret) { - case KIN_SYSFUNC_FAIL: - KINProcessError(kin_mem, KIN_SYSFUNC_FAIL, "KINSOL", "KINSol", MSG_SYSFUNC_FAILED); - break; - case KIN_REPTD_SYSFUNC_ERR: - KINProcessError(kin_mem, KIN_REPTD_SYSFUNC_ERR, "KINSOL", "KINSol", MSG_SYSFUNC_REPTD); - break; - case KIN_LSETUP_FAIL: - KINProcessError(kin_mem, KIN_LSETUP_FAIL, "KINSOL", "KINSol", MSG_LSETUP_FAILED); - break; - case KIN_LSOLVE_FAIL: - KINProcessError(kin_mem, KIN_LSOLVE_FAIL, "KINSOL", "KINSol", MSG_LSOLVE_FAILED); - break; - case KIN_LINSOLV_NO_RECOVERY: - KINProcessError(kin_mem, KIN_LINSOLV_NO_RECOVERY, "KINSOL", "KINSol", MSG_LINSOLV_NO_RECOVERY); - break; - case KIN_LINESEARCH_NONCONV: - KINProcessError(kin_mem, KIN_LINESEARCH_NONCONV, "KINSOL", "KINSol", MSG_LINESEARCH_NONCONV); - break; - case KIN_LINESEARCH_BCFAIL: - KINProcessError(kin_mem, KIN_LINESEARCH_BCFAIL, "KINSOL", "KINSol", MSG_LINESEARCH_BCFAIL); - break; - case KIN_MAXITER_REACHED: - KINProcessError(kin_mem, KIN_MAXITER_REACHED, "KINSOL", "KINSol", MSG_MAXITER_REACHED); - break; - case KIN_MXNEWT_5X_EXCEEDED: - KINProcessError(kin_mem, KIN_MXNEWT_5X_EXCEEDED, "KINSOL", "KINSol", MSG_MXNEWT_5X_EXCEEDED); - break; - } - - return(ret); -} - -/* - * ----------------------------------------------------------------- - * Deallocation function - * ----------------------------------------------------------------- - */ - -/* - * Function : KINFree - * - * This routine frees the problem memory allocated by KINInit. - * Such memory includes all the vectors allocated by - * KINAllocVectors, and the memory lmem for the linear solver - * (deallocated by a call to lfree). - */ - -void KINFree(void **kinmem) -{ - KINMem kin_mem; - - if (*kinmem == NULL) return; - - kin_mem = (KINMem) (*kinmem); - KINFreeVectors(kin_mem); - - /* call lfree if non-NULL */ - - if (kin_mem->kin_lfree != NULL) kin_mem->kin_lfree(kin_mem); - - free(*kinmem); - *kinmem = NULL; -} - -/* - * ================================================================= - * PRIVATE FUNCTIONS - * ================================================================= - */ - -/* - * Function : KINCheckNvector - * - * This routine checks if all required vector operations are - * implemented (excluding those required by KINConstraint). If all - * necessary operations are present, then KINCheckNvector returns - * SUNTRUE. Otherwise, SUNFALSE is returned. - */ - -static booleantype KINCheckNvector(N_Vector tmpl) -{ - if ((tmpl->ops->nvclone == NULL) || - (tmpl->ops->nvdestroy == NULL) || - (tmpl->ops->nvlinearsum == NULL) || - (tmpl->ops->nvprod == NULL) || - (tmpl->ops->nvdiv == NULL) || - (tmpl->ops->nvscale == NULL) || - (tmpl->ops->nvabs == NULL) || - (tmpl->ops->nvinv == NULL) || - (tmpl->ops->nvmaxnorm == NULL) || - (tmpl->ops->nvmin == NULL) || - (tmpl->ops->nvwl2norm == NULL)) return(SUNFALSE); - else return(SUNTRUE); -} - -/* - * ----------------------------------------------------------------- - * Memory allocation/deallocation - * ----------------------------------------------------------------- - */ - -/* - * Function : KINAllocVectors - * - * This routine allocates the KINSol vectors. If all memory - * allocations are successful, KINAllocVectors returns SUNTRUE. - * Otherwise all allocated memory is freed and KINAllocVectors - * returns SUNFALSE. - */ - -static booleantype KINAllocVectors(KINMem kin_mem, N_Vector tmpl) -{ - /* allocate unew, fval, pp, vtemp1 and vtemp2. */ - /* allocate df, dg, q, for Anderson Acceleration, Broyden and EN */ - - if (kin_mem->kin_unew == NULL) { - kin_mem->kin_unew = N_VClone(tmpl); - if (kin_mem->kin_unew == NULL) return(SUNFALSE); - kin_mem->kin_liw += kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_lrw1; - } - - if (kin_mem->kin_fval == NULL) { - kin_mem->kin_fval = N_VClone(tmpl); - if (kin_mem->kin_fval == NULL) { - N_VDestroy(kin_mem->kin_unew); - kin_mem->kin_liw -= kin_mem->kin_liw1; - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - return(SUNFALSE); - } - kin_mem->kin_liw += kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_lrw1; - } - - if (kin_mem->kin_pp == NULL) { - kin_mem->kin_pp = N_VClone(tmpl); - if (kin_mem->kin_pp == NULL) { - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - kin_mem->kin_liw -= 2*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 2*kin_mem->kin_lrw1; - return(SUNFALSE); - } - kin_mem->kin_liw += kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_lrw1; - } - - if (kin_mem->kin_vtemp1 == NULL) { - kin_mem->kin_vtemp1 = N_VClone(tmpl); - if (kin_mem->kin_vtemp1 == NULL) { - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - kin_mem->kin_liw -= 3*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 3*kin_mem->kin_lrw1; - return(SUNFALSE); - } - kin_mem->kin_liw += kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_lrw1; - } - - if (kin_mem->kin_vtemp2 == NULL) { - kin_mem->kin_vtemp2 = N_VClone(tmpl); - if (kin_mem->kin_vtemp2 == NULL) { - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - kin_mem->kin_liw -= 4*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 4*kin_mem->kin_lrw1; - return(SUNFALSE); - } - kin_mem->kin_liw += kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_lrw1; - } - - /* Vectors for Anderson acceleration */ - - if (kin_mem->kin_m_aa) { - - if (kin_mem->kin_R_aa == NULL) { - kin_mem->kin_R_aa = (realtype *) malloc((kin_mem->kin_m_aa*kin_mem->kin_m_aa) * sizeof(realtype)); - if (kin_mem->kin_R_aa == NULL) { - KINProcessError(kin_mem, 0, "KINSOL", "KINAllocVectors", MSG_MEM_FAIL); - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - N_VDestroy(kin_mem->kin_vtemp2); - kin_mem->kin_liw -= 5*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 5*kin_mem->kin_lrw1; - return(KIN_MEM_FAIL); - } - } - - if (kin_mem->kin_gamma_aa == NULL) { - kin_mem->kin_gamma_aa = (realtype *) malloc(kin_mem->kin_m_aa * sizeof(realtype)); - if (kin_mem->kin_gamma_aa == NULL) { - KINProcessError(kin_mem, 0, "KINSOL", "KINAllocVectors", MSG_MEM_FAIL); - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - N_VDestroy(kin_mem->kin_vtemp2); - free(kin_mem->kin_R_aa); - kin_mem->kin_liw -= 5*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 5*kin_mem->kin_lrw1; - return(KIN_MEM_FAIL); - } - } - - if (kin_mem->kin_ipt_map == NULL) { - kin_mem->kin_ipt_map = (long int *) malloc(kin_mem->kin_m_aa * sizeof(long int)); - if (kin_mem->kin_ipt_map == NULL) { - KINProcessError(kin_mem, 0, "KINSOL", "KINAllocVectors", MSG_MEM_FAIL); - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - N_VDestroy(kin_mem->kin_vtemp2); - free(kin_mem->kin_R_aa); - free(kin_mem->kin_gamma_aa); - kin_mem->kin_liw -= 5*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 5*kin_mem->kin_lrw1; - return(KIN_MEM_FAIL); - } - } - - if (kin_mem->kin_cv == NULL) { - kin_mem->kin_cv = (realtype *) malloc(2 * (kin_mem->kin_m_aa+1) * sizeof(realtype)); - if (kin_mem->kin_cv == NULL) { - KINProcessError(kin_mem, 0, "KINSOL", "KINAllocVectors", MSG_MEM_FAIL); - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - N_VDestroy(kin_mem->kin_vtemp2); - free(kin_mem->kin_R_aa); - free(kin_mem->kin_gamma_aa); - free(kin_mem->kin_ipt_map); - kin_mem->kin_liw -= 5*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 5*kin_mem->kin_lrw1; - return(KIN_MEM_FAIL); - } - } - - if (kin_mem->kin_Xv == NULL) { - kin_mem->kin_Xv = (N_Vector *) malloc(2 * (kin_mem->kin_m_aa+1) * sizeof(N_Vector)); - if (kin_mem->kin_Xv == NULL) { - KINProcessError(kin_mem, 0, "KINSOL", "KINAllocVectors", MSG_MEM_FAIL); - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - N_VDestroy(kin_mem->kin_vtemp2); - free(kin_mem->kin_R_aa); - free(kin_mem->kin_gamma_aa); - free(kin_mem->kin_ipt_map); - free(kin_mem->kin_cv); - kin_mem->kin_liw -= 5*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 5*kin_mem->kin_lrw1; - return(KIN_MEM_FAIL); - } - } - - if (kin_mem->kin_fold_aa == NULL) { - kin_mem->kin_fold_aa = N_VClone(tmpl); - if (kin_mem->kin_fold_aa == NULL) { - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - N_VDestroy(kin_mem->kin_vtemp2); - free(kin_mem->kin_R_aa); - free(kin_mem->kin_gamma_aa); - free(kin_mem->kin_ipt_map); - free(kin_mem->kin_cv); - free(kin_mem->kin_Xv); - kin_mem->kin_liw -= 5*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 5*kin_mem->kin_lrw1; - return(SUNFALSE); - } - kin_mem->kin_liw += kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_lrw1; - } - - if (kin_mem->kin_gold_aa == NULL) { - kin_mem->kin_gold_aa = N_VClone(tmpl); - if (kin_mem->kin_gold_aa == NULL) { - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - N_VDestroy(kin_mem->kin_vtemp2); - free(kin_mem->kin_R_aa); - free(kin_mem->kin_gamma_aa); - free(kin_mem->kin_ipt_map); - free(kin_mem->kin_cv); - free(kin_mem->kin_Xv); - N_VDestroy(kin_mem->kin_fold_aa); - kin_mem->kin_liw -= 6*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 6*kin_mem->kin_lrw1; - return(SUNFALSE); - } - kin_mem->kin_liw += kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_lrw1; - } - - if (kin_mem->kin_df_aa == NULL) { - kin_mem->kin_df_aa = N_VCloneVectorArray((int) kin_mem->kin_m_aa,tmpl); - if (kin_mem->kin_df_aa == NULL) { - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - N_VDestroy(kin_mem->kin_vtemp2); - free(kin_mem->kin_R_aa); - free(kin_mem->kin_gamma_aa); - free(kin_mem->kin_ipt_map); - free(kin_mem->kin_cv); - free(kin_mem->kin_Xv); - N_VDestroy(kin_mem->kin_fold_aa); - N_VDestroy(kin_mem->kin_gold_aa); - kin_mem->kin_liw -= 7*kin_mem->kin_liw1; - kin_mem->kin_lrw -= 7*kin_mem->kin_lrw1; - return(SUNFALSE); - } - kin_mem->kin_liw += kin_mem->kin_m_aa * kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_m_aa * kin_mem->kin_lrw1; - } - - if (kin_mem->kin_dg_aa == NULL) { - kin_mem->kin_dg_aa = N_VCloneVectorArray((int) kin_mem->kin_m_aa,tmpl); - if (kin_mem->kin_dg_aa == NULL) { - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - N_VDestroy(kin_mem->kin_vtemp2); - free(kin_mem->kin_R_aa); - free(kin_mem->kin_gamma_aa); - free(kin_mem->kin_ipt_map); - free(kin_mem->kin_cv); - free(kin_mem->kin_Xv); - N_VDestroy(kin_mem->kin_fold_aa); - N_VDestroy(kin_mem->kin_gold_aa); - N_VDestroyVectorArray(kin_mem->kin_df_aa, (int) kin_mem->kin_m_aa); - kin_mem->kin_liw -= (7 + kin_mem->kin_m_aa) * kin_mem->kin_liw1; - kin_mem->kin_lrw -= (7 + kin_mem->kin_m_aa) * kin_mem->kin_lrw1; - return(SUNFALSE); - } - kin_mem->kin_liw += kin_mem->kin_m_aa * kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_m_aa * kin_mem->kin_lrw1; - } - - if (kin_mem->kin_q_aa == NULL) { - kin_mem->kin_q_aa = N_VCloneVectorArray((int) kin_mem->kin_m_aa,tmpl); - if (kin_mem->kin_q_aa == NULL) { - N_VDestroy(kin_mem->kin_unew); - N_VDestroy(kin_mem->kin_fval); - N_VDestroy(kin_mem->kin_pp); - N_VDestroy(kin_mem->kin_vtemp1); - N_VDestroy(kin_mem->kin_vtemp2); - free(kin_mem->kin_R_aa); - free(kin_mem->kin_gamma_aa); - free(kin_mem->kin_ipt_map); - free(kin_mem->kin_cv); - free(kin_mem->kin_Xv); - N_VDestroy(kin_mem->kin_fold_aa); - N_VDestroy(kin_mem->kin_gold_aa); - N_VDestroyVectorArray(kin_mem->kin_df_aa, (int) kin_mem->kin_m_aa); - N_VDestroyVectorArray(kin_mem->kin_dg_aa, (int) kin_mem->kin_m_aa); - kin_mem->kin_liw -= (7 + 2 * kin_mem->kin_m_aa) * kin_mem->kin_liw1; - kin_mem->kin_lrw -= (7 + 2 * kin_mem->kin_m_aa) * kin_mem->kin_lrw1; - return(SUNFALSE); - } - kin_mem->kin_liw += kin_mem->kin_m_aa * kin_mem->kin_liw1; - kin_mem->kin_lrw += kin_mem->kin_m_aa * kin_mem->kin_lrw1; - } - } - - return(SUNTRUE); -} - -/* - * KINFreeVectors - * - * This routine frees the KINSol vectors allocated by - * KINAllocVectors. - */ - -static void KINFreeVectors(KINMem kin_mem) -{ - if (kin_mem->kin_unew != NULL) { - N_VDestroy(kin_mem->kin_unew); - kin_mem->kin_unew = NULL; - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_liw1; - } - - if (kin_mem->kin_fval != NULL) { - N_VDestroy(kin_mem->kin_fval); - kin_mem->kin_fval = NULL; - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_liw1; - } - - if (kin_mem->kin_pp != NULL) { - N_VDestroy(kin_mem->kin_pp); - kin_mem->kin_pp = NULL; - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_liw1; - } - - if (kin_mem->kin_vtemp1 != NULL) { - N_VDestroy(kin_mem->kin_vtemp1); - kin_mem->kin_vtemp1 = NULL; - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_liw1; - } - - if (kin_mem->kin_vtemp2 != NULL) { - N_VDestroy(kin_mem->kin_vtemp2); - kin_mem->kin_vtemp2 = NULL; - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_liw1; - } - - if (kin_mem->kin_gval != NULL) { - N_VDestroy(kin_mem->kin_gval); - kin_mem->kin_gval = NULL; - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_liw1; - } - - if (kin_mem->kin_R_aa != NULL) { - free(kin_mem->kin_R_aa); - kin_mem->kin_R_aa = NULL; - } - - if (kin_mem->kin_gamma_aa != NULL) { - free(kin_mem->kin_gamma_aa); - kin_mem->kin_gamma_aa = NULL; - } - - if (kin_mem->kin_ipt_map != NULL) { - free(kin_mem->kin_ipt_map); - kin_mem->kin_ipt_map = NULL; - } - - if (kin_mem->kin_cv != NULL) { - free(kin_mem->kin_cv); - kin_mem->kin_cv = NULL; - } - - if (kin_mem->kin_Xv != NULL) { - free(kin_mem->kin_Xv); - kin_mem->kin_Xv = NULL; - } - - if (kin_mem->kin_fold_aa != NULL) { - N_VDestroy(kin_mem->kin_fold_aa); - kin_mem->kin_fold_aa = NULL; - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_liw1; - } - - if (kin_mem->kin_gold_aa != NULL) { - N_VDestroy(kin_mem->kin_gold_aa); - kin_mem->kin_gold_aa = NULL; - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_liw1; - } - - if (kin_mem->kin_df_aa != NULL) { - N_VDestroyVectorArray(kin_mem->kin_df_aa, (int) kin_mem->kin_m_aa); - kin_mem->kin_df_aa = NULL; - kin_mem->kin_lrw -= kin_mem->kin_m_aa * kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_m_aa * kin_mem->kin_liw1; - } - - if (kin_mem->kin_dg_aa != NULL) { - N_VDestroyVectorArray(kin_mem->kin_dg_aa, (int) kin_mem->kin_m_aa); - kin_mem->kin_dg_aa = NULL; - kin_mem->kin_lrw -= kin_mem->kin_m_aa * kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_m_aa * kin_mem->kin_liw1; - } - - if (kin_mem->kin_q_aa != NULL) { - N_VDestroyVectorArray(kin_mem->kin_q_aa, (int) kin_mem->kin_m_aa); - kin_mem->kin_q_aa = NULL; - kin_mem->kin_lrw -= kin_mem->kin_m_aa * kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_m_aa * kin_mem->kin_liw1; - } - - if (kin_mem->kin_constraints != NULL) { - N_VDestroy(kin_mem->kin_constraints); - kin_mem->kin_constraints = NULL; - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_liw1; - } - - return; -} - -/* - * ----------------------------------------------------------------- - * Initial setup - * ----------------------------------------------------------------- - */ - -/* - * KINSolInit - * - * KINSolInit initializes the problem for the specific input - * received in this call to KINSol (which calls KINSolInit). All - * problem specification inputs are checked for errors. If any error - * occurs during initialization, it is reported to the file whose - * file pointer is errfp. - * - * The possible return values for KINSolInit are: - * KIN_SUCCESS : indicates a normal initialization - * - * KIN_ILL_INPUT : indicates that an input error has been found - * - * KIN_INITIAL_GUESS_OK : indicates that the guess uu - * satisfied the system func(uu) = 0 - * within the tolerances specified - */ - -static int KINSolInit(KINMem kin_mem) -{ - int retval; - realtype fmax; - - /* check for illegal input parameters */ - - if (kin_mem->kin_uu == NULL) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_UU_NULL); - return(KIN_ILL_INPUT); - } - - /* check for valid strategy */ - - if ( (kin_mem->kin_globalstrategy != KIN_NONE) && - (kin_mem->kin_globalstrategy != KIN_LINESEARCH) && - (kin_mem->kin_globalstrategy != KIN_PICARD) && - (kin_mem->kin_globalstrategy != KIN_FP) ) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_BAD_GLSTRAT); - return(KIN_ILL_INPUT); - } - - if (kin_mem->kin_uscale == NULL) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_BAD_USCALE); - return(KIN_ILL_INPUT); - } - - if (N_VMin(kin_mem->kin_uscale) <= ZERO){ - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_USCALE_NONPOSITIVE); - return(KIN_ILL_INPUT); - } - - if (kin_mem->kin_fscale == NULL) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_BAD_FSCALE); - return(KIN_ILL_INPUT); - } - - if (N_VMin(kin_mem->kin_fscale) <= ZERO){ - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_FSCALE_NONPOSITIVE); - return(KIN_ILL_INPUT); - } - - if ( (kin_mem->kin_constraints != NULL) && - ( (kin_mem->kin_globalstrategy == KIN_PICARD) || - (kin_mem->kin_globalstrategy == KIN_FP) ) ) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_CONSTRAINTS_NOTOK); - return(KIN_ILL_INPUT); - } - - - /* set the constraints flag */ - - if (kin_mem->kin_constraints == NULL) - kin_mem->kin_constraintsSet = SUNFALSE; - else { - kin_mem->kin_constraintsSet = SUNTRUE; - if ((kin_mem->kin_constraints->ops->nvconstrmask == NULL) || - (kin_mem->kin_constraints->ops->nvminquotient == NULL)) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_BAD_NVECTOR); - return(KIN_ILL_INPUT); - } - } - - /* check the initial guess uu against the constraints */ - - if (kin_mem->kin_constraintsSet) { - if (!N_VConstrMask(kin_mem->kin_constraints, kin_mem->kin_uu, kin_mem->kin_vtemp1)) { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINSOL", "KINSolInit", MSG_INITIAL_CNSTRNT); - return(KIN_ILL_INPUT); - } - } - - /* all error checking is complete at this point */ - - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_TOL, "KINSOL", "KINSolInit", INFO_TOL, kin_mem->kin_scsteptol, kin_mem->kin_fnormtol); - - /* calculate the default value for mxnewtstep (maximum Newton step) */ - - if (kin_mem->kin_mxnstepin == ZERO) kin_mem->kin_mxnewtstep = THOUSAND * N_VWL2Norm(kin_mem->kin_uu, kin_mem->kin_uscale); - else kin_mem->kin_mxnewtstep = kin_mem->kin_mxnstepin; - - if (kin_mem->kin_mxnewtstep < ONE) kin_mem->kin_mxnewtstep = ONE; - - /* additional set-up for inexact linear solvers */ - - if (kin_mem->kin_inexact_ls) { - - /* set up the coefficients for the eta calculation */ - - kin_mem->kin_callForcingTerm = (kin_mem->kin_etaflag != KIN_ETACONSTANT); - - /* this value is always used for choice #1 */ - - if (kin_mem->kin_etaflag == KIN_ETACHOICE1) kin_mem->kin_eta_alpha = (ONE + SUNRsqrt(FIVE)) * HALF; - - /* initial value for eta set to 0.5 for other than the - KIN_ETACONSTANT option */ - - if (kin_mem->kin_etaflag != KIN_ETACONSTANT) kin_mem->kin_eta = HALF; - - /* disable residual monitoring if using an inexact linear solver */ - - kin_mem->kin_noResMon = SUNTRUE; - - } else { - - kin_mem->kin_callForcingTerm = SUNFALSE; - - } - - /* initialize counters */ - - kin_mem->kin_nfe = kin_mem->kin_nnilset = kin_mem->kin_nnilset_sub = kin_mem->kin_nni = kin_mem->kin_nbcf = kin_mem->kin_nbktrk = 0; - - /* see if the initial guess uu satisfies the nonlinear system */ - retval = kin_mem->kin_func(kin_mem->kin_uu, kin_mem->kin_fval, kin_mem->kin_user_data); kin_mem->kin_nfe++; - - if (retval < 0) { - KINProcessError(kin_mem, KIN_SYSFUNC_FAIL, "KINSOL", "KINSolInit", - MSG_SYSFUNC_FAILED); - return(KIN_SYSFUNC_FAIL); - } else if (retval > 0) { - KINProcessError(kin_mem, KIN_FIRST_SYSFUNC_ERR, "KINSOL", "KINSolInit", - MSG_SYSFUNC_FIRST); - return(KIN_FIRST_SYSFUNC_ERR); - } - - fmax = KINScFNorm(kin_mem, kin_mem->kin_fval, kin_mem->kin_fscale); - if (fmax <= (POINT01 * kin_mem->kin_fnormtol)) { - kin_mem->kin_fnorm = N_VWL2Norm(kin_mem->kin_fval, kin_mem->kin_fscale); - return(KIN_INITIAL_GUESS_OK); - } - - if (kin_mem->kin_printfl > 1) - KINPrintInfo(kin_mem, PRNT_FMAX, "KINSOL", "KINSolInit", INFO_FMAX, fmax); - - /* initialize the linear solver if linit != NULL */ - - if (kin_mem->kin_linit != NULL) { - retval = kin_mem->kin_linit(kin_mem); - if (retval != 0) { - KINProcessError(kin_mem, KIN_LINIT_FAIL, "KINSOL", "KINSolInit", MSG_LINIT_FAIL); - return(KIN_LINIT_FAIL); - } - } - - /* initialize the L2 (Euclidean) norms of f for the linear iteration steps */ - - kin_mem->kin_fnorm = N_VWL2Norm(kin_mem->kin_fval, kin_mem->kin_fscale); - kin_mem->kin_f1norm = HALF * kin_mem->kin_fnorm * kin_mem->kin_fnorm; - kin_mem->kin_fnorm_sub = kin_mem->kin_fnorm; - - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_NNI, "KINSOL", "KINSolInit", - INFO_NNI, kin_mem->kin_nni, kin_mem->kin_nfe, kin_mem->kin_fnorm); - - /* problem has now been successfully initialized */ - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Step functions - * ----------------------------------------------------------------- - */ - -/* - * KINLinSolDrv - * - * This routine handles the process of solving for the approximate - * solution of the Newton equations in the Newton iteration. - * Subsequent routines handle the nonlinear aspects of its - * application. - */ - -static int KINLinSolDrv(KINMem kin_mem) -{ - N_Vector x, b; - int retval; - - if ((kin_mem->kin_nni - kin_mem->kin_nnilset) >= kin_mem->kin_msbset) { - kin_mem->kin_sthrsh = TWO; - kin_mem->kin_update_fnorm_sub = SUNTRUE; - } - - for(;;){ - - kin_mem->kin_jacCurrent = SUNFALSE; - - if ((kin_mem->kin_sthrsh > ONEPT5) && (kin_mem->kin_lsetup != NULL)) { - retval = kin_mem->kin_lsetup(kin_mem); - kin_mem->kin_jacCurrent = SUNTRUE; - kin_mem->kin_nnilset = kin_mem->kin_nni; - kin_mem->kin_nnilset_sub = kin_mem->kin_nni; - if (retval != 0) return(KIN_LSETUP_FAIL); - } - - /* rename vectors for readability */ - - b = kin_mem->kin_unew; - x = kin_mem->kin_pp; - - /* load b with the current value of -fval */ - - N_VScale(-ONE, kin_mem->kin_fval, b); - - /* call the generic 'lsolve' routine to solve the system Jx = b */ - - retval = kin_mem->kin_lsolve(kin_mem, x, b, &(kin_mem->kin_sJpnorm), - &(kin_mem->kin_sFdotJp)); - - if (retval == 0) return(KIN_SUCCESS); - else if (retval < 0) return(KIN_LSOLVE_FAIL); - else if ((kin_mem->kin_lsetup == NULL) || (kin_mem->kin_jacCurrent)) return(KIN_LINSOLV_NO_RECOVERY); - - /* loop back only if the linear solver setup is in use - and Jacobian information is not current */ - - kin_mem->kin_sthrsh = TWO; - - } -} - -/* - * KINFullNewton - * - * This routine is the main driver for the Full Newton - * algorithm. Its purpose is to compute unew = uu + pp in the - * direction pp from uu, taking the full Newton step. The - * step may be constrained if the constraint conditions are - * violated, or if the norm of pp is greater than mxnewtstep. - */ - -static int KINFullNewton(KINMem kin_mem, realtype *fnormp, realtype *f1normp, - booleantype *maxStepTaken) -{ - realtype pnorm, ratio; - booleantype fOK; - int ircvr, retval; - - *maxStepTaken = SUNFALSE; - pnorm = N_VWL2Norm(kin_mem->kin_pp, kin_mem->kin_uscale); - ratio = ONE; - if (pnorm > kin_mem->kin_mxnewtstep) { - ratio = kin_mem->kin_mxnewtstep / pnorm; - N_VScale(ratio, kin_mem->kin_pp, kin_mem->kin_pp); - pnorm = kin_mem->kin_mxnewtstep; - } - - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_PNORM, "KINSOL", "KINFullNewton", INFO_PNORM, pnorm); - - /* If constraints are active, then constrain the step accordingly */ - - kin_mem->kin_stepl = pnorm; - kin_mem->kin_stepmul = ONE; - if (kin_mem->kin_constraintsSet) { - retval = KINConstraint(kin_mem); - if (retval == CONSTR_VIOLATED) { - /* Apply stepmul set in KINConstraint */ - ratio *= kin_mem->kin_stepmul; - N_VScale(kin_mem->kin_stepmul, kin_mem->kin_pp, kin_mem->kin_pp); - pnorm *= kin_mem->kin_stepmul; - kin_mem->kin_stepl = pnorm; - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_PNORM, "KINSOL", "KINFullNewton", INFO_PNORM, pnorm); - if (pnorm <= kin_mem->kin_scsteptol) { - N_VLinearSum(ONE, kin_mem->kin_uu, ONE, kin_mem->kin_pp, kin_mem->kin_unew); - return(STEP_TOO_SMALL);} - } - } - - /* Attempt (at most MAX_RECVR times) to evaluate function at the new iterate */ - - fOK = SUNFALSE; - - for (ircvr = 1; ircvr <= MAX_RECVR; ircvr++) { - - /* compute the iterate unew = uu + pp */ - N_VLinearSum(ONE, kin_mem->kin_uu, ONE, kin_mem->kin_pp, kin_mem->kin_unew); - - /* evaluate func(unew) and its norm, and return */ - retval = kin_mem->kin_func(kin_mem->kin_unew, kin_mem->kin_fval, kin_mem->kin_user_data); kin_mem->kin_nfe++; - - /* if func was successful, accept pp */ - if (retval == 0) {fOK = SUNTRUE; break;} - - /* if func failed unrecoverably, give up */ - else if (retval < 0) return(KIN_SYSFUNC_FAIL); - - /* func failed recoverably; cut step in half and try again */ - ratio *= HALF; - N_VScale(HALF, kin_mem->kin_pp, kin_mem->kin_pp); - pnorm *= HALF; - kin_mem->kin_stepl = pnorm; - } - - /* If func() failed recoverably MAX_RECVR times, give up */ - - if (!fOK) return(KIN_REPTD_SYSFUNC_ERR); - - /* Evaluate function norms */ - - *fnormp = N_VWL2Norm(kin_mem->kin_fval, kin_mem->kin_fscale); - *f1normp = HALF * (*fnormp) * (*fnormp); - - /* scale sFdotJp and sJpnorm by ratio for later use in KINForcingTerm */ - - kin_mem->kin_sFdotJp *= ratio; - kin_mem->kin_sJpnorm *= ratio; - - if (kin_mem->kin_printfl > 1) - KINPrintInfo(kin_mem, PRNT_FNORM, "KINSOL", "KINFullNewton", INFO_FNORM, *fnormp); - - if (pnorm > (POINT99 * kin_mem->kin_mxnewtstep)) *maxStepTaken = SUNTRUE; - - return(KIN_SUCCESS); -} - -/* - * KINLineSearch - * - * The routine KINLineSearch implements the LineSearch algorithm. - * Its purpose is to find unew = uu + rl * pp in the direction pp - * from uu so that: - * t - * func(unew) <= func(uu) + alpha * g (unew - uu) (alpha = 1.e-4) - * - * and - * t - * func(unew) >= func(uu) + beta * g (unew - uu) (beta = 0.9) - * - * where 0 < rlmin <= rl <= rlmax. - * - * Note: - * mxnewtstep - * rlmax = ---------------- if uu+pp is feasible - * ||uscale*pp||_L2 - * - * rlmax = 1 otherwise - * - * and - * - * scsteptol - * rlmin = -------------------------- - * || pp || - * || -------------------- ||_L-infinity - * || (1/uscale + SUNRabs(uu)) || - * - * - * If the system function fails unrecoverably at any time, KINLineSearch - * returns KIN_SYSFUNC_FAIL which will halt the solver. - * - * We attempt to corect recoverable system function failures only before - * the alpha-condition loop; i.e. when the solution is updated with the - * full Newton step (possibly reduced due to constraint violations). - * Once we find a feasible pp, we assume that any update up to pp is - * feasible. - * - * If the step size is limited due to constraint violations and/or - * recoverable system function failures, we set rlmax=1 to ensure - * that the update remains feasible during the attempts to enforce - * the beta-condition (this is not an issue while enforcing the alpha - * condition, as rl can only decrease from 1 at that stage) - */ - -static int KINLineSearch(KINMem kin_mem, realtype *fnormp, realtype *f1normp, - booleantype *maxStepTaken) -{ - realtype pnorm, ratio, slpi, rlmin, rlength, rl, rlmax, rldiff; - realtype rltmp, rlprev, pt1trl, f1nprv, rllo, rlinc, alpha, beta; - realtype alpha_cond, beta_cond, rl_a, tmp1, rl_b, tmp2, disc; - int ircvr, nbktrk_l, retval; - booleantype firstBacktrack, fOK; - - /* Initializations */ - - nbktrk_l = 0; /* local backtracking counter */ - ratio = ONE; /* step change ratio */ - alpha = POINT0001; - beta = POINT9; - - firstBacktrack = SUNTRUE; - *maxStepTaken = SUNFALSE; - - rlprev = f1nprv = ZERO; - - /* Compute length of Newton step */ - - pnorm = N_VWL2Norm(kin_mem->kin_pp, kin_mem->kin_uscale); - rlmax = kin_mem->kin_mxnewtstep / pnorm; - kin_mem->kin_stepl = pnorm; - - /* If the full Newton step is too large, set it to the maximum allowable value */ - - if(pnorm > kin_mem->kin_mxnewtstep ) { - ratio = kin_mem->kin_mxnewtstep / pnorm; - N_VScale(ratio, kin_mem->kin_pp, kin_mem->kin_pp); - pnorm = kin_mem->kin_mxnewtstep; - rlmax = ONE; - kin_mem->kin_stepl = pnorm; - } - - /* If constraint checking is activated, check and correct violations */ - - kin_mem->kin_stepmul = ONE; - - if(kin_mem->kin_constraintsSet){ - retval = KINConstraint(kin_mem); - if(retval == CONSTR_VIOLATED){ - /* Apply stepmul set in KINConstraint */ - N_VScale(kin_mem->kin_stepmul, kin_mem->kin_pp, kin_mem->kin_pp); - ratio *= kin_mem->kin_stepmul; - pnorm *= kin_mem->kin_stepmul; - rlmax = ONE; - kin_mem->kin_stepl = pnorm; - if (kin_mem->kin_printfl > 0) KINPrintInfo(kin_mem, PRNT_PNORM1, "KINSOL", "KINLineSearch", INFO_PNORM1, pnorm); - if (pnorm <= kin_mem->kin_scsteptol) { - N_VLinearSum(ONE, kin_mem->kin_uu, ONE, kin_mem->kin_pp, kin_mem->kin_unew); - return(STEP_TOO_SMALL);} - } - } - - /* Attempt (at most MAX_RECVR times) to evaluate function at the new iterate */ - - fOK = SUNFALSE; - - for (ircvr = 1; ircvr <= MAX_RECVR; ircvr++) { - - /* compute the iterate unew = uu + pp */ - N_VLinearSum(ONE, kin_mem->kin_uu, ONE, kin_mem->kin_pp, kin_mem->kin_unew); - - /* evaluate func(unew) and its norm, and return */ - retval = kin_mem->kin_func(kin_mem->kin_unew, kin_mem->kin_fval, kin_mem->kin_user_data); kin_mem->kin_nfe++; - - /* if func was successful, accept pp */ - if (retval == 0) {fOK = SUNTRUE; break;} - - /* if func failed unrecoverably, give up */ - else if (retval < 0) return(KIN_SYSFUNC_FAIL); - - /* func failed recoverably; cut step in half and try again */ - N_VScale(HALF, kin_mem->kin_pp, kin_mem->kin_pp); - ratio *= HALF; - pnorm *= HALF; - rlmax = ONE; - kin_mem->kin_stepl = pnorm; - - } - - /* If func() failed recoverably MAX_RECVR times, give up */ - - if (!fOK) return(KIN_REPTD_SYSFUNC_ERR); - - /* Evaluate function norms */ - - *fnormp = N_VWL2Norm(kin_mem->kin_fval, kin_mem->kin_fscale); - *f1normp = HALF * (*fnormp) * (*fnormp) ; - - /* Estimate the line search value rl (lambda) to satisfy both ALPHA and BETA conditions */ - - slpi = kin_mem->kin_sFdotJp * ratio; - rlength = KINScSNorm(kin_mem, kin_mem->kin_pp, kin_mem->kin_uu); - rlmin = (kin_mem->kin_scsteptol) / rlength; - rl = ONE; - - if (kin_mem->kin_printfl > 2) - KINPrintInfo(kin_mem, PRNT_LAM, "KINSOL", "KINLineSearch", INFO_LAM, rlmin, kin_mem->kin_f1norm, pnorm); - - /* Loop until the ALPHA condition is satisfied. Terminate if rl becomes too small */ - - for(;;) { - - /* Evaluate test quantity */ - - alpha_cond = kin_mem->kin_f1norm + (alpha * slpi * rl); - - if (kin_mem->kin_printfl > 2) - KINPrintInfo(kin_mem, PRNT_ALPHA, "KINSOL", "KINLinesearch", - INFO_ALPHA, *fnormp, *f1normp, alpha_cond, rl); - - /* If ALPHA condition is satisfied, break out from loop */ - - if ((*f1normp) <= alpha_cond) break; - - /* Backtracking. Use quadratic fit the first time and cubic fit afterwards. */ - - if (firstBacktrack) { - - rltmp = -slpi / (TWO * ((*f1normp) - kin_mem->kin_f1norm - slpi)); - firstBacktrack = SUNFALSE; - - } else { - - tmp1 = (*f1normp) - kin_mem->kin_f1norm - (rl * slpi); - tmp2 = f1nprv - kin_mem->kin_f1norm - (rlprev * slpi); - rl_a = ((ONE / (rl * rl)) * tmp1) - ((ONE / (rlprev * rlprev)) * tmp2); - rl_b = ((-rlprev / (rl * rl)) * tmp1) + ((rl / (rlprev * rlprev)) * tmp2); - tmp1 = ONE / (rl - rlprev); - rl_a *= tmp1; - rl_b *= tmp1; - disc = (rl_b * rl_b) - (THREE * rl_a * slpi); - - if (SUNRabs(rl_a) < kin_mem->kin_uround) { /* cubic is actually just a quadratic (rl_a ~ 0) */ - rltmp = -slpi / (TWO * rl_b); - } else { /* real cubic */ - rltmp = (-rl_b + SUNRsqrt(disc)) / (THREE * rl_a); - } - } - if (rltmp > (HALF * rl)) rltmp = HALF * rl; - - /* Set new rl (do not allow a reduction by a factor larger than 10) */ - - rlprev = rl; - f1nprv = (*f1normp); - pt1trl = POINT1 * rl; - rl = SUNMAX(pt1trl, rltmp); - nbktrk_l++; - - /* Update unew and re-evaluate function */ - - N_VLinearSum(ONE, kin_mem->kin_uu, rl, kin_mem->kin_pp, kin_mem->kin_unew); - - retval = kin_mem->kin_func(kin_mem->kin_unew, kin_mem->kin_fval, kin_mem->kin_user_data); kin_mem->kin_nfe++; - if (retval != 0) return(KIN_SYSFUNC_FAIL); - - *fnormp = N_VWL2Norm(kin_mem->kin_fval, kin_mem->kin_fscale); - *f1normp = HALF * (*fnormp) * (*fnormp) ; - - /* Check if rl (lambda) is too small */ - - if (rl < rlmin) { - /* unew sufficiently distinct from uu cannot be found. - copy uu into unew (step remains unchanged) and - return STEP_TOO_SMALL */ - N_VScale(ONE, kin_mem->kin_uu, kin_mem->kin_unew); - return(STEP_TOO_SMALL); - } - - } /* end ALPHA condition loop */ - - - /* ALPHA condition is satisfied. Now check the BETA condition */ - - beta_cond = kin_mem->kin_f1norm + (beta * slpi * rl); - - if ((*f1normp) < beta_cond) { - - /* BETA condition not satisfied */ - - if ((rl == ONE) && (pnorm < kin_mem->kin_mxnewtstep)) { - - do { - - rlprev = rl; - f1nprv = *f1normp; - rl = SUNMIN((TWO * rl), rlmax); - nbktrk_l++; - - N_VLinearSum(ONE, kin_mem->kin_uu, rl, kin_mem->kin_pp, kin_mem->kin_unew); - retval = kin_mem->kin_func(kin_mem->kin_unew, kin_mem->kin_fval, kin_mem->kin_user_data); kin_mem->kin_nfe++; - if (retval != 0) return(KIN_SYSFUNC_FAIL); - *fnormp = N_VWL2Norm(kin_mem->kin_fval, kin_mem->kin_fscale); - *f1normp = HALF * (*fnormp) * (*fnormp); - - alpha_cond = kin_mem->kin_f1norm + (alpha * slpi * rl); - beta_cond = kin_mem->kin_f1norm + (beta * slpi * rl); - - if (kin_mem->kin_printfl > 2) - KINPrintInfo(kin_mem, PRNT_BETA, "KINSOL", "KINLineSearch", - INFO_BETA, *f1normp, beta_cond, rl); - - } while (((*f1normp) <= alpha_cond) && - ((*f1normp) < beta_cond) && (rl < rlmax)); - - } /* end if (rl == ONE) block */ - - if ((rl < ONE) || ((rl > ONE) && (*f1normp > alpha_cond))) { - - rllo = SUNMIN(rl, rlprev); - rldiff = SUNRabs(rlprev - rl); - - do { - - rlinc = HALF * rldiff; - rl = rllo + rlinc; - nbktrk_l++; - - N_VLinearSum(ONE, kin_mem->kin_uu, rl, kin_mem->kin_pp, kin_mem->kin_unew); - retval = kin_mem->kin_func(kin_mem->kin_unew, kin_mem->kin_fval, kin_mem->kin_user_data); kin_mem->kin_nfe++; - if (retval != 0) return(KIN_SYSFUNC_FAIL); - *fnormp = N_VWL2Norm(kin_mem->kin_fval, kin_mem->kin_fscale); - *f1normp = HALF * (*fnormp) * (*fnormp); - - alpha_cond = kin_mem->kin_f1norm + (alpha * slpi * rl); - beta_cond = kin_mem->kin_f1norm + (beta * slpi * rl); - - if (kin_mem->kin_printfl > 2) - KINPrintInfo(kin_mem, PRNT_ALPHABETA, "KINSOL", "KINLineSearch", - INFO_ALPHABETA, *f1normp, alpha_cond, beta_cond, rl); - - if ((*f1normp) > alpha_cond) rldiff = rlinc; - else if (*f1normp < beta_cond) { - rllo = rl; - rldiff = rldiff - rlinc; - } - - } while ((*f1normp > alpha_cond) || - ((*f1normp < beta_cond) && (rldiff >= rlmin))); - - if ( (*f1normp < beta_cond) || ((rldiff < rlmin) && (*f1normp > alpha_cond)) ) { - - /* beta condition could not be satisfied or rldiff too small - and alpha_cond not satisfied, so set unew to last u value - that satisfied the alpha condition and continue */ - - N_VLinearSum(ONE, kin_mem->kin_uu, rllo, kin_mem->kin_pp, kin_mem->kin_unew); - retval = kin_mem->kin_func(kin_mem->kin_unew, kin_mem->kin_fval, kin_mem->kin_user_data); kin_mem->kin_nfe++; - if (retval != 0) return(KIN_SYSFUNC_FAIL); - *fnormp = N_VWL2Norm(kin_mem->kin_fval, kin_mem->kin_fscale); - *f1normp = HALF * (*fnormp) * (*fnormp); - - /* increment beta-condition failures counter */ - - kin_mem->kin_nbcf++; - - } - - } /* end of if (rl < ONE) block */ - - } /* end of if (f1normp < beta_cond) block */ - - /* Update number of backtracking operations */ - - kin_mem->kin_nbktrk += nbktrk_l; - - if (kin_mem->kin_printfl > 1) - KINPrintInfo(kin_mem, PRNT_ADJ, "KINSOL", "KINLineSearch", INFO_ADJ, nbktrk_l); - - /* scale sFdotJp and sJpnorm by rl * ratio for later use in KINForcingTerm */ - - kin_mem->kin_sFdotJp = kin_mem->kin_sFdotJp * rl * ratio; - kin_mem->kin_sJpnorm = kin_mem->kin_sJpnorm * rl * ratio; - - if ((rl * pnorm) > (POINT99 * kin_mem->kin_mxnewtstep)) *maxStepTaken = SUNTRUE; - - return(KIN_SUCCESS); -} - -/* - * Function : KINConstraint - * - * This routine checks if the proposed solution vector uu + pp - * violates any constraints. If a constraint is violated, then the - * scalar stepmul is determined such that uu + stepmul * pp does - * not violate any constraints. - * - * Note: This routine is called by the functions - * KINLineSearch and KINFullNewton. - */ - -static int KINConstraint(KINMem kin_mem) -{ - N_VLinearSum(ONE, kin_mem->kin_uu, ONE, kin_mem->kin_pp, kin_mem->kin_vtemp1); - - /* if vtemp1[i] violates constraint[i] then vtemp2[i] = 1 - else vtemp2[i] = 0 (vtemp2 is the mask vector) */ - - if(N_VConstrMask(kin_mem->kin_constraints, kin_mem->kin_vtemp1, kin_mem->kin_vtemp2)) return(KIN_SUCCESS); - - /* vtemp1[i] = SUNRabs(pp[i]) */ - - N_VAbs(kin_mem->kin_pp, kin_mem->kin_vtemp1); - - /* consider vtemp1[i] only if vtemp2[i] = 1 (constraint violated) */ - - N_VProd(kin_mem->kin_vtemp2, kin_mem->kin_vtemp1, kin_mem->kin_vtemp1); - - N_VAbs(kin_mem->kin_uu, kin_mem->kin_vtemp2); - kin_mem->kin_stepmul = POINT9 * N_VMinQuotient(kin_mem->kin_vtemp2, kin_mem->kin_vtemp1); - - return(CONSTR_VIOLATED); -} - -/* - * ----------------------------------------------------------------- - * Stopping tests - * ----------------------------------------------------------------- - */ - -/* - * KINStop - * - * This routine checks the current iterate unew to see if the - * system func(unew) = 0 is satisfied by a variety of tests. - * - * strategy is one of KIN_NONE or KIN_LINESEARCH - * sflag is one of KIN_SUCCESS, STEP_TOO_SMALL - */ - -static int KINStop(KINMem kin_mem, booleantype maxStepTaken, int sflag) -{ - realtype fmax, rlength, omexp; - N_Vector delta; - - /* Check for too small a step */ - - if (sflag == STEP_TOO_SMALL) { - - if ((kin_mem->kin_lsetup != NULL) && !(kin_mem->kin_jacCurrent)) { - /* If the Jacobian is out of date, update it and retry */ - kin_mem->kin_sthrsh = TWO; - return(RETRY_ITERATION); - } else { - /* Give up */ - if (kin_mem->kin_globalstrategy == KIN_NONE) return(KIN_STEP_LT_STPTOL); - else return(KIN_LINESEARCH_NONCONV); - } - - } - - /* Check tolerance on scaled function norm at the current iterate */ - - fmax = KINScFNorm(kin_mem, kin_mem->kin_fval, kin_mem->kin_fscale); - - if (kin_mem->kin_printfl > 1) - KINPrintInfo(kin_mem, PRNT_FMAX, "KINSOL", "KINStop", INFO_FMAX, fmax); - - if (fmax <= kin_mem->kin_fnormtol) return(KIN_SUCCESS); - - /* Check if the scaled distance between the last two steps is too small */ - /* NOTE: pp used as work space to store this distance */ - - delta = kin_mem->kin_pp; - N_VLinearSum(ONE, kin_mem->kin_unew, -ONE, kin_mem->kin_uu, delta); - rlength = KINScSNorm(kin_mem, delta, kin_mem->kin_unew); - - if (rlength <= kin_mem->kin_scsteptol) { - - if ((kin_mem->kin_lsetup != NULL) && !(kin_mem->kin_jacCurrent)) { - /* If the Jacobian is out of date, update it and retry */ - kin_mem->kin_sthrsh = TWO; - return(CONTINUE_ITERATIONS); - } else { - /* give up */ - return(KIN_STEP_LT_STPTOL); - } - - } - - /* Check if the maximum number of iterations is reached */ - - if (kin_mem->kin_nni >= kin_mem->kin_mxiter) return(KIN_MAXITER_REACHED); - - /* Check for consecutive number of steps taken of size mxnewtstep - and if not maxStepTaken, then set ncscmx to 0 */ - - if (maxStepTaken) kin_mem->kin_ncscmx++; - else kin_mem->kin_ncscmx = 0; - - if (kin_mem->kin_ncscmx == 5) return(KIN_MXNEWT_5X_EXCEEDED); - - /* Proceed according to the type of linear solver used */ - - if (kin_mem->kin_inexact_ls) { - - /* We're doing inexact Newton. - Load threshold for reevaluating the Jacobian. */ - - kin_mem->kin_sthrsh = rlength; - - } else if (!(kin_mem->kin_noResMon)) { - - /* We're doing modified Newton and the user did not disable residual monitoring. - Check if it is time to monitor residual. */ - - if ((kin_mem->kin_nni - kin_mem->kin_nnilset_sub) >= kin_mem->kin_msbset_sub) { - - /* Residual monitoring needed */ - - kin_mem->kin_nnilset_sub = kin_mem->kin_nni; - - /* If indicated, estimate new OMEGA value */ - if (kin_mem->kin_eval_omega) { - omexp = SUNMAX(ZERO,((kin_mem->kin_fnorm)/(kin_mem->kin_fnormtol))-ONE); - kin_mem->kin_omega = (omexp > TWELVE)? kin_mem->kin_omega_max : SUNMIN(kin_mem->kin_omega_min * SUNRexp(omexp), kin_mem->kin_omega_max); - } - /* Check if making satisfactory progress */ - - if (kin_mem->kin_fnorm > kin_mem->kin_omega * kin_mem->kin_fnorm_sub) { - /* Insufficient progress */ - if ((kin_mem->kin_lsetup != NULL) && !(kin_mem->kin_jacCurrent)) { - /* If the Jacobian is out of date, update it and retry */ - kin_mem->kin_sthrsh = TWO; - return(CONTINUE_ITERATIONS); - } else { - /* Otherwise, we cannot do anything, so just return. */ - } - } else { - /* Sufficient progress */ - kin_mem->kin_fnorm_sub = kin_mem->kin_fnorm; - kin_mem->kin_sthrsh = ONE; - } - - } else { - - /* Residual monitoring not needed */ - - /* Reset sthrsh */ - if (kin_mem->kin_retry_nni || kin_mem->kin_update_fnorm_sub) kin_mem->kin_fnorm_sub = kin_mem->kin_fnorm; - if (kin_mem->kin_update_fnorm_sub) kin_mem->kin_update_fnorm_sub = SUNFALSE; - kin_mem->kin_sthrsh = ONE; - - } - - } - - /* if made it to here, then the iteration process is not finished - so return CONTINUE_ITERATIONS flag */ - - return(CONTINUE_ITERATIONS); -} - -/* - * KINForcingTerm - * - * This routine computes eta, the scaling factor in the linear - * convergence stopping tolerance eps when choice #1 or choice #2 - * forcing terms are used. Eta is computed here for all but the - * first iterative step, which is set to the default in routine - * KINSolInit. - * - * This routine was written by Homer Walker of Utah State - * University with subsequent modifications by Allan Taylor @ LLNL. - * - * It is based on the concepts of the paper 'Choosing the forcing - * terms in an inexact Newton method', SIAM J Sci Comput, 17 - * (1996), pp 16 - 32, or Utah State University Research Report - * 6/94/75 of the same title. - */ - -static void KINForcingTerm(KINMem kin_mem, realtype fnormp) -{ - realtype eta_max, eta_min, eta_safe, linmodel_norm; - - eta_max = POINT9; - eta_min = POINT0001; - eta_safe = HALF; - - /* choice #1 forcing term */ - - if (kin_mem->kin_etaflag == KIN_ETACHOICE1) { - - /* compute the norm of f + Jp , scaled L2 norm */ - - linmodel_norm = SUNRsqrt((kin_mem->kin_fnorm * kin_mem->kin_fnorm) + - (TWO * kin_mem->kin_sFdotJp) + - (kin_mem->kin_sJpnorm * kin_mem->kin_sJpnorm)); - - /* form the safeguarded for choice #1 */ - - eta_safe = SUNRpowerR(kin_mem->kin_eta, kin_mem->kin_eta_alpha); - kin_mem->kin_eta = SUNRabs(fnormp - linmodel_norm) / kin_mem->kin_fnorm; - } - - /* choice #2 forcing term */ - - if (kin_mem->kin_etaflag == KIN_ETACHOICE2) { - eta_safe = kin_mem->kin_eta_gamma * - SUNRpowerR(kin_mem->kin_eta, kin_mem->kin_eta_alpha); - - kin_mem->kin_eta = kin_mem->kin_eta_gamma * - SUNRpowerR((fnormp / kin_mem->kin_fnorm), kin_mem->kin_eta_alpha); - } - - /* apply safeguards */ - - if(eta_safe < POINT1) eta_safe = ZERO; - kin_mem->kin_eta = SUNMAX(kin_mem->kin_eta, eta_safe); - kin_mem->kin_eta = SUNMAX(kin_mem->kin_eta, eta_min); - kin_mem->kin_eta = SUNMIN(kin_mem->kin_eta, eta_max); - - return; -} - - -/* - * ----------------------------------------------------------------- - * Norm functions - * ----------------------------------------------------------------- - */ - -/* - * Function : KINScFNorm - * - * This routine computes the max norm for scaled vectors. The - * scaling vector is scale, and the vector of which the norm is to - * be determined is vv. The returned value, fnormval, is the - * resulting scaled vector norm. This routine uses N_Vector - * functions from the vector module. - */ - -static realtype KINScFNorm(KINMem kin_mem, N_Vector v, N_Vector scale) -{ - N_VProd(scale, v, kin_mem->kin_vtemp1); - return(N_VMaxNorm(kin_mem->kin_vtemp1)); -} - -/* - * Function : KINScSNorm - * - * This routine computes the max norm of the scaled steplength, ss. - * Here ucur is the current step and usc is the u scale factor. - */ - -static realtype KINScSNorm(KINMem kin_mem, N_Vector v, N_Vector u) -{ - realtype length; - - N_VInv(kin_mem->kin_uscale, kin_mem->kin_vtemp1); - N_VAbs(u, kin_mem->kin_vtemp2); - N_VLinearSum(ONE, kin_mem->kin_vtemp1, ONE, kin_mem->kin_vtemp2, kin_mem->kin_vtemp1); - N_VDiv(v, kin_mem->kin_vtemp1, kin_mem->kin_vtemp1); - - length = N_VMaxNorm(kin_mem->kin_vtemp1); - - return(length); -} - -/* - * ================================================================= - * KINSOL Verbose output functions - * ================================================================= - */ - -/* - * KINPrintInfo - * - * KINPrintInfo is a high level error handling function - * Based on the value info_code, it composes the info message and - * passes it to the info handler function. - */ - -void KINPrintInfo(KINMem kin_mem, - int info_code, const char *module, const char *fname, - const char *msgfmt, ...) -{ - va_list ap; - char msg[256], msg1[40]; - char retstr[30]; - int ret; - - /* Initialize argument processing - (msgfrmt is the last required argument) */ - - va_start(ap, msgfmt); - - if (info_code == PRNT_RETVAL) { - - /* If info_code = PRNT_RETVAL, decode the numeric value */ - - ret = va_arg(ap, int); - - switch(ret) { - case KIN_SUCCESS: - sprintf(retstr, "KIN_SUCCESS"); - break; - case KIN_SYSFUNC_FAIL: - sprintf(retstr, "KIN_SYSFUNC_FAIL"); - break; - case KIN_REPTD_SYSFUNC_ERR: - sprintf(retstr, "KIN_REPTD_SYSFUNC_ERR"); - break; - case KIN_STEP_LT_STPTOL: - sprintf(retstr, "KIN_STEP_LT_STPTOL"); - break; - case KIN_LINESEARCH_NONCONV: - sprintf(retstr, "KIN_LINESEARCH_NONCONV"); - break; - case KIN_LINESEARCH_BCFAIL: - sprintf(retstr, "KIN_LINESEARCH_BCFAIL"); - break; - case KIN_MAXITER_REACHED: - sprintf(retstr, "KIN_MAXITER_REACHED"); - break; - case KIN_MXNEWT_5X_EXCEEDED: - sprintf(retstr, "KIN_MXNEWT_5X_EXCEEDED"); - break; - case KIN_LINSOLV_NO_RECOVERY: - sprintf(retstr, "KIN_LINSOLV_NO_RECOVERY"); - break; - case KIN_LSETUP_FAIL: - sprintf(retstr, "KIN_PRECONDSET_FAILURE"); - break; - case KIN_LSOLVE_FAIL: - sprintf(retstr, "KIN_PRECONDSOLVE_FAILURE"); - break; - } - - /* Compose the message */ - - sprintf(msg1, msgfmt, ret); - sprintf(msg,"%s (%s)",msg1,retstr); - - - } else { - - /* Compose the message */ - - vsprintf(msg, msgfmt, ap); - - } - - /* call the info message handler */ - - kin_mem->kin_ihfun(module, fname, msg, kin_mem->kin_ih_data); - - /* finalize argument processing */ - - va_end(ap); - - return; -} - - -/* - * KINInfoHandler - * - * This is the default KINSOL info handling function. - * It sends the info message to the stream pointed to by kin_infofp - */ - -void KINInfoHandler(const char *module, const char *function, - char *msg, void *data) -{ - KINMem kin_mem; - - /* data points to kin_mem here */ - - kin_mem = (KINMem) data; - -#ifndef NO_FPRINTF_OUTPUT - if (kin_mem->kin_infofp != NULL) { - fprintf(kin_mem->kin_infofp,"\n[%s] %s\n",module, function); - fprintf(kin_mem->kin_infofp," %s\n",msg); - } -#endif - -} - -/* - * ================================================================= - * KINSOL Error Handling functions - * ================================================================= - */ - -/* - * KINProcessError - * - * KINProcessError is a high level error handling function. - * - If cv_mem==NULL it prints the error message to stderr. - * - Otherwise, it sets up and calls the error handling function - * pointed to by cv_ehfun. - */ - -void KINProcessError(KINMem kin_mem, - int error_code, const char *module, const char *fname, - const char *msgfmt, ...) -{ - va_list ap; - char msg[256]; - - /* Initialize the argument pointer variable - (msgfmt is the last required argument to KINProcessError) */ - - va_start(ap, msgfmt); - - /* Compose the message */ - - vsprintf(msg, msgfmt, ap); - - if (kin_mem == NULL) { /* We write to stderr */ -#ifndef NO_FPRINTF_OUTPUT - fprintf(stderr, "\n[%s ERROR] %s\n ", module, fname); - fprintf(stderr, "%s\n\n", msg); -#endif - - } else { /* We can call ehfun */ - kin_mem->kin_ehfun(error_code, module, fname, msg, kin_mem->kin_eh_data); - } - - /* Finalize argument processing */ - va_end(ap); - - return; -} - -/* - * KINErrHandler - * - * This is the default error handling function. - * It sends the error message to the stream pointed to by kin_errfp - */ - -void KINErrHandler(int error_code, const char *module, - const char *function, char *msg, void *data) -{ - KINMem kin_mem; - char err_type[10]; - - /* data points to kin_mem here */ - - kin_mem = (KINMem) data; - - if (error_code == KIN_WARNING) - sprintf(err_type,"WARNING"); - else - sprintf(err_type,"ERROR"); - -#ifndef NO_FPRINTF_OUTPUT - if (kin_mem->kin_errfp != NULL) { - fprintf(kin_mem->kin_errfp,"\n[%s %s] %s\n",module,err_type,function); - fprintf(kin_mem->kin_errfp," %s\n\n",msg); - } -#endif - - return; -} - - -/* - * ======================================================================= - * Picard and fixed point solvers - * ======================================================================= - */ - -/* - * KINPicardAA - * - * This routine is the main driver for the Picard iteration with - * acclerated fixed point. - */ - -static int KINPicardAA(KINMem kin_mem, long int *iterp, realtype *R, - realtype *gamma, realtype *fmaxptr) -{ - int retval, ret; - long int iter; - realtype fmax, epsmin, fnormp; - N_Vector delta, gval; - - delta = kin_mem->kin_vtemp1; - gval = kin_mem->kin_gval; - ret = CONTINUE_ITERATIONS; - fmax = kin_mem->kin_fnormtol + ONE; - iter = 0; - epsmin = ZERO; - fnormp = -ONE; - - N_VConst(ZERO, gval); - - /* if eps is to be bounded from below, set the bound */ - if (kin_mem->kin_inexact_ls && !(kin_mem->kin_noMinEps)) epsmin = POINT01 * kin_mem->kin_fnormtol; - - while (ret == CONTINUE_ITERATIONS) { - - iter++; - - /* Update the forcing term for the inexact linear solves */ - if (kin_mem->kin_inexact_ls) { - kin_mem->kin_eps = (kin_mem->kin_eta + kin_mem->kin_uround) * kin_mem->kin_fnorm; - if(!(kin_mem->kin_noMinEps)) kin_mem->kin_eps = SUNMAX(epsmin, kin_mem->kin_eps); - } - - /* evaluate g = uu - L^{-1}func(uu) and return if failed. - For Picard, assume that the fval vector has been filled - with an eval of the nonlinear residual prior to this call. */ - retval = KINPicardFcnEval(kin_mem, gval, kin_mem->kin_uu, kin_mem->kin_fval); - - if (retval < 0) { - ret = KIN_SYSFUNC_FAIL; - break; - } - - if (kin_mem->kin_m_aa == 0) { - N_VScale(ONE, gval, kin_mem->kin_unew); - } - else { /* use Anderson, if desired */ - N_VScale(ONE, kin_mem->kin_uu, kin_mem->kin_unew); - AndersonAcc(kin_mem, gval, delta, kin_mem->kin_unew, kin_mem->kin_uu, iter-1, R, gamma); - } - - /* Fill the Newton residual based on the new solution iterate */ - retval = kin_mem->kin_func(kin_mem->kin_unew, kin_mem->kin_fval, kin_mem->kin_user_data); kin_mem->kin_nfe++; - - if (retval < 0) { - ret = KIN_SYSFUNC_FAIL; - break; - } - - /* Evaluate function norms */ - fnormp = N_VWL2Norm(kin_mem->kin_fval, kin_mem->kin_fscale); - fmax = KINScFNorm(kin_mem, kin_mem->kin_fval, kin_mem->kin_fscale); /* measure || F(x) ||_max */ - kin_mem->kin_fnorm = fmax; - *fmaxptr = fmax; - - if (kin_mem->kin_printfl > 1) - KINPrintInfo(kin_mem, PRNT_FMAX, "KINSOL", "KINPicardAA", INFO_FMAX, fmax); - - /* print the current iter, fnorm, and nfe values if printfl > 0 */ - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_NNI, "KINSOL", "KINPicardAA", INFO_NNI, iter, kin_mem->kin_nfe, kin_mem->kin_fnorm); - - /* Check if the maximum number of iterations is reached */ - if (iter >= kin_mem->kin_mxiter) { - ret = KIN_MAXITER_REACHED; - } - if (fmax <= kin_mem->kin_fnormtol) { - ret = KIN_SUCCESS; - } - - /* Update with new iterate. */ - N_VScale(ONE, kin_mem->kin_unew, kin_mem->kin_uu); - - if (ret == CONTINUE_ITERATIONS) { - /* evaluate eta by calling the forcing term routine */ - if (kin_mem->kin_callForcingTerm) KINForcingTerm(kin_mem, fnormp); - } - - fflush(kin_mem->kin_errfp); - - } /* end of loop; return */ - - *iterp = iter; - - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_RETVAL, "KINSOL", "KINPicardAA", INFO_RETVAL, ret); - - return(ret); -} - -/* - * KINPicardFcnEval - * - * This routine evaluates the Picard fixed point function - * using the linear solver, gval = u - L^{-1}F(u). - * The function assumes the user has defined L either through - * a user-supplied matvec if using a SPILS solver or through - * a supplied matrix if using a dense solver. This assumption is - * tested by a check on the strategy and the requisite functionality - * within the linear solve routines. - * - * This routine fills gval = uu - L^{-1}F(uu) given uu and fval = F(uu). - */ - -static int KINPicardFcnEval(KINMem kin_mem, N_Vector gval, N_Vector uval, N_Vector fval1) -{ - int retval; - - if ((kin_mem->kin_nni - kin_mem->kin_nnilset) >= kin_mem->kin_msbset) { - kin_mem->kin_sthrsh = TWO; - kin_mem->kin_update_fnorm_sub = SUNTRUE; - } - - for(;;){ - - kin_mem->kin_jacCurrent = SUNFALSE; - - if ((kin_mem->kin_sthrsh > ONEPT5) && (kin_mem->kin_lsetup != NULL)) { - retval = kin_mem->kin_lsetup(kin_mem); - kin_mem->kin_jacCurrent = SUNTRUE; - kin_mem->kin_nnilset = kin_mem->kin_nni; - kin_mem->kin_nnilset_sub = kin_mem->kin_nni; - if (retval != 0) return(KIN_LSETUP_FAIL); - } - - /* call the generic 'lsolve' routine to solve the system Lx = -fval - Note that we are using gval to hold x. */ - N_VScale(-ONE, fval1, fval1); - retval = kin_mem->kin_lsolve(kin_mem, gval, fval1, &(kin_mem->kin_sJpnorm), - &(kin_mem->kin_sFdotJp)); - - if (retval == 0) { - /* Update gval = uval + gval since gval = -L^{-1}F(uu) */ - N_VLinearSum(ONE, uval, ONE, gval, gval); - return(KIN_SUCCESS); - } - else if (retval < 0) return(KIN_LSOLVE_FAIL); - else if ((kin_mem->kin_lsetup == NULL) || (kin_mem->kin_jacCurrent)) return(KIN_LINSOLV_NO_RECOVERY); - - /* loop back only if the linear solver setup is in use - and matrix information is not current */ - - kin_mem->kin_sthrsh = TWO; - } - -} - - -/* - * KINFP - * - * This routine is the main driver for the fixed point iteration with - * Anderson Acceleration. - */ - -static int KINFP(KINMem kin_mem) -{ - int retval; /* return value from user func */ - int ret; /* iteration status */ - realtype fmax; /* max norm of residual func */ - N_Vector delta; /* temporary workspace vector */ - - delta = kin_mem->kin_vtemp1; - ret = CONTINUE_ITERATIONS; - fmax = kin_mem->kin_fnormtol + ONE; - - /* initialize iteration count */ - kin_mem->kin_nni = 0; - - while (ret == CONTINUE_ITERATIONS) { - - /* update iteration count */ - kin_mem->kin_nni++; - - /* evaluate func(uu) and return if failed */ - retval = kin_mem->kin_func(kin_mem->kin_uu, kin_mem->kin_fval, - kin_mem->kin_user_data); - kin_mem->kin_nfe++; - - if (retval < 0) { - ret = KIN_SYSFUNC_FAIL; - break; - } - - /* compute new solution */ - if (kin_mem->kin_m_aa == 0) { - /* standard fixed point */ - N_VScale(ONE, kin_mem->kin_fval, kin_mem->kin_unew); - } else { - /* apply Anderson acceleration */ - AndersonAcc(kin_mem, kin_mem->kin_fval, delta, kin_mem->kin_unew, - kin_mem->kin_uu, kin_mem->kin_nni - 1, kin_mem->kin_R_aa, - kin_mem->kin_gamma_aa); - } - - /* compute change between iterations */ - N_VLinearSum(ONE, kin_mem->kin_unew, -ONE, kin_mem->kin_uu, delta); - - fmax = KINScFNorm(kin_mem, delta, kin_mem->kin_fscale); /* measure || g(x)-x || */ - - if (kin_mem->kin_printfl > 1) - KINPrintInfo(kin_mem, PRNT_FMAX, "KINSOL", "KINFP", INFO_FMAX, fmax); - - kin_mem->kin_fnorm = fmax; - - /* print the current iter, fnorm, and nfe values if printfl > 0 */ - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_NNI, "KINSOL", "KINFP", INFO_NNI, - kin_mem->kin_nni, kin_mem->kin_nfe, kin_mem->kin_fnorm); - - /* Check if the maximum number of iterations is reached */ - if (kin_mem->kin_nni >= kin_mem->kin_mxiter) { - ret = KIN_MAXITER_REACHED; - } - if (fmax <= kin_mem->kin_fnormtol) { - ret = KIN_SUCCESS; - } - - if (ret == CONTINUE_ITERATIONS) { - /* Only update solution if taking a next iteration. */ - /* CSW Should put in a conditional to send back the newest iterate or - the one consistent with the fval */ - N_VScale(ONE, kin_mem->kin_unew, kin_mem->kin_uu); - } - - fflush(kin_mem->kin_errfp); - - } /* end of loop; return */ - - if (kin_mem->kin_printfl > 0) - KINPrintInfo(kin_mem, PRNT_RETVAL, "KINSOL", "KINFP", INFO_RETVAL, ret); - - return(ret); -} - - -/* ----------------------------------------------------------------- - * Stopping tests - * ----------------------------------------------------------------- - */ - - -/* - * ======================================================================== - * Anderson Acceleration - * ======================================================================== - */ - -static int AndersonAcc(KINMem kin_mem, N_Vector gval, N_Vector fv, - N_Vector x, N_Vector xold, - long int iter, realtype *R, realtype *gamma) -{ - int retval; - long int i_pt, i, j, lAA; - long int *ipt_map; - realtype alfa; - realtype onembeta; - realtype a, b, temp, c, s; - - /* local shortcuts for fused vector operation */ - int nvec=0; - realtype* cv=kin_mem->kin_cv; - N_Vector* Xv=kin_mem->kin_Xv; - - ipt_map = kin_mem->kin_ipt_map; - i_pt = iter-1 - ((iter-1) / kin_mem->kin_m_aa) * kin_mem->kin_m_aa; - N_VLinearSum(ONE, gval, -ONE, xold, fv); - if (iter > 0) { - /* compute dg_new = gval - gval_old */ - N_VLinearSum(ONE, gval, -ONE, kin_mem->kin_gold_aa, kin_mem->kin_dg_aa[i_pt]); - /* compute df_new = fval - fval_old */ - N_VLinearSum(ONE, fv, -ONE, kin_mem->kin_fold_aa, kin_mem->kin_df_aa[i_pt]); - } - - N_VScale(ONE, gval, kin_mem->kin_gold_aa); - N_VScale(ONE, fv, kin_mem->kin_fold_aa); - - /* on first iteration, just do basic fixed-point update */ - if (iter == 0) { - N_VScale(ONE, gval, x); - return(0); - } - - /* update data structures based on current iteration index */ - - if (iter == 1) { - - /* second iteration */ - R[0] = SUNRsqrt(N_VDotProd(kin_mem->kin_df_aa[i_pt], kin_mem->kin_df_aa[i_pt])); - alfa = ONE/R[0]; - N_VScale(alfa, kin_mem->kin_df_aa[i_pt], kin_mem->kin_q_aa[i_pt]); - ipt_map[0] = 0; - - } else if (iter <= kin_mem->kin_m_aa) { - - /* another iteration before we've reached maa */ - N_VScale(ONE, kin_mem->kin_df_aa[i_pt], kin_mem->kin_vtemp2); - for (j=0; j < (iter-1); j++) { - ipt_map[j] = j; - R[(iter-1)*kin_mem->kin_m_aa+j] = N_VDotProd(kin_mem->kin_q_aa[j], kin_mem->kin_vtemp2); - N_VLinearSum(ONE,kin_mem->kin_vtemp2, -R[(iter-1)*kin_mem->kin_m_aa+j], kin_mem->kin_q_aa[j], kin_mem->kin_vtemp2); - } - R[(iter-1)*kin_mem->kin_m_aa+iter-1] = SUNRsqrt(N_VDotProd(kin_mem->kin_vtemp2, kin_mem->kin_vtemp2)); - N_VScale((1/R[(iter-1)*kin_mem->kin_m_aa+iter-1]), kin_mem->kin_vtemp2, kin_mem->kin_q_aa[i_pt]); - ipt_map[iter-1] = iter-1; - - } else { - - /* we've filled the acceleration subspace, so start recycling */ - - /* Delete left-most column vector from QR factorization */ - for (i=0; i < kin_mem->kin_m_aa-1; i++) { - a = R[(i+1)*kin_mem->kin_m_aa + i]; - b = R[(i+1)*kin_mem->kin_m_aa + i+1]; - temp = SUNRsqrt(a*a + b*b); - c = a / temp; - s = b / temp; - R[(i+1)*kin_mem->kin_m_aa + i] = temp; - R[(i+1)*kin_mem->kin_m_aa + i+1] = ZERO; - /* OK to re-use temp */ - if (i < kin_mem->kin_m_aa-1) { - for (j = i+2; j < kin_mem->kin_m_aa; j++) { - a = R[j*kin_mem->kin_m_aa + i]; - b = R[j*kin_mem->kin_m_aa + i+1]; - temp = c * a + s * b; - R[j*kin_mem->kin_m_aa + i+1] = -s*a + c*b; - R[j*kin_mem->kin_m_aa + i] = temp; - } - } - N_VLinearSum(c, kin_mem->kin_q_aa[i], s, kin_mem->kin_q_aa[i+1], kin_mem->kin_vtemp2); - N_VLinearSum(-s, kin_mem->kin_q_aa[i], c, kin_mem->kin_q_aa[i+1], kin_mem->kin_q_aa[i+1]); - N_VScale(ONE, kin_mem->kin_vtemp2, kin_mem->kin_q_aa[i]); - } - - /* Shift R to the left by one. */ - for (i = 1; i < kin_mem->kin_m_aa; i++) { - for (j = 0; j < kin_mem->kin_m_aa-1; j++) { - R[(i-1)*kin_mem->kin_m_aa + j] = R[i*kin_mem->kin_m_aa + j]; - } - } - - /* Add the new df vector */ - N_VScale(ONE, kin_mem->kin_df_aa[i_pt], kin_mem->kin_vtemp2); - for (j=0; j < (kin_mem->kin_m_aa-1); j++) { - R[(kin_mem->kin_m_aa-1)*kin_mem->kin_m_aa+j] = N_VDotProd(kin_mem->kin_q_aa[j], kin_mem->kin_vtemp2); - N_VLinearSum(ONE, kin_mem->kin_vtemp2, -R[(kin_mem->kin_m_aa-1)*kin_mem->kin_m_aa+j], kin_mem->kin_q_aa[j],kin_mem->kin_vtemp2); - } - R[(kin_mem->kin_m_aa-1)*kin_mem->kin_m_aa+kin_mem->kin_m_aa-1] = SUNRsqrt(N_VDotProd(kin_mem->kin_vtemp2, kin_mem->kin_vtemp2)); - N_VScale((1/R[(kin_mem->kin_m_aa-1)*kin_mem->kin_m_aa+kin_mem->kin_m_aa-1]), kin_mem->kin_vtemp2, kin_mem->kin_q_aa[kin_mem->kin_m_aa-1]); - - /* Update the iteration map */ - j = 0; - for (i=i_pt+1; i < kin_mem->kin_m_aa; i++) - ipt_map[j++] = i; - for (i=0; i < (i_pt+1); i++) - ipt_map[j++] = i; - } - - /* Solve least squares problem and update solution */ - lAA = iter; - if (kin_mem->kin_m_aa < iter) lAA = kin_mem->kin_m_aa; - - retval = N_VDotProdMulti((int) lAA, fv, kin_mem->kin_q_aa, gamma); - if (retval != KIN_SUCCESS) return(KIN_VECTOROP_ERR); - - /* set arrays for fused vector operation */ - cv[0] = ONE; - Xv[0] = gval; - nvec = 1; - - for (i=lAA-1; i > -1; i--) { - for (j=i+1; j < lAA; j++) { - gamma[i] = gamma[i]-R[j*kin_mem->kin_m_aa+i]*gamma[j]; - } - gamma[i] = gamma[i]/R[i*kin_mem->kin_m_aa+i]; - - cv[nvec] = -gamma[i]; - Xv[nvec] = kin_mem->kin_dg_aa[ipt_map[i]]; - nvec += 1; - } - - /* if enabled, apply damping */ - if (kin_mem->kin_damping_aa) { - onembeta = (ONE - kin_mem->kin_beta_aa); - cv[nvec] = -onembeta; - Xv[nvec] = fv; - nvec += 1; - for (i = lAA - 1; i > -1; i--) { - cv[nvec] = onembeta * gamma[i]; - Xv[nvec] = kin_mem->kin_df_aa[ipt_map[i]]; - nvec += 1; - } - } - - /* update solution */ - retval = N_VLinearCombination(nvec, cv, Xv, x); - if (retval != KIN_SUCCESS) return(KIN_VECTOROP_ERR); - - return 0; -} diff --git a/ThirdParty/sundials/src/kinsol/kinsol_bbdpre.c b/ThirdParty/sundials/src/kinsol/kinsol_bbdpre.c deleted file mode 100644 index 4bdff30790..0000000000 --- a/ThirdParty/sundials/src/kinsol/kinsol_bbdpre.c +++ /dev/null @@ -1,582 +0,0 @@ -/* ----------------------------------------------------------------- - * Programmer(s): David J. Gardner @ LLNL - * Allan Taylor, Alan Hindmarsh, Radu Serban, and - * Aaron Collier @ LLNL - * ----------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - * ----------------------------------------------------------------- - * This file contains implementations of routines for a - * band-block-diagonal preconditioner, i.e. a block-diagonal - * matrix with banded blocks, for use with KINSol and the - * KINLS linear solver interface. - * - * Note: With only one process, a banded matrix results - * rather than a b-b-d matrix with banded blocks. Diagonal - * blocking occurs at the process level. - * -----------------------------------------------------------------*/ - -#include -#include - -#include "kinsol_impl.h" -#include "kinsol_ls_impl.h" -#include "kinsol_bbdpre_impl.h" - -#include -#include - -#define ZERO RCONST(0.0) -#define ONE RCONST(1.0) - -/* Prototypes of functions KINBBDPrecSetup and KINBBDPrecSolve */ -static int KINBBDPrecSetup(N_Vector uu, N_Vector uscale, - N_Vector fval, N_Vector fscale, - void *pdata); - -static int KINBBDPrecSolve(N_Vector uu, N_Vector uscale, - N_Vector fval, N_Vector fscale, - N_Vector vv, void *pdata); - -/* Prototype for KINBBDPrecFree */ -static int KINBBDPrecFree(KINMem kin_mem); - -/* Prototype for difference quotient jacobian calculation routine */ -static int KBBDDQJac(KBBDPrecData pdata, - N_Vector uu, N_Vector uscale, - N_Vector gu, N_Vector gtemp, N_Vector utemp); - -/*------------------------------------------------------------------ - user-callable functions - ------------------------------------------------------------------*/ - -/*------------------------------------------------------------------ - KINBBDPrecInit - ------------------------------------------------------------------*/ -int KINBBDPrecInit(void *kinmem, sunindextype Nlocal, - sunindextype mudq, sunindextype mldq, - sunindextype mukeep, sunindextype mlkeep, - realtype dq_rel_uu, - KINBBDLocalFn gloc, KINBBDCommFn gcomm) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - KBBDPrecData pdata; - sunindextype muk, mlk, storage_mu, lrw1, liw1; - long int lrw, liw; - int flag; - - if (kinmem == NULL) { - KINProcessError(NULL, KINLS_MEM_NULL, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_MEM_NULL); - return(KINLS_MEM_NULL); - } - kin_mem = (KINMem) kinmem; - - /* Test if the LS linear solver interface has been created */ - if (kin_mem->kin_lmem == NULL) { - KINProcessError(kin_mem, KINLS_LMEM_NULL, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_LMEM_NULL); - return(KINLS_LMEM_NULL); - } - kinls_mem = (KINLsMem) kin_mem->kin_lmem; - - /* Test compatibility of NVECTOR package with the BBD preconditioner */ - /* Note: Do NOT need to check for N_VScale since has already been checked for in KINSOL */ - if (kin_mem->kin_vtemp1->ops->nvgetarraypointer == NULL) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_BAD_NVECTOR); - return(KINLS_ILL_INPUT); - } - - /* Allocate data memory */ - pdata = NULL; - pdata = (KBBDPrecData) malloc(sizeof *pdata); - if (pdata == NULL) { - KINProcessError(kin_mem, KINLS_MEM_FAIL, - "KINBBDPRE", "KINBBDPrecInit", MSGBBD_MEM_FAIL); - return(KINLS_MEM_FAIL); - } - - /* Set pointers to gloc and gcomm; load half-bandwidths */ - pdata->kin_mem = kinmem; - pdata->gloc = gloc; - pdata->gcomm = gcomm; - pdata->mudq = SUNMIN(Nlocal-1, SUNMAX(0, mudq)); - pdata->mldq = SUNMIN(Nlocal-1, SUNMAX(0, mldq)); - muk = SUNMIN(Nlocal-1, SUNMAX(0, mukeep)); - mlk = SUNMIN(Nlocal-1, SUNMAX(0, mlkeep)); - pdata->mukeep = muk; - pdata->mlkeep = mlk; - - /* Set extended upper half-bandwidth for PP (required for pivoting) */ - storage_mu = SUNMIN(Nlocal-1, muk+mlk); - - /* Allocate memory for preconditioner matrix */ - pdata->PP = NULL; - pdata->PP = SUNBandMatrixStorage(Nlocal, muk, mlk, storage_mu); - if (pdata->PP == NULL) { - free(pdata); pdata = NULL; - KINProcessError(kin_mem, KINLS_MEM_FAIL, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_MEM_FAIL); - return(KINLS_MEM_FAIL); - } - - /* Allocate memory for temporary N_Vectors */ - pdata->zlocal = NULL; - pdata->zlocal = N_VNew_Serial(Nlocal); - if (pdata->zlocal == NULL) { - SUNMatDestroy(pdata->PP); - free(pdata); pdata = NULL; - KINProcessError(kin_mem, KINLS_MEM_FAIL, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_MEM_FAIL); - return(KINLS_MEM_FAIL); - } - - pdata->rlocal = NULL; - pdata->rlocal = N_VNewEmpty_Serial(Nlocal); /* empty vector */ - if (pdata->rlocal == NULL) { - N_VDestroy(pdata->zlocal); - SUNMatDestroy(pdata->PP); - free(pdata); pdata = NULL; - KINProcessError(kin_mem, KINLS_MEM_FAIL, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_MEM_FAIL); - return(KINLS_MEM_FAIL); - } - - pdata->tempv1 = NULL; - pdata->tempv1 = N_VClone(kin_mem->kin_vtemp1); - if (pdata->tempv1 == NULL) { - N_VDestroy(pdata->zlocal); - N_VDestroy(pdata->rlocal); - SUNMatDestroy(pdata->PP); - free(pdata); pdata = NULL; - KINProcessError(kin_mem, KINLS_MEM_FAIL, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_MEM_FAIL); - return(KINLS_MEM_FAIL); - } - - pdata->tempv2 = NULL; - pdata->tempv2 = N_VClone(kin_mem->kin_vtemp1); - if (pdata->tempv2 == NULL) { - N_VDestroy(pdata->zlocal); - N_VDestroy(pdata->rlocal); - N_VDestroy(pdata->tempv1); - SUNMatDestroy(pdata->PP); - free(pdata); pdata = NULL; - KINProcessError(kin_mem, KINLS_MEM_FAIL, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_MEM_FAIL); - return(KINLS_MEM_FAIL); - } - - pdata->tempv3 = NULL; - pdata->tempv3 = N_VClone(kin_mem->kin_vtemp1); - if (pdata->tempv3 == NULL) { - N_VDestroy(pdata->zlocal); - N_VDestroy(pdata->rlocal); - N_VDestroy(pdata->tempv1); - N_VDestroy(pdata->tempv2); - SUNMatDestroy(pdata->PP); - free(pdata); pdata = NULL; - KINProcessError(kin_mem, KINLS_MEM_FAIL, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_MEM_FAIL); - return(KINLS_MEM_FAIL); - } - - /* Allocate memory for banded linear solver */ - pdata->LS = NULL; - pdata->LS = SUNLinSol_Band(pdata->zlocal, pdata->PP); - if (pdata->LS == NULL) { - N_VDestroy(pdata->zlocal); - N_VDestroy(pdata->rlocal); - N_VDestroy(pdata->tempv1); - N_VDestroy(pdata->tempv2); - N_VDestroy(pdata->tempv3); - SUNMatDestroy(pdata->PP); - free(pdata); pdata = NULL; - KINProcessError(kin_mem, KINLS_MEM_FAIL, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_MEM_FAIL); - return(KINLS_MEM_FAIL); - } - - /* initialize band linear solver object */ - flag = SUNLinSolInitialize(pdata->LS); - if (flag != SUNLS_SUCCESS) { - N_VDestroy(pdata->zlocal); - N_VDestroy(pdata->rlocal); - N_VDestroy(pdata->tempv1); - N_VDestroy(pdata->tempv2); - N_VDestroy(pdata->tempv3); - SUNMatDestroy(pdata->PP); - SUNLinSolFree(pdata->LS); - free(pdata); pdata = NULL; - KINProcessError(kin_mem, KINLS_SUNLS_FAIL, "KINBBDPRE", - "KINBBDPrecInit", MSGBBD_SUNLS_FAIL); - return(KINLS_SUNLS_FAIL); - } - - /* Set rel_uu based on input value dq_rel_uu (0 implies default) */ - pdata->rel_uu = (dq_rel_uu > ZERO) ? dq_rel_uu : SUNRsqrt(kin_mem->kin_uround); - - /* Store Nlocal to be used in KINBBDPrecSetup */ - pdata->n_local = Nlocal; - - /* Set work space sizes and initialize nge */ - pdata->rpwsize = 0; - pdata->ipwsize = 0; - if (kin_mem->kin_vtemp1->ops->nvspace) { - N_VSpace(kin_mem->kin_vtemp1, &lrw1, &liw1); - pdata->rpwsize += 3*lrw1; - pdata->ipwsize += 3*liw1; - } - if (pdata->zlocal->ops->nvspace) { - N_VSpace(pdata->zlocal, &lrw1, &liw1); - pdata->rpwsize += lrw1; - pdata->ipwsize += liw1; - } - if (pdata->rlocal->ops->nvspace) { - N_VSpace(pdata->rlocal, &lrw1, &liw1); - pdata->rpwsize += lrw1; - pdata->ipwsize += liw1; - } - if (pdata->PP->ops->space) { - flag = SUNMatSpace(pdata->PP, &lrw, &liw); - pdata->rpwsize += lrw; - pdata->ipwsize += liw; - } - if (pdata->LS->ops->space) { - flag = SUNLinSolSpace(pdata->LS, &lrw, &liw); - pdata->rpwsize += lrw; - pdata->ipwsize += liw; - } - pdata->nge = 0; - - /* make sure pdata is free from any previous allocations */ - if (kinls_mem->pfree != NULL) - kinls_mem->pfree(kin_mem); - - /* Point to the new pdata field in the LS memory */ - kinls_mem->pdata = pdata; - - /* Attach the pfree function */ - kinls_mem->pfree = KINBBDPrecFree; - - /* Attach preconditioner solve and setup functions */ - flag = KINSetPreconditioner(kinmem, KINBBDPrecSetup, - KINBBDPrecSolve); - - return(flag); -} - - -/*------------------------------------------------------------------ - KINBBDPrecGetWorkSpace - ------------------------------------------------------------------*/ -int KINBBDPrecGetWorkSpace(void *kinmem, - long int *lenrwBBDP, - long int *leniwBBDP) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - KBBDPrecData pdata; - - if (kinmem == NULL) { - KINProcessError(NULL, KINLS_MEM_NULL, "KINBBDPRE", - "KINBBDPrecGetWorkSpace", MSGBBD_MEM_NULL); - return(KINLS_MEM_NULL); - } - kin_mem = (KINMem) kinmem; - - if (kin_mem->kin_lmem == NULL) { - KINProcessError(kin_mem, KINLS_LMEM_NULL, "KINBBDPRE", - "KINBBDPrecGetWorkSpace", MSGBBD_LMEM_NULL); - return(KINLS_LMEM_NULL); - } - kinls_mem = (KINLsMem) kin_mem->kin_lmem; - - if (kinls_mem->pdata == NULL) { - KINProcessError(kin_mem, KINLS_PMEM_NULL, "KINBBDPRE", - "KINBBDPrecGetWorkSpace", MSGBBD_PMEM_NULL); - return(KINLS_PMEM_NULL); - } - pdata = (KBBDPrecData) kinls_mem->pdata; - - *lenrwBBDP = pdata->rpwsize; - *leniwBBDP = pdata->ipwsize; - - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINBBDPrecGetNumGfnEvals - -------------------------------------------------------------------*/ -int KINBBDPrecGetNumGfnEvals(void *kinmem, - long int *ngevalsBBDP) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - KBBDPrecData pdata; - - if (kinmem == NULL) { - KINProcessError(NULL, KINLS_MEM_NULL, "KINBBDPRE", - "KINBBDPrecGetNumGfnEvals", MSGBBD_MEM_NULL); - return(KINLS_MEM_NULL); - } - kin_mem = (KINMem) kinmem; - - if (kin_mem->kin_lmem == NULL) { - KINProcessError(kin_mem, KINLS_LMEM_NULL, "KINBBDPRE", - "KINBBDPrecGetNumGfnEvals", MSGBBD_LMEM_NULL); - return(KINLS_LMEM_NULL); - } - kinls_mem = (KINLsMem) kin_mem->kin_lmem; - - if (kinls_mem->pdata == NULL) { - KINProcessError(kin_mem, KINLS_PMEM_NULL, "KINBBDPRE", - "KINBBDPrecGetNumGfnEvals", MSGBBD_PMEM_NULL); - return(KINLS_PMEM_NULL); - } - pdata = (KBBDPrecData) kinls_mem->pdata; - - *ngevalsBBDP = pdata->nge; - - return(KINLS_SUCCESS); -} - - -/*------------------------------------------------------------------ - KINBBDPrecSetup - - KINBBDPrecSetup generates and factors a banded block of the - preconditioner matrix on each processor, via calls to the - user-supplied gloc and gcomm functions. It uses difference - quotient approximations to the Jacobian elements. - - KINBBDPrecSetup calculates a new Jacobian, stored in banded - matrix PP and does an LU factorization of P in place in PP. - - The parameters of KINBBDPrecSetup are as follows: - - uu is the current value of the dependent variable vector, - namely the solutin to func(uu)=0 - - uscale is the dependent variable scaling vector (i.e. uu) - - fval is the vector f(u) - - fscale is the function scaling vector - - bbd_data is the pointer to BBD data set by KINBBDInit. - - Note: The value to be returned by the KINBBDPrecSetup function - is a flag indicating whether it was successful. This value is: - 0 if successful, - > 0 for a recoverable error - step will be retried. - ------------------------------------------------------------------*/ -static int KINBBDPrecSetup(N_Vector uu, N_Vector uscale, - N_Vector fval, N_Vector fscale, - void *bbd_data) -{ - KBBDPrecData pdata; - KINMem kin_mem; - int retval; - - pdata = (KBBDPrecData) bbd_data; - - kin_mem = (KINMem) pdata->kin_mem; - - /* Call KBBDDQJac for a new Jacobian calculation and store in PP */ - retval = SUNMatZero(pdata->PP); - if (retval != 0) { - KINProcessError(kin_mem, -1, "KINBBDPRE", "KINBBDPrecSetup", - MSGBBD_SUNMAT_FAIL); - return(-1); - } - - retval = KBBDDQJac(pdata, uu, uscale, - pdata->tempv1, pdata->tempv2, pdata->tempv3); - if (retval != 0) { - KINProcessError(kin_mem, -1, "KINBBDPRE", "KINBBDPrecSetup", - MSGBBD_FUNC_FAILED); - return(-1); - } - - /* Do LU factorization of P and return error flag */ - retval = SUNLinSolSetup_Band(pdata->LS, pdata->PP); - return(retval); -} - -/*------------------------------------------------------------------ - INBBDPrecSolve - - KINBBDPrecSolve solves a linear system P z = r, with the - banded blocked preconditioner matrix P generated and factored - by KINBBDPrecSetup. Here, r comes in as vv and z is - returned in vv as well. - - The parameters for KINBBDPrecSolve are as follows: - - uu an N_Vector giving the current iterate for the system - - uscale an N_Vector giving the diagonal entries of the - uu scaling matrix - - fval an N_Vector giving the current function value - - fscale an N_Vector giving the diagonal entries of the - function scaling matrix - - vv vector initially set to the right-hand side vector r, but - which upon return contains a solution of the linear system - P*z = r - - bbd_data is the pointer to BBD data set by KINBBDInit. - - Note: The value returned by the KINBBDPrecSolve function is a - flag returned from the lienar solver object. - ------------------------------------------------------------------*/ - -static int KINBBDPrecSolve(N_Vector uu, N_Vector uscale, - N_Vector fval, N_Vector fscale, - N_Vector vv, void *bbd_data) -{ - KBBDPrecData pdata; - realtype *vd; - realtype *zd; - int i, retval; - - pdata = (KBBDPrecData) bbd_data; - - /* Get data pointers */ - vd = N_VGetArrayPointer(vv); - zd = N_VGetArrayPointer(pdata->zlocal); - - /* Attach local data array for vv to rlocal */ - N_VSetArrayPointer(vd, pdata->rlocal); - - /* Call banded solver object to do the work */ - retval = SUNLinSolSolve(pdata->LS, pdata->PP, pdata->zlocal, - pdata->rlocal, ZERO); - - /* Copy result into vv */ - for (i=0; in_local; i++) - vd[i] = zd[i]; - - return(retval); -} - - -/*------------------------------------------------------------------ - KINBBDPrecFree - ------------------------------------------------------------------*/ -static int KINBBDPrecFree(KINMem kin_mem) -{ - KINLsMem kinls_mem; - KBBDPrecData pdata; - - if (kin_mem->kin_lmem == NULL) return(0); - kinls_mem = (KINLsMem) kin_mem->kin_lmem; - - if (kinls_mem->pdata == NULL) return(0); - pdata = (KBBDPrecData) kinls_mem->pdata; - - SUNLinSolFree(pdata->LS); - N_VDestroy(pdata->zlocal); - N_VDestroy(pdata->rlocal); - N_VDestroy(pdata->tempv1); - N_VDestroy(pdata->tempv2); - N_VDestroy(pdata->tempv3); - SUNMatDestroy(pdata->PP); - - free(pdata); - pdata = NULL; - - return(0); -} - - -/*------------------------------------------------------------------ - KBBDDQJac - - This routine generates a banded difference quotient - approximation to the Jacobian of f(u). It assumes that a band - matrix of type SUNMatrix is stored column-wise, and that elements - within each column are contiguous. All matrix elements are - generated as difference quotients, by way of calls to the user - routine gloc. By virtue of the band structure, the number of - these calls is bandwidth + 1, where bandwidth = ml + mu + 1. - This routine also assumes that the local elements of a vector - are stored contiguously. - ------------------------------------------------------------------*/ -static int KBBDDQJac(KBBDPrecData pdata, - N_Vector uu, N_Vector uscale, - N_Vector gu, N_Vector gtemp, N_Vector utemp) -{ - KINMem kin_mem; - realtype inc, inc_inv; - int retval; - sunindextype group, i, j, width, ngroups, i1, i2; - realtype *udata, *uscdata, *gudata, *gtempdata, *utempdata, *col_j; - - kin_mem = (KINMem) pdata->kin_mem; - - /* load utemp with uu = predicted solution vector */ - N_VScale(ONE, uu, utemp); - - /* set pointers to the data for all vectors */ - udata = N_VGetArrayPointer(uu); - uscdata = N_VGetArrayPointer(uscale); - gudata = N_VGetArrayPointer(gu); - gtempdata = N_VGetArrayPointer(gtemp); - utempdata = N_VGetArrayPointer(utemp); - - /* Call gcomm and gloc to get base value of g(uu) */ - if (pdata->gcomm != NULL) { - retval = pdata->gcomm(pdata->n_local, uu, kin_mem->kin_user_data); - if (retval != 0) return(retval); - } - - retval = pdata->gloc(pdata->n_local, uu, gu, kin_mem->kin_user_data); - pdata->nge++; - if (retval != 0) return(retval); - - /* Set bandwidth and number of column groups for band differencing */ - width = pdata->mldq + pdata->mudq + 1; - ngroups = SUNMIN(width, pdata->n_local); - - /* Loop over groups */ - for(group = 1; group <= ngroups; group++) { - - /* increment all u_j in group */ - for(j = group - 1; j < pdata->n_local; j += width) { - inc = pdata->rel_uu * SUNMAX(SUNRabs(udata[j]), (ONE / uscdata[j])); - utempdata[j] += inc; - } - - /* Evaluate g with incremented u */ - retval = pdata->gloc(pdata->n_local, utemp, gtemp, kin_mem->kin_user_data); - pdata->nge++; - if (retval != 0) return(retval); - - /* restore utemp, then form and load difference quotients */ - for (j = group - 1; j < pdata->n_local; j += width) { - utempdata[j] = udata[j]; - col_j = SUNBandMatrix_Column(pdata->PP,j); - inc = pdata->rel_uu * SUNMAX(SUNRabs(udata[j]) , (ONE / uscdata[j])); - inc_inv = ONE / inc; - i1 = SUNMAX(0, (j - pdata->mukeep)); - i2 = SUNMIN((j + pdata->mlkeep), (pdata->n_local - 1)); - for (i = i1; i <= i2; i++) - SM_COLUMN_ELEMENT_B(col_j, i, j) = inc_inv * (gtempdata[i] - gudata[i]); - } - } - - return(0); -} diff --git a/ThirdParty/sundials/src/kinsol/kinsol_bbdpre_impl.h b/ThirdParty/sundials/src/kinsol/kinsol_bbdpre_impl.h deleted file mode 100644 index 6541a32be0..0000000000 --- a/ThirdParty/sundials/src/kinsol/kinsol_bbdpre_impl.h +++ /dev/null @@ -1,82 +0,0 @@ -/* ----------------------------------------------------------------- - * Programmer(s): David J. Gardner @ LLNL - * Allan Taylor, Alan Hindmarsh, Radu Serban, and - * Aaron Collier @ LLNL - * ----------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - * ----------------------------------------------------------------- - * KINBBDPRE module header file (private version) - * -----------------------------------------------------------------*/ - -#ifndef _KINBBDPRE_IMPL_H -#define _KINBBDPRE_IMPL_H - -#include -#include -#include - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -/*------------------------------------------------------------------ - Definition of KBBDData - ------------------------------------------------------------------*/ - -typedef struct KBBDPrecDataRec { - - /* passed by user to KINBBDPrecAlloc, used by pset/psolve functions */ - sunindextype mudq, mldq, mukeep, mlkeep; - realtype rel_uu; /* relative error for the Jacobian DQ routine */ - KINBBDLocalFn gloc; - KINBBDCommFn gcomm; - - /* set by KINBBDPrecSetup and used by KINBBDPrecSetup and - KINBBDPrecSolve functions */ - sunindextype n_local; - SUNMatrix PP; - SUNLinearSolver LS; - N_Vector rlocal; - N_Vector zlocal; - N_Vector tempv1; - N_Vector tempv2; - N_Vector tempv3; - - /* available for optional output */ - long int rpwsize; - long int ipwsize; - long int nge; - - /* pointer to KINSol memory */ - void *kin_mem; - -} *KBBDPrecData; - -/* - *----------------------------------------------------------------- - * KINBBDPRE error messages - *----------------------------------------------------------------- - */ - -#define MSGBBD_MEM_NULL "KINSOL Memory is NULL." -#define MSGBBD_LMEM_NULL "Linear solver memory is NULL. One of the SPILS linear solvers must be attached." -#define MSGBBD_MEM_FAIL "A memory request failed." -#define MSGBBD_BAD_NVECTOR "A required vector operation is not implemented." -#define MSGBBD_SUNMAT_FAIL "An error arose from a SUNBandMatrix routine." -#define MSGBBD_SUNLS_FAIL "An error arose from a SUNBandLinearSolver routine." -#define MSGBBD_PMEM_NULL "BBD peconditioner memory is NULL. IDABBDPrecInit must be called." -#define MSGBBD_FUNC_FAILED "The gloc or gcomm routine failed in an unrecoverable manner." - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ThirdParty/sundials/src/kinsol/kinsol_direct.c b/ThirdParty/sundials/src/kinsol/kinsol_direct.c deleted file mode 100644 index d5b0e3805f..0000000000 --- a/ThirdParty/sundials/src/kinsol/kinsol_direct.c +++ /dev/null @@ -1,55 +0,0 @@ -/*----------------------------------------------------------------- - * Programmer(s): Daniel R. Reynolds @ SMU - * Radu Serban @ LLNL - *----------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - *----------------------------------------------------------------- - * Implementation file for the deprecated direct linear solver interface in - * KINSOL; these routines now just wrap the updated KINSOL generic - * linear solver interface in kinsol_ls.h. - *-----------------------------------------------------------------*/ - -#include -#include - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -/*================================================================= - Exported Functions (wrappers for equivalent routines in kinsol_ls.h) - =================================================================*/ - -int KINDlsSetLinearSolver(void *kinmem, SUNLinearSolver LS, SUNMatrix A) -{ return(KINSetLinearSolver(kinmem, LS, A)); } - -int KINDlsSetJacFn(void *kinmem, KINDlsJacFn jac) -{ return(KINSetJacFn(kinmem, jac)); } - -int KINDlsGetWorkSpace(void *kinmem, long int *lenrw, long int *leniw) -{ return(KINGetLinWorkSpace(kinmem, lenrw, leniw)); } - -int KINDlsGetNumJacEvals(void *kinmem, long int *njevals) -{ return(KINGetNumJacEvals(kinmem, njevals)); } - -int KINDlsGetNumFuncEvals(void *kinmem, long int *nfevals) -{ return(KINGetNumLinFuncEvals(kinmem, nfevals)); } - -int KINDlsGetLastFlag(void *kinmem, long int *flag) -{ return(KINGetLastLinFlag(kinmem, flag)); } - -char *KINDlsGetReturnFlagName(long int flag) -{ return(KINGetLinReturnFlagName(flag)); } - -#ifdef __cplusplus -} -#endif - diff --git a/ThirdParty/sundials/src/kinsol/kinsol_impl.h b/ThirdParty/sundials/src/kinsol/kinsol_impl.h deleted file mode 100644 index ad1ccb6564..0000000000 --- a/ThirdParty/sundials/src/kinsol/kinsol_impl.h +++ /dev/null @@ -1,489 +0,0 @@ -/* - * ----------------------------------------------------------------- - * Programmer(s): Allan Taylor, Alan Hindmarsh, Radu Serban, and - * Aaron Collier @ LLNL - * ----------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - * ----------------------------------------------------------------- - * KINSOL solver module header file (private version) - * ----------------------------------------------------------------- - */ - -#ifndef _KINSOL_IMPL_H -#define _KINSOL_IMPL_H - -#include - -#include - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -/* - * ================================================================= - * M A I N S O L V E R M E M O R Y B L O C K - * ================================================================= - */ - -/* KINSOL default constants */ - -#define PRINTFL_DEFAULT 0 -#define MXITER_DEFAULT 200 -#define MXNBCF_DEFAULT 10 -#define MSBSET_DEFAULT 10 -#define MSBSET_SUB_DEFAULT 5 - -#define OMEGA_MIN RCONST(0.00001) -#define OMEGA_MAX RCONST(0.9) - -/* - * ----------------------------------------------------------------- - * Types : struct KINMemRec and struct *KINMem - * ----------------------------------------------------------------- - * A variable declaration of type struct *KINMem denotes a - * pointer to a data structure of type struct KINMemRec. The - * KINMemRec structure contains numerous fields that must be - * accessible by KINSOL solver module routines. - * ----------------------------------------------------------------- - */ - -typedef struct KINMemRec { - - realtype kin_uround; /* machine epsilon (or unit roundoff error) - (defined in sundials_types.h) */ - - /* problem specification data */ - - KINSysFn kin_func; /* nonlinear system function implementation */ - void *kin_user_data; /* work space available to func routine */ - realtype kin_fnormtol; /* stopping tolerance on L2-norm of function - value */ - realtype kin_scsteptol; /* scaled step length tolerance */ - int kin_globalstrategy; /* choices are KIN_NONE, KIN_LINESEARCH - KIN_PICARD and KIN_FP */ - int kin_printfl; /* level of verbosity of output */ - long int kin_mxiter; /* maximum number of nonlinear iterations */ - long int kin_msbset; /* maximum number of nonlinear iterations that - may be performed between calls to the - linear solver setup routine (lsetup) */ - long int kin_msbset_sub; /* subinterval length for residual monitoring */ - long int kin_mxnbcf; /* maximum number of beta condition failures */ - int kin_etaflag; /* choices are KIN_ETACONSTANT, KIN_ETACHOICE1 - and KIN_ETACHOICE2 */ - booleantype kin_noMinEps; /* flag controlling whether or not the value - of eps is bounded below */ - booleantype kin_constraintsSet; /* flag indicating if constraints are being - used */ - booleantype kin_jacCurrent; /* flag indicating if the Jacobian info. - used by the linear solver is current */ - booleantype kin_callForcingTerm; /* flag set if using either KIN_ETACHOICE1 - or KIN_ETACHOICE2 */ - booleantype kin_noResMon; /* flag indicating if the nonlinear - residual monitoring scheme should be - used */ - booleantype kin_retry_nni; /* flag indicating if nonlinear iteration - should be retried (set by residual - monitoring algorithm) */ - booleantype kin_update_fnorm_sub; /* flag indicating if the fnorm associated - with the subinterval needs to be - updated (set by residual monitoring - algorithm) */ - - realtype kin_mxnewtstep; /* maximum allowable scaled step length */ - realtype kin_mxnstepin; /* input (or preset) value for mxnewtstep */ - realtype kin_sqrt_relfunc; /* relative error bound for func(u) */ - realtype kin_stepl; /* scaled length of current step */ - realtype kin_stepmul; /* step scaling factor */ - realtype kin_eps; /* current value of eps */ - realtype kin_eta; /* current value of eta */ - realtype kin_eta_gamma; /* gamma value used in eta calculation - (choice #2) */ - realtype kin_eta_alpha; /* alpha value used in eta calculation - (choice #2) */ - booleantype kin_noInitSetup; /* flag controlling whether or not the KINSol - routine makes an initial call to the - linear solver setup routine (lsetup) */ - realtype kin_sthrsh; /* threshold value for calling the linear - solver setup routine */ - - /* counters */ - - long int kin_nni; /* number of nonlinear iterations */ - long int kin_nfe; /* number of calls made to func routine */ - long int kin_nnilset; /* value of nni counter when the linear solver - setup was last called */ - long int kin_nnilset_sub; /* value of nni counter when the linear solver - setup was last called (subinterval) */ - long int kin_nbcf; /* number of times the beta-condition could not - be met in KINLineSearch */ - long int kin_nbktrk; /* number of backtracks performed by - KINLineSearch */ - long int kin_ncscmx; /* number of consecutive steps of size - mxnewtstep taken */ - - /* vectors */ - - N_Vector kin_uu; /* solution vector/current iterate (initially - contains initial guess, but holds approximate - solution upon completion if no errors occurred) */ - N_Vector kin_unew; /* next iterate (unew = uu+pp) */ - N_Vector kin_fval; /* vector containing result of nonlinear system - function evaluated at a given iterate - (fval = func(uu)) */ - N_Vector kin_gval; /* vector containing result of the fixed point - function evaluated at a given iterate; - used in KIN_PICARD strategy only. - (gval = uu - L^{-1}fval(uu)) */ - N_Vector kin_uscale; /* iterate scaling vector */ - N_Vector kin_fscale; /* fval scaling vector */ - N_Vector kin_pp; /* incremental change vector (pp = unew-uu) */ - N_Vector kin_constraints; /* constraints vector */ - N_Vector kin_vtemp1; /* scratch vector #1 */ - N_Vector kin_vtemp2; /* scratch vector #2 */ - - /* space requirements for AA, Broyden and NLEN */ - N_Vector kin_fold_aa; /* vector needed for AA, Broyden, and NLEN */ - N_Vector kin_gold_aa; /* vector needed for AA, Broyden, and NLEN */ - N_Vector *kin_df_aa; /* vector array needed for AA, Broyden, and NLEN */ - N_Vector *kin_dg_aa; /* vector array needed for AA, Broyden and NLEN */ - N_Vector *kin_q_aa; /* vector array needed for AA */ - realtype kin_beta_aa; /* beta damping parameter for AA */ - realtype *kin_gamma_aa; /* array of size maa used in AA */ - realtype *kin_R_aa; /* array of size maa*maa used in AA */ - long int *kin_ipt_map; /* array of size maa used in AA */ - long int kin_m_aa; /* parameter for AA, Broyden or NLEN */ - booleantype kin_aamem_aa; /* sets additional memory needed for Anderson Acc */ - booleantype kin_setstop_aa; /* determines whether user will set stopping criterion */ - booleantype kin_damping_aa; /* flag to apply damping in AA */ - realtype *kin_cv; /* scalar array for fused vector operations */ - N_Vector *kin_Xv; /* vector array for fused vector operations */ - - /* space requirements for vector storage */ - - sunindextype kin_lrw1; /* number of realtype-sized memory blocks needed - for a single N_Vector */ - sunindextype kin_liw1; /* number of int-sized memory blocks needed for - a single N_Vecotr */ - long int kin_lrw; /* total number of realtype-sized memory blocks - needed for all KINSOL work vectors */ - long int kin_liw; /* total number of int-sized memory blocks needed - for all KINSOL work vectors */ - - /* linear solver data */ - - /* function prototypes (pointers) */ - - int (*kin_linit)(struct KINMemRec *kin_mem); - - int (*kin_lsetup)(struct KINMemRec *kin_mem); - - int (*kin_lsolve)(struct KINMemRec *kin_mem, N_Vector xx, N_Vector bb, - realtype *sJpnorm, realtype *sFdotJp); - - int (*kin_lfree)(struct KINMemRec *kin_mem); - - booleantype kin_inexact_ls; /* flag set by the linear solver module - (in linit) indicating whether this is an - iterative linear solver (SUNTRUE), or a direct - linear solver (SUNFALSE) */ - - void *kin_lmem; /* pointer to linear solver memory block */ - - realtype kin_fnorm; /* value of L2-norm of fscale*fval */ - realtype kin_f1norm; /* f1norm = 0.5*(fnorm)^2 */ - realtype kin_sFdotJp; /* value of scaled F(u) vector (fscale*fval) - dotted with scaled J(u)*pp vector (set by lsolve) */ - realtype kin_sJpnorm; /* value of L2-norm of fscale*(J(u)*pp) - (set by lsolve) */ - - realtype kin_fnorm_sub; /* value of L2-norm of fscale*fval (subinterval) */ - booleantype kin_eval_omega; /* flag indicating that omega must be evaluated. */ - realtype kin_omega; /* constant value for real scalar used in test to - determine if reduction of norm of nonlinear - residual is sufficient. Unless a valid constant - value is specified by the user, omega is estimated - from omega_min and omega_max at each iteration. */ - realtype kin_omega_min; /* lower bound on omega */ - realtype kin_omega_max; /* upper bound on omega */ - - /* - * ----------------------------------------------------------------- - * Note: The KINLineSearch subroutine scales the values of the - * variables sFdotJp and sJpnorm by a factor rl (lambda) that is - * chosen by the line search algorithm such that the sclaed Newton - * step satisfies the following conditions: - * - * F(u_k+1) <= F(u_k) + alpha*(F(u_k)^T * J(u_k))*p*rl - * - * F(u_k+1) >= F(u_k) + beta*(F(u_k)^T * J(u_k))*p*rl - * - * where alpha = 1.0e-4, beta = 0.9, u_k+1 = u_k + rl*p, - * 0 < rl <= 1, J denotes the system Jacobian, and F represents - * the nonliner system function. - * ----------------------------------------------------------------- - */ - - booleantype kin_MallocDone; /* flag indicating if KINMalloc has been - called yet */ - - /* message files */ - /*------------------------------------------- - Error handler function and error ouput file - -------------------------------------------*/ - - KINErrHandlerFn kin_ehfun; /* Error messages are handled by ehfun */ - void *kin_eh_data; /* dats pointer passed to ehfun */ - FILE *kin_errfp; /* KINSOL error messages are sent to errfp */ - - KINInfoHandlerFn kin_ihfun; /* Info messages are handled by ihfun */ - void *kin_ih_data; /* dats pointer passed to ihfun */ - FILE *kin_infofp; /* where KINSol info messages are sent */ - -} *KINMem; - -/* - * ================================================================= - * I N T E R F A C E T O L I N E A R S O L V E R - * ================================================================= - */ - -/* - * ----------------------------------------------------------------- - * Function : int (*kin_linit)(KINMem kin_mem) - * ----------------------------------------------------------------- - * kin_linit initializes solver-specific data structures (including - * variables used as counters or for storing statistical information), - * but system memory allocation should be done by the subroutine - * that actually initializes the environment for liner solver - * package. If the linear system is to be preconditioned, then the - * variable setupNonNull (type booleantype) should be set to SUNTRUE - * (predefined constant) and the kin_lsetup routine should be - * appropriately defined. - * - * kinmem pointer to an internal memory block allocated during - * prior calls to KINCreate and KINMalloc - * - * If the necessary variables have been successfully initialized, - * then the kin_linit function should return 0 (zero). Otherwise, - * the subroutine should indicate a failure has occurred by - * returning a non-zero integer value. - * ----------------------------------------------------------------- - */ - -/* - * ----------------------------------------------------------------- - * Function : int (*kin_lsetup)(KINMem kin_mem) - * ----------------------------------------------------------------- - * kin_lsetup interfaces with the user-supplied pset subroutine (the - * preconditioner setup routine), and updates relevant variable - * values (see KINSpgmrSetup/KINSpbcgSetup). Simply stated, the - * kin_lsetup routine prepares the linear solver for a subsequent - * call to the user-supplied kin_lsolve function. - * - * kinmem pointer to an internal memory block allocated during - * prior calls to KINCreate and KINMalloc - * - * If successful, the kin_lsetup routine should return 0 (zero). - * Otherwise it should return a non-zero value. - * ----------------------------------------------------------------- - */ - -/* - * ----------------------------------------------------------------- - * Function : int (*kin_lsolve)(KINMem kin_mem, N_Vector xx, - * N_Vector bb, realtype *sJpnorm, realtype *sFdotJp) - * ----------------------------------------------------------------- - * kin_lsolve interfaces with the subroutine implementing the - * numerical method to be used to solve the linear system J*xx = bb, - * and must increment the relevant counter variable values in - * addition to computing certain values used by the global strategy - * and forcing term routines (see KINInexactNewton, KINLineSearch, - * KINForcingTerm, and KINSpgmrSolve/KINSpbcgSolve). - * - * kinmem pointer to an internal memory block allocated during - * prior calls to KINCreate and KINMalloc - * - * xx vector (type N_Vector) set to initial guess by kin_lsolve - * routine prior to calling the linear solver, but which upon - * return contains an approximate solution of the linear - * system J*xx = bb, where J denotes the system Jacobian - * - * bb vector (type N_Vector) set to -func(u) (negative of the - * value of the system function evaluated at the current - * iterate) by KINLinSolDrv before kin_lsolve is called - * - * sJpnorm holds the value of the L2-norm (Euclidean norm) of - * fscale*(J(u)*pp) upon return - * - * sFdotJp holds the value of the scaled F(u) (fscale*F) dotted - * with the scaled J(u)*pp vector upon return - * - * If successful, the kin_lsolve routine should return 0 (zero). - * Otherwise it should return a positive value if a re-evaluation - * of the lsetup function could recover, or a negative value if - * no such recovery is possible. - * ----------------------------------------------------------------- - */ - -/* - * ----------------------------------------------------------------- - * Function : int (*kin_lfree)(KINMem kin_mem) - * ----------------------------------------------------------------- - * kin_lfree is called by KINFree and should free (deallocate) all - * system memory resources allocated for the linear solver module - * (see KINSpgmrFree/KINSpbcgFree). It should return 0 upon - * success, nonzero on failure. - * - * kinmem pointer to an internal memory block allocated during - * prior calls to KINCreate and KINMalloc - * ----------------------------------------------------------------- - */ - -/* - * ================================================================= - * K I N S O L I N T E R N A L F U N C T I O N S - * ================================================================= - */ - - -/* High level error handler */ - -void KINProcessError(KINMem kin_mem, - int error_code, const char *module, const char *fname, - const char *msgfmt, ...); - -/* Prototype of internal errHandler function */ - -void KINErrHandler(int error_code, const char *module, const char *function, - char *msg, void *user_data); - - -/* High level info handler */ - -void KINPrintInfo(KINMem kin_mem, - int info_code, const char *module, const char *fname, - const char *msgfmt, ...); - -/* Prototype of internal infoHandler function */ - -void KINInfoHandler(const char *module, const char *function, - char *msg, void *user_data); - -/* - * ================================================================= - * K I N S O L E R R O R M E S S A G E S - * ================================================================= - */ - -#define MSG_MEM_FAIL "A memory request failed." -#define MSG_NO_MEM "kinsol_mem = NULL illegal." -#define MSG_BAD_NVECTOR "A required vector operation is not implemented." -#define MSG_FUNC_NULL "func = NULL illegal." -#define MSG_NO_MALLOC "Attempt to call before KINMalloc illegal." - -#define MSG_BAD_PRINTFL "Illegal value for printfl." -#define MSG_BAD_MXITER "Illegal value for mxiter." -#define MSG_BAD_MSBSET "Illegal msbset < 0." -#define MSG_BAD_MSBSETSUB "Illegal msbsetsub < 0." -#define MSG_BAD_ETACHOICE "Illegal value for etachoice." -#define MSG_BAD_ETACONST "eta out of range." -#define MSG_BAD_GAMMA "gamma out of range." -#define MSG_BAD_ALPHA "alpha out of range." -#define MSG_BAD_MXNEWTSTEP "Illegal mxnewtstep < 0." -#define MSG_BAD_RELFUNC "relfunc < 0 illegal." -#define MSG_BAD_FNORMTOL "fnormtol < 0 illegal." -#define MSG_BAD_SCSTEPTOL "scsteptol < 0 illegal." -#define MSG_BAD_MXNBCF "mxbcf < 0 illegal." -#define MSG_BAD_CONSTRAINTS "Illegal values in constraints vector." -#define MSG_BAD_OMEGA "scalars < 0 illegal." -#define MSG_BAD_MAA "maa < 0 illegal." -#define MSG_ZERO_MAA "maa = 0 illegal." - -#define MSG_LSOLV_NO_MEM "The linear solver memory pointer is NULL." -#define MSG_UU_NULL "uu = NULL illegal." -#define MSG_BAD_GLSTRAT "Illegal value for global strategy." -#define MSG_BAD_USCALE "uscale = NULL illegal." -#define MSG_USCALE_NONPOSITIVE "uscale has nonpositive elements." -#define MSG_BAD_FSCALE "fscale = NULL illegal." -#define MSG_FSCALE_NONPOSITIVE "fscale has nonpositive elements." -#define MSG_CONSTRAINTS_NOTOK "Constraints not allowed with fixed point or Picard iterations" -#define MSG_INITIAL_CNSTRNT "Initial guess does NOT meet constraints." -#define MSG_LINIT_FAIL "The linear solver's init routine failed." - -#define MSG_SYSFUNC_FAILED "The system function failed in an unrecoverable manner." -#define MSG_SYSFUNC_FIRST "The system function failed at the first call." -#define MSG_LSETUP_FAILED "The linear solver's setup function failed in an unrecoverable manner." -#define MSG_LSOLVE_FAILED "The linear solver's solve function failed in an unrecoverable manner." -#define MSG_LINSOLV_NO_RECOVERY "The linear solver's solve function failed recoverably, but the Jacobian data is already current." -#define MSG_LINESEARCH_NONCONV "The line search algorithm was unable to find an iterate sufficiently distinct from the current iterate." -#define MSG_LINESEARCH_BCFAIL "The line search algorithm was unable to satisfy the beta-condition for nbcfails iterations." -#define MSG_MAXITER_REACHED "The maximum number of iterations was reached before convergence." -#define MSG_MXNEWT_5X_EXCEEDED "Five consecutive steps have been taken that satisfy a scaled step length test." -#define MSG_SYSFUNC_REPTD "Unable to correct repeated recoverable system function errors." -#define MSG_NOL_FAIL "Unable to find user's Linear Jacobian, which is required for the KIN_PICARD Strategy" - -/* - * ================================================================= - * K I N S O L I N F O M E S S A G E S - * ================================================================= - */ - -#define INFO_RETVAL "Return value: %d" -#define INFO_ADJ "no. of lambda adjustments = %ld" - -#if defined(SUNDIALS_EXTENDED_PRECISION) - -#define INFO_NNI "nni = %4ld nfe = %6ld fnorm = %26.16Lg" -#define INFO_TOL "scsteptol = %12.3Lg fnormtol = %12.3Lg" -#define INFO_FMAX "scaled f norm (for stopping) = %12.3Lg" -#define INFO_PNORM "pnorm = %12.4Le" -#define INFO_PNORM1 "(ivio=1) pnorm = %12.4Le" -#define INFO_FNORM "fnorm(L2) = %20.8Le" -#define INFO_LAM "min_lam = %11.4Le f1norm = %11.4Le pnorm = %11.4Le" -#define INFO_ALPHA "fnorm = %15.8Le f1norm = %15.8Le alpha_cond = %15.8Le lam = %15.8Le" -#define INFO_BETA "f1norm = %15.8Le beta_cond = %15.8Le lam = %15.8Le" -#define INFO_ALPHABETA "f1norm = %15.8Le alpha_cond = %15.8Le beta_cond = %15.8Le lam = %15.8Le" - -#elif defined(SUNDIALS_DOUBLE_PRECISION) - -#define INFO_NNI "nni = %4ld nfe = %6ld fnorm = %26.16lg" -#define INFO_TOL "scsteptol = %12.3lg fnormtol = %12.3lg" -#define INFO_FMAX "scaled f norm (for stopping) = %12.3lg" -#define INFO_PNORM "pnorm = %12.4le" -#define INFO_PNORM1 "(ivio=1) pnorm = %12.4le" -#define INFO_FNORM "fnorm(L2) = %20.8le" -#define INFO_LAM "min_lam = %11.4le f1norm = %11.4le pnorm = %11.4le" -#define INFO_ALPHA "fnorm = %15.8le f1norm = %15.8le alpha_cond = %15.8le lam = %15.8le" -#define INFO_BETA "f1norm = %15.8le beta_cond = %15.8le lam = %15.8le" -#define INFO_ALPHABETA "f1norm = %15.8le alpha_cond = %15.8le beta_cond = %15.8le lam = %15.8le" - -#else - -#define INFO_NNI "nni = %4ld nfe = %6ld fnorm = %26.16g" -#define INFO_TOL "scsteptol = %12.3g fnormtol = %12.3g" -#define INFO_FMAX "scaled f norm (for stopping) = %12.3g" -#define INFO_PNORM "pnorm = %12.4e" -#define INFO_PNORM1 "(ivio=1) pnorm = %12.4e" -#define INFO_FNORM "fnorm(L2) = %20.8e" -#define INFO_LAM "min_lam = %11.4e f1norm = %11.4e pnorm = %11.4e" -#define INFO_ALPHA "fnorm = %15.8e f1norm = %15.8e alpha_cond = %15.8e lam = %15.8e" -#define INFO_BETA "f1norm = %15.8e beta_cond = %15.8e lam = %15.8e" -#define INFO_ALPHABETA "f1norm = %15.8e alpha_cond = %15.8e beta_cond = %15.8e lam = %15.8e" - -#endif - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ThirdParty/sundials/src/kinsol/kinsol_io.c b/ThirdParty/sundials/src/kinsol/kinsol_io.c deleted file mode 100644 index 5f11b0dda7..0000000000 --- a/ThirdParty/sundials/src/kinsol/kinsol_io.c +++ /dev/null @@ -1,1073 +0,0 @@ -/* ----------------------------------------------------------------- - * Programmer(s): Allan Taylor, Alan Hindmarsh, Radu Serban, and - * Aaron Collier @ LLNL - * ----------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - * ----------------------------------------------------------------- - * This is the implementation file for the optional input and output - * functions for the KINSOL solver. - * ----------------------------------------------------------------- - */ - -#include -#include - -#include "kinsol_impl.h" -#include -#include - -#define ZERO RCONST(0.0) -#define POINT1 RCONST(0.1) -#define ONETHIRD RCONST(0.3333333333333333) -#define HALF RCONST(0.5) -#define TWOTHIRDS RCONST(0.6666666666666667) -#define POINT9 RCONST(0.9) -#define ONE RCONST(1.0) -#define TWO RCONST(2.0) -#define TWOPT5 RCONST(2.5) - -/* - * ================================================================= - * KINSOL optional input functions - * ================================================================= - */ - -/* - * ----------------------------------------------------------------- - * KINSetErrHandlerFn - * ----------------------------------------------------------------- - */ - -int KINSetErrHandlerFn(void *kinmem, KINErrHandlerFn ehfun, void *eh_data) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetErrHandlerFn", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - kin_mem->kin_ehfun = ehfun; - kin_mem->kin_eh_data = eh_data; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetErrFile - * ----------------------------------------------------------------- - */ - -int KINSetErrFile(void *kinmem, FILE *errfp) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetErrFile", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - kin_mem->kin_errfp = errfp; - - return(KIN_SUCCESS); -} - -#define errfp (kin_mem->kin_errfp) - -/* - * ----------------------------------------------------------------- - * Function : KINSetPrintLevel - * ----------------------------------------------------------------- - */ - -int KINSetPrintLevel(void *kinmem, int printfl) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetPrintLevel", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if ((printfl < 0) || (printfl > 3)) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetPrintLevel", MSG_BAD_PRINTFL); - return(KIN_ILL_INPUT); - } - - kin_mem->kin_printfl = printfl; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * KINSetInfoHandlerFn - * ----------------------------------------------------------------- - */ - -int KINSetInfoHandlerFn(void *kinmem, KINInfoHandlerFn ihfun, void *ih_data) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetInfoHandlerFn", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - kin_mem->kin_ihfun = ihfun; - kin_mem->kin_ih_data = ih_data; - - return(KIN_SUCCESS); -} - - -/* - * ----------------------------------------------------------------- - * Function : KINSetInfoFile - * ----------------------------------------------------------------- - */ - -int KINSetInfoFile(void *kinmem, FILE *infofp) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetInfoFile", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - kin_mem->kin_infofp = infofp; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetUserData - * ----------------------------------------------------------------- - */ - -int KINSetUserData(void *kinmem, void *user_data) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetUserData", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - kin_mem->kin_user_data = user_data; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetMAA - * ----------------------------------------------------------------- - */ - -int KINSetMAA(void *kinmem, long int maa) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetMAA", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (maa < 0) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetMAA", MSG_BAD_MAA); - return(KIN_ILL_INPUT); - } - - if (maa > kin_mem->kin_mxiter) maa = kin_mem->kin_mxiter; - - kin_mem->kin_m_aa = maa; - kin_mem->kin_aamem_aa = (maa == 0) ? SUNFALSE : SUNTRUE; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetDampingAA - * ----------------------------------------------------------------- - */ - -int KINSetDampingAA(void *kinmem, realtype beta) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetMAA", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - /* check for illegal input value */ - if (beta <= ZERO) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetDampingAA", - "beta <= 0 illegal"); - return(KIN_ILL_INPUT); - } - - if (beta < ONE) { - /* enable damping */ - kin_mem->kin_beta_aa = beta; - kin_mem->kin_damping_aa = SUNTRUE; - } else { - /* disable damping */ - kin_mem->kin_beta_aa = ONE; - kin_mem->kin_damping_aa = SUNFALSE; - } - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetAAStopCrit - * ----------------------------------------------------------------- - */ - -/* CSW: This function is currently not supported. - -int KINSetAAStopCrit(void *kinmem, booleantype setstop) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetAAStopCrit", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - kin_mem->kin_setstop_aa = setstop; - - return(KIN_SUCCESS); -} -*/ - -/* - * ----------------------------------------------------------------- - * Function : KINSetNumMaxIters - * ----------------------------------------------------------------- - */ - -int KINSetNumMaxIters(void *kinmem, long int mxiter) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetNumMaxIters", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (mxiter < 0) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetNumMaxIters", MSG_BAD_MXITER); - return(KIN_ILL_INPUT); - } - - if (mxiter == 0) - kin_mem->kin_mxiter = MXITER_DEFAULT; - else - kin_mem->kin_mxiter = mxiter; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetNoInitSetup - * ----------------------------------------------------------------- - */ - -int KINSetNoInitSetup(void *kinmem, booleantype noInitSetup) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetNoInitSetup", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - kin_mem->kin_noInitSetup = noInitSetup; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetNoResMon - * ----------------------------------------------------------------- - */ - -int KINSetNoResMon(void *kinmem, booleantype noResMon) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetNoResMon", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - kin_mem->kin_noResMon = noResMon; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetMaxSetupCalls - * ----------------------------------------------------------------- - */ - -int KINSetMaxSetupCalls(void *kinmem, long int msbset) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetMaxSetupCalls", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (msbset < 0) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetMaxSetupCalls", MSG_BAD_MSBSET); - return(KIN_ILL_INPUT); - } - - if (msbset == 0) - kin_mem->kin_msbset = MSBSET_DEFAULT; - else - kin_mem->kin_msbset = msbset; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetMaxSubSetupCalls - * ----------------------------------------------------------------- - */ - -int KINSetMaxSubSetupCalls(void *kinmem, long int msbsetsub) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetMaxSubSetupCalls", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (msbsetsub < 0) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetMaxSubSetupCalls", MSG_BAD_MSBSETSUB); - return(KIN_ILL_INPUT); - } - - if (msbsetsub == 0) - kin_mem->kin_msbset_sub = MSBSET_SUB_DEFAULT; - else - kin_mem->kin_msbset_sub = msbsetsub; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetEtaForm - * ----------------------------------------------------------------- - */ - -int KINSetEtaForm(void *kinmem, int etachoice) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetEtaForm", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if ((etachoice != KIN_ETACONSTANT) && - (etachoice != KIN_ETACHOICE1) && - (etachoice != KIN_ETACHOICE2)) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetEtaForm", MSG_BAD_ETACHOICE); - return(KIN_ILL_INPUT); - } - - kin_mem->kin_etaflag = etachoice; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetEtaConstValue - * ----------------------------------------------------------------- - */ - -int KINSetEtaConstValue(void *kinmem, realtype eta) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetEtaConstValue", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if ((eta < ZERO) || (eta > ONE)) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetEtaConstValue", MSG_BAD_ETACONST); - return(KIN_ILL_INPUT); - } - - if (eta == ZERO) - kin_mem->kin_eta = POINT1; - else - kin_mem->kin_eta = eta; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetEtaParams - * ----------------------------------------------------------------- - */ - -int KINSetEtaParams(void *kinmem, realtype egamma, realtype ealpha) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetEtaParams", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if ((ealpha <= ONE) || (ealpha > TWO)) - if (ealpha != ZERO) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetEtaParams", MSG_BAD_ALPHA); - return(KIN_ILL_INPUT); - } - - if (ealpha == ZERO) - kin_mem->kin_eta_alpha = TWO; - else - kin_mem->kin_eta_alpha = ealpha; - - if ((egamma <= ZERO) || (egamma > ONE)) - if (egamma != ZERO) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetEtaParams", MSG_BAD_GAMMA); - return(KIN_ILL_INPUT); - } - - if (egamma == ZERO) - kin_mem->kin_eta_gamma = POINT9; - else - kin_mem->kin_eta_gamma = egamma; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetResMonParams - * ----------------------------------------------------------------- - */ - -int KINSetResMonParams(void *kinmem, realtype omegamin, realtype omegamax) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetResMonParams", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - /* check omegamin */ - - if (omegamin < ZERO) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetResMonParams", MSG_BAD_OMEGA); - return(KIN_ILL_INPUT); - } - - if (omegamin == ZERO) - kin_mem->kin_omega_min = OMEGA_MIN; - else - kin_mem->kin_omega_min = omegamin; - - /* check omegamax */ - - if (omegamax < ZERO) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetResMonParams", MSG_BAD_OMEGA); - return(KIN_ILL_INPUT); - } - - if (omegamax == ZERO) { - - if (kin_mem->kin_omega_min > OMEGA_MAX) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetResMonParams", MSG_BAD_OMEGA); - return(KIN_ILL_INPUT); - } - else kin_mem->kin_omega_max = OMEGA_MAX; - - } else { - - if (kin_mem->kin_omega_min > omegamax) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetResMonParams", MSG_BAD_OMEGA); - return(KIN_ILL_INPUT); - } - else kin_mem->kin_omega_max = omegamax; - - } - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetResMonConstValue - * ----------------------------------------------------------------- - */ - -int KINSetResMonConstValue(void *kinmem, realtype omegaconst) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetResMonConstValue", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - /* check omegaconst */ - - if (omegaconst < ZERO) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetResMonConstValue", MSG_BAD_OMEGA); - return(KIN_ILL_INPUT); - } - - /* Load omega value. A value of 0 will force using omega_min and omega_max */ - kin_mem->kin_omega = omegaconst; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetNoMinEps - * ----------------------------------------------------------------- - */ - -int KINSetNoMinEps(void *kinmem, booleantype noMinEps) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetNoMinEps", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - kin_mem->kin_noMinEps = noMinEps; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetMaxNewtonStep - * ----------------------------------------------------------------- - */ - -int KINSetMaxNewtonStep(void *kinmem, realtype mxnewtstep) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetMaxNewtonStep", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (mxnewtstep < ZERO) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetMaxNewtonStep", MSG_BAD_MXNEWTSTEP); - return(KIN_ILL_INPUT); - } - - /* Note: passing a value of 0.0 will use the default - value (computed in KINSolInit) */ - - kin_mem->kin_mxnstepin = mxnewtstep; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetMaxBetaFails - * ----------------------------------------------------------------- - */ - -int KINSetMaxBetaFails(void *kinmem, long int mxnbcf) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetMaxBetaFails", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (mxnbcf < 0) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetMaxBetaFails", MSG_BAD_MXNBCF); - return(KIN_ILL_INPUT); - } - - if (mxnbcf == 0) - kin_mem->kin_mxnbcf = MXNBCF_DEFAULT; - else - kin_mem->kin_mxnbcf = mxnbcf; - - return(KIN_SUCCESS); - -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetRelErrFunc - * ----------------------------------------------------------------- - */ - -int KINSetRelErrFunc(void *kinmem, realtype relfunc) -{ - KINMem kin_mem; - realtype uround; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetRelErrFunc", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (relfunc < ZERO) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetRelErrFunc", MSG_BAD_RELFUNC); - return(KIN_ILL_INPUT); - } - - if (relfunc == ZERO) { - uround = kin_mem->kin_uround; - kin_mem->kin_sqrt_relfunc = SUNRsqrt(uround); - } else { - kin_mem->kin_sqrt_relfunc = SUNRsqrt(relfunc); - } - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetFuncNormTol - * ----------------------------------------------------------------- - */ - -int KINSetFuncNormTol(void *kinmem, realtype fnormtol) -{ - KINMem kin_mem; - realtype uround; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetFuncNormTol", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (fnormtol < ZERO) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetFuncNormTol", MSG_BAD_FNORMTOL); - return(KIN_ILL_INPUT); - } - - if (fnormtol == ZERO) { - uround = kin_mem->kin_uround; - kin_mem->kin_fnormtol = SUNRpowerR(uround,ONETHIRD); - } else { - kin_mem->kin_fnormtol = fnormtol; - } - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetScaledStepTol - * ----------------------------------------------------------------- - */ - -int KINSetScaledStepTol(void *kinmem, realtype scsteptol) -{ - KINMem kin_mem; - realtype uround; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetScaledStepTol", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (scsteptol < ZERO) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetScaledStepTol", MSG_BAD_SCSTEPTOL); - return(KIN_ILL_INPUT); - } - - if (scsteptol == ZERO) { - uround = kin_mem->kin_uround; - kin_mem->kin_scsteptol = SUNRpowerR(uround,TWOTHIRDS); - } else { - kin_mem->kin_scsteptol = scsteptol; - } - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetConstraints - * ----------------------------------------------------------------- - */ - -int KINSetConstraints(void *kinmem, N_Vector constraints) -{ - KINMem kin_mem; - realtype temptest; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetConstraints", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (constraints == NULL) { - if (kin_mem->kin_constraintsSet) { - N_VDestroy(kin_mem->kin_constraints); - kin_mem->kin_lrw -= kin_mem->kin_lrw1; - kin_mem->kin_liw -= kin_mem->kin_liw1; - } - kin_mem->kin_constraintsSet = SUNFALSE; - return(KIN_SUCCESS); - } - - /* Check the constraints vector */ - - temptest = N_VMaxNorm(constraints); - if (temptest > TWOPT5){ - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetConstraints", MSG_BAD_CONSTRAINTS); - return(KIN_ILL_INPUT); - } - - if (!kin_mem->kin_constraintsSet) { - kin_mem->kin_constraints = N_VClone(constraints); - kin_mem->kin_lrw += kin_mem->kin_lrw1; - kin_mem->kin_liw += kin_mem->kin_liw1; - kin_mem->kin_constraintsSet = SUNTRUE; - } - - /* Load the constraint vector */ - - N_VScale(ONE, constraints, kin_mem->kin_constraints); - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINSetSysFunc - * ----------------------------------------------------------------- - */ - -int KINSetSysFunc(void *kinmem, KINSysFn func) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINSetSysFunc", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - if (func == NULL) { - KINProcessError(NULL, KIN_ILL_INPUT, "KINSOL", "KINSetSysFunc", MSG_FUNC_NULL); - return(KIN_ILL_INPUT); - } - - kin_mem->kin_func = func; - - return(KIN_SUCCESS); -} - - -/* - * ================================================================= - * KINSOL optional output functions - * ================================================================= - */ - -/* - * ----------------------------------------------------------------- - * Function : KINGetWorkSpace - * ----------------------------------------------------------------- - */ - -int KINGetWorkSpace(void *kinmem, long int *lenrw, long int *leniw) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINGetWorkSpace", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - - *lenrw = kin_mem->kin_lrw; - *leniw = kin_mem->kin_liw; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINGetNumNonlinSolvIters - * ----------------------------------------------------------------- - */ - -int KINGetNumNonlinSolvIters(void *kinmem, long int *nniters) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINGetNumNonlinSolvIters", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - *nniters = kin_mem->kin_nni; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINGetNumFuncEvals - * ----------------------------------------------------------------- - */ - -int KINGetNumFuncEvals(void *kinmem, long int *nfevals) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINGetNumFuncEvals", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - *nfevals = kin_mem->kin_nfe; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINGetNumBetaCondFails - * ----------------------------------------------------------------- - */ - -int KINGetNumBetaCondFails(void *kinmem, long int *nbcfails) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINGetNumBetaCondFails", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - *nbcfails = kin_mem->kin_nbcf; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINGetNumBacktrackOps - * ----------------------------------------------------------------- - */ - -int KINGetNumBacktrackOps(void *kinmem, long int *nbacktr) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINGetNumBacktrackOps", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - *nbacktr = kin_mem->kin_nbktrk; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINGetFuncNorm - * ----------------------------------------------------------------- - */ - -int KINGetFuncNorm(void *kinmem, realtype *funcnorm) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINGetFuncNorm", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - *funcnorm = kin_mem->kin_fnorm; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINGetStepLength - * ----------------------------------------------------------------- - */ - -int KINGetStepLength(void *kinmem, realtype *steplength) -{ - KINMem kin_mem; - - if (kinmem == NULL) { - KINProcessError(NULL, KIN_MEM_NULL, "KINSOL", "KINGetStepLength", MSG_NO_MEM); - return(KIN_MEM_NULL); - } - - kin_mem = (KINMem) kinmem; - *steplength = kin_mem->kin_stepl; - - return(KIN_SUCCESS); -} - -/* - * ----------------------------------------------------------------- - * Function : KINGetReturnFlagName - * ----------------------------------------------------------------- - */ - -char *KINGetReturnFlagName(long int flag) -{ - char *name; - - name = (char *)malloc(24*sizeof(char)); - - switch(flag) { - case KIN_SUCCESS: - sprintf(name, "KIN_SUCCESS"); - break; - case KIN_INITIAL_GUESS_OK: - sprintf(name, "KIN_INITIAL_GUESS_OK"); - break; - case KIN_STEP_LT_STPTOL: - sprintf(name, "KIN_STEP_LT_STPTOL"); - break; - case KIN_WARNING: - sprintf(name, "KIN_WARNING"); - break; - case KIN_MEM_NULL: - sprintf(name, "KIN_MEM_NULL"); - break; - case KIN_ILL_INPUT: - sprintf(name, "KIN_ILL_INPUT"); - break; - case KIN_NO_MALLOC: - sprintf(name, "KIN_NO_MALLOC"); - break; - case KIN_MEM_FAIL: - sprintf(name, "KIN_MEM_FAIL"); - break; - case KIN_LINESEARCH_NONCONV: - sprintf(name, "KIN_LINESEARCH_NONCONV"); - break; - case KIN_MAXITER_REACHED: - sprintf(name, "KIN_MAXITER_REACHED"); - break; - case KIN_MXNEWT_5X_EXCEEDED: - sprintf(name, "KIN_MXNEWT_5X_EXCEEDED"); - break; - case KIN_LINESEARCH_BCFAIL: - sprintf(name, "KIN_LINESEARCH_BCFAIL"); - break; - case KIN_LINSOLV_NO_RECOVERY: - sprintf(name, "KIN_LINSOLV_NO_RECOVERY"); - break; - case KIN_LINIT_FAIL: - sprintf(name, "KIN_LINIT_FAIL"); - break; - case KIN_LSETUP_FAIL: - sprintf(name, "KIN_LSETUP_FAIL"); - break; - case KIN_LSOLVE_FAIL: - sprintf(name, "KIN_LSOLVE_FAIL"); - break; - default: - sprintf(name, "NONE"); - } - - return(name); -} diff --git a/ThirdParty/sundials/src/kinsol/kinsol_ls.c b/ThirdParty/sundials/src/kinsol/kinsol_ls.c deleted file mode 100644 index 28128614b1..0000000000 --- a/ThirdParty/sundials/src/kinsol/kinsol_ls.c +++ /dev/null @@ -1,1365 +0,0 @@ -/*----------------------------------------------------------------- - * Programmer(s): Daniel R. Reynolds @ SMU - * David J. Gardner, Radu Serban and Aaron Collier @ LLNL - *----------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - *----------------------------------------------------------------- - * Implementation file for KINSOL's linear solver interface. - *-----------------------------------------------------------------*/ - -#include -#include -#include -#include - -#include "kinsol_impl.h" -#include "kinsol_ls_impl.h" - -#include -#include -#include -#include - -/* constants */ -#define MIN_INC_MULT RCONST(1000.0) -#define ZERO RCONST(0.0) -#define ONE RCONST(1.0) -#define TWO RCONST(2.0) - - -/*================================================================== - KINLS Exported functions -- Required - ==================================================================*/ - -/*--------------------------------------------------------------- - KINSetLinearSolver specifies the linear solver - ---------------------------------------------------------------*/ -int KINSetLinearSolver(void *kinmem, SUNLinearSolver LS, SUNMatrix A) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval, LSType; - booleantype iterative; /* is the solver iterative? */ - booleantype matrixbased; /* is a matrix structure used? */ - - /* Return immediately if either kinmem or LS inputs are NULL */ - if (kinmem == NULL) { - KINProcessError(NULL, KINLS_MEM_NULL, "KINLS", - "KINSetLinearSolver", MSG_LS_KINMEM_NULL); - return(KINLS_MEM_NULL); - } - if (LS == NULL) { - KINProcessError(NULL, KINLS_ILL_INPUT, "KINLS", - "KINSetLinearSolver", - "LS must be non-NULL"); - return(KINLS_ILL_INPUT); - } - kin_mem = (KINMem) kinmem; - - /* Test if solver is compatible with LS interface */ - if ( (LS->ops->gettype == NULL) || (LS->ops->solve == NULL) ) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", - "KINSetLinearSolver", - "LS object is missing a required operation"); - return(KINLS_ILL_INPUT); - } - - /* Retrieve the LS type */ - LSType = SUNLinSolGetType(LS); - - /* Set flags based on LS type */ - iterative = (LSType != SUNLINEARSOLVER_DIRECT); - matrixbased = (LSType != SUNLINEARSOLVER_ITERATIVE); - - /* check for required vector operations for KINLS interface */ - if ( (kin_mem->kin_vtemp1->ops->nvconst == NULL) || - (kin_mem->kin_vtemp1->ops->nvdotprod == NULL) ) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", - "KINSetLinearSolver", MSG_LS_BAD_NVECTOR); - return(KINLS_ILL_INPUT); - } - - /* Check for compatible LS type, matrix and "atimes" support */ - if (iterative) { - - if ((LS->ops->setscalingvectors == NULL) && - (kin_mem->kin_vtemp1->ops->nvgetlength == NULL)) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", - "KINSetLinearSolver", MSG_LS_BAD_NVECTOR); - return(KINLS_ILL_INPUT); - } - - if (!matrixbased && (LS->ops->setatimes == NULL)) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", "KINSetLinearSolver", - "Incompatible inputs: iterative LS must support ATimes routine"); - return(KINLS_ILL_INPUT); - } - - if (matrixbased && A == NULL) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", "KINSetLinearSolver", - "Incompatible inputs: matrix-iterative LS requires non-NULL matrix"); - return(KINLS_ILL_INPUT); - } - - } else if (A == NULL) { - - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", "KINSetLinearSolver", - "Incompatible inputs: direct LS requires non-NULL matrix"); - return(KINLS_ILL_INPUT); - } - - /* free any existing system solver attached to KIN */ - if (kin_mem->kin_lfree) kin_mem->kin_lfree(kin_mem); - - /* Determine if this is an iterative linear solver */ - kin_mem->kin_inexact_ls = iterative; - - /* Set four main system linear solver function fields in kin_mem */ - kin_mem->kin_linit = kinLsInitialize; - kin_mem->kin_lsetup = kinLsSetup; - kin_mem->kin_lsolve = kinLsSolve; - kin_mem->kin_lfree = kinLsFree; - - /* Get memory for KINLsMemRec */ - kinls_mem = NULL; - kinls_mem = (KINLsMem) malloc(sizeof(struct KINLsMemRec)); - if (kinls_mem == NULL) { - KINProcessError(kin_mem, KINLS_MEM_FAIL, "KINLS", - "KINSetLinearSolver", MSG_LS_MEM_FAIL); - return(KINLS_MEM_FAIL); - } - memset(kinls_mem, 0, sizeof(struct KINLsMemRec)); - - /* set SUNLinearSolver pointer */ - kinls_mem->LS = LS; - - /* Set defaults for Jacobian-related fields */ - if (A != NULL) { - kinls_mem->jacDQ = SUNTRUE; - kinls_mem->jac = kinLsDQJac; - kinls_mem->J_data = kin_mem; - } else { - kinls_mem->jacDQ = SUNFALSE; - kinls_mem->jac = NULL; - kinls_mem->J_data = NULL; - } - kinls_mem->jtimesDQ = SUNTRUE; - kinls_mem->jtimes = kinLsDQJtimes; - kinls_mem->jt_func = kin_mem->kin_func; - kinls_mem->jt_data = kin_mem; - - /* Set defaults for preconditioner-related fields */ - kinls_mem->pset = NULL; - kinls_mem->psolve = NULL; - kinls_mem->pfree = NULL; - kinls_mem->pdata = kin_mem->kin_user_data; - - /* Initialize counters */ - kinLsInitializeCounters(kinls_mem); - - /* Set default values for the rest of the LS parameters */ - kinls_mem->last_flag = KINLS_SUCCESS; - - /* If LS supports ATimes, attach KINLs routine */ - if (LS->ops->setatimes) { - retval = SUNLinSolSetATimes(LS, kin_mem, kinLsATimes); - if (retval != SUNLS_SUCCESS) { - KINProcessError(kin_mem, KINLS_SUNLS_FAIL, "KINLS", - "KINSetLinearSolver", - "Error in calling SUNLinSolSetATimes"); - free(kinls_mem); kinls_mem = NULL; - return(KINLS_SUNLS_FAIL); - } - } - - /* If LS supports preconditioning, initialize pset/psol to NULL */ - if (LS->ops->setpreconditioner) { - retval = SUNLinSolSetPreconditioner(LS, kin_mem, NULL, NULL); - if (retval != SUNLS_SUCCESS) { - KINProcessError(kin_mem, KINLS_SUNLS_FAIL, "KINLS", - "KINSetLinearSolver", - "Error in calling SUNLinSolSetPreconditioner"); - free(kinls_mem); kinls_mem = NULL; - return(KINLS_SUNLS_FAIL); - } - } - - /* initialize tolerance scaling factor */ - kinls_mem->tol_fac = -ONE; - - /* set SUNMatrix pointer (can be NULL) */ - kinls_mem->J = A; - - /* Attach linear solver memory to integrator memory */ - kin_mem->kin_lmem = kinls_mem; - - return(KINLS_SUCCESS); -} - - -/*================================================================== - Optional input/output routines - ==================================================================*/ - -/*------------------------------------------------------------------ - KINSetJacFn specifies the Jacobian function - ------------------------------------------------------------------*/ -int KINSetJacFn(void *kinmem, KINLsJacFn jac) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure */ - retval = kinLs_AccessLMem(kinmem, "KINSetJacFn", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - - /* return with failure if jac cannot be used */ - if ((jac != NULL) && (kinls_mem->J == NULL)) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", "KINSetJacFn", - "Jacobian routine cannot be supplied for NULL SUNMatrix"); - return(KINLS_ILL_INPUT); - } - - if (jac != NULL) { - kinls_mem->jacDQ = SUNFALSE; - kinls_mem->jac = jac; - kinls_mem->J_data = kin_mem->kin_user_data; - } else { - kinls_mem->jacDQ = SUNTRUE; - kinls_mem->jac = kinLsDQJac; - kinls_mem->J_data = kin_mem; - } - - return(KINLS_SUCCESS); -} - - -/*------------------------------------------------------------------ - KINSetPreconditioner sets the preconditioner setup and solve - functions - ------------------------------------------------------------------*/ -int KINSetPreconditioner(void *kinmem, - KINLsPrecSetupFn psetup, - KINLsPrecSolveFn psolve) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - PSetupFn kinls_psetup; - PSolveFn kinls_psolve; - int retval; - - /* access KINLsMem structure */ - retval = kinLs_AccessLMem(kinmem, "KINSetPreconditioner", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - - /* store function pointers for user-supplied routines in KINLS interface */ - kinls_mem->pset = psetup; - kinls_mem->psolve = psolve; - - /* issue error if LS object does not support user-supplied preconditioning */ - if (kinls_mem->LS->ops->setpreconditioner == NULL) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", "KINSetPreconditioner", - "SUNLinearSolver object does not support user-supplied preconditioning"); - return(KINLS_ILL_INPUT); - } - - /* notify iterative linear solver to call KINLs interface routines */ - kinls_psetup = (psetup == NULL) ? NULL : kinLsPSetup; - kinls_psolve = (psolve == NULL) ? NULL : kinLsPSolve; - retval = SUNLinSolSetPreconditioner(kinls_mem->LS, kin_mem, - kinls_psetup, kinls_psolve); - if (retval != SUNLS_SUCCESS) { - KINProcessError(kin_mem, KINLS_SUNLS_FAIL, "KINLS", "KINSetPreconditioner", - "Error in calling SUNLinSolSetPreconditioner"); - return(KINLS_SUNLS_FAIL); - } - - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINSetJacTimesVecFn sets the matrix-vector product function - ------------------------------------------------------------------*/ -int KINSetJacTimesVecFn(void *kinmem, KINLsJacTimesVecFn jtv) -{ - int retval; - KINMem kin_mem; - KINLsMem kinls_mem; - - /* access KINLsMem structure */ - retval = kinLs_AccessLMem(kinmem, "KINSetJacTimesVecFn", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - - /* issue error if LS object does not support user-supplied ATimes */ - if (kinls_mem->LS->ops->setatimes == NULL) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", "KINSetJacTimesVecFn", - "SUNLinearSolver object does not support user-supplied ATimes routine"); - return(KINLS_ILL_INPUT); - } - - /* store function pointers for user-supplied routine in KINLs - interface (NULL jtimes implies use of DQ default) */ - if (jtv != NULL) { - kinls_mem->jtimesDQ = SUNFALSE; - kinls_mem->jtimes = jtv; - kinls_mem->jt_data = kin_mem->kin_user_data; - } else { - kinls_mem->jtimesDQ = SUNTRUE; - kinls_mem->jtimes = kinLsDQJtimes; - kinls_mem->jt_func = kin_mem->kin_func; - kinls_mem->jt_data = kin_mem; - } - - return(KINLS_SUCCESS); -} - - -/* KINSetJacTimesVecSysFn specifies an alternative user-supplied system function - to use in the internal finite difference Jacobian-vector product */ -int KINSetJacTimesVecSysFn(void *kinmem, KINSysFn jtimesSysFn) -{ - int retval; - KINMem kin_mem = NULL; - KINLsMem kinls_mem = NULL; - - /* access KINLsMem structure */ - retval = kinLs_AccessLMem(kin_mem, "KINSetJacTimesVecSysFn", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - - /* check if using internal finite difference approximation */ - if (!(kinls_mem->jtimesDQ)) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", "KINSetJacTimesVecSysFn", - "Internal finite-difference Jacobian-vector product is disabled."); - return(KINLS_ILL_INPUT); - } - - /* store function pointers for system function (NULL implies use kin_func) */ - if (jtimesSysFn != NULL) - kinls_mem->jt_func = jtimesSysFn; - else - kinls_mem->jt_func = kin_mem->kin_func; - - return(KINLS_SUCCESS); -} - - -/*------------------------------------------------------------------ - KINGetLinWorkSpace returns the integer and real workspace size - ------------------------------------------------------------------*/ -int KINGetLinWorkSpace(void *kinmem, long int *lenrwLS, long int *leniwLS) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - sunindextype lrw1, liw1; - long int lrw, liw; - int retval; - - /* access KINLsMem structure */ - retval = kinLs_AccessLMem(kinmem, "KINGetLinWorkSpace", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - - /* start with fixed sizes plus vector/matrix pointers */ - *lenrwLS = 1; - *leniwLS = 21; - - /* add N_Vector sizes */ - if (kin_mem->kin_vtemp1->ops->nvspace) { - N_VSpace(kin_mem->kin_vtemp1, &lrw1, &liw1); - *lenrwLS += lrw1; - *leniwLS += liw1; - } - - /* add LS sizes */ - if (kinls_mem->LS->ops->space) { - retval = SUNLinSolSpace(kinls_mem->LS, &lrw, &liw); - if (retval == 0) { - *lenrwLS += lrw; - *leniwLS += liw; - } - } - - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINGetNumJacEvals returns the number of Jacobian evaluations - ------------------------------------------------------------------*/ -int KINGetNumJacEvals(void *kinmem, long int *njevals) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure; set output value and return */ - retval = kinLs_AccessLMem(kinmem, "KINGetNumJacEvals", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - *njevals = kinls_mem->nje; - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINGetNumPrecEvals returns the total number of preconditioner - evaluations - ------------------------------------------------------------------*/ -int KINGetNumPrecEvals(void *kinmem, long int *npevals) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure; set output value and return */ - retval = kinLs_AccessLMem(kinmem, "KINGetNumPrecEvals", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - *npevals = kinls_mem->npe; - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINGetNumPrecSolves returns the total number of times the - preconditioner was applied - ------------------------------------------------------------------*/ -int KINGetNumPrecSolves(void *kinmem, long int *npsolves) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure; set output value and return */ - retval = kinLs_AccessLMem(kinmem, "KINGetNumPrecSolves", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - *npsolves = kinls_mem->nps; - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINGetNumLinIters returns the total number of linear - iterations - ------------------------------------------------------------------*/ -int KINGetNumLinIters(void *kinmem, long int *nliters) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure; set output value and return */ - retval = kinLs_AccessLMem(kinmem, "KINGetNumLinIters", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - *nliters = kinls_mem->nli; - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINGetNumLinConvFails returns the total numbe of convergence - failures - ------------------------------------------------------------------*/ -int KINGetNumLinConvFails(void *kinmem, long int *nlcfails) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure; set output value and return */ - retval = kinLs_AccessLMem(kinmem, "KINGetNumLinConvFails", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - *nlcfails = kinls_mem->ncfl; - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINGetNumJtimesEvals returns the number of times the matrix - vector product was computed - ------------------------------------------------------------------*/ -int KINGetNumJtimesEvals(void *kinmem, long int *njvevals) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure; set output value and return */ - retval = kinLs_AccessLMem(kinmem, "KINGetNumJtimesEvals", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - *njvevals = kinls_mem->njtimes; - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINGetNumLinFuncEvals returns the number of calls to the user's - F routine by the linear solver module - ------------------------------------------------------------------*/ -int KINGetNumLinFuncEvals(void *kinmem, long int *nfevals) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure; set output value and return */ - retval = kinLs_AccessLMem(kinmem, "KINGetNumLinFuncEvals", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - *nfevals = kinls_mem->nfeDQ; - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINGetLastLinFlag returns the last flag set in the KINLS - function - ------------------------------------------------------------------*/ -int KINGetLastLinFlag(void *kinmem, long int *flag) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure; set output value and return */ - retval = kinLs_AccessLMem(kinmem, "KINGetLastLinFlag", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - *flag = kinls_mem->last_flag; - return(KINLS_SUCCESS); -} - -/*------------------------------------------------------------------ - KINGetLinReturnFlagName - ------------------------------------------------------------------*/ -char *KINGetLinReturnFlagName(long int flag) -{ - char *name; - - name = (char *)malloc(30*sizeof(char)); - - switch(flag) { - case KINLS_SUCCESS: - sprintf(name, "KINLS_SUCCESS"); - break; - case KINLS_MEM_NULL: - sprintf(name, "KINLS_MEM_NULL"); - break; - case KINLS_LMEM_NULL: - sprintf(name, "KINLS_LMEM_NULL"); - break; - case KINLS_ILL_INPUT: - sprintf(name, "KINLS_ILL_INPUT"); - break; - case KINLS_MEM_FAIL: - sprintf(name, "KINLS_MEM_FAIL"); - break; - case KINLS_PMEM_NULL: - sprintf(name, "KINLS_PMEM_NULL"); - break; - case KINLS_JACFUNC_ERR: - sprintf(name,"KINLS_JACFUNC_ERR"); - break; - case KINLS_SUNMAT_FAIL: - sprintf(name,"KINLS_SUNMAT_FAIL"); - break; - case KINLS_SUNLS_FAIL: - sprintf(name,"KINLS_SUNLS_FAIL"); - break; - default: - sprintf(name, "NONE"); - } - - return(name); -} - - -/*================================================================== - KINLS Private functions - ==================================================================*/ - -/*------------------------------------------------------------------ - kinLsATimes - - This routine coordinates the generation of the matrix-vector - product z = J*v by calling either kinLsDQJtimes, which uses - a difference quotient approximation for J*v, or by calling the - user-supplied routine KINLsJacTimesVecFn if it is non-null. - ------------------------------------------------------------------*/ -int kinLsATimes(void *kinmem, N_Vector v, N_Vector z) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure */ - retval = kinLs_AccessLMem(kinmem, "kinLsATimes", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - - /* call Jacobian-times-vector product routine - (either user-supplied or internal DQ) */ - retval = kinls_mem->jtimes(v, z, kin_mem->kin_uu, - &(kinls_mem->new_uu), - kinls_mem->jt_data); - kinls_mem->njtimes++; - return(retval); -} - - -/*--------------------------------------------------------------- - kinLsPSetup: - - This routine interfaces between the generic iterative linear - solvers and the user's psetup routine. It passes to psetup all - required state information from kin_mem. Its return value - is the same as that returned by psetup. Note that the generic - iterative linear solvers guarantee that kinLsPSetup will only - be called in the case that the user's psetup routine is non-NULL. - ---------------------------------------------------------------*/ -int kinLsPSetup(void *kinmem) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure */ - retval = kinLs_AccessLMem(kinmem, "kinLsPSetup", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - - /* Call user pset routine to update preconditioner */ - retval = kinls_mem->pset(kin_mem->kin_uu, kin_mem->kin_uscale, - kin_mem->kin_fval, kin_mem->kin_fscale, - kinls_mem->pdata); - kinls_mem->npe++; - return(retval); -} - - -/*------------------------------------------------------------------ - kinLsPSolve - - This routine interfaces between the generic iterative linear - solvers and the user's psolve routine. It passes to psolve all - required state information from kinsol_mem. Its return value is - the same as that returned by psolve. Note that the generic - SUNLinSol solver guarantees that kinLsPSolve will not be called - in the case in which preconditioning is not done. This is the only - case in which the user's psolve routine is allowed to be NULL. - ------------------------------------------------------------------*/ -int kinLsPSolve(void *kinmem, N_Vector r, N_Vector z, realtype tol, int lr) -{ - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure */ - retval = kinLs_AccessLMem(kinmem, "kinLsPSolve", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - - /* copy the rhs into z before the psolve call */ - /* Note: z returns with the solution */ - N_VScale(ONE, r, z); - - /* note: user-supplied preconditioning with KINSOL does not - support either the 'tol' or 'lr' inputs */ - retval = kinls_mem->psolve(kin_mem->kin_uu, kin_mem->kin_uscale, - kin_mem->kin_fval, kin_mem->kin_fscale, - z, kinls_mem->pdata); - kinls_mem->nps++; - return(retval); -} - - -/*------------------------------------------------------------------ - kinLsDQJac - - This routine is a wrapper for the Dense and Band implementations - of the difference quotient Jacobian approximation routines. - ------------------------------------------------------------------*/ -int kinLsDQJac(N_Vector u, N_Vector fu, SUNMatrix Jac, - void *kinmem, N_Vector tmp1, N_Vector tmp2) -{ - KINMem kin_mem; - int retval; - - /* access KINMem structure */ - if (kinmem == NULL) { - KINProcessError(NULL, KINLS_MEM_NULL, "KINLS", - "kinLsDQJac", MSG_LS_KINMEM_NULL); - return(KINLS_MEM_NULL); - } - kin_mem = (KINMem) kinmem; - - /* verify that Jac is non-NULL */ - if (Jac == NULL) { - KINProcessError(kin_mem, KINLS_LMEM_NULL, "KINLS", - "kinLsDQJac", MSG_LS_LMEM_NULL); - return(KINLS_LMEM_NULL); - } - - /* Call the matrix-structure-specific DQ approximation routine */ - if (SUNMatGetID(Jac) == SUNMATRIX_DENSE) { - retval = kinLsDenseDQJac(u, fu, Jac, kin_mem, tmp1, tmp2); - } else if (SUNMatGetID(Jac) == SUNMATRIX_BAND) { - retval = kinLsBandDQJac(u, fu, Jac, kin_mem, tmp1, tmp2); - } else { - KINProcessError(kin_mem, KIN_ILL_INPUT, "KINLS", "kinLsDQJac", - "unrecognized matrix type for kinLsDQJac"); - retval = KIN_ILL_INPUT; - } - return(retval); -} - - -/*------------------------------------------------------------------ - kinLsDenseDQJac - - This routine generates a dense difference quotient approximation - to the Jacobian of F(u). It assumes a dense SUNMatrix input - stored column-wise, and that elements within each column are - contiguous. The address of the jth column of J is obtained via - the function SUNDenseMatrix_Column() and this pointer is - associated with an N_Vector using the N_VGetArrayPointer and - N_VSetArrayPointer functions. Finally, the actual computation of - the jth column of the Jacobian is done with a call to N_VLinearSum. - - The increment used in the finite-difference approximation - J_ij = ( F_i(u+sigma_j * e_j) - F_i(u) ) / sigma_j - is - sigma_j = max{|u_j|, |1/uscale_j|} * sqrt(uround) - - Note: uscale_j = 1/typ(u_j) - - NOTE: Any type of failure of the system function here leads to an - unrecoverable failure of the Jacobian function and thus of - the linear solver setup function, stopping KINSOL. - ------------------------------------------------------------------*/ -int kinLsDenseDQJac(N_Vector u, N_Vector fu, SUNMatrix Jac, - KINMem kin_mem, N_Vector tmp1, N_Vector tmp2) -{ - realtype inc, inc_inv, ujsaved, ujscale, sign; - realtype *tmp2_data, *u_data, *uscale_data; - N_Vector ftemp, jthCol; - sunindextype j, N; - KINLsMem kinls_mem; - int retval = 0; - - /* access LsMem interface structure */ - kinls_mem = (KINLsMem) kin_mem->kin_lmem; - - /* access matrix dimension */ - N = SUNDenseMatrix_Columns(Jac); - - /* Save pointer to the array in tmp2 */ - tmp2_data = N_VGetArrayPointer(tmp2); - - /* Rename work vectors for readibility */ - ftemp = tmp1; - jthCol = tmp2; - - /* Obtain pointers to the data for u and uscale */ - u_data = N_VGetArrayPointer(u); - uscale_data = N_VGetArrayPointer(kin_mem->kin_uscale); - - /* This is the only for loop for 0..N-1 in KINSOL */ - - for (j = 0; j < N; j++) { - - /* Generate the jth col of J(u) */ - - /* Set data address of jthCol, and save u_j values and scaling */ - N_VSetArrayPointer(SUNDenseMatrix_Column(Jac,j), jthCol); - ujsaved = u_data[j]; - ujscale = ONE/uscale_data[j]; - - /* Compute increment */ - sign = (ujsaved >= ZERO) ? ONE : -ONE; - inc = kin_mem->kin_sqrt_relfunc*SUNMAX(SUNRabs(ujsaved), ujscale)*sign; - - /* Increment u_j, call F(u), and return if error occurs */ - u_data[j] += inc; - - retval = kin_mem->kin_func(u, ftemp, kin_mem->kin_user_data); - kinls_mem->nfeDQ++; - if (retval != 0) break; - - /* reset u_j */ - u_data[j] = ujsaved; - - /* Construct difference quotient in jthCol */ - inc_inv = ONE/inc; - N_VLinearSum(inc_inv, ftemp, -inc_inv, fu, jthCol); - } - - /* Restore original array pointer in tmp2 */ - N_VSetArrayPointer(tmp2_data, tmp2); - - return(retval); -} - - -/*------------------------------------------------------------------ - kinLsBandDQJac - - This routine generates a banded difference quotient approximation - to the Jacobian of F(u). It assumes a SUNBandMatrix input stored - column-wise, and that elements within each column are contiguous. - This makes it possible to get the address of a column of J via the - function SUNBandMatrix_Column() and to write a simple for loop to - set each of the elements of a column in succession. - - NOTE: Any type of failure of the system function her leads to an - unrecoverable failure of the Jacobian function and thus of - the linear solver setup function, stopping KINSOL. - ------------------------------------------------------------------*/ -int kinLsBandDQJac(N_Vector u, N_Vector fu, SUNMatrix Jac, - KINMem kin_mem, N_Vector tmp1, N_Vector tmp2) -{ - realtype inc, inc_inv; - N_Vector futemp, utemp; - sunindextype group, i, j, width, ngroups, i1, i2; - sunindextype N, mupper, mlower; - realtype *col_j, *fu_data, *futemp_data, *u_data, *utemp_data, *uscale_data; - KINLsMem kinls_mem; - int retval = 0; - - /* access LsMem interface structure */ - kinls_mem = (KINLsMem) kin_mem->kin_lmem; - - /* access matrix dimensions */ - N = SUNBandMatrix_Columns(Jac); - mupper = SUNBandMatrix_UpperBandwidth(Jac); - mlower = SUNBandMatrix_LowerBandwidth(Jac); - - /* Rename work vectors for use as temporary values of u and fu */ - futemp = tmp1; - utemp = tmp2; - - /* Obtain pointers to the data for ewt, fy, futemp, y, ytemp */ - fu_data = N_VGetArrayPointer(fu); - futemp_data = N_VGetArrayPointer(futemp); - u_data = N_VGetArrayPointer(u); - uscale_data = N_VGetArrayPointer(kin_mem->kin_uscale); - utemp_data = N_VGetArrayPointer(utemp); - - /* Load utemp with u */ - N_VScale(ONE, u, utemp); - - /* Set bandwidth and number of column groups for band differencing */ - width = mlower + mupper + 1; - ngroups = SUNMIN(width, N); - - for (group=1; group <= ngroups; group++) { - - /* Increment all utemp components in group */ - for(j=group-1; j < N; j+=width) { - inc = kin_mem->kin_sqrt_relfunc*SUNMAX(SUNRabs(u_data[j]), - ONE/SUNRabs(uscale_data[j])); - utemp_data[j] += inc; - } - - /* Evaluate f with incremented u */ - retval = kin_mem->kin_func(utemp, futemp, kin_mem->kin_user_data); - if (retval != 0) return(retval); - - /* Restore utemp components, then form and load difference quotients */ - for (j=group-1; j < N; j+=width) { - utemp_data[j] = u_data[j]; - col_j = SUNBandMatrix_Column(Jac, j); - inc = kin_mem->kin_sqrt_relfunc*SUNMAX(SUNRabs(u_data[j]), - ONE/SUNRabs(uscale_data[j])); - inc_inv = ONE/inc; - i1 = SUNMAX(0, j-mupper); - i2 = SUNMIN(j+mlower, N-1); - for (i=i1; i <= i2; i++) - SM_COLUMN_ELEMENT_B(col_j,i,j) = inc_inv * (futemp_data[i] - fu_data[i]); - } - } - - /* Increment counter nfeDQ */ - kinls_mem->nfeDQ += ngroups; - - return(0); -} - - -/*------------------------------------------------------------------ - kinLsDQJtimes - - This routine generates the matrix-vector product z = J*v using a - difference quotient approximation. The approximation is - J*v = [func(uu + sigma*v) - func(uu)]/sigma. Here sigma is based - on the dot products (uscale*uu, uscale*v) and - (uscale*v, uscale*v), the L1Norm(uscale*v), and on sqrt_relfunc - (the square root of the relative error in the function). Note - that v in the argument list has already been both preconditioned - and unscaled. - - NOTE: Unlike the DQ Jacobian functions for direct linear solvers - (which are called from within the lsetup function), this - function is called from within the lsolve function and thus - a recovery may still be possible even if the system function - fails (recoverably). - ------------------------------------------------------------------*/ -int kinLsDQJtimes(N_Vector v, N_Vector Jv, N_Vector u, - booleantype *new_u, void *kinmem) -{ - realtype sigma, sigma_inv, sutsv, sq1norm, sign, vtv; - KINMem kin_mem; - KINLsMem kinls_mem; - int retval; - - /* access KINLsMem structure */ - retval = kinLs_AccessLMem(kinmem, "kinLsDQJtimes", - &kin_mem, &kinls_mem); - if (retval != KIN_SUCCESS) return(retval); - - /* ensure that NVector supplies requisite routines */ - if ( (v->ops->nvprod == NULL) || (v->ops->nvdotprod == NULL) || - (v->ops->nvl1norm == NULL) || (v->ops->nvlinearsum == NULL) ){ - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", - "kinLsDQJtimes", MSG_LS_BAD_NVECTOR); - return(KINLS_ILL_INPUT); - } - - /* scale the vector v and put Du*v into vtemp1 */ - N_VProd(v, kin_mem->kin_uscale, kin_mem->kin_vtemp1); - - /* scale u and put into Jv (used as a temporary storage) */ - N_VProd(u, kin_mem->kin_uscale, Jv); - - /* compute dot product (Du*u).(Du*v) */ - sutsv = N_VDotProd(Jv, kin_mem->kin_vtemp1); - - /* compute dot product (Du*v).(Du*v) */ - vtv = N_VDotProd(kin_mem->kin_vtemp1, kin_mem->kin_vtemp1); - - /* compute differencing factor -- this is from p. 469, Brown and Saad paper */ - sq1norm = N_VL1Norm(kin_mem->kin_vtemp1); - sign = (sutsv >= ZERO) ? ONE : -ONE ; - sigma = sign*(kin_mem->kin_sqrt_relfunc)*SUNMAX(SUNRabs(sutsv),sq1norm)/vtv; - sigma_inv = ONE/sigma; - - /* compute the u-prime at which to evaluate the function func */ - N_VLinearSum(ONE, u, sigma, v, kin_mem->kin_vtemp1); - - /* call the system function to calculate func(u+sigma*v) */ - retval = kinls_mem->jt_func(kin_mem->kin_vtemp1, kin_mem->kin_vtemp2, - kin_mem->kin_user_data); - kinls_mem->nfeDQ++; - if (retval != 0) return(retval); - - /* finish the computation of the difference quotient */ - N_VLinearSum(sigma_inv, kin_mem->kin_vtemp2, -sigma_inv, kin_mem->kin_fval, Jv); - - return(0); -} - - -/*------------------------------------------------------------------ - kinLsInitialize performs remaining initializations specific - to the iterative linear solver interface (and solver itself) - ------------------------------------------------------------------*/ -int kinLsInitialize(KINMem kin_mem) -{ - KINLsMem kinls_mem; - int retval; - - /* Access KINLsMem structure */ - if (kin_mem->kin_lmem == NULL) { - KINProcessError(kin_mem, KINLS_LMEM_NULL, "KINLS", - "kinLsInitialize", MSG_LS_LMEM_NULL); - return(KINLS_LMEM_NULL); - } - kinls_mem = (KINLsMem) kin_mem->kin_lmem; - - /* Test for valid combinations of matrix & Jacobian routines: */ - if (kinls_mem->J == NULL) { - - /* If SUNMatrix A is NULL: ensure 'jac' function pointer is NULL */ - kinls_mem->jacDQ = SUNFALSE; - kinls_mem->jac = NULL; - kinls_mem->J_data = NULL; - - } else if (kinls_mem->jacDQ) { - - /* If J is non-NULL, and 'jac' is not user-supplied: - - if A is dense or band, ensure that our DQ approx. is used - - otherwise => error */ - retval = 0; - if (kinls_mem->J->ops->getid) { - - if ( (SUNMatGetID(kinls_mem->J) == SUNMATRIX_DENSE) || - (SUNMatGetID(kinls_mem->J) == SUNMATRIX_BAND) ) { - kinls_mem->jac = kinLsDQJac; - kinls_mem->J_data = kin_mem; - } else { - retval++; - } - - } else { - retval++; - } - if (retval) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", "kinLsInitialize", - "No Jacobian constructor available for SUNMatrix type"); - kinls_mem->last_flag = KINLS_ILL_INPUT; - return(KINLS_ILL_INPUT); - } - - /* check for required vector operations for kinLsDQJac routine */ - if ( (kin_mem->kin_vtemp1->ops->nvlinearsum == NULL) || - (kin_mem->kin_vtemp1->ops->nvscale == NULL) || - (kin_mem->kin_vtemp1->ops->nvgetarraypointer == NULL) || - (kin_mem->kin_vtemp1->ops->nvsetarraypointer == NULL) ) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", - "kinLsInitialize", MSG_LS_BAD_NVECTOR); - return(KINLS_ILL_INPUT); - } - - } else { - - /* If J is non-NULL, and 'jac' is user-supplied, - reset J_data pointer (just in case) */ - kinls_mem->J_data = kin_mem->kin_user_data; - } - - /* Prohibit Picard iteration with DQ Jacobian approximation or difference-quotient J*v */ - if ( (kin_mem->kin_globalstrategy == KIN_PICARD) && - kinls_mem->jacDQ && kinls_mem->jtimesDQ ) { - KINProcessError(kin_mem, KINLS_ILL_INPUT, "KINLS", - "kinLsInitialize", MSG_NOL_FAIL); - return(KINLS_ILL_INPUT); - } - - - /** error-checking is complete, begin initializtions **/ - - /* Initialize counters */ - kinLsInitializeCounters(kinls_mem); - - /* Set Jacobian-related fields, based on jtimesDQ */ - if (kinls_mem->jtimesDQ) { - kinls_mem->jtimes = kinLsDQJtimes; - kinls_mem->jt_data = kin_mem; - } else { - kinls_mem->jt_data = kin_mem->kin_user_data; - } - - /* if J is NULL and: NOT preconditioning or do NOT need to setup the - preconditioner, then set the lsetup function to NULL */ - if (kinls_mem->J == NULL) - if ((kinls_mem->psolve == NULL) || (kinls_mem->pset == NULL)) - kin_mem->kin_lsetup = NULL; - - /* Set scaling vectors assuming RIGHT preconditioning */ - /* NOTE: retval is non-zero only if LS == NULL */ - if (kinls_mem->LS->ops->setscalingvectors) { - retval = SUNLinSolSetScalingVectors(kinls_mem->LS, - kin_mem->kin_fscale, - kin_mem->kin_fscale); - if (retval != SUNLS_SUCCESS) { - KINProcessError(kin_mem, KINLS_SUNLS_FAIL, "KINLS", "kinLsInitialize", - "Error in calling SUNLinSolSetScalingVectors"); - return(KINLS_SUNLS_FAIL); - } - } - - /* If the linear solver is iterative or matrix-iterative, and if left/right - scaling are not supported, we must update linear solver tolerances in an - attempt to account for the fscale vector. We make the following assumptions: - 1. fscale_i = fs_mean, for i=0,...,n-1 (i.e. the weights are homogeneous) - 2. the linear solver uses a basic 2-norm to measure convergence - Hence (using the notation from sunlinsol_spgmr.h, with S = diag(fscale)), - || bbar - Abar xbar ||_2 < tol - <=> || S b - S A x ||_2 < tol - <=> || S (b - A x) ||_2 < tol - <=> \sum_{i=0}^{n-1} (fscale_i (b - A x)_i)^2 < tol^2 - <=> fs_mean^2 \sum_{i=0}^{n-1} (b - A x_i)^2 < tol^2 - <=> \sum_{i=0}^{n-1} (b - A x_i)^2 < tol^2 / fs_mean^2 - <=> || b - A x ||_2 < tol / fs_mean - <=> || b - A x ||_2 < tol * tol_fac - So we compute tol_fac = sqrt(N) / ||fscale||_L2 for scaling desired tolerances */ - if (kinls_mem->iterative && kinls_mem->LS->ops->setscalingvectors == NULL) { - N_VConst(ONE, kin_mem->kin_vtemp1); - kinls_mem->tol_fac = SUNRsqrt(N_VGetLength(kin_mem->kin_vtemp1)) - / N_VWL2Norm(kin_mem->kin_fscale, kin_mem->kin_vtemp1); - } else { - kinls_mem->tol_fac = ONE; - } - - /* Call LS initialize routine, and return result */ - kinls_mem->last_flag = SUNLinSolInitialize(kinls_mem->LS); - return(kinls_mem->last_flag); -} - - -/*------------------------------------------------------------------ - kinLsSetup call the LS setup routine - ------------------------------------------------------------------*/ -int kinLsSetup(KINMem kin_mem) -{ - KINLsMem kinls_mem; - int retval; - - /* Access KINLsMem structure */ - if (kin_mem->kin_lmem == NULL) { - KINProcessError(kin_mem, KINLS_LMEM_NULL, "KINLS", - "kinLsSetup", MSG_LS_LMEM_NULL); - return(KINLS_LMEM_NULL); - } - kinls_mem = (KINLsMem) kin_mem->kin_lmem; - - /* recompute if J if it is non-NULL */ - if (kinls_mem->J) { - - /* Increment nje counter. */ - kinls_mem->nje++; - - /* Clear the linear system matrix if necessary */ - if (SUNLinSolGetType(kinls_mem->LS) == SUNLINEARSOLVER_DIRECT) { - retval = SUNMatZero(kinls_mem->J); - if (retval != 0) { - KINProcessError(kin_mem, KINLS_SUNMAT_FAIL, "KINLS", - "kinLsSetup", MSG_LS_MATZERO_FAILED); - kinls_mem->last_flag = KINLS_SUNMAT_FAIL; - return(kinls_mem->last_flag); - } - } - - /* Call Jacobian routine */ - retval = kinls_mem->jac(kin_mem->kin_uu, kin_mem->kin_fval, - kinls_mem->J, kinls_mem->J_data, - kin_mem->kin_vtemp1, kin_mem->kin_vtemp2); - if (retval != 0) { - KINProcessError(kin_mem, KINLS_JACFUNC_ERR, "KINLS", - "kinLsSetup", MSG_LS_JACFUNC_FAILED); - kinls_mem->last_flag = KINLS_JACFUNC_ERR; - return(kinls_mem->last_flag); - } - - } - - /* Call LS setup routine -- the LS will call kinLsPSetup (if applicable) */ - kinls_mem->last_flag = SUNLinSolSetup(kinls_mem->LS, kinls_mem->J); - - /* save nni value from most recent lsetup call */ - kin_mem->kin_nnilset = kin_mem->kin_nni; - - return(kinls_mem->last_flag); -} - - -/*------------------------------------------------------------------ - kinLsSolve interfaces between KINSOL and the generic - SUNLinearSolver object - ------------------------------------------------------------------*/ -int kinLsSolve(KINMem kin_mem, N_Vector xx, N_Vector bb, - realtype *sJpnorm, realtype *sFdotJp) -{ - KINLsMem kinls_mem; - int nli_inc, retval; - realtype res_norm, tol; - - /* Access KINLsMem structure */ - if (kin_mem->kin_lmem == NULL) { - KINProcessError(kin_mem, KINLS_LMEM_NULL, "KINLS", - "kinLsSolve", MSG_LS_LMEM_NULL); - return(KINLS_LMEM_NULL); - } - kinls_mem = (KINLsMem) kin_mem->kin_lmem; - - /* Set linear solver tolerance as input value times scaling factor - (to account for possible lack of support for left/right scaling - vectors in SUNLinSol object) */ - tol = kin_mem->kin_eps * kinls_mem->tol_fac; - - /* Set initial guess x = 0 to LS */ - N_VConst(ZERO, xx); - - /* set flag required for user-supplied J*v routine */ - kinls_mem->new_uu = SUNTRUE; - - /* Call solver */ - retval = SUNLinSolSolve(kinls_mem->LS, kinls_mem->J, xx, bb, tol); - - /* Retrieve solver statistics */ - res_norm = ZERO; - if (kinls_mem->LS->ops->resnorm) - res_norm = SUNLinSolResNorm(kinls_mem->LS); - nli_inc = 0; - if (kinls_mem->LS->ops->numiters) - nli_inc = SUNLinSolNumIters(kinls_mem->LS); - - if (kinls_mem->iterative && kin_mem->kin_printfl > 2) - KINPrintInfo(kin_mem, PRNT_NLI, "KINLS", "kinLsSolve", - INFO_NLI, nli_inc); - - /* Increment counters nli and ncfl */ - kinls_mem->nli += nli_inc; - if (retval != SUNLS_SUCCESS) kinls_mem->ncfl++; - - /* Interpret solver return value */ - kinls_mem->last_flag = retval; - - if ( (retval != 0) && (retval != SUNLS_RES_REDUCED) ) { - - switch(retval) { - case SUNLS_ATIMES_FAIL_REC: - case SUNLS_PSOLVE_FAIL_REC: - return(1); - break; - case SUNLS_MEM_NULL: - case SUNLS_ILL_INPUT: - case SUNLS_MEM_FAIL: - case SUNLS_GS_FAIL: - case SUNLS_CONV_FAIL: - case SUNLS_QRFACT_FAIL: - case SUNLS_LUFACT_FAIL: - case SUNLS_QRSOL_FAIL: - break; - case SUNLS_PACKAGE_FAIL_REC: - KINProcessError(kin_mem, SUNLS_PACKAGE_FAIL_REC, "KINLS", - "kinLsSolve", - "Failure in SUNLinSol external package"); - break; - case SUNLS_PACKAGE_FAIL_UNREC: - KINProcessError(kin_mem, SUNLS_PACKAGE_FAIL_UNREC, "KINLS", - "kinLsSolve", - "Failure in SUNLinSol external package"); - break; - case SUNLS_ATIMES_FAIL_UNREC: - KINProcessError(kin_mem, SUNLS_ATIMES_FAIL_UNREC, "KINLS", - "kinLsSolve", MSG_LS_JTIMES_FAILED); - break; - case SUNLS_PSOLVE_FAIL_UNREC: - KINProcessError(kin_mem, SUNLS_PSOLVE_FAIL_UNREC, "KINLS", - "kinLsSolve", MSG_LS_PSOLVE_FAILED); - break; - } - return(retval); - } - - /* SUNLinSolSolve returned SUNLS_SUCCESS or SUNLS_RES_REDUCED */ - - /* Compute auxiliary values for use in the linesearch and in KINForcingTerm. - These will be subsequently corrected if the step is reduced by constraints - or the linesearch. */ - if (kin_mem->kin_globalstrategy != KIN_FP) { - - /* sJpnorm is the norm of the scaled product (scaled by fscale) of the - current Jacobian matrix J and the step vector p (= solution vector xx) */ - if (kin_mem->kin_inexact_ls && kin_mem->kin_etaflag == KIN_ETACHOICE1) { - retval = kinLsATimes(kin_mem, xx, bb); - if (retval > 0) { - kinls_mem->last_flag = SUNLS_ATIMES_FAIL_REC; - return(1); - } - else if (retval < 0) { - kinls_mem->last_flag = SUNLS_ATIMES_FAIL_UNREC; - return(-1); - } - *sJpnorm = N_VWL2Norm(bb, kin_mem->kin_fscale); - } - - /* sFdotJp is the dot product of the scaled f vector and the scaled - vector J*p, where the scaling uses fscale */ - if ((kin_mem->kin_inexact_ls && kin_mem->kin_etaflag == KIN_ETACHOICE1) || - kin_mem->kin_globalstrategy == KIN_LINESEARCH) { - N_VProd(bb, kin_mem->kin_fscale, bb); - N_VProd(bb, kin_mem->kin_fscale, bb); - *sFdotJp = N_VDotProd(kin_mem->kin_fval, bb); - } - } - - if (kin_mem->kin_inexact_ls && kin_mem->kin_printfl > 2) - KINPrintInfo(kin_mem, PRNT_EPS, "KINLS", "kinLsSolve", - INFO_EPS, res_norm, kin_mem->kin_eps); - - return(0); -} - - -/*------------------------------------------------------------------ - kinLsFree frees memory associated with the KINLs system - solver interface - ------------------------------------------------------------------*/ -int kinLsFree(KINMem kin_mem) -{ - KINLsMem kinls_mem; - - /* Return immediately if kin_mem or kin_mem->kin_lmem are NULL */ - if (kin_mem == NULL) return (KINLS_SUCCESS); - if (kin_mem->kin_lmem == NULL) return(KINLS_SUCCESS); - kinls_mem = (KINLsMem) kin_mem->kin_lmem; - - /* Nullify SUNMatrix pointer */ - kinls_mem->J = NULL; - - /* Free preconditioner memory (if applicable) */ - if (kinls_mem->pfree) kinls_mem->pfree(kin_mem); - - /* free KINLs interface structure */ - free(kin_mem->kin_lmem); - - return(KINLS_SUCCESS); -} - - -/*------------------------------------------------------------------ - kinLsInitializeCounters resets counters for the LS interface - ------------------------------------------------------------------*/ -int kinLsInitializeCounters(KINLsMem kinls_mem) -{ - kinls_mem->nje = 0; - kinls_mem->nfeDQ = 0; - kinls_mem->npe = 0; - kinls_mem->nli = 0; - kinls_mem->nps = 0; - kinls_mem->ncfl = 0; - kinls_mem->njtimes = 0; - return(0); -} - - -/*--------------------------------------------------------------- - kinLs_AccessLMem - - This routine unpacks the kin_mem and ls_mem structures from - void* pointer. If either is missing it returns KINLS_MEM_NULL - or KINLS_LMEM_NULL. - ---------------------------------------------------------------*/ -int kinLs_AccessLMem(void* kinmem, const char *fname, - KINMem *kin_mem, KINLsMem *kinls_mem) -{ - if (kinmem==NULL) { - KINProcessError(NULL, KINLS_MEM_NULL, "KINLS", - fname, MSG_LS_KINMEM_NULL); - return(KINLS_MEM_NULL); - } - *kin_mem = (KINMem) kinmem; - if ((*kin_mem)->kin_lmem==NULL) { - KINProcessError(*kin_mem, KINLS_LMEM_NULL, "KINLS", - fname, MSG_LS_LMEM_NULL); - return(KINLS_LMEM_NULL); - } - *kinls_mem = (KINLsMem) (*kin_mem)->kin_lmem; - return(KINLS_SUCCESS); -} - - -/*--------------------------------------------------------------- - EOF - ---------------------------------------------------------------*/ diff --git a/ThirdParty/sundials/src/kinsol/kinsol_ls_impl.h b/ThirdParty/sundials/src/kinsol/kinsol_ls_impl.h deleted file mode 100644 index 1977887e2a..0000000000 --- a/ThirdParty/sundials/src/kinsol/kinsol_ls_impl.h +++ /dev/null @@ -1,185 +0,0 @@ -/*----------------------------------------------------------------- - * Programmer(s): Daniel R. Reynolds @ SMU - * David J. Gardner, Radu Serban and Aaron Collier @ LLNL - *----------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - *----------------------------------------------------------------- - * Implementation header file for KINSOL's linear solver interface. - *-----------------------------------------------------------------*/ - -#ifndef _KINLS_IMPL_H -#define _KINLS_IMPL_H - -#include -#include "kinsol_impl.h" - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - - -/*------------------------------------------------------------------ - keys for KINPrintInfo (do not use 1 -> conflict with PRNT_RETVAL) - ------------------------------------------------------------------*/ -#define PRNT_NLI 101 -#define PRNT_EPS 102 - - -/*------------------------------------------------------------------ - Types : struct KINLsMemRec, struct *KINLsMem - - The type KINLsMem is a pointer to a KINLsMemRec, which is a - structure containing fields that must be accessible by LS module - routines. - ------------------------------------------------------------------*/ -typedef struct KINLsMemRec { - - /* Linear solver type information */ - booleantype iterative; /* is the solver iterative? */ - booleantype matrixbased; /* is a matrix structure used? */ - - /* Jacobian construction & storage */ - booleantype jacDQ; /* SUNTRUE if using internal DQ Jacobian approx. */ - KINLsJacFn jac; /* Jacobian routine to be called */ - void *J_data; /* J_data is passed to jac */ - - /* Linear solver, matrix and vector objects/pointers */ - SUNLinearSolver LS; /* generic iterative linear solver object */ - SUNMatrix J; /* problem Jacobian */ - - /* Solver tolerance adjustment factor (if needed, see kinLsSolve) */ - realtype tol_fac; - - /* Statistics and associated parameters */ - long int nje; /* no. of calls to jac */ - long int nfeDQ; /* no. of calls to F due to DQ Jacobian or J*v - approximations */ - long int npe; /* npe = total number of precond calls */ - long int nli; /* nli = total number of linear iterations */ - long int nps; /* nps = total number of psolve calls */ - long int ncfl; /* ncfl = total number of convergence failures */ - long int njtimes; /* njtimes = total number of calls to jtimes */ - - booleantype new_uu; /* flag indicating if the iterate has been - updated - the Jacobian must be updated or - reevaluated (meant to be used by a - user-supplied jtimes function */ - - int last_flag; /* last error return flag */ - - /* Preconditioner computation - (a) user-provided: - - pdata == user_data - - pfree == NULL (the user dealocates memory) - (b) internal preconditioner module - - pdata == kin_mem - - pfree == set by the prec. module and called in kinLsFree */ - KINLsPrecSetupFn pset; - KINLsPrecSolveFn psolve; - int (*pfree)(KINMem kin_mem); - void *pdata; - - /* Jacobian times vector compuation - (a) jtimes function provided by the user: - - jt_data == user_data - - jtimesDQ == SUNFALSE - (b) internal jtimes - - jt_data == kin_mem - - jtimesDQ == SUNTRUE */ - booleantype jtimesDQ; - KINLsJacTimesVecFn jtimes; - KINSysFn jt_func; - void *jt_data; - -} *KINLsMem; - - -/*------------------------------------------------------------------ - Prototypes of internal functions - ------------------------------------------------------------------*/ - -/* Interface routines called by system SUNLinearSolvers */ -int kinLsATimes(void *kinmem, N_Vector v, N_Vector z); -int kinLsPSetup(void *kinmem); -int kinLsPSolve(void *kinmem, N_Vector r, N_Vector z, - realtype tol, int lr); - -/* Difference quotient approximation for Jacobian times vector */ -int kinLsDQJtimes(N_Vector v, N_Vector Jv, N_Vector u, - booleantype *new_u, void *data); - -/* Difference-quotient Jacobian approximation routines */ -int kinLsDQJac(N_Vector u, N_Vector fu, SUNMatrix Jac, - void *data, N_Vector tmp1, N_Vector tmp2); - -int kinLsDenseDQJac(N_Vector u, N_Vector fu, SUNMatrix Jac, - KINMem kin_mem, N_Vector tmp1, N_Vector tmp2); - -int kinLsBandDQJac(N_Vector u, N_Vector fu, SUNMatrix Jac, - KINMem kin_mem, N_Vector tmp1, N_Vector tmp2); - -/* Generic linit/lsetup/lsolve/lfree interface routines for KINSOL to call */ -int kinLsInitialize(KINMem kin_mem); -int kinLsSetup(KINMem kin_mem); -int kinLsSolve(KINMem kin_mem, N_Vector x, N_Vector b, - realtype *sJpnorm, realtype *sFdotJp); -int kinLsFree(KINMem kin_mem); - -/* Auxilliary functions */ -int kinLsInitializeCounters(KINLsMem kinls_mem); -int kinLs_AccessLMem(void* kinmem, const char *fname, - KINMem* kin_mem, KINLsMem *kinls_mem); - - -/*------------------------------------------------------------------ - Error messages - ------------------------------------------------------------------*/ - -#define MSG_LS_KINMEM_NULL "KINSOL memory is NULL." -#define MSG_LS_MEM_FAIL "A memory request failed." -#define MSG_LS_BAD_NVECTOR "A required vector operation is not implemented." -#define MSG_LS_LMEM_NULL "Linear solver memory is NULL." -#define MSG_LS_NEG_MAXRS "maxrs < 0 illegal." -#define MSG_LS_BAD_SIZES "Illegal bandwidth parameter(s). Must have 0 <= ml, mu <= N-1." - -#define MSG_LS_JACFUNC_FAILED "The Jacobian routine failed in an unrecoverable manner." -#define MSG_LS_PSET_FAILED "The preconditioner setup routine failed in an unrecoverable manner." -#define MSG_LS_PSOLVE_FAILED "The preconditioner solve routine failed in an unrecoverable manner." -#define MSG_LS_JTIMES_FAILED "The Jacobian x vector routine failed in an unrecoverable manner." -#define MSG_LS_MATZERO_FAILED "The SUNMatZero routine failed in an unrecoverable manner." - - -/*------------------------------------------------------------------ - Info messages - ------------------------------------------------------------------*/ - -#define INFO_NLI "nli_inc = %d" - -#if defined(SUNDIALS_EXTENDED_PRECISION) - -#define INFO_EPS "residual norm = %12.3Lg eps = %12.3Lg" - -#elif defined(SUNDIALS_DOUBLE_PRECISION) - -#define INFO_EPS "residual norm = %12.3lg eps = %12.3lg" - -#else - -#define INFO_EPS "residual norm = %12.3g eps = %12.3g" - -#endif - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ThirdParty/sundials/src/kinsol/kinsol_spils.c b/ThirdParty/sundials/src/kinsol/kinsol_spils.c deleted file mode 100644 index 9af333554d..0000000000 --- a/ThirdParty/sundials/src/kinsol/kinsol_spils.c +++ /dev/null @@ -1,73 +0,0 @@ -/*----------------------------------------------------------------- - * Programmer(s): Daniel R. Reynolds @ SMU - * Scott Cohen, Alan Hindmarsh, Radu Serban, - * and Aaron Collier @ LLNL - *----------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - *----------------------------------------------------------------- - * Header file for the deprecated Scaled Preconditioned Iterative - * Linear Solver interface in KINSOL; these routines now just wrap - * the updated KINSOL generic linear solver interface in kinsol_ls.h. - *-----------------------------------------------------------------*/ - -#include -#include - -#ifdef __cplusplus /* wrapper to enable C++ usage */ -extern "C" { -#endif - -/*================================================================= - Exported Functions (wrappers for equivalent routines in kinsol_ls.h) - =================================================================*/ - -int KINSpilsSetLinearSolver(void *kinmem, SUNLinearSolver LS) -{ return(KINSetLinearSolver(kinmem, LS, NULL)); } - -int KINSpilsSetPreconditioner(void *kinmem, KINSpilsPrecSetupFn psetup, - KINSpilsPrecSolveFn psolve) -{ return(KINSetPreconditioner(kinmem, psetup, psolve)); } - -int KINSpilsSetJacTimesVecFn(void *kinmem, KINSpilsJacTimesVecFn jtv) -{ return(KINSetJacTimesVecFn(kinmem, jtv)); } - -int KINSpilsGetWorkSpace(void *kinmem, long int *lenrwLS, long int *leniwLS) -{ return(KINGetLinWorkSpace(kinmem, lenrwLS, leniwLS)); } - -int KINSpilsGetNumPrecEvals(void *kinmem, long int *npevals) -{ return(KINGetNumPrecEvals(kinmem, npevals)); } - -int KINSpilsGetNumPrecSolves(void *kinmem, long int *npsolves) -{ return(KINGetNumPrecSolves(kinmem, npsolves)); } - -int KINSpilsGetNumLinIters(void *kinmem, long int *nliters) -{ return(KINGetNumLinIters(kinmem, nliters)); } - -int KINSpilsGetNumConvFails(void *kinmem, long int *nlcfails) -{ return(KINGetNumLinConvFails(kinmem, nlcfails)); } - -int KINSpilsGetNumJtimesEvals(void *kinmem, long int *njvevals) -{ return(KINGetNumJtimesEvals(kinmem, njvevals)); } - -int KINSpilsGetNumFuncEvals(void *kinmem, long int *nfevals) -{ return(KINGetNumLinFuncEvals(kinmem, nfevals)); } - -int KINSpilsGetLastFlag(void *kinmem, long int *flag) -{ return(KINGetLastLinFlag(kinmem, flag)); } - -char *KINSpilsGetReturnFlagName(long int flag) -{ return(KINGetLinReturnFlagName(flag)); } - - -#ifdef __cplusplus -} -#endif - diff --git a/ThirdParty/sundials/src/sunnonlinsol/fixedpoint/fmod/CMakeLists.txt b/ThirdParty/sundials/src/sunnonlinsol/fixedpoint/fmod/CMakeLists.txt deleted file mode 100644 index a5ded42bc5..0000000000 --- a/ThirdParty/sundials/src/sunnonlinsol/fixedpoint/fmod/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -# --------------------------------------------------------------- -# Programmer(s): Cody J. Balos @ LLNL -# --------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# --------------------------------------------------------------- -# CMakeLists.txt file for the F2003 fixed-point SUNNonlinearSolver -# object library -# --------------------------------------------------------------- - -sundials_add_f2003_library(sundials_fsunnonlinsolfixedpoint_mod - SOURCES - fsunnonlinsol_fixedpoint_mod.f90 fsunnonlinsol_fixedpoint_mod.c - OBJECT_LIBRARIES - sundials_fgeneric_mod_obj - OUTPUT_NAME - sundials_fsunnonlinsolfixedpoint_mod - VERSION - ${sunnonlinsollib_VERSION} - SOVERSION - ${sunnonlinsollib_SOVERSION} -) - -message(STATUS "Added SUNNONLINSOL_FIXEDPOINT F2003 interface") diff --git a/ThirdParty/sundials/src/sunnonlinsol/fixedpoint/fmod/fsunnonlinsol_fixedpoint_mod.c b/ThirdParty/sundials/src/sunnonlinsol/fixedpoint/fmod/fsunnonlinsol_fixedpoint_mod.c deleted file mode 100644 index 1a01c6da84..0000000000 --- a/ThirdParty/sundials/src/sunnonlinsol/fixedpoint/fmod/fsunnonlinsol_fixedpoint_mod.c +++ /dev/null @@ -1,443 +0,0 @@ -/* ---------------------------------------------------------------------------- - * This file was automatically generated by SWIG (http://www.swig.org). - * Version 4.0.0 - * - * This file is not intended to be easily readable and contains a number of - * coding conventions designed to improve portability and efficiency. Do not make - * changes to this file unless you know what you are doing--modify the SWIG - * interface file instead. - * ----------------------------------------------------------------------------- */ - -/* --------------------------------------------------------------- - * Programmer(s): Auto-generated by swig. - * --------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - * -------------------------------------------------------------*/ - -/* ----------------------------------------------------------------------------- - * This section contains generic SWIG labels for method/variable - * declarations/attributes, and other compiler dependent labels. - * ----------------------------------------------------------------------------- */ - -/* template workaround for compilers that cannot correctly implement the C++ standard */ -#ifndef SWIGTEMPLATEDISAMBIGUATOR -# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) -# define SWIGTEMPLATEDISAMBIGUATOR template -# elif defined(__HP_aCC) -/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ -/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ -# define SWIGTEMPLATEDISAMBIGUATOR template -# else -# define SWIGTEMPLATEDISAMBIGUATOR -# endif -#endif - -/* inline attribute */ -#ifndef SWIGINLINE -# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) -# define SWIGINLINE inline -# else -# define SWIGINLINE -# endif -#endif - -/* attribute recognised by some compilers to avoid 'unused' warnings */ -#ifndef SWIGUNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -# elif defined(__ICC) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -#endif - -#ifndef SWIG_MSC_UNSUPPRESS_4505 -# if defined(_MSC_VER) -# pragma warning(disable : 4505) /* unreferenced local function has been removed */ -# endif -#endif - -#ifndef SWIGUNUSEDPARM -# ifdef __cplusplus -# define SWIGUNUSEDPARM(p) -# else -# define SWIGUNUSEDPARM(p) p SWIGUNUSED -# endif -#endif - -/* internal SWIG method */ -#ifndef SWIGINTERN -# define SWIGINTERN static SWIGUNUSED -#endif - -/* internal inline SWIG method */ -#ifndef SWIGINTERNINLINE -# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE -#endif - -/* qualifier for exported *const* global data variables*/ -#ifndef SWIGEXTERN -# ifdef __cplusplus -# define SWIGEXTERN extern -# else -# define SWIGEXTERN -# endif -#endif - -/* exporting methods */ -#if defined(__GNUC__) -# if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) -# ifndef GCC_HASCLASSVISIBILITY -# define GCC_HASCLASSVISIBILITY -# endif -# endif -#endif - -#ifndef SWIGEXPORT -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# if defined(STATIC_LINKED) -# define SWIGEXPORT -# else -# define SWIGEXPORT __declspec(dllexport) -# endif -# else -# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) -# define SWIGEXPORT __attribute__ ((visibility("default"))) -# else -# define SWIGEXPORT -# endif -# endif -#endif - -/* calling conventions for Windows */ -#ifndef SWIGSTDCALL -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# define SWIGSTDCALL __stdcall -# else -# define SWIGSTDCALL -# endif -#endif - -/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ -#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) -# define _CRT_SECURE_NO_DEPRECATE -#endif - -/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ -#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) -# define _SCL_SECURE_NO_DEPRECATE -#endif - -/* Deal with Apple's deprecated 'AssertMacros.h' from Carbon-framework */ -#if defined(__APPLE__) && !defined(__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES) -# define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 -#endif - -/* Intel's compiler complains if a variable which was never initialised is - * cast to void, which is a common idiom which we use to indicate that we - * are aware a variable isn't used. So we just silence that warning. - * See: https://github.com/swig/swig/issues/192 for more discussion. - */ -#ifdef __INTEL_COMPILER -# pragma warning disable 592 -#endif - -/* Errors in SWIG */ -#define SWIG_UnknownError -1 -#define SWIG_IOError -2 -#define SWIG_RuntimeError -3 -#define SWIG_IndexError -4 -#define SWIG_TypeError -5 -#define SWIG_DivisionByZero -6 -#define SWIG_OverflowError -7 -#define SWIG_SyntaxError -8 -#define SWIG_ValueError -9 -#define SWIG_SystemError -10 -#define SWIG_AttributeError -11 -#define SWIG_MemoryError -12 -#define SWIG_NullReferenceError -13 - - - - -#include -#define SWIG_exception_impl(DECL, CODE, MSG, RETURNNULL) \ - { printf("In " DECL ": " MSG); assert(0); RETURNNULL; } - - -#include -#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) -# ifndef snprintf -# define snprintf _snprintf -# endif -#endif - - -/* Support for the `contract` feature. - * - * Note that RETURNNULL is first because it's inserted via a 'Replaceall' in - * the fortran.cxx file. - */ -#define SWIG_contract_assert(RETURNNULL, EXPR, MSG) \ - if (!(EXPR)) { SWIG_exception_impl("$decl", SWIG_ValueError, MSG, RETURNNULL); } - - -#define SWIGVERSION 0x040000 -#define SWIG_VERSION SWIGVERSION - - -#define SWIG_as_voidptr(a) (void *)((const void *)(a)) -#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) - - -#include "sundials/sundials_nonlinearsolver.h" - - -#include "sunnonlinsol/sunnonlinsol_fixedpoint.h" - -SWIGEXPORT SUNNonlinearSolver _wrap_FSUNNonlinSol_FixedPoint(N_Vector farg1, int const *farg2) { - SUNNonlinearSolver fresult ; - N_Vector arg1 = (N_Vector) 0 ; - int arg2 ; - SUNNonlinearSolver result; - - arg1 = (N_Vector)(farg1); - arg2 = (int)(*farg2); - result = (SUNNonlinearSolver)SUNNonlinSol_FixedPoint(arg1,arg2); - fresult = result; - return fresult; -} - - -SWIGEXPORT SUNNonlinearSolver _wrap_FSUNNonlinSol_FixedPointSens(int const *farg1, N_Vector farg2, int const *farg3) { - SUNNonlinearSolver fresult ; - int arg1 ; - N_Vector arg2 = (N_Vector) 0 ; - int arg3 ; - SUNNonlinearSolver result; - - arg1 = (int)(*farg1); - arg2 = (N_Vector)(farg2); - arg3 = (int)(*farg3); - result = (SUNNonlinearSolver)SUNNonlinSol_FixedPointSens(arg1,arg2,arg3); - fresult = result; - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolGetType_FixedPoint(SUNNonlinearSolver farg1) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - SUNNonlinearSolver_Type result; - - arg1 = (SUNNonlinearSolver)(farg1); - result = (SUNNonlinearSolver_Type)SUNNonlinSolGetType_FixedPoint(arg1); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolInitialize_FixedPoint(SUNNonlinearSolver farg1) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - result = (int)SUNNonlinSolInitialize_FixedPoint(arg1); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSolve_FixedPoint(SUNNonlinearSolver farg1, N_Vector farg2, N_Vector farg3, N_Vector farg4, double const *farg5, int const *farg6, void *farg7) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - N_Vector arg2 = (N_Vector) 0 ; - N_Vector arg3 = (N_Vector) 0 ; - N_Vector arg4 = (N_Vector) 0 ; - realtype arg5 ; - int arg6 ; - void *arg7 = (void *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (N_Vector)(farg2); - arg3 = (N_Vector)(farg3); - arg4 = (N_Vector)(farg4); - arg5 = (realtype)(*farg5); - arg6 = (int)(*farg6); - arg7 = (void *)(farg7); - result = (int)SUNNonlinSolSolve_FixedPoint(arg1,arg2,arg3,arg4,arg5,arg6,arg7); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolFree_FixedPoint(SUNNonlinearSolver farg1) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - result = (int)SUNNonlinSolFree_FixedPoint(arg1); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetSysFn_FixedPoint(SUNNonlinearSolver farg1, SUNNonlinSolSysFn farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - SUNNonlinSolSysFn arg2 = (SUNNonlinSolSysFn) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (SUNNonlinSolSysFn)(farg2); - result = (int)SUNNonlinSolSetSysFn_FixedPoint(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetConvTestFn_FixedPoint(SUNNonlinearSolver farg1, SUNNonlinSolConvTestFn farg2, void *farg3) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - SUNNonlinSolConvTestFn arg2 = (SUNNonlinSolConvTestFn) 0 ; - void *arg3 = (void *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (SUNNonlinSolConvTestFn)(farg2); - arg3 = (void *)(farg3); - result = (int)SUNNonlinSolSetConvTestFn_FixedPoint(arg1,arg2,arg3); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetMaxIters_FixedPoint(SUNNonlinearSolver farg1, int const *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - int arg2 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (int)(*farg2); - result = (int)SUNNonlinSolSetMaxIters_FixedPoint(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetDamping_FixedPoint(SUNNonlinearSolver farg1, double const *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - realtype arg2 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (realtype)(*farg2); - result = (int)SUNNonlinSolSetDamping_FixedPoint(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolGetNumIters_FixedPoint(SUNNonlinearSolver farg1, long *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - long *arg2 = (long *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (long *)(farg2); - result = (int)SUNNonlinSolGetNumIters_FixedPoint(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolGetCurIter_FixedPoint(SUNNonlinearSolver farg1, int *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - int *arg2 = (int *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (int *)(farg2); - result = (int)SUNNonlinSolGetCurIter_FixedPoint(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolGetNumConvFails_FixedPoint(SUNNonlinearSolver farg1, long *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - long *arg2 = (long *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (long *)(farg2); - result = (int)SUNNonlinSolGetNumConvFails_FixedPoint(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolGetSysFn_FixedPoint(SUNNonlinearSolver farg1, void *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - SUNNonlinSolSysFn *arg2 = (SUNNonlinSolSysFn *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (SUNNonlinSolSysFn *)(farg2); - result = (int)SUNNonlinSolGetSysFn_FixedPoint(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetInfoFile_FixedPoint(SUNNonlinearSolver farg1, void *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - FILE *arg2 = (FILE *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (FILE *)(farg2); - result = (int)SUNNonlinSolSetInfoFile_FixedPoint(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetPrintLevel_FixedPoint(SUNNonlinearSolver farg1, int const *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - int arg2 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (int)(*farg2); - result = (int)SUNNonlinSolSetPrintLevel_FixedPoint(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - - diff --git a/ThirdParty/sundials/src/sunnonlinsol/fixedpoint/fmod/fsunnonlinsol_fixedpoint_mod.f90 b/ThirdParty/sundials/src/sunnonlinsol/fixedpoint/fmod/fsunnonlinsol_fixedpoint_mod.f90 deleted file mode 100644 index 4b5531731e..0000000000 --- a/ThirdParty/sundials/src/sunnonlinsol/fixedpoint/fmod/fsunnonlinsol_fixedpoint_mod.f90 +++ /dev/null @@ -1,473 +0,0 @@ -! This file was automatically generated by SWIG (http://www.swig.org). -! Version 4.0.0 -! -! Do not make changes to this file unless you know what you are doing--modify -! the SWIG interface file instead. - -! --------------------------------------------------------------- -! Programmer(s): Auto-generated by swig. -! --------------------------------------------------------------- -! SUNDIALS Copyright Start -! Copyright (c) 2002-2021, Lawrence Livermore National Security -! and Southern Methodist University. -! All rights reserved. -! -! See the top-level LICENSE and NOTICE files for details. -! -! SPDX-License-Identifier: BSD-3-Clause -! SUNDIALS Copyright End -! --------------------------------------------------------------- - -module fsunnonlinsol_fixedpoint_mod - use, intrinsic :: ISO_C_BINDING - use fsundials_nvector_mod - use fsundials_types_mod - use fsundials_nonlinearsolver_mod - use fsundials_nvector_mod - use fsundials_types_mod - implicit none - private - - ! DECLARATION CONSTRUCTS - public :: FSUNNonlinSol_FixedPoint - public :: FSUNNonlinSol_FixedPointSens - public :: FSUNNonlinSolGetType_FixedPoint - public :: FSUNNonlinSolInitialize_FixedPoint - public :: FSUNNonlinSolSolve_FixedPoint - public :: FSUNNonlinSolFree_FixedPoint - public :: FSUNNonlinSolSetSysFn_FixedPoint - public :: FSUNNonlinSolSetConvTestFn_FixedPoint - public :: FSUNNonlinSolSetMaxIters_FixedPoint - public :: FSUNNonlinSolSetDamping_FixedPoint - public :: FSUNNonlinSolGetNumIters_FixedPoint - public :: FSUNNonlinSolGetCurIter_FixedPoint - public :: FSUNNonlinSolGetNumConvFails_FixedPoint - public :: FSUNNonlinSolGetSysFn_FixedPoint - public :: FSUNNonlinSolSetInfoFile_FixedPoint - public :: FSUNNonlinSolSetPrintLevel_FixedPoint - -! WRAPPER DECLARATIONS -interface -function swigc_FSUNNonlinSol_FixedPoint(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSol_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT), intent(in) :: farg2 -type(C_PTR) :: fresult -end function - -function swigc_FSUNNonlinSol_FixedPointSens(farg1, farg2, farg3) & -bind(C, name="_wrap_FSUNNonlinSol_FixedPointSens") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -integer(C_INT), intent(in) :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT), intent(in) :: farg3 -type(C_PTR) :: fresult -end function - -function swigc_FSUNNonlinSolGetType_FixedPoint(farg1) & -bind(C, name="_wrap_FSUNNonlinSolGetType_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolInitialize_FixedPoint(farg1) & -bind(C, name="_wrap_FSUNNonlinSolInitialize_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSolve_FixedPoint(farg1, farg2, farg3, farg4, farg5, farg6, farg7) & -bind(C, name="_wrap_FSUNNonlinSolSolve_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -type(C_PTR), value :: farg3 -type(C_PTR), value :: farg4 -real(C_DOUBLE), intent(in) :: farg5 -integer(C_INT), intent(in) :: farg6 -type(C_PTR), value :: farg7 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolFree_FixedPoint(farg1) & -bind(C, name="_wrap_FSUNNonlinSolFree_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetSysFn_FixedPoint(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetSysFn_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_FUNPTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetConvTestFn_FixedPoint(farg1, farg2, farg3) & -bind(C, name="_wrap_FSUNNonlinSolSetConvTestFn_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_FUNPTR), value :: farg2 -type(C_PTR), value :: farg3 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetMaxIters_FixedPoint(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetMaxIters_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT), intent(in) :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetDamping_FixedPoint(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetDamping_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -real(C_DOUBLE), intent(in) :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolGetNumIters_FixedPoint(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolGetNumIters_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolGetCurIter_FixedPoint(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolGetCurIter_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolGetNumConvFails_FixedPoint(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolGetNumConvFails_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolGetSysFn_FixedPoint(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolGetSysFn_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetInfoFile_FixedPoint(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetInfoFile_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetPrintLevel_FixedPoint(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetPrintLevel_FixedPoint") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT), intent(in) :: farg2 -integer(C_INT) :: fresult -end function - -end interface - - -contains - ! MODULE SUBPROGRAMS -function FSUNNonlinSol_FixedPoint(y, m) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -type(SUNNonlinearSolver), pointer :: swig_result -type(N_Vector), target, intent(inout) :: y -integer(C_INT), intent(in) :: m -type(C_PTR) :: fresult -type(C_PTR) :: farg1 -integer(C_INT) :: farg2 - -farg1 = c_loc(y) -farg2 = m -fresult = swigc_FSUNNonlinSol_FixedPoint(farg1, farg2) -call c_f_pointer(fresult, swig_result) -end function - -function FSUNNonlinSol_FixedPointSens(count, y, m) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -type(SUNNonlinearSolver), pointer :: swig_result -integer(C_INT), intent(in) :: count -type(N_Vector), target, intent(inout) :: y -integer(C_INT), intent(in) :: m -type(C_PTR) :: fresult -integer(C_INT) :: farg1 -type(C_PTR) :: farg2 -integer(C_INT) :: farg3 - -farg1 = count -farg2 = c_loc(y) -farg3 = m -fresult = swigc_FSUNNonlinSol_FixedPointSens(farg1, farg2, farg3) -call c_f_pointer(fresult, swig_result) -end function - -function FSUNNonlinSolGetType_FixedPoint(nls) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(SUNNonlinearSolver_Type) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT) :: fresult -type(C_PTR) :: farg1 - -farg1 = c_loc(nls) -fresult = swigc_FSUNNonlinSolGetType_FixedPoint(farg1) -swig_result = fresult -end function - -function FSUNNonlinSolInitialize_FixedPoint(nls) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT) :: fresult -type(C_PTR) :: farg1 - -farg1 = c_loc(nls) -fresult = swigc_FSUNNonlinSolInitialize_FixedPoint(farg1) -swig_result = fresult -end function - -function FSUNNonlinSolSolve_FixedPoint(nls, y0, y, w, tol, callsetup, mem) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(N_Vector), target, intent(inout) :: y0 -type(N_Vector), target, intent(inout) :: y -type(N_Vector), target, intent(inout) :: w -real(C_DOUBLE), intent(in) :: tol -integer(C_INT), intent(in) :: callsetup -type(C_PTR) :: mem -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 -type(C_PTR) :: farg3 -type(C_PTR) :: farg4 -real(C_DOUBLE) :: farg5 -integer(C_INT) :: farg6 -type(C_PTR) :: farg7 - -farg1 = c_loc(nls) -farg2 = c_loc(y0) -farg3 = c_loc(y) -farg4 = c_loc(w) -farg5 = tol -farg6 = callsetup -farg7 = mem -fresult = swigc_FSUNNonlinSolSolve_FixedPoint(farg1, farg2, farg3, farg4, farg5, farg6, farg7) -swig_result = fresult -end function - -function FSUNNonlinSolFree_FixedPoint(nls) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT) :: fresult -type(C_PTR) :: farg1 - -farg1 = c_loc(nls) -fresult = swigc_FSUNNonlinSolFree_FixedPoint(farg1) -swig_result = fresult -end function - -function FSUNNonlinSolSetSysFn_FixedPoint(nls, sysfn) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(C_FUNPTR), intent(in), value :: sysfn -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_FUNPTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = sysfn -fresult = swigc_FSUNNonlinSolSetSysFn_FixedPoint(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolSetConvTestFn_FixedPoint(nls, ctestfn, ctest_data) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(C_FUNPTR), intent(in), value :: ctestfn -type(C_PTR) :: ctest_data -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_FUNPTR) :: farg2 -type(C_PTR) :: farg3 - -farg1 = c_loc(nls) -farg2 = ctestfn -farg3 = ctest_data -fresult = swigc_FSUNNonlinSolSetConvTestFn_FixedPoint(farg1, farg2, farg3) -swig_result = fresult -end function - -function FSUNNonlinSolSetMaxIters_FixedPoint(nls, maxiters) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT), intent(in) :: maxiters -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -integer(C_INT) :: farg2 - -farg1 = c_loc(nls) -farg2 = maxiters -fresult = swigc_FSUNNonlinSolSetMaxIters_FixedPoint(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolSetDamping_FixedPoint(nls, beta) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -real(C_DOUBLE), intent(in) :: beta -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -real(C_DOUBLE) :: farg2 - -farg1 = c_loc(nls) -farg2 = beta -fresult = swigc_FSUNNonlinSolSetDamping_FixedPoint(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolGetNumIters_FixedPoint(nls, niters) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_LONG), dimension(*), target, intent(inout) :: niters -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = c_loc(niters(1)) -fresult = swigc_FSUNNonlinSolGetNumIters_FixedPoint(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolGetCurIter_FixedPoint(nls, iter) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT), dimension(*), target, intent(inout) :: iter -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = c_loc(iter(1)) -fresult = swigc_FSUNNonlinSolGetCurIter_FixedPoint(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolGetNumConvFails_FixedPoint(nls, nconvfails) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_LONG), dimension(*), target, intent(inout) :: nconvfails -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = c_loc(nconvfails(1)) -fresult = swigc_FSUNNonlinSolGetNumConvFails_FixedPoint(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolGetSysFn_FixedPoint(nls, sysfn) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(C_FUNPTR), target, intent(inout) :: sysfn -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = c_loc(sysfn) -fresult = swigc_FSUNNonlinSolGetSysFn_FixedPoint(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolSetInfoFile_FixedPoint(nls, info_file) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(C_PTR) :: info_file -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = info_file -fresult = swigc_FSUNNonlinSolSetInfoFile_FixedPoint(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolSetPrintLevel_FixedPoint(nls, print_level) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT), intent(in) :: print_level -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -integer(C_INT) :: farg2 - -farg1 = c_loc(nls) -farg2 = print_level -fresult = swigc_FSUNNonlinSolSetPrintLevel_FixedPoint(farg1, farg2) -swig_result = fresult -end function - - -end module diff --git a/ThirdParty/sundials/src/sunnonlinsol/newton/fmod/CMakeLists.txt b/ThirdParty/sundials/src/sunnonlinsol/newton/fmod/CMakeLists.txt deleted file mode 100644 index 16be4d4387..0000000000 --- a/ThirdParty/sundials/src/sunnonlinsol/newton/fmod/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -# --------------------------------------------------------------- -# Programmer(s): Cody J. Balos @ LLNL -# --------------------------------------------------------------- -# SUNDIALS Copyright Start -# Copyright (c) 2002-2021, Lawrence Livermore National Security -# and Southern Methodist University. -# All rights reserved. -# -# See the top-level LICENSE and NOTICE files for details. -# -# SPDX-License-Identifier: BSD-3-Clause -# SUNDIALS Copyright End -# --------------------------------------------------------------- -# CMakeLists.txt file for the F2003 Newton SUNNonlinearSolver -# object library -# --------------------------------------------------------------- - -sundials_add_f2003_library(sundials_fsunnonlinsolnewton_mod - SOURCES - fsunnonlinsol_newton_mod.f90 fsunnonlinsol_newton_mod.c - OBJECT_LIBRARIES - sundials_fgeneric_mod_obj - OUTPUT_NAME - sundials_fsunnonlinsolnewton_mod - VERSION - ${sunnonlinsollib_VERSION} - SOVERSION - ${sunnonlinsollib_SOVERSION} -) - -message(STATUS "Added SUNNONLINSOL_NEWTON F2003 interface") diff --git a/ThirdParty/sundials/src/sunnonlinsol/newton/fmod/fsunnonlinsol_newton_mod.c b/ThirdParty/sundials/src/sunnonlinsol/newton/fmod/fsunnonlinsol_newton_mod.c deleted file mode 100644 index e011e8006f..0000000000 --- a/ThirdParty/sundials/src/sunnonlinsol/newton/fmod/fsunnonlinsol_newton_mod.c +++ /dev/null @@ -1,453 +0,0 @@ -/* ---------------------------------------------------------------------------- - * This file was automatically generated by SWIG (http://www.swig.org). - * Version 4.0.0 - * - * This file is not intended to be easily readable and contains a number of - * coding conventions designed to improve portability and efficiency. Do not make - * changes to this file unless you know what you are doing--modify the SWIG - * interface file instead. - * ----------------------------------------------------------------------------- */ - -/* --------------------------------------------------------------- - * Programmer(s): Auto-generated by swig. - * --------------------------------------------------------------- - * SUNDIALS Copyright Start - * Copyright (c) 2002-2021, Lawrence Livermore National Security - * and Southern Methodist University. - * All rights reserved. - * - * See the top-level LICENSE and NOTICE files for details. - * - * SPDX-License-Identifier: BSD-3-Clause - * SUNDIALS Copyright End - * -------------------------------------------------------------*/ - -/* ----------------------------------------------------------------------------- - * This section contains generic SWIG labels for method/variable - * declarations/attributes, and other compiler dependent labels. - * ----------------------------------------------------------------------------- */ - -/* template workaround for compilers that cannot correctly implement the C++ standard */ -#ifndef SWIGTEMPLATEDISAMBIGUATOR -# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) -# define SWIGTEMPLATEDISAMBIGUATOR template -# elif defined(__HP_aCC) -/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ -/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ -# define SWIGTEMPLATEDISAMBIGUATOR template -# else -# define SWIGTEMPLATEDISAMBIGUATOR -# endif -#endif - -/* inline attribute */ -#ifndef SWIGINLINE -# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) -# define SWIGINLINE inline -# else -# define SWIGINLINE -# endif -#endif - -/* attribute recognised by some compilers to avoid 'unused' warnings */ -#ifndef SWIGUNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -# elif defined(__ICC) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -#endif - -#ifndef SWIG_MSC_UNSUPPRESS_4505 -# if defined(_MSC_VER) -# pragma warning(disable : 4505) /* unreferenced local function has been removed */ -# endif -#endif - -#ifndef SWIGUNUSEDPARM -# ifdef __cplusplus -# define SWIGUNUSEDPARM(p) -# else -# define SWIGUNUSEDPARM(p) p SWIGUNUSED -# endif -#endif - -/* internal SWIG method */ -#ifndef SWIGINTERN -# define SWIGINTERN static SWIGUNUSED -#endif - -/* internal inline SWIG method */ -#ifndef SWIGINTERNINLINE -# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE -#endif - -/* qualifier for exported *const* global data variables*/ -#ifndef SWIGEXTERN -# ifdef __cplusplus -# define SWIGEXTERN extern -# else -# define SWIGEXTERN -# endif -#endif - -/* exporting methods */ -#if defined(__GNUC__) -# if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) -# ifndef GCC_HASCLASSVISIBILITY -# define GCC_HASCLASSVISIBILITY -# endif -# endif -#endif - -#ifndef SWIGEXPORT -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# if defined(STATIC_LINKED) -# define SWIGEXPORT -# else -# define SWIGEXPORT __declspec(dllexport) -# endif -# else -# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) -# define SWIGEXPORT __attribute__ ((visibility("default"))) -# else -# define SWIGEXPORT -# endif -# endif -#endif - -/* calling conventions for Windows */ -#ifndef SWIGSTDCALL -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# define SWIGSTDCALL __stdcall -# else -# define SWIGSTDCALL -# endif -#endif - -/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ -#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) -# define _CRT_SECURE_NO_DEPRECATE -#endif - -/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ -#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) -# define _SCL_SECURE_NO_DEPRECATE -#endif - -/* Deal with Apple's deprecated 'AssertMacros.h' from Carbon-framework */ -#if defined(__APPLE__) && !defined(__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES) -# define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 -#endif - -/* Intel's compiler complains if a variable which was never initialised is - * cast to void, which is a common idiom which we use to indicate that we - * are aware a variable isn't used. So we just silence that warning. - * See: https://github.com/swig/swig/issues/192 for more discussion. - */ -#ifdef __INTEL_COMPILER -# pragma warning disable 592 -#endif - -/* Errors in SWIG */ -#define SWIG_UnknownError -1 -#define SWIG_IOError -2 -#define SWIG_RuntimeError -3 -#define SWIG_IndexError -4 -#define SWIG_TypeError -5 -#define SWIG_DivisionByZero -6 -#define SWIG_OverflowError -7 -#define SWIG_SyntaxError -8 -#define SWIG_ValueError -9 -#define SWIG_SystemError -10 -#define SWIG_AttributeError -11 -#define SWIG_MemoryError -12 -#define SWIG_NullReferenceError -13 - - - - -#include -#define SWIG_exception_impl(DECL, CODE, MSG, RETURNNULL) \ - { printf("In " DECL ": " MSG); assert(0); RETURNNULL; } - - -#include -#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) -# ifndef snprintf -# define snprintf _snprintf -# endif -#endif - - -/* Support for the `contract` feature. - * - * Note that RETURNNULL is first because it's inserted via a 'Replaceall' in - * the fortran.cxx file. - */ -#define SWIG_contract_assert(RETURNNULL, EXPR, MSG) \ - if (!(EXPR)) { SWIG_exception_impl("$decl", SWIG_ValueError, MSG, RETURNNULL); } - - -#define SWIGVERSION 0x040000 -#define SWIG_VERSION SWIGVERSION - - -#define SWIG_as_voidptr(a) (void *)((const void *)(a)) -#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) - - -#include "sundials/sundials_nonlinearsolver.h" - - -#include "sunnonlinsol/sunnonlinsol_newton.h" - -SWIGEXPORT SUNNonlinearSolver _wrap_FSUNNonlinSol_Newton(N_Vector farg1) { - SUNNonlinearSolver fresult ; - N_Vector arg1 = (N_Vector) 0 ; - SUNNonlinearSolver result; - - arg1 = (N_Vector)(farg1); - result = (SUNNonlinearSolver)SUNNonlinSol_Newton(arg1); - fresult = result; - return fresult; -} - - -SWIGEXPORT SUNNonlinearSolver _wrap_FSUNNonlinSol_NewtonSens(int const *farg1, N_Vector farg2) { - SUNNonlinearSolver fresult ; - int arg1 ; - N_Vector arg2 = (N_Vector) 0 ; - SUNNonlinearSolver result; - - arg1 = (int)(*farg1); - arg2 = (N_Vector)(farg2); - result = (SUNNonlinearSolver)SUNNonlinSol_NewtonSens(arg1,arg2); - fresult = result; - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolGetType_Newton(SUNNonlinearSolver farg1) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - SUNNonlinearSolver_Type result; - - arg1 = (SUNNonlinearSolver)(farg1); - result = (SUNNonlinearSolver_Type)SUNNonlinSolGetType_Newton(arg1); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolInitialize_Newton(SUNNonlinearSolver farg1) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - result = (int)SUNNonlinSolInitialize_Newton(arg1); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSolve_Newton(SUNNonlinearSolver farg1, N_Vector farg2, N_Vector farg3, N_Vector farg4, double const *farg5, int const *farg6, void *farg7) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - N_Vector arg2 = (N_Vector) 0 ; - N_Vector arg3 = (N_Vector) 0 ; - N_Vector arg4 = (N_Vector) 0 ; - realtype arg5 ; - int arg6 ; - void *arg7 = (void *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (N_Vector)(farg2); - arg3 = (N_Vector)(farg3); - arg4 = (N_Vector)(farg4); - arg5 = (realtype)(*farg5); - arg6 = (int)(*farg6); - arg7 = (void *)(farg7); - result = (int)SUNNonlinSolSolve_Newton(arg1,arg2,arg3,arg4,arg5,arg6,arg7); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolFree_Newton(SUNNonlinearSolver farg1) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - result = (int)SUNNonlinSolFree_Newton(arg1); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetSysFn_Newton(SUNNonlinearSolver farg1, SUNNonlinSolSysFn farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - SUNNonlinSolSysFn arg2 = (SUNNonlinSolSysFn) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (SUNNonlinSolSysFn)(farg2); - result = (int)SUNNonlinSolSetSysFn_Newton(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetLSetupFn_Newton(SUNNonlinearSolver farg1, SUNNonlinSolLSetupFn farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - SUNNonlinSolLSetupFn arg2 = (SUNNonlinSolLSetupFn) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (SUNNonlinSolLSetupFn)(farg2); - result = (int)SUNNonlinSolSetLSetupFn_Newton(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetLSolveFn_Newton(SUNNonlinearSolver farg1, SUNNonlinSolLSolveFn farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - SUNNonlinSolLSolveFn arg2 = (SUNNonlinSolLSolveFn) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (SUNNonlinSolLSolveFn)(farg2); - result = (int)SUNNonlinSolSetLSolveFn_Newton(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetConvTestFn_Newton(SUNNonlinearSolver farg1, SUNNonlinSolConvTestFn farg2, void *farg3) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - SUNNonlinSolConvTestFn arg2 = (SUNNonlinSolConvTestFn) 0 ; - void *arg3 = (void *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (SUNNonlinSolConvTestFn)(farg2); - arg3 = (void *)(farg3); - result = (int)SUNNonlinSolSetConvTestFn_Newton(arg1,arg2,arg3); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetMaxIters_Newton(SUNNonlinearSolver farg1, int const *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - int arg2 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (int)(*farg2); - result = (int)SUNNonlinSolSetMaxIters_Newton(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolGetNumIters_Newton(SUNNonlinearSolver farg1, long *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - long *arg2 = (long *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (long *)(farg2); - result = (int)SUNNonlinSolGetNumIters_Newton(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolGetCurIter_Newton(SUNNonlinearSolver farg1, int *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - int *arg2 = (int *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (int *)(farg2); - result = (int)SUNNonlinSolGetCurIter_Newton(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolGetNumConvFails_Newton(SUNNonlinearSolver farg1, long *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - long *arg2 = (long *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (long *)(farg2); - result = (int)SUNNonlinSolGetNumConvFails_Newton(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolGetSysFn_Newton(SUNNonlinearSolver farg1, void *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - SUNNonlinSolSysFn *arg2 = (SUNNonlinSolSysFn *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (SUNNonlinSolSysFn *)(farg2); - result = (int)SUNNonlinSolGetSysFn_Newton(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetInfoFile_Newton(SUNNonlinearSolver farg1, void *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - FILE *arg2 = (FILE *) 0 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (FILE *)(farg2); - result = (int)SUNNonlinSolSetInfoFile_Newton(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - -SWIGEXPORT int _wrap_FSUNNonlinSolSetPrintLevel_Newton(SUNNonlinearSolver farg1, int const *farg2) { - int fresult ; - SUNNonlinearSolver arg1 = (SUNNonlinearSolver) 0 ; - int arg2 ; - int result; - - arg1 = (SUNNonlinearSolver)(farg1); - arg2 = (int)(*farg2); - result = (int)SUNNonlinSolSetPrintLevel_Newton(arg1,arg2); - fresult = (int)(result); - return fresult; -} - - - diff --git a/ThirdParty/sundials/src/sunnonlinsol/newton/fmod/fsunnonlinsol_newton_mod.f90 b/ThirdParty/sundials/src/sunnonlinsol/newton/fmod/fsunnonlinsol_newton_mod.f90 deleted file mode 100644 index 8d6ab88250..0000000000 --- a/ThirdParty/sundials/src/sunnonlinsol/newton/fmod/fsunnonlinsol_newton_mod.f90 +++ /dev/null @@ -1,491 +0,0 @@ -! This file was automatically generated by SWIG (http://www.swig.org). -! Version 4.0.0 -! -! Do not make changes to this file unless you know what you are doing--modify -! the SWIG interface file instead. - -! --------------------------------------------------------------- -! Programmer(s): Auto-generated by swig. -! --------------------------------------------------------------- -! SUNDIALS Copyright Start -! Copyright (c) 2002-2021, Lawrence Livermore National Security -! and Southern Methodist University. -! All rights reserved. -! -! See the top-level LICENSE and NOTICE files for details. -! -! SPDX-License-Identifier: BSD-3-Clause -! SUNDIALS Copyright End -! --------------------------------------------------------------- - -module fsunnonlinsol_newton_mod - use, intrinsic :: ISO_C_BINDING - use fsundials_nvector_mod - use fsundials_types_mod - use fsundials_nonlinearsolver_mod - use fsundials_nvector_mod - use fsundials_types_mod - implicit none - private - - ! DECLARATION CONSTRUCTS - public :: FSUNNonlinSol_Newton - public :: FSUNNonlinSol_NewtonSens - public :: FSUNNonlinSolGetType_Newton - public :: FSUNNonlinSolInitialize_Newton - public :: FSUNNonlinSolSolve_Newton - public :: FSUNNonlinSolFree_Newton - public :: FSUNNonlinSolSetSysFn_Newton - public :: FSUNNonlinSolSetLSetupFn_Newton - public :: FSUNNonlinSolSetLSolveFn_Newton - public :: FSUNNonlinSolSetConvTestFn_Newton - public :: FSUNNonlinSolSetMaxIters_Newton - public :: FSUNNonlinSolGetNumIters_Newton - public :: FSUNNonlinSolGetCurIter_Newton - public :: FSUNNonlinSolGetNumConvFails_Newton - public :: FSUNNonlinSolGetSysFn_Newton - public :: FSUNNonlinSolSetInfoFile_Newton - public :: FSUNNonlinSolSetPrintLevel_Newton - -! WRAPPER DECLARATIONS -interface -function swigc_FSUNNonlinSol_Newton(farg1) & -bind(C, name="_wrap_FSUNNonlinSol_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR) :: fresult -end function - -function swigc_FSUNNonlinSol_NewtonSens(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSol_NewtonSens") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -integer(C_INT), intent(in) :: farg1 -type(C_PTR), value :: farg2 -type(C_PTR) :: fresult -end function - -function swigc_FSUNNonlinSolGetType_Newton(farg1) & -bind(C, name="_wrap_FSUNNonlinSolGetType_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolInitialize_Newton(farg1) & -bind(C, name="_wrap_FSUNNonlinSolInitialize_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSolve_Newton(farg1, farg2, farg3, farg4, farg5, farg6, farg7) & -bind(C, name="_wrap_FSUNNonlinSolSolve_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -type(C_PTR), value :: farg3 -type(C_PTR), value :: farg4 -real(C_DOUBLE), intent(in) :: farg5 -integer(C_INT), intent(in) :: farg6 -type(C_PTR), value :: farg7 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolFree_Newton(farg1) & -bind(C, name="_wrap_FSUNNonlinSolFree_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetSysFn_Newton(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetSysFn_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_FUNPTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetLSetupFn_Newton(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetLSetupFn_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_FUNPTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetLSolveFn_Newton(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetLSolveFn_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_FUNPTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetConvTestFn_Newton(farg1, farg2, farg3) & -bind(C, name="_wrap_FSUNNonlinSolSetConvTestFn_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_FUNPTR), value :: farg2 -type(C_PTR), value :: farg3 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetMaxIters_Newton(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetMaxIters_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT), intent(in) :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolGetNumIters_Newton(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolGetNumIters_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolGetCurIter_Newton(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolGetCurIter_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolGetNumConvFails_Newton(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolGetNumConvFails_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolGetSysFn_Newton(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolGetSysFn_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetInfoFile_Newton(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetInfoFile_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -type(C_PTR), value :: farg2 -integer(C_INT) :: fresult -end function - -function swigc_FSUNNonlinSolSetPrintLevel_Newton(farg1, farg2) & -bind(C, name="_wrap_FSUNNonlinSolSetPrintLevel_Newton") & -result(fresult) -use, intrinsic :: ISO_C_BINDING -type(C_PTR), value :: farg1 -integer(C_INT), intent(in) :: farg2 -integer(C_INT) :: fresult -end function - -end interface - - -contains - ! MODULE SUBPROGRAMS -function FSUNNonlinSol_Newton(y) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -type(SUNNonlinearSolver), pointer :: swig_result -type(N_Vector), target, intent(inout) :: y -type(C_PTR) :: fresult -type(C_PTR) :: farg1 - -farg1 = c_loc(y) -fresult = swigc_FSUNNonlinSol_Newton(farg1) -call c_f_pointer(fresult, swig_result) -end function - -function FSUNNonlinSol_NewtonSens(count, y) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -type(SUNNonlinearSolver), pointer :: swig_result -integer(C_INT), intent(in) :: count -type(N_Vector), target, intent(inout) :: y -type(C_PTR) :: fresult -integer(C_INT) :: farg1 -type(C_PTR) :: farg2 - -farg1 = count -farg2 = c_loc(y) -fresult = swigc_FSUNNonlinSol_NewtonSens(farg1, farg2) -call c_f_pointer(fresult, swig_result) -end function - -function FSUNNonlinSolGetType_Newton(nls) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(SUNNonlinearSolver_Type) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT) :: fresult -type(C_PTR) :: farg1 - -farg1 = c_loc(nls) -fresult = swigc_FSUNNonlinSolGetType_Newton(farg1) -swig_result = fresult -end function - -function FSUNNonlinSolInitialize_Newton(nls) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT) :: fresult -type(C_PTR) :: farg1 - -farg1 = c_loc(nls) -fresult = swigc_FSUNNonlinSolInitialize_Newton(farg1) -swig_result = fresult -end function - -function FSUNNonlinSolSolve_Newton(nls, y0, y, w, tol, calllsetup, mem) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(N_Vector), target, intent(inout) :: y0 -type(N_Vector), target, intent(inout) :: y -type(N_Vector), target, intent(inout) :: w -real(C_DOUBLE), intent(in) :: tol -integer(C_INT), intent(in) :: calllsetup -type(C_PTR) :: mem -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 -type(C_PTR) :: farg3 -type(C_PTR) :: farg4 -real(C_DOUBLE) :: farg5 -integer(C_INT) :: farg6 -type(C_PTR) :: farg7 - -farg1 = c_loc(nls) -farg2 = c_loc(y0) -farg3 = c_loc(y) -farg4 = c_loc(w) -farg5 = tol -farg6 = calllsetup -farg7 = mem -fresult = swigc_FSUNNonlinSolSolve_Newton(farg1, farg2, farg3, farg4, farg5, farg6, farg7) -swig_result = fresult -end function - -function FSUNNonlinSolFree_Newton(nls) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT) :: fresult -type(C_PTR) :: farg1 - -farg1 = c_loc(nls) -fresult = swigc_FSUNNonlinSolFree_Newton(farg1) -swig_result = fresult -end function - -function FSUNNonlinSolSetSysFn_Newton(nls, sysfn) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(C_FUNPTR), intent(in), value :: sysfn -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_FUNPTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = sysfn -fresult = swigc_FSUNNonlinSolSetSysFn_Newton(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolSetLSetupFn_Newton(nls, lsetupfn) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(C_FUNPTR), intent(in), value :: lsetupfn -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_FUNPTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = lsetupfn -fresult = swigc_FSUNNonlinSolSetLSetupFn_Newton(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolSetLSolveFn_Newton(nls, lsolvefn) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(C_FUNPTR), intent(in), value :: lsolvefn -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_FUNPTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = lsolvefn -fresult = swigc_FSUNNonlinSolSetLSolveFn_Newton(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolSetConvTestFn_Newton(nls, ctestfn, ctest_data) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(C_FUNPTR), intent(in), value :: ctestfn -type(C_PTR) :: ctest_data -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_FUNPTR) :: farg2 -type(C_PTR) :: farg3 - -farg1 = c_loc(nls) -farg2 = ctestfn -farg3 = ctest_data -fresult = swigc_FSUNNonlinSolSetConvTestFn_Newton(farg1, farg2, farg3) -swig_result = fresult -end function - -function FSUNNonlinSolSetMaxIters_Newton(nls, maxiters) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT), intent(in) :: maxiters -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -integer(C_INT) :: farg2 - -farg1 = c_loc(nls) -farg2 = maxiters -fresult = swigc_FSUNNonlinSolSetMaxIters_Newton(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolGetNumIters_Newton(nls, niters) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_LONG), dimension(*), target, intent(inout) :: niters -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = c_loc(niters(1)) -fresult = swigc_FSUNNonlinSolGetNumIters_Newton(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolGetCurIter_Newton(nls, iter) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT), dimension(*), target, intent(inout) :: iter -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = c_loc(iter(1)) -fresult = swigc_FSUNNonlinSolGetCurIter_Newton(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolGetNumConvFails_Newton(nls, nconvfails) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_LONG), dimension(*), target, intent(inout) :: nconvfails -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = c_loc(nconvfails(1)) -fresult = swigc_FSUNNonlinSolGetNumConvFails_Newton(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolGetSysFn_Newton(nls, sysfn) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(C_FUNPTR), target, intent(inout) :: sysfn -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = c_loc(sysfn) -fresult = swigc_FSUNNonlinSolGetSysFn_Newton(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolSetInfoFile_Newton(nls, info_file) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -type(C_PTR) :: info_file -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -type(C_PTR) :: farg2 - -farg1 = c_loc(nls) -farg2 = info_file -fresult = swigc_FSUNNonlinSolSetInfoFile_Newton(farg1, farg2) -swig_result = fresult -end function - -function FSUNNonlinSolSetPrintLevel_Newton(nls, print_level) & -result(swig_result) -use, intrinsic :: ISO_C_BINDING -integer(C_INT) :: swig_result -type(SUNNonlinearSolver), target, intent(inout) :: nls -integer(C_INT), intent(in) :: print_level -integer(C_INT) :: fresult -type(C_PTR) :: farg1 -integer(C_INT) :: farg2 - -farg1 = c_loc(nls) -farg2 = print_level -fresult = swigc_FSUNNonlinSolSetPrintLevel_Newton(farg1, farg2) -swig_result = fresult -end function - - -end module From 61eb4ffd523ffad8d7cc0c6a392dccbb07377cb5 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Wed, 9 Mar 2022 16:34:48 +0100 Subject: [PATCH 19/45] Revert "Model import: Get rid of multiplications with 1.0 (#1681)" (#1697) This reverts commit 5e750654c76c5f574d1bb4a0803bf17f9ef549ef. For larger models, this just takes too long (~30min exta for https://github.com/ICB-DCM/CS_Signalling_ERBB_RAS_AKT/tree/master/FroehlichKes2018/PEtab). --- python/amici/ode_export.py | 9 +++------ python/amici/sbml_import.py | 3 +-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/python/amici/ode_export.py b/python/amici/ode_export.py index 863c9c9be3..82bb4df058 100644 --- a/python/amici/ode_export.py +++ b/python/amici/ode_export.py @@ -982,12 +982,9 @@ class ODEModel: Code printer to generate C++ code """ - def __init__( - self, verbose: Optional[Union[bool, int]] = False, - simplify: Optional[Callable] - = lambda x: sp.powsimp(x, deep=True).subs(1.0, 1), - cache_simplify: bool = False - ): + def __init__(self, verbose: Optional[Union[bool, int]] = False, + simplify: Optional[Callable] = sp.powsimp, + cache_simplify: bool = False): """ Create a new ODEModel instance. diff --git a/python/amici/sbml_import.py b/python/amici/sbml_import.py index 45d8444d0f..b54865d363 100644 --- a/python/amici/sbml_import.py +++ b/python/amici/sbml_import.py @@ -217,8 +217,7 @@ def sbml2amici(self, allow_reinit_fixpar_initcond: bool = True, compile: bool = True, compute_conservation_laws: bool = True, - simplify: Callable = lambda x: - sp.powsimp(x, deep=True).subs(1.0, 1), + simplify: Callable = lambda x: sp.powsimp(x, deep=True), cache_simplify: bool = False, log_as_log10: bool = True, generate_sensitivity_code: bool = True, From e02699a94ca01873c056c1a9165b7753cebf5cdf Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Wed, 9 Mar 2022 21:55:59 +0100 Subject: [PATCH 20/45] Refactor: Move swig wrappers out of __init__.py (#1696) Closes #1215. Will also make it easier to reuse those wrappers for #1119 --- python/amici/__init__.py | 220 +-------------------------- python/amici/swig_wrappers.py | 226 ++++++++++++++++++++++++++++ python/sdist/amici/swig_wrappers.py | 1 + python/tests/test_swig_interface.py | 16 +- 4 files changed, 243 insertions(+), 220 deletions(-) create mode 100644 python/amici/swig_wrappers.py create mode 120000 python/sdist/amici/swig_wrappers.py diff --git a/python/amici/__init__.py b/python/amici/__init__.py index 40d6966420..2a54c60c1c 100644 --- a/python/amici/__init__.py +++ b/python/amici/__init__.py @@ -24,9 +24,8 @@ import os import re import sys -from contextlib import suppress, contextmanager from types import ModuleType as ModelModule -from typing import Any, Dict, Optional, Union, Sequence, List +from typing import Optional def _get_amici_path(): @@ -81,23 +80,6 @@ def _imported_from_setup() -> bool: return False -try: - from wurlitzer import sys_pipes -except ModuleNotFoundError: - sys_pipes = suppress - - -@contextmanager -def _capture_cstdout(): - """Redirect C/C++ stdout to python stdout if python stdout is redirected, - e.g. in ipython notebook""" - if sys.stdout == sys.__stdout__: - yield - else: - with sys_pipes(): - yield - - # Initialize AMICI paths amici_path = _get_amici_path() amiciSwigPath = os.path.join(amici_path, 'swig') @@ -106,12 +88,7 @@ def _capture_cstdout(): has_clibs = any([os.path.isfile(os.path.join(amici_path, wrapper)) for wrapper in ['amici.py', 'amici_without_hdf5.py']]) - -AmiciModel = Union['amici.Model', 'amici.ModelPtr'] -AmiciSolver = Union['amici.Solver', 'amici.SolverPtr'] -AmiciExpData = Union['amici.ExpData', 'amici.ExpDataPtr'] -AmiciReturnData = Union['amici.ReturnData', 'amici.ReturnDataPtr'] -AmiciExpDataVector = Union['amici.ExpDataPtrVector', Sequence[AmiciExpData]] +hdf5_enabled = False # Get version number from file with open(os.path.join(amici_path, 'version.txt')) as f: @@ -124,8 +101,12 @@ def _capture_cstdout(): if has_clibs: from . import amici from .amici import * + # has to be done before importing readSolverSettingsFromHDF5 + # from .swig_wrappers + hdf5_enabled = 'readSolverSettingsFromHDF5' in dir() + from .swig_wrappers import * - # These module require the swig interface and other dependencies + # These modules require the swig interface and other dependencies from .numpy import ReturnDataView, ExpDataView from .pandas import * @@ -145,193 +126,6 @@ def getModel(self) -> amici.Model: except ImportError: pass -hdf5_enabled = 'readSolverSettingsFromHDF5' in dir() - - -def _get_ptr(obj: Union[AmiciModel, AmiciExpData, AmiciSolver, AmiciReturnData] - ) -> Union['amici.Model', 'amici.ExpData', 'amici.Solver', - 'amici.ReturnData']: - """ - Convenience wrapper that returns the smart pointer pointee, if applicable - - :param obj: - Potential smart pointer - - :returns: - Non-smart pointer - """ - if isinstance(obj, (amici.ModelPtr, amici.ExpDataPtr, amici.SolverPtr, - amici.ReturnDataPtr)): - return obj.get() - return obj - - -def runAmiciSimulation( - model: AmiciModel, - solver: AmiciSolver, - edata: Optional[AmiciExpData] = None -) -> 'numpy.ReturnDataView': - """ - Convenience wrapper around :py:func:`amici.amici.runAmiciSimulation` - (generated by swig) - - :param model: - Model instance - -` :param solver: - Solver instance, must be generated from - :py:meth:`amici.amici.Model.getSolver` - - :param edata: - ExpData instance (optional) - - :returns: - ReturnData object with simulation results - """ - with _capture_cstdout(): - rdata = amici.runAmiciSimulation(_get_ptr(solver), _get_ptr(edata), - _get_ptr(model)) - return numpy.ReturnDataView(rdata) - - -def ExpData(*args) -> 'amici.ExpData': - """ - Convenience wrapper for :py:class:`amici.amici.ExpData` constructors - - :param args: arguments - - :returns: ExpData Instance - """ - if isinstance(args[0], ReturnDataView): - return amici.ExpData(_get_ptr(args[0]['ptr']), *args[1:]) - elif isinstance(args[0], (amici.ExpData, amici.ExpDataPtr)): - # the *args[:1] should be empty, but by the time you read this, - # the constructor signature may have changed and you are glad this - # wrapper did not break. - return amici.ExpData(_get_ptr(args[0]), *args[1:]) - elif isinstance(args[0], (amici.Model, amici.ModelPtr)): - return amici.ExpData(_get_ptr(args[0])) - else: - return amici.ExpData(*args) - - -def runAmiciSimulations( - model: AmiciModel, - solver: AmiciSolver, - edata_list: AmiciExpDataVector, - failfast: bool = True, - num_threads: int = 1, -) -> List['numpy.ReturnDataView']: - """ - Convenience wrapper for loops of amici.runAmiciSimulation - - :param model: Model instance - :param solver: Solver instance, must be generated from Model.getSolver() - :param edata_list: list of ExpData instances - :param failfast: returns as soon as an integration failure is encountered - :param num_threads: number of threads to use (only used if compiled - with openmp) - - :returns: list of simulation results - """ - with _capture_cstdout(): - edata_ptr_vector = amici.ExpDataPtrVector(edata_list) - rdata_ptr_list = amici.runAmiciSimulations(_get_ptr(solver), - edata_ptr_vector, - _get_ptr(model), - failfast, - num_threads) - return [numpy.ReturnDataView(r) for r in rdata_ptr_list] - - -def readSolverSettingsFromHDF5( - file: str, - solver: AmiciSolver, - location: Optional[str] = 'solverSettings' -) -> None: - """ - Convenience wrapper for :py:func:`amici.readSolverSettingsFromHDF5` - - :param file: hdf5 filename - :param solver: Solver instance to which settings will be transferred - :param location: location of solver settings in hdf5 file - """ - amici.readSolverSettingsFromHDF5(file, _get_ptr(solver), location) - - -def writeSolverSettingsToHDF5( - solver: AmiciSolver, - file: Union[str, object], - location: Optional[str] = 'solverSettings' -) -> None: - """ - Convenience wrapper for :py:func:`amici.amici.writeSolverSettingsToHDF5` - - :param file: hdf5 filename, can also be object created by - :py:func:`amici.amici.createOrOpenForWriting` - :param solver: Solver instance from which settings will stored - :param location: location of solver settings in hdf5 file - """ - amici.writeSolverSettingsToHDF5(_get_ptr(solver), file, location) - - -# Values are suffixes of `get[...]` and `set[...]` `amici.Model` methods. -# If either the getter or setter is not named with this pattern, then the value -# is a tuple where the first and second elements are the getter and setter -# methods, respectively. -model_instance_settings = [ - 'AddSigmaResiduals', - 'AlwaysCheckFinite', - 'FixedParameters', - 'InitialStates', - 'InitialStateSensitivities', - 'MinimumSigmaResiduals', - ('nMaxEvent', 'setNMaxEvent'), - 'Parameters', - 'ParameterList', - 'ParameterScale', # getter returns a SWIG object - 'ReinitializationStateIdxs', - 'ReinitializeFixedParameterInitialStates', - 'StateIsNonNegative', - 'SteadyStateSensitivityMode', - ('t0', 'setT0'), - 'Timepoints', -] - - -def get_model_settings( - model: AmiciModel, -) -> Dict[str, Any]: - """Get model settings that are set independently of the compiled model. - - :param model: The AMICI model instance. - - :returns: Keys are AMICI model attributes, values are attribute values. - """ - settings = {} - for setting in model_instance_settings: - getter = setting[0] if isinstance(setting, tuple) else f'get{setting}' - settings[setting] = getattr(model, getter)() - # TODO `amici.Model.getParameterScale` returns a SWIG object instead - # of a Python list/tuple. - if setting == 'ParameterScale': - settings[setting] = tuple(settings[setting]) - return settings - - -def set_model_settings( - model: AmiciModel, - settings: Dict[str, Any], -) -> None: - """Set model settings. - - :param model: The AMICI model instance. - :param settings: Keys are callable attributes (setters) of an AMICI model, - values are provided to the setters. - """ - for setting, value in settings.items(): - setter = setting[1] if isinstance(setting, tuple) else f'set{setting}' - getattr(model, setter)(value) class add_path: diff --git a/python/amici/swig_wrappers.py b/python/amici/swig_wrappers.py new file mode 100644 index 0000000000..77008a3e31 --- /dev/null +++ b/python/amici/swig_wrappers.py @@ -0,0 +1,226 @@ +"""Convenience wrappers for the swig interface""" +import sys +from contextlib import contextmanager, suppress +from typing import List, Optional, Union, Sequence, Dict, Any +import amici.amici as amici_swig +from . import numpy + +__all__ = [ + 'runAmiciSimulation', 'runAmiciSimulations', 'ExpData', + 'readSolverSettingsFromHDF5', 'writeSolverSettingsToHDF5', + 'set_model_settings', 'get_model_settings', + 'AmiciModel', 'AmiciSolver', 'AmiciExpData', 'AmiciReturnData', + 'AmiciExpDataVector' +] + +AmiciModel = Union['amici.Model', 'amici.ModelPtr'] +AmiciSolver = Union['amici.Solver', 'amici.SolverPtr'] +AmiciExpData = Union['amici.ExpData', 'amici.ExpDataPtr'] +AmiciReturnData = Union['amici.ReturnData', 'amici.ReturnDataPtr'] +AmiciExpDataVector = Union['amici.ExpDataPtrVector', Sequence[AmiciExpData]] + + +try: + from wurlitzer import sys_pipes +except ModuleNotFoundError: + sys_pipes = suppress + + +@contextmanager +def _capture_cstdout(): + """Redirect C/C++ stdout to python stdout if python stdout is redirected, + e.g. in ipython notebook""" + if sys.stdout == sys.__stdout__: + yield + else: + with sys_pipes(): + yield + + +def _get_ptr( + obj: Union[AmiciModel, AmiciExpData, AmiciSolver, AmiciReturnData] +) -> Union['amici_swig.Model', 'amici_swig.ExpData', + 'amici_swig.Solver', 'amici_swig.ReturnData']: + """ + Convenience wrapper that returns the smart pointer pointee, if applicable + + :param obj: + Potential smart pointer + + :returns: + Non-smart pointer + """ + if isinstance(obj, (amici_swig.ModelPtr, amici_swig.ExpDataPtr, + amici_swig.SolverPtr, amici_swig.ReturnDataPtr)): + return obj.get() + return obj + + +def runAmiciSimulation( + model: AmiciModel, + solver: AmiciSolver, + edata: Optional[AmiciExpData] = None +) -> 'numpy.ReturnDataView': + """ + Convenience wrapper around :py:func:`amici.amici.runAmiciSimulation` + (generated by swig) + + :param model: + Model instance + +` :param solver: + Solver instance, must be generated from + :py:meth:`amici.amici.Model.getSolver` + + :param edata: + ExpData instance (optional) + + :returns: + ReturnData object with simulation results + """ + with _capture_cstdout(): + rdata = amici_swig.runAmiciSimulation( + _get_ptr(solver), _get_ptr(edata), _get_ptr(model)) + return numpy.ReturnDataView(rdata) + + +def ExpData(*args) -> 'amici_swig.ExpData': + """ + Convenience wrapper for :py:class:`amici.amici.ExpData` constructors + + :param args: arguments + + :returns: ExpData Instance + """ + if isinstance(args[0], numpy.ReturnDataView): + return amici_swig.ExpData(_get_ptr(args[0]['ptr']), *args[1:]) + elif isinstance(args[0], (amici_swig.ExpData, amici_swig.ExpDataPtr)): + # the *args[:1] should be empty, but by the time you read this, + # the constructor signature may have changed, and you are glad this + # wrapper did not break. + return amici_swig.ExpData(_get_ptr(args[0]), *args[1:]) + elif isinstance(args[0], (amici_swig.Model, amici_swig.ModelPtr)): + return amici_swig.ExpData(_get_ptr(args[0])) + else: + return amici_swig.ExpData(*args) + + +def runAmiciSimulations( + model: AmiciModel, + solver: AmiciSolver, + edata_list: AmiciExpDataVector, + failfast: bool = True, + num_threads: int = 1, +) -> List['numpy.ReturnDataView']: + """ + Convenience wrapper for loops of amici.runAmiciSimulation + + :param model: Model instance + :param solver: Solver instance, must be generated from Model.getSolver() + :param edata_list: list of ExpData instances + :param failfast: returns as soon as an integration failure is encountered + :param num_threads: number of threads to use (only used if compiled + with openmp) + + :returns: list of simulation results + """ + with _capture_cstdout(): + edata_ptr_vector = amici_swig.ExpDataPtrVector(edata_list) + rdata_ptr_list = amici_swig.runAmiciSimulations( + _get_ptr(solver), + edata_ptr_vector, + _get_ptr(model), + failfast, + num_threads + ) + return [numpy.ReturnDataView(r) for r in rdata_ptr_list] + + +def readSolverSettingsFromHDF5( + file: str, + solver: AmiciSolver, + location: Optional[str] = 'solverSettings' +) -> None: + """ + Convenience wrapper for :py:func:`amici.readSolverSettingsFromHDF5` + + :param file: hdf5 filename + :param solver: Solver instance to which settings will be transferred + :param location: location of solver settings in hdf5 file + """ + amici_swig.readSolverSettingsFromHDF5(file, _get_ptr(solver), location) + + +def writeSolverSettingsToHDF5( + solver: AmiciSolver, + file: Union[str, object], + location: Optional[str] = 'solverSettings' +) -> None: + """ + Convenience wrapper for :py:func:`amici.amici.writeSolverSettingsToHDF5` + + :param file: hdf5 filename, can also be an object created by + :py:func:`amici.amici.createOrOpenForWriting` + :param solver: Solver instance from which settings will be stored + :param location: location of solver settings in hdf5 file + """ + amici_swig.writeSolverSettingsToHDF5(_get_ptr(solver), file, location) + + +# Values are suffixes of `get[...]` and `set[...]` `amici.Model` methods. +# If either the getter or setter is not named with this pattern, then the value +# is a tuple where the first and second elements are the getter and setter +# methods, respectively. +model_instance_settings = [ + 'AddSigmaResiduals', + 'AlwaysCheckFinite', + 'FixedParameters', + 'InitialStates', + 'InitialStateSensitivities', + 'MinimumSigmaResiduals', + ('nMaxEvent', 'setNMaxEvent'), + 'Parameters', + 'ParameterList', + 'ParameterScale', # getter returns a SWIG object + 'ReinitializationStateIdxs', + 'ReinitializeFixedParameterInitialStates', + 'StateIsNonNegative', + 'SteadyStateSensitivityMode', + ('t0', 'setT0'), + 'Timepoints', +] + + +def get_model_settings( + model: AmiciModel, +) -> Dict[str, Any]: + """Get model settings that are set independently of the compiled model. + + :param model: The AMICI model instance. + + :returns: Keys are AMICI model attributes, values are attribute values. + """ + settings = {} + for setting in model_instance_settings: + getter = setting[0] if isinstance(setting, tuple) else f'get{setting}' + settings[setting] = getattr(model, getter)() + # TODO `amici.Model.getParameterScale` returns a SWIG object instead + # of a Python list/tuple. + if setting == 'ParameterScale': + settings[setting] = tuple(settings[setting]) + return settings + + +def set_model_settings( + model: AmiciModel, + settings: Dict[str, Any], +) -> None: + """Set model settings. + + :param model: The AMICI model instance. + :param settings: Keys are callable attributes (setters) of an AMICI model, + values are provided to the setters. + """ + for setting, value in settings.items(): + setter = setting[1] if isinstance(setting, tuple) else f'set{setting}' + getattr(model, setter)(value) diff --git a/python/sdist/amici/swig_wrappers.py b/python/sdist/amici/swig_wrappers.py new file mode 120000 index 0000000000..83af20e099 --- /dev/null +++ b/python/sdist/amici/swig_wrappers.py @@ -0,0 +1 @@ +../../amici/swig_wrappers.py \ No newline at end of file diff --git a/python/tests/test_swig_interface.py b/python/tests/test_swig_interface.py index 2958539b46..63b0ae0aff 100644 --- a/python/tests/test_swig_interface.py +++ b/python/tests/test_swig_interface.py @@ -129,18 +129,20 @@ def test_model_instance_settings(pysb_example_presimulation_module): i_setter = 1 # All settings are tested. - assert set(model_instance_settings0) == set(amici.model_instance_settings) + assert set(model_instance_settings0) \ + == set(amici.swig_wrappers.model_instance_settings) # Skip settings with interdependencies. model_instance_settings = \ {k: v for k, v in model_instance_settings0.items() if v is not None} # All custom values are different to default values. - assert all([ + assert all( default != custom for name, (default, custom) in model_instance_settings.items() if name != 'ReinitializeFixedParameterInitialStates' - ]) + ) + # All default values are as expected. for name, (default, custom) in model_instance_settings.items(): @@ -173,11 +175,11 @@ def test_model_instance_settings(pysb_example_presimulation_module): if model_instance_settings0[name] is not None } amici.set_model_settings(model, custom_settings_not_none) - assert all([ + assert all( value == custom_settings_not_none[name] for name, value in amici.get_model_settings(model).items() if name in custom_settings_not_none - ]) + ) def test_interdependent_settings(pysb_example_presimulation_module): @@ -299,10 +301,10 @@ def test_unhandled_settings(pysb_example_presimulation_module): 'setParametersByNameRegex', 'setUnscaledInitialStateSensitivities', ] - + from amici.swig_wrappers import model_instance_settings handled = [ name - for names in amici.model_instance_settings + for names in model_instance_settings for name in ( names if isinstance(names, tuple) else From 2db5e8505a662f40600e10f5c96bc437c3983518 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Wed, 9 Mar 2022 21:56:47 +0100 Subject: [PATCH 21/45] Use sympy `x.has(y)` instead of `y in x.free_symbols` (#1699) Significantly faster for larger matrices. --- python/amici/import_utils.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/python/amici/import_utils.py b/python/amici/import_utils.py index c5510a3306..d2f778456e 100644 --- a/python/amici/import_utils.py +++ b/python/amici/import_utils.py @@ -252,7 +252,7 @@ def smart_subs_dict(sym: sp.Expr, for substitution in s: # note that substitution may change free symbols, so we have to do # this recursively - if substitution[0] in sym.free_symbols: + if sym.has(substitution[0]): sym = sym.subs(*substitution) return sym @@ -273,11 +273,7 @@ def smart_subs(element: sp.Expr, old: sp.Symbol, new: sp.Expr) -> sp.Expr: :return: substituted expression """ - - if old in element.free_symbols: - return element.subs(old, new) - - return element + return element.subs(old, new) if element.has(old) else element def toposort_symbols(symbols: SymbolDef, From 576c1f8f078f796f0832b960138f0eaad2b15ed7 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Wed, 9 Mar 2022 21:57:14 +0100 Subject: [PATCH 22/45] Don't repeat the same matrix multiplication (#1700) ... instead save intermediate result --- python/amici/ode_export.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/python/amici/ode_export.py b/python/amici/ode_export.py index 82bb4df058..43b0a847b2 100644 --- a/python/amici/ode_export.py +++ b/python/amici/ode_export.py @@ -2189,12 +2189,13 @@ def _total_derivative(self, name: str, eq: str, chainvars: List[str], # which is not checked for by sympy if not smart_is_zero_matrix(dydx) and not \ smart_is_zero_matrix(dxdz): + dydx_times_dxdz = smart_multiply(dydx, dxdz) if dxdz.shape[1] == 1 and \ self._eqs[name].shape[1] != dxdz.shape[1]: for iz in range(self._eqs[name].shape[1]): - self._eqs[name][:, iz] += smart_multiply(dydx, dxdz) + self._eqs[name][:, iz] += dydx_times_dxdz else: - self._eqs[name] += smart_multiply(dydx, dxdz) + self._eqs[name] += dydx_times_dxdz def sym_or_eq(self, name: str, varname: str) -> sp.Matrix: """ From 8d88ccc5ac2b78a4ab189bfe4e65535393e4e6e0 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Wed, 9 Mar 2022 23:05:05 +0100 Subject: [PATCH 23/45] Fix outdated C++/Python minimum versions (#1704) --- documentation/development.rst | 4 ++-- python/amici/setup.template.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/development.rst b/documentation/development.rst index 2b6bd563e8..b26980ceda 100644 --- a/documentation/development.rst +++ b/documentation/development.rst @@ -56,7 +56,7 @@ process described below: - Run ``scripts/run-doxygen.sh`` to check completeness of your documentation -- Make sure your code is compatible with C++11, ``gcc`` and ``clang`` +- Make sure your code is compatible with C++14, ``gcc`` and ``clang`` (our CI pipeline will do this for you) - When adding new functionality, please also provide test cases (see @@ -99,7 +99,7 @@ General Python ^^^^^^ -- We want to be compatible with Python 3.7 +- We want to be compatible with Python 3.8 - For the Python code we want to follow `PEP8 `__. Although this diff --git a/python/amici/setup.template.py b/python/amici/setup.template.py index 688b29f400..06bfbe4e4d 100644 --- a/python/amici/setup.template.py +++ b/python/amici/setup.template.py @@ -170,7 +170,7 @@ def get_extension() -> Extension: packages=find_packages(), install_requires=['amici==TPL_AMICI_VERSION'], extras_require={'wurlitzer': ['wurlitzer']}, - python_requires='>=3.7', + python_requires='>=3.8', package_data={}, zip_safe=False, include_package_data=True, From db89d384a360f01fffb4b74eb7b53c61c1d2bde0 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Thu, 10 Mar 2022 16:58:53 +0100 Subject: [PATCH 24/45] Skip time-sensitive tests when running valgrind (#1702) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fabian Fröhlich --- .github/workflows/test_valgrind.yml | 2 +- python/tests/test_conserved_moieties.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test_valgrind.yml b/.github/workflows/test_valgrind.yml index 17b39b5a24..ce45a842aa 100644 --- a/.github/workflows/test_valgrind.yml +++ b/.github/workflows/test_valgrind.yml @@ -10,7 +10,7 @@ on: workflow_dispatch: jobs: - build: + valgrind: name: Tests Valgrind # TODO: prepare image with more deps preinstalled diff --git a/python/tests/test_conserved_moieties.py b/python/tests/test_conserved_moieties.py index 9a7b2c811a..e7b06830c8 100644 --- a/python/tests/test_conserved_moieties.py +++ b/python/tests/test_conserved_moieties.py @@ -209,6 +209,9 @@ def test_compute_moiety_conservation_laws_demartino2014( return runtime +@pytest.mark.skipif( + os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Performance test under valgrind is not meaningful.") @log_execution_time("Detecting moiety conservation laws", logger) def test_cl_detect_execution_time(data_demartino2014): """Test execution time stays within a certain predefined bound. From b81d3e5a15e81d55f25a4cea078d855e37ffa4df Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Thu, 10 Mar 2022 16:59:16 +0100 Subject: [PATCH 25/45] CI: Run valgrind on debugging build (#1701) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fabian Fröhlich --- .github/workflows/test_valgrind.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/test_valgrind.yml b/.github/workflows/test_valgrind.yml index ce45a842aa..5e63d84ee9 100644 --- a/.github/workflows/test_valgrind.yml +++ b/.github/workflows/test_valgrind.yml @@ -20,6 +20,9 @@ jobs: matrix: python-version: [ 3.8 ] + env: + ENABLE_AMICI_DEBUGGING: "TRUE" + steps: - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 From a131bef1dbb4fbb98566157e8c0e1cc517cc4d87 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Thu, 10 Mar 2022 17:00:32 +0100 Subject: [PATCH 26/45] Fix fdsigmaydy (#1703) * Fix vector size / out-of-bounds access in fdsigmaydy * oops * doc --- include/amici/abstract_model.h | 3 +-- python/amici/ode_export.py | 2 +- src/abstract_model.cpp | 3 +-- src/model.cpp | 22 ++++++++++------------ 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/include/amici/abstract_model.h b/include/amici/abstract_model.h index d333fab1d0..3fb945d831 100644 --- a/include/amici/abstract_model.h +++ b/include/amici/abstract_model.h @@ -586,11 +586,10 @@ class AbstractModel { * @param p parameter vector * @param k constant vector * @param y model output at timepoint t - * @param ip sensitivity index */ virtual void fdsigmaydy(realtype *dsigmaydy, const realtype t, const realtype *p, const realtype *k, - const realtype *y, int ip); + const realtype *y); /** diff --git a/python/amici/ode_export.py b/python/amici/ode_export.py index 43b0a847b2..f824dd29b7 100644 --- a/python/amici/ode_export.py +++ b/python/amici/ode_export.py @@ -172,7 +172,7 @@ class _FunctionInfo: 'dsigmaydy': _FunctionInfo( 'realtype *dsigmaydy, const realtype t, const realtype *p, ' - 'const realtype *k, const realtype *y, const int ip', + 'const realtype *k, const realtype *y' ), 'dsigmaydp': _FunctionInfo( diff --git a/src/abstract_model.cpp b/src/abstract_model.cpp index 859b9d8424..8bbb1ebdf8 100644 --- a/src/abstract_model.cpp +++ b/src/abstract_model.cpp @@ -365,8 +365,7 @@ AbstractModel::fdsigmaydy(realtype */*dsigmaydy*/, const realtype /*t*/, const realtype */*p*/, const realtype */*k*/, - const realtype */*y*/, - int /*ip*/) + const realtype */*y*/) { throw AmiException("Requested functionality is not supported as %s is " "not implemented for this model!", diff --git a/src/model.cpp b/src/model.cpp index 2bb2dd6fbb..dc66b815d9 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -1528,24 +1528,22 @@ void Model::fdsigmaydy(const int it, const ExpData *edata) { if (!ny) return; - derived_state_.dsigmaydy_.assign(ny * nplist(), 0.0); + derived_state_.dsigmaydy_.assign(ny * ny, 0.0); - for (int ip = 0; ip < nplist(); ip++) - // get dsigmaydy slice (ny) for current timepoint and parameter - fdsigmaydy(&derived_state_.dsigmaydy_.at(ip * ny), getTimepoint(it), - state_.unscaledParameters.data(), - state_.fixedParameters.data(), - derived_state_.y_.data(), - plist(ip)); + // get dsigmaydy slice (ny) for current timepoint + fdsigmaydy(derived_state_.dsigmaydy_.data(), getTimepoint(it), + state_.unscaledParameters.data(), + state_.fixedParameters.data(), + derived_state_.y_.data()); // sigmas in edata override model-sigma -> for those sigmas, set dsigmaydy // to zero if (edata) { - for (int iy = 0; iy < nytrue; iy++) { - if (!edata->isSetObservedDataStdDev(it, iy)) + for (int isigmay = 0; isigmay < nytrue; ++isigmay) { + if (!edata->isSetObservedDataStdDev(it, isigmay)) continue; - for (int ip = 0; ip < nplist(); ip++) { - derived_state_.dsigmaydy_.at(ip * ny + iy) = 0.0; + for (int iy = 0; iy < nytrue; ++iy) { + derived_state_.dsigmaydy_.at(isigmay * ny + iy) = 0.0; } } } From d63d13e1dcd37e31223e0533fcfdf84961f8ddb7 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Fri, 11 Mar 2022 10:23:54 +0100 Subject: [PATCH 27/45] Remove python3.8 check for ModelModule (#1706) As py3.8 is anyways required by now --- python/amici/__init__.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/python/amici/__init__.py b/python/amici/__init__.py index 2a54c60c1c..9b2d6158cc 100644 --- a/python/amici/__init__.py +++ b/python/amici/__init__.py @@ -114,19 +114,15 @@ def _imported_from_setup() -> bool: from .sbml_import import SbmlImporter, assignmentRules2observables from .ode_export import ODEModel, ODEExporter - try: - # Requires Python>=3.8 - from typing import Protocol - - class ModelModule(Protocol): - """Enable Python static type checking for AMICI-generated model - modules""" - def getModel(self) -> amici.Model: - pass - except ImportError: - pass + from typing import Protocol + class ModelModule(Protocol): + """Enable Python static type checking for AMICI-generated model + modules""" + def getModel(self) -> amici.Model: + pass + class add_path: """Context manager for temporarily changing PYTHONPATH""" From c33dfa318363abc8bf3cf67be0841132bf07ca1d Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Fri, 11 Mar 2022 11:53:26 +0100 Subject: [PATCH 28/45] Fix documentation build / pin nbformat (#1707) --- documentation/rtd_requirements.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/documentation/rtd_requirements.txt b/documentation/rtd_requirements.txt index fcb9061795..d386993726 100644 --- a/documentation/rtd_requirements.txt +++ b/documentation/rtd_requirements.txt @@ -5,6 +5,9 @@ pysb>=1.11.0 matplotlib>=3.4.3 pkgconfig>=1.5.5 nbsphinx>=0.8.7 +# nbformat-5.2.0 fails with: +# Could not import extension nbsphinx (exception: No module named 'ipython_genutils') +nbformat==5.1.3 recommonmark>=0.6.0 sphinx_rtd_theme>=1.0.0 petab>=0.1.20 From 0bbae56c7cae9d4b98241a5eb9dcde267f12ad2d Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Fri, 11 Mar 2022 15:00:35 +0100 Subject: [PATCH 29/45] Refactor ode_export.py (#1705) * Refactor ode_export.py Slim down ode_export.py (>3K loc). Move functions to import_utils.py and create ode_model.py. ODEModel should also go to ode_model.py at some point, but this is too much entangled with pysb/sbml importers and code generation. * fixup --- python/amici/import_utils.py | 107 +++++- python/amici/ode_export.py | 573 ++------------------------------ python/amici/ode_model.py | 469 ++++++++++++++++++++++++++ python/amici/pysb_import.py | 37 +-- python/amici/sbml_import.py | 10 +- python/sdist/amici/ode_model.py | 1 + 6 files changed, 622 insertions(+), 575 deletions(-) create mode 100644 python/amici/ode_model.py create mode 120000 python/sdist/amici/ode_model.py diff --git a/python/amici/import_utils.py b/python/amici/import_utils.py index d2f778456e..93925c519e 100644 --- a/python/amici/import_utils.py +++ b/python/amici/import_utils.py @@ -2,15 +2,21 @@ model format""" import enum import itertools as itt +import numbers import sys -from typing import (Any, Callable, Dict, Iterable, Optional, Sequence, Tuple, - Union) +from typing import (Any, Callable, Dict, Iterable, Optional, Sequence, + SupportsFloat, Tuple, Union) import sympy as sp from sympy.functions.elementary.piecewise import ExprCondPair from sympy.logic.boolalg import BooleanAtom from toposort import toposort +try: + import pysb +except ImportError: + pysb = None + SymbolDef = Dict[sp.Symbol, Union[Dict[str, sp.Expr], sp.Expr]] @@ -560,3 +566,100 @@ def _check_unsupported_functions(sym: sp.Expr, f'{expression_type}: "{full_sym}"!') for arg in list(sym.args): _check_unsupported_functions(arg, expression_type) + + +def cast_to_sym(value: Union[SupportsFloat, sp.Expr, BooleanAtom], + input_name: str) -> sp.Expr: + """ + Typecasts the value to :py:class:`sympy.Float` if possible, and ensures the + value is a symbolic expression. + + :param value: + value to be cast + + :param input_name: + name of input variable + + :return: + typecast value + """ + if isinstance(value, (sp.RealNumber, numbers.Number)): + value = sp.Float(float(value)) + elif isinstance(value, BooleanAtom): + value = sp.Float(float(bool(value))) + + if not isinstance(value, sp.Expr): + raise TypeError(f"Couldn't cast {input_name} to sympy.Expr, was " + f"{type(value)}") + + return value + + +def generate_measurement_symbol(observable_id: Union[str, sp.Symbol]): + """ + Generates the appropriate measurement symbol for the provided observable + + :param observable_id: + symbol (or string representation) of the observable + + :return: + symbol for the corresponding measurement + """ + if not isinstance(observable_id, str): + observable_id = strip_pysb(observable_id) + return symbol_with_assumptions(f'm{observable_id}') + + +def generate_flux_symbol( + reaction_index: int, + name: Optional[str] = None +) -> sp.Symbol: + """ + Generate identifier symbol for a reaction flux. + This function will always return the same unique python object for a + given entity. + + :param reaction_index: + index of the reaction to which the flux corresponds + :param name: + an optional identifier of the reaction to which the flux corresponds + :return: + identifier symbol + """ + if name is not None: + return symbol_with_assumptions(name) + + return symbol_with_assumptions(f'flux_r{reaction_index}') + + +def symbol_with_assumptions(name: str): + """ + Central function to create symbols with consistent, canonical assumptions + + :param name: + name of the symbol + + :return: + symbol with canonical assumptions + """ + return sp.Symbol(name, real=True) + + +def strip_pysb(symbol: sp.Basic) -> sp.Basic: + """ + Strips pysb info from a :class:`pysb.Component` object + + :param symbol: + symbolic expression + + :return: + stripped expression + """ + # strip pysb type and transform into a flat sympy.Symbol. + # this ensures that the pysb type specific __repr__ is used when converting + # to string + if pysb and isinstance(symbol, pysb.Component): + return sp.Symbol(symbol.name, real=True) + else: + # in this case we will use sympy specific transform anyways + return symbol diff --git a/python/amici/ode_export.py b/python/amici/ode_export.py index f824dd29b7..a065a088fc 100644 --- a/python/amici/ode_export.py +++ b/python/amici/ode_export.py @@ -8,44 +8,41 @@ :py:func:`amici.sbml_import.SbmlImporter.sbml2amici` and :py:func:`amici.petab_import.import_model`. """ -import sympy as sp -import numpy as np +import contextlib +import copy +import itertools +import logging +import os import re import shutil import subprocess import sys -import os -import copy -import numbers -import logging -import itertools -import contextlib +from dataclasses import dataclass +from itertools import chain +from string import Template +from typing import (Any, Callable, Dict, List, Optional, Sequence, Set, Tuple, + Union) + +import numpy as np +import sympy as sp +from sympy.matrices.dense import MutableDenseMatrix +from sympy.matrices.immutable import ImmutableDenseMatrix + +from . import (__commit__, __version__, amiciModulePath, amiciSrcPath, + amiciSwigPath, sbml_import) +from .constants import SymbolId +from .cxxcodeprinter import AmiciCxxCodePrinter, get_switch_statement +from .import_utils import (ObservableTransformation, generate_flux_symbol, + smart_subs_dict, strip_pysb, + symbol_with_assumptions, toposort_symbols) +from .logging import get_logger, log_execution_time, set_log_level +from .ode_model import * try: import pysb except ImportError: pysb = None -from typing import ( - Callable, Optional, Union, List, Dict, Tuple, SupportsFloat, Sequence, - Set, Any -) -from dataclasses import dataclass -from string import Template -from sympy.matrices.immutable import ImmutableDenseMatrix -from sympy.matrices.dense import MutableDenseMatrix -from sympy.logic.boolalg import BooleanAtom -from itertools import chain -from .cxxcodeprinter import AmiciCxxCodePrinter, get_switch_statement - -from . import ( - amiciSwigPath, amiciSrcPath, amiciModulePath, __version__, __commit__, - sbml_import -) -from .logging import get_logger, log_execution_time, set_log_level -from .constants import SymbolId -from .import_utils import smart_subs_dict, toposort_symbols, \ - ObservableTransformation # Template for model simulation main.cpp file CXX_MAIN_TEMPLATE_FILE = os.path.join(amiciSrcPath, 'main.template.cpp') @@ -377,429 +374,6 @@ def var_in_function_signature(name: str, varname: str) -> bool: ) -class ModelQuantity: - """ - Base class for model components - """ - def __init__(self, - identifier: sp.Symbol, - name: str, - value: Union[SupportsFloat, numbers.Number, sp.Expr]): - """ - Create a new ModelQuantity instance. - - :param identifier: - unique identifier of the quantity - - :param name: - individual name of the quantity (does not need to be unique) - - :param value: - either formula, numeric value or initial value - """ - - if not isinstance(identifier, sp.Symbol): - raise TypeError(f'identifier must be sympy.Symbol, was ' - f'{type(identifier)}') - self._identifier: sp.Symbol = identifier - - if not isinstance(name, str): - raise TypeError(f'name must be str, was {type(name)}') - - self._name: str = name - - self._value: sp.Expr = cast_to_sym(value, 'value') - - def __repr__(self) -> str: - """ - Representation of the ModelQuantity object - - :return: - string representation of the ModelQuantity - """ - return str(self._identifier) - - def get_id(self) -> sp.Symbol: - """ - ModelQuantity identifier - - :return: - identifier of the ModelQuantity - """ - return self._identifier - - def get_name(self) -> str: - """ - ModelQuantity name - - :return: - name of the ModelQuantity - """ - return self._name - - def get_val(self) -> sp.Expr: - """ - ModelQuantity value - - :return: - value of the ModelQuantity - """ - return self._value - - def set_val(self, val: sp.Expr): - """ - Set ModelQuantity value - - :return: - value of the ModelQuantity - """ - self._value = cast_to_sym(val, 'value') - - -class State(ModelQuantity): - """ - A State variable defines an entity that evolves with time according to - the provided time derivative, abbreviated by ``x``. - - :ivar _conservation_law: - algebraic formula that allows computation of this - state according to a conservation law - - :ivar _dt: - algebraic formula that defines the temporal derivative of this state - - """ - - _dt: Union[sp.Expr, None] = None - _conservation_law: Union[sp.Expr, None] = None - - def __init__(self, - identifier: sp.Symbol, - name: str, - init: sp.Expr, - dt: sp.Expr): - """ - Create a new State instance. Extends :meth:`ModelQuantity.__init__` - by ``dt`` - - :param identifier: - unique identifier of the state - - :param name: - individual name of the state (does not need to be unique) - - :param init: - initial value - - :param dt: - time derivative - """ - super(State, self).__init__(identifier, name, init) - self._dt = cast_to_sym(dt, 'dt') - self._conservation_law = None - - def set_conservation_law(self, - law: sp.Expr) -> None: - """ - Sets the conservation law of a state. - - If a conservation law is set, the respective state will be replaced by - an algebraic formula according to the respective conservation law. - - :param law: - linear sum of states that if added to this state remain - constant over time - """ - if not isinstance(law, sp.Expr): - raise TypeError(f'conservation law must have type sympy.Expr, ' - f'was {type(law)}') - - self._conservation_law = law - - def set_dt(self, - dt: sp.Expr) -> None: - """ - Sets the time derivative - - :param dt: - time derivative - """ - self._dt = cast_to_sym(dt, 'dt') - - def get_dt(self) -> sp.Expr: - """ - Gets the time derivative - - :return: - time derivative - """ - return self._dt - - def get_free_symbols(self) -> Set[sp.Symbol]: - """ - Gets the set of free symbols in time derivative and initial conditions - - :return: - free symbols - """ - return self._dt.free_symbols.union(self._value.free_symbols) - - -class ConservationLaw(ModelQuantity): - """ - A conservation law defines the absolute the total amount of a - (weighted) sum of states - - """ - def __init__(self, - identifier: sp.Symbol, - name: str, - value: sp.Expr): - """ - Create a new ConservationLaw instance. - - :param identifier: - unique identifier of the ConservationLaw - - :param name: - individual name of the ConservationLaw (does not need to be - unique) - - :param value: formula (sum of states) - """ - super(ConservationLaw, self).__init__(identifier, name, value) - - -class Observable(ModelQuantity): - """ - An Observable links model simulations to experimental measurements, - abbreviated by ``y``. - - :ivar _measurement_symbol: - sympy symbol used in the objective function to represent - measurements to this observable - - :ivar trafo: - observable transformation, only applies when evaluating objective - function or residuals - """ - - _measurement_symbol: Union[sp.Symbol, None] = None - - def __init__(self, - identifier: sp.Symbol, - name: str, - value: sp.Expr, - measurement_symbol: Optional[sp.Symbol] = None, - transformation: Optional[ObservableTransformation] = 'lin'): - """ - Create a new Observable instance. - - :param identifier: - unique identifier of the Observable - - :param name: - individual name of the Observable (does not need to be unique) - - :param value: - formula - - :param transformation: - observable transformation, only applies when evaluating objective - function or residuals - """ - super(Observable, self).__init__(identifier, name, value) - self._measurement_symbol = measurement_symbol - self.trafo = transformation - - def get_measurement_symbol(self) -> sp.Symbol: - if self._measurement_symbol is None: - self._measurement_symbol = generate_measurement_symbol( - self.get_id() - ) - - return self._measurement_symbol - - -class SigmaY(ModelQuantity): - """ - A Standard Deviation SigmaY rescales the distance between simulations - and measurements when computing residuals or objective functions, - abbreviated by ``sigmay``. - """ - def __init__(self, - identifier: sp.Symbol, - name: str, - value: sp.Expr): - """ - Create a new Standard Deviation instance. - - :param identifier: - unique identifier of the Standard Deviation - - :param name: - individual name of the Standard Deviation (does not need to - be unique) - - :param value: - formula - """ - super(SigmaY, self).__init__(identifier, name, value) - - -class Expression(ModelQuantity): - """ - An Expression is a recurring elements in symbolic formulas. Specifying - this may yield more compact expression which may lead to substantially - shorter model compilation times, but may also reduce model simulation time. - Abbreviated by ``w``. - """ - def __init__(self, - identifier: sp.Symbol, - name: str, - value: sp.Expr): - """ - Create a new Expression instance. - - :param identifier: - unique identifier of the Expression - - :param name: - individual name of the Expression (does not need to be unique) - - :param value: - formula - """ - super(Expression, self).__init__(identifier, name, value) - - -class Parameter(ModelQuantity): - """ - A Parameter is a free variable in the model with respect to which - sensitivities may be computed, abbreviated by ``p``. - """ - - def __init__(self, - identifier: sp.Symbol, - name: str, - value: numbers.Number): - """ - Create a new Expression instance. - - :param identifier: - unique identifier of the Parameter - - :param name: - individual name of the Parameter (does not need to be - unique) - - :param value: - numeric value - """ - super(Parameter, self).__init__(identifier, name, value) - - -class Constant(ModelQuantity): - """ - A Constant is a fixed variable in the model with respect to which - sensitivities cannot be computed, abbreviated by ``k``. - """ - - def __init__(self, - identifier: sp.Symbol, - name: str, - value: numbers.Number): - """ - Create a new Expression instance. - - :param identifier: - unique identifier of the Constant - - :param name: - individual name of the Constant (does not need to be unique) - - :param value: - numeric value - """ - super(Constant, self).__init__(identifier, name, value) - - -class LogLikelihood(ModelQuantity): - """ - A LogLikelihood defines the distance between measurements and - experiments for a particular observable. The final LogLikelihood value - in the simulation will be the sum of all specified LogLikelihood - instances evaluated at all timepoints, abbreviated by ``Jy``. - """ - - def __init__(self, - identifier: sp.Symbol, - name: str, - value: sp.Expr): - """ - Create a new Expression instance. - - :param identifier: - unique identifier of the LogLikelihood - - :param name: - individual name of the LogLikelihood (does not need to be - unique) - - :param value: - formula - """ - super(LogLikelihood, self).__init__(identifier, name, value) - - -class Event(ModelQuantity): - """ - An Event defines either a SBML event or a root of the argument of a - Heaviside function. The Heaviside functions will be tracked via the - vector ``h`` during simulation and are needed to inform the ODE solver - about a discontinuity in either the right-hand side or the states - themselves, causing a reinitialization of the solver. - """ - - def __init__(self, - identifier: sp.Symbol, - name: str, - value: sp.Expr, - state_update: Union[sp.Expr, None], - event_observable: Union[sp.Expr, None]): - """ - Create a new Event instance. - - :param identifier: - unique identifier of the Event - - :param name: - individual name of the Event (does not need to be unique) - - :param value: - formula for the root / trigger function - - :param state_update: - formula for the bolus function (None for Heaviside functions, - zero vector for events without bolus) - - :param event_observable: - formula a potential observable linked to the event - (None for Heaviside functions, empty events without observable) - """ - super(Event, self).__init__(identifier, name, value) - # add the Event specific components - self._state_update = state_update - self._observable = event_observable - - def __eq__(self, other): - """ - Check equality of events at the level of trigger/root functions, as we - need to collect unique root functions for ``roots.cpp`` - """ - return self.get_val() == other.get_val() - - # defines the type of some attributes in ODEModel symbol_to_type = { SymbolId.SPECIES: State, @@ -3510,26 +3084,6 @@ def apply_template(source_file: str, fileout.write(result) -def strip_pysb(symbol: sp.Basic) -> sp.Basic: - """ - Strips pysb info from a :class:`pysb.Component` object - - :param symbol: - symbolic expression - - :return: - stripped expression - """ - # strip pysb type and transform into a flat sympy.Symbol. - # this ensures that the pysb type specific __repr__ is used when converting - # to string - if pysb and isinstance(symbol, pysb.Component): - return sp.Symbol(symbol.name, real=True) - else: - # in this case we will use sympy specific transform anyways - return symbol - - def get_function_extern_declaration(fun: str, name: str) -> str: """ Constructs the extern function declaration for a given function @@ -3700,83 +3254,6 @@ def is_valid_identifier(x: str) -> bool: return re.match(r'^[a-zA-Z_]\w*$', x) is not None -def generate_measurement_symbol(observable_id: Union[str, sp.Symbol]): - """ - Generates the appropriate measurement symbol for the provided observable - - :param observable_id: - symbol (or string representation) of the observable - - :return: - symbol for the corresponding measurement - """ - if not isinstance(observable_id, str): - observable_id = strip_pysb(observable_id) - return symbol_with_assumptions(f'm{observable_id}') - - -def generate_flux_symbol( - reaction_index: int, - name: Optional[str] = None -) -> sp.Symbol: - """ - Generate identifier symbol for a reaction flux. - This function will always return the same unique python object for a - given entity. - - :param reaction_index: - index of the reaction to which the flux corresponds - :param name: - an optional identifier of the reaction to which the flux corresponds - :return: - identifier symbol - """ - if name is not None: - return symbol_with_assumptions(name) - - return symbol_with_assumptions(f'flux_r{reaction_index}') - - -def symbol_with_assumptions(name: str): - """ - Central function to create symbols with consistent, canonical assumptions - - :param name: - name of the symbol - - :return: - symbol with canonical assumptions - """ - return sp.Symbol(name, real=True) - - -def cast_to_sym(value: Union[SupportsFloat, sp.Expr, BooleanAtom], - input_name: str) -> sp.Expr: - """ - Typecasts the value to :py:class:`sympy.Float` if possible, and ensures the - value is a symbolic expression. - - :param value: - value to be cast - - :param input_name: - name of input variable - - :return: - typecast value - """ - if isinstance(value, (sp.RealNumber, numbers.Number)): - value = sp.Float(float(value)) - elif isinstance(value, BooleanAtom): - value = sp.Float(float(bool(value))) - - if not isinstance(value, sp.Expr): - raise TypeError(f"Couldn't cast {input_name} to sympy.Expr, was " - f"{type(value)}") - - return value - - @contextlib.contextmanager def _monkeypatched(obj: object, name: str, patch: Any): """ diff --git a/python/amici/ode_model.py b/python/amici/ode_model.py new file mode 100644 index 0000000000..b9aeec8f77 --- /dev/null +++ b/python/amici/ode_model.py @@ -0,0 +1,469 @@ +"""Objects for AMICI's internal ODE model representation""" + + +import sympy as sp +import numpy as np +import re +import shutil +import subprocess +import sys +import os +import copy +import numbers +import logging +import itertools +import contextlib + +try: + import pysb +except ImportError: + pysb = None + +from typing import ( + Callable, Optional, Union, List, Dict, Tuple, SupportsFloat, Sequence, + Set, Any +) +from dataclasses import dataclass +from string import Template +from sympy.matrices.immutable import ImmutableDenseMatrix +from sympy.matrices.dense import MutableDenseMatrix +from sympy.logic.boolalg import BooleanAtom +from itertools import chain +from .cxxcodeprinter import AmiciCxxCodePrinter, get_switch_statement + +from . import ( + amiciSwigPath, amiciSrcPath, amiciModulePath, __version__, __commit__, + sbml_import +) +from .logging import get_logger, log_execution_time, set_log_level +from .constants import SymbolId +from .import_utils import smart_subs_dict, toposort_symbols, \ + ObservableTransformation, generate_measurement_symbol +from .import_utils import cast_to_sym + +__all__ = [ + 'ConservationLaw', 'Constant', 'Event', 'Expression', 'LogLikelihood', + 'ModelQuantity', 'Observable', 'Parameter', 'SigmaY', 'State' +] + +class ModelQuantity: + """ + Base class for model components + """ + def __init__(self, + identifier: sp.Symbol, + name: str, + value: Union[SupportsFloat, numbers.Number, sp.Expr]): + """ + Create a new ModelQuantity instance. + + :param identifier: + unique identifier of the quantity + + :param name: + individual name of the quantity (does not need to be unique) + + :param value: + either formula, numeric value or initial value + """ + + if not isinstance(identifier, sp.Symbol): + raise TypeError(f'identifier must be sympy.Symbol, was ' + f'{type(identifier)}') + self._identifier: sp.Symbol = identifier + + if not isinstance(name, str): + raise TypeError(f'name must be str, was {type(name)}') + + self._name: str = name + + self._value: sp.Expr = cast_to_sym(value, 'value') + + def __repr__(self) -> str: + """ + Representation of the ModelQuantity object + + :return: + string representation of the ModelQuantity + """ + return str(self._identifier) + + def get_id(self) -> sp.Symbol: + """ + ModelQuantity identifier + + :return: + identifier of the ModelQuantity + """ + return self._identifier + + def get_name(self) -> str: + """ + ModelQuantity name + + :return: + name of the ModelQuantity + """ + return self._name + + def get_val(self) -> sp.Expr: + """ + ModelQuantity value + + :return: + value of the ModelQuantity + """ + return self._value + + def set_val(self, val: sp.Expr): + """ + Set ModelQuantity value + + :return: + value of the ModelQuantity + """ + self._value = cast_to_sym(val, 'value') + + +class State(ModelQuantity): + """ + A State variable defines an entity that evolves with time according to + the provided time derivative, abbreviated by ``x``. + + :ivar _conservation_law: + algebraic formula that allows computation of this + state according to a conservation law + + :ivar _dt: + algebraic formula that defines the temporal derivative of this state + + """ + + _dt: Union[sp.Expr, None] = None + _conservation_law: Union[sp.Expr, None] = None + + def __init__(self, + identifier: sp.Symbol, + name: str, + init: sp.Expr, + dt: sp.Expr): + """ + Create a new State instance. Extends :meth:`ModelQuantity.__init__` + by ``dt`` + + :param identifier: + unique identifier of the state + + :param name: + individual name of the state (does not need to be unique) + + :param init: + initial value + + :param dt: + time derivative + """ + super(State, self).__init__(identifier, name, init) + self._dt = cast_to_sym(dt, 'dt') + self._conservation_law = None + + def set_conservation_law(self, + law: sp.Expr) -> None: + """ + Sets the conservation law of a state. + + If a conservation law is set, the respective state will be replaced by + an algebraic formula according to the respective conservation law. + + :param law: + linear sum of states that if added to this state remain + constant over time + """ + if not isinstance(law, sp.Expr): + raise TypeError(f'conservation law must have type sympy.Expr, ' + f'was {type(law)}') + + self._conservation_law = law + + def set_dt(self, + dt: sp.Expr) -> None: + """ + Sets the time derivative + + :param dt: + time derivative + """ + self._dt = cast_to_sym(dt, 'dt') + + def get_dt(self) -> sp.Expr: + """ + Gets the time derivative + + :return: + time derivative + """ + return self._dt + + def get_free_symbols(self) -> Set[sp.Symbol]: + """ + Gets the set of free symbols in time derivative and initial conditions + + :return: + free symbols + """ + return self._dt.free_symbols.union(self._value.free_symbols) + + +class ConservationLaw(ModelQuantity): + """ + A conservation law defines the absolute the total amount of a + (weighted) sum of states + + """ + def __init__(self, + identifier: sp.Symbol, + name: str, + value: sp.Expr): + """ + Create a new ConservationLaw instance. + + :param identifier: + unique identifier of the ConservationLaw + + :param name: + individual name of the ConservationLaw (does not need to be + unique) + + :param value: formula (sum of states) + """ + super(ConservationLaw, self).__init__(identifier, name, value) + + +class Observable(ModelQuantity): + """ + An Observable links model simulations to experimental measurements, + abbreviated by ``y``. + + :ivar _measurement_symbol: + sympy symbol used in the objective function to represent + measurements to this observable + + :ivar trafo: + observable transformation, only applies when evaluating objective + function or residuals + """ + + _measurement_symbol: Union[sp.Symbol, None] = None + + def __init__(self, + identifier: sp.Symbol, + name: str, + value: sp.Expr, + measurement_symbol: Optional[sp.Symbol] = None, + transformation: Optional[ObservableTransformation] = 'lin'): + """ + Create a new Observable instance. + + :param identifier: + unique identifier of the Observable + + :param name: + individual name of the Observable (does not need to be unique) + + :param value: + formula + + :param transformation: + observable transformation, only applies when evaluating objective + function or residuals + """ + super(Observable, self).__init__(identifier, name, value) + self._measurement_symbol = measurement_symbol + self.trafo = transformation + + def get_measurement_symbol(self) -> sp.Symbol: + if self._measurement_symbol is None: + self._measurement_symbol = generate_measurement_symbol( + self.get_id() + ) + + return self._measurement_symbol + + +class SigmaY(ModelQuantity): + """ + A Standard Deviation SigmaY rescales the distance between simulations + and measurements when computing residuals or objective functions, + abbreviated by ``sigmay``. + """ + def __init__(self, + identifier: sp.Symbol, + name: str, + value: sp.Expr): + """ + Create a new Standard Deviation instance. + + :param identifier: + unique identifier of the Standard Deviation + + :param name: + individual name of the Standard Deviation (does not need to + be unique) + + :param value: + formula + """ + super(SigmaY, self).__init__(identifier, name, value) + + +class Expression(ModelQuantity): + """ + An Expression is a recurring elements in symbolic formulas. Specifying + this may yield more compact expression which may lead to substantially + shorter model compilation times, but may also reduce model simulation time. + Abbreviated by ``w``. + """ + def __init__(self, + identifier: sp.Symbol, + name: str, + value: sp.Expr): + """ + Create a new Expression instance. + + :param identifier: + unique identifier of the Expression + + :param name: + individual name of the Expression (does not need to be unique) + + :param value: + formula + """ + super(Expression, self).__init__(identifier, name, value) + + +class Parameter(ModelQuantity): + """ + A Parameter is a free variable in the model with respect to which + sensitivities may be computed, abbreviated by ``p``. + """ + + def __init__(self, + identifier: sp.Symbol, + name: str, + value: numbers.Number): + """ + Create a new Expression instance. + + :param identifier: + unique identifier of the Parameter + + :param name: + individual name of the Parameter (does not need to be + unique) + + :param value: + numeric value + """ + super(Parameter, self).__init__(identifier, name, value) + + +class Constant(ModelQuantity): + """ + A Constant is a fixed variable in the model with respect to which + sensitivities cannot be computed, abbreviated by ``k``. + """ + + def __init__(self, + identifier: sp.Symbol, + name: str, + value: numbers.Number): + """ + Create a new Expression instance. + + :param identifier: + unique identifier of the Constant + + :param name: + individual name of the Constant (does not need to be unique) + + :param value: + numeric value + """ + super(Constant, self).__init__(identifier, name, value) + + +class LogLikelihood(ModelQuantity): + """ + A LogLikelihood defines the distance between measurements and + experiments for a particular observable. The final LogLikelihood value + in the simulation will be the sum of all specified LogLikelihood + instances evaluated at all timepoints, abbreviated by ``Jy``. + """ + + def __init__(self, + identifier: sp.Symbol, + name: str, + value: sp.Expr): + """ + Create a new Expression instance. + + :param identifier: + unique identifier of the LogLikelihood + + :param name: + individual name of the LogLikelihood (does not need to be + unique) + + :param value: + formula + """ + super(LogLikelihood, self).__init__(identifier, name, value) + + +class Event(ModelQuantity): + """ + An Event defines either a SBML event or a root of the argument of a + Heaviside function. The Heaviside functions will be tracked via the + vector ``h`` during simulation and are needed to inform the ODE solver + about a discontinuity in either the right-hand side or the states + themselves, causing a reinitialization of the solver. + """ + + def __init__(self, + identifier: sp.Symbol, + name: str, + value: sp.Expr, + state_update: Union[sp.Expr, None], + event_observable: Union[sp.Expr, None]): + """ + Create a new Event instance. + + :param identifier: + unique identifier of the Event + + :param name: + individual name of the Event (does not need to be unique) + + :param value: + formula for the root / trigger function + + :param state_update: + formula for the bolus function (None for Heaviside functions, + zero vector for events without bolus) + + :param event_observable: + formula a potential observable linked to the event + (None for Heaviside functions, empty events without observable) + """ + super(Event, self).__init__(identifier, name, value) + # add the Event specific components + self._state_update = state_update + self._observable = event_observable + + def __eq__(self, other): + """ + Check equality of events at the level of trigger/root functions, as we + need to collect unique root functions for ``roots.cpp`` + """ + return self.get_val() == other.get_val() diff --git a/python/amici/pysb_import.py b/python/amici/pysb_import.py index bc7c15da0c..d8faf627a0 100644 --- a/python/amici/pysb_import.py +++ b/python/amici/pysb_import.py @@ -5,34 +5,31 @@ in the :class:`pysb.core.Model` format. """ -from .ode_export import ( - ODEExporter, ODEModel, State, Constant, Parameter, Observable, SigmaY, - Expression, LogLikelihood, generate_measurement_symbol -) -from .import_utils import ( - noise_distribution_to_cost_function, _get_str_symbol_identifiers, - noise_distribution_to_observable_transformation, _parse_special_functions -) -import logging -from .logging import get_logger, log_execution_time, set_log_level - -import sympy as sp -import numpy as np import itertools +import logging import os import sys +from typing import (Any, Callable, Dict, Iterable, List, Optional, Set, Tuple, + Union) -from typing import ( - List, Union, Dict, Tuple, Set, Iterable, Any, Callable, Optional -) +import numpy as np +import pysb +import pysb.bng +import pysb.pattern +import sympy as sp + +from .import_utils import (_get_str_symbol_identifiers, + _parse_special_functions, + generate_measurement_symbol, + noise_distribution_to_cost_function, + noise_distribution_to_observable_transformation) +from .logging import get_logger, log_execution_time, set_log_level +from .ode_export import (Constant, Expression, LogLikelihood, ODEExporter, + ODEModel, Observable, Parameter, SigmaY, State) CL_Prototype = Dict[str, Dict[str, Any]] ConservationLaw = Dict[str, Union[str, sp.Basic]] -import pysb.bng -import pysb -import pysb.pattern - logger = get_logger(__name__, logging.ERROR) diff --git a/python/amici/sbml_import.py b/python/amici/sbml_import.py index b54865d363..aa438f5233 100644 --- a/python/amici/sbml_import.py +++ b/python/amici/sbml_import.py @@ -19,17 +19,17 @@ from . import has_clibs from .conserved_moieties import compute_moiety_conservation_laws from .constants import SymbolId -from .import_utils import (_check_unsupported_functions, +from .import_utils import (CircularDependencyError, + _check_unsupported_functions, _get_str_symbol_identifiers, _parse_special_functions, + generate_measurement_symbol, noise_distribution_to_cost_function, noise_distribution_to_observable_transformation, - smart_subs, smart_subs_dict, toposort_symbols, - CircularDependencyError) + smart_subs, smart_subs_dict, toposort_symbols) from .logging import get_logger, log_execution_time, set_log_level from .ode_export import ( - ODEExporter, ODEModel, generate_measurement_symbol, - symbol_with_assumptions + ODEExporter, ODEModel, symbol_with_assumptions ) diff --git a/python/sdist/amici/ode_model.py b/python/sdist/amici/ode_model.py new file mode 120000 index 0000000000..cbd58833cd --- /dev/null +++ b/python/sdist/amici/ode_model.py @@ -0,0 +1 @@ +../../amici/ode_model.py \ No newline at end of file From e5375d55e74d2fb070d7b83b9d994831302ecbe1 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Fri, 11 Mar 2022 20:55:10 +0100 Subject: [PATCH 30/45] Fix documentation for sz, srz, ssigmaz dimensions (#1711) Incorrect dimensions were stated in the docs as pointed out by @dilpath --- include/amici/rdata.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/include/amici/rdata.h b/include/amici/rdata.h index d83c775b6a..f8b82875b3 100644 --- a/include/amici/rdata.h +++ b/include/amici/rdata.h @@ -125,12 +125,14 @@ class ReturnData: public ModelDimensions { std::vector sigmaz; /** - * parameter derivative of event output (shape `nmaxevent` x `nz`, row-major) + * parameter derivative of event output + * (shape `nmaxevent` x `nplist` x `nz`, row-major) */ std::vector sz; /** - * parameter derivative of event output standard deviation (shape `nmaxevent` x `nz`, row-major) + * parameter derivative of event output standard deviation + * (shape `nmaxevent` x `nplist` x `nz`, row-major) */ std::vector ssigmaz; @@ -138,7 +140,8 @@ class ReturnData: public ModelDimensions { std::vector rz; /** - * parameter derivative of event trigger output (shape `nmaxevent` x `nz` x `nplist`, row-major) + * parameter derivative of event trigger output + * (shape `nmaxevent` x `nplist` x `nz`, row-major) */ std::vector srz; @@ -169,7 +172,8 @@ class ReturnData: public ModelDimensions { std::vector sy; /** - * parameter derivative of observable standard deviation (shape `nt` x `nplist` x `ny`, row-major) + * parameter derivative of observable standard deviation + * (shape `nt` x `nplist` x `ny`, row-major) */ std::vector ssigmay; From e4d3a3cd0d0a40c292e190cf0b42fc9709523b27 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Sat, 12 Mar 2022 00:23:46 +0100 Subject: [PATCH 31/45] Don't compute sx_rdata symbolically (#1710) Files get too large. Compute numerically. --- include/amici/abstract_model.h | 37 +++++++++++++++++ include/amici/cblas.h | 2 +- include/amici/model.h | 3 ++ include/amici/model_state.h | 7 ++++ python/amici/ode_export.py | 70 +++++++++++++++++---------------- src/abstract_model.cpp | 27 +++++++++++++ src/model.cpp | 45 ++++++++++++++++----- src/model_header.ODE_template.h | 10 ++++- src/model_state.cpp | 7 ++++ 9 files changed, 163 insertions(+), 45 deletions(-) diff --git a/include/amici/abstract_model.h b/include/amici/abstract_model.h index 3fb945d831..14fe96a769 100644 --- a/include/amici/abstract_model.h +++ b/include/amici/abstract_model.h @@ -870,6 +870,43 @@ class AbstractModel { * @param dwdw sparse matrix to which rowvals will be written */ virtual void fdwdw_rowvals(SUNMatrixWrapper &dwdw); + + /** + * @brief Compute dx_rdata / dx_solver + * @param dx_rdatadx_solver dx_rdata / dx_solver + * @param p parameter vector + * @param k constant vector + * @param x State variables with conservation laws applied + * @param tcl Total abundances for conservation laws + */ + virtual void fdx_rdatadx_solver(realtype *dx_rdatadx_solver, + const realtype *x, const realtype *tcl, + const realtype *p, const realtype *k); + + /** + * @brief Compute dx_rdata / dp + * @param dx_rdatadp dx_rdata / dp + * @param p parameter vector + * @param k constant vector + * @param x State variables with conservation laws applied + * @param tcl Total abundances for conservation laws + * @param ip Sensitivity index + */ + virtual void fdx_rdatadp(realtype *dx_rdatadp, const realtype *x, + const realtype *tcl, const realtype *p, + const realtype *k, const int ip); + + /** + * @brief Compute dx_rdata / dtcl + * @param dx_rdatadtcl dx_rdata / dtcl + * @param p parameter vector + * @param k constant vector + * @param x State variables with conservation laws applied + * @param tcl Total abundances for conservation laws + */ + virtual void fdx_rdatadtcl(realtype *dx_rdatadtcl, const realtype *x, + const realtype *tcl, const realtype *p, + const realtype *k); }; } // namespace amici diff --git a/include/amici/cblas.h b/include/amici/cblas.h index 6aed56ba43..608b6fd390 100644 --- a/include/amici/cblas.h +++ b/include/amici/cblas.h @@ -6,7 +6,7 @@ namespace amici { /** - * amici_dgemm provides an interface to the CBlas matrix vector multiplication + * amici_dgemv provides an interface to the CBlas matrix vector multiplication * routine dgemv. This routines computes * y = alpha*A*x + beta*y with A: [MxN] x:[Nx1] y:[Mx1] * diff --git a/include/amici/model.h b/include/amici/model.h index 18e5928be3..cb008ac621 100644 --- a/include/amici/model.h +++ b/include/amici/model.h @@ -146,6 +146,9 @@ class Model : public AbstractModel, public ModelDimensions { using AbstractModel::fx0_fixedParameters; using AbstractModel::fy; using AbstractModel::fz; + using AbstractModel::fdx_rdatadx_solver; + using AbstractModel::fdx_rdatadp; + using AbstractModel::fdx_rdatadtcl; /** * @brief Initialize model properties. diff --git a/include/amici/model_state.h b/include/amici/model_state.h index 60b91f2ea9..19b48b13d0 100644 --- a/include/amici/model_state.h +++ b/include/amici/model_state.h @@ -222,6 +222,13 @@ struct ModelStateDerived { /** temporary storage for `sx_rdata` slice (dimension: `nx_rdata`) */ std::vector sx_rdata_; + /** temporary storage for `dx_rdatadx_solver` + * (dimension: `nx_rdata` x `nx_solver`) */ + std::vector dx_rdatadx_solver; + + /** temporary storage for `dx_rdatadtcl` (dimension: `nx_rdata` x `ntcl`) */ + std::vector dx_rdatadtcl; + /** temporary storage for time-resolved observable (dimension: ny) */ std::vector y_; diff --git a/python/amici/ode_export.py b/python/amici/ode_export.py index a065a088fc..30d233ab9c 100644 --- a/python/amici/ode_export.py +++ b/python/amici/ode_export.py @@ -273,12 +273,6 @@ class _FunctionInfo: 'realtype *x_rdata, const realtype *x, const realtype *tcl, ' 'const realtype *p, const realtype *k' ), - 'sx_rdata': - _FunctionInfo( - 'realtype *sx_rdata, const realtype *sx_solver, ' - 'const realtype *stotal_cl, const realtype *p, const realtype *k, ' - 'const realtype *x, const realtype *tcl, const int ip' - ), 'total_cl': _FunctionInfo( 'realtype *total_cl, const realtype *x_rdata, ' @@ -291,7 +285,23 @@ class _FunctionInfo: 'const realtype *tcl' ), 'x_solver': - _FunctionInfo('realtype *x_solver, const realtype *x_rdata') + _FunctionInfo('realtype *x_solver, const realtype *x_rdata'), + 'dx_rdatadx_solver': + _FunctionInfo( + 'realtype *dx_rdatadx_solver, const realtype *x, ' + 'const realtype *tcl, const realtype *p, const realtype *k' + ), + 'dx_rdatadp': + _FunctionInfo( + 'realtype *dx_rdatadp, const realtype *x, ' + 'const realtype *tcl, const realtype *p, const realtype *k, ' + 'const int ip' + ), + 'dx_rdatadtcl': + _FunctionInfo( + 'realtype *dx_rdatadtcl, const realtype *x, ' + 'const realtype *tcl, const realtype *p, const realtype *k' + ), } # list of sparse functions @@ -1458,39 +1468,33 @@ def _compute_equation(self, name: str) -> None: self._eqs[name][:, ip] += tmp elif name == 'dx_rdatadx_solver': - self._eqs[name] = smart_jacobian(self.eq('x_rdata'), - self.sym('x')) + if self.num_cons_law(): + self._eqs[name] = smart_jacobian(self.eq('x_rdata'), + self.sym('x')) + else: + # so far, dx_rdatadx_solver is only required for sx_rdata + # in case of no conservation laws, C++ code will directly use + # sx, we don't need this + self._eqs[name] = \ + sp.zeros(self.num_states_rdata(), + self.num_states_solver()) elif name == 'dx_rdatadp': - self._eqs[name] = smart_jacobian(self.eq('x_rdata'), - self.sym('p')) + if self.num_cons_law(): + self._eqs[name] = smart_jacobian(self.eq('x_rdata'), + self.sym('p')) + else: + # so far, dx_rdatadp is only required for sx_rdata + # in case of no conservation laws, C++ code will directly use + # sx, we don't need this + self._eqs[name] = \ + sp.zeros(self.num_states_rdata(), + self.num_par()) elif name == 'dx_rdatadtcl': self._eqs[name] = smart_jacobian(self.eq('x_rdata'), self.sym('tcl')) - elif name == 'sx_rdata': - if self.num_cons_law(): - # sx_rdata = dx_rdata/dx_solver * sx_solver - # + dx_rdata/d_tcl * stcl + dxrdata/dp - # shape: nx_rdata, 1 - dx_rdata_dx_solver = self.eq('dx_rdatadx_solver') - sym_sx_solver = self.sym('sx_solver') - dx_rdata_dp = self.eq('dx_rdatadp') - self._eqs[name] = dx_rdata_dp - tmp = smart_multiply(dx_rdata_dx_solver, sym_sx_solver) - for ip in range(self._eqs[name].shape[1]): - self._eqs[name][:, ip] += tmp - - sym_stotal_cl = self.sym('stotal_cl') - dx_rdata_dtotal_cl = self.eq('dx_rdatadtcl') - tmp = smart_multiply(dx_rdata_dtotal_cl, sym_stotal_cl) - for ip in range(self._eqs[name].shape[1]): - self._eqs[name][:, ip] += tmp - else: - # if there are no conservation laws, this is simply sx_solver - self._eqs[name] = self.sym('sx_solver') - elif name == 'dxdotdx_explicit': # force symbols self._derivative('xdot', 'x', name=name) diff --git a/src/abstract_model.cpp b/src/abstract_model.cpp index 8bbb1ebdf8..01929ccb9f 100644 --- a/src/abstract_model.cpp +++ b/src/abstract_model.cpp @@ -654,4 +654,31 @@ void AbstractModel::fdwdw_rowvals(SUNMatrixWrapper &/*dwdw*/) { __func__); } +void AbstractModel::fdx_rdatadx_solver(realtype */*dx_rdatadx_solver*/, + const realtype */*x*/, const realtype */*tcl*/, + const realtype */*p*/, const realtype */*k*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + +void AbstractModel::fdx_rdatadp(realtype */*dx_rdatadp*/, const realtype */*x*/, + const realtype */*tcl*/, const realtype */*p*/, + const realtype */*k*/, const int /*ip*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + +void AbstractModel::fdx_rdatadtcl(realtype */*dx_rdatadtcl*/, const realtype */*x*/, + const realtype */*tcl*/, const realtype */*p*/, + const realtype */*k*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + } // namespace amici diff --git a/src/model.cpp b/src/model.cpp index dc66b815d9..a3a346d1f0 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -2183,15 +2183,42 @@ void Model::fx_rdata(realtype *x_rdata, const realtype *x_solver, } void Model::fsx_rdata(realtype *sx_rdata, const realtype *sx_solver, - const realtype */*stcl*/, const realtype */*p*/, - const realtype */*k*/, const realtype * /*x_solver*/, - const realtype */*tcl*/, - const int /*ip*/) { - if (nx_solver != nx_rdata) - throw AmiException( - "A model that has differing nx_solver and nx_rdata needs " - "to implement its own fx_rdata"); - std::copy_n(sx_solver, nx_solver, sx_rdata); + const realtype *stcl, const realtype *p, + const realtype *k, const realtype *x_solver, + const realtype *tcl, + const int ip) { + if (nx_solver == nx_rdata) { + std::copy_n(sx_solver, nx_solver, sx_rdata); + return; + } + + // sx_rdata = dx_rdata/dx_solver * sx_solver + // + dx_rdata/d_tcl * stcl + dxrdata/dp + + // 1) sx_rdata(nx_rdata, 1) = dx_rdatadp + std::fill_n(sx_rdata, nx_rdata, 0.0); + fdx_rdatadp(sx_rdata, x_solver, tcl, p, k, ip); + + + // the following could be moved to the calling function, as it's independent + // of `ip` + + // 2) sx_rdata(nx_rdata, 1) += + // dx_rdata/dx_solver(nx_rdata,nx_solver) * sx_solver(nx_solver, 1) + derived_state_.dx_rdatadx_solver.assign(nx_rdata * nx_solver, 0.0); + fdx_rdatadx_solver(derived_state_.dx_rdatadx_solver.data(), + x_solver, tcl, p, k); + amici_dgemv(BLASLayout::rowMajor, BLASTranspose::noTrans, nx_rdata, + nx_solver, 1.0, derived_state_.dx_rdatadx_solver.data(), + nx_solver, sx_solver, 1, 1.0, sx_rdata, 1); + + // 3) sx_rdata(nx_rdata, 1) += dx_rdata/d_tcl(nx_rdata,ntcl) * stcl + derived_state_.dx_rdatadtcl.assign(nx_rdata * (nx_rdata - nx_solver), 0.0); + fdx_rdatadtcl(derived_state_.dx_rdatadtcl.data(), x_solver, tcl, p, k); + amici_dgemv(BLASLayout::rowMajor, BLASTranspose::noTrans, nx_rdata, + nx_rdata - nx_solver, 1.0, derived_state_.dx_rdatadtcl.data(), + ncl(), stcl, 1, 1.0, sx_rdata, 1); + } void Model::fx_solver(realtype *x_solver, const realtype *x_rdata) { diff --git a/src/model_header.ODE_template.h b/src/model_header.ODE_template.h index c253d79efc..862aa69a2f 100644 --- a/src/model_header.ODE_template.h +++ b/src/model_header.ODE_template.h @@ -71,7 +71,9 @@ TPL_X_RDATA_DEF TPL_X_SOLVER_DEF TPL_TOTAL_CL_DEF TPL_STOTAL_CL_DEF -TPL_SX_RDATA_DEF +TPL_DX_RDATADX_SOLVER_DEF +TPL_DX_RDATADP_DEF +TPL_DX_RDATADTCL_DEF /** * @brief AMICI-generated model subclass. @@ -471,7 +473,11 @@ class Model_TPL_MODELNAME : public amici::Model_ODE { TPL_STOTAL_CL_IMPL - TPL_SX_RDATA_IMPL + TPL_DX_RDATADX_SOLVER_IMPL + + TPL_DX_RDATADP_IMPL + + TPL_DX_RDATADTCL_IMPL std::string getName() const override { return "TPL_MODELNAME"; diff --git a/src/model_state.cpp b/src/model_state.cpp index 913912ae7f..14a4fd8b02 100644 --- a/src/model_state.cpp +++ b/src/model_state.cpp @@ -9,6 +9,13 @@ ModelStateDerived::ModelStateDerived(const ModelDimensions &dim) w_(dim.nw), x_rdata_(dim.nx_rdata, 0.0), sx_rdata_(dim.nx_rdata, 0.0), + // only required if there are conservation laws + dx_rdatadx_solver(dim.nx_rdata - dim.nx_solver > 0 + ? dim.nx_rdata * dim.nx_solver : 0, 0.0), + // only required if there are conservation laws + dx_rdatadtcl(dim.nx_rdata - dim.nx_solver > 0 + ? dim.nx_rdata * (dim.nx_rdata - dim.nx_solver) : 0, + 0.0), x_pos_tmp_(dim.nx_solver) {} From b7c4921bb3405c021250e790a13a948dd3546fff Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Sat, 12 Mar 2022 00:59:39 +0100 Subject: [PATCH 32/45] CI: Skip Python-only tests when running valgrind (#1714) --- python/tests/test_conserved_moieties.py | 8 ++++++++ python/tests/test_parameter_mapping.py | 11 +++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/python/tests/test_conserved_moieties.py b/python/tests/test_conserved_moieties.py index e7b06830c8..e039fe9f9e 100644 --- a/python/tests/test_conserved_moieties.py +++ b/python/tests/test_conserved_moieties.py @@ -56,6 +56,8 @@ def data_demartino2014(): return S, row_names +@pytest.mark.skipif(os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Python-only") def test_kernel_demartino2014(data_demartino2014, quiet=True): """Invoke test case and benchmarking for De Martino's published results for E. coli network. Kernel-only.""" @@ -92,6 +94,8 @@ def test_kernel_demartino2014(data_demartino2014, quiet=True): f"Moiety #{i + 1} failed for test case (De Martino et al.)" +@pytest.mark.skipif(os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Python-only") def test_fill_demartino2014(data_demartino2014): """Test creation of interaction matrix""" stoichiometric_list, row_names = data_demartino2014 @@ -184,6 +188,8 @@ def test_fill_demartino2014(data_demartino2014): assert not any(fields[len(ref_for_fields):]) +@pytest.mark.skipif(os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Python-only") def test_compute_moiety_conservation_laws_demartino2014( data_demartino2014, quiet=False ): @@ -231,6 +237,8 @@ def test_cl_detect_execution_time(data_demartino2014): assert runtime < max_time_seconds, "Took too long" +@pytest.mark.skipif(os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Python-only") def test_compute_moiety_conservation_laws_simple(): """Test a simple example, ensure the conservation laws are identified reliably. Requires the Monte Carlo to identify all.""" diff --git a/python/tests/test_parameter_mapping.py b/python/tests/test_parameter_mapping.py index 65f48d146b..73f72eef8e 100644 --- a/python/tests/test_parameter_mapping.py +++ b/python/tests/test_parameter_mapping.py @@ -1,9 +1,14 @@ """Test for ``amici.parameter_mapping``""" +import os -from amici.parameter_mapping import ( - ParameterMappingForCondition, ParameterMapping) +import pytest +from amici.parameter_mapping import (ParameterMapping, + ParameterMappingForCondition) + +@pytest.mark.skipif(os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Python-only") def test_parameter_mapping_for_condition_default_args(): """Check we can initialize the mapping with default arguments.""" @@ -32,6 +37,8 @@ def test_parameter_mapping_for_condition_default_args(): expected_scale_map_sim_fix +@pytest.mark.skipif(os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Python-only") def test_parameter_mapping(): """Test :class:``amici.parameter_mapping.ParameterMapping``.""" From e5d10d8208a5deaa08dea7146b50ce560494c9bf Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Sat, 12 Mar 2022 01:00:32 +0100 Subject: [PATCH 33/45] CI: Fix C++ tests under valgrind (#1716) Previously, tests were not found and silently skipped. Probably since changing to gtest. Fixes #1715. --- scripts/run-valgrind-cpp.sh | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/scripts/run-valgrind-cpp.sh b/scripts/run-valgrind-cpp.sh index 7d868d98ef..fd08cbda54 100755 --- a/scripts/run-valgrind-cpp.sh +++ b/scripts/run-valgrind-cpp.sh @@ -8,12 +8,6 @@ AMICI_PATH=$(cd "$SCRIPT_PATH/.." && pwd) set -eou pipefail # run tests -cd "${AMICI_PATH}/build/tests/cpp/" - +cd "${AMICI_PATH}/build/" VALGRIND_OPTS="--leak-check=full --error-exitcode=1 --trace-children=yes --show-leak-kinds=definite" -set -x -for MODEL in $(ctest -N | grep "Test[ ]*#" | grep -v unittests | sed --regexp-extended 's/ *Test[ ]*#[0-9]+: model_(.*)_test/\1/') - do cd "${AMICI_PATH}/build/tests/cpp/${MODEL}/" && valgrind ${VALGRIND_OPTS} "./model_${MODEL}_test" -done -cd "${AMICI_PATH}/build/tests/cpp/unittests/" -valgrind ${VALGRIND_OPTS} ./unittests +valgrind ${VALGRIND_OPTS} ctest From ceea87a6f5897a599fe15396e6c7ad4568e038ba Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Sat, 12 Mar 2022 02:12:48 +0100 Subject: [PATCH 34/45] Don't compute stotal_cl symbolically (#1713) Avoids unnecessarily large fstotal_cl. --- include/amici/abstract_model.h | 25 +++++++++++++++++++++++++ include/amici/cblas.h | 24 +++++++++++++----------- include/amici/model.h | 2 ++ include/amici/model_state.h | 6 +++++- python/amici/ode_export.py | 24 ++++++++---------------- src/abstract_model.cpp | 22 ++++++++++++++++++++++ src/model.cpp | 33 ++++++++++++++++++++++++--------- src/model_header.ODE_template.h | 9 ++++++--- src/model_state.cpp | 4 ++++ 9 files changed, 109 insertions(+), 40 deletions(-) diff --git a/include/amici/abstract_model.h b/include/amici/abstract_model.h index 14fe96a769..28ee2db328 100644 --- a/include/amici/abstract_model.h +++ b/include/amici/abstract_model.h @@ -907,6 +907,31 @@ class AbstractModel { virtual void fdx_rdatadtcl(realtype *dx_rdatadtcl, const realtype *x, const realtype *tcl, const realtype *p, const realtype *k); + + /** + * @brief Compute dtotal_cl / dp + * @param dtotal_cldp dtotal_cl / dp + * @param x_rdata State variables with conservation laws applied + * @param p parameter vector + * @param k constant vector + * @param ip Sensitivity index + */ + virtual void fdtotal_cldp(realtype *dtotal_cldp, const realtype *x_rdata, + const realtype *p, const realtype *k, + const int ip); + + /** + * @brief Compute dtotal_cl / dx_rdata + * @param dtotal_cldx_rdata dtotal_cl / dx_rdata + * @param x_rdata State variables with conservation laws applied + * @param p parameter vector + * @param k constant vector + * @param tcl Total abundances for conservation laws + */ + virtual void fdtotal_cldx_rdata(realtype *dtotal_cldx_rdata, + const realtype *x_rdata, const realtype *p, + const realtype *k, const realtype *tcl); + }; } // namespace amici diff --git a/include/amici/cblas.h b/include/amici/cblas.h index 608b6fd390..bbfef955fe 100644 --- a/include/amici/cblas.h +++ b/include/amici/cblas.h @@ -6,18 +6,19 @@ namespace amici { /** - * amici_dgemv provides an interface to the CBlas matrix vector multiplication - * routine dgemv. This routines computes - * y = alpha*A*x + beta*y with A: [MxN] x:[Nx1] y:[Mx1] + * @brief CBLAS matrix vector multiplication (dgemv). * - * @param layout always needs to be AMICI_BLAS_ColMajor. + * Computes \f$ y = alpha*A*x + beta*y \f$ with A: [MxN] x:[Nx1] y:[Mx1] + * + * @param layout Matrix layout, column major or row major. * @param TransA flag indicating whether A should be transposed before * multiplication * @param M number of rows in A * @param N number of columns in A * @param alpha coefficient alpha * @param A matrix A - * @param lda leading dimension of A (m or n) + * @param lda leading dimension / stride of A (>=N if row-major, + * >=M if col-major) * @param X vector X * @param incX increment for entries of X * @param beta coefficient beta @@ -30,9 +31,10 @@ void amici_dgemv(BLASLayout layout, BLASTranspose TransA, double beta, double *Y, int incY); /** - * amici_dgemm provides an interface to the CBlas matrix matrix multiplication - * routine dgemm. This routines computes - * C = alpha*A*B + beta*C with A: [MxK] B:[KxN] C:[MxN] + * @brief CBLAS matrix matrix multiplication (dgemm) + * + * This routines computes \f$ C = alpha*A*B + beta*C \f$ + * with A: [MxK] B:[KxN] C:[MxN] * * @param layout memory layout. * @param TransA flag indicating whether A should be transposed before @@ -44,12 +46,12 @@ void amici_dgemv(BLASLayout layout, BLASTranspose TransA, * @param K number of rows in B, number of columns in A * @param alpha coefficient alpha * @param A matrix A - * @param lda leading dimension of A (m or k) + * @param lda leading dimension of A (>=M or >=K) * @param B matrix B - * @param ldb leading dimension of B (k or n) + * @param ldb leading dimension of B (>=K or >=N) * @param beta coefficient beta * @param C matrix C - * @param ldc leading dimension of C (m or n) + * @param ldc leading dimension of C (>=M or >= N) */ void amici_dgemm(BLASLayout layout, BLASTranspose TransA, BLASTranspose TransB, int M, int N, diff --git a/include/amici/model.h b/include/amici/model.h index cb008ac621..409617a29b 100644 --- a/include/amici/model.h +++ b/include/amici/model.h @@ -149,6 +149,8 @@ class Model : public AbstractModel, public ModelDimensions { using AbstractModel::fdx_rdatadx_solver; using AbstractModel::fdx_rdatadp; using AbstractModel::fdx_rdatadtcl; + using AbstractModel::fdtotal_cldx_rdata; + using AbstractModel::fdtotal_cldp; /** * @brief Initialize model properties. diff --git a/include/amici/model_state.h b/include/amici/model_state.h index 19b48b13d0..42a000b4e3 100644 --- a/include/amici/model_state.h +++ b/include/amici/model_state.h @@ -226,9 +226,13 @@ struct ModelStateDerived { * (dimension: `nx_rdata` x `nx_solver`) */ std::vector dx_rdatadx_solver; - /** temporary storage for `dx_rdatadtcl` (dimension: `nx_rdata` x `ntcl`) */ + /** temporary storage for `dx_rdatadtcl` (dimension: `nx_rdata` x `ncl`) */ std::vector dx_rdatadtcl; + /** temporary storage for `dtotal_cldx_rdata` + * (dimension: `ncl` x `nx_rdata`) */ + std::vector dtotal_cldx_rdata; + /** temporary storage for time-resolved observable (dimension: ny) */ std::vector y_; diff --git a/python/amici/ode_export.py b/python/amici/ode_export.py index 30d233ab9c..007d3377fb 100644 --- a/python/amici/ode_export.py +++ b/python/amici/ode_export.py @@ -278,11 +278,15 @@ class _FunctionInfo: 'realtype *total_cl, const realtype *x_rdata, ' 'const realtype *p, const realtype *k' ), - 'stotal_cl': + 'dtotal_cldp': _FunctionInfo( - 'realtype *stotal_cl, const realtype *sx_rdata, const int ip, ' - 'const realtype *x_rdata, const realtype *p, const realtype *k, ' - 'const realtype *tcl' + 'realtype *dtotal_cldp, const realtype *x_rdata, ' + 'const realtype *p, const realtype *k, const int ip' + ), + 'dtotal_cldx_rdata': + _FunctionInfo( + 'realtype *dtotal_cldx_rdata, const realtype *x_rdata, ' + 'const realtype *p, const realtype *k, const realtype *tcl' ), 'x_solver': _FunctionInfo('realtype *x_solver, const realtype *x_rdata'), @@ -1455,18 +1459,6 @@ def _compute_equation(self, name: str) -> None: self._eqs[name] = \ sp.zeros(self.num_cons_law(), self.num_states_solver()) - elif name == 'dtcldp': - self._derivative('total_cl', 'p', name=name) - - elif name == 'stotal_cl': - # stotal_cl = dtotal_cl/dp + dtotal_cl/dx_rdata * sx_rdata - # shape: ncl x np - self._eqs[name] = self.eq('dtcldp') - dtotal_cldx_rdata = self.eq('dtotal_cldx_rdata') - tmp = smart_multiply(dtotal_cldx_rdata, self.sym('sx_rdata')) - for ip in range(self._eqs[name].shape[1]): - self._eqs[name][:, ip] += tmp - elif name == 'dx_rdatadx_solver': if self.num_cons_law(): self._eqs[name] = smart_jacobian(self.eq('x_rdata'), diff --git a/src/abstract_model.cpp b/src/abstract_model.cpp index 01929ccb9f..0d860de3c6 100644 --- a/src/abstract_model.cpp +++ b/src/abstract_model.cpp @@ -681,4 +681,26 @@ void AbstractModel::fdx_rdatadtcl(realtype */*dx_rdatadtcl*/, const realtype */* __func__); } +void AbstractModel::fdtotal_cldp(realtype */*dtotal_cldp*/, + const realtype */*x_rdata*/, + const realtype */*p*/, + const realtype */*k*/, + const int /*ip*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + +void AbstractModel::fdtotal_cldx_rdata(realtype */*dtotal_cldx_rdata*/, + const realtype */*x_rdata*/, + const realtype */*p*/, + const realtype */*k*/, + const realtype */*tcl*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + } // namespace amici diff --git a/src/model.cpp b/src/model.cpp index a3a346d1f0..b8088b655f 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -2218,7 +2218,6 @@ void Model::fsx_rdata(realtype *sx_rdata, const realtype *sx_solver, amici_dgemv(BLASLayout::rowMajor, BLASTranspose::noTrans, nx_rdata, nx_rdata - nx_solver, 1.0, derived_state_.dx_rdatadtcl.data(), ncl(), stcl, 1, 1.0, sx_rdata, 1); - } void Model::fx_solver(realtype *x_solver, const realtype *x_rdata) { @@ -2244,14 +2243,30 @@ void Model::ftotal_cl(realtype * /*total_cl*/, const realtype * /*x_rdata*/, "to implement its own ftotal_cl"); } -void Model::fstotal_cl(realtype */*stotal_cl*/, const realtype */*sx_rdata*/, - const int /*ip*/, const realtype */*x_rdata*/, - const realtype */*p*/, const realtype */*k*/, - const realtype */*tcl*/) { - if (nx_solver != nx_rdata) - throw AmiException( - "A model that has differing nx_solver and nx_rdata needs " - "to implement its own ftotal_cl"); +void Model::fstotal_cl(realtype *stotal_cl, const realtype *sx_rdata, + const int ip, const realtype *x_rdata, + const realtype *p, const realtype *k, + const realtype *tcl) { + if (nx_solver == nx_rdata) + return; + + // stotal_cl(ncl,1) = + // dtotal_cl/dp(ncl,1) + // + dtotal_cl/dx_rdata(ncl,nx_rdata) * sx_rdata(nx_rdata,1) + + // 1) stotal_cl = dtotal_cl/dp + std::fill_n(stotal_cl, ncl(), 0.0); + fdtotal_cldp(stotal_cl, x_rdata, p, k, ip); + + + // 2) stotal_cl += dtotal_cl/dx_rdata(ncl,nx_rdata) * sx_rdata(nx_rdata,1) + derived_state_.dtotal_cldx_rdata.assign(ncl() * nx_rdata, 0.0); + fdtotal_cldx_rdata(derived_state_.dtotal_cldx_rdata.data(), + x_rdata, tcl, p, k); + amici_dgemv(BLASLayout::rowMajor, BLASTranspose::noTrans, ncl(), + nx_rdata, 1.0, derived_state_.dtotal_cldx_rdata.data(), + nx_rdata, sx_rdata, 1, 1.0, stotal_cl, 1); + } const_N_Vector Model::computeX_pos(const_N_Vector x) { diff --git a/src/model_header.ODE_template.h b/src/model_header.ODE_template.h index 862aa69a2f..db507fcd9d 100644 --- a/src/model_header.ODE_template.h +++ b/src/model_header.ODE_template.h @@ -70,10 +70,11 @@ TPL_DELTASX_DEF TPL_X_RDATA_DEF TPL_X_SOLVER_DEF TPL_TOTAL_CL_DEF -TPL_STOTAL_CL_DEF TPL_DX_RDATADX_SOLVER_DEF TPL_DX_RDATADP_DEF TPL_DX_RDATADTCL_DEF +TPL_DTOTAL_CLDP_DEF +TPL_DTOTAL_CLDX_RDATA_DEF /** * @brief AMICI-generated model subclass. @@ -471,14 +472,16 @@ class Model_TPL_MODELNAME : public amici::Model_ODE { TPL_TOTAL_CL_IMPL - TPL_STOTAL_CL_IMPL - TPL_DX_RDATADX_SOLVER_IMPL TPL_DX_RDATADP_IMPL TPL_DX_RDATADTCL_IMPL + TPL_DTOTAL_CLDP_IMPL + + TPL_DTOTAL_CLDX_RDATA_IMPL + std::string getName() const override { return "TPL_MODELNAME"; } diff --git a/src/model_state.cpp b/src/model_state.cpp index 14a4fd8b02..52800f59ba 100644 --- a/src/model_state.cpp +++ b/src/model_state.cpp @@ -16,6 +16,10 @@ ModelStateDerived::ModelStateDerived(const ModelDimensions &dim) dx_rdatadtcl(dim.nx_rdata - dim.nx_solver > 0 ? dim.nx_rdata * (dim.nx_rdata - dim.nx_solver) : 0, 0.0), + // only required if there are conservation laws + dtotal_cldx_rdata(dim.nx_rdata - dim.nx_solver > 0 + ? (dim.nx_rdata - dim.nx_solver) * dim.nx_rdata : 0, + 0.0), x_pos_tmp_(dim.nx_solver) {} From 5ab916520bafe3f4ae5a834be25fef3cc1d52f27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Fr=C3=B6hlich?= Date: Fri, 11 Mar 2022 22:12:45 -0500 Subject: [PATCH 35/45] add bngl import (#1709) * add bngl import * fixups + doc * fixup * fixup * continue example fails due to naming conflict, egfr_net takes foreever * add reserved symbol check pysb * doh * fix doc * fix test skip & doc * Apply suggestions from code review Co-authored-by: Daniel Weindl * fixup * Update python/tests/test_bngl.py Co-authored-by: Daniel Weindl * fixup and avoid pysb namespace clashes Co-authored-by: Daniel Weindl --- documentation/glossary.rst | 8 ++- documentation/python_interface.rst | 8 +-- documentation/python_modules.rst | 2 + python/amici/bngl_import.py | 32 ++++++++++++ python/amici/import_utils.py | 2 + python/amici/ode_model.py | 8 ++- python/amici/pysb_import.py | 3 +- python/amici/sbml_import.py | 7 ++- python/sdist/amici/bngl_import.py | 1 + python/tests/test_bngl.py | 83 ++++++++++++++++++++++++++++++ python/tests/test_pysb.py | 1 - 11 files changed, 143 insertions(+), 12 deletions(-) create mode 100644 python/amici/bngl_import.py create mode 120000 python/sdist/amici/bngl_import.py create mode 100644 python/tests/test_bngl.py diff --git a/documentation/glossary.rst b/documentation/glossary.rst index 4f92d18e1a..c732af7a3a 100644 --- a/documentation/glossary.rst +++ b/documentation/glossary.rst @@ -5,6 +5,10 @@ Glossary .. glossary:: :sorted: + BNGL + `BioNetGenLanguage `_ is a language for + modular, structure-based modeling of biochemical reaction networks. + CVODES `CVODES `_ is a solver for stiff and non-stiff :term:`ODE` systems with sensitivity @@ -46,8 +50,8 @@ Glossary biology models as Python code. SBML - `SBML `_ is a commonly used format for specifying - systems biology models. + The `Systems Biology Markup Language `_ is a + commonly used format for specifying systems biology models. SUNDIALS `SUNDIALS `_: diff --git a/documentation/python_interface.rst b/documentation/python_interface.rst index 9db3a06c7c..bea321b4ab 100644 --- a/documentation/python_interface.rst +++ b/documentation/python_interface.rst @@ -104,9 +104,11 @@ PySB import AMICI can import :term:`PySB` models via :py:func:`amici.pysb_import.pysb2amici`. -`BioNetGen `_ and -`Kappa `_ models can be imported into AMICI using -PySB. +BNGL import +----------- + +AMICI can import :term:`BNGL` models via +:py:func:`amici.bngl_import.bngl2amici`. PEtab import ------------ diff --git a/documentation/python_modules.rst b/documentation/python_modules.rst index 013261fb9d..080e512a49 100644 --- a/documentation/python_modules.rst +++ b/documentation/python_modules.rst @@ -10,12 +10,14 @@ AMICI Python API amici.amici amici.sbml_import amici.pysb_import + amici.bngl_import amici.petab_import amici.petab_import_pysb amici.petab_objective amici.petab_simulate amici.import_utils amici.ode_export + amici.ode_model amici.plotting amici.pandas amici.logging diff --git a/python/amici/bngl_import.py b/python/amici/bngl_import.py new file mode 100644 index 0000000000..840e4a4229 --- /dev/null +++ b/python/amici/bngl_import.py @@ -0,0 +1,32 @@ +""" +BNGL Import +------------ +This module provides all necessary functionality to import a model specified +in the :term:`BNGL` format. +""" + + +from pysb.importers.bngl import model_from_bngl + +from .pysb_import import pysb2amici + + +def bngl2amici(bngl_model: str, *args, **kwargs) -> None: + r""" + Generate AMICI C++ files for the provided model. + + :param bngl_model: + bngl model file, model name will determine the name of the generated + module + + :param args: + see :func:`amici.pysb_import.pysb2amici` for additional arguments + + :param kwargs: + see :func:`amici.pysb_import.pysb2amici` for additional arguments + + """ + if 'model' in kwargs: + raise ValueError('model argument not allowed') + pysb_model = model_from_bngl(bngl_model) + pysb2amici(pysb_model, *args, **kwargs) diff --git a/python/amici/import_utils.py b/python/amici/import_utils.py index 93925c519e..76f35a2c30 100644 --- a/python/amici/import_utils.py +++ b/python/amici/import_utils.py @@ -12,6 +12,8 @@ from sympy.logic.boolalg import BooleanAtom from toposort import toposort +RESERVED_SYMBOLS = ['x', 'k', 'p', 'y', 'w', 'h', 't', 'AMICI_EMPTY_BOLUS'] + try: import pysb except ImportError: diff --git a/python/amici/ode_model.py b/python/amici/ode_model.py index b9aeec8f77..60d44147d2 100644 --- a/python/amici/ode_model.py +++ b/python/amici/ode_model.py @@ -38,7 +38,7 @@ from .logging import get_logger, log_execution_time, set_log_level from .constants import SymbolId from .import_utils import smart_subs_dict, toposort_symbols, \ - ObservableTransformation, generate_measurement_symbol + ObservableTransformation, generate_measurement_symbol, RESERVED_SYMBOLS from .import_utils import cast_to_sym __all__ = [ @@ -70,6 +70,12 @@ def __init__(self, if not isinstance(identifier, sp.Symbol): raise TypeError(f'identifier must be sympy.Symbol, was ' f'{type(identifier)}') + + if str(identifier) in RESERVED_SYMBOLS or \ + (hasattr(identifier, 'name') and + identifier.name in RESERVED_SYMBOLS): + raise ValueError(f'Cannot add model quantity with name "{name}", ' + f'please rename.') self._identifier: sp.Symbol = identifier if not isinstance(name, str): diff --git a/python/amici/pysb_import.py b/python/amici/pysb_import.py index d8faf627a0..6c78d39f59 100644 --- a/python/amici/pysb_import.py +++ b/python/amici/pysb_import.py @@ -22,7 +22,8 @@ _parse_special_functions, generate_measurement_symbol, noise_distribution_to_cost_function, - noise_distribution_to_observable_transformation) + noise_distribution_to_observable_transformation, + RESERVED_SYMBOLS) from .logging import get_logger, log_execution_time, set_log_level from .ode_export import (Constant, Expression, LogLikelihood, ODEExporter, ODEModel, Observable, Parameter, SigmaY, State) diff --git a/python/amici/sbml_import.py b/python/amici/sbml_import.py index aa438f5233..4fd56d984e 100644 --- a/python/amici/sbml_import.py +++ b/python/amici/sbml_import.py @@ -26,7 +26,8 @@ generate_measurement_symbol, noise_distribution_to_cost_function, noise_distribution_to_observable_transformation, - smart_subs, smart_subs_dict, toposort_symbols) + smart_subs, smart_subs_dict, toposort_symbols, + RESERVED_SYMBOLS) from .logging import get_logger, log_execution_time, set_log_level from .ode_export import ( ODEExporter, ODEModel, symbol_with_assumptions @@ -1691,9 +1692,7 @@ def _clean_reserved_symbols(self) -> None: """ Remove all reserved symbols from self.symbols """ - reserved_symbols = ['x', 'k', 'p', 'y', 'w', 'h', 't', - 'AMICI_EMPTY_BOLUS'] - for sym in reserved_symbols: + for sym in RESERVED_SYMBOLS: old_symbol = symbol_with_assumptions(sym) new_symbol = symbol_with_assumptions(f'amici_{sym}') self._replace_in_all_expressions(old_symbol, new_symbol, diff --git a/python/sdist/amici/bngl_import.py b/python/sdist/amici/bngl_import.py new file mode 120000 index 0000000000..5aa807079a --- /dev/null +++ b/python/sdist/amici/bngl_import.py @@ -0,0 +1 @@ +../../amici/bngl_import.py \ No newline at end of file diff --git a/python/tests/test_bngl.py b/python/tests/test_bngl.py new file mode 100644 index 0000000000..212235ef63 --- /dev/null +++ b/python/tests/test_bngl.py @@ -0,0 +1,83 @@ +import pytest +import os +import amici +import shutil +import numpy as np + +pysb = pytest.importorskip("pysb") + +from amici.bngl_import import bngl2amici +from pysb.simulator import ScipyOdeSimulator +from pysb.importers.bngl import model_from_bngl + +tests = [ + 'CaOscillate_Func', 'deleteMolecules', 'empty_compartments_block', + 'gene_expr', 'gene_expr_func', 'gene_expr_simple', 'isomerization', + 'Motivating_example_cBNGL', 'motor', 'simple_system', + 'test_compartment_XML', 'test_setconc', 'test_synthesis_cBNGL_simple', + 'test_synthesis_complex', 'test_synthesis_complex_0_cBNGL', + 'test_synthesis_complex_source_cBNGL', 'test_synthesis_simple', + 'univ_synth', 'Repressilator', 'test_paramname', 'tlmr' +] + + +@pytest.mark.parametrize('example', tests) +def test_compare_to_pysb_simulation(example): + + atol = 1e-8 + rtol = 1e-8 + + model_file = os.path.join(os.path.dirname(__file__), '..', '..', + 'ThirdParty', 'BioNetGen-2.7.0', 'Validate', + f'{example}.bngl') + + pysb_model = model_from_bngl(model_file) + + # pysb part + tspan = np.linspace(0, 100, 101) + sim = ScipyOdeSimulator( + pysb_model, + tspan=tspan, + integrator_options={'rtol': rtol, 'atol': atol}, + compiler='python' + ) + pysb_simres = sim.run() + + # amici part + + outdir = pysb_model.name + + cl = example not in ['Motivating_example_cBNGL', 'univ_synth'] + + kwargs = { + 'compute_conservation_laws': cl, + 'observables': list(pysb_model.observables.keys()) + } + if not cl: + with pytest.raises(ValueError, match="Conservation laws"): + bngl2amici(model_file, outdir, compute_conservation_laws=True) + + if example in ['empty_compartments_block', 'motor']: + with pytest.raises(ValueError, match="Cannot add"): + bngl2amici(model_file, outdir, **kwargs) + return + else: + bngl2amici(model_file, outdir, **kwargs) + + amici_model_module = amici.import_model_module(pysb_model.name, + outdir) + + model_amici = amici_model_module.getModel() + + model_amici.setTimepoints(tspan) + + solver = model_amici.getSolver() + solver.setMaxSteps(10**6) + solver.setAbsoluteTolerance(atol) + solver.setRelativeTolerance(rtol) + rdata = amici.runAmiciSimulation(model_amici, solver) + + # check agreement of species simulation + assert np.isclose(rdata.x, pysb_simres.species, 1e-4, 1e-4).all() + + shutil.rmtree(outdir, ignore_errors=True) diff --git a/python/tests/test_pysb.py b/python/tests/test_pysb.py index de86865e22..ac7ea5b178 100644 --- a/python/tests/test_pysb.py +++ b/python/tests/test_pysb.py @@ -3,7 +3,6 @@ import importlib import logging import os -import platform import shutil import pytest From de3075e237afcb18767e4075c7421a44435d2371 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Sat, 12 Mar 2022 19:48:20 +0100 Subject: [PATCH 36/45] CI: performance test - increase time for creating sdist --- tests/performance/reference.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/performance/reference.yml b/tests/performance/reference.yml index 6d8c974166..b123a95d50 100644 --- a/tests/performance/reference.yml +++ b/tests/performance/reference.yml @@ -1,5 +1,5 @@ # Reference wall times (seconds) with some buffer -create_sdist: 12 +create_sdist: 15 install_sdist: 150 petab_import: 2100 install_model: 120 From 8b8141eea70821b21e9120418ada885a5c8bea79 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Sun, 13 Mar 2022 02:57:21 +0100 Subject: [PATCH 37/45] Don't repeat the same matrix multiplication for sx0_fixedParameters (#1718) ... instead save intermediate result --- python/amici/ode_export.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/python/amici/ode_export.py b/python/amici/ode_export.py index 007d3377fb..e18f837e6b 100644 --- a/python/amici/ode_export.py +++ b/python/amici/ode_export.py @@ -1434,10 +1434,9 @@ def _compute_equation(self, name: str) -> None: if not smart_is_zero_matrix(dx0_fixed_parametersdx): if isinstance(self._eqs[name], ImmutableDenseMatrix): self._eqs[name] = MutableDenseMatrix(self._eqs[name]) + tmp = smart_multiply(dx0_fixed_parametersdx, self.sym('sx0')) for ip in range(self._eqs[name].shape[1]): - self._eqs[name][:, ip] += smart_multiply( - dx0_fixed_parametersdx, self.sym('sx0') - ) + self._eqs[name][:, ip] += tmp elif name == 'x0_fixedParameters': k = self.sym('k') From 96b8b9d19fe95ca1c3b7fa76c5b4ee4945d5feb6 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Sun, 13 Mar 2022 02:57:42 +0100 Subject: [PATCH 38/45] Fix default value for `amici_import_petab --no-sensitivities` (#1717) * Fix default value for `amici_import_petab --no-sensitivities` Fixup for a366a63404e3ea94339ce36f01a72619052504cc (#1688) Due to wrong default value, sensitivity equations were never generated. * dtcldp - force symbols --- python/amici/ode_export.py | 4 ++++ python/amici/petab_import.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/python/amici/ode_export.py b/python/amici/ode_export.py index e18f837e6b..1a481a9d88 100644 --- a/python/amici/ode_export.py +++ b/python/amici/ode_export.py @@ -1458,6 +1458,10 @@ def _compute_equation(self, name: str) -> None: self._eqs[name] = \ sp.zeros(self.num_cons_law(), self.num_states_solver()) + elif name == 'dtcldp': + # force symbols + self._eqs[name] = self.sym(name) + elif name == 'dx_rdatadx_solver': if self.num_cons_law(): self._eqs[name] = smart_jacobian(self.eq('x_rdata'), diff --git a/python/amici/petab_import.py b/python/amici/petab_import.py index 0446570a14..e2b69e424a 100644 --- a/python/amici/petab_import.py +++ b/python/amici/petab_import.py @@ -715,7 +715,7 @@ def _parse_cli_args(): help='Flatten measurement specific overrides of ' 'observable and noise parameters') parser.add_argument('--no-sensitivities', dest='generate_sensitivity_code', - default=False, action='store_false', + default=True, action='store_false', help='Skip generation of sensitivity code') # Call with set of files From ca74a19feb571afd7a45704a83a50b58c49ccdf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Fr=C3=B6hlich?= Date: Sun, 13 Mar 2022 19:49:25 -0400 Subject: [PATCH 39/45] Use sparse matrix multiplications for sx_rdata (#1719) * sparsify python * cpp part * fixup & regenerate matlab * fixup cpp tests * fixup csc init * fixup * fixup * fix model dims * swig ignore * .. * fix serialization test * fix test * more serialization fixes Co-authored-by: Daniel Weindl --- include/amici/abstract_model.h | 24 ++++++++++++++++ include/amici/model.h | 4 +++ include/amici/model_dimensions.h | 14 ++++++++++ include/amici/model_state.h | 19 ++++++++----- matlab/@amimodel/generateC.m | 2 ++ models/model_calvetti/model_calvetti.h | 6 ++-- models/model_dirac/model_dirac.h | 6 ++-- models/model_events/model_events.h | 6 ++-- .../model_jakstat_adjoint.h | 6 ++-- .../model_jakstat_adjoint_o2.h | 6 ++-- .../model_nested_events/model_nested_events.h | 6 ++-- models/model_neuron/model_neuron.h | 6 ++-- models/model_neuron_o2/model_neuron_o2.h | 6 ++-- models/model_robertson/model_robertson.h | 6 ++-- models/model_steadystate/model_steadystate.h | 6 ++-- python/amici/ode_export.py | 12 ++++++-- src/abstract_model.cpp | 28 +++++++++++++++++++ src/model.cpp | 18 ++++++------ src/model_header.ODE_template.h | 10 +++++++ src/model_state.cpp | 11 +++----- swig/abstract_model.i | 4 +++ tests/cpp/unittests/testExpData.cpp | 2 ++ tests/cpp/unittests/testMisc.cpp | 4 +++ tests/cpp/unittests/testSerialization.cpp | 16 +++++++---- 24 files changed, 178 insertions(+), 50 deletions(-) diff --git a/include/amici/abstract_model.h b/include/amici/abstract_model.h index 28ee2db328..c56b84e8a1 100644 --- a/include/amici/abstract_model.h +++ b/include/amici/abstract_model.h @@ -882,6 +882,18 @@ class AbstractModel { virtual void fdx_rdatadx_solver(realtype *dx_rdatadx_solver, const realtype *x, const realtype *tcl, const realtype *p, const realtype *k); + + /** + * @brief Model-specific implementation of fdx_rdatadx_solver, colptrs part + * @param dxrdatadxsolver sparse matrix to which colptrs will be written + */ + virtual void fdx_rdatadx_solver_colptrs(SUNMatrixWrapper &dxrdatadxsolver); + + /** + * @brief Model-specific implementation of fdx_rdatadx_solver, rowvals part + * @param dxrdatadxsolver sparse matrix to which rowvals will be written + */ + virtual void fdx_rdatadx_solver_rowvals(SUNMatrixWrapper &dxrdatadxsolver); /** * @brief Compute dx_rdata / dp @@ -907,6 +919,18 @@ class AbstractModel { virtual void fdx_rdatadtcl(realtype *dx_rdatadtcl, const realtype *x, const realtype *tcl, const realtype *p, const realtype *k); + + /** + * @brief Model-specific implementation of fdx_rdatadtcl, colptrs part + * @param dx_rdatadtcl sparse matrix to which colptrs will be written + */ + virtual void fdx_rdatadtcl_colptrs(SUNMatrixWrapper &dx_rdatadtcl); + + /** + * @brief Model-specific implementation of fdx_rdatadtcl, rowvals part + * @param dx_rdatadtcl sparse matrix to which rowvals will be written + */ + virtual void fdx_rdatadtcl_rowvals(SUNMatrixWrapper &dx_rdatadtcl); /** * @brief Compute dtotal_cl / dp diff --git a/include/amici/model.h b/include/amici/model.h index 409617a29b..54b47242e5 100644 --- a/include/amici/model.h +++ b/include/amici/model.h @@ -147,8 +147,12 @@ class Model : public AbstractModel, public ModelDimensions { using AbstractModel::fy; using AbstractModel::fz; using AbstractModel::fdx_rdatadx_solver; + using AbstractModel::fdx_rdatadx_solver_colptrs; + using AbstractModel::fdx_rdatadx_solver_rowvals; using AbstractModel::fdx_rdatadp; using AbstractModel::fdx_rdatadtcl; + using AbstractModel::fdx_rdatadtcl_colptrs; + using AbstractModel::fdx_rdatadtcl_rowvals; using AbstractModel::fdtotal_cldx_rdata; using AbstractModel::fdtotal_cldp; diff --git a/include/amici/model_dimensions.h b/include/amici/model_dimensions.h index ca7f0f1af0..59933ff13a 100644 --- a/include/amici/model_dimensions.h +++ b/include/amici/model_dimensions.h @@ -41,6 +41,8 @@ struct ModelDimensions { * repeating elements * @param ndxdotdw Number of nonzero elements in the \f$ w\f$ derivative of \f$ xdot\f$ * @param ndJydy Number of nonzero elements in the \f$ y\f$ derivative of \f$ dJy\f$ (shape `nytrue`) + * @param ndxrdatadxsolver Number of nonzero elements in the \f$ x\f$ derivative of \f$ x_rdata\f$ + * @param ndxrdatadtcl Number of nonzero elements in the \f$ tcl\f$ derivative of \f$ x_rdata\f$ * @param nnz Number of nonzero elements in Jacobian * @param ubw Upper matrix bandwidth in the Jacobian * @param lbw Lower matrix bandwidth in the Jacobian @@ -52,6 +54,7 @@ struct ModelDimensions { const int nytrue, const int nz, const int nztrue, const int ne, const int nJ, const int nw, const int ndwdx, const int ndwdp, const int ndwdw, const int ndxdotdw, std::vector ndJydy, + const int ndxrdatadxsolver, const int ndxrdatadtcl, const int nnz, const int ubw, const int lbw) : nx_rdata(nx_rdata), nxtrue_rdata(nxtrue_rdata), nx_solver(nx_solver), nxtrue_solver(nxtrue_solver), nx_solver_reinit(nx_solver_reinit), @@ -59,6 +62,7 @@ struct ModelDimensions { ny(ny), nytrue(nytrue), nz(nz), nztrue(nztrue), ne(ne), nw(nw), ndwdx(ndwdx), ndwdp(ndwdp), ndwdw(ndwdw), ndxdotdw(ndxdotdw), ndJydy(std::move(ndJydy)), + ndxrdatadxsolver(ndxrdatadxsolver), ndxrdatadtcl(ndxrdatadtcl), nnz(nnz), nJ(nJ), ubw(ubw), lbw(lbw) { Expects(nxtrue_rdata >= 0); Expects(nxtrue_rdata <= nx_rdata); @@ -82,6 +86,10 @@ struct ModelDimensions { Expects(ndwdw >= 0); Expects(ndwdw <= nw * nw); Expects(ndxdotdw >= 0); + Expects(ndxrdatadxsolver >= 0); + Expects(ndxrdatadxsolver <= nx_rdata * nx_solver); + Expects(ndxrdatadtcl >= 0); + Expects(ndxrdatadtcl <= nx_rdata * (nx_rdata-nx_solver)); Expects(nnz >= 0); Expects(nJ >= 0); Expects(ubw >= 0); @@ -156,6 +164,12 @@ struct ModelDimensions { * \f$ dJy \f$ (dimension `nytrue`) */ std::vector ndJydy; + + /** Number of nonzero elements in the \f$ x \f$ derivative of \f$ x_rdata \f$ */ + int ndxrdatadxsolver{0}; + + /** Number of nonzero elements in the \f$ tcl\f$ derivative of \f$ x_rdata \f$ */ + int ndxrdatadtcl{0}; /** Number of nonzero entries in Jacobian */ int nnz{0}; diff --git a/include/amici/model_state.h b/include/amici/model_state.h index 42a000b4e3..ad17dc6793 100644 --- a/include/amici/model_state.h +++ b/include/amici/model_state.h @@ -115,6 +115,18 @@ struct ModelStateDerived { * type `CSC_MAT`) */ SUNMatrixWrapper dxdotdx_implicit; + + /** + * Temporary storage for `dx_rdatadx_solver` + * (dimension: `nx_rdata` x `nx_solver`, nnz: `ndxrdatadxsolver`, type: `CSC_MAT`) + */ + SUNMatrixWrapper dx_rdatadx_solver; + + /** + * Temporary storage for `dx_rdatadtcl` + * (dimension: `nx_rdata` x `ncl`, nnz: `ndxrdatadtclr`, type: `CSC_MAT`) + */ + SUNMatrixWrapper dx_rdatadtcl; /** * Temporary storage of `dxdotdp` data across functions, Matlab only @@ -222,13 +234,6 @@ struct ModelStateDerived { /** temporary storage for `sx_rdata` slice (dimension: `nx_rdata`) */ std::vector sx_rdata_; - /** temporary storage for `dx_rdatadx_solver` - * (dimension: `nx_rdata` x `nx_solver`) */ - std::vector dx_rdatadx_solver; - - /** temporary storage for `dx_rdatadtcl` (dimension: `nx_rdata` x `ncl`) */ - std::vector dx_rdatadtcl; - /** temporary storage for `dtotal_cldx_rdata` * (dimension: `ncl` x `nx_rdata`) */ std::vector dtotal_cldx_rdata; diff --git a/matlab/@amimodel/generateC.m b/matlab/@amimodel/generateC.m index d2d0435a32..c9f746dc90 100644 --- a/matlab/@amimodel/generateC.m +++ b/matlab/@amimodel/generateC.m @@ -170,6 +170,8 @@ function generateC(this) fprintf(fid,[' 0,\n']); fprintf(fid,[' 0,\n']); fprintf(fid,[' {},\n']); +fprintf(fid,[' 0,\n']); +fprintf(fid,[' 0,\n']); fprintf(fid,[' ' num2str(this.nnz) ',\n']); fprintf(fid,[' ' num2str(this.ubw) ',\n']); fprintf(fid,[' ' num2str(this.lbw) '\n']); diff --git a/models/model_calvetti/model_calvetti.h b/models/model_calvetti/model_calvetti.h index 41fe28a957..e267bf9daa 100644 --- a/models/model_calvetti/model_calvetti.h +++ b/models/model_calvetti/model_calvetti.h @@ -1,6 +1,6 @@ #ifndef _amici_model_calvetti_h #define _amici_model_calvetti_h -/* Generated by amiwrap (R2017b) e8e46ac8ec0c895549703eace15f2135fdb1747b */ +/* Generated by amiwrap (R2017b) 7d30aeae1966478050ba52aacc1760de3acebee3 */ #include #include #include "amici/defines.h" @@ -52,6 +52,8 @@ class Model_model_calvetti : public amici::Model_DAE { 0, 0, {}, + 0, + 0, 26, 5, 3 @@ -67,7 +69,7 @@ class Model_model_calvetti : public amici::Model_DAE { amici::Model* clone() const override { return new Model_model_calvetti(*this); }; - std::string getAmiciCommit() const override { return "e8e46ac8ec0c895549703eace15f2135fdb1747b"; }; + std::string getAmiciCommit() const override { return "7d30aeae1966478050ba52aacc1760de3acebee3"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype cj, const realtype *dx, const realtype *w, const realtype *dwdx) override { JSparse_model_calvetti(JSparse, t, x, p, k, h, cj, dx, w, dwdx); diff --git a/models/model_dirac/model_dirac.h b/models/model_dirac/model_dirac.h index a379b3ea24..9b765fe867 100644 --- a/models/model_dirac/model_dirac.h +++ b/models/model_dirac/model_dirac.h @@ -1,6 +1,6 @@ #ifndef _amici_model_dirac_h #define _amici_model_dirac_h -/* Generated by amiwrap (R2017b) e8e46ac8ec0c895549703eace15f2135fdb1747b */ +/* Generated by amiwrap (R2017b) 7d30aeae1966478050ba52aacc1760de3acebee3 */ #include #include #include "amici/defines.h" @@ -52,6 +52,8 @@ class Model_model_dirac : public amici::Model_ODE { 0, 0, {}, + 0, + 0, 3, 0, 1 @@ -67,7 +69,7 @@ class Model_model_dirac : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_dirac(*this); }; - std::string getAmiciCommit() const override { return "e8e46ac8ec0c895549703eace15f2135fdb1747b"; }; + std::string getAmiciCommit() const override { return "7d30aeae1966478050ba52aacc1760de3acebee3"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_dirac(JSparse, t, x, p, k, h, w, dwdx); diff --git a/models/model_events/model_events.h b/models/model_events/model_events.h index c83b1dbe62..b5c4cb1505 100644 --- a/models/model_events/model_events.h +++ b/models/model_events/model_events.h @@ -1,6 +1,6 @@ #ifndef _amici_model_events_h #define _amici_model_events_h -/* Generated by amiwrap (R2017b) e8e46ac8ec0c895549703eace15f2135fdb1747b */ +/* Generated by amiwrap (R2017b) 7d30aeae1966478050ba52aacc1760de3acebee3 */ #include #include #include "amici/defines.h" @@ -66,6 +66,8 @@ class Model_model_events : public amici::Model_ODE { 0, 0, {}, + 0, + 0, 4, 0, 1 @@ -81,7 +83,7 @@ class Model_model_events : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_events(*this); }; - std::string getAmiciCommit() const override { return "e8e46ac8ec0c895549703eace15f2135fdb1747b"; }; + std::string getAmiciCommit() const override { return "7d30aeae1966478050ba52aacc1760de3acebee3"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_events(JSparse, t, x, p, k, h, w, dwdx); diff --git a/models/model_jakstat_adjoint/model_jakstat_adjoint.h b/models/model_jakstat_adjoint/model_jakstat_adjoint.h index 5ec0de560d..28addfd0e0 100644 --- a/models/model_jakstat_adjoint/model_jakstat_adjoint.h +++ b/models/model_jakstat_adjoint/model_jakstat_adjoint.h @@ -1,6 +1,6 @@ #ifndef _amici_model_jakstat_adjoint_h #define _amici_model_jakstat_adjoint_h -/* Generated by amiwrap (R2017b) e8e46ac8ec0c895549703eace15f2135fdb1747b */ +/* Generated by amiwrap (R2017b) 7d30aeae1966478050ba52aacc1760de3acebee3 */ #include #include #include "amici/defines.h" @@ -55,6 +55,8 @@ class Model_model_jakstat_adjoint : public amici::Model_ODE { 0, 0, {}, + 0, + 0, 18, 8, 1 @@ -70,7 +72,7 @@ class Model_model_jakstat_adjoint : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_jakstat_adjoint(*this); }; - std::string getAmiciCommit() const override { return "e8e46ac8ec0c895549703eace15f2135fdb1747b"; }; + std::string getAmiciCommit() const override { return "7d30aeae1966478050ba52aacc1760de3acebee3"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_jakstat_adjoint(JSparse, t, x, p, k, h, w, dwdx); diff --git a/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h b/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h index d8a0167aad..ae7225237f 100644 --- a/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h +++ b/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h @@ -1,6 +1,6 @@ #ifndef _amici_model_jakstat_adjoint_o2_h #define _amici_model_jakstat_adjoint_o2_h -/* Generated by amiwrap (R2017b) e8e46ac8ec0c895549703eace15f2135fdb1747b */ +/* Generated by amiwrap (R2017b) 7d30aeae1966478050ba52aacc1760de3acebee3 */ #include #include #include "amici/defines.h" @@ -55,6 +55,8 @@ class Model_model_jakstat_adjoint_o2 : public amici::Model_ODE { 0, 0, {}, + 0, + 0, 384, 8, 154 @@ -70,7 +72,7 @@ class Model_model_jakstat_adjoint_o2 : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_jakstat_adjoint_o2(*this); }; - std::string getAmiciCommit() const override { return "e8e46ac8ec0c895549703eace15f2135fdb1747b"; }; + std::string getAmiciCommit() const override { return "7d30aeae1966478050ba52aacc1760de3acebee3"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_jakstat_adjoint_o2(JSparse, t, x, p, k, h, w, dwdx); diff --git a/models/model_nested_events/model_nested_events.h b/models/model_nested_events/model_nested_events.h index bcc1969455..5c5507ea40 100644 --- a/models/model_nested_events/model_nested_events.h +++ b/models/model_nested_events/model_nested_events.h @@ -1,6 +1,6 @@ #ifndef _amici_model_nested_events_h #define _amici_model_nested_events_h -/* Generated by amiwrap (R2017b) e8e46ac8ec0c895549703eace15f2135fdb1747b */ +/* Generated by amiwrap (R2017b) 7d30aeae1966478050ba52aacc1760de3acebee3 */ #include #include #include "amici/defines.h" @@ -55,6 +55,8 @@ class Model_model_nested_events : public amici::Model_ODE { 0, 0, {}, + 0, + 0, 1, 0, 0 @@ -70,7 +72,7 @@ class Model_model_nested_events : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_nested_events(*this); }; - std::string getAmiciCommit() const override { return "e8e46ac8ec0c895549703eace15f2135fdb1747b"; }; + std::string getAmiciCommit() const override { return "7d30aeae1966478050ba52aacc1760de3acebee3"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_nested_events(JSparse, t, x, p, k, h, w, dwdx); diff --git a/models/model_neuron/model_neuron.h b/models/model_neuron/model_neuron.h index d32f24c4fd..d57b69be06 100644 --- a/models/model_neuron/model_neuron.h +++ b/models/model_neuron/model_neuron.h @@ -1,6 +1,6 @@ #ifndef _amici_model_neuron_h #define _amici_model_neuron_h -/* Generated by amiwrap (R2017b) e8e46ac8ec0c895549703eace15f2135fdb1747b */ +/* Generated by amiwrap (R2017b) 7d30aeae1966478050ba52aacc1760de3acebee3 */ #include #include #include "amici/defines.h" @@ -69,6 +69,8 @@ class Model_model_neuron : public amici::Model_ODE { 0, 0, {}, + 0, + 0, 4, 1, 1 @@ -84,7 +86,7 @@ class Model_model_neuron : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_neuron(*this); }; - std::string getAmiciCommit() const override { return "e8e46ac8ec0c895549703eace15f2135fdb1747b"; }; + std::string getAmiciCommit() const override { return "7d30aeae1966478050ba52aacc1760de3acebee3"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_neuron(JSparse, t, x, p, k, h, w, dwdx); diff --git a/models/model_neuron_o2/model_neuron_o2.h b/models/model_neuron_o2/model_neuron_o2.h index c3879526c3..75cc64c7f0 100644 --- a/models/model_neuron_o2/model_neuron_o2.h +++ b/models/model_neuron_o2/model_neuron_o2.h @@ -1,6 +1,6 @@ #ifndef _amici_model_neuron_o2_h #define _amici_model_neuron_o2_h -/* Generated by amiwrap (R2017b) e8e46ac8ec0c895549703eace15f2135fdb1747b */ +/* Generated by amiwrap (R2017b) 7d30aeae1966478050ba52aacc1760de3acebee3 */ #include #include #include "amici/defines.h" @@ -71,6 +71,8 @@ class Model_model_neuron_o2 : public amici::Model_ODE { 0, 0, {}, + 0, + 0, 27, 1, 8 @@ -86,7 +88,7 @@ class Model_model_neuron_o2 : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_neuron_o2(*this); }; - std::string getAmiciCommit() const override { return "e8e46ac8ec0c895549703eace15f2135fdb1747b"; }; + std::string getAmiciCommit() const override { return "7d30aeae1966478050ba52aacc1760de3acebee3"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_neuron_o2(JSparse, t, x, p, k, h, w, dwdx); diff --git a/models/model_robertson/model_robertson.h b/models/model_robertson/model_robertson.h index 7e0756ffef..8d208e17e5 100644 --- a/models/model_robertson/model_robertson.h +++ b/models/model_robertson/model_robertson.h @@ -1,6 +1,6 @@ #ifndef _amici_model_robertson_h #define _amici_model_robertson_h -/* Generated by amiwrap (R2017b) e8e46ac8ec0c895549703eace15f2135fdb1747b */ +/* Generated by amiwrap (R2017b) 7d30aeae1966478050ba52aacc1760de3acebee3 */ #include #include #include "amici/defines.h" @@ -53,6 +53,8 @@ class Model_model_robertson : public amici::Model_DAE { 0, 0, {}, + 0, + 0, 9, 2, 2 @@ -68,7 +70,7 @@ class Model_model_robertson : public amici::Model_DAE { amici::Model* clone() const override { return new Model_model_robertson(*this); }; - std::string getAmiciCommit() const override { return "e8e46ac8ec0c895549703eace15f2135fdb1747b"; }; + std::string getAmiciCommit() const override { return "7d30aeae1966478050ba52aacc1760de3acebee3"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype cj, const realtype *dx, const realtype *w, const realtype *dwdx) override { JSparse_model_robertson(JSparse, t, x, p, k, h, cj, dx, w, dwdx); diff --git a/models/model_steadystate/model_steadystate.h b/models/model_steadystate/model_steadystate.h index dfbddbd850..6d55a1c8db 100644 --- a/models/model_steadystate/model_steadystate.h +++ b/models/model_steadystate/model_steadystate.h @@ -1,6 +1,6 @@ #ifndef _amici_model_steadystate_h #define _amici_model_steadystate_h -/* Generated by amiwrap (R2017b) e8e46ac8ec0c895549703eace15f2135fdb1747b */ +/* Generated by amiwrap (R2017b) 7d30aeae1966478050ba52aacc1760de3acebee3 */ #include #include #include "amici/defines.h" @@ -52,6 +52,8 @@ class Model_model_steadystate : public amici::Model_ODE { 0, 0, {}, + 0, + 0, 9, 2, 2 @@ -67,7 +69,7 @@ class Model_model_steadystate : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_steadystate(*this); }; - std::string getAmiciCommit() const override { return "e8e46ac8ec0c895549703eace15f2135fdb1747b"; }; + std::string getAmiciCommit() const override { return "7d30aeae1966478050ba52aacc1760de3acebee3"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_steadystate(JSparse, t, x, p, k, h, w, dwdx); diff --git a/python/amici/ode_export.py b/python/amici/ode_export.py index 1a481a9d88..afa198b00c 100644 --- a/python/amici/ode_export.py +++ b/python/amici/ode_export.py @@ -293,7 +293,8 @@ class _FunctionInfo: 'dx_rdatadx_solver': _FunctionInfo( 'realtype *dx_rdatadx_solver, const realtype *x, ' - 'const realtype *tcl, const realtype *p, const realtype *k' + 'const realtype *tcl, const realtype *p, const realtype *k', + sparse=True ), 'dx_rdatadp': _FunctionInfo( @@ -304,7 +305,8 @@ class _FunctionInfo: 'dx_rdatadtcl': _FunctionInfo( 'realtype *dx_rdatadtcl, const realtype *x, ' - 'const realtype *tcl, const realtype *p, const realtype *k' + 'const realtype *tcl, const realtype *p, const realtype *k', + sparse=True ), } @@ -2803,6 +2805,12 @@ def _write_model_header_cpp(self) -> None: 'NDJYDY': 'std::vector{%s}' % ','.join(str(len(x)) for x in self.model.sparsesym('dJydy')), + 'NDXRDATADXSOLVER': str( + len(self.model.sparsesym('dx_rdatadx_solver')) + ), + 'NDXRDATADTCL': str( + len(self.model.sparsesym('dx_rdatadtcl')) + ), 'UBW': str(self.model.num_states_solver()), 'LBW': str(self.model.num_states_solver()), 'NP': str(self.model.num_par()), diff --git a/src/abstract_model.cpp b/src/abstract_model.cpp index 0d860de3c6..1f8f0ecdae 100644 --- a/src/abstract_model.cpp +++ b/src/abstract_model.cpp @@ -663,6 +663,20 @@ void AbstractModel::fdx_rdatadx_solver(realtype */*dx_rdatadx_solver*/, __func__); } +void AbstractModel::fdx_rdatadx_solver_rowvals(SUNMatrixWrapper &/*dxrdxs*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + +void AbstractModel::fdx_rdatadx_solver_colptrs(SUNMatrixWrapper &/*dxrdxs*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + void AbstractModel::fdx_rdatadp(realtype */*dx_rdatadp*/, const realtype */*x*/, const realtype */*tcl*/, const realtype */*p*/, const realtype */*k*/, const int /*ip*/) @@ -681,6 +695,20 @@ void AbstractModel::fdx_rdatadtcl(realtype */*dx_rdatadtcl*/, const realtype */* __func__); } +void AbstractModel::fdx_rdatadtcl_rowvals(SUNMatrixWrapper &/*dxrdtcl*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + +void AbstractModel::fdx_rdatadtcl_colptrs(SUNMatrixWrapper &/*dxrdtcl*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + void AbstractModel::fdtotal_cldp(realtype */*dtotal_cldp*/, const realtype */*x_rdata*/, const realtype */*p*/, diff --git a/src/model.cpp b/src/model.cpp index b8088b655f..ec4dbf3818 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -2205,19 +2205,21 @@ void Model::fsx_rdata(realtype *sx_rdata, const realtype *sx_solver, // 2) sx_rdata(nx_rdata, 1) += // dx_rdata/dx_solver(nx_rdata,nx_solver) * sx_solver(nx_solver, 1) - derived_state_.dx_rdatadx_solver.assign(nx_rdata * nx_solver, 0.0); + derived_state_.dx_rdatadx_solver.zero(); fdx_rdatadx_solver(derived_state_.dx_rdatadx_solver.data(), x_solver, tcl, p, k); - amici_dgemv(BLASLayout::rowMajor, BLASTranspose::noTrans, nx_rdata, - nx_solver, 1.0, derived_state_.dx_rdatadx_solver.data(), - nx_solver, sx_solver, 1, 1.0, sx_rdata, 1); + fdx_rdatadx_solver_colptrs(derived_state_.dx_rdatadx_solver); + fdx_rdatadx_solver_rowvals(derived_state_.dx_rdatadx_solver); + derived_state_.dx_rdatadx_solver.multiply(gsl::make_span(sx_rdata, nx_rdata), + gsl::make_span(sx_solver, nx_solver)); // 3) sx_rdata(nx_rdata, 1) += dx_rdata/d_tcl(nx_rdata,ntcl) * stcl - derived_state_.dx_rdatadtcl.assign(nx_rdata * (nx_rdata - nx_solver), 0.0); + derived_state_.dx_rdatadtcl.zero(); fdx_rdatadtcl(derived_state_.dx_rdatadtcl.data(), x_solver, tcl, p, k); - amici_dgemv(BLASLayout::rowMajor, BLASTranspose::noTrans, nx_rdata, - nx_rdata - nx_solver, 1.0, derived_state_.dx_rdatadtcl.data(), - ncl(), stcl, 1, 1.0, sx_rdata, 1); + fdx_rdatadtcl_colptrs(derived_state_.dx_rdatadtcl); + fdx_rdatadtcl_rowvals(derived_state_.dx_rdatadtcl); + derived_state_.dx_rdatadtcl.multiply(gsl::make_span(sx_rdata, nx_rdata), + gsl::make_span(stcl, (nx_rdata - nx_solver))); } void Model::fx_solver(realtype *x_solver, const realtype *x_rdata) { diff --git a/src/model_header.ODE_template.h b/src/model_header.ODE_template.h index db507fcd9d..e1b894b147 100644 --- a/src/model_header.ODE_template.h +++ b/src/model_header.ODE_template.h @@ -71,8 +71,12 @@ TPL_X_RDATA_DEF TPL_X_SOLVER_DEF TPL_TOTAL_CL_DEF TPL_DX_RDATADX_SOLVER_DEF +TPL_DX_RDATADX_SOLVER_COLPTRS_DEF +TPL_DX_RDATADX_SOLVER_ROWVALS_DEF TPL_DX_RDATADP_DEF TPL_DX_RDATADTCL_DEF +TPL_DX_RDATADTCL_COLPTRS_DEF +TPL_DX_RDATADTCL_ROWVALS_DEF TPL_DTOTAL_CLDP_DEF TPL_DTOTAL_CLDX_RDATA_DEF @@ -106,6 +110,8 @@ class Model_TPL_MODELNAME : public amici::Model_ODE { TPL_NDWDW, // ndwdw TPL_NDXDOTDW, // ndxdotdw TPL_NDJYDY, // ndjydy + TPL_NDXRDATADXSOLVER, // ndxrdatadxsolver + TPL_NDXRDATADTCL, // ndxrdatadtcl 0, // nnz TPL_UBW, // ubw TPL_LBW // lbw @@ -473,10 +479,14 @@ class Model_TPL_MODELNAME : public amici::Model_ODE { TPL_TOTAL_CL_IMPL TPL_DX_RDATADX_SOLVER_IMPL + TPL_DX_RDATADX_SOLVER_COLPTRS_IMPL + TPL_DX_RDATADX_SOLVER_ROWVALS_IMPL TPL_DX_RDATADP_IMPL TPL_DX_RDATADTCL_IMPL + TPL_DX_RDATADTCL_COLPTRS_IMPL + TPL_DX_RDATADTCL_ROWVALS_IMPL TPL_DTOTAL_CLDP_IMPL diff --git a/src/model_state.cpp b/src/model_state.cpp index 52800f59ba..19a0ae939c 100644 --- a/src/model_state.cpp +++ b/src/model_state.cpp @@ -6,17 +6,14 @@ ModelStateDerived::ModelStateDerived(const ModelDimensions &dim) : J_(dim.nx_solver, dim.nx_solver, dim.nnz, CSC_MAT), JB_(dim.nx_solver, dim.nx_solver, dim.nnz, CSC_MAT), dxdotdw_(dim.nx_solver, dim.nw, dim.ndxdotdw, CSC_MAT), + dx_rdatadx_solver(dim.nx_rdata, dim.nx_solver, dim.ndxrdatadxsolver, + CSC_MAT), + dx_rdatadtcl(dim.nx_rdata, dim.nx_rdata - dim.nx_solver, dim.ndxrdatadtcl, + CSC_MAT), w_(dim.nw), x_rdata_(dim.nx_rdata, 0.0), sx_rdata_(dim.nx_rdata, 0.0), // only required if there are conservation laws - dx_rdatadx_solver(dim.nx_rdata - dim.nx_solver > 0 - ? dim.nx_rdata * dim.nx_solver : 0, 0.0), - // only required if there are conservation laws - dx_rdatadtcl(dim.nx_rdata - dim.nx_solver > 0 - ? dim.nx_rdata * (dim.nx_rdata - dim.nx_solver) : 0, - 0.0), - // only required if there are conservation laws dtotal_cldx_rdata(dim.nx_rdata - dim.nx_solver > 0 ? (dim.nx_rdata - dim.nx_solver) * dim.nx_rdata : 0, 0.0), diff --git a/swig/abstract_model.i b/swig/abstract_model.i index 73cbe9139a..a507d7e3d5 100644 --- a/swig/abstract_model.i +++ b/swig/abstract_model.i @@ -62,5 +62,9 @@ %ignore fx0_fixedParameters; %ignore fsx0; %ignore fsx0_fixedParameters; +%ignore fdx_rdatadtcl_colptrs; +%ignore fdx_rdatadtcl_rowvals; +%ignore fdx_rdatadx_solver_colptrs; +%ignore fdx_rdatadx_solver_rowvals; %include "amici/abstract_model.h" diff --git a/tests/cpp/unittests/testExpData.cpp b/tests/cpp/unittests/testExpData.cpp index 4cf947341c..152d25246b 100644 --- a/tests/cpp/unittests/testExpData.cpp +++ b/tests/cpp/unittests/testExpData.cpp @@ -56,6 +56,8 @@ class ExpDataTest : public ::testing::Test { 0, // dwdw 0, // ndxdotdw {}, // ndJydy + 0, // ndxrdatadxsolver + 0, // ndxrdatadtcl 0, // nnz 0, // ubw 0 // lbw diff --git a/tests/cpp/unittests/testMisc.cpp b/tests/cpp/unittests/testMisc.cpp index 686330f4f8..0b9521c258 100644 --- a/tests/cpp/unittests/testMisc.cpp +++ b/tests/cpp/unittests/testMisc.cpp @@ -71,6 +71,8 @@ class ModelTest : public ::testing::Test { 0, // dwdw 0, // ndxdotdw {}, // ndJydy + 0, // ndxrdatadxsolver + 0, // ndxrdatadtcl 0, // nnz 0, // ubw 0 // lbw @@ -305,6 +307,8 @@ class SolverTest : public ::testing::Test { 0, // dwdw 0, // ndxdotdw {}, // ndJydy + 0, // ndxrdatadxsolver + 0, // ndxrdatadtcl 1, // nnz 0, // ubw 0 // lbw diff --git a/tests/cpp/unittests/testSerialization.cpp b/tests/cpp/unittests/testSerialization.cpp index f349424408..557e50e8a0 100644 --- a/tests/cpp/unittests/testSerialization.cpp +++ b/tests/cpp/unittests/testSerialization.cpp @@ -153,9 +153,11 @@ TEST(ModelSerializationTest, ToFile) 2, // dwdw 13, // ndxdotdw {}, // ndJydy - 15, // nnz - 16, // ubw - 17 // lbw + 9, // ndxrdatadxsolver + 0, // ndxrdatadtcl + 17, // nnz + 18, // ubw + 19 // lbw ), amici::SimulationParameters( std::vector(nk, 0.0), @@ -214,9 +216,11 @@ TEST(ReturnDataSerializationTest, ToString) 12, // dwdw 13, // ndxdotdw {}, // ndJydy - 15, // nnz - 16, // ubw - 17 // lbw + 9, // ndxrdatadxsolver + 0, // ndxrdatadtcl + 17, // nnz + 18, // ubw + 19 // lbw ), amici::SimulationParameters( std::vector(nk, 0.0), From 1567abb94950eb4c00ba9db942fd00a71eaf0227 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Mon, 14 Mar 2022 11:28:53 +0100 Subject: [PATCH 40/45] Use sparse matrix multiplications for stotal_cl (#1720) Significantly faster than previous dense multiplications for large models. --- include/amici/abstract_model.h | 18 +++++++++++-- include/amici/model.h | 2 ++ include/amici/model_dimensions.h | 26 ++++++++++++++----- include/amici/model_state.h | 13 ++++++---- matlab/@amimodel/generateC.m | 1 + models/model_calvetti/model_calvetti.h | 5 ++-- models/model_dirac/model_dirac.h | 5 ++-- models/model_events/model_events.h | 5 ++-- .../model_jakstat_adjoint.h | 5 ++-- .../model_jakstat_adjoint_o2.h | 5 ++-- .../model_nested_events/model_nested_events.h | 5 ++-- models/model_neuron/model_neuron.h | 5 ++-- models/model_neuron_o2/model_neuron_o2.h | 5 ++-- models/model_robertson/model_robertson.h | 5 ++-- models/model_steadystate/model_steadystate.h | 5 ++-- python/amici/ode_export.py | 18 ++++++++++--- src/abstract_model.cpp | 16 ++++++++++++ src/model.cpp | 11 ++++---- src/model_header.ODE_template.h | 6 ++++- src/model_state.cpp | 6 ++--- swig/abstract_model.i | 3 ++- tests/cpp/unittests/testExpData.cpp | 1 + tests/cpp/unittests/testMisc.cpp | 8 +++--- tests/cpp/unittests/testSerialization.cpp | 2 ++ 24 files changed, 131 insertions(+), 50 deletions(-) diff --git a/include/amici/abstract_model.h b/include/amici/abstract_model.h index c56b84e8a1..2d703a93ba 100644 --- a/include/amici/abstract_model.h +++ b/include/amici/abstract_model.h @@ -882,7 +882,7 @@ class AbstractModel { virtual void fdx_rdatadx_solver(realtype *dx_rdatadx_solver, const realtype *x, const realtype *tcl, const realtype *p, const realtype *k); - + /** * @brief Model-specific implementation of fdx_rdatadx_solver, colptrs part * @param dxrdatadxsolver sparse matrix to which colptrs will be written @@ -919,7 +919,7 @@ class AbstractModel { virtual void fdx_rdatadtcl(realtype *dx_rdatadtcl, const realtype *x, const realtype *tcl, const realtype *p, const realtype *k); - + /** * @brief Model-specific implementation of fdx_rdatadtcl, colptrs part * @param dx_rdatadtcl sparse matrix to which colptrs will be written @@ -956,6 +956,20 @@ class AbstractModel { const realtype *x_rdata, const realtype *p, const realtype *k, const realtype *tcl); + /** + * @brief Model-specific implementation of fdtotal_cldx_rdata, colptrs part + * @param dtotal_cldx_rdata sparse matrix to which colptrs will be written + */ + virtual void fdtotal_cldx_rdata_colptrs( + SUNMatrixWrapper &dtotal_cldx_rdata); + + /** + * @brief Model-specific implementation of fdtotal_cldx_rdata, rowvals part + * @param dtotal_cldx_rdata sparse matrix to which rowvals will be written + */ + virtual void fdtotal_cldx_rdata_rowvals( + SUNMatrixWrapper &dtotal_cldx_rdata); + }; } // namespace amici diff --git a/include/amici/model.h b/include/amici/model.h index 54b47242e5..fac088af2c 100644 --- a/include/amici/model.h +++ b/include/amici/model.h @@ -154,6 +154,8 @@ class Model : public AbstractModel, public ModelDimensions { using AbstractModel::fdx_rdatadtcl_colptrs; using AbstractModel::fdx_rdatadtcl_rowvals; using AbstractModel::fdtotal_cldx_rdata; + using AbstractModel::fdtotal_cldx_rdata_colptrs; + using AbstractModel::fdtotal_cldx_rdata_rowvals; using AbstractModel::fdtotal_cldp; /** diff --git a/include/amici/model_dimensions.h b/include/amici/model_dimensions.h index 59933ff13a..eb53756e44 100644 --- a/include/amici/model_dimensions.h +++ b/include/amici/model_dimensions.h @@ -39,10 +39,16 @@ struct ModelDimensions { * repeating elements * @param ndwdw Number of nonzero elements in the `w` derivative of the * repeating elements - * @param ndxdotdw Number of nonzero elements in the \f$ w\f$ derivative of \f$ xdot\f$ - * @param ndJydy Number of nonzero elements in the \f$ y\f$ derivative of \f$ dJy\f$ (shape `nytrue`) - * @param ndxrdatadxsolver Number of nonzero elements in the \f$ x\f$ derivative of \f$ x_rdata\f$ - * @param ndxrdatadtcl Number of nonzero elements in the \f$ tcl\f$ derivative of \f$ x_rdata\f$ + * @param ndxdotdw Number of nonzero elements in the \f$ w\f$ derivative of + * \f$ xdot\f$ + * @param ndJydy Number of nonzero elements in the \f$ y\f$ derivative of + * \f$ dJy\f$ (shape `nytrue`) + * @param ndxrdatadxsolver Number of nonzero elements in the \f$ x\f$ + * derivative of \f$ x_rdata\f$ + * @param ndxrdatadtcl Number of nonzero elements in the \f$ tcl\f$ + * derivative of \f$ x_rdata\f$ + * @param ndtotal_cldx_rdata Number of nonzero elements in the + * \f$ x_rdata \f$ derivative of \f$ total_cl \f$ * @param nnz Number of nonzero elements in Jacobian * @param ubw Upper matrix bandwidth in the Jacobian * @param lbw Lower matrix bandwidth in the Jacobian @@ -55,6 +61,7 @@ struct ModelDimensions { const int nJ, const int nw, const int ndwdx, const int ndwdp, const int ndwdw, const int ndxdotdw, std::vector ndJydy, const int ndxrdatadxsolver, const int ndxrdatadtcl, + const int ndtotal_cldx_rdata, const int nnz, const int ubw, const int lbw) : nx_rdata(nx_rdata), nxtrue_rdata(nxtrue_rdata), nx_solver(nx_solver), nxtrue_solver(nxtrue_solver), nx_solver_reinit(nx_solver_reinit), @@ -63,6 +70,7 @@ struct ModelDimensions { ne(ne), nw(nw), ndwdx(ndwdx), ndwdp(ndwdp), ndwdw(ndwdw), ndxdotdw(ndxdotdw), ndJydy(std::move(ndJydy)), ndxrdatadxsolver(ndxrdatadxsolver), ndxrdatadtcl(ndxrdatadtcl), + ndtotal_cldx_rdata(ndtotal_cldx_rdata), nnz(nnz), nJ(nJ), ubw(ubw), lbw(lbw) { Expects(nxtrue_rdata >= 0); Expects(nxtrue_rdata <= nx_rdata); @@ -90,6 +98,8 @@ struct ModelDimensions { Expects(ndxrdatadxsolver <= nx_rdata * nx_solver); Expects(ndxrdatadtcl >= 0); Expects(ndxrdatadtcl <= nx_rdata * (nx_rdata-nx_solver)); + Expects(ndtotal_cldx_rdata >= 0); + Expects(ndtotal_cldx_rdata <= (nx_rdata-nx_solver) * nx_rdata); Expects(nnz >= 0); Expects(nJ >= 0); Expects(ubw >= 0); @@ -164,13 +174,17 @@ struct ModelDimensions { * \f$ dJy \f$ (dimension `nytrue`) */ std::vector ndJydy; - + /** Number of nonzero elements in the \f$ x \f$ derivative of \f$ x_rdata \f$ */ int ndxrdatadxsolver{0}; - + /** Number of nonzero elements in the \f$ tcl\f$ derivative of \f$ x_rdata \f$ */ int ndxrdatadtcl{0}; + /** Number of nonzero elements in the \f$ x_rdata\f$ derivative of + * \f$ total_cl \f$ */ + int ndtotal_cldx_rdata{0}; + /** Number of nonzero entries in Jacobian */ int nnz{0}; diff --git a/include/amici/model_state.h b/include/amici/model_state.h index ad17dc6793..2523dce21f 100644 --- a/include/amici/model_state.h +++ b/include/amici/model_state.h @@ -115,7 +115,7 @@ struct ModelStateDerived { * type `CSC_MAT`) */ SUNMatrixWrapper dxdotdx_implicit; - + /** * Temporary storage for `dx_rdatadx_solver` * (dimension: `nx_rdata` x `nx_solver`, nnz: `ndxrdatadxsolver`, type: `CSC_MAT`) @@ -128,6 +128,13 @@ struct ModelStateDerived { */ SUNMatrixWrapper dx_rdatadtcl; + /** + * Temporary storage for `dtotal_cldx_rdata` + * (dimension: `ncl` x `nx_rdata`, nnz: `ndtotal_cldx_rdata`, + * type: `CSC_MAT`) + */ + SUNMatrixWrapper dtotal_cldx_rdata; + /** * Temporary storage of `dxdotdp` data across functions, Matlab only * (dimension: `nplist` x `nx_solver` , row-major) @@ -234,10 +241,6 @@ struct ModelStateDerived { /** temporary storage for `sx_rdata` slice (dimension: `nx_rdata`) */ std::vector sx_rdata_; - /** temporary storage for `dtotal_cldx_rdata` - * (dimension: `ncl` x `nx_rdata`) */ - std::vector dtotal_cldx_rdata; - /** temporary storage for time-resolved observable (dimension: ny) */ std::vector y_; diff --git a/matlab/@amimodel/generateC.m b/matlab/@amimodel/generateC.m index c9f746dc90..331b17ba6f 100644 --- a/matlab/@amimodel/generateC.m +++ b/matlab/@amimodel/generateC.m @@ -172,6 +172,7 @@ function generateC(this) fprintf(fid,[' {},\n']); fprintf(fid,[' 0,\n']); fprintf(fid,[' 0,\n']); +fprintf(fid,[' 0,\n']); fprintf(fid,[' ' num2str(this.nnz) ',\n']); fprintf(fid,[' ' num2str(this.ubw) ',\n']); fprintf(fid,[' ' num2str(this.lbw) '\n']); diff --git a/models/model_calvetti/model_calvetti.h b/models/model_calvetti/model_calvetti.h index e267bf9daa..10db9447c5 100644 --- a/models/model_calvetti/model_calvetti.h +++ b/models/model_calvetti/model_calvetti.h @@ -1,6 +1,6 @@ #ifndef _amici_model_calvetti_h #define _amici_model_calvetti_h -/* Generated by amiwrap (R2017b) 7d30aeae1966478050ba52aacc1760de3acebee3 */ +/* Generated by amiwrap (R2017b) ef4445d1c2b3241a8faa11a25a7729648b56300b */ #include #include #include "amici/defines.h" @@ -54,6 +54,7 @@ class Model_model_calvetti : public amici::Model_DAE { {}, 0, 0, + 0, 26, 5, 3 @@ -69,7 +70,7 @@ class Model_model_calvetti : public amici::Model_DAE { amici::Model* clone() const override { return new Model_model_calvetti(*this); }; - std::string getAmiciCommit() const override { return "7d30aeae1966478050ba52aacc1760de3acebee3"; }; + std::string getAmiciCommit() const override { return "ef4445d1c2b3241a8faa11a25a7729648b56300b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype cj, const realtype *dx, const realtype *w, const realtype *dwdx) override { JSparse_model_calvetti(JSparse, t, x, p, k, h, cj, dx, w, dwdx); diff --git a/models/model_dirac/model_dirac.h b/models/model_dirac/model_dirac.h index 9b765fe867..cc6ce2f222 100644 --- a/models/model_dirac/model_dirac.h +++ b/models/model_dirac/model_dirac.h @@ -1,6 +1,6 @@ #ifndef _amici_model_dirac_h #define _amici_model_dirac_h -/* Generated by amiwrap (R2017b) 7d30aeae1966478050ba52aacc1760de3acebee3 */ +/* Generated by amiwrap (R2017b) ef4445d1c2b3241a8faa11a25a7729648b56300b */ #include #include #include "amici/defines.h" @@ -54,6 +54,7 @@ class Model_model_dirac : public amici::Model_ODE { {}, 0, 0, + 0, 3, 0, 1 @@ -69,7 +70,7 @@ class Model_model_dirac : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_dirac(*this); }; - std::string getAmiciCommit() const override { return "7d30aeae1966478050ba52aacc1760de3acebee3"; }; + std::string getAmiciCommit() const override { return "ef4445d1c2b3241a8faa11a25a7729648b56300b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_dirac(JSparse, t, x, p, k, h, w, dwdx); diff --git a/models/model_events/model_events.h b/models/model_events/model_events.h index b5c4cb1505..16272b1be0 100644 --- a/models/model_events/model_events.h +++ b/models/model_events/model_events.h @@ -1,6 +1,6 @@ #ifndef _amici_model_events_h #define _amici_model_events_h -/* Generated by amiwrap (R2017b) 7d30aeae1966478050ba52aacc1760de3acebee3 */ +/* Generated by amiwrap (R2017b) ef4445d1c2b3241a8faa11a25a7729648b56300b */ #include #include #include "amici/defines.h" @@ -68,6 +68,7 @@ class Model_model_events : public amici::Model_ODE { {}, 0, 0, + 0, 4, 0, 1 @@ -83,7 +84,7 @@ class Model_model_events : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_events(*this); }; - std::string getAmiciCommit() const override { return "7d30aeae1966478050ba52aacc1760de3acebee3"; }; + std::string getAmiciCommit() const override { return "ef4445d1c2b3241a8faa11a25a7729648b56300b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_events(JSparse, t, x, p, k, h, w, dwdx); diff --git a/models/model_jakstat_adjoint/model_jakstat_adjoint.h b/models/model_jakstat_adjoint/model_jakstat_adjoint.h index 28addfd0e0..ffd1e7fe34 100644 --- a/models/model_jakstat_adjoint/model_jakstat_adjoint.h +++ b/models/model_jakstat_adjoint/model_jakstat_adjoint.h @@ -1,6 +1,6 @@ #ifndef _amici_model_jakstat_adjoint_h #define _amici_model_jakstat_adjoint_h -/* Generated by amiwrap (R2017b) 7d30aeae1966478050ba52aacc1760de3acebee3 */ +/* Generated by amiwrap (R2017b) ef4445d1c2b3241a8faa11a25a7729648b56300b */ #include #include #include "amici/defines.h" @@ -57,6 +57,7 @@ class Model_model_jakstat_adjoint : public amici::Model_ODE { {}, 0, 0, + 0, 18, 8, 1 @@ -72,7 +73,7 @@ class Model_model_jakstat_adjoint : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_jakstat_adjoint(*this); }; - std::string getAmiciCommit() const override { return "7d30aeae1966478050ba52aacc1760de3acebee3"; }; + std::string getAmiciCommit() const override { return "ef4445d1c2b3241a8faa11a25a7729648b56300b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_jakstat_adjoint(JSparse, t, x, p, k, h, w, dwdx); diff --git a/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h b/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h index ae7225237f..bec91a063e 100644 --- a/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h +++ b/models/model_jakstat_adjoint_o2/model_jakstat_adjoint_o2.h @@ -1,6 +1,6 @@ #ifndef _amici_model_jakstat_adjoint_o2_h #define _amici_model_jakstat_adjoint_o2_h -/* Generated by amiwrap (R2017b) 7d30aeae1966478050ba52aacc1760de3acebee3 */ +/* Generated by amiwrap (R2017b) ef4445d1c2b3241a8faa11a25a7729648b56300b */ #include #include #include "amici/defines.h" @@ -57,6 +57,7 @@ class Model_model_jakstat_adjoint_o2 : public amici::Model_ODE { {}, 0, 0, + 0, 384, 8, 154 @@ -72,7 +73,7 @@ class Model_model_jakstat_adjoint_o2 : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_jakstat_adjoint_o2(*this); }; - std::string getAmiciCommit() const override { return "7d30aeae1966478050ba52aacc1760de3acebee3"; }; + std::string getAmiciCommit() const override { return "ef4445d1c2b3241a8faa11a25a7729648b56300b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_jakstat_adjoint_o2(JSparse, t, x, p, k, h, w, dwdx); diff --git a/models/model_nested_events/model_nested_events.h b/models/model_nested_events/model_nested_events.h index 5c5507ea40..b40ec0e0fc 100644 --- a/models/model_nested_events/model_nested_events.h +++ b/models/model_nested_events/model_nested_events.h @@ -1,6 +1,6 @@ #ifndef _amici_model_nested_events_h #define _amici_model_nested_events_h -/* Generated by amiwrap (R2017b) 7d30aeae1966478050ba52aacc1760de3acebee3 */ +/* Generated by amiwrap (R2017b) ef4445d1c2b3241a8faa11a25a7729648b56300b */ #include #include #include "amici/defines.h" @@ -57,6 +57,7 @@ class Model_model_nested_events : public amici::Model_ODE { {}, 0, 0, + 0, 1, 0, 0 @@ -72,7 +73,7 @@ class Model_model_nested_events : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_nested_events(*this); }; - std::string getAmiciCommit() const override { return "7d30aeae1966478050ba52aacc1760de3acebee3"; }; + std::string getAmiciCommit() const override { return "ef4445d1c2b3241a8faa11a25a7729648b56300b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_nested_events(JSparse, t, x, p, k, h, w, dwdx); diff --git a/models/model_neuron/model_neuron.h b/models/model_neuron/model_neuron.h index d57b69be06..92a8e71262 100644 --- a/models/model_neuron/model_neuron.h +++ b/models/model_neuron/model_neuron.h @@ -1,6 +1,6 @@ #ifndef _amici_model_neuron_h #define _amici_model_neuron_h -/* Generated by amiwrap (R2017b) 7d30aeae1966478050ba52aacc1760de3acebee3 */ +/* Generated by amiwrap (R2017b) ef4445d1c2b3241a8faa11a25a7729648b56300b */ #include #include #include "amici/defines.h" @@ -71,6 +71,7 @@ class Model_model_neuron : public amici::Model_ODE { {}, 0, 0, + 0, 4, 1, 1 @@ -86,7 +87,7 @@ class Model_model_neuron : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_neuron(*this); }; - std::string getAmiciCommit() const override { return "7d30aeae1966478050ba52aacc1760de3acebee3"; }; + std::string getAmiciCommit() const override { return "ef4445d1c2b3241a8faa11a25a7729648b56300b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_neuron(JSparse, t, x, p, k, h, w, dwdx); diff --git a/models/model_neuron_o2/model_neuron_o2.h b/models/model_neuron_o2/model_neuron_o2.h index 75cc64c7f0..800e76282a 100644 --- a/models/model_neuron_o2/model_neuron_o2.h +++ b/models/model_neuron_o2/model_neuron_o2.h @@ -1,6 +1,6 @@ #ifndef _amici_model_neuron_o2_h #define _amici_model_neuron_o2_h -/* Generated by amiwrap (R2017b) 7d30aeae1966478050ba52aacc1760de3acebee3 */ +/* Generated by amiwrap (R2017b) ef4445d1c2b3241a8faa11a25a7729648b56300b */ #include #include #include "amici/defines.h" @@ -73,6 +73,7 @@ class Model_model_neuron_o2 : public amici::Model_ODE { {}, 0, 0, + 0, 27, 1, 8 @@ -88,7 +89,7 @@ class Model_model_neuron_o2 : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_neuron_o2(*this); }; - std::string getAmiciCommit() const override { return "7d30aeae1966478050ba52aacc1760de3acebee3"; }; + std::string getAmiciCommit() const override { return "ef4445d1c2b3241a8faa11a25a7729648b56300b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_neuron_o2(JSparse, t, x, p, k, h, w, dwdx); diff --git a/models/model_robertson/model_robertson.h b/models/model_robertson/model_robertson.h index 8d208e17e5..a1d9a3cfa8 100644 --- a/models/model_robertson/model_robertson.h +++ b/models/model_robertson/model_robertson.h @@ -1,6 +1,6 @@ #ifndef _amici_model_robertson_h #define _amici_model_robertson_h -/* Generated by amiwrap (R2017b) 7d30aeae1966478050ba52aacc1760de3acebee3 */ +/* Generated by amiwrap (R2017b) ef4445d1c2b3241a8faa11a25a7729648b56300b */ #include #include #include "amici/defines.h" @@ -55,6 +55,7 @@ class Model_model_robertson : public amici::Model_DAE { {}, 0, 0, + 0, 9, 2, 2 @@ -70,7 +71,7 @@ class Model_model_robertson : public amici::Model_DAE { amici::Model* clone() const override { return new Model_model_robertson(*this); }; - std::string getAmiciCommit() const override { return "7d30aeae1966478050ba52aacc1760de3acebee3"; }; + std::string getAmiciCommit() const override { return "ef4445d1c2b3241a8faa11a25a7729648b56300b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype cj, const realtype *dx, const realtype *w, const realtype *dwdx) override { JSparse_model_robertson(JSparse, t, x, p, k, h, cj, dx, w, dwdx); diff --git a/models/model_steadystate/model_steadystate.h b/models/model_steadystate/model_steadystate.h index 6d55a1c8db..0238e21c52 100644 --- a/models/model_steadystate/model_steadystate.h +++ b/models/model_steadystate/model_steadystate.h @@ -1,6 +1,6 @@ #ifndef _amici_model_steadystate_h #define _amici_model_steadystate_h -/* Generated by amiwrap (R2017b) 7d30aeae1966478050ba52aacc1760de3acebee3 */ +/* Generated by amiwrap (R2017b) ef4445d1c2b3241a8faa11a25a7729648b56300b */ #include #include #include "amici/defines.h" @@ -54,6 +54,7 @@ class Model_model_steadystate : public amici::Model_ODE { {}, 0, 0, + 0, 9, 2, 2 @@ -69,7 +70,7 @@ class Model_model_steadystate : public amici::Model_ODE { amici::Model* clone() const override { return new Model_model_steadystate(*this); }; - std::string getAmiciCommit() const override { return "7d30aeae1966478050ba52aacc1760de3acebee3"; }; + std::string getAmiciCommit() const override { return "ef4445d1c2b3241a8faa11a25a7729648b56300b"; }; void fJSparse(SUNMatrixContent_Sparse JSparse, const realtype t, const realtype *x, const realtype *p, const realtype *k, const realtype *h, const realtype *w, const realtype *dwdx) override { JSparse_model_steadystate(JSparse, t, x, p, k, h, w, dwdx); diff --git a/python/amici/ode_export.py b/python/amici/ode_export.py index afa198b00c..26acc49e55 100644 --- a/python/amici/ode_export.py +++ b/python/amici/ode_export.py @@ -286,7 +286,8 @@ class _FunctionInfo: 'dtotal_cldx_rdata': _FunctionInfo( 'realtype *dtotal_cldx_rdata, const realtype *x_rdata, ' - 'const realtype *p, const realtype *k, const realtype *tcl' + 'const realtype *p, const realtype *k, const realtype *tcl', + sparse=True ), 'x_solver': _FunctionInfo('realtype *x_solver, const realtype *x_rdata'), @@ -1331,8 +1332,16 @@ def _generate_sparse_symbol(self, name: str) -> None: matrix = self.eq(name) match_deriv = re.match(r'd([\w]+)d([a-z]+)', name) if match_deriv: - rownames = self.sym(match_deriv.group(1)) - colnames = self.sym(match_deriv.group(2)) + eq = match_deriv.group(1) + var = match_deriv.group(2) + + if name == 'dtotal_cldx_rdata': + # not correctly parsed in regex + eq = 'total_cl' + var = 'x_rdata' + + rownames = self.sym(eq) + colnames = self.sym(var) if name == 'dJydy': # One entry per y-slice @@ -2811,6 +2820,9 @@ def _write_model_header_cpp(self) -> None: 'NDXRDATADTCL': str( len(self.model.sparsesym('dx_rdatadtcl')) ), + 'NDTOTALCLDXRDATA': str( + len(self.model.sparsesym('dtotal_cldx_rdata')) + ), 'UBW': str(self.model.num_states_solver()), 'LBW': str(self.model.num_states_solver()), 'NP': str(self.model.num_par()), diff --git a/src/abstract_model.cpp b/src/abstract_model.cpp index 1f8f0ecdae..a610023bd1 100644 --- a/src/abstract_model.cpp +++ b/src/abstract_model.cpp @@ -731,4 +731,20 @@ void AbstractModel::fdtotal_cldx_rdata(realtype */*dtotal_cldx_rdata*/, __func__); } +void AbstractModel::fdtotal_cldx_rdata_colptrs( + SUNMatrixWrapper &/*dtotal_cldx_rdata*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + +void AbstractModel::fdtotal_cldx_rdata_rowvals( + SUNMatrixWrapper &/*dtotal_cldx_rdata*/) +{ + throw AmiException("Requested functionality is not supported as %s is " + "not implemented for this model!", + __func__); +} + } // namespace amici diff --git a/src/model.cpp b/src/model.cpp index ec4dbf3818..f195bbd80a 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -2262,13 +2262,14 @@ void Model::fstotal_cl(realtype *stotal_cl, const realtype *sx_rdata, // 2) stotal_cl += dtotal_cl/dx_rdata(ncl,nx_rdata) * sx_rdata(nx_rdata,1) - derived_state_.dtotal_cldx_rdata.assign(ncl() * nx_rdata, 0.0); + derived_state_.dtotal_cldx_rdata.zero(); fdtotal_cldx_rdata(derived_state_.dtotal_cldx_rdata.data(), x_rdata, tcl, p, k); - amici_dgemv(BLASLayout::rowMajor, BLASTranspose::noTrans, ncl(), - nx_rdata, 1.0, derived_state_.dtotal_cldx_rdata.data(), - nx_rdata, sx_rdata, 1, 1.0, stotal_cl, 1); - + fdtotal_cldx_rdata_colptrs(derived_state_.dtotal_cldx_rdata); + fdtotal_cldx_rdata_rowvals(derived_state_.dtotal_cldx_rdata); + derived_state_.dtotal_cldx_rdata.multiply( + gsl::make_span(stotal_cl, ncl()), + gsl::make_span(sx_rdata, nx_rdata)); } const_N_Vector Model::computeX_pos(const_N_Vector x) { diff --git a/src/model_header.ODE_template.h b/src/model_header.ODE_template.h index e1b894b147..27e664bd8f 100644 --- a/src/model_header.ODE_template.h +++ b/src/model_header.ODE_template.h @@ -79,7 +79,8 @@ TPL_DX_RDATADTCL_COLPTRS_DEF TPL_DX_RDATADTCL_ROWVALS_DEF TPL_DTOTAL_CLDP_DEF TPL_DTOTAL_CLDX_RDATA_DEF - +TPL_DTOTAL_CLDX_RDATA_COLPTRS_DEF +TPL_DTOTAL_CLDX_RDATA_ROWVALS_DEF /** * @brief AMICI-generated model subclass. */ @@ -112,6 +113,7 @@ class Model_TPL_MODELNAME : public amici::Model_ODE { TPL_NDJYDY, // ndjydy TPL_NDXRDATADXSOLVER, // ndxrdatadxsolver TPL_NDXRDATADTCL, // ndxrdatadtcl + TPL_NDTOTALCLDXRDATA, // ndtotal_cldx_rdata 0, // nnz TPL_UBW, // ubw TPL_LBW // lbw @@ -491,6 +493,8 @@ class Model_TPL_MODELNAME : public amici::Model_ODE { TPL_DTOTAL_CLDP_IMPL TPL_DTOTAL_CLDX_RDATA_IMPL + TPL_DTOTAL_CLDX_RDATA_COLPTRS_IMPL + TPL_DTOTAL_CLDX_RDATA_ROWVALS_IMPL std::string getName() const override { return "TPL_MODELNAME"; diff --git a/src/model_state.cpp b/src/model_state.cpp index 19a0ae939c..6bad8db959 100644 --- a/src/model_state.cpp +++ b/src/model_state.cpp @@ -10,13 +10,11 @@ ModelStateDerived::ModelStateDerived(const ModelDimensions &dim) CSC_MAT), dx_rdatadtcl(dim.nx_rdata, dim.nx_rdata - dim.nx_solver, dim.ndxrdatadtcl, CSC_MAT), + dtotal_cldx_rdata(dim.nx_rdata - dim.nx_solver, dim.nx_rdata, + dim.ndtotal_cldx_rdata, CSC_MAT), w_(dim.nw), x_rdata_(dim.nx_rdata, 0.0), sx_rdata_(dim.nx_rdata, 0.0), - // only required if there are conservation laws - dtotal_cldx_rdata(dim.nx_rdata - dim.nx_solver > 0 - ? (dim.nx_rdata - dim.nx_solver) * dim.nx_rdata : 0, - 0.0), x_pos_tmp_(dim.nx_solver) {} diff --git a/swig/abstract_model.i b/swig/abstract_model.i index a507d7e3d5..75a48c1675 100644 --- a/swig/abstract_model.i +++ b/swig/abstract_model.i @@ -66,5 +66,6 @@ %ignore fdx_rdatadtcl_rowvals; %ignore fdx_rdatadx_solver_colptrs; %ignore fdx_rdatadx_solver_rowvals; - +%ignore fdtotal_cldx_rdata_colptrs; +%ignore fdtotal_cldx_rdata_rowvals; %include "amici/abstract_model.h" diff --git a/tests/cpp/unittests/testExpData.cpp b/tests/cpp/unittests/testExpData.cpp index 152d25246b..5a77c8ad00 100644 --- a/tests/cpp/unittests/testExpData.cpp +++ b/tests/cpp/unittests/testExpData.cpp @@ -58,6 +58,7 @@ class ExpDataTest : public ::testing::Test { {}, // ndJydy 0, // ndxrdatadxsolver 0, // ndxrdatadtcl + 0, // ndtotal_cldx_rdata 0, // nnz 0, // ubw 0 // lbw diff --git a/tests/cpp/unittests/testMisc.cpp b/tests/cpp/unittests/testMisc.cpp index 0b9521c258..a7246f5ad7 100644 --- a/tests/cpp/unittests/testMisc.cpp +++ b/tests/cpp/unittests/testMisc.cpp @@ -70,9 +70,10 @@ class ModelTest : public ::testing::Test { 0, // ndwdp 0, // dwdw 0, // ndxdotdw - {}, // ndJydy + {}, // ndJydy 0, // ndxrdatadxsolver 0, // ndxrdatadtcl + 0, // ndtotal_cldx_rdata 0, // nnz 0, // ubw 0 // lbw @@ -306,12 +307,13 @@ class SolverTest : public ::testing::Test { 0, // ndwdp 0, // dwdw 0, // ndxdotdw - {}, // ndJydy + {}, // ndJydy 0, // ndxrdatadxsolver 0, // ndxrdatadtcl + 0, // ndtotal_cldx_rdata 1, // nnz 0, // ubw - 0 // lbw + 0 // lbw ), SimulationParameters( std::vector(3, 0.0), diff --git a/tests/cpp/unittests/testSerialization.cpp b/tests/cpp/unittests/testSerialization.cpp index 557e50e8a0..61e9c7a9a3 100644 --- a/tests/cpp/unittests/testSerialization.cpp +++ b/tests/cpp/unittests/testSerialization.cpp @@ -155,6 +155,7 @@ TEST(ModelSerializationTest, ToFile) {}, // ndJydy 9, // ndxrdatadxsolver 0, // ndxrdatadtcl + 0, // ndtotal_cldx_rdata 17, // nnz 18, // ubw 19 // lbw @@ -218,6 +219,7 @@ TEST(ReturnDataSerializationTest, ToString) {}, // ndJydy 9, // ndxrdatadxsolver 0, // ndxrdatadtcl + 0, // ndtotal_cldx_rdata 17, // nnz 18, // ubw 19 // lbw From cc42f4818e84508fa60885537b40abb2d9b43db0 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Mon, 14 Mar 2022 13:32:44 +0100 Subject: [PATCH 41/45] speed: equation-wise check for disjoint free symbols in `smart_jacobian` (#1722) Speeds up model import for larger models: With this change: Elapsed (wall clock) time (h:mm:ss or m:ss): 28:27.82 Before: Elapsed (wall clock) time (h:mm:ss or m:ss): 32:21.23 --- python/amici/ode_export.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/python/amici/ode_export.py b/python/amici/ode_export.py index 26acc49e55..8c9fa7e96a 100644 --- a/python/amici/ode_export.py +++ b/python/amici/ode_export.py @@ -420,9 +420,12 @@ def smart_jacobian(eq: sp.MutableDenseMatrix, """ if min(eq.shape) and min(sym_var.shape) \ and not smart_is_zero_matrix(eq) \ - and not smart_is_zero_matrix(sym_var) \ - and not sym_var.free_symbols.isdisjoint(eq.free_symbols): - return eq.jacobian(sym_var) + and not smart_is_zero_matrix(sym_var): + return sp.Matrix([ + eq[i, :].jacobian(sym_var) if eq[i, :].has(*sym_var.flat()) + else [0] * sym_var.shape[0] + for i in range(eq.shape[0]) + ]) return sp.zeros(eq.shape[0], sym_var.shape[0]) From ade2d3a92e85ab96d4b95786696307fb17bdf2d7 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Mon, 14 Mar 2022 21:23:34 +0100 Subject: [PATCH 42/45] CI: Fix osx build (pin hdf5, boost dirs, omp dir) (#1723) Most recent HDF5 version (1.13) fails for unknown reasons: ``` __________________________ test_solver_hdf5_roundtrip __________________________ sbml_example_presimulation_module = @pytest.mark.skipif(not amici.hdf5_enabled, reason='AMICI was compiled without HDF5') def test_solver_hdf5_roundtrip(sbml_example_presimulation_module): """TestCase class for AMICI HDF5 I/O""" model = sbml_example_presimulation_module.getModel() solver = model.getSolver() _modify_solver_attrs(solver) hdf5file = 'solverSettings.hdf5' > amici.writeSolverSettingsToHDF5(solver, hdf5file, 'ssettings') test_hdf5.py:46: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../sdist/amici/swig_wrappers.py:167: in writeSolverSettingsToHDF5 amici_swig.writeSolverSettingsToHDF5(_get_ptr(solver), file, location) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ args = (::pointer' at 0x12309bc90> >, 'solverSettings.hdf5', 'ssettings') def writeSolverSettingsToHDF5(*args) -> None: """ *Overload 1:* Write solver options to HDF5 file. :type hdf5Filename: str :param hdf5Filename: Name of HDF5 file to write to :type solver: :py:class:`Solver` :param solver: Solver to write options from :type hdf5Location: str :param hdf5Location: Path inside the HDF5 file | *Overload 2:* Write solver options to HDF5 file. :type file: H5::H5File :param file: File to read from :type solver: :py:class:`Solver` :param solver: Solver to write options from :type hdf5Location: str :param hdf5Location: Path inside the HDF5 file """ > return _amici.writeSolverSettingsToHDF5(*args) E RuntimeError: Failed to create group in hdf5CreateGroup: ssettings ../sdist/amici/amici.py:6150: RuntimeError ----------------------------- Captured stderr call ----------------------------- HDF5-DIAG: Error detected in HDF5 (1.13.0) thread 0: //000: H5Plcpl.c line 152 in H5Pset_create_intermediate_group(): can't find object for ID major: Object ID minor: Unable to find ID information (already closed?) //001: H5Pint.c line 4116 in H5P_object_verify(): property list is not a member of the class major: Property lists minor: Unable to register new ID //002: H5Pint.c line 4067 in H5P_isa_class(): not a property list major: Invalid arguments to routine minor: Inappropriate type HDF5-DIAG: Error detected in HDF5 (1.13.0) thread 0: //000: H5G.c line 232 in H5Gcreate2(): unable to synchronously create group major: Symbol table minor: Unable to create file //001: H5G.c line 171 in H5G__create_api_common(): not a link creation property list major: Invalid arguments to routine minor: Inappropriate type //002: H5Pint.c line 4067 in H5P_isa_class(): not a property list major: Invalid arguments to routine minor: Inappropriate type HDF5-DIAG: Error detected in HDF5 (1.13.0) thread 0: //000: H5P.c line 1487 in H5Pclose(): not a property list major: Invalid arguments to routine minor: Inappropriate type ``` Also, `libomp` as well as `boost` directories seems to have changed. --- .github/workflows/test_pypi.yml | 6 +++++- .github/workflows/test_python_cplusplus.yml | 8 +++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test_pypi.yml b/.github/workflows/test_pypi.yml index da50ad7389..4b68180830 100644 --- a/.github/workflows/test_pypi.yml +++ b/.github/workflows/test_pypi.yml @@ -31,7 +31,11 @@ jobs: - name: homebrew run: | if [[ ${{ matrix.os }} == macos* ]] ; then \ - brew install hdf5 swig gcc libomp + brew install hdf5@1.10 swig gcc libomp \ + && echo "/usr/local/opt/hdf5@1.10/bin" >> $GITHUB_PATH \ + && echo LDFLAGS="-L/usr/local/lib/ -L/usr/local/opt/hdf5@1.10/lib" >> $GITHUB_ENV \ + && echo CPPFLAGS="-I/usr/local/opt/hdf5@1.10/include" >> $GITHUB_ENV \ + && echo HDF5_BASE="/usr/local/opt/hdf5@1.10/" >> $GITHUB_ENV fi - name: Set up Python ${{ matrix.python-version }} diff --git a/.github/workflows/test_python_cplusplus.yml b/.github/workflows/test_python_cplusplus.yml index cb8da194a1..ac3a10fa76 100644 --- a/.github/workflows/test_python_cplusplus.yml +++ b/.github/workflows/test_python_cplusplus.yml @@ -152,7 +152,13 @@ jobs: # install amici dependencies - name: homebrew run: | - brew install hdf5 swig gcc cppcheck libomp boost + brew install hdf5@1.10 swig gcc cppcheck libomp boost \ + && brew ls -v boost \ + && brew ls -v libomp \ + && echo "/usr/local/opt/hdf5@1.10/bin" >> $GITHUB_PATH \ + && echo LDFLAGS="-L/usr/local/lib/ -L/usr/local/opt/hdf5@1.10/lib -L/usr/local/Cellar/boost/1.78.0_1/lib/" >> $GITHUB_ENV \ + && echo CPPFLAGS="-I/usr/local/opt/hdf5@1.10/include -I/usr/local/Cellar/boost/1.78.0_1/include/" >> $GITHUB_ENV \ + && echo HDF5_BASE="/usr/local/opt/hdf5@1.10/" >> $GITHUB_ENV - name: Build AMICI run: | From 3d6e980f8b5b3ac85c8398ec93a8594fae6d9a81 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Mon, 14 Mar 2022 22:52:13 +0100 Subject: [PATCH 43/45] Refactor setup.py clibs - add basedir argument (#1724) Adds an argument to specify base directories for extension files. Prerequisite for #1119. --- python/sdist/setup.py | 40 ++-- python/sdist/setup_clibs.py | 383 ++++++++++++++++++++---------------- 2 files changed, 240 insertions(+), 183 deletions(-) diff --git a/python/sdist/setup.py b/python/sdist/setup.py index 2b97a5d7dd..4b35aa6ba9 100755 --- a/python/sdist/setup.py +++ b/python/sdist/setup.py @@ -12,6 +12,7 @@ import os import sys +from pathlib import Path # Add containing directory to path, as we need some modules from the AMICI # package already for installation @@ -19,7 +20,7 @@ import numpy as np import setup_clibs # Must run from within containing directory -from setuptools import find_packages, setup, Extension +from setuptools import setup, Extension from amici.custom_commands import ( AmiciInstall, AmiciBuildCLib, AmiciDevelop, @@ -32,6 +33,7 @@ add_openmp_flags, ) + def main(): # Extra compiler flags cxx_flags = [] @@ -82,12 +84,25 @@ def main(): amici_module_linker_flags.extend( os.environ['AMICI_LDFLAGS'].split(' ')) + amici_base_dir = Path('amici') + suitesparse_base_dir = amici_base_dir / 'ThirdParty' / 'SuiteSparse' + sundials_base_dir = amici_base_dir / 'ThirdParty' / 'sundials' + libamici = setup_clibs.get_lib_amici( + amici_base_dir=amici_base_dir, + sundials_base_dir=sundials_base_dir, + suitesparse_base_dir=suitesparse_base_dir, h5pkgcfg=h5pkgcfg, blaspkgcfg=blaspkgcfg, - extra_compiler_flags=cxx_flags) - libsundials = setup_clibs.get_lib_sundials(extra_compiler_flags=cxx_flags) + extra_compiler_flags=cxx_flags + ) + libsundials = setup_clibs.get_lib_sundials( + sundials_base_dir=sundials_base_dir, + suitesparse_base_dir=suitesparse_base_dir, + extra_compiler_flags=cxx_flags + ) libsuitesparse = setup_clibs.get_lib_suite_sparse( - extra_compiler_flags=cxx_flags + ['-DDLONG'] + extra_compiler_flags=cxx_flags + ['-DDLONG'], + suitesparse_base_dir=suitesparse_base_dir ) # Readme as long package description to go on PyPi @@ -100,14 +115,15 @@ def main(): amici_module = Extension( name='amici._amici', sources=extension_sources, - include_dirs=['amici/include', - 'amici/ThirdParty/gsl/', - *libsundials[1]['include_dirs'], - *libsuitesparse[1]['include_dirs'], - *h5pkgcfg['include_dirs'], - *blaspkgcfg['include_dirs'], - np.get_include() - ], + include_dirs=[ + amici_base_dir / 'include', + amici_base_dir / 'ThirdParty' / 'gsl', + *libsundials[1]['include_dirs'], + *libsuitesparse[1]['include_dirs'], + *h5pkgcfg['include_dirs'], + *blaspkgcfg['include_dirs'], + np.get_include() + ], # Cannot use here, see above # libraries=[ # 'hdf5_hl_cpp', 'hdf5_hl', 'hdf5_cpp', 'hdf5' diff --git a/python/sdist/setup_clibs.py b/python/sdist/setup_clibs.py index 1b68320f84..c570a597b9 100644 --- a/python/sdist/setup_clibs.py +++ b/python/sdist/setup_clibs.py @@ -6,154 +6,179 @@ AMICI-generated models. """ -import os -import glob import re - -from typing import Dict, List, Union, Tuple, Any, Optional +from pathlib import Path +from typing import Any, Dict, List, Optional, Tuple, Union PackageInfo = Dict[str, List[Union[str, Tuple[str, Any]]]] Library = Tuple[str, PackageInfo] -# suite sparse include directories -suite_sparse_include_dirs = [ - 'amici/ThirdParty/SuiteSparse/KLU/Include/', - 'amici/ThirdParty/SuiteSparse/AMD/Include/', - 'amici/ThirdParty/SuiteSparse/COLAMD/Include/', - 'amici/ThirdParty/SuiteSparse/BTF/Include/', - 'amici/ThirdParty/SuiteSparse/SuiteSparse_config', - 'amici/ThirdParty/SuiteSparse/include' -] - -# sundials include directories -sundials_include_dirs = [ - 'amici/ThirdParty/sundials/include', - 'amici/ThirdParty/sundials/src', -] - - -def get_sundials_sources() -> List[str]: - """Get list of Sundials source files""" - srcs = [ - os.path.join('src', 'sunmatrix', 'dense', 'sunmatrix_dense.c'), - os.path.join('src', 'sunmatrix', 'band', 'sunmatrix_band.c'), - os.path.join('src', 'sunmatrix', 'sparse', 'sunmatrix_sparse.c'), - os.path.join('src', 'sunlinsol', 'spgmr', 'sunlinsol_spgmr.c'), - os.path.join('src', 'sunlinsol', 'sptfqmr', 'sunlinsol_sptfqmr.c'), - os.path.join('src', 'sunlinsol', 'klu', 'sunlinsol_klu.c'), - os.path.join('src', 'sunlinsol', 'dense', 'sunlinsol_dense.c'), - os.path.join('src', 'sunlinsol', 'spfgmr', 'sunlinsol_spfgmr.c'), - os.path.join('src', 'sunlinsol', 'pcg', 'sunlinsol_pcg.c'), - os.path.join('src', 'sunlinsol', 'spbcgs', 'sunlinsol_spbcgs.c'), - os.path.join('src', 'sunlinsol', 'band', 'sunlinsol_band.c'), - os.path.join('src', 'idas', 'idas_direct.c'), - os.path.join('src', 'idas', 'idaa.c'), - os.path.join('src', 'idas', 'idas_ic.c'), - os.path.join('src', 'idas', 'idas_nls_stg.c'), - os.path.join('src', 'idas', 'idas.c'), - os.path.join('src', 'idas', 'idas_bbdpre.c'), - os.path.join('src', 'idas', 'idas_spils.c'), - os.path.join('src', 'idas', 'idas_nls.c'), - os.path.join('src', 'idas', 'idas_ls.c'), - os.path.join('src', 'idas', 'idas_io.c'), - os.path.join('src', 'idas', 'idas_nls_sim.c'), - os.path.join('src', 'idas', 'idaa_io.c'), - os.path.join('src', 'sundials', 'sundials_math.c'), - os.path.join('src', 'sundials', 'sundials_matrix.c'), - os.path.join('src', 'sundials', 'sundials_direct.c'), - os.path.join('src', 'sundials', 'sundials_nvector_senswrapper.c'), - os.path.join('src', 'sundials', 'sundials_dense.c'), - os.path.join('src', 'sundials', 'sundials_nvector.c'), - os.path.join('src', 'sundials', 'sundials_version.c'), - os.path.join('src', 'sundials', 'sundials_iterative.c'), - os.path.join('src', 'sundials', 'sundials_nonlinearsolver.c'), - os.path.join('src', 'sundials', 'sundials_linearsolver.c'), - os.path.join('src', 'sundials', 'sundials_band.c'), - os.path.join('src', 'sundials', 'sundials_futils.c'), - os.path.join('src', 'sunnonlinsol', 'newton', 'sunnonlinsol_newton.c'), - os.path.join('src', 'sunnonlinsol', 'fixedpoint', - 'sunnonlinsol_fixedpoint.c'), - os.path.join('src', 'nvector', 'serial', 'nvector_serial.c'), - os.path.join('src', 'cvodes', 'cvodes_spils.c'), - os.path.join('src', 'cvodes', 'cvodes_nls_stg.c'), - os.path.join('src', 'cvodes', 'cvodes_ls.c'), - os.path.join('src', 'cvodes', 'cvodes_nls_stg1.c'), - os.path.join('src', 'cvodes', 'cvodes_bbdpre.c'), - os.path.join('src', 'cvodes', 'cvodes.c'), - os.path.join('src', 'cvodes', 'cvodes_bandpre.c'), - os.path.join('src', 'cvodes', 'cvodea.c'), - os.path.join('src', 'cvodes', 'cvodes_nls_sim.c'), - os.path.join('src', 'cvodes', 'cvodea_io.c'), - os.path.join('src', 'cvodes', 'cvodes_nls.c'), - os.path.join('src', 'cvodes', 'cvodes_diag.c'), - os.path.join('src', 'cvodes', 'cvodes_io.c'), - os.path.join('src', 'cvodes', 'cvodes_direct.c') - ] - return [os.path.join('amici', 'ThirdParty', 'sundials', src) - for src in srcs] - - -def get_suite_sparse_sources() -> List[str]: - """Get list of SuiteSparse source files""" - srcs = [ - os.path.join('KLU', 'Source', 'klu_analyze_given.c'), - os.path.join('KLU', 'Source', 'klu_analyze.c'), - os.path.join('KLU', 'Source', 'klu_defaults.c'), - os.path.join('KLU', 'Source', 'klu_diagnostics.c'), - os.path.join('KLU', 'Source', 'klu_dump.c'), - os.path.join('KLU', 'Source', 'klu_extract.c'), - os.path.join('KLU', 'Source', 'klu_factor.c'), - os.path.join('KLU', 'Source', 'klu_free_numeric.c'), - os.path.join('KLU', 'Source', 'klu_free_symbolic.c'), - os.path.join('KLU', 'Source', 'klu_kernel.c'), - os.path.join('KLU', 'Source', 'klu_memory.c'), - os.path.join('KLU', 'Source', 'klu_refactor.c'), - os.path.join('KLU', 'Source', 'klu_scale.c'), - os.path.join('KLU', 'Source', 'klu_sort.c'), - os.path.join('KLU', 'Source', 'klu_solve.c'), - os.path.join('KLU', 'Source', 'klu_tsolve.c'), - os.path.join('KLU', 'Source', 'klu.c'), - os.path.join('AMD', 'Source', 'amd_1.c'), - os.path.join('AMD', 'Source', 'amd_2.c'), - os.path.join('AMD', 'Source', 'amd_aat.c'), - os.path.join('AMD', 'Source', 'amd_control.c'), - os.path.join('AMD', 'Source', 'amd_defaults.c'), - os.path.join('AMD', 'Source', 'amd_dump.c'), - os.path.join('AMD', 'Source', 'amd_global.c'), - os.path.join('AMD', 'Source', 'amd_info.c'), - os.path.join('AMD', 'Source', 'amd_order.c'), - os.path.join('AMD', 'Source', 'amd_post_tree.c'), - os.path.join('AMD', 'Source', 'amd_postorder.c'), - os.path.join('AMD', 'Source', 'amd_preprocess.c'), - os.path.join('AMD', 'Source', 'amd_valid.c'), - os.path.join('COLAMD', 'Source', 'colamd.c'), - os.path.join('BTF', 'Source', 'btf_maxtrans.c'), - os.path.join('BTF', 'Source', 'btf_order.c'), - os.path.join('BTF', 'Source', 'btf_strongcomp.c'), - os.path.join('SuiteSparse_config', 'SuiteSparse_config.c'), - ] - return [os.path.join('amici', 'ThirdParty', 'SuiteSparse', src) - for src in srcs] +def get_suite_sparse_include_dirs(ss_base_dir: Path) -> List[str]: + """Suite sparse include directories + + :param ss_base_dir: SuiteSparse base directory + """ + return list(map(str, [ + ss_base_dir / 'KLU' / 'Include', + ss_base_dir / 'AMD' / 'Include', + ss_base_dir / 'COLAMD' / 'Include', + ss_base_dir / 'BTF' / 'Include', + ss_base_dir / 'SuiteSparse_config', + ss_base_dir / 'include', + ])) + + +def get_sundials_include_dirs(sundials_base_dir: Path) -> List[str]: + """Sundials include directories -def get_amici_base_sources(with_hdf5: bool = True) -> List[str]: + :param sundials_base_dir: sundials base directory + """ + return list(map(str, [ + sundials_base_dir / 'include', + sundials_base_dir / 'src', + ])) + + +def get_sundials_sources(sundials_base_dir: Path) -> List[str]: + """Get list of Sundials source files + + :param sundials_base_dir: sundials base directory + """ + return list(map(str, [ + sundials_base_dir / 'src' / 'sunmatrix' / 'dense' + / 'sunmatrix_dense.c', + sundials_base_dir / 'src' / 'sunmatrix' / 'band' + / 'sunmatrix_band.c', + sundials_base_dir / 'src' / 'sunmatrix' / 'sparse' + / 'sunmatrix_sparse.c', + sundials_base_dir / 'src' / 'sunlinsol' / 'spgmr' + / 'sunlinsol_spgmr.c', + sundials_base_dir / 'src' / 'sunlinsol' / 'sptfqmr' + / 'sunlinsol_sptfqmr.c', + sundials_base_dir / 'src' / 'sunlinsol' / 'klu' / 'sunlinsol_klu.c', + sundials_base_dir / 'src' / 'sunlinsol' / 'dense' + / 'sunlinsol_dense.c', + sundials_base_dir / 'src' / 'sunlinsol' / 'spfgmr' + / 'sunlinsol_spfgmr.c', + sundials_base_dir / 'src' / 'sunlinsol' / 'pcg' / 'sunlinsol_pcg.c', + sundials_base_dir / 'src' / 'sunlinsol' / 'spbcgs' + / 'sunlinsol_spbcgs.c', + sundials_base_dir / 'src' / 'sunlinsol' / 'band' / 'sunlinsol_band.c', + sundials_base_dir / 'src' / 'idas' / 'idas_direct.c', + sundials_base_dir / 'src' / 'idas' / 'idaa.c', + sundials_base_dir / 'src' / 'idas' / 'idas_ic.c', + sundials_base_dir / 'src' / 'idas' / 'idas_nls_stg.c', + sundials_base_dir / 'src' / 'idas' / 'idas.c', + sundials_base_dir / 'src' / 'idas' / 'idas_bbdpre.c', + sundials_base_dir / 'src' / 'idas' / 'idas_spils.c', + sundials_base_dir / 'src' / 'idas' / 'idas_nls.c', + sundials_base_dir / 'src' / 'idas' / 'idas_ls.c', + sundials_base_dir / 'src' / 'idas' / 'idas_io.c', + sundials_base_dir / 'src' / 'idas' / 'idas_nls_sim.c', + sundials_base_dir / 'src' / 'idas' / 'idaa_io.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_math.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_matrix.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_direct.c', + sundials_base_dir / 'src' / 'sundials' + / 'sundials_nvector_senswrapper.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_dense.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_nvector.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_version.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_iterative.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_nonlinearsolver.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_linearsolver.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_band.c', + sundials_base_dir / 'src' / 'sundials' / 'sundials_futils.c', + sundials_base_dir / 'src' / 'sunnonlinsol' / 'newton' + / 'sunnonlinsol_newton.c', + sundials_base_dir / 'src' / 'sunnonlinsol' / 'fixedpoint' + / 'sunnonlinsol_fixedpoint.c', + sundials_base_dir / 'src' / 'nvector' / 'serial' / 'nvector_serial.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_spils.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_nls_stg.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_ls.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_nls_stg1.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_bbdpre.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_bandpre.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodea.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_nls_sim.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodea_io.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_nls.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_diag.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_io.c', + sundials_base_dir / 'src' / 'cvodes' / 'cvodes_direct.c' + ])) + + +def get_suite_sparse_sources(ss_base_dir: Path) -> List[str]: + """Get list of SuiteSparse source files + + :param ss_base_dir: SuiteSparse base directory + """ + return list(map(str, [ + ss_base_dir / 'KLU' / 'Source' / 'klu_analyze_given.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_analyze.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_defaults.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_diagnostics.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_dump.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_extract.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_factor.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_free_numeric.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_free_symbolic.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_kernel.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_memory.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_refactor.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_scale.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_sort.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_solve.c', + ss_base_dir / 'KLU' / 'Source' / 'klu_tsolve.c', + ss_base_dir / 'KLU' / 'Source' / 'klu.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_1.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_2.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_aat.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_control.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_defaults.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_dump.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_global.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_info.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_order.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_post_tree.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_postorder.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_preprocess.c', + ss_base_dir / 'AMD' / 'Source' / 'amd_valid.c', + ss_base_dir / 'COLAMD' / 'Source' / 'colamd.c', + ss_base_dir / 'BTF' / 'Source' / 'btf_maxtrans.c', + ss_base_dir / 'BTF' / 'Source' / 'btf_order.c', + ss_base_dir / 'BTF' / 'Source' / 'btf_strongcomp.c', + ss_base_dir / 'SuiteSparse_config' / 'SuiteSparse_config.c', + ])) + + +def get_amici_base_sources( + base_dir: Path, + with_hdf5: bool = True +) -> List[str]: """Get list of source files for the amici base library Expects that we are inside $AMICI_ROOT/python/sdist Arguments: + base_dir: AMICI base dir containing ``src/`` and ``include/`` with_hdf5: compile with HDF5 support """ - - amici_base_sources = glob.glob(os.path.join('amici', 'src', '*.cpp')) - amici_base_sources = [src for src in amici_base_sources - if not re.search(r'(matlab)|(\.(ODE_)?template\.)', src)] + amici_base_sources = (base_dir / 'src').glob('*.cpp') + amici_base_sources = [ + str(src) for src in amici_base_sources + if not re.search(r'(matlab)|(\.(ODE_)?template\.)', str(src)) + ] if not with_hdf5: - hdf5_cpp = os.path.join('amici', 'src', 'hdf5.cpp') + hdf5_cpp = base_dir / 'src' / 'hdf5.cpp' try: - # sometimes this fails for unknwon reasons... - amici_base_sources.remove(hdf5_cpp) + # sometimes this fails for unknown reasons... + amici_base_sources.remove(str(hdf5_cpp)) except ValueError: print(f'Warning: could not find {hdf5_cpp} in ' f'{amici_base_sources}') @@ -161,8 +186,11 @@ def get_amici_base_sources(with_hdf5: bool = True) -> List[str]: return amici_base_sources -def get_lib_sundials(extra_compiler_flags: Optional[List[str]] = None) -> \ - Library: +def get_lib_sundials( + sundials_base_dir: Path, + suitesparse_base_dir: Path, + extra_compiler_flags: Optional[List[str]] = None +) -> Library: """ Get sundials library build info for setuptools @@ -172,20 +200,25 @@ def get_lib_sundials(extra_compiler_flags: Optional[List[str]] = None) -> \ if extra_compiler_flags is None: extra_compiler_flags = [] - libsundials = ('sundials', { - 'sources': get_sundials_sources(), - 'include_dirs': [*sundials_include_dirs, - *suite_sparse_include_dirs, - ], - 'cflags': [*extra_compiler_flags], - 'cflags_mingw32': ['-Wno-misleading-indentation'], - 'cflags_unix': ['-Wno-misleading-indentation'], - }) - return libsundials - - -def get_lib_suite_sparse(extra_compiler_flags: Optional[List[str]] = None) -> \ - Library: + return ( + 'sundials', + { + 'sources': get_sundials_sources(sundials_base_dir), + 'include_dirs': [ + *get_sundials_include_dirs(sundials_base_dir), + *get_suite_sparse_include_dirs(suitesparse_base_dir), + ], + 'cflags': [*extra_compiler_flags], + 'cflags_mingw32': ['-Wno-misleading-indentation'], + 'cflags_unix': ['-Wno-misleading-indentation'], + } + ) + + +def get_lib_suite_sparse( + suitesparse_base_dir: Path, + extra_compiler_flags: Optional[List[str]] = None +) -> Library: """ Get SuiteSparse library build info for setuptools @@ -195,19 +228,26 @@ def get_lib_suite_sparse(extra_compiler_flags: Optional[List[str]] = None) -> \ if extra_compiler_flags is None: extra_compiler_flags = [] - libsuitesparse = ('suitesparse', { - 'sources': get_suite_sparse_sources(), - 'include_dirs': suite_sparse_include_dirs, - 'cflags': [*extra_compiler_flags], - 'cflags_mingw32': ['-Wno-unused-but-set-variable'], - 'cflags_unix': ['-Wno-unused-but-set-variable'] - }) - return libsuitesparse - - -def get_lib_amici(extra_compiler_flags: List[str] = None, - h5pkgcfg: Optional[PackageInfo] = None, - blaspkgcfg: Optional[PackageInfo] = None) -> Library: + return ( + 'suitesparse', + { + 'sources': get_suite_sparse_sources(suitesparse_base_dir), + 'include_dirs': + get_suite_sparse_include_dirs(suitesparse_base_dir), + 'cflags': [*extra_compiler_flags], + 'cflags_mingw32': ['-Wno-unused-but-set-variable'], + 'cflags_unix': ['-Wno-unused-but-set-variable'] + }) + + +def get_lib_amici( + amici_base_dir: Path, + sundials_base_dir: Path, + suitesparse_base_dir: Path, + extra_compiler_flags: List[str] = None, + h5pkgcfg: Optional[PackageInfo] = None, + blaspkgcfg: Optional[PackageInfo] = None, +) -> Library: """ Get AMICI core library build info for setuptools @@ -219,23 +259,24 @@ def get_lib_amici(extra_compiler_flags: List[str] = None, :param blaspkgcfg: blas package info - """ - if extra_compiler_flags is None: extra_compiler_flags = [] libamici = ('amici', { - 'sources': get_amici_base_sources( - with_hdf5=(h5pkgcfg - and 'include_dirs' in h5pkgcfg - and len(h5pkgcfg['include_dirs'])) + 'sources': + get_amici_base_sources( + amici_base_dir, + with_hdf5=(h5pkgcfg + and 'include_dirs' in h5pkgcfg + and len(h5pkgcfg['include_dirs'])) ), - 'include_dirs': ['amici/include', - *suite_sparse_include_dirs, - *sundials_include_dirs, - 'amici/ThirdParty/gsl/', - ], + 'include_dirs': [ + str(amici_base_dir / 'include'), + *get_suite_sparse_include_dirs(suitesparse_base_dir), + *get_sundials_include_dirs(sundials_base_dir), + str(amici_base_dir / 'ThirdParty' / 'gsl'), + ], 'cflags': [*extra_compiler_flags], 'cflags_mingw32': ['-std=c++14'], 'cflags_unix': ['-std=c++14'], From 28de20e5166baf1080e347999a19db8e39cb78a3 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Tue, 15 Mar 2022 06:31:27 +0100 Subject: [PATCH 44/45] CI: Skip some long running tests under valgrind (#1725) --- python/tests/test_bngl.py | 2 ++ python/tests/test_pregenerated_models.py | 4 +++- python/tests/test_pysb.py | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/python/tests/test_bngl.py b/python/tests/test_bngl.py index 212235ef63..722359236d 100644 --- a/python/tests/test_bngl.py +++ b/python/tests/test_bngl.py @@ -21,6 +21,8 @@ ] +@pytest.mark.skipif(os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Takes too long under valgrind") @pytest.mark.parametrize('example', tests) def test_compare_to_pysb_simulation(example): diff --git a/python/tests/test_pregenerated_models.py b/python/tests/test_pregenerated_models.py index f746ea4d6b..77d91714c3 100755 --- a/python/tests/test_pregenerated_models.py +++ b/python/tests/test_pregenerated_models.py @@ -22,11 +22,13 @@ for case in list(expected_results[sub_test].keys())] +@pytest.mark.skipif(os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Takes too long under valgrind") @pytest.mark.skipif(os.environ.get('AMICI_SKIP_CMAKE_TESTS', '') == 'TRUE', reason='skipping cmake based test') @pytest.mark.parametrize("sub_test,case", model_cases) def test_pregenerated_model(sub_test, case): - """Tests models that were pregenerated using the the matlab code + """Tests models that were pregenerated using the matlab code generation routines and cmake build routines. NOTE: requires having run `make python-tests` in /build/ before to build diff --git a/python/tests/test_pysb.py b/python/tests/test_pysb.py index ac7ea5b178..0fd050b596 100644 --- a/python/tests/test_pysb.py +++ b/python/tests/test_pysb.py @@ -20,6 +20,8 @@ from amici.gradient_check import check_derivatives +@pytest.mark.skipif(os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Takes too long under valgrind") def test_compare_to_sbml_import(pysb_example_presimulation_module, sbml_example_presimulation_module): # -------------- PYSB ----------------- @@ -99,6 +101,8 @@ def test_compare_to_sbml_import(pysb_example_presimulation_module, ] +@pytest.mark.skipif(os.environ.get('GITHUB_JOB') == 'valgrind', + reason="Takes too long under valgrind") @pytest.mark.parametrize('example', pysb_models + custom_models) def test_compare_to_pysb_simulation(example): From 52b7ab5c83ebbb9b16981c1b617e507054632296 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Mon, 14 Mar 2022 13:51:06 +0100 Subject: [PATCH 45/45] Update changelog, bump version number --- CHANGELOG.md | 31 +++++++++++++++++++++++++++++++ version.txt | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5adefb5033..207072c787 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,37 @@ ## v0.X Series +### v0.11.26 (2022-03-14) + +New features: +* Import of BioNetGenLanguage (BNGL) models by @FFroehlich in + https://github.com/AMICI-dev/AMICI/pull/1709 +* Added support for observable-dependent sigmas by @dweindl, @FFroehlich in + https://github.com/AMICI-dev/AMICI/pull/1692 +* Added support for pysb local functions by @FFroehlich in + https://github.com/AMICI-dev/AMICI/pull/1666 +* Added experimental support for conservation laws for non-constant species to + SBML import: conservation laws for non-constant species + by @stephanmg, @dweindl in https://github.com/AMICI-dev/AMICI/pull/1669 + Enable this feature by setting environment variable + `AMICI_EXPERIMENTAL_SBML_NONCONST_CLS` to any value + * Allow using states eliminated by conservation laws to be used in root + functions by @dweindl in https://github.com/AMICI-dev/AMICI/pull/1677 + * Added support for parameter-dependent conservation laws by @dweindl, + @FFroehlich in https://github.com/AMICI-dev/AMICI/pull/1678 +* Added optional caching for symbolic simplifications in ODE export by @dilpath + in https://github.com/AMICI-dev/AMICI/pull/1672 +* Added CLI option `--no-sensitivities` to `amici_import_petab` by @dweindl in + https://github.com/AMICI-dev/AMICI/pull/1688 + +Fixes: +* SBML import: Raise in case of nested observables by @dweindl in + https://github.com/AMICI-dev/AMICI/pull/1690 +* Sympy 1.10 compatibility by @dweindl in + https://github.com/AMICI-dev/AMICI/pull/1694 + +**Full Changelog**: https://github.com/AMICI-dev/AMICI/compare/v0.11.25...v0.11.26 + ### v0.11.25 (2022-02-09) * Fixed a bug diff --git a/version.txt b/version.txt index 7874d114d3..efb9e6c966 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.11.25 +0.11.26