package main import ( "fmt" "gopkg.in/cheggaaa/pb.v1" "math" "math/rand" "os" ) const ( sigma = 200.0 f_0 = 0.1 G = 4.302e-3 R_s = 1e4 ) type star struct { x float64 y float64 z float64 } func rho(x, y, z float64) float64 { var r float64 = math.Sqrt((x * x) + (y * y) + (z * z)) var a float64 = (1) / (math.Sqrt(2*math.Pi) * sigma) var b float64 = math.Exp(-(phi(r) / float64(sigma*sigma))) //aphi := phi(r) //asigma := float64(sigma * sigma) //fmt.Println(aphi, asigma, math.Exp( - (aphi / asigma))) return a * b } func phi(x float64) float64 { if x == 0 { return (-4 * math.Pi * f_0 * G * (R_s * R_s)) } else { var a float64 = -(4 * math.Pi * G * f_0 * (R_s * R_s * R_s) / x) var b float64 = math.Log(1.0 + (x / R_s)) return (a * b) } } func genStar(f *os.File) (bool, star) { var length float64 = 1.5e7 var rangeMin float64 = -length var rangeMax float64 = length var randMin float64 = rho(0, 0, 0) var randMax float64 = rho(length, length, length) //(max - min) * rand.Float64()) + min var x float64 = ((rangeMax - rangeMin) * rand.Float64()) + rangeMin var y float64 = ((rangeMax - rangeMin) * rand.Float64()) + rangeMin var z float64 = ((rangeMax - rangeMin) * rand.Float64()) + rangeMin var randVal float64 = (randMax-randMin)*rand.Float64() + randMin var rhoVal float64 = rho(x, y, z) //fmt.Printf("x: %-20f y: %-20f z: %-20f randVal: %-20f rhoVal: %-20f\n", x, y, z, randVal, rhoVal) if randVal < rhoVal { var starString string = fmt.Sprintf("%f, %f, %f\n", x, y, z) _, err := f.WriteString(starString) if err != nil { panic(err) } f.Sync() //fmt.Printf("x: %-20f y: %-20f z: %-20f randVal: %-20f rhoVal: %-20f\n", x, y, z, randVal, rhoVal) newStar := star{ x: x, y: y, z: z, } // return that a star was generated return true, newStar } // return that no star was generated return false, star{ x: 0, y: 0, z: 0, } } func generateGoMethods(starCount int, f *os.File, channel chan star) { var generatedStars int = 0 // for the amount of stars for generatedStars < starCount { // try to generate a new star result, star := genStar(f) if result == true { generatedStars += 1 channel <- star } } } func main() { // define some arguments var stars int = 1e6 var threads int = 1 var threadStarCount int = stars / threads // create a channel with a buffer of 10 channel := make(chan star, 10) // create a file that stores the data hostname, _ := os.Hostname() pid := os.Getpid() f, err := os.Create(fmt.Sprintf("%s_%d.csv", hostname, pid)) if err != nil { panic(err) } // use 8 threads // each thread should generate stars / 8 stars for i := 0; i < threads; i++ { fmt.Printf("Creating a happy worker! He/She is trying to generate %d stars!", threadStarCount) // generate a go-method creating threadStarCound stars go generateGoMethods(threadStarCount, f, channel) fmt.Printf(" He/She just started working!\n") } // start the missing threads threads var missingStars int = stars - (threadStarCount * threads) fmt.Printf("A special worker was assigned to generate the last %d stars.\n", missingStars) go generateGoMethods(missingStars, f, channel) var starSlice []star // Initialize a new progress bar bar := pb.New(stars).Prefix("Stars: ") bar.Start() // get the stars for i := 0; i < stars; i++ { var newStar = <-channel bar.Increment() starSlice = append(starSlice, newStar) } bar.Finish() // print all elements in the starslice for _, element := range starSlice { fmt.Println(element) } }