Пример #1
0
        /// <summary>
        /// This method creates the input to be used in finite element analysis.
        /// </summary>
        /// <param name="request"></param>
        /// <returns>A new instance of class <see cref="FiniteElementMethodInput"/>.</returns>
        public override async Task <FiniteElementMethodInput> CreateInput(TRequest request)
        {
            uint degreesOfFreedom = await this.CalculateDegreesOfFreedom(request.NumberOfElements).ConfigureAwait(false);

            TBeam beam = await this.BuildBeam(request, degreesOfFreedom);

            (bool[] boundaryConditions, uint numberOfTrueBoundaryConditions) = await this._mainMatrix.CalculateBoundaryConditions(beam, degreesOfFreedom).ConfigureAwait(false);

            double[,] mass = await this._mainMatrix.CalculateMass(beam, degreesOfFreedom).ConfigureAwait(false);

            double[,] stiffness = await this._mainMatrix.CalculateStiffness(beam, degreesOfFreedom).ConfigureAwait(false);

            double[,] damping = await this._mainMatrix.CalculateDamping(mass, stiffness).ConfigureAwait(false);

            double[] forces = await this._mainMatrix.CalculateForce(beam).ConfigureAwait(false);

            FiniteElementMethodInput input = await base.CreateInput(request).ConfigureAwait(false);

            input.NumericalMethod = (NumericalMethod)Enum.Parse(typeof(NumericalMethod), request.NumericalMethod, ignoreCase: true);
            input.Mass            = await mass.ApplyBoundaryConditionsAsync(boundaryConditions, numberOfTrueBoundaryConditions).ConfigureAwait(false);

            input.Stiffness = await stiffness.ApplyBoundaryConditionsAsync(boundaryConditions, numberOfTrueBoundaryConditions).ConfigureAwait(false);

            input.Damping = await damping.ApplyBoundaryConditionsAsync(boundaryConditions, numberOfTrueBoundaryConditions).ConfigureAwait(false);

            input.OriginalForce = await forces.ApplyBoundaryConditionsAsync(boundaryConditions, numberOfTrueBoundaryConditions).ConfigureAwait(false);

            input.NumberOfTrueBoundaryConditions = numberOfTrueBoundaryConditions;

            return(input);
        }
Пример #2
0
        /// <summary>
        /// Calculates and write in a file the results for two degrees of freedom analysis.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="time"></param>
        /// <param name="previousResult"></param>
        /// <returns></returns>
        public virtual async Task <double[]> CalculateTwoDegreesOfFreedomResult(TwoDegreesOfFreedomInput input, double time, double[] previousResult)
        {
            FiniteElementMethodInput finiteElementMethodInput = await this._mappingResolver.BuildFiniteElementMethodInput(input).ConfigureAwait(false);

            FiniteElementResult previousFiniteElementResult = await this._mappingResolver.BuildFiniteElementResult(previousResult, input.Force).ConfigureAwait(false);

            FiniteElementResult finiteElementResult = await this.CalculateFiniteElementResult(finiteElementMethodInput, previousFiniteElementResult, time).ConfigureAwait(false);

            double[] result = await this._mappingResolver.BuildVariableVector(finiteElementResult).ConfigureAwait(false);

            return(result);
        }
Пример #3
0
        /// <summary>
        /// Calculates the equivalent stiffness to calculate the displacement in Newmark-Beta method.
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public Task <double[, ]> CalculateEquivalentStiffness(FiniteElementMethodInput input)
        {
            double[,] equivalentStiffness = new double[input.NumberOfTrueBoundaryConditions, input.NumberOfTrueBoundaryConditions];

            double const1 = 1 / (input.Beta * Math.Pow(input.TimeStep, 2));
            double const2 = input.Gama / (input.Beta * input.TimeStep);

            for (int i = 0; i < input.NumberOfTrueBoundaryConditions; i++)
            {
                for (int j = 0; j < input.NumberOfTrueBoundaryConditions; j++)
                {
                    equivalentStiffness[i, j] = const1 * input.Mass[i, j] + const2 * input.Damping[i, j] + input.Stiffness[i, j];
                }
            }

            return(Task.FromResult(equivalentStiffness));
        }
