Skip to content

Commit a569b1e

Browse files
author
Roberto Di Remigio
committed
Accepting host_input when host is Fortran seems finally working
1 parent fc98f62 commit a569b1e

File tree

10 files changed

+92
-122
lines changed

10 files changed

+92
-122
lines changed

api/pcmsolver.F90

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,24 @@ module pcmsolver
2525
public pcmsolver_write_timings
2626

2727
type, public, bind(C) :: PCMInput
28-
character(kind=c_char, len=1) :: cavity_type(8)
29-
integer(c_int) :: patch_level
30-
real(c_double) :: coarsity
31-
real(c_double) :: area
32-
real(c_double) :: min_distance
33-
integer(c_int) :: der_order
34-
logical(c_bool) :: scaling
35-
character(kind=c_char, len=1) :: radii_set(8)
36-
character(kind=c_char, len=1) :: restart_name(20)
37-
real(c_double) :: min_radius
38-
character(kind=c_char, len=1) :: solver_type(7)
39-
character(kind=c_char, len=1) :: solvent(16)
40-
character(kind=c_char, len=1) :: equation_type(11)
41-
real(c_double) :: correction
42-
real(c_double) :: probe_radius
43-
character(kind=c_char, len=1) :: inside_type(7)
44-
real(c_double) :: outside_epsilon
45-
character(kind=c_char, len=1) :: outside_type(22)
28+
character(kind=c_char, len=1) :: cavity_type(8) = 'abcdefg'//c_null_char
29+
integer(c_int) :: patch_level = 0
30+
real(c_double) :: coarsity = 0.0
31+
real(c_double) :: area = 0.0
32+
character(kind=c_char, len=1) :: radii_set(8) = 'abcdefg'//c_null_char
33+
real(c_double) :: min_distance = 0.0
34+
integer(c_int) :: der_order = 0
35+
logical(c_bool) :: scaling = .false.
36+
character(kind=c_char, len=1) :: restart_name(20) = 'abcdefghijklmnopqrs'//c_null_char
37+
real(c_double) :: min_radius = 0.0
38+
character(kind=c_char, len=1) :: solver_type(7) = 'abcdef'//c_null_char
39+
real(c_double) :: correction = 0.0
40+
character(kind=c_char, len=1) :: solvent(16) = 'abcdefghijklmno'//c_null_char
41+
real(c_double) :: probe_radius = 0.0
42+
character(kind=c_char, len=1) :: equation_type(11) = 'abcdefghij'//c_null_char
43+
character(kind=c_char, len=1) :: inside_type(7) = 'abcde'//c_null_char
44+
real(c_double) :: outside_epsilon = 0.0
45+
character(kind=c_char, len=1) :: outside_type(22) = 'abcdefghijklmnopqrstu'//c_null_char
4646
end type PCMInput
4747

4848
public PCMSOLVER_READER_OWN

