Example #1
0
/** Computes the bending force (Dupin2007 eqn. 20 and 21) and adds this
    force to the particle forces (see \ref tclcommand_inter). 
    @param p1,p2,p3     Pointers to particles of triangle 1.
    @param p2,p3,p4     Pointers to particles of triangle 2.
    (triangles have particles p2 and p3 in common)
    @param iaparams  bending stiffness kb, initial rest angle phi0 (see \ref tclcommand_inter).
    @param force1 returns force on particles of triangle 1
    @param force2 returns force on particles of triangle 2
    (p1 += force1; p2 += 0.5*force1+0.5*force2; p3 += 0.5*force1+0.5*force2; p4 += force2;
    @return 0
*/
inline int calc_bending_force(Particle *p2, Particle *p1, Particle *p3, Particle *p4,
				 Bonded_ia_parameters *iaparams, double force1[3],
				 double force2[2])// first-fold-then-the-same approach
{		
	double n1[3],n2[3],dn1,dn2,phi,aa,fac,penal;
	int k;
	double fp1[3],fp2[3],fp3[3],fp4[3];
#ifdef LEES_EDWARDS
    double vv[3];
#endif
	int img[3];

	memcpy(fp1, p1->r.p, 3*sizeof(double));
	memcpy(img, p1->l.i, 3*sizeof(int));
	fold_position(fp1, img);
					
	memcpy(fp2, p2->r.p, 3*sizeof(double));
	memcpy(img, p2->l.i, 3*sizeof(int));
	fold_position(fp2, img);

	memcpy(fp3, p3->r.p, 3*sizeof(double));
	memcpy(img, p3->l.i, 3*sizeof(int));
	fold_position(fp3, img);

	memcpy(fp4, p4->r.p, 3*sizeof(double));
	memcpy(img, p4->l.i, 3*sizeof(int));
	fold_position(fp4, img);
	
	get_n_triangle(fp2,fp1,fp3,n1);
	dn1=normr(n1);
	get_n_triangle(fp2,fp3,fp4,n2);
	dn2=normr(n2);
	phi = angle_btw_triangles(fp1,fp2,fp3,fp4);		
	
	if (iaparams->p.bending_force.phi0 < 0.001 || iaparams->p.bending_force.phi0 > 2*M_PI - 0.001) 
		printf("bending_force.h, calc_bending_force: Resting angle is close to zero!!!\n");

	aa = (phi-iaparams->p.bending_force.phi0)/iaparams->p.bending_force.phi0;
	fac = iaparams->p.bending_force.kb * aa;

    penal = (1+1/pow(10*(2*M_PI-phi),2) + 1/pow(10*(phi),2));
	if (penal > 5.) penal = 5.;

//	fac = fac*penal; // This is to penalize the angles smaller than some threshold tr and also it penalizes angles greater than 2*Pi - tr. It prevents the objects to have negative angles.
	if (phi < 0.001 || phi > 2*M_PI - 0.001) printf("bending_force.h, calc_bending_force: Angle approaches 0 or 2*Pi\n");
	
	for(k=0;k<3;k++) {
		force1[k]=fac * n1[k]/dn1;
		force2[k]=fac * n2[k]/dn2;
	}	
  return 0;
}
inline void calc_volume(double *volume, int molType){ //first-fold-then-the-same approach
	double partVol=0.,A,norm[3],dn,hz;
	
	/** loop over particles */
	int c, np, i ,j;
	Cell *cell;
	Particle *p, *p1, *p2, *p3;
	double p11[3],p22[3],p33[3];
	int img[3];
	
	Bonded_ia_parameters *iaparams;
    int type_num, n_partners, id;
    BondedInteraction type;
	char *errtxt;

	//int test=0;
	//printf("rank%d, molType2: %d\n", rank,molType);
	/* Loop local cells */
	for (c = 0; c < local_cells.n; c++) {
		cell = local_cells.cell[c];
		p   = cell->part;
		np  = cell->n;
		/* Loop cell particles */
		for(i=0; i < np; i++) {				
			j = 0;
			p1 = &p[i];
			//printf("rank%d, i=%d neigh=%d\n", rank, i, p1->bl.n);
			while(j<p1->bl.n){
				/* bond type */
				type_num = p1->bl.e[j++];				//bond_number
				iaparams = &bonded_ia_params[type_num];
				type = iaparams->type;		  					//type of interaction 14...volume_force
				n_partners = iaparams->num;  					//bonded_neigbours
				id=p1->p.mol_id;						//mol_id of blood cell
				if(type == BONDED_IA_VOLUME_FORCE && id == molType){ // BONDED_IA_VOLUME_FORCE with correct molType   !!!!!!!!!!!!! needs area force local !!!!!!!!!!!!!!!!!!
					p2 = local_particles[p1->bl.e[j++]];
					if (!p2) {
						printf("broken: particles sum %d, id %d, partn %d, bond %d\n", np,id,n_partners,type_num); 
						errtxt = runtime_error(128 + 2*ES_INTEGER_SPACE);
						ERROR_SPRINTF(errtxt,"{volume calc 078 bond broken between particles %d and %d (particles not stored on the same node - volume_force1)} ",
						  p1->p.identity, p1->bl.e[j-1]);
						return;
					}
					/* fetch particle 3 */
					p3 = local_particles[p1->bl.e[j++]];
					if (!p3) {
						errtxt = runtime_error(128 + 3*ES_INTEGER_SPACE);
						ERROR_SPRINTF(errtxt,"{volume calc 079 bond broken between particles %d, %d and %d (particles not stored on the same node); n %d max %d} ",
							p1->p.identity, p1->bl.e[j-2], p1->bl.e[j-1],p1->bl.n,p1->bl.max);
						return;
					}
					memcpy(p11, p1->r.p, 3*sizeof(double));
					memcpy(img, p1->l.i, 3*sizeof(int));
					fold_position(p11, img);
									
					memcpy(p22, p2->r.p, 3*sizeof(double));
					memcpy(img, p2->l.i, 3*sizeof(int));
					fold_position(p22, img);
				
					memcpy(p33, p3->r.p, 3*sizeof(double));
					memcpy(img, p3->l.i, 3*sizeof(int));
					fold_position(p33, img);
				
					get_n_triangle(p11,p22,p33,norm);
					dn=normr(norm);
					A=area_triangle(p11,p22,p33);
					hz=1.0/3.0 *(p11[2]+p22[2]+p33[2]);
					partVol += A * -1*norm[2]/dn * hz;	
				}
				else{
					j+=n_partners;
				}	
			}
		}
    }
	MPI_Allreduce(&partVol, volume, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
}
inline void add_volume_force(double volume, int molType){  //first-fold-then-the-same approach
	double A,norm[3],dn; //partVol=0.

	double vv, force[3];
	int k;
	int img[3];
	
	/** loop over particles */
	int c, np, i ,j;
	Cell *cell;
	Particle *p, *p1, *p2, *p3;
	double p11[3],p22[3],p33[3];
	Bonded_ia_parameters *iaparams;
    int type_num, n_partners, id;
    BondedInteraction type;
	char *errtxt;

	int test=0;
	
	/* Loop local cells */
	for (c = 0; c < local_cells.n; c++) {
		cell = local_cells.cell[c];
		p   = cell->part;
		np  = cell->n;
		
		/* Loop cell particles */
		for(i=0; i < np; i++) {				
			j = 0;
			p1=&p[i];
			//printf("i=%d neigh=%d\n", i, p1->bl.n);
			while(j<p1->bl.n){
				/* bond type */
				type_num = p1->bl.e[j++];
				iaparams = &bonded_ia_params[type_num];
				type = iaparams->type;
				n_partners = iaparams->num;
				id=p1->p.mol_id;
				if(type == BONDED_IA_VOLUME_FORCE && id == molType){ // BONDED_IA_VOLUME_FORCE with correct molType
					test++;
					/* fetch particle 2 */
					p2 = local_particles[p1->bl.e[j++]];
					if (!p2) {
						errtxt = runtime_error(128 + 2*ES_INTEGER_SPACE);
						ERROR_SPRINTF(errtxt,"{volume add 078 bond broken between particles %d and %d (particles not stored on the same node - volume_force2)} ",
						  p1->p.identity, p1->bl.e[j-1]);
						return;
					}
					/* fetch particle 3 */
					p3 = local_particles[p1->bl.e[j++]];
					if (!p3) {
						errtxt = runtime_error(128 + 3*ES_INTEGER_SPACE);
						ERROR_SPRINTF(errtxt,"{volume add 079 bond broken between particles %d, %d and %d (particles not stored on the same node); n %d max %d} ",
							p1->p.identity, p1->bl.e[j-2], p1->bl.e[j-1],p1->bl.n,p1->bl.max);
						return;
					}
					memcpy(p11, p1->r.p, 3*sizeof(double));
					memcpy(img, p1->l.i, 3*sizeof(int));
					fold_position(p11, img);
									
					memcpy(p22, p2->r.p, 3*sizeof(double));
					memcpy(img, p2->l.i, 3*sizeof(int));
					fold_position(p22, img);
				
					memcpy(p33, p3->r.p, 3*sizeof(double));
					memcpy(img, p3->l.i, 3*sizeof(int));
					fold_position(p33, img);
				

					
					get_n_triangle(p11,p22,p33,norm);
					dn=normr(norm);
					A=area_triangle(p11,p22,p33);
					{
				}
					vv=(volume - iaparams->p.volume_force.V0)/iaparams->p.volume_force.V0;
					
					for(k=0;k<3;k++) {
						force[k]=iaparams->p.volume_force.kv * vv * A * norm[k]/dn * 1.0 / 3.0;
						//printf("%e ",force[k]);
						p1->f.f[k] += force[k]; 
						p2->f.f[k] +=  force[k];
						p3->f.f[k] +=  force[k];
					}

				}
				else{
					j+=n_partners;
				}
			}
		}
    }
	
}
Example #4
0
inline void calc_volume(double *volume, int molType){ //first-fold-then-the-same approach
	double partVol=0.,A,norm[3],dn,hz;
	
	/** loop over particles */
	int c, np, i ,j;
	Cell *cell;
	Particle *p, *p1, *p2, *p3;
	double p11[3],p22[3],p33[3];
	int img[3];
	double AA[3],BB[3];
	
	Bonded_ia_parameters *iaparams;
    int type_num, n_partners, id;
    BondedInteraction type;

	//int test=0;
	//printf("rank%d, molType2: %d\n", rank,molType);
	/* Loop local cells */
	for (c = 0; c < local_cells.n; c++) {
		cell = local_cells.cell[c];
		p   = cell->part;
		np  = cell->n;
		/* Loop cell particles */
		for(i=0; i < np; i++) {				
			j = 0;
			p1 = &p[i];
			//printf("rank%d, i=%d neigh=%d\n", rank, i, p1->bl.n);
			while(j<p1->bl.n){
				/* bond type */
				type_num = p1->bl.e[j++];				//bond_number
				iaparams = &bonded_ia_params[type_num];
				type = iaparams->type;		  					//type of interaction 14...volume_force
				n_partners = iaparams->num;  					//bonded_neigbours
				id=p1->p.mol_id;						//mol_id of blood cell
				if(type == BONDED_IA_VOLUME_FORCE && id == molType){ // BONDED_IA_VOLUME_FORCE with correct molType   !!!!!!!!!!!!! needs area force local !!!!!!!!!!!!!!!!!!
					p2 = local_particles[p1->bl.e[j++]];
					if (!p2) {
                        printf("broken: particles sum %d, id %d, partn %d, bond %d\n", np,id,n_partners,type_num);
                        ostringstream msg;
                        msg <<"volume calc: bond broken between particles " << p1->p.identity << " and " << p1->bl.e[j-1] << " (particles not stored on the same node - volume_force1)";
                        runtimeError(msg);
						return;
					}
					/* fetch particle 3 */
					p3 = local_particles[p1->bl.e[j++]];
                    if (!p3) {
                        ostringstream msg;
                        msg <<"volume calc: bond broken between particles " << p1->p.identity << ", " << p1->bl.e[j-2] << " and " << p1->bl.e[j-1] << " (particles not stored on the same node); n " << p1->bl.n << " max " << p1->bl.max;
                        runtimeError(msg);
						return;
					}
					// particles fetched

					#ifdef GHOST_FLAG
					// first find out which particle out of p1, p2 (possibly p3, p4) is not a ghost particle. In almost all cases it is p1, however, it might be other one. we call this particle reference particle.
					if (p1->l.ghost != 1) {
						//unfold non-ghost particle using image, because for physical particles, the structure p->l.i is correctly set
						memmove(p11, p1->r.p, 3*sizeof(double));
						memmove(img, p1->l.i, 3*sizeof(int));
						unfold_position(p11,img);
						// other coordinates are obtained from its relative positions to the reference particle
						get_mi_vector(AA, p2->r.p, p11);
						get_mi_vector(BB, p3->r.p, p11);
						for (int i=0; i < 3; i++) { p22[i] = p11[i] + AA[i]; p33[i] = p11[i] + BB[i]; }
					} else {
						// in case the first particle is a ghost particle
						if (p2->l.ghost != 1) {
							memmove(p22, p2->r.p, 3*sizeof(double));
							memmove(img, p2->l.i, 3*sizeof(int));
							unfold_position(p22,img);
							get_mi_vector(AA, p1->r.p, p22);
							get_mi_vector(BB, p3->r.p, p22);
							for (int i=0; i < 3; i++) { p11[i] = p22[i] + AA[i]; p33[i] = p22[i] + BB[i]; }
						} else {
							// in case the first and the second particle are ghost particles
							if (p3->l.ghost != 1) {
								memmove(p33, p3->r.p, 3*sizeof(double));
								memmove(img, p3->l.i, 3*sizeof(int));
								unfold_position(p33,img);
								get_mi_vector(AA, p1->r.p, p33);
								get_mi_vector(BB, p2->r.p, p33);
								for (int i=0; i < 3; i++) { p11[i] = p33[i] + AA[i]; p22[i] = p33[i] + BB[i]; }
							} else {
								printf("Something wrong in area_force_local.hpp: All particles in a bond are ghost particles, impossible to unfold the positions...");
								return;
							}
						}
					}
					#endif
					#ifndef GHOST_FLAG
						// if ghost flag was not defined we have no other option than to assume the first particle is a physical one.
						memmove(p11, p1->r.p, 3*sizeof(double));
						memmove(img, p1->l.i, 3*sizeof(int));
						unfold_position(p11,img);
						// other coordinates are obtained from its relative positions to the reference particle
						get_mi_vector(AA, p2->r.p, p11);
						get_mi_vector(BB, p3->r.p, p11);
						for (int i=0; i < 3; i++) { p22[i] = p11[i] + AA[i]; p33[i] = p11[i] + BB[i]; }
					#endif

					get_n_triangle(p11,p22,p33,norm);
					dn=normr(norm);
					A=area_triangle(p11,p22,p33);
					hz=1.0/3.0 *(p11[2]+p22[2]+p33[2]);
					partVol += A * -1*norm[2]/dn * hz;	
				}
				else{
					j+=n_partners;
				}	
			}
		}
    }
	MPI_Allreduce(&partVol, volume, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
}
Example #5
0
inline void add_volume_force(double volume, int molType){  //first-fold-then-the-same approach
	double A,norm[3],dn; //partVol=0.

	double vv, force[3];
	int k;
	int img[3];
	
	/** loop over particles */
	int c, np, i ,j;
	Cell *cell;
	Particle *p, *p1, *p2, *p3;
	double p11[3],p22[3],p33[3];
	Bonded_ia_parameters *iaparams;
    int type_num, n_partners, id;
    BondedInteraction type;

	double AA[3],BB[3];
	
	int test=0;
	
	/* Loop local cells */
	for (c = 0; c < local_cells.n; c++) {
		cell = local_cells.cell[c];
		p   = cell->part;
		np  = cell->n;
		
		/* Loop cell particles */
		for(i=0; i < np; i++) {				
			j = 0;
			p1=&p[i];
			//printf("i=%d neigh=%d\n", i, p1->bl.n);
			while(j<p1->bl.n){
				/* bond type */
				type_num = p1->bl.e[j++];
				iaparams = &bonded_ia_params[type_num];
				type = iaparams->type;
				n_partners = iaparams->num;
				id=p1->p.mol_id;
				if(type == BONDED_IA_VOLUME_FORCE && id == molType){ // BONDED_IA_VOLUME_FORCE with correct molType
					test++;
					/* fetch particle 2 */
					p2 = local_particles[p1->bl.e[j++]];
                    if (!p2) {
                        ostringstream msg;
                        msg <<"volume add: bond broken between particles " << p1->p.identity << " and " << p1->bl.e[j-1] << " (particles not stored on the same node - volume_force2)";
                        runtimeError(msg);
						return;
					}
					/* fetch particle 3 */
					p3 = local_particles[p1->bl.e[j++]];
                    if (!p3) {
                        ostringstream msg;
                        msg <<"volume calc: bond broken between particles " << p1->p.identity << ", " << p1->bl.e[j-2] << " and " << p1->bl.e[j-1] << " (particles not stored on the same node); n " << p1->bl.n << " max " << p1->bl.max;
                        runtimeError(msg);
						return;
					}
					// particles fetched

					#ifdef GHOST_FLAG
					// first find out which particle out of p1, p2 (possibly p3, p4) is not a ghost particle. In almost all cases it is p1, however, it might be other one. we call this particle reference particle.
					if (p1->l.ghost != 1) {
						//unfold non-ghost particle using image, because for physical particles, the structure p->l.i is correctly set
						memmove(p11, p1->r.p, 3*sizeof(double));
						memmove(img, p1->l.i, 3*sizeof(int));
						unfold_position(p11,img);
						// other coordinates are obtained from its relative positions to the reference particle
						get_mi_vector(AA, p2->r.p, p11);
						get_mi_vector(BB, p3->r.p, p11);
						for (int i=0; i < 3; i++) { p22[i] = p11[i] + AA[i]; p33[i] = p11[i] + BB[i]; }
					} else {
						// in case the first particle is a ghost particle
						if (p2->l.ghost != 1) {
							memmove(p22, p2->r.p, 3*sizeof(double));
							memmove(img, p2->l.i, 3*sizeof(int));
							unfold_position(p22,img);
							get_mi_vector(AA, p1->r.p, p22);
							get_mi_vector(BB, p3->r.p, p22);
							for (int i=0; i < 3; i++) { p11[i] = p22[i] + AA[i]; p33[i] = p22[i] + BB[i]; }
						} else {
							// in case the first and the second particle are ghost particles
							if (p3->l.ghost != 1) {
								memmove(p33, p3->r.p, 3*sizeof(double));
								memmove(img, p3->l.i, 3*sizeof(int));
								unfold_position(p33,img);
								get_mi_vector(AA, p1->r.p, p33);
								get_mi_vector(BB, p2->r.p, p33);
								for (int i=0; i < 3; i++) { p11[i] = p33[i] + AA[i]; p22[i] = p33[i] + BB[i]; }
							} else {
								printf("Something wrong in area_force_local.hpp: All particles in a bond are ghost particles, impossible to unfold the positions...");
								return;
							}
						}
					}
					#endif
					#ifndef GHOST_FLAG
						// if ghost flag was not defined we have no other option than to assume the first particle is a physical one.
						memmove(p11, p1->r.p, 3*sizeof(double));
						memmove(img, p1->l.i, 3*sizeof(int));
						unfold_position(p11,img);
						// other coordinates are obtained from its relative positions to the reference particle
						get_mi_vector(AA, p2->r.p, p11);
						get_mi_vector(BB, p3->r.p, p11);
						for (int i=0; i < 3; i++) { p22[i] = p11[i] + AA[i]; p33[i] = p11[i] + BB[i]; }
					#endif

					get_n_triangle(p11,p22,p33,norm);
					dn=normr(norm);
					A=area_triangle(p11,p22,p33);
					{
				}
					vv=(volume - iaparams->p.volume_force.V0)/iaparams->p.volume_force.V0;					
					for(k=0;k<3;k++) {
						force[k]=iaparams->p.volume_force.kv * vv * A * norm[k]/dn * 1.0 / 3.0;
						//printf("%e ",force[k]);
						p1->f.f[k] += force[k]; 
						p2->f.f[k] +=  force[k];
						p3->f.f[k] +=  force[k];
					}

				}
				else{
					j+=n_partners;
				}
			}
		}
    }
	
}