Molecular Layer - Fundamental Membrane Biophysics

Core Philosophy

“Every membrane property emerges from molecular interactions - and every molecular interaction can be expressed as circuit parameters”

The Molecular Layer implements the fundamental biophysical processes that determine membrane electrical properties. This layer translates lipid bilayer physics, protein-membrane interactions, membrane curvature dynamics, and electrochemical gradients into the circuit parameters that Nebuchadnezzar requires for ATP-based differential equations.

Lipid Bilayer Physics

Membrane Capacitance Calculation

The bilayer capacitance is the most fundamental electrical property of membranes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
pub struct LipidBilayerCapacitance {
    // Physical constants
    vacuum_permittivity: f64,       // ε₀ = 8.854 × 10⁻¹² F/m
    
    // Composition-dependent properties
    lipid_composition: LipidComposition,
    cholesterol_fraction: f64,      // 0.0 - 1.0
    temperature: f64,               // Kelvin
    
    // Dynamic properties
    membrane_thickness: f64,        // nm - varies with composition
    dielectric_profile: DielectricProfile,
    
    // ATP-dependent modifications
    atp_dependent_lipid_synthesis: AtpLipidSynthesis,
    membrane_asymmetry: MembraneAsymmetry,
}

impl LipidBilayerCapacitance {
    pub fn calculate_specific_capacitance(&self) -> f64 {
        // Multi-layer dielectric model for biological membranes
        let effective_permittivity = self.calculate_effective_permittivity();
        let effective_thickness = self.calculate_effective_thickness();
        
        self.vacuum_permittivity * effective_permittivity / (effective_thickness * 1e-9)
    }
    
    fn calculate_effective_permittivity(&self) -> f64 {
        // Weighted average based on lipid composition
        let mut effective_permittivity = 0.0;
        
        for (lipid_type, fraction) in &self.lipid_composition.lipid_fractions {
            let lipid_permittivity = match lipid_type {
                LipidType::PhosphatidylCholine => 2.3,  // PC headgroup
                LipidType::PhosphatidylSerine => 3.1,   // PS headgroup (charged)
                LipidType::Cholesterol => 2.1,          // Cholesterol
                LipidType::Sphingomyelin => 2.5,        // SM headgroup
                _ => 2.2, // Default value
            };
            effective_permittivity += lipid_permittivity * fraction;
        }
        
        // Temperature correction
        let temperature_factor = 1.0 + 0.002 * (self.temperature - 298.0); // ~0.2% per K
        effective_permittivity * temperature_factor
    }
    
    fn calculate_effective_thickness(&self) -> f64 {
        // Bilayer thickness depends on acyl chain length and saturation
        let base_thickness = self.calculate_base_thickness();
        let cholesterol_correction = 1.0 + 0.15 * self.cholesterol_fraction; // Cholesterol increases thickness
        let temperature_correction = 1.0 - 0.001 * (self.temperature - 298.0); // Higher T decreases thickness
        
        base_thickness * cholesterol_correction * temperature_correction
    }
    
    pub fn update_for_atp_consumption(&mut self, atp_consumed: f64, dt: f64) {
        // ATP consumption affects membrane through lipid synthesis
        let lipid_synthesis_rate = self.atp_dependent_lipid_synthesis.calculate_synthesis_rate(atp_consumed);
        
        // Update membrane composition
        self.lipid_composition.update_from_synthesis(lipid_synthesis_rate, dt);
        
        // Recalculate thickness and permittivity
        self.membrane_thickness = self.calculate_effective_thickness();
    }
}

Membrane Resistance and Permeability

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
pub struct MembranePermeability {
    // Ion-specific permeabilities (m/s)
    sodium_permeability: f64,
    potassium_permeability: f64,
    chloride_permeability: f64,
    calcium_permeability: f64,
    
    // Composition dependencies
    lipid_composition: LipidComposition,
    cholesterol_effect: CholesterolEffect,
    temperature: f64,
    
    // ATP-dependent modifications
    atp_dependent_flippases: Vec<AtpFlippase>,
    asymmetric_composition: AsymmetricComposition,
}