cmake/custom/autogenerated.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ configure_file(${PROJECT_SOURCE_DIR}/Config.hpp.in ${PROJECT_BINARY_DIR}/include
44
get_property(PCMSOLVER_EXECUTABLE GLOBAL PROPERTY PCMSolver_EXECUTABLE)
55
# Configure the input parsing script
66
configure_file(${PROJECT_SOURCE_DIR}/tools/pcmsolver.py.in ${PROJECT_BINARY_DIR}/bin/pcmsolver.py @ONLY)
7+
install(FILES ${PROJECT_BINARY_DIR}/bin/pcmsolver.py DESTINATION bin)

cmake/custom/compilers/GNU.Fortran.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Overrides contents of all variables previously set by CMake
22
if(NOT DEFINED ENV{FCFLAGS})
33
if(CMAKE_Fortran_COMPILER_ID MATCHES GNU)
4-
set(CMAKE_Fortran_FLAGS "-DVAR_GFORTRAN -DGFORTRAN=445 -fimplicit-none -fPIC -fautomatic -fmax-errors=1")
4+
set(CMAKE_Fortran_FLAGS "-fimplicit-none -fPIC -fautomatic -fmax-errors=1")
55
set(CMAKE_Fortran_FLAGS_DEBUG "-O0 -g -fbacktrace -Wall -Wextra ${Fcheck_all}")
66
set(CMAKE_Fortran_FLAGS_RELEASE "-O3 -funroll-all-loops -ftree-vectorize")
77
endif()

doc/gfx/interface.png

-242 Bytes
Loading

doc/gfx/utils.png

544 Bytes
Loading

src/interface/PCMInput.hpp

Lines changed: 6 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,13 @@
2626
#ifndef PCMINPUT_HPP
2727
#define PCMINPUT_HPP
2828

29-
#include <algorithm>
3029
#include <iostream>
3130
#include <string>
3231

3332
#include "Config.hpp"
3433

35-
#include <boost/algorithm/string.hpp>
36-
37-
inline bool invalidChar(char c);
38-
3934
struct PCMInput;
4035
inline void print(const PCMInput &);
41-
inline void init(PCMInput &);
42-
inline void trim(PCMInput &);
43-
44-
bool invalidChar(char c)
45-
{
46-
return !std::isprint( static_cast<unsigned char>( c ) );
47-
}
4836

4937
/*! @struct PCMInput
5038
* @brief Data structure for host-API input communication.
@@ -59,28 +47,28 @@ struct PCMInput
5947
double coarsity;
6048
/// Average tesserae area.
6149
double area;
50+
/// The built-in radii set to be used.
51+
char radii_set[8];
6252
/// Minimal distance between sampling points.
6353
double min_distance;
6454
/// Derivative order for the switching function.
6555
int der_order;
6656
/// Whether to scale or not the atomic radii.
6757
bool scaling;
68-
/// The built-in radii set to be used.
69-
char radii_set[8];
7058
/// Name of the .npz file for GePol cavity restart.
7159
char restart_name[20];
7260
/// Minimal radius for the added spheres.
7361
double min_radius;
7462
/// Type of solver requested.
7563
char solver_type[7];
76-
/// Name of the solvent.
77-
char solvent[16];
78-
/// Type of the integral equation to be used.
79-
char equation_type[11];
8064
/// Correction in the CPCM apparent surface charge scaling factor.
8165
double correction;
66+
/// Name of the solvent.
67+
char solvent[16];
8268
/// Radius of the spherical probe mimicking the solvent.
8369
double probe_radius;
70+
/// Type of the integral equation to be used.
71+
char equation_type[11];
8472
/// Type of Green's function requested inside the cavity.
8573
char inside_type[7];
8674
/// Value of the static permittivity outside the cavity.
@@ -110,78 +98,5 @@ void print(const PCMInput & inp)
11098
std::cout << "outside type " << std::string(inp.outside_type) << std::endl;
11199
std::cout << "epsilon outside " << inp.outside_epsilon << std::endl;
112100
}
113-
void init(PCMInput & inp)
114-
{
115-
inp.patch_level = 0;
116-
std::fill((inp.cavity_type), (inp.cavity_type) + 8, 0);
117-
inp.coarsity = 0.0;
118-
inp.area = 0.0;
119-
inp.min_distance = 0.0;
120-
inp.der_order = 0;
121-
inp.scaling = false;
122-
std::fill((inp.radii_set), (inp.radii_set) + 8, 0);
123-
std::fill((inp.restart_name), (inp.restart_name) + 20, 0);
124-
inp.min_radius = 0.0;
125-
std::fill((inp.solver_type), (inp.solver_type) + 7, 0);
126-
inp.correction = 0.0;
127-
std::fill((inp.solvent), (inp.solvent) + 16, 0);
128-
inp.probe_radius = 0.0;
129-
std::fill((inp.equation_type), (inp.equation_type) + 11, 0);
130-
std::fill((inp.inside_type), (inp.inside_type) + 7, 0);
131-
inp.outside_epsilon = 0.0;
132-
std::fill((inp.outside_type), (inp.outside_type) + 22, 0);
133-
}
134-
void trim(PCMInput & inp)
135-
{
136-
std::string s1(inp.cavity_type);
137-
s1.erase(std::remove_if(s1.begin(), s1.end(), invalidChar), s1.end());
138-
boost::algorithm::trim(s1);
139-
std::fill((inp.cavity_type), (inp.cavity_type) + 8, 0);
140-
strncpy(inp.cavity_type, s1.c_str(), s1.length());
141-
142-
/*
143-
std::string s2(inp.restart_name);
144-
s2.erase(std::remove_if(s2.begin(), s2.end(), invalidChar), s2.end());
145-
boost::algorithm::trim(s2);
146-
std::fill((inp.restart_name), (inp.restart_name) + 20, 0);
147-
strncpy(inp.cavity_type, s2.c_str(), s2.length());
148-
149-
std::string s3(inp.radii_set);
150-
s3.erase(std::remove_if(s3.begin(), s3.end(), invalidChar), s3.end());
151-
boost::algorithm::trim(s3);
152-
std::fill((inp.radii_set), (inp.radii_set) + 8, 0);
153-
strncpy(inp.cavity_type, s3.c_str(), s3.length());
154-
155-
std::string s4(inp.solver_type);
156-
s4.erase(std::remove_if(s4.begin(), s4.end(), invalidChar), s4.end());
157-
boost::algorithm::trim(s4);
158-
std::fill((inp.solver_type), (inp.solver_type) + 7, 0);
159-
strncpy(inp.solver_type, s4.c_str(), s4.length());
160-
161-
std::string s5(inp.solvent);
162-
s5.erase(std::remove_if(s5.begin(), s5.end(), invalidChar), s5.end());
163-
boost::algorithm::trim(s5);
164-
std::fill((inp.solvent), (inp.solvent) + 16, 0);
165-
strncpy(inp.solvent, s5.c_str(), s5.length());
166-
167-
std::string s6(inp.equation_type);
168-
s6.erase(std::remove_if(s6.begin(), s6.end(), invalidChar), s6.end());
169-
boost::algorithm::trim(s6);
170-
std::fill((inp.equation_type), (inp.equation_type) + 11, 0);
171-
strncpy(inp.equation_type, s6.c_str(), s6.length());
172-
173-
std::string s7(inp.inside_type);
174-
s7.erase(std::remove_if(s7.begin(), s7.end(), invalidChar), s7.end());
175-
boost::algorithm::trim(s7);
176-
std::fill((inp.inside_type), (inp.inside_type) + 7, 0);
177-
strncpy(inp.inside_type, s7.c_str(), s7.length());
178-
179-
std::string s8(inp.outside_type);
180-
s8.erase(std::remove_if(s8.begin(), s8.end(), invalidChar), s8.end());
181-
boost::algorithm::trim(s8);
182-
std::fill((inp.outside_type), (inp.outside_type) + 22, 0);
183-
strncpy(inp.outside_type, s8.c_str(), s8.length());
184-
*/
185-
}
186101

