aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrideout <rideout@6a38eb6e-646e-4a02-a296-d141613ad6c4>2003-05-13 13:52:02 +0000
committerrideout <rideout@6a38eb6e-646e-4a02-a296-d141613ad6c4>2003-05-13 13:52:02 +0000
commit1ef1806f0950b044c02c9c32d7e583ec10d17178 (patch)
tree74b86a290cf297e2c9d2b435076bccbf0cd101e7
parent3813ff38d50167d133fb7853b9ba10d70f114534 (diff)
Check that only one physical bc is selected for any given face.
git-svn-id: http://svn.cactuscode.org/arrangements/CactusBase/Boundary/trunk@232 6a38eb6e-646e-4a02-a296-d141613ad6c4
-rw-r--r--src/Boundary.c335
1 files changed, 207 insertions, 128 deletions
diff --git a/src/Boundary.c b/src/Boundary.c
index eccb73a..91362e0 100644
--- a/src/Boundary.c
+++ b/src/Boundary.c
@@ -70,6 +70,7 @@ struct BCDATA
static int entry_greater_than(struct BCVAR *new, struct BCVAR *current);
#ifdef DEBUG
static void print_selections_database(void);
+static void print_selected_faces(void);
#endif
/********************************************************************
@@ -131,6 +132,10 @@ static int physbc_table_handle = -1;
/* Linked list for storing data associated with selections list itself */
static struct BCDATA *bcdata_list = NULL;
+/* Array of (number of variables) faces specifications, for checking
+ for duplicate bc selection */
+static CCTK_INT *selected_faces;
+static int num_cctk_vars;
/********************************************************************
********************* Aliased Routines **********************
@@ -355,9 +360,8 @@ CCTK_INT Bdry_Boundary_SelectVarForBC(CCTK_POINTER GH,
@returntype CCTK_INT
@returndesc
0 success
- -1 error allocating memory for new entry in selected variables database
-2 no such physical boundary condition registered
- -4 error allocating memory for new entry in 'bcdata' database
+ -3 faces already selected for bc
@endreturndesc
@@*/
CCTK_INT Bdry_Boundary_SelectVarForBCI(CCTK_POINTER GH,
@@ -390,6 +394,9 @@ CCTK_INT Bdry_Boundary_SelectVarForBCI(CCTK_POINTER GH,
/* Ignore GH */
GH = GH;
+ /* Check that this request is allowed
+ ---------------------------------- */
+
/* Has some function implementing bc_name been registered? */
if (!Util_TableQueryValueInfo(physbc_table_handle, NULL, NULL, bc_name))
{
@@ -399,165 +406,202 @@ CCTK_INT Bdry_Boundary_SelectVarForBCI(CCTK_POINTER GH,
retval = -2;
}
- /* allocate memory for new entry in database */
- new_entry = (struct BCVAR *) malloc(sizeof(struct BCVAR));
- if (!new_entry)
+ /* Have any of these faces already been selected for a bc? */
+#ifdef DEBUG
+ print_selected_faces();
+#endif
+ if (selected_faces && selected_faces[var_index]&faces)
{
- CCTK_VWarn(0, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Unable to allocate memory for entry into "
- "'selected for bcs' database");
- retval = -1;
+ CCTK_VWarn(1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "%s has already been selected for a bc",
+ CCTK_VarName(var_index));
+ retval = -3;
}
- /* populate new entry with data */
- new_entry -> faces = faces;
- new_entry -> width = width;
- new_entry -> table = table_handle;
- new_entry -> var = var_index;
- /* new_entry -> next will be filled in later */
-
- /* Into which of bcdata's lists should this variable be placed? */
- for (current_bcdata = bcdata_list;
- current_bcdata;
- previous_bcdata=current_bcdata, current_bcdata = current_bcdata->next)
+
+ /* Honor request
+ ------------- */
+ if (!retval)
{
-#ifdef DEBUG
- printf("Boundary_SelectVarForBCI: looping through bcdata list, at "
- "current_bcdata for %s\n",current_bcdata->bc_name);
-#endif
- if (CCTK_Equals(current_bcdata->bc_name,bc_name))
+ /* allocate memory for new entry in database */
+ new_entry = (struct BCVAR *) malloc(sizeof(struct BCVAR));
+ if (!new_entry)
+ {
+ CCTK_VWarn(0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Unable to allocate memory for entry into "
+ "'selected for bcs' database");
+ retval = -1;
+ }
+
+ /* populate new entry with data */
+ new_entry -> faces = faces;
+ new_entry -> width = width;
+ new_entry -> table = table_handle;
+ new_entry -> var = var_index;
+ /* new_entry -> next will be filled in later */
+
+ /* Into which of bcdata's lists should this variable be placed? */
+ for (current_bcdata = bcdata_list;
+ current_bcdata;
+ previous_bcdata=current_bcdata, current_bcdata = current_bcdata->next)
{
- current = current_bcdata->var_list;
- current_bcdata->num++;
#ifdef DEBUG
- printf("Boundary_SelectVarForBCI: var %s brings bc %s to %d vars\n",
- CCTK_VarName(var_index),bc_name, current_bcdata->num);
+ printf("Boundary_SelectVarForBCI: looping through bcdata list, at "
+ "current_bcdata for %s\n",current_bcdata->bc_name);
#endif
- break; /* now that current is set we don't need to look at any
- more bcdata entries */
- }
- }
-
- /* If current_bcdata is NULL, we got to the end of the above loop, this is a
- * new bc_name that does not appear in the bcdata list.
- */
- if (!current_bcdata) /* bc_name was not found in bcdata_list */
- {
+
+ if (CCTK_Equals(current_bcdata->bc_name,bc_name))
+ {
+ current = current_bcdata->var_list;
+ current_bcdata->num++;
#ifdef DEBUG
- printf("Boundary_SelectVarForBCI: adding new entry to bcdata list\n");
+ printf("Boundary_SelectVarForBCI: var %s brings bc %s to %d vars\n",
+ CCTK_VarName(var_index),bc_name, current_bcdata->num);
#endif
-
- /* new bc_name. Create new entry for bcdata list. */
- new_bcdata = (struct BCDATA *) malloc(sizeof(struct BCDATA));
- if (!new_bcdata) {
- CCTK_VWarn(0, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Unable to allocate memory for internal 'bcdata' list");
- retval = -4;
+ break; /* now that current is set we don't need to look at any
+ more bcdata entries */
+ }
}
-
- /* Place new entry into bcdata list, maintaining case independent sort. */
- for (current_bcdata = bcdata_list, previous_bcdata = NULL;
- current_bcdata;
- previous_bcdata=current_bcdata, current_bcdata = current_bcdata->next)
+
+ /* If current_bcdata is NULL, we got to the end of the above loop, this is
+ * a new bc_name that does not appear in the bcdata list.
+ */
+ if (!current_bcdata) /* bc_name was not found in bcdata_list */
{
#ifdef DEBUG
- printf(" looping through bcdata list, to insert new entry; at %s\n",
- current_bcdata->bc_name);
+ printf("Boundary_SelectVarForBCI: adding new entry to bcdata list\n");
#endif
- if (Util_StrCmpi(bc_name, current_bcdata->bc_name) < 0)
+
+ /* new bc_name. Create new entry for bcdata list. */
+ new_bcdata = (struct BCDATA *) malloc(sizeof(struct BCDATA));
+ if (!new_bcdata) {
+ CCTK_VWarn(0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Unable to allocate memory for internal 'bcdata' list");
+ retval = -4;
+ }
+
+ /* Place new entry into bcdata list, maintaining case independent sort. */
+ for (current_bcdata = bcdata_list, previous_bcdata = NULL;
+ current_bcdata;
+ previous_bcdata=current_bcdata,
+ current_bcdata = current_bcdata->next)
{
- /* bc_name precedes current->bc_name; place new entry here */
- if (!previous_bcdata) /* goes at start of bcdata list */
+#ifdef DEBUG
+ printf(" looping through bcdata list, to insert new entry; at %s\n",
+ current_bcdata->bc_name);
+#endif
+ if (Util_StrCmpi(bc_name, current_bcdata->bc_name) < 0)
{
+ /* bc_name precedes current->bc_name; place new entry here */
+ if (!previous_bcdata) /* goes at start of bcdata list */
+ {
#ifdef DEBUG
- printf(" new entry goes at beginning of bcdata list\n");
+ printf(" new entry goes at beginning of bcdata list\n");
#endif
+ bcdata_list = new_bcdata;
+ new_bcdata->next = current_bcdata;
+ } else
+ {
+ new_bcdata->next = current_bcdata;
+ previous_bcdata->next = new_bcdata;
+ }
+ break;
+ }
+ }
+
+ /* If current_bcdata still NULL, this is the last entry in the list */
+ if (!current_bcdata)
+ {
+ if (!bcdata_list) /* list is empty */
+ {
bcdata_list = new_bcdata;
- new_bcdata->next = current_bcdata;
} else
{
- new_bcdata->next = current_bcdata;
previous_bcdata->next = new_bcdata;
}
- break;
- }
- }
-
- /* If current_bcdata still NULL, this is the last entry in the list */
- if (!current_bcdata)
- {
- if (!bcdata_list) /* list is empty */
- {
- bcdata_list = new_bcdata;
- } else
- {
- previous_bcdata->next = new_bcdata;
- }
new_bcdata->next = NULL;
+ }
+
+ /* Set current_bcdata to new_bcdata, so the new bcdata entry will be
+ filled in below */
+ current_bcdata = new_bcdata;
}
-
- /* Set current_bcdata to new_bcdata, so the new bcdata entry will be filled in below */
- current_bcdata = new_bcdata;
- }
-
+
#ifdef DEBUG
- printf(" Finished sorting out which bcdata to use. Now add entry to var list.\n");
- printf(" Preparing to loop through elements of var list. current is %p"
- " previous is %p\n", current, previous);
+ printf(" Finished sorting out which bcdata to use. Now add entry to var list.\n");
+ printf(" Preparing to loop through elements of var list. current is %p"
+ " previous is %p\n", current, previous);
#endif
-
- if (!current) /* This is the first element in the var_list */
- {
+
+ if (!current) /* This is the first element in the var_list */
+ {
#ifdef DEBUG
- printf(" New element of var list.\n");
+ printf(" New element of var list.\n");
#endif
- current_bcdata->var_list = new_entry; /* new_entry will be first element */
- new_entry->next = NULL; /* of var list for this bcdata entry */
- current_bcdata->bc_name = Util_Strdup(bc_name);
- current_bcdata->num = 1;
- }
-
-
- /* Enter new_entry into correct location in linked list.
- * Note that this loop is skipped if new_entry was already inserted as first
- * element of a new var list above (since in that case current will be
- * NULL) */
- for (; /* starting value for current is selected using the bcdata
- list, above */
- current && entry_greater_than(new_entry,current) > 0;
- /* continue if not at end of list, and new_entry is greater than
- current entry */
- previous = current, current = current->next)
- /* store previous value for later use */
- {
- }
-
- /* The possibilities:
- * 1 nothing NULL: new_entry goes between previous and current
- * 2 previous NULL, but current non-null : new_entry goes at the start of
- * the list
- * 3 current NULL, previous non-NULL : new_entry goes at the end of the list
- * 4 both NULL: selections list is empty, case already caught above
- */
- if (previous) /* case 1 or 3 */
- {
- if (current) /* case 1 : goes in middle of list */
+ current_bcdata->var_list = new_entry;
+ new_entry->next = NULL;
+ current_bcdata->bc_name = Util_Strdup(bc_name);
+ current_bcdata->num = 1;
+ }
+
+
+ /* Enter new_entry into correct location in linked list.
+ * Note that this loop is skipped if new_entry was already inserted as
+ * first element of a new var list above (since in that case current will
+ * be NULL) */
+ for (; /* starting value for current is selected using the bcdata
+ list, above */
+ current && entry_greater_than(new_entry,current) > 0;
+ /* continue if not at end of list, and new_entry is greater than
+ current entry */
+ previous = current, current = current->next)
+ /* store previous value for later use */
+ {
+ }
+
+ /* The possibilities:
+ * 1 nothing NULL: new_entry goes between previous and current
+ * 2 previous NULL, but current non-null : new_entry goes at the start of
+ * the list
+ * 3 current NULL, previous non-NULL : new_entry goes at the end of list
+ * 4 both NULL: selections list is empty, case already caught above
+ */
+ if (previous) /* case 1 or 3 */
{
- previous->next = new_entry;
- new_entry->next = current;
- } else /* case 3 : goes at end of list */
+ if (current) /* case 1 : goes in middle of list */
+ {
+ previous->next = new_entry;
+ new_entry->next = current;
+ } else /* case 3 : goes at end of list */
+ {
+ previous->next = new_entry;
+ new_entry->next = NULL;
+ }
+ } else /* case 2 or 4 */
{
- previous->next = new_entry;
- new_entry->next = NULL;
+ if (current) /* case 2 : goes at start of list */
+ {
+ current_bcdata->var_list = new_entry;
+ new_entry->next = current;
+ } /* case 4 : starts list, this case has already been handled above */
}
- } else /* case 2 or 4 */
- {
- if (current) /* case 2 : goes at start of list */
+
+
+ /* Record that this variable has been selected for a bc on these
+ faces, for duplicate physical bc checking */
+ if (!selected_faces)
{
- current_bcdata->var_list = new_entry;
- new_entry->next = current;
- } /* case 4 : starts list, this case has already been handled above */
+ num_cctk_vars = CCTK_NumVars();
+ selected_faces = (CCTK_INT *) calloc(num_cctk_vars, sizeof(CCTK_INT));
+ if (!selected_faces)
+ {
+ CCTK_VWarn(0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Unable to allocate memory for internal 'selected_faces' "
+ "array");
+ }
+ }
+ selected_faces[var_index] |= faces;
}
#ifdef DEBUG
@@ -1042,6 +1086,9 @@ void Boundary_ClearSelection(void)
current_bcdata->var_list = NULL;
current_bcdata->num = 0;
}
+
+ /* Clear list of selected faces */
+ memset(selected_faces, 0, num_cctk_vars*sizeof(CCTK_INT));
}
/********************************************************************
@@ -1143,3 +1190,35 @@ static void print_selections_database(void)
}
#endif
+
+ /*@@
+ @routine print_selected_faces
+ @date 13 May 2003
+ @author David Rideout
+ @desc
+ Prints selected faces database, for debugging only
+ @enddesc
+ @calls
+ @history
+ @endhistory
+@@*/
+
+#ifdef DEBUG
+
+static void print_selected_faces(void)
+{
+ int i;
+
+ if (selected_faces)
+ {
+ for (i=0; i<num_cctk_vars; ++i)
+ {
+ printf("selected_faces[%d] = %d\n", i, selected_faces[i]);
+ }
+ } else
+ {
+ printf("no selected faces database yet\n");
+ }
+}
+
+#endif