impl MembranePermeability {
    pub fn calculate_ion_resistance(&self, ion_type: IonType, membrane_area: f64) -> f64 {
        let permeability = match ion_type {
            IonType::Sodium => self.sodium_permeability,
            IonType::Potassium => self.potassium_permeability,
            IonType::Chloride => self.chloride_permeability,
            IonType::Calcium => self.calcium_permeability,
        };
        
        // Apply composition corrections
        let composition_factor = self.calculate_composition_factor(ion_type);
        let temperature_factor = self.calculate_temperature_factor();
        
        let effective_permeability = permeability * composition_factor * temperature_factor;
        
        // Convert permeability to resistance: R = 1/(P × A × F²/RT × z²)
        let faraday_constant = 96485.0; // C/mol
        let gas_constant = 8.314; // J/(mol⋅K)
        let ion_charge = ion_type.charge();
        
        1.0 / (effective_permeability * membrane_area * 
               faraday_constant.powi(2) / (gas_constant * self.temperature) * 
               ion_charge.powi(2))
    }
    
    fn calculate_composition_factor(&self, ion_type: IonType) -> f64 {
        // Different lipids have different effects on ion permeability
        let mut factor = 1.0;
        
        // Cholesterol generally decreases permeability
        factor *= 1.0 - 0.5 * self.cholesterol_effect.permeability_reduction * 
                  self.lipid_composition.cholesterol_fraction();
        
        // Charged lipids affect charged ion permeability
        if ion_type.is_cation() {
            let negative_lipid_fraction = self.lipid_composition.get_fraction(LipidType::PhosphatidylSerine);
            factor *= 1.0 + 0.3 * negative_lipid_fraction; // PS increases cation permeability
        }
        
        factor
    }
    
    pub fn update_for_atp_flippase_activity(&mut self, atp_consumed: f64) {
        // ATP-dependent flippases change membrane asymmetry
        for flippase in &mut self.atp_dependent_flippases {
            let flippase_activity = flippase.calculate_activity(atp_consumed);
            self.asymmetric_composition.update_from_flippase_activity(flippase_activity);
        }
        
        // Asymmetry affects permeability
        self.update_permeabilities_from_asymmetry();
    }
}

Protein-Membrane Interactions

Transmembrane Protein Electrical Models

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
pub struct TransmembraneProteinElectrics {
    protein_id: String,
    protein_type: ProteinType,
    
    // Structural properties
    transmembrane_domains: u8,
    hydrophobic_mismatch: f64,    // nm - difference between protein and membrane thickness
    protein_radius: f64,          // nm - effective radius
    
    // Electrical properties
    intrinsic_conductance: f64,   // S - protein conductance
    voltage_dependence: VoltageGating,
    ion_selectivity: IonSelectivity,
    
    // ATP-dependent properties
    atp_binding_sites: Vec<AtpBindingSite>,
    conformational_states: HashMap<AtpConcentration, ProteinConformation>,
    
    // Membrane perturbation
    lipid_annulus: LipidAnnulus,  // Perturbed lipids around protein
    membrane_curvature_induction: f64,
}

impl TransmembraneProteinElectrics {
    pub fn calculate_equivalent_circuit(&self, membrane_voltage: f64, atp_concentration: f64) -> ProteinEquivalentCircuit {
        match &self.protein_type {
            ProteinType::IonChannel { gating_mechanism, .. } => {
                self.calculate_ion_channel_circuit(membrane_voltage, atp_concentration)
            }
            ProteinType::AtpPump { .. } => {
                self.calculate_atp_pump_circuit(membrane_voltage, atp_concentration)
            }
            ProteinType::AtpSynthase { .. } => {
                self.calculate_atp_synthase_circuit(membrane_voltage, atp_concentration)
            }
            _ => ProteinEquivalentCircuit::default(),
        }
    }
    
    fn calculate_ion_channel_circuit(&self, voltage: f64, atp_conc: f64) -> ProteinEquivalentCircuit {
        // Calculate open probability from voltage and ATP dependence
        let open_probability = self.calculate_open_probability(voltage, atp_conc);
        
        // Effective conductance
        let effective_conductance = self.intrinsic_conductance * open_probability;
        
        // Channel as voltage-dependent resistor
        ProteinEquivalentCircuit::VoltageGatedResistor {
            max_conductance: self.intrinsic_conductance,
            current_conductance: effective_conductance,
            reversal_potential: self.calculate_reversal_potential(),
            gating_dynamics: self.calculate_gating_dynamics(voltage, atp_conc),
        }
    }
    
