adapted all potential to new scheme + necessary mods to main code
[physik/posic.git] / potentials / harmonic_oscillator.c
1 /*
2  * harmonic_oscillator.c - harmonic oscillator potential
3  *
4  * author: Frank Zirkelbach <frank.zirkelbach@physik.uni-augsburg.de>
5  *
6  */
7
8 #define _GNU_SOURCE
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <fcntl.h>
15 #include <unistd.h>
16 #include <math.h>
17
18 #include "../moldyn.h"
19 #include "../math/math.h"
20 #include "harmonic_oscillator.h"
21
22 int harmonic_oscillator_set_params(t_moldyn *moldyn,int element) {
23
24         t_ho_params *p;
25
26         // set cutoff before parameters (actually only necessary for some pots)
27         if(moldyn->cutoff==0.0) {
28                 printf("[harmonic oscillator] WARNING: no cutoff!\n");
29                 return -1;
30         }
31
32         /* alloc mem for potential parameters */
33         moldyn->pot_params=malloc(sizeof(t_ho_params));
34         if(moldyn->pot_params==NULL) {
35                 perror("[harmonic oscillator] pot params alloc");
36                 return -1;
37         }
38
39         /* these are now ho parameters */
40         p=moldyn->pot_params;
41
42         switch(element) {
43                 case SI:
44                         /* type: silicon */
45                         p->spring_constant=HO_SC_SI;
46                         p->equilibrium_distance=HO_ED_SI;
47                         break;
48                 case C:
49                         /* type: carbon */
50                         p->spring_constant=HO_SC_C;
51                         p->equilibrium_distance=HO_ED_C;
52                         break;
53                 default:
54                         printf("[harmonic oscillator] WARNING: element\n");
55                         return -1;
56         }
57
58
59         return 0;
60 }
61
62 int harmonic_oscillator(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) {
63
64         t_ho_params *params;
65         t_3dvec force,distance;
66         double d,f;
67         double sc,equi_dist;
68         double energy;
69
70         params=moldyn->pot_params;
71         sc=params->spring_constant;
72         equi_dist=params->equilibrium_distance;
73
74         if(ai<aj) return 0;
75
76         v3_sub(&distance,&(aj->r),&(ai->r));
77
78         if(bc) check_per_bound(moldyn,&distance);
79         d=v3_norm(&distance);
80         if(d<=moldyn->cutoff) {
81                 energy=(0.5*sc*(d-equi_dist)*(d-equi_dist));
82                 moldyn->energy+=energy;
83                 ai->e+=0.5*energy;
84                 aj->e+=0.5*energy;
85                 /* f = -grad E; grad r_ij = -1 1/r_ij distance */
86                 f=sc*(1.0-equi_dist/d);
87                 v3_scale(&force,&distance,f);
88                 v3_add(&(ai->f),&(ai->f),&force);
89                 virial_calc(ai,&force,&distance);
90                 virial_calc(aj,&force,&distance); /* f and d signe switched */
91                 v3_scale(&force,&distance,-f);
92                 v3_add(&(aj->f),&(aj->f),&force);
93         }
94
95         return 0;
96 }
97
98 int harmonic_oscillator_check_2b_bond(t_moldyn *moldyn,
99                                       t_atom *ai,t_atom *aj,u8 bc) {
100
101         t_3dvec distance;
102         double d;
103
104         v3_sub(&distance,&(aj->r),&(ai->r));
105         if(bc) check_per_bound(moldyn,&distance);
106         d=v3_norm(&distance);
107
108         if(d>moldyn->cutoff)
109                 return FALSE;
110
111         return TRUE;
112 }
113