অনুশীলন: 2 ডি অরবিটাল মেকানিক্স সিমুলেশন (অজগর)


12

এর আগে মাত্র কিছুটা অস্বীকার: আমি কখনও জ্যোতির্বিদ্যায় বা সে বিষয়ে কোনও সঠিক বিজ্ঞান অধ্যয়ন করি নি (এমনকি আইটিও নয়), তাই আমি স্ব-শিক্ষার মাধ্যমে এই ফাঁক পূরণ করার চেষ্টা করছি। জ্যোতির্বিজ্ঞান এমন একটি ক্ষেত্র যা আমার দৃষ্টি আকর্ষণ করেছে এবং আমার স্ব-শিক্ষার ধারণাটি প্রয়োগের পদ্ধতির দিকে এগিয়ে। সুতরাং, সরাসরি কথা বলা - এটি অরবিটাল সিমুলেশন মডেল যা আমার / সময় / মেজাজের সময় আমি আকস্মিকভাবে কাজ করছি। আমার বড় লক্ষ্য গতিতে সম্পূর্ণ সৌরজগৎ তৈরি করা এবং অন্যান্য গ্রহে মহাকাশযান চালানোর পরিকল্পনা করার ক্ষমতা।

আপনি যে কোনও সময়ে এই প্রকল্পটি বাছাই করতে মোটামুটি মুক্ত এবং পরীক্ষায় মজা পান!

হালনাগাদ!!! (Nov10)

  • বেগ এখন যথাযথ ডেল্টাভি এবং অতিরিক্ত গতি প্রদান করা এখন বেগের যোগফলের গণনা করে
  • আপনি প্রতিটি উত্স থেকে মাধ্যাকর্ষণ ভেক্টর (এবং সংঘর্ষের জন্য চেক) গতি চেক প্রতিটি সময় ইউনিট অবজেক্টে আপনি চান হিসাবে অনেক স্থিতিশীল বস্তু রাখতে পারেন
  • গণনার কার্যকারিতা অনেক উন্নত করেছে improved
  • matplotlib মধ্যে ইন্টারেক্টিভ Mod জন্য অ্যাকাউন্টে স্থির। দেখে মনে হচ্ছে এটি কেবল আইপথনের জন্য ডিফল্ট বিকল্প। নিয়মিত পাইথন 3 এর স্পষ্টভাবে বিবৃতি প্রয়োজন।

মূলত এখন পৃথিবীর তলদেশ থেকে একটি মহাকাশযান "চালু" করা এবং গিভমোশন () এর মাধ্যমে ডেল্টাভি ভেক্টর সংশোধন করে চাঁদে একটি মিশনের পরিকল্পনা করা সম্ভব। পরের লাইনে একযোগে গতি সক্ষম করার জন্য গ্লোবাল টাইম ভেরিয়েবল বাস্তবায়নের চেষ্টা করা হয় যেমন চাঁদ পৃথিবীর প্রদক্ষিণ করে যখন মহাকাশযান একটি মাধ্যাকর্ষণ সহায়তা কৌশল চালানোর চেষ্টা করে।

উন্নতির জন্য মন্তব্য এবং পরামর্শ সর্বদা স্বাগত!

ম্যাটপ্ল্লটিব লাইব্রেরির সাথে পাইথন 3 এ শেষ

import matplotlib.pyplot as plt
import math
plt.ion()

G = 6.673e-11  # gravity constant
gridArea = [0, 200, 0, 200]  # margins of the coordinate grid
gridScale = 1000000  # 1 unit of grid equals 1000000m or 1000km

plt.clf()  # clear plot area
plt.axis(gridArea)  # create new coordinate grid
plt.grid(b="on")  # place grid