    fn calculate_atp_pump_circuit(&self, voltage: f64, atp_conc: f64) -> ProteinEquivalentCircuit {
        // ATP pump as current source with internal resistance
        let pump_current = self.calculate_pump_current(voltage, atp_conc);
        let internal_resistance = self.calculate_pump_resistance(atp_conc);
        let atp_consumption_rate = self.calculate_atp_consumption_rate(pump_current);
        
        ProteinEquivalentCircuit::CurrentSource {
            current: pump_current,
            internal_resistance,
            voltage_dependence: self.calculate_pump_voltage_dependence(),
            atp_consumption_rate,
            power_consumption: pump_current * voltage,
        }
    }
    
    fn calculate_atp_synthase_circuit(&self, voltage: f64, atp_conc: f64) -> ProteinEquivalentCircuit {
        // ATP synthase as reversible current source/sink
        let synthase_current = self.calculate_synthase_current(voltage, atp_conc);
        let internal_resistance = self.calculate_synthase_resistance(atp_conc);
        let atp_production_rate = self.calculate_atp_production_rate(synthase_current);
        
        ProteinEquivalentCircuit::ReversibleCurrentSource {
            current: synthase_current,
            internal_resistance,
            forward_bias_voltage: self.calculate_forward_bias_voltage(atp_conc),
            reverse_bias_voltage: self.calculate_reverse_bias_voltage(atp_conc),
            atp_production_rate,
            power_generation: -synthase_current * voltage, // Negative for power generation
        }
    }
    
    pub fn calculate_membrane_perturbation(&self) -> MembranePertu rbation {
        // How protein affects surrounding membrane
        let thickness_perturbation = self.calculate_thickness_perturbation();
        let curvature_induction = self.calculate_curvature_induction();
        let lipid_ordering = self.calculate_lipid_ordering_effect();
        
        MembraneP erturbation {
            affected_radius: self.protein_radius + 2.0, // ~2 nm perturbation radius
            thickness_change: thickness_perturbation,
            curvature_change: curvature_induction,
            lipid_ordering_change: lipid_ordering,
            capacitance_change: self.calculate_capacitance_perturbation(),
            resistance_change: self.calculate_resistance_perturbation(),
        }
    }
}

ATP-Dependent Protein Conformational Changes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
pub struct AtpDependentConformations {
    protein_id: String,
    
    // ATP binding sites and their effects
    atp_binding_sites: Vec<AtpBindingSite>,
    cooperative_binding: CooperativeBinding,
    
    // Conformational states
    conformational_states: HashMap<ConformationId, ProteinConformation>,
    transition_rates: HashMap<(ConformationId, ConformationId), f64>,
    
    // Electrical consequences
    conformation_conductances: HashMap<ConformationId, f64>,
    conformation_capacitances: HashMap<ConformationId, f64>,
}

#[derive(Debug, Clone)]
pub struct AtpBindingSite {
    site_id: String,
    binding_affinity: f64,        // M⁻¹ - association constant
    cooperativity_factor: f64,    // Hill coefficient
    conformational_effect: ConformationalEffect,
}

#[derive(Debug, Clone)]
pub enum ConformationalEffect {
    ConductanceChange(f64),       // Factor by which conductance changes
    GatingEffect(GatingEffect),   // Changes in voltage/time dependence
    SelectivityChange(SelectivityChange), // Changes in ion selectivity
    ATPConsumptionChange(f64),    // Changes in ATP consumption rate
}

impl AtpDependentConformations {
    pub fn calculate_current_conformation(&self, atp_concentration: f64) -> ProteinConformation {
        // Calculate occupancy of each ATP binding site
        let site_occupancies = self.calculate_site_occupancies(atp_concentration);
        
        // Determine most probable conformation
        let conformation_probabilities = self.calculate_conformation_probabilities(&site_occupancies);
        
        // Weighted average of conformational properties
        self.average_conformational_properties(&conformation_probabilities)
    }
    
    fn calculate_site_occupancies(&self, atp_conc: f64) -> Vec<f64> {
        let mut occupancies = Vec::new();
        
        for site in &self.atp_binding_sites {
            // Hill equation for cooperative binding
            let occupancy = (site.binding_affinity * atp_conc).powf(site.cooperativity_factor) /
                          (1.0 + (site.binding_affinity * atp_conc).powf(site.cooperativity_factor));
            occupancies.push(occupancy);
        }
        
        occupancies
    }
    
