DEV Community

Thana B.
Thana B.

Posted on • Edited on

Implementation of Optimization of Red Blood Cell Shape Using Spherical Harmonics Parameterization

Introduction

Red blood cells (RBCs) exhibit a distinctive biconcave disc shape, essential for their role in gas exchange and traversing microvasculature. Modeling and optimizing this shape can provide valuable insights into the cell's mechanical properties and behaviors under physiological and pathological conditions.

This article presents a comprehensive mathematical model for optimizing the RBC shape using spherical harmonics parameterization under axial symmetry. We then provide a detailed Python implementation, explicitly mapping each mathematical expression to corresponding code blocks. The implementation utilizes the CasADi library for symbolic computations and numerical optimization.


Mathematical Formulation for RBC Shape Optimization with Fixed Posture and Symmetry

1. Decision Variables

Spherical Harmonics Coefficients (Axially Symmetric):

The shape of the RBC is represented using only the coefficients for axisymmetric spherical harmonics:

CL,0for L0,1,,Lmax C_{L,0} \quad \text{for } L \in {0, 1, \ldots, L_{\text{max}}}

This reduces the number of decision variables significantly since only the coefficients corresponding to K=0K = 0 are retained due to axial symmetry.


2. Objective Function

The objective is to minimize the total energy of the RBC membrane:

MinimizeEtotal(CL,0)=Ebending(CL,0)+Eshear(CL,0)+Ecoupling(CL,0)+Eviscous(CL,0)+Ethermal(CL,0)+Ehydro(CL,0) \text{Minimize} \quad E_{\text{total}}(C_{L,0}) = E_{\text{bending}}(C_{L,0}) + E_{\text{shear}}(C_{L,0}) + E_{\text{coupling}}(C_{L,0}) + E_{\text{viscous}}(C_{L,0}) + E_{\text{thermal}}(C_{L,0}) + E_{\text{hydro}}(C_{L,0})

Where each energy term is calculated using the reduced set of coefficients. The energy components are:

Bending Energy

Ebending=i=1Nkb2(2HiC0)2Ai E_{\text{bending}} = \sum_{i=1}^{N} \frac{k_b}{2} \left( 2H_i - C_0 \right)^2 \cdot A_i
  • kbk_b : Bending modulus.
  • HiH_i : Mean curvature at point ii .
  • C0C_0 : Spontaneous curvature (assumed zero in this model).
  • AiA_i : Area element at point ii .

Shear Energy

Eshear=i=1NKs2(λ1,i2+λ2,i22)Ai E_{\text{shear}} = \sum_{i=1}^{N} \frac{K_s}{2} \left( \lambda_{1,i}^2 + \lambda_{2,i}^2 - 2 \right) \cdot A_i
  • KsK_s : Shear modulus.
  • λ1,i,λ2,i\lambda_{1,i}, \lambda_{2,i} : Principal stretches at point ii .

Coupling Energy

Ecoupling=i=1Nγ(HiC0)(λ1,i2+λ2,i2)Ai E_{\text{coupling}} = \sum_{i=1}^{N} \gamma (H_i - C_0) \left( \lambda_{1,i}^2 + \lambda_{2,i}^2 \right) \cdot A_i
  • γ\gamma : Coupling constant.

Viscous Energy

Eviscous=i=1Nη(Hit)2Ai E_{\text{viscous}} = \sum_{i=1}^{N} \eta \left( \frac{\partial H_i}{\partial t} \right)^2 \cdot A_i
  • η\eta : Viscosity coefficient.
  • Hit\frac{\partial H_i}{\partial t} : Temporal change in curvature.

Thermal Fluctuation Energy

Ethermal=i=1NFthermal,iAi E_{\text{thermal}} = \sum_{i=1}^{N} F_{\text{thermal},i} \cdot A_i
  • Fthermal,iF_{\text{thermal},i} : Stochastic thermal fluctuation force at point ii .

Hydrodynamic Forces

