/// <summary> /// Computes the energy balance for the given organelles in biome /// </summary> public static EnergyBalanceInfo ComputeEnergyBalance(IEnumerable <OrganelleTemplate> organelles, BiomeConditions biome, MembraneType membrane) { var organellesList = organelles.ToList(); var maximumMovementDirection = MicrobeInternalCalculations.MaximumSpeedDirection(organellesList); return(ComputeEnergyBalance(organellesList, biome, membrane, maximumMovementDirection)); }
/// <summary> /// Computes the energy balance for the given organelles in biome /// </summary> /// <param name="organelles">The organelles to compute the balance with</param> /// <param name="biome">The conditions the organelles are simulated in</param> /// <param name="membrane">The membrane type to adjust the energy balance with</param> /// <param name="onlyMovementInDirection"> /// Only movement organelles that can move in this (cell origin relative) direction are calculated. Other /// movement organelles are assumed to be inactive in the balance calculation. /// </param> public static EnergyBalanceInfo ComputeEnergyBalance(IEnumerable <OrganelleTemplate> organelles, BiomeConditions biome, MembraneType membrane, Vector3 onlyMovementInDirection) { var result = new EnergyBalanceInfo(); float processATPProduction = 0.0f; float processATPConsumption = 0.0f; float movementATPConsumption = 0.0f; int hexCount = 0; foreach (var organelle in organelles) { foreach (var process in organelle.Definition.RunnableProcesses) { var processData = CalculateProcessMaximumSpeed(process, biome); if (processData.WritableInputs.ContainsKey(ATP)) { var amount = processData.WritableInputs[ATP]; processATPConsumption += amount; result.AddConsumption(organelle.Definition.InternalName, amount); } if (processData.WritableOutputs.ContainsKey(ATP)) { var amount = processData.WritableOutputs[ATP]; processATPProduction += amount; result.AddProduction(organelle.Definition.InternalName, amount); } } // Take special cell components that take energy into account if (organelle.Definition.HasComponentFactory <MovementComponentFactory>()) { var amount = Constants.FLAGELLA_ENERGY_COST; var organelleDirection = MicrobeInternalCalculations.GetOrganelleDirection(organelle); if (organelleDirection.Dot(onlyMovementInDirection) > 0) { movementATPConsumption += amount; result.Flagella += amount; result.AddConsumption(organelle.Definition.InternalName, amount); } } // Store hex count hexCount += organelle.Definition.HexCount; } // Add movement consumption together result.BaseMovement = Constants.BASE_MOVEMENT_ATP_COST * hexCount; result.AddConsumption("baseMovement", result.BaseMovement); var totalMovementConsumption = movementATPConsumption + result.BaseMovement; // Add osmoregulation result.Osmoregulation = Constants.ATP_COST_FOR_OSMOREGULATION * hexCount * membrane.OsmoregulationFactor; result.AddConsumption("osmoregulation", result.Osmoregulation); // Compute totals result.TotalProduction = processATPProduction; result.TotalConsumptionStationary = processATPConsumption + result.Osmoregulation; result.TotalConsumption = result.TotalConsumptionStationary + totalMovementConsumption; result.FinalBalance = result.TotalProduction - result.TotalConsumption; result.FinalBalanceStationary = result.TotalProduction - result.TotalConsumptionStationary; return(result); }