From 46afb6bf501f4001c4bdb7bd2f2db7c466f95554 Mon Sep 17 00:00:00 2001 From: Juan Marin Noguera Date: Tue, 25 Jul 2023 18:22:04 +0200 Subject: Solvned project from 2020 Note that Go didn't have generics back then. --- ivp/throw.go | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 ivp/throw.go (limited to 'ivp/throw.go') diff --git a/ivp/throw.go b/ivp/throw.go new file mode 100644 index 0000000..e91d989 --- /dev/null +++ b/ivp/throw.go @@ -0,0 +1,68 @@ +// Parabolic throw problem with air friction. +// +// Copyright (C) 2020 Juan MarĂ­n Noguera +// +// This file is part of Solvned. +// +// Solvned is free software: you can redistribute it and/or modify it under the +// terms of the GNU Lesser General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any +// later version. +// +// Solvned is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with Solvned. If not, see . + +package ivp + +import ( + "math" + "github.com/JwanMan/mned" +) + +// Gravity acceleration in the Earth surface +const EARTH_GRAVITY float64 = 9.806 + +// A ParabolicThrow is the result of throwing an object, which we consider to +// be punctual, from a given height and with some initial velocity. We assume +// that Newton mechanics apply and that air resistance has a force proportional +// to the square of the velocity, and opposite to it. +// +// The resulting ODE is `x'' = -gj - (k/m)*x'*|x'|`, where `x` is the position, +// `g` is the gravity acceleration, `j` is the vertical unit vector (upwards), +// `k` is the air resistance, and `m` is the mass of the object. +// +// The comments on fields assume standard SI units, but other units may be used. +type ParabolicThrow struct { + Height float64 // Initial height over the floor (m). + Mass float64 // Mass of the object (kg). *Must* be positive. + V0 [2]float64 // Initial velocity (x,y) (m/s). + Resistance float64 // Air resistance (kg/m). + Gravity float64 // Gravity acceleration (m/s^2). +} + +// Create an IVP from the data on this problem. +// +// Result values have the form (x,y,vx,vy), where (x,y) is the position and +// (vx,vy) is the velocity. The initial x and time are 0. +func (p *ParabolicThrow) ToIVP() mned.IVP { + ratio := p.Resistance / p.Mass + gravity := p.Gravity + return mned.IVP{ + Derivative: func(p mned.Point) ([]float64, bool) { + x := p.Value + air := -ratio * math.Sqrt(x[2]*x[2]+x[3]*x[3]) + return []float64{ + x[2], x[3], air * x[2], air*x[3] - gravity, + }, true + }, + Start: mned.Point{ + Time: 0, + Value: []float64{0, p.Height, p.V0[0], p.V0[1]}, + }, + } +} -- cgit v1.2.3