diff options
author | rideout <rideout@6a38eb6e-646e-4a02-a296-d141613ad6c4> | 2003-05-13 13:52:02 +0000 |
---|---|---|
committer | rideout <rideout@6a38eb6e-646e-4a02-a296-d141613ad6c4> | 2003-05-13 13:52:02 +0000 |
commit | 1ef1806f0950b044c02c9c32d7e583ec10d17178 (patch) | |
tree | 74b86a290cf297e2c9d2b435076bccbf0cd101e7 | |
parent | 3813ff38d50167d133fb7853b9ba10d70f114534 (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.c | 335 |
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 |