class Object:
    _instances = []
    def __init__(self, name, position, radius, mass):
        self.name = name
        self.position = position
        self.radius = radius  # in grid values
        self.mass = mass
        self.placeObject()
        self.velocity = 0
        Object._instances.append(self)

    def placeObject(self):
        drawObject = plt.Circle(self.position, radius=self.radius, fill=False, color="black")
        plt.gca().add_patch(drawObject)
        plt.show()

    def giveMotion(self, deltaV, motionDirection, time):
        if self.velocity != 0:
            x_comp = math.sin(math.radians(self.motionDirection))*self.velocity
            y_comp = math.cos(math.radians(self.motionDirection))*self.velocity
            x_comp += math.sin(math.radians(motionDirection))*deltaV
            y_comp += math.cos(math.radians(motionDirection))*deltaV
            self.velocity = math.sqrt((x_comp**2)+(y_comp**2))

            if x_comp > 0 and y_comp > 0:  # calculate degrees depending on the coordinate quadrant
                self.motionDirection = math.degrees(math.asin(abs(x_comp)/self.velocity))  # update motion direction
            elif x_comp > 0 and y_comp < 0:
                self.motionDirection = math.degrees(math.asin(abs(y_comp)/self.velocity)) + 90
            elif x_comp < 0 and y_comp < 0:
                self.motionDirection = math.degrees(math.asin(abs(x_comp)/self.velocity)) + 180
            else:
                self.motionDirection = math.degrees(math.asin(abs(y_comp)/self.velocity)) + 270

        else:
            self.velocity = self.velocity + deltaV  # in m/s
            self.motionDirection = motionDirection  # degrees
        self.time = time  # in seconds
        self.vectorUpdate()

    def vectorUpdate(self):
        self.placeObject()
        data = []

        for t in range(self.time):
            motionForce = self.mass * self.velocity  # F = m * v
            x_net = 0
            y_net = 0
            for x in [y for y in Object._instances if y is not self]:
                distance = math.sqrt(((self.position[0]-x.position[0])**2) +
                             (self.position[1]-x.position[1])**2)
                gravityForce = G*(self.mass * x.mass)/((distance*gridScale)**2)

                x_pos = self.position[0] - x.position[0]
                y_pos = self.position[1] - x.position[1]

                if x_pos <= 0 and y_pos > 0:  # calculate degrees depending on the coordinate quadrant
                    gravityDirection = math.degrees(math.asin(abs(y_pos)/distance))+90

                elif x_pos > 0 and y_pos >= 0:
                    gravityDirection = math.degrees(math.asin(abs(x_pos)/distance))+180

                elif x_pos >= 0 and y_pos < 0:
                    gravityDirection = math.degrees(math.asin(abs(y_pos)/distance))+270

                else:
                    gravityDirection = math.degrees(math.asin(abs(x_pos)/distance))

                x_gF = gravityForce * math.sin(math.radians(gravityDirection))  # x component of vector
                y_gF = gravityForce * math.cos(math.radians(gravityDirection))  # y component of vector

                x_net += x_gF
                y_net += y_gF

            x_mF = motionForce * math.sin(math.radians(self.motionDirection))
            y_mF = motionForce * math.cos(math.radians(self.motionDirection))
            x_net += x_mF
            y_net += y_mF
            netForce = math.sqrt((x_net**2)+(y_net**2))

            if x_net > 0 and y_net > 0:  # calculate degrees depending on the coordinate quadrant
                self.motionDirection = math.degrees(math.asin(abs(x_net)/netForce))  # update motion direction
            elif x_net > 0 and y_net < 0:
                self.motionDirection = math.degrees(math.asin(abs(y_net)/netForce)) + 90
            elif x_net < 0 and y_net < 0:
                self.motionDirection = math.degrees(math.asin(abs(x_net)/netForce)) + 180
            else:
                self.motionDirection = math.degrees(math.asin(abs(y_net)/netForce)) + 270

            self.velocity = netForce/self.mass  # update velocity
            traveled = self.velocity/gridScale  # grid distance traveled per 1 sec
            self.position = (self.position[0] + math.sin(math.radians(self.motionDirection))*traveled,
                             self.position[1] + math.cos(math.radians(self.motionDirection))*traveled)  # update pos
            data.append([self.position[0], self.position[1]])

            collision = 0
            for x in [y for y in Object._instances if y is not self]:
                if (self.position[0] - x.position[0])**2 + (self.position[1] - x.position[1])**2 <= x.radius**2:
                    collision = 1
                    break
            if collision != 0:
                print("Collision!")
                break

        plt.plot([x[0] for x in data], [x[1] for x in data])

