48#include "applications/sequentialProps/ContactAngle2.hpp"
55#include "math/Eigenvalue.hpp"
57#include "utils/Constants.hpp"
58#include "utils/simError.h"
62 ContactAngle2::ContactAngle2(
SimInfo* info,
const std::string& filename,
63 const std::string& sele1,
64 const std::string& sele2, RealType solidZ,
65 RealType centroidX, RealType centroidY,
66 RealType threshDens, RealType bufferLength,
67 int nrbins,
int nzbins) :
69 solidZ_(solidZ), centroidX_(centroidX), centroidY_(centroidY),
70 threshDens_(threshDens), bufferLength_(bufferLength), nRBins_(nrbins),
72 setOutputName(
getPrefix(filename) +
".ca2");
74 std::stringstream params;
75 params <<
" referenceZ = " << solidZ_ <<
", centroid = (" << centroidX_
76 <<
", " << centroidY_ <<
")"
77 <<
", threshDens = " << threshDens_
78 <<
", bufferLength = " << bufferLength_ <<
", nbins = " << nRBins_
79 <<
", nbins_z = " << nZBins_;
81 const std::string paramString = params.str();
82 setParameterString(paramString);
85 void ContactAngle2::doFrame(
int) {
91 Mat3x3d hmat = info_->getSnapshotManager()->getCurrentSnapshot()->getHmat();
92 RealType len = std::min(hmat(0, 0), hmat(1, 1));
93 RealType zLen = hmat(2, 2);
95 RealType dr = len / (RealType)nRBins_;
96 RealType dz = zLen / (RealType)nZBins_;
98 std::vector<std::vector<RealType>> histo;
99 histo.resize(nRBins_);
100 for (
unsigned int i = 0; i < histo.size(); ++i) {
101 histo[i].resize(nZBins_);
102 std::fill(histo[i].begin(), histo[i].end(), 0.0);
105 if (evaluator1_.isDynamic()) {
106 seleMan1_.setSelectionSet(evaluator1_.evaluate());
109 Vector3d com(centroidX_, centroidY_, solidZ_);
116 for (sd = seleMan1_.beginSelected(i); sd != NULL;
117 sd = seleMan1_.nextSelected(i)) {
118 pos = sd->getPos() - com;
121 r = std::sqrt(std::pow(pos.x(), 2) + std::pow(pos.y(), 2));
125 int whichRBin = int(r / dr);
126 int whichZBin = int((zLen / 2.0 + z) / dz);
128 if ((whichRBin <
int(nRBins_)) && (whichZBin >= 0) &&
129 (whichZBin <
int(nZBins_))) {
130 histo[whichRBin][whichZBin] += sd->getMass();
134 for (
unsigned int i = 0; i < histo.size(); ++i) {
135 RealType rL = i * dr;
136 RealType rU = rL + dr;
137 RealType volSlice = Constants::PI * dz * ((rU * rU) - (rL * rL));
139 for (
unsigned int j = 0; j < histo[i].size(); ++j) {
140 histo[i][j] *= Constants::densityConvert / volSlice;
144 std::vector<Vector<RealType, 2>> points;
147 for (
unsigned int j = 0; j < nZBins_; ++j) {
153 RealType thez = com.z() - solidZ_ - zLen / 2.0 + dz * (j + 0.5);
154 bool aboveThresh =
false;
155 bool foundThresh =
false;
158 for (std::size_t i = 0; i < nRBins_; ++i) {
159 if (histo[i][j] >= threshDens_) aboveThresh =
true;
161 if (aboveThresh && (histo[i][j] <= threshDens_)) {
168 Vector<RealType, 2> point;
169 point[0] = dr * (rloc + 0.5);
172 if (thez > bufferLength_) { points.push_back(point); }
176 int numPoints = points.size();
179 Vector<RealType, 2> average = points[0];
181 for (i0 = 1; i0 < numPoints; ++i0) {
182 average += points[i0];
184 RealType invNumPoints = ((RealType)1) / (RealType)numPoints;
185 average *= invNumPoints;
189 for (row = 0; row < 4; ++row) {
190 for (col = 0; col < 4; ++col) {
194 for (
int i = 0; i < numPoints; ++i) {
195 RealType x = points[i][0];
196 RealType y = points[i][1];
200 RealType r2 = x2 + y2;
201 RealType xr2 = x * r2;
202 RealType yr2 = y * r2;
203 RealType r4 = r2 * r2;
215 mat(0, 0) = (RealType)numPoints;
217 for (row = 0; row < 4; ++row) {
218 for (col = 0; col < row; ++col) {
219 mat(row, col) = mat(col, row);
223 for (row = 0; row < 4; ++row) {
224 for (col = 0; col < 4; ++col) {
225 mat(row, col) *= invNumPoints;
233 eigensystem.getRealEigenvalues(evals);
234 eigensystem.getV(evects);
237 RealType inv = ((RealType)1) / evector[3];
239 for (row = 0; row < 3; ++row) {
240 coeff[row] = inv * evector[row];
243 Vector<RealType, 2> center;
245 center[0] = -((RealType)0.5) * coeff[1];
246 center[1] = -((RealType)0.5) * coeff[2];
248 std::sqrt(std::abs(center[0] * center[0] +
249 center[1] * center[1] - coeff[0]));
252 for (i1 = 0; i1 < 100; ++i1) {
254 Vector<RealType, 2> current = center;
257 RealType lenAverage = (RealType)0;
258 Vector<RealType, 2> derLenAverage = Vector<RealType, 2>(0.0);
259 for (i0 = 0; i0 < numPoints; ++i0) {
260 Vector<RealType, 2> diff = points[i0] - center;
261 RealType length = diff.length();
263 lenAverage += length;
264 RealType invLength = ((RealType)1) / length;
265 derLenAverage -= invLength * diff;
268 lenAverage *= invNumPoints;
269 derLenAverage *= invNumPoints;
271 center = average + lenAverage * derLenAverage;
274 Vector<RealType, 2> diff = center - current;
275 if (std::abs(diff[0]) <= 1e-6 && std::abs(diff[1]) <= 1e-6) {
break; }
278 RealType zCen = center[1];
279 RealType rDrop = radius;
282 if (std::abs(zCen) > rDrop) {
285 ca = 90.0 + std::asin(zCen / rDrop) * (180.0 / Constants::PI);
288 values_.push_back(ca);
Computes eigenvalues and eigenvectors of a real (non-complex) matrix.
Rectangular matrix class with contiguous flat storage.
Dynamically-sized vector class.
"applications/sequentialProps/SequentialAnalyzer"
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
std::string getPrefix(const std::string &str)