-
Jan Thorbecke authoredJan Thorbecke authored
roughint.c 2.28 KiB
#include <math.h>
#include <time.h>
#include <genfft.h>
#include <stdlib.h>
#define NINT(x) ((int)((x)>0.0?(x)+0.5:(x)-0.5))
#define SGN(x) ((x) < 0 ? -1.0 : 1.0)
/**
* compute rough shaped interface used in makemod
*
* AUTHOR:
* Jan Thorbecke (janth@xs4all.nl)
* The Netherlands
**/
#ifndef COMPLEX
typedef struct _complexStruct { /* complex number */
float r,i;
} complex;
#endif/* complex */
void statics(float *array, int n, float *mean, float *std);
int npfa (int nmin);
int npfar (int nmin);
void pfacc (int isign, int n, complex z[]);
void pfarc (int isign, int n, float rz[], complex cz[]);
void roughint(int *zp, int minx, int maxx, float dz, float *interface, float ampl, float beta, float seed)
{
int j, i, ndeltx, optn;
long idum;
float *fract;
float dk, mean, std;
complex *fracc, *fracc2;
ndeltx = maxx - minx + 1;
optn = npfar(npfa(ndeltx));
fract = (float *)malloc(optn*sizeof(float));
fracc = (complex *)malloc((optn/2+1)*sizeof(complex));
fracc2 = (complex *)malloc(optn*sizeof(complex));
/*
srandom(seed);
fact = 1.0/(float)pow(2.0, 31.0);
for (j = 0; j < optn; j++) fract[j] = (float)random()*fact;
*/
idum = (long) seed;
srand48(idum);
for (j = 0; j < optn; j++) {
fract[j] = (float)drand48();
}
pfarc(-1, optn, fract, fracc);
dk = 1.0/(float)optn;
for (j = 1; j < optn/2+1; j++) {
fracc2[j].r = fracc[j].r*pow(j*dk, -beta/2.0);
fracc2[j].i = fracc[j].i*pow(j*dk, -beta/2.0);
}
for (j = optn/2+2; j < optn; j++) {
fracc2[j].r = fracc[optn-j].r;
fracc2[j].i = -1.0*fracc[optn-j].i;
}
fracc2[0].r = 0.0;
fracc2[0].i = 0.0;
pfacc(1, optn, fracc2);
for (j = 0; j < optn; j++) fract[j] = fracc2[j].r;
statics(fract, optn, &mean, &std);
for (j = 0; j < optn; j++) fract[j] -= mean;
dk = ampl/(2*std);
for (j = 0; j < optn; j++) fract[j] *= dk;
j = 0;
for (i = minx; i < maxx; i++) {
interface[i] += fract[j];
zp[i] = NINT(interface[i]/dz);
j++;
if (SGN(zp[i]) < 0) {zp[i] = 0;}
}
free(fract);
free(fracc);
free(fracc2);
return;
}
void statics(float *array, int n, float *mean, float *std)
{
int i;
*mean = 0;
*std = 0;
for(i = 0; i < n; i++) *mean += array[i];
*mean = *mean/(float)n;
for(i = 0; i < n; i++) *std += pow((array[i]-*mean), 2.0);
*std = sqrt(*std/((float)(n-1)));
return;
}