Skip to content

Commit dec431e

Browse files
Initial commit.
Simple simulation using the verlet integration with electrostatic non-bound potentials
0 parents  commit dec431e

File tree

11 files changed

+308
-0
lines changed

11 files changed

+308
-0
lines changed

LICENSE

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Copyright (c) <year>, <copyright holder>
2+
All rights reserved.
3+
4+
Redistribution and use in source and binary forms, with or without
5+
modification, are permitted provided that the following conditions are met:
6+
7+
1. Redistributions of source code must retain the above copyright notice, this
8+
list of conditions and the following disclaimer.
9+
2. Redistributions in binary form must reproduce the above copyright notice,
10+
this list of conditions and the following disclaimer in the documentation
11+
and/or other materials provided with the distribution.
12+
13+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23+
24+
The views and conclusions contained in the software and documentation are those
25+
of the authors and should not be interpreted as representing official policies,
26+
either expressed or implied, of the FreeBSD Project.

Makefile

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# $@ = target file
2+
# $< = first dependency
3+
# $^ = all dependencies
4+
#
5+
C_SOURCES = $(wildcard Physics/*.c *.c)
6+
C_HEADERS = $(wildcard Physics/*.h *.h)
7+
C_OBJECTS = ${C_SOURCES:.c=.o}
8+
9+
CC = gcc
10+
CFLAGS=-lm
11+
12+
# FIRST RULE IS RUN BY DEFAULT
13+
build: ${C_OBJECTS}
14+
${CC} -o $@ $^ ${CFLAGS}
15+
16+
%.o: %.c ${C_HEADERS}
17+
${CC} -c $< -o $@
18+
19+
clean:
20+
rm -rf ${C_OBJECTS} build
21+
22+
backup:
23+
cp -r ./ $(shell pwd)_bak
24+
25+
.PHONY: backup clean

Physics/Differentiation.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#include "Differentiation.h"
2+
3+
Particle** copyPpp(int n, Particle** p) {
4+
Particle** copy = (Particle**)malloc(sizeof(Particle*) * n);
5+
for(int i = 0; i < n; i++) {
6+
copy[i] = malloc(sizeof(Particle));
7+
copy[i] = copy_particle(p[i]);
8+
}
9+
return copy;
10+
}
11+
12+
void clonePpp(int n, Particle** src, Particle** dest) {
13+
for(int i = 0; i < n; i++) {
14+
for(int j = 0; j < DIM; j++) {
15+
dest[i]->pos[j] = src[i]->pos[j];
16+
dest[i]->vel[j] = src[i]->vel[j];
17+
}
18+
dest[i]->m = src[i]->m;
19+
dest[i]->q = src[i]->q;
20+
}
21+
}
22+
23+
void freePpp(int n, Particle** p) {
24+
for(int i = 0; i < n; i++) {
25+
free_particle(p[i]);
26+
}
27+
free(p);
28+
}
29+
30+
double* particle_force(int n, Particle** fin, int j, double (*potential)(int, Particle**, int)) {
31+
double* returnSlope = calloc(DIM, sizeof(double));
32+
for(int i = 0; i < n; i++) {
33+
if(j != i) {
34+
for(int k = 0; k < DIM; k++) {
35+
Particle** pCopyUp = copyPpp(n, fin);
36+
Particle** pCopyDown = copyPpp(n, fin);
37+
pCopyUp[i]->pos[k] += DERIV_STEP;
38+
pCopyDown[i]->pos[k] -= DERIV_STEP;
39+
double high = potential(n, pCopyUp, j);
40+
double low = potential(n, pCopyDown, j);
41+
freePpp(n, pCopyUp);
42+
freePpp(n, pCopyDown);
43+
returnSlope[k] += (high - low) / (2 * DERIV_STEP);
44+
}
45+
}
46+
}
47+
return returnSlope;
48+
}

Physics/Differentiation.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#ifndef DIFFERENTIATION_H
2+
#define DIFFERENTIATION_H
3+
4+
#include <stdlib.h>
5+
#include <math.h>
6+
#include "Particle.h"
7+
8+
#define DERIV_STEP 0.0000001
9+
10+
double* particle_force(int, Particle**, int, double (*potential)(int, Particle**, int));
11+
12+
Particle** copyPpp(int n, Particle** p);
13+
14+
void clonePpp(int n, Particle** src, Particle** dest);
15+
16+
void freePpp(int n, Particle** p);
17+
18+
#endif

Physics/Particle.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include "Particle.h"
2+
3+
Particle* make_particle_at(int n, double* pos) {
4+
Particle* p = malloc(sizeof(Particle));
5+
for(int i = 0; i < n; i++) {
6+
if(i < DIM) {
7+
p->pos[i] = pos[i];
8+
p->vel[i] = 0;
9+
}
10+
}
11+
p->m = 1;
12+
p->q = 1;
13+
return p;
14+
}
15+
16+
Particle* copy_particle(Particle* p) {
17+
Particle* copy = malloc(sizeof(Particle));
18+
for(int i = 0; i < DIM; i++) {
19+
copy->pos[i] = p->pos[i];
20+
copy->vel[i] = p->vel[i];
21+
}
22+
copy->m = p->m;
23+
copy->q = p->q;
24+
return copy;
25+
}
26+
27+
void free_particle(Particle* p) {
28+
free(p);
29+
}

Physics/Particle.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#ifndef PARTICLE_H
2+
#define PARTICLE_H
3+
4+
#include <stdlib.h>
5+
6+
#define DIM 3
7+
8+
typedef struct {
9+
double pos[DIM];
10+
double vel[DIM];
11+
double m, q;
12+
} Particle;
13+
14+
Particle* make_particle_at(int, double*);
15+
16+
Particle* copy_particle(Particle*);
17+
18+
void free_particle(Particle*);
19+
20+
#endif

Physics/Potentials.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include "Potentials.h"
2+
3+
double electrostaticPotential(int n, Particle** ps, int j) {
4+
double retPot = 0;
5+
for(int i = 0; i < n; i++) {
6+
if(i != j) {
7+
double rs = 0;
8+
for(int k = 0; k < DIM; k++) {
9+
rs += pow(ps[i]->pos[k] - ps[j]->pos[k], 2);
10+
}
11+
rs = sqrt(rs);
12+
retPot += ps[i]->q * ps[j]->q * 9e9 / rs;
13+
}
14+
}
15+
return retPot;
16+
}

Physics/Potentials.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#ifndef POTENTIALS_C
2+
#define POTENTIALS_C
3+
4+
#include <math.h>
5+
#include "Particle.h"
6+
7+
double electrostaticPotential(int n, Particle** ps, int j);
8+
9+
#endif

Physics/Verlet.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#include "Verlet.h"
2+
3+
Particle* next_position(int n, Particle** prev, Particle** current, int i, int nf, double (*potential[])(int, Particle**, int)) {
4+
Particle* next = copy_particle(current[i]);
5+
// From the verlet algorithm - first terms for the next position
6+
for(int k = 0; k < DIM; k++) {
7+
next->pos[k] = 2 * current[i]->pos[k] - prev[i]->pos[k];
8+
}
9+
// Calculate the forces
10+
for(int j = 0; j < n; j++) {
11+
if(i != j) {
12+
for(int k = 0; k < nf; k++) {
13+
double* force = particle_force(n, current, i, potential[k]);
14+
for(int m = 0; m < DIM; m++) {
15+
next->pos[m] += force[m] / next->m * DT * DT;
16+
}
17+
free(force);
18+
}
19+
}
20+
}
21+
return next;
22+
}
23+
24+
Particle* next_velocity(int n, Particle** prev, Particle** next, int i) {
25+
Particle* updated = copy_particle(next[i]);
26+
for(int k = 0; k < DIM; k++) {
27+
updated->vel[k] = (1 / (2.0 * DT)) * (updated->pos[k] - prev[i]->pos[k]);
28+
}
29+
return updated;
30+
}
31+
32+
void next_step(int n, Particle** prev, Particle** current, Particle** next, int nf, double (*potentials[])(int, Particle**, int)) {
33+
Particle** next_p = (Particle**)malloc(sizeof(Particle*) * n);
34+
for(int i = 0; i < n; i++) {
35+
next_p[i] = next_position(n, prev, current, i, nf, potentials);
36+
}
37+
for(int i = 0; i < n; i++) {
38+
next[i] = next_velocity(n, prev, next_p, i);
39+
}
40+
for(int i = 0; i < n; i++) {
41+
free_particle(next_p[i]);
42+
}
43+
free(next_p);
44+
}

Physics/Verlet.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#ifndef VERLET_H
2+
#define VERLET_H
3+
4+
#include <math.h>
5+
#include <stdlib.h>
6+
#include "Particle.h"
7+
#include "Differentiation.h"
8+
9+
#define DT 0.00001
10+
11+
Particle* next_position(int n, Particle** prev, Particle** current, int i, int nf, double (*potential[])(int, Particle**, int));
12+
13+
Particle* next_velocity(int n, Particle** prev, Particle** next, int i);
14+
15+
void next_step(int n, Particle** prev, Particle** current, Particle** next, int nf, double (*potential[])(int, Particle**, int));
16+
17+
#endif

main.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#include <stdio.h>
2+
#include <math.h>
3+
#include "Physics/Differentiation.h"
4+
#include "Physics/Particle.h"
5+
#include "Physics/Verlet.h"
6+
#include "Physics/Potentials.h"
7+
8+
double mean_dist(int n, Particle** ps) {
9+
double mean = 0;
10+
for(int i = 0; i < n; i++) {
11+
for(int j = i+1; j < n; j++) {
12+
double rs = 0;
13+
for(int k = 0; k < DIM; k++) {
14+
rs += pow(ps[i]->pos[k]-ps[j]->pos[k], 2);
15+
}
16+
rs = sqrt(rs);
17+
mean += rs;
18+
}
19+
}
20+
return mean;
21+
}
22+
23+
int main(int argc, const char* argv[]) {
24+
printf("Booting up a simple simulation that only considers the non-bonded electrostatic potential\n");
25+
int MAX_STEP = 10;
26+
double (*pf[1])(int, Particle**, int);
27+
pf[0] = electrostaticPotential;
28+
double pos[] = { 0, 0, 0 };
29+
int len = 2;
30+
Particle* p1 = make_particle_at(3, pos);
31+
p1->q = -1;
32+
pos[0] = 2;
33+
Particle* p2 = make_particle_at(3, pos);
34+
Particle* rs[] = { p1, p2 };
35+
36+
Particle** prev = copyPpp(len, rs);
37+
Particle** current = copyPpp(len, rs);
38+
Particle** next = copyPpp(len, rs);
39+
for(int step = 0; step < MAX_STEP; step++) {
40+
for(int i = 0; i < len; i++) {
41+
printf("%i's position is now: (%f, %f, %f)\n", i, next[i]->pos[0], next[i]->pos[1], next[i]->pos[2]);
42+
printf("%i's velocity is now: (%f, %f, %f)\n", i, next[i]->vel[0], next[i]->vel[1], next[i]->vel[2]);
43+
}
44+
printf("Mean distance is: %f\n", mean_dist(len, next));
45+
clonePpp(len, current, prev);
46+
clonePpp(len, next, current);
47+
next_step(len, prev, current, next, 1, pf);
48+
}
49+
freePpp(len, next);
50+
freePpp(len, current);
51+
freePpp(len, prev);
52+
for(int i = 0; i < len; i++) {
53+
free_particle(rs[i]);
54+
}
55+
return 0;
56+
}

0 commit comments

Comments
 (0)