수실잡
공부는 저희 친구들이 잘해요
수실잡
전체 방문자
오늘
어제

블로그 메뉴

  • 🏠블로그 홈
  • 💭태그 클라우드
  • 📬방명록
  • 🛠️블로그 관리
  • 📝글 쓰러 가기
  • 분류 전체보기 (127)
    • 교양(학문의 기초) (22)
      • 미적분학 (1)
      • 물리 (1)
      • 화학 (1)
      • 생물 (0)
      • 통계 (0)
      • 공학수학 (19)
    • 프로그래밍 언어 (2)
      • C (0)
      • C++ (0)
      • Java (0)
      • Python (2)
      • MATLAB (0)
      • R (0)
      • Julia (0)
    • 수학 (35)
      • 집합론 (Set Theory) (19)
      • 해석개론 (9)
      • 해석개론의 정수 (1)
      • 선형대수학 (1)
      • 미분방정식 (0)
      • 실해석학 (0)
      • 복소해석학 (0)
      • 대수학 (0)
      • 위상수학 (0)
      • 미분기하학 (0)
      • 응용수학 (0)
      • 확률론 (5)
    • 물리학 (32)
      • 물리수학 (3)
      • 역학 (9)
      • 전자기학 (13)
      • 양자물리 (0)
      • 열역학과 통계물리 (5)
      • 전자기파와 광학 (0)
      • 응집물질물리학 (2)
      • 논문 리뷰 (0)
    • 화학 (16)
      • 물리화학 (11)
      • 분석화학 (1)
      • 유기화학 (1)
      • 무기화학 (0)
      • 생화학 (3)
      • 고분자화학 (0)
      • 화학실험 (0)
      • 논문 리뷰 (0)
    • 재료공학 (1)
      • 재료공학원리 (0)
      • 재료열역학 (0)
      • 결정학개론 (0)
      • 재료상변태 (0)
      • 재료의 기계적 거동 (0)
      • 재료의 전자기적 성질 (1)
      • 재료역학 (0)
      • 기타 (0)
    • 컴퓨터공학 (9)
      • 자료구조 및 알고리즘 (0)
      • 인공지능 (0)
      • 양자컴퓨터 (1)
      • 컴퓨터구조 (5)
      • 논리설계 (0)
      • 컴파일러 (0)
      • 운영체제 및 시스템프로그래밍 (1)
      • 논문 리뷰 (1)
      • 계산이론 (1)
    • 전기전자공학 (0)
      • 전기전자회로 (0)
      • 소자 (0)
      • 집적회로 (0)
      • 신호처리, 제어공학 (0)
      • 전파공학 (0)
      • 전력전자공학 (0)
    • 기계공학 (2)
      • 고체역학 (2)
      • 열역학 (0)
      • 동역학 (0)
      • 유체역학 (0)
    • 언어학 (2)
      • 음성학 (0)
      • 음운론 (0)
      • 형태론 (0)
      • 통사론 (2)
    • 기타 등등 (6)
      • 학회리뷰 (3)
      • 꿀팁 (0)
      • 역대 교양수학 성적 통계량 정리 (1)
      • 기타 등등 (2)

공지사항

인기 글

최근 글

최근 댓글

태그

  • 레닌저생화학
  • ZFC 집합론
  • 확산
  • Random walk
  • 랭크
  • Diffusion
  • 텐서
  • 선형변환
  • Physical Chemistry
  • 공학수학
  • 일차독립
  • 벡터공간
  • 앳킨스 물리화학
  • 레닌저 생화학
  • 선형대수
  • Atkins' Physical Chemistry
  • Thermal and statistical physics
  • 열 및 통계물리
  • 행렬식
  • 백응생
  • 물리화학
  • Athreya
  • 벡터
  • 확률론
  • 가역
  • 행렬
  • 기본행렬
  • ZFC Set Theory
  • 차원
  • 컴퓨터구조

티스토리

hELLO · Designed By 정상우.
수실잡

공부는 저희 친구들이 잘해요

정사각형 축전기의 전하 밀도를 코딩으로 구해보자!-1
물리학/전자기학

정사각형 축전기의 전하 밀도를 코딩으로 구해보자!-1

By 서울대의 감자
2022. 8. 4. 09:35
Language

이 글은 언어로 작성되어 있습니다.
익숙하신 언어를 선택하십시오.

This post is written in Language.
Select the language you prefer.

この文は言語で作成されています。
使用する言語を選択してください。