Earth = Object(name="Earth", position=(50.0, 50.0), radius=6.371, mass=5.972e24)
Moon = Object(name="Moon", position=(100.0, 100.0), radius=1.737, mass = 7.347e22)  # position not to real scale
Craft = Object(name="SpaceCraft", position=(49.0, 40.0), radius=1, mass=1.0e4)

Craft.giveMotion(deltaV=8500.0, motionDirection=100, time=130000)
Craft.giveMotion(deltaV=2000.0, motionDirection=90, time=60000)
plt.show(block=True)

কিভাবে এটা কাজ করে

এগুলি দুটি জিনিসকে ফোটায়:

  1. Earth = Object(name="Earth", position=(50.0, 50.0), radius=6.371, mass=5.972e24)গ্রিডে অবস্থানের পরামিতিগুলির মতো বস্তু তৈরি করা (গ্রিডের 1 ইউনিট ডিফল্টরূপে 1000km তবে এটিও পরিবর্তন করা যেতে পারে), গ্রিড ইউনিটে ব্যাসার্ধ এবং কেজিতে ভর in
  2. বস্তুটি কিছু ডেল্টাভি দেওয়া যেমন Craft.giveMotion(deltaV=8500.0, motionDirection=100, time=130000)স্পষ্টতই এটি Craft = Object(...)পূর্ববর্তী পয়েন্টে উল্লিখিত হিসাবে প্রথমে তৈরি করা প্রয়োজন । এখানে প্যারামিটারগুলি মেস deltaV/ সেকেন্ডে রয়েছে (দ্রষ্টব্য যে আপাতত ত্বরণ তাত্ক্ষণিক), motionDirectionডেল্টা ডিগ্রি-তে দিকনির্দেশনা (বর্তমান অবস্থান থেকে বস্তুর চারপাশে ৩ degree০ ডিগ্রি বৃত্তটি কল্পনা করুন, সুতরাং দিকটি সেই বৃত্তের একটি বিন্দু) এবং অবশেষে প্যারামিটারটি timeকত সেকেন্ডে হয় অবজেক্টটির ডেল্টাভি পুশ ট্র্যাজেক্টোরির পরে পর্যবেক্ষণ করা হবে। পরবর্তীের giveMotion()শেষের অবস্থান থেকে পরবর্তী শুরুটি বন্ধ giveMotion()

প্রশ্নাবলী:

  1. কক্ষপথ গণনা করার জন্য এটি কি বৈধ অ্যালগরিদম?
  2. সুস্পষ্ট উন্নতিগুলি কী করা উচিত?
  3. আমি "টাইমস্কেল" ভেরিয়েবলটি বিবেচনা করছি যা গণনাগুলি অনুকূল করে তুলবে, কারণ প্রতি সেকেন্ডের জন্য ভেক্টর এবং অবস্থানগুলি পুনরায় গণনা করা প্রয়োজন হতে পারে না। কীভাবে এটি কার্যকর করা উচিত সে সম্পর্কে কোনও ধারণা বা এটি সাধারণত একটি ভাল ধারণা? (উন্নত পারফরম্যান্সের তুলনায় নির্ভুলতার ক্ষতি)

মূলত আমার উদ্দেশ্য বিষয়টির উপর একটি আলোচনা শুরু করা এবং এটি কোথায় নিয়ে যায় তা দেখতে। এবং, যদি সম্ভব হয় তবে নতুন এবং আকর্ষণীয় কিছু শিখুন (বা আরও ভাল - শেখানো)।

নিখরচায় পরীক্ষায়!

ব্যবহার করার চেষ্টা করুন:

Earth = Object(name="Earth", position=(50.0, 100.0), radius=6.371, mass=5.972e24)
Moon = Object(name="Moon", position=(434.0, 100.0), radius=1.737, mass = 7.347e22)
Craft = Object(name="SpaceCraft", position=(43.0, 100.0), radius=1, mass=1.0e4)

Craft.giveMotion(deltaV=10575.0, motionDirection=180, time=322000)
Craft.giveMotion(deltaV=400.0, motionDirection=180, time=50000)