    fn calculate_conformation_probabilities(&self, site_occupancies: &[f64]) -> HashMap<ConformationId, f64> {
        let mut probabilities = HashMap::new();
        
        // Each combination of site occupancies corresponds to a conformation
        for (conformation_id, conformation) in &self.conformational_states {
            let mut probability = 1.0;
            
            for (site_idx, required_occupancy) in conformation.required_site_states.iter().enumerate() {
                if *required_occupancy {
                    probability *= site_occupancies[site_idx];
                } else {
                    probability *= 1.0 - site_occupancies[site_idx];
                }
            }
            
            probabilities.insert(*conformation_id, probability);
        }
        
        // Normalize probabilities
        let total_probability: f64 = probabilities.values().sum();
        for probability in probabilities.values_mut() {
            *probability /= total_probability;
        }
        
        probabilities
    }
    
    pub fn calculate_atp_dependent_conductance(&self, atp_concentration: f64) -> f64 {
        let conformation_probabilities = self.calculate_conformation_probabilities(
            &self.calculate_site_occupancies(atp_concentration)
        );
        
        let mut weighted_conductance = 0.0;
        for (conformation_id, probability) in conformation_probabilities {
            let conductance = self.conformation_conductances[&conformation_id];
            weighted_conductance += conductance * probability;
        }
        
        weighted_conductance
    }
}

Membrane Curvature Dynamics

Curvature-Electrical Property Coupling

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
pub struct MembraneCurvatureDynamics {
    // Curvature properties
    spontaneous_curvature: f64,   // m⁻¹ - intrinsic curvature preference
    bending_modulus: f64,         // J - resistance to bending
    gaussian_modulus: f64,        // J - resistance to topology changes
    
    // Current membrane shape
    mean_curvature: f64,          // m⁻¹ - average curvature
    gaussian_curvature: f64,      // m⁻² - topology measure
    
    // Protein-curvature coupling
    curvature_sensing_proteins: Vec<CurvatureSensingProtein>,
    curvature_inducing_proteins: Vec<CurvatureInducingProtein>,
    
    // ATP-dependent curvature generation
    atp_dependent_curvature_generators: Vec<AtpCurvatureGenerator>,
}

impl MembraneCurvatureDynamics {
    pub fn calculate_curvature_electrical_effects(&self) -> CurvatureElectricalEffects {
        // Curvature affects membrane electrical properties
        let capacitance_effect = self.calculate_curvature_capacitance_effect();
        let resistance_effect = self.calculate_curvature_resistance_effect();
        let protein_activity_effect = self.calculate_curvature_protein_effects();
        
        CurvatureElectricalEffects {
            capacitance_modification: capacitance_effect,
            resistance_modification: resistance_effect,
            protein_activity_modifications: protein_activity_effect,
        }
    }
    
    fn calculate_curvature_capacitance_effect(&self) -> f64 {
        // Curvature changes effective membrane area and thickness
        let area_factor = 1.0 + self.mean_curvature.abs() * 0.1; // Curved membranes have larger effective area
        let thickness_factor = 1.0 - self.mean_curvature.abs() * 0.05; // Curvature slightly reduces effective thickness
        
        area_factor / thickness_factor
    }
    
    fn calculate_curvature_resistance_effect(&self) -> f64 {
        // Curvature affects lipid packing and permeability
        let packing_factor = 1.0 + self.mean_curvature.abs() * 0.2; // Curvature loosens packing
        let permeability_factor = 1.0 + packing_factor * 0.3; // Looser packing increases permeability
        
        1.0 / permeability_factor // Resistance is inverse of permeability
    }
    
    fn calculate_curvature_protein_effects(&self) -> HashMap<String, f64> {
        let mut effects = HashMap::new();
        
        // Curvature-sensing proteins change activity with curvature
        for protein in &self.curvature_sensing_proteins {
            let activity_change = protein.calculate_curvature_response(self.mean_curvature);
            effects.insert(protein.protein_id.clone(), activity_change);
        }
        
        effects
    }
    
    pub fn update_curvature_for_atp_consumption(&mut self, atp_consumed: f64, dt: f64) {
        // ATP-dependent processes can generate membrane curvature
        for generator in &mut self.atp_dependent_curvature_generators {
            let curvature_change = generator.calculate_curvature_generation(atp_consumed, dt);
            self.apply_curvature_change(curvature_change);
        }
        
        // Update protein activities based on new curvature
        self.update_protein_curvature_responses();
    }
    
