/*
This file is part of the Snoopy code.
Snoopy code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Snoopy code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Snoopy code. If not, see .
*/
#include "snoopy.h"
#include
#include "common.h"
#include "error.h"
#include "gfft.h"
#include "symmetries.h"
#include "debug.h"
// Mask in reak space
double *mask_real;
/***********************************/
/**
Experimental Bounadry conditions call
This routine enforces a set of boundary conditions
on fldi (eg rigid boundary conditions, obstacles)
@param fldi: field stucture on which we apply the BC
************************************/
void boundary_c(struct Field fldi) {
DEBUG_START_FUNC;
symmetrize_walls_z(fldi);
DEBUG_END_FUNC;
return;
}
////////////////////////////////////////////////////////////
// The following routines are experimental /////////////////
// They allow the inclusion of a hard cylinder in the flow//
////////////////////////////////////////////////////////////
/******************************************
** init the real mask to introduce some
** object in the flow
******************************************/
void init_real_mask() {
double *x,*y,*z;
int i,j,k;
mask_real = (double *) fftw_malloc( sizeof(double complex) * NTOTAL_COMPLEX);
if (mask_real == NULL) ERROR_HANDLER( ERROR_CRITICAL, "no memory for mask_real profile allocation");
/*******************************************************************
** This part does not need to be modified **************************
********************************************************************/
// Allocate coordinate arrays
x = (double *) fftw_malloc( sizeof(double complex) * NTOTAL_COMPLEX);
if (x == NULL) ERROR_HANDLER( ERROR_CRITICAL, "No memory for x allocation");
y = (double *) fftw_malloc( sizeof(double complex) * NTOTAL_COMPLEX);
if (y == NULL) ERROR_HANDLER( ERROR_CRITICAL, "No memory for y allocation");
z = (double *) fftw_malloc( sizeof(double complex) * NTOTAL_COMPLEX);
if (z == NULL) ERROR_HANDLER( ERROR_CRITICAL, "No memory for z allocation");
// Initialize the (transposed!) arrays
for(i = 0 ; i < NX ; i++) {
for(j = 0 ; j < NY/NPROC ; j++) {
for(k = 0 ; k < NZ ; k++) {
x[k + (NZ + 2) * i + (NZ + 2) * NX * j] = - param.lx / 2 + (param.lx * i ) / NX;
y[k + (NZ + 2) * i + (NZ + 2) * NX * j] = - param.ly / 2 + (param.ly * (j + rank * NY / NPROC)) / NY;
z[k + (NZ + 2) * i + (NZ + 2) * NX * j] = - param.lz / 2 + (param.lz * k ) / NZ;
}
}
}
// Initialize the extra points (k=NZ and k=NZ+1) to zero to prevent stupid things from happening...
for(i = 0 ; i < NX ; i++) {
for(j = 0 ; j < NY/NPROC ; j++) {
for(k = NZ ; k < NZ + 2 ; k++) {
x[k + (NZ + 2) * i + (NZ + 2) * NX * j] = 0.0;
y[k + (NZ + 2) * i + (NZ + 2) * NX * j] = 0.0;
z[k + (NZ + 2) * i + (NZ + 2) * NX * j] = 0.0;
}
}
}
// Init array to zero
for(i = 0 ; i < NX ; i++) {
for(j = 0 ; j < NY/NPROC ; j++) {
for(k = 0 ; k < NZ + 2 ; k++) {
mask_real[ k + (NZ + 2) * i + (NZ + 2) * NX * j ] = 1.0;
}
}
}
// Insert a radius=1 object in the system
for(i = 0 ; i < 2*NTOTAL_COMPLEX ; i++) {
if((x[i]*x[i]+y[i]*y[i])<1.0) {
mask_real[i] = 0.0;
}
}
free(x);
free(y);
free(z);
}
/******************************************
** Enforce the real mask ******************
*******************************************/
void enforce_real_mask(struct Field fldi) {
int i;
for( i = 0 ; i < NTOTAL_COMPLEX ; i++) {
w1[i] = fldi.vx[i];
w2[i] = fldi.vy[i];
w3[i] = fldi.vz[i];
}
gfft_c2r_t(w1);
gfft_c2r_t(w2);
gfft_c2r_t(w3);
for( i = 0 ; i < 2*NTOTAL_COMPLEX ; i++) {
wr1[i] = wr1[i] * mask_real[i] / ((double) NTOTAL);
wr2[i] = wr2[i] * mask_real[i] / ((double) NTOTAL);
wr3[i] = wr3[i] * mask_real[i] / ((double) NTOTAL);
}
gfft_r2c_t(wr1);
gfft_r2c_t(wr2);
gfft_r2c_t(wr3);
for( i = 0 ; i < NTOTAL_COMPLEX ; i++) {
fldi.vx[i] = w1[i] * mask[i];
fldi.vy[i] = w2[i] * mask[i];
fldi.vz[i] = w3[i] * mask[i];
}
return;
}