187102
#endif // PCMINPUT_HPP

src/utils/FortranCUtils.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@
2525

2626
#include "FortranCUtils.hpp"
2727

28+
#include "Config.hpp"
29+
30+
#include <cctype>
31+
#include <cstring>
32+
33+
#ifndef _fcdtocp
34+
#define _fcdtocp(desc) (desc)
35+
#endif
36+
2837
void pcmsolver_c2f_string(char * src, char * dest, int * len)
2938
{
3039
int sofar;
@@ -33,3 +42,20 @@ void pcmsolver_c2f_string(char * src, char * dest, int * len)
3342
while (sofar++ < *len)
3443
*dest++ = ' ';
3544
}
45+
46+
void pcmsolver_f2c_string(char * src, char * dest, int * len)
47+
{
48+
char * str; /* Pointer to FORTRAN string */
49+
int i; /* Local index variable */
50+
51+
/* Search for the end of the string */
52+
str = _fcdtocp(src);
53+
for(i = (int)*len - 1; i >= 0 && !std::isgraph((int)str[i]); i--)
54+
/*EMPTY*/;
55+
56+
/* Copy text from FORTRAN to C string */
57+
std::memcpy(dest, str, (size_t)(i + 1));
58+
59+
/* Terminate C string */
60+
dest[i + 1] = '\0';
61+
}

src/utils/FortranCUtils.hpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,28 @@
3232
extern "C" {
3333
#endif
3434

35-
/*! \brief Convert C string to Fortran string
35+
/*! \brief Convert a C string to a Fortran string
3636
* \param[in] src the string to convert
37-
* \param[out] src the string to convert
37+
* \param[out] dest the converted string
3838
* \param[in] len length of Fortran string
3939
* Change a C string (NULL terminated) into a Fortran string.
4040
* Basically, all that is done is that the NULL is ripped out
4141
* and the string is padded with spaces
4242
*/
4343
#define pcmsolver_c2f_string \
4444
FortranCInterface_GLOBAL_(pcmsolver_c2f_string, PCMSOLVER_C2F_STRING)
45-
void pcmsolver_c2f_string(char * src, char * dest, int * len);
45+
void pcmsolver_c2f_string(char * src, char * dest, int * len);
46+
47+
/*! \brief Convert a Fortran string to a C string
48+
* \param[in] src Fortran string
49+
* \param[out] dest C string
50+
* \param[in] len length of Fortran string
51+
* Chop off trailing blanks off of a Fortran string and
52+
* move it into C string.
53+
*/
54+
#define pcmsolver_f2c_string \
55+
FortranCInterface_GLOBAL_(pcmsolver_f2c_string, PCMSOLVER_F2C_STRING)
56+
void pcmsolver_f2c_string(char * src, char * dest, int * len);
4657

4758
#ifdef __cplusplus
4859
}

