static double get_invariant_nvt(const struct md *md) { struct nvt_data *data = (struct nvt_data *)md->data; double t_tau = cfg_get_double(md->state->cfg, "thermostat_tau"); double t_target = cfg_get_double(md->state->cfg, "temperature"); double kbt = BOLTZMANN * t_target; double t_virt = kbt * md->n_freedom * (data->chi_dt + data->chi * data->chi * t_tau * t_tau / 2.0); return md->potential_energy + get_kinetic_energy(md) + t_virt; }
RealModel::RealModel(Config cfg) { /* Read prior power spectrum from file */ if(!cfg_has_key(cfg, "pkfile")) { fprintf(stderr, "RealModel: must set config option 'pkfile'\n"); return; } const char* pkfile = cfg_get(cfg, "pkfile"); pk = CubicSpline(pkfile); /* Determine bands */ Band b; if(cfg_has_key(cfg, "bands")) { /* Read bands directly */ vector<double> kvals(100); cfg_get_array_double(cfg, "bands", 100, &kvals[0]); if((kvals.size() % 2) != 0) { fprintf(stderr, "RealModel: odd number of kvals\n"); kvals.pop_back(); } for(int n = 0; n < (int)kvals.size()/2; n++) { b.min = kvals[2*n]; b.max = kvals[2*n+1]; bands.push_back(b); } Nbands = bands.size(); } else if(cfg_has_keys(cfg, "Nbands,kmin,kmax")) { /* Use regularly spaced bands */ Nbands = cfg_get_int(cfg, "Nbands"); double kmin = cfg_get_double(cfg, "kmin"); double kmax = cfg_get_double(cfg, "kmax"); /* (Assume linearly spaced bands for now) */ for(int n = 0; n < Nbands; n++) { b.min = kmin + n*(kmax - kmin)/Nbands; b.max = kmin + (n+1)*(kmax - kmin)/Nbands; bands.push_back(b); } } else { fprintf(stderr, "RealModel: k-bands not specified in configuration\n"); return; } }
bool dispatch_command(struct watchman_client *client, json_t *args, int mode) { struct watchman_command_handler_def *def; char *errmsg = NULL; bool result = false; char sample_name[128]; // Stash a reference to the current command to make it easier to log // the command context in some of the error paths client->current_command = args; json_incref(client->current_command); def = lookup(args, &errmsg, mode); if (!def) { send_error_response(client, "%s", errmsg); goto done; } if (poisoned_reason && (def->flags & CMD_POISON_IMMUNE) == 0) { send_error_response(client, "%s", poisoned_reason); goto done; } if (!client->client_is_owner && (def->flags & CMD_ALLOW_ANY_USER) == 0) { send_error_response(client, "you must be the process owner to execute '%s'", def->name); return false; } w_log(W_LOG_DBG, "dispatch_command: %s\n", def->name); snprintf(sample_name, sizeof(sample_name), "dispatch_command:%s", def->name); w_perf_start(&client->perf_sample, sample_name); w_perf_set_wall_time_thresh( &client->perf_sample, cfg_get_double(NULL, "slow_command_log_threshold_seconds", 1.0)); result = true; def->func(client, args); if (w_perf_finish(&client->perf_sample)) { json_incref(args); w_perf_add_meta(&client->perf_sample, "args", args); w_perf_log(&client->perf_sample); } else { w_log(W_LOG_DBG, "dispatch_command: %s (completed)\n", def->name); } done: free(errmsg); json_decref(client->current_command); client->current_command = NULL; w_perf_destroy(&client->perf_sample); return result; }
static double get_invariant_npt(const struct md *md) { struct npt_data *data = (struct npt_data *)md->data; double t_tau = cfg_get_double(md->state->cfg, "thermostat_tau"); double t_target = cfg_get_double(md->state->cfg, "temperature"); double p_tau = cfg_get_double(md->state->cfg, "barostat_tau"); double p_target = cfg_get_double(md->state->cfg, "pressure"); double kbt = BOLTZMANN * t_target; double volume = get_volume(md); double t_virt = kbt * md->n_freedom * (data->chi_dt + data->chi * data->chi * t_tau * t_tau / 2.0); double p_virt = p_target * volume + 3.0 * md->n_bodies * kbt * data->eta * data->eta * p_tau * p_tau / 2.0; return md->potential_energy + get_kinetic_energy(md) + t_virt + p_virt; }
static void velocitize(struct md *md) { rand_init(); double temperature = cfg_get_double(md->state->cfg, "temperature"); double ke = temperature * BOLTZMANN * md->n_freedom / (2.0 * 6.0 * md->n_bodies); for (size_t i = 0; i < md->n_bodies; i++) { struct body *body = md->bodies + i; double vel = sqrt(2.0 * ke / body->mass); body->vel.x = vel * rand_normal(); body->vel.y = vel * rand_normal(); body->vel.z = vel * rand_normal(); body->angmom.x = sqrt(2.0 * ke * body->inertia.x) * rand_normal(); body->angmom.y = sqrt(2.0 * ke * body->inertia.y) * rand_normal(); body->angmom.z = sqrt(2.0 * ke * body->inertia.z) * rand_normal(); } }
static void update_step_nve(struct md *md) { double dt = cfg_get_double(md->state->cfg, "time_step"); for (size_t i = 0; i < md->n_bodies; i++) { struct body *body = md->bodies + i; body->vel.x += 0.5 * body->force.x * dt / body->mass; body->vel.y += 0.5 * body->force.y * dt / body->mass; body->vel.z += 0.5 * body->force.z * dt / body->mass; body->angmom.x += 0.5 * body->torque.x * dt; body->angmom.y += 0.5 * body->torque.y * dt; body->angmom.z += 0.5 * body->torque.z * dt; body->pos.x += body->vel.x * dt; body->pos.y += body->vel.y * dt; body->pos.z += body->vel.z * dt; rotate_body(body, dt); } compute_forces(md); for (size_t i = 0; i < md->n_bodies; i++) { struct body *body = md->bodies + i; body->vel.x += 0.5 * body->force.x * dt / body->mass; body->vel.y += 0.5 * body->force.y * dt / body->mass; body->vel.z += 0.5 * body->force.z * dt / body->mass; body->angmom.x += 0.5 * body->torque.x * dt; body->angmom.y += 0.5 * body->torque.y * dt; body->angmom.z += 0.5 * body->torque.z * dt; } }
static void compute_hessian(struct state *state, double *hess) { size_t n_frags, n_coord; double *xyzabc, *grad_f, *grad_b; bool central = cfg_get_bool(state->cfg, "hess_central"); check_fail(efp_get_frag_count(state->efp, &n_frags)); n_coord = 6 * n_frags; xyzabc = xmalloc(n_coord * sizeof(double)); grad_f = xmalloc(n_coord * sizeof(double)); grad_b = xmalloc(n_coord * sizeof(double)); check_fail(efp_get_coordinates(state->efp, xyzabc)); if (!central) { memcpy(grad_b, state->grad, n_frags * 6 * sizeof(double)); for (size_t i = 0; i < n_frags; i++) { const double *euler = xyzabc + 6 * i + 3; double *gradptr = grad_b + 6 * i + 3; efp_torque_to_derivative(euler, gradptr, gradptr); } } for (size_t i = 0; i < n_coord; i++) { double save = xyzabc[i]; double step = i % 6 < 3 ? cfg_get_double(state->cfg, "num_step_dist") : cfg_get_double(state->cfg, "num_step_angle"); show_progress(i + 1, n_coord, "FORWARD"); xyzabc[i] = save + step; compute_gradient(state, n_frags, xyzabc, grad_f); if (central) { show_progress(i + 1, n_coord, "BACKWARD"); xyzabc[i] = save - step; compute_gradient(state, n_frags, xyzabc, grad_b); } double delta = central ? 2.0 * step : step; for (size_t j = 0; j < n_coord; j++) hess[i * n_coord + j] = (grad_f[j] - grad_b[j]) / delta; xyzabc[i] = save; } /* restore original coordinates */ check_fail(efp_set_coordinates(state->efp, EFP_COORD_TYPE_XYZABC, xyzabc)); /* reduce error by computing the average of H(i,j) and H(j,i) */ for (size_t i = 0; i < n_coord; i++) { for (size_t j = i + 1; j < n_coord; j++) { double sum = hess[i * n_coord + j] + hess[j * n_coord + i]; hess[i * n_coord + j] = 0.5 * sum; hess[j * n_coord + i] = hess[i * n_coord + j]; } } free(xyzabc); free(grad_f); free(grad_b); msg("\n\n"); }
/* * Reference * * Simone Melchionna, Giovanni Ciccotti, Brad Lee Holian * * Hoover NPT dynamics for systems varying in shape and size * * Mol. Phys. 78, 533 (1993) */ static void update_step_npt(struct md *md) { struct npt_data *data = (struct npt_data *)md->data; double dt = cfg_get_double(md->state->cfg, "time_step"); double t_tau = cfg_get_double(md->state->cfg, "thermostat_tau"); double t_target = cfg_get_double(md->state->cfg, "temperature"); double p_tau = cfg_get_double(md->state->cfg, "barostat_tau"); double p_target = cfg_get_double(md->state->cfg, "pressure"); double t_tau2 = t_tau * t_tau; double p_tau2 = p_tau * p_tau; double kbt = BOLTZMANN * t_target; double t0 = get_temperature(md); double p0 = get_pressure(md); double v0 = get_volume(md); for (size_t i = 0; i < md->n_bodies; i++) { struct body *body = md->bodies + i; body->vel.x += 0.5 * dt * (body->force.x / body->mass - body->vel.x * (data->chi + data->eta)); body->vel.y += 0.5 * dt * (body->force.y / body->mass - body->vel.y * (data->chi + data->eta)); body->vel.z += 0.5 * dt * (body->force.z / body->mass - body->vel.z * (data->chi + data->eta)); body->angmom.x += 0.5 * dt * (body->torque.x - body->angmom.x * data->chi); body->angmom.y += 0.5 * dt * (body->torque.y - body->angmom.y * data->chi); body->angmom.z += 0.5 * dt * (body->torque.z - body->angmom.z * data->chi); rotate_body(body, dt); } data->chi += 0.5 * dt * (t0 / t_target - 1.0) / t_tau2; data->chi_dt += 0.5 * dt * data->chi; data->eta += 0.5 * dt * v0 * (p0 - p_target) / md->n_bodies / kbt / p_tau2; vec_t com = get_system_com(md); vec_t pos_init[md->n_bodies]; for (size_t i = 0; i < md->n_bodies; i++) pos_init[i] = md->bodies[i].pos; for (size_t iter = 1; iter <= MAX_ITER; iter++) { bool done = true; for (size_t i = 0; i < md->n_bodies; i++) { struct body *body = md->bodies + i; vec_t pos = wrap(md, &body->pos); vec_t v = { data->eta * (pos.x - com.x), data->eta * (pos.y - com.y), data->eta * (pos.z - com.z) }; vec_t new_pos = { pos_init[i].x + dt * (body->vel.x + v.x), pos_init[i].y + dt * (body->vel.y + v.y), pos_init[i].z + dt * (body->vel.z + v.z) }; done = done && vec_dist(&body->pos, &new_pos) < EPSILON; body->pos = new_pos; } if (done) break; if (iter == MAX_ITER) msg("WARNING: NPT UPDATE DID NOT CONVERGE\n\n"); } vec_scale(&md->box, exp(dt * data->eta)); check_fail(efp_set_periodic_box(md->state->efp, md->box.x, md->box.y, md->box.z)); compute_forces(md); double chi_init = data->chi, eta_init = data->eta; vec_t angmom_init[md->n_bodies], vel_init[md->n_bodies]; for (size_t i = 0; i < md->n_bodies; i++) { angmom_init[i] = md->bodies[i].angmom; vel_init[i] = md->bodies[i].vel; } for (size_t iter = 1; iter <= MAX_ITER; iter++) { double chi_prev = data->chi; double eta_prev = data->eta; double t_cur = get_temperature(md); double p_cur = get_pressure(md); double v_cur = get_volume(md); data->chi = chi_init + 0.5 * dt * (t_cur / t_target - 1.0) / t_tau2; data->eta = eta_init + 0.5 * dt * v_cur * (p_cur - p_target) / md->n_bodies / kbt / p_tau2; for (size_t i = 0; i < md->n_bodies; i++) { struct body *body = md->bodies + i; body->vel.x = vel_init[i].x + 0.5 * dt * (body->force.x / body->mass - vel_init[i].x * (data->chi + data->eta)); body->vel.y = vel_init[i].y + 0.5 * dt * (body->force.y / body->mass - vel_init[i].y * (data->chi + data->eta)); body->vel.z = vel_init[i].z + 0.5 * dt * (body->force.z / body->mass - vel_init[i].z * (data->chi + data->eta)); body->angmom.x = angmom_init[i].x + 0.5 * dt * (body->torque.x - angmom_init[i].x * data->chi); body->angmom.y = angmom_init[i].y + 0.5 * dt * (body->torque.y - angmom_init[i].y * data->chi); body->angmom.z = angmom_init[i].z + 0.5 * dt * (body->torque.z - angmom_init[i].z * data->chi); } if (fabs(data->chi - chi_prev) < EPSILON && fabs(data->eta - eta_prev) < EPSILON) break; if (iter == MAX_ITER) msg("WARNING: NPT UPDATE DID NOT CONVERGE\n\n"); } data->chi_dt += 0.5 * dt * data->chi; }
/* * NVT with Nose-Hoover thermostat: * * William G. Hoover * * Canonical dynamics: Equilibrium phase-space distributions * * Phys. Rev. A 31, 1695 (1985) */ static void update_step_nvt(struct md *md) { struct nvt_data *data = (struct nvt_data *)md->data; double dt = cfg_get_double(md->state->cfg, "time_step"); double target = cfg_get_double(md->state->cfg, "temperature"); double tau = cfg_get_double(md->state->cfg, "thermostat_tau"); double t0 = get_temperature(md); for (size_t i = 0; i < md->n_bodies; i++) { struct body *body = md->bodies + i; body->vel.x += 0.5 * dt * (body->force.x / body->mass - body->vel.x * data->chi); body->vel.y += 0.5 * dt * (body->force.y / body->mass - body->vel.y * data->chi); body->vel.z += 0.5 * dt * (body->force.z / body->mass - body->vel.z * data->chi); body->angmom.x += 0.5 * dt * (body->torque.x - body->angmom.x * data->chi); body->angmom.y += 0.5 * dt * (body->torque.y - body->angmom.y * data->chi); body->angmom.z += 0.5 * dt * (body->torque.z - body->angmom.z * data->chi); body->pos.x += body->vel.x * dt; body->pos.y += body->vel.y * dt; body->pos.z += body->vel.z * dt; rotate_body(body, dt); } data->chi += 0.5 * dt * (t0 / target - 1.0) / tau / tau; data->chi_dt += 0.5 * dt * data->chi; compute_forces(md); double chi_init = data->chi; vec_t angmom_init[md->n_bodies], vel_init[md->n_bodies]; for (size_t i = 0; i < md->n_bodies; i++) { angmom_init[i] = md->bodies[i].angmom; vel_init[i] = md->bodies[i].vel; } for (size_t iter = 1; iter <= MAX_ITER; iter++) { double chi_prev = data->chi; double ratio = get_temperature(md) / target; data->chi = chi_init + 0.5 * dt * (ratio - 1.0) / tau / tau; for (size_t i = 0; i < md->n_bodies; i++) { struct body *body = md->bodies + i; body->vel.x = vel_init[i].x + 0.5 * dt * (body->force.x / body->mass - vel_init[i].x * data->chi); body->vel.y = vel_init[i].y + 0.5 * dt * (body->force.y / body->mass - vel_init[i].y * data->chi); body->vel.z = vel_init[i].z + 0.5 * dt * (body->force.z / body->mass - vel_init[i].z * data->chi); body->angmom.x = angmom_init[i].x + 0.5 * dt * (body->torque.x - angmom_init[i].x * data->chi); body->angmom.y = angmom_init[i].y + 0.5 * dt * (body->torque.y - angmom_init[i].y * data->chi); body->angmom.z = angmom_init[i].z + 0.5 * dt * (body->torque.z - angmom_init[i].z * data->chi); } if (fabs(data->chi - chi_prev) < EPSILON) break; if (iter == MAX_ITER) msg("WARNING: NVT UPDATE DID NOT CONVERGE\n\n"); } data->chi_dt += 0.5 * dt * data->chi; }
static void *fsevents_thread(void *arg) { w_root_t *root = arg; FSEventStreamContext ctx; CFMutableArrayRef parray; CFStringRef cpath; FSEventStreamRef fs_stream = NULL; CFFileDescriptorContext fdctx; CFFileDescriptorRef fdref; struct fsevents_root_state *state = root->watch; double latency; w_set_thread_name("fsevents %.*s", root->root_path->len, root->root_path->buf); // Block until fsevents_root_start is waiting for our initialization pthread_mutex_lock(&state->fse_mtx); memset(&ctx, 0, sizeof(ctx)); ctx.info = root; memset(&fdctx, 0, sizeof(fdctx)); fdctx.info = root; fdref = CFFileDescriptorCreate(NULL, state->fse_pipe[0], true, fse_pipe_callback, &fdctx); CFFileDescriptorEnableCallBacks(fdref, kCFFileDescriptorReadCallBack); { CFRunLoopSourceRef fdsrc; fdsrc = CFFileDescriptorCreateRunLoopSource(NULL, fdref, 0); if (!fdsrc) { root->failure_reason = w_string_new( "CFFileDescriptorCreateRunLoopSource failed"); goto done; } CFRunLoopAddSource(CFRunLoopGetCurrent(), fdsrc, kCFRunLoopDefaultMode); CFRelease(fdsrc); } parray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); if (!parray) { root->failure_reason = w_string_new("CFArrayCreateMutable failed"); goto done; } cpath = CFStringCreateWithBytes(NULL, (const UInt8*)root->root_path->buf, root->root_path->len, kCFStringEncodingUTF8, false); if (!cpath) { root->failure_reason = w_string_new("CFStringCreateWithBytes failed"); goto done; } CFArrayAppendValue(parray, cpath); CFRelease(cpath); latency = cfg_get_double(root, "fsevents_latency", 0.01), w_log(W_LOG_DBG, "FSEventStreamCreate for path %.*s with latency %f seconds\n", root->root_path->len, root->root_path->buf, latency); fs_stream = FSEventStreamCreate(NULL, fse_callback, &ctx, parray, kFSEventStreamEventIdSinceNow, latency, kFSEventStreamCreateFlagNoDefer| kFSEventStreamCreateFlagWatchRoot| kFSEventStreamCreateFlagFileEvents); if (!fs_stream) { root->failure_reason = w_string_new("FSEventStreamCreate failed"); goto done; } FSEventStreamScheduleWithRunLoop(fs_stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); if (!FSEventStreamStart(fs_stream)) { root->failure_reason = w_string_make_printf( "FSEventStreamStart failed, look at your log file %s for " "lines mentioning FSEvents and see " "https://facebook.github.io/watchman/docs/troubleshooting.html#" "fsevents for more information\n", log_name); goto done; } // Signal to fsevents_root_start that we're done initializing pthread_cond_signal(&state->fse_cond); pthread_mutex_unlock(&state->fse_mtx); // Process the events stream until we get signalled to quit CFRunLoopRun(); // Since the goto's above hold fse_mtx, we should grab it here pthread_mutex_lock(&state->fse_mtx); done: if (fs_stream) { FSEventStreamStop(fs_stream); FSEventStreamInvalidate(fs_stream); FSEventStreamRelease(fs_stream); } if (fdref) { CFRelease(fdref); } // Signal to fsevents_root_start that we're done initializing in // the failure path. We'll also do this after we've completed // the run loop in the success path; it's a spurious wakeup but // harmless and saves us from adding and setting a control flag // in each of the failure `goto` statements. fsevents_root_dtor // will `pthread_join` us before `state` is freed. pthread_cond_signal(&state->fse_cond); pthread_mutex_unlock(&state->fse_mtx); w_log(W_LOG_DBG, "fse_thread done\n"); w_root_delref(root); return NULL; }