Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F91149295
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
Fri, Nov 8, 09:52
Size
10 KB
Mime Type
text/x-c
Expires
Sun, Nov 10, 09:52 (2 d)
Engine
blob
Format
Raw Data
Handle
22205775
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
+
5
);
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
,
"
\n
Parse 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