void filTreadmill(simptr sim,filamentptr fil,int steps) { int i,mxs,done,iter; double thk,length,angle[3],sigmamult,angletry[3],dcm[9]; filamentptr fil2; for(i=0;i<steps;i++) { thk=fil->pthk[0]; done=0; sigmamult=1; angletry[0]=angletry[1]=angletry[2]=0; for(iter=0;iter<500 && !done;iter++) { length=filRandomLength(fil,thk,sigmamult); filRandomAngle(fil,thk,angle,sigmamult); if(iter>0 && coinrandD(0.5)) filAddMonomer(fil,NULL,length,angletry,thk,'b'); else filAddMonomer(fil,NULL,length,angle,thk,'b'); mxs=filMonomerXSurface(sim,fil,'b'); if(!mxs) { mxs=filMonomerXFilament(sim,fil,'b',&fil2); if(mxs) { mxs=coinrandD(0.995); Sph_DcmxDcmt(fil2->po[fil2->back-1],fil->po[fil->back-2],dcm); Sph_Dcm2Xyz(dcm,angletry); }} if(mxs) { filRemoveMonomer(fil,'b'); sigmamult*=1.01; } else done=1; } if(done) filRemoveMonomer(fil,'f'); } return; }
/* checkwalls does the reflection, wrap-around, or absorption of molecules at walls by checking the current position, relative to the wall positions (as well as a past position for absorbing walls). Only molecules in live list ll are checked. If reborn is 1, only the newly added molecules are checked; if it's 0, the full list is checked. It does not reassign the molecules to boxes or sort the live and dead ones. It does not matter if molecules are assigned to the proper boxes or not. If bptr is NULL, all diffusing molecules are checked, otherwise only those in box bptr are checked. */ int checkwalls(simptr sim,int ll,int reborn,boxptr bptr) { int nmol,w,d,m; moleculeptr *mlist; double pos2,diff,difi,step,**difstep; wallptr wptr; if(sim->srfss) return 0; if(bptr) { nmol=bptr->nmol[ll]; mlist=bptr->mol[ll]; } else { nmol=sim->mols->nl[ll]; mlist=sim->mols->live[ll]; } if(!reborn) m=0; else if(reborn&&!bptr) m=sim->mols->topl[ll]; else {m=0;printf("SMOLDYN ERROR: in checkwalls, both bptr and reborn are defined");} for(w=0;w<2*sim->dim;w++) { wptr=sim->wlist[w]; d=wptr->wdim; if(wptr->type=='r'&&wptr->side==0) { // reflective pos2=2*wptr->pos; for(m=0;m<nmol;m++) if(mlist[m]->pos[d]<wptr->pos) { sim->eventcount[ETwall]++; mlist[m]->pos[d]=pos2-mlist[m]->pos[d];}} else if(wptr->type=='r') { pos2=2*wptr->pos; for(m=0;m<nmol;m++) if(mlist[m]->pos[d]>wptr->pos) { sim->eventcount[ETwall]++; mlist[m]->pos[d]=pos2-mlist[m]->pos[d];}} else if(wptr->type=='p'&&wptr->side==0) { // periodic pos2=wptr->opp->pos-wptr->pos; for(m=0;m<nmol;m++) if(mlist[m]->pos[d]<wptr->pos) { sim->eventcount[ETwall]++; mlist[m]->pos[d]+=pos2; mlist[m]->posoffset[d]-=pos2; }} else if(wptr->type=='p') { pos2=wptr->opp->pos-wptr->pos; for(m=0;m<nmol;m++) if(mlist[m]->pos[d]>wptr->pos) { sim->eventcount[ETwall]++; mlist[m]->pos[d]+=pos2; mlist[m]->posoffset[d]-=pos2; }} else if(wptr->type=='a') { // absorbing difstep=sim->mols->difstep; for(m=0;m<nmol;m++) { diff=wptr->pos-mlist[m]->pos[d]; difi=wptr->pos-mlist[m]->posx[d]; step=difstep[mlist[m]->ident][MSsoln]; if((!(wptr->side)&&diff>0)||(wptr->side&&diff<0)||coinrandD(exp(-2*difi*diff/step/step))) { sim->eventcount[ETwall]++; molkill(sim,mlist[m],ll,-1); }}}} return 0; }