안녕하세요! 서울대감자입니다.

그동안 선형대수학의 기초라는 딱딱한 주제의 글만 10개 넘게 썼는데요,

이번에는 색다른 컨텐츠를 준비해봤습니다.

 

우리는 축전기를 어떻게 배웠나요? 아마 대부분 극판의 넓이가 극판 사이의 감격보다 매우 크다면 전하가 거의 고르게 분포하게 된다고 베웠을 것입니다. 하지만 여기서 의문이 생기지 않나요? 그러면 정확히 어떤 분포를 띠는지.

그래서 이번 글에서는 제목에서도 알 수 있듯이

 

정사각형 축전기의 전하 밀도를 코딩으로 구해보자!

라는 주제를 가지고 왔습니다. 이 주제로는 총 2개의 글을 쓸 예정이며, 이번 글에서는 코딩 아이디어와, 이 코드가 실제로 결과를 어떻게 내는지 살펴보겠습니다. 사용 언어는 C++입니다.

 

1. 아이디어

(1단계) 먼저 정사각형 금속판 2개를 $\texttt{size} \times \texttt{size}$ 격자로 나눠주고 하나의 판에는 모든 격자에 동일한 전하 $\texttt{1}$, 나머지 판에는 모든 격자에 동일한 전하 $\texttt{-1}$만큼 체워줍시다. 그리고 두께 $\texttt{thickness}$를 지정합니다.

 

(2단계) 각각의 그리드의 면전하가 받는 전기력의 크기를 계산합니다.

$$\mathbf{F} = \frac{1}{4 \pi \epsilon_0} \frac{q_1q_2}{r^2}\hat{\mathbf{r}}$$

에서 편의를 위해 상수항 $\dfrac{1}{4 \pi \epsilon_0}$은 무시합니다.

 

(3단계) 2단계에서 전하에 작용하는 힘을 구했으니 이제는 그 전기력에 따라 전하를 움직여야 합니다. 전하를 움직이는 규칙은 다음과 같이 합시다.

  • 전하가 판을 빠져나가지 않습니다.
  • $\texttt{[i][j]}$에 있는 전하가 받는 힘의 $\texttt{x}$축 방향 성분 $\texttt{F_x}$가 양수면 $\texttt{[i+1][j]}$로 전하가 $\texttt{F_x}$에 비례하는 만큼 이동하고, $\texttt{F_x}$가 음수면 $\texttt{[i-1][j]}$로 전하가 $\texttt{-F_x}$에 비례하는 만큼 이동한다.
  • $\texttt{[i][j]}$에 있는 전하가 받는 힘의 $\texttt{y}$축 방향 성분 $\texttt{F_y}$가 양수면 $\texttt{[i][j+1]}$로 전하가 $\texttt{F_y}$에 비례하는 만큼 이동하고, $\texttt{F_y}$가 음수면 $\texttt{[i][j-1]}$로 전하가 $\texttt{-F_y}$에 비례하는 만큼 이동한다.

 

(4단계) 2단계와 3단계를 반복하는 $\texttt{for}$문을 짭니다.

 

(5단계) 텍스트 파일에 전하량 정보를 출력합니다.

 

1단계부터 5단계를 모두 반영한 코드는 다음과 같습니다.

#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;

int signal(double a) {
	if (a > 0) return 1;
	if (a == 0) return 0;
	if (a < 0) return -1;
}
// 3단계