Ehydro=i=1NPflow,iniAi E_{\text{hydro}} = \sum_{i=1}^{N} P_{\text{flow},i} \cdot \mathbf{n}_i \cdot A_i
  • Pflow,iP_{\text{flow},i} : Pressure or shear force from fluid at point ii .
  • ni\mathbf{n}_i : Normal vector at point ii .

3. Constraints

3.1 Volume Constraint

Ensure the RBC volume matches physiological values:

V(CL,0)=i=1NVi=Vtarget(e.g., Vtarget90μm3) V(C_{L,0}) = \sum_{i=1}^{N} V_i = V_{\text{target}} \quad \text{(e.g., } V_{\text{target}} \approx 90 \, \mu\text{m}^3 \text{)}

3.2 Surface Area Constraint

Ensure the surface area remains constant:

A(CL,0)=i=1NAi=Atarget(e.g., Atarget145μm2) A(C_{L,0}) = \sum_{i=1}^{N} A_i = A_{\text{target}} \quad \text{(e.g., } A_{\text{target}} \approx 145 \, \mu\text{m}^2 \text{)}

3.3 Area Difference Constraint

Account for the area difference between the inner and outer leaflets:

ΔA(CL,0)=i=1N2HiAi=ΔAtarget(e.g., ΔAtarget0.61.0) \Delta A(C_{L,0}) = \sum_{i=1}^{N} 2H_i \cdot A_i = \Delta A_{\text{target}} \quad \text{(e.g., } \Delta A_{\text{target}} \approx 0.6 - 1.0 \text{)}

3.4 Reduced Volume Constraint

Maintain a reduced volume less than 1 for a non-spherical shape:

v=V(CL,0)(43π(A(CL,0)4π)3/2)and v[0.6,0.7] v = \frac{V(C_{L,0})}{\left( \frac{4}{3} \pi \left( \frac{A(C_{L,0})}{4 \pi} \right)^{3/2} \right)} \quad \text{and } v \in [0.6, 0.7]

3.5 Symmetry Constraints

Impose symmetry on the coefficients:

CL,K=0for all K0 C_{L,K} = 0 \quad \text{for all } K \neq 0

Python Implementation Using CasADi

We implement the mathematical model using Python and the CasADi library, which allows for symbolic differentiation and optimization. Below, each code block is mapped to the corresponding mathematical expression.

1. Import Necessary Libraries

import casadi as ca  # CasADi for symbolic computations
import numpy as np   # NumPy for numerical operations
import matplotlib.pyplot as plt  # For plotting
from mpl_toolkits.mplot3d import Axes3D  # For 3D plotting
Enter fullscreen mode Exit fullscreen mode

2. Define Constants and Parameters

Set the physical constants, target values, and discretization parameters as per physiological data.

# Physical constants
k_b = 2e-19    # Bending modulus (J)
K_s = 5e-2     # Shear modulus (N/m), may be simplified
gamma = 1e-9   # Coupling constant
C_0 = 0        # Spontaneous curvature (assumed zero)

# Target values for constraints
V_target = 90e-18      # Target volume (m³)
A_target = 145e-12     # Target surface area (m²)
Delta_A_target = 0.85  # Target area difference
v_target = 0.7         # Target reduced volume

# Spherical harmonics parameters
L_max = 6    # Maximum degree for spherical harmonics

# Discretization parameters
N_theta = 200    # Number of discretization points for theta
theta_values = np.linspace(0, np.pi, N_theta)  # θ grid points
dtheta = theta_values[1] - theta_values[0]
Enter fullscreen mode Exit fullscreen mode

3. Set Up the Optimization Problem

Decision Variables:

Mathematical Expression:

CL,0for L=0 to Lmax C_{L,0} \quad \text{for } L = 0 \text{ to } L_{\text{max}}

Code Implementation:

# Create an optimization problem
opt = ca.Opti()