    pub fn calculate_curvature_energy(&self) -> f64 {
        // Helfrich bending energy
        let bending_energy = 0.5 * self.bending_modulus * 
                           (self.mean_curvature - self.spontaneous_curvature).powi(2);
        let gaussian_energy = self.gaussian_modulus * self.gaussian_curvature;
        
        bending_energy + gaussian_energy
    }
}

#[derive(Debug, Clone)]
pub struct CurvatureSensingProtein {
    protein_id: String,
    curvature_sensitivity: f64,   // Response magnitude per unit curvature
    optimal_curvature: f64,       // m⁻¹ - preferred curvature
    activity_modulation: ActivityModulation,
}

impl CurvatureSensingProtein {
    pub fn calculate_curvature_response(&self, membrane_curvature: f64) -> f64 {
        // Activity changes based on deviation from optimal curvature
        let curvature_deviation = (membrane_curvature - self.optimal_curvature).abs();
        let activity_factor = 1.0 + self.curvature_sensitivity * curvature_deviation;
        
        match self.activity_modulation {
            ActivityModulation::Increase => activity_factor,
            ActivityModulation::Decrease => 1.0 / activity_factor,
            ActivityModulation::Optimal => {
                // Bell-shaped response - maximum activity at optimal curvature
                (-0.5 * curvature_deviation.powi(2)).exp()
            }
        }
    }
}

Electrochemical Gradients

Ion Distribution and Membrane Potential

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
pub struct ElectrochemicalGradients {
    // Ion concentrations (mM)
    intracellular_concentrations: HashMap<IonType, f64>,
    extracellular_concentrations: HashMap<IonType, f64>,
    
    // Membrane properties
    membrane_potential: f64,      // mV
    temperature: f64,             // K
    
    // ATP-dependent ion pumps
    atp_pumps: Vec<AtpIonPump>,
    
    // Passive leak channels
    leak_channels: HashMap<IonType, f64>, // Permeabilities in m/s
}

impl ElectrochemicalGradients {
    pub fn calculate_nernst_potential(&self, ion_type: IonType) -> f64 {
        // Nernst equation: E = (RT/zF) * ln([ion]_out / [ion]_in)
        let gas_constant = 8.314; // J/(mol⋅K)
        let faraday_constant = 96485.0; // C/mol
        let ion_charge = ion_type.charge();
        
        let conc_out = self.extracellular_concentrations[&ion_type];
        let conc_in = self.intracellular_concentrations[&ion_type];
        
        (gas_constant * self.temperature) / (ion_charge as f64 * faraday_constant) * 
        (conc_out / conc_in).ln() * 1000.0 // Convert to mV
    }
    
    pub fn calculate_goldman_potential(&self) -> f64 {
        // Goldman-Hodgkin-Katz equation for membrane potential
        let pk = self.leak_channels[&IonType::Potassium];
        let pna = self.leak_channels[&IonType::Sodium];
        let pcl = self.leak_channels[&IonType::Chloride];
        
        let k_out = self.extracellular_concentrations[&IonType::Potassium];
        let k_in = self.intracellular_concentrations[&IonType::Potassium];
        let na_out = self.extracellular_concentrations[&IonType::Sodium];
        let na_in = self.intracellular_concentrations[&IonType::Sodium];
        let cl_out = self.extracellular_concentrations[&IonType::Chloride];
        let cl_in = self.intracellular_concentrations[&IonType::Chloride];
        
        let numerator = pk * k_out + pna * na_out + pcl * cl_in; // Note: Cl inside for anions
        let denominator = pk * k_in + pna * na_in + pcl * cl_out;
        
        let rt_f = 8.314 * self.temperature / 96485.0;
        rt_f * (numerator / denominator).ln() * 1000.0 // Convert to mV
    }
    
    pub fn update_for_atp_pump_activity(&mut self, atp_consumed: f64, dt: f64) {
        // Update ion concentrations based on ATP pump activity
        for pump in &mut self.atp_pumps {
            let pump_activity = pump.calculate_activity(atp_consumed, self.membrane_potential);
            let ion_flux = pump.calculate_ion_flux(pump_activity, dt);
            
            // Update concentrations
            for (ion_type, flux) in ion_flux {
                self.intracellular_concentrations.entry(ion_type)
                    .and_modify(|conc| *conc += flux.intracellular_change);
                self.extracellular_concentrations.entry(ion_type)
                    .and_modify(|conc| *conc += flux.extracellular_change);
            }
        }
        
        // Recalculate membrane potential
        self.membrane_potential = self.calculate_goldman_potential();
    }
    