int main() {
	const int size = 30;
   	double thickness = 10;
	double plane1[size][size];
	double plane2[size][size];
	double temp_plane1[size][size];
	double temp_plane2[size][size];
    for (int i = 0; i < size; i++) {
		for (int j = 0; j < size; j++) {
			plane1[i][j] = 1;
			plane2[i][j] = -1;
			temp_plane1[i][j] = 1;
			temp_plane2[i][j] = -1;
		}
	}
    // 1단계
    
    const double ratio = 0.01; // 3단계
    
    int final_time = 1000; // 4단계
    
    // This line is intentionally left blank. - (1)

	for (int time = 0; time < final_time; time++) {
		//plane1
		for (int i = 0; i < size; i++) {
			for (int j = 0; j < size; j++) {
				double F_x = 0;
				double F_y = 0;
				//plane1 and plane2
				for (int i1 = 0; i1 < size; i1++) {
					for (int j1 = 0; j1 < size; j1++) {
						double distance = sqrt(pow((i - i1), 2) + pow((j - j1), 2) + pow(thickness, 2));
						F_x -= plane1[i][j] * plane2[i1][j1] * (i1 - i) / pow(distance, 3);
						F_y -= plane1[i][j] * plane2[i1][j1] * (j1 - j) / pow(distance, 3);
						temp_F_z += plane1[i][j] * plane2[i1][j1] * thickness / pow(distance, 3);
					}
				}
				//plane1 and plane1
				for (int i1 = 0; i1 < size; i1++) {
					for (int j1 = 0; j1 < size; j1++) {
						double distance = sqrt(pow((i - i1), 2) + pow((j - j1), 2));
						if (distance != 0) {
							F_x -= plane1[i][j] * plane1[i1][j1] * (i1 - i) / pow(distance, 3);
							F_y -= plane1[i][j] * plane1[i1][j1] * (j1 - j) / pow(distance, 3);
						}
					}
				}
                // 2단계
                
				double moved_charge = 0;
				bool x_exist = false;
				bool y_exist = false;
				if ((i + signal(F_x)) < size && (i + signal(F_x)) > -1) x_exist = true;
				if ((j + signal(F_y)) < size && (j + signal(F_y)) > -1) y_exist = true;

				temp_plane1[i + x_exist * signal(F_x)][j] += x_exist * fabs(F_x) * ratio;
				moved_charge += x_exist * fabs(F_x) * ratio;

				temp_plane1[i][j + y_exist * signal(F_y)] += y_exist * fabs(F_y) * ratio;
				moved_charge += y_exist * fabs(F_y) * ratio;

				temp_plane1[i][j] -= moved_charge;
                // 3단계
                
                // This line is intentionally left blank. - (2)
			}
		}
		//plane2
		for (int i = 0; i < size; i++) {
			for (int j = 0; j < size; j++) {
				double F_x = 0;
				double F_y = 0;
				//plane2 and plane1
				for (int i1 = 0; i1 < size; i1++) {
					for (int j1 = 0; j1 < size; j1++) {
						double distance = sqrt(pow((i - i1), 2) + pow((j - j1), 2) + pow(thickness, 2));
						F_x -= plane2[i][j] * plane1[i1][j1] * (i1 - i) / pow(distance, 3);
						F_y -= plane2[i][j] * plane1[i1][j1] * (j1 - j) / pow(distance, 3);
					}
				}
				//plane2 and plane2
				for (int i1 = 0; i1 < size; i1++) {
					for (int j1 = 0; j1 < size; j1++) {
						double distance = sqrt(pow((i - i1), 2) + pow((j - j1), 2));
						if (distance != 0) {
							F_x -= plane2[i][j] * plane2[i1][j1] * (i1 - i) / pow(distance, 3);
							F_y -= plane2[i][j] * plane2[i1][j1] * (j1 - j) / pow(distance, 3);
						}
					}
				}
                // 2단계
                
				double moved_charge = 0;
				bool x_exist = false;
				bool y_exist = false;
				if ((i + signal(F_x)) < size && (i + signal(F_x)) > -1) x_exist = true;
				if ((j + signal(F_y)) < size && (j + signal(F_y)) > -1) y_exist = true;

				temp_plane2[i + x_exist * signal(F_x)][j] -= x_exist * fabs(F_x) * ratio;
				moved_charge -= x_exist * fabs(F_x) * ratio;

				temp_plane2[i][j + y_exist * signal(F_y)] -= y_exist * fabs(F_y) * ratio;
				moved_charge -= y_exist * fabs(F_y) * ratio;

				temp_plane2[i][j] -= moved_charge;
                // 3단계
			}
		}
		
		for (int i = 0; i < size; i++) {
			for (int j = 0; j < size; j++) {
				plane1[i][j] = temp_plane1[i][j];
				plane2[i][j] = temp_plane2[i][j];
			}
		}
        // 2단계와 3단계가 모두 끝난 뒤 plane1, plane2 갱신
        
        cout << time + 1 << " "; // 진행상황 표시
	}
    // 4단계
    
    ofstream fout;
	fout.open("Conductor.txt");
	for (int i = 0; i < size; i++) {
		for (int j = 0; j < size; j++) {
			fout << plane1[i][j] << " ";
		}
		fout << "\n";
	}

	fout << "\n";
	for (int i = 0; i < size; i++) {
		for (int j = 0; j < size; j++) {
			fout << plane2[i][j] << " ";
		}
		fout << "\n";
	}
    
    // This line is intentionally left blank. - (3)

	fout.close();
    // 5단계
    
	cout << "END";
	return 0;
}

 