# Define Theta as a parameter
theta_mx = opt.parameter(N_theta)
opt.set_value(theta_mx, theta_values)
cos_theta = ca.cos(theta_mx)
sin_theta = ca.sin(theta_mx)

# Define Decision Variables
C_L0_var = opt.variable(L_max + 1)  # Spherical harmonics coefficients
Enter fullscreen mode Exit fullscreen mode

4. Compute Legendre Polynomials

Compute PL(cosθ)P_L(\cos\theta) for L=0L = 0 to LmaxL_{\text{max}} .

Mathematical Expression:

PL(cosθ) P_L(\cos\theta)

Code Implementation:

# Function to compute Legendre polynomials iteratively
def legendre_P_iterative(L_max, x):
    P = []
    P.append(ca.MX.ones(x.shape))  # P0 = 1
    if L_max >= 1:
        P.append(x)  # P1 = x
        for L in range(2, L_max + 1):
            P_L = ((2 * L - 1) * x * P[L - 1] - (L - 1) * P[L - 2]) / L
            P.append(P_L)
    return P

# Compute Legendre Polynomials
P_L_list = legendre_P_iterative(L_max, cos_theta)
Enter fullscreen mode Exit fullscreen mode

5. Shape Representation r(θ)r(\theta)

Mathematical Expression:

r(θ)=L=0LmaxCL,0PL(cosθ) r(\theta) = \sum_{L=0}^{L_{\text{max}}} C_{L,0} \, P_L(\cos\theta)

Code Implementation:

# Compute r(θ) symbolically
r_theta_var = C_L0_var[0] * P_L_list[0]
for L in range(1, L_max + 1):
    r_theta_var += C_L0_var[L] * P_L_list[L]
Enter fullscreen mode Exit fullscreen mode

6. Compute Geometric Quantities

First Derivative drdθ\frac{dr}{d\theta}

Mathematical Expression:

drdθ \frac{dr}{d\theta}

Code Implementation:

# Compute first derivative dr/dθ
dr_dtheta_var = ca.jtimes(r_theta_var, theta_mx, ca.DM.ones(N_theta))
Enter fullscreen mode Exit fullscreen mode

Second Derivative d2rdθ2\frac{d^2r}{d\theta^2}

Mathematical Expression:

d2rdθ2 \frac{d^2r}{d\theta^2}

Code Implementation:

# Compute second derivative d²r/dθ²
d2r_dtheta2_var = ca.jtimes(dr_dtheta_var, theta_mx, ca.DM.ones(N_theta))
Enter fullscreen mode Exit fullscreen mode

Metric Coefficient EE

Mathematical Expression:

E=(drdθ)2+r(θ)2 E = \left( \frac{dr}{d\theta} \right)^2 + r(\theta)^2

Code Implementation:

# Compute metric coefficient E (First Fundamental Form)
E_var = dr_dtheta_var**2 + r_theta_var**2
Enter fullscreen mode Exit fullscreen mode

Area Element dAdA

Mathematical Expression:

Ai=r(θi)sinθiE(θi)Δθ A_i = r(\theta_i) \sin\theta_i \sqrt{E(\theta_i)} \Delta\theta

Code Implementation:

# Compute area elements dA
dA_var = r_theta_var * sin_theta * ca.sqrt(E_var) * dtheta
Enter fullscreen mode Exit fullscreen mode

Mean Curvature HH

Mathematical Expression (Simplified for Axisymmetric Surfaces):

H=(drdθ)2rd2rdθ2+rdrdθtanθ((drdθ)2+r2)3/2 H = \frac{\left( \frac{dr}{d\theta} \right)^2 - r \frac{d^2r}{d\theta^2} + r \frac{dr}{d\theta} \tan\theta}{\left( \left( \frac{dr}{d\theta} \right)^2 + r^2 \right)^{3/2}}

Code Implementation:

# Compute mean curvature H(θ)
numerator_var = (
    dr_dtheta_var**2
    - r_theta_var * d2r_dtheta2_var
    + r_theta_var * dr_dtheta_var * ca.tan(theta_mx)
)
denominator_var = (dr_dtheta_var**2 + r_theta_var**2) ** (1.5)
H_i_var = numerator_var / denominator_var
Enter fullscreen mode Exit fullscreen mode

7. Define Energy Components

Bending Energy

Mathematical Expression:

Ebending=i=1Nkb2(2HiC0)2Ai E_{\text{bending}} = \sum_{i=1}^{N} \frac{k_b}{2} \left( 2H_i - C_0 \right)^2 A_i

Code Implementation:

# Bending Energy
E_bending_var = (k_b / 2.0) * ca.sum1((2.0 * H_i_var - C_0) ** 2 * dA_var)
Enter fullscreen mode Exit fullscreen mode

Shear Energy

Assuming negligible shear deformation:

Mathematical Expression:

Eshear=0 E_{\text{shear}} = 0

Code Implementation:

# Shear Energy (simplified)
E_shear_var = 0
Enter fullscreen mode Exit fullscreen mode

Coupling Energy

Mathematical Expression:

Ecoupling=i=1Nγ(HiC0)Ai E_{\text{coupling}} = \sum_{i=1}^{N} \gamma (H_i - C_0) \cdot A_i

Code Implementation:

# Coupling Energy
E_coupling_var = gamma * ca.sum1((H_i_var - C_0) * dA_var)
Enter fullscreen mode Exit fullscreen mode

Total Energy

Mathematical Expression:

Etotal=Ebending+Eshear+Ecoupling E_{\text{total}} = E_{\text{bending}} + E_{\text{shear}} + E_{\text{coupling}}

Code Implementation:

# Total Energy
E_total_var = E_bending_var + E_shear_var + E_coupling_var
Enter fullscreen mode Exit fullscreen mode

8. Define Constraints

Volume Constraint

Mathematical Expression:

V=i=1NVi=Vtarget V = \sum_{i=1}^{N} V_i = V_{\text{target}}

Where:

Vi=2πri2sinθiΔθ V_i = 2\pi r_i^2 \sin\theta_i \Delta\theta

Code Implementation:

# Volume Constraint
V_var = 2 * np.pi * ca.sum1((r_theta_var**2) * sin_theta * dtheta)
opt.subject_to(V_var == V_target)
Enter fullscreen mode Exit fullscreen mode

Surface Area Constraint

Mathematical Expression:

A=i=1NAi=Atarget A = \sum_{i=1}^{N} A_i = A_{\text{target}}

Code Implementation:

# Surface Area Constraint
A_var = 2.0 * ca.pi * ca.sum1(r_theta_var * sin_theta * ca.sqrt(E_var) * dtheta)
opt.subject_to(A_var == A_target)
Enter fullscreen mode Exit fullscreen mode

Reduced Volume Constraint

Mathematical Expression:

v=V(43πR03)=vtarget,R0=A4π v = \frac{V}{\left( \frac{4}{3} \pi R_0^3 \right)} = v_{\text{target}}, \quad R_0 = \sqrt{\frac{A}{4\pi}}

Code Implementation:

# Reduced Volume Constraint
v_var = V_var / ((4.0 / 3.0) * ca.pi * (A_var / (4.0 * ca.pi)) ** 1.5)
opt.subject_to(v_var == v_target)
Enter fullscreen mode Exit fullscreen mode

Area Difference Constraint

Mathematical Expression:

ΔA=i=1N2HiAi=ΔAtarget \Delta A = \sum_{i=1}^{N} 2H_i A_i = \Delta A_{\text{target}}

Code Implementation:

# Area Difference Constraint
Delta_A_var = ca.sum1(2.0 * H_i_var * dA_var)
opt.subject_to(Delta_A_var == Delta_A_target)
Enter fullscreen mode Exit fullscreen mode

Symmetry Constraints

Only coefficients CL,0C_{L,0} are considered, ensuring axial symmetry.

Code Implementation:

  • Implicitly enforced by only defining CL,0C_{L,0} variables (no CL,KC_{L,K} for K0K \neq 0 ).

