/home/runner/work/kynema/kynema/kynema/src/math/least_squares_fit.hpp Source File

Kynema API: /home/runner/work/kynema/kynema/kynema/src/math/least_squares_fit.hpp Source File
Kynema API
A flexible multibody structural dynamics code for wind turbines
Loading...
Searching...
No Matches
least_squares_fit.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4#include <ranges>
5#include <span>
6#include <stdexcept>
7#include <vector>
8
9#include <Eigen/Dense>
10
11#include "interpolation.hpp"
12
13namespace kynema::math {
14
22inline std::vector<double> MapGeometricLocations(std::span<const double> geom_locations) {
23 // Get first and last points of the input domain (assumed to be sorted)
24 const double domain_start = geom_locations.front();
25 const double domain_end = geom_locations.back();
26 if (domain_end == domain_start) {
27 throw std::invalid_argument(
28 "Invalid geometric locations: domain start and end points are equal."
29 );
30 }
31
32 // Map each point from domain -> [-1, 1]
33 std::vector<double> mapped_locations(geom_locations.size());
34 const auto domain_span = domain_end - domain_start;
35 std::ranges::transform(
36 geom_locations, std::begin(mapped_locations),
37 [domain_start, domain_span](auto geom_location) {
38 return (2. * (geom_location - domain_start) / domain_span) - 1.;
39 }
40 );
41 return mapped_locations;
42}
43
53inline std::vector<std::vector<double>> ComputeShapeFunctionValues(
54 std::span<const double> input_points, std::span<const double> output_points
55) {
56 // Number of points in input and output arrays
57 const auto num_input_points = input_points.size();
58 const auto num_output_points = output_points.size();
59
60 // Compute weights for the shape functions and its derivatives at the evaluation points
61 std::vector<double> weights(num_output_points, 0.);
62
63 // Create shape function interpolation matrix
64 auto shape_functions = std::vector<std::vector<double>>(
65 num_output_points, std::vector<double>(num_input_points, 0.)
66 );
67 for (auto input_point : std::views::iota(0U, num_input_points)) {
68 math::LagrangePolynomialInterpWeights(input_points[input_point], output_points, weights);
69 for (auto output_point : std::views::iota(0U, num_output_points)) {
70 shape_functions[output_point][input_point] = weights[output_point];
71 }
72 }
73
74 return shape_functions;
75}
76
86inline std::vector<std::vector<double>> ComputeShapeFunctionDerivatives(
87 std::span<const double> input_points, std::span<const double> output_points
88) {
89 // Number of points in input and output arrays
90 const auto num_input_points = input_points.size();
91 const auto num_output_points = output_points.size();
92
93 // Compute weights for the shape functions and its derivatives at the evaluation points
94 std::vector<double> weights(num_output_points, 0.);
95
96 // Create shape function derivative matrix
97 auto derivative_functions = std::vector<std::vector<double>>(
98 num_output_points, std::vector<double>(num_input_points, 0.)
99 );
100 for (auto input_point : std::views::iota(0U, num_input_points)) {
101 math::LagrangePolynomialDerivWeights(input_points[input_point], output_points, weights);
102 for (auto output_point : std::views::iota(0U, num_output_points)) {
103 derivative_functions[output_point][input_point] = weights[output_point];
104 }
105 }
106
107 return derivative_functions;
108}
109
121std::vector<std::array<double, 3>> PerformLeastSquaresFitting(
122 std::span<const std::vector<double>> shape_functions,
123 std::span<const std::array<double, 3>> points_to_fit
124);
125} // namespace kynema::math
Definition gl_quadrature.hpp:8
std::vector< double > MapGeometricLocations(std::span< const double > geom_locations)
Maps input geometric locations -> normalized domain using linear mapping.
Definition least_squares_fit.hpp:22
void LagrangePolynomialInterpWeights(double x, std::span< const double > xs, std::vector< double > &weights)
Computes weights for Lagrange polynomial interpolation.
Definition interpolation.hpp:70
void LagrangePolynomialDerivWeights(double x, std::span< const double > xs, std::vector< double > &weights)
Computes weights for Lagrange polynomial derivative interpolation.
Definition interpolation.hpp:98
std::vector< std::array< double, 3 > > PerformLeastSquaresFitting(std::span< const std::vector< double > > shape_functions, std::span< const std::array< double, 3 > > points_to_fit)
Performs least squares fitting to determine interpolation coefficients.
Definition least_squares_fit.cpp:10
std::vector< std::vector< double > > ComputeShapeFunctionValues(std::span< const double > input_points, std::span< const double > output_points)
Computes shape function matrices ϕg relating points ξb to ξg At least two input points are required a...
Definition least_squares_fit.hpp:53
std::vector< std::vector< double > > ComputeShapeFunctionDerivatives(std::span< const double > input_points, std::span< const double > output_points)
Computes shape function derivatives dϕg relating points ξb to ξg At least two input points are requir...
Definition least_squares_fit.hpp:86