int relax_shell_flexcon(FILE *fplog, t_commrec *cr, gmx_bool bVerbose, gmx_int64_t mdstep, t_inputrec *inputrec, gmx_bool bDoNS, int force_flags, gmx_localtop_t *top, gmx_constr_t constr, gmx_enerdata_t *enerd, t_fcdata *fcd, t_state *state, rvec f[], tensor force_vir, t_mdatoms *md, t_nrnb *nrnb, gmx_wallcycle_t wcycle, t_graph *graph, gmx_groups_t *groups, struct gmx_shellfc *shfc, t_forcerec *fr, gmx_bool bBornRadii, double t, rvec mu_tot, gmx_bool *bConverged, gmx_vsite_t *vsite, FILE *fp_field) { int nshell; t_shell *shell; t_idef *idef; rvec *pos[2], *force[2], *acc_dir = NULL, *x_old = NULL; real Epot[2], df[2]; rvec dx; real sf_dir, invdt; real ftol, xiH, xiS, dum = 0; char sbuf[22]; gmx_bool bCont, bInit; int nat, dd_ac0, dd_ac1 = 0, i; int start = 0, homenr = md->homenr, end = start+homenr, cg0, cg1; int nflexcon, g, number_steps, d, Min = 0, count = 0; #define Try (1-Min) /* At start Try = 1 */ bCont = (mdstep == inputrec->init_step) && inputrec->bContinuation; bInit = (mdstep == inputrec->init_step) || shfc->bRequireInit; ftol = inputrec->em_tol; number_steps = inputrec->niter; nshell = shfc->nshell; shell = shfc->shell; nflexcon = shfc->nflexcon; idef = &top->idef; if (DOMAINDECOMP(cr)) { nat = dd_natoms_vsite(cr->dd); if (nflexcon > 0) { dd_get_constraint_range(cr->dd, &dd_ac0, &dd_ac1); nat = max(nat, dd_ac1); } } else { nat = state->natoms; } if (nat > shfc->x_nalloc) { /* Allocate local arrays */ shfc->x_nalloc = over_alloc_dd(nat); for (i = 0; (i < 2); i++) { srenew(shfc->x[i], shfc->x_nalloc); srenew(shfc->f[i], shfc->x_nalloc); } } for (i = 0; (i < 2); i++) { pos[i] = shfc->x[i]; force[i] = shfc->f[i]; } /* When we had particle decomposition, this code only worked with * PD when all particles involved with each shell were in the same * charge group. Not sure if this is still relevant. */ if (bDoNS && inputrec->ePBC != epbcNONE && !DOMAINDECOMP(cr)) { /* This is the only time where the coordinates are used * before do_force is called, which normally puts all * charge groups in the box. */ cg0 = 0; cg1 = top->cgs.nr; put_charge_groups_in_box(fplog, cg0, cg1, fr->ePBC, state->box, &(top->cgs), state->x, fr->cg_cm); if (graph) { mk_mshift(fplog, graph, fr->ePBC, state->box, state->x); } } /* After this all coordinate arrays will contain whole molecules */ if (graph) { shift_self(graph, state->box, state->x); } if (nflexcon) { if (nat > shfc->flex_nalloc) { shfc->flex_nalloc = over_alloc_dd(nat); srenew(shfc->acc_dir, shfc->flex_nalloc); srenew(shfc->x_old, shfc->flex_nalloc); } acc_dir = shfc->acc_dir; x_old = shfc->x_old; for (i = 0; i < homenr; i++) { for (d = 0; d < DIM; d++) { shfc->x_old[i][d] = state->x[start+i][d] - state->v[start+i][d]*inputrec->delta_t; } } } /* Do a prediction of the shell positions */ if (shfc->bPredict && !bCont) { predict_shells(fplog, state->x, state->v, inputrec->delta_t, nshell, shell, md->massT, NULL, bInit); } /* do_force expected the charge groups to be in the box */ if (graph) { unshift_self(graph, state->box, state->x); } /* Calculate the forces first time around */ if (gmx_debug_at) { pr_rvecs(debug, 0, "x b4 do_force", state->x + start, homenr); } do_force(fplog, cr, inputrec, mdstep, nrnb, wcycle, top, groups, state->box, state->x, &state->hist, force[Min], force_vir, md, enerd, fcd, state->lambda, graph, fr, vsite, mu_tot, t, fp_field, NULL, bBornRadii, (bDoNS ? GMX_FORCE_NS : 0) | force_flags); sf_dir = 0; if (nflexcon) { init_adir(fplog, shfc, constr, idef, inputrec, cr, dd_ac1, mdstep, md, start, end, shfc->x_old-start, state->x, state->x, force[Min], shfc->acc_dir-start, fr->bMolPBC, state->box, state->lambda, &dum, nrnb); for (i = start; i < end; i++) { sf_dir += md->massT[i]*norm2(shfc->acc_dir[i-start]); } } Epot[Min] = enerd->term[F_EPOT]; df[Min] = rms_force(cr, shfc->f[Min], nshell, shell, nflexcon, &sf_dir, &Epot[Min]); df[Try] = 0; if (debug) { fprintf(debug, "df = %g %g\n", df[Min], df[Try]); } if (gmx_debug_at) { pr_rvecs(debug, 0, "force0", force[Min], md->nr); } if (nshell+nflexcon > 0) { /* Copy x to pos[Min] & pos[Try]: during minimization only the * shell positions are updated, therefore the other particles must * be set here. */ memcpy(pos[Min], state->x, nat*sizeof(state->x[0])); memcpy(pos[Try], state->x, nat*sizeof(state->x[0])); } if (bVerbose && MASTER(cr)) { print_epot(stdout, mdstep, 0, Epot[Min], df[Min], nflexcon, sf_dir); } if (debug) { fprintf(debug, "%17s: %14.10e\n", interaction_function[F_EKIN].longname, enerd->term[F_EKIN]); fprintf(debug, "%17s: %14.10e\n", interaction_function[F_EPOT].longname, enerd->term[F_EPOT]); fprintf(debug, "%17s: %14.10e\n", interaction_function[F_ETOT].longname, enerd->term[F_ETOT]); fprintf(debug, "SHELLSTEP %s\n", gmx_step_str(mdstep, sbuf)); } /* First check whether we should do shells, or whether the force is * low enough even without minimization. */ *bConverged = (df[Min] < ftol); for (count = 1; (!(*bConverged) && (count < number_steps)); count++) { if (vsite) { construct_vsites(vsite, pos[Min], inputrec->delta_t, state->v, idef->iparams, idef->il, fr->ePBC, fr->bMolPBC, cr, state->box); } if (nflexcon) { init_adir(fplog, shfc, constr, idef, inputrec, cr, dd_ac1, mdstep, md, start, end, x_old-start, state->x, pos[Min], force[Min], acc_dir-start, fr->bMolPBC, state->box, state->lambda, &dum, nrnb); directional_sd(pos[Min], pos[Try], acc_dir-start, start, end, fr->fc_stepsize); } /* New positions, Steepest descent */ shell_pos_sd(pos[Min], pos[Try], force[Min], nshell, shell, count); /* do_force expected the charge groups to be in the box */ if (graph) { unshift_self(graph, state->box, pos[Try]); } if (gmx_debug_at) { pr_rvecs(debug, 0, "RELAX: pos[Min] ", pos[Min] + start, homenr); pr_rvecs(debug, 0, "RELAX: pos[Try] ", pos[Try] + start, homenr); } /* Try the new positions */ do_force(fplog, cr, inputrec, 1, nrnb, wcycle, top, groups, state->box, pos[Try], &state->hist, force[Try], force_vir, md, enerd, fcd, state->lambda, graph, fr, vsite, mu_tot, t, fp_field, NULL, bBornRadii, force_flags); if (gmx_debug_at) { pr_rvecs(debug, 0, "RELAX: force[Min]", force[Min] + start, homenr); pr_rvecs(debug, 0, "RELAX: force[Try]", force[Try] + start, homenr); } sf_dir = 0; if (nflexcon) { init_adir(fplog, shfc, constr, idef, inputrec, cr, dd_ac1, mdstep, md, start, end, x_old-start, state->x, pos[Try], force[Try], acc_dir-start, fr->bMolPBC, state->box, state->lambda, &dum, nrnb); for (i = start; i < end; i++) { sf_dir += md->massT[i]*norm2(acc_dir[i-start]); } } Epot[Try] = enerd->term[F_EPOT]; df[Try] = rms_force(cr, force[Try], nshell, shell, nflexcon, &sf_dir, &Epot[Try]); if (debug) { fprintf(debug, "df = %g %g\n", df[Min], df[Try]); } if (debug) { if (gmx_debug_at) { pr_rvecs(debug, 0, "F na do_force", force[Try] + start, homenr); } if (gmx_debug_at) { fprintf(debug, "SHELL ITER %d\n", count); dump_shells(debug, pos[Try], force[Try], ftol, nshell, shell); } } if (bVerbose && MASTER(cr)) { print_epot(stdout, mdstep, count, Epot[Try], df[Try], nflexcon, sf_dir); } *bConverged = (df[Try] < ftol); if ((df[Try] < df[Min])) { if (debug) { fprintf(debug, "Swapping Min and Try\n"); } if (nflexcon) { /* Correct the velocities for the flexible constraints */ invdt = 1/inputrec->delta_t; for (i = start; i < end; i++) { for (d = 0; d < DIM; d++) { state->v[i][d] += (pos[Try][i][d] - pos[Min][i][d])*invdt; } } } Min = Try; } else { decrease_step_size(nshell, shell); } } if (MASTER(cr) && !(*bConverged)) { /* Note that the energies and virial are incorrect when not converged */ if (fplog) { fprintf(fplog, "step %s: EM did not converge in %d iterations, RMS force %.3f\n", gmx_step_str(mdstep, sbuf), number_steps, df[Min]); } fprintf(stderr, "step %s: EM did not converge in %d iterations, RMS force %.3f\n", gmx_step_str(mdstep, sbuf), number_steps, df[Min]); } /* Copy back the coordinates and the forces */ memcpy(state->x, pos[Min], nat*sizeof(state->x[0])); memcpy(f, force[Min], nat*sizeof(f[0])); return count; }
void process_command(int descr, dbref player, char *command) { char *arg1; char *arg2; char *full_command; char *p; /* utility */ char pbuf[BUFFER_LEN]; char xbuf[BUFFER_LEN]; char ybuf[BUFFER_LEN]; struct timeval starttime; struct timeval endtime; double totaltime; if (command == 0) abort(); /* robustify player */ if (player < 0 || player >= db_top || (Typeof(player) != TYPE_PLAYER && Typeof(player) != TYPE_THING)) { log_status("process_command: bad player %d", player); return; } if ((tp_log_commands || Wizard(OWNER(player)))) { if (!(FLAGS(player) & (INTERACTIVE | READMODE))) { if (!*command) { return; } log_command("%s: %s", whowhere(player), command); } else { if (tp_log_interactive) { log_command("%s: %s%s", whowhere(player), (FLAGS(player) & (READMODE)) ? "[READ] " : "[INTERP] ", command); } } } if (FLAGS(player) & INTERACTIVE) { interactive(descr, player, command); return; } /* eat leading whitespace */ while (*command && isspace(*command)) command++; /* Disable null command once past READ line */ if (!*command) return; /* check for single-character commands */ if (!tp_enable_prefix) { if (*command == SAY_TOKEN) { snprintf(pbuf, sizeof(pbuf), "say %s", command + 1); command = &pbuf[0]; } else if (*command == POSE_TOKEN) { snprintf(pbuf, sizeof(pbuf), "pose %s", command + 1); command = &pbuf[0]; } else if (*command == EXIT_DELIMITER) { snprintf(pbuf, sizeof(pbuf), "delimiter %s", command + 1); command = &pbuf[0]; } } /* profile how long command takes. */ gettimeofday(&starttime, NULL); /* if player is a wizard, and uses overide token to start line... */ /* ... then do NOT run actions, but run the command they specify. */ if (!(TrueWizard(OWNER(player)) && (*command == OVERIDE_TOKEN))) { if (can_move(descr, player, command, 0)) { do_move(descr, player, command, 0); /* command is exact match for exit */ *match_args = 0; *match_cmdname = 0; } else { if (tp_enable_prefix) { if (*command == SAY_TOKEN) { snprintf(pbuf, sizeof(pbuf), "say %s", command + 1); command = &pbuf[0]; } else if (*command == POSE_TOKEN) { snprintf(pbuf, sizeof(pbuf), "pose %s", command + 1); command = &pbuf[0]; } else if (*command == EXIT_DELIMITER) { snprintf(pbuf, sizeof(pbuf), "delimiter %s", command + 1); command = &pbuf[0]; } else { goto bad_pre_command; } if (can_move(descr, player, command, 0)) { do_move(descr, player, command, 0); /* command is exact match for exit */ *match_args = 0; *match_cmdname = 0; } else { goto bad_pre_command; } } else { goto bad_pre_command; } } } else { bad_pre_command: if (TrueWizard(OWNER(player)) && (*command == OVERIDE_TOKEN)) command++; full_command = strcpyn(xbuf, sizeof(xbuf), command); for (; *full_command && !isspace(*full_command); full_command++) ; if (*full_command) full_command++; /* find arg1 -- move over command word */ command = strcpyn(ybuf, sizeof(ybuf), command); for (arg1 = command; *arg1 && !isspace(*arg1); arg1++) ; /* truncate command */ if (*arg1) *arg1++ = '\0'; /* remember command for programs */ strcpyn(match_args, sizeof(match_args), full_command); strcpyn(match_cmdname, sizeof(match_cmdname), command); /* move over spaces */ while (*arg1 && isspace(*arg1)) arg1++; /* find end of arg1, start of arg2 */ for (arg2 = arg1; *arg2 && *arg2 != ARG_DELIMITER; arg2++) ; /* truncate arg1 */ for (p = arg2 - 1; p >= arg1 && isspace(*p); p--) *p = '\0'; /* go past delimiter if present */ if (*arg2) *arg2++ = '\0'; while (*arg2 && isspace(*arg2)) arg2++; switch (command[0]) { case '@': switch (command[1]) { case 'a': case 'A': /* @action, @armageddon, @attach */ switch (command[2]) { case 'c': case 'C': Matched("@action"); NOGUEST("@action", player); BUILDERONLY("@action", player); do_action(descr, player, arg1, arg2); break; case 'r': case 'R': if (strcmp(command, "@armageddon")) goto bad; /* WIZARDONLY("@armageddon", player); PLAYERONLY("@armageddon", player); */ do_armageddon(player, full_command); break; case 't': case 'T': Matched("@attach"); NOGUEST("@attach", player); BUILDERONLY("@attach", player); do_attach(descr, player, arg1, arg2); break; default: goto bad; } break; case 'b': case 'B': /* @bless, @boot */ switch (command[2]) { case 'l': case 'L': Matched("@bless"); WIZARDONLY("@bless", player); PLAYERONLY("@bless", player); NOFORCE("@bless", force_level, player); do_bless(descr, player, arg1, arg2); break; case 'o': case 'O': Matched("@boot"); WIZARDONLY("@boot", player); PLAYERONLY("@boot", player); do_boot(player, arg1); break; default: goto bad; } break; case 'c': case 'C': /* @chlock, @chown, @chown_lock, @clone, @conlock, @contents, @create, @credits */ switch (command[2]) { case 'h': case 'H': switch (command[3]) { case 'l': case 'L': Matched("@chlock"); NOGUEST("@chlock", player); set_standard_lock(descr, player, arg1, MESGPROP_CHLOCK, "Chown Lock", arg2); break; case 'o': case 'O': if(strlen(command) < 7) { Matched("@chown"); do_chown(descr, player, arg1, arg2); } else { Matched("@chown_lock"); NOGUEST("@chown_lock", player); set_standard_lock(descr, player, arg1, MESGPROP_CHLOCK, "Chown Lock", arg2); } break; default: goto bad; } break; case 'l': case 'L': Matched("@clone"); NOGUEST("@clone", player); BUILDERONLY("@clone", player); do_clone(descr, player, arg1); break; case 'o': case 'O': switch (command[4]) { case 'l': case 'L': Matched("@conlock"); NOGUEST("@conlock", player); set_standard_lock(descr, player, arg1, MESGPROP_CONLOCK, "Container Lock", arg2); break; case 't': case 'T': Matched("@contents"); do_contents(descr, player, arg1, arg2); break; default: goto bad; } break; case 'r': case 'R': if (string_compare(command, "@credits")) { Matched("@create"); NOGUEST("@create", player); BUILDERONLY("@create", player); do_create(player, arg1, arg2); } else { do_credits(player); } break; default: goto bad; } break; case 'd': case 'D': /* @dbginfo, @describe, @dig, @doing, @drop, @dump */ switch (command[2]) { #ifdef DISKBASE case 'b': case 'B': Matched("@dbginfo"); WIZARDONLY("@dbginfo", player); diskbase_debug(player); break; #endif case 'e': case 'E': Matched("@describe"); NOGUEST("@describe", player); set_standard_property(descr, player, arg1, MESGPROP_DESC, "Object Description", arg2); break; case 'i': case 'I': Matched("@dig"); NOGUEST("@dig", player); BUILDERONLY("@dig", player); do_dig(descr, player, arg1, arg2); break; case 'o': case 'O': Matched("@doing"); if (!tp_who_doing) goto bad; NOGUEST("@doing", player); set_standard_property(descr, player, arg1, MESGPROP_DOING, "Doing", arg2); break; case 'r': case 'R': Matched("@drop"); NOGUEST("@drop", player); set_standard_property(descr, player, arg1, MESGPROP_DROP, "Drop Message", arg2); break; case 'u': case 'U': Matched("@dump"); WIZARDONLY("@dump", player); PLAYERONLY("@dump", player); do_dump(player, full_command); break; default: goto bad; } break; case 'e': case 'E': /* @edit, @entrances, @examine */ switch (command[2]) { case 'd': case 'D': Matched("@edit"); NOGUEST("@edit", player); PLAYERONLY("@edit", player); MUCKERONLY("@edit", player); do_edit(descr, player, arg1); break; case 'n': case 'N': Matched("@entrances"); do_entrances(descr, player, arg1, arg2); break; case 'x': case 'X': Matched("@examine"); GODONLY("@examine", player); sane_dump_object(player, arg1); break; default: goto bad; } break; case 'f': case 'F': /* @fail, @find, @flock, @force, @force_lock */ switch (command[2]) { case 'a': case 'A': Matched("@fail"); NOGUEST("@fail", player); set_standard_property(descr, player, arg1, MESGPROP_FAIL, "Fail Message", arg2); break; case 'i': case 'I': Matched("@find"); do_find(player, arg1, arg2); break; case 'l': case 'L': Matched("@flock"); NOGUEST("@flock", player); NOFORCE("@flock", force_level, player); set_standard_lock(descr, player, arg1, MESGPROP_FLOCK, "Force Lock", arg2); break; case 'o': case 'O': if(strlen(command) < 7) { Matched("@force"); do_force(descr, player, arg1, arg2); } else { Matched("@force_lock"); NOGUEST("@force_lock", player); NOFORCE("@force_lock", force_level, player); set_standard_lock(descr, player, arg1, MESGPROP_FLOCK, "Force Lock", arg2); } break; default: goto bad; } break; case 'h': case 'H': /* @hashes */ Matched("@hashes"); do_hashes(player, arg1); break; case 'i': case 'I': /* @idescribe */ Matched("@idescribe"); NOGUEST("@idescribe", player); set_standard_property(descr, player, arg1, MESGPROP_IDESC, "Inside Description", arg2); break; case 'k': case 'K': /* @kill */ Matched("@kill"); do_dequeue(descr, player, arg1); break; case 'l': case 'L': /* @link, @list, @lock */ switch (command[2]) { case 'i': case 'I': switch (command[3]) { case 'n': case 'N': Matched("@link"); NOGUEST("@link", player); do_link(descr, player, arg1, arg2); break; case 's': case 'S': Matched("@list"); match_and_list(descr, player, arg1, arg2); break; default: goto bad; } break; case 'o': case 'O': Matched("@lock"); NOGUEST("@lock", player); set_standard_lock(descr, player, arg1, MESGPROP_LOCK, "Lock", arg2); break; default: goto bad; } break; case 'm': case 'M': /* @mcpedit, @mcpprogram, @memory, @mpitops, @muftops */ switch (command[2]) { #ifdef MCP_SUPPORT case 'c': case 'C': if (string_prefix("@mcpedit", command)) { Matched("@mcpedit"); NOGUEST("@mcpedit", player); PLAYERONLY("@mcpedit", player); MUCKERONLY("@mcpedit", player); do_mcpedit(descr, player, arg1); break; } else { Matched("@mcpprogram"); NOGUEST("@mcpprogram", player); PLAYERONLY("@mcpprogram", player); MUCKERONLY("@mcpprogram", player); do_mcpprogram(descr, player, arg1); break; } #endif #ifndef NO_MEMORY_COMMAND case 'e': case 'E': Matched("@memory"); WIZARDONLY("@memory", player); do_memory(player); break; #endif case 'p': case 'P': Matched("@mpitops"); WIZARDONLY("@mpitops", player); do_mpi_topprofs(player, arg1); break; case 'u': case 'U': Matched("@muftops"); WIZARDONLY("@muftops", player); do_muf_topprofs(player, arg1); break; default: goto bad; } break; case 'n': case 'N': /* @name, @newpassword */ switch (command[2]) { case 'a': case 'A': Matched("@name"); NOGUEST("@name", player); do_name(descr, player, arg1, arg2); break; case 'e': case 'E': if (strcmp(command, "@newpassword")) goto bad; WIZARDONLY("@newpassword", player); PLAYERONLY("@newpassword", player); do_newpassword(player, arg1, arg2); break; default: goto bad; } break; case 'o': case 'O': /* @odrop, @oecho, @ofail, @open, @osuccess, @owned */ switch (command[2]) { case 'd': case 'D': Matched("@odrop"); NOGUEST("@odrop", player); set_standard_property(descr, player, arg1, MESGPROP_ODROP, "ODrop Message", arg2); break; case 'e': case 'E': Matched("@oecho"); NOGUEST("@oecho", player); set_standard_property(descr, player, arg1, MESGPROP_OECHO, "Outside-echo Prefix", arg2); break; case 'f': case 'F': Matched("@ofail"); NOGUEST("@ofail", player); set_standard_property(descr, player, arg1, MESGPROP_OFAIL, "OFail Message", arg2); break; case 'p': case 'P': Matched("@open"); NOGUEST("@open", player); BUILDERONLY("@open", player); do_open(descr, player, arg1, arg2); break; case 's': case 'S': Matched("@osuccess"); NOGUEST("@osuccess", player); set_standard_property(descr, player, arg1, MESGPROP_OSUCC, "OSuccess Message", arg2); break; case 'w': case 'W': Matched("@owned"); do_owned(player, arg1, arg2); break; default: goto bad; } break; case 'p': case 'P': /* @password, @pcreate, @pecho, @program, @propset, @ps */ switch (command[2]) { case 'a': case 'A': Matched("@password"); PLAYERONLY("@password", player); NOGUEST("@password", player); do_password(player, arg1, arg2); break; case 'c': case 'C': Matched("@pcreate"); WIZARDONLY("@pcreate", player); PLAYERONLY("@pcreate", player); do_pcreate(player, arg1, arg2); break; case 'e': case 'E': Matched("@pecho"); NOGUEST("@pecho", player); set_standard_property(descr, player, arg1, MESGPROP_PECHO, "Puppet-echo Prefix", arg2); break; case 'r': case 'R': if (string_prefix("@program", command)) { Matched("@program"); NOGUEST("@program", player); PLAYERONLY("@program", player); MUCKERONLY("@program", player); do_prog(descr, player, arg1); break; } else { Matched("@propset"); NOGUEST("@propset", player); do_propset(descr, player, arg1, arg2); break; } case 's': case 'S': Matched("@ps"); list_events(player); break; default: goto bad; } break; case 'r': case 'R': /* @recycle, @reconfiguressl, @relink, @restart, @restrict */ switch (command[3]) { case 'c': case 'C': #ifdef USE_SSL if (!strcmp(command, "@reconfiguressl")) { WIZARDONLY("@reconfiguressl", player); PLAYERONLY("@reconfiguressl", player); do_reconfigure_ssl(player); break; } #endif Matched("@recycle"); NOGUEST("@recycle", player); do_recycle(descr, player, arg1); break; case 'l': case 'L': Matched("@relink"); NOGUEST("@relink", player); do_relink(descr, player, arg1, arg2); break; case 's': case 'S': if (!strcmp(command, "@restart")) { /* WIZARDONLY("@restart", player); PLAYERONLY("@restart", player); */ do_restart(player); } else if (!strcmp(command, "@restrict")) { WIZARDONLY("@restrict", player); PLAYERONLY("@restrict", player); do_restrict(player, arg1); } else { goto bad; } break; default: goto bad; } break; case 's': case 'S': /* @sanity, @sanchange, @sanfix, @set, @shutdown, @stats, @success, @sweep */ switch (command[2]) { case 'a': case 'A': if (!strcmp(command, "@sanity")) { GODONLY("@sanity", player); sanity(player); } else if (!strcmp(command, "@sanchange")) { GODONLY("@sanchange", player); sanechange(player, full_command); } else if (!strcmp(command, "@sanfix")) { GODONLY("@sanfix", player); sanfix(player); } else { goto bad; } break; case 'e': case 'E': Matched("@set"); NOGUEST("@set", player); do_set(descr, player, arg1, arg2); break; case 'h': case 'H': if (strcmp(command, "@shutdown")) goto bad; /* WIZARDONLY("@shutdown", player); PLAYERONLY("@shutdown", player); */ do_shutdown(player); break; case 't': case 'T': Matched("@stats"); do_stats(player, arg1); break; case 'u': case 'U': Matched("@success"); NOGUEST("@success", player); set_standard_property(descr, player, arg1, MESGPROP_SUCC, "Success Message", arg2); break; case 'w': case 'W': Matched("@sweep"); do_sweep(descr, player, arg1); break; default: goto bad; } break; case 't': case 'T': /* @teleport, @toad, @trace, @tune */ switch (command[2]) { case 'e': case 'E': Matched("@teleport"); do_teleport(descr, player, arg1, arg2); break; case 'o': case 'O': if (!strcmp(command, "@toad")) { WIZARDONLY("@toad", player); PLAYERONLY("@toad", player); do_toad(descr, player, arg1, arg2); } else if (!strcmp(command, "@tops")) { WIZARDONLY("@tops", player); do_all_topprofs(player, arg1); } else { goto bad; } break; case 'r': case 'R': Matched("@trace"); do_trace(descr, player, arg1, atoi(arg2)); break; case 'u': case 'U': Matched("@tune"); WIZARDONLY("@tune", player); PLAYERONLY("@tune", player); do_tune(player, arg1, arg2, !!strchr(full_command, ARG_DELIMITER)); break; default: goto bad; } break; case 'u': case 'U': /* @unbless, @unlink, @unlock, @uncompile, @usage */ switch (command[2]) { case 'N': case 'n': if (string_prefix(command, "@unb")) { Matched("@unbless"); WIZARDONLY("@unbless", player); PLAYERONLY("@unbless", player); NOFORCE("@unbless", force_level, player); do_unbless(descr, player, arg1, arg2); } else if (string_prefix(command, "@unli")) { Matched("@unlink"); NOGUEST("@unlink", player); do_unlink(descr, player, arg1); } else if (string_prefix(command, "@unlo")) { Matched("@unlock"); NOGUEST("@unlock", player); set_standard_lock(descr, player, arg1, MESGPROP_LOCK, "Lock", ""); } else if (string_prefix(command, "@uncom")) { Matched("@uncompile"); WIZARDONLY("@uncompile", player); PLAYERONLY("@uncompile", player); do_uncompile(player); } else { goto bad; } break; #ifndef NO_USAGE_COMMAND case 'S': case 's': Matched("@usage"); WIZARDONLY("@usage", player); do_usage(player); break; #endif default: goto bad; break; } break; case 'v': case 'V': /* @version */ Matched("@version"); do_version(player); break; case 'w': case 'W': /* @wall */ if (strcmp(command, "@wall")) goto bad; WIZARDONLY("@wall", player); PLAYERONLY("@wall", player); do_wall(player, full_command); break; default: goto bad; } break; case 'd': case 'D': /* disembark, drop */ switch (command[1]) { case 'i': case 'I': Matched("disembark"); do_leave(descr, player); break; case 'r': case 'R': Matched("drop"); do_drop(descr, player, arg1, arg2); break; default: goto bad; } break; case 'e': case 'E': /* examine */ Matched("examine"); do_examine(descr, player, arg1, arg2); break; case 'g': case 'G': /* get, give, goto, gripe */ switch (command[1]) { case 'e': case 'E': Matched("get"); do_get(descr, player, arg1, arg2); break; case 'i': case 'I': Matched("give"); do_give(descr, player, arg1, atoi(arg2)); break; case 'o': case 'O': Matched("goto"); do_move(descr, player, arg1, 0); break; case 'r': case 'R': if (string_compare(command, "gripe")) goto bad; do_gripe(player, full_command); break; default: goto bad; } break; case 'h': case 'H': /* help */ Matched("help"); do_help(player, arg1, arg2); break; case 'i': case 'I': /* inventory, info */ if (string_compare(command, "info")) { Matched("inventory"); do_inventory(player); } else { Matched("info"); do_info(player, arg1, arg2); } break; case 'k': case 'K': /* kill */ Matched("kill"); do_kill(descr, player, arg1, atoi(arg2)); break; case 'l': case 'L': /* leave, look */ if (string_prefix("look", command)) { Matched("look"); do_look_at(descr, player, arg1, arg2); break; } else { Matched("leave"); do_leave(descr, player); break; } case 'm': case 'M': /* man, motd, move, mpi */ if (string_prefix(command, "move")) { do_move(descr, player, arg1, 0); break; } else if (!string_compare(command, "motd")) { do_motd(player, full_command); break; } else if (!string_compare(command, "mpi")) { do_mpihelp(player, arg1, arg2); break; } else { if (string_compare(command, "man")) goto bad; do_man(player, (!*arg1 && !*arg2 && arg1 != arg2) ? "=" : arg1, arg2); } break; case 'n': case 'N': /* news */ Matched("news"); do_news(player, arg1, arg2); break; case 'p': case 'P': /* page, pose, put */ switch (command[1]) { case 'a': case 'A': Matched("page"); do_page(player, arg1, arg2); break; case 'o': case 'O': Matched("pose"); do_pose(player, full_command); break; case 'u': case 'U': Matched("put"); do_drop(descr, player, arg1, arg2); break; default: goto bad; } break; case 'r': case 'R': /* read, rob */ switch (command[1]) { case 'e': case 'E': Matched("read"); /* undocumented alias for look */ do_look_at(descr, player, arg1, arg2); break; case 'o': case 'O': Matched("rob"); do_rob(descr, player, arg1); break; default: goto bad; } break; case 's': case 'S': /* say, score */ switch (command[1]) { case 'a': case 'A': Matched("say"); do_say(player, full_command); break; case 'c': case 'C': Matched("score"); do_score(player); break; default: goto bad; } break; case 't': case 'T': /* take, throw */ switch (command[1]) { case 'a': case 'A': Matched("take"); do_get(descr, player, arg1, arg2); break; case 'h': case 'H': Matched("throw"); do_drop(descr, player, arg1, arg2); break; default: goto bad; } break; case 'w': case 'W': /* whisper */ Matched("whisper"); do_whisper(descr, player, arg1, arg2); break; default: bad: if (tp_m3_huh != 0) { char hbuf[BUFFER_LEN]; snprintf(hbuf,BUFFER_LEN,"HUH? %s", command); if(can_move(descr, player, hbuf, 3)) { do_move(descr, player, hbuf, 3); *match_args = 0; *match_cmdname = 0; break; } } notify(player, tp_huh_mesg); if (tp_log_failed_commands && !controls(player, LOCATION(player))) { log_status("HUH from %s(%d) in %s(%d)[%s]: %s %s", NAME(player), player, NAME(LOCATION(player)), LOCATION(player), NAME(OWNER(LOCATION(player))), command, full_command); } break; } } /* calculate time command took. */ gettimeofday(&endtime, NULL); if (starttime.tv_usec > endtime.tv_usec) { endtime.tv_usec += 1000000; endtime.tv_sec -= 1; } endtime.tv_usec -= starttime.tv_usec; endtime.tv_sec -= starttime.tv_sec; totaltime = endtime.tv_sec + (endtime.tv_usec * 1.0e-6); if (totaltime > (tp_cmd_log_threshold_msec / 1000.0)) { log2file(LOG_CMD_TIMES, "%6.3fs, %.16s: %s: %s", totaltime, ctime((time_t *)&starttime.tv_sec), whowhere(player), command); } }
double do_tpi(FILE *fplog, t_commrec *cr, int nfile, const t_filenm fnm[], const output_env_t oenv, gmx_bool bVerbose, gmx_bool gmx_unused bCompact, int gmx_unused nstglobalcomm, gmx_vsite_t gmx_unused *vsite, gmx_constr_t gmx_unused constr, int gmx_unused stepout, t_inputrec *inputrec, gmx_mtop_t *top_global, t_fcdata *fcd, t_state *state, t_mdatoms *mdatoms, t_nrnb *nrnb, gmx_wallcycle_t wcycle, gmx_edsam_t gmx_unused ed, t_forcerec *fr, int gmx_unused repl_ex_nst, int gmx_unused repl_ex_nex, int gmx_unused repl_ex_seed, gmx_membed_t gmx_unused membed, real gmx_unused cpt_period, real gmx_unused max_hours, const char gmx_unused *deviceOptions, int gmx_unused imdport, unsigned long gmx_unused Flags, gmx_walltime_accounting_t walltime_accounting) { const char *TPI = "Test Particle Insertion"; gmx_localtop_t *top; gmx_groups_t *groups; gmx_enerdata_t *enerd; rvec *f; real lambda, t, temp, beta, drmax, epot; double embU, sum_embU, *sum_UgembU, V, V_all, VembU_all; t_trxstatus *status; t_trxframe rerun_fr; gmx_bool bDispCorr, bCharge, bRFExcl, bNotLastFrame, bStateChanged, bNS; tensor force_vir, shake_vir, vir, pres; int cg_tp, a_tp0, a_tp1, ngid, gid_tp, nener, e; rvec *x_mol; rvec mu_tot, x_init, dx, x_tp; int nnodes, frame; gmx_int64_t frame_step_prev, frame_step; gmx_int64_t nsteps, stepblocksize = 0, step; gmx_int64_t rnd_count_stride, rnd_count; gmx_int64_t seed; double rnd[4]; int i, start, end; FILE *fp_tpi = NULL; char *ptr, *dump_pdb, **leg, str[STRLEN], str2[STRLEN]; double dbl, dump_ener; gmx_bool bCavity; int nat_cavity = 0, d; real *mass_cavity = NULL, mass_tot; int nbin; double invbinw, *bin, refvolshift, logV, bUlogV; real dvdl, prescorr, enercorr, dvdlcorr; gmx_bool bEnergyOutOfBounds; const char *tpid_leg[2] = {"direct", "reweighted"}; /* Since there is no upper limit to the insertion energies, * we need to set an upper limit for the distribution output. */ real bU_bin_limit = 50; real bU_logV_bin_limit = bU_bin_limit + 10; nnodes = cr->nnodes; top = gmx_mtop_generate_local_top(top_global, inputrec); groups = &top_global->groups; bCavity = (inputrec->eI == eiTPIC); if (bCavity) { ptr = getenv("GMX_TPIC_MASSES"); if (ptr == NULL) { nat_cavity = 1; } else { /* Read (multiple) masses from env var GMX_TPIC_MASSES, * The center of mass of the last atoms is then used for TPIC. */ nat_cavity = 0; while (sscanf(ptr, "%lf%n", &dbl, &i) > 0) { srenew(mass_cavity, nat_cavity+1); mass_cavity[nat_cavity] = dbl; fprintf(fplog, "mass[%d] = %f\n", nat_cavity+1, mass_cavity[nat_cavity]); nat_cavity++; ptr += i; } if (nat_cavity == 0) { gmx_fatal(FARGS, "Found %d masses in GMX_TPIC_MASSES", nat_cavity); } } } /* init_em(fplog,TPI,inputrec,&lambda,nrnb,mu_tot, state->box,fr,mdatoms,top,cr,nfile,fnm,NULL,NULL);*/ /* We never need full pbc for TPI */ fr->ePBC = epbcXYZ; /* Determine the temperature for the Boltzmann weighting */ temp = inputrec->opts.ref_t[0]; if (fplog) { for (i = 1; (i < inputrec->opts.ngtc); i++) { if (inputrec->opts.ref_t[i] != temp) { fprintf(fplog, "\nWARNING: The temperatures of the different temperature coupling groups are not identical\n\n"); fprintf(stderr, "\nWARNING: The temperatures of the different temperature coupling groups are not identical\n\n"); } } fprintf(fplog, "\n The temperature for test particle insertion is %.3f K\n\n", temp); } beta = 1.0/(BOLTZ*temp); /* Number of insertions per frame */ nsteps = inputrec->nsteps; /* Use the same neighborlist with more insertions points * in a sphere of radius drmax around the initial point */ /* This should be a proper mdp parameter */ drmax = inputrec->rtpi; /* An environment variable can be set to dump all configurations * to pdb with an insertion energy <= this value. */ dump_pdb = getenv("GMX_TPI_DUMP"); dump_ener = 0; if (dump_pdb) { sscanf(dump_pdb, "%lf", &dump_ener); } atoms2md(top_global, inputrec, 0, NULL, top_global->natoms, mdatoms); update_mdatoms(mdatoms, inputrec->fepvals->init_lambda); snew(enerd, 1); init_enerdata(groups->grps[egcENER].nr, inputrec->fepvals->n_lambda, enerd); snew(f, top_global->natoms); /* Print to log file */ walltime_accounting_start(walltime_accounting); wallcycle_start(wcycle, ewcRUN); print_start(fplog, cr, walltime_accounting, "Test Particle Insertion"); /* The last charge group is the group to be inserted */ cg_tp = top->cgs.nr - 1; a_tp0 = top->cgs.index[cg_tp]; a_tp1 = top->cgs.index[cg_tp+1]; if (debug) { fprintf(debug, "TPI cg %d, atoms %d-%d\n", cg_tp, a_tp0, a_tp1); } if (a_tp1 - a_tp0 > 1 && (inputrec->rlist < inputrec->rcoulomb || inputrec->rlist < inputrec->rvdw)) { gmx_fatal(FARGS, "Can not do TPI for multi-atom molecule with a twin-range cut-off"); } snew(x_mol, a_tp1-a_tp0); bDispCorr = (inputrec->eDispCorr != edispcNO); bCharge = FALSE; for (i = a_tp0; i < a_tp1; i++) { /* Copy the coordinates of the molecule to be insterted */ copy_rvec(state->x[i], x_mol[i-a_tp0]); /* Check if we need to print electrostatic energies */ bCharge |= (mdatoms->chargeA[i] != 0 || (mdatoms->chargeB && mdatoms->chargeB[i] != 0)); } bRFExcl = (bCharge && EEL_RF(fr->eeltype) && fr->eeltype != eelRF_NEC); calc_cgcm(fplog, cg_tp, cg_tp+1, &(top->cgs), state->x, fr->cg_cm); if (bCavity) { if (norm(fr->cg_cm[cg_tp]) > 0.5*inputrec->rlist && fplog) { fprintf(fplog, "WARNING: Your TPI molecule is not centered at 0,0,0\n"); fprintf(stderr, "WARNING: Your TPI molecule is not centered at 0,0,0\n"); } } else { /* Center the molecule to be inserted at zero */ for (i = 0; i < a_tp1-a_tp0; i++) { rvec_dec(x_mol[i], fr->cg_cm[cg_tp]); } } if (fplog) { fprintf(fplog, "\nWill insert %d atoms %s partial charges\n", a_tp1-a_tp0, bCharge ? "with" : "without"); fprintf(fplog, "\nWill insert %d times in each frame of %s\n", (int)nsteps, opt2fn("-rerun", nfile, fnm)); } if (!bCavity) { if (inputrec->nstlist > 1) { if (drmax == 0 && a_tp1-a_tp0 == 1) { gmx_fatal(FARGS, "Re-using the neighborlist %d times for insertions of a single atom in a sphere of radius %f does not make sense", inputrec->nstlist, drmax); } if (fplog) { fprintf(fplog, "Will use the same neighborlist for %d insertions in a sphere of radius %f\n", inputrec->nstlist, drmax); } } } else { if (fplog) { fprintf(fplog, "Will insert randomly in a sphere of radius %f around the center of the cavity\n", drmax); } } ngid = groups->grps[egcENER].nr; gid_tp = GET_CGINFO_GID(fr->cginfo[cg_tp]); nener = 1 + ngid; if (bDispCorr) { nener += 1; } if (bCharge) { nener += ngid; if (bRFExcl) { nener += 1; } if (EEL_FULL(fr->eeltype)) { nener += 1; } } snew(sum_UgembU, nener); /* Copy the random seed set by the user */ seed = inputrec->ld_seed; /* We use the frame step number as one random counter. * The second counter use the insertion (step) count. But we * need multiple random numbers per insertion. This number is * not fixed, since we generate random locations in a sphere * by putting locations in a cube and some of these fail. * A count of 20 is already extremely unlikely, so 10000 is * a safe margin for random numbers per insertion. */ rnd_count_stride = 10000; if (MASTER(cr)) { fp_tpi = xvgropen(opt2fn("-tpi", nfile, fnm), "TPI energies", "Time (ps)", "(kJ mol\\S-1\\N) / (nm\\S3\\N)", oenv); xvgr_subtitle(fp_tpi, "f. are averages over one frame", oenv); snew(leg, 4+nener); e = 0; sprintf(str, "-kT log(<Ve\\S-\\betaU\\N>/<V>)"); leg[e++] = strdup(str); sprintf(str, "f. -kT log<e\\S-\\betaU\\N>"); leg[e++] = strdup(str); sprintf(str, "f. <e\\S-\\betaU\\N>"); leg[e++] = strdup(str); sprintf(str, "f. V"); leg[e++] = strdup(str); sprintf(str, "f. <Ue\\S-\\betaU\\N>"); leg[e++] = strdup(str); for (i = 0; i < ngid; i++) { sprintf(str, "f. <U\\sVdW %s\\Ne\\S-\\betaU\\N>", *(groups->grpname[groups->grps[egcENER].nm_ind[i]])); leg[e++] = strdup(str); } if (bDispCorr) { sprintf(str, "f. <U\\sdisp c\\Ne\\S-\\betaU\\N>"); leg[e++] = strdup(str); } if (bCharge) { for (i = 0; i < ngid; i++) { sprintf(str, "f. <U\\sCoul %s\\Ne\\S-\\betaU\\N>", *(groups->grpname[groups->grps[egcENER].nm_ind[i]])); leg[e++] = strdup(str); } if (bRFExcl) { sprintf(str, "f. <U\\sRF excl\\Ne\\S-\\betaU\\N>"); leg[e++] = strdup(str); } if (EEL_FULL(fr->eeltype)) { sprintf(str, "f. <U\\sCoul recip\\Ne\\S-\\betaU\\N>"); leg[e++] = strdup(str); } } xvgr_legend(fp_tpi, 4+nener, (const char**)leg, oenv); for (i = 0; i < 4+nener; i++) { sfree(leg[i]); } sfree(leg); } clear_rvec(x_init); V_all = 0; VembU_all = 0; invbinw = 10; nbin = 10; snew(bin, nbin); /* Avoid frame step numbers <= -1 */ frame_step_prev = -1; bNotLastFrame = read_first_frame(oenv, &status, opt2fn("-rerun", nfile, fnm), &rerun_fr, TRX_NEED_X); frame = 0; if (rerun_fr.natoms - (bCavity ? nat_cavity : 0) != mdatoms->nr - (a_tp1 - a_tp0)) { gmx_fatal(FARGS, "Number of atoms in trajectory (%d)%s " "is not equal the number in the run input file (%d) " "minus the number of atoms to insert (%d)\n", rerun_fr.natoms, bCavity ? " minus one" : "", mdatoms->nr, a_tp1-a_tp0); } refvolshift = log(det(rerun_fr.box)); switch (inputrec->eI) { case eiTPI: stepblocksize = inputrec->nstlist; break; case eiTPIC: stepblocksize = 1; break; default: gmx_fatal(FARGS, "Unknown integrator %s", ei_names[inputrec->eI]); } #ifdef GMX_SIMD /* Make sure we don't detect SIMD overflow generated before this point */ gmx_simd_check_and_reset_overflow(); #endif while (bNotLastFrame) { frame_step = rerun_fr.step; if (frame_step <= frame_step_prev) { /* We don't have step number in the trajectory file, * or we have constant or decreasing step numbers. * Ensure we have increasing step numbers, since we use * the step numbers as a counter for random numbers. */ frame_step = frame_step_prev + 1; } frame_step_prev = frame_step; lambda = rerun_fr.lambda; t = rerun_fr.time; sum_embU = 0; for (e = 0; e < nener; e++) { sum_UgembU[e] = 0; } /* Copy the coordinates from the input trajectory */ for (i = 0; i < rerun_fr.natoms; i++) { copy_rvec(rerun_fr.x[i], state->x[i]); } copy_mat(rerun_fr.box, state->box); V = det(state->box); logV = log(V); bStateChanged = TRUE; bNS = TRUE; step = cr->nodeid*stepblocksize; while (step < nsteps) { /* Initialize the second counter for random numbers using * the insertion step index. This ensures that we get * the same random numbers independently of how many * MPI ranks we use. Also for the same seed, we get * the same initial random sequence for different nsteps. */ rnd_count = step*rnd_count_stride; if (!bCavity) { /* Random insertion in the whole volume */ bNS = (step % inputrec->nstlist == 0); if (bNS) { /* Generate a random position in the box */ gmx_rng_cycle_2uniform(frame_step, rnd_count++, seed, RND_SEED_TPI, rnd); gmx_rng_cycle_2uniform(frame_step, rnd_count++, seed, RND_SEED_TPI, rnd+2); for (d = 0; d < DIM; d++) { x_init[d] = rnd[d]*state->box[d][d]; } } if (inputrec->nstlist == 1) { copy_rvec(x_init, x_tp); } else { /* Generate coordinates within |dx|=drmax of x_init */ do { gmx_rng_cycle_2uniform(frame_step, rnd_count++, seed, RND_SEED_TPI, rnd); gmx_rng_cycle_2uniform(frame_step, rnd_count++, seed, RND_SEED_TPI, rnd+2); for (d = 0; d < DIM; d++) { dx[d] = (2*rnd[d] - 1)*drmax; } } while (norm2(dx) > drmax*drmax); rvec_add(x_init, dx, x_tp); } } else { /* Random insertion around a cavity location * given by the last coordinate of the trajectory. */ if (step == 0) { if (nat_cavity == 1) { /* Copy the location of the cavity */ copy_rvec(rerun_fr.x[rerun_fr.natoms-1], x_init); } else { /* Determine the center of mass of the last molecule */ clear_rvec(x_init); mass_tot = 0; for (i = 0; i < nat_cavity; i++) { for (d = 0; d < DIM; d++) { x_init[d] += mass_cavity[i]*rerun_fr.x[rerun_fr.natoms-nat_cavity+i][d]; } mass_tot += mass_cavity[i]; } for (d = 0; d < DIM; d++) { x_init[d] /= mass_tot; } } } /* Generate coordinates within |dx|=drmax of x_init */ do { gmx_rng_cycle_2uniform(frame_step, rnd_count++, seed, RND_SEED_TPI, rnd); gmx_rng_cycle_2uniform(frame_step, rnd_count++, seed, RND_SEED_TPI, rnd+2); for (d = 0; d < DIM; d++) { dx[d] = (2*rnd[d] - 1)*drmax; } } while (norm2(dx) > drmax*drmax); rvec_add(x_init, dx, x_tp); } if (a_tp1 - a_tp0 == 1) { /* Insert a single atom, just copy the insertion location */ copy_rvec(x_tp, state->x[a_tp0]); } else { /* Copy the coordinates from the top file */ for (i = a_tp0; i < a_tp1; i++) { copy_rvec(x_mol[i-a_tp0], state->x[i]); } /* Rotate the molecule randomly */ gmx_rng_cycle_2uniform(frame_step, rnd_count++, seed, RND_SEED_TPI, rnd); gmx_rng_cycle_2uniform(frame_step, rnd_count++, seed, RND_SEED_TPI, rnd+2); rotate_conf(a_tp1-a_tp0, state->x+a_tp0, NULL, 2*M_PI*rnd[0], 2*M_PI*rnd[1], 2*M_PI*rnd[2]); /* Shift to the insertion location */ for (i = a_tp0; i < a_tp1; i++) { rvec_inc(state->x[i], x_tp); } } /* Clear some matrix variables */ clear_mat(force_vir); clear_mat(shake_vir); clear_mat(vir); clear_mat(pres); /* Set the charge group center of mass of the test particle */ copy_rvec(x_init, fr->cg_cm[top->cgs.nr-1]); /* Calc energy (no forces) on new positions. * Since we only need the intermolecular energy * and the RF exclusion terms of the inserted molecule occur * within a single charge group we can pass NULL for the graph. * This also avoids shifts that would move charge groups * out of the box. * * Some checks above ensure than we can not have * twin-range interactions together with nstlist > 1, * therefore we do not need to remember the LR energies. */ /* Make do_force do a single node force calculation */ cr->nnodes = 1; do_force(fplog, cr, inputrec, step, nrnb, wcycle, top, &top_global->groups, state->box, state->x, &state->hist, f, force_vir, mdatoms, enerd, fcd, state->lambda, NULL, fr, NULL, mu_tot, t, NULL, NULL, FALSE, GMX_FORCE_NONBONDED | GMX_FORCE_ENERGY | (bNS ? GMX_FORCE_DYNAMICBOX | GMX_FORCE_NS | GMX_FORCE_DO_LR : 0) | (bStateChanged ? GMX_FORCE_STATECHANGED : 0)); cr->nnodes = nnodes; bStateChanged = FALSE; bNS = FALSE; /* Calculate long range corrections to pressure and energy */ calc_dispcorr(fplog, inputrec, fr, step, top_global->natoms, state->box, lambda, pres, vir, &prescorr, &enercorr, &dvdlcorr); /* figure out how to rearrange the next 4 lines MRS 8/4/2009 */ enerd->term[F_DISPCORR] = enercorr; enerd->term[F_EPOT] += enercorr; enerd->term[F_PRES] += prescorr; enerd->term[F_DVDL_VDW] += dvdlcorr; epot = enerd->term[F_EPOT]; bEnergyOutOfBounds = FALSE; #ifdef GMX_SIMD_X86_SSE2_OR_HIGHER /* With SSE the energy can overflow, check for this */ if (gmx_mm_check_and_reset_overflow()) { if (debug) { fprintf(debug, "Found an SSE overflow, assuming the energy is out of bounds\n"); } bEnergyOutOfBounds = TRUE; } #endif /* If the compiler doesn't optimize this check away * we catch the NAN energies. * The epot>GMX_REAL_MAX check catches inf values, * which should nicely result in embU=0 through the exp below, * but it does not hurt to check anyhow. */ /* Non-bonded Interaction usually diverge at r=0. * With tabulated interaction functions the first few entries * should be capped in a consistent fashion between * repulsion, dispersion and Coulomb to avoid accidental * negative values in the total energy. * The table generation code in tables.c does this. * With user tbales the user should take care of this. */ if (epot != epot || epot > GMX_REAL_MAX) { bEnergyOutOfBounds = TRUE; } if (bEnergyOutOfBounds) { if (debug) { fprintf(debug, "\n time %.3f, step %d: non-finite energy %f, using exp(-bU)=0\n", t, (int)step, epot); } embU = 0; } else { embU = exp(-beta*epot); sum_embU += embU; /* Determine the weighted energy contributions of each energy group */ e = 0; sum_UgembU[e++] += epot*embU; if (fr->bBHAM) { for (i = 0; i < ngid; i++) { sum_UgembU[e++] += (enerd->grpp.ener[egBHAMSR][GID(i, gid_tp, ngid)] + enerd->grpp.ener[egBHAMLR][GID(i, gid_tp, ngid)])*embU; } } else { for (i = 0; i < ngid; i++) { sum_UgembU[e++] += (enerd->grpp.ener[egLJSR][GID(i, gid_tp, ngid)] + enerd->grpp.ener[egLJLR][GID(i, gid_tp, ngid)])*embU; } } if (bDispCorr) { sum_UgembU[e++] += enerd->term[F_DISPCORR]*embU; } if (bCharge) { for (i = 0; i < ngid; i++) { sum_UgembU[e++] += (enerd->grpp.ener[egCOULSR][GID(i, gid_tp, ngid)] + enerd->grpp.ener[egCOULLR][GID(i, gid_tp, ngid)])*embU; } if (bRFExcl) { sum_UgembU[e++] += enerd->term[F_RF_EXCL]*embU; } if (EEL_FULL(fr->eeltype)) { sum_UgembU[e++] += enerd->term[F_COUL_RECIP]*embU; } } } if (embU == 0 || beta*epot > bU_bin_limit) { bin[0]++; } else { i = (int)((bU_logV_bin_limit - (beta*epot - logV + refvolshift))*invbinw + 0.5); if (i < 0) { i = 0; } if (i >= nbin) { realloc_bins(&bin, &nbin, i+10); } bin[i]++; } if (debug) { fprintf(debug, "TPI %7d %12.5e %12.5f %12.5f %12.5f\n", (int)step, epot, x_tp[XX], x_tp[YY], x_tp[ZZ]); } if (dump_pdb && epot <= dump_ener) { sprintf(str, "t%g_step%d.pdb", t, (int)step); sprintf(str2, "t: %f step %d ener: %f", t, (int)step, epot); write_sto_conf_mtop(str, str2, top_global, state->x, state->v, inputrec->ePBC, state->box); } step++; if ((step/stepblocksize) % cr->nnodes != cr->nodeid) { /* Skip all steps assigned to the other MPI ranks */ step += (cr->nnodes - 1)*stepblocksize; } } if (PAR(cr)) { /* When running in parallel sum the energies over the processes */ gmx_sumd(1, &sum_embU, cr); gmx_sumd(nener, sum_UgembU, cr); } frame++; V_all += V; VembU_all += V*sum_embU/nsteps; if (fp_tpi) { if (bVerbose || frame%10 == 0 || frame < 10) { fprintf(stderr, "mu %10.3e <mu> %10.3e\n", -log(sum_embU/nsteps)/beta, -log(VembU_all/V_all)/beta); } fprintf(fp_tpi, "%10.3f %12.5e %12.5e %12.5e %12.5e", t, VembU_all == 0 ? 20/beta : -log(VembU_all/V_all)/beta, sum_embU == 0 ? 20/beta : -log(sum_embU/nsteps)/beta, sum_embU/nsteps, V); for (e = 0; e < nener; e++) { fprintf(fp_tpi, " %12.5e", sum_UgembU[e]/nsteps); } fprintf(fp_tpi, "\n"); fflush(fp_tpi); } bNotLastFrame = read_next_frame(oenv, status, &rerun_fr); } /* End of the loop */ walltime_accounting_end(walltime_accounting); close_trj(status); if (fp_tpi != NULL) { gmx_fio_fclose(fp_tpi); } if (fplog != NULL) { fprintf(fplog, "\n"); fprintf(fplog, " <V> = %12.5e nm^3\n", V_all/frame); fprintf(fplog, " <mu> = %12.5e kJ/mol\n", -log(VembU_all/V_all)/beta); } /* Write the Boltzmann factor histogram */ if (PAR(cr)) { /* When running in parallel sum the bins over the processes */ i = nbin; global_max(cr, &i); realloc_bins(&bin, &nbin, i); gmx_sumd(nbin, bin, cr); } if (MASTER(cr)) { fp_tpi = xvgropen(opt2fn("-tpid", nfile, fnm), "TPI energy distribution", "\\betaU - log(V/<V>)", "count", oenv); sprintf(str, "number \\betaU > %g: %9.3e", bU_bin_limit, bin[0]); xvgr_subtitle(fp_tpi, str, oenv); xvgr_legend(fp_tpi, 2, (const char **)tpid_leg, oenv); for (i = nbin-1; i > 0; i--) { bUlogV = -i/invbinw + bU_logV_bin_limit - refvolshift + log(V_all/frame); fprintf(fp_tpi, "%6.2f %10d %12.5e\n", bUlogV, (int)(bin[i]+0.5), bin[i]*exp(-bUlogV)*V_all/VembU_all); } gmx_fio_fclose(fp_tpi); } sfree(bin); sfree(sum_UgembU); walltime_accounting_set_nsteps_done(walltime_accounting, frame*inputrec->nsteps); return 0; }
void process_command(int descr, dbref player, char *command) { char *arg1; char *arg2; char *full_command, *commandline=command, *commandstuff; char *p; /* utility */ char pbuf[BUFFER_LEN]; char xbuf[BUFFER_LEN]; char ybuf[BUFFER_LEN]; const char *path; struct frame *tmpfr; if (command == 0) abort(); /* robustify player */ if (player < 0 || player >= db_top || (Typeof(player) != TYPE_PLAYER && Typeof(player) != TYPE_THING)) { log_status("process_command: bad player %d\n", player); return; } if ((tp_log_commands || (tp_log_guests && Guest(OWNER(player)))) && (!(FLAGS(player)&(INTERACTIVE | READMODE)))) { log_command("%s%s%s%s(%d) in %s(%d):%s %s\n", Mage(OWNER(player)) ? "WIZ: " : "", (Typeof(player) != TYPE_PLAYER) ? NAME(player) : "", (Typeof(player) != TYPE_PLAYER) ? " by " : "", NAME(OWNER(player)), (int) player, NAME(DBFETCH(player)->location), (int) DBFETCH(player)->location, (FLAGS(player) & INTERACTIVE) ? " [interactive]" : " ", command); } if (FLAGS(player) & INTERACTIVE) { interactive(descr, player, command); return; } /* eat leading whitespace */ while (*command && isspace(*command)) command++; commandstuff = command; /* check for single-character commands */ if (*command == SAY_TOKEN || *command == '\'') { sprintf(pbuf, "say %s", command + 1); command = &pbuf[0]; } else if (*command == POSE_TOKEN || *command == ';') { sprintf(pbuf, "pose %s", command + 1); command = &pbuf[0]; } else if ((*command == '|' || (*commandstuff++ == '\\' && *commandstuff == '\\') ) && can_move(descr, player, "spoof", 0)) { if(*command = '\\') sprintf(pbuf, "spoof %s", command + 2); else sprintf(pbuf, "spoof %s", command + 1); command = &pbuf[0]; } /* if player is a wizard, and uses overide token to start line...*/ /* ... then do NOT run actions, but run the command they specify. */ if (!strcmp(command, WHO_COMMAND)) { char xxbuf[BUFFER_LEN]; strcpy(xxbuf, "@"); strcat(xxbuf, WHO_COMMAND); strcat(xxbuf, " "); strcat(xxbuf, command + sizeof(WHO_COMMAND) - 1); if (can_move(descr, player, xxbuf, 5)) { do_move(descr, player, xxbuf, 5); } else { pdump_who_users(descr, command + sizeof(WHO_COMMAND) - 1); } return; } if (!( *command == OVERIDE_TOKEN && TMage(player) )) { if( can_move(descr, player, command, 0) ) { do_move(descr, player, command, 0); /* command is exact match for exit */ *match_args = 0; *match_cmdname = 0; return; } } if (*command == OVERIDE_TOKEN && TMage(player)) command++; full_command = strcpy(xbuf, command); for (; *full_command && !isspace(*full_command); full_command++); if (*full_command) full_command++; /* find arg1 -- move over command word */ command = strcpy(ybuf, command); for (arg1 = command; *arg1 && !isspace(*arg1); arg1++); /* truncate command */ if (*arg1) *arg1++ = '\0'; /* remember command for programs */ strcpy(match_cmdname, command); /* move over spaces */ while (*arg1 && isspace(*arg1)) arg1++; /* find end of arg1, start of arg2 */ for (arg2 = arg1; *arg2 && *arg2 != ARG_DELIMITER; arg2++); /* truncate arg1 */ for (p = arg2 - 1; p >= arg1 && isspace(*p); p--) *p = '\0'; /* go past delimiter if present */ if (*arg2) *arg2++ = '\0'; while (*arg2 && isspace(*arg2)) arg2++; strcpy(match_cmdname, command); strcpy(match_args, full_command); switch (command[0]) { case '@': switch (command[1]) { case 'a': case 'A': /* @action, @attach */ switch (command[2]) { case 'c': case 'C': Matched("@action"); do_action(descr, player, arg1, arg2); break; case 'r': case 'R': if (string_compare(command, "@armageddon")) goto bad; do_armageddon(player, full_command); break; case 't': case 'T': Matched("@attach"); do_attach(descr, player, arg1, arg2); break; case 'n': case 'N': Matched("@ansidescribe"); do_ansidescribe(descr, player, arg1, arg2); break; default: goto bad; } break; case 'b': case 'B': Matched("@boot"); do_boot(player, arg1); break; case 'c': case 'C': /* chown, contents, create */ switch (command[2]) { case 'h': case 'H': switch (command[3]) { case 'l': case 'L': Matched("@chlock"); do_chlock(descr, player, arg1, arg2); break; case 'o': case 'O': Matched("@chown"); do_chown(descr, player, arg1, arg2); break; default: goto bad; } break; case 'o': case 'O': switch (command[4]) { case 'l': case 'L': Matched("@conlock"); do_conlock(descr, player, arg1, arg2); break; case 't': case 'T': Matched("@contents"); do_contents(descr, player, arg1, arg2); break; default: goto bad; } break; case 'r': case 'R': if (string_compare(command, "@credits")) { Matched("@create"); do_create(player, arg1, arg2); } else { do_credits(player); } break; default: goto bad; } break; case 'd': case 'D': /* describe, dequeue, dig, or dump */ switch (command[2]) { case 'b': case 'B': Matched("@dbginfo"); do_serverdebug(descr, player, arg1, arg2); break; case 'e': case 'E': #ifdef DELTADUMPS if(command[3] == 'l' || command[3] == 'L') { Matched("@delta"); do_delta(player); } else #endif { if( (command[3] == 's' || command[3] == 'S') && (command[4] == 't' || command[4] == 'T') ) { Matched("@destroy"); do_recycle(descr, player, arg1); } else { Matched("@describe"); do_describe(descr, player, arg1, arg2); } } break; case 'i': case 'I': Matched("@dig"); do_dig(descr, player, arg1, arg2); break; #ifdef DELTADUMPS case 'l': case 'L': Matched("@dlt"); do_delta(player); break; #endif case 'o': case 'O': Matched("@doing"); if (!tp_who_doing) goto bad; do_doing(descr, player, arg1, arg2); break; case 'r': case 'R': Matched("@drop"); do_drop_message(descr, player, arg1, arg2); break; case 'u': case 'U': Matched("@dump"); do_dump(player, full_command); break; default: goto bad; } break; case 'e': case 'E': switch (command[2]) { case 'd': case 'D': Matched("@edit"); do_edit(descr, player, arg1); break; case 'n': case 'N': Matched("@entrances"); do_entrances(descr, player, arg1, arg2); break; case 'x': case 'X': Matched("@examine"); sane_dump_object(player, arg1); break; default: goto bad; } break; case 'f': case 'F': /* fail, find, force, or frob */ switch (command[2]) { case 'a': case 'A': Matched("@fail"); do_fail(descr, player, arg1, arg2); break; case 'i': case 'I': if(command[3] == 'x' || command[3] == 'X') { Matched("@fixwizbits"); do_fixw(player, full_command); } else { Matched("@find"); do_find(player, arg1, arg2); } break; case 'l': case 'L': Matched("@flock"); do_flock(descr, player, arg1, arg2); break; case 'o': case 'O': Matched("@force"); do_force(descr, player, arg1, arg2); break; case 'r': case 'R': if (string_compare(command, "@frob")) goto bad; do_frob(descr, player, arg1, arg2); break; default: goto bad; } break; case 'h': case 'H': switch (command[2]) { case 'T': case 't': Matched("@htmldescribe"); do_htmldescribe(descr, player, arg1, arg2); break; default: Matched("@hopper"); do_hopper(player, arg1); break; } break; case 'i': case 'I': switch(command[2]) { case 'h': case 'H': Matched("@ihtmldescribe"); do_ihtmldescribe(descr, player, arg1, arg2); break; case 'a': case 'A': Matched("@iansidescribe"); do_iansidescribe(descr, player, arg1, arg2); break; default: Matched("@idescribe"); do_idescribe(descr, player, arg1, arg2); break; } break; case 'k': case 'K': Matched("@kill"); do_dequeue(descr, player, arg1); break; case 'l': case 'L': /* lock or link */ switch (command[2]) { case 'i': case 'I': switch (command[3]) { case 'n': case 'N': Matched("@link"); do_link(descr, player, arg1, arg2); break; case 's': case 'S': Matched("@list"); match_and_list(descr, player, arg1, arg2, 1); break; default: goto bad; } break; case 'o': case 'O': Matched("@lock"); do_lock(descr, player, arg1, arg2); break; default: goto bad; } break; case 'm': case 'M': switch (command[2]) { case 'e': case 'E': Matched("@memory"); do_memory(player); break; case 'c': case 'C': switch (command[4]) { case '2': Matched("@mcp2muf"); match_and_list(descr, player, arg1, arg2, 0); break; default: Matched("@mcp"); do_prog(descr, player, arg1, 1); break; } default: goto bad; } break; case 'n': case 'N': /* @name or @newpassword */ switch (command[2]) { case 'a': case 'A': Matched("@name"); do_name(descr, player, arg1, arg2); break; case 'e': case 'E': if (string_compare(command, "@newpassword")) goto bad; do_newpassword(player, arg1, arg2); break; default: goto bad; } break; case 'o': case 'O': switch (command[2]) { case 'd': case 'D': Matched("@odrop"); do_odrop(descr, player, arg1, arg2); break; case 'e': case 'E': Matched("@oecho"); do_oecho(descr, player, arg1, arg2); break; case 'f': case 'F': Matched("@ofail"); do_ofail(descr, player, arg1, arg2); break; case 'p': case 'P': Matched("@open"); do_open(descr, player, arg1, arg2); break; case 's': case 'S': Matched("@osuccess"); do_osuccess(descr, player, arg1, arg2); break; case 'w': case 'W': Matched("@owned"); do_owned(player, arg1, arg2); break; default: goto bad; } break; case 'p': case 'P': switch (command[2]) { case 'a': case 'A': Matched("@password"); do_password(player, arg1, arg2); break; case 'c': case 'C': Matched("@pcreate"); do_pcreate(player, arg1, arg2); break; case 'e': case 'E': Matched("@pecho"); do_pecho(descr, player, arg1, arg2); break; case 'r': case 'R': if (string_prefix("@program", command)) { do_prog(descr, player, arg1, 0); break; } else if (string_prefix("@proginfo", command)) { do_proginfo(player, arg1); break; } else { Matched("@propset"); do_propset(descr, player, arg1, arg2); break; } case 's': case 'S': Matched("@ps"); list_events(player); break; case 'u': case 'U': Matched("@purge"); do_purge(descr, player, arg1, arg2); break; default: goto bad; } break; case 'r': case 'R': switch (command[3]) { case 'c': case 'C': Matched("@recycle"); do_recycle(descr, player, arg1); break; case 's': case 'S': if (!string_compare(command, "@restart")) { do_restart(player, full_command); } else if (!string_compare(command, "@restrict")) { do_restrict(player, arg1); } else { goto bad; } break; default: goto bad; } break; case 's': case 'S': /* set, shutdown, success */ switch (command[2]) { case 'a': case 'A': if (!string_compare(command, "@sanity")) { sanity(player); } else if (!string_compare(command, "@sanchange")) { sanechange(player, full_command); } else if (!string_compare(command, "@sanfix")) { sanfix(player); } else { goto bad; } break; case 'e': case 'E': Matched("@set"); do_set(descr, player, arg1, arg2); break; case 'h': case 'H': if (!string_compare(command, "@shout")) { do_wall(player, full_command); break; } if (string_compare(command, "@shutdown")) goto bad; do_shutdown(player, arg1); break; case 't': case 'T': Matched("@stats"); do_stats(player, arg1); break; case 'u': case 'U': Matched("@success"); do_success(descr, player, arg1, arg2); break; case 'w': case 'W': Matched("@sweep"); do_sweep(descr, player, arg1); break; default: goto bad; } break; case 't': case 'T': switch (command[2]) { case 'e': case 'E': Matched("@teleport"); do_teleport(descr, player, arg1, arg2); break; case 'o': case 'O': if (string_compare(command, "@toad")) goto bad; do_frob(descr, player, arg1, arg2); break; case 'r': case 'R': Matched("@trace"); do_trace(descr, player, arg1, atoi(arg2)); break; case 'u': case 'U': Matched("@tune"); do_tune(player, arg1, arg2); break; default: goto bad; } break; case 'u': case 'U': switch (command[2]) { case 'N': case 'n': if (string_prefix(command, "@unlink")) { do_unlink(descr, player, arg1); } else if (string_prefix(command, "@unlock")) { do_unlock(descr, player, arg1); } else if (string_prefix(command, "@uncompile")) { do_uncompile(player); } else { goto bad; } break; #ifndef NO_USAGE_COMMAND case 'S': case 's': Matched("@usage"); do_usage(player); break; #endif default: goto bad; break; } break; case 'v': case 'V': Matched("@version"); anotify_nolisten2(player, CRIMSON "ProtoMUCK " PROTOBASE PURPLE " (" RED VERSION WHITE " -- " AQUA NEONVER PURPLE ")" ); break; case 'w': case 'W': if (string_compare(command, "@wall")) goto bad; do_wall(player, full_command); break; default: goto bad; } break; case '&': do_mush_set(descr, player, arg1, arg2, command); break; case 'd': case 'D': switch (command[1]) { case 'b': case 'B': Matched("dboot"); do_dboot(player, arg1); break; case 'i': case 'I': Matched("dinfo"); do_dinfo(player, arg1); break; case 'r': case 'R': Matched("drop"); do_drop(descr, player, arg1, arg2); break; case 'w': case 'W': Matched("dwall"); do_dwall(player, arg1, arg2); break; default: goto bad; } break; case 'e': case 'E': switch (command[1]) { case 'm': case 'M': Matched("emote"); do_pose(descr, player, full_command); break; case 'x': case 'X': case '\0': Matched("examine"); do_examine(descr, player, arg1, arg2); break; default: goto bad; } break; case 'g': case 'G': /* get, give, go, or gripe */ switch (command[1]) { case 'e': case 'E': Matched("get"); do_get(descr, player, arg1, arg2); break; case 'i': case 'I': Matched("give"); do_give(descr, player, arg1, atoi(arg2)); break; case 'o': case 'O': Matched("goto"); do_move(descr, player, arg1, 0); break; case 'r': case 'R': if(command[2]=='i' || command[2]=='I') { if (string_compare(command, "gripe")) goto bad; do_gripe(player, full_command); break; } default: goto bad; } break; case 'h': case 'H': switch (command[1]) { case 'a': case 'A': Matched("hand"); do_drop(descr, player, arg1, arg2); break; case 'e': case 'E': Matched("help"); do_help(player, arg1, arg2); break; default: goto bad; } break; case 'i': case 'I': if (string_compare(command, "info")) { Matched("inventory"); do_inventory(player); } else { do_info(player, arg1, arg2); } break; case 'l': case 'L': if (string_prefix("look", command)) { do_look_at(descr, player, arg1, arg2); break; } else { Matched("leave"); do_leave(descr, player); break; } case 'm': case 'M': if (string_prefix(command, "move")) { do_move(descr, player, arg1, 0); break; } else if (!string_compare(command, "motd")) { do_motd(player, full_command); break; } else if (!string_compare(command, "mpi")) { do_mpihelp(player, arg1, arg2); break; } else { if (string_compare(command, "man")) goto bad; do_man(player, arg1, arg2); } break; case 'n': case 'N': /* news */ Matched("news"); do_news(player, arg1, arg2); break; case 'p': case 'P': switch (command[1]) { case 'a': case 'A': case '\0': Matched("page"); do_page(descr, player, arg1, arg2); break; case 'o': case 'O': Matched("pose"); do_pose(descr, player, full_command); break; case 'u': case 'U': Matched("put"); do_drop(descr, player, arg1, arg2); break; default: goto bad; } break; case 'r': case 'R': switch (command[1]) { case 'e': case 'E': if(command[2] == 'q' || command[2] == 'Q'){ Matched("request"); request(player, NULL, commandline); } else { Matched("read"); /* undocumented alias for look */ do_look_at(descr, player, arg1, arg2); } break; default: goto bad; } break; case 's': case 'S': /* say, "score" */ switch (command[1]) { case 'a': case 'A': Matched("say"); do_say(descr, player, full_command); break; case 'c': case 'C': case '\0': if( command[1] && (command[2] == 'a' || command[2] == 'A' )) { Matched("scan"); do_sweep(descr, player, arg1); } else { Matched("score"); do_score(player, 1); } break; default: goto bad; } break; case 't': case 'T': switch (command[1]) { case 'a': case 'A': Matched("take"); do_get(descr, player, arg1, arg2); break; case 'h': case 'H': Matched("throw"); do_drop(descr, player, arg1, arg2); break; default: goto bad; } break; case 'w': case 'W': switch (command[1]){ case 'c': case 'C': Matched("wc"); do_wizchat(player, full_command); break; case 'i': case 'I': Matched("wizchat"); do_wizchat(player, arg1); break; case 'h': case 'H': case '\0': Matched("whisper"); do_whisper(descr, player, arg1, arg2); break; default: goto bad; } break; default: bad: if ( Typeof(tp_huh_command) == TYPE_PROGRAM && !(player == -1)) { tmpfr = interp(descr, player, DBFETCH(player)->location, tp_huh_command, (dbref)-4, FOREGROUND, STD_REGUID); if (!tmpfr) goto bad2; (void) interp_loop(player, tp_huh_command, tmpfr, 0); } else { bad2: anotify_fmt(player, CINFO "%s",tp_huh_mesg); if (tp_log_failed_commands && !controls(player, DBFETCH(player)->location)) { log_status("HUH from %s(%d) in %s(%d)[%s]: %s %s\n", NAME(player), player, NAME(DBFETCH(player)->location), DBFETCH(player)->location, NAME(OWNER(DBFETCH(player)->location)), command, full_command); } } break; } }