Positivity Constraint for r(θ)r(\theta)

Ensure physical validity of the shape.

Mathematical Expression:

r(θi)>0i r(\theta_i) > 0 \quad \forall i

Code Implementation:

# Ensure positive radius
opt.subject_to(r_theta_var > 0)
Enter fullscreen mode Exit fullscreen mode

Biconcavity Enforcement

To ensure a biconcave shape, enforce drdθ<0\frac{dr}{d\theta} < 0 around θ=π2\theta = \frac{\pi}{2} .

Mathematical Expression:

drdθθ=π2<0 \frac{dr}{d\theta} \bigg|_{\theta = \frac{\pi}{2}} < 0

Code Implementation:

# Enforce biconcavity around θ = π/2
delta_theta = np.pi / 20        # Range around θ = π/2
theta_mid = np.pi / 2
theta_lower = theta_mid - delta_theta
theta_upper = theta_mid + delta_theta

# Indices within specified θ range
theta_mid_indices = np.where(
    (theta_values >= theta_lower) & (theta_values <= theta_upper)
)[0]

epsilon = 1e-6  # Small positive value

# Enforce dr/dθ <= -epsilon in the specified θ range
for idx in theta_mid_indices:
    opt.subject_to(dr_dtheta_var[idx] <= -epsilon)
Enter fullscreen mode Exit fullscreen mode

9. Set Objective and Solve

Code Implementation:

# Set the objective function
opt.minimize(E_total_var)

# Set initial guesses for coefficients
C_L0_initial = np.zeros(L_max + 1)
C_L0_initial[0] = bound_scale  # Approximate radius
opt.set_initial(C_L0_var, C_L0_initial)

# Set solver options
p_opts = {"expand": True}
s_opts = {"max_iter": 10000, "tol": 1e-10, "acceptable_tol": 1e-8}

# Specify solver
opt.solver("ipopt", p_opts, s_opts)

# Solve the optimization problem
try:
    sol = opt.solve()
except RuntimeError as e:
    print("Solver failed:", e)
    sol = opt.debug   # Retrieve solution even if solver fails

# Retrieve the optimal coefficients
C_L0_opt = sol.value(C_L0_var)
Enter fullscreen mode Exit fullscreen mode

10. Post-processing and Visualization

Compute Optimized Shape

Mathematical Expression:

ropt(θ)=L=0LmaxCL,0optPL(cosθ) r_{\text{opt}}(\theta) = \sum_{L=0}^{L_{\text{max}}} C_{L,0}^{\text{opt}} \, P_L(\cos\theta)

Code Implementation:

# Compute the optimal shape r(θ) using the optimal coefficients
r_theta_opt = C_L0_opt[0] * P_L_list[0]
for L in range(1, L_max + 1):
    r_theta_opt += C_L0_opt[L] * P_L_list[L]
r_theta_opt = sol.value(r_theta_opt)
Enter fullscreen mode Exit fullscreen mode

Generate 3D Coordinates

Convert ropt(θ)r_{\text{opt}}(\theta) to Cartesian coordinates for visualization.

Mathematical Expressions:

x=r(θ)sinθcosϕ y=r(θ)sinθsinϕ z=r(θ)cosθ \begin{align*} x &= r(\theta) \sin\theta \cos\phi \ y &= r(\theta) \sin\theta \sin\phi \ z &= r(\theta) \cos\theta \end{align*}

Code Implementation:

# Additional discretization for φ
N_phi = 200
phi_values = np.linspace(0, 2 * np.pi, N_phi)
theta_grid, phi_grid = np.meshgrid(theta_values, phi_values)

# Replicate r(θ) across φ
r_grid = np.tile(r_theta_opt, (N_phi, 1))

# Compute the 3D coordinates (x, y, z)
x_coords = r_grid * np.sin(theta_grid) * np.cos(phi_grid)
y_coords = r_grid * np.sin(theta_grid) * np.sin(phi_grid)
z_coords = r_grid * np.cos(theta_grid)
Enter fullscreen mode Exit fullscreen mode