দুটি পোড়া দিয়ে - একটি পৃথিবীর কক্ষপথে অগ্রসর এবং একটি চাঁদ কক্ষপথে একটি প্রত্যাহার আমি স্থির চাঁদ কক্ষপথ অর্জন। এগুলি কি তাত্ত্বিক প্রত্যাশিত মানগুলির কাছাকাছি?

প্রস্তাবিত অনুশীলন: 3 বার্নে এটি ব্যবহার করে দেখুন - পৃথিবী পৃষ্ঠ থেকে স্থিতিশীল পৃথিবী কক্ষপথ, চাঁদে পৌঁছতে অগ্রগতি বার্ন, চাঁদের চারপাশে কক্ষপথ স্থিতিশীল করতে প্রত্যাবর্তন বার্ন। তারপরে ডেল্টাভি কমানোর চেষ্টা করুন।

দ্রষ্টব্য: আমি পাইথন 3 সিনট্যাক্সের সাথে পরিচিত না তাদের পক্ষে বিস্তৃত মন্তব্য সহ কোডটি আপডেট করার পরিকল্পনা করছি।


স্ব-শিক্ষার জন্য খুব ভাল ধারণা! আমরা যারা পাইথন সিনট্যাক্সের সাথে পরিচিত নই তাদের জন্য আপনার সূত্রগুলি সংক্ষিপ্ত করা কি সম্ভব হবে?

আমার অনুমান নিশ্চিত. আমি তাদের মধ্যে কোডটিতে আরও বিস্তৃত মন্তব্য করব যাঁরা এটিকে বাছাই করতে চান এবং প্রশ্নটিতেই সাধারণ যুক্তিটির সংক্ষিপ্তসার করতে চান।
স্টেটস স্পেস 21

আমার মাথার শীর্ষটি বন্ধ করুন: গতি এবং দিককে আলাদাভাবে চিকিত্সার পরিবর্তে বেগের জন্য ভেক্টর ব্যবহারের কথা বিবেচনা করুন। আপনি যেখানে "এফ = এম * ভি" বলছেন আপনার অর্থ "এফ = মি * এ"? আপনি ধরে নিচ্ছেন যে পৃথিবী নড়াচড়া করছে না কারণ এটি গ্রহাণু থেকে অনেক বেশি ভারী? দিকে তাকিয়ে কথা বিবেচনা করুন github.com/barrycarter/bcapps/blob/master/bc-grav-sim.pl
barrycarter

আপনি পৃথিবী সহ যে কোনও বস্তুকে গতি দিতে পারেন। পরীক্ষার উদ্দেশ্যে আমি কেবল লুপে -> আর্থ সম্পর্কটি অন্তর্ভুক্ত করি। এটি সহজে রূপান্তরিত হতে পারে যে প্রতিটি বস্তু অন্য যে সমস্ত বস্তু তৈরি হয়েছিল তার সাথে সম্পর্কিত। এবং প্রতিটি বস্তুর নিজস্ব গতি ভেক্টর থাকতে পারে। আমি কেন এটি করিনি কেন কারণ - 1 টি বস্তুর জন্য এমনকি খুব ধীর গণনা। আমি আশা করি স্কেলিং টাইম ইউনিটগুলি অনেকটা সহায়তা করতে পারে তবে কীভাবে এটি সঠিকভাবে করবেন তা আমি এখনও নিশ্চিত নই।
স্টেটস্পেস

1
ঠিক আছে. একটি চিন্তা: দুটি বাস্তব বস্তুর (যেমন, পৃথিবী / চাঁদ বা পৃথিবী / সূর্যের) সিমুলেশন করবেন এবং আপনার ফলাফলকে নির্ভুলতার জন্য ssd.jpl.nasa.gov/?horizons এর সাথে তুলনা করুন ? অন্যান্য উত্সগুলি দ্বারা বিবিধ কারণে এটি নিখুঁত হবে না, তবে এটি আপনাকে সঠিকতার কিছু ধারণা দেবে?
ব্যারিকার্টার

উত্তর:


11

m1,m2

F=ma
a