    pub fn calculate_driving_force(&self, ion_type: IonType) -> f64 {
        // Electrochemical driving force: V_m - E_ion
        let nernst_potential = self.calculate_nernst_potential(ion_type);
        self.membrane_potential - nernst_potential
    }
    
    pub fn calculate_ion_current(&self, ion_type: IonType, conductance: f64) -> f64 {
        // Ohmic current: I = g * (V_m - E_ion)
        let driving_force = self.calculate_driving_force(ion_type);
        conductance * driving_force / 1000.0 // Convert mV to V
    }
}

#[derive(Debug, Clone)]
pub struct AtpIonPump {
    pump_type: PumpType,
    max_turnover_rate: f64,       // s⁻¹
    atp_stoichiometry: f64,       // ATP consumed per cycle
    ion_stoichiometry: HashMap<IonType, i8>, // Ions moved per cycle (+ out, - in)
    voltage_dependence: f64,      // Voltage dependence factor
    atp_km: f64,                  // mM - Michaelis constant for ATP
}

impl AtpIonPump {
    pub fn calculate_activity(&self, atp_concentration: f64, membrane_voltage: f64) -> f64 {
        // Michaelis-Menten kinetics for ATP dependence
        let atp_factor = atp_concentration / (self.atp_km + atp_concentration);
        
        // Voltage dependence (some pumps are electrogenic)
        let voltage_factor = if self.voltage_dependence != 0.0 {
            (-self.voltage_dependence * membrane_voltage / 1000.0).exp() // Convert mV to V
        } else {
            1.0
        };
        
        self.max_turnover_rate * atp_factor * voltage_factor
    }
    
    pub fn calculate_atp_consumption_rate(&self, activity: f64) -> f64 {
        activity * self.atp_stoichiometry
    }
}

Circuit Parameter Integration

Dynamic Circuit Parameter Calculation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
pub struct MolecularToCircuitMapper {
    // Layer components
    bilayer_physics: LipidBilayerCapacitance,
    protein_electrics: HashMap<String, TransmembraneProteinElectrics>,
    curvature_dynamics: MembraneCurvatureDynamics,
    gradients: ElectrochemicalGradients,
    
    // Mapping parameters
    membrane_area: f64,           // m² - total membrane area
    temperature: f64,             // K
    
    // ATP coupling
    current_atp_concentration: f64, // mM
}

impl MolecularToCircuitMapper {
    pub fn calculate_circuit_parameters(&self) -> CircuitParameters {
        // Membrane capacitance
        let specific_capacitance = self.bilayer_physics.calculate_specific_capacitance();
        let curvature_effects = self.curvature_dynamics.calculate_curvature_electrical_effects();
        let total_capacitance = specific_capacitance * self.membrane_area * 
                               curvature_effects.capacitance_modification;
        
        // Membrane resistance (parallel combination of all ion pathways)
        let total_conductance = self.calculate_total_membrane_conductance();
        let total_resistance = 1.0 / total_conductance;
        
        // Protein circuit elements
        let protein_circuits = self.calculate_protein_circuit_elements();
        
        // Electrochemical potentials
        let equilibrium_potentials = self.calculate_equilibrium_potentials();
        
        CircuitParameters {
            membrane_capacitance: total_capacitance,
            membrane_resistance: total_resistance,
            protein_elements: protein_circuits,
            equilibrium_potentials,
            membrane_potential: self.gradients.membrane_potential,
            atp_dependencies: self.calculate_atp_dependencies(),
        }
    }
    
    fn calculate_total_membrane_conductance(&self) -> f64 {
        let mut total_conductance = 0.0;
        
        // Passive leak conductances
        for (ion_type, permeability) in &self.gradients.leak_channels {
            let ion_conductance = self.permeability_to_conductance(*permeability, *ion_type);
            total_conductance += ion_conductance;
        }
        
        // Protein conductances
        for (protein_id, protein) in &self.protein_electrics {
            let protein_conductance = protein.calculate_atp_dependent_conductance(
                self.current_atp_concentration
            );
            total_conductance += protein_conductance;
        }
        
        // Curvature effects
        let curvature_effects = self.curvature_dynamics.calculate_curvature_electrical_effects();
        total_conductance *= curvature_effects.resistance_modification;
        
        total_conductance
    }
    