Пример #4
0
        /// <summary>
        /// Calculates the equivalent force to calculate the displacement to Newmark method.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="previousDisplacement"></param>
        /// <param name="previousVelocity"></param>
        /// <param name="previousAcceleration"></param>
        /// <returns></returns>
        public async Task <double[]> CalculateEquivalentForce(FiniteElementMethodInput input, double[] previousDisplacement, double[] previousVelocity, double[] previousAcceleration, double time)
        {
            double[] equivalentVelocity = await this.CalculateEquivalentVelocity(previousDisplacement, previousVelocity, previousAcceleration, input.NumberOfTrueBoundaryConditions).ConfigureAwait(false);

            double[] equivalentAcceleration = await this.CalculateEquivalentAcceleration(previousDisplacement, previousVelocity, previousAcceleration, input.NumberOfTrueBoundaryConditions).ConfigureAwait(false);

            double[] mass_accel = await input.Mass.MultiplyAsync(equivalentAcceleration).ConfigureAwait(false);

            double[] damping_vel = await input.Damping.MultiplyAsync(equivalentVelocity).ConfigureAwait(false);

            double[] equivalentForce = new double[input.NumberOfTrueBoundaryConditions];

            for (int i = 0; i < input.NumberOfTrueBoundaryConditions; i++)
            {
                equivalentForce[i] = input.OriginalForce[i] * Math.Sin(input.AngularFrequency * time) + mass_accel[i] + damping_vel[i];
            }

            return(equivalentForce);
        }
Пример #5
0
        /// <summary>
        /// Calculates the equivalent force to calculate the displacement in Newmark-Beta method.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="previousResult"></param>
        /// <param name="time"></param>
        /// <returns></returns>
        public async Task <double[]> CalculateEquivalentForce(FiniteElementMethodInput input, FiniteElementResult previousResult, double time)
        {
            double[,] equivalentDamping = await this.CalculateEquivalentDamping(input).ConfigureAwait(false);

            double[,] equivalentMass = await this.CalculateEquivalentMass(input).ConfigureAwait(false);

            double[] damping_vel = await equivalentDamping.MultiplyAsync(previousResult.Velocity).ConfigureAwait(false);

            double[] mass_accel = await equivalentMass.MultiplyAsync(previousResult.Acceleration).ConfigureAwait(false);

            double[] previousForce = await this._force.CalculateForceByType(input.OriginalForce, input.AngularFrequency, time, input.ForceType).ConfigureAwait(false);

            double[] force = await this._force.CalculateForceByType(input.OriginalForce, input.AngularFrequency, time + input.TimeStep, input.ForceType).ConfigureAwait(false);

            double[] deltaForce = await force.SubtractAsync(previousForce).ConfigureAwait(false);

            double[] equivalentForce = await deltaForce.SumAsync(damping_vel, mass_accel).ConfigureAwait(false);

            return(equivalentForce);
        }
Пример #6
0
        /// <summary>
        /// This method creates the path to save the solution files.
        /// </summary>
        /// <param name="request"></param>
        /// <param name="input"></param>
        /// <returns>The path to save the solution files.</returns>
        public override Task <string> CreateSolutionPath(BeamRequest <TProfile> request, FiniteElementMethodInput input)
        {
            string previousPath = Path.GetDirectoryName(Directory.GetCurrentDirectory());

            string fileUri = Path.Combine(
                previousPath,
                $"Solutions/FiniteElement/Beam/{request.Profile.GetType().Name}/nEl={request.NumberOfElements}/{request.NumericalMethod}");

            string fileName = $"{request.AnalysisType}_{request.Profile.GetType().Name}_w={Math.Round(input.AngularFrequency, 2)}_nEl={request.NumberOfElements}.csv";

            string path = Path.Combine(fileUri, fileName);

            Directory.CreateDirectory(fileUri);

            return(Task.FromResult(path));
        }
