void energy_calc(double *result) { if (!check_obs_calc_initialized()) return; init_energies(&energy); on_observable_calc(); switch (cell_structure.type) { case CELL_STRUCTURE_LAYERED: layered_calculate_energies(); break; case CELL_STRUCTURE_DOMDEC: if(dd.use_vList) { if (rebuild_verletlist) build_verlet_lists(); calculate_verlet_energies(); } else calculate_link_cell_energies(); break; case CELL_STRUCTURE_NSQUARE: nsq_calculate_energies(); } /* rescale kinetic energy */ energy.data.e[0] /= (2.0*time_step*time_step); calc_long_range_energies(); /* gather data */ MPI_Reduce(energy.data.e, result, energy.data.n, MPI_DOUBLE, MPI_SUM, 0, comm_cart); }
void pressure_calc(double *result, double *result_t, double *result_nb, double *result_t_nb, int v_comp) { int n, i; double volume = box_l[0]*box_l[1]*box_l[2]; if (!interactions_sanity_checks()) return; init_virials(&virials); init_p_tensor(&p_tensor); init_virials_non_bonded(&virials_non_bonded); init_p_tensor_non_bonded(&p_tensor_non_bonded); on_observable_calc(); switch (cell_structure.type) { case CELL_STRUCTURE_LAYERED: layered_calculate_virials(v_comp); break; case CELL_STRUCTURE_DOMDEC: if(dd.use_vList) { if (rebuild_verletlist) build_verlet_lists(); calculate_verlet_virials(v_comp); } else calculate_link_cell_virials(v_comp); break; case CELL_STRUCTURE_NSQUARE: nsq_calculate_virials(v_comp); } /* rescale kinetic energy (=ideal contribution) */ #ifdef ROTATION_PER_PARTICLE fprintf(stderr, "Switching rotation per particle (#define ROTATION_PER_PARTICLE) and pressure calculation are incompatible.\n"); #endif virials.data.e[0] /= (3.0*volume*time_step*time_step); calc_long_range_virials(); #ifdef VIRTUAL_SITES_RELATIVE vs_relative_pressure_and_stress_tensor(virials.vs_relative,p_tensor.vs_relative); #endif for (n = 1; n < virials.data.n; n++) virials.data.e[n] /= 3.0*volume; for(i=0; i<9; i++) p_tensor.data.e[i] /= (volume*time_step*time_step); for(i=9; i<p_tensor.data.n; i++) p_tensor.data.e[i] /= volume; /* Intra- and Inter- part of nonbonded interaction */ for (n = 0; n < virials_non_bonded.data_nb.n; n++) virials_non_bonded.data_nb.e[n] /= 3.0*volume; for(i=0; i<p_tensor_non_bonded.data_nb.n; i++) p_tensor_non_bonded.data_nb.e[i] /= volume; /* gather data */ MPI_Reduce(virials.data.e, result, virials.data.n, MPI_DOUBLE, MPI_SUM, 0, comm_cart); MPI_Reduce(p_tensor.data.e, result_t, p_tensor.data.n, MPI_DOUBLE, MPI_SUM, 0, comm_cart); MPI_Reduce(virials_non_bonded.data_nb.e, result_nb, virials_non_bonded.data_nb.n, MPI_DOUBLE, MPI_SUM, 0, comm_cart); MPI_Reduce(p_tensor_non_bonded.data_nb.e, result_t_nb, p_tensor_non_bonded.data_nb.n, MPI_DOUBLE, MPI_SUM, 0, comm_cart); }
int aggregation(double dist_criteria2, int min_contact, int s_mol_id, int f_mol_id, int *head_list, int *link_list, int *agg_id_list, int *agg_num, int *agg_size, int *agg_max, int *agg_min, int *agg_avg, int *agg_std, int charge) { int c, np, n, i; Particle *p1, *p2, **pairs; double dist2; int target1; int p1molid, p2molid; int *contact_num, ind; if (min_contact > 1) { contact_num = (int *) malloc(n_molecules*n_molecules *sizeof(int)); for (i = 0; i < n_molecules *n_molecules; i++) contact_num[i]=0; } else { contact_num = (int *) 0; /* Just to keep the compiler happy */ } on_observable_calc(); build_verlet_lists(); for (i = s_mol_id; i <= f_mol_id; i++) { head_list[i]=i; link_list[i]=-1; agg_id_list[i]=i; agg_size[i]=0; } /* Loop local cells */ 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 */ p1molid = p1->p.mol_id; p2molid = p2->p.mol_id; if (((p1molid <= f_mol_id) && (p1molid >= s_mol_id)) && ((p2molid <= f_mol_id) && (p2molid >= s_mol_id))) { if (agg_id_list[p1molid] != agg_id_list[p2molid]) { dist2 = min_distance2(p1->r.p, p2->r.p); #ifdef ELECTROSTATICS if (charge && (p1->p.q * p2->p.q >= 0)) {continue;} #endif if (dist2 < dist_criteria2) { if ( p1molid > p2molid ) { ind=p1molid*n_molecules + p2molid;} else { ind=p2molid*n_molecules +p1molid;} if (min_contact > 1) { contact_num[ind] ++; if (contact_num[ind] >= min_contact) { merge_aggregate_lists( head_list, agg_id_list, p1molid, p2molid, link_list); } } else { merge_aggregate_lists( head_list, agg_id_list, p1molid, p2molid, link_list); } } } } } } } /* count number of aggregates find aggregate size find max and find min size, and std */ for (i = s_mol_id ; i <= f_mol_id ; i++) { if (head_list[i] != -2) { (*agg_num)++; agg_size[*agg_num -1]++; target1= head_list[i]; while( link_list[target1] != -1) { target1= link_list[target1]; agg_size[*agg_num -1]++; } } } for (i = 0 ; i < *agg_num; i++) { *agg_avg += agg_size[i]; *agg_std += agg_size[i] * agg_size[i]; if (*agg_min > agg_size[i]) { *agg_min = agg_size[i]; } if (*agg_max < agg_size[i]) { *agg_max = agg_size[i]; } } return 0; }
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 REACTIONS if(reaction.rate != 0.0) { if(max_cut < reaction.range) { errtext = runtime_error(128); ERROR_SPRINTF(errtext,"{105 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(); #ifdef SCAFACOS /* initialize Scafacos, set up the system and solver specific parameters, all on each node. functions include MPI_Bcast */ mpi_bcast_coulomb_method(); switch(coulomb.method) { case COULOMB_SCAFACOS_DIRECT: case COULOMB_SCAFACOS_EWALD: case COULOMB_SCAFACOS_FMM: case COULOMB_SCAFACOS_MEMD: case COULOMB_SCAFACOS_MMM1D: case COULOMB_SCAFACOS_MMM2D: case COULOMB_SCAFACOS_P2NFFT: case COULOMB_SCAFACOS_P3M: case COULOMB_SCAFACOS_PEPC: case COULOMB_SCAFACOS_PP3MG: case COULOMB_SCAFACOS_VMG: { mpi_scafacos_bcast_common_params(); mpi_scafacos_bcast_solver_specific(); mpi_scafacos_init(); mpi_scafacos_common_set(); mpi_scafacos_solver_specific_set(); break; } default: break; } /* tune in order to generate at least defaults for cutoff, transfer the cutoff back to Espresso and generate new cell system on each node*/ switch(coulomb.method) { case COULOMB_SCAFACOS_P2NFFT: if( scafacos.short_range_flag == 0 ) { scafacos_tune(); recalc_maximal_cutoff(); cells_on_geometry_change(0); } break; case COULOMB_SCAFACOS_P3M: if( scafacos.short_range_flag == 0 ) { scafacos_tune(); recalc_maximal_cutoff(); cells_on_geometry_change(0); } default: break; } #endif /* Update particle and observable information for routines in statistics.c */ invalidate_obs(); freePartCfg(); on_observable_calc(); }
void energy_calc(double *result) { if (!interactions_sanity_checks()) return; init_energies(&energy); #ifdef CUDA clear_energy_on_GPU(); #endif espressoSystemInterface.update(); // Compute the energies from the energyActors for (ActorList::iterator actor= energyActors.begin(); actor != energyActors.end(); ++actor) (*actor)->computeEnergy(espressoSystemInterface); on_observable_calc(); switch (cell_structure.type) { case CELL_STRUCTURE_LAYERED: layered_calculate_energies(); break; case CELL_STRUCTURE_DOMDEC: if(dd.use_vList) { if (rebuild_verletlist) build_verlet_lists(); calculate_verlet_energies(); } else calculate_link_cell_energies(); break; case CELL_STRUCTURE_NSQUARE: nsq_calculate_energies(); } /* rescale kinetic energy */ energy.data.e[0] /= (2.0*time_step*time_step); calc_long_range_energies(); #ifdef CUDA copy_energy_from_GPU(); #endif /* gather data */ MPI_Reduce(energy.data.e, result, energy.data.n, MPI_DOUBLE, MPI_SUM, 0, comm_cart); if (n_external_potentials > 0) { double* energies = (double*) malloc(n_external_potentials*sizeof(double)); for (int i=0; i<n_external_potentials; i++) { energies[i]=external_potentials[i].energy; } double* energies_sum = (double*) malloc(n_external_potentials*sizeof(double)); MPI_Reduce(energies, energies_sum, n_external_potentials, MPI_DOUBLE, MPI_SUM, 0, comm_cart); for (int i=0; i<n_external_potentials; i++) { external_potentials[i].energy=energies_sum[i]; } free(energies); free(energies_sum); } }
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 on_integration_start() { 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 */ /********************************************/ integrator_sanity_checks(); #ifdef NPT integrator_npt_sanity_checks(); #endif interactions_sanity_checks(); #ifdef CATALYTIC_REACTIONS reactions_sanity_checks(); #endif #ifdef LB if(lattice_switch & LATTICE_LB) { lb_sanity_checks(); } #endif #ifdef LB_GPU if(lattice_switch & LATTICE_LB_GPU) { lb_GPU_sanity_checks(); } #endif /********************************************/ /* end sanity checks */ /********************************************/ #ifdef LB_GPU if(this_node == 0){ if (lb_reinit_particles_gpu) { lb_realloc_particles_gpu(); lb_reinit_particles_gpu = 0; } } #endif #ifdef CUDA if (reinit_particle_comm_gpu){ gpu_change_number_of_part_to_comm(); reinit_particle_comm_gpu = 0; } MPI_Bcast(gpu_get_global_particle_vars_pointer_host(), sizeof(CUDA_global_part_vars), MPI_BYTE, 0, comm_cart); #endif #ifdef METADYNAMICS meta_init(); #endif /* 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.cpp */ invalidate_obs(); freePartCfg(); on_observable_calc(); }
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_reaction() { int c, np, n, i; 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) { printf("DEBUG: integrate_reaction; back_react\n"); //TODO delete p1[i].p.type=reaction.reactant_type; } } } } } on_particle_change(); } }
void on_integration_start() { char *errtext; int i; 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} "); } for (i = 0; i < 3; i++) if (local_box_l[i] < max_range) { errtext = runtime_error(128 + TCL_INTEGER_SPACE); ERROR_SPRINTF(errtext,"{013 box_l in direction %d is still too small} ", i); } #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} "); } if(cell_structure.type!=CELL_STRUCTURE_DOMDEC) { char *errtext = runtime_error(128); ERROR_SPRINTF(errtext,"{014 npt requires domain decomposition cellsystem} "); } #ifdef ELECTROSTATICS switch(coulomb.method) { case COULOMB_NONE: break; #ifdef ELP3M case COULOMB_P3M: break; #endif /*ELP3M*/ case COULOMB_EWALD: break; default: { char *errtext = runtime_error(128); ERROR_SPRINTF(errtext,"{014 npt only works with Ewald sum or P3M} "); } } #endif /*ELECTROSTATICS*/ } #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} "); } } #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 /********************************************/ /* 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 pressure_calc(double *result, double *result_t, double *result_nb, double *result_t_nb, int v_comp) { int n, i; double volume = box_l[0]*box_l[1]*box_l[2]; if (!check_obs_calc_initialized()) return; init_virials(&virials); init_p_tensor(&p_tensor); init_virials_non_bonded(&virials_non_bonded); init_p_tensor_non_bonded(&p_tensor_non_bonded); on_observable_calc(); switch (cell_structure.type) { case CELL_STRUCTURE_LAYERED: layered_calculate_virials(v_comp); break; case CELL_STRUCTURE_DOMDEC: if(dd.use_vList) { if (rebuild_verletlist) build_verlet_lists(); calculate_verlet_virials(v_comp); } else calculate_link_cell_virials(v_comp); break; case CELL_STRUCTURE_NSQUARE: nsq_calculate_virials(v_comp); } /* rescale kinetic energy (=ideal contribution) */ virials.data.e[0] /= (3.0*volume*time_step*time_step); calc_long_range_virials(); for (n = 1; n < virials.data.n; n++) virials.data.e[n] /= 3.0*volume; /* stress tensor part */ /* ROTATION option does not effect stress tensor calculations since rotational energy is not included in the ideal term (unlike for the pressure) */ for(i=0; i<9; i++) p_tensor.data.e[i] /= (volume*time_step*time_step); for(i=9; i<p_tensor.data.n; i++) p_tensor.data.e[i] /= volume; /* Intra- and Inter- part of nonbonded interaction */ for (n = 0; n < virials_non_bonded.data_nb.n; n++) virials_non_bonded.data_nb.e[n] /= 3.0*volume; for(i=0; i<p_tensor_non_bonded.data_nb.n; i++) p_tensor_non_bonded.data_nb.e[i] /= volume; /* gather data */ MPI_Reduce(virials.data.e, result, virials.data.n, MPI_DOUBLE, MPI_SUM, 0, comm_cart); MPI_Reduce(p_tensor.data.e, result_t, p_tensor.data.n, MPI_DOUBLE, MPI_SUM, 0, comm_cart); MPI_Reduce(virials_non_bonded.data_nb.e, result_nb, virials_non_bonded.data_nb.n, MPI_DOUBLE, MPI_SUM, 0, comm_cart); MPI_Reduce(p_tensor_non_bonded.data_nb.e, result_t_nb, p_tensor_non_bonded.data_nb.n, MPI_DOUBLE, MPI_SUM, 0, comm_cart); }