    fn permeability_to_conductance(&self, permeability: f64, ion_type: IonType) -> f64 {
        // Convert permeability (m/s) to conductance (S)
        let faraday_constant = 96485.0; // C/mol
        let gas_constant = 8.314; // J/(mol⋅K)
        let ion_charge = ion_type.charge();
        
        let ion_concentration = (self.gradients.intracellular_concentrations[&ion_type] + 
                               self.gradients.extracellular_concentrations[&ion_type]) / 2.0; // Average
        
        permeability * self.membrane_area * ion_concentration * 
        faraday_constant.powi(2) / (gas_constant * self.temperature) * 
        ion_charge.powi(2)
    }
    
    pub fn update_for_atp_changes(&mut self, atp_consumption: f64, new_atp_concentration: f64, dt: f64) {
        // Update all molecular components for ATP changes
        self.bilayer_physics.update_for_atp_consumption(atp_consumption, dt);
        
        for protein in self.protein_electrics.values_mut() {
            protein.update_for_atp_changes(atp_consumption, new_atp_concentration);
        }
        
        self.curvature_dynamics.update_curvature_for_atp_consumption(atp_consumption, dt);
        self.gradients.update_for_atp_pump_activity(atp_consumption, dt);
        
        self.current_atp_concentration = new_atp_concentration;
    }
}

Example: ATP Synthase Circuit Modeling

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// Example: Detailed ATP synthase circuit model
pub fn create_atp_synthase_circuit() -> TransmembraneProteinElectrics {
    let mut atp_synthase = TransmembraneProteinElectrics::new("atp_synthase_f0f1");
    
    // F0 motor properties
    atp_synthase.set_f0_properties(F0Properties {
        c_ring_stoichiometry: 8,        // 8 c-subunits
        proton_binding_sites: 8,        // One per c-subunit
        rotational_resistance: 1e-21,   // Nm⋅s - rotational friction
        torque_per_proton: 40e-21,      // Nm - torque generated per proton
    });
    
    // F1 motor properties  
    atp_synthase.set_f1_properties(F1Properties {
        catalytic_sites: 3,             // 3 β subunits
        atp_binding_cooperativity: 2.0, // Hill coefficient
        atp_synthesis_rate: 100.0,      // s⁻¹ maximum rate
        atp_km: 0.5,                    // mM
    });
    
    // Coupling between F0 and F1
    atp_synthase.set_coupling(F0F1Coupling {
        gear_ratio: 8.0 / 3.0,          // 8 protons per 3 ATP
        coupling_efficiency: 0.95,       // 95% mechanical coupling
        slip_rate: 0.01,                // 1% slip under load
    });
    
    atp_synthase
}

// Circuit parameter calculation for ATP synthase
impl TransmembraneProteinElectrics {
    pub fn calculate_atp_synthase_circuit(&self, proton_gradient: f64, atp_concentration: f64) -> ProteinEquivalentCircuit {
        let f0_properties = self.f0_properties.as_ref().unwrap();
        let f1_properties = self.f1_properties.as_ref().unwrap();
        let coupling = self.coupling.as_ref().unwrap();
        
        // Calculate driving torque from proton gradient
        let proton_chemical_potential = 2.3 * 8.314 * 310.0 * proton_gradient.log10(); // J/mol
        let driving_torque = f0_properties.torque_per_proton * f0_properties.proton_binding_sites;
        
        // Calculate load torque from ATP synthesis
        let atp_load = f1_properties.calculate_atp_synthesis_load(atp_concentration);
        
        // Net torque and rotation rate
        let net_torque = driving_torque - atp_load / coupling.gear_ratio;
        let rotation_rate = net_torque / f0_properties.rotational_resistance;
        
        // ATP synthesis rate
        let atp_synthesis_rate = rotation_rate * coupling.coupling_efficiency / coupling.gear_ratio;
        
        // Equivalent circuit
        ProteinEquivalentCircuit::AtpSynthase {
            proton_current: rotation_rate * f0_properties.c_ring_stoichiometry,
            atp_production_rate: atp_synthesis_rate,
            internal_resistance: self.calculate_synthase_internal_resistance(),
            torque_constant: driving_torque / proton_gradient,
            back_emf: atp_load,
        }
    }
}

The Molecular Layer provides the fundamental biophysical foundation for all membrane electrical properties, translating lipid-protein interactions, membrane curvature, and electrochemical gradients into the circuit parameters that enable Nebuchadnezzar’s ATP-based differential equation modeling of biological systems.