void integrate_vv(int n_steps) { int i; /* Prepare the Integrator */ on_integration_start(); /* if any method vetoes (P3M not initialized), immediately bail out */ if (check_runtime_errors()) return; /* Verlet list criterion */ skin2 = SQR(0.5 * skin); INTEG_TRACE(fprintf(stderr,"%d: integrate_vv: integrating %d steps (recalc_forces=%d)\n", this_node, n_steps, recalc_forces)); /* Integration Step: Preparation for first integration step: Calculate forces f(t) as function of positions p(t) ( and velocities v(t) ) */ if (recalc_forces) { thermo_heat_up(); #ifdef LB transfer_momentum = 0; #endif #ifdef LB_GPU transfer_momentum_gpu = 0; #endif //VIRTUAL_SITES pos (and vel for DPD) update for security reason !!! #ifdef VIRTUAL_SITES update_mol_vel_pos(); ghost_communicator(&cell_structure.update_ghost_pos_comm); if (check_runtime_errors()) return; #ifdef ADRESS // adress_update_weights(); if (check_runtime_errors()) return; #endif #endif force_calc(); //VIRTUAL_SITES distribute forces #ifdef VIRTUAL_SITES ghost_communicator(&cell_structure.collect_ghost_force_comm); init_forces_ghosts(); distribute_mol_force(); if (check_runtime_errors()) return; #endif ghost_communicator(&cell_structure.collect_ghost_force_comm); #ifdef ROTATION convert_initial_torques(); #endif thermo_cool_down(); /* Communication Step: ghost forces */ /*apply trap forces to trapped molecules*/ #ifdef MOLFORCES calc_and_apply_mol_constraints(); #endif rescale_forces(); recalc_forces = 0; } if (check_runtime_errors()) return; n_verlet_updates = 0; /* Integration loop */ for(i=0;i<n_steps;i++) { INTEG_TRACE(fprintf(stderr,"%d: STEP %d\n",this_node,i)); #ifdef BOND_CONSTRAINT save_old_pos(); #endif /* Integration Steps: Step 1 and 2 of Velocity Verlet scheme: v(t+0.5*dt) = v(t) + 0.5*dt * f(t) p(t + dt) = p(t) + dt * v(t+0.5*dt) NOTE 1: Prefactors do not occur in formulas since we use rescaled forces and velocities. NOTE 2: Depending on the integration method Step 1 and Step 2 cannot be combined for the translation. */ if(integ_switch == INTEG_METHOD_NPT_ISO || nemd_method != NEMD_METHOD_OFF) { propagate_vel(); propagate_pos(); } else propagate_vel_pos(); #ifdef ROTATION propagate_omega_quat(); #endif #ifdef BOND_CONSTRAINT /**Correct those particle positions that participate in a rigid/constrained bond */ ghost_communicator(&cell_structure.update_ghost_pos_comm); correct_pos_shake(); #endif #ifdef ELECTROSTATICS if(coulomb.method == COULOMB_MAGGS) { maggs_propagate_B_field(0.5*time_step); } #endif #ifdef NPT if (check_runtime_errors()) break; #endif cells_update_ghosts(); //VIRTUAL_SITES update pos and vel (for DPD) #ifdef VIRTUAL_SITES update_mol_vel_pos(); ghost_communicator(&cell_structure.update_ghost_pos_comm); if (check_runtime_errors()) break; #if defined(VIRTUAL_SITES_RELATIVE) && defined(LB) // This is on a workaround stage: // When using virtual sites relative and LB at the same time, it is necessary // to reassemble the cell lists after all position updates, also of virtual // particles. if (cell_structure.type == CELL_STRUCTURE_DOMDEC && (!dd.use_vList) ) cells_update_ghosts(); #endif #ifdef ADRESS //adress_update_weights(); if (check_runtime_errors()) break; #endif #endif /* Integration Step: Step 3 of Velocity Verlet scheme: Calculate f(t+dt) as function of positions p(t+dt) ( and velocities v(t+0.5*dt) ) */ #ifdef LB transfer_momentum = 1; #endif #ifdef LB_GPU transfer_momentum_gpu = 1; #endif force_calc(); //VIRTUAL_SITES distribute forces #ifdef VIRTUAL_SITES ghost_communicator(&cell_structure.collect_ghost_force_comm); init_forces_ghosts(); distribute_mol_force(); if (check_runtime_errors()) break; #endif /* Communication step: ghost forces */ ghost_communicator(&cell_structure.collect_ghost_force_comm); /*apply trap forces to trapped molecules*/ #ifdef MOLFORCES calc_and_apply_mol_constraints(); #endif if (check_runtime_errors()) break; /* Integration Step: Step 4 of Velocity Verlet scheme: v(t+dt) = v(t+0.5*dt) + 0.5*dt * f(t+dt) */ rescale_forces_propagate_vel(); recalc_forces = 0; #ifdef LB if (lattice_switch & LATTICE_LB) lattice_boltzmann_update(); if (check_runtime_errors()) break; #endif #ifdef LB_GPU if(this_node == 0){ if (lattice_switch & LATTICE_LB_GPU) lattice_boltzmann_update_gpu(); } #endif #ifdef BOND_CONSTRAINT ghost_communicator(&cell_structure.update_ghost_pos_comm); correct_vel_shake(); #endif #ifdef ROTATION convert_torques_propagate_omega(); #endif //VIRTUAL_SITES update vel #ifdef VIRTUAL_SITES ghost_communicator(&cell_structure.update_ghost_pos_comm); update_mol_vel(); if (check_runtime_errors()) break; #endif #ifdef ELECTROSTATICS if(coulomb.method == COULOMB_MAGGS) { maggs_propagate_B_field(0.5*time_step); } #endif #ifdef NPT if((this_node==0) && (integ_switch == INTEG_METHOD_NPT_ISO)) nptiso.p_inst_av += nptiso.p_inst; #endif /* Propagate time: t = t+dt */ sim_time += time_step; } /* verlet list statistics */ if(n_verlet_updates>0) verlet_reuse = n_steps/(double) n_verlet_updates; else verlet_reuse = 0; #ifdef NPT if(integ_switch == INTEG_METHOD_NPT_ISO) { nptiso.invalidate_p_vel = 0; MPI_Bcast(&nptiso.p_inst, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); MPI_Bcast(&nptiso.p_diff, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); MPI_Bcast(&nptiso.volume, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); if(this_node==0) nptiso.p_inst_av /= 1.0*n_steps; MPI_Bcast(&nptiso.p_inst_av, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); } #endif }
void integrate_vv(int n_steps) { int i; /* Prepare the Integrator */ on_integration_start(); /* if any method vetoes (P3M not initialized), immediately bail out */ if (check_runtime_errors()) return; /* Verlet list criterion */ skin2 = SQR(0.5 * skin); INTEG_TRACE(fprintf(stderr,"%d: integrate_vv: integrating %d steps (recalc_forces=%d)\n", this_node, n_steps, recalc_forces)); /* Integration Step: Preparation for first integration step: Calculate forces f(t) as function of positions p(t) ( and velocities v(t) ) */ if (recalc_forces) { thermo_heat_up(); #ifdef LB transfer_momentum = 0; #endif #ifdef LB_GPU transfer_momentum_gpu = 0; #endif //VIRTUAL_SITES pos (and vel for DPD) update for security reason !!! #ifdef VIRTUAL_SITES update_mol_vel_pos(); ghost_communicator(&cell_structure.update_ghost_pos_comm); if (check_runtime_errors()) return; #ifdef ADRESS // adress_update_weights(); if (check_runtime_errors()) return; #endif #endif force_calc(); //VIRTUAL_SITES distribute forces #ifdef VIRTUAL_SITES ghost_communicator(&cell_structure.collect_ghost_force_comm); init_forces_ghosts(); distribute_mol_force(); if (check_runtime_errors()) return; #endif ghost_communicator(&cell_structure.collect_ghost_force_comm); #ifdef ROTATION convert_initial_torques(); #endif thermo_cool_down(); /* Communication Step: ghost forces */ /*apply trap forces to trapped molecules*/ #ifdef MOLFORCES calc_and_apply_mol_constraints(); #endif rescale_forces(); recalc_forces = 0; } if (check_runtime_errors()) return; n_verlet_updates = 0; /* Integration loop */ for(i=0;i<n_steps;i++) { INTEG_TRACE(fprintf(stderr,"%d: STEP %d\n",this_node,i)); #ifdef BOND_CONSTRAINT save_old_pos(); #endif /* Integration Steps: Step 1 and 2 of Velocity Verlet scheme: v(t+0.5*dt) = v(t) + 0.5*dt * f(t) p(t + dt) = p(t) + dt * v(t+0.5*dt) NOTE 1: Prefactors do not occur in formulas since we use rescaled forces and velocities. NOTE 2: Depending on the integration method Step 1 and Step 2 cannot be combined for the translation. */ if(integ_switch == INTEG_METHOD_NPT_ISO || nemd_method != NEMD_METHOD_OFF) { propagate_vel(); propagate_pos(); } else propagate_vel_pos(); #ifdef ROTATION propagate_omega_quat(); #endif #ifdef BOND_CONSTRAINT /**Correct those particle positions that participate in a rigid/constrained bond */ ghost_communicator(&cell_structure.update_ghost_pos_comm); correct_pos_shake(); #endif #ifdef ELECTROSTATICS if(coulomb.method == COULOMB_MAGGS) { propagate_B_field(0.5*time_step); if(maggs.yukawa) maggs_propagate_psi_vel_pos(time_step); } #endif #ifdef NPT if (check_runtime_errors()) break; #endif cells_update_ghosts(); //VIRTUAL_SITES update pos and vel (for DPD) #ifdef VIRTUAL_SITES update_mol_vel_pos(); ghost_communicator(&cell_structure.update_ghost_pos_comm); if (check_runtime_errors()) break; #ifdef ADRESS //adress_update_weights(); if (check_runtime_errors()) break; #endif #endif /* Integration Step: Step 3 of Velocity Verlet scheme: Calculate f(t+dt) as function of positions p(t+dt) ( and velocities v(t+0.5*dt) ) */ #ifdef LB transfer_momentum = 1; #endif #ifdef LB_GPU transfer_momentum_gpu = 1; #endif force_calc(); //VIRTUAL_SITES distribute forces #ifdef VIRTUAL_SITES ghost_communicator(&cell_structure.collect_ghost_force_comm); init_forces_ghosts(); distribute_mol_force(); if (check_runtime_errors()) break; #endif /* Communication step: ghost forces */ ghost_communicator(&cell_structure.collect_ghost_force_comm); /*apply trap forces to trapped molecules*/ #ifdef MOLFORCES calc_and_apply_mol_constraints(); #endif if (check_runtime_errors()) break; /* Integration Step: Step 4 of Velocity Verlet scheme: v(t+dt) = v(t+0.5*dt) + 0.5*dt * f(t+dt) */ rescale_forces_propagate_vel(); #ifdef LB if (lattice_switch & LATTICE_LB) lattice_boltzmann_update(); if (check_runtime_errors()) break; #endif #ifdef LB_GPU if(this_node == 0){ if (lattice_switch & LATTICE_LB_GPU) lattice_boltzmann_update_gpu(); } #endif #ifdef BOND_CONSTRAINT ghost_communicator(&cell_structure.update_ghost_pos_comm); correct_vel_shake(); #endif //VIRTUAL_SITES update vel #ifdef VIRTUAL_SITES ghost_communicator(&cell_structure.update_ghost_pos_comm); update_mol_vel(); if (check_runtime_errors()) break; #endif #ifdef ELECTROSTATICS if(coulomb.method == COULOMB_MAGGS) { propagate_B_field(0.5*time_step); if(maggs.yukawa) maggs_propagate_psi_vel(0.5*time_step); MAGGS_TRACE(check_gauss_law();); }
int lattice_read_file(Lattice* lattice, char* filename) { // ExternalPotentialTabulated *e = &(external_potentials[number].e.tabulated); FILE* infile = fopen(filename, "r"); if (!infile) { runtimeErrorMsg() <<"Could not open file "<< filename << "\n"; return ES_ERROR; } char first_line[100]; char* token; double res[3]; double size[3]; double offset[3]={0,0,0}; int dim=0; if (fgets(first_line, 100, infile) == NULL) { fprintf(stderr, "Nothing read from file\n"); return ES_ERROR; } token = strtok(first_line, " \t"); if (!token) { fprintf(stderr, "Error reading dimensionality\n"); return ES_ERROR; } dim = atoi(token); if (dim<=0) { fprintf(stderr, "Error reading dimensionality\n"); return ES_ERROR; } token = strtok(NULL, " \t"); if (!token) { fprintf(stderr, "Could not read box_l[0]\n"); return ES_ERROR; } size[0] = atof(token); token = strtok(NULL, " \t"); if (!token) { fprintf(stderr, "Could not read box_l[1]\n"); return ES_ERROR; } size[1] = atof(token); token = strtok(NULL, " \t"); if (!token) { fprintf(stderr, "Could not read box_l[2]\n"); return ES_ERROR;} size[2] = atof(token); token = strtok(NULL, " \t"); if (!token) { fprintf(stderr, "Could not read res[0]\n"); return ES_ERROR;} res[0] = atof(token); token = strtok(NULL, " \t"); if (!token) { fprintf(stderr, "Could not read res[1]\n"); return ES_ERROR;} res[1] = atof(token); token = strtok(NULL, " \t"); if (!token) { fprintf(stderr, "Could not read res[2]\n"); return ES_ERROR;} res[2] = atof(token); token = strtok(NULL, " \t"); if (token) { offset[0]=atof(token); token = strtok(NULL, " \t"); if (!token) { fprintf(stderr, "Could not read offset[1]\n"); return ES_ERROR;} offset[1] = atof(token); token = strtok(NULL, " \t"); if (!token) { fprintf(stderr, "Could not read offset[2]\n"); return ES_ERROR;} offset[2] = atof(token); } lattice->offset[0]=offset[0]; lattice->offset[1]=offset[1]; lattice->offset[2]=offset[2]; int halosize=1; if (size[0] > 0 && fabs(size[0] - box_l[0]) > ROUND_ERROR_PREC) { runtimeErrorMsg() <<"Box size in x is wrong "<< size[0] << " vs " << box_l[0] <<"\n"; return ES_ERROR; } if (size[1] > 0 && fabs(size[1] - box_l[1]) > ROUND_ERROR_PREC) { runtimeErrorMsg() <<"Box size in y is wrong "<< size[1] << " vs " << box_l[1] <<"\n"; return ES_ERROR; } if (size[2] > 0 && fabs(size[2] - box_l[2]) > ROUND_ERROR_PREC) { runtimeErrorMsg() <<"Box size in z is wrong "<< size[2] << " vs " << box_l[2] <<"\n"; return ES_ERROR; } if (res[0] > 0) if (skin/res[0]>halosize) halosize = (int)ceil(skin/res[0]); if (res[1] > 0) if (skin/res[1]>halosize) halosize = (int)ceil(skin/res[1]); if (res[2] > 0) if (skin/res[2]>halosize) halosize = (int)ceil(skin/res[2]); // Now we count how many entries we have: lattice->init(res, offset, halosize, dim); lattice->interpolation_type = INTERPOLATION_LINEAR; char* line = (char*) Utils::malloc((3+dim)*ES_DOUBLE_SPACE); double pos[3]; double f[3]; int i; while (fgets(line, 200, infile)) { if (strlen(line)<2) continue; token = strtok(line, " \t"); if (!token) { fprintf(stderr, "Could not read pos[0]\n"); return ES_ERROR; } pos[0] = atof(token); token = strtok(NULL, " \t"); if (!token) { fprintf(stderr, "Could not read pos[1] in line:\n%s\n", line); return ES_ERROR; } pos[1] = atof(token); token = strtok(NULL, " \t"); if (!token) { fprintf(stderr, "Could not read pos[1]\n"); return ES_ERROR; } pos[2] = atof(token); for (i=0; i<dim;i++) { token = strtok(NULL, " \t"); if (!token) { fprintf(stderr, "Could not read f[%d]\n", i); return ES_ERROR; } f[i] = atof(token); } lattice->set_data_for_global_position_with_periodic_image(pos, f); } free(line); write_local_lattice_to_file("lattice", lattice); if (check_runtime_errors()!=0) return ES_ERROR; return ES_OK; }
void on_integration_start() { char *errtext; EVENT_TRACE(fprintf(stderr, "%d: on_integration_start\n", this_node)); INTEG_TRACE(fprintf(stderr,"%d: on_integration_start: reinit_thermo = %d, resort_particles=%d\n", this_node,reinit_thermo,resort_particles)); /********************************************/ /* sanity checks */ /********************************************/ if ( time_step < 0.0 ) { errtext = runtime_error(128); ERROR_SPRINTF(errtext, "{010 time_step not set} "); } if ( skin < 0.0 ) { errtext = runtime_error(128); ERROR_SPRINTF(errtext,"{011 skin not set} "); } if ( temperature < 0.0 ) { errtext = runtime_error(128); ERROR_SPRINTF(errtext,"{012 thermostat not initialized} "); } #ifdef NPT if (integ_switch == INTEG_METHOD_NPT_ISO) { if (nptiso.piston <= 0.0) { char *errtext = runtime_error(128); ERROR_SPRINTF(errtext,"{014 npt on, but piston mass not set} "); } #ifdef ELECTROSTATICS switch(coulomb.method) { case COULOMB_NONE: break; #ifdef P3M case COULOMB_P3M: break; #endif /*P3M*/ default: { char *errtext = runtime_error(128); ERROR_SPRINTF(errtext,"{014 npt only works with P3M} "); } } #endif /*ELECTROSTATICS*/ #ifdef DIPOLES switch (coulomb.Dmethod) { case DIPOLAR_NONE: break; #ifdef DP3M case DIPOLAR_P3M: break; #endif default: { char *errtext = runtime_error(128); ERROR_SPRINTF(errtext,"NpT does not work with your dipolar method, please use P3M."); } } #endif /* ifdef DIPOLES */ } #endif /*NPT*/ if (!check_obs_calc_initialized()) return; #ifdef LB if(lattice_switch & LATTICE_LB) { if (lbpar.agrid <= 0.0) { errtext = runtime_error(128); ERROR_SPRINTF(errtext,"{098 Lattice Boltzmann agrid not set} "); } if (lbpar.tau <= 0.0) { errtext = runtime_error(128); ERROR_SPRINTF(errtext,"{099 Lattice Boltzmann time step not set} "); } if (lbpar.rho <= 0.0) { errtext = runtime_error(128); ERROR_SPRINTF(errtext,"{100 Lattice Boltzmann fluid density not set} "); } if (lbpar.viscosity <= 0.0) { errtext = runtime_error(128); ERROR_SPRINTF(errtext,"{101 Lattice Boltzmann fluid viscosity not set} "); } if (dd.use_vList && skin>=lbpar.agrid/2.0) { errtext = runtime_error(128); ERROR_SPRINTF(errtext, "{104 LB requires either no Verlet lists or that the skin of the verlet list to be less than half of lattice-Boltzmann grid spacing.} "); } } #endif #ifdef LB_GPU if(this_node == 0){ if(lattice_switch & LATTICE_LB_GPU) { if (lbpar_gpu.agrid < 0.0) { errtext = runtime_error(128); ERROR_SPRINTF(errtext,"{098 Lattice Boltzmann agrid not set} "); } if (lbpar_gpu.tau < 0.0) { errtext = runtime_error(128); ERROR_SPRINTF(errtext,"{099 Lattice Boltzmann time step not set} "); } if (lbpar_gpu.rho < 0.0) { errtext = runtime_error(128); ERROR_SPRINTF(errtext,"{100 Lattice Boltzmann fluid density not set} "); } if (lbpar_gpu.viscosity < 0.0) { errtext = runtime_error(128); ERROR_SPRINTF(errtext,"{101 Lattice Boltzmann fluid viscosity not set} "); } if (lb_reinit_particles_gpu) { lb_realloc_particles_gpu(); lb_reinit_particles_gpu = 0; } } } #endif #ifdef METADYNAMICS meta_init(); #endif #ifdef CATALYTIC_REACTIONS if(reaction.ct_rate != 0.0) { if( dd.use_vList == 0 || cell_structure.type != CELL_STRUCTURE_DOMDEC) { errtext = runtime_error(128); ERROR_SPRINTF(errtext,"{105 The CATALYTIC_REACTIONS feature requires verlet lists and domain decomposition} "); check_runtime_errors(); } if(max_cut < reaction.range) { errtext = runtime_error(128); ERROR_SPRINTF(errtext,"{106 Reaction range of %f exceeds maximum cutoff of %f} ", reaction.range, max_cut); } } #endif /********************************************/ /* end sanity checks */ /********************************************/ /* Prepare the thermostat */ if (reinit_thermo) { thermo_init(); reinit_thermo = 0; recalc_forces = 1; } /* Ensemble preparation: NVT or NPT */ integrate_ensemble_init(); /* Update particle and observable information for routines in statistics.c */ invalidate_obs(); freePartCfg(); on_observable_calc(); }
void integrate_sd(int n_steps) { /* Prepare the Integrator */ on_integration_start(); /* if any method vetoes (P3M not initialized), immediately bail out */ if (check_runtime_errors()) return; INTEG_TRACE(fprintf(stderr,"%d: integrate_vv: integrating %d steps (recalc_forces=%d)\n", this_node, n_steps, recalc_forces)); /* Integration Step: Calculate forces f(t) as function of positions p(t) ( and velocities v(t) ) */ //if (recalc_forces) { //thermo_heat_up(); ghost_communicator(&cell_structure.collect_ghost_force_comm); #ifdef ROTATION convert_initial_torques(); #endif //thermo_cool_down(); /* Communication Step: ghost forces */ /*apply trap forces to trapped molecules*/ #ifdef MOLFORCES // prob. works only with harmonic bounds calc_and_apply_mol_constraints(); #endif /* should be pretty late, since it needs to zero out the total force */ #ifdef COMFIXED calc_comfixed(); #endif //rescale_forces(); #ifdef COLLISION_DETECTION //should not be neccessery, as integrator avoids collision handle_collisions(); #endif // end of force calculation #ifdef GHMC if(thermo_switch & THERMO_GHMC) ghmc_init(); #endif if (check_runtime_errors()) return; n_verlet_updates = 0; /* Integration loop */ for(int step=0;step<n_steps;step++) { INTEG_TRACE(fprintf(stderr,"%d: STEP %d\n",this_node,step)); //sd_set_particles_apart(); #ifdef BOND_CONSTRAINT save_old_pos(); #endif #ifdef GHMC if(thermo_switch & THERMO_GHMC) { if (step % ghmc_nmd == 0) ghmc_momentum_update(); } #endif if(thermo_switch & ~(THERMO_SD|THERMO_BD) ){ static bool warned_thermo_sd_other=false; if (!warned_thermo_sd_other){ fprintf (stderr, "Warning, using another thermo than the one provided by StokesDynamics breaks (most likely) StokesDynamics.\n"); warned_thermo_sd_other=true; } } if (thermo_switch & THERMO_SD && thermo_switch &THERMO_BD) { fprintf (stderr, "Warning: cannot use BD and SD. Disabeling BD!\n"); thermo_switch &= ~THERMO_BD; } /* Integration Step: Step 3 of Velocity Verlet scheme: Calculate f(t) as function of positions p(t) ( and ``velocities'' v(t) ) */ #ifdef LB transfer_momentum = 1; #endif #ifdef LB_GPU transfer_momentum_gpu = 1; #endif force_calc(); #ifdef CATALYTIC_REACTIONS integrate_reaction(); #endif if (check_runtime_errors()) break; #ifdef LB if (lattice_switch & LATTICE_LB) lattice_boltzmann_update(); if (check_runtime_errors()) break; #endif #ifdef LB_GPU if(this_node == 0){ #ifdef ELECTROKINETICS if (ek_initialized) { ek_integrate(); } else { #endif if (lattice_switch & LATTICE_LB_GPU) lattice_boltzmann_update_gpu(); #ifdef ELECTROKINETICS } #endif } #endif //LB_GPU #ifdef ELECTROSTATICS if(coulomb.method == COULOMB_MAGGS) { maggs_propagate_B_field(0.5*time_step); } #endif #ifdef NPT if((this_node==0) && (integ_switch == INTEG_METHOD_NPT_ISO)) nptiso.p_inst_av += nptiso.p_inst; #endif #ifdef GHMC if(thermo_switch & THERMO_GHMC) { if (step % ghmc_nmd == ghmc_nmd-1) ghmc_mc(); } #endif /** Integration Steps: Update the Positions \[ p_i(t + dt) = p_i(t) + dt * \mu_{ij} * f_j(t) + dt * \mu_{ij} * f^B_j \] */ propagate_pos_sd(); // we dont have velocities #ifdef BOND_CONSTRAINT static bool bond_constraint_with_sd_warned=false; if (!bond_constraint_with_sd_warned){ // warn only once fprintf (stderr, "Warning, using BOND_CONSTRAINT with StokesDynamics might not work as expected!.\n"); bond_constraint_with_sd_warned=true; } /**Correct those particle positions that participate in a rigid/constrained bond */ cells_update_ghosts(); correct_pos_shake(); #endif #ifdef ELECTROSTATICS if(coulomb.method == COULOMB_MAGGS) { maggs_propagate_B_field(0.5*time_step); } #endif #ifdef NPT if (check_runtime_errors()) break; #endif /* Propagate time: t = t+dt */ sim_time += time_step; } /* verlet list statistics */ if(n_verlet_updates>0) verlet_reuse = n_steps/(double) n_verlet_updates; else verlet_reuse = 0; #ifdef NPT if(integ_switch == INTEG_METHOD_NPT_ISO) { nptiso.invalidate_p_vel = 0; MPI_Bcast(&nptiso.p_inst, 1, MPI_DOUBLE, 0, comm_cart); MPI_Bcast(&nptiso.p_diff, 1, MPI_DOUBLE, 0, comm_cart); MPI_Bcast(&nptiso.volume, 1, MPI_DOUBLE, 0, comm_cart); if(this_node==0) nptiso.p_inst_av /= 1.0*n_steps; MPI_Bcast(&nptiso.p_inst_av, 1, MPI_DOUBLE, 0, comm_cart); } #endif #ifdef GHMC if(thermo_switch & THERMO_GHMC) ghmc_close(); #endif }
void integrate_vv(int n_steps) { int i; #ifdef REACTIONS int c, np, n; Particle * p1, *p2, **pairs; Cell * cell; double dist2, vec21[3], rand; if(reaction.rate > 0) { int reactants = 0, products = 0; int tot_reactants = 0, tot_products = 0; double ratexp, back_ratexp; ratexp = exp(-time_step*reaction.rate); on_observable_calc(); for (c = 0; c < local_cells.n; c++) { /* Loop cell neighbors */ for (n = 0; n < dd.cell_inter[c].n_neighbors; n++) { pairs = dd.cell_inter[c].nList[n].vList.pair; np = dd.cell_inter[c].nList[n].vList.n; /* verlet list loop */ for(i = 0; i < 2 * np; i += 2) { p1 = pairs[i]; //pointer to particle 1 p2 = pairs[i+1]; //pointer to particle 2 if( (p1->p.type == reaction.reactant_type && p2->p.type == reaction.catalyzer_type) || (p2->p.type == reaction.reactant_type && p1->p.type == reaction.catalyzer_type) ) { get_mi_vector(vec21, p1->r.p, p2->r.p); dist2 = sqrlen(vec21); if(dist2 < reaction.range * reaction.range) { rand =d_random(); if(rand > ratexp) { if(p1->p.type==reaction.reactant_type) { p1->p.type = reaction.product_type; } else { p2->p.type = reaction.product_type; } } } } } } } if (reaction.back_rate < 0) { // we have to determine it dynamically /* we count now how many reactants and products are in the sim box */ for (c = 0; c < local_cells.n; c++) { cell = local_cells.cell[c]; p1 = cell->part; np = cell->n; for(i = 0; i < np; i++) { if(p1[i].p.type == reaction.reactant_type) reactants++; else if(p1[i].p.type == reaction.product_type) products++; } } MPI_Allreduce(&reactants, &tot_reactants, 1, MPI_INT, MPI_SUM, comm_cart); MPI_Allreduce(&products, &tot_products, 1, MPI_INT, MPI_SUM, comm_cart); back_ratexp = ratexp * tot_reactants / tot_products ; //with this the asymptotic ratio reactant/product becomes 1/1 and the catalyzer volume only determines the time that it takes to reach this } else { //use the back reaction rate supplied by the user back_ratexp = exp(-time_step*reaction.back_rate); } if(back_ratexp < 1 ) { for (c = 0; c < local_cells.n; c++) { cell = local_cells.cell[c]; p1 = cell->part; np = cell->n; for(i = 0; i < np; i++) { if(p1[i].p.type == reaction.product_type) { rand = d_random(); if(rand > back_ratexp) { p1[i].p.type=reaction.reactant_type; } } } } } on_particle_change(); } #endif /* ifdef REACTIONS */ /* Prepare the Integrator */ on_integration_start(); /* if any method vetoes (P3M not initialized), immediately bail out */ if (check_runtime_errors()) return; /* Verlet list criterion */ skin2 = SQR(0.5 * skin); INTEG_TRACE(fprintf(stderr,"%d: integrate_vv: integrating %d steps (recalc_forces=%d)\n", this_node, n_steps, recalc_forces)); /* Integration Step: Preparation for first integration step: Calculate forces f(t) as function of positions p(t) ( and velocities v(t) ) */ if (recalc_forces) { thermo_heat_up(); #ifdef LB transfer_momentum = 0; #endif #ifdef LB_GPU transfer_momentum_gpu = 0; #endif //VIRTUAL_SITES pos (and vel for DPD) update for security reason !!! #ifdef VIRTUAL_SITES update_mol_vel_pos(); ghost_communicator(&cell_structure.update_ghost_pos_comm); if (check_runtime_errors()) return; #ifdef ADRESS // adress_update_weights(); if (check_runtime_errors()) return; #endif #endif #ifdef COLLISION_DETECTION prepare_collision_queue(); #endif force_calc(); //VIRTUAL_SITES distribute forces #ifdef VIRTUAL_SITES ghost_communicator(&cell_structure.collect_ghost_force_comm); init_forces_ghosts(); distribute_mol_force(); if (check_runtime_errors()) return; #endif ghost_communicator(&cell_structure.collect_ghost_force_comm); #ifdef ROTATION convert_initial_torques(); #endif thermo_cool_down(); /* Communication Step: ghost forces */ /*apply trap forces to trapped molecules*/ #ifdef MOLFORCES calc_and_apply_mol_constraints(); #endif rescale_forces(); recalc_forces = 0; #ifdef COLLISION_DETECTION handle_collisions(); #endif } if (check_runtime_errors()) return; n_verlet_updates = 0; /* Integration loop */ for(i=0;i<n_steps;i++) { INTEG_TRACE(fprintf(stderr,"%d: STEP %d\n",this_node,i)); #ifdef BOND_CONSTRAINT save_old_pos(); #endif /* Integration Steps: Step 1 and 2 of Velocity Verlet scheme: v(t+0.5*dt) = v(t) + 0.5*dt * f(t) p(t + dt) = p(t) + dt * v(t+0.5*dt) NOTE 1: Prefactors do not occur in formulas since we use rescaled forces and velocities. NOTE 2: Depending on the integration method Step 1 and Step 2 cannot be combined for the translation. */ if(integ_switch == INTEG_METHOD_NPT_ISO || nemd_method != NEMD_METHOD_OFF) { propagate_vel(); propagate_pos(); } else propagate_vel_pos(); #ifdef BOND_CONSTRAINT /**Correct those particle positions that participate in a rigid/constrained bond */ cells_update_ghosts(); correct_pos_shake(); #endif #ifdef ELECTROSTATICS if(coulomb.method == COULOMB_MAGGS) { maggs_propagate_B_field(0.5*time_step); } #endif #ifdef NPT if (check_runtime_errors()) break; #endif cells_update_ghosts(); //VIRTUAL_SITES update pos and vel (for DPD) #ifdef VIRTUAL_SITES update_mol_vel_pos(); ghost_communicator(&cell_structure.update_ghost_pos_comm); if (check_runtime_errors()) break; #if defined(VIRTUAL_SITES_RELATIVE) && defined(LB) // This is on a workaround stage: // When using virtual sites relative and LB at the same time, it is necessary // to reassemble the cell lists after all position updates, also of virtual // particles. if (cell_structure.type == CELL_STRUCTURE_DOMDEC && (!dd.use_vList) ) cells_update_ghosts(); #endif #ifdef ADRESS //adress_update_weights(); if (check_runtime_errors()) break; #endif #endif /* Integration Step: Step 3 of Velocity Verlet scheme: Calculate f(t+dt) as function of positions p(t+dt) ( and velocities v(t+0.5*dt) ) */ #ifdef LB transfer_momentum = 1; #endif #ifdef LB_GPU transfer_momentum_gpu = 1; #endif #ifdef COLLISION_DETECTION prepare_collision_queue(); #endif force_calc(); //VIRTUAL_SITES distribute forces #ifdef VIRTUAL_SITES ghost_communicator(&cell_structure.collect_ghost_force_comm); init_forces_ghosts(); distribute_mol_force(); if (check_runtime_errors()) break; #endif /* Communication step: ghost forces */ ghost_communicator(&cell_structure.collect_ghost_force_comm); /*apply trap forces to trapped molecules*/ #ifdef MOLFORCES calc_and_apply_mol_constraints(); #endif if (check_runtime_errors()) break; /* Integration Step: Step 4 of Velocity Verlet scheme: v(t+dt) = v(t+0.5*dt) + 0.5*dt * f(t+dt) */ rescale_forces_propagate_vel(); recalc_forces = 0; #ifdef LB if (lattice_switch & LATTICE_LB) lattice_boltzmann_update(); if (check_runtime_errors()) break; #endif #ifdef LB_GPU if(this_node == 0){ if (lattice_switch & LATTICE_LB_GPU) lattice_boltzmann_update_gpu(); } #endif #ifdef BOND_CONSTRAINT ghost_communicator(&cell_structure.update_ghost_pos_comm); correct_vel_shake(); #endif #ifdef ROTATION convert_torques_propagate_omega(); #endif //VIRTUAL_SITES update vel #ifdef VIRTUAL_SITES ghost_communicator(&cell_structure.update_ghost_pos_comm); update_mol_vel(); if (check_runtime_errors()) break; #endif #ifdef ELECTROSTATICS if(coulomb.method == COULOMB_MAGGS) { maggs_propagate_B_field(0.5*time_step); } #endif #ifdef COLLISION_DETECTION handle_collisions(); #endif #ifdef NPT if((this_node==0) && (integ_switch == INTEG_METHOD_NPT_ISO)) nptiso.p_inst_av += nptiso.p_inst; #endif /* Propagate time: t = t+dt */ sim_time += time_step; } /* verlet list statistics */ if(n_verlet_updates>0) verlet_reuse = n_steps/(double) n_verlet_updates; else verlet_reuse = 0; #ifdef NPT if(integ_switch == INTEG_METHOD_NPT_ISO) { nptiso.invalidate_p_vel = 0; MPI_Bcast(&nptiso.p_inst, 1, MPI_DOUBLE, 0, comm_cart); MPI_Bcast(&nptiso.p_diff, 1, MPI_DOUBLE, 0, comm_cart); MPI_Bcast(&nptiso.volume, 1, MPI_DOUBLE, 0, comm_cart); if(this_node==0) nptiso.p_inst_av /= 1.0*n_steps; MPI_Bcast(&nptiso.p_inst_av, 1, MPI_DOUBLE, 0, comm_cart); } #endif }
void integrate_vv(int n_steps, int reuse_forces) { /* Prepare the Integrator */ on_integration_start(); #ifdef IMMERSED_BOUNDARY // Here we initialize volume conservation // This function checks if the reference volumes have been set and if necessary calculates them IBM_InitVolumeConservation(); #endif /* if any method vetoes (P3M not initialized), immediately bail out */ if (check_runtime_errors()) return; /* Verlet list criterion */ skin2 = SQR(0.5 * skin); INTEG_TRACE(fprintf(stderr,"%d: integrate_vv: integrating %d steps (recalc_forces=%d)\n", this_node, n_steps, recalc_forces)); /* Integration Step: Preparation for first integration step: Calculate forces f(t) as function of positions p(t) ( and velocities v(t) ) */ /* reuse_forces logic: -1: recalculate forces unconditionally, mostly used for timing 0: recalculate forces if recalc_forces is set, meaning it is probably necessary 1: do not recalculate forces. Mostly when reading checkpoints with forces */ if (reuse_forces == -1 || (recalc_forces && reuse_forces != 1)) { thermo_heat_up(); #ifdef LB transfer_momentum = 0; if (lattice_switch & LATTICE_LB && this_node == 0) if (warnings) fprintf (stderr, "Warning: Recalculating forces, so the LB coupling forces are not included in the particle force the first time step. This only matters if it happens frequently during sampling.\n"); #endif #ifdef LB_GPU transfer_momentum_gpu = 0; if (lattice_switch & LATTICE_LB_GPU && this_node == 0) if (warnings) fprintf (stderr, "Warning: Recalculating forces, so the LB coupling forces are not included in the particle force the first time step. This only matters if it happens frequently during sampling.\n"); #endif force_calc(); if(integ_switch != INTEG_METHOD_STEEPEST_DESCENT) { rescale_forces(); #ifdef ROTATION convert_initial_torques(); #endif } thermo_cool_down(); } #ifdef GHMC if(thermo_switch & THERMO_GHMC) ghmc_init(); #endif if (check_runtime_errors()) return; n_verlet_updates = 0; /* Integration loop */ for (int step=0; step<n_steps; step++) { INTEG_TRACE(fprintf(stderr,"%d: STEP %d\n", this_node, step)); #ifdef BOND_CONSTRAINT save_old_pos(); #endif #ifdef GHMC if(thermo_switch & THERMO_GHMC) { if (step % ghmc_nmd == 0) ghmc_momentum_update(); } #endif /* Integration Steps: Step 1 and 2 of Velocity Verlet scheme: v(t+0.5*dt) = v(t) + 0.5*dt * f(t) p(t + dt) = p(t) + dt * v(t+0.5*dt) NOTE 1: Prefactors do not occur in formulas since we use rescaled forces and velocities. NOTE 2: Depending on the integration method Step 1 and Step 2 cannot be combined for the translation. */ if (integ_switch == INTEG_METHOD_NPT_ISO || nemd_method != NEMD_METHOD_OFF) { propagate_vel(); propagate_pos(); } else if(integ_switch == INTEG_METHOD_STEEPEST_DESCENT) { if(steepest_descent_step()) break; } else { propagate_vel_pos(); } #ifdef BOND_CONSTRAINT /**Correct those particle positions that participate in a rigid/constrained bond */ cells_update_ghosts(); correct_pos_shake(); #endif #ifdef ELECTROSTATICS if(coulomb.method == COULOMB_MAGGS) { maggs_propagate_B_field(0.5*time_step); } #endif #ifdef NPT if (check_runtime_errors()) break; #endif /* Integration Step: Step 3 of Velocity Verlet scheme: Calculate f(t+dt) as function of positions p(t+dt) ( and velocities v(t+0.5*dt) ) */ #ifdef LB transfer_momentum = 1; #endif #ifdef LB_GPU transfer_momentum_gpu = 1; #endif force_calc(); // IMMERSED_BOUNDARY #ifdef IMMERSED_BOUNDARY // Now the forces are computed and need to go into the LB fluid if (lattice_switch & LATTICE_LB) IBM_ForcesIntoFluid_CPU(); #ifdef LB_GPU if (lattice_switch & LATTICE_LB_GPU) IBM_ForcesIntoFluid_GPU(); #endif #endif #ifdef CATALYTIC_REACTIONS integrate_reaction(); #endif if (check_runtime_errors()) break; /* Integration Step: Step 4 of Velocity Verlet scheme: v(t+dt) = v(t+0.5*dt) + 0.5*dt * f(t+dt) */ if(integ_switch != INTEG_METHOD_STEEPEST_DESCENT) { rescale_forces_propagate_vel(); #ifdef ROTATION convert_torques_propagate_omega(); #endif } // SHAKE velocity updates #ifdef BOND_CONSTRAINT ghost_communicator(&cell_structure.update_ghost_pos_comm); correct_vel_shake(); #endif //VIRTUAL_SITES update vel #ifdef VIRTUAL_SITES ghost_communicator(&cell_structure.update_ghost_pos_comm); update_mol_vel(); if (check_runtime_errors()) break; #endif // progagate one-step functionalities #ifdef LB if (lattice_switch & LATTICE_LB) lattice_boltzmann_update(); if (check_runtime_errors()) break; #endif #ifdef LB_GPU if(this_node == 0){ #ifdef ELECTROKINETICS if (ek_initialized) { ek_integrate(); } else { #endif if (lattice_switch & LATTICE_LB_GPU) lattice_boltzmann_update_gpu(); #ifdef ELECTROKINETICS } #endif } #endif //LB_GPU // IMMERSED_BOUNDARY #ifdef IMMERSED_BOUNDARY IBM_UpdateParticlePositions(); // We reset all since otherwise the halo nodes may not be reset // NB: the normal Espresso reset is also done after applying the forces // if (lattice_switch & LATTICE_LB) IBM_ResetLBForces_CPU(); #ifdef LB_GPU //if (lattice_switch & LATTICE_LB_GPU) IBM_ResetLBForces_GPU(); #endif if (check_runtime_errors()) break; // Ghost positions are now out-of-date // We should update. // Actually we seem to get the same results whether we do this here or not, but it is safer to do it ghost_communicator(&cell_structure.update_ghost_pos_comm); #endif // IMMERSED_BOUNDARY #ifdef ELECTROSTATICS if(coulomb.method == COULOMB_MAGGS) { maggs_propagate_B_field(0.5*time_step); } #endif #ifdef NPT if((this_node==0) && (integ_switch == INTEG_METHOD_NPT_ISO)) nptiso.p_inst_av += nptiso.p_inst; #endif #ifdef GHMC if(thermo_switch & THERMO_GHMC) { if (step % ghmc_nmd == ghmc_nmd-1) ghmc_mc(); } #endif if(integ_switch != INTEG_METHOD_STEEPEST_DESCENT) { /* Propagate time: t = t+dt */ sim_time += time_step; } } /* verlet list statistics */ if(n_verlet_updates>0) verlet_reuse = n_steps/(double) n_verlet_updates; else verlet_reuse = 0; #ifdef NPT if(integ_switch == INTEG_METHOD_NPT_ISO) { nptiso.invalidate_p_vel = 0; MPI_Bcast(&nptiso.p_inst, 1, MPI_DOUBLE, 0, comm_cart); MPI_Bcast(&nptiso.p_diff, 1, MPI_DOUBLE, 0, comm_cart); MPI_Bcast(&nptiso.volume, 1, MPI_DOUBLE, 0, comm_cart); if(this_node==0) nptiso.p_inst_av /= 1.0*n_steps; MPI_Bcast(&nptiso.p_inst_av, 1, MPI_DOUBLE, 0, comm_cart); } #endif #ifdef GHMC if(thermo_switch & THERMO_GHMC) ghmc_close(); #endif }
void integrate_vv(int n_steps, int reuse_forces) { int i; /* Prepare the Integrator */ on_integration_start(); /* if any method vetoes (P3M not initialized), immediately bail out */ if (check_runtime_errors()) return; /* Verlet list criterion */ skin2 = SQR(0.5 * skin); INTEG_TRACE(fprintf(stderr,"%d: integrate_vv: integrating %d steps (recalc_forces=%d)\n", this_node, n_steps, recalc_forces)); /* Integration Step: Preparation for first integration step: Calculate forces f(t) as function of positions p(t) ( and velocities v(t) ) */ /* reuse_forces logic: -1: recalculate forces unconditionally, mostly used for timing 0: recalculate forces if recalc_forces is set, meaning it is probably necessary 1: do not recalculate forces. Mostly when reading checkpoints with forces */ if (reuse_forces == -1 || (recalc_forces && reuse_forces != 1)) { thermo_heat_up(); #ifdef LB transfer_momentum = 0; if (lattice_switch & LATTICE_LB && this_node == 0) if (warnings) fprintf (stderr, "Warning: Recalculating forces, so the LB coupling forces are not included in the particle force the first time step. This only matters if it happens frequently during sampling.\n"); #endif #ifdef LB_GPU transfer_momentum_gpu = 0; if (lattice_switch & LATTICE_LB_GPU && this_node == 0) if (warnings) fprintf (stderr, "Warning: Recalculating forces, so the LB coupling forces are not included in the particle force the first time step. This only matters if it happens frequently during sampling.\n"); #endif force_calc(); rescale_forces(); #ifdef ROTATION convert_initial_torques(); #endif thermo_cool_down(); } #ifdef GHMC if(thermo_switch & THERMO_GHMC) ghmc_init(); #endif if (check_runtime_errors()) return; n_verlet_updates = 0; /* Integration loop */ for(i=0;i<n_steps;i++) { INTEG_TRACE(fprintf(stderr,"%d: STEP %d\n",this_node,i)); #ifdef BOND_CONSTRAINT save_old_pos(); #endif #ifdef GHMC if(thermo_switch & THERMO_GHMC) { if ((int) fmod(i,ghmc_nmd) == 0) ghmc_momentum_update(); } #endif /* Integration Steps: Step 1 and 2 of Velocity Verlet scheme: v(t+0.5*dt) = v(t) + 0.5*dt * f(t) p(t + dt) = p(t) + dt * v(t+0.5*dt) NOTE 1: Prefactors do not occur in formulas since we use rescaled forces and velocities. NOTE 2: Depending on the integration method Step 1 and Step 2 cannot be combined for the translation. */ if(integ_switch == INTEG_METHOD_NPT_ISO || nemd_method != NEMD_METHOD_OFF) { propagate_vel(); propagate_pos(); } else propagate_vel_pos(); #ifdef BOND_CONSTRAINT /**Correct those particle positions that participate in a rigid/constrained bond */ cells_update_ghosts(); correct_pos_shake(); #endif #ifdef ELECTROSTATICS if(coulomb.method == COULOMB_MAGGS) { maggs_propagate_B_field(0.5*time_step); } #endif #ifdef NPT if (check_runtime_errors()) break; #endif /* Integration Step: Step 3 of Velocity Verlet scheme: Calculate f(t+dt) as function of positions p(t+dt) ( and velocities v(t+0.5*dt) ) */ #ifdef LB transfer_momentum = 1; #endif #ifdef LB_GPU transfer_momentum_gpu = 1; #endif force_calc(); #ifdef CATALYTIC_REACTIONS integrate_reaction(); #endif if (check_runtime_errors()) break; /* Integration Step: Step 4 of Velocity Verlet scheme: v(t+dt) = v(t+0.5*dt) + 0.5*dt * f(t+dt) */ rescale_forces_propagate_vel(); #ifdef ROTATION convert_torques_propagate_omega(); #endif // SHAKE velocity updates #ifdef BOND_CONSTRAINT ghost_communicator(&cell_structure.update_ghost_pos_comm); correct_vel_shake(); #endif //VIRTUAL_SITES update vel #ifdef VIRTUAL_SITES ghost_communicator(&cell_structure.update_ghost_pos_comm); update_mol_vel(); if (check_runtime_errors()) break; #endif // progagate one-step functionalities #ifdef LB if (lattice_switch & LATTICE_LB) lattice_boltzmann_update(); if (check_runtime_errors()) break; #endif #ifdef LB_GPU if(this_node == 0){ #ifdef ELECTROKINETICS if (ek_initialized) { ek_integrate(); } else { #endif if (lattice_switch & LATTICE_LB_GPU) lattice_boltzmann_update_gpu(); #ifdef ELECTROKINETICS } #endif } #endif //LB_GPU #ifdef ELECTROSTATICS if(coulomb.method == COULOMB_MAGGS) { maggs_propagate_B_field(0.5*time_step); } #endif #ifdef NPT if((this_node==0) && (integ_switch == INTEG_METHOD_NPT_ISO)) nptiso.p_inst_av += nptiso.p_inst; #endif #ifdef GHMC if(thermo_switch & THERMO_GHMC) { if ((int) fmod(i,ghmc_nmd) == ghmc_nmd-1) ghmc_mc(); } #endif /* Propagate time: t = t+dt */ sim_time += time_step; } /* verlet list statistics */ if(n_verlet_updates>0) verlet_reuse = n_steps/(double) n_verlet_updates; else verlet_reuse = 0; #ifdef NPT if(integ_switch == INTEG_METHOD_NPT_ISO) { nptiso.invalidate_p_vel = 0; MPI_Bcast(&nptiso.p_inst, 1, MPI_DOUBLE, 0, comm_cart); MPI_Bcast(&nptiso.p_diff, 1, MPI_DOUBLE, 0, comm_cart); MPI_Bcast(&nptiso.volume, 1, MPI_DOUBLE, 0, comm_cart); if(this_node==0) nptiso.p_inst_av /= 1.0*n_steps; MPI_Bcast(&nptiso.p_inst_av, 1, MPI_DOUBLE, 0, comm_cart); } #endif #ifdef GHMC if(thermo_switch & THERMO_GHMC) ghmc_close(); #endif }