- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Actions/FillAction/SuspendInMoleculeAction.cpp
raa55d0 r2440ce 129 129 filler->CenterEdge(); 130 130 131 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 131 137 /// first we need to calculate some volumes and masses 132 std::vector<molecule *> molecules = World::getInstance().getAllMolecules();133 138 double totalmass = 0.; 134 139 const bool IsAngstroem = true; … … 139 144 iter != molecules.end(); ++iter) 140 145 { 146 // skip the filler 147 if (*iter == filler) 148 continue; 141 149 molecule & mol = **iter; 142 150 const double mass = calculateMass(mol); … … 152 160 LOG(1, "INFO: The average density is " << setprecision(10) 153 161 << totalmass / clustervolume << " atomicmassunit/" 154 << (IsAngstroem ? "angstrom" : "atomiclength") << "^3."); 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 } 155 168 156 169 // calculate maximum solvent density 157 170 std::vector<double> fillerdiameters(NDIM, 0.); 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); 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; 163 177 164 178 /// solve cubic polynomial 165 179 double cellvolume = 0.; 166 180 LOG(1, "Solving equidistant suspension in water problem ..."); 167 cellvolume = (totalmass / solventdensity 168 - (totalmass / clustervolume)) / (params.density.get() - 1.); 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; 169 184 LOG(1, "Cellvolume needed for a density of " << params.density.get() 170 185 << " g/cm^3 is " << cellvolume << " angstroem^3."); … … 173 188 (GreatestDiameter[0] * GreatestDiameter[1] * GreatestDiameter[2]); 174 189 LOG(1, "Minimum volume of the convex envelope contained in a rectangular box is " 175 << minimumvolume << " angstrom^3.");190 << minimumvolume << " angstrom^3."); 176 191 177 192 if (minimumvolume > cellvolume) { … … 187 202 + GreatestDiameter[1] * GreatestDiameter[2]; 188 203 BoxLengths[2] = minimumvolume - cellvolume; 189 double x0 = 0.; 190 double x1 = 0.; 191 double x2 = 0.; 204 std::vector<double> x(3, 0.); 192 205 // for cubic polynomial there are either 1 or 3 unique solutions 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 } 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 << " ."); 199 213 200 214 cellvolume = 1.; 201 215 for (size_t i = 0; i < NDIM; ++i) { 202 BoxLengths[i] = x 0+ GreatestDiameter[i];216 BoxLengths[i] = x[i] + GreatestDiameter[i]; 203 217 cellvolume *= BoxLengths[i]; 204 218 } 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(); 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); 215 228 } 216 229 … … 231 244 params.RandMoleculeDisplacement.get(), 232 245 params.DoRotate.get()); 246 Vector offset(.5,.5,.5); 233 247 filler_preparator.addCubeMesh( 234 248 counts,
Note:
See TracChangeset
for help on using the changeset viewer.