Exemple #1
0
 public MembraneActionData(MembraneType oldMembrane, MembraneType newMembrane)
 {
     OldMembrane = oldMembrane;
     NewMembrane = newMembrane;
 }
Exemple #2
0
    /// <summary>
    ///   Computes the energy balance for the given organelles in biome
    /// </summary>
    public static EnergyBalanceInfo ComputeEnergyBalance(IEnumerable <OrganelleDefinition> organelles, Biome biome,
                                                         MembraneType membrane)
    {
        var result = new EnergyBalanceInfo();

        float processATPProduction   = 0.0f;
        float processATPConsumption  = 0.0f;
        float movementATPConsumption = 0.0f;

        int hexCount = 0;

        var atp = SimulationParameters.Instance.GetCompound("atp");

        var enumerated = organelles.ToList();

        // Compute all process efficiencies once
        var efficiencies = ComputeOrganelleProcessEfficiencies(enumerated, biome);

        foreach (var organelle in enumerated)
        {
            foreach (var efficiencyInfo in efficiencies)
            {
                foreach (var processData in efficiencyInfo.Value.Processes)
                {
                    // Find process inputs and outputs that use/produce ATP
                    // and that are performed by this organelle
                    // and add to totals
                    if (!organelle.Processes.ContainsKey(processData.Process.InternalName))
                    {
                        continue;
                    }

                    if (processData.OtherInputs.ContainsKey(atp.InternalName))
                    {
                        var amount = processData.OtherInputs[atp.InternalName].Amount;

                        processATPConsumption += amount;

                        result.AddConsumption(organelle.Name, amount);
                    }

                    if (processData.Outputs.ContainsKey(atp.InternalName))
                    {
                        var amount = processData.Outputs[atp.InternalName].Amount;

                        processATPProduction += amount;

                        result.AddProduction(organelle.Name, amount);
                    }
                }
            }

            // Take special cell components that take energy into account
            if (organelle.HasComponentFactory <MovementComponentFactory>())
            {
                var amount = Constants.FLAGELLA_ENERGY_COST;

                movementATPConsumption += amount;
                result.Flagella        += amount;

                result.AddConsumption(organelle.Name, amount);
            }

            // Store hex count
            hexCount += organelle.HexCount;
        }

        // Add movement consumption together
        result.BaseMovement = Constants.BASE_MOVEMENT_ATP_COST * hexCount;
        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);
    }
Exemple #3
0
    /// <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);
    }
Exemple #4
0
    public static float CalculateSpeed(IEnumerable <OrganelleTemplate> organelles, MembraneType membraneType,
                                       float membraneRigidity)
    {
        float microbeMass = Constants.MICROBE_BASE_MASS;

        float organelleMovementForce = 0;

        // For each direction we calculate the organelles contribution to the movement force
        float forwardsDirectionMovementForce  = 0;
        float backwardsDirectionMovementForce = 0;
        float leftwardDirectionMovementForce  = 0;
        float rightwardDirectionMovementForce = 0;

        // Force factor for each direction
        float forwardDirectionFactor;
        float backwardDirectionFactor;
        float rightDirectionFactor;
        float leftDirectionFactor;

        var organellesList = organelles.ToList();

        foreach (var organelle in organellesList)
        {
            microbeMass += organelle.Definition.Mass;

            if (organelle.Definition.HasComponentFactory <MovementComponentFactory>())
            {
                Vector3 organelleDirection = GetOrganelleDirection(organelle);

                // We decompose the vector of the organelle orientation in 2 vectors, forward and right
                // To get the backward and left is easy because they are the opposite of those former 2
                forwardDirectionFactor  = organelleDirection.Dot(Vector3.Forward);
                backwardDirectionFactor = -forwardDirectionFactor;
                rightDirectionFactor    = organelleDirection.Dot(Vector3.Right);
                leftDirectionFactor     = -rightDirectionFactor;

                float movementConstant = Constants.FLAGELLA_BASE_FORCE
                                         * organelle.Definition.Components.Movement !.Momentum / 100.0f;

                // We get the movement force for every direction as well
                forwardsDirectionMovementForce  += MovementForce(movementConstant, forwardDirectionFactor);
                backwardsDirectionMovementForce += MovementForce(movementConstant, backwardDirectionFactor);
                rightwardDirectionMovementForce += MovementForce(movementConstant, rightDirectionFactor);
                leftwardDirectionMovementForce  += MovementForce(movementConstant, leftDirectionFactor);
            }
        }

        var maximumMovementDirection = MaximumSpeedDirection(organellesList);

        // Maximum-force direction is not normalized so we need to normalize it here
        maximumMovementDirection = maximumMovementDirection.Normalized();

        // Calculate the maximum total force-factors in the maximum-force direction
        forwardDirectionFactor  = maximumMovementDirection.Dot(Vector3.Forward);
        backwardDirectionFactor = -forwardDirectionFactor;
        rightDirectionFactor    = maximumMovementDirection.Dot(Vector3.Right);
        leftDirectionFactor     = -rightDirectionFactor;

        // Add each movement force to the total movement force in the maximum-force direction.
        organelleMovementForce += MovementForce(forwardsDirectionMovementForce, forwardDirectionFactor);
        organelleMovementForce += MovementForce(backwardsDirectionMovementForce, backwardDirectionFactor);
        organelleMovementForce += MovementForce(rightwardDirectionMovementForce, rightDirectionFactor);
        organelleMovementForce += MovementForce(leftwardDirectionMovementForce, leftDirectionFactor);

        float baseMovementForce = Constants.CELL_BASE_THRUST *
                                  (membraneType.MovementFactor - membraneRigidity * Constants.MEMBRANE_RIGIDITY_MOBILITY_MODIFIER);

        float finalSpeed = (baseMovementForce + organelleMovementForce) / microbeMass;

        return(finalSpeed);
    }