Plot the Optimized Shape

Code Implementation:

# Plot the 3D shape
fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(111, projection="3d")
ax.plot_surface(
    x_coords,
    y_coords,
    z_coords,
    rstride=4,
    cstride=4,
    color='red',
    edgecolor="none",
    alpha=0.8
)
ax.set_xlabel("x (m)")
ax.set_ylabel("y (m)")
ax.set_zlabel("z (m)")
ax.set_title("Optimized Red Blood Cell Shape (3D)")

# Ensure equal scaling on all axes
ax.set_box_aspect([np.ptp(x_coords), np.ptp(y_coords), np.ptp(z_coords)])

plt.tight_layout()
plt.show()
Enter fullscreen mode Exit fullscreen mode

Shape Of Red Blood Cell at Optimize Energy

Rotate around x axis


11. Validate Results

Ensure that the optimized shape satisfies the constraints.

Code Implementation:

# Compute final volume and area
V_final = sol.value(V_var)
A_final = sol.value(A_var)
v_final = sol.value(v_var)
Delta_A_final = sol.value(Delta_A_var)

print(f"Final Volume: {V_final:.3e}")
print(f"Target Volume: {V_target:.3e}")
print(f"Final Surface Area: {A_final:.3e}")
print(f"Target Surface Area: {A_target:.3e}")
print(f"Final Reduced Volume: {v_final:.3f}")
print(f"Target Reduced Volume: {v_target:.3f}")
print(f"Final Delta A: {Delta_A_final:.3e}")
print(f"Target Delta A: {Delta_A_target:.3e}")
Enter fullscreen mode Exit fullscreen mode

Discussion

Mapping Mathematical Expressions to Code

In the above implementation, we meticulously map each mathematical expression from the model to corresponding code blocks. This explicit correspondence ensures that the code accurately reflects the theoretical formulations and that each component is correctly implemented.

  • Decision Variables: The spherical harmonics coefficients CL,0C_{L,0} are represented by C_L0_var.
  • Shape Representation: The radial function r(θ)r(\theta) is constructed using the Legendre polynomials and the coefficients.
  • Geometric Quantities: Derivatives, mean curvature, and area elements are computed symbolically, matching the mathematical definitions.
  • Energy Components: The bending and coupling energies are calculated as per their mathematical expressions, and summed to form the total energy.
  • Constraints: Volume, surface area, reduced volume, area difference, and symmetry constraints are enforced using opt.subject_to.
  • Optimization: The total energy is minimized using IPOPT via CasADi.
  • Visualization: The optimized shape is visualized in 3D, providing a graphical representation of the results.
  • Validation: Final values are compared to target constraints to verify the optimization's success.

Simplifications and Assumptions

  • Shear Energy: Set to zero, assuming negligible shear deformation for simplicity.
  • Viscous, Thermal, and Hydrodynamic Energies: Omitted in this static optimization model.
  • Spontaneous Curvature ( C0C_0 ): Assumed zero, but can be adjusted if needed.

Advantages of Using CasADi

  • Symbolic Differentiation: Enables precise computation of derivatives required for curvature and energy calculations.
  • Optimization Framework: Provides tools to define variables, objectives, and constraints in an intuitive manner.
  • Solver Integration: Seamlessly integrates with IPOPT and other solvers for efficient numerical optimization.

Conclusion

This article presented a detailed mathematical model for optimizing the shape of a red blood cell using spherical harmonics parameterization under axial symmetry. By mapping each mathematical expression to corresponding code blocks, we provided a transparent and precise implementation.

The model minimizes the membrane's total energy while satisfying physiological constraints, resulting in an optimized biconcave shape consistent with actual RBCs. The approach demonstrates the power of combining mathematical modeling with computational tools like CasADi to explore and analyze complex biological systems.

Top comments (0)