Пример #7
0
        /// <summary>
        /// This method creates the path to save the file with the maximum values for each angular frequency.
        /// </summary>
        /// <param name="request"></param>
        /// <param name="input"></param>
        /// <returns>The path to save the file with the maximum values for each angular frequency.</returns>
        public override Task <string> CreateMaxValuesPath(BeamWithDvaRequest <TProfile> request, FiniteElementMethodInput input)
        {
            string previousPath = Path.GetDirectoryName(Directory.GetCurrentDirectory());

            string fileUri = Path.Combine(
                previousPath,
                $"Solutions/FiniteElement/BeamWithDva/MaxValues/{request.NumericalMethod}");

            string fileName = $"MaxValues_{request.AnalysisType}_{request.Profile.GetType().Name}_NumberOfDvas={request.Dvas.Count}_w0={Math.Round(request.InitialAngularFrequency, 2)}_wf={Math.Round(request.FinalAngularFrequency, 2)}_nEl={request.NumberOfElements}.csv";

            string path = Path.Combine(fileUri, fileName);

            Directory.CreateDirectory(fileUri);

            return(Task.FromResult(path));
        }
Пример #8
0
        /// <summary>
        /// This method calculates the vibration using finite element concepts and writes the results in a file.
        /// Each line in the file contains the result in an instant of time at an angular frequency.
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        protected override async Task <FiniteElementResponse> ProcessOperation(TRequest request)
        {
            var response = new FiniteElementResponse {
                Data = new FiniteElementResponseData()
            };

            response.SetSuccessCreated();

            // Step 1 - Sets the numerical method to be used in analysis.
            base._numericalMethod = NumericalMethodFactory.CreateMethod(request.NumericalMethod);

            // Step 2 - Creates the input to numerical method.
            FiniteElementMethodInput input = await this.CreateInput(request).ConfigureAwait(false);

            // Step 3 - Generates the path to save the maximum values of analysis results and save the file URI.
            string maxValuesPath = await this.CreateMaxValuesPath(request, input).ConfigureAwait(false);

            ICollection <string> fileUris = new Collection <string>();

            fileUris.Add(Path.GetDirectoryName(maxValuesPath));

            while (input.AngularFrequency <= input.FinalAngularFrequency)
            {
                // Step 4 - Sets the value for time step and final time based on angular frequency and element mechanical properties.
                input.TimeStep = await this._time.CalculateTimeStep(input.AngularFrequency, request.PeriodDivision).ConfigureAwait(false);

                input.FinalTime = await this._time.CalculateFinalTime(input.AngularFrequency, request.PeriodCount).ConfigureAwait(false);

                // Step 5 - Generates the path to save the analysis results.
                // Each combination of damping ratio and angular frequency will have a specific path.
                string solutionPath = await this.CreateSolutionPath(request, input).ConfigureAwait(false);

                string solutionFolder = Path.GetDirectoryName(solutionPath);

                if (fileUris.Contains(solutionFolder) == false)
                {
                    fileUris.Add(Path.GetDirectoryName(solutionPath));
                }

                var previousResult = new FiniteElementResult
                {
                    Displacement = new double[input.NumberOfTrueBoundaryConditions],
                    Velocity     = new double[input.NumberOfTrueBoundaryConditions],
                    Acceleration = new double[input.NumberOfTrueBoundaryConditions],
                    Force        = input.OriginalForce
                };

                var maxValuesResult = new FiniteElementResult
                {
                    Displacement = new double[input.NumberOfTrueBoundaryConditions],
                    Velocity     = new double[input.NumberOfTrueBoundaryConditions],
                    Acceleration = new double[input.NumberOfTrueBoundaryConditions],
                    Force        = new double[input.NumberOfTrueBoundaryConditions]
                };

                try
                {
                    using (StreamWriter streamWriter = new StreamWriter(solutionPath))
                    {
                        // Step 6 - Calculates the initial results and writes it into a file.
                        FiniteElementResult result = await this._numericalMethod.CalculateFiniteElementResultForInitialTime(input).ConfigureAwait(false);

                        streamWriter.WriteResult(input.InitialTime, result.Displacement);

                        // Step 7 - Sets the next time.
                        double time = input.InitialTime + input.TimeStep;

                        while (time <= input.FinalTime)
                        {
                            // Step 8 - Calculates the results and writes it into a file.
                            result = await this._numericalMethod.CalculateFiniteElementResult(input, previousResult, time).ConfigureAwait(false);

                            streamWriter.WriteResult(time, result.Displacement);

                            previousResult = result;

                            // Step 9 - Compares the previous results with the new calculated to catch the maximum values.
                            await this.CompareValuesAndUpdateMaxValuesResult(result, maxValuesResult).ConfigureAwait(false);

                            time += input.TimeStep;
                        }
                    }
                }
                catch (Exception ex)
                {
                    response.AddError(OperationErrorCode.InternalServerError, $"Occurred error while calculating the analysis results and writing them in the file. {ex.Message}", HttpStatusCode.InternalServerError);

                    response.SetInternalServerError();
                    return(response);
                }

                try
                {
                    // Step 10 - Writes the maximum values of analysis result into a file.
                    using (StreamWriter streamWriter = new StreamWriter(maxValuesPath, true))
                    {
                        streamWriter.WriteResult(input.AngularFrequency, maxValuesResult.Displacement);
                    }
                }
                catch (Exception ex)
                {
                    response.AddError(OperationErrorCode.InternalServerError, $"Occurred error while writing the maximum values in the file. {ex.Message}", HttpStatusCode.InternalServerError);

                    response.SetInternalServerError();
                    return(response);
                }

                input.AngularFrequency += input.AngularFrequencyStep;
            }

            // Step 11 - Calculates the structure natural frequencies and writes them into a file.
            //double[] naturalFrequencies = await this._naturalFrequency.CalculateByQRDecomposition(input.Mass, input.Stiffness, tolerance: 1e-3).ConfigureAwait(false);
            //this._file.Write("Natural Frequencies", naturalFrequencies, maxValuesPath);

            // Step 12 - Maps the response.
            response.Data.Author = request.Author;
            response.Data.AnalysisExplanation = "Not implemented.";
            response.Data.FileUris            = fileUris;
            return(response);
        }
 /// <summary>
 /// Calculates the result for the initial time for a finite element analysis using Runge Kutta Forth Order numerical method.
 /// </summary>
 /// <param name="input"></param>
 /// <returns></returns>
 public override Task <FiniteElementResult> CalculateFiniteElementResultForInitialTime(FiniteElementMethodInput input)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 /// Calculates and write in a file the results for a finite element analysis using Runge Kutta Forth Order numerical method.
 /// </summary>
 /// <param name="input"></param>
 /// <param name="previousResult"></param>
 /// <param name="time"></param>
 /// <returns></returns>
 public override Task <FiniteElementResult> CalculateFiniteElementResult(FiniteElementMethodInput input, FiniteElementResult previousResult, double time)
 {
     throw new NotImplementedException();
 }
