Skip to content

Commit d093f30

Browse files
mrp089claude
andcommitted
Use Guccione passive law in the ChamberSphere block
Replace the neo-Hookean passive stress (4*gamma_W1*(1-CG^-3)) with the Guccione spherical wall stress derived for a thin-walled incompressible sphere, so the forward 0D model and the Yale calibration use the same material: S_pas = C exp(Q) [ (b_f+b_t)/2 lam^2 E_p - b_t lam^-4 E_r ] Rename gamma_W1 -> guccione_C and add the dimensionless exponents b_f, b_t as input parameters (b_fs drops out: no shear in the equibiaxial deformation). Regenerate update_solution/update_gradient from scripts/ChamberSphere.yaml. The synthetic full-state identifiability test recovers all 11 parameters (including guccione_C, b_f, b_t) to machine precision; all calibrator tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 51ff7a8 commit d093f30

5 files changed

Lines changed: 1362 additions & 1283 deletions

File tree

scripts/ChamberSphere.yaml

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,19 @@ derivatives:
2323
# below, which are exactly the quantities provided in the solver input file.
2424
# stress here represents gamma * stress
2525
# tau here represents gamma * tau
26+
# guccione_C represents gamma * C (the Guccione passive scaling)
2627
constants:
2728
- volume0
28-
- gamma_W1
29+
- guccione_C # gamma * C, scaling in front of the Guccione exponential
2930
- gamma_sigma_max # gamma * sigma_max
3031
- prestress
3132
- alpha_max
3233
- alpha_min
3334
- tsys
3435
- tdias
3536
- steepness
37+
- b_f # Guccione fiber exponent (dimensionless)
38+
- b_t # Guccione transverse exponent (dimensionless)
3639

3740
# In-cycle time of the activation. Not a state variable and not a calibration
3841
# parameter (no Jacobian column), but the activation depends on it. The solver
@@ -43,7 +46,7 @@ constants:
4346
time_symbol: t
4447

4548
helper_functions: |
46-
from sympy import Abs, Max, tanh
49+
from sympy import Abs, Max, tanh, exp
4750
4851
def V(volume):
4952
return volume + volume0
@@ -56,6 +59,27 @@ helper_functions: |
5659
stretch_val = stretch(volume)
5760
return (stretch_val) ** 2
5861
62+
# Guccione passive spherical wall stress for a thin-walled incompressible
63+
# sphere. The in-plane stretch is lam = stretch, the radial stretch lam^-2, so
64+
# the Green-Lagrange strains are E_p = (lam^2 - 1)/2 (in-plane fiber/sheet) and
65+
# E_r = (lam^-4 - 1)/2 (radial). With no shear, Q = (b_f + b_t) E_p^2 + b_t E_r^2
66+
# and the mean in-plane Cauchy stress (sigma_radial = 0 for the thin wall) is
67+
# S = C exp(Q) [ (b_f + b_t)/2 lam^2 E_p - b_t lam^-4 E_r ].
68+
# b_fs drops out: it only multiplies shear terms, which vanish here.
69+
def E_p(volume):
70+
return 0.5 * (CG(volume) - 1)
71+
72+
def E_r(volume):
73+
return 0.5 * (CG(volume) ** (-2) - 1)
74+
75+
def Q_guc(volume):
76+
return (b_f + b_t) * E_p(volume) ** 2 + b_t * E_r(volume) ** 2
77+
78+
def passive(volume):
79+
cg = CG(volume)
80+
return guccione_C * exp(Q_guc(volume)) * (
81+
0.5 * (b_f + b_t) * cg * E_p(volume) - b_t * cg ** (-2) * E_r(volume))
82+
5983
# Active contraction activation, identical to
6084
# ChamberSphere::get_elastance_values (t is the in-cycle time).
6185
S_plus = 0.5 * (1.0 + tanh((t - tsys) / steepness))
@@ -67,7 +91,7 @@ helper_functions: |
6791
6892
residuals:
6993
- stretch(volume) * stress - Pout * CG(volume)
70-
- -stress + tau + 4 * gamma_W1 * (1 - CG(volume) ** (-3)) + prestress
94+
- -stress + tau + passive(volume) + prestress
7195
- dtau_dt + act * tau - gamma_sigma_max * act_plus
7296
- Qin - Qout - dvolume_dt
7397
- Pin - Pout

