aboutsummaryrefslogtreecommitdiff
path: root/src/puncture_tracker.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/puncture_tracker.c')
-rw-r--r--src/puncture_tracker.c285
1 files changed, 285 insertions, 0 deletions
diff --git a/src/puncture_tracker.c b/src/puncture_tracker.c
new file mode 100644
index 0000000..d3da795
--- /dev/null
+++ b/src/puncture_tracker.c
@@ -0,0 +1,285 @@
+#include <assert.h>
+#include <stdio.h>
+
+#include "cctk.h"
+#include "cctk_Arguments.h"
+#include "cctk_Parameters.h"
+
+#include "util_Table.h"
+
+
+
+static int const max_num_tracked = 10;
+
+
+
+void
+PunctureTracker_Init (CCTK_ARGUMENTS)
+{
+ DECLARE_CCTK_ARGUMENTS;
+ DECLARE_CCTK_PARAMETERS;
+
+ if (verbose) {
+ CCTK_INFO ("Initializing PunctureTracker");
+ }
+
+ for (int n = 0; n < max_num_tracked; ++ n) {
+ if (track[n]) {
+ pt_loc_t[n] = cctk_time;
+ pt_loc_x[n] = initial_x[n];
+ pt_loc_y[n] = initial_y[n];
+ pt_loc_z[n] = initial_z[n];
+ } else {
+ // Initialise to some sensible but unimportant values
+ pt_loc_t[n] = 0.0;
+ pt_loc_x[n] = 0.0;
+ pt_loc_y[n] = 0.0;
+ pt_loc_z[n] = 0.0;
+ }
+ pt_loc_t_p[n] = 0.0;
+ pt_loc_x_p[n] = 0.0;
+ pt_loc_y_p[n] = 0.0;
+ pt_loc_z_p[n] = 0.0;
+ }
+}
+
+
+
+void
+PunctureTracker_Track (CCTK_ARGUMENTS)
+{
+ DECLARE_CCTK_ARGUMENTS;
+ DECLARE_CCTK_PARAMETERS;
+
+ // Do not track while setting up initial data;
+ // time interpolation may fail
+
+ if (cctk_iteration == 0) {
+ return;
+ }
+
+ // Some output
+
+ if (verbose) {
+ CCTK_INFO ("Tracking punctures...");
+ }
+
+ if (verbose) {
+ for (int n = 0; n < max_num_tracked; ++ n) {
+ if (track[n]) {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "Puncture #%d is at (%g,%g,%g)",
+ n,
+ (double)pt_loc_x[n],
+ (double)pt_loc_y[n],
+ (double)pt_loc_z[n]);
+ }
+ }
+ }
+
+ // Manual time level cycling
+
+ for (int n = 0; n < max_num_tracked; ++ n) {
+ if (track[n]) {
+ pt_loc_t_p[n] = pt_loc_t[n];
+ pt_loc_x_p[n] = pt_loc_x[n];
+ pt_loc_y_p[n] = pt_loc_y[n];
+ pt_loc_z_p[n] = pt_loc_z[n];
+
+ pt_loc_t[n] = cctk_time;
+ }
+ }
+
+ // Interpolate
+
+ // Dimensions
+ int const dim = 3;
+
+ // Interpolation operator
+ int const operator_handle =
+ CCTK_InterpHandle ("Lagrange polynomial interpolation");
+ if (operator_handle < 0) {
+ CCTK_WARN (CCTK_WARN_ALERT, "Can’t get interpolation handle");
+ goto label_return;
+ }
+
+ // Interpolation parameter table
+ int const param_table_handle = Util_TableCreateFromString ("order=4");
+ if (param_table_handle < 0) {
+ CCTK_WARN (CCTK_WARN_ALERT, "Can't create parameter table");
+ goto label_return;
+ }
+
+ {
+
+ // Interpolation coordinate system
+ int const coordsys_handle = CCTK_CoordSystemHandle ("cart3d");
+ if (coordsys_handle < 0) {
+ CCTK_WARN (CCTK_WARN_ALERT, "Can't get coordinate system handle");
+ goto label_free_param_table;
+ }
+
+ // Only processor 0 interpolates
+ int const num_points = CCTK_MyProc(cctkGH) == 0 ? max_num_tracked : 0;
+
+ // Interpolation coordinates
+ assert (dim == 3);
+ CCTK_POINTER_TO_CONST interp_coords[3];
+ interp_coords[0] = pt_loc_x_p;
+ interp_coords[1] = pt_loc_y_p;
+ interp_coords[2] = pt_loc_z_p;
+
+ // Number of interpolation variables
+ int const num_vars = 3;
+
+ // Interpolated variables
+ assert (num_vars == 3);
+ int input_array_indices[3];
+ input_array_indices[0] = CCTK_VarIndex ("ADMBase::betax");
+ input_array_indices[1] = CCTK_VarIndex ("ADMBase::betay");
+ input_array_indices[2] = CCTK_VarIndex ("ADMBase::betaz");
+
+ // Interpolation result types
+ assert (num_vars == 3);
+ CCTK_INT output_array_type_codes[3];
+ output_array_type_codes[0] = CCTK_VARIABLE_REAL;
+ output_array_type_codes[1] = CCTK_VARIABLE_REAL;
+ output_array_type_codes[2] = CCTK_VARIABLE_REAL;
+
+ // Interpolation result
+ CCTK_REAL pt_betax[max_num_tracked];
+ CCTK_REAL pt_betay[max_num_tracked];
+ CCTK_REAL pt_betaz[max_num_tracked];
+
+ assert (num_vars == 3);
+ CCTK_POINTER output_arrays[3];
+ output_arrays[0] = pt_betax;
+ output_arrays[1] = pt_betay;
+ output_arrays[2] = pt_betaz;
+
+ // Interpolate
+ int const ierr = CCTK_InterpGridArrays
+ (cctkGH, dim,
+ operator_handle, param_table_handle, coordsys_handle,
+ num_points,
+ CCTK_VARIABLE_REAL,
+ interp_coords,
+ num_vars, input_array_indices,
+ num_vars, output_array_type_codes, output_arrays);
+ if (ierr < 0) {
+ CCTK_WARN (CCTK_WARN_ALERT, "Interpolation error");
+ goto label_free_param_table;
+ }
+
+ if (CCTK_MyProc(cctkGH) == 0) {
+
+ // Some more output
+
+ if (verbose && CCTK_MyProc(cctkGH) == 0) {
+ for (int n = 0; n < max_num_tracked; ++ n) {
+ if (track[n]) {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "Shift at puncture #%d is at (%g,%g,%g)",
+ n,
+ (double)pt_betax[n],
+ (double)pt_betay[n],
+ (double)pt_betaz[n]);
+ }
+ }
+ }
+
+ // Time evolution
+
+ for (int n = 0; n < max_num_tracked; ++ n) {
+ if (track[n]) {
+ CCTK_REAL const dt = pt_loc_t[n] - pt_loc_t_p[n];
+ // First order time integrator
+ // Michael Koppitz says this works...
+ // if it doesn't, we can make it second order accurate
+ pt_loc_x[n] = pt_loc_x_p[n] + dt * (- pt_betax[n]);
+ pt_loc_y[n] = pt_loc_y_p[n] + dt * (- pt_betay[n]);
+ pt_loc_z[n] = pt_loc_z_p[n] + dt * (- pt_betaz[n]);
+ }
+ }
+
+ }
+
+ // Broadcast result
+
+ CCTK_REAL loc_local[3*max_num_tracked];
+ if (CCTK_MyProc(cctkGH) == 0) {
+ for (int n = 0; n < max_num_tracked; ++ n) {
+ loc_local[ n] = pt_loc_x[n];
+ loc_local[ max_num_tracked+n] = pt_loc_y[n];
+ loc_local[2*max_num_tracked+n] = pt_loc_z[n];
+ }
+ } else {
+ for (int n = 0; n < max_num_tracked; ++ n) {
+ loc_local[ n] = 0.0;
+ loc_local[ max_num_tracked+n] = 0.0;
+ loc_local[2*max_num_tracked+n] = 0.0;
+ }
+ }
+
+ CCTK_REAL loc_global[3*max_num_tracked];
+
+ int const handle_sum = CCTK_ReductionHandle ("sum");
+ if (handle_sum < 0) {
+ CCTK_WARN (CCTK_WARN_ALERT, "Can't get redunction handle");
+ goto label_free_param_table;
+ }
+
+ int const ierr2 = CCTK_ReduceLocArrayToArray1D
+ (cctkGH, -1, handle_sum,
+ loc_local, loc_global, 3*max_num_tracked, CCTK_VARIABLE_REAL);
+ if (ierr2 < 0) {
+ CCTK_WARN (CCTK_WARN_ALERT, "Reduction error");
+ goto label_free_param_table;
+ }
+
+ for (int n = 0; n < max_num_tracked; ++ n) {
+ pt_loc_x[n] = loc_global[ n];
+ pt_loc_y[n] = loc_global[ max_num_tracked+n];
+ pt_loc_z[n] = loc_global[2*max_num_tracked+n];
+ }
+
+ }
+
+ // Done
+
+ // Poor man's exception handling
+ label_free_param_table:
+ Util_TableDestroy (param_table_handle);
+
+ label_return:
+ return;
+}
+
+
+
+void
+PunctureTracker_SetPositions (CCTK_ARGUMENTS)
+{
+ DECLARE_CCTK_ARGUMENTS;
+ DECLARE_CCTK_PARAMETERS;
+
+ for (int n = 0; n < max_num_tracked; ++ n) {
+ if (track[n]) {
+
+ if (verbose) {
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "Setting position of refined region from puncture #%d to (%g,%g,%g)",
+ n,
+ (double)pt_loc_x[n],
+ (double)pt_loc_y[n],
+ (double)pt_loc_z[n]);
+ }
+
+ // Set position in CarpetRegrid2
+ position_x[n] = pt_loc_x[n];
+ position_y[n] = pt_loc_y[n];
+ position_z[n] = pt_loc_z[n];
+
+ }
+ }
+}