#include #include #include #include #include #include "cctk.h" #include "util_ErrorCodes.h" #include "util_Table.h" #include "rotatingsymmetry180.h" void Rot180_CheckTensorTypes (CCTK_ARGUMENTS) { int gi; /* Check tensor types of all groups */ for (gi=0; gi0); firstvar = CCTK_FirstVarIndexI(gi); assert (firstvar>=0); table = CCTK_GroupTagsTableI(gi); assert (table>=0); ierr = Util_TableGetString (table, sizeof tensortypealias, tensortypealias, "tensortypealias"); if (ierr == UTIL_ERROR_TABLE_NO_SUCH_KEY) { char * groupname = CCTK_GroupName(gi); assert (groupname); CCTK_VWarn (4, __LINE__, __FILE__, CCTK_THORNSTRING, "Tensor type alias not declared for group \"%s\" -- assuming a scalar", groupname); free (groupname); strcpy (tensortypealias, ""); } else if (ierr<0) { char * groupname = CCTK_GroupName(gi); assert (groupname); CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING, "Error in tensor type alias declaration for group \"%s\"", groupname); free (groupname); } if (CCTK_EQUALS (tensortypealias, "")) { /* do nothing */ } else if (CCTK_EQUALS (tensortypealias, "scalar")) { /* scalar */ if (numvars != 1) { char * groupname = CCTK_GroupName(gi); assert (groupname); CCTK_VWarn (4, __LINE__, __FILE__, CCTK_THORNSTRING, "Group \"%s\" has the tensor type alias \"scalar\", but contains more than 1 element", groupname); free (groupname); } } else if (CCTK_EQUALS (tensortypealias, "4-scalar")) { /* 4-scalar */ if (numvars != 1) { char * groupname = CCTK_GroupName(gi); assert (groupname); CCTK_VWarn (4, __LINE__, __FILE__, CCTK_THORNSTRING, "Group \"%s\" has the tensor type alias \"4scalar\", but contains more than 1 element", groupname); free (groupname); } } else if (CCTK_EQUALS (tensortypealias, "u") || CCTK_EQUALS (tensortypealias, "d")) { /* vector */ if (numvars != 3) { char * groupname = CCTK_GroupName(gi); assert (groupname); CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, "Group \"%s\" has the tensor type alias \"u\", but does not contain 3 elements (but %d)", groupname, numvars); free (groupname); } assert (numvars == 3); } else if (CCTK_EQUALS (tensortypealias, "4u") || CCTK_EQUALS (tensortypealias, "4d")) { /* 4-vector */ assert (numvars == 4); } else if (CCTK_EQUALS (tensortypealias, "uu_sym") || CCTK_EQUALS (tensortypealias, "dd_sym")) { /* symmetric tensor */ assert (numvars == 6); } else if (CCTK_EQUALS (tensortypealias, "uu") || CCTK_EQUALS (tensortypealias, "ud") || CCTK_EQUALS (tensortypealias, "du") || CCTK_EQUALS (tensortypealias, "dd")) { /* tensor */ assert (numvars == 9); } else if (CCTK_EQUALS (tensortypealias, "ddd_sym")) { /* 3rd rank tensor, symmetric in last 2 indices */ assert (numvars == 18); } else if (CCTK_EQUALS (tensortypealias, "4uu_sym") || CCTK_EQUALS (tensortypealias, "4dd_sym")) { /* symmetric 4-tensor */ assert (numvars == 10); } else if (CCTK_EQUALS (tensortypealias, "weylscalars_real")) { /* Weyl scalars, stored as 10 real values */ assert (numvars == 10); } else if (CCTK_EQUALS (tensortypealias, "ManualCartesian")) { /* No restriction */ } else { char * groupname = CCTK_GroupName(gi); assert (groupname); CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING, "Illegal tensor type alias for group \"%s\"", groupname); free (groupname); } } } /* Symmetry interpolation */ CCTK_INT Rot180_SymmetryInterpolate (CCTK_POINTER_TO_CONST const cctkGH, CCTK_INT const N_dims, CCTK_INT const local_interp_handle, CCTK_INT const param_table_handle, CCTK_INT const coord_system_handle, CCTK_INT const N_interp_points, CCTK_INT const interp_coords_type, CCTK_POINTER_TO_CONST const interp_coords[], CCTK_INT const N_input_arrays, CCTK_INT const input_array_indices[], CCTK_INT const N_output_arrays, CCTK_INT const output_array_types[], CCTK_POINTER const output_arrays[], CCTK_INT const faces) { CCTK_POINTER new_interp_coords[3]; CCTK_INT new_faces; CCTK_INT * restrict operand_indices; CCTK_INT * restrict operation_codes; CCTK_INT * restrict output_array_indices; int parities[3]; /* variable parities */ int m; /* output array */ int n; /* point */ int d; /* dimension */ int iret; /* interpolator return value */ int ierr; /* Check arguments */ assert (N_dims == 3); assert (N_interp_points >= 0); assert (interp_coords_type >= 0); for (d=0; d<3; ++d) { assert (N_interp_points == 0 || interp_coords[d]); } assert (N_output_arrays >= 0); /* Coordinates must be CCTK_REAL */ assert (interp_coords_type == CCTK_VARIABLE_REAL); for (m=0; m=0 && operand_indices[m]=0 && output_array_indices[m]=0 && vi=0 && gi0); firstvar = CCTK_FirstVarIndexI(gi); assert (firstvar>=0); index = vi - firstvar; assert (index>=0 && index=0); ierr = Util_TableGetString (table, sizeof tensortypealias, tensortypealias, "tensortypealias"); if (ierr == UTIL_ERROR_TABLE_NO_SUCH_KEY) { char * groupname = CCTK_GroupName(gi); assert (groupname); CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, "Tensor type alias not declared for group \"%s\" -- assuming a scalar", groupname); free (groupname); strcpy (tensortypealias, "scalar"); } else if (ierr<0) { char * groupname = CCTK_GroupName(gi); assert (groupname); CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING, "Error in tensor type alias declaration for group \"%s\"", groupname); free (groupname); } if (CCTK_EQUALS (tensortypealias, "scalar")) { if (numvars != 1) { char * groupname = CCTK_GroupName(gi); assert (groupname); CCTK_VWarn (4, __LINE__, __FILE__, CCTK_THORNSTRING, "Group \"%s\" has the tensor type alias \"scalar\", but contains more than 1 element", groupname); free (groupname); } parities[0] = parities[1] = parities[2] = +1; } else if (CCTK_EQUALS (tensortypealias, "4scalar")) { if (numvars != 1) { char * groupname = CCTK_GroupName(gi); assert (groupname); CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, "Group \"%s\" has the tensor type alias \"scalar\", but contains more than 1 element", groupname); free (groupname); } parities[0] = parities[1] = parities[2] = +1; } else if (CCTK_EQUALS (tensortypealias, "u") || CCTK_EQUALS (tensortypealias, "d")) { assert (numvars == 3); parities[0] = parities[1] = parities[2] = +1; parities[index] = -1; } else if (CCTK_EQUALS (tensortypealias, "4u") || CCTK_EQUALS (tensortypealias, "4d")) { assert (numvars == 4); if (vi == firstvar) { parities[0] = parities[1] = parities[2] = +1; } else { parities[0] = parities[1] = parities[2] = +1; parities[index-1] = -1; } } else if (CCTK_EQUALS (tensortypealias, "uu_sym") || CCTK_EQUALS (tensortypealias, "dd_sym")) { assert (numvars == 6); parities[0] = parities[1] = parities[2] = +1; switch (index) { case 0: break; case 1: parities[0] = parities[1] = -1; break; case 2: parities[0] = parities[2] = -1; break; case 3: break; case 4: parities[1] = parities[2] = -1; break; case 5: break; default: assert(0); } } else if (CCTK_EQUALS (tensortypealias, "uu") || CCTK_EQUALS (tensortypealias, "ud") || CCTK_EQUALS (tensortypealias, "du") || CCTK_EQUALS (tensortypealias, "dd")) { assert (numvars == 9); parities[0] = parities[1] = parities[2] = +1; int const d1 = index % 3; int const d2 = index / 3; parities[d1] *= -1; parities[d2] *= -1; } else if (CCTK_EQUALS (tensortypealias, "ddd_sym")) { assert (numvars == 18); parities[0] = parities[1] = parities[2] = +1; switch (index%6) { case 0: break; case 1: parities[0] = parities[1] = -1; break; case 2: parities[0] = parities[2] = -1; break; case 3: break; case 4: parities[1] = parities[2] = -1; break; case 5: break; default: assert(0); } parities[index/6] *= -1; } else if (CCTK_EQUALS (tensortypealias, "4uu_sym") || CCTK_EQUALS (tensortypealias, "4dd_sym")) { assert (numvars == 10); if (vi == firstvar) { parities[0] = parities[1] = parities[2] = +1; } else if (vi < firstvar + 4) { parities[0] = parities[1] = parities[2] = +1; parities[index-1] = -1; } else { parities[0] = parities[1] = parities[2] = +1; switch (index-4) { case 0: break; case 1: parities[0] = parities[1] = -1; break; case 2: parities[0] = parities[2] = -1; break; case 3: break; case 4: parities[1] = parities[2] = -1; break; case 5: break; default: assert(0); } } } else if (CCTK_EQUALS (tensortypealias, "weylscalars_real")) { assert (numvars == 10); { static int const weylparities[10][3] = {{+1,+1,+1}, {-1,-1,-1}, {+1,+1,+1}, {-1,-1,-1}, {+1,+1,+1}, {-1,-1,-1}, {+1,+1,+1}, {-1,-1,-1}, {+1,+1,+1}, {-1,-1,-1}}; for (d=0; d<3; ++d) { parities[d] = weylparities[index][d]; } } } else if (CCTK_EQUALS (tensortypealias, "ManualCartesian")) { RotatingSymmetry180_GetManualParities(table, gi, parities); } else { char * groupname = CCTK_GroupName(gi); assert (groupname); CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING, "Illegal tensor type alias for group \"%s\"", groupname); free (groupname); } for (d=0; d<3; ++d) { assert (abs(parities[d])==1); } } /* Find parity */ /* Modify parity */ { int code = operation_codes[m]; while (code) { const int dir = code % 10; code /= 10; assert (dir>=1 && dir<=3); parities[dir-1] *= -1; } } /* Loop over all points and unfold */ if (parities[0] * parities[1] == -1) { for (n=0; n