scripts/make_chamber_sphere_calibration.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,26 @@
3535
# meaningful). Order matches the ParamId enum in ChamberSphere.h.
3636
TRUE = {
3737
"volume0": 1.0e-4,
38-
"gamma_W1": 1.0e4,
38+
"guccione_C": 1.0e3,
3939
"gamma_sigma_max": 1.85e5,
4040
"prestress": 1.0e3,
4141
"alpha_max": 30.0,
4242
"alpha_min": -30.0,
4343
"tsys": 0.17,
4444
"tdias": 0.484,
4545
"steepness": 0.05,
46+
"b_f": 8.0,
47+
"b_t": 3.0,
4648
}
49+
50+
51+
def passive_guccione(lam, C, b_f, b_t):
52+
"""Guccione passive spherical wall stress (matches ChamberSphere)."""
53+
Ep = 0.5 * (lam ** 2 - 1.0)
54+
Er = 0.5 * (lam ** (-4) - 1.0)
55+
Q = (b_f + b_t) * Ep ** 2 + b_t * Er ** 2
56+
return C * np.exp(Q) * (
57+
0.5 * (b_f + b_t) * lam ** 2 * Ep - b_t * lam ** (-4) * Er)
4758
PERIOD = 1.0
4859
NUM_OBS = 200
4960
PERTURB = 1.20 # 20% perturbed start
@@ -98,7 +109,8 @@ def main():
98109
# Reconstruct the consistent full state (every residual vanishes exactly).
99110
act, act_plus = activation(t, p)
100111
dtau_dt = -act * tau + p["gamma_sigma_max"] * act_plus # residual 2
101-
stress = tau + 4.0 * p["gamma_W1"] * (1.0 - CG ** (-3)) + p["prestress"] # residual 1
112+
stress = tau + passive_guccione(stretch, p["guccione_C"], p["b_f"], p["b_t"]) \
113+
+ p["prestress"] # residual 1
102114
Pout = stress / stretch # residual 0
103115
Pin = Pout # residual 4
104116

@@ -179,7 +191,7 @@ def main():
179191
rel = abs(calibrated[k] - TRUE[k]) / abs(TRUE[k])
180192
ok = ok and rel < 1e-6
181193
print(f"{k:<18}{TRUE[k]:>14.6g}{start[k]:>14.6g}{calibrated[k]:>16.8g}{rel:>12.2e}")
182-
print(f"\nAll 9 parameters recovered to rtol<1e-6: {ok}")
194+
print(f"\nAll {len(names)} parameters recovered to rtol<1e-6: {ok}")
183195
return 0 if ok else 1
184196

185197

src/model/ChamberSphere.cpp

