Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F78500142
libqmmm.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Wed, Aug 21, 06:30
Size
10 KB
Mime Type
text/x-c
Expires
Fri, Aug 23, 06:30 (2 d)
Engine
blob
Format
Raw Data
Handle
19933300
Attached To
rLAMMPS lammps
libqmmm.c
View Options
/*
* This file is distributed under the terms of the
* GNU General Public License. See the file `License'
* in the root directory of the present distribution,
* or http://www.gnu.org/copyleft/gpl.txt .
*
* generic QM/MM support library
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include "libqmmm.h"
#define BUF_SIZE 1024
/* global variable for global QM/MM configuration */
qmmm_config_t qmmmcfg;
/* local helper function: advance char pointer beyond leading whitespace */
static char *skip_whitespace(char *ptr)
{
while ((*ptr == ' ') || (*ptr == '\t')
|| (*ptr == '\r') || (*ptr == '\n')) ++ptr;
return ptr;
}
/* local helper function: trim string to remove trailing whitespace */
static void trim_whitespace(char *ptr)
{
while ((*ptr != ' ') && (*ptr != '\t')
&& (*ptr != '\r') && (*ptr != '\n')) ++ptr;
*ptr = '\0';
}
/* read and parse global QM/MM configuration file and
store the result in a qmmm_config_t struct */
int read_qmmm_config(const char *file, qmmm_config_t *cfg)
{
FILE *fp;
char *ptr;
int i, lineno, len;
char buf[BUF_SIZE];
/* need to have config file and storage for config provided */
if ((file == NULL) || (cfg == NULL))
return QMMM_ERROR;
/* clear config */
memset(cfg, 0, sizeof(qmmm_config_t));
fp = fopen(file,"r");
if (fp == NULL) return QMMM_ERROR;
lineno = 0;
while (fgets(buf,BUF_SIZE,fp)) {
++lineno;
/* remove comments */
ptr = strchr(buf,'#');
if (ptr != NULL) *ptr = '\0';
/* skip over leading whitespace */
ptr = skip_whitespace(buf);
len = strlen(ptr);
if (len == 0) continue;
/* convert keyword to lower case */
for (i=0; i < len; ++i) {
if ((ptr[i]=='\0') || (ptr[i]==' ') || (ptr[i]=='\t'))
break;
ptr[i] = tolower(ptr[i]);
}
/* handle keywords */
if (strncmp(ptr,"mode",4) == 0) {
ptr = skip_whitespace(ptr+4);
if ((*ptr=='m') || (*ptr=='M'))
cfg->qmmm_mode = QMMM_MODE_MECH;
else if ((*ptr=='e') || (*ptr=='E'))
cfg->qmmm_mode = QMMM_MODE_ELEC;
else if ((*ptr=='o') || (*ptr=='O'))
cfg->qmmm_mode = QMMM_MODE_OFF;
else cfg->qmmm_mode = QMMM_ERROR;
} else if (strncmp(ptr,"comm",4) == 0) {
ptr = skip_whitespace(ptr+4);
if ((*ptr=='m') || (*ptr=='M'))
cfg->comm_mode = QMMM_COMM_MPI;
else if ((*ptr=='s') || (*ptr=='S'))
cfg->comm_mode = QMMM_COMM_SHM;
else cfg->comm_mode = QMMM_ERROR;
} else if (strncmp(ptr,"steps",5) == 0) {
ptr = skip_whitespace(ptr+5);
trim_whitespace(ptr);
cfg->steps = atoi(ptr);
} else if (strncmp(ptr,"verbose",7) == 0) {
ptr = skip_whitespace(ptr+7);
trim_whitespace(ptr);
cfg->verbose = atoi(ptr);
} else if (strncmp(ptr,"handle",6) == 0) {
ptr = skip_whitespace(ptr+6);
trim_whitespace(ptr);
if (cfg->handle) free(cfg->handle);
cfg->handle = strdup(ptr);
} else if (strncmp(ptr,"restart",7) == 0) {
ptr = skip_whitespace(ptr+7);
trim_whitespace(ptr);
if (cfg->restart) free(cfg->restart);
cfg->restart = strdup(ptr);
} else if (strncmp(ptr,"qmdir",5) == 0) {
ptr = skip_whitespace(ptr+5);
trim_whitespace(ptr);
if (cfg->qmdir) free(cfg->qmdir);
cfg->qmdir = strdup(ptr);
} else if (strncmp(ptr,"madir",5) == 0) {
ptr = skip_whitespace(ptr+5);
trim_whitespace(ptr);
if (cfg->madir) free(cfg->madir);
cfg->madir = strdup(ptr);
} else if (strncmp(ptr,"sldir",5) == 0) {
ptr = skip_whitespace(ptr+5);
trim_whitespace(ptr);
if (cfg->sldir) free(cfg->sldir);
cfg->sldir = strdup(ptr);
} else if (strncmp(ptr,"qminp",5) == 0) {
ptr = skip_whitespace(ptr+5);
trim_whitespace(ptr);
if (cfg->qminp) free(cfg->qminp);
cfg->qminp = strdup(ptr);
} else if (strncmp(ptr,"mainp",5) == 0) {
ptr = skip_whitespace(ptr+5);
trim_whitespace(ptr);
if (cfg->mainp) free(cfg->mainp);
cfg->mainp = strdup(ptr);
} else if (strncmp(ptr,"slinp",5) == 0) {
ptr = skip_whitespace(ptr+5);
trim_whitespace(ptr);
if (cfg->slinp) free(cfg->slinp);
cfg->slinp = strdup(ptr);
} else if (strncmp(ptr,"qmout",5) == 0) {
ptr = skip_whitespace(ptr+5);
trim_whitespace(ptr);
if (cfg->qmout) free(cfg->qmout);
cfg->qmout = strdup(ptr);
} else if (strncmp(ptr,"maout",5) == 0) {
ptr = skip_whitespace(ptr+5);
trim_whitespace(ptr);
if (cfg->maout) free(cfg->maout);
cfg->maout = strdup(ptr);
} else if (strncmp(ptr,"slout",5) == 0) {
ptr = skip_whitespace(ptr+5);
trim_whitespace(ptr);
if (cfg->slout) free(cfg->slout);
cfg->slout = strdup(ptr);
} else if (strncmp(ptr,"qmcmd",5) == 0) {
ptr = skip_whitespace(ptr+5);
if (cfg->qmcmd) free(cfg->qmcmd);
cfg->qmcmd = strdup(ptr);
} else if (strncmp(ptr,"macmd",5) == 0) {
ptr = skip_whitespace(ptr+5);
if (cfg->macmd) free(cfg->macmd);
cfg->macmd = strdup(ptr);
} else if (strncmp(ptr,"slcmd",5) == 0) {
ptr = skip_whitespace(ptr+5);
if (cfg->slcmd) free(cfg->slcmd);
cfg->slcmd = strdup(ptr);
} else if (strncmp(ptr,"qmarg",5) == 0) {
ptr = skip_whitespace(ptr+5);
if (cfg->qmarg) free(cfg->qmarg);
cfg->qmarg = strdup(ptr);
} else if (strncmp(ptr,"maarg",5) == 0) {
ptr = skip_whitespace(ptr+5);
if (cfg->maarg) free(cfg->maarg);
cfg->maarg = strdup(ptr);
} else if (strncmp(ptr,"slarg",5) == 0) {
ptr = skip_whitespace(ptr+5);
if (cfg->slarg) free(cfg->slarg);
cfg->slarg = strdup(ptr);
} else {
fprintf(stderr,"\nParse error in line %d of file %s\n>>%s<<\n\n",
lineno, file, buf);
return QMMM_ERROR;
}
if (feof(fp)) break;
}
fclose(fp);
return QMMM_OK;
}
/* perform consistency checks on a qmmm_config_t struct */
const char *check_qmmm_config(qmmm_config_t *cfg) {
const char *msg = NULL;
if (cfg->qmmm_mode == QMMM_MODE_NONE) {
msg = "QM/MM coupling mode not set";
} else if (cfg->steps < 1) {
msg = "Number of QM/MM steps must be > 0";
} else if (cfg->qmdir == NULL) {
msg = "QM directory not set";
} else if (cfg->madir == NULL) {
msg = "MM master directory not set";
} else if (cfg->sldir == NULL) {
msg = "MM slave directory not set";
} else if (cfg->qminp == NULL) {
msg = "QM input file not set";
} else if (cfg->mainp == NULL) {
msg = "MM master input file not set";
} else if (cfg->slinp == NULL) {
msg = "MM slave input file not set";
} else if (cfg->qmout == NULL) {
msg = "QM output file not set";
} else if (cfg->maout == NULL) {
msg = "MM master output file not set";
} else if (cfg->slout == NULL) {
msg = "MM slave output file not set";
}
return msg;
}
/* take the existing global QM/MM configuration and write it to a file */
int write_qmmm_config(const char *file, qmmm_config_t *cfg)
{
FILE *fp;
time_t now;
if (cfg == NULL)
return QMMM_ERROR;
if (file == NULL)
fp = stderr;
else {
fp = fopen(file,"w");
if (fp == NULL) return QMMM_ERROR;
}
now = time(NULL);
fprintf(fp,"# QM/MM global configuration. %s\n",ctime(&now));
fprintf(fp,"# comm_mode: %d\n", cfg->comm_mode);
if (cfg->qmmm_mode == QMMM_MODE_OFF) {
fputs("mode off\n",fp);
} else if (cfg->qmmm_mode == QMMM_MODE_NONE) {
fputs("mode none\n",fp);
} else if (cfg->qmmm_mode == QMMM_MODE_MECH) {
fputs("mode mechanical\n",fp);
} else if (cfg->qmmm_mode == QMMM_MODE_ELEC) {
fputs("mode electrostatic\n",fp);
} else fputs("mode unknown\n",fp);
if (cfg->restart) fprintf(fp,"restart %s\n",cfg->restart);
if (cfg->handle) fprintf(fp,"handle %s\n", cfg->handle);
fprintf(fp,"steps %d\n",cfg->steps);
fprintf(fp,"verbose %d\n",cfg->verbose);
fputs("\n# QM system configuration:\n",fp);
if (cfg->qmdir) fprintf(fp,"qmdir %s\n", cfg->qmdir);
else fputs("qmdir (required input not set)\n",fp);
if (cfg->qminp) fprintf(fp,"qminp %s\n", cfg->qminp);
else fputs("qminp (required input not set)\n",fp);
if (cfg->qmout) fprintf(fp,"qmout %s\n", cfg->qmout);
else fputs("qmout NULL\n",fp);
if (cfg->qmcmd) fprintf(fp,"qmcmd %s\n", cfg->qmcmd);
if (cfg->qmarg) fprintf(fp,"qmarg %s\n", cfg->qmarg);
fputs("\n# MM master system configuration:\n",fp);
if (cfg->madir) fprintf(fp,"madir %s\n", cfg->madir);
else fputs("madir (required input not set)\n",fp);
if (cfg->mainp) fprintf(fp,"mainp %s\n", cfg->mainp);
else fputs("mainp (required input not set)\n",fp);
if (cfg->maout) fprintf(fp,"maout %s\n", cfg->maout);
else fputs("maout NULL\n",fp);
if (cfg->macmd) fprintf(fp,"macmd %s\n", cfg->macmd);
if (cfg->maarg) fprintf(fp,"maarg %s\n", cfg->maarg);
fputs("\n# MM slave system configuration:\n",fp);
if (cfg->sldir) fprintf(fp,"sldir %s\n", cfg->sldir);
else fputs("sldir (required input not set)\n",fp);
if (cfg->slinp) fprintf(fp,"slinp %s\n", cfg->slinp);
else fputs("slinp (required input not set)\n",fp);
if (cfg->slout) fprintf(fp,"slout %s\n", cfg->slout);
else fputs("slout NULL\n",fp);
if (cfg->slcmd) fprintf(fp,"slcmd %s\n", cfg->slcmd);
if (cfg->slarg) fprintf(fp,"slarg %s\n", cfg->slarg);
if (file != NULL) fclose(fp);
return QMMM_OK;
}
/* free storage associated with qmmm_config_t struct */
void free_qmmm_config(qmmm_config_t *cfg) {
if (cfg->qmdir != NULL) free(cfg->qmdir);
if (cfg->madir != NULL) free(cfg->madir);
if (cfg->sldir != NULL) free(cfg->sldir);
if (cfg->qminp != NULL) free(cfg->qminp);
if (cfg->mainp != NULL) free(cfg->mainp);
if (cfg->slinp != NULL) free(cfg->slinp);
if (cfg->qmout != NULL) free(cfg->qmout);
if (cfg->maout != NULL) free(cfg->maout);
if (cfg->slout != NULL) free(cfg->slout);
if (cfg->qmcmd != NULL) free(cfg->qmcmd);
if (cfg->macmd != NULL) free(cfg->macmd);
if (cfg->slcmd != NULL) free(cfg->slcmd);
if (cfg->qmarg != NULL) free(cfg->qmarg);
if (cfg->maarg != NULL) free(cfg->maarg);
if (cfg->slarg != NULL) free(cfg->slarg);
}
Event Timeline
Log In to Comment