Пример #11
0
        /// <summary>
        /// Calculates and write in a file the results for a finite element analysis using Newmark integration method.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="previousResult"></param>
        /// <param name="time"></param>
        /// <returns></returns>
        public override async Task <FiniteElementResult> CalculateFiniteElementResult(FiniteElementMethodInput input, FiniteElementResult previousResult, double time)
        {
            FiniteElementResult result = new FiniteElementResult
            {
                Displacement = new double[input.NumberOfTrueBoundaryConditions],
                Velocity     = new double[input.NumberOfTrueBoundaryConditions],
                Acceleration = new double[input.NumberOfTrueBoundaryConditions],
                Force        = previousResult.Force
            };

            this.CalculateIngrationContants(input);

            double[,] equivalentStiffness = await this.CalculateEquivalentStiffness(input.Mass, input.Stiffness, input.Damping, input.NumberOfTrueBoundaryConditions).ConfigureAwait(false);

            double[,] inversedEquivalentStiffness = await equivalentStiffness.InverseMatrixAsync().ConfigureAwait(false);

            double[] equivalentForce = await this.CalculateEquivalentForce(input, previousResult.Displacement, previousResult.Velocity, previousResult.Acceleration, time).ConfigureAwait(false);

            result.Displacement = await inversedEquivalentStiffness.MultiplyAsync(equivalentForce).ConfigureAwait(false);

            string path = @"C:\Users\bruno\OneDrive\Área de Trabalho\Testes - IC Vibrações\Matrizes resultantes\master.csv";

            using (StreamWriter streamWriter = new StreamWriter(path))
            {
                this.WriteMatrix(streamWriter, equivalentStiffness, "Keq");
                this.WriteMatrix(streamWriter, inversedEquivalentStiffness, "IKeq");

                this.WriteVector(streamWriter, equivalentForce, "Feq");
                this.WriteVector(streamWriter, result.Displacement, "Y");
            }

            for (int i = 0; i < input.NumberOfTrueBoundaryConditions; i++)
            {
                result.Acceleration[i] = a0 * (result.Displacement[i] - previousResult.Displacement[i]) - a2 * previousResult.Velocity[i] - a3 * previousResult.Acceleration[i];
                result.Velocity[i]     = previousResult.Velocity[i] + a6 * previousResult.Acceleration[i] + a7 * result.Acceleration[i];
            }

            return(result);
        }
