45#include "applications/sequentialProps/ContactAngle2.hpp"
52#include "math/Eigenvalue.hpp"
54#include "utils/Constants.hpp"
55#include "utils/simError.h"
59 ContactAngle2::ContactAngle2(
SimInfo* info,
const std::string& filename,
60 const std::string& sele1,
61 const std::string& sele2, RealType solidZ,
62 RealType centroidX, RealType centroidY,
63 RealType threshDens, RealType bufferLength,
64 int nrbins,
int nzbins) :
66 solidZ_(solidZ), centroidX_(centroidX), centroidY_(centroidY),
67 threshDens_(threshDens), bufferLength_(bufferLength), nRBins_(nrbins),
69 setOutputName(
getPrefix(filename) +
".ca2");
71 std::stringstream params;
72 params <<
" referenceZ = " << solidZ_ <<
", centroid = (" << centroidX_
73 <<
", " << centroidY_ <<
")"
74 <<
", threshDens = " << threshDens_
75 <<
", bufferLength = " << bufferLength_ <<
", nbins = " << nRBins_
76 <<
", nbins_z = " << nZBins_;
78 const std::string paramString = params.str();
79 setParameterString(paramString);
82 void ContactAngle2::doFrame(
int) {
89 RealType len = std::min(hmat(0, 0), hmat(1, 1));
90 RealType zLen = hmat(2, 2);
92 RealType dr = len / (RealType)nRBins_;
93 RealType dz = zLen / (RealType)nZBins_;
95 std::vector<std::vector<RealType>> histo;
96 histo.resize(nRBins_);
97 for (
unsigned int i = 0; i < histo.size(); ++i) {
98 histo[i].resize(nZBins_);
99 std::fill(histo[i].begin(), histo[i].end(), 0.0);
103 seleMan1_.setSelectionSet(evaluator1_.evaluate());
106 Vector3d com(centroidX_, centroidY_, solidZ_);
118 r = sqrt(pow(pos.
x(), 2) + pow(pos.
y(), 2));
122 int whichRBin = int(r / dr);
123 int whichZBin = int((zLen / 2.0 + z) / dz);
125 if ((whichRBin <
int(nRBins_)) && (whichZBin >= 0) &&
126 (whichZBin <
int(nZBins_))) {
127 histo[whichRBin][whichZBin] += sd->
getMass();
131 for (
unsigned int i = 0; i < histo.size(); ++i) {
132 RealType rL = i * dr;
133 RealType rU = rL + dr;
134 RealType volSlice = Constants::PI * dz * ((rU * rU) - (rL * rL));
136 for (
unsigned int j = 0; j < histo[i].size(); ++j) {
137 histo[i][j] *= Constants::densityConvert / volSlice;
141 std::vector<Vector<RealType, 2>> points;
144 for (
unsigned int j = 0; j < nZBins_; ++j) {
150 RealType thez = com.z() - solidZ_ - zLen / 2.0 + dz * (j + 0.5);
151 bool aboveThresh =
false;
152 bool foundThresh =
false;
155 for (std::size_t i = 0; i < nRBins_; ++i) {
156 if (histo[i][j] >= threshDens_) aboveThresh =
true;
158 if (aboveThresh && (histo[i][j] <= threshDens_)) {
166 point[0] = dr * (rloc + 0.5);
169 if (thez > bufferLength_) { points.push_back(point); }
173 int numPoints = points.size();
178 for (i0 = 1; i0 < numPoints; ++i0) {
179 average += points[i0];
181 RealType invNumPoints = ((RealType)1) / (RealType)numPoints;
182 average *= invNumPoints;
186 for (row = 0; row < 4; ++row) {
187 for (col = 0; col < 4; ++col) {
191 for (
int i = 0; i < numPoints; ++i) {
192 RealType x = points[i][0];
193 RealType y = points[i][1];
197 RealType r2 = x2 + y2;
198 RealType xr2 = x * r2;
199 RealType yr2 = y * r2;
200 RealType r4 = r2 * r2;
212 mat(0, 0) = (RealType)numPoints;
214 for (row = 0; row < 4; ++row) {
215 for (col = 0; col < row; ++col) {
216 mat(row, col) = mat(col, row);
220 for (row = 0; row < 4; ++row) {
221 for (col = 0; col < 4; ++col) {
222 mat(row, col) *= invNumPoints;
230 eigensystem.getRealEigenvalues(evals);
231 eigensystem.getV(evects);
234 RealType inv = ((RealType)1) / evector[3];
236 for (row = 0; row < 3; ++row) {
237 coeff[row] = inv * evector[row];
242 center[0] = -((RealType)0.5) * coeff[1];
243 center[1] = -((RealType)0.5) * coeff[2];
245 sqrt(fabs(center[0] * center[0] + center[1] * center[1] - coeff[0]));
248 for (i1 = 0; i1 < 100; ++i1) {
253 RealType lenAverage = (RealType)0;
255 for (i0 = 0; i0 < numPoints; ++i0) {
257 RealType length = diff.
length();
259 lenAverage += length;
260 RealType invLength = ((RealType)1) / length;
261 derLenAverage -= invLength * diff;
264 lenAverage *= invNumPoints;
265 derLenAverage *= invNumPoints;
267 center = average + lenAverage * derLenAverage;
271 if (fabs(diff[0]) <= 1e-6 && fabs(diff[1]) <= 1e-6) {
break; }
274 RealType zCen = center[1];
275 RealType rDrop = radius;
278 if (fabs(zCen) > rDrop) {
281 ca = 90.0 + asin(zCen / rDrop) * (180.0 / Constants::PI);
284 values_.push_back(ca);
Computes eigenvalues and eigenvectors of a real (non-complex) matrix.
Dynamically-sized vector class.
bool isDynamic()
Tests if the result from evaluation of script is dynamic.
StuntDouble * nextSelected(int &i)
Finds the next selected StuntDouble in the selection.
StuntDouble * beginSelected(int &i)
Finds the first selected StuntDouble in the selection.
"applications/sequentialProps/SequentialAnalyzer"
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
SnapshotManager * getSnapshotManager()
Returns the snapshot manager.
Mat3x3d getHmat()
Returns the H-Matrix.
Snapshot * getCurrentSnapshot()
Returns the pointer of current snapshot.
"Don't move, or you're dead! Stand up! Captain, we've got them!"
RealType getMass()
Returns the mass of this stuntDouble.
Vector3d getPos()
Returns the current position of this stuntDouble.
Real & z()
Returns reference of the third element of Vector3.
Real & x()
Returns reference of the first element of Vector3.
Real & y()
Returns reference of the second element of Vector3.
Real length()
Returns the length of this vector.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
std::string getPrefix(const std::string &str)