위 코드에서는 총 1000번 2단계와 3단계를 반복하도록 코드를 짰습니다. 그런데 의문이 하나 들지 않나요? 1000번 반복 계산하여 얻은 결과는 전하에 작용하는 힘의 크기가 충분히 0에 가깝다고 할 수 있을지요. 그렇다면 0에 충분히 가깝다의 기준은 어떻게 잡아야 할까요?

 

저는 각 그리드마다 (1000번 지난 후 전하에 작용하는 힘의 크기)/(초기 상태에서 전하에 작용하는 힘의 크기)를 구해서 가장자리를 제외한 영역에서 이 값이 0.01보다 작으면 0에 충분히 가깝다고 할 수 있다고 가정했습니다. 그래서 힘의 크기의 비율을 확인하기 위해 다음과 같은 코드를 추가하였습니다.

 

// This line is intentionally left blank. - (1)
double initial_force[size][size];
double final_force[size][size];
    
// This line is intentionally left blank. - (2)
if (time == 0) initial_force[i][j] = sqrt(pow(acc_x, 2) + pow(acc_y, 2));
if (time == final_time - 1) final_force[i][j] = sqrt(pow(acc_x, 2) + pow(acc_y, 2));
                
// This line is intentionally left blank. - (3)
fout << "\n";
for (int i = 0; i < size; i++) {
    for (int j = 0; j < size; j++) {
        if (initial_force[i][j] != 0) fout << final_force[i][j] / initial_force[i][j] << " ";
        else fout << 100 << " ";
    }
    fout << "\n";
}

 

2. 실행 결과

이제 위의 코드를 실행시켜 전하밀도를 구해봅시다.

약간 울퉁불퉁하지만 전체적으로 중심에서는 전하가 고르게 퍼져 있고, 가장자리로 갈수록 전하밀도가 급격히 증가하는 형태를 띱니다. (1000번 지난 후 전하에 작용하는 힘의 크기)/(초기 상태에서 전하에 작용하는 힘의 크기)는 다음과 같습니다.

붉게 칠한 부분이 0.01 이상인 곳인데, 붉은 영역이 매우 적어 힘의 평형이 도달했다고 판단해도 무방한 수준입니다.

 

여기서 호기심이 생겼습니다. 1500번, 2000번 반복하면 결과가 어떻게 나올까? 더 좋은 결과가 나올까? 결과는 다음과 같았습니다.

 

1500번 반복

 

2000번 반복

 

횟수가 늘어나면서 그래프가 울퉁불퉁해지고, (n번 지난 후 전하에 작용하는 힘의 크기)/(초기 상태에서 전하에 작용하는 힘의 크기)가 0.01인 곳이 늘어났습니다.

 

이유는 알 수 없지만, 두께가 10일 때는 전하에 작용하는 힘의 크기는 횟수가 늘어날 수록 줄어들다가 다시 증가하는 양상을 보였습니다. 아래 표는 가장자리를 제외한 28×28개의 그리드에서 (n번 지난 후 전하에 작용하는 힘의 크기)/(초기 상태에서 전하에 작용하는 힘의 크기)의 합을 나타낸 것입니다.

n 500 700 1000 1500 2000
$\displaystyle \sum \dfrac{F_f}{F_i}$ 25.41 7.110 2.264 3.346 4.499

 

$\displaystyle \sum \dfrac{F_f}{F_i}$가 최소가 될 때가 실제 전하밀도와 가장 유사한 시점이라고 생각할 수 있을 것입니다.

다음 시간에는 $\displaystyle \sum \dfrac{F_f}{F_i}$가 최소가 될 때까지(좀 더 정확히는 극소가 될 때까지)만 연산 과정을 반복하는 코드를 짜보겠습니다. 그리고 축전기 두께를 바꾸어 보고, 축전기 사이에 작용하는 힘의 크기를 계산하여 실제 이론과 비교해보겠습니다.

'물리학 > 전자기학' 카테고리의 다른 글

11. Epilogue  (0) 2022.08.01
10. 맥스웰 방정식, 전자기파 방사  (0) 2022.08.01
9. 전자기 유도, 자기 에너지  (0) 2022.07.31
8. 물질 속 자기장, 자기장 세기  (0) 2022.07.30
7. 자기 퍼텐셜  (0) 2022.07.28

티스토리툴바