376 lines
9.6 KiB
C
376 lines
9.6 KiB
C
/**************************************************************
|
|
File : act_def_linklist.c
|
|
Func. : provide linear linking list functions
|
|
: for active particle def.
|
|
CODED BY : Zhong Shiyan
|
|
START : 2014-03-28, 12:30
|
|
**************************************************************/
|
|
|
|
//***********************************************************//
|
|
/* Definition of T/P-node */
|
|
//***********************************************************//
|
|
typedef struct PNODE
|
|
{
|
|
int Pid; // Particle's real ID
|
|
struct PNODE *NextPNODE;
|
|
} PNODE;
|
|
|
|
typedef struct TNODE
|
|
{
|
|
double t_node; // t_node = t + dt
|
|
int n_node; // number of P-nodes under this node
|
|
|
|
struct PNODE *PartList, *PartListEnd;
|
|
struct TNODE *NextTNODE;
|
|
} TNODE;
|
|
|
|
struct TNODE *CurrT=NULL;
|
|
|
|
//***********************************************************//
|
|
/* Operations on T/P-node */
|
|
//***********************************************************//
|
|
struct TNODE *CreateTNODE( double t ){
|
|
|
|
struct TNODE *ptr;
|
|
|
|
ptr = (TNODE*)malloc(sizeof(*ptr));
|
|
if( ptr == NULL ){
|
|
printf("Fail to create a node.");
|
|
exit(-1);
|
|
}
|
|
|
|
ptr->t_node = t;
|
|
ptr->n_node = 0;
|
|
|
|
ptr->NextTNODE = NULL;
|
|
|
|
ptr->PartList = NULL;
|
|
ptr->PartListEnd = NULL;
|
|
|
|
return ptr;
|
|
}
|
|
//***********************************************************//
|
|
struct PNODE *DeletePNODE( struct PNODE *ptr ){
|
|
struct PNODE *next;
|
|
|
|
next = ptr->NextPNODE;
|
|
free(ptr);
|
|
|
|
return next;
|
|
}
|
|
//***********************************************************//
|
|
void DeleteTNODE( struct TNODE *Tptr ){
|
|
|
|
struct PNODE *Pptr;
|
|
|
|
Pptr = Tptr->PartList;
|
|
|
|
while( Pptr != NULL ){
|
|
Pptr = DeletePNODE( Pptr );
|
|
}
|
|
|
|
free(Tptr);
|
|
return;
|
|
}
|
|
//***********************************************************//
|
|
struct PNODE *CreatePNODE( int id ){
|
|
struct PNODE *ptr;
|
|
|
|
ptr = (PNODE*)malloc(sizeof(*ptr));
|
|
if( ptr == NULL ){
|
|
printf("Fail to create a P-node.");
|
|
return NULL;
|
|
}
|
|
|
|
ptr->Pid = id;
|
|
ptr->NextPNODE = NULL;
|
|
|
|
return ptr;
|
|
|
|
}
|
|
//***********************************************************//
|
|
void InsertTNODE( struct TNODE *front,
|
|
struct TNODE *rear,
|
|
struct TNODE *ptr )
|
|
{
|
|
front->NextTNODE = ptr;
|
|
ptr->NextTNODE = rear;
|
|
|
|
}
|
|
//***********************************************************//
|
|
|
|
|
|
|
|
|
|
//***********************************************************//
|
|
/* Functions about act_def */
|
|
//***********************************************************//
|
|
/**************************************************************
|
|
This function only called 1 time, at beginning of simulation.
|
|
After all particle's dt are computed
|
|
**************************************************************/
|
|
|
|
void CreateLinkList(){
|
|
|
|
struct TNODE *head,*tail,*Tp1,*Tp2,*newTNODE,*Tptr;
|
|
struct PNODE *Pptr,*Ptail;
|
|
|
|
int i, iii;
|
|
double ttmp, t1, t2;
|
|
|
|
head = CreateTNODE( -1.0 ); // will be discarded at the end of this routine
|
|
tail = CreateTNODE( 2.0*t_end );
|
|
|
|
head->NextTNODE = tail;
|
|
tail->NextTNODE = NULL;
|
|
|
|
// building link list
|
|
|
|
for(i=0;i<N;i++){
|
|
|
|
ttmp = t[i] + dt[i];
|
|
iii = ind[i];
|
|
if( m[iii] == 0.0 ) ttmp = t_end + 0.125;
|
|
|
|
Tp1 = head;
|
|
Tp2 = Tp1->NextTNODE;
|
|
t1 = Tp1->t_node;
|
|
t2 = Tp2->t_node;
|
|
|
|
Pptr = CreatePNODE( iii );
|
|
|
|
while( Tp1->NextTNODE != NULL ){
|
|
if( ttmp == t1 ){ // if T-node exist, add a P-node
|
|
|
|
if( Tp1->PartListEnd == NULL ){ // This is the first P-node under current T-node
|
|
Tp1->PartList = Pptr;
|
|
Tp1->PartListEnd = Pptr;
|
|
Tp1->n_node = Tp1->n_node + 1;
|
|
}
|
|
else{ // There are already many P-nodes under this T-node
|
|
Ptail = Tp1->PartListEnd;
|
|
Ptail->NextPNODE = Pptr;
|
|
Tp1->PartListEnd = Pptr;
|
|
Tp1->n_node = Tp1->n_node + 1;
|
|
}
|
|
break; // jump out of this "while" loop
|
|
}
|
|
|
|
if( ttmp > t1 && ttmp < t2 ){ // Create a new T-node and insert between *Tp1 and *Tp2, then add P-node to it
|
|
|
|
newTNODE = CreateTNODE(ttmp);
|
|
InsertTNODE( Tp1, Tp2, newTNODE);
|
|
|
|
newTNODE->n_node = 1;
|
|
newTNODE->PartList = Pptr;
|
|
newTNODE->PartListEnd = Pptr;
|
|
break; // jump out of this "while" loop
|
|
}
|
|
|
|
// move to next T-node
|
|
Tp1 = Tp1->NextTNODE;
|
|
t1 = Tp1->t_node;
|
|
|
|
if(Tp2->NextTNODE != NULL){
|
|
Tp2 = Tp2->NextTNODE;
|
|
t2 = Tp2->t_node;
|
|
}
|
|
else{ break; }
|
|
|
|
}// while( Tp1->NextTNODE != NULL )
|
|
|
|
}//for(i=0;i<N;i++)
|
|
|
|
CurrT = head->NextTNODE;
|
|
free(head);
|
|
|
|
}
|
|
|
|
//End of CreateLinkList()
|
|
/**************************************************************/
|
|
|
|
|
|
/**************************************************************
|
|
This Function is used to modify the link list,
|
|
after get new dt for active particles. Then point *CurrT to next
|
|
T-node.
|
|
**************************************************************/
|
|
|
|
void ModifyLinkList(){
|
|
|
|
struct TNODE *Tp1,*Tp2,*newTNODE;
|
|
struct PNODE *Pptr,*Ptail;
|
|
|
|
int i, iii;
|
|
double ttmp, t1, t2;
|
|
|
|
for(i=0;i<n_act;i++){
|
|
|
|
iii = ind_act[i];
|
|
ttmp = t[iii] + dt[iii];
|
|
|
|
Tp1 = CurrT;
|
|
Tp2 = Tp1->NextTNODE;
|
|
t1 = Tp1->t_node;
|
|
t2 = Tp2->t_node;
|
|
|
|
Pptr = CreatePNODE( iii );
|
|
|
|
while( Tp1->NextTNODE != NULL ){
|
|
if( ttmp == t1 ){ // if T-node exist, add a P-node
|
|
|
|
if( Tp1->PartListEnd == NULL ){ // This is the first P-node under current T-node
|
|
Tp1->PartList = Pptr;
|
|
Tp1->PartListEnd = Pptr;
|
|
Tp1->n_node = Tp1->n_node + 1;
|
|
}
|
|
else{ // There are already many P-nodes under this T-node
|
|
Ptail = Tp1->PartListEnd;
|
|
Ptail->NextPNODE = Pptr;
|
|
Tp1->PartListEnd = Pptr;
|
|
Tp1->n_node = Tp1->n_node + 1;
|
|
}
|
|
break; // jump out of this "while" loop
|
|
}
|
|
|
|
if( ttmp > t1 && ttmp < t2 ){ // Create a new T-node and insert between *Tp1 and *Tp2, then add P-node to it
|
|
|
|
newTNODE = CreateTNODE(ttmp);
|
|
InsertTNODE( Tp1, Tp2, newTNODE);
|
|
|
|
newTNODE->n_node = 1;
|
|
newTNODE->PartList = Pptr;
|
|
newTNODE->PartListEnd = Pptr;
|
|
|
|
break; // jump out of this "while" loop
|
|
}
|
|
|
|
// move to next T-node
|
|
Tp1 = Tp1->NextTNODE;
|
|
t1 = Tp1->t_node;
|
|
|
|
if(Tp2->NextTNODE != NULL){
|
|
Tp2 = Tp2->NextTNODE;
|
|
t2 = Tp2->t_node;
|
|
}
|
|
else{ break; }
|
|
|
|
}//while( Tp1->NextTNODE != NULL )
|
|
|
|
}//for(i=0;i<n_act;i++)
|
|
|
|
Tp1 = CurrT;
|
|
CurrT = CurrT->NextTNODE;
|
|
DeleteTNODE( Tp1 );
|
|
}
|
|
|
|
//End of ModifyLinkList()
|
|
/***************************************************************/
|
|
|
|
|
|
/***************************************************************/
|
|
/*
|
|
void i_swap(int *a, int *b)
|
|
{
|
|
register int tmp;
|
|
tmp = *a; *a = *b; *b = tmp;
|
|
}
|
|
*/
|
|
/***************************************************************/
|
|
/***************************************************************/
|
|
void ind_act_sort(int l, int r)
|
|
{
|
|
|
|
int i, j, cikl, tmp;
|
|
|
|
i = l; j = r;
|
|
tmp = ind_act[(l+r)/2];
|
|
|
|
cikl = 1;
|
|
|
|
while(cikl)
|
|
{
|
|
while (ind_act[i]<tmp) i++;
|
|
while (tmp<ind_act[j]) j--;
|
|
|
|
if (i<=j)
|
|
{
|
|
i_swap(&ind_act[i],&ind_act[j]);
|
|
i++; j--;
|
|
}
|
|
else
|
|
{
|
|
cikl = 0;
|
|
}
|
|
}
|
|
if (l<j) ind_act_sort(l, j);
|
|
if (i<r) ind_act_sort(i, r);
|
|
}
|
|
/**************************************************************/
|
|
|
|
/**************************************************************
|
|
Get active particle list
|
|
**************************************************************/
|
|
void get_act_plist()
|
|
{
|
|
struct PNODE *Pptr;
|
|
int i, iii, j,k, itmp, ipt, flag;
|
|
|
|
char idcFile[30];
|
|
FILE *idcomp;
|
|
|
|
i=0;
|
|
Pptr = CurrT->PartList;
|
|
n_act = 0;
|
|
|
|
min_t = CurrT->t_node; // IMPORTANT !!
|
|
|
|
flag = 0;
|
|
|
|
while(Pptr != NULL)
|
|
{
|
|
iii = Pptr->Pid;
|
|
Pptr = Pptr->NextPNODE;
|
|
if( m[iii] != 0.0 ) // Do not put zero mass part. in active plist
|
|
{
|
|
ind_act[i] = iii;
|
|
// if(ind_act[i]==N-1) flag=1;
|
|
i++; n_act++;
|
|
}
|
|
}
|
|
|
|
if( n_act > 2 ) ind_act_sort( 0, n_act-1 );
|
|
|
|
// printf("last pid: %06d\n", ind_act_ll[n_act-1]);
|
|
// if( flag == 0 ) printf("Warning: BH not in the ind_act array!\n");
|
|
// if( ind_act[n_act-1]!= N-1) printf("Warning: BH not in the last of ind_act array!\n");
|
|
|
|
}// End of get_act_plist()
|
|
/**************************************************************/
|
|
|
|
|
|
#ifdef DEBUG_extra
|
|
/**************************************************************
|
|
Check link list
|
|
**************************************************************/
|
|
void check_linklist(int Tstep)
|
|
{
|
|
FILE *listf;
|
|
struct TNODE *Tptr;
|
|
|
|
listf = fopen("Check_linklist.dat","a");
|
|
Tptr = CurrT;
|
|
fprintf(listf,"Timesteps = %04d\n", Tstep);
|
|
while(Tptr != NULL)
|
|
{
|
|
fprintf(listf,"% 8E %04d\n", Tptr->t_node, Tptr->n_node);
|
|
Tptr = Tptr->NextTNODE;
|
|
}
|
|
|
|
fprintf(listf,"========================\n\n");
|
|
|
|
fclose(listf);
|
|
}
|
|
/**************************************************************/
|
|
#endif
|
|
|