- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Actions/FillAction/SuspendInMoleculeAction.cpp
r2440ce raa55d0 129 129 filler->CenterEdge(); 130 130 131 /// first we need to calculate some volumes and masses 131 132 std::vector<molecule *> molecules = World::getInstance().getAllMolecules(); 132 if (molecules.size() < 2) {133 STATUS("There must be at least two molecules: filler and to be suspended.");134 return Action::failure;135 }136 137 /// first we need to calculate some volumes and masses138 133 double totalmass = 0.; 139 134 const bool IsAngstroem = true; … … 144 139 iter != molecules.end(); ++iter) 145 140 { 146 // skip the filler147 if (*iter == filler)148 continue;149 141 molecule & mol = **iter; 150 142 const double mass = calculateMass(mol); … … 160 152 LOG(1, "INFO: The average density is " << setprecision(10) 161 153 << totalmass / clustervolume << " atomicmassunit/" 162 << (IsAngstroem ? " angstrom" : " atomiclength") << "^3."); 163 if ( ((totalmass / clustervolume < 1.) && (params.density.get() > 1.)) 164 || ((totalmass / clustervolume > 1.) && (params.density.get() < 1.))) { 165 STATUS("Desired and present molecular densities must both be either in [0,1) or in (1, inf)."); 166 return Action::failure; 167 } 154 << (IsAngstroem ? "angstrom" : "atomiclength") << "^3."); 168 155 169 156 // calculate maximum solvent density 170 157 std::vector<double> fillerdiameters(NDIM, 0.); 171 const double fillervolume = calculateEnvelopeVolume(*filler, fillerdiameters); 172 const double fillermass = calculateMass(*filler); 173 LOG(1, "INFO: The filler's mass is " << setprecision(10) 174 << fillermass << " atomicmassunit, and it's volume is " 175 << fillervolume << (IsAngstroem ? " angstrom" : " atomiclength") << "^3."); 176 const double solventdensity = fillermass / fillervolume; 158 const double solventdensity = 159 calculateMass(*filler) / calculateEnvelopeVolume(*filler, fillerdiameters); 160 161 std::vector<unsigned int> counts(3, 0); 162 Vector offset(.5,.5,.5); 177 163 178 164 /// solve cubic polynomial 179 165 double cellvolume = 0.; 180 166 LOG(1, "Solving equidistant suspension in water problem ..."); 181 // s = solvent, f = filler, 0 = initial molecules/cluster 182 // v_s = v_0 + v_f, m_s = m_0 + rho_f * v_f --> rho_s = m_s/v_s ==> v_f = (m_0 - rho_s * v_o) / (rho_s - rho_f) 183 cellvolume = (totalmass - params.density.get() * clustervolume) / (params.density.get() - 1.) + clustervolume; 167 cellvolume = (totalmass / solventdensity 168 - (totalmass / clustervolume)) / (params.density.get() - 1.); 184 169 LOG(1, "Cellvolume needed for a density of " << params.density.get() 185 170 << " g/cm^3 is " << cellvolume << " angstroem^3."); … … 188 173 (GreatestDiameter[0] * GreatestDiameter[1] * GreatestDiameter[2]); 189 174 LOG(1, "Minimum volume of the convex envelope contained in a rectangular box is " 190 << minimumvolume << " 175 << minimumvolume << "angstrom^3."); 191 176 192 177 if (minimumvolume > cellvolume) { … … 202 187 + GreatestDiameter[1] * GreatestDiameter[2]; 203 188 BoxLengths[2] = minimumvolume - cellvolume; 204 std::vector<double> x(3, 0.); 189 double x0 = 0.; 190 double x1 = 0.; 191 double x2 = 0.; 205 192 // for cubic polynomial there are either 1 or 3 unique solutions 206 if (gsl_poly_solve_cubic(BoxLengths[0], BoxLengths[1], BoxLengths[2], &x[0], &x[1], &x[2]) == 1) { 207 x[1] = x[0]; 208 x[2] = x[0]; 209 } else { 210 std::swap(x[0], x[2]); // sorted in ascending order 211 } 212 LOG(0, "RESULT: The resulting spacing is: " << x << " ."); 193 if (gsl_poly_solve_cubic(BoxLengths[0], BoxLengths[1], BoxLengths[2], &x0, &x1, &x2) == 1) 194 LOG(0, "RESULT: The resulting spacing is: " << x0 << " ."); 195 else { 196 LOG(0, "RESULT: The resulting spacings are: " << x0 << " and " << x1 << " and " << x2 << " ."); 197 std::swap(x0, x2); // sorted in ascending order 198 } 213 199 214 200 cellvolume = 1.; 215 201 for (size_t i = 0; i < NDIM; ++i) { 216 BoxLengths[i] = x [i]+ GreatestDiameter[i];202 BoxLengths[i] = x0 + GreatestDiameter[i]; 217 203 cellvolume *= BoxLengths[i]; 218 204 } 219 } 220 221 // TODO: Determine counts from resulting mass correctly (hard problem due to integers) 222 std::vector<unsigned int> counts(3, 0); 223 const unsigned int totalcounts = round(params.density.get() * cellvolume - totalmass) / fillermass; 224 if (totalcounts > 0) { 225 counts[0] = ceil(BoxLengths[0]/3.1); 226 counts[1] = ceil(BoxLengths[1]/3.1); 227 counts[2] = ceil(BoxLengths[2]/3.1); 205 206 // set new box dimensions 207 LOG(0, "Translating to box with these boundaries."); 208 { 209 RealSpaceMatrix domain; 210 for(size_t i =0; i<NDIM;++i) 211 domain.at(i,i) = BoxLengths[i]; 212 World::getInstance().setDomain(domain); 213 } 214 // mol->CenterInBox(); 228 215 } 229 216 … … 244 231 params.RandMoleculeDisplacement.get(), 245 232 params.DoRotate.get()); 246 Vector offset(.5,.5,.5);247 233 filler_preparator.addCubeMesh( 248 234 counts,
Note:
See TracChangeset
for help on using the changeset viewer.