Lines changed: 80 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,20 @@ void ChamberSphere::update_solution(
3838
SparseSystem& system, std::vector<double>& parameters,
3939
const Eigen::Matrix<double, Eigen::Dynamic, 1>& y,
4040
const Eigen::Matrix<double, Eigen::Dynamic, 1>& dy) {
41-
const double prestress = parameters[global_param_ids[ParamId::prestress]];
41+
const double b_t = parameters[global_param_ids[ParamId::b_t]];
42+
const double b_f = parameters[global_param_ids[ParamId::b_f]];
4243
const double volume0 = parameters[global_param_ids[ParamId::volume0]];
43-
const double gamma_W1 = parameters[global_param_ids[ParamId::gamma_W1]];
44+
const double guccione_C = parameters[global_param_ids[ParamId::guccione_C]];
45+
const double prestress = parameters[global_param_ids[ParamId::prestress]];
4446
const double Pout = y[global_var_ids[2]];
45-
const double stress = y[global_var_ids[4]];
4647
const double volume = y[global_var_ids[6]];
48+
const double stress = y[global_var_ids[4]];
4749
system.C.coeffRef(global_eqn_ids[0]) = -Pout*pow((volume + volume0)/volume0, 0.66666666666666663) + Pout + stress*pow((volume + volume0)/volume0, 0.33333333333333331) - stress;
48-
system.C.coeffRef(global_eqn_ids[1]) = -4*gamma_W1*pow(volume/volume0 + 1, -2.0) + 4*gamma_W1 + prestress;
50+
system.C.coeffRef(global_eqn_ids[1]) = pow((volume + volume0)/volume0, -2.6666666666666665)*(-guccione_C*(0.5*b_t*(1 - pow((volume + volume0)/volume0, 1.3333333333333333)) - 0.25*pow((volume + volume0)/volume0, 3.333333333333333)*(b_f + b_t)*(pow((volume + volume0)/volume0, 0.66666666666666663) - 1))*exp(0.25*pow((volume + volume0)/volume0, -2.6666666666666665)*(b_t*pow(1 - pow((volume + volume0)/volume0, 1.3333333333333333), 2) + pow((volume + volume0)/volume0, 2.6666666666666665)*(b_f + b_t)*pow(pow((volume + volume0)/volume0, 0.66666666666666663) - 1, 2))) + prestress*pow((volume + volume0)/volume0, 2.6666666666666665));
4951
system.dC_dy.coeffRef(global_eqn_ids[0], global_var_ids[2]) = 1 - pow((volume + volume0)/volume0, 0.66666666666666663);
5052
system.dC_dy.coeffRef(global_eqn_ids[0], global_var_ids[4]) = pow((volume + volume0)/volume0, 0.33333333333333331) - 1;
5153
system.dC_dy.coeffRef(global_eqn_ids[0], global_var_ids[6]) = (-0.66666666666666663*Pout*pow((volume + volume0)/volume0, 0.66666666666666663) + 0.33333333333333331*stress*pow((volume + volume0)/volume0, 0.33333333333333331))/(volume + volume0);
52-
system.dC_dy.coeffRef(global_eqn_ids[1], global_var_ids[6]) = 8.0*gamma_W1*pow((volume + volume0)/volume0, -3.0)/volume0;
54+
system.dC_dy.coeffRef(global_eqn_ids[1], global_var_ids[6]) = pow((volume + volume0)/volume0, -8.0)*(pow((volume + volume0)/volume0, 2.6666666666666665)*(guccione_C*(0.5*b_t*(pow((volume + volume0)/volume0, 1.3333333333333333) - 1) + 0.25*pow((volume + volume0)/volume0, 3.333333333333333)*(b_f + b_t)*(pow((volume + volume0)/volume0, 0.66666666666666663) - 1))*(0.66666666666666663*b_t*pow((volume + volume0)/volume0, 1.3333333333333333)*(pow((volume + volume0)/volume0, 1.3333333333333333) - 1) - 0.66666666666666663*b_t*pow(pow((volume + volume0)/volume0, 1.3333333333333333) - 1, 2) + 0.33333333333333331*pow((volume + volume0)/volume0, 3.333333333333333)*(b_f + b_t)*(pow((volume + volume0)/volume0, 0.66666666666666663) - 1))*exp(0.25*pow((volume + volume0)/volume0, -2.6666666666666665)*(b_t*pow(pow((volume + volume0)/volume0, 1.3333333333333333) - 1, 2) + pow((volume + volume0)/volume0, 2.6666666666666665)*(b_f + b_t)*pow(pow((volume + volume0)/volume0, 0.66666666666666663) - 1, 2))) + pow((volume + volume0)/volume0, 2.6666666666666665)*(guccione_C*(0.66666666666666663*b_t*pow((volume + volume0)/volume0, 1.3333333333333333) + 0.83333333333333326*pow((volume + volume0)/volume0, 3.333333333333333)*(b_f + b_t)*(pow((volume + volume0)/volume0, 0.66666666666666663) - 1) + 0.16666666666666666*pow((volume + volume0)/volume0, 3.9999999999999996)*(b_f + b_t))*exp(0.25*pow((volume + volume0)/volume0, -2.6666666666666665)*(b_t*pow(pow((volume + volume0)/volume0, 1.3333333333333333) - 1, 2) + pow((volume + volume0)/volume0, 2.6666666666666665)*(b_f + b_t)*pow(pow((volume + volume0)/volume0, 0.66666666666666663) - 1, 2))) + 2.6666666666666665*prestress*pow((volume + volume0)/volume0, 2.6666666666666665))) - 2.6666666666666665*pow((volume + volume0)/volume0, 5.333333333333333)*(guccione_C*(0.5*b_t*(pow((volume + volume0)/volume0, 1.3333333333333333) - 1) + 0.25*pow((volume + volume0)/volume0, 3.333333333333333)*(b_f + b_t)*(pow((volume + volume0)/volume0, 0.66666666666666663) - 1))*exp(0.25*pow((volume + volume0)/volume0, -2.6666666666666665)*(b_t*pow(pow((volume + volume0)/volume0, 1.3333333333333333) - 1, 2) + pow((volume + volume0)/volume0, 2.6666666666666665)*(b_f + b_t)*pow(pow((volume + volume0)/volume0, 0.66666666666666663) - 1, 2))) + prestress*pow((volume + volume0)/volume0, 2.6666666666666665)))/(volume + volume0);
5355
}
5456