F21=Gm1m2|r21|3r21

r21F12=F21r12=r21(x1,y1)(x2,y2)

r21=(x1x2y1y2).

এবং

|r|=(x1x2)2+(y1y2)2.
a=F/m

x1(t)=Gm2(x2x1)|r|3y1(t)=Gm2(y2y1)|r|3x2(t)=Gm1(x1x2)|r|3y2(t)=Gm1(y1y2)|r|3.

প্রাথমিক অবস্থান এবং বেগের সাথে একসাথে সাধারণ ডিফারেনশিয়াল সমীকরণের এই পদ্ধতিতে (ওডিইএস) একটি প্রাথমিক মান সমস্যা থাকে। সাধারণ পদ্ধতির মধ্যে এটি 8 টি সমীকরণের প্রথম-ক্রম সিস্টেম হিসাবে লেখা এবং সেগুলি সমাধান করার জন্য একটি রানজে-কত্তা বা মাল্টিস্টেপ পদ্ধতি প্রয়োগ করা হয়।

আপনি যদি ফরওয়ার্ড অয়লার বা পশ্চাৎপদ অলারের মতো সাধারণ কিছু প্রয়োগ করেন তবে আপনি পৃথিবীটিকে অনন্ত বা সূর্যের দিকে যথাক্রমে সর্পিল দেখতে পাবেন, তবে এটি সংখ্যাসূচক ত্রুটির প্রভাব। ধ্রুপদী ৪ র্থ অর্ডার রঞ্জ-কোট্টা পদ্ধতির মতো আপনি যদি আরও সঠিক পদ্ধতি ব্যবহার করেন তবে আপনি দেখতে পাবেন এটি কিছুক্ষণের জন্য সত্য কক্ষপথের কাছাকাছি থাকলেও অবশেষে অনন্তের দিকে চলে যায়। সঠিক পন্থাটি হচ্ছে একটি সিম্প্লেটিক পদ্ধতি ব্যবহার করা, যা পৃথিবীকে সঠিক কক্ষপথে রাখবে - যদিও এটির সংখ্যাটি ত্রুটির কারণে এখনও বন্ধ থাকবে।

2-শারীরিক সমস্যার জন্য আপনার স্থানাঙ্কিতব্যবস্থাকে ভর কেন্দ্রে আশেপাশে একটি সহজ সিস্টেম তৈরি করা সম্ভব। তবে আমি মনে করি এটি যদি আপনার কাছে নতুন হয় তবে উপরের সূত্রটি আরও স্পষ্ট।


এটি হজম হতে কিছুটা সময় নেবে।
30:30

এখনও হজম করছে। আমার কাছে অনেক অজানা শব্দ তবে একরকম আমি অনুভব করছি যে কোনও একসময় আমি সেখানে পৌঁছে যাব। জিনিসগুলির জন্য কেবল কাজ করার জন্য এখন আমার নিজস্ব অ্যালগরিদম যথেষ্ট ভাল। তবে যখন আমি যুগপত গতিতে প্লাগ করব - আমাকে সাহিত্যে উঠতে এবং সঠিক অ্যালগরিদমগুলি পড়তে বাধ্য করা হবে। আধুনিক হার্ডওয়্যারটির সীমাবদ্ধতাগুলি অনেক লঘুযুক্ত হওয়ায় এটিকে আমি সাধারণ সমীকরণের সাথে বোকা বানাতে পারি। ভীত যদিও দীর্ঘ সময়ের জন্য না।
স্টেটস্পেস

প্রকৃতপক্ষে সিম্পিলিক পদ্ধতিগুলি সবচেয়ে সঠিক, তবে আমি মনে করি যে বিজ্ঞানের কোনও পটভূমি নেই তাদের বাস্তবায়ন করা কঠিন implement পরিবর্তে আপনি ফেনম্যান সংশোধনের পাশাপাশি খুব সাধারণ ইউলার পদ্ধতি ব্যবহার করতে পারেন। আমি মনে করি না যে স্ব-শিক্ষার উদ্দেশ্যে আপনার চেয়ে আরও জটিল কিছু দরকার।
ক্রিশপাপ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.