/* this function (a) undoes what make_move() did and (b) determines the next move sequence by calling checkpoint() */ void restore(system_t *system) { // restore the remaining observables memcpy(system->observables, system->checkpoint->observables, sizeof(observables_t)); /* restore state by undoing the steps of make_move() */ switch (system->checkpoint->movetype) { case MOVETYPE_INSERT: /* take altered out of the list */ if (!system->checkpoint->head) { /* handle the case where we inserted at the head of the list */ system->molecules = system->molecules->next; } else { system->checkpoint->head->next = system->checkpoint->tail; } unupdate_pairs_insert(system); free_molecule(system, system->checkpoint->molecule_altered); system->checkpoint->molecule_altered = NULL; /* Insurance against memory errors */ //reset atom and molecule id's enumerate_particles(system); break; case MOVETYPE_REMOVE: /* put backup back into the list */ if (!system->checkpoint->head) { system->molecules = system->checkpoint->molecule_backup; } else { system->checkpoint->head->next = system->checkpoint->molecule_backup; } system->checkpoint->molecule_backup->next = system->checkpoint->tail; unupdate_pairs_remove(system); system->checkpoint->molecule_backup = NULL; //reset atom and molecule id's enumerate_particles(system); break; case MOVETYPE_VOLUME: revert_volume_change(system); break; default: /* link the backup into the working list again */ if (!system->checkpoint->head) system->molecules = system->checkpoint->molecule_backup; else system->checkpoint->head->next = system->checkpoint->molecule_backup; system->checkpoint->molecule_backup->next = system->checkpoint->tail; free_molecule(system, system->checkpoint->molecule_altered); system->checkpoint->molecule_altered = NULL; /* Insurance against memory errors */ system->checkpoint->molecule_backup = NULL; } /* renormalize charges */ if (system->spectre) spectre_charge_renormalize(system); /* establish the previous checkpoint again */ checkpoint(system); return; }
/* free all of our data structures */ void cleanup(system_t *system) { int i,j; #ifdef QM_ROTATION if(system->quantum_rotation) free_rotational(system); #endif /* QM_ROTATION */ if(system->polarization && !system->cuda) free_matrices(system); if(system->polar_wolf_alpha_lookup) if ( system->polar_wolf_alpha_table ) free(system->polar_wolf_alpha_table); //need to rebuild atom and pair arrays so we can free everything system->natoms = countNatoms(system); rebuild_arrays(system); free_all_pairs(system); free_all_molecules(system, system->molecules); //free our arrays free(system->molecule_array); free(system->atom_array); free(system->pqr_input); free(system->pqr_output); free(system->energy_output); free(system->energy_output_csv); free(system->virial_output); if(system->surf_output) free(system->surf_output); if(system->traj_output) free(system->traj_output); if(system->traj_input) free(system->traj_input); if(system->dipole_output) free(system->dipole_output); if(system->field_output) free(system->field_output); if(system->frozen_output) free(system->frozen_output); if(system->surf_preserve_rotation_on) free(system->surf_preserve_rotation_on); if(system->cavity_bias) free_cavity_grid(system); if ( system->vdw_eiso_info ) free_vdw_eiso(system->vdw_eiso_info); // free multi sorbate related stuff if ( system->fugacities ) free(system->fugacities); if(system->insert_input) free(system->insert_input); //insert.pdb arrays and shit if(system->insertion_molecules_array) free(system->insertion_molecules_array); if(system->insertion_molecules) free_all_molecules(system, system->insertion_molecules); // free sorbate info array free(system->sorbateInfo); /* free statistics */ free(system->nodestats); free(system->avg_nodestats); free(system->observables); free(system->avg_observables); free(system->checkpoint->observables); if ( system->checkpoint->molecule_backup != NULL ) free_molecule(system, system->checkpoint->molecule_backup); free(system->checkpoint); /*free histogram stuff*/ for ( i=0; i<system->grids->histogram->x_dim; i++ ) { for ( j=0; j<system->grids->histogram->y_dim; j++ ) { free(system->grids->histogram->grid[i][j]); } free(system->grids->histogram->grid[i]); } if ( !rank ) { for ( i=0; i<system->grids->histogram->x_dim; i++ ) { for ( j=0; j<system->grids->histogram->y_dim; j++ ) { free(system->grids->avg_histogram->grid[i][j]); } free(system->grids->avg_histogram->grid[i]); } free(system->grids->avg_histogram->grid); } free(system->grids->histogram->grid); free(system->grids->avg_histogram); free(system->grids->histogram); free(system->grids); free(system->histogram_output); /* free fit input lists*/ if ( system->fit_input_list.data.count > 0 ) { fileNode_t *node = &(system->fit_input_list); fileNode_t *nextnode; //the first one is statically declared //the others are malloc'd in input.c if ( node->next ) node=node->next; while ( node->next ) { nextnode=node->next; free(node->data.filename); free(node); node=nextnode; } free(node->data.filename); free(node); } free(system->pqr_restart); free(system->pbc); free(system->job_name); // (CRC) kill_rng(); free(system); }
/* apply what was already determined in checkpointing */ void make_move(system_t *system) { int i, j, k, p, q; cavity_t *cavities_array; int cavities_array_counter, random_index; double com[3], rand[3]; molecule_t *molecule_ptr; atom_t *atom_ptr; pair_t *pair_ptr; /* update the cavity grid prior to making a move */ if (system->cavity_bias) { cavity_update_grid(system); system->checkpoint->biased_move = 0; } switch (system->checkpoint->movetype) { case MOVETYPE_INSERT: /* insert a molecule at a random pos and orientation */ /* umbrella sampling */ if (system->cavity_bias && system->cavities_open) { /* doing a biased move - this flag lets mc.c know about it */ system->checkpoint->biased_move = 1; /* make an array of possible insertion points */ cavities_array = calloc(system->cavities_open, sizeof(cavity_t)); memnullcheck(cavities_array, system->cavities_open * sizeof(cavity_t), __LINE__ - 1, __FILE__); for (i = 0, cavities_array_counter = 0; i < system->cavity_grid_size; i++) { for (j = 0; j < system->cavity_grid_size; j++) { for (k = 0; k < system->cavity_grid_size; k++) { if (!system->cavity_grid[i][j][k].occupancy) { for (p = 0; p < 3; p++) cavities_array[cavities_array_counter].pos[p] = system->cavity_grid[i][j][k].pos[p]; ++cavities_array_counter; } } /* end k */ } /* end j */ } /* end i */ /* insert randomly at one of the free cavity points */ random_index = (system->cavities_open - 1) - (int)rint(((double)(system->cavities_open - 1)) * get_rand(system)); for (p = 0; p < 3; p++) com[p] = cavities_array[random_index].pos[p]; /* free the insertion array */ free(cavities_array); } // end umbrella else { /* insert the molecule to a random location within the unit cell */ for (p = 0; p < 3; p++) rand[p] = 0.5 - get_rand(system); for (p = 0; p < 3; p++) for (q = 0, com[p] = 0; q < 3; q++) com[p] += system->pbc->basis[q][p] * rand[q]; } /* process the inserted molecule */ for (atom_ptr = system->checkpoint->molecule_backup->atoms; atom_ptr; atom_ptr = atom_ptr->next) { /* move the molecule back to the origin and then assign it to com */ for (p = 0; p < 3; p++) atom_ptr->pos[p] += com[p] - system->checkpoint->molecule_backup->com[p]; } /* update the molecular com */ for (p = 0; p < 3; p++) system->checkpoint->molecule_backup->com[p] = com[p]; /* give it a random orientation */ rotate(system, system->checkpoint->molecule_backup, system->pbc, 1.0); // insert into the list if (system->num_insertion_molecules) { // If inserting a molecule from an insertion list, we will always insert at the end system->checkpoint->head->next = system->checkpoint->molecule_backup; system->checkpoint->molecule_backup->next = NULL; } else { if (!system->checkpoint->head) { // if we're at the start of the list: system->molecules = system->checkpoint->molecule_backup; } else { system->checkpoint->head->next = system->checkpoint->molecule_backup; } system->checkpoint->molecule_backup->next = system->checkpoint->molecule_altered; } /* set new altered and tail to reflect the insertion */ system->checkpoint->molecule_altered = system->checkpoint->molecule_backup; system->checkpoint->tail = system->checkpoint->molecule_altered->next; system->checkpoint->molecule_backup = NULL; if (system->num_insertion_molecules) { //multi sorbate // Free all pair memory in the list for (molecule_ptr = system->molecules; molecule_ptr; molecule_ptr = molecule_ptr->next) { for (atom_ptr = molecule_ptr->atoms; atom_ptr; atom_ptr = atom_ptr->next) { pair_ptr = atom_ptr->pairs; while (pair_ptr) { pair_t *temp = pair_ptr; pair_ptr = pair_ptr->next; free(temp); } } } // Generate new pairs lists for all atoms in system setup_pairs(system); } // only one sorbate else update_pairs_insert(system); //reset atom and molecule id's enumerate_particles(system); break; case MOVETYPE_REMOVE: /* remove a randomly chosen molecule */ if (system->cavity_bias) { if (get_rand(system) < pow((1.0 - system->avg_observables->cavity_bias_probability), ((double)system->cavity_grid_size * system->cavity_grid_size * system->cavity_grid_size))) system->checkpoint->biased_move = 0; else system->checkpoint->biased_move = 1; } /* remove 'altered' from the list */ if (!system->checkpoint->head) { /* handle the case where we're removing from the start of the list */ system->checkpoint->molecule_altered = system->molecules; system->molecules = system->molecules->next; } else { system->checkpoint->head->next = system->checkpoint->tail; } free_molecule(system, system->checkpoint->molecule_altered); system->checkpoint->molecule_altered = NULL; /* Insurance against memory errors */ update_pairs_remove(system); //reset atom and molecule id's enumerate_particles(system); break; case MOVETYPE_DISPLACE: /* change coords of 'altered' */ if (system->rd_anharmonic) displace_1D(system, system->checkpoint->molecule_altered, system->move_factor); else if (system->spectre) spectre_displace(system, system->checkpoint->molecule_altered, system->move_factor, system->spectre_max_charge, system->spectre_max_target); else if (system->gwp) { if (system->checkpoint->molecule_altered->atoms->gwp_spin) { displace(system, system->checkpoint->molecule_altered, system->pbc, system->gwp_probability, system->rot_factor); displace_gwp(system, system->checkpoint->molecule_altered, system->gwp_probability); } else displace(system, system->checkpoint->molecule_altered, system->pbc, system->move_factor, system->rot_factor); } else displace(system, system->checkpoint->molecule_altered, system->pbc, system->move_factor, system->rot_factor); break; case MOVETYPE_ADIABATIC: /* change coords of 'altered' */ displace(system, system->checkpoint->molecule_altered, system->pbc, system->adiabatic_probability, 1.0); break; case MOVETYPE_SPINFLIP: if (get_rand(system) < 0.5) system->checkpoint->molecule_altered->nuclear_spin = NUCLEAR_SPIN_PARA; else system->checkpoint->molecule_altered->nuclear_spin = NUCLEAR_SPIN_ORTHO; break; case MOVETYPE_VOLUME: volume_change(system); // I don't want to contribute to the god damned mess -- kmclaugh break; default: error( "MC_MOVES: invalid mc move\n"); die(-1); } return; }