src/utils/Input.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "Sphere.hpp"
4747

4848
using boost::algorithm::to_upper_copy;
49+
using boost::algorithm::trim;
4950

5051
Input::Input(const std::string & filename)
5152
{
@@ -172,38 +173,50 @@ void Input::reader(const std::string & filename)
172173
providedBy_ = std::string("API-side");
173174
}
174175

176+
std::string trim(const char * src)
177+
{
178+
std::string tmp(src);
179+
trim(tmp);
180+
return tmp;
181+
}
182+
183+
std::string trim_and_upper(const char * src)
184+
{
185+
return to_upper_copy(trim(src));
186+
}
187+
175188
void Input::reader(const PCMInput & host_input)
176189
{
177190
CODATAyear_ = 2010;
178191

179-
type_ = to_upper_copy(std::string(host_input.cavity_type));
192+
type_ = trim_and_upper(host_input.cavity_type);
180193
area_ = host_input.area * angstrom2ToBohr2(CODATAyear_);
181194
patchLevel_ = host_input.patch_level;
182195
coarsity_ = host_input.coarsity * angstromToBohr(CODATAyear_);
183196
minDistance_ = host_input.min_distance * angstromToBohr(CODATAyear_);
184197
derOrder_ = host_input.der_order;
185198
if (type_ == "RESTART") {
186-
cavFilename_ = std::string(host_input.restart_name); // No case conversion here!
199+
cavFilename_ = trim(host_input.restart_name); // No case conversion here!
187200
}
188201

189202
scaling_ = host_input.scaling;
190-
radiiSet_ = host_input.radii_set;
203+
radiiSet_ = trim_and_upper(host_input.radii_set);
191204
minimalRadius_ = host_input.min_radius * angstromToBohr(CODATAyear_);
192205
mode_ = std::string("IMPLICIT");
193206

194-
std::string name = to_upper_copy(std::string(host_input.solvent));
207+
std::string name = trim_and_upper(host_input.solvent);
195208
if (name.empty()) {
196209
hasSolvent_ = false;
197210
// Get the probe radius
198211
probeRadius_ = host_input.probe_radius * angstromToBohr(CODATAyear_);
199212
// Get the contents of the Green<inside> section...
200213
// ...and initialize the data members
201-
greenInsideType_ = to_upper_copy(std::string(host_input.inside_type));
214+
greenInsideType_ = trim_and_upper(host_input.inside_type);
202215
derivativeInsideType_ = derivativeTraits("DERIVATIVE");
203216
epsilonInside_ = 1.0;
204217
// Get the contents of the Green<outside> section...
205218
// ...and initialize the data members
206-
greenOutsideType_ = to_upper_copy(std::string(host_input.outside_type));
219+
greenOutsideType_ = trim_and_upper(host_input.outside_type);
207220
derivativeOutsideType_ = derivativeTraits("DERIVATIVE");
208221
epsilonStaticOutside_ = host_input.outside_epsilon;
209222
epsilonDynamicOutside_ = host_input.outside_epsilon;
@@ -226,8 +239,8 @@ void Input::reader(const PCMInput & host_input)
226239
}
227240
integratorType_ = integratorPolicy("COLLOCATION"); // Currently hardcoded!!!
228241

229-
solverType_ = to_upper_copy(std::string(host_input.solver_type));
230-
std::string inteq = to_upper_copy(std::string(host_input.equation_type));
242+
solverType_ = trim_and_upper(host_input.solver_type);
243+
std::string inteq = trim_and_upper(host_input.equation_type);
231244
equationType_ = integralEquation(inteq);
232245
correction_ = host_input.correction;
233246
hermitivitize_ = true;

src/utils/Input.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ class Input
136136
* The "Atoms" and "Explicit" methods are only available using the explicit parsing
137137
* by our Python script of a separate input file.
138138
*/
139-
void reader(const PCMInput & host_input);
139+
void reader(const PCMInput & host_input);
140140
/*! Perform semantic input parsing aka sanity check */
141141
void semanticCheck();
142142

@@ -264,4 +264,8 @@ int profilePolicy(const std::string & name);
264264
/*! A useful map to convert the EquationType string to an integer which will be passed to the Solver CTOR. */
265265
int integralEquation(const std::string & name);
266266

267+
std::string trim(const char * src);
268+
269+
std::string trim_and_upper(const char * src);
270+
267271
#endif // INPUT_HPP

0 commit comments

Comments
 (0)