aboutsummaryrefslogtreecommitdiff
path: root/src/RadiationBoundary.c
diff options
context:
space:
mode:
authortradke <tradke@6a38eb6e-646e-4a02-a296-d141613ad6c4>2001-04-14 17:38:46 +0000
committertradke <tradke@6a38eb6e-646e-4a02-a296-d141613ad6c4>2001-04-14 17:38:46 +0000
commit24e77dfa5b967707146fb536c9b58988827f3db9 (patch)
tree42c0fc4563acb37f19c97a56006dc1132a9f8277 /src/RadiationBoundary.c
parent2cbf9679f3326c80e65c0a71fdaa764b10af6d4f (diff)
Generalized boundary condition routines for applying to
arbitrary CCTK data types (except CCTK_COMPLEX). Added/completed grdoc. git-svn-id: http://svn.cactuscode.org/arrangements/CactusBase/Boundary/trunk@136 6a38eb6e-646e-4a02-a296-d141613ad6c4
Diffstat (limited to 'src/RadiationBoundary.c')
-rw-r--r--src/RadiationBoundary.c2462
1 files changed, 1352 insertions, 1110 deletions
diff --git a/src/RadiationBoundary.c b/src/RadiationBoundary.c
index 8ebc6d4..dfe0e46 100644
--- a/src/RadiationBoundary.c
+++ b/src/RadiationBoundary.c
@@ -1,1318 +1,1560 @@
/*@@
- @file RadiationBoundaryWrappers.c
+ @file RadiationBoundary.c
@date Mon Mar 15 15:09:00 1999
- @author Gabrielle Allen, Gerd Lanfermann
- @desc
- Radiation boundary conditions for 3D only callable from Fortran or C
- @enddesc
- @version $Header$
+ @author Miguel Alcubierre, Gabrielle Allen, Gerd Lanfermann
+ @desc
+ <PRE>
+ Routines for applying radiation boundary conditions
+
+ The radiative boundary condition that is implemented is:
+
+ f = f0 + u(r - v*t) / r + h(r + v*t) / r
+
+ That is, I assume outgoing radial waves with a 1/r
+ fall off, and the correct asymptotic value f0, plus
+ I include the possibility of incoming waves as well
+ (these incoming waves should be modeled somehow).
+
+ The condition above leads to the differential equation:
+
+ (x / r) d f + v d f + v x (f - f0) / r^2 = v x H / r^2
+ i t i i i
+
+ where x_i is the normal direction to the given boundaries,
+ and H = 2 dh(s)/ds.
+
+ So at a given boundary I only worry about derivatives in
+ the normal direction. Notice that u(r-v*t) has dissapeared,
+ but we still do not know the value of H.
+
+ To get H what I do is the following: I evaluate the
+ expression one point in from the boundary and solve for H
+ there. We now need a way of extrapolation H to the boundary.
+ For this I assume that H falls off as a power law:
+
+ H = k/r**n => d H = - n H/r
+ i
+
+ The value of n is is defined by the parameter "radpower".
+ If this parameter is negative, H is forced to be zero (this
+ corresponds to pure outgoing waves and is the default).
+ <P>
+ The behaviour I have observed is the following: Using H=0
+ is very stable, but has a very bad initial transient. Taking
+ n to be 0 or positive improves the initial behaviour considerably,
+ but introduces a drift that can kill the evolution at very late
+ times. Empirically, the best value I have found is n=2, for
+ which the initial behaviour is very nice, and the late time drift
+ is quite small.
+
+ Another problem with this condition is that it does not
+ use the physical characteristic speed, but rather it assumes
+ a wave speed of v, so the boundaries should be out in
+ the region where the characteristic speed is constant.
+ Notice that this speed does not have to be 1. For gauge
+ quantities {alpha,phi,trK} we can have a different asymptotic
+ speed, which is why the value of v is passed as a parameter.
+ </PRE>
+ @enddesc
+ @history
+ @hdate unknown
+ @hauthor Gerd Lanfermann
+ @hdesc Ported to Cactus 4.0
+ @hdate Fri 6 Apr 2001
+ @hauthor Thomas Radke
+ @hdesc BC routines generalized for applying to arbitrary CCTK data types
+ @endhistory
+ @version $Id$
@@*/
-/*#define DEBUG_BOUNDARY*/
-
-#include <stdio.h>
-#include <assert.h>
#include <stdlib.h>
-#include <ctype.h>
-#include <stdarg.h>
#include <string.h>
#include "cctk.h"
#include "cctk_FortranString.h"
#include "cctk_Parameters.h"
-#include "cctk_Stagger.h"
-#include "BoundarySymmetries.h"
+#include "Symmetry.h"
#include "Boundary.h"
-#define SQR(a) ((a)*(a))
-
+/* the rcs ID and its dummy function to use it */
static char *rcsid = "$Header$";
-
-CCTK_FILEVERSION(CactusBase_Boundary_RadiationBoundaryWrappers_c)
-
-/* Internal routine prototypes */
-
-static int BndApplyRadiative3Di(cGH *GH,
- int doBC,
- int *lssh,
- int *stencil_size,
- CCTK_REAL *dxyz,
- CCTK_REAL dt,
- CCTK_REAL *var_n,
- CCTK_REAL *var_p,
- CCTK_REAL *x,
- CCTK_REAL *y,
- CCTK_REAL *z,
- CCTK_REAL *r,
- CCTK_REAL var0,
- CCTK_REAL v0) ;
-
-static int ApplyBndRadiative(cGH *GH,
- int stencil,
- int *stencil_array,
- CCTK_REAL var0,
- CCTK_REAL v0,
- int var_current,
- int var_previous,
- int num_vars,
- int dir);
-
-/* Local variables */
+CCTK_FILEVERSION(CactusBase_Boundary_RadiationBoundary_c)
/********************************************************************
******************** External Routines ************************
********************************************************************/
+/* prototypes for external C routines are declared in header Boundary.h
+ here only follow the fortran wrapper prototypes */
+void CCTK_FCALL CCTK_FNAME (BndRadiativeDirGI)
+ (int *ierr,
+ cGH *GH,
+ const int *stencil_size,
+ const int *dir,
+ const CCTK_REAL *var0,
+ const CCTK_REAL *speed,
+ const int *gi_to,
+ const int *gi_from);
+void CCTK_FCALL CCTK_FNAME (BndRadiativeGI)
+ (int *ierr,
+ cGH *GH,
+ int stencil[],
+ const CCTK_REAL *var0,
+ const CCTK_REAL *speed,
+ const int *gi_to,
+ const int *gi_from);
+void CCTK_FCALL CCTK_FNAME (BndRadiativeDirGN)
+ (int *ierr,
+ cGH *GH,
+ const int *stencil_size,
+ const int *dir,
+ const CCTK_REAL *var0,
+ const CCTK_REAL *speed,
+ TWO_FORTSTRINGS_ARGS);
+void CCTK_FCALL CCTK_FNAME (BndRadiativeGN)
+ (int *ierr,
+ cGH *GH,
+ int stencil[],
+ const CCTK_REAL *var0,
+ const CCTK_REAL *speed,
+ TWO_FORTSTRINGS_ARGS);
+void CCTK_FCALL CCTK_FNAME (BndRadiativeDirVI)
+ (int *ierr,
+ cGH *GH,
+ const int *stencil_size,
+ const int *dir,
+ const CCTK_REAL *var0,
+ const CCTK_REAL *speed,
+ const int *vi_to,
+ const int *vi_from);
+void CCTK_FCALL CCTK_FNAME (BndRadiativeVI)
+ (int *ierr,
+ cGH *GH,
+ int stencil[],
+ const CCTK_REAL *var0,
+ const CCTK_REAL *speed,
+ const int *vi_to,
+ const int *vi_from);
+void CCTK_FCALL CCTK_FNAME (BndRadiativeDirVN)
+ (int *ierr,
+ cGH *GH,
+ const int *stencil_size,
+ const int *dir,
+ const CCTK_REAL *var0,
+ const CCTK_REAL *speed,
+ TWO_FORTSTRINGS_ARGS);
+void CCTK_FCALL CCTK_FNAME (BndRadiativeVN)
+ (int *ierr,
+ cGH *GH,
+ int stencil[],
+ const CCTK_REAL *var0,
+ const CCTK_REAL *speed,
+ TWO_FORTSTRINGS_ARGS);
+
+
+/********************************************************************
+ ******************** Internal Routines ************************
+ ********************************************************************/
+static int ApplyBndRadiative (cGH *GH,
+ int stencil_dir,
+ int stencil_alldirs[],
+ int dir,
+ CCTK_REAL var0,
+ CCTK_REAL speed,
+ int first_var_to,
+ int first_var_from,
+ int num_vars);
+
/*@@
@routine BndRadiativeDirGI
@date Sat Jan 20 2001
@author Gabrielle Allen
- @desc
- Aply radiative BC's by group index in given direction
- @enddesc
- @calls
- @calledby
- @history
- @endhistory
-
+ @desc
+ Aply radiative BC's by group index in given direction
+ @enddesc
+ @calls ApplyBndRadiative
+
+ @var GH
+ @vdesc Pointer to CCTK grid hierarchy
+ @vtype cGH *
+ @vio in
+ @endvar
+ @var stencil_size
+ @vdesc stencil size in this direction
+ @vtype int
+ @vio in
+ @endvar
+ @var dir
+ @vdesc direction to apply BC
+ @vtype int
+ @vio in
+ @endvar
+ @var var0
+ @vdesc asymptotic value of function at infinity
+ @vtype CCTK_REAL
+ @vio in
+ @endvar
+ @var speed
+ @vdesc wave speed
+ @vtype CCTK_REAL
+ @vio in
+ @endvar
+ @var gi_to
+ @vdesc index of group to apply BC to
+ @vtype int
+ @vio in
+ @endvar
+ @var gi_from
+ @vdesc index of group to apply BC from
+ @vtype int
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ return code of @seeroutine ApplyBndRadiative <BR>
+ -1 if invalid group indices are given
+ @endreturndesc
@@*/
-
-int BndRadiativeDirGI(cGH *GH,
- int stencil_size,
- int dir,
- CCTK_REAL var0,
- CCTK_REAL speed,
- int gi,
- int gi_p)
+int BndRadiativeDirGI (cGH *GH,
+ int stencil_size,
+ int dir,
+ CCTK_REAL var0,
+ CCTK_REAL speed,
+ int gi_to,
+ int gi_from)
{
- int numvars, first_vi, first_vi_p;
+ int first_vi_to, first_vi_from, retval;
- first_vi = CCTK_FirstVarIndexI(gi);
- first_vi_p = CCTK_FirstVarIndexI(gi_p);
- numvars = CCTK_NumVarsInGroupI(gi);
- return ApplyBndRadiative(GH,stencil_size,NULL,var0,
- speed,first_vi,first_vi_p,numvars,dir);
+ first_vi_to = CCTK_FirstVarIndexI (gi_to);
+ first_vi_from = CCTK_FirstVarIndexI (gi_from);
+ if (first_vi_to >= 0 && first_vi_from >= 0)
+ {
+ retval = ApplyBndRadiative (GH, stencil_size, NULL, dir, var0, speed,
+ first_vi_to, first_vi_from,
+ CCTK_NumVarsInGroupI (gi_to));
+ }
+ else
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Invalid group indices %d and/or %d in BndRadiativeDirGI",
+ gi_to, gi_from);
+ retval = -1;
+ }
+ return (retval);
}
-void CCTK_FCALL CCTK_FNAME(BndRadiativeDirGI)
- (int *ierr, cGH *GH, int *stencil_size, int *dir, CCTK_REAL *var0,
- CCTK_REAL *speed, int *gi, int *gi_p)
+void CCTK_FCALL CCTK_FNAME (BndRadiativeDirGI)
+ (int *ierr,
+ cGH *GH,
+ const int *stencil_size,
+ const int *dir,
+ const CCTK_REAL *var0,
+ const CCTK_REAL *speed,
+ const int *gi_to,
+ const int *gi_from)
{
- *ierr = BndRadiativeDirGI(GH, *stencil_size, *dir, *var0, *speed, *gi, *gi_p);
+ *ierr = BndRadiativeDirGI (GH, *stencil_size, *dir, *var0, *speed,
+ *gi_to, *gi_from);
}
+
/*@@
@routine BndRadiativeGI
@date Tue Jul 18 18:04:07 2000
@author Gerd Lanfermann
- @desc
- Aply radiative BC's by group index
- @enddesc
- @calls
- @calledby
- @history
- @endhistory
-
+ @desc
+ Aply radiative BC's by group index
+ @enddesc
+ @calls ApplyBndRadiative
+
+ @var GH
+ @vdesc Pointer to CCTK grid hierarchy
+ @vtype cGH *
+ @vio in
+ @endvar
+ @var stencil
+ @vdesc stencil width
+ @vtype int [ dimension of group ]
+ @vio in
+ @endvar
+ @var var0
+ @vdesc asymptotic value of function at infinity
+ @vtype CCTK_REAL
+ @vio in
+ @endvar
+ @var speed
+ @vdesc wave speed
+ @vtype CCTK_REAL
+ @vio in
+ @endvar
+ @var gi_to
+ @vdesc index of group to apply BC to
+ @vtype int
+ @vio in
+ @endvar
+ @var gi_from
+ @vdesc index of group to apply BC from
+ @vtype int
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ return code of @seeroutine ApplyBndRadiative <BR>
+ -1 if invalid group indices are given
+ @endreturndesc
@@*/
-
-int BndRadiativeGI(cGH *GH,
- int *stencil_array,
- CCTK_REAL var0,
- CCTK_REAL speed,
- int gi,
- int gi_p)
+int BndRadiativeGI (cGH *GH,
+ int stencil[],
+ CCTK_REAL var0,
+ CCTK_REAL speed,
+ int gi_to,
+ int gi_from)
{
- int numvars, first_vi, first_vi_p;
+ int first_vi_to, first_vi_from, retval;
- first_vi = CCTK_FirstVarIndexI(gi);
- first_vi_p = CCTK_FirstVarIndexI(gi_p);
- numvars = CCTK_NumVarsInGroupI(gi);
- return ApplyBndRadiative(GH,-1,stencil_array,var0,speed,first_vi,first_vi_p,numvars,0);
+ first_vi_to = CCTK_FirstVarIndexI (gi_to);
+ first_vi_from = CCTK_FirstVarIndexI (gi_from);
+ if (first_vi_to >= 0 && first_vi_from >= 0)
+ {
+ retval = ApplyBndRadiative (GH, -1, stencil, 0, var0, speed,
+ first_vi_to, first_vi_from,
+ CCTK_NumVarsInGroupI (gi_to));
+ }
+ else
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Invalid group indices %d and/or %d in BndRadiativeGI",
+ gi_to, gi_from);
+ retval = -1;
+ }
+ return (retval);
}
-void CCTK_FCALL CCTK_FNAME(BndRadiativeGI)
- (int *ierr, cGH *GH, int *stencil_array, CCTK_REAL *var0,
- CCTK_REAL *speed, int *gi, int *gi_p)
+void CCTK_FCALL CCTK_FNAME (BndRadiativeGI)
+ (int *ierr,
+ cGH *GH,
+ int stencil[],
+ const CCTK_REAL *var0,
+ const CCTK_REAL *speed,
+ const int *gi_to,
+ const int *gi_from)
{
- *ierr = BndRadiativeGI(GH, stencil_array, *var0, *speed, *gi, *gi_p);
+ *ierr = BndRadiativeGI (GH, stencil, *var0, *speed, *gi_to, *gi_from);
}
/* ===================================================================== */
-
/*@@
@routine BndRadiativeDirGN
@date Sat Jan 20 2001
@author Gabrielle Allen
- @desc
- Apply radiative BC's by group name in given direction
- @enddesc
- @calls
- @calledby
- @history
- @endhistory
-
+ @desc
+ Apply radiative BC's by group name in given direction
+ @enddesc
+ @calls BndRadiativeDirGI
+
+ @var GH
+ @vdesc Pointer to CCTK grid hierarchy
+ @vtype cGH *
+ @vio in
+ @endvar
+ @var stencil_size
+ @vdesc stencil size in this direction
+ @vtype int
+ @vio in
+ @endvar
+ @var dir
+ @vdesc direction to apply BC
+ @vtype int
+ @vio in
+ @endvar
+ @var var0
+ @vdesc asymptotic value of function at infinity
+ @vtype CCTK_REAL
+ @vio in
+ @endvar
+ @var speed
+ @vdesc wave speed
+ @vtype CCTK_REAL
+ @vio in
+ @endvar
+ @var gn_to
+ @vdesc name of group to apply BC to
+ @vtype char []
+ @vio in
+ @endvar
+ @var gn_from
+ @vdesc name of group to apply BC from
+ @vtype char []
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ return code of @seeroutine BndRadiativeDirGI <BR>
+ -1 if invalid group names are given
+ @endreturndesc
@@*/
-
-int BndRadiativeDirGN(cGH *GH,
- int stencil_size,
- int dir,
- CCTK_REAL var0,
- CCTK_REAL speed,
- const char *gn,
- const char *gn_p)
+int BndRadiativeDirGN (cGH *GH,
+ int stencil_size,
+ int dir,
+ CCTK_REAL var0,
+ CCTK_REAL speed,
+ char gn_to[],
+ char gn_from[])
{
- int retval;
- int gi = CCTK_GroupIndex(gn);
- int gi_p = CCTK_GroupIndex(gn_p);
-
- if ((gi>-1)&&(gi_p>-1))
- retval = BndRadiativeDirGI(GH, stencil_size, dir, var0, speed, gi, gi_p);
- else
+ int gi_to, gi_from, retval;
+
+
+ gi_to = CCTK_GroupIndex (gn_to);
+ gi_from = CCTK_GroupIndex (gn_from);
+ if (gi_to >= 0 && gi_from >= 0)
{
- CCTK_VWarn(1,__LINE__,__FILE__,"Boundary",
- "BndRadiativeDirGN: Grid variable groups %s or %s not found",
- gn, gn_p);
+ retval = BndRadiativeDirGI (GH, stencil_size, dir, var0, speed,
+ gi_to, gi_from);
+ }
+ else
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Invalid group names '%s' and/or '%s' in BndRadiativeDirGN",
+ gn_to, gn_from);
retval = -1;
}
- return retval;
+ return (retval);
}
-
-void CCTK_FCALL CCTK_FNAME(BndRadiativeDirGN)
- (int *ierr, cGH *GH, int *stencil_size, int *dir, CCTK_REAL *var0,
- CCTK_REAL *speed, TWO_FORTSTRINGS_ARGS)
+
+void CCTK_FCALL CCTK_FNAME (BndRadiativeDirGN)
+ (int *ierr,
+ cGH *GH,
+ const int *stencil_size,
+ const int *dir,
+ const CCTK_REAL *var0,
+ const CCTK_REAL *speed,
+ TWO_FORTSTRINGS_ARGS)
{
- TWO_FORTSTRINGS_CREATE(gn, gn_p)
- *ierr = BndRadiativeDirGN(GH, *stencil_size, *dir, *var0, *speed, gn, gn_p);
- free(gn);
- free(gn_p);
- return;
+ TWO_FORTSTRINGS_CREATE (gn_to, gn_from)
+ *ierr = BndRadiativeDirGN (GH, *stencil_size, *dir, *var0, *speed,
+ gn_to, gn_from);
+ free (gn_to);
+ free (gn_from);
}
/*@@
- @routine BndRadiativeGI
+ @routine BndRadiativeGN
@date Tue Jul 18 18:04:07 2000
@author Gerd Lanfermann
- @desc
- Aply radiative BC's by group name @enddesc
- @calls
- @calledby
- @history
- @endhistory
-
+ @desc
+ Aply radiative BC's by group name
+ @enddesc
+ @calls BndRadiativeGI
+
+ @var GH
+ @vdesc Pointer to CCTK grid hierarchy
+ @vtype cGH *
+ @vio in
+ @endvar
+ @var stencil
+ @vdesc stencil width
+ @vtype int [ dimension of group ]
+ @vio in
+ @endvar
+ @var var0
+ @vdesc asymptotic value of function at infinity
+ @vtype CCTK_REAL
+ @vio in
+ @endvar
+ @var speed
+ @vdesc wave speed
+ @vtype CCTK_REAL
+ @vio in
+ @endvar
+ @var gn_to
+ @vdesc name of group to apply BC to
+ @vtype int
+ @vio in
+ @endvar
+ @var gn_from
+ @vdesc name of group to apply BC from
+ @vtype int
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ return code of @seeroutine BndRadiativeGI <BR>
+ -1 if invalid group names are given
+ @endreturndesc
@@*/
-
-int BndRadiativeGN(cGH *GH,
- int *stencil_array,
- CCTK_REAL var0,
- CCTK_REAL speed,
- const char *gn,
- const char *gn_p)
+int BndRadiativeGN (cGH *GH,
+ int stencil[],
+ CCTK_REAL var0,
+ CCTK_REAL speed,
+ char gn_to[],
+ char gn_from[])
{
- int retval;
- int gi = CCTK_GroupIndex(gn);
- int gi_p = CCTK_GroupIndex(gn_p);
-
- if ((gi>-1)&&(gi_p>-1))
- retval = BndRadiativeGI(GH, stencil_array, var0, speed, gi, gi_p);
- else
+ int gi_to, gi_from, retval;
+
+
+ gi_to = CCTK_GroupIndex (gn_to);
+ gi_from = CCTK_GroupIndex (gn_from);
+ if (gi_to >= 0 && gi_from >= 0)
{
- CCTK_VWarn(1,__LINE__,__FILE__,"Boundary",
- "BndRadiativeGN: Grid variable groups %s or %s not found",
- gn, gn_p);
+ retval = BndRadiativeGI (GH, stencil, var0, speed, gi_to, gi_from);
+ }
+ else
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Invalid group names '%s' and/or '%s' in BndRadiativeGN",
+ gn_to, gn_from);
retval = -1;
}
- return retval;
+ return (retval);
}
-
-void CCTK_FCALL CCTK_FNAME(BndRadiativeGN)
- (int *ierr, cGH *GH, int *stencil_array, CCTK_REAL *var0,
- CCTK_REAL *speed, TWO_FORTSTRINGS_ARGS)
+
+void CCTK_FCALL CCTK_FNAME (BndRadiativeGN)
+ (int *ierr,
+ cGH *GH,
+ int stencil[],
+ const CCTK_REAL *var0,
+ const CCTK_REAL *speed,
+ TWO_FORTSTRINGS_ARGS)
{
- TWO_FORTSTRINGS_CREATE(gn, gn_p)
- *ierr = BndRadiativeGN(GH, stencil_array, *var0, *speed, gn, gn_p);
- free(gn);
- free(gn_p);
- return;
+ TWO_FORTSTRINGS_CREATE (gn_to, gn_from)
+ *ierr = BndRadiativeGN (GH, stencil, *var0, *speed, gn_to, gn_from);
+ free (gn_to);
+ free (gn_from);
}
/* ===================================================================== */
-
/*@@
@routine BndRadiativeDirVI
@date Sat Jan 20 2001
@author Gabrielle Allen
- @desc
- Apply radiative BC's by variable index in given direction
- @enddesc
- @calls
- @calledby
- @history
- @endhistory
-
+ @desc
+ Apply radiative BC's by variable index in given direction
+ @enddesc
+ @calls ApplyBndRadiative
+
+ @var GH
+ @vdesc Pointer to CCTK grid hierarchy
+ @vtype cGH *
+ @vio in
+ @endvar
+ @var stencil_size
+ @vdesc stencil size in this direction
+ @vtype int
+ @vio in
+ @endvar
+ @var dir
+ @vdesc direction to apply BC
+ @vtype int
+ @vio in
+ @endvar
+ @var var0
+ @vdesc asymptotic value of function at infinity
+ @vtype CCTK_REAL
+ @vio in
+ @endvar
+ @var speed
+ @vdesc wave speed
+ @vtype CCTK_REAL
+ @vio in
+ @endvar
+ @var vi_to
+ @vdesc index of variable to apply BC to
+ @vtype int
+ @vio in
+ @endvar
+ @var vi_from
+ @vdesc index of variable to apply BC from
+ @vtype int
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ return code of @seeroutine ApplyBndRadiative <BR>
+ -1 if invalid variable indices are given
+ @endreturndesc
@@*/
-
-int BndRadiativeDirVI(cGH *GH,
- int stencil_size,
- int dir,
- CCTK_REAL var0,
- CCTK_REAL speed,
- int vi,
- int vi_p)
+int BndRadiativeDirVI (cGH *GH,
+ int stencil_size,
+ int dir,
+ CCTK_REAL var0,
+ CCTK_REAL speed,
+ int vi_to,
+ int vi_from)
{
- return ApplyBndRadiative(GH,stencil_size,NULL,var0,speed,vi,vi_p,1,dir);
+ int retval, num_vars;
+
+
+ num_vars = CCTK_NumVars ();
+ if (vi_to >= 0 && vi_to < num_vars && vi_from >= 0 && vi_from < num_vars)
+ {
+ retval = ApplyBndRadiative (GH, stencil_size, NULL, dir, var0, speed,
+ vi_to, vi_from, 1);
+ }
+ else
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Invalid variable indices %d and/or %d in BndRadiativeDirVI",
+ vi_to, vi_from);
+ retval = -1;
+ }
+
+ return (retval);
}
-void CCTK_FCALL CCTK_FNAME(BndRadiativeDirVI)
- (int *ierr, cGH *GH, int *stencil_size, int *dir, CCTK_REAL *var0,
- CCTK_REAL *speed, int *vi, int *vi_p)
+void CCTK_FCALL CCTK_FNAME (BndRadiativeDirVI)
+ (int *ierr,
+ cGH *GH,
+ const int *stencil_size,
+ const int *dir,
+ const CCTK_REAL *var0,
+ const CCTK_REAL *speed,
+ const int *vi_to,
+ const int *vi_from)
{
- *ierr = BndRadiativeDirVI(GH, *stencil_size, *dir, *var0,
- *speed, *vi, *vi_p);
- return;
+ *ierr = BndRadiativeDirVI (GH, *stencil_size, *dir, *var0, *speed,
+ *vi_to, *vi_from);
}
-
/*@@
@routine BndRadiativeVI
@date Tue Jul 18 18:04:07 2000
@author Gerd Lanfermann
- @desc
- Apply radiative BC's by variable index
- @enddesc
- @calls
- @calledby
- @history
- @endhistory
-
+ @desc
+ Apply radiative BC's by variable index
+ @enddesc
+ @calls ApplyBndRadiative
+
+ @var GH
+ @vdesc Pointer to CCTK grid hierarchy
+ @vtype cGH *
+ @vio in
+ @endvar
+ @var stencil
+ @vdesc stencil width
+ @vtype int [ dimension of variable ]
+ @vio in
+ @endvar
+ @var var0
+ @vdesc asymptotic value of function at infinity
+ @vtype CCTK_REAL
+ @vio in
+ @endvar
+ @var speed
+ @vdesc wave speed
+ @vtype CCTK_REAL
+ @vio in
+ @endvar
+ @var vi_to
+ @vdesc index of variable to apply BC to
+ @vtype int
+ @vio in
+ @endvar
+ @var vi_from
+ @vdesc index of variable to apply BC from
+ @vtype int
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ return code of @seeroutine ApplyBndRadiative <BR>
+ -1 if invalid variable indices are given
+ @endreturndesc
@@*/
-
-int BndRadiativeVI(cGH *GH,
- int *stencil_array,
- CCTK_REAL var0,
- CCTK_REAL speed,
- int vi,
- int vi_p)
+int BndRadiativeVI (cGH *GH,
+ int stencil[],
+ CCTK_REAL var0,
+ CCTK_REAL speed,
+ int vi_to,
+ int vi_from)
{
- return ApplyBndRadiative(GH,-1,stencil_array,var0,speed,vi,vi_p,1,0);
-}
-
-void CCTK_FCALL CCTK_FNAME(BndRadiativeVI)
- (int *ierr, cGH *GH, int *stencil_array, CCTK_REAL *var0,
- CCTK_REAL *speed, int *vi, int *vi_p)
-{
- *ierr = BndRadiativeVI(GH, stencil_array, *var0, *speed, *vi, *vi_p);
- return;
-}
+ int retval, num_vars;
-/* ======================================================================= */
-
-
-/*@@
- @routine BndRadiativeDirGI
- @date Sat Jan 20 2001
- @author Gabrielle Allen
- @desc
- Apply radiative BC's by variable name in given direction
- @enddesc
- @calls
- @calledby
- @history
- @endhistory
-
-@@*/
-
-int BndRadiativeDirVN(cGH *GH,
- int stencil_size,
- int dir,
- CCTK_REAL var0,
- CCTK_REAL speed,
- const char *vn,
- const char *vn_p)
-{
- int retval;
- int vi = CCTK_VarIndex(vn);
- int vi_p = CCTK_VarIndex(vn_p);
-
- if (vi>=0 && vi_p>=0)
+ num_vars = CCTK_NumVars ();
+ if (vi_to >= 0 && vi_to < num_vars && vi_from >= 0 && vi_from < num_vars)
{
- retval = BndRadiativeDirVI(GH, stencil_size, dir, var0, speed, vi, vi_p);
+ retval = ApplyBndRadiative (GH, -1, stencil, 0, var0, speed,
+ vi_to, vi_from, 1);
}
else
{
- CCTK_VWarn(1,__LINE__,__FILE__,"Boundary",
- "BndRadiativeDirVN: Grid variable %s or %s not found",
- vn, vn_p);
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Invalid variable indices %d and/or %d in BndRadiativeVI",
+ vi_to, vi_from);
retval = -1;
}
- return retval;
-
+ return (retval);
}
-void CCTK_FCALL CCTK_FNAME(BndRadiativeDirVN)
- (int *ierr, cGH *GH, int *stencil_size, int *dir, CCTK_REAL *var0,
- CCTK_REAL *speed, TWO_FORTSTRINGS_ARGS)
+void CCTK_FCALL CCTK_FNAME (BndRadiativeVI)
+ (int *ierr,
+ cGH *GH,
+ int stencil[],
+ const CCTK_REAL *var0,
+ const CCTK_REAL *speed,
+ const int *vi_to,
+ const int *vi_from)
{
- TWO_FORTSTRINGS_CREATE(vn,vn_p)
- *ierr = BndRadiativeDirVN(GH, *stencil_size, *dir, *var0, *speed, vn, vn_p);
- free(vn);
- free(vn_p);
- return;
-}
+ *ierr = BndRadiativeVI (GH, stencil, *var0, *speed, *vi_to, *vi_from);
+}
-/*@@
- @routine BndRadiativeGI
- @date Tue Jul 18 18:04:07 2000
- @author Gerd Lanfermann
- @desc
- Apply radiative BC's by variable name
- @enddesc
- @calls
- @calledby
- @history
- @endhistory
+/* ======================================================================= */
+/*@@
+ @routine BndRadiativeDirVN
+ @date Sat Jan 20 2001
+ @author Gabrielle Allen
+ @desc
+ Apply radiative BC's by variable name in given direction
+ @enddesc
+ @calls BndRadiativeDirVI
+
+ @var GH
+ @vdesc Pointer to CCTK grid hierarchy
+ @vtype cGH *
+ @vio in
+ @endvar
+ @var stencil_size
+ @vdesc stencil size in this direction
+ @vtype int
+ @vio in
+ @endvar
+ @var dir
+ @vdesc direction to apply BC
+ @vtype int
+ @vio in
+ @endvar
+ @var var0
+ @vdesc asymptotic value of function at infinity
+ @vtype CCTK_REAL
+ @vio in
+ @endvar
+ @var speed
+ @vdesc wave speed
+ @vtype CCTK_REAL
+ @vio in
+ @endvar
+ @var vn_to
+ @vdesc name of variable to apply BC to
+ @vtype char []
+ @vio in
+ @endvar
+ @var vn_from
+ @vdesc name of variable to apply BC from
+ @vtype char []
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ return code of @seeroutine BndRadiativeDirVI <BR>
+ -1 if invalid variable names are given
+ @endreturndesc
@@*/
-
-int BndRadiativeVN(cGH *GH,
- int *stencil_array,
- CCTK_REAL var0,
- CCTK_REAL speed,
- const char *vn,
- const char *vn_p)
+int BndRadiativeDirVN (cGH *GH,
+ int stencil_size,
+ int dir,
+ CCTK_REAL var0,
+ CCTK_REAL speed,
+ char vn_to[],
+ char vn_from[])
{
- int retval;
- int vi = CCTK_VarIndex(vn);
- int vi_p = CCTK_VarIndex(vn_p);
-
- if (vi>=0 && vi_p>=0)
+ int vi_to, vi_from, num_vars, retval;
+
+
+ vi_to = CCTK_VarIndex (vn_to);
+ vi_from = CCTK_VarIndex (vn_from);
+ num_vars = CCTK_NumVars ();
+
+ if (vi_to >= 0 && vi_to < num_vars && vi_from >= 0 && vi_from < num_vars)
{
- retval = BndRadiativeVI(GH, stencil_array, var0, speed, vi, vi_p);
+ retval = BndRadiativeDirVI (GH, stencil_size, dir, var0, speed,
+ vi_to, vi_from);
}
else
{
- CCTK_VWarn(1,__LINE__,__FILE__,"Boundary",
- "BndRadiativeVN: Grid variable %s or %s not found",
- vn, vn_p);
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Invalid variable names '%s' and/or '%s' in BndRadiativeDirVN",
+ vn_to, vn_from);
retval = -1;
}
- return retval;
-
+ return (retval);
}
-void CCTK_FCALL CCTK_FNAME(BndRadiativeVN)
- (int *ierr, cGH *GH, int *stencil_array, CCTK_REAL *var0,
- CCTK_REAL *speed, TWO_FORTSTRINGS_ARGS)
+void CCTK_FCALL CCTK_FNAME (BndRadiativeDirVN)
+ (int *ierr,
+ cGH *GH,
+ const int *stencil_size,
+ const int *dir,
+ const CCTK_REAL *var0,
+ const CCTK_REAL *speed,
+ TWO_FORTSTRINGS_ARGS)
{
- TWO_FORTSTRINGS_CREATE(vn,vn_p)
- *ierr = BndRadiativeVN(GH, stencil_array, *var0, *speed, vn, vn_p);
- free(vn);
- free(vn_p);
- return;
-}
-
+ TWO_FORTSTRINGS_CREATE (vn_to, vn_from)
+ *ierr = BndRadiativeDirVN (GH, *stencil_size, *dir, *var0, *speed,
+ vn_to, vn_from);
+ free (vn_to);
+ free (vn_from);
+}
-/********************************************************************
- ********************* Local Routines *************************
- ********************************************************************/
/*@@
- @routine ApplyBndRadiative
+ @routine BndRadiativeVN
@date Tue Jul 18 18:04:07 2000
@author Gerd Lanfermann
- @desc
- Apply radiative BC's - internal routine
- @enddesc
- @calls
- @calledby
- @history
- @endhistory
-
+ @desc
+ Apply radiative BC's by variable name
+ @enddesc
+ @calls BndRadiativeVI
+
+ @var GH
+ @vdesc Pointer to CCTK grid hierarchy
+ @vtype cGH *
+ @vio in
+ @endvar
+ @var stencil
+ @vdesc stencil width
+ @vtype int [ dimension of variable ]
+ @vio in
+ @endvar
+ @var var0
+ @vdesc asymptotic value of function at infinity
+ @vtype CCTK_REAL
+ @vio in
+ @endvar
+ @var speed
+ @vdesc wave speed
+ @vtype CCTK_REAL
+ @vio in
+ @endvar
+ @var vn_to
+ @vdesc name of variable to apply BC to
+ @vtype int
+ @vio in
+ @endvar
+ @var vn_from
+ @vdesc name of variable to apply BC from
+ @vtype int
+ @vio in
+ @endvar
+
+ @returntype int
+ @returndesc
+ return code of @seeroutine BndRadiativeVI <BR>
+ -1 if invalid variable names are given
+ @endreturndesc
@@*/
-
-static int ApplyBndRadiative(cGH *GH,
- int stencil,
- int *stencil_array,
- CCTK_REAL var0,
- CCTK_REAL speed,
- int var_current,
- int var_previous,
- int num_vars,
- int dir)
+int BndRadiativeVN (cGH *GH,
+ int stencil[],
+ CCTK_REAL var0,
+ CCTK_REAL speed,
+ char vn_to[],
+ char vn_from[])
{
- int xi=-1;
- int yi=-1;
- int zi=-1;
- int ri=-1;
- int count;
- int gi;
- int vi1, vi2;
- int symmetry_handle;
- int idim, dim;
- int time, time_p;
- int berr,ierr;
- int dirloop1,dirloop2;
- int doBC;
- int retval;
- int *sw;
- int *dstag;
- int *lssh;
- CCTK_REAL dx[3], dt;
- SymmetryGHex *sGHex;
+ int vi_to, vi_from, num_vars, retval;
-#ifdef DEBUG_BOUNDARY
- printf("Input arguments for ApplyBndRadiative:\n");
- printf("GH = %x\n",GH);
- printf("stencil = %d\n",stencil);
- printf("stencil_array = %x\n",stencil_array);
- printf("var0 = %f\n",var0);
- printf("speed = %f\n",speed);
- printf("var_current = %d\n",var_current);
- printf("var_previous = %d\n",var_previous);
- printf("num_vars = %d\n",num_vars);
- printf("dir = %d\n",dir);
- printf("-----------------------------------\n");
-#endif
-
- retval = 0;
- /* Get group dimension */
- dim = CCTK_GroupDimFromVarI(var_current);
+ vi_to = CCTK_VarIndex (vn_to);
+ vi_from = CCTK_VarIndex (vn_from);
+ num_vars = CCTK_NumVars ();
- if (dim<3 || dim>3)
+ if (vi_to >= 0 && vi_to < num_vars && vi_from >= 0 && vi_from < num_vars)
{
- CCTK_VWarn(1,__LINE__,__FILE__,CCTK_THORNSTRING,
- "ApplyBndRadiative: Invalid grid function dimension %d",
- dim);
- retval=-1;
+ retval = BndRadiativeVI (GH, stencil, var0, speed, vi_to, vi_from);
}
else
{
- /* See if we have a symmetry array */
- symmetry_handle = CCTK_GHExtensionHandle("Symmetry");
- if (symmetry_handle < 0)
- {
- sGHex = NULL;
- }
- else
- {
- sGHex = (SymmetryGHex*)GH->extensions[symmetry_handle];
- }
-
- /* Set up stencil width array if needed */
- if (stencil_array && dir == 0)
- {
- sw = stencil_array;
- }
- else if (dir==0)
- {
- CCTK_WARN(0,"ApplyBndRadiative: Direction 0 invalid for directional BC");
- }
- else if (dir>dim||-dir>dim)
- {
- CCTK_VWarn(0,__LINE__,__FILE__,CCTK_THORNSTRING,
- "ApplyBndRadiative: Direction %d greater than dimension %d",
- dir,dim);
- }
- else
- {
-
- int i;
- /* Should be single direction */
- sw = (int *)malloc(dim*sizeof(int));
- if (sw)
- {
- for (i=0;i<dim;i++)
- {
- sw[i] = 0;
- }
- if (dir > 0)
- {
- sw[dir-1] = stencil;
- }
- else
- {
- sw[-dir-1] = stencil;
- }
- }
- else
- {
- CCTK_WARN(0,"ApplyBndRadiative: Malloc sw failed");
- }
- }
-
- /* Radiative boundaries need the underlying Cartesian coordinates */
- switch (dim)
- {
- case 1:
- xi = CCTK_CoordIndex(-1,"x","cart1d");
- break;
- case 2:
- xi = CCTK_CoordIndex(-1,"x","cart2d");
- yi = CCTK_CoordIndex(-1,"y","cart2d");
- break;
- case 3:
- xi = CCTK_CoordIndex(-1,"x","cart3d");
- yi = CCTK_CoordIndex(-1,"y","cart3d");
- zi = CCTK_CoordIndex(-1,"z","cart3d");
- ri = CCTK_CoordIndex(-1,"r","spher3d");
- break;
- default:
- CCTK_VWarn(1,__LINE__,__FILE__,CCTK_THORNSTRING,
- "ApplyBndRadiative: Radiative boundary only for dim=3: grid variable '%s'",
- CCTK_VarName(var_current));
- break;
- }
-
- /* Allocate temporary arrays */
- dstag = (int *)malloc(dim*sizeof(int));
- lssh = (int *)malloc(dim*sizeof(int));
-
- /* get the directional staggering of the group */
- gi = CCTK_GroupIndexFromVarI(var_current);
- ierr = CCTK_GroupStaggerDirArrayGI(dstag, dim, gi);
-
-
- /* Use next time level, if available */
- time = CCTK_NumTimeLevelsFromVarI(var_current) - 1;
- if (time < 0)
- {
- time = 0;
- }
- /* Use current time level, if available */
- time_p = CCTK_NumTimeLevelsFromVarI(var_previous) - 2;
- if (time_p < 0)
- {
- time_p = 0;
- }
-
- /* Treat all boundaries or just one? */
- if (dir>0)
- {
- dirloop1 = 2*(dir-1)+1;
- dirloop2 = dirloop1+1;
- }
- else if (dir<0)
- {
- dirloop1 = 2*(-dir-1);
- dirloop2 = dirloop1+1;
- }
- else
- {
- dirloop1 = 0;
- dirloop2 = 2*dim;
- }
-
- for (vi1=var_current; vi1<var_current+num_vars; vi1++)
- {
-
- vi2 = (vi1-var_current+var_previous);
-
- /* Apply condition if:
- + boundary is not a symmetry boundary
- (no symmetry or unset(=unsed))
- + boundary is a physical boundary
- + have enough grid points */
-
- for (idim=0;idim<dim;idim++)
- {
- /* FIXME: THIS LINE FAILS WAVE TESTSUITES */
- /*lssh[idim] = GH->cctk_lssh[CCTK_LSSH_IDX(dstag[idim],idim)];*/
- lssh[idim] = GH->cctk_lsh[idim];
- }
-
- for (count=dirloop1;count<dirloop2;count++)
- {
- if (sGHex)
- {
- doBC = (
- ( (sGHex->GFSym[vi1][count]==GFSYM_NOSYM) ||
- (sGHex->GFSym[vi1][count]==GFSYM_UNSET) ) &&
- GH->cctk_lsh[count/2]>1 && GH->cctk_bbox[count]) ?
- count : -1;
- }
- else
- {
- doBC = (GH->cctk_lsh[count/2]>1 && GH->cctk_bbox[count]) ?
- count : -1 ;
- }
-
- if (doBC >=0)
- {
- switch (dim)
- {
- case 1:
- berr = -1;
- CCTK_VWarn(1,__LINE__,__FILE__,CCTK_THORNSTRING,
- "ApplyBndRadiative: Radiative boundary conditions"
- "not implemented for dimension = 1, grid variable %s",
- CCTK_VarName(vi1));
- break;
- case 2:
- berr = -1;
- CCTK_VWarn(1,__LINE__,__FILE__,CCTK_THORNSTRING,
- "ApplyBndRadiative: Radiative boundary conditions"
- "not implemented for dimension = 2, grid variable %s",
- CCTK_VarName(vi1));
- break;
- case 3:
- /* According to the Cactus spec, the true dx and dt values for a
- grid are calculated as follows: */
- dx[0] = GH->cctk_delta_space[0] / GH->cctk_levfac[0];
- dx[1] = GH->cctk_delta_space[1] / GH->cctk_levfac[1];
- dx[2] = GH->cctk_delta_space[2] / GH->cctk_levfac[2];
- dt = GH->cctk_delta_time;
-
- berr = BndApplyRadiative3Di
- (GH,
- doBC, /* apply BC on which face */
- lssh, /* local shape, respects staggering */
- sw, /* stencil width array */
- dx, /* dx,dy,dz */
- dt, /* dt */
- GH->data[vi1][time ], /* start of data array GF[] */
- GH->data[vi2][time_p], /* start of prev data array */
- GH->data[xi][0], /* pointer to the X field */
- GH->data[yi][0], /* pointer to the Y field */
- GH->data[zi][0], /* pointer to the Z field */
- GH->data[ri][0], /* pointer to the R field */
- var0, /* asymptotic limit */
- speed); /* wave speed */
- break;
- default :
- berr=-1;
- CCTK_VWarn(1,__LINE__,__FILE__,CCTK_THORNSTRING,
- "ApplyBndRadiative: No Radiative BC for dim>3, grid variable %s",
- CCTK_VarName(vi1));
- }
- }
- }
- retval=(berr<0)?-1:0;
- }
- free(dstag);
- free(lssh);
-
- if (!stencil_array)
- {
- free(sw);
- }
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Invalid variable names '%s' and/or '%s' in BndRadiativeVN",
+ vn_to, vn_from);
+ retval = -1;
}
- return retval;
+ return (retval);
}
-/*@@
- @routine BndApplyRadiative3Di
- @date May 2000
- @author Miguel Alcubierre
- @desc
- Implements radiative boundary condition.
-
- The radiative boundary condition that is implemented is:
-
-
- f = f0 + u(r - v*t) / r + h(r + v*t) / r
-
-
- That is, I assume outgoing radial waves with a 1/r
- fall off, and the correct asymptotic value f0, plus
- I include the possibility of incoming waves as well
- (these incoming waves should be modeled somehow).
-
- The condition above leads to the differential equation:
+void CCTK_FCALL CCTK_FNAME (BndRadiativeVN)
+ (int *ierr,
+ cGH *GH,
+ int stencil[],
+ const CCTK_REAL *var0,
+ const CCTK_REAL *speed,
+ TWO_FORTSTRINGS_ARGS)
+{
+ TWO_FORTSTRINGS_CREATE (vn_to, vn_from)
+ *ierr = BndRadiativeVN (GH, stencil, *var0, *speed, vn_to, vn_from);
+ free (vn_to);
+ free (vn_from);
+}
-
- (x / r) d f + v d f + v x (f - f0) / r^2 = v x H / r^2
- i t i i i
- where x_i is the normal direction to the given boundaries,
- and H = 2 dh(s)/ds.
+/********************************************************************
+ ********************* Local Routines *************************
+ ********************************************************************/
- So at a given boundary I only worry about derivatives in
- the normal direction. Notice that u(r-v*t) has dissapeared,
- but we still do not know the value of H.
+/* shortcut for multiplying a variable with itself */
+#define SQR(a) ((a) * (a))
- To get H what I do is the following: I evaluate the
- expression one point in from the boundary and solve for H
- there. We now need a way of extrapolation H to the boundary.
- For this I assume that H falls off as a power law:
+/* the maximum dimension we can deal with */
+#define MAXDIM 3
- H = k/r**n => d H = - n H/r
- i
+/*@@
+ @routine LOWER_RADIATIVE_BOUNDARY_3D
+ @date Mon 9 Apr 2001
+ @author Thomas Radke
+ @desc
+ Macro to apply radiative BC to a lower bound of a 3D variable
+ @enddesc
- The value of n is is defined by the parameter "radpower".
- If this parameter is negative, H is forced to be zero (this
- corresponds to pure outgoing waves and is the default).
+ @var istart, jstart, kstart
+ @vdesc start index for the x,y,z direction
+ @vtype int
+ @vio in
+ @endvar
+ @var xyz
+ @vdesc coordinate arrays for x, y, and z
+ @vtype CCTK_REAL [ MAXDIM ]
+ @vio in
+ @endvar
+ @var radius
+ @vdesc radius coordinate array
+ @vtype CCTK_REAL []
+ @vio in
+ @endvar
+ @var offset
+ @vdesc offset to the next element in this direction
+ @vtype int
+ @vio in
+ @endvar
+ @var var_to
+ @vdesc target variable array
+ @vtype cctk_type []
+ @vio in
+ @endvar
+ @var var_from
+ @vdesc source variable array
+ @vtype cctk_type []
+ @vio in
+ @endvar
+ @var cctk_type
+ @vdesc CCTK datatypes of the source and target variable
+ @vtype <cctk_type>
+ @vio in
+ @endvar
+@@*/
+#define LOWER_RADIATIVE_BOUNDARY_3D(istart, jstart, kstart, \
+ xyz, \
+ radius, \
+ offset, \
+ var_to, \
+ var_from, \
+ cctk_type) \
+{ \
+ int _i, _j, _k; \
+ \
+ \
+ for (_k = kstart-1; _k >= 0; _k--) \
+ { \
+ for (_j = jstart-1; _j >= 0; _j--) \
+ { \
+ int _0 = 0*offset, \
+ _1 = 1*offset, \
+ _2 = 2*offset; \
+ int _index = CCTK_GFINDEX3D (GH, istart-1, _j, _k); \
+ CCTK_REAL *_radius = radius + _index, \
+ *_xyz = xyz + _index; \
+ cctk_type *_to = (cctk_type *) (var_to) + _index, \
+ *_from = (cctk_type *) (var_from) + _index; \
+ \
+ \
+ for (_i = istart-1; _i >= 0; _i--) \
+ { \
+ CCTK_REAL _radius0_inv = 1/_radius[_0], \
+ _radius1_inv = 1/_radius[_1]; \
+ \
+ \
+ if (radpower > 0) \
+ { \
+ CCTK_REAL H; \
+ \
+ \
+ H = 0.25 * radpower * dxyz[0] \
+ * (_xyz[_0]*SQR (_radius0_inv) + _xyz[_1]*SQR (_radius1_inv)); \
+ H = (1 + H) / (1 - H); \
+ H *= dtv * (0.25*(_to[_1] + _to[_2] + _from[_1] + _from[_2]) - var0)\
+ + 0.5*( _radius[_1] * (_to[_1] - _from[_1]) \
+ + _radius[_2] * (_to[_2] - _from[_2])) \
+ + 0.25*(_to[_2] - _to[_1] + _from[_2] - _from[_1]) * rho[0] \
+ *( SQR (_radius[_1]) / _xyz[_1] \
+ + SQR (_radius[_2]) / _xyz[_2]); \
+ dtvvar0H = dtvvar0 + H; \
+ } \
+ \
+ _to[_0] = (cctk_type) ( \
+ (dtvvar0H * ( _xyz[_0] * SQR (_radius0_inv) \
+ + _xyz[_1] * SQR (_radius1_inv)) \
+ - _to[_1] * ( rho[0] + _xyz[_1]*_radius1_inv \
+ *(1 + dtvh*_radius1_inv))\
+ + _from[_0] * ( rho[0] + _xyz[_0]*_radius0_inv \
+ *(1 - dtvh*_radius0_inv))\
+ - _from[_1] * ( rho[0] - _xyz[_1]*_radius1_inv \
+ *(1 - dtvh*_radius1_inv))\
+ ) \
+ / (-rho[0] + _xyz[_0]*_radius0_inv \
+ *(1 + dtvh*_radius0_inv))\
+ ); \
+ _radius--; _xyz--; _to--; _from--; \
+ } \
+ } \
+ } \
+}
- The behaviour I have observed is the following: Using H=0
- is very stable, but has a very bad initial transient. Taking
- n to be 0 or positive improves the initial behaviour considerably,
- but introduces a drift that can kill the evolution at very late
- times. Empirically, the best value I have found is n=2, for
- which the initial behaviour is very nice, and the late time drift
- is quite small.
- Another problem with this condition is that it does not
- use the physical characteristic speed, but rather it assumes
- a wave speed of v, so the boundaries should be out in
- the region where the characteristic speed is constant.
- Notice that this speed does not have to be 1. For gauge
- quantities {alpha,phi,trK} we can have a different asymptotic
- speed, which is why the value of v is passed as a parameter.
+/*@@
+ @routine UPPER_RADIATIVE_BOUNDARY_3D
+ @date Mon 9 Apr 2001
+ @author Thomas Radke
+ @desc
+ Macro to apply radiative BC to an upper bound of a 3D variable
+ @enddesc
+ @var istart, jstart, kstart
+ @vdesc start index for the x,y,z direction
+ @vtype int
+ @vio in
+ @endvar
+ @var xyz
+ @vdesc coordinate arrays for x, y, and z
+ @vtype CCTK_REAL [ MAXDIM ]
+ @vio in
+ @endvar
+ @var radius
+ @vdesc radius coordinate array
+ @vtype CCTK_REAL []
+ @vio in
+ @endvar
+ @var offset
+ @vdesc offset to the next element in this direction
+ @vtype int
+ @vio in
+ @endvar
+ @var var_to
+ @vdesc target variable array
+ @vtype cctk_type []
+ @vio in
+ @endvar
+ @var var_from
+ @vdesc source variable array
+ @vtype cctk_type []
+ @vio in
+ @endvar
+ @var cctk_type
+ @vdesc CCTK datatypes of the source and target variable
+ @vtype <cctk_type>
+ @vio in
+ @endvar
+@@*/
+#define UPPER_RADIATIVE_BOUNDARY_3D(istart, jstart, kstart, \
+ xyz, \
+ radius, \
+ offset, \
+ var_to, \
+ var_from, \
+ cctk_type) \
+{ \
+ int _i, _j, _k; \
+ \
+ \
+ for (_k = kstart; _k < GH->cctk_lsh[2]; _k++) \
+ { \
+ for (_j = jstart; _j < GH->cctk_lsh[1]; _j++) \
+ { \
+ int _0 = -0*offset, \
+ _1 = -1*offset, \
+ _2 = -2*offset; \
+ int _index = CCTK_GFINDEX3D (GH, istart, _j, _k); \
+ CCTK_REAL *_radius = radius + _index, \
+ *_xyz = xyz + _index; \
+ cctk_type *_to = (cctk_type *) (var_to) + _index, \
+ *_from = (cctk_type *) (var_from) + _index; \
+ \
+ \
+ for (_i = istart; _i < GH->cctk_lsh[0]; _i++) \
+ { \
+ CCTK_REAL _radius0_inv = 1/_radius[_0], \
+ _radius1_inv = 1/_radius[_1]; \
+ \
+ \
+ if (radpower > 0) \
+ { \
+ CCTK_REAL H; \
+ \
+ \
+ H = 0.25 * radpower * dxyz[0] \
+ * (_xyz[_0]*SQR (_radius0_inv) + _xyz[_1]*SQR (_radius1_inv)); \
+ H = (1 - H) / (1 + H); \
+ H *= dtv * (0.25*(_to[_1] + _to[_2] + _from[_1] + _from[_2]) - var0)\
+ + 0.5 *( _radius[_1] * (_to[_1] - _from[_1]) \
+ + _radius[_2] * (_to[_2] - _from[_2])) \
+ + 0.25*(_to[_1] - _to[_2] + _from[_1] - _from[_2]) * rho[0] \
+ * ( SQR (_radius[_1]) / _xyz[_1] \
+ + SQR (_radius[_2]) / _xyz[_2]); \
+ dtvvar0H = dtvvar0 + H; \
+ } \
+ \
+ _to[_0] = (cctk_type) ( \
+ (dtvvar0H * ( _xyz[_0] * (SQR (_radius0_inv)) \
+ + _xyz[_1] * (SQR (_radius1_inv))) \
+ + _to[_1] * ( rho[0] - _xyz[_1]*_radius1_inv \
+ *(1 + dtvh*_radius1_inv))\
+ + _from[_0] * (-rho[0] + _xyz[_0]*_radius0_inv \
+ *(1 - dtvh*_radius0_inv))\
+ + _from[_1] * ( rho[0] + _xyz[_1]*_radius1_inv \
+ *(1 - dtvh*_radius1_inv))\
+ ) \
+ / ( rho[0] + _xyz[_0]*_radius0_inv \
+ *(1 + dtvh*_radius0_inv))\
+ ); \
+ _radius++; _xyz++; _to++; _from++; \
+ } \
+ } \
+ } \
+}
- Some remarks on the C version for Fortran programmers:
- This is 1:1 translation of the F code, which used the very
- nice looking F array assignments x(2,:,:), etc. In C this
- needs to be written as loops, but to my surprise it doesn't
- look too bad actually. F statments like x(1,:,:) become x(xgp0)
- (the integer index "xgp0" meaning the zeroth gridpoint from
- the boundary), x(2,:,:) --> x(xgp1), where:
+/*@@
+ @routine RADIATIVE_BOUNDARY
+ @date Mon 9 Apr 2001
+ @author Thomas Radke
+ @desc
+ Macro to apply radiative BC to a variable
+ Currently it is limited to 3D variables only.
+ @enddesc
+ @calls LOWER_RADIATIVE_BOUNDARY_3D
+ UPPER_RADIATIVE_BOUNDARY_3D
+
+ @var lsh
+ @vdesc local shape of the variable
+ @vtype int [ dim ]
+ @vio in
+ @endvar
+ @var doBC
+ @vdesc flags telling whether to apply BC in a given direction or not
+ @vtype int [ 2*dim ]
+ @vio in
+ @endvar
+ @var stencil
+ @vdesc stencils in every direction
+ @vtype int [ 2*dim ]
+ @vio in
+ @endvar
+ @var coords
+ @vdesc coordinate arrays for x, y, z, and the radius
+ @vtype CCTK_REAL [ MAXDIM+1 ]
+ @vio in
+ @endvar
+ @var offset
+ @vdesc offsets to the next element in each dimension
+ @vtype int [ dim ]
+ @vio in
+ @endvar
+ @var var_to
+ @vdesc target variable array
+ @vtype cctk_type []
+ @vio in
+ @endvar
+ @var var_from
+ @vdesc source variable array
+ @vtype cctk_type []
+ @vio in
+ @endvar
+ @var dim
+ @vdesc dimension of the source and target variable
+ @vtype int
+ @vio in
+ @endvar
+ @var cctk_type
+ @vdesc CCTK datatypes of the source and target variable
+ @vtype <cctk_type>
+ @vio in
+ @endvar
+@@*/
+#define RADIATIVE_BOUNDARY(lsh, \
+ doBC, \
+ stencil, \
+ coords, \
+ offset, \
+ var_to, \
+ var_from, \
+ dim, \
+ cctk_type) \
+{ \
+ /* check the dimensionality */ \
+ if (dim != 3) \
+ { \
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, \
+ "ApplyBndRadiative: variable dimension of %d not supported", \
+ dim); \
+ return (-5); \
+ } \
+ \
+ /* Lower x-bound */ \
+ if (doBC[0]) \
+ { \
+ LOWER_RADIATIVE_BOUNDARY_3D (stencil[0], lsh[1], lsh[2], \
+ coords[0], coords[MAXDIM], offset[0], \
+ var_to, var_from, cctk_type); \
+ } \
+ \
+ /* Upper x-bound */ \
+ if (doBC[1]) \
+ { \
+ UPPER_RADIATIVE_BOUNDARY_3D (lsh[0] - stencil[0], 0, 0, \
+ coords[0], coords[MAXDIM], offset[0], \
+ var_to, var_from, cctk_type); \
+ } \
+ \
+ /* Lower y-bound */ \
+ if (doBC[2]) \
+ { \
+ LOWER_RADIATIVE_BOUNDARY_3D (lsh[0], stencil[1], lsh[2], \
+ coords[1], coords[MAXDIM], offset[1], \
+ var_to, var_from, cctk_type); \
+ } \
+ \
+ /* Upper y-bound */ \
+ if (doBC[3]) \
+ { \
+ UPPER_RADIATIVE_BOUNDARY_3D (0, lsh[1] - stencil[1], 0, \
+ coords[1], coords[MAXDIM], offset[1], \
+ var_to, var_from, cctk_type); \
+ } \
+ \
+ /* Lower z-bound */ \
+ if (doBC[4]) \
+ { \
+ LOWER_RADIATIVE_BOUNDARY_3D (lsh[0], lsh[1], stencil[2], \
+ coords[2], coords[MAXDIM], offset[2], \
+ var_to, var_from, cctk_type); \
+ } \
+ \
+ /* Upper z-bound */ \
+ if (doBC[5]) \
+ { \
+ UPPER_RADIATIVE_BOUNDARY_3D (0, 0, lsh[2] - stencil[2], \
+ coords[2], coords[MAXDIM], offset[2], \
+ var_to, var_from, cctk_type); \
+ } \
+}
- xgp0 = CCTK_GFINDEX3D(GH,0,j,k)
- xgp1 = CCTK_GFINDEX3D(GH,1,j,k)
- and i,j are looping of the grid sizes.
+/*@@
+ @routine ApplyBndRadiative
+ @date Tue Jul 18 18:04:07 2000
+ @author Gerd Lanfermann
+ @desc
+ Apply radiation boundary conditions to a group of grid functions
+ given by their indices
+ This routine is called by the various BndRadiativeXXX wrappers.
+ Although it is currently limited to handle 3D variables only
+ it can easily be extended for other dimensions
+ by adapting the appropriate macros.
@enddesc
- @calls
- @calledby
+
+ @var GH
+ @vdesc Pointer to CCTK grid hierarchy
+ @vtype cGH *
+ @vio in
+ @endvar
+ @var stencil_dir
+ @vdesc stencil width in direction dir
+ @vtype int
+ @vio in
+ @endvar
+ @var stencil_alldirs
+ @vdesc stencil widths for all directions
+ @vtype int [ dimension of variable(s) ]
+ @vio in
+ @endvar
+ @var dir
+ @vdesc direction to copy boundaries (0 for copying all directions)
+ @vtype int
+ @vio in
+ @endvar
+ @var var0
+ @vdesc asymptotic value of function at infinity
+ @vtype CCTK_REAL
+ @vio in
+ @endvar
+ @var speed
+ @vdesc wave speed
+ @vtype CCTK_REAL
+ @vio in
+ @endvar
+ @var first_var_to
+ @vdesc index of first variable to copy boundaries to
+ @vtype int
+ @vio in
+ @endvar
+ @var first_var_from
+ @vdesc index of first variable to copy boundaries from
+ @vtype int
+ @vio in
+ @endvar
+ @var num_vars
+ @vdesc number of variables
+ @vtype int
+ @vio in
+ @endvar
+ CCTK_VarTypeI
+ CCTK_GroupDimFromVarI
+ CCTK_NumTimeLevelsFromVarI
+ RADIATIVE_BOUNDARY
@history
- Cactus 4.0 by Gerd Lanfermann
+ @hdate Mon 9 Apr 2001
+ @hauthor Thomas Radke
+ @hdesc Merged separate routines for 1D, 2D, and 3D
+ into a single generic routine
@endhistory
-@@*/
-static int BndApplyRadiative3Di(cGH *GH,
- int doBC,
- int *lssh,
- int *sw,
- CCTK_REAL *dxyz,
- CCTK_REAL dt,
- CCTK_REAL *var_n,
- CCTK_REAL *var_p,
- CCTK_REAL *x,
- CCTK_REAL *y,
- CCTK_REAL *z,
- CCTK_REAL *r,
- CCTK_REAL var0,
- CCTK_REAL speed)
+ @returntype int
+ @returndesc
+ 0 for success
+ -1 if abs(direction) is greater than variables' dimension
+ -2 if variable dimension is not supported
+ -3 if NULL pointer passed as stencil array
+ -4 if variable type is not supported
+ -5 if variable dimension is other than 3D
+ @endreturndesc
+@@*/
+static int ApplyBndRadiative (cGH *GH,
+ int stencil_dir,
+ int stencil_alldirs[],
+ int dir,
+ CCTK_REAL var0,
+ CCTK_REAL speed,
+ int first_var_to,
+ int first_var_from,
+ int num_vars)
{
-
DECLARE_CCTK_PARAMETERS
+ int i, gdim;
+ int var_to, var_from;
+ int timelvl_to, timelvl_from;
+ SymmetryGHex *sGHex;
+ char coord_system_name[10];
+ CCTK_REAL dxyz[MAXDIM], rho[MAXDIM], *coords[MAXDIM+1];
+ int doBC[2*MAXDIM], stencil[MAXDIM], offset[MAXDIM];
+ CCTK_REAL dtv, dtvh, dtvvar0, dtvvar0H;
- int i,j,k;
-
- CCTK_REAL dtv,dtvh,dtvvar0;
- CCTK_REAL dx,dy,dz;
- CCTK_REAL rhox,rhoy,rhoz;
- CCTK_REAL H,fac,aux;
- CCTK_REAL half,one;
-
- /* Linear grid point index, used to access the 0th/1st gridpoint away
- from the BC in the calculation.
- In Fortran,
- x(1,:,:) --> x[xgp0],
- x(2,:,:) --> x[xgp1],
- where xgp0/1 are calculated with CCTK_GFINDEX3D */
-
- int xgp0,xgp1,xgp2,ygp0,ygp1,ygp2,zgp0,zgp1,zgp2;
-
- CCTK_REAL u0,u1,u2;
- CCTK_REAL ui1,ui2;
- CCTK_REAL r0,r1,r2;
- CCTK_REAL ri0,ri1;
-
- /* Grid sizes */
-
- int lssh0, lssh1, lssh2;
-
- /* stencil widths */
-
- int sw0, sw1, sw2;
-
- /* Grid parameters. */
-
- dx = dxyz[0];
- dy = dxyz[1];
- dz = dxyz[2];
-
- /* Numbers */
-
- half = 0.5;
- one = 1.0;
-
- /* Store the grid shape in local variables to help the optimiser */
-
- lssh0 = lssh[0];
- lssh1 = lssh[1];
- lssh2 = lssh[2];
-
- /* Ditto with the stencil widths */
-
- sw0 = sw[0];
- sw1 = sw[1];
- sw2 = sw[2];
-
- /* Find Courant parameters. */
-
- dtv = speed*dt;
- dtvh = half*dtv;
- dtvvar0 = dtv*var0;
+ /* check the direction parameter */
+ if (abs (dir) > MAXDIM)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "ApplyBndRadiative: direction %d is greater than maximum "
+ "dimension %d", dir, MAXDIM);
+ return (-1);
+ }
- rhox = dtv/dx;
- rhoy = dtv/dy;
- rhoz = dtv/dz;
+ /* get the dimensionality */
+ gdim = CCTK_GroupDimFromVarI (first_var_to);
- /* Extrapolation power */
+ /* check the dimensionality */
+ if (gdim > MAXDIM)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "ApplyBndRadiative: variable dimension of %d not supported",
+ gdim);
+ return (-2);
+ }
- if (radpower<0)
+ /* set up stencil width array */
+ if (dir)
{
- fac = 0;
- }
- else
+ stencil[abs (dir) - 1] = stencil_dir;
+ }
+ else if (stencil_alldirs)
{
- fac = radpower;
+ memcpy (stencil, stencil_alldirs, gdim * sizeof (int));
}
-
- /* Lower x-bound: x(2,:,:) --> x[xgp2] */
-
- if (doBC == 0)
+ else
{
-#ifdef DEBUG_BOUNDARY
- printf("Applying radiative boundary (lower x)\n");
-#endif
- for (k=0;k<lssh2;k++)
- {
- for (j=0;j<lssh1;j++)
- {
- for (i=sw0-1;i>=0;i--)
- {
- xgp0 = CCTK_GFINDEX3D(GH,i ,j,k);
- xgp1 = CCTK_GFINDEX3D(GH,i+1,j,k);
- xgp2 = CCTK_GFINDEX3D(GH,i+2,j,k);
-
- u0 = x[xgp0];
- u1 = x[xgp1];
- u2 = x[xgp2];
-
- r0 = r[xgp0];
- r1 = r[xgp1];
- r2 = r[xgp2];
-
- ui1 = 1.0/u1;
- ui2 = 1.0/u2;
-
- ri0 = 1.0/r0;
- ri1 = 1.0/r1;
-
- if (fac==0)
- {
-
- H = 0;
-
- }
- else
- {
-
- H = 0;
-
- H = dtv*(-var0 + 0.25
- *(var_n[xgp1] + var_n[xgp2]
- + var_p[xgp1] + var_p[xgp2]))
- +(r1*(var_n[xgp1] - var_p[xgp1])
- + r2*(var_n[xgp2] - var_p[xgp2]))*half
- + 0.25*rhox*(SQR(r1)*ui1 + SQR(r2)*ui2)
- *(var_n[xgp2] - var_n[xgp1]
- + var_p[xgp2] - var_p[xgp1]);
-
- aux = 0.25*radpower*dx*(u0*SQR(ri0) + u1*SQR(ri1));
-
- H = H*(one + aux)/(one - aux);
-
- }
-
- var_n[xgp0] =
- ((dtvvar0 + H)*(u0*SQR(ri0) + u1*SQR(ri1))
- - var_n[xgp1]*( rhox + u1*ri1*(one + dtvh*ri1))
- + var_p[xgp0]*( rhox + u0*ri0*(one - dtvh*ri0))
- - var_p[xgp1]*( rhox - u1*ri1*(one - dtvh*ri1)))
- / (-rhox + u0*ri0*(one + dtvh*ri0));
-
- }
- }
- }
+ CCTK_WARN (1, "ApplyBndRadiative: NULL pointer passed "
+ "for stencil width array");
+ return (-3);
}
- /* Upper x-bound: x(nx,:,:) --> xgp[xgp0] */
-
- if (doBC == 1)
+ /* Use next time level, if available */
+ timelvl_to = CCTK_NumTimeLevelsFromVarI (first_var_to) - 1;
+ if (timelvl_to < 0)
{
-#ifdef DEBUG_BOUNDARY
- printf("Applying radiative boundary (upper x)\n");
-#endif
- for (k=0;k<lssh2;k++)
- {
- for (j=0;j<lssh1;j++)
- {
- for (i=lssh0-sw0;i<lssh0;i++)
- {
-
- xgp0 = CCTK_GFINDEX3D(GH,i ,j,k);
- xgp1 = CCTK_GFINDEX3D(GH,i-1,j,k);
- xgp2 = CCTK_GFINDEX3D(GH,i-2,j,k);
-
- u0 = x[xgp0];
- u1 = x[xgp1];
- u2 = x[xgp2];
-
- r0 = r[xgp0];
- r1 = r[xgp1];
- r2 = r[xgp2];
-
- ui1 = 1.0/u1;
- ui2 = 1.0/u2;
-
- ri0 = 1.0/r0;
- ri1 = 1.0/r1;
-
- if (fac==0)
- {
-
- H = 0;
-
- }
- else
- {
-
- H = 0;
-
- H = dtv*(-var0 + 0.25
- *(var_n[xgp1] + var_n[xgp2]
- + var_p[xgp1] + var_p[xgp2]))
- +(r1*(var_n[xgp1] - var_p[xgp1])
- + r2*(var_n[xgp2] - var_p[xgp2]))*half
- + 0.25*rhox*(SQR(r1)*ui1 + SQR(r2)*ui2)
- *(var_n[xgp1] - var_n[xgp2]
- + var_p[xgp1] - var_p[xgp2]);
-
- aux = 0.25*radpower*dx*(u0*SQR(ri0) + u1*SQR(ri1));
-
- H = H*(one - aux)/(one + aux);
-
- }
-
- var_n[xgp0] =
- ((dtvvar0 + H)*(u0*(SQR(ri0)) + u1*(SQR(ri1)))
- + var_n[xgp1]*( rhox - u1*ri1*(one + dtvh*ri1))
- + var_p[xgp0]*(-rhox + u0*ri0*(one - dtvh*ri0))
- + var_p[xgp1]*( rhox + u1*ri1*(one - dtvh*ri1)))
- / ( rhox + u0*ri0*(one + dtvh*ri0));
-
- }
- }
- }
+ timelvl_to = 0;
}
-
- /* Lower y-bound */
-
- if (doBC == 2)
+ /* Use current time level, if available */
+ timelvl_from = CCTK_NumTimeLevelsFromVarI (first_var_from) - 2;
+ if (timelvl_from < 0)
{
-#ifdef DEBUG_BOUNDARY
- printf("Applying radiative boundary (lower y)\n");
-#endif
- for (k=0;k<lssh2;k++)
- {
- for (i=0;i<lssh0;i++)
- {
- for (j=sw1-1;j>=0;j--)
- {
- ygp0 = CCTK_GFINDEX3D(GH,i,j ,k);
- ygp1 = CCTK_GFINDEX3D(GH,i,j+1,k);
- ygp2 = CCTK_GFINDEX3D(GH,i,j+2,k);
-
- u0 = y[ygp0];
- u1 = y[ygp1];
- u2 = y[ygp2];
-
- r0 = r[ygp0];
- r1 = r[ygp1];
- r2 = r[ygp2];
-
- ui1 = 1.0/u1;
- ui2 = 1.0/u2;
-
- ri0 = 1.0/r0;
- ri1 = 1.0/r1;
-
- if (fac==0)
- {
-
- H = 0;
-
- }
- else
- {
-
- H = 0;
-
- H = dtv*(-var0 + 0.25
- *(var_n[ygp1] + var_n[ygp2]
- + var_p[ygp1] + var_p[ygp2]))
- +(r1*(var_n[ygp1] - var_p[ygp1])
- + r2*(var_n[ygp2] - var_p[ygp2]))*half
- + 0.25*rhoy*(SQR(r1)*ui1 + SQR(r2)*ui2)
- *(var_n[ygp2] - var_n[ygp1]
- + var_p[ygp2] - var_p[ygp1]);
+ timelvl_from = 0;
+ }
- aux = 0.25*radpower*dy*(u0*SQR(ri0) + u1*SQR(ri1));
+ /* Find Courant parameters. */
+ dtv = speed * GH->cctk_delta_time;
+ dtvh = 0.5 * dtv;
+ dtvvar0 = dtv * var0;
+ dtvvar0H = dtvvar0;
- H = H*(one + aux)/(one - aux);
+ sprintf (coord_system_name, "cart%dd", gdim);
+ for (i = 0; i < gdim; i++)
+ {
+ /* Radiative boundaries need the underlying Cartesian coordinates */
+ coords[i] = GH->data[CCTK_CoordIndex (i + 1, NULL, coord_system_name)][0];
- }
+ /* According to the Cactus spec, the true delta_space values for a
+ grid are calculated as follows: */
+ dxyz[i] = GH->cctk_delta_space[i] / GH->cctk_levfac[i];
- var_n[ygp0] =
- ((dtvvar0 + H)*(u0*SQR(ri0) + u1*SQR(ri1))
- - var_n[ygp1]*( rhoy + u1*ri1*(one + dtvh*ri1))
- + var_p[ygp0]*( rhoy + u0*ri0*(one - dtvh*ri0))
- - var_p[ygp1]*( rhoy - u1*ri1*(one - dtvh*ri1)))
- / (-rhoy + u0*ri0*(one + dtvh*ri0));
+ rho[i] = dtv / dxyz[i];
- }
- }
- }
+ offset[i] = i == 0 ? 1 : offset[i-1] * GH->cctk_lsh[i-1];
}
+ sprintf (coord_system_name, "spher%dd", gdim);
+ coords[MAXDIM] = GH->data[CCTK_CoordIndex (-1, "r", coord_system_name)][0];
- /* Upper y bound */
+ /* see if we have a symmetry array */
+ sGHex = (SymmetryGHex *) CCTK_GHExtension (GH, "Symmetry");
- if (doBC == 3)
+ /* now loop over all variables */
+ for (var_to = first_var_to, var_from = first_var_from;
+ var_to < first_var_to + num_vars;
+ var_to++, var_from++)
{
-#ifdef DEBUG_BOUNDARY
- printf("Applying radiative boundary (upper y)\n");
-#endif
- for (k=0;k<lssh2;k++)
+ /* Apply condition if:
+ + boundary is not a symmetry boundary
+ (no symmetry or unset(=unsed))
+ + boundary is a physical boundary
+ + have enough grid points
+ */
+ memset (doBC, 1, sizeof (doBC));
+ if (sGHex)
{
- for (i=0;i<lssh0;i++)
+ for (i = 0; i < 2 * MAXDIM; i++)
{
- for (j=lssh1-sw1;j<lssh1;j++)
- {
-
- ygp0 = CCTK_GFINDEX3D(GH,i,j ,k);
- ygp1 = CCTK_GFINDEX3D(GH,i,j-1,k);
- ygp2 = CCTK_GFINDEX3D(GH,i,j-2,k);
-
- u0 = y[ygp0];
- u1 = y[ygp1];
- u2 = y[ygp2];
-
- r0 = r[ygp0];
- r1 = r[ygp1];
- r2 = r[ygp2];
-
- ui1 = 1.0/u1;
- ui2 = 1.0/u2;
-
- ri0 = 1.0/r0;
- ri1 = 1.0/r1;
-
- if (fac==0)
- {
-
- H = 0;
-
- }
- else
- {
-
- H = 0;
-
- H = dtv*(-var0 + 0.25
- *(var_n[ygp1] + var_n[ygp2]
- + var_p[ygp1] + var_p[ygp2]))
- +(r1*(var_n[ygp1] - var_p[ygp1])
- + r2*(var_n[ygp2] - var_p[ygp2]))*half
- + 0.25*rhoy*(SQR(r1)*ui1 + SQR(r2)*ui2)
- *(var_n[ygp1] - var_n[ygp2]
- + var_p[ygp1] - var_p[ygp2]);
-
- aux = 0.25*radpower*dy*(u0*SQR(ri0) + u1*SQR(ri1));
-
- H = H*(one - aux)/(one + aux);
-
- }
-
- var_n[ygp0] =
- ((dtvvar0 + H)*(u0*(SQR(ri0)) + u1*(SQR(ri1)))
- + var_n[ygp1]*( rhoy - u1*ri1*(one + dtvh*ri1))
- + var_p[ygp0]*(-rhoy + u0*ri0*(one - dtvh*ri0))
- + var_p[ygp1]*( rhoy + u1*ri1*(one - dtvh*ri1)))
- / ( rhoy + u0*ri0*(one + dtvh*ri0));
-
- }
+ doBC[i] = sGHex->GFSym[var_to][i] == GFSYM_NOSYM ||
+ sGHex->GFSym[var_to][i] == GFSYM_UNSET;
}
}
- }
-
- /* Lower z-bound */
-
- if (doBC==4)
- {
-#ifdef DEBUG_BOUNDARY
- printf("Applying radiative boundary (lower z)\n");
-#endif
- for (j=0;j<lssh1;j++)
+ for (i = 0; i < MAXDIM; i++)
{
- for (i=0;i<lssh0;i++)
+ doBC[i*2] &= GH->cctk_lsh[i] > 1 && GH->cctk_bbox[i*2];
+ doBC[i*2+1] &= GH->cctk_lsh[i] > 1 && GH->cctk_bbox[i*2+1];
+ if (dir != 0)
{
- for (k=sw2-1;k>=0;k--)
- {
-
- zgp0 = CCTK_GFINDEX3D(GH,i,j,k );
- zgp1 = CCTK_GFINDEX3D(GH,i,j,k+1);
- zgp2 = CCTK_GFINDEX3D(GH,i,j,k+2);
-
- u0 = z[zgp0];
- u1 = z[zgp1];
- u2 = z[zgp2];
-
- r0 = r[zgp0];
- r1 = r[zgp1];
- r2 = r[zgp2];
-
- ui1 = 1.0/u1;
- ui2 = 1.0/u2;
-
- ri0 = 1.0/r0;
- ri1 = 1.0/r1;
-
- if (fac==0)
- {
-
- H = 0;
-
- }
- else
- {
-
- H = 0;
-
- H = dtv*(-var0 + 0.25
- *(var_n[zgp1] + var_n[zgp2]
- + var_p[zgp1] + var_p[zgp2]))
- +(r1*(var_n[zgp1] - var_p[zgp1])
- + r2*(var_n[zgp2] - var_p[zgp2]))*half
- + 0.25*rhoz*(SQR(r1)*ui1 + SQR(r2)*ui2)
- *(var_n[zgp2] - var_n[zgp1]
- + var_p[zgp2] - var_p[zgp1]);
-
- aux = 0.25*radpower*dz*(u0*SQR(ri0) + u1*SQR(ri1));
-
- H = H*(one + aux)/(one - aux);
-
- }
-
- var_n[zgp0] =
- ((dtvvar0 + H)*(u0*SQR(ri0) + u1*SQR(ri1))
- - var_n[zgp1]*( rhoz + u1*ri1*(one + dtvh*ri1))
- + var_p[zgp0]*( rhoz + u0*ri0*(one - dtvh*ri0))
- - var_p[zgp1]*( rhoz - u1*ri1*(one - dtvh*ri1)))
- / (-rhoz + u0*ri0*(one + dtvh*ri0));
-
- }
+ doBC[i*2] &= (dir < 0 && (i + 1 == abs (dir)));
+ doBC[i*2+1] &= (dir > 0 && (i + 1 == abs (dir)));
}
}
- }
- /* Upper z-bound */
-
- if (doBC == 5)
- {
-#ifdef DEBUG_BOUNDARY
- printf("Applying radiative boundary (upper z)\n");
-#endif
- for (j=0;j<lssh1;j++)
+ switch (CCTK_VarTypeI (var_to))
{
- for (i=0;i<lssh0;i++)
- {
- for (k=lssh2-sw2;k<lssh2;k++)
- {
-
- zgp0 = CCTK_GFINDEX3D(GH,i,j,k );
- zgp1 = CCTK_GFINDEX3D(GH,i,j,k-1);
- zgp2 = CCTK_GFINDEX3D(GH,i,j,k-2);
-
- u0 = z[zgp0];
- u1 = z[zgp1];
- u2 = z[zgp2];
-
- r0 = r[zgp0];
- r1 = r[zgp1];
- r2 = r[zgp2];
-
- ui1 = 1.0/u1;
- ui2 = 1.0/u2;
-
- ri0 = 1.0/r0;
- ri1 = 1.0/r1;
-
- if (fac==0)
- {
-
- H = 0;
-
- }
- else
- {
-
- H = 0;
+ case CCTK_VARIABLE_CHAR:
+ RADIATIVE_BOUNDARY (GH->cctk_lsh, doBC, stencil, coords, offset,
+ GH->data[var_to][timelvl_to],
+ GH->data[var_from][timelvl_from], gdim, CCTK_CHAR);
+ break;
+
+ case CCTK_VARIABLE_INT:
+ RADIATIVE_BOUNDARY (GH->cctk_lsh, doBC, stencil, coords, offset,
+ GH->data[var_to][timelvl_to],
+ GH->data[var_from][timelvl_from], gdim, CCTK_INT);
+ break;
+
+ case CCTK_VARIABLE_REAL:
+ RADIATIVE_BOUNDARY (GH->cctk_lsh, doBC, stencil, coords, offset,
+ GH->data[var_to][timelvl_to],
+ GH->data[var_from][timelvl_from], gdim, CCTK_REAL);
+ break;
+
+#ifdef CCTK_VARIABLE_INT2
+ case CCTK_VARIABLE_INT2:
+ RADIATIVE_BOUNDARY (GH->cctk_lsh, doBC, stencil, coords, offset,
+ GH->data[var_to][timelvl_to],
+ GH->data[var_from][timelvl_from], gdim, CCTK_INT2);
+ break;
+#endif
- H = dtv*(-var0 + 0.25
- *(var_n[zgp1] + var_n[zgp2]
- + var_p[zgp1] + var_p[zgp2]))
- +(r1*(var_n[zgp1] - var_p[zgp1])
- + r2*(var_n[zgp2] - var_p[zgp2]))*half
- + 0.25*rhoz*(SQR(r1)*ui1 + SQR(r2)*ui2)
- *(var_n[zgp1] - var_n[zgp2]
- + var_p[zgp1] - var_p[zgp2]);
+#ifdef CCTK_VARIABLE_INT4
+ case CCTK_VARIABLE_INT4:
+ RADIATIVE_BOUNDARY (GH->cctk_lsh, doBC, stencil, coords, offset,
+ GH->data[var_to][timelvl_to],
+ GH->data[var_from][timelvl_from], gdim, CCTK_INT4);
+ break;
+#endif
- aux = 0.25*radpower*dz*(u0*SQR(ri0) + u1*SQR(ri1));
+#ifdef CCTK_VARIABLE_INT8
+ case CCTK_VARIABLE_INT8:
+ RADIATIVE_BOUNDARY (GH->cctk_lsh, doBC, stencil, coords, offset,
+ GH->data[var_to][timelvl_to],
+ GH->data[var_from][timelvl_from], gdim, CCTK_INT8);
+ break;
+#endif
- H = H*(one - aux)/(one + aux);
+#ifdef CCTK_REAL4
+ case CCTK_VARIABLE_REAL4:
+ RADIATIVE_BOUNDARY (GH->cctk_lsh, doBC, stencil, coords, offset,
+ GH->data[var_to][timelvl_to],
+ GH->data[var_from][timelvl_from], gdim, CCTK_REAL4);
+ break;
+#endif
- }
+#ifdef CCTK_REAL8
+ case CCTK_VARIABLE_REAL8:
+ RADIATIVE_BOUNDARY (GH->cctk_lsh, doBC, stencil, coords, offset,
+ GH->data[var_to][timelvl_to],
+ GH->data[var_from][timelvl_from], gdim, CCTK_REAL8);
+ break;
+#endif
- var_n[zgp0] =
- ((dtvvar0 + H)*(u0*(SQR(ri0)) + u1*(SQR(ri1)))
- + var_n[zgp1]*( rhoz - u1*ri1*(one + dtvh*ri1))
- + var_p[zgp0]*(-rhoz + u0*ri0*(one - dtvh*ri0))
- + var_p[zgp1]*( rhoz + u1*ri1*(one - dtvh*ri1)))
- / ( rhoz + u0*ri0*(one + dtvh*ri0));
+#ifdef CCTK_REAL16
+ case CCTK_VARIABLE_REAL16:
+ RADIATIVE_BOUNDARY (GH->cctk_lsh, doBC, stencil, coords, offset,
+ GH->data[var_to][timelvl_to],
+ GH->data[var_from][timelvl_from], gdim,CCTK_REAL16);
+ break;
+#endif
- }
- }
+ default:
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Unsupported variable type %d for variable '%s'",
+ CCTK_VarTypeI (var_to), CCTK_VarName (var_to));
+ return (-4);
}
}
- return 0;
-}
-
-
+ return (0);
+}