5557
void ChamberSphere::get_elastance_values(std::vector<double>& parameters) {
@@ -82,22 +84,18 @@ void ChamberSphere::update_gradient(
8284
Eigen::Matrix<double, Eigen::Dynamic, 1>& residual,
8385
Eigen::Matrix<double, Eigen::Dynamic, 1>& alpha, std::vector<double>& y,
8486
std::vector<double>& dy) {
85-
// Calibrates the chamber parameters from a full-state observation set. The
86-
// time-independent parameters (volume0, gamma_W1, prestress) appear in the
87-
// momentum and spherical-stress equations; the active-stress equation (eq 2)
88-
// and its parameters (gamma_sigma_max and the activation timing) depend on the
89-
// observation time, which the optimizer supplies via model->time when a time
90-
// vector is given. Shared subexpressions are hoisted into temporaries (xN).
91-
// Generated by scripts/jacobian.py from scripts/ChamberSphere.yaml.
87+
// Guccione passive law; generated by scripts/jacobian.py from scripts/ChamberSphere.yaml.
9288
const double volume0 = alpha[global_param_ids[ParamId::volume0]];
93-
const double gamma_W1 = alpha[global_param_ids[ParamId::gamma_W1]];
89+
const double guccione_C = alpha[global_param_ids[ParamId::guccione_C]];
9490
const double gamma_sigma_max = alpha[global_param_ids[ParamId::gamma_sigma_max]];
9591
const double prestress = alpha[global_param_ids[ParamId::prestress]];
9692
const double alpha_max = alpha[global_param_ids[ParamId::alpha_max]];
9793
const double alpha_min = alpha[global_param_ids[ParamId::alpha_min]];
9894
const double tsys = alpha[global_param_ids[ParamId::tsys]];
9995
const double tdias = alpha[global_param_ids[ParamId::tdias]];
10096
const double steepness = alpha[global_param_ids[ParamId::steepness]];
97+
const double b_f = alpha[global_param_ids[ParamId::b_f]];
98+
const double b_t = alpha[global_param_ids[ParamId::b_t]];
10199
const double Pin = y[global_var_ids[0]];
102100
const double Qin = y[global_var_ids[1]];
103101
const double Pout = y[global_var_ids[2]];
@@ -112,54 +110,76 @@ void ChamberSphere::update_gradient(
112110
const double x0 = 1.0/volume0;
113111
const double x1 = volume + volume0;
114112
const double x2 = x0*x1;
115-
const double x3 = Pout*pow(x2, 0.66666666666666663);
116-
const double x4 = pow(x2, 0.33333333333333331);
117-
const double x5 = pow(x2, -2.0);
118-
const double x6 = 1.0/steepness;
119-
const double x7 = t - tdias;
120-
const double x8 = tanh(x6*x7);
121-
const double x9 = 0.5*x8 - 0.5;
122-
const double x10 = t - tsys;
123-
const double x11 = tanh(x10*x6);
124-
const double x12 = 0.5*x11 + 0.5;
125-
const double x13 = x12*x9;
126-
const double x14 = x13 + 1;
127-
const double x15 = alpha_max*x13 - alpha_min*x14;
128-
const double x16 = -x9;
129-
const double x17 = x12*x16;
130-
const double x18 = 1 - x17;
131-
const double x19 = alpha_max*x17 + alpha_min*x18;
132-
const double x20 = fmax(0, x19);
133-
const double x21 = volume*x0;
134-
const double x22 = x21/x1;
135-
const double x23 = gamma_sigma_max*(x19 > 0 ? 1.0 : 0.0);
136-
const double x24 = (((x15) > 0) - ((x15) < 0));
137-
const double x25 = 1 - pow(x11, 2);
138-
const double x26 = 0.5*x6;
139-
const double x27 = x25*x26;
140-
const double x28 = 1 - pow(x8, 2);
141-
const double x29 = x12*x28;
142-
const double x30 = alpha_max*x26*x29 - 0.5*alpha_min*x12*x28*x6;
143-
const double x31 = 0.5/pow(steepness, 2);
144-
const double x32 = x10*x25*x31;
145-
const double x33 = x16*x32;
146-
const double x34 = x29*x31*x7;
147-
const double x35 = alpha_max*x34;
148-
const double x36 = x32*x9;
149-
150-
residual(global_eqn_ids[0]) = stress*x4 - x3;
151-
residual(global_eqn_ids[1]) = 4*gamma_W1*(1 - x5) + prestress - stress + tau;
152-
residual(global_eqn_ids[2]) = dtau_dt - gamma_sigma_max*x20 + tau*fabs(x15);
113+
const double x3 = pow(x2, 0.66666666666666663);
114+
const double x4 = Pout*x3;
115+
const double x5 = pow(x2, 0.33333333333333331);
116+
const double x6 = pow(x2, 1.3333333333333333);
117+
const double x7 = 1.0/x6;
118+
const double x8 = 0.5*x7 - 0.5;
119+
const double x9 = b_f + b_t;
120+
const double x10 = 0.5*x3 - 0.5;
121+
const double x11 = 0.5*b_t;
122+
const double x12 = 1.0/steepness;
123+
const double x13 = t - tdias;
124+
const double x14 = tanh(x12*x13);
125+
const double x15 = 0.5*x14 - 0.5;
126+
const double x16 = t - tsys;
127+
const double x17 = tanh(x12*x16);
128+
const double x18 = 0.5*x17 + 0.5;
129+
const double x19 = x15*x18;
130+
const double x20 = x19 + 1;
131+
const double x21 = alpha_max*x19 - alpha_min*x20;
132+
const double x22 = -x15;
133+
const double x23 = x18*x22;
134+
const double x24 = 1 - x23;
135+
const double x25 = alpha_max*x23 + alpha_min*x24;
136+
const double x26 = fmax(0, x25);
137+
const double x27 = volume*x0/x1;
138+
const double x28 = pow(x2, 5.333333333333333);
139+
const double x29 = 0.66666666666666663*b_t;
140+
const double x30 = pow(x2, 2.6666666666666665);
141+
const double x31 = x3 - 1;
142+
const double x32 = 1 - x6;
143+
const double x33 = pow(x2, 3.333333333333333);
144+
const double x34 = x11*x32 - 0.25*x31*x33*x9;
145+
const double x35 = x30*x34;
146+
const double x36 = pow(x32, 2);
147+
const double x37 = x30*pow(x31, 2);
148+
const double x38 = 1.0/x30;
149+
const double x39 = 0.25*x38;
150+
const double x40 = exp(x39*(b_t*x36 + x37*x9));
151+
const double x41 = guccione_C*x40;
152+
const double x42 = pow(x2, -8.0)*x41;
153+
const double x43 = gamma_sigma_max*(x25 > 0 ? 1.0 : 0.0);
154+
const double x44 = (((x21) > 0) - ((x21) < 0));
155+
const double x45 = 1 - pow(x17, 2);
156+
const double x46 = 0.5*x12;
157+
const double x47 = x45*x46;
158+
const double x48 = 1 - pow(x14, 2);
159+
const double x49 = x18*x48;
160+
const double x50 = alpha_max*x46*x49 - 0.5*alpha_min*x12*x18*x48;
161+
const double x51 = 0.5/pow(steepness, 2);
162+
const double x52 = x16*x45*x51;
163+
const double x53 = x22*x52;
164+
const double x54 = x13*x49*x51;
165+
const double x55 = alpha_max*x54;
166+
const double x56 = x15*x52;
167+
168+
residual(global_eqn_ids[0]) = stress*x5 - x4;
169+
residual(global_eqn_ids[1]) = guccione_C*(-b_t*x7*x8 + x10*x3*(0.5*b_f + x11))*exp(b_t*pow(x8, 2) + pow(x10, 2)*x9) + prestress - stress + tau;
170+
residual(global_eqn_ids[2]) = dtau_dt - gamma_sigma_max*x26 + tau*fabs(x21);
153171
residual(global_eqn_ids[3]) = Qin - Qout - dvolume_dt;
154172
residual(global_eqn_ids[4]) = Pin - Pout;
155-
jacobian.coeffRef(global_eqn_ids[0], global_param_ids[ParamId::volume0]) = x22*(-0.33333333333333331*stress*x4 + 0.66666666666666663*x3);
156-
jacobian.coeffRef(global_eqn_ids[1], global_param_ids[ParamId::volume0]) = -8.0*gamma_W1*x22*x5;
157-
jacobian.coeffRef(global_eqn_ids[1], global_param_ids[ParamId::gamma_W1]) = 4 - 4*pow(x21 + 1, -2.0);
158-
jacobian.coeffRef(global_eqn_ids[2], global_param_ids[ParamId::gamma_sigma_max]) = -x20;
173+
jacobian.coeffRef(global_eqn_ids[0], global_param_ids[ParamId::volume0]) = x27*(-0.33333333333333331*stress*x5 + 0.66666666666666663*x4);
174+
jacobian.coeffRef(global_eqn_ids[1], global_param_ids[ParamId::volume0]) = x27*x42*(x28*(x29*(x6 - 2) + 0.16666666666666666*x30*x9*(-x3*x31 - x6)) + x35*(-x29*x32 + 0.33333333333333331*x31*x33*x9));
175+
jacobian.coeffRef(global_eqn_ids[1], global_param_ids[ParamId::guccione_C]) = -x34*x38*x40;
176+
jacobian.coeffRef(global_eqn_ids[2], global_param_ids[ParamId::gamma_sigma_max]) = -x26;
159177
jacobian.coeffRef(global_eqn_ids[1], global_param_ids[ParamId::prestress]) = 1;
160-
jacobian.coeffRef(global_eqn_ids[2], global_param_ids[ParamId::alpha_max]) = tau*x12*x24*x9 - x17*x23;
161-
jacobian.coeffRef(global_eqn_ids[2], global_param_ids[ParamId::alpha_min]) = -tau*x14*x24 - x18*x23;
162-
jacobian.coeffRef(global_eqn_ids[2], global_param_ids[ParamId::tsys]) = tau*x24*(-alpha_max*x27*x9 + 0.5*alpha_min*x25*x6*x9) - x23*(-alpha_max*x16*x27 + 0.5*alpha_min*x16*x25*x6);
163-
jacobian.coeffRef(global_eqn_ids[2], global_param_ids[ParamId::tdias]) = -tau*x24*x30 - x23*x30;
164-
jacobian.coeffRef(global_eqn_ids[2], global_param_ids[ParamId::steepness]) = tau*x24*(-alpha_max*x36 - alpha_min*(-x34 - x36) - x35) - x23*(-alpha_max*x33 + alpha_min*(x33 - x34) + x35);
178+
jacobian.coeffRef(global_eqn_ids[2], global_param_ids[ParamId::alpha_max]) = tau*x15*x18*x44 - x23*x43;
179+
jacobian.coeffRef(global_eqn_ids[2], global_param_ids[ParamId::alpha_min]) = -tau*x20*x44 - x24*x43;
180+
jacobian.coeffRef(global_eqn_ids[2], global_param_ids[ParamId::tsys]) = tau*x44*(-alpha_max*x15*x47 + 0.5*alpha_min*x12*x15*x45) - x43*(-alpha_max*x22*x47 + 0.5*alpha_min*x12*x22*x45);
181+
jacobian.coeffRef(global_eqn_ids[2], global_param_ids[ParamId::tdias]) = -tau*x44*x50 - x43*x50;
182+
jacobian.coeffRef(global_eqn_ids[2], global_param_ids[ParamId::steepness]) = tau*x44*(-alpha_max*x56 - alpha_min*(-x54 - x56) - x55) - x43*(-alpha_max*x53 + alpha_min*(x53 - x54) + x55);
183+
jacobian.coeffRef(global_eqn_ids[1], global_param_ids[ParamId::b_f]) = x31*x39*x41*(-x31*x34 + x33);
184+
jacobian.coeffRef(global_eqn_ids[1], global_param_ids[ParamId::b_t]) = x42*(x28*(x33*(0.25*x3 - 0.25) + 0.5*x6 - 0.5) - 0.25*x35*(x36 + x37));
165185
}

0 commit comments

Comments
 (0)