Пример #12
0
 /// <summary>
 /// Calculates the result for the initial time for a finite element analysis using Newmark integration method.
 /// </summary>
 /// <param name="input"></param>
 /// <returns></returns>
 public override Task <FiniteElementResult> CalculateFiniteElementResultForInitialTime(FiniteElementMethodInput input)
 {
     return(Task.FromResult(new FiniteElementResult
     {
         Displacement = new double[input.NumberOfTrueBoundaryConditions],
         Velocity = new double[input.NumberOfTrueBoundaryConditions],
         Acceleration = new double[input.NumberOfTrueBoundaryConditions],
         Force = input.OriginalForce
     }));
 }
Пример #13
0
        /// <summary>
        /// Calculates and write in a file the results for a one degree of freedom analysis using Newmark-Beta integration method.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="previousResult"></param>
        /// <param name="time"></param>
        /// <returns></returns>
        public override async Task <FiniteElementResult> CalculateFiniteElementResult(FiniteElementMethodInput input, FiniteElementResult previousResult, double time)
        {
            double[,] equivalentStiffness = await this.CalculateEquivalentStiffness(input).ConfigureAwait(false);

            double[,] inversedEquivalentStiffness = await equivalentStiffness.InverseMatrixAsync().ConfigureAwait(false);

            double[] equivalentForce = await this.CalculateEquivalentForce(input, previousResult, time).ConfigureAwait(false);

            double[] deltaDisplacement = await inversedEquivalentStiffness.MultiplyAsync(equivalentForce).ConfigureAwait(false);

            double[] deltaVelocity     = new double[input.NumberOfTrueBoundaryConditions];
            double[] deltaAcceleration = new double[input.NumberOfTrueBoundaryConditions];

            for (int i = 0; i < input.NumberOfTrueBoundaryConditions; i++)
            {
                deltaVelocity[i]     = input.Gama / (input.Beta * input.TimeStep) * deltaDisplacement[i] - input.Gama / input.Beta * previousResult.Velocity[i] + input.TimeStep * (1 - input.Gama / (2 * input.Beta)) * previousResult.Acceleration[i];
                deltaAcceleration[i] = (1 / (input.Beta * Math.Pow(input.TimeStep, 2))) * deltaDisplacement[i] - (1 / (input.Beta * input.TimeStep)) * previousResult.Velocity[i] - (1 / (2 * input.Beta)) * previousResult.Acceleration[i];
            }

            return(new FiniteElementResult
            {
                Displacement = await previousResult.Displacement.SumAsync(deltaDisplacement).ConfigureAwait(false),
                Velocity = await previousResult.Velocity.SumAsync(deltaVelocity).ConfigureAwait(false),
                Acceleration = await previousResult.Acceleration.SumAsync(deltaAcceleration).ConfigureAwait(false),
                Force = await this._force.CalculateForceByType(input.OriginalForce, input.AngularFrequency, time, input.ForceType).ConfigureAwait(false)
            });
        }
Пример #14
0
 /// <summary>
 /// Calculates and write in a file the results for a finite element analysis.
 /// </summary>
 /// <param name="input"></param>
 /// <param name="previousResult"></param>
 /// <param name="time"></param>
 /// <returns></returns>
 public abstract Task <FiniteElementResult> CalculateFiniteElementResult(FiniteElementMethodInput input, FiniteElementResult previousResult, double time);
Пример #15
0
 /// <summary>
 /// Calculates the result for the initial time for a finite element analysis.
 /// </summary>
 /// <param name="input"></param>
 /// <returns></returns>
 public abstract Task <FiniteElementResult> CalculateFiniteElementResultForInitialTime(FiniteElementMethodInput input);