about summary refs log tree commit diff
path: root/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'main.go')
-rw-r--r--main.go189
1 files changed, 189 insertions, 0 deletions
diff --git a/main.go b/main.go
index 7905807..e39e8e5 100644
--- a/main.go
+++ b/main.go
@@ -1,5 +1,194 @@
 package main
 
+import (
+	"encoding/csv"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"log"
+	"math"
+	"strconv"
+	"strings"
+	"time"
+)
+
+var (
+	amountOfStars int
+)
+
 func main() {
+	var tests = []int64{
+		1000,
+		2000,
+		4000,
+		8000,
+		16000,
+		32000,
+		64000,
+		128000,
+	}
+	data := ReadData("data/200000.csv")
+
+	for _, element := range tests {
+		data = data[:element]
+		var processedStars []Star
+		var cores = 8
+		amountOfStars = len(data)
+		processedChannel := make(chan Star, 1)
+
+		var starsPerCore = amountOfStars / cores
+		overallStartTime := time.Now()
+
+		// start n threads processing stars
+		for i := 0; i < cores; i++ {
+			//fmt.Printf("Core %d processing #%d-#%d\n", i, i*starsPerCore, (i*starsPerCore)+(starsPerCore-1))
+
+			var begin = i * starsPerCore
+			var end = (i * starsPerCore) + (starsPerCore)
+
+			go ProcessStar(data, begin, end, processedChannel)
+		}
+
+		processedChannel <- Star{}
+
+		doneStartingThreads := time.Now()
+
+		// get the results through the processedChannel
+		for i := 0; i < amountOfStars+1; i++ {
+			newStar := <-processedChannel
+			processedStars = append(processedStars, newStar)
+		}
+
+		doneGettingResults := time.Now()
+
+		threadStartTime := doneStartingThreads.Sub(overallStartTime)
+		calculationTime := doneGettingResults.Sub(overallStartTime)
+
+		fmt.Printf("--------------------------------------------------------------------------------")
+		fmt.Printf("Amount of Stars: %d\n", amountOfStars)
+		fmt.Printf("Amount of Threads: %d\n", cores)
+		fmt.Printf("Amount of stars per thread: %d\n", starsPerCore)
+		fmt.Printf("Thread start time: %f sec.\n", threadStartTime.Seconds())
+		fmt.Printf("Calculation time: %f sec.\n", calculationTime.Seconds())
+		fmt.Printf("Calculation time per star: %f sec.\n", calculationTime.Seconds()/float64(amountOfStars))
+		fmt.Printf("Calculation per second: %f sec.\n", calculationTime.Seconds()/float64(amountOfStars))
+	}
+
+}
+
+type Star struct {
+	C, V Vec3
+	M    float64
+}
+
+type Vec3 struct {
+	X, Y, Z float64
+}
+
+func check(e error) {
+	if e != nil {
+		panic(e)
+	}
+}
+
+func ReadData(filepath string) []Star {
+	// open the .csv
+	dat, err := ioutil.ReadFile(filepath)
+	check(err)
+
+	// create a new csv reader
+	r := csv.NewReader(strings.NewReader(string(dat)))
+
+	var arrayOfStars []Star
+
+	for {
+		record, err := r.Read()
+		if err == io.EOF {
+			break
+		}
+		if err != nil {
+			log.Fatal(err)
+		}
+
+		// parse the values
+		x, parseErr := strconv.ParseFloat(record[0], 64)
+		y, parseErr := strconv.ParseFloat(record[0], 64)
+		z, parseErr := strconv.ParseFloat(record[0], 64)
+		check(parseErr)
+
+		// define a star
+		var localStar = Star{Vec3{x, y, z}, Vec3{0, 0, 0}, 2e30}
+
+		// append the star to the list of stars
+		arrayOfStars = append(arrayOfStars, localStar)
+	}
+
+	return arrayOfStars
+}
+
+// CalcForce calculates the force exerted on s1 by s2 and returns a vector representing that force
+func CalcForce(s1 Star, s2 Star) Vec3 {
+	G := 6.6726 * math.Pow(10, -11)
+
+	// calculate the force acting
+	var combinedMass = s1.M * s2.M
+	var distance = math.Sqrt(math.Pow(math.Abs(s1.C.X-s2.C.X), 2) + math.Pow(math.Abs(s1.C.Y-s2.C.Y), 2))
+
+	var scalar = G * ((combinedMass) / math.Pow(distance, 2))
+
+	// define a unit vector pointing from s1 to s2
+	var vector = Vec3{s2.C.X - s1.C.X, s2.C.Y - s1.C.Y, s2.C.Z - s1.C.Z}
+	var UnitVector = Vec3{vector.X / distance, vector.Y / distance, vector.Z / distance}
+
+	// multiply the vector with the force to get a vector representing the force acting
+	var force = UnitVector.Multiply(scalar)
+
+	// return the force exerted on s1 by s2
+	return force
+}
+
+// Multiply returns the product of the vector and a scalar s
+func (v *Vec3) Multiply(s float64) Vec3 {
+	return Vec3{v.X * s, v.Y * s, v.Z * s}
+}
+
+func ProcessStar(data []Star, begin int, end int, returnChannel chan Star) {
+
+	// iterate over the given range of data
+	for i := begin; i < end; i++ {
+		localStar := data[i]
+		var Force Vec3
+
+		// iterate over all the other stars
+		for index := range data {
+			if index != i {
+
+				// calculate the force acting on the star
+				force := CalcForce(localStar, data[index])
+
+				// add the force onto the overall force
+				Force.X += force.X
+				Force.Y += force.Y
+				Force.Z += force.Z
+			}
+		}
+
+		newStar := Star{
+			C: Vec3{
+				X: data[i].C.X,
+				Y: data[i].C.Y,
+				Z: data[i].C.Z,
+			},
+			V: Vec3{
+				X: Force.X / float64(amountOfStars),
+				Y: Force.Y / float64(amountOfStars),
+				Z: Force.Z / float64(amountOfStars),
+			},
+			M: data[i].M,
+		}
+
+		returnChannel <- newStar
+	}
 
+	return
 }