aboutsummaryrefslogtreecommitdiff
path: root/src/setup_epsdis.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/setup_epsdis.c')
-rw-r--r--src/setup_epsdis.c233
1 files changed, 233 insertions, 0 deletions
diff --git a/src/setup_epsdis.c b/src/setup_epsdis.c
new file mode 100644
index 0000000..9a3b2cf
--- /dev/null
+++ b/src/setup_epsdis.c
@@ -0,0 +1,233 @@
+/* $Header$ */
+
+#include <assert.h>
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "cctk.h"
+#include "cctk_Arguments.h"
+#include "cctk_Parameters.h"
+#include "cctk_Functions.h"
+
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+
+#define MAXDIM 3
+
+void
+setup_epsdis (CCTK_ARGUMENTS)
+{
+ DECLARE_CCTK_ARGUMENTS;
+ DECLARE_CCTK_PARAMETERS;
+
+ int ni,nj,nk;
+ int i,j,k,s;
+ int index,indexP;
+ int ierr;
+ int npts;
+ int *inds;
+ CCTK_REAL *xa,*ya,*za,*rads;
+ CCTK_REAL maxrad;
+ CCTK_REAL xmin,xmax, ymin,ymax, zmin,zmax;
+ CCTK_REAL odx,ody,odz;
+ CCTK_REAL radp;
+ const CCTK_INT MAXSURFNUM=100; /* XXX hard limit */
+ CCTK_INT doBC[2*MAXDIM],symbnd[2*MAXDIM];
+ CCTK_INT symtable;
+
+ if (verbose) {
+ CCTK_VInfo(CCTK_THORNSTRING,"Setting up spatially varying dissipation at T=%g",
+ (double)cctk_time);
+ }
+
+ ni=cctk_lsh[0];
+ nj=cctk_lsh[1];
+ nk=cctk_lsh[2];
+
+ for (i=0;i<ni*nj*nk;i++) {
+ epsdisA[i]=epsdis;
+ }
+
+
+
+ if (extra_dissipation_at_outerbound)
+ {
+ symtable = SymmetryTableHandleForGrid (cctkGH);
+ if (symtable < 0) CCTK_WARN (1, "unable to get symmetry table");
+ ierr=Util_TableGetIntArray(symtable, 6, symbnd, "symmetry_handle");
+ if (ierr != 6) CCTK_WARN (1, "unable to get symmetry handle");
+ for (i = 0; i < 6; i++) {
+ doBC[i] = cctk_bbox[i]!=0 && symbnd[i] < 0;
+ }
+ if(doBC[0]) {
+ for (k=0;k<nk;k++) {
+ for (j=0;j<nj;j++) {
+ for (i=0;i<outer_bound_npoints;i++) {
+ index = CCTK_GFINDEX3D(cctkGH,i,j,k);
+ indexP= CCTK_GFINDEX3D(cctkGH,outer_bound_npoints,j,k);
+ epsdisA[index]=epsdis+epsdis*ob_slope*abs(x[index]-x[indexP]);
+ }
+ }
+ }
+ }
+ if(doBC[1]) {
+ for (k=0;k<nk;k++) {
+ for (j=0;j<nj;j++) {
+ for (i=ni;i>ni-outer_bound_npoints;i--) {
+ index = CCTK_GFINDEX3D(cctkGH,i,j,k);
+ indexP= CCTK_GFINDEX3D(cctkGH,ni-outer_bound_npoints,j,k);
+ epsdisA[index]=epsdis+epsdis*ob_slope*abs(x[index]-x[indexP]);
+ }
+ }
+ }
+ }
+
+ if(doBC[2]) {
+ for (k=0;k<nk;k++) {
+ for (j=0;j<outer_bound_npoints;j++) {
+ for (i=0;i<ni;i++) {
+ index = CCTK_GFINDEX3D(cctkGH,i,j,k);
+ indexP= CCTK_GFINDEX3D(cctkGH,i,outer_bound_npoints,k);
+ epsdisA[index]=epsdis+epsdis*ob_slope*abs(y[index]-y[indexP]);
+ }
+ }
+ }
+ }
+ if(doBC[3]) {
+ for (k=0;k<nk;k++) {
+ for (j=nj;j>nj-outer_bound_npoints;j--) {
+ for (i=0;i<ni;i++) {
+ index = CCTK_GFINDEX3D(cctkGH,i,j,k);
+ indexP= CCTK_GFINDEX3D(cctkGH,i,nj-outer_bound_npoints,k);
+ epsdisA[index]=epsdis+epsdis*ob_slope*abs(y[index]-y[indexP]);
+ }
+ }
+ }
+ }
+
+ if(doBC[4]) {
+ for (k=0;k<outer_bound_npoints;k++) {
+ for (j=0;j<nj;j++) {
+ for (i=0;i<ni;i++) {
+ index = CCTK_GFINDEX3D(cctkGH,i,j,k);
+ indexP= CCTK_GFINDEX3D(cctkGH,i,j,outer_bound_npoints);
+ epsdisA[index]=epsdis+epsdis*ob_slope*abs(z[index]-z[indexP]);
+ }
+ }
+ }
+ }
+ if(doBC[5]) {
+ for (k=nk;k>nk-outer_bound_npoints;k--) {
+ for (j=0;j<nj;j++) {
+ for (i=0;i<ni;i++) {
+ index = CCTK_GFINDEX3D(cctkGH,i,j,k);
+ indexP= CCTK_GFINDEX3D(cctkGH,i,j,nk-outer_bound_npoints);
+ epsdisA[index]=epsdis+epsdis*ob_slope*abs(z[index]-z[indexP]);
+ }
+ }
+ }
+ }
+ }
+
+
+
+ if (extra_dissipation_in_horizons && cctk_iteration%update_ah_every == 0)
+ {
+ if (verbose) {
+ CCTK_INFO("Linear Interpolation into AH surfaces");
+ }
+
+ for (s=0;s<MAXSURFNUM;s++)
+ {
+ if (surface_number[s]==-1 && horizon_number[s]==-1) {
+ continue;
+ }
+
+ if (surface_number[s]<0 || horizon_number[s]<=0) {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Invalid specification for horizon %d", s);
+ continue;
+ }
+
+ if (! sf_valid[surface_number[s]]) {
+ if (verbose) {
+ CCTK_VInfo(CCTK_THORNSTRING,
+ "Invalid Surface: s=%d, sf_va=%d, surf_no=%d, ah_no=%d",
+ s,sf_valid[surface_number[s]],surface_number[s],horizon_number[s]);
+ }
+ continue;
+ }
+
+ if (! CCTK_IsFunctionAliased ("HorizonRadiusInDirection"))
+ {
+ CCTK_WARN (1, "The aliased function \"HorizonRadiusInDirection\" must be defined when the parameter \"extra_dissipation_in_horizons\" is set and one of the sources is AHFinderDirect");
+ continue;
+ }
+
+ maxrad=sf_max_radius[surface_number[s]];
+ odx=sf_origin_x[surface_number[s]];
+ ody=sf_origin_y[surface_number[s]];
+ odz=sf_origin_z[surface_number[s]];
+ xmin=odx-maxrad;
+ xmax=odx+maxrad;
+ ymin=ody-maxrad;
+ ymax=ody+maxrad;
+ zmin=odz-maxrad;
+ zmax=odz+maxrad;
+
+ npts=0;
+ for (i=0;i<ni*nj*nk;i++) {
+ if ( x[i]<=xmax&&x[i]>=xmin
+ &&y[i]<=ymax&&y[i]>=ymin
+ &&z[i]<=zmax&&z[i]>=zmin)
+ {
+ npts++;
+ }
+ }
+
+ xa=(CCTK_REAL *) malloc(npts*sizeof(CCTK_REAL));
+ ya=(CCTK_REAL *) malloc(npts*sizeof(CCTK_REAL));
+ za=(CCTK_REAL *) malloc(npts*sizeof(CCTK_REAL));
+ rads=(CCTK_REAL *) malloc(npts*sizeof(CCTK_REAL));
+ inds=(CCTK_INT *) malloc(npts*sizeof(CCTK_INT));
+
+ for (i=0;i<npts;i++) {
+ rads[i]=0;
+ inds[i]=0;
+ }
+
+ j=0;
+ for (i=0;i<ni*nj*nk;i++) {
+ if ( x[i]<=xmax&&x[i]>=xmin
+ &&y[i]<=ymax&&y[i]>=ymin
+ &&z[i]<=zmax&&z[i]>=zmin)
+ {
+ xa[j]=x[i];
+ ya[j]=y[i];
+ za[j]=z[i];
+ inds[j]=i;
+ j++;
+ }
+ }
+
+ ierr=HorizonRadiusInDirection(horizon_number[s],
+ npts,
+ xa, ya, za, rads);
+ assert(!ierr);
+
+ for (i=0;i<npts;i++) {
+ radp=sqrt(xa[i]*xa[i]+ya[i]*ya[i]+za[i]*za[i]);
+ if (radp<=rads[i]) {
+ epsdisA[inds[i]]=epsdis+ ah_slope*(rads[i]-radp)*epsdis;
+ }
+ }
+
+ free(xa);
+ free(ya);
+ free(za);
+ free(rads);
+ free(inds);
+ }
+ }
+}