OpenMD 3.2
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
ContactAngle1.cpp
1/*
2 * Copyright (c) 2004-present, The University of Notre Dame. All rights
3 * reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
32 * research, please cite the following paper when you publish your work:
33 *
34 * [1] Drisko et al., J. Open Source Softw. 9, 7004 (2024).
35 *
36 * Good starting points for code and simulation methodology are:
37 *
38 * [2] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
39 * [3] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
40 * [4] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
41 * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
42 * [6] Kuang & Gezelter, Mol. Phys., 110, 691-701 (2012).
43 * [7] Lamichhane, Gezelter & Newman, J. Chem. Phys. 141, 134109 (2014).
44 * [8] Bhattarai, Newman & Gezelter, Phys. Rev. B 99, 094106 (2019).
45 * [9] Drisko & Gezelter, J. Chem. Theory Comput. 20, 4986-4997 (2024).
46 */
47
48#include "applications/sequentialProps/ContactAngle1.hpp"
49
50#include <algorithm>
51#include <functional>
52#include <sstream>
53
54#include "io/DumpReader.hpp"
55#include "math/Polynomial.hpp"
57#include "utils/Constants.hpp"
58#include "utils/simError.h"
59
60namespace OpenMD {
61
62 ContactAngle1::ContactAngle1(SimInfo* info, const std::string& filename,
63 const std::string& sele1,
64 const std::string& sele2, RealType solidZ,
65 RealType dropletRadius) :
66 SequentialAnalyzer(info, filename, sele1, sele2),
67 solidZ_(solidZ), dropletRadius_(dropletRadius) {
68 setOutputName(getPrefix(filename) + ".ca1");
69
70 std::stringstream params;
71 params << " solid Z = " << solidZ_
72 << ", droplet radius = " << dropletRadius_;
73
74 const std::string paramString = params.str();
75 setParameterString(paramString);
76 }
77
78 void ContactAngle1::doFrame(int) {
79 StuntDouble* sd;
80 int i;
81
82 if (evaluator1_.isDynamic()) {
83 seleMan1_.setSelectionSet(evaluator1_.evaluate());
84 }
85
86 RealType mtot = 0.0;
87 Vector3d com(V3Zero);
88 RealType mass;
89
90 // Prevents double counting atoms that are part of rigid bodies
91 // and therefore miscalculating the total mass:
92
93 auto reducedSeleMan = seleMan1_.removeAtomsInRigidBodies();
94
95 for (sd = reducedSeleMan.beginSelected(i); sd != NULL;
96 sd = reducedSeleMan.nextSelected(i)) {
97 mass = sd->getMass();
98 mtot += mass;
99 com += sd->getPos() * mass;
100 }
101
102 com /= mtot;
103
104 RealType dz = com.z() - solidZ_;
105
106 if (dz < 0.0) {
107 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
108 "ContactAngle1: Z-center of mass of selection, %lf, was\n"
109 "\tlocated below the solid reference plane, %lf\n",
110 com.z(), solidZ_);
111 painCave.isFatal = 1;
112 painCave.severity = OPENMD_ERROR;
113 simError();
114 }
115
116 if (dz > dropletRadius_) {
117 values_.push_back(180.0);
118 } else {
119 RealType k = pow(2.0, -4.0 / 3.0) * dropletRadius_;
120
121 RealType z2 = dz * dz;
122 RealType z3 = z2 * dz;
123 RealType k2 = k * k;
124 RealType k3 = k2 * k;
125
126 Polynomial<RealType> poly;
127 poly.setCoefficient(4, z3 + k3);
128 poly.setCoefficient(3, 8.0 * z3 + 8.0 * k3);
129 poly.setCoefficient(2, 24.0 * z3 + 18.0 * k3);
130 poly.setCoefficient(1, 32.0 * z3);
131 poly.setCoefficient(0, 16.0 * z3 - 27.0 * k3);
132 vector<RealType> realRoots = poly.FindRealRoots();
133
134 RealType ct;
135
136 vector<RealType>::iterator ri;
137
138 RealType maxct = -1.0;
139 for (ri = realRoots.begin(); ri != realRoots.end(); ++ri) {
140 ct = *ri;
141 if (ct > 1.0) ct = 1.0;
142 if (ct < -1.0) ct = -1.0;
143
144 // use the largest magnitude of ct that it finds:
145 if (ct > maxct) { maxct = ct; }
146 }
147
148 values_.push_back(acos(maxct) * (180.0 / Constants::PI));
149 }
150 }
151} // namespace OpenMD
"applications/sequentialProps/SequentialAnalyzer"
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
Definition SimInfo.hpp:96
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
std